|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "plastictool.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzTools includes
|
|
Shinya Kitaoka |
120a6e |
#include "tw/keycodes.h" // Obsolete by now... still currently used though
|
|
Toshihiro Shimizu |
890ddd |
#include "tooloptionscontrols.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tools/toolcommandids.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzQt includes
|
|
Toshihiro Shimizu |
890ddd |
#include "toonzqt/selection.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonzqt/tselectionhandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonzqt/dvmimedata.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonzqt/dvdialog.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonzqt/selectioncommandids.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzLib includes
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tframehandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tcolumnhandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txsheethandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tobjecthandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tonionskinmaskhandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tstageobject.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/doubleparamcmd.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/palettecontroller.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshsimplelevel.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzExt includes
|
|
Toshihiro Shimizu |
890ddd |
#include "ext/plasticskeleton.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ext/plasticdeformerstorage.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzCore includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tgl.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tundo.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tfunctorinvoker.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Qt includes
|
|
Toshihiro Shimizu |
890ddd |
#include <qapplication></qapplication>
|
|
Toshihiro Shimizu |
890ddd |
#include <qstring></qstring>
|
|
Campbell Barton |
d0e335 |
#include <qtoolbar></qtoolbar>
|
|
Toshihiro Shimizu |
890ddd |
#include <qpushbutton></qpushbutton>
|
|
Toshihiro Shimizu |
890ddd |
#include <qlabel></qlabel>
|
|
Toshihiro Shimizu |
890ddd |
#include <qclipboard></qclipboard>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// tcg includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tcg/tcg_macros.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcg/tcg_point_ops.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcg/tcg_list.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcg/tcg_function_types.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcg/tcg_iterator_ops.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Local namespace
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
static const double l_dmax = (std::numeric_limits<double>::max)();</double>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// PlasticToolLocals namespace
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
using namespace PlasticToolLocals;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace PlasticToolLocals {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
PlasticTool l_plasticTool;
|
|
Toshihiro Shimizu |
890ddd |
bool l_suspendParamsObservation = false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPointD projection(const PlasticSkeleton &skeleton, int e, const TPointD &pos) {
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeleton::edge_type &ed = skeleton.edge(e);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TPointD &p0 = skeleton.vertex(ed.vertex(0)).P();
|
|
Shinya Kitaoka |
120a6e |
const TPointD &p1 = skeleton.vertex(ed.vertex(1)).P();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return tcg::point_ops::projection(pos, p0, tcg::point_ops::direction(p0, p1));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double frame() {
|
|
Shinya Kitaoka |
120a6e |
return TTool::getApplication()->getCurrentFrame()->getFrame();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int row() { return int(frame()) + 1; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int column() {
|
|
Shinya Kitaoka |
120a6e |
return TTool::getApplication()->getCurrentColumn()->getColumnIndex();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void setCell(int row, int col) {
|
|
Shinya Kitaoka |
120a6e |
TTool::Application *app = TTool::getApplication();
|
|
Shinya Kitaoka |
120a6e |
app->getCurrentFrame()->setCurrentFrame(row);
|
|
Shinya Kitaoka |
120a6e |
app->getCurrentColumn()->setColumnIndex(col);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TXshColumn *xshColumn() {
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = TTool::getApplication()->getCurrentXsheet()->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
return xsh->getColumn(column());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStageObject *stageObject() {
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = TTool::getApplication()->getCurrentXsheet()->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
return xsh->getStageObject(TStageObjectId::ColumnId(column()));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TXshCell &xshCell() {
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = TTool::getApplication()->getCurrentXsheet()->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
return xsh->getCell(frame(), column());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int skeletonId() {
|
|
Shinya Kitaoka |
120a6e |
TStageObject *obj = stageObject();
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonDeformationP &def = obj->getPlasticSkeletonDeformation();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return def ? def->skeletonId(obj->paramsTime(frame()))
|
|
Shinya Kitaoka |
120a6e |
: 1; // 1 (not -1) is intended.
|
|
Shinya Kitaoka |
120a6e |
} // Means '' (empty string)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double sdFrame() { return stageObject()->paramsTime(frame()); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void setKeyframe(TDoubleParamP ¶m, double frame) {
|
|
Shinya Kitaoka |
120a6e |
if (!param->isKeyframe(frame)) {
|
|
Shinya Kitaoka |
120a6e |
KeyframeSetter setter(param.getPointer(), -1,
|
|
Shinya Kitaoka |
120a6e |
false); // Not placing undos through this setter
|
|
Shinya Kitaoka |
120a6e |
setter.createKeyframe(frame);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void setKeyframe(SkVD *vd, double frame) {
|
|
Shinya Kitaoka |
120a6e |
// vd->setKeyframe(frame); // Nope. In fact...
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Keyframe set is performed with a special tool that is NOT AVAILABLE in
|
|
Shinya Kitaoka |
120a6e |
// TnzExt
|
|
Shinya Kitaoka |
120a6e |
// (thus, not available to m_sd). It deals with specifying the correct
|
|
Shinya Kitaoka |
120a6e |
// interpolation
|
|
Shinya Kitaoka |
120a6e |
// type (by user preference, which is TnzLib stuff), etc...
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Traverse vd's parameters. In case they don't have a keyframe at current
|
|
Shinya Kitaoka |
120a6e |
// frame, add one.
|
|
Shinya Kitaoka |
120a6e |
for (int p = 0; p < SkVD::PARAMS_COUNT; ++p)
|
|
Shinya Kitaoka |
120a6e |
setKeyframe(vd->m_params[p], frame);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void setKeyframe(const PlasticSkeletonDeformationP &sd, double frame) {
|
|
Shinya Kitaoka |
120a6e |
// NOTE: The skeleton ids parameter is NOT affected
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
SkD::vd_iterator vdt, vdEnd;
|
|
Shinya Kitaoka |
120a6e |
sd->vertexDeformations(vdt, vdEnd);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (; vdt != vdEnd; ++vdt) setKeyframe((*vdt).second, frame);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void invalidateXsheet() {
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged();
|
|
Shinya Kitaoka |
120a6e |
stageObject()->updateKeyframes();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
l_plasticTool.storeDeformation();
|
|
Shinya Kitaoka |
120a6e |
l_plasticTool.invalidate();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace PlasticToolLocals
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Mime definitions
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
struct PlasticSkeletonPMime final : public DvMimeData {
|
|
Shinya Kitaoka |
120a6e |
PlasticSkeletonP m_skeleton;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
PlasticSkeletonPMime(const PlasticSkeletonP &skeleton)
|
|
Shinya Kitaoka |
120a6e |
: m_skeleton(skeleton) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
473e70 |
DvMimeData *clone() const override {
|
|
Shinya Kitaoka |
120a6e |
return new PlasticSkeletonPMime(m_skeleton);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
473e70 |
|
|
Shinya Kitaoka |
473e70 |
void releaseData() override { m_skeleton = PlasticSkeletonP(); }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
struct SkDPMime final : public DvMimeData {
|
|
Shinya Kitaoka |
120a6e |
SkDP m_sd;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
SkDPMime(const SkDP &sd) : m_sd(sd) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
473e70 |
DvMimeData *clone() const override { return new SkDPMime(m_sd); }
|
|
Shinya Kitaoka |
473e70 |
|
|
Shinya Kitaoka |
473e70 |
void releaseData() override { m_sd = SkDP(); }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Undo definitions
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// NOTE: Some of the following UNDOs have complex and dynamic contents, and I
|
|
Shinya Kitaoka |
120a6e |
// don't want to
|
|
Shinya Kitaoka |
120a6e |
// trace their size thoroughly. So, I'll follow this guideline: given the
|
|
Shinya Kitaoka |
120a6e |
// standard
|
|
Shinya Kitaoka |
120a6e |
// 100 MB undos pool, how many undos of one specific type I'd want the
|
|
Shinya Kitaoka |
120a6e |
// pool to be able
|
|
Toshihiro Shimizu |
890ddd |
// to store?
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class SetVertexNameUndo final : public TUndo {
|
|
Shinya Kitaoka |
120a6e |
int m_row, m_col; //!< Xsheet coordinates
|
|
Shinya Kitaoka |
120a6e |
int m_v; //!< Changed vertex
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
mutable QString m_oldName, m_newName; //!< Vertex names
|
|
Shinya Kitaoka |
120a6e |
mutable SkVD
|
|
Shinya Kitaoka |
120a6e |
m_oldVd; //!< Old Vertex deformation (SHARE-OWNED, rather than CLONED)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
SetVertexNameUndo(int v, const QString &newName)
|
|
Shinya Kitaoka |
120a6e |
: m_row(::row()), m_col(::column()), m_v(v), m_newName(newName) {
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonP &skeleton = l_plasticTool.skeleton();
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonVertex &vx = skeleton->vertex(v);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_oldName = vx.name();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
38fd86 |
int getSize() const override {
|
|
Shinya Kitaoka |
38fd86 |
return sizeof(*this);
|
|
Shinya Kitaoka |
38fd86 |
} // sizeof this is roughly ok
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
473e70 |
void redo() const override {
|
|
Shinya Kitaoka |
120a6e |
PlasticTool::TemporaryActivation tempActivate(m_row, m_col);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Store the vertex deformation before it's released (possibly destroyed)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
const SkDP &sd = l_plasticTool.deformation();
|
|
Shinya Kitaoka |
120a6e |
TCG_ASSERT(sd, return );
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const SkVD *vd = sd->vertexDeformation(m_oldName);
|
|
Shinya Kitaoka |
120a6e |
TCG_ASSERT(vd, return );
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_oldVd = *vd;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_v >= 0) l_plasticTool.setSkeletonSelection(m_v);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
l_plasticTool.setVertexName(m_newName);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
::invalidateXsheet();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
473e70 |
void undo() const override {
|
|
Shinya Kitaoka |
120a6e |
PlasticTool::TemporaryActivation tempActivate(m_row, m_col);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const SkDP &sd = l_plasticTool.deformation();
|
|
Shinya Kitaoka |
120a6e |
TCG_ASSERT(sd, return );
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_v >= 0) l_plasticTool.setSkeletonSelection(m_v);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
l_plasticTool.setVertexName(m_oldName);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Restore the vertex deformation.
|
|
Shinya Kitaoka |
120a6e |
SkVD *vd = sd->vertexDeformation(m_oldName);
|
|
Shinya Kitaoka |
120a6e |
assert(vd);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
*vd = m_oldVd;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
::invalidateXsheet();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//========================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class PasteDeformationUndo final : public TUndo {
|
|
Shinya Kitaoka |
120a6e |
int m_col; //!< Affected column
|
|
Shinya Kitaoka |
120a6e |
SkDP m_oldSd, m_newSd; //!< The skeleton deformations
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
PasteDeformationUndo(const SkDP &newSd)
|
|
Shinya Kitaoka |
120a6e |
: m_col(column())
|
|
Shinya Kitaoka |
120a6e |
, m_oldSd(stageObject()->getPlasticSkeletonDeformation())
|
|
Shinya Kitaoka |
120a6e |
, m_newSd(newSd) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
int getSize() const override { return 1 << 20; }
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void redo() const override {
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()->getCurrentColumn()->setColumnIndex(m_col);
|
|
Shinya Kitaoka |
120a6e |
stageObject()->setPlasticSkeletonDeformation(m_newSd);
|
|
Shinya Kitaoka |
120a6e |
::invalidateXsheet();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void undo() const override {
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()->getCurrentColumn()->setColumnIndex(m_col);
|
|
Shinya Kitaoka |
120a6e |
stageObject()->setPlasticSkeletonDeformation(m_oldSd);
|
|
Shinya Kitaoka |
120a6e |
::invalidateXsheet();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// PlasticTool::TemporaryActivation implementation
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
PlasticTool::TemporaryActivation::TemporaryActivation(int row, int col)
|
|
Shinya Kitaoka |
120a6e |
: m_activate(!l_plasticTool.isActive()) {
|
|
Shinya Kitaoka |
120a6e |
if (m_activate) l_plasticTool.onActivate();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
::setCell(row, col);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
PlasticTool::TemporaryActivation::~TemporaryActivation() {
|
|
Shinya Kitaoka |
120a6e |
if (m_activate) l_plasticTool.onDeactivate();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// PlasticToolOptionsBox::SkelIdComboBox definition
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class PlasticToolOptionsBox::SkelIdsComboBox final : public QComboBox {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
SkelIdsComboBox(QWidget *parent = 0) : QComboBox(parent) {
|
|
Shinya Kitaoka |
120a6e |
updateSkeletonsList();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void updateSkeletonsList();
|
|
Shinya Kitaoka |
120a6e |
void updateCurrentSkeleton();
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticToolOptionsBox::SkelIdsComboBox::updateSkeletonsList() {
|
|
Shinya Kitaoka |
120a6e |
clear();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const SkDP &sd = l_plasticTool.deformation();
|
|
Shinya Kitaoka |
120a6e |
if (!sd) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QStringList skeletonsList;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
SkD::skelId_iterator st, sEnd;
|
|
Shinya Kitaoka |
120a6e |
sd->skeletonIds(st, sEnd);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (; st != sEnd; ++st) skeletonsList.push_back(QString::number(*st));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QComboBox::insertItems(0, skeletonsList);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
updateCurrentSkeleton();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticToolOptionsBox::SkelIdsComboBox::updateCurrentSkeleton() {
|
|
Shinya Kitaoka |
120a6e |
setCurrentIndex(findText(QString::number(::skeletonId())));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// PlasticToolOptionsBox implementation
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
PlasticToolOptionsBox::PlasticToolOptionsBox(QWidget *parent, TTool *tool,
|
|
Shinya Kitaoka |
120a6e |
TPaletteHandle *pltHandle)
|
|
Shinya Kitaoka |
120a6e |
: GenericToolOptionsBox(parent, tool, pltHandle, PlasticTool::MODES_COUNT)
|
|
Shinya Kitaoka |
120a6e |
, m_tool(tool)
|
|
Shinya Kitaoka |
120a6e |
, m_subToolbars(new GenericToolOptionsBox *[PlasticTool::MODES_COUNT])
|
|
Toshihiro Shimizu |
890ddd |
//, m_subToolbarActions(new QAction*[PlasticTool::MODES_COUNT])
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
120a6e |
struct locals {
|
|
Shinya Kitaoka |
120a6e |
static inline QWidget *newSpace(QWidget *parent = 0) {
|
|
Shinya Kitaoka |
120a6e |
QWidget *space = new QWidget(parent);
|
|
Shinya Kitaoka |
120a6e |
space->setFixedWidth(TOOL_OPTIONS_LEFT_MARGIN);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return space;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Create Mesh button
|
|
Shinya Kitaoka |
120a6e |
QPushButton *meshifyButton = new QPushButton(tr("Create Mesh"));
|
|
Shinya Kitaoka |
120a6e |
// Add skeleton id-related widgets
|
|
Shinya Kitaoka |
120a6e |
QLabel *skelIdLabel = new QLabel(tr("Skeleton:"));
|
|
Shinya Kitaoka |
120a6e |
m_skelIdComboBox = new SkelIdsComboBox;
|
|
Shinya Kitaoka |
120a6e |
m_addSkelButton = new QPushButton("+"); // Connected in the show event
|
|
Shinya Kitaoka |
120a6e |
m_removeSkelButton = new QPushButton("-"); // Connected in the show event
|
|
Shinya Kitaoka |
120a6e |
// Add sub-options for each mode group
|
|
Shinya Kitaoka |
120a6e |
for (int m = 0; m != PlasticTool::MODES_COUNT; ++m)
|
|
Shinya Kitaoka |
120a6e |
m_subToolbars[m] = new GenericToolOptionsBox(0, tool, pltHandle, m);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
meshifyButton->setFixedHeight(20);
|
|
Shinya Kitaoka |
120a6e |
QAction *meshifyAction =
|
|
Shinya Kitaoka |
120a6e |
CommandManager::instance()->getAction("A_ToolOption_Meshify");
|
|
Shinya Kitaoka |
120a6e |
meshifyButton->addAction(meshifyAction);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
skelIdLabel->setFixedHeight(20);
|
|
Shinya Kitaoka |
120a6e |
m_skelIdComboBox->setFixedWidth(50);
|
|
Shinya Kitaoka |
120a6e |
m_addSkelButton->setFixedSize(20, 20);
|
|
Shinya Kitaoka |
120a6e |
m_removeSkelButton->setFixedSize(20, 20);
|
|
Shinya Kitaoka |
120a6e |
for (int m = 0; m != PlasticTool::MODES_COUNT; ++m)
|
|
Shinya Kitaoka |
120a6e |
m_subToolbars[m]->setContentsMargins(0, 0, 0, 0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- Layout -*/
|
|
Shinya Kitaoka |
120a6e |
// Add created widgets to the toolbar (in reverse order since we're inserting
|
|
Shinya Kitaoka |
120a6e |
// at 0)
|
|
Shinya Kitaoka |
120a6e |
m_layout->insertWidget(0, m_removeSkelButton);
|
|
Shinya Kitaoka |
120a6e |
m_layout->insertWidget(0, m_addSkelButton);
|
|
Shinya Kitaoka |
120a6e |
m_layout->insertWidget(0, m_skelIdComboBox);
|
|
Shinya Kitaoka |
120a6e |
m_layout->insertWidget(0, skelIdLabel);
|
|
Shinya Kitaoka |
120a6e |
m_layout->insertWidget(0, locals::newSpace(this));
|
|
Shinya Kitaoka |
120a6e |
m_layout->insertWidget(0, meshifyButton);
|
|
Shinya Kitaoka |
120a6e |
m_layout->insertWidget(0, locals::newSpace(this));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (int m = 0; m != PlasticTool::MODES_COUNT; ++m)
|
|
Shinya Kitaoka |
120a6e |
m_layout->insertWidget(m_layout->count() - 1, m_subToolbars[m], 1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool ret = true;
|
|
Shinya Kitaoka |
120a6e |
ret = ret && connect(meshifyButton, SIGNAL(clicked()), meshifyAction,
|
|
Shinya Kitaoka |
120a6e |
SLOT(trigger()));
|
|
Shinya Kitaoka |
120a6e |
assert(ret);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Add Animation mode fields corresponding to vertex properties
|
|
Shinya Kitaoka |
120a6e |
GenericToolOptionsBox *animateOptionsBox =
|
|
Shinya Kitaoka |
120a6e |
m_subToolbars[PlasticTool::ANIMATE_IDX];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Adjust some specific controls first
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
ToolOptionTextField *minAngleField = static_cast<tooloptiontextfield *="">(</tooloptiontextfield>
|
|
Shinya Kitaoka |
120a6e |
animateOptionsBox->control("minAngle"));
|
|
Shinya Kitaoka |
120a6e |
assert(minAngleField);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
minAngleField->setFixedWidth(40);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ToolOptionTextField *maxAngleField = static_cast<tooloptiontextfield *="">(</tooloptiontextfield>
|
|
Shinya Kitaoka |
120a6e |
animateOptionsBox->control("maxAngle"));
|
|
Shinya Kitaoka |
120a6e |
assert(maxAngleField);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
maxAngleField->setFixedWidth(40);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Distance
|
|
Shinya Kitaoka |
120a6e |
ToolOptionParamRelayField *distanceField = new ToolOptionParamRelayField(
|
|
Shinya Kitaoka |
120a6e |
&l_plasticTool, &l_plasticTool.m_distanceRelay);
|
|
Shinya Kitaoka |
120a6e |
distanceField->setGlobalKey(&l_plasticTool.m_globalKey,
|
|
Shinya Kitaoka |
120a6e |
&l_plasticTool.m_relayGroup);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QLabel *distanceLabel = new QLabel(tr("Distance"));
|
|
Shinya Kitaoka |
120a6e |
distanceLabel->setFixedHeight(20);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Angle
|
|
Shinya Kitaoka |
120a6e |
ToolOptionParamRelayField *angleField = new ToolOptionParamRelayField(
|
|
Shinya Kitaoka |
120a6e |
&l_plasticTool, &l_plasticTool.m_angleRelay);
|
|
Shinya Kitaoka |
120a6e |
angleField->setGlobalKey(&l_plasticTool.m_globalKey,
|
|
Shinya Kitaoka |
120a6e |
&l_plasticTool.m_relayGroup);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QLabel *angleLabel = new QLabel(tr("Angle"));
|
|
Shinya Kitaoka |
120a6e |
angleLabel->setFixedHeight(20);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// SO
|
|
Shinya Kitaoka |
120a6e |
ToolOptionParamRelayField *soField =
|
|
Shinya Kitaoka |
120a6e |
new ToolOptionParamRelayField(&l_plasticTool, &l_plasticTool.m_soRelay);
|
|
Shinya Kitaoka |
120a6e |
soField->setGlobalKey(&l_plasticTool.m_globalKey,
|
|
Shinya Kitaoka |
120a6e |
&l_plasticTool.m_relayGroup);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QLabel *soLabel = new QLabel(tr("SO"));
|
|
Shinya Kitaoka |
120a6e |
soLabel->setFixedHeight(20);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QHBoxLayout *animateLayout = animateOptionsBox->hLayout();
|
|
Shinya Kitaoka |
120a6e |
animateLayout->insertWidget(0, soField);
|
|
Shinya Kitaoka |
120a6e |
animateLayout->insertWidget(0, soLabel);
|
|
Shinya Kitaoka |
120a6e |
animateLayout->insertWidget(0, angleField);
|
|
Shinya Kitaoka |
120a6e |
animateLayout->insertWidget(0, angleLabel);
|
|
Shinya Kitaoka |
120a6e |
animateLayout->insertWidget(0, distanceField);
|
|
Shinya Kitaoka |
120a6e |
animateLayout->insertWidget(0, distanceLabel);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
onPropertyChanged();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticToolOptionsBox::showEvent(QShowEvent *se) {
|
|
Shinya Kitaoka |
120a6e |
bool ret = true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ret = ret && connect(&l_plasticTool, SIGNAL(skelIdsListChanged()),
|
|
Shinya Kitaoka |
120a6e |
SLOT(onSkelIdsListChanged()));
|
|
Shinya Kitaoka |
120a6e |
ret = ret && connect(&l_plasticTool, SIGNAL(skelIdChanged()),
|
|
Shinya Kitaoka |
120a6e |
SLOT(onSkelIdChanged()));
|
|
Shinya Kitaoka |
120a6e |
ret = ret && connect(m_skelIdComboBox, SIGNAL(activated(int)),
|
|
Shinya Kitaoka |
120a6e |
SLOT(onSkelIdEdited()));
|
|
Shinya Kitaoka |
120a6e |
ret = ret &&
|
|
Shinya Kitaoka |
120a6e |
connect(m_addSkelButton, SIGNAL(released()), SLOT(onAddSkeleton()));
|
|
Shinya Kitaoka |
120a6e |
ret = ret && connect(m_removeSkelButton, SIGNAL(released()),
|
|
Shinya Kitaoka |
120a6e |
SLOT(onRemoveSkeleton()));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(ret);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_skelIdComboBox->updateSkeletonsList();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticToolOptionsBox::hideEvent(QHideEvent *he) {
|
|
Shinya Kitaoka |
120a6e |
disconnect(&l_plasticTool, 0, this, 0);
|
|
Shinya Kitaoka |
120a6e |
disconnect(m_skelIdComboBox, 0, this, 0);
|
|
Shinya Kitaoka |
120a6e |
disconnect(m_addSkelButton, 0, this, 0);
|
|
Shinya Kitaoka |
120a6e |
disconnect(m_removeSkelButton, 0, this, 0);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticToolOptionsBox::onPropertyChanged() {
|
|
Shinya Kitaoka |
120a6e |
// Fetch current mode index
|
|
Shinya Kitaoka |
120a6e |
TPropertyGroup *pGroup = m_tool->getProperties(PlasticTool::MODES_COUNT);
|
|
Shinya Kitaoka |
120a6e |
assert(pGroup);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TEnumProperty *prop =
|
|
Shinya Kitaoka |
120a6e |
dynamic_cast<tenumproperty *="">(pGroup->getProperty("mode"));</tenumproperty>
|
|
Shinya Kitaoka |
120a6e |
assert(prop);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int mode = prop->getIndex();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Show the specified mode options, hide all the others
|
|
Shinya Kitaoka |
120a6e |
for (int m = 0; m != PlasticTool::MODES_COUNT; ++m)
|
|
Shinya Kitaoka |
120a6e |
m_subToolbars[m]->setVisible(m == mode);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticToolOptionsBox::onSkelIdsListChanged() {
|
|
Shinya Kitaoka |
120a6e |
m_skelIdComboBox->updateSkeletonsList();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticToolOptionsBox::onSkelIdChanged() {
|
|
Shinya Kitaoka |
120a6e |
m_skelIdComboBox->updateCurrentSkeleton();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticToolOptionsBox::onSkelIdEdited() {
|
|
Shinya Kitaoka |
120a6e |
int skelId = m_skelIdComboBox->currentText().toInt();
|
|
Shinya Kitaoka |
120a6e |
if (skelId == ::skeletonId()) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!l_plasticTool.deformation()) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
l_plasticTool.editSkelId_undo(skelId);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticToolOptionsBox::onAddSkeleton() {
|
|
Shinya Kitaoka |
120a6e |
if (l_plasticTool.isEnabled())
|
|
Shinya Kitaoka |
120a6e |
l_plasticTool.addSkeleton_undo(new PlasticSkeleton);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticToolOptionsBox::onRemoveSkeleton() {
|
|
Shinya Kitaoka |
120a6e |
if (l_plasticTool.isEnabled() && l_plasticTool.deformation())
|
|
Shinya Kitaoka |
120a6e |
l_plasticTool.removeSkeleton_withKeyframes_undo(::skeletonId());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//****************************************************************************************
|
|
Shinya Kitaoka |
120a6e |
// PlasticTool implementation
|
|
Shinya Kitaoka |
120a6e |
//****************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
PlasticTool::PlasticTool()
|
|
Shinya Kitaoka |
120a6e |
: TTool(T_Plastic)
|
|
Shinya Kitaoka |
120a6e |
, m_skelId(-(std::numeric_limits<int>::max)())</int>
|
|
Shinya Kitaoka |
120a6e |
, m_propGroup(new TPropertyGroup[MODES_COUNT + 1])
|
|
Shinya Kitaoka |
120a6e |
, m_mode("mode")
|
|
Shinya Kitaoka |
120a6e |
, m_vertexName("vertexName", L"")
|
|
Shinya Kitaoka |
120a6e |
, m_interpolate("interpolate", false)
|
|
Shinya Kitaoka |
120a6e |
, m_snapToMesh("snapToMesh", false)
|
|
Shinya Kitaoka |
120a6e |
, m_thickness("Thickness", 1, 100, 5)
|
|
Shinya Kitaoka |
120a6e |
, m_rigidValue("rigidValue")
|
|
Shinya Kitaoka |
120a6e |
, m_globalKey("globalKeyframe", true)
|
|
Shinya Kitaoka |
120a6e |
, m_keepDistance("keepDistance", true)
|
|
Shinya Kitaoka |
120a6e |
, m_minAngle("minAngle", L"")
|
|
Shinya Kitaoka |
120a6e |
, m_maxAngle("maxAngle", L"")
|
|
Shinya Kitaoka |
120a6e |
, m_distanceRelay("distanceRelay")
|
|
Shinya Kitaoka |
120a6e |
, m_angleRelay("angleRelay")
|
|
Shinya Kitaoka |
120a6e |
, m_soRelay("soRelay")
|
|
Shinya Kitaoka |
120a6e |
, m_skelIdRelay("skelIdRelay")
|
|
Shinya Kitaoka |
120a6e |
, m_pressedPos(TConsts::napd)
|
|
Shinya Kitaoka |
120a6e |
, m_dragged(false)
|
|
Shinya Kitaoka |
120a6e |
, m_svHigh(-1)
|
|
Shinya Kitaoka |
120a6e |
, m_seHigh(-1)
|
|
Shinya Kitaoka |
120a6e |
, m_mvHigh(-1)
|
|
Shinya Kitaoka |
120a6e |
, m_meHigh(-1)
|
|
Shinya Kitaoka |
120a6e |
, m_rigidityPainter(createRigidityPainter())
|
|
Shinya Kitaoka |
120a6e |
, m_showSkeletonOS(true)
|
|
Shinya Kitaoka |
120a6e |
, m_recompileOnMouseRelease(false) {
|
|
Shinya Kitaoka |
120a6e |
// And now, a little trick about tool binding
|
|
Shinya Kitaoka |
120a6e |
bind(TTool::AllImages); // Attach the tool to all types :)
|
|
Shinya Kitaoka |
120a6e |
bind(TTool::MeshLevels); // But disable it for all but meshes :0
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// This little trick is needed to associate the tool to common levels (the
|
|
Shinya Kitaoka |
120a6e |
// toolbar must appear), in
|
|
Shinya Kitaoka |
120a6e |
// order to make them meshable.
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Bind properties to the appropriate property group (needed by the automatic
|
|
Shinya Kitaoka |
120a6e |
// toolbar builder)
|
|
Shinya Kitaoka |
120a6e |
m_propGroup[MODES_COUNT].bind(m_mode);
|
|
Shinya Kitaoka |
120a6e |
m_propGroup[MODES_COUNT].bind(m_vertexName);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_propGroup[RIGIDITY_IDX].bind(m_thickness);
|
|
Shinya Kitaoka |
120a6e |
m_propGroup[RIGIDITY_IDX].bind(m_rigidValue);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_propGroup[BUILD_IDX].bind(m_interpolate);
|
|
Shinya Kitaoka |
120a6e |
m_propGroup[BUILD_IDX].bind(m_snapToMesh);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_propGroup[ANIMATE_IDX].bind(m_globalKey);
|
|
Shinya Kitaoka |
120a6e |
m_propGroup[ANIMATE_IDX].bind(m_keepDistance);
|
|
Shinya Kitaoka |
120a6e |
m_propGroup[ANIMATE_IDX].bind(m_minAngle);
|
|
Shinya Kitaoka |
120a6e |
m_propGroup[ANIMATE_IDX].bind(m_maxAngle);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_relayGroup.bind(m_distanceRelay);
|
|
Shinya Kitaoka |
120a6e |
m_relayGroup.bind(m_angleRelay);
|
|
Shinya Kitaoka |
120a6e |
m_relayGroup.bind(m_soRelay);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_mode.setId("SkeletonMode");
|
|
Shinya Kitaoka |
120a6e |
m_vertexName.setId("VertexName");
|
|
Shinya Kitaoka |
120a6e |
m_interpolate.setId("Interpolate");
|
|
Shinya Kitaoka |
120a6e |
m_snapToMesh.setId("SnapToMesh");
|
|
Shinya Kitaoka |
120a6e |
m_thickness.setId("Thickness");
|
|
Shinya Kitaoka |
120a6e |
m_rigidValue.setId("RigidValue");
|
|
Shinya Kitaoka |
120a6e |
m_globalKey.setId("GlobalKey");
|
|
Shinya Kitaoka |
120a6e |
m_keepDistance.setId("KeepDistance");
|
|
Shinya Kitaoka |
120a6e |
m_minAngle.setId("MinAngle");
|
|
Shinya Kitaoka |
120a6e |
m_maxAngle.setId("MaxAngle");
|
|
Shinya Kitaoka |
120a6e |
m_distanceRelay.setId("DistanceRelay");
|
|
Shinya Kitaoka |
120a6e |
m_angleRelay.setId("AngleRelay");
|
|
Shinya Kitaoka |
120a6e |
m_soRelay.setId("SoRelay");
|
|
Shinya Kitaoka |
120a6e |
m_skelIdRelay.setId("SkelIdRelay");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Attach to selections
|
|
Shinya Kitaoka |
120a6e |
m_svSel.setView(this);
|
|
Shinya Kitaoka |
120a6e |
m_mvSel.setView(this), m_meSel.setView(this);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
PlasticTool::~PlasticTool() {
|
|
Shinya Kitaoka |
120a6e |
if (m_sd) m_sd->removeObserver(this);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TTool::ToolType PlasticTool::getToolType() const {
|
|
Shinya Kitaoka |
120a6e |
switch (m_mode.getIndex()) {
|
|
Shinya Kitaoka |
120a6e |
case MESH_IDX:
|
|
Shinya Kitaoka |
120a6e |
case RIGIDITY_IDX:
|
|
Shinya Kitaoka |
120a6e |
return TTool::LevelWriteTool;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case BUILD_IDX:
|
|
Shinya Kitaoka |
120a6e |
case ANIMATE_IDX:
|
|
Shinya Kitaoka |
120a6e |
return TTool::ColumnTool;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(false);
|
|
Shinya Kitaoka |
120a6e |
return TTool::GenericTool;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::updateTranslation() {
|
|
Shinya Kitaoka |
120a6e |
m_mode.setQStringName(tr("Mode:"));
|
|
Shinya Kitaoka |
120a6e |
m_mode.deleteAllValues();
|
|
Shinya Kitaoka |
120a6e |
m_mode.addValue(tr("Edit Mesh").toStdWString());
|
|
Shinya Kitaoka |
120a6e |
m_mode.addValue(tr("Paint Rigid").toStdWString());
|
|
Shinya Kitaoka |
120a6e |
m_mode.addValue(tr("Build Skeleton").toStdWString());
|
|
Shinya Kitaoka |
120a6e |
m_mode.addValue(tr("Animate").toStdWString());
|
|
Shinya Kitaoka |
120a6e |
m_mode.setIndex(BUILD_IDX);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_vertexName.setQStringName(tr("Vertex Name:"));
|
|
Shinya Kitaoka |
120a6e |
m_interpolate.setQStringName(tr("Allow Stretching"));
|
|
Shinya Kitaoka |
120a6e |
m_snapToMesh.setQStringName(tr("Snap To Mesh"));
|
|
Shinya Kitaoka |
120a6e |
m_thickness.setQStringName(tr("Thickness"));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_rigidValue.setQStringName("");
|
|
Shinya Kitaoka |
120a6e |
m_rigidValue.deleteAllValues();
|
|
Shinya Kitaoka |
120a6e |
m_rigidValue.addValue(tr("Rigid").toStdWString());
|
|
Shinya Kitaoka |
120a6e |
m_rigidValue.addValue(tr("Flex").toStdWString());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_globalKey.setQStringName(tr("Global Key"));
|
|
Shinya Kitaoka |
120a6e |
m_keepDistance.setQStringName(tr("Keep Distance"));
|
|
Shinya Kitaoka |
120a6e |
m_minAngle.setQStringName(tr("Angle Bounds"));
|
|
Shinya Kitaoka |
120a6e |
m_maxAngle.setQStringName("");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ToolOptionsBox *PlasticTool::createOptionsBox() {
|
|
Shinya Kitaoka |
120a6e |
// Create the options box
|
|
Shinya Kitaoka |
120a6e |
TPaletteHandle *currPalette =
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()->getPaletteController()->getCurrentLevelPalette();
|
|
Shinya Kitaoka |
120a6e |
PlasticToolOptionsBox *optionsBox =
|
|
Shinya Kitaoka |
120a6e |
new PlasticToolOptionsBox(0, this, currPalette);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Connect it to receive m_mode notifications
|
|
Shinya Kitaoka |
120a6e |
m_mode.addListener(optionsBox);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return optionsBox;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
PlasticSkeletonP PlasticTool::skeleton() const {
|
|
Shinya Kitaoka |
120a6e |
return m_sd ? m_sd->skeleton(::sdFrame()) : PlasticSkeletonP();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
PlasticSkeleton &PlasticTool::deformedSkeleton() {
|
|
Shinya Kitaoka |
120a6e |
typedef tcg::function
|
|
Shinya Kitaoka |
120a6e |
&PlasticTool::updateDeformedSkeleton>
|
|
Shinya Kitaoka |
120a6e |
Func;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return m_deformedSkeleton(tcg::bind1st(Func(), *this));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::touchSkeleton() {
|
|
Shinya Kitaoka |
120a6e |
touchDeformation();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int skelId = ::skeletonId();
|
|
Shinya Kitaoka |
120a6e |
if (!m_sd->skeleton(skelId)) {
|
|
Shinya Kitaoka |
120a6e |
m_sd->attach(skelId, new PlasticSkeleton);
|
|
Shinya Kitaoka |
120a6e |
emit skelIdsListChanged();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::touchDeformation() {
|
|
Shinya Kitaoka |
120a6e |
if (m_sd) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Store a new deformation in the column's stage object
|
|
Shinya Kitaoka |
120a6e |
stageObject()->setPlasticSkeletonDeformation(new PlasticSkeletonDeformation);
|
|
Shinya Kitaoka |
120a6e |
storeDeformation(); // Builds the deformed skeleton too
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::storeDeformation() {
|
|
Shinya Kitaoka |
120a6e |
const SkDP &sd = stageObject()->getPlasticSkeletonDeformation();
|
|
Shinya Kitaoka |
120a6e |
if (m_sd != sd) {
|
|
Shinya Kitaoka |
120a6e |
clearSkeletonSelections();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_sd) {
|
|
Shinya Kitaoka |
120a6e |
m_sd->removeObserver(this);
|
|
Shinya Kitaoka |
120a6e |
m_skelIdRelay.setParam(TDoubleParamP());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Store the deformation, retrieving it from current column stage object
|
|
Shinya Kitaoka |
120a6e |
m_sd = sd;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_sd) {
|
|
Shinya Kitaoka |
120a6e |
m_sd->addObserver(this);
|
|
Shinya Kitaoka |
120a6e |
m_skelIdRelay.setParam(m_sd->skeletonIdsParam());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_skelIdRelay.notifyListeners();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
storeSkeletonId();
|
|
Shinya Kitaoka |
120a6e |
if (m_mode.getIndex() == ANIMATE_IDX)
|
|
Shinya Kitaoka |
120a6e |
m_deformedSkeleton.invalidate(); // Store the deformed skeleton too
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
emit skelIdsListChanged();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::storeSkeletonId() {
|
|
Shinya Kitaoka |
120a6e |
int skelId = m_sd ? m_sd->skeletonIdsParam()->getValue(::sdFrame())
|
|
Shinya Kitaoka |
120a6e |
: -(std::numeric_limits<int>::max)();</int>
|
|
Shinya Kitaoka |
120a6e |
if (m_skelId != skelId) {
|
|
Shinya Kitaoka |
120a6e |
m_skelId = skelId;
|
|
Shinya Kitaoka |
120a6e |
clearSkeletonSelections();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
emit skelIdChanged();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::updateDeformedSkeleton(PlasticSkeleton &deformedSkeleton) {
|
|
Shinya Kitaoka |
120a6e |
if (m_sd)
|
|
Shinya Kitaoka |
120a6e |
m_sd->storeDeformedSkeleton(::skeletonId(), ::sdFrame(), deformedSkeleton);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
deformedSkeleton.clear();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::onFrameSwitched() {
|
|
Shinya Kitaoka |
120a6e |
storeSkeletonId();
|
|
Shinya Kitaoka |
120a6e |
storeMeshImage();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
switch (m_mode.getIndex()) {
|
|
Shinya Kitaoka |
120a6e |
case ANIMATE_IDX:
|
|
Shinya Kitaoka |
120a6e |
m_deformedSkeleton.invalidate();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Update the relays' current frame
|
|
Shinya Kitaoka |
120a6e |
double frame = ::sdFrame();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_distanceRelay.frame() = frame;
|
|
Shinya Kitaoka |
120a6e |
m_angleRelay.frame() = frame;
|
|
Shinya Kitaoka |
120a6e |
m_soRelay.frame() = frame;
|
|
Shinya Kitaoka |
120a6e |
m_skelIdRelay.frame() = frame;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_distanceRelay.notifyListeners();
|
|
Shinya Kitaoka |
120a6e |
m_angleRelay.notifyListeners();
|
|
Shinya Kitaoka |
120a6e |
m_soRelay.notifyListeners();
|
|
Shinya Kitaoka |
120a6e |
m_skelIdRelay.notifyListeners();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::onColumnSwitched() {
|
|
Shinya Kitaoka |
120a6e |
switch (m_mode.getIndex()) {
|
|
Shinya Kitaoka |
120a6e |
case MESH_IDX:
|
|
Shinya Kitaoka |
120a6e |
case BUILD_IDX:
|
|
Shinya Kitaoka |
120a6e |
case RIGIDITY_IDX:
|
|
Shinya Kitaoka |
120a6e |
m_pvs.m_showOriginalColumn = xshColumn();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
storeDeformation();
|
|
Shinya Kitaoka |
120a6e |
storeMeshImage();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::onXsheetChanged() {
|
|
Shinya Kitaoka |
120a6e |
onColumnSwitched();
|
|
Shinya Kitaoka |
120a6e |
TTool::updateEnabled(); // Current cell may no longer be a mesh one (or
|
|
Shinya Kitaoka |
120a6e |
// viceversa),
|
|
Shinya Kitaoka |
120a6e |
} // so tool enabled status must be updated.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::onChange() {
|
|
Shinya Kitaoka |
120a6e |
// Since parameters are typically coupled, we could pass multiple, consecutive
|
|
Shinya Kitaoka |
120a6e |
// times in
|
|
Shinya Kitaoka |
120a6e |
// this notification function. We have to employ counter-measures to prevent
|
|
Shinya Kitaoka |
120a6e |
// multiple
|
|
Shinya Kitaoka |
120a6e |
// calls from affecting performance.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
static bool refresh = false; // Accessible from locals since static
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
struct locals {
|
|
Shinya Kitaoka |
d1f6c4 |
struct RefreshFunctor final : public TFunctorInvoker::BaseFunctor {
|
|
Shinya Kitaoka |
473e70 |
void operator()() override {
|
|
Shinya Kitaoka |
120a6e |
refresh = false;
|
|
Shinya Kitaoka |
120a6e |
l_plasticTool.storeSkeletonId(); // Calls ::sdFrame()
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// This is needed to repaint the xsheet (not automatic otherwise)
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()->getCurrentObject()->notifyObjectIdChanged(
|
|
Shinya Kitaoka |
120a6e |
false);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
}; // locals
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Using invalidate/update and delayed invocation to prevent multiple calls to
|
|
Shinya Kitaoka |
120a6e |
// ::sdFrame()
|
|
Shinya Kitaoka |
120a6e |
m_deformedSkeleton.invalidate();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!refresh) {
|
|
Shinya Kitaoka |
120a6e |
refresh = true;
|
|
Shinya Kitaoka |
120a6e |
QMetaObject::invokeMethod(TFunctorInvoker::instance(), "invoke",
|
|
Shinya Kitaoka |
120a6e |
Qt::QueuedConnection,
|
|
Shinya Kitaoka |
120a6e |
Q_ARG(void *, new locals::RefreshFunctor));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Passing through Qt's event system to compress repaints in a single one
|
|
Shinya Kitaoka |
120a6e |
TTool::Viewer *viewer = getViewer();
|
|
Shinya Kitaoka |
120a6e |
if (viewer) // This goes through paintEvent(),
|
|
Shinya Kitaoka |
120a6e |
viewer->invalidateAll(); // \a unlike TTool::invalidate()
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::onChange(const TParamChange &pc) {
|
|
Shinya Kitaoka |
120a6e |
if (l_suspendParamsObservation) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
onChange();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::onSetViewer() {
|
|
Shinya Kitaoka |
120a6e |
Viewer *viewer = getViewer();
|
|
Shinya Kitaoka |
120a6e |
if (viewer) {
|
|
Shinya Kitaoka |
120a6e |
PlasticVisualSettings &pvs =
|
|
Shinya Kitaoka |
120a6e |
viewer->visualSettings().m_plasticVisualSettings;
|
|
Shinya Kitaoka |
120a6e |
pvs = m_pvs;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Force options if needed
|
|
Shinya Kitaoka |
120a6e |
if (m_mode.getIndex() == RIGIDITY_IDX) pvs.m_drawRigidity = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::onActivate() {
|
|
Shinya Kitaoka |
120a6e |
bool ret;
|
|
Shinya Kitaoka |
120a6e |
ret = connect(TTool::m_application->getCurrentFrame(),
|
|
Shinya Kitaoka |
120a6e |
SIGNAL(frameSwitched()), this, SLOT(onFrameSwitched())),
|
|
Shinya Kitaoka |
120a6e |
assert(ret);
|
|
Shinya Kitaoka |
120a6e |
ret = connect(TTool::m_application->getCurrentColumn(),
|
|
Shinya Kitaoka |
120a6e |
SIGNAL(columnIndexSwitched()), this, SLOT(onColumnSwitched())),
|
|
Shinya Kitaoka |
120a6e |
assert(ret);
|
|
Shinya Kitaoka |
120a6e |
ret = connect(TTool::m_application->getCurrentXsheet(),
|
|
Shinya Kitaoka |
120a6e |
SIGNAL(xsheetChanged()), this, SLOT(onXsheetChanged())),
|
|
Shinya Kitaoka |
120a6e |
assert(ret);
|
|
Shinya Kitaoka |
120a6e |
ret = connect(TTool::m_application->getCurrentXsheet(),
|
|
Shinya Kitaoka |
120a6e |
SIGNAL(xsheetSwitched()), this, SLOT(onXsheetChanged())),
|
|
Shinya Kitaoka |
120a6e |
assert(ret);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
onSetViewer();
|
|
Shinya Kitaoka |
120a6e |
onColumnSwitched();
|
|
Shinya Kitaoka |
120a6e |
onFrameSwitched();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
setActive(true);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::onDeactivate() {
|
|
Shinya Kitaoka |
120a6e |
setActive(false);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool ret;
|
|
Shinya Kitaoka |
120a6e |
ret = disconnect(TTool::m_application->getCurrentFrame(),
|
|
Shinya Kitaoka |
120a6e |
SIGNAL(frameSwitched()), this, SLOT(onFrameSwitched())),
|
|
Shinya Kitaoka |
120a6e |
assert(ret);
|
|
Shinya Kitaoka |
120a6e |
ret =
|
|
Shinya Kitaoka |
120a6e |
disconnect(TTool::m_application->getCurrentColumn(),
|
|
Shinya Kitaoka |
120a6e |
SIGNAL(columnIndexSwitched()), this, SLOT(onColumnSwitched())),
|
|
Shinya Kitaoka |
120a6e |
assert(ret);
|
|
Shinya Kitaoka |
120a6e |
ret = disconnect(TTool::m_application->getCurrentXsheet(),
|
|
Shinya Kitaoka |
120a6e |
SIGNAL(xsheetChanged()), this, SLOT(onXsheetChanged())),
|
|
Shinya Kitaoka |
120a6e |
assert(ret);
|
|
Shinya Kitaoka |
120a6e |
ret = disconnect(TTool::m_application->getCurrentXsheet(),
|
|
Shinya Kitaoka |
120a6e |
SIGNAL(xsheetSwitched()), this, SLOT(onXsheetChanged())),
|
|
Shinya Kitaoka |
120a6e |
assert(ret);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Viewer *viewer = getViewer();
|
|
Shinya Kitaoka |
120a6e |
if (viewer)
|
|
Shinya Kitaoka |
120a6e |
viewer->visualSettings().m_plasticVisualSettings = PlasticVisualSettings();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_sd = PlasticSkeletonDeformationP();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::onEnter() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::onLeave() {
|
|
Shinya Kitaoka |
120a6e |
// Clear visualization vars
|
|
Shinya Kitaoka |
120a6e |
m_pos = TConsts::napd;
|
|
Shinya Kitaoka |
120a6e |
m_svHigh = m_seHigh = -1;
|
|
Shinya Kitaoka |
120a6e |
m_mvHigh = m_meHigh = MeshIndex();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::onSelectionChanged() {
|
|
Shinya Kitaoka |
120a6e |
SkVD *vd = 0;
|
|
Shinya Kitaoka |
120a6e |
if (m_sd && m_svSel.hasSingleObject()) {
|
|
Shinya Kitaoka |
120a6e |
int skelId = ::skeletonId();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeleton::vertex_type &vx =
|
|
Shinya Kitaoka |
120a6e |
m_sd->skeleton(skelId)->vertex(m_svSel);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_vertexName.setValue(vx.name().toStdWString());
|
|
Shinya Kitaoka |
120a6e |
m_interpolate.setValue(vx.m_interpolate);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_minAngle.setValue((vx.m_minAngle == -l_dmax)
|
|
Shinya Kitaoka |
120a6e |
? L""
|
|
Shinya Kitaoka |
120a6e |
: QString::number(vx.m_minAngle).toStdWString());
|
|
Shinya Kitaoka |
120a6e |
m_maxAngle.setValue((vx.m_maxAngle == l_dmax)
|
|
Shinya Kitaoka |
120a6e |
? L""
|
|
Shinya Kitaoka |
120a6e |
: QString::number(vx.m_maxAngle).toStdWString());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
vd = m_sd->vertexDeformation(skelId, m_svSel);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
m_vertexName.setValue(L"");
|
|
Shinya Kitaoka |
120a6e |
m_interpolate.setValue(false);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_minAngle.setValue(L"");
|
|
Shinya Kitaoka |
120a6e |
m_maxAngle.setValue(L"");
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Attach or detach relays depending on selected vertex's parameters
|
|
Shinya Kitaoka |
120a6e |
m_soRelay.setParam(vd ? vd->m_params[SkVD::SO] : TDoubleParamP());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (vd && m_svSel.hasSingleObject() && m_svSel.objects().front() > 0) {
|
|
Shinya Kitaoka |
120a6e |
m_distanceRelay.setParam(vd->m_params[SkVD::DISTANCE]);
|
|
Shinya Kitaoka |
120a6e |
m_angleRelay.setParam(vd->m_params[SkVD::ANGLE]);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
m_distanceRelay.setParam(TDoubleParamP());
|
|
Shinya Kitaoka |
120a6e |
m_angleRelay.setParam(TDoubleParamP());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_vertexName.notifyListeners();
|
|
Shinya Kitaoka |
120a6e |
m_interpolate.notifyListeners();
|
|
Shinya Kitaoka |
120a6e |
m_minAngle.notifyListeners();
|
|
Shinya Kitaoka |
120a6e |
m_maxAngle.notifyListeners();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_distanceRelay.notifyListeners();
|
|
Shinya Kitaoka |
120a6e |
m_angleRelay.notifyListeners();
|
|
Shinya Kitaoka |
120a6e |
m_soRelay.notifyListeners();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::enableCommands() {
|
|
Shinya Kitaoka |
120a6e |
if (TSelection::getCurrent() == &m_svSel)
|
|
Shinya Kitaoka |
120a6e |
m_svSel.enableCommand(this, MI_Clear,
|
|
Shinya Kitaoka |
120a6e |
&PlasticTool::deleteSelectedVertex_undo);
|
|
Shinya Kitaoka |
120a6e |
else if (TSelection::getCurrent() == &m_meSel) {
|
|
Shinya Kitaoka |
120a6e |
m_meSel.enableCommand(this, MI_Clear, &PlasticTool::collapseEdge_mesh_undo);
|
|
Shinya Kitaoka |
120a6e |
m_meSel.enableCommand(this, MI_Insert, &PlasticTool::splitEdge_mesh_undo);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::setSkeletonSelection(const PlasticVertexSelection &vSel) {
|
|
Shinya Kitaoka |
120a6e |
if (vSel.isEmpty()) {
|
|
Shinya Kitaoka |
120a6e |
m_svSel.selectNone();
|
|
Shinya Kitaoka |
120a6e |
m_svSel.makeNotCurrent();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(m_sd);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_svSel.skeletonId() = m_skelId;
|
|
Shinya Kitaoka |
120a6e |
m_svSel.setObjects(vSel.objects());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_svSel.notifyView();
|
|
Shinya Kitaoka |
120a6e |
m_svSel.makeCurrent();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Okay, the following is cheap - we have to update the Function Editor
|
|
Shinya Kitaoka |
120a6e |
// (specifically)
|
|
Shinya Kitaoka |
120a6e |
// since current vertex is shown in a special color. We know that the same
|
|
Shinya Kitaoka |
120a6e |
// happens for
|
|
Shinya Kitaoka |
120a6e |
// the current stage object, so... we'll attach there.
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()->getCurrentObject()->notifyObjectIdChanged(
|
|
Shinya Kitaoka |
120a6e |
false); // Carry on, you've seen nothing ;)
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::toggleSkeletonSelection(
|
|
Shinya Kitaoka |
120a6e |
const PlasticVertexSelection &addition) {
|
|
Shinya Kitaoka |
120a6e |
const std::vector<int> &storedIdxs = m_svSel.objects();</int>
|
|
Shinya Kitaoka |
120a6e |
const std::vector<int> &addedIdxs = addition.objects();</int>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Build new selection
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> selectedIdxs;</int>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_svSel.contains(addition)) {
|
|
Shinya Kitaoka |
120a6e |
std::set_difference(storedIdxs.begin(), storedIdxs.end(), addedIdxs.begin(),
|
|
Shinya Kitaoka |
120a6e |
addedIdxs.end(), std::back_inserter(selectedIdxs));
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
std::set_union(storedIdxs.begin(), storedIdxs.end(), addedIdxs.begin(),
|
|
Shinya Kitaoka |
120a6e |
addedIdxs.end(), std::back_inserter(selectedIdxs));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
setSkeletonSelection(selectedIdxs);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::clearSkeletonSelections() {
|
|
Shinya Kitaoka |
120a6e |
m_svHigh = m_seHigh = -1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_svSel.selectNone();
|
|
Shinya Kitaoka |
120a6e |
m_svSel.makeNotCurrent();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
PlasticVertexSelection PlasticTool::branchSelection(int vIdx) const {
|
|
Shinya Kitaoka |
120a6e |
struct locals {
|
|
Shinya Kitaoka |
120a6e |
static void addBranch(const PlasticSkeleton &skeleton, int v,
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> &branch) {</int>
|
|
Shinya Kitaoka |
120a6e |
branch.push_back(v);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonVertex &vx = skeleton.vertex(v);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
PlasticSkeletonVertex::edges_const_iterator et, eEnd = vx.edgesEnd();
|
|
Shinya Kitaoka |
120a6e |
for (et = vx.edgesBegin(); et != eEnd; ++et) {
|
|
Shinya Kitaoka |
120a6e |
int child = skeleton.edge(*et).vertex(1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (v != child) // The edge to parent is in the list
|
|
Shinya Kitaoka |
120a6e |
addBranch(skeleton, child,
|
|
Shinya Kitaoka |
120a6e |
branch); // I wonder if it's ensured to be always at begin?
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(skeleton());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> selectedIdxs;</int>
|
|
Shinya Kitaoka |
120a6e |
locals::addBranch(*skeleton(), vIdx, selectedIdxs);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return selectedIdxs;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::copySkeleton() {
|
|
Shinya Kitaoka |
120a6e |
if (!m_sd) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonP &skel = m_sd->skeleton(::skeletonId());
|
|
Shinya Kitaoka |
120a6e |
if (!skel) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Copy a CLONE of currently addressed skeleton in the app clipboard
|
|
Shinya Kitaoka |
120a6e |
QMimeData *data = new PlasticSkeletonPMime(new PlasticSkeleton(*skel));
|
|
Shinya Kitaoka |
120a6e |
QApplication::clipboard()->setMimeData(data, QClipboard::Clipboard);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::pasteSkeleton_undo() {
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonPMime *data = dynamic_cast<const *="" plasticskeletonpmime="">(</const>
|
|
Shinya Kitaoka |
120a6e |
QApplication::clipboard()->mimeData());
|
|
Shinya Kitaoka |
120a6e |
if (!data) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
PlasticSkeletonP newSkeleton(new PlasticSkeleton(*data->m_skeleton));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
touchDeformation();
|
|
Shinya Kitaoka |
120a6e |
assert(m_sd);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int skelId = ::skeletonId();
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonP &oldSkel = m_sd->skeleton(skelId);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (oldSkel && !oldSkel->empty()) {
|
|
Shinya Kitaoka |
120a6e |
// In case there exists a not-empty skeleton, add a NEW skeleton
|
|
Shinya Kitaoka |
120a6e |
addSkeleton_undo(newSkeleton);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
TUndoManager *manager = TUndoManager::manager();
|
|
Shinya Kitaoka |
120a6e |
manager->beginBlock();
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
removeSkeleton_undo(skelId); // No problem - it's eventually empty
|
|
Shinya Kitaoka |
120a6e |
addSkeleton_undo(skelId, newSkeleton.getPointer());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
manager->endBlock();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::copyDeformation() {
|
|
Shinya Kitaoka |
120a6e |
if (!m_sd) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Copy a reference to currently addressed skeleton in the app clipboard
|
|
Shinya Kitaoka |
120a6e |
QMimeData *data = new SkDPMime(m_sd);
|
|
Shinya Kitaoka |
120a6e |
QApplication::clipboard()->setMimeData(data, QClipboard::Clipboard);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::pasteDeformation_undo() {
|
|
Shinya Kitaoka |
120a6e |
const SkDPMime *data =
|
|
Shinya Kitaoka |
120a6e |
dynamic_cast<const *="" skdpmime="">(QApplication::clipboard()->mimeData());</const>
|
|
Shinya Kitaoka |
120a6e |
if (!data) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Given a skeleton, attempt to assign it to the current stage object
|
|
Shinya Kitaoka |
120a6e |
TStageObject *obj = ::stageObject();
|
|
Shinya Kitaoka |
120a6e |
assert(obj);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonDeformationP &oldSd =
|
|
Shinya Kitaoka |
120a6e |
obj->getPlasticSkeletonDeformation();
|
|
Shinya Kitaoka |
120a6e |
if (oldSd) {
|
|
Shinya Kitaoka |
120a6e |
// A skeleton already exists. Ask the user if it has to be replaced.
|
|
Shinya Kitaoka |
120a6e |
bool replace = DVGui::MsgBox(tr("A group of skeletons already exists for "
|
|
Shinya Kitaoka |
120a6e |
"current column. Replacing it will also "
|
|
Shinya Kitaoka |
120a6e |
"substitute any existing vertex "
|
|
Shinya Kitaoka |
120a6e |
"animation.\n\nDo you want to continue?"),
|
|
Shinya Kitaoka |
120a6e |
tr("Ok"), tr("Cancel")) == 1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!replace) return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Clone the whole skeleton deformation (skeleton itself included)
|
|
Shinya Kitaoka |
120a6e |
SkDP newSd(new PlasticSkeletonDeformation(*data->m_sd));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Insert the undo and perform the op
|
|
Shinya Kitaoka |
120a6e |
TUndoManager::manager()->add(new PasteDeformationUndo(newSd));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
obj->setPlasticSkeletonDeformation(newSd);
|
|
Shinya Kitaoka |
120a6e |
::invalidateXsheet();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::setKey() {
|
|
Shinya Kitaoka |
120a6e |
assert(m_svSel.hasSingleObject());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
SkVD *vd = m_sd->vertexDeformation(::skeletonId(), m_svSel);
|
|
Shinya Kitaoka |
120a6e |
double frame = ::frame();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (vd->isFullKeyframe(frame))
|
|
Shinya Kitaoka |
120a6e |
vd->deleteKeyframe(frame);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
::setKeyframe(vd, frame);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::setGlobalKey() {
|
|
Shinya Kitaoka |
120a6e |
struct locals {
|
|
Shinya Kitaoka |
120a6e |
inline static bool isFullKeyframe(const SkDP &sd, double frame) {
|
|
Shinya Kitaoka |
120a6e |
SkD::vd_iterator vdt, vdEnd;
|
|
Shinya Kitaoka |
120a6e |
sd->vertexDeformations(vdt, vdEnd);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (; vdt != vdEnd; ++vdt)
|
|
Shinya Kitaoka |
120a6e |
if (!(*vdt).second->isFullKeyframe(frame)) return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double frame = ::frame();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (locals::isFullKeyframe(m_sd, frame))
|
|
Shinya Kitaoka |
120a6e |
m_sd->deleteKeyframe(frame);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
::setKeyframe(m_sd, frame);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::setRestKey() {
|
|
Shinya Kitaoka |
120a6e |
assert(m_svSel.hasSingleObject());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
SkVD *vd = m_sd->vertexDeformation(::skeletonId(), m_svSel);
|
|
Shinya Kitaoka |
120a6e |
double frame = ::frame();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (int p = 0; p != SkVD::PARAMS_COUNT; ++p)
|
|
Shinya Kitaoka |
120a6e |
vd->m_params[p]->setValue(frame, vd->m_params[p]->getDefaultValue());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::setGlobalRestKey() {
|
|
Shinya Kitaoka |
120a6e |
double frame = ::frame();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
SkD::vd_iterator vdt, vdEnd;
|
|
Shinya Kitaoka |
120a6e |
m_sd->vertexDeformations(vdt, vdEnd);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (; vdt != vdEnd; ++vdt) {
|
|
Shinya Kitaoka |
120a6e |
SkVD *vd = (*vdt).second;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (int p = 0; p != SkVD::PARAMS_COUNT; ++p)
|
|
Shinya Kitaoka |
120a6e |
vd->m_params[p]->setValue(frame, vd->m_params[p]->getDefaultValue());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::setKey_undo() { keyFunc_undo(&PlasticTool::setKey); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::setGlobalKey_undo() {
|
|
Shinya Kitaoka |
120a6e |
keyFunc_undo(&PlasticTool::setGlobalKey);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::setRestKey_undo() { keyFunc_undo(&PlasticTool::setRestKey); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::setGlobalRestKey_undo() {
|
|
Shinya Kitaoka |
120a6e |
keyFunc_undo(&PlasticTool::setGlobalRestKey);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::setVertexName(QString &name) {
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonP &skeleton = this->skeleton();
|
|
Shinya Kitaoka |
120a6e |
assert(skeleton && m_svSel.hasSingleObject() && m_svSel > 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Update the selected vertex's name
|
|
Shinya Kitaoka |
120a6e |
while (!m_sd->skeleton(::skeletonId())->setVertexName(m_svSel, name))
|
|
Shinya Kitaoka |
120a6e |
name += "_";
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_vertexName.setValue(name.toStdWString());
|
|
Shinya Kitaoka |
120a6e |
m_vertexName.notifyListeners(); // NOTE: This should NOT invoke this function
|
|
Shinya Kitaoka |
120a6e |
// recursively
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Re-store the deformed skeleton. This is necessary since any follow-up
|
|
Shinya Kitaoka |
120a6e |
// vertex
|
|
Shinya Kitaoka |
120a6e |
// manipulation must refer the correct vd name.
|
|
Shinya Kitaoka |
120a6e |
m_deformedSkeleton.invalidate();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
PlasticDeformerStorage::instance()->invalidateSkeleton(
|
|
Shinya Kitaoka |
120a6e |
m_sd.getPointer(), ::skeletonId(), PlasticDeformerStorage::NONE);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::mouseMove(const TPointD &pos, const TMouseEvent &me) {
|
|
Shinya Kitaoka |
120a6e |
// Discriminate mode
|
|
Shinya Kitaoka |
120a6e |
switch (m_mode.getIndex()) {
|
|
Shinya Kitaoka |
120a6e |
case MESH_IDX:
|
|
Shinya Kitaoka |
120a6e |
mouseMove_mesh(pos, me);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case BUILD_IDX:
|
|
Shinya Kitaoka |
120a6e |
mouseMove_build(pos, me);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case RIGIDITY_IDX:
|
|
Shinya Kitaoka |
120a6e |
mouseMove_rigidity(pos, me);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case ANIMATE_IDX:
|
|
Shinya Kitaoka |
120a6e |
mouseMove_animate(pos, me);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::leftButtonDown(const TPointD &pos, const TMouseEvent &me) {
|
|
Shinya Kitaoka |
120a6e |
switch (m_mode.getIndex()) {
|
|
Shinya Kitaoka |
120a6e |
case MESH_IDX:
|
|
Shinya Kitaoka |
120a6e |
leftButtonDown_mesh(pos, me);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case BUILD_IDX:
|
|
Shinya Kitaoka |
120a6e |
leftButtonDown_build(pos, me);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case RIGIDITY_IDX:
|
|
Shinya Kitaoka |
120a6e |
leftButtonDown_rigidity(pos, me);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case ANIMATE_IDX:
|
|
Shinya Kitaoka |
120a6e |
leftButtonDown_animate(pos, me);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::leftButtonDrag(const TPointD &pos, const TMouseEvent &me) {
|
|
Shinya Kitaoka |
120a6e |
// Track dragging status
|
|
Shinya Kitaoka |
120a6e |
m_dragged = true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
switch (m_mode.getIndex()) {
|
|
Shinya Kitaoka |
120a6e |
case MESH_IDX:
|
|
Shinya Kitaoka |
120a6e |
leftButtonDrag_mesh(pos, me);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case BUILD_IDX:
|
|
Shinya Kitaoka |
120a6e |
leftButtonDrag_build(pos, me);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case RIGIDITY_IDX:
|
|
Shinya Kitaoka |
120a6e |
leftButtonDrag_rigidity(pos, me);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case ANIMATE_IDX:
|
|
Shinya Kitaoka |
120a6e |
leftButtonDrag_animate(pos, me);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::leftButtonUp(const TPointD &pos, const TMouseEvent &me) {
|
|
Shinya Kitaoka |
120a6e |
switch (m_mode.getIndex()) {
|
|
Shinya Kitaoka |
120a6e |
case MESH_IDX:
|
|
Shinya Kitaoka |
120a6e |
leftButtonUp_mesh(pos, me);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case BUILD_IDX:
|
|
Shinya Kitaoka |
120a6e |
leftButtonUp_build(pos, me);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case RIGIDITY_IDX:
|
|
Shinya Kitaoka |
120a6e |
leftButtonUp_rigidity(pos, me);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case ANIMATE_IDX:
|
|
Shinya Kitaoka |
120a6e |
leftButtonUp_animate(pos, me);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_pressedPos = TConsts::napd;
|
|
Shinya Kitaoka |
120a6e |
m_pressedVxsPos.clear();
|
|
Shinya Kitaoka |
120a6e |
m_dragged = false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::addContextMenuItems(QMenu *menu) {
|
|
Shinya Kitaoka |
120a6e |
bool ret = true;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Add global actions
|
|
Shinya Kitaoka |
120a6e |
if (m_sd && m_sd->skeleton(::skeletonId())) {
|
|
Shinya Kitaoka |
120a6e |
QAction *copySkeleton = menu->addAction(tr("Copy Skeleton"));
|
|
Shinya Kitaoka |
120a6e |
ret = ret && connect(copySkeleton, SIGNAL(triggered()), &l_plasticTool,
|
|
Shinya Kitaoka |
120a6e |
SLOT(copySkeleton()));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (dynamic_cast<const *="" plasticskeletonpmime="">(</const>
|
|
Shinya Kitaoka |
120a6e |
QApplication::clipboard()->mimeData())) {
|
|
Shinya Kitaoka |
120a6e |
QAction *pasteSkeleton = menu->addAction(tr("Paste Skeleton"));
|
|
Shinya Kitaoka |
120a6e |
ret = ret && connect(pasteSkeleton, SIGNAL(triggered()), &l_plasticTool,
|
|
Shinya Kitaoka |
120a6e |
SLOT(pasteSkeleton_undo()));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
menu->addSeparator(); // Separate actions type
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Add editing actions
|
|
Shinya Kitaoka |
120a6e |
switch (m_mode.getIndex()) {
|
|
Shinya Kitaoka |
120a6e |
case MESH_IDX:
|
|
Shinya Kitaoka |
120a6e |
addContextMenuActions_mesh(menu);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case BUILD_IDX:
|
|
Shinya Kitaoka |
120a6e |
addContextMenuActions_build(menu);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case RIGIDITY_IDX:
|
|
Shinya Kitaoka |
120a6e |
addContextMenuActions_rigidity(menu);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case ANIMATE_IDX:
|
|
Shinya Kitaoka |
120a6e |
addContextMenuActions_animate(menu);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Add view actions
|
|
Shinya Kitaoka |
120a6e |
QAction *showMesh = menu->addAction(tr("Show Mesh"));
|
|
Shinya Kitaoka |
120a6e |
showMesh->setCheckable(true);
|
|
Shinya Kitaoka |
120a6e |
showMesh->setChecked(m_pvs.m_drawMeshesWireframe);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ret = ret && connect(showMesh, SIGNAL(triggered(bool)), &l_plasticTool,
|
|
Shinya Kitaoka |
120a6e |
SLOT(onShowMeshToggled(bool)));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
QAction *showRigidity = menu->addAction(tr("Show Rigidity"));
|
|
Shinya Kitaoka |
120a6e |
showRigidity->setCheckable(true);
|
|
Shinya Kitaoka |
120a6e |
showRigidity->setChecked(m_pvs.m_drawRigidity);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ret = ret && connect(showRigidity, SIGNAL(triggered(bool)), &l_plasticTool,
|
|
Shinya Kitaoka |
120a6e |
SLOT(onShowRigidityToggled(bool)));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
QAction *showSO = menu->addAction(tr("Show SO"));
|
|
Shinya Kitaoka |
120a6e |
showSO->setCheckable(true);
|
|
Shinya Kitaoka |
120a6e |
showSO->setChecked(m_pvs.m_drawSO);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ret = ret && connect(showSO, SIGNAL(triggered(bool)), &l_plasticTool,
|
|
Shinya Kitaoka |
120a6e |
SLOT(onShowSOToggled(bool)));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
QAction *showSkeletonOS = menu->addAction(tr("Show Skeleton Onion Skin"));
|
|
Shinya Kitaoka |
120a6e |
showSkeletonOS->setCheckable(true);
|
|
Shinya Kitaoka |
120a6e |
showSkeletonOS->setChecked(m_showSkeletonOS);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ret = ret && connect(showSkeletonOS, SIGNAL(triggered(bool)), &l_plasticTool,
|
|
Shinya Kitaoka |
120a6e |
SLOT(onShowSkelOSToggled(bool)));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(ret);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
menu->addSeparator(); // Separate from common view options
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::reset() {
|
|
Shinya Kitaoka |
120a6e |
// NOTE: This is an inherited virtual. Please leave it even if it's empty.
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool PlasticTool::onPropertyChanged(std::string propertyName) {
|
|
Shinya Kitaoka |
120a6e |
struct locals {
|
|
Shinya Kitaoka |
120a6e |
static bool alreadyContainsVertexName(const PlasticSkeleton &skel,
|
|
Shinya Kitaoka |
120a6e |
const QString &name) {
|
|
Shinya Kitaoka |
120a6e |
tcg::list<plasticskeletonvertex>::const_iterator vt,</plasticskeletonvertex>
|
|
Shinya Kitaoka |
120a6e |
vEnd(skel.vertices().end());
|
|
Shinya Kitaoka |
120a6e |
for (vt = skel.vertices().begin(); vt != vEnd; ++vt)
|
|
Shinya Kitaoka |
120a6e |
if (vt->name() == name) return true;
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
static int vdCount(const SkDP &sd, const QString &name) {
|
|
Shinya Kitaoka |
120a6e |
SkD::vx_iterator vxBegin, vxEnd;
|
|
Shinya Kitaoka |
120a6e |
sd->vdSkeletonVertices(name, vxBegin, vxEnd);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return std::distance(vxBegin, vxEnd);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}; // locals
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (propertyName == "mode") {
|
|
Shinya Kitaoka |
120a6e |
switch (m_mode.getIndex()) {
|
|
Shinya Kitaoka |
120a6e |
case MESH_IDX:
|
|
Shinya Kitaoka |
120a6e |
case BUILD_IDX:
|
|
Shinya Kitaoka |
120a6e |
case RIGIDITY_IDX:
|
|
Shinya Kitaoka |
120a6e |
m_pvs.m_showOriginalColumn = xshColumn();
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case ANIMATE_IDX:
|
|
Shinya Kitaoka |
120a6e |
m_pvs.m_showOriginalColumn = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_svSel.objects().size() > 1) setSkeletonSelection(-1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
storeDeformation(); // Rebuild deformed skeleton
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_mode.notifyListeners(); // You thought that was automatic, eh? BTW, this
|
|
Shinya Kitaoka |
120a6e |
// means
|
|
Shinya Kitaoka |
120a6e |
// we're requesting toolbars to update options visibility
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
onSetViewer(); // Store m_pvs in the viewer's visual settings
|
|
Shinya Kitaoka |
120a6e |
invalidate();
|
|
Shinya Kitaoka |
120a6e |
} else if (propertyName == "vertexName") {
|
|
Shinya Kitaoka |
120a6e |
if (m_sd && m_svSel >= 0) {
|
|
Shinya Kitaoka |
120a6e |
// Update the selected vertex's name
|
|
Shinya Kitaoka |
120a6e |
QString newName(QString::fromStdWString(m_vertexName.getValue()));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonP skeleton = this->skeleton();
|
|
Shinya Kitaoka |
120a6e |
assert(skeleton);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const QString &oldName = skeleton->vertex(m_svSel).name();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool doRename = true;
|
|
Shinya Kitaoka |
120a6e |
if (oldName != newName &&
|
|
Shinya Kitaoka |
120a6e |
!locals::alreadyContainsVertexName(*skeleton, newName) &&
|
|
Shinya Kitaoka |
120a6e |
m_sd->vertexDeformation(newName) &&
|
|
Shinya Kitaoka |
120a6e |
locals::vdCount(m_sd, oldName) == 1)
|
|
Shinya Kitaoka |
120a6e |
doRename =
|
|
Shinya Kitaoka |
120a6e |
(DVGui::MsgBox(
|
|
Shinya Kitaoka |
120a6e |
tr("The previous vertex name will be discarded, and all "
|
|
Shinya Kitaoka |
120a6e |
"associated keys will be lost.\n\nDo you want to proceed?"),
|
|
Shinya Kitaoka |
120a6e |
QObject::tr("Ok"), QObject::tr("Cancel")) == 1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (doRename) {
|
|
Shinya Kitaoka |
120a6e |
TUndo *undo = new SetVertexNameUndo(m_svSel, newName);
|
|
Shinya Kitaoka |
120a6e |
TUndoManager::manager()->add(undo);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
undo->redo();
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
m_vertexName.setValue(oldName.toStdWString());
|
|
Shinya Kitaoka |
120a6e |
m_vertexName.notifyListeners();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else if (propertyName == "interpolate") {
|
|
Shinya Kitaoka |
120a6e |
if (m_sd && m_svSel >= 0) {
|
|
Shinya Kitaoka |
120a6e |
// Set interpolation property to the associated skeleton vertex
|
|
Shinya Kitaoka |
120a6e |
int skelId = ::skeletonId();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_sd->skeleton(skelId)->vertex(m_svSel).m_interpolate =
|
|
Shinya Kitaoka |
120a6e |
m_interpolate.getValue();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_interpolate.notifyListeners(); // NOTE: This should NOT invoke this
|
|
Shinya Kitaoka |
120a6e |
// function recursively
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
PlasticDeformerStorage::instance()->invalidateSkeleton(
|
|
Shinya Kitaoka |
120a6e |
m_sd.getPointer(), skelId, PlasticDeformerStorage::ALL);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else if (propertyName == "minAngle") {
|
|
Shinya Kitaoka |
120a6e |
if (m_sd && m_svSel >= 0) {
|
|
Shinya Kitaoka |
120a6e |
// Set maxAngle property to the associated skeleton vertex
|
|
Shinya Kitaoka |
120a6e |
int skelId = ::skeletonId();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool ok;
|
|
Shinya Kitaoka |
120a6e |
double value =
|
|
Shinya Kitaoka |
120a6e |
QString::fromStdWString(m_minAngle.getValue()).toDouble(&ok);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!ok) value = -l_dmax, m_minAngle.setValue(L"");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_sd->skeleton(skelId)->vertex(m_svSel).m_minAngle = value;
|
|
Shinya Kitaoka |
120a6e |
if (m_mode.getIndex() == ANIMATE_IDX)
|
|
Shinya Kitaoka |
120a6e |
deformedSkeleton().vertex(m_svSel).m_minAngle = value;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_minAngle.notifyListeners(); // NOTE: This should NOT invoke this
|
|
Shinya Kitaoka |
120a6e |
// function recursively
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else if (propertyName == "maxAngle") {
|
|
Shinya Kitaoka |
120a6e |
if (m_sd && m_svSel >= 0) {
|
|
Shinya Kitaoka |
120a6e |
// Set maxAngle property to the associated skeleton vertex
|
|
Shinya Kitaoka |
120a6e |
int skelId = ::skeletonId();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool ok;
|
|
Shinya Kitaoka |
120a6e |
double value =
|
|
Shinya Kitaoka |
120a6e |
QString::fromStdWString(m_maxAngle.getValue()).toDouble(&ok);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!ok) value = l_dmax, m_maxAngle.setValue(L"");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_sd->skeleton(skelId)->vertex(m_svSel).m_maxAngle = value;
|
|
Shinya Kitaoka |
120a6e |
if (m_mode.getIndex() == ANIMATE_IDX)
|
|
Shinya Kitaoka |
120a6e |
deformedSkeleton().vertex(m_svSel).m_maxAngle = value;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_maxAngle.notifyListeners(); // NOTE: This should NOT invoke this
|
|
Shinya Kitaoka |
120a6e |
// function recursively
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::onShowMeshToggled(bool on) {
|
|
Shinya Kitaoka |
120a6e |
m_pvs.m_drawMeshesWireframe = on;
|
|
Shinya Kitaoka |
120a6e |
invalidate();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::onShowSOToggled(bool on) {
|
|
Shinya Kitaoka |
120a6e |
m_pvs.m_drawSO = on;
|
|
Shinya Kitaoka |
120a6e |
invalidate();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::onShowRigidityToggled(bool on) {
|
|
Shinya Kitaoka |
120a6e |
m_pvs.m_drawRigidity = on;
|
|
Shinya Kitaoka |
120a6e |
invalidate();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::onShowSkelOSToggled(bool on) {
|
|
Shinya Kitaoka |
120a6e |
m_showSkeletonOS = on;
|
|
Shinya Kitaoka |
120a6e |
invalidate();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Drawing functions
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace PlasticToolLocals {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void drawSquare(const TPointD &pos, double radius) {
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_LINE_LOOP);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(pos.x - radius, pos.y - radius);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(pos.x + radius, pos.y - radius);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(pos.x + radius, pos.y + radius);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(pos.x - radius, pos.y + radius);
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void drawFullSquare(const TPointD &pos, double radius) {
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_QUADS);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(pos.x - radius, pos.y - radius);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(pos.x + radius, pos.y - radius);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(pos.x + radius, pos.y + radius);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(pos.x - radius, pos.y + radius);
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void drawFilledSquare(const TPointD &pos, double radius) {
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_QUADS);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(pos.x - radius, pos.y - radius);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(pos.x + radius, pos.y - radius);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(pos.x + radius, pos.y + radius);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(pos.x - radius, pos.y + radius);
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void drawHandle(const TPointD &pos, double radius, const TPixel32 &color) {
|
|
Shinya Kitaoka |
120a6e |
glColor4ub(0, 0, 0, color.m); // Black border
|
|
Shinya Kitaoka |
120a6e |
glLineWidth(4.0f);
|
|
Shinya Kitaoka |
120a6e |
drawSquare(pos, radius);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glColor4ub(color.r, color.g, color.b, color.m);
|
|
Shinya Kitaoka |
120a6e |
glLineWidth(2.0f);
|
|
Shinya Kitaoka |
120a6e |
drawSquare(pos, radius);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void drawFilledHandle(const TPointD &pos, double radius, double pixelSize,
|
|
Shinya Kitaoka |
120a6e |
const TPixel32 &color) {
|
|
Shinya Kitaoka |
120a6e |
glColor4ub(0, 0, 0, color.m);
|
|
Shinya Kitaoka |
120a6e |
drawFilledSquare(pos, radius + pixelSize);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glColor4ub(color.r, color.g, color.b, color.m);
|
|
Shinya Kitaoka |
120a6e |
drawFilledSquare(pos, radius);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void drawText(const TPointD &pos, const QString &text, double fontScale) {
|
|
Shinya Kitaoka |
120a6e |
// Get the world-to-window affine
|
|
Shinya Kitaoka |
120a6e |
double matrix[16];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glGetDoublev(GL_MODELVIEW_MATRIX, matrix);
|
|
Shinya Kitaoka |
120a6e |
TAffine worldToWindowAff(matrix[0], matrix[4], matrix[12], matrix[1],
|
|
Shinya Kitaoka |
120a6e |
matrix[5], matrix[13]);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Push the window reference
|
|
Shinya Kitaoka |
120a6e |
glPushMatrix();
|
|
Shinya Kitaoka |
120a6e |
glLoadIdentity();
|
|
Shinya Kitaoka |
120a6e |
glScaled(fontScale, fontScale, 1.0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
tglDrawText(TScale(1.0 / fontScale) * worldToWindowAff * pos,
|
|
Shinya Kitaoka |
120a6e |
text.toStdWString());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Bottom-left fixed text version
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// double origin = 10.0 / fontScale
|
|
Shinya Kitaoka |
120a6e |
// tglDrawText(TPointD(origin, origin), text.toStdWString());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glPopMatrix();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace PlasticToolLocals
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//========================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::drawHighlights(const SkDP &sd,
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeleton *skeleton,
|
|
Shinya Kitaoka |
120a6e |
double pixelSize) {
|
|
Shinya Kitaoka |
120a6e |
glColor3f(1.0f, 0.0f, 0.0f); // Red
|
|
Shinya Kitaoka |
120a6e |
glLineWidth(1.0f);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Vertex highlights
|
|
Shinya Kitaoka |
120a6e |
if (m_svHigh >= 0) {
|
|
Shinya Kitaoka |
120a6e |
double handleRadius = HIGHLIGHTED_HANDLE_SIZE * pixelSize;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeleton::vertex_type &vx = skeleton->vertex(m_svHigh);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int hookNumber = sd->hookNumber(vx.name());
|
|
Shinya Kitaoka |
120a6e |
assert(hookNumber >= 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
glPushAttrib(GL_LINE_BIT);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glEnable(GL_LINE_STIPPLE);
|
|
Shinya Kitaoka |
120a6e |
glLineStipple(1, 0xCCCC);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
drawSquare(vx.P(), handleRadius);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glPopAttrib();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
drawText(vx.P() + TPointD(2.0 * handleRadius, 2.0 * handleRadius),
|
|
Shinya Kitaoka |
120a6e |
QString("(%1) ").arg(hookNumber) + vx.name(), 1.7);
|
|
Shinya Kitaoka |
120a6e |
} else if (m_seHigh >= 0) {
|
|
Shinya Kitaoka |
120a6e |
// Draw a handle at the projection of current mouse position towards the
|
|
Shinya Kitaoka |
120a6e |
// highlighted edge
|
|
Shinya Kitaoka |
120a6e |
double handleRadius = HANDLE_SIZE * pixelSize;
|
|
Shinya Kitaoka |
120a6e |
drawSquare(projection(*skeleton, m_seHigh, m_pos), handleRadius);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::drawSelections(const SkDP &sd,
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeleton &skeleton,
|
|
Shinya Kitaoka |
120a6e |
double pixelSize) {
|
|
Shinya Kitaoka |
120a6e |
glColor3f(1.0f, 0.0f, 0.0f); // Red
|
|
Shinya Kitaoka |
120a6e |
glLineWidth(1.0f);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double handleRadius = SELECTED_HANDLE_SIZE * pixelSize;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!m_svSel.isEmpty()) {
|
|
Shinya Kitaoka |
120a6e |
typedef PlasticVertexSelection::objects_container objects_container;
|
|
Shinya Kitaoka |
120a6e |
const objects_container &vIdxs = m_svSel.objects();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Draw a handle square for each selected vertex
|
|
Shinya Kitaoka |
120a6e |
objects_container::const_iterator vst, vsEnd = vIdxs.end();
|
|
Shinya Kitaoka |
120a6e |
for (vst = vIdxs.begin(); vst != vsEnd; ++vst)
|
|
Shinya Kitaoka |
120a6e |
drawSquare(skeleton.vertex(*vst).P(), handleRadius);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Draw vertex descriptions (only in the single selection case - to avoid
|
|
Shinya Kitaoka |
120a6e |
// text pollution)
|
|
Shinya Kitaoka |
120a6e |
if (vIdxs.size() == 1) {
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeleton::vertex_type &vx = skeleton.vertex(m_svSel);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int hookNumber = sd->hookNumber(vx.name());
|
|
Shinya Kitaoka |
120a6e |
assert(hookNumber >= 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
drawText(vx.P() + TPointD(2.0 * handleRadius, 2.0 * handleRadius),
|
|
Shinya Kitaoka |
120a6e |
QString("(%1) ").arg(hookNumber) + vx.name(), 1.7);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::drawSkeleton(const PlasticSkeleton &skel, double pixelSize,
|
|
Shinya Kitaoka |
120a6e |
UCHAR alpha) {
|
|
Shinya Kitaoka |
120a6e |
struct locals {
|
|
Shinya Kitaoka |
120a6e |
inline static void drawLine(const TPointD &p0, const TPointD &p1) {
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(p0.x, p0.y);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(p1.x, p1.y);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}; // locals
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const tcg::list<plasticskeleton::vertex_type> &vertices = skel.vertices();</plasticskeleton::vertex_type>
|
|
Shinya Kitaoka |
120a6e |
if (vertices.size() > 0) {
|
|
Shinya Kitaoka |
120a6e |
// Draw edges
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
const tcg::list<plasticskeleton::edge_type> &edges = skel.edges();</plasticskeleton::edge_type>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
tcg::list<plasticskeleton::edge_type>::const_iterator et,</plasticskeleton::edge_type>
|
|
Shinya Kitaoka |
120a6e |
eEnd(edges.end());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glColor4ub(0, 0, 0, alpha);
|
|
Shinya Kitaoka |
120a6e |
glLineWidth(4.0f); // Black border
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_LINES);
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
for (et = edges.begin(); et != eEnd; ++et)
|
|
Shinya Kitaoka |
120a6e |
locals::drawLine(skel.vertex(et->vertex(0)).P(),
|
|
Shinya Kitaoka |
120a6e |
skel.vertex(et->vertex(1)).P());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glColor4ub(250, 184, 70, alpha);
|
|
Shinya Kitaoka |
120a6e |
glLineWidth(2.0f); // Yellow/Orange-ish line center
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_LINES);
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
for (et = edges.begin(); et != eEnd; ++et)
|
|
Shinya Kitaoka |
120a6e |
locals::drawLine(skel.vertex(et->vertex(0)).P(),
|
|
Shinya Kitaoka |
120a6e |
skel.vertex(et->vertex(1)).P());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Draw vertices
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
const TPixel32 magenta(255, 0, 255, alpha);
|
|
Shinya Kitaoka |
120a6e |
const TPixel32 yellow(255, 255, 0, alpha);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double handleRadius = HANDLE_SIZE * pixelSize;
|
|
Shinya Kitaoka |
120a6e |
float intHandleThick = 2.0f, extHandleThick = 4.0f;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Draw root
|
|
Shinya Kitaoka |
120a6e |
drawFilledHandle(vertices.begin()->P(), handleRadius, pixelSize, magenta);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Draw remaining vertices
|
|
Shinya Kitaoka |
120a6e |
tcg::list<plasticskeleton::vertex_type>::const_iterator vt(</plasticskeleton::vertex_type>
|
|
Shinya Kitaoka |
120a6e |
vertices.begin()),
|
|
Shinya Kitaoka |
120a6e |
vEnd(vertices.end());
|
|
Shinya Kitaoka |
120a6e |
if (vt != vEnd) {
|
|
Shinya Kitaoka |
120a6e |
for (vt = ++vertices.begin(); vt != vEnd; ++vt)
|
|
Shinya Kitaoka |
120a6e |
drawHandle(vt->P(), handleRadius,
|
|
Shinya Kitaoka |
120a6e |
vt->m_interpolate ? magenta : yellow);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::drawOnionSkinSkeletons_build(double pixelSize) {
|
|
Shinya Kitaoka |
120a6e |
if (!(m_showSkeletonOS && m_sd)) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const OnionSkinMask &os =
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()->getCurrentOnionSkin()->getOnionSkinMask();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> osRows;</int>
|
|
Shinya Kitaoka |
120a6e |
int currentRow = ::row();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
os.getAll(currentRow, osRows);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStageObject *obj = ::stageObject();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Sieve osRows' associated skeleton ids first
|
|
Shinya Kitaoka |
120a6e |
std::map<int, uchar=""> skelAlphas;</int,>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int r, rCount = int(osRows.size());
|
|
Shinya Kitaoka |
120a6e |
for (r = 0; r != rCount; ++r) {
|
|
Shinya Kitaoka |
120a6e |
assert(osRows[r] != currentRow);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double sdFrame = obj->paramsTime(double(osRows[r] - 1));
|
|
Shinya Kitaoka |
120a6e |
int skelId = m_sd->skeletonId(sdFrame);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
UCHAR &skelAlpha = skelAlphas[skelId];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
UCHAR alpha =
|
|
Shinya Kitaoka |
120a6e |
255 -
|
|
Shinya Kitaoka |
120a6e |
UCHAR(255.0 * OnionSkinMask::getOnionSkinFade(osRows[r] - currentRow));
|
|
Shinya Kitaoka |
120a6e |
skelAlpha = std::max(skelAlpha, alpha);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::map<int, uchar="">::iterator st, sEnd(skelAlphas.end());</int,>
|
|
Shinya Kitaoka |
120a6e |
for (st = skelAlphas.begin(); st != sEnd; ++st) {
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonP &skel = m_sd->skeleton(st->first);
|
|
Shinya Kitaoka |
120a6e |
drawSkeleton(*skel, pixelSize, st->second);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::drawOnionSkinSkeletons_animate(double pixelSize) {
|
|
Shinya Kitaoka |
120a6e |
if (!(m_showSkeletonOS && m_sd)) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const OnionSkinMask &os =
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()->getCurrentOnionSkin()->getOnionSkinMask();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> osRows;</int>
|
|
Shinya Kitaoka |
120a6e |
int currentRow = ::row();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
os.getAll(currentRow, osRows);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStageObject *obj = ::stageObject();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int r, rCount = int(osRows.size());
|
|
Shinya Kitaoka |
120a6e |
for (r = 0; r != rCount; ++r) {
|
|
Shinya Kitaoka |
120a6e |
assert(osRows[r] != currentRow);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double sdFrame = obj->paramsTime(double(osRows[r] - 1));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
PlasticSkeleton skel;
|
|
Shinya Kitaoka |
120a6e |
m_sd->storeDeformedSkeleton(m_sd->skeletonId(sdFrame), sdFrame, skel);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
UCHAR alpha =
|
|
Shinya Kitaoka |
120a6e |
255 -
|
|
Shinya Kitaoka |
120a6e |
255.0 * OnionSkinMask::getOnionSkinFade(abs(osRows[r] - currentRow));
|
|
Shinya Kitaoka |
120a6e |
drawSkeleton(skel, pixelSize, alpha);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::drawAngleLimits(const SkDP &sd, int skelId, int v,
|
|
Shinya Kitaoka |
120a6e |
double pixelSize) {
|
|
Shinya Kitaoka |
120a6e |
struct {
|
|
Shinya Kitaoka |
120a6e |
PlasticTool *m_this;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void drawAnnulusArc(const TPointD ¢er, double angleStart,
|
|
Shinya Kitaoka |
120a6e |
double angleEnd, double radiusA, double radiusB,
|
|
Shinya Kitaoka |
120a6e |
double pixelSize) {
|
|
Shinya Kitaoka |
120a6e |
double angleDelta = acos(1.0 - pixelSize / std::max(radiusA, radiusB)) *
|
|
Shinya Kitaoka |
120a6e |
((angleStart <= angleEnd) ? 1.0 : -1.0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int a, aCount = tcg::numeric_ops::grow(
|
|
Shinya Kitaoka |
120a6e |
fabs((angleEnd - angleStart) / angleDelta));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_QUAD_STRIP);
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
for (a = 0; a != aCount; ++a) {
|
|
Shinya Kitaoka |
120a6e |
double angle = angleStart + a * angleDelta;
|
|
Shinya Kitaoka |
120a6e |
TPointD direction(cos(angle), sin(angle));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
tglVertex(center + radiusA * direction);
|
|
Shinya Kitaoka |
120a6e |
tglVertex(center + radiusB * direction);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPointD direction(cos(angleEnd), sin(angleEnd));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
tglVertex(center + radiusA * direction);
|
|
Shinya Kitaoka |
120a6e |
tglVertex(center + radiusB * direction);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void drawLimit(const SkDP &sd, int skelId, int v, double angleLimit,
|
|
Shinya Kitaoka |
120a6e |
double pixelSize) {
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeleton &skel = *sd->skeleton(skelId);
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeleton &defSkel = m_this->deformedSkeleton();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonVertex &vx = skel.vertex(v);
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonVertex &defVx = defSkel.vertex(v);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int vParent = vx.parent();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonVertex &vxParent = skel.vertex(vParent);
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonVertex &defVxParent = defSkel.vertex(vParent);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Build directions
|
|
Shinya Kitaoka |
120a6e |
int vGrandParent = vxParent.parent();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPointD dirFromParent(vx.P() - vxParent.P()), dirFromGrandParent(1, 0),
|
|
Shinya Kitaoka |
120a6e |
dirFromDeformedGrandParent(1, 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (vGrandParent >= 0) {
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonVertex &vxGrandParent = skel.vertex(vGrandParent),
|
|
Shinya Kitaoka |
120a6e |
&defVxGrandParent =
|
|
Shinya Kitaoka |
120a6e |
defSkel.vertex(vGrandParent);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
dirFromGrandParent = vxParent.P() - vxGrandParent.P();
|
|
Shinya Kitaoka |
120a6e |
dirFromDeformedGrandParent = defVxParent.P() - defVxGrandParent.P();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Retrieve angular data
|
|
Shinya Kitaoka |
120a6e |
double angleShift =
|
|
Shinya Kitaoka |
120a6e |
sd->vertexDeformation(skelId, v)->m_params[SkVD::ANGLE]->getValue(
|
|
Shinya Kitaoka |
120a6e |
::frame());
|
|
Shinya Kitaoka |
120a6e |
double defaultAngleValue =
|
|
Shinya Kitaoka |
120a6e |
tcg::point_ops::angle(dirFromGrandParent, dirFromParent) * M_180_PI;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Convert to radians
|
|
Shinya Kitaoka |
120a6e |
double currentBranchAngle_rad =
|
|
Shinya Kitaoka |
120a6e |
tcg::point_ops::rad(dirFromDeformedGrandParent);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double currentAngle_rad =
|
|
Shinya Kitaoka |
120a6e |
currentBranchAngle_rad + (angleShift + defaultAngleValue) * M_PI_180;
|
|
Shinya Kitaoka |
120a6e |
double limitDirection_rad =
|
|
Shinya Kitaoka |
120a6e |
currentBranchAngle_rad + (angleLimit + defaultAngleValue) * M_PI_180;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glColor4ub(0, 0, 255, 128);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Draw limit lines
|
|
Shinya Kitaoka |
120a6e |
if (angleShift - 180.0 <= angleLimit &&
|
|
Shinya Kitaoka |
120a6e |
angleLimit <= angleShift + 180.0) {
|
|
Shinya Kitaoka |
120a6e |
TPointD limitDirection(cos(limitDirection_rad),
|
|
Shinya Kitaoka |
120a6e |
sin(limitDirection_rad));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_LINES);
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
tglVertex(defVxParent.P());
|
|
Shinya Kitaoka |
120a6e |
tglVertex(defVxParent.P() + 1e4 * limitDirection);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Draw limit annulus arc
|
|
Shinya Kitaoka |
120a6e |
angleLimit = tcrop(angleLimit, angleShift - 180.0, angleShift + 180.0);
|
|
Shinya Kitaoka |
120a6e |
limitDirection_rad =
|
|
Shinya Kitaoka |
120a6e |
currentBranchAngle_rad + (angleLimit + defaultAngleValue) * M_PI_180;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double radius = tcg::point_ops::dist(defVx.P(), defVxParent.P()) * 0.25;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
drawAnnulusArc(defVxParent.P(), limitDirection_rad, currentAngle_rad,
|
|
Shinya Kitaoka |
120a6e |
radius - 5.0 * pixelSize, radius + 5.0 * pixelSize,
|
|
Shinya Kitaoka |
120a6e |
pixelSize);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} locals = {this};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Dismiss no-ops
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonP &skel = sd->skeleton(skelId);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!skel || v < 0) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Ensure we're editing a vertex with an existing parent
|
|
Shinya Kitaoka |
120a6e |
if (m_dragged) {
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonVertex &vx = skel->vertex(v);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int vParent = vx.parent();
|
|
Shinya Kitaoka |
120a6e |
if (vParent >= 0) {
|
|
Shinya Kitaoka |
120a6e |
// Draw angular limits
|
|
Shinya Kitaoka |
120a6e |
if (vx.m_minAngle != -l_dmax)
|
|
Shinya Kitaoka |
120a6e |
locals.drawLimit(sd, skelId, v, vx.m_minAngle, pixelSize);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (vx.m_maxAngle != l_dmax)
|
|
Shinya Kitaoka |
120a6e |
locals.drawLimit(sd, skelId, v, vx.m_maxAngle, pixelSize);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::draw() {
|
|
Shinya Kitaoka |
120a6e |
glPushAttrib(GL_LINE_BIT | GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glEnable(GL_BLEND);
|
|
Shinya Kitaoka |
120a6e |
glEnable(GL_LINE_SMOOTH);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
switch (m_mode.getIndex()) {
|
|
Shinya Kitaoka |
120a6e |
case MESH_IDX:
|
|
Shinya Kitaoka |
120a6e |
draw_mesh();
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case BUILD_IDX:
|
|
Shinya Kitaoka |
120a6e |
draw_build();
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case RIGIDITY_IDX:
|
|
Shinya Kitaoka |
120a6e |
draw_rigidity();
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case ANIMATE_IDX:
|
|
Shinya Kitaoka |
120a6e |
draw_animate();
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glPopAttrib();
|
|
Toshihiro Shimizu |
890ddd |
}
|