|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzCore includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tundo.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzExt includes
|
|
Toshihiro Shimizu |
890ddd |
#include "ext/plasticdeformerstorage.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzLib includes
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshcell.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshsimplelevel.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txsheethandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/stage.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// tcg includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tcg/tcg_point_ops.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcg/tcg_algorithm.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 |
#include "plastictool.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
using namespace PlasticToolLocals;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Local namespace stuff
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPointD closestMeshVertexPos(const TPointD &pos, double *distance = 0) {
|
|
Shinya Kitaoka |
120a6e |
const TXshCell &imageCell = TTool::getImageCell();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TXshSimpleLevel *sl = imageCell.getSimpleLevel();
|
|
Shinya Kitaoka |
120a6e |
assert(sl);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TMeshImageP mi(TTool::getImage(false));
|
|
Shinya Kitaoka |
120a6e |
assert(mi);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Retrieve *level* dpi
|
|
Shinya Kitaoka |
120a6e |
// NOTE: This is different than current IMAGE's dpi. An image is actually
|
|
Shinya Kitaoka |
120a6e |
// displayed with
|
|
Shinya Kitaoka |
120a6e |
// its level owner's dpi, RATHER than its own.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TPointD &dpi = sl->getDpi(imageCell.getFrameId());
|
|
Shinya Kitaoka |
120a6e |
assert(dpi.x > 0.0 && dpi.y > 0.0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Cast pos to image coordinates
|
|
Shinya Kitaoka |
120a6e |
const TPointD pos_mesh(pos.x * (dpi.x / Stage::inch),
|
|
Shinya Kitaoka |
120a6e |
pos.y * (dpi.y / Stage::inch));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Retrieve the closest vertex to pos_mesh
|
|
Shinya Kitaoka |
120a6e |
const std::pair<double, plastictool::meshindex=""> &closest =</double,>
|
|
Shinya Kitaoka |
120a6e |
PlasticToolLocals::closestVertex(*mi, pos_mesh);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TPointD &vxPos_mesh =
|
|
Shinya Kitaoka |
120a6e |
mi->meshes()[closest.second.m_meshIdx]->vertex(closest.second.m_idx).P();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (distance)
|
|
Shinya Kitaoka |
120a6e |
*distance =
|
|
Shinya Kitaoka |
120a6e |
std::min(Stage::inch / dpi.x, Stage::inch / dpi.y) * closest.first;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Cast it back to world coordinates
|
|
Shinya Kitaoka |
120a6e |
return TPointD(vxPos_mesh.x * (Stage::inch / dpi.x),
|
|
Shinya Kitaoka |
120a6e |
vxPos_mesh.y * (Stage::inch / dpi.y));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPointD closestSkeletonVertexPos(const TPointD &pos) {
|
|
Shinya Kitaoka |
120a6e |
struct locals {
|
|
Shinya Kitaoka |
120a6e |
static inline double dist2(const TPointD &pos,
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonVertex &vx) {
|
|
Shinya Kitaoka |
120a6e |
return tcg::point_ops::dist2(pos, vx.P());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonP &skeleton = l_plasticTool.skeleton();
|
|
Shinya Kitaoka |
120a6e |
if (!skeleton || skeleton->empty()) return TConsts::napd;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeleton::vertices_container &vertices = skeleton->vertices();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return tcg::min_transform(vertices.begin(), vertices.end(),
|
|
Shinya Kitaoka |
120a6e |
tcg::bind1st(&locals::dist2, pos))
|
|
Shinya Kitaoka |
120a6e |
->P();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Undo definitions
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class VertexUndo : public TUndo {
|
|
Toshihiro Shimizu |
890ddd |
protected:
|
|
Shinya Kitaoka |
120a6e |
int m_row, m_col; //!< Xsheet coordinates
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int m_v, m_vParent; //!< Indices of the added vertex and its parent
|
|
Shinya Kitaoka |
120a6e |
PlasticSkeletonVertex m_vx; //!< Added vertex
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> m_children; //!< Children of the vertex to insert</int>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
VertexUndo() : m_row(::row()), m_col(::column()), m_v(-1), m_vParent(-1) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
473e70 |
int getSize() const override { return sizeof(*this); } // sizeof this is roughly ok
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void storeChildren(const PlasticSkeleton &skeleton,
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonVertex &vx) {
|
|
Shinya Kitaoka |
120a6e |
m_children.clear();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Traverse vx's edges and build its children table
|
|
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 vChild = skeleton.edge(*et).vertex(1);
|
|
Shinya Kitaoka |
120a6e |
if (vChild == vx.getIndex()) continue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_children.push_back(vChild);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void addVertex() {
|
|
Shinya Kitaoka |
120a6e |
assert(m_vx.edges().empty());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Load the right skeleton by moving to the stored xsheet pos
|
|
Shinya Kitaoka |
120a6e |
PlasticTool::TemporaryActivation tempActivate(m_row, m_col);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonP &skeleton = l_plasticTool.skeleton();
|
|
Shinya Kitaoka |
120a6e |
TCG_ASSERT(skeleton || m_vParent < 0, return );
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Perform addition
|
|
Shinya Kitaoka |
120a6e |
l_plasticTool.setSkeletonSelection(m_vParent);
|
|
Shinya Kitaoka |
120a6e |
l_plasticTool.addVertex(m_vx);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Store data to invert the operation
|
|
Shinya Kitaoka |
120a6e |
assert(l_plasticTool.skeletonVertexSelection().hasSingleObject());
|
|
Shinya Kitaoka |
120a6e |
m_v = l_plasticTool.skeletonVertexSelection();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void insertVertex() {
|
|
Shinya Kitaoka |
120a6e |
if (m_children.empty()) {
|
|
Shinya Kitaoka |
120a6e |
addVertex();
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(m_vx.edges().empty());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TCG_ASSERT(m_vParent >= 0, return );
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
PlasticTool::TemporaryActivation tempActivate(m_row, m_col);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonP &skeleton = l_plasticTool.skeleton();
|
|
Shinya Kitaoka |
120a6e |
TCG_ASSERT(skeleton, return );
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Perform insertion
|
|
Shinya Kitaoka |
120a6e |
l_plasticTool.insertVertex(m_vx, m_vParent, m_children);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Store data to invert the operation
|
|
Shinya Kitaoka |
120a6e |
assert(l_plasticTool.skeletonVertexSelection().hasSingleObject());
|
|
Shinya Kitaoka |
120a6e |
m_v = l_plasticTool.skeletonVertexSelection();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void removeVertex() {
|
|
Shinya Kitaoka |
120a6e |
TCG_ASSERT(m_v >= 0, return );
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
PlasticTool::TemporaryActivation tempActivate(m_row, m_col);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonP &skeleton = l_plasticTool.skeleton();
|
|
Shinya Kitaoka |
120a6e |
TCG_ASSERT(skeleton, return );
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Store data to invert the operation
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonVertex &vx = skeleton->vertex(m_v);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_vParent = vx.parent();
|
|
Shinya Kitaoka |
120a6e |
m_vx = PlasticSkeletonVertex(vx.P());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
storeChildren(*skeleton, vx);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Perform removal
|
|
Shinya Kitaoka |
120a6e |
if (m_v > 0) {
|
|
Shinya Kitaoka |
120a6e |
l_plasticTool.setSkeletonSelection(m_v);
|
|
Shinya Kitaoka |
120a6e |
l_plasticTool.removeVertex();
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
l_plasticTool.removeSkeleton(::skeletonId());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class AddVertexUndo : public VertexUndo {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
AddVertexUndo(int vParent, const PlasticSkeletonVertex &vx) {
|
|
Shinya Kitaoka |
120a6e |
m_vParent = vParent, m_vx = vx;
|
|
Shinya Kitaoka |
120a6e |
assert(m_vx.edges().empty());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void redo() const override {
|
|
Shinya Kitaoka |
120a6e |
const_cast<addvertexundo &="">(*this).VertexUndo::addVertex();</addvertexundo>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
473e70 |
void undo() const override {
|
|
Shinya Kitaoka |
120a6e |
const_cast<addvertexundo &="">(*this).VertexUndo::removeVertex();</addvertexundo>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class RemoveVertexUndo : public VertexUndo {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
RemoveVertexUndo(int v) {
|
|
Shinya Kitaoka |
120a6e |
assert(v >= 0);
|
|
Shinya Kitaoka |
120a6e |
m_v = v;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void redo() const override {
|
|
Shinya Kitaoka |
120a6e |
const_cast<removevertexundo &="">(*this).VertexUndo::removeVertex();</removevertexundo>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
473e70 |
void undo() const override {
|
|
Shinya Kitaoka |
120a6e |
const_cast<removevertexundo &="">(*this).VertexUndo::insertVertex();</removevertexundo>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//========================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class InsertVertexUndo : public VertexUndo {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
InsertVertexUndo(int e, const PlasticSkeletonVertex &vx) {
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeleton &skeleton = *l_plasticTool.skeleton();
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeleton::edge_type &ed = skeleton.edge(e);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_vParent = ed.vertex(0), m_vx = vx;
|
|
Shinya Kitaoka |
120a6e |
std::vector<int>(1, ed.vertex(1)).swap(m_children);</int>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
473e70 |
void redo() const override {
|
|
Shinya Kitaoka |
120a6e |
const_cast<insertvertexundo &="">(*this).VertexUndo::insertVertex();</insertvertexundo>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
473e70 |
void undo() const override {
|
|
Shinya Kitaoka |
120a6e |
TCG_ASSERT(!m_children.empty(), return );
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const_cast<insertvertexundo &="">(*this).VertexUndo::removeVertex();</insertvertexundo>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//========================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class AddSkeletonUndo : public TUndo {
|
|
Shinya Kitaoka |
120a6e |
protected:
|
|
Shinya Kitaoka |
120a6e |
int m_row, m_col; //!< Xsheet coordinates
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int m_skelId; //!< The added skeleton's id
|
|
Shinya Kitaoka |
120a6e |
PlasticSkeletonP m_skeleton; //!< A COPY of the added skeleton
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
public:
|
|
Shinya Kitaoka |
120a6e |
AddSkeletonUndo(int skelId, const PlasticSkeletonP &skeletonCopy)
|
|
Shinya Kitaoka |
120a6e |
: m_row(::row())
|
|
Shinya Kitaoka |
120a6e |
, m_col(::column())
|
|
Shinya Kitaoka |
120a6e |
, m_skelId(skelId)
|
|
Shinya Kitaoka |
120a6e |
, m_skeleton(skeletonCopy) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// This is not correct... it's tough to build the right one! We're like
|
|
Shinya Kitaoka |
120a6e |
// storing the whole
|
|
Shinya Kitaoka |
120a6e |
// cleared deformation! So, I guess 1 MB (100 of these in the standard undos
|
|
Shinya Kitaoka |
120a6e |
// pool)
|
|
Shinya Kitaoka |
120a6e |
// is a reasonable estimate...
|
|
Shinya Kitaoka |
473e70 |
int getSize() const override { return 1 << 20; }
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void redo() const override {
|
|
Shinya Kitaoka |
120a6e |
PlasticTool::TemporaryActivation tempActivate(m_row, m_col);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
l_plasticTool.addSkeleton(m_skelId, new PlasticSkeleton(*m_skeleton));
|
|
Shinya Kitaoka |
120a6e |
::invalidateXsheet();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void undo() const override {
|
|
Shinya Kitaoka |
120a6e |
PlasticTool::TemporaryActivation tempActivate(m_row, m_col);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
l_plasticTool.removeSkeleton(m_skelId);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//========================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class RemoveSkeletonUndo : public AddSkeletonUndo {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
RemoveSkeletonUndo(int skelId)
|
|
Shinya Kitaoka |
120a6e |
: AddSkeletonUndo(skelId, l_plasticTool.skeleton()) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
473e70 |
void redo() const override { AddSkeletonUndo::undo(); }
|
|
Shinya Kitaoka |
473e70 |
void undo() const override { AddSkeletonUndo::redo(); }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class RemoveSkeletonUndo_WithKeyframes : public RemoveSkeletonUndo {
|
|
Shinya Kitaoka |
120a6e |
mutable std::vector<tdoublekeyframe></tdoublekeyframe>
|
|
Shinya Kitaoka |
120a6e |
m_skelIdsKeyframes; //!< Skeleton Ids param curve keyframes
|
|
Shinya Kitaoka |
120a6e |
//!< for m_skelId
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
RemoveSkeletonUndo_WithKeyframes(int skelId) : RemoveSkeletonUndo(skelId) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
473e70 |
void redo() const override {
|
|
Shinya Kitaoka |
120a6e |
// Erase all keyframes corresponding to m_skelId from sd's skeleton ids
|
|
Shinya Kitaoka |
120a6e |
// curve
|
|
Shinya Kitaoka |
120a6e |
const SkDP &sd = l_plasticTool.deformation();
|
|
Shinya Kitaoka |
120a6e |
TCG_ASSERT(sd, return );
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TDoubleParamP &skelIdsParam = sd->skeletonIdsParam();
|
|
Shinya Kitaoka |
120a6e |
if (skelIdsParam->getKeyframeCount() > 0) {
|
|
Shinya Kitaoka |
120a6e |
double frame;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (int k = 0; k >= 0; k = skelIdsParam->getNextKeyframe(frame)) {
|
|
Shinya Kitaoka |
120a6e |
const TDoubleKeyframe &kf = skelIdsParam->getKeyframe(k);
|
|
Shinya Kitaoka |
120a6e |
frame = kf.m_frame;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_skelId == (int)kf.m_value) {
|
|
Shinya Kitaoka |
120a6e |
m_skelIdsKeyframes.push_back(kf);
|
|
Shinya Kitaoka |
120a6e |
skelIdsParam->deleteKeyframe(frame);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
RemoveSkeletonUndo::redo(); // Invalidates the xsheet
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
473e70 |
void undo() const override {
|
|
Shinya Kitaoka |
120a6e |
l_plasticTool
|
|
Shinya Kitaoka |
120a6e |
.touchDeformation(); // Skeleton removal could have destroyed the sd
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Restore saved keyframes to sd's skelIdsParam curve
|
|
Shinya Kitaoka |
120a6e |
const SkDP &sd = l_plasticTool.deformation();
|
|
Shinya Kitaoka |
120a6e |
assert(sd);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TDoubleParamP &skelIdsParam = sd->skeletonIdsParam();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::vector<tdoublekeyframe>::iterator kt, kEnd(m_skelIdsKeyframes.end());</tdoublekeyframe>
|
|
Shinya Kitaoka |
120a6e |
for (kt = m_skelIdsKeyframes.begin(); kt != kEnd; ++kt)
|
|
Shinya Kitaoka |
120a6e |
skelIdsParam->setKeyframe(*kt);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_skelIdsKeyframes.clear();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
RemoveSkeletonUndo::undo(); // Invalidates the xsheet
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//========================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class SetSkeletonIdUndo : public TUndo {
|
|
Shinya Kitaoka |
120a6e |
int m_row, m_col; //!< Xsheet coordinates
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int m_skelId; //!< The new skeleton id value
|
|
Shinya Kitaoka |
120a6e |
mutable TDoubleKeyframe
|
|
Shinya Kitaoka |
120a6e |
m_oldKf; //!< Old keyframe values for skelIds parameter
|
|
Shinya Kitaoka |
120a6e |
mutable bool m_added1stKeyframe; //!< Whether the redo() added the first
|
|
Shinya Kitaoka |
120a6e |
//!skelIds keyframe
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
SetSkeletonIdUndo(int skelId)
|
|
Shinya Kitaoka |
120a6e |
: m_row(::row()), m_col(::column()), m_skelId(skelId) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
473e70 |
int getSize() const override { return sizeof(*this); }
|
|
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 |
const SkDP &sd = l_plasticTool.deformation();
|
|
Shinya Kitaoka |
120a6e |
TCG_ASSERT(sd, return );
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TDoubleParamP &skelIdsParam = sd->skeletonIdsParam();
|
|
Shinya Kitaoka |
120a6e |
double frame = ::frame();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_oldKf = skelIdsParam->getKeyframeAt(frame);
|
|
Shinya Kitaoka |
120a6e |
m_added1stKeyframe = false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (frame > 0.0 && (skelIdsParam->getKeyframeCount() == 0 ||
|
|
Shinya Kitaoka |
120a6e |
skelIdsParam->getKeyframe(0).m_frame >= frame)) {
|
|
Shinya Kitaoka |
120a6e |
// Put a keyframe at the previous cell to preserve values before current
|
|
Shinya Kitaoka |
120a6e |
// frame
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe kf(frame - 1.0, skelIdsParam->getDefaultValue());
|
|
Shinya Kitaoka |
120a6e |
kf.m_type = TDoubleKeyframe::Constant;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
skelIdsParam->setKeyframe(kf);
|
|
Shinya Kitaoka |
120a6e |
m_added1stKeyframe = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe kf(frame, m_skelId);
|
|
Shinya Kitaoka |
120a6e |
kf.m_type = TDoubleKeyframe::Constant;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
skelIdsParam->setKeyframe(kf);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// No need to invoke PlasticTool::storeSkeletonId() - automatic through
|
|
Shinya Kitaoka |
120a6e |
// onChange()
|
|
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 |
const TDoubleParamP &skelIdsParam = sd->skeletonIdsParam();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_oldKf.m_isKeyframe)
|
|
Shinya Kitaoka |
120a6e |
skelIdsParam->setKeyframe(m_oldKf);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
skelIdsParam->deleteKeyframe(m_oldKf.m_frame);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_added1stKeyframe) {
|
|
Shinya Kitaoka |
120a6e |
const TDoubleKeyframe &kf = skelIdsParam->getKeyframe(0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(kf.m_value == skelIdsParam->getDefaultValue());
|
|
Shinya Kitaoka |
120a6e |
if (kf.m_value == skelIdsParam->getDefaultValue())
|
|
Shinya Kitaoka |
120a6e |
skelIdsParam->deleteKeyframe(kf.m_frame);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//========================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class MoveVertexUndo_Build : public TUndo {
|
|
Shinya Kitaoka |
120a6e |
int m_row, m_col; //!< Xsheet coordinates
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> m_vIdxs; //!< Moved vertices</int>
|
|
Shinya Kitaoka |
120a6e |
std::vector<tpointd> m_origVxsPos; //!< Original vertex positions</tpointd>
|
|
Shinya Kitaoka |
120a6e |
TPointD m_posShift; //!< Vertex positions shift
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
MoveVertexUndo_Build(const std::vector<int> &vIdxs,</int>
|
|
Shinya Kitaoka |
120a6e |
const std::vector<tpointd> &origVxsPos,</tpointd>
|
|
Shinya Kitaoka |
120a6e |
const TPointD &posShift)
|
|
Shinya Kitaoka |
120a6e |
: m_row(::row())
|
|
Shinya Kitaoka |
120a6e |
, m_col(::column())
|
|
Shinya Kitaoka |
120a6e |
, m_vIdxs(vIdxs)
|
|
Shinya Kitaoka |
120a6e |
, m_origVxsPos(origVxsPos)
|
|
Shinya Kitaoka |
120a6e |
, m_posShift(posShift) {
|
|
Shinya Kitaoka |
120a6e |
assert(m_vIdxs.size() == m_origVxsPos.size());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
int getSize() const override {
|
|
Shinya Kitaoka |
120a6e |
return int(sizeof(*this) +
|
|
Shinya Kitaoka |
120a6e |
m_vIdxs.size() * (sizeof(int) + 2 * sizeof(TPointD)));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void redo() const override {
|
|
Shinya Kitaoka |
120a6e |
PlasticTool::TemporaryActivation tempActivate(m_row, m_col);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
l_plasticTool.setSkeletonSelection(m_vIdxs);
|
|
Shinya Kitaoka |
120a6e |
l_plasticTool.moveVertex_build(m_origVxsPos, m_posShift);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
::stageObject()
|
|
Shinya Kitaoka |
120a6e |
->invalidate(); // Should be a TStageObject's implementation detail ...
|
|
Shinya Kitaoka |
120a6e |
l_plasticTool.invalidate();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void undo() const override {
|
|
Shinya Kitaoka |
120a6e |
PlasticTool::TemporaryActivation tempActivate(m_row, m_col);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
l_plasticTool.setSkeletonSelection(m_vIdxs);
|
|
Shinya Kitaoka |
120a6e |
l_plasticTool.moveVertex_build(m_origVxsPos, TPointD());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
::stageObject()
|
|
Shinya Kitaoka |
120a6e |
->invalidate(); // Should be a TStageObject's implementation detail ...
|
|
Shinya Kitaoka |
120a6e |
l_plasticTool.invalidate();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// PlasticTool functions
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::mouseMove_build(const TPointD &pos, const TMouseEvent &me) {
|
|
Shinya Kitaoka |
120a6e |
// Track mouse position
|
|
Shinya Kitaoka |
120a6e |
m_pos = pos; // Needs to be done now - ensures m_pos is valid
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_svHigh = m_seHigh = -1; // Reset highlighted primitives
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double d, highlightRadius = getPixelSize() * HIGHLIGHT_DISTANCE;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonP &skeleton = this->skeleton();
|
|
Shinya Kitaoka |
120a6e |
if (skeleton) {
|
|
Shinya Kitaoka |
120a6e |
// Search nearest skeleton entities
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Look for nearest vertex
|
|
Shinya Kitaoka |
120a6e |
int v = skeleton->closestVertex(pos, &d);
|
|
Shinya Kitaoka |
120a6e |
if (v >= 0 && d < highlightRadius)
|
|
Shinya Kitaoka |
120a6e |
m_svHigh = v;
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
// Look for nearest edge
|
|
Shinya Kitaoka |
120a6e |
int e = skeleton->closestEdge(pos, &d);
|
|
Shinya Kitaoka |
120a6e |
if (e >= 0 && d < highlightRadius) m_seHigh = e;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_svHigh < 0 && m_seHigh < 0) {
|
|
Shinya Kitaoka |
120a6e |
// No highlighted skeleton primitive. Mouse position may be
|
|
Shinya Kitaoka |
120a6e |
// a candidate for vertex addition - snap to mesh if required
|
|
Shinya Kitaoka |
120a6e |
if (m_snapToMesh.getValue()) {
|
|
Shinya Kitaoka |
120a6e |
const TPointD &mvPos = ::closestMeshVertexPos(
|
|
Shinya Kitaoka |
120a6e |
pos, &d); // No need to check against closest skeleton vertex,
|
|
Shinya Kitaoka |
120a6e |
// since vertex highlighting kicks in at the same time
|
|
Shinya Kitaoka |
120a6e |
if (d < highlightRadius) // the snapping would take place.
|
|
Shinya Kitaoka |
120a6e |
m_pos = mvPos;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
invalidate();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::leftButtonDown_build(const TPointD &pos,
|
|
Shinya Kitaoka |
120a6e |
const TMouseEvent &me) {
|
|
Shinya Kitaoka |
120a6e |
// Track mouse position
|
|
Shinya Kitaoka |
120a6e |
m_pressedPos = m_pos = pos;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Update selections
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonP &skel = skeleton();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_svHigh >= 0) {
|
|
Shinya Kitaoka |
120a6e |
PlasticVertexSelection vSel(
|
|
Shinya Kitaoka |
120a6e |
me.isShiftPressed()
|
|
Shinya Kitaoka |
120a6e |
? PlasticVertexSelection(branchSelection(m_svHigh))
|
|
Shinya Kitaoka |
120a6e |
: PlasticVertexSelection(m_svHigh));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (me.isCtrlPressed())
|
|
Shinya Kitaoka |
120a6e |
toggleSkeletonSelection(vSel);
|
|
Shinya Kitaoka |
120a6e |
else if (!m_svSel.contains(vSel))
|
|
Shinya Kitaoka |
120a6e |
setSkeletonSelection(vSel);
|
|
Shinya Kitaoka |
120a6e |
} else if (m_seHigh >= 0) {
|
|
Shinya Kitaoka |
120a6e |
// Insert a vertex in the edge
|
|
Shinya Kitaoka |
120a6e |
TUndo *op = new InsertVertexUndo(
|
|
Shinya Kitaoka |
120a6e |
m_seHigh, PlasticSkeletonVertex(projection(*skel, m_seHigh, m_pos)));
|
|
Shinya Kitaoka |
120a6e |
TUndoManager::manager()->add(op);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
op->redo();
|
|
Shinya Kitaoka |
120a6e |
} else if (!skel || skel->empty() || m_svSel.hasSingleObject()) {
|
|
Shinya Kitaoka |
120a6e |
// Snap to mesh if required
|
|
Shinya Kitaoka |
120a6e |
if (m_snapToMesh.getValue()) {
|
|
Shinya Kitaoka |
120a6e |
double d, highlightRadius = getPixelSize() * HIGHLIGHT_DISTANCE;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const TPointD &mvPos = ::closestMeshVertexPos(
|
|
Shinya Kitaoka |
120a6e |
pos, &d); // Again, no need to check against closest
|
|
Shinya Kitaoka |
120a6e |
// skeleton vertex.
|
|
Shinya Kitaoka |
120a6e |
if (d < highlightRadius) m_pos = mvPos;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Add a new vertex
|
|
Shinya Kitaoka |
120a6e |
TUndo *op = new AddVertexUndo(m_svSel, PlasticSkeletonVertex(m_pos));
|
|
Shinya Kitaoka |
120a6e |
TUndoManager::manager()->add(op);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
op->redo();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(skeleton());
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
setSkeletonSelection(-1);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Start move vertex operation
|
|
Shinya Kitaoka |
120a6e |
if (!m_svSel.isEmpty()) {
|
|
Shinya Kitaoka |
120a6e |
struct locals {
|
|
Shinya Kitaoka |
120a6e |
static TPointD vertexPos(const PlasticSkeleton &skel, int v) {
|
|
Shinya Kitaoka |
120a6e |
return skel.vertex(v).P();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonP &skel = skeleton();
|
|
Shinya Kitaoka |
120a6e |
assert(skel);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Adjust mouse press to the selected skeleton vertex, if necessary
|
|
Shinya Kitaoka |
120a6e |
if (m_svSel.hasSingleObject()) m_pressedPos = skel->vertex(m_svSel).P();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Store original vertex positions
|
|
Shinya Kitaoka |
120a6e |
m_pressedVxsPos = std::vector<tpointd>(</tpointd>
|
|
Shinya Kitaoka |
120a6e |
tcg::make_cast_it(m_svSel.objects().begin(),
|
|
Shinya Kitaoka |
120a6e |
tcg::bind1st(&locals::vertexPos, *skel)),
|
|
Shinya Kitaoka |
120a6e |
tcg::make_cast_it(m_svSel.objects().end(),
|
|
Shinya Kitaoka |
120a6e |
tcg::bind1st(&locals::vertexPos, *skel)));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
invalidate();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::leftButtonDrag_build(const TPointD &pos,
|
|
Shinya Kitaoka |
120a6e |
const TMouseEvent &me) {
|
|
Shinya Kitaoka |
120a6e |
// Track mouse position
|
|
Shinya Kitaoka |
120a6e |
if (m_snapToMesh.getValue()) {
|
|
Shinya Kitaoka |
120a6e |
const TPointD &mvPos = ::closestMeshVertexPos(pos),
|
|
Shinya Kitaoka |
120a6e |
&svPos = ::closestSkeletonVertexPos(mvPos);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (tcg::point_ops::dist(mvPos, svPos) >
|
|
Shinya Kitaoka |
120a6e |
getPixelSize()) // 1) If said distance is sub-pixel, the user
|
|
Shinya Kitaoka |
120a6e |
m_pos = mvPos; // just cannot see the assignment - so it's not safe.
|
|
Shinya Kitaoka |
120a6e |
} // 2) The moveVertex_build() below manipulates m_pos
|
|
Shinya Kitaoka |
120a6e |
else // (not how m_pressedPos is subtracted), so !=
|
|
Shinya Kitaoka |
120a6e |
m_pos = pos; // is not a choice.
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
moveVertex_build(m_pressedVxsPos, m_pos - m_pressedPos);
|
|
Shinya Kitaoka |
120a6e |
invalidate();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::leftButtonUp_build(const TPointD &pos,
|
|
Shinya Kitaoka |
120a6e |
const TMouseEvent &me) {
|
|
Shinya Kitaoka |
120a6e |
// Track mouse position
|
|
Shinya Kitaoka |
120a6e |
if (m_snapToMesh.getValue()) {
|
|
Shinya Kitaoka |
120a6e |
const TPointD &mvPos = ::closestMeshVertexPos(pos),
|
|
Shinya Kitaoka |
120a6e |
&svPos = ::closestSkeletonVertexPos(mvPos);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (tcg::point_ops::dist(mvPos, svPos) > getPixelSize()) // Same as above
|
|
Shinya Kitaoka |
120a6e |
m_pos = mvPos;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
m_pos = pos;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!m_svSel.isEmpty() && m_dragged) {
|
|
Shinya Kitaoka |
120a6e |
TUndoManager::manager()->add(new MoveVertexUndo_Build(
|
|
Shinya Kitaoka |
120a6e |
m_svSel.objects(), m_pressedVxsPos, m_pos - m_pressedPos));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
::stageObject()
|
|
Shinya Kitaoka |
120a6e |
->invalidate(); // Should be a TStageObject's implementation detail ...
|
|
Shinya Kitaoka |
120a6e |
invalidate(); // .. it's that it caches placement data and we must
|
|
Shinya Kitaoka |
120a6e |
} // invalidate it. Gross. Can't we do anything about it?
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::addContextMenuActions_build(QMenu *menu) {
|
|
Shinya Kitaoka |
120a6e |
bool ret = true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!m_svSel.isEmpty()) {
|
|
Shinya Kitaoka |
120a6e |
QAction *deleteVertex = menu->addAction(tr("Delete Vertex"));
|
|
Shinya Kitaoka |
120a6e |
ret = ret && connect(deleteVertex, SIGNAL(triggered()), &l_plasticTool,
|
|
Shinya Kitaoka |
120a6e |
SLOT(deleteSelectedVertex_undo()));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
menu->addSeparator();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(ret);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::moveVertex_build(const std::vector<tpointd> &origVxsPos,</tpointd>
|
|
Shinya Kitaoka |
120a6e |
const TPointD &posShift) {
|
|
Shinya Kitaoka |
120a6e |
if (!m_svSel.isEmpty()) {
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonP &skeleton = this->skeleton();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Move selected vertices
|
|
Shinya Kitaoka |
120a6e |
int v, vCount = int(m_svSel.objects().size());
|
|
Shinya Kitaoka |
120a6e |
for (v = 0; v != vCount; ++v)
|
|
Shinya Kitaoka |
120a6e |
skeleton->moveVertex(m_svSel.objects()[v], origVxsPos[v] + posShift);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Deformation must be recompiled
|
|
Shinya Kitaoka |
120a6e |
PlasticDeformerStorage::instance()->invalidateSkeleton(
|
|
Shinya Kitaoka |
120a6e |
m_sd.getPointer(), ::skeletonId(), PlasticDeformerStorage::ALL);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_mode.getIndex() == ANIMATE_IDX)
|
|
Shinya Kitaoka |
120a6e |
storeDeformation(); // Rebuild deformed skeleton - default values have
|
|
Shinya Kitaoka |
120a6e |
// changed
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::addVertex(const PlasticSkeletonVertex &vx) {
|
|
Shinya Kitaoka |
120a6e |
touchSkeleton();
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonP &skeleton = this->skeleton();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
l_suspendParamsObservation =
|
|
Shinya Kitaoka |
120a6e |
true; // Some vertex parameters change during insert
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(
|
|
Shinya Kitaoka |
120a6e |
m_svSel.isEmpty() ||
|
|
Shinya Kitaoka |
120a6e |
m_svSel
|
|
Shinya Kitaoka |
120a6e |
.hasSingleObject()); // Could there be no parent (inserting the root)
|
|
Shinya Kitaoka |
120a6e |
setSkeletonSelection(skeleton->addVertex(vx, m_svSel));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
l_suspendParamsObservation = false;
|
|
Shinya Kitaoka |
120a6e |
onChange(); // Update once after add
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// NOTE: Root addition does NOT currently add channels, so the above
|
|
Shinya Kitaoka |
120a6e |
// onChange() is
|
|
Shinya Kitaoka |
120a6e |
// quite necessary to cover that case too!
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Xsheet change notification is necessary to inform the Function Editor that
|
|
Shinya Kitaoka |
120a6e |
// new
|
|
Shinya Kitaoka |
120a6e |
// channels (the vertex deformation ones) have been introduced
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged();
|
|
Shinya Kitaoka |
120a6e |
PlasticDeformerStorage::instance()->invalidateSkeleton(
|
|
Shinya Kitaoka |
120a6e |
m_sd.getPointer(), ::skeletonId(), PlasticDeformerStorage::ALL);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::insertVertex(const PlasticSkeletonVertex &vx, int parent,
|
|
Shinya Kitaoka |
120a6e |
const std::vector<int> &children) {</int>
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonP &skeleton = this->skeleton();
|
|
Shinya Kitaoka |
120a6e |
assert(skeleton);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
l_suspendParamsObservation =
|
|
Shinya Kitaoka |
120a6e |
true; // Some vertex parameters change during insert.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
setSkeletonSelection(skeleton->insertVertex(vx, parent, children));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
l_suspendParamsObservation = false;
|
|
Shinya Kitaoka |
120a6e |
onChange(); // Update once after insertion
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged();
|
|
Shinya Kitaoka |
120a6e |
PlasticDeformerStorage::instance()->invalidateSkeleton(
|
|
Shinya Kitaoka |
120a6e |
m_sd.getPointer(), ::skeletonId(), PlasticDeformerStorage::ALL);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::insertVertex(const PlasticSkeletonVertex &vx, int e) {
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonP &skeleton = this->skeleton();
|
|
Shinya Kitaoka |
120a6e |
assert(skeleton);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeleton::edge_type &ed = skeleton->edge(e);
|
|
Shinya Kitaoka |
120a6e |
insertVertex(vx, ed.vertex(0),
|
|
Shinya Kitaoka |
120a6e |
std::vector<int>(1, skeleton->edge(e).vertex(1)));</int>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::removeVertex() {
|
|
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 |
l_suspendParamsObservation =
|
|
Shinya Kitaoka |
120a6e |
true; // Some vertex parameters change during removal.
|
|
Shinya Kitaoka |
120a6e |
// We need to avoid updating WHILE removing.
|
|
Shinya Kitaoka |
120a6e |
skeleton->removeVertex(m_svSel);
|
|
Shinya Kitaoka |
120a6e |
PlasticDeformerStorage::instance()->invalidateSkeleton(
|
|
Shinya Kitaoka |
120a6e |
m_sd.getPointer(), ::skeletonId(), PlasticDeformerStorage::ALL);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
l_suspendParamsObservation = false;
|
|
Shinya Kitaoka |
120a6e |
onChange();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
clearSkeletonSelections(); // Remove mesh references - could be
|
|
Shinya Kitaoka |
120a6e |
// invalidated...
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Xsheet change notification is necessary to inform the Function Editor that
|
|
Shinya Kitaoka |
120a6e |
// some
|
|
Shinya Kitaoka |
120a6e |
// channels (the vertex deformation ones) have been removed
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()
|
|
Shinya Kitaoka |
120a6e |
->getCurrentXsheet()
|
|
Shinya Kitaoka |
120a6e |
->notifyXsheetChanged(); // NOTE: This COULD invoke invalidate()...
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Rebuild the stage object's keyframes table
|
|
Shinya Kitaoka |
120a6e |
stageObject()->updateKeyframes();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int PlasticTool::addSkeleton(const PlasticSkeletonP &skeleton) {
|
|
Shinya Kitaoka |
120a6e |
assert(TTool::isEnabled());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
touchDeformation();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int skelId;
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if (m_sd->empty())
|
|
Shinya Kitaoka |
120a6e |
skelId = 1;
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
// Get the first unused skeleton id in m_sd
|
|
Shinya Kitaoka |
120a6e |
SkD::skelId_iterator st, sEnd;
|
|
Shinya Kitaoka |
120a6e |
m_sd->skeletonIds(st, sEnd);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (skelId = 1; st != sEnd && skelId == *st; ++skelId, ++st)
|
|
Shinya Kitaoka |
120a6e |
;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
addSkeleton(skelId, skeleton);
|
|
Shinya Kitaoka |
120a6e |
return skelId;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::addSkeleton(int skelId, const PlasticSkeletonP &skeleton) {
|
|
Shinya Kitaoka |
120a6e |
assert(TTool::isEnabled());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
touchDeformation();
|
|
Shinya Kitaoka |
120a6e |
m_sd->attach(skelId, skeleton.getPointer());
|
|
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::removeSkeleton(int skelId) {
|
|
Shinya Kitaoka |
120a6e |
// Remove the entire deformation
|
|
Shinya Kitaoka |
120a6e |
clearSkeletonSelections();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_sd) {
|
|
Shinya Kitaoka |
120a6e |
m_sd->detach(skelId);
|
|
Shinya Kitaoka |
120a6e |
if (m_sd->empty())
|
|
Shinya Kitaoka |
120a6e |
stageObject()->setPlasticSkeletonDeformation(
|
|
Shinya Kitaoka |
120a6e |
PlasticSkeletonDeformationP());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
::invalidateXsheet(); // Updates m_sd
|
|
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::deleteSelectedVertex_undo() {
|
|
Shinya Kitaoka |
120a6e |
if (m_svSel.isEmpty()) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TUndoManager *manager = TUndoManager::manager();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_svSel.contains(0)) {
|
|
Shinya Kitaoka |
120a6e |
TUndo *op = new RemoveSkeletonUndo(::skeletonId());
|
|
Shinya Kitaoka |
120a6e |
manager->add(op);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
op->redo();
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
typedef PlasticVertexSelection::objects_container objects_container;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
objects_container vertexIdxs =
|
|
Shinya Kitaoka |
120a6e |
m_svSel.objects(); // Each undo will reset the vertex selection,
|
|
Shinya Kitaoka |
120a6e |
// so we need a copy
|
|
Shinya Kitaoka |
120a6e |
manager->beginBlock();
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
objects_container::const_iterator vit, viEnd = vertexIdxs.end();
|
|
Shinya Kitaoka |
120a6e |
for (vit = vertexIdxs.begin(); vit != viEnd; ++vit) {
|
|
Shinya Kitaoka |
120a6e |
TUndo *op = new RemoveVertexUndo(*vit);
|
|
Shinya Kitaoka |
120a6e |
manager->add(op);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
op->redo();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
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 |
int PlasticTool::addSkeleton_undo(const PlasticSkeletonP &skeleton) {
|
|
Shinya Kitaoka |
120a6e |
int skelId;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TUndoManager *manager = TUndoManager::manager();
|
|
Shinya Kitaoka |
120a6e |
manager->beginBlock();
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
skelId = l_plasticTool.addSkeleton(skeleton);
|
|
Shinya Kitaoka |
120a6e |
assert(l_plasticTool.deformation());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TUndo *addUndo =
|
|
Shinya Kitaoka |
120a6e |
new AddSkeletonUndo(skelId, new PlasticSkeleton(*skeleton));
|
|
Shinya Kitaoka |
120a6e |
manager->add(addUndo);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TUndo *setIdUndo = new SetSkeletonIdUndo(skelId);
|
|
Shinya Kitaoka |
120a6e |
manager->add(setIdUndo);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
setIdUndo->redo();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
manager->endBlock();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
::invalidateXsheet();
|
|
Shinya Kitaoka |
120a6e |
return skelId;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::addSkeleton_undo(int skelId,
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonP &skeleton) {
|
|
Shinya Kitaoka |
120a6e |
TUndoManager *manager = TUndoManager::manager();
|
|
Shinya Kitaoka |
120a6e |
manager->beginBlock();
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
l_plasticTool.addSkeleton(skelId, skeleton);
|
|
Shinya Kitaoka |
120a6e |
assert(l_plasticTool.deformation());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TUndo *addUndo =
|
|
Shinya Kitaoka |
120a6e |
new AddSkeletonUndo(skelId, new PlasticSkeleton(*skeleton));
|
|
Shinya Kitaoka |
120a6e |
manager->add(addUndo);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TUndo *setIdUndo = new SetSkeletonIdUndo(skelId);
|
|
Shinya Kitaoka |
120a6e |
manager->add(setIdUndo);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
setIdUndo->redo();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
manager->endBlock();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
::invalidateXsheet();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::removeSkeleton_undo(int skelId) {
|
|
Shinya Kitaoka |
120a6e |
TUndo *op = new RemoveSkeletonUndo(skelId);
|
|
Shinya Kitaoka |
120a6e |
TUndoManager::manager()->add(op);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
op->redo();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::removeSkeleton_withKeyframes_undo(int skelId) {
|
|
Shinya Kitaoka |
120a6e |
TUndo *op = new RemoveSkeletonUndo_WithKeyframes(skelId);
|
|
Shinya Kitaoka |
120a6e |
TUndoManager::manager()->add(op);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
op->redo();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::editSkelId_undo(int skelId) {
|
|
Shinya Kitaoka |
120a6e |
TUndo *op = new SetSkeletonIdUndo(skelId);
|
|
Shinya Kitaoka |
120a6e |
TUndoManager::manager()->add(op);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
op->redo();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticTool::draw_build() {
|
|
Shinya Kitaoka |
120a6e |
double pixelSize = getPixelSize();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Draw original skeleton
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonP &skeleton = this->skeleton();
|
|
Shinya Kitaoka |
120a6e |
if (skeleton) {
|
|
Shinya Kitaoka |
120a6e |
drawOnionSkinSkeletons_build(pixelSize);
|
|
Shinya Kitaoka |
120a6e |
drawSkeleton(*skeleton, pixelSize);
|
|
Shinya Kitaoka |
120a6e |
drawSelections(m_sd, *skeleton, pixelSize);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
drawHighlights(m_sd, skeleton.getPointer(), pixelSize);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!skeleton || skeleton->vertices().empty() ||
|
|
Shinya Kitaoka |
120a6e |
(m_svSel.hasSingleObject() && m_svHigh < 0 && m_seHigh < 0)) {
|
|
Shinya Kitaoka |
120a6e |
// Draw a handle at current mouse pos (will add a vertex)
|
|
Shinya Kitaoka |
120a6e |
drawSquare(m_pos, HANDLE_SIZE * pixelSize);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|