Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tundo.h"
Toshihiro Shimizu 890ddd
#include "tgl.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/tframehandle.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// tcg includes
Toshihiro Shimizu 890ddd
#include "tcg/tcg_point_ops.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// boost includes
Toshihiro Shimizu 890ddd
#include <boost noncopyable.hpp=""></boost>
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
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
enum { RIGID_IDX = 0,
Toshihiro Shimizu 890ddd
	   FLEX_IDX };
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
//    Undo  definitions
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class PaintRigidityUndo : public TUndo
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TXshCell m_cell;							   //!< Affected image (cell == level + frame)
Toshihiro Shimizu 890ddd
	std::vector<std::map<int, double="">> m_vertices; //!< Affected vertices</std::map<int,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double m_paintValue; //!< Rigidity value the vertices were
Toshihiro Shimizu 890ddd
						 //!< painted with
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	PaintRigidityUndo(const TXshCell &cell,
Toshihiro Shimizu 890ddd
					  const std::vector<std::map<int, double="">> &vertices,</std::map<int,>
Toshihiro Shimizu 890ddd
					  double paintValue)
Toshihiro Shimizu 890ddd
		: m_cell(cell), m_vertices(vertices), m_paintValue(paintValue) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getSize() const { return 1 << 20; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void redo() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		TXshSimpleLevel *sl = static_cast<txshsimplelevel *="">(m_cell.m_level.getPointer());</txshsimplelevel>
Toshihiro Shimizu 890ddd
		sl->setDirtyFlag(true);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TMeshImageP mi(sl->getFrame(m_cell.m_frameId, true));
Toshihiro Shimizu 890ddd
		if (!mi || mi->meshes().size() != m_vertices.size())
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int m, mCount = int(mi->meshes().size());
Toshihiro Shimizu 890ddd
		for (m = 0; m != mCount; ++m) {
Toshihiro Shimizu 890ddd
			TTextureMesh &mesh = *mi->meshes()[m];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			std::map<int, double="">::const_iterator vt, vEnd(m_vertices[m].end());</int,>
Toshihiro Shimizu 890ddd
			for (vt = m_vertices[m].begin(); vt != vEnd; ++vt)
Toshihiro Shimizu 890ddd
				mesh.vertex(vt->first).P().rigidity = m_paintValue;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		PlasticDeformerStorage::instance()->invalidateMeshImage(
Toshihiro Shimizu 890ddd
			mi.getPointer(), PlasticDeformerStorage::MESH);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void undo() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		TXshSimpleLevel *sl = static_cast<txshsimplelevel *="">(m_cell.m_level.getPointer());</txshsimplelevel>
Toshihiro Shimizu 890ddd
		sl->setDirtyFlag(true);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TMeshImageP mi(sl->getFrame(m_cell.m_frameId, true));
Toshihiro Shimizu 890ddd
		if (!mi || mi->meshes().size() != m_vertices.size())
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int m, mCount = int(mi->meshes().size());
Toshihiro Shimizu 890ddd
		for (m = 0; m != mCount; ++m) {
Toshihiro Shimizu 890ddd
			TTextureMesh &mesh = *mi->meshes()[m];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			std::map<int, double="">::const_iterator vt, vEnd(m_vertices[m].end());</int,>
Toshihiro Shimizu 890ddd
			for (vt = m_vertices[m].begin(); vt != vEnd; ++vt)
Toshihiro Shimizu 890ddd
				mesh.vertex(vt->first).P().rigidity = vt->second;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		PlasticDeformerStorage::instance()->invalidateMeshImage(
Toshihiro Shimizu 890ddd
			mi.getPointer(), PlasticDeformerStorage::MESH);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
//    RigidityPainter  definition
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class RigidityPainter : public tcg::polymorphic
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	std::vector<std::map<int, double="">> m_oldRigidities; //!< The original values of painted vertices</std::map<int,>
Toshihiro Shimizu 890ddd
	double m_sqRadius, m_value;							//!< Drawing parameters
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	RigidityPainter() : m_sqRadius(), m_value() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void startPainting(double radius, int rigidIdx);
Toshihiro Shimizu 890ddd
	void paint(const TPointD &pos);
Toshihiro Shimizu 890ddd
	void commit();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	void reset()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_sqRadius = 0.0, m_value = 0.0;
Toshihiro Shimizu 890ddd
		std::vector<std::map<int, double="">>().swap(m_oldRigidities);</std::map<int,>
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RigidityPainter::startPainting(double radius, int rigidIdx)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_sqRadius = sq(radius);
Toshihiro Shimizu 890ddd
	m_value = (rigidIdx == RIGID_IDX) ? 1e4 : 1.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(m_oldRigidities.empty());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RigidityPainter::paint(const TPointD &pos)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const TXshCell &cell = ::xshCell();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshSimpleLevel *sl = dynamic_cast<txshsimplelevel *="">(cell.m_level.getPointer());</txshsimplelevel>
Toshihiro Shimizu 890ddd
	if (!sl)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TMeshImageP meshImg = TTool::getImage(true);
Toshihiro Shimizu 890ddd
	if (!meshImg)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Soil the level - schedules it for save
Toshihiro Shimizu 890ddd
	sl->setDirtyFlag(true);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Paint all mesh vertices inside the circle with center pos and given radius
Toshihiro Shimizu 890ddd
	const std::vector<ttexturemeshp> &meshes = meshImg->meshes();</ttexturemeshp>
Toshihiro Shimizu 890ddd
	int m, mCount = int(meshImg->meshes().size());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_oldRigidities.resize(mCount);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (m = 0; m != mCount; ++m) {
Toshihiro Shimizu 890ddd
		TTextureMesh &mesh = *meshes[m];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int v, vCount = mesh.verticesCount();
Toshihiro Shimizu 890ddd
		for (v = 0; v != vCount; ++v) {
Toshihiro Shimizu 890ddd
			RigidPoint &vxPos = mesh.vertex(v).P();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (tcg::point_ops::dist2(pos, (const TPointD &)vxPos) < m_sqRadius) {
Toshihiro Shimizu 890ddd
				if (!m_oldRigidities[m].count(v))
Toshihiro Shimizu 890ddd
					m_oldRigidities[m][v] = vxPos.rigidity;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				vxPos.rigidity = m_value;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	PlasticDeformerStorage::instance()->invalidateMeshImage(
Toshihiro Shimizu 890ddd
		meshImg.getPointer(), PlasticDeformerStorage::MESH);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RigidityPainter::commit()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TUndoManager::manager()->add(new PaintRigidityUndo(::xshCell(), m_oldRigidities, m_value));
Toshihiro Shimizu 890ddd
	reset();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
//    PlasticTool  functions
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
std::auto_ptr<tcg::polymorphic> PlasticTool::createRigidityPainter()</tcg::polymorphic>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return std::auto_ptr<tcg::polymorphic>(new RigidityPainter);</tcg::polymorphic>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticTool::mouseMove_rigidity(const TPointD &pos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	// Track mouse position
Toshihiro Shimizu 890ddd
	m_pos = pos; // Needs to be done now - ensures m_pos is valid
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticTool::leftButtonDown_rigidity(const TPointD &pos, const TMouseEvent &)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	// Track mouse position
Toshihiro Shimizu 890ddd
	m_pressedPos = m_pos = pos;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	RigidityPainter *painter = static_cast<rigiditypainter *="">(m_rigidityPainter.get());</rigiditypainter>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	painter->startPainting(m_thickness.getValue(), m_rigidValue.getIndex());
Toshihiro Shimizu 890ddd
	painter->paint(m_pos);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticTool::leftButtonDrag_rigidity(const TPointD &pos, const TMouseEvent &)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	// Track mouse position
Toshihiro Shimizu 890ddd
	m_pos = pos;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	RigidityPainter *painter = static_cast<rigiditypainter *="">(m_rigidityPainter.get());</rigiditypainter>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	painter->paint(m_pos);
Toshihiro Shimizu 890ddd
	invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticTool::leftButtonUp_rigidity(const TPointD &pos, const TMouseEvent &)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	// Track mouse position
Toshihiro Shimizu 890ddd
	m_pos = pos;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	RigidityPainter *painter = static_cast<rigiditypainter *="">(m_rigidityPainter.get());</rigiditypainter>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	painter->commit();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticTool::addContextMenuActions_rigidity(QMenu *menu)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticTool::draw_rigidity()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (TTool::getApplication()->getCurrentFrame()->isEditingScene()) {
Toshihiro Shimizu 890ddd
		// In the rigidity case, we're editing the mesh level - so the implicit
Toshihiro Shimizu 890ddd
		// transformation affine loaded by OpenGL gets multiplied by the level's
Toshihiro Shimizu 890ddd
		// dpi scale. We have to revert the scale before showing column-related data.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		const TPointD &dpiScale = TTool::getViewer()->getDpiScale();
Toshihiro Shimizu 890ddd
		glPushMatrix();
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			tglMultMatrix(TScale(1.0 / dpiScale.x, 1.0 / dpiScale.y));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			double pixelSize = sqrt(tglGetPixelSize2());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			// Draw original skeleton
Toshihiro Shimizu 890ddd
			const PlasticSkeletonP &skeleton = this->skeleton();
Toshihiro Shimizu 890ddd
			if (skeleton) {
Toshihiro Shimizu 890ddd
				drawOnionSkinSkeletons_build(pixelSize);
Toshihiro Shimizu 890ddd
				drawSkeleton(*skeleton, pixelSize);
Toshihiro Shimizu 890ddd
				drawSelections(m_sd, *skeleton, pixelSize);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		glPopMatrix();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Draw a circle centered at m_pos with m_thickness radius
Toshihiro Shimizu 890ddd
	glColor3f(1.0f, 0.0f, 0.0f); // Red
Toshihiro Shimizu 890ddd
	tglDrawCircle(m_pos, m_thickness.getValue());
Toshihiro Shimizu 890ddd
}