Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/txsheet.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshcell.h"
Toshihiro Shimizu 890ddd
#include "toonz/hook.h"
Toshihiro Shimizu 890ddd
#include "toonz/dpiscale.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshsimplelevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/stage.h"
Toshihiro Shimizu 890ddd
#include "toonz/hook.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "xshhandlemanager.h"
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
// Returns the sum of each pass hook between fid and precFid.
Toshihiro Shimizu 890ddd
TPointD forwardPass(const TFrameId &fid, const TFrameId &precFid,
Toshihiro Shimizu 890ddd
					TXshSimpleLevel *sl, Hook *hook)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TPointD delta;
Toshihiro Shimizu 890ddd
	std::vector<tframeid> levelFids;</tframeid>
Toshihiro Shimizu 890ddd
	sl->getFids(levelFids);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int f, fCount = levelFids.size();
Toshihiro Shimizu 890ddd
	for (f = 0; f != fCount; ++f) {
Toshihiro Shimizu 890ddd
		const TFrameId &levelFid = levelFids[f];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (levelFid < precFid)
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (levelFid >= fid)
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (hook->isKeyframe(levelFid))
Toshihiro Shimizu 890ddd
			delta += hook->getAPos(levelFid) - hook->getBPos(levelFid);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return delta;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
// Returns subtraction of each pass hook between fid and precFid.
Toshihiro Shimizu 890ddd
TPointD backwardPass(const TFrameId &fid, const TFrameId &precFid,
Toshihiro Shimizu 890ddd
					 TXshSimpleLevel *sl, Hook *hook)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TPointD delta;
Toshihiro Shimizu 890ddd
	std::vector<tframeid> levelFids;</tframeid>
Toshihiro Shimizu 890ddd
	sl->getFids(levelFids);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int f, fCount = levelFids.size();
Toshihiro Shimizu 890ddd
	for (f = 0; f != fCount; ++f) {
Toshihiro Shimizu 890ddd
		const TFrameId &levelFid = levelFids[f];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (levelFid < fid)
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (levelFid >= precFid)
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (hook->isKeyframe(levelFid))
Toshihiro Shimizu 890ddd
			delta -= hook->getAPos(levelFid) - hook->getBPos(levelFid);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return delta;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
// Compute pass hook between fid and precFid
Toshihiro Shimizu 890ddd
TPointD computePassHook(const TFrameId &fid, const TFrameId &precFid,
Toshihiro Shimizu 890ddd
						TXshSimpleLevel *sl, Hook *hook)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (fid < precFid && (precFid.getNumber() - fid.getNumber()) <= 2)
Toshihiro Shimizu 890ddd
		return backwardPass(fid, precFid, sl, hook);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return forwardPass(fid, precFid, sl, hook);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//*******************************************************************************
Toshihiro Shimizu 890ddd
//    XshHandleManager  implementation
Toshihiro Shimizu 890ddd
//*******************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPointD XshHandleManager::getHandlePos(
Toshihiro Shimizu 890ddd
	const TStageObjectId &id,
Toshihiro Shimizu 890ddd
	const std::string &handle,
Toshihiro Shimizu 890ddd
	int row) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	static const double unit = 8.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(m_xsh->getScene());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (handle == "")
Toshihiro Shimizu 890ddd
		return TPointD();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	else if (handle[0] == 'H' && handle.length() > 1) {
Toshihiro Shimizu 890ddd
		// Hook port case
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (!id.isColumn())
Toshihiro Shimizu 890ddd
			return TPointD();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int hookIndex = 0;
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			int h, hLength = handle.length();
Toshihiro Shimizu 890ddd
			for (h = 1; h != hLength; ++h)
Toshihiro Shimizu 890ddd
				hookIndex = hookIndex * 10 + (handle[h] - '0');
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TStageObject *obj = m_xsh->getStageObject(id);
Toshihiro Shimizu 890ddd
		if (const PlasticSkeletonDeformationP &def = obj->getPlasticSkeletonDeformation()) {
Toshihiro Shimizu 890ddd
			int skelId = def->skeletonId(row);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			PlasticSkeleton skel;
Toshihiro Shimizu 890ddd
			def->storeDeformedSkeleton(skelId, row, skel);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			int v = def->vertexIndex(hookIndex, skelId);
Toshihiro Shimizu 890ddd
			return (v >= 0) ? TScale(1.0 / Stage::inch) * skel.vertex(v).P() : TPointD();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		--hookIndex;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int col = id.getIndex();
Toshihiro Shimizu 890ddd
		TXshCell cell(m_xsh->getCell(row, col));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TXshLevel *xl = cell.m_level.getPointer();
Toshihiro Shimizu 890ddd
		if (!xl)
Toshihiro Shimizu 890ddd
			return TPointD();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TXshSimpleLevel *sl = xl->getSimpleLevel();
Toshihiro Shimizu 890ddd
		if (!sl)
Toshihiro Shimizu 890ddd
			return TPointD();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		Hook *hook = sl->getHookSet()->getHook(hookIndex);
Toshihiro Shimizu 890ddd
		if (!hook)
Toshihiro Shimizu 890ddd
			return TPointD();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TFrameId fid(cell.m_frameId);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TPointD pos = hook->getAPos(fid) * (1.0 / Stage::inch);
Toshihiro Shimizu 890ddd
		TPointD delta;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (int r = row - 1; r >= 0; --r) {
Toshihiro Shimizu 890ddd
			cell = m_xsh->getCell(r, col);
Toshihiro Shimizu 890ddd
			if (cell.m_level.getPointer() != xl)
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			const TFrameId &precFid = cell.m_frameId;
Toshihiro Shimizu 890ddd
			delta += computePassHook(fid, precFid, sl, hook);
Toshihiro Shimizu 890ddd
			fid = precFid;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		pos += delta * (1.0 / Stage::inch);
Toshihiro Shimizu 890ddd
		pos = getDpiAffine(sl, cell.m_frameId, true) * pos;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		return pos;
Toshihiro Shimizu 890ddd
	} else if ('A' <= handle[0] && handle[0] <= 'Z')
Toshihiro Shimizu 890ddd
		return TPointD(unit * (handle[0] - 'B'), 0);
Toshihiro Shimizu 890ddd
	else if ('a' <= handle[0] && handle[0] <= 'z')
Toshihiro Shimizu 890ddd
		return TPointD(0.5 * unit * (handle[0] - 'b'), 0);
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		return TPointD();
Toshihiro Shimizu 890ddd
}