Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tstream.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzBase includes
Toshihiro Shimizu 890ddd
#include "tdoublekeyframe.h"
Toshihiro Shimizu 890ddd
#include "tparamchange.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
// tcg includes
Toshihiro Shimizu 890ddd
#include "tcg/tcg_misc.h"
Toshihiro Shimizu 890ddd
#include "tcg/tcg_function_types.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// STL includes
Toshihiro Shimizu 890ddd
#include <memory></memory>
Toshihiro Shimizu 890ddd
#include <set></set>
Toshihiro Shimizu 890ddd
#include <map></map>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Boost includes
Toshihiro Shimizu 890ddd
#include <boost bimap.hpp=""></boost>
Toshihiro Shimizu 890ddd
#include <boost multi_index_container.hpp=""></boost>
Toshihiro Shimizu 890ddd
#include <boost multi_index="" ordered_index.hpp=""></boost>
Toshihiro Shimizu 890ddd
#include <boost member.hpp="" multi_index=""></boost>
Toshihiro Shimizu 890ddd
#include <boost iterator="" transform_iterator.hpp=""></boost>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "ext/plasticskeletondeformation.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
PERSIST_IDENTIFIER(PlasticSkeletonVertexDeformation, "PlasticSkeletonVertexDeformation")
Toshihiro Shimizu 890ddd
PERSIST_IDENTIFIER(PlasticSkeletonDeformation, "PlasticSkeletonDeformation")
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DEFINE_CLASS_CODE(PlasticSkeletonDeformation, 121)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//**************************************************************************************
Toshihiro Shimizu 890ddd
//    Boost-related  stuff
Toshihiro Shimizu 890ddd
//**************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace boost::multi_index;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef boost::bimap<int, plasticskeletonp=""> SkeletonSet;</int,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//======================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct VDKey {
Toshihiro Shimizu 890ddd
	QString m_name;
Toshihiro Shimizu 890ddd
	int m_hookNumber;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	mutable std::map<int, int=""> m_vIndices; //!< Skeleton index to Vertex index map</int,>
Toshihiro Shimizu 890ddd
	mutable SkVD m_vd;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef boost::multi_index_container
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
												ordered_unique<tag<qstring>, member<vdkey, &vdkey::m_name="" qstring,="">>,</vdkey,></tag<qstring>
Toshihiro Shimizu 890ddd
												ordered_unique<tag<int>, member<vdkey, &vdkey::m_hooknumber="" int,="">></vdkey,></tag<int>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
												>> SkVDSet;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef SkVDSet::index<int>::type SkVDByHookNumber;</int>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//**************************************************************************************
Toshihiro Shimizu 890ddd
//    Local  namespace
Toshihiro Shimizu 890ddd
//**************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static const char *parNames[SkVD::PARAMS_COUNT] = {"Angle", "Distance", "SO"};
Toshihiro Shimizu 890ddd
static const char *parMeasures[SkVD::PARAMS_COUNT] = {"angle", "fxLength", ""};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Extract the angle between edges vParent->v and vGrandParent->vParent
Toshihiro Shimizu 890ddd
double buildAngle(const PlasticSkeleton &skeleton, int v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const PlasticSkeletonVertex &vx = skeleton.vertex(v);
Toshihiro Shimizu 890ddd
	int vParent = vx.parent();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(vx.parent() >= 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const PlasticSkeletonVertex &vxParent = skeleton.vertex(vParent);
Toshihiro Shimizu 890ddd
	int vGrandParent = vxParent.parent();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Build reference orientation
Toshihiro Shimizu 890ddd
	TPointD dir(1.0, 0.0); // Standard horizontal axis if no grandParent
Toshihiro Shimizu 890ddd
	if (vGrandParent >= 0) {
Toshihiro Shimizu 890ddd
		// Relative orientation
Toshihiro Shimizu 890ddd
		const PlasticSkeletonVertex &vxGrandParent = skeleton.vertex(vGrandParent);
Toshihiro Shimizu 890ddd
		dir = vxParent.P() - vxGrandParent.P();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return tcg::consts::rad_to_deg * tcg::point_ops::angle(dir, vx.P() - vxParent.P());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//**************************************************************************************
Toshihiro Shimizu 890ddd
//    PlasticSkeletonVertex  implementation
Toshihiro Shimizu 890ddd
//**************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
SkVD::Keyframe SkVD::getKeyframe(double frame) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	Keyframe kf;
Toshihiro Shimizu 890ddd
	for (int p = 0; p < PARAMS_COUNT; ++p)
Toshihiro Shimizu 890ddd
		kf.m_keyframes[p] = m_params[p]->getKeyframeAt(frame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return kf;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void SkVD::setKeyframe(double frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	for (int p = 0; p < PARAMS_COUNT; ++p)
Toshihiro Shimizu 890ddd
		m_params[p]->setKeyframe(m_params[p]->getKeyframeAt(frame));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool SkVD::setKeyframe(const SkVD::Keyframe &values)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	bool keyWasSet = false;
Toshihiro Shimizu 890ddd
	for (int p = 0; p < PARAMS_COUNT; ++p)
Toshihiro Shimizu 890ddd
		if (values.m_keyframes[p].m_isKeyframe) {
Toshihiro Shimizu 890ddd
			m_params[p]->setKeyframe(values.m_keyframes[p]);
Toshihiro Shimizu 890ddd
			keyWasSet = true;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return keyWasSet;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool SkVD::setKeyframe(
Toshihiro Shimizu 890ddd
	const SkVD::Keyframe &values, double frame, double easeIn, double easeOut)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	bool keyWasSet = false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (int p = 0; p < PARAMS_COUNT; ++p)
Toshihiro Shimizu 890ddd
		if (values.m_keyframes[p].m_isKeyframe) {
Toshihiro Shimizu 890ddd
			TDoubleKeyframe kf(values.m_keyframes[p]);
Toshihiro Shimizu 890ddd
			kf.m_frame = frame;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (easeIn >= 0.0)
Toshihiro Shimizu 890ddd
				kf.m_speedIn = TPointD(-easeIn, kf.m_speedIn.y);
Toshihiro Shimizu 890ddd
			if (easeOut >= 0.0)
Toshihiro Shimizu 890ddd
				kf.m_speedOut = TPointD(easeOut, kf.m_speedOut.y);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			m_params[p]->setKeyframe(kf);
Toshihiro Shimizu 890ddd
			keyWasSet = true;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return keyWasSet;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool SkVD::isKeyframe(double frame) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	for (int p = 0; p < PARAMS_COUNT; ++p)
Toshihiro Shimizu 890ddd
		if (m_params[p]->isKeyframe(frame))
Toshihiro Shimizu 890ddd
			return true;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool SkVD::isFullKeyframe(double frame) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	for (int p = 0; p < PARAMS_COUNT; ++p)
Toshihiro Shimizu 890ddd
		if (!m_params[p]->isKeyframe(frame))
Toshihiro Shimizu 890ddd
			return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void SkVD::deleteKeyframe(double frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	for (int p = 0; p < PARAMS_COUNT; ++p)
Toshihiro Shimizu 890ddd
		m_params[p]->deleteKeyframe(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void SkVD::saveData(TOStream &os)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	for (int p = 0; p < PARAMS_COUNT; ++p)
Toshihiro Shimizu 890ddd
		if (!m_params[p]->isDefault())
Toshihiro Shimizu 890ddd
			os.child(::parNames[p]) << *m_params[p];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void SkVD::loadData(TIStream &is)
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 3bfa54
	std::string tagName;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	while (is.matchTag(tagName)) {
Toshihiro Shimizu 890ddd
		int p;
Toshihiro Shimizu 890ddd
		for (p = 0; p < PARAMS_COUNT; ++p) {
Toshihiro Shimizu 890ddd
			if (tagName == parNames[p]) {
Toshihiro Shimizu 890ddd
				is >> *m_params[p], is.matchEndTag();
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (p >= PARAMS_COUNT)
Toshihiro Shimizu 890ddd
			is.skipCurrentTag();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//**************************************************************************************
Toshihiro Shimizu 890ddd
//    PlasticSkeletonDeformation::Imp  definition
Toshihiro Shimizu 890ddd
//**************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class PlasticSkeletonDeformation::Imp : public TParamObserver
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	PlasticSkeletonDeformation *m_back; //!< Back-pointer to the interface class
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	SkeletonSet m_skeletons; //!< Skeletons owned by the deformation
Toshihiro Shimizu 890ddd
	SkVDSet m_vds;			 //!< Container of vertex deformations
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TDoubleParamP m_skelIdsParam; //!< Curve of skeleton ids by xsheet frame
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::set<tparamobserver *=""> m_observers; //!< Set of the deformation's observers</tparamobserver>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TSyntax::Grammar *m_grammar; //!< The params' grammar. Weird though - it's a VERY
Toshihiro Shimizu 890ddd
								 //!< occult requirement to TDoubleParams...
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// NOTE: There \a is a deformation even for a skeleton's root node. This is now required due to the
Toshihiro Shimizu 890ddd
	// onwership of \a multiple skeletons at once. However, its angle and distance params will be unused.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	Imp(PlasticSkeletonDeformation *back);
Toshihiro Shimizu 890ddd
	~Imp();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Imp(PlasticSkeletonDeformation *back, const Imp &other);
Toshihiro Shimizu 890ddd
	Imp &operator=(const Imp &other);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	PlasticSkeleton &skeleton(int skelId) const;
Toshihiro Shimizu 890ddd
	SkVD &vertexDeformation(const QString &name) const;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void attach(int skeletonId, PlasticSkeleton *skeleton);
Toshihiro Shimizu 890ddd
	void detach(int skeletonId);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void attachVertex(const QString &name, int skelId, int v);
Toshihiro Shimizu 890ddd
	void detachVertex(const QString &name, int skelId, int v);
Toshihiro Shimizu 890ddd
	void rebindVertex(const QString &name, int skelId, const QString &newName);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void touchParams(SkVD &vd);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//! Applies stored vertex deformations to the skeleton branch starting at v
Toshihiro Shimizu 890ddd
	void updateBranchPositions(
Toshihiro Shimizu 890ddd
		const PlasticSkeleton &originalSkeleton, PlasticSkeleton &deformedSkeleton,
Toshihiro Shimizu 890ddd
		double frame, int v);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void onChange(const TParamChange &change); // Passes param notifications to external observers
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	// Not directly copy-constructible
Toshihiro Shimizu 890ddd
	Imp(const Imp &other);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
PlasticSkeletonDeformation::Imp::Imp(PlasticSkeletonDeformation *back)
Toshihiro Shimizu 890ddd
	: m_back(back), m_skelIdsParam(1.0), m_grammar()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_skelIdsParam->setName("Skeleton Id");
Toshihiro Shimizu 890ddd
	m_skelIdsParam->addObserver(this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
PlasticSkeletonDeformation::Imp::~Imp()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_skelIdsParam->removeObserver(this);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	SkVDSet::iterator dt, dEnd(m_vds.end());
Toshihiro Shimizu 890ddd
	for (dt = m_vds.begin(); dt != dEnd; ++dt)
Toshihiro Shimizu 890ddd
		for (int p = 0; p < SkVD::PARAMS_COUNT; ++p)
Toshihiro Shimizu 890ddd
			dt->m_vd.m_params[p]->removeObserver(this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
PlasticSkeletonDeformation::Imp::Imp(PlasticSkeletonDeformation *back, const Imp &other)
Toshihiro Shimizu 890ddd
	: m_back(back), m_skelIdsParam(other.m_skelIdsParam->clone()), m_grammar()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_skelIdsParam->setGrammar(m_grammar);
Toshihiro Shimizu 890ddd
	m_skelIdsParam->addObserver(this);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Clone the skeletons
Toshihiro Shimizu 890ddd
	SkeletonSet::const_iterator st, sEnd(other.m_skeletons.end());
Toshihiro Shimizu 890ddd
	for (st = other.m_skeletons.begin(); st != sEnd; ++st)
Toshihiro Shimizu 890ddd
		m_skeletons.insert(SkeletonSet::value_type(
Toshihiro Shimizu 890ddd
			st->get_left(), new PlasticSkeleton(*st->get_right())));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Clone each parameters curve
Toshihiro Shimizu 890ddd
	SkVD vd;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	SkVDSet::const_iterator dt, dEnd(other.m_vds.end());
Toshihiro Shimizu 890ddd
	for (dt = other.m_vds.begin(); dt != dEnd; ++dt) {
Toshihiro Shimizu 890ddd
		VDKey vdKey = {dt->m_name, dt->m_hookNumber, dt->m_vIndices};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (int p = 0; p < SkVD::PARAMS_COUNT; ++p) {
Toshihiro Shimizu 890ddd
			TDoubleParamP ¶m = vdKey.m_vd.m_params[p];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			param = TDoubleParamP(dt->m_vd.m_params[p]->clone());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			param->setGrammar(m_grammar);
Toshihiro Shimizu 890ddd
			param->addObserver(this);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_vds.insert(vdKey);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
PlasticSkeletonDeformation::Imp &PlasticSkeletonDeformation::Imp::operator=(const Imp &other)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	*m_skelIdsParam = *other.m_skelIdsParam;
Toshihiro Shimizu 890ddd
	m_skelIdsParam->setGrammar(m_grammar);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Take in all curves whose name matches one of the stored ones
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Traverse known curves
Toshihiro Shimizu 890ddd
	SkVDSet::iterator dt, dEnd(m_vds.end());
Toshihiro Shimizu 890ddd
	SkVDSet::const_iterator st, sEnd(other.m_vds.end());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (dt = m_vds.begin(); dt != dEnd; ++dt) {
Toshihiro Shimizu 890ddd
		// Search a corresponding curve in the input ones
Toshihiro Shimizu 890ddd
		st = other.m_vds.find(dt->m_name);
Toshihiro Shimizu 890ddd
		if (st != sEnd)
Toshihiro Shimizu 890ddd
			for (int p = 0; p < SkVD::PARAMS_COUNT; ++p) {
Toshihiro Shimizu 890ddd
				TDoubleParam ¶m = *dt->m_vd.m_params[p];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				param = *st->m_vd.m_params[p];
Toshihiro Shimizu 890ddd
				param.setGrammar(m_grammar);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
PlasticSkeleton &PlasticSkeletonDeformation::Imp::skeleton(int skelId) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	SkeletonSet::left_map::const_iterator st(m_skeletons.left.find(skelId));
Toshihiro Shimizu 890ddd
	assert(st != m_skeletons.left.end());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return *st->second;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
SkVD &PlasticSkeletonDeformation::Imp::vertexDeformation(const QString &name) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	SkVDSet::const_iterator vdt(m_vds.find(name));
Toshihiro Shimizu 890ddd
	assert(vdt != m_vds.end());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return vdt->m_vd;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::Imp::attach(int skeletonId, PlasticSkeleton *skeleton)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(skeleton);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Store the skeleton - acquires shared ownership
Toshihiro Shimizu 890ddd
	assert(m_skeletons.left.find(skeletonId) == m_skeletons.left.end());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_skeletons.insert(SkeletonSet::value_type(skeletonId, skeleton));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Deal with vertex deformations and parameter defaults
Toshihiro Shimizu 890ddd
	tcg::list<plasticskeleton::vertex_type> &vertices = skeleton->vertices();</plasticskeleton::vertex_type>
Toshihiro Shimizu 890ddd
	if (!vertices.empty()) {
Toshihiro Shimizu 890ddd
		tcg::list<plasticskeletonvertex>::iterator vt, vEnd(vertices.end());</plasticskeletonvertex>
Toshihiro Shimizu 890ddd
		for (vt = vertices.begin(); vt != vEnd; ++vt)
Toshihiro Shimizu 890ddd
			attachVertex(vt->name(), skeletonId, vt.index());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::Imp::detach(int skeletonId)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	// First, detach all vertices
Toshihiro Shimizu 890ddd
	tcg::list<plasticskeleton::vertex_type> &vertices = skeleton(skeletonId).vertices();</plasticskeleton::vertex_type>
Toshihiro Shimizu 890ddd
	if (!vertices.empty()) {
Toshihiro Shimizu 890ddd
		tcg::list<plasticskeletonvertex>::iterator vt, vEnd(vertices.end());</plasticskeletonvertex>
Toshihiro Shimizu 890ddd
		for (vt = vertices.begin(); vt != vEnd; ++vt)
Toshihiro Shimizu 890ddd
			detachVertex(vt->name(), skeletonId, vt.index());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Then, release the skeleton itself
Toshihiro Shimizu 890ddd
	m_skeletons.left.erase(skeletonId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::Imp::attachVertex(const QString &name, int skelId, int v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	struct locals {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		static int newHookNumber(Imp *imp)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			int h = 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			SkVDByHookNumber::iterator vdt, vdEnd(imp->m_vds.get<int>().end());</int>
Toshihiro Shimizu 890ddd
			for (vdt = imp->m_vds.get<int>().begin(); vdt != vdEnd && vdt->m_hookNumber == h; ++vdt, ++h)</int>
Toshihiro Shimizu 890ddd
				;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			return h;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	}; // locals
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Insert a new VD if necessary
Toshihiro Shimizu 890ddd
	SkVDSet::iterator vdt(m_vds.find(name));
Toshihiro Shimizu 890ddd
	if (vdt == m_vds.end()) {
Toshihiro Shimizu 890ddd
		VDKey vdKey = {name, locals::newHookNumber(this)};
Toshihiro Shimizu 890ddd
		touchParams(vdKey.m_vd);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		vdt = m_vds.insert(vdKey).first;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Register (skelId, v) on the vd
Toshihiro Shimizu 890ddd
	vdt->m_vIndices.insert(std::make_pair(skelId, v));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::Imp::detachVertex(const QString &name, int skelId, int v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	SkVDSet::iterator vdt = m_vds.find(name);
Toshihiro Shimizu 890ddd
	assert(vdt != m_vds.end());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Unregister skelId
Toshihiro Shimizu 890ddd
	int count = vdt->m_vIndices.erase(skelId);
Toshihiro Shimizu 890ddd
	assert(count > 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (vdt->m_vIndices.empty()) {
Toshihiro Shimizu 890ddd
		// De-register as vdt's observer, and release it from stored vds
Toshihiro Shimizu 890ddd
		SkVD &vd = vdt->m_vd;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (int p = 0; p < SkVD::PARAMS_COUNT; ++p)
Toshihiro Shimizu 890ddd
			vd.m_params[p]->removeObserver(this);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_vds.erase(vdt);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::Imp::rebindVertex(
Toshihiro Shimizu 890ddd
	const QString &name, int skelId, const QString &newName)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (name == newName)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	SkVDSet::iterator oldVdt = m_vds.find(name);
Toshihiro Shimizu 890ddd
	if (oldVdt == m_vds.end())
Toshihiro Shimizu 890ddd
		return; // We get here when creating a new vertex
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::map<int, int="">::iterator vit = oldVdt->m_vIndices.find(skelId);</int,>
Toshihiro Shimizu 890ddd
	assert(vit != oldVdt->m_vIndices.end());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int v = vit->second;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	SkVDSet::iterator newVdt = m_vds.find(newName);
Toshihiro Shimizu 890ddd
	if (newVdt != m_vds.end()) {
Toshihiro Shimizu 890ddd
		detachVertex(name, skelId, v);
Toshihiro Shimizu 890ddd
		attachVertex(newName, skelId, v);
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		// Creating a new vd entry
Toshihiro Shimizu 890ddd
		if (oldVdt->m_vIndices.size() == 1) {
Toshihiro Shimizu 890ddd
			// The old entry should be removed - it is actually *purely* renamed
Toshihiro Shimizu 890ddd
			VDKey vdKey(*oldVdt);
Toshihiro Shimizu 890ddd
			vdKey.m_name = newName;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			m_vds.erase(name);
Toshihiro Shimizu 890ddd
			m_vds.insert(vdKey);
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			// The old entry remains - and data must be copied from there
Toshihiro Shimizu 890ddd
			detachVertex(name, skelId, v);
Toshihiro Shimizu 890ddd
			attachVertex(newName, skelId, v);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			newVdt = m_vds.find(newName); // Fetch the newly created vd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			// Copy the existing vd into the new one
Toshihiro Shimizu 890ddd
			SkVD &oldVd = oldVdt->m_vd, &newVd = newVdt->m_vd;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			int p, pCount = SkVD::PARAMS_COUNT;
Toshihiro Shimizu 890ddd
			for (p = 0; p != pCount; ++p)
Toshihiro Shimizu 890ddd
				*newVd.m_params[p] = *oldVd.m_params[p];
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::Imp::touchParams(SkVD &vd)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	for (int p = 0; p < SkVD::PARAMS_COUNT; ++p) {
Toshihiro Shimizu 890ddd
		if (vd.m_params[p])
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TDoubleParam *param = new TDoubleParam;
Toshihiro Shimizu 890ddd
		param->setName(parNames[p]);
Toshihiro Shimizu 890ddd
		param->setMeasureName(parMeasures[p]);
Toshihiro Shimizu 890ddd
		param->setGrammar(m_grammar);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		vd.m_params[p] = param;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		param->addObserver(this);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::Imp::onChange(const TParamChange &change)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	// Since the deformation was changed, any associated deformer
Toshihiro Shimizu 890ddd
	// must be invalidated (at the animation-deform level only)
Toshihiro Shimizu 890ddd
	PlasticDeformerStorage::instance()->invalidateDeformation(
Toshihiro Shimizu 890ddd
		m_back, PlasticDeformerStorage::NONE);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Propagate notification to this object's observers
Toshihiro Shimizu 890ddd
	std::set<tparamobserver *="">::iterator ot, oEnd(m_observers.end());</tparamobserver>
Toshihiro Shimizu 890ddd
	for (ot = m_observers.begin(); ot != oEnd; ++ot)
Toshihiro Shimizu 890ddd
		(*ot)->onChange(change);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::Imp::updateBranchPositions(
Toshihiro Shimizu 890ddd
	const PlasticSkeleton &originalSkeleton, PlasticSkeleton &deformedSkeleton,
Toshihiro Shimizu 890ddd
	double frame, int v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	struct locals {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		static void buildParentDirection(const PlasticSkeleton &skel, int v, TPointD &dir)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			assert(v >= 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			const PlasticSkeletonVertex &vx = skel.vertex(v);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			int vParent = vx.parent();
Toshihiro Shimizu 890ddd
			if (vParent < 0)
Toshihiro Shimizu 890ddd
				return; // dir remains as passed
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			const TPointD &dir_ = tcg::point_ops::direction(
Toshihiro Shimizu 890ddd
				skel.vertex(vParent).P(), vx.P(), 1e-4);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (dir_ != tcg::point_ops::NaP<tpointd>())</tpointd>
Toshihiro Shimizu 890ddd
				dir = dir_;
Toshihiro Shimizu 890ddd
			else
Toshihiro Shimizu 890ddd
				buildParentDirection(skel, vParent, dir);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}; // locals
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	PlasticSkeletonVertex &dvx = deformedSkeleton.vertex(v);
Toshihiro Shimizu 890ddd
	int vParent = dvx.parent();
Toshihiro Shimizu 890ddd
	if (vParent >= 0) {
Toshihiro Shimizu 890ddd
		// Rebuild vertex position
Toshihiro Shimizu 890ddd
		const TPointD &ovxPos = originalSkeleton.vertex(v).P();
Toshihiro Shimizu 890ddd
		const TPointD &ovxParentPos = originalSkeleton.vertex(vParent).P();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// Start by getting the polar reference
Toshihiro Shimizu 890ddd
		TPointD oDir(1.0, 0.0), dDir(1.0, 0.0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		locals::buildParentDirection(originalSkeleton, vParent, oDir);
Toshihiro Shimizu 890ddd
		locals::buildParentDirection(deformedSkeleton, vParent, dDir);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// Now, rebuild vx's position
Toshihiro Shimizu 890ddd
		const SkVD &vd = m_vds.find(dvx.name())->m_vd;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		double a = tcg::consts::rad_to_deg * tcg::point_ops::angle(oDir, ovxPos - ovxParentPos);
Toshihiro Shimizu 890ddd
		double d = tcg::point_ops::dist(ovxParentPos, ovxPos);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		double aDelta = vd.m_params[SkVD::ANGLE]->getValue(frame);
Toshihiro Shimizu 890ddd
		double dDelta = vd.m_params[SkVD::DISTANCE]->getValue(frame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		dvx.P() = deformedSkeleton.vertex(vParent).P() +
Toshihiro Shimizu 890ddd
				  (d + dDelta) * (TRotation(a + aDelta) * dDir);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Finally, update children positions
Toshihiro Shimizu 890ddd
	PlasticSkeleton::vertex_type::edges_iterator et, eEnd(dvx.edgesEnd());
Toshihiro Shimizu 890ddd
	for (et = dvx.edgesBegin(); et != eEnd; ++et) {
Toshihiro Shimizu 890ddd
		int vChild = deformedSkeleton.edge(*et).vertex(1);
Toshihiro Shimizu 890ddd
		if (vChild == v)
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		updateBranchPositions(originalSkeleton, deformedSkeleton, frame, vChild);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//**************************************************************************************
Toshihiro Shimizu 890ddd
//    PlasticSkeletonDeformation  implementation
Toshihiro Shimizu 890ddd
//**************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
PlasticSkeletonDeformation::PlasticSkeletonDeformation()
Toshihiro Shimizu 890ddd
	: m_imp(new Imp(this))
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
PlasticSkeletonDeformation::PlasticSkeletonDeformation(const PlasticSkeletonDeformation &other)
Toshihiro Shimizu 890ddd
	: TSmartObject(m_classCode), m_imp(new Imp(this, *other.m_imp))
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	// Register deformation
Toshihiro Shimizu 890ddd
	SkeletonSet::iterator st, sEnd(m_imp->m_skeletons.end());
Toshihiro Shimizu 890ddd
	for (st = m_imp->m_skeletons.begin(); st != sEnd; ++st)
Toshihiro Shimizu 890ddd
		st->get_right()->addListener(this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
PlasticSkeletonDeformation::~PlasticSkeletonDeformation()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	// Unregister deformation
Toshihiro Shimizu 890ddd
	SkeletonSet::iterator st, sEnd(m_imp->m_skeletons.end());
Toshihiro Shimizu 890ddd
	for (st = m_imp->m_skeletons.begin(); st != sEnd; ++st)
Toshihiro Shimizu 890ddd
		st->get_right()->removeListener(this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
PlasticSkeletonDeformation &PlasticSkeletonDeformation::operator=(const PlasticSkeletonDeformation &other)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	// The meaning of operator= is DIFFERENT from that implemented in the copy constructor.
Toshihiro Shimizu 890ddd
	// Skeletons are NOT cloned.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	*m_imp = *other.m_imp;
Toshihiro Shimizu 890ddd
	return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool PlasticSkeletonDeformation::empty() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_imp->m_skeletons.empty();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int PlasticSkeletonDeformation::skeletonsCount() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_imp->m_skeletons.size();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
namespace skeletonIds
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
typedef boost::bimap<int, plasticskeletonp="">::left_map::const_iterator iter_type;</int,>
Toshihiro Shimizu 890ddd
typedef iter_type::value_type value_type;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline int func_(const value_type &val) { return val.first; }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
} // namespace ::skeletonIds
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::skeletonIds(skelId_iterator &begin, skelId_iterator &end) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	using namespace ::skeletonIds;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	typedef tcg::function<int &),="" (*)(const="" func_="" value_type=""> func;</int>
Toshihiro Shimizu 890ddd
	typedef boost::transform_iterator<func, iter_type=""> adapt_it;</func,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	begin = adapt_it(m_imp->m_skeletons.left.begin());
Toshihiro Shimizu 890ddd
	end = adapt_it(m_imp->m_skeletons.left.end());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TDoubleParamP PlasticSkeletonDeformation::skeletonIdsParam() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_imp->m_skelIdsParam;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
PlasticSkeletonP PlasticSkeletonDeformation::skeleton(double frame) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return skeleton(skeletonId(frame));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int PlasticSkeletonDeformation::skeletonId(double frame) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_imp->m_skelIdsParam->getValue(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::attach(int skeletonId, PlasticSkeleton *skeleton)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp->attach(skeletonId, skeleton);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	skeleton->addListener(this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::detach(int skeletonId)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	SkeletonSet::left_map::iterator st(m_imp->m_skeletons.left.find(skeletonId));
Toshihiro Shimizu 890ddd
	if (st != m_imp->m_skeletons.left.end()) {
Toshihiro Shimizu 890ddd
		st->second->removeListener(this);
Toshihiro Shimizu 890ddd
		m_imp->detach(skeletonId);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
PlasticSkeletonP PlasticSkeletonDeformation::skeleton(int skeletonId) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	SkeletonSet::left_map::const_iterator st = m_imp->m_skeletons.left.find(skeletonId);
Toshihiro Shimizu 890ddd
	return (st == m_imp->m_skeletons.left.end()) ? PlasticSkeletonP() : st->second;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int PlasticSkeletonDeformation::skeletonId(PlasticSkeleton *skeleton) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	SkeletonSet::right_map::const_iterator st = m_imp->m_skeletons.right.find(skeleton);
Toshihiro Shimizu 890ddd
	return (st == m_imp->m_skeletons.right.end()) ? -(std::numeric_limits<int>::max)() : st->second;</int>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int PlasticSkeletonDeformation::vertexDeformationsCount() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_imp->m_vds.size();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
SkVD *PlasticSkeletonDeformation::vertexDeformation(const QString &vxName) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	SkVDSet::const_iterator vdt = m_imp->m_vds.find(vxName);
Toshihiro Shimizu 890ddd
	return (vdt == m_imp->m_vds.end()) ? (SkVD *)0 : &vdt->m_vd;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
SkVD *PlasticSkeletonDeformation::vertexDeformation(int skelId, int v) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const QString &name = skeleton(skelId)->vertex(v).name();
Toshihiro Shimizu 890ddd
	return vertexDeformation(name);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
namespace vertexDeformations
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
inline std::pair<const *="" *,="" qstring="" skvd=""> func_(const VDKey &vdKey)</const>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return std::make_pair(&vdKey.m_name, &vdKey.m_vd);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
} // namespace ::vertexDeformations
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::vertexDeformations(vd_iterator &begin, vd_iterator &end) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	using namespace ::vertexDeformations;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	typedef std::pair<const *="" *,="" qstring="" skvd=""> (*func_type)(const VDKey &vdKey);</const>
Toshihiro Shimizu 890ddd
	typedef tcg::function<func_type, func_=""> func;</func_type,>
Toshihiro Shimizu 890ddd
	typedef boost::transform_iterator<func, skvdset::const_iterator=""> adapt_it;</func,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	begin = adapt_it(m_imp->m_vds.begin());
Toshihiro Shimizu 890ddd
	end = adapt_it(m_imp->m_vds.end());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
namespace vdSkeletonVertices
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
inline std::pair<int, int=""> func_(const std::map<int, int="">::value_type &val)</int,></int,>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return std::make_pair(val.first, val.second);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
} // namespace ::vdSkeletonVertices
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::vdSkeletonVertices(const QString &vertexName,
Toshihiro Shimizu 890ddd
													vx_iterator &begin, vx_iterator &end) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	using namespace ::vdSkeletonVertices;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	typedef std::pair<int, int=""> (*func_type)(const std::map<int, int="">::value_type &);</int,></int,>
Toshihiro Shimizu 890ddd
	typedef tcg::function<func_type, func_=""> func;</func_type,>
Toshihiro Shimizu 890ddd
	typedef boost::transform_iterator<func, int="" std::map<int,="">::const_iterator> adapt_it;</func,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	SkVDSet::const_iterator nt(m_imp->m_vds.find(vertexName));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (nt == m_imp->m_vds.end())
Toshihiro Shimizu 890ddd
		begin = adapt_it(), end = adapt_it();
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		begin = adapt_it(nt->m_vIndices.begin()), end = adapt_it(nt->m_vIndices.end());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int PlasticSkeletonDeformation::hookNumber(const QString &name) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	SkVDSet::const_iterator nt(m_imp->m_vds.find(name));
Toshihiro Shimizu 890ddd
	return (nt == m_imp->m_vds.end()) ? -1 : nt->m_hookNumber;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int PlasticSkeletonDeformation::hookNumber(int skelId, int v) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const QString &name = skeleton(skelId)->vertex(v).name();
Toshihiro Shimizu 890ddd
	return hookNumber(name);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
QString PlasticSkeletonDeformation::vertexName(int hookNumber) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const SkVDByHookNumber &vds = m_imp->m_vds.get<int>();</int>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	SkVDByHookNumber::const_iterator ht(vds.find(hookNumber));
Toshihiro Shimizu 890ddd
	return (ht == vds.end()) ? QString() : ht->m_name;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int PlasticSkeletonDeformation::vertexIndex(int hookNumber, int skelId) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const SkVDByHookNumber &vds = m_imp->m_vds.get<int>();</int>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	SkVDByHookNumber::const_iterator ht(vds.find(hookNumber));
Toshihiro Shimizu 890ddd
	if (ht == vds.end())
Toshihiro Shimizu 890ddd
		return -1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::map<int, int="">::const_iterator st(ht->m_vIndices.find(skelId));</int,>
Toshihiro Shimizu 890ddd
	return (st == ht->m_vIndices.end()) ? -1 : st->second;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::getKeyframeAt(double frame, SkDKey &keyframe) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	keyframe.m_skelIdKeyframe = m_imp->m_skelIdsParam->getKeyframeAt(frame);
Toshihiro Shimizu 890ddd
	keyframe.m_vertexKeyframes.clear();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	SkVDSet::const_iterator dt, dEnd(m_imp->m_vds.end());
Toshihiro Shimizu 890ddd
	for (dt = m_imp->m_vds.begin(); dt != dEnd; ++dt)
Toshihiro Shimizu 890ddd
		keyframe.m_vertexKeyframes.insert(std::make_pair(dt->m_name, dt->m_vd.getKeyframe(frame)));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::setKeyframe(double frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp->m_skelIdsParam->setKeyframe(frame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	SkVDSet::iterator dt, dEnd(m_imp->m_vds.end());
Toshihiro Shimizu 890ddd
	for (dt = m_imp->m_vds.begin(); dt != dEnd; ++dt)
Toshihiro Shimizu 890ddd
		dt->m_vd.setKeyframe(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool PlasticSkeletonDeformation::setKeyframe(const SkDKey &keyframe)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	bool keyWasSet = false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (keyframe.m_skelIdKeyframe.m_isKeyframe) {
Toshihiro Shimizu 890ddd
		m_imp->m_skelIdsParam->setKeyframe(keyframe.m_skelIdKeyframe);
Toshihiro Shimizu 890ddd
		keyWasSet = true;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const std::map<qstring, skvd::keyframe=""> &vdKeys = keyframe.m_vertexKeyframes;</qstring,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Iterate the keyframe's vertex deformations
Toshihiro Shimizu 890ddd
	std::map<qstring, skvd::keyframe="">::const_iterator kt, kEnd(vdKeys.end());</qstring,>
Toshihiro Shimizu 890ddd
	for (kt = vdKeys.begin(); kt != vdKeys.end(); ++kt) {
Toshihiro Shimizu 890ddd
		// Search for a corresponding vertex deformation among stored ones
Toshihiro Shimizu 890ddd
		SkVDSet::iterator vdt = m_imp->m_vds.find(kt->first);
Toshihiro Shimizu 890ddd
		if (vdt != m_imp->m_vds.end()) {
Toshihiro Shimizu 890ddd
			// Set the corresponding keyframe
Toshihiro Shimizu 890ddd
			keyWasSet = vdt->m_vd.setKeyframe(kt->second) || keyWasSet;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return keyWasSet;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool PlasticSkeletonDeformation::setKeyframe(
Toshihiro Shimizu 890ddd
	const SkDKey &keyframe, double frame, double easeIn, double easeOut)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	bool keyWasSet = false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (keyframe.m_skelIdKeyframe.m_isKeyframe) {
Toshihiro Shimizu 890ddd
		TDoubleKeyframe kf(keyframe.m_skelIdKeyframe);
Toshihiro Shimizu 890ddd
		kf.m_frame = frame;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_imp->m_skelIdsParam->setKeyframe(kf);
Toshihiro Shimizu 890ddd
		keyWasSet = true;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const std::map<qstring, skvd::keyframe=""> &vdKeys = keyframe.m_vertexKeyframes;</qstring,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Iterate the keyframe's vertex deformations
Toshihiro Shimizu 890ddd
	std::map<qstring, skvd::keyframe="">::const_iterator kt, kEnd(vdKeys.end());</qstring,>
Toshihiro Shimizu 890ddd
	for (kt = vdKeys.begin(); kt != vdKeys.end(); ++kt) {
Toshihiro Shimizu 890ddd
		// Search for a corresponding vertex deformation among stored ones
Toshihiro Shimizu 890ddd
		SkVDSet::iterator vdt = m_imp->m_vds.find(kt->first);
Toshihiro Shimizu 890ddd
		if (vdt != m_imp->m_vds.end()) {
Toshihiro Shimizu 890ddd
			// Set the corresponding keyframe
Toshihiro Shimizu 890ddd
			keyWasSet = vdt->m_vd.setKeyframe(kt->second, frame, easeIn, easeOut) || keyWasSet;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return keyWasSet;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool PlasticSkeletonDeformation::isKeyframe(double frame) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_imp->m_skelIdsParam->isKeyframe(frame))
Toshihiro Shimizu 890ddd
		return true;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	SkVDSet::const_iterator dt, dEnd(m_imp->m_vds.end());
Toshihiro Shimizu 890ddd
	for (dt = m_imp->m_vds.begin(); dt != dEnd; ++dt)
Toshihiro Shimizu 890ddd
		if (dt->m_vd.isKeyframe(frame))
Toshihiro Shimizu 890ddd
			return true;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool PlasticSkeletonDeformation::isFullKeyframe(double frame) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_imp->m_skelIdsParam->isKeyframe(frame))
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	SkVDSet::const_iterator dt, dEnd(m_imp->m_vds.end());
Toshihiro Shimizu 890ddd
	for (dt = m_imp->m_vds.begin(); dt != dEnd; ++dt)
Toshihiro Shimizu 890ddd
		if (!dt->m_vd.isFullKeyframe(frame))
Toshihiro Shimizu 890ddd
			return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::deleteKeyframe(double frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp->m_skelIdsParam->deleteKeyframe(frame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	SkVDSet::iterator dt, dEnd(m_imp->m_vds.end());
Toshihiro Shimizu 890ddd
	for (dt = m_imp->m_vds.begin(); dt != dEnd; ++dt)
Toshihiro Shimizu 890ddd
		dt->m_vd.deleteKeyframe(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::storeDeformedSkeleton(int skelId, double frame, PlasticSkeleton &skeleton) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	// Copy the un-deformed skeleton to the output one
Toshihiro Shimizu 890ddd
	const PlasticSkeletonP &origSkel = this->skeleton(skelId);
Toshihiro Shimizu 890ddd
	skeleton = origSkel ? *origSkel : PlasticSkeleton();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Update the skeleton to the specified frame
Toshihiro Shimizu 890ddd
	if (!skeleton.vertices().empty())
Toshihiro Shimizu 890ddd
		m_imp->updateBranchPositions(*origSkel, skeleton, frame, skeleton.vertices().begin().m_idx);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::updatePosition(
Toshihiro Shimizu 890ddd
	const PlasticSkeleton &originalSkeleton, PlasticSkeleton &deformedSkeleton,
Toshihiro Shimizu 890ddd
	double frame, int v, const TPointD &pos)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const PlasticSkeletonVertex &vx = deformedSkeleton.vertex(v);
Toshihiro Shimizu 890ddd
	int vParent = vx.parent();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const TPointD &vParentPos = deformedSkeleton.vertex(vParent).P();
Toshihiro Shimizu 890ddd
	const TPointD &vPos = deformedSkeleton.vertex(v).P();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	SkVD &vd = m_imp->m_vds.find(vx.name())->m_vd;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// NOTE: The following aDelta calculation should be done as a true difference - this is still ok and spares
Toshihiro Shimizu 890ddd
	// access to v's grandParent...
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double aDelta = tcg::consts::rad_to_deg * tcg::point_ops::angle(vPos - vParentPos, pos - vParentPos),
Toshihiro Shimizu 890ddd
		   dDelta = tcg::point_ops::dist(vParentPos, pos) - tcg::point_ops::dist(vParentPos, vPos),
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		   a = tcrop(vd.m_params[SkVD::ANGLE]->getValue(frame) + aDelta, vx.m_minAngle, vx.m_maxAngle),
Toshihiro Shimizu 890ddd
		   d = vd.m_params[SkVD::DISTANCE]->getValue(frame) + dDelta;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	vd.m_params[SkVD::ANGLE]->setValue(frame, a);
Toshihiro Shimizu 890ddd
	vd.m_params[SkVD::DISTANCE]->setValue(frame, d);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_imp->updateBranchPositions(originalSkeleton, deformedSkeleton, frame, v);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::updateAngle(
Toshihiro Shimizu 890ddd
	const PlasticSkeleton &originalSkeleton, PlasticSkeleton &deformedSkeleton,
Toshihiro Shimizu 890ddd
	double frame, int v, const TPointD &pos)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const PlasticSkeletonVertex &vx = deformedSkeleton.vertex(v);
Toshihiro Shimizu 890ddd
	int vParent = vx.parent();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const TPointD &vParentPos = deformedSkeleton.vertex(vParent).P();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// No need to access the grandParent, we're making the diff against the old vx position
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	SkVD &vd = m_imp->m_vds.find(vx.name())->m_vd;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double aDelta = tcg::consts::rad_to_deg * tcg::point_ops::angle(vx.P() - vParentPos, pos - vParentPos),
Toshihiro Shimizu 890ddd
		   a = tcrop(vd.m_params[SkVD::ANGLE]->getValue(frame) + aDelta, vx.m_minAngle, vx.m_maxAngle);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	vd.m_params[SkVD::ANGLE]->setValue(frame, a);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_imp->updateBranchPositions(originalSkeleton, deformedSkeleton, frame, v);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::addVertex(PlasticSkeleton *skel, int v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int skelId = skeletonId(skel);
Toshihiro Shimizu 890ddd
	assert(skelId >= 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_imp->attachVertex(skel->vertex(v).name(), skelId, v);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::insertVertex(PlasticSkeleton *skel, int v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int skelId = skeletonId(skel);
Toshihiro Shimizu 890ddd
	assert(skelId >= 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_imp->attachVertex(skel->vertex(v).name(), skelId, v);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::deleteVertex(PlasticSkeleton *skel, int v)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(v > 0); // Root should not be deleted
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int skelId = skeletonId(skel);
Toshihiro Shimizu 890ddd
	assert(skelId >= 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Remove the vertex deformation associated with v
Toshihiro Shimizu 890ddd
	m_imp->detachVertex(skel->vertex(v).name(), skelId, v);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::vertexNameChange(
Toshihiro Shimizu 890ddd
	PlasticSkeleton *skel, int v, const QString &newName)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int skelId = skeletonId(skel);
Toshihiro Shimizu 890ddd
	assert(skelId >= 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_imp->rebindVertex(skel->vertex(v).name(), skelId, newName);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::clear(PlasticSkeleton *skel)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int skelId = skeletonId(skel);
Toshihiro Shimizu 890ddd
	assert(skelId >= 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_imp->detach(skelId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::addObserver(TParamObserver *observer)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp->m_observers.insert(observer);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::removeObserver(TParamObserver *observer)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp->m_observers.erase(observer);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::setGrammar(TSyntax::Grammar *grammar)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	SkVDSet::iterator vdt, vdEnd(m_imp->m_vds.end());
Toshihiro Shimizu 890ddd
	for (vdt = m_imp->m_vds.begin(); vdt != vdEnd; ++vdt) {
Toshihiro Shimizu 890ddd
		SkVD &vd = vdt->m_vd;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (int c = 0; c != SkVD::PARAMS_COUNT; ++c)
Toshihiro Shimizu 890ddd
			vd.m_params[c]->setGrammar(grammar);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_imp->m_skelIdsParam->setGrammar(grammar);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_imp->m_grammar = grammar;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::saveData(TOStream &os)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	// Save skeleton vertex deformations
Toshihiro Shimizu 890ddd
	os.openChild("VertexDeforms");							  // These are saved *before* skeletons
Toshihiro Shimizu 890ddd
	{														  // ON PURPOSE - in loadData(), we'll
Toshihiro Shimizu 890ddd
		SkVDSet::iterator vdt, vdEnd(m_imp->m_vds.end());	 // attach() skeletons to a completely
Toshihiro Shimizu 890ddd
		for (vdt = m_imp->m_vds.begin(); vdt != vdEnd; ++vdt) // rebuilt set of vertex deformations.
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			os.child("Name") << vdt->m_name;
Toshihiro Shimizu 890ddd
			os.child("Hook") << vdt->m_hookNumber;
Toshihiro Shimizu 890ddd
			os.child("VD") << vdt->m_vd;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	os.closeChild();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Save skeleton ids param
Toshihiro Shimizu 890ddd
	os.child("SkelIdsParam") << *m_imp->m_skelIdsParam;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Save skeletons
Toshihiro Shimizu 890ddd
	os.openChild("Skeletons");
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		SkeletonSet::iterator st, sEnd(m_imp->m_skeletons.end());
Toshihiro Shimizu 890ddd
		for (st = m_imp->m_skeletons.begin(); st != sEnd; ++st) {
Toshihiro Shimizu 890ddd
			os.child("SkelId") << st->get_left();
Toshihiro Shimizu 890ddd
			os.child("Skeleton") << *st->get_right();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	os.closeChild();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::loadData(TIStream &is)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (is.getVersion() < VersionNumber(1, 21)) {
Toshihiro Shimizu 890ddd
		loadData_prerelease(is);
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int skeletonId;
Toshihiro Shimizu 890ddd
	PlasticSkeleton *skeleton;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::string tagName;
Toshihiro Shimizu 890ddd
	while (is.openChild(tagName)) {
Toshihiro Shimizu 890ddd
		if (tagName == "VertexDeforms") {
Toshihiro Shimizu 890ddd
			VDKey vKey;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			while (is.openChild(tagName)) {
Toshihiro Shimizu 890ddd
				if (tagName == "Name")
Toshihiro Shimizu 890ddd
					is >> vKey.m_name, is.matchEndTag();
Toshihiro Shimizu 890ddd
				else if (tagName == "Hook")
Toshihiro Shimizu 890ddd
					is >> vKey.m_hookNumber, is.matchEndTag();
Toshihiro Shimizu 890ddd
				else if (tagName == "VD") {
Toshihiro Shimizu 890ddd
					m_imp->touchParams(vKey.m_vd);
Toshihiro Shimizu 890ddd
					is >> vKey.m_vd, is.matchEndTag();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					m_imp->m_vds.insert(vKey);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					vKey = VDKey();
Toshihiro Shimizu 890ddd
				} else
Toshihiro Shimizu 890ddd
					is.skipCurrentTag();
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			is.matchEndTag();
Toshihiro Shimizu 890ddd
		} else if (tagName == "SkelIdsParam")
Toshihiro Shimizu 890ddd
			is >> *m_imp->m_skelIdsParam, is.matchEndTag();
Toshihiro Shimizu 890ddd
		else if (tagName == "Skeletons") {
Toshihiro Shimizu 890ddd
			while (is.openChild(tagName)) {
Toshihiro Shimizu 890ddd
				if (tagName == "SkelId")
Toshihiro Shimizu 890ddd
					is >> skeletonId, is.matchEndTag();
Toshihiro Shimizu 890ddd
				else if (tagName == "Skeleton") {
Toshihiro Shimizu 890ddd
					skeleton = new PlasticSkeleton;
Toshihiro Shimizu 890ddd
					is >> *skeleton, is.matchEndTag();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					attach(skeletonId, skeleton);
Toshihiro Shimizu 890ddd
					skeletonId = 0, skeleton = 0;
Toshihiro Shimizu 890ddd
				} else
Toshihiro Shimizu 890ddd
					is.skipCurrentTag();
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			is.matchEndTag();
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			is.skipCurrentTag();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PlasticSkeletonDeformation::loadData_prerelease(TIStream &is)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	struct locals {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		static void buildParentDirection(const PlasticSkeleton &skel, int v, TPointD &dir)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			assert(v >= 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			const PlasticSkeletonVertex &vx = skel.vertex(v);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			int vParent = vx.parent();
Toshihiro Shimizu 890ddd
			if (vParent < 0)
Toshihiro Shimizu 890ddd
				return; // dir remains as passed
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			const TPointD &dir_ = tcg::point_ops::direction(
Toshihiro Shimizu 890ddd
				skel.vertex(vParent).P(), vx.P(), 1e-4);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (dir_ != tcg::point_ops::NaP<tpointd>())</tpointd>
Toshihiro Shimizu 890ddd
				dir = dir_;
Toshihiro Shimizu 890ddd
			else
Toshihiro Shimizu 890ddd
				buildParentDirection(skel, vParent, dir);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		static void adjust(SkD &sd, int v)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			PlasticSkeleton &skeleton = *sd.skeleton(1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			PlasticSkeletonVertex &vx = skeleton.vertex(v);
Toshihiro Shimizu 890ddd
			int vParent = vx.parent();
Toshihiro Shimizu 890ddd
			if (vParent >= 0) {
Toshihiro Shimizu 890ddd
				// Rebuild vertex position
Toshihiro Shimizu 890ddd
				const TPointD &vxPos = skeleton.vertex(v).P();
Toshihiro Shimizu 890ddd
				const TPointD &vxParentPos = skeleton.vertex(vParent).P();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				// Start by getting the polar reference
Toshihiro Shimizu 890ddd
				TPointD dir(1.0, 0.0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				buildParentDirection(skeleton, vParent, dir);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				// Now, rebuild vx's position
Toshihiro Shimizu 890ddd
				SkVD &vd = sd.m_imp->m_vds.find(vx.name())->m_vd;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				double a = tcg::consts::rad_to_deg * tcg::point_ops::angle(dir, vxPos - vxParentPos);
Toshihiro Shimizu 890ddd
				double d = tcg::point_ops::dist(vxParentPos, vxPos);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				{
Toshihiro Shimizu 890ddd
					TDoubleParamP param(vd.m_params[SkVD::ANGLE]);
Toshihiro Shimizu 890ddd
					param->setDefaultValue(0.0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					int k, kCount = param->getKeyframeCount();
Toshihiro Shimizu 890ddd
					for (k = 0; k != kCount; ++k) {
Toshihiro Shimizu 890ddd
						TDoubleKeyframe kf(param->getKeyframe(k));
Toshihiro Shimizu 890ddd
						kf.m_value -= a;
Toshihiro Shimizu 890ddd
						param->setKeyframe(k, kf);
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				{
Toshihiro Shimizu 890ddd
					TDoubleParamP param(vd.m_params[SkVD::DISTANCE]);
Toshihiro Shimizu 890ddd
					param->setDefaultValue(0.0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					int k, kCount = param->getKeyframeCount();
Toshihiro Shimizu 890ddd
					for (k = 0; k != kCount; ++k) {
Toshihiro Shimizu 890ddd
						TDoubleKeyframe kf(param->getKeyframe(k));
Toshihiro Shimizu 890ddd
						kf.m_value -= d;
Toshihiro Shimizu 890ddd
						param->setKeyframe(k, kf);
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			// Finally, update children positions
Toshihiro Shimizu 890ddd
			PlasticSkeleton::vertex_type::edges_iterator et, eEnd(vx.edgesEnd());
Toshihiro Shimizu 890ddd
			for (et = vx.edgesBegin(); et != eEnd; ++et) {
Toshihiro Shimizu 890ddd
				int vChild = skeleton.edge(*et).vertex(1);
Toshihiro Shimizu 890ddd
				if (vChild == v)
Toshihiro Shimizu 890ddd
					continue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				adjust(sd, vChild);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}; // locals
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	PlasticSkeletonP skeleton(new PlasticSkeleton);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::string tagName;
Toshihiro Shimizu 890ddd
	while (is.openChild(tagName)) {
Toshihiro Shimizu 890ddd
		if (tagName == "Skeleton")
Toshihiro Shimizu 890ddd
			is >> *skeleton, is.matchEndTag();
Toshihiro Shimizu 890ddd
		else if (tagName == "VertexDeforms") {
Toshihiro Shimizu 890ddd
			while (is.openChild(tagName)) {
Toshihiro Shimizu 890ddd
				if (tagName == "VD") {
Toshihiro Shimizu 890ddd
					VDKey vKey;
Toshihiro Shimizu 890ddd
					m_imp->touchParams(vKey.m_vd);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					is >> vKey.m_name, is >> vKey.m_vd;
Toshihiro Shimizu 890ddd
					is.closeChild();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					// Rebuild vKey's data from skeleton
Toshihiro Shimizu 890ddd
					int v, vCount = skeleton->verticesCount();
Toshihiro Shimizu 890ddd
					for (v = 0; v != vCount; ++v)
Toshihiro Shimizu 890ddd
						if (skeleton->vertex(v).name() == vKey.m_name)
Toshihiro Shimizu 890ddd
							break;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					assert(v < vCount);
Toshihiro Shimizu 890ddd
					vKey.m_hookNumber = skeleton->vertex(v).number();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					m_imp->m_vds.insert(vKey);
Toshihiro Shimizu 890ddd
				} else
Toshihiro Shimizu 890ddd
					is.skipCurrentTag();
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			is.matchEndTag();
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			is.skipCurrentTag();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	attach(1, skeleton.getPointer());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// SkVD params are now intended as deltas. Adjusting...
Toshihiro Shimizu 890ddd
	locals::adjust(*this, 0);
Toshihiro Shimizu 890ddd
}