Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tfxparam.h"
Toshihiro Shimizu 890ddd
#include "tparamset.h"
Toshihiro Shimizu 890ddd
#include "stdfx.h"
Toshihiro Shimizu 890ddd
#include "time.h"
Toshihiro Shimizu 890ddd
#include "trop.h"
Toshihiro Shimizu 890ddd
#include "trasterfx.h"
Toshihiro Shimizu 890ddd
#include "ttzpimagefx.h"
Toshihiro Shimizu 890ddd
#include "toonz/tdistort.h"
Toshihiro Shimizu 890ddd
#include "texturefxP.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
inline bool myIsEmpty(const TRectD &r)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return r.x0 >= r.x1 || r.y0 >= r.y1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class CornerPinFx : public TStandardRasterFx
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	FX_PLUGIN_DECLARATION(CornerPinFx)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	enum { PERSPECTIVE,
Toshihiro Shimizu 890ddd
		   BILINEAR };
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	CornerPinFx();
Toshihiro Shimizu 890ddd
	~CornerPinFx();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool doGetBBox(double frame, TRectD &bBox, const TRenderSettings &info);
Toshihiro Shimizu 890ddd
	void doCompute(TTile &tile, double frame, const TRenderSettings &ri);
Toshihiro Shimizu 890ddd
	void doDryCompute(TRectD &rect, double frame, const TRenderSettings &info);
Toshihiro Shimizu 890ddd
	int getMemoryRequirement(const TRectD &rect, double frame, const TRenderSettings &info);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void onPortConnected(TFxPort *port);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool canHandle(const TRenderSettings &info, double frame) { return true; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool allowUserCacheOnPort(int port) { return port != 0; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void transform(double frame,
Toshihiro Shimizu 890ddd
				   int port,
Toshihiro Shimizu 890ddd
				   const TRectD &rectOnOutput,
Toshihiro Shimizu 890ddd
				   const TRenderSettings &infoOnOutput,
Toshihiro Shimizu 890ddd
				   TRectD &rectOnInput,
Toshihiro Shimizu 890ddd
				   TRenderSettings &infoOnInput);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void safeTransform(
Toshihiro Shimizu 890ddd
		double frame,
Toshihiro Shimizu 890ddd
		int port,
Toshihiro Shimizu 890ddd
		const TRectD &rectOnOutput,
Toshihiro Shimizu 890ddd
		const TRenderSettings &infoOnOutput,
Toshihiro Shimizu 890ddd
		TRectD &rectOnInput,
Toshihiro Shimizu 890ddd
		TRenderSettings &infoOnInput,
Toshihiro Shimizu 890ddd
		TRectD &inBBox);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	TRasterFxPort m_input;
Toshihiro Shimizu 890ddd
	TRasterFxPort m_texture;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TIntEnumParamP m_distortType;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPointParamP m_p00_a;
Toshihiro Shimizu 890ddd
	TPointParamP m_p00_b;
Toshihiro Shimizu 890ddd
	TPointParamP m_p01_a;
Toshihiro Shimizu 890ddd
	TPointParamP m_p01_b;
Toshihiro Shimizu 890ddd
	TPointParamP m_p11_a;
Toshihiro Shimizu 890ddd
	TPointParamP m_p11_b;
Toshihiro Shimizu 890ddd
	TPointParamP m_p10_a;
Toshihiro Shimizu 890ddd
	TPointParamP m_p10_b;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TBoolParamP m_deactivate;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TStringParamP m_string;
Toshihiro Shimizu 890ddd
	TIntEnumParamP m_mode;
Toshihiro Shimizu 890ddd
	TIntEnumParamP m_keep;
Toshihiro Shimizu 890ddd
	TDoubleParamP m_value;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TAffine getPort1Affine(double frame) const;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
CornerPinFx::CornerPinFx()
Toshihiro Shimizu 890ddd
	: m_distortType(new TIntEnumParam(PERSPECTIVE, "Perspective")), m_deactivate(false), m_string(L"1,2,3"), m_mode(new TIntEnumParam(SUBSTITUTE, "Texture")), m_keep(new TIntEnumParam(0, "Delete")), m_value(100)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double ext = 400.;
Toshihiro Shimizu 890ddd
	double inn = 400.;
Toshihiro Shimizu 890ddd
	m_p00_a = TPointD(-ext, -ext);
Toshihiro Shimizu 890ddd
	m_p00_b = TPointD(-inn, -inn);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_p01_a = TPointD(-ext, ext);
Toshihiro Shimizu 890ddd
	m_p01_b = TPointD(-inn, inn);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_p11_a = TPointD(ext, ext);
Toshihiro Shimizu 890ddd
	m_p11_b = TPointD(inn, inn);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_p10_a = TPointD(ext, -ext);
Toshihiro Shimizu 890ddd
	m_p10_b = TPointD(inn, -inn);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_p00_b->getX()->setMeasureName("fxLength");
Toshihiro Shimizu 890ddd
	m_p00_b->getY()->setMeasureName("fxLength");
Toshihiro Shimizu 890ddd
	m_p10_b->getX()->setMeasureName("fxLength");
Toshihiro Shimizu 890ddd
	m_p10_b->getY()->setMeasureName("fxLength");
Toshihiro Shimizu 890ddd
	m_p01_b->getX()->setMeasureName("fxLength");
Toshihiro Shimizu 890ddd
	m_p01_b->getY()->setMeasureName("fxLength");
Toshihiro Shimizu 890ddd
	m_p11_b->getX()->setMeasureName("fxLength");
Toshihiro Shimizu 890ddd
	m_p11_b->getY()->setMeasureName("fxLength");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_p00_a->getX()->setMeasureName("fxLength");
Toshihiro Shimizu 890ddd
	m_p00_a->getY()->setMeasureName("fxLength");
Toshihiro Shimizu 890ddd
	m_p10_a->getX()->setMeasureName("fxLength");
Toshihiro Shimizu 890ddd
	m_p10_a->getY()->setMeasureName("fxLength");
Toshihiro Shimizu 890ddd
	m_p01_a->getX()->setMeasureName("fxLength");
Toshihiro Shimizu 890ddd
	m_p01_a->getY()->setMeasureName("fxLength");
Toshihiro Shimizu 890ddd
	m_p11_a->getX()->setMeasureName("fxLength");
Toshihiro Shimizu 890ddd
	m_p11_a->getY()->setMeasureName("fxLength");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bindParam(this, "distort_type", m_distortType);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bindParam(this, "bottom_left_b", m_p00_b);
Toshihiro Shimizu 890ddd
	bindParam(this, "bottom_right_b", m_p10_b);
Toshihiro Shimizu 890ddd
	bindParam(this, "top_left_b", m_p01_b);
Toshihiro Shimizu 890ddd
	bindParam(this, "top_right_b", m_p11_b);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bindParam(this, "bottom_left_a", m_p00_a);
Toshihiro Shimizu 890ddd
	bindParam(this, "bottom_right_a", m_p10_a);
Toshihiro Shimizu 890ddd
	bindParam(this, "top_left_a", m_p01_a);
Toshihiro Shimizu 890ddd
	bindParam(this, "top_right_a", m_p11_a);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bindParam(this, "deactivate", m_deactivate);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bindParam(this, "indexes", m_string);
Toshihiro Shimizu 890ddd
	bindParam(this, "mode", m_mode);
Toshihiro Shimizu 890ddd
	bindParam(this, "keep", m_keep);
Toshihiro Shimizu 890ddd
	bindParam(this, "value", m_value);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	addInputPort("source", m_input);
Toshihiro Shimizu 890ddd
	addInputPort("Texture", m_texture);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_value->setValueRange(0, 100);
Toshihiro Shimizu 890ddd
	m_keep->addItem(1, "Keep");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_mode->addItem(PATTERNTYPE, "Pattern");
Toshihiro Shimizu 890ddd
	m_mode->addItem(ADD, "Add");
Toshihiro Shimizu 890ddd
	m_mode->addItem(SUBTRACT, "Subtract");
Toshihiro Shimizu 890ddd
	m_mode->addItem(MULTIPLY, "Multiply");
Toshihiro Shimizu 890ddd
	m_mode->addItem(LIGHTEN, "Lighten");
Toshihiro Shimizu 890ddd
	m_mode->addItem(DARKEN, "Darken");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_p00_a->getX()->setValueRange(-1000, 1000);
Toshihiro Shimizu 890ddd
	m_p00_b->getX()->setValueRange(-1000, 1000);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_p00_a->getY()->setValueRange(-1000, 1000);
Toshihiro Shimizu 890ddd
	m_p00_b->getY()->setValueRange(-1000, 1000);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_p01_a->getX()->setValueRange(-1000, 1000);
Toshihiro Shimizu 890ddd
	m_p01_b->getX()->setValueRange(-1000, 1000);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_p01_a->getY()->setValueRange(-1000, 1000);
Toshihiro Shimizu 890ddd
	m_p01_b->getY()->setValueRange(-1000, 1000);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_p11_a->getX()->setValueRange(-1000, 1000);
Toshihiro Shimizu 890ddd
	m_p11_b->getX()->setValueRange(-1000, 1000);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_p11_a->getY()->setValueRange(-1000, 1000);
Toshihiro Shimizu 890ddd
	m_p11_b->getY()->setValueRange(-1000, 1000);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_p10_a->getX()->setValueRange(-1000, 1000);
Toshihiro Shimizu 890ddd
	m_p10_b->getX()->setValueRange(-1000, 1000);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_p10_a->getY()->setValueRange(-1000, 1000);
Toshihiro Shimizu 890ddd
	m_p10_b->getY()->setValueRange(-1000, 1000);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_distortType->addItem(BILINEAR, "Bilinear");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// ------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
CornerPinFx::~CornerPinFx()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// ------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool CornerPinFx::doGetBBox(double frame, TRectD &bBox, const TRenderSettings &info)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_input.isConnected()) {
Toshihiro Shimizu 890ddd
		bool ret = m_input->doGetBBox(frame, bBox, info);
Toshihiro Shimizu 890ddd
		return ret;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		bBox = TRectD();
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// ------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TAffine CornerPinFx::getPort1Affine(double frame) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//Explanation: Fxs tree decomposition on n-ary fxs (n>1) works the following way.
Toshihiro Shimizu 890ddd
	//Fxs on port 0 are considered 'column representants' - so affines found on them
Toshihiro Shimizu 890ddd
	//must be passed throughout the tree hierarchy. Therefore, their inverses are multiplied
Toshihiro Shimizu 890ddd
	//just below the other input ports in order to push the former affine above.
Toshihiro Shimizu 890ddd
	//In other words:
Toshihiro Shimizu 890ddd
	//  port  0:  A -|                  ---|
Toshihiro Shimizu 890ddd
	//               +--   =>              + A --
Toshihiro Shimizu 890ddd
	//  port >0:  B -|         B - (Ainv) -|
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Retrieve the affine that lies just below texture's port.
Toshihiro Shimizu 890ddd
	TGeometryFx *AinvFx = dynamic_cast<tgeometryfx *="">(m_texture.getFx());</tgeometryfx>
Toshihiro Shimizu 890ddd
	if (!AinvFx)
Toshihiro Shimizu 890ddd
		return TAffine();
Toshihiro Shimizu 890ddd
	TGeometryFx *BFx = dynamic_cast<tgeometryfx *="">(AinvFx->getInputPort(0)->getFx());</tgeometryfx>
Toshihiro Shimizu 890ddd
	if (!BFx)
Toshihiro Shimizu 890ddd
		return AinvFx->getPlacement(frame);
Toshihiro Shimizu 890ddd
	return AinvFx->getPlacement(frame) * BFx->getPlacement(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// ------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CornerPinFx::transform(
Toshihiro Shimizu 890ddd
	double frame,
Toshihiro Shimizu 890ddd
	int port,
Toshihiro Shimizu 890ddd
	const TRectD &rectOnOutput,
Toshihiro Shimizu 890ddd
	const TRenderSettings &infoOnOutput,
Toshihiro Shimizu 890ddd
	TRectD &rectOnInput,
Toshihiro Shimizu 890ddd
	TRenderSettings &infoOnInput)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//Build the input affine
Toshihiro Shimizu 890ddd
	infoOnInput = infoOnOutput;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPointD p00_b = m_p00_b->getValue(frame);
Toshihiro Shimizu 890ddd
	TPointD p10_b = m_p10_b->getValue(frame);
Toshihiro Shimizu 890ddd
	TPointD p01_b = m_p01_b->getValue(frame);
Toshihiro Shimizu 890ddd
	TPointD p11_b = m_p11_b->getValue(frame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPointD p00_a = m_p00_a->getValue(frame);
Toshihiro Shimizu 890ddd
	TPointD p10_a = m_p10_a->getValue(frame);
Toshihiro Shimizu 890ddd
	TPointD p01_a = m_p01_a->getValue(frame);
Toshihiro Shimizu 890ddd
	TPointD p11_a = m_p11_a->getValue(frame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//NOTE 1: An appropriate scale factor is sent below in the schematic, depending
Toshihiro Shimizu 890ddd
	//on the image distortion. For example, if the distortion brings a 2 scale factor,
Toshihiro Shimizu 890ddd
	//we want the same factor applied on image levels, so that their detail is appropriate
Toshihiro Shimizu 890ddd
	//(especially for vector images).
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double scale = 0;
Toshihiro Shimizu 890ddd
	scale = tmax(scale, norm(p10_a - p00_a) / norm(p10_b - p00_b));
Toshihiro Shimizu 890ddd
	scale = tmax(scale, norm(p01_a - p00_a) / norm(p01_b - p00_b));
Toshihiro Shimizu 890ddd
	scale = tmax(scale, norm(p11_a - p10_a) / norm(p11_b - p10_b));
Toshihiro Shimizu 890ddd
	scale = tmax(scale, norm(p11_a - p01_a) / norm(p11_b - p01_b));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TAffine A_1B(getPort1Affine(frame));
Toshihiro Shimizu 890ddd
	TAffine B(infoOnOutput.m_affine * A_1B);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	scale *= sqrt(fabs(B.det()));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (infoOnOutput.m_isSwatch) {
Toshihiro Shimizu 890ddd
		//Swatch viewers work out a lite version of the distort: only contractions
Toshihiro Shimizu 890ddd
		//are passed below in the schematic - so that input memory load is always at minimum.
Toshihiro Shimizu 890ddd
		//This is allowed in order to make fx adjusts the less frustrating as possible.
Toshihiro Shimizu 890ddd
		if (scale > 1)
Toshihiro Shimizu 890ddd
			scale = 1;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//NOTE 2: We further include A_1B.inv() to be applied on the level. This is done to
Toshihiro Shimizu 890ddd
	//counter the presence of A_1B just below this node - since it is preferable to place A_1B
Toshihiro Shimizu 890ddd
	//directly in the distort.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	infoOnInput.m_affine = TScale(scale) * A_1B.inv();
Toshihiro Shimizu 890ddd
	//rectOnInput = (TScale(scale) * B.inv()) * rectOnOutput;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//NOTE 3: The original distortion points are intended on the source port *before* applying A.
Toshihiro Shimizu 890ddd
	//But we want to have them on texture port *before* applying B; so, the following ref change arises:
Toshihiro Shimizu 890ddd
	//  p_b = (TScale(scale) * A_1B.inv()) * p_b == infoOnInput.m_aff * p_b;
Toshihiro Shimizu 890ddd
	//  p_a = (B * A_1B.inv()) * p_a == infoOnOutput.m_aff * p_a;
Toshihiro Shimizu 890ddd
	//Observe that scale and B are here due to NOTES 1 and 2.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Build rectOnInput
Toshihiro Shimizu 890ddd
	p00_a = infoOnOutput.m_affine * p00_a;
Toshihiro Shimizu 890ddd
	p10_a = infoOnOutput.m_affine * p10_a;
Toshihiro Shimizu 890ddd
	p01_a = infoOnOutput.m_affine * p01_a;
Toshihiro Shimizu 890ddd
	p11_a = infoOnOutput.m_affine * p11_a;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	p00_b = infoOnInput.m_affine * p00_b;
Toshihiro Shimizu 890ddd
	p10_b = infoOnInput.m_affine * p10_b;
Toshihiro Shimizu 890ddd
	p01_b = infoOnInput.m_affine * p01_b;
Toshihiro Shimizu 890ddd
	p11_b = infoOnInput.m_affine * p11_b;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_distortType->getValue() == PERSPECTIVE) {
Toshihiro Shimizu 890ddd
		PerspectiveDistorter pd(
Toshihiro Shimizu 890ddd
			p00_b, p10_b, p01_b, p11_b,
Toshihiro Shimizu 890ddd
			p00_a, p10_a, p01_a, p11_a);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		rectOnInput = ((TQuadDistorter *)&pd)->invMap(rectOnOutput);
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		BilinearDistorter bd(
Toshihiro Shimizu 890ddd
			p00_b, p10_b, p01_b, p11_b,
Toshihiro Shimizu 890ddd
			p00_a, p10_a, p01_a, p11_a);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		rectOnInput = ((TQuadDistorter *)&bd)->invMap(rectOnOutput);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (rectOnInput.x0 != TConsts::infiniteRectD.x0)
Toshihiro Shimizu 890ddd
		rectOnInput.x0 = tfloor(rectOnInput.x0);
Toshihiro Shimizu 890ddd
	if (rectOnInput.y0 != TConsts::infiniteRectD.y0)
Toshihiro Shimizu 890ddd
		rectOnInput.y0 = tfloor(rectOnInput.y0);
Toshihiro Shimizu 890ddd
	if (rectOnInput.x1 != TConsts::infiniteRectD.x1)
Toshihiro Shimizu 890ddd
		rectOnInput.x1 = tceil(rectOnInput.x1);
Toshihiro Shimizu 890ddd
	if (rectOnInput.y1 != TConsts::infiniteRectD.y1)
Toshihiro Shimizu 890ddd
		rectOnInput.y1 = tceil(rectOnInput.y1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// ------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CornerPinFx::safeTransform(
Toshihiro Shimizu 890ddd
	double frame,
Toshihiro Shimizu 890ddd
	int port,
Toshihiro Shimizu 890ddd
	const TRectD &rectOnOutput,
Toshihiro Shimizu 890ddd
	const TRenderSettings &infoOnOutput,
Toshihiro Shimizu 890ddd
	TRectD &rectOnInput,
Toshihiro Shimizu 890ddd
	TRenderSettings &infoOnInput,
Toshihiro Shimizu 890ddd
	TRectD &inBBox)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(port == 1 && m_texture.isConnected());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_deactivate->getValue()) {
Toshihiro Shimizu 890ddd
		infoOnInput = infoOnOutput;
Toshihiro Shimizu 890ddd
		rectOnInput = rectOnOutput;
Toshihiro Shimizu 890ddd
		m_texture->getBBox(frame, inBBox, infoOnInput);
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Avoid the singular matrix cases
Toshihiro Shimizu 890ddd
	if (fabs(infoOnOutput.m_affine.det()) < 1.e-3) {
Toshihiro Shimizu 890ddd
		infoOnInput = infoOnOutput;
Toshihiro Shimizu 890ddd
		rectOnInput.empty();
Toshihiro Shimizu 890ddd
		m_texture->getBBox(frame, inBBox, infoOnInput);
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	transform(frame, port, rectOnOutput, infoOnOutput, rectOnInput, infoOnInput);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_texture->getBBox(frame, inBBox, infoOnInput);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//In case inBBox is infinite, such as with gradients, also intersect with the input quadrilateral's bbox
Toshihiro Shimizu 890ddd
	if (inBBox == TConsts::infiniteRectD) {
Toshihiro Shimizu 890ddd
		TPointD affP00_b(infoOnInput.m_affine * m_p00_b->getValue(frame));
Toshihiro Shimizu 890ddd
		TPointD affP10_b(infoOnInput.m_affine * m_p10_b->getValue(frame));
Toshihiro Shimizu 890ddd
		TPointD affP01_b(infoOnInput.m_affine * m_p01_b->getValue(frame));
Toshihiro Shimizu 890ddd
		TPointD affP11_b(infoOnInput.m_affine * m_p11_b->getValue(frame));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TRectD source;
Toshihiro Shimizu 890ddd
		source.x0 = tmin(affP00_b.x, affP10_b.x, affP01_b.x, affP11_b.x);
Toshihiro Shimizu 890ddd
		source.y0 = tmin(affP00_b.y, affP10_b.y, affP01_b.y, affP11_b.y);
Toshihiro Shimizu 890ddd
		source.x1 = tmax(affP00_b.x, affP10_b.x, affP01_b.x, affP11_b.x);
Toshihiro Shimizu 890ddd
		source.y1 = tmax(affP00_b.y, affP10_b.y, affP01_b.y, affP11_b.y);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		rectOnInput *= source;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// ------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CornerPinFx::doDryCompute(TRectD &rect, double frame, const TRenderSettings &ri)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_input.isConnected())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	vector<string> items;</string>
Toshihiro Shimizu 890ddd
	string indexes = toString(m_string->getValue());
Toshihiro Shimizu 890ddd
	parseIndexes(indexes, items);
Toshihiro Shimizu 890ddd
	TRenderSettings ri2(ri);
Toshihiro Shimizu 890ddd
	PaletteFilterFxRenderData *PaletteFilterData = new PaletteFilterFxRenderData;
Toshihiro Shimizu 890ddd
	TRasterFxRenderDataP smartP(PaletteFilterData);
Toshihiro Shimizu 890ddd
	insertIndexes(items, PaletteFilterData);
Toshihiro Shimizu 890ddd
	PaletteFilterData->m_keep = (m_keep->getValue() == 1);
Toshihiro Shimizu 890ddd
	ri2.m_data.push_back(PaletteFilterData);
Toshihiro Shimizu 890ddd
	ri2.m_userCachable = false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//First child compute: part of output that IS NOT texturized
Toshihiro Shimizu 890ddd
	m_input->dryCompute(rect, frame, ri2);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!m_texture.isConnected())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool isSwatch = ri2.m_isSwatch;
Toshihiro Shimizu 890ddd
	if (isSwatch)
Toshihiro Shimizu 890ddd
		ri2.m_isSwatch = false;
Toshihiro Shimizu 890ddd
	PaletteFilterData->m_keep = !(m_keep->getValue() == 1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Second child compute: part of output that IS to be texturized
Toshihiro Shimizu 890ddd
	m_input->dryCompute(rect, frame, ri2);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Deal with the texture
Toshihiro Shimizu 890ddd
	if (m_deactivate->getValue())
Toshihiro Shimizu 890ddd
		m_texture->dryCompute(rect, frame, ri);
Toshihiro Shimizu 890ddd
	else {
Toshihiro Shimizu 890ddd
		TRectD inRect;
Toshihiro Shimizu 890ddd
		TRenderSettings riNew;
Toshihiro Shimizu 890ddd
		TRectD inBBox;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		safeTransform(frame, 1, rect, ri, inRect, riNew, inBBox);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		inRect *= inBBox;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (myIsEmpty(inRect))
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_texture->dryCompute(inRect, frame, riNew);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// ------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CornerPinFx::doCompute(TTile &tile, double frame, const TRenderSettings &ri)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_input.isConnected()) {
Toshihiro Shimizu 890ddd
		tile.getRaster()->clear();
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TTile invertMaskTile;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//carico il vettore items con gli indici dei colori
Toshihiro Shimizu 890ddd
	vector<string> items;</string>
Toshihiro Shimizu 890ddd
	string indexes = toString(m_string->getValue());
Toshihiro Shimizu 890ddd
	parseIndexes(indexes, items);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//genero il tile il cui raster contiene l'immagine in input a cui sono stati tolti i pixel
Toshihiro Shimizu 890ddd
	//colorati con gli indici contenuti nel vettore items
Toshihiro Shimizu 890ddd
	TRenderSettings ri2(ri);
Toshihiro Shimizu 890ddd
	PaletteFilterFxRenderData *PaletteFilterData = new PaletteFilterFxRenderData;
Toshihiro Shimizu 890ddd
	TRasterFxRenderDataP smartP(PaletteFilterData);
Toshihiro Shimizu 890ddd
	insertIndexes(items, PaletteFilterData);
Toshihiro Shimizu 890ddd
	PaletteFilterData->m_keep = (m_keep->getValue() == 1);
Toshihiro Shimizu 890ddd
	ri2.m_data.push_back(PaletteFilterData);
Toshihiro Shimizu 890ddd
	ri2.m_userCachable = false;
Toshihiro Shimizu 890ddd
	m_input->allocateAndCompute(invertMaskTile, tile.m_pos, tile.getRaster()->getSize(), tile.getRaster(), frame, ri2);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!m_texture.isConnected()) {
Toshihiro Shimizu 890ddd
		tile.getRaster()->copy(invertMaskTile.getRaster());
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//genero il tile il cui raster contiene l'immagine in input a cui sono stati tolti i pixel
Toshihiro Shimizu 890ddd
	//colorati con indici diversi da quelli contenuti nel vettore items
Toshihiro Shimizu 890ddd
	bool isSwatch = ri2.m_isSwatch;
Toshihiro Shimizu 890ddd
	if (isSwatch)
Toshihiro Shimizu 890ddd
		ri2.m_isSwatch = false;
Toshihiro Shimizu 890ddd
	PaletteFilterData->m_keep = !(m_keep->getValue() == 1);
Toshihiro Shimizu 890ddd
	m_input->compute(tile, frame, ri2);
Toshihiro Shimizu 890ddd
	if (isSwatch)
Toshihiro Shimizu 890ddd
		ri2.m_isSwatch = true;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//controllo se ho ottenuto quaclosa su cui si possa lavorare.
Toshihiro Shimizu 890ddd
	TRect saveBox;
Toshihiro Shimizu 890ddd
	TRop::computeBBox(tile.getRaster(), saveBox);
Toshihiro Shimizu 890ddd
	if (saveBox.isEmpty()) {
Toshihiro Shimizu 890ddd
		//I guess that this case should be wiped out...
Toshihiro Shimizu 890ddd
		m_input->compute(tile, frame, ri); //Could the invertMask be copied??
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Then, generate the texture tile and make its distortion
Toshihiro Shimizu 890ddd
	TTile textureTile;
Toshihiro Shimizu 890ddd
	if (m_deactivate->getValue()) {
Toshihiro Shimizu 890ddd
		TDimension size = tile.getRaster()->getSize();
Toshihiro Shimizu 890ddd
		TPointD pos = tile.m_pos;
Toshihiro Shimizu 890ddd
		m_texture->allocateAndCompute(textureTile, pos, size, tile.getRaster(), frame, ri);
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		//Build the interesting texture region
Toshihiro Shimizu 890ddd
		TRasterP tileRas(tile.getRaster());
Toshihiro Shimizu 890ddd
		TRectD tileRect(convert(tileRas->getBounds()) + tile.m_pos);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TRectD inRect;
Toshihiro Shimizu 890ddd
		TRenderSettings riNew;
Toshihiro Shimizu 890ddd
		TRectD inBBox;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		safeTransform(frame, 1, tileRect, ri, inRect, riNew, inBBox);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		inRect *= inBBox;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (myIsEmpty(inRect))
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TDimension inRectSize(tceil(inRect.getLx()), tceil(inRect.getLy()));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TTile inTile;
Toshihiro Shimizu 890ddd
		m_texture->allocateAndCompute(inTile, inRect.getP00(), inRectSize, tileRas, frame, riNew);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Get the source quad
Toshihiro Shimizu 890ddd
		TPointD p00_b = m_p00_b->getValue(frame);
Toshihiro Shimizu 890ddd
		TPointD p10_b = m_p10_b->getValue(frame);
Toshihiro Shimizu 890ddd
		TPointD p01_b = m_p01_b->getValue(frame);
Toshihiro Shimizu 890ddd
		TPointD p11_b = m_p11_b->getValue(frame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Get destination quad
Toshihiro Shimizu 890ddd
		TPointD p00_a = m_p00_a->getValue(frame);
Toshihiro Shimizu 890ddd
		TPointD p10_a = m_p10_a->getValue(frame);
Toshihiro Shimizu 890ddd
		TPointD p01_a = m_p01_a->getValue(frame);
Toshihiro Shimizu 890ddd
		TPointD p11_a = m_p11_a->getValue(frame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		double scale = 0;
Toshihiro Shimizu 890ddd
		scale = tmax(scale, norm(p10_a - p00_a) / norm(p10_b - p00_b));
Toshihiro Shimizu 890ddd
		scale = tmax(scale, norm(p01_a - p00_a) / norm(p01_b - p00_b));
Toshihiro Shimizu 890ddd
		scale = tmax(scale, norm(p11_a - p10_a) / norm(p11_b - p10_b));
Toshihiro Shimizu 890ddd
		scale = tmax(scale, norm(p11_a - p01_a) / norm(p11_b - p01_b));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TAffine A_1B(getPort1Affine(frame));
Toshihiro Shimizu 890ddd
		TAffine B(ri.m_affine * A_1B);
Toshihiro Shimizu 890ddd
		scale *= sqrt(fabs(B.det()));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (ri.m_isSwatch)
Toshihiro Shimizu 890ddd
			if (scale > 1)
Toshihiro Shimizu 890ddd
				scale = 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		p00_b = riNew.m_affine * p00_b;
Toshihiro Shimizu 890ddd
		p10_b = riNew.m_affine * p10_b;
Toshihiro Shimizu 890ddd
		p01_b = riNew.m_affine * p01_b;
Toshihiro Shimizu 890ddd
		p11_b = riNew.m_affine * p11_b;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		p00_a = ri.m_affine * p00_a;
Toshihiro Shimizu 890ddd
		p10_a = ri.m_affine * p10_a;
Toshihiro Shimizu 890ddd
		p01_a = ri.m_affine * p01_a;
Toshihiro Shimizu 890ddd
		p11_a = ri.m_affine * p11_a;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		PerspectiveDistorter perpDistorter(
Toshihiro Shimizu 890ddd
			p00_b - inTile.m_pos, p10_b - inTile.m_pos, p01_b - inTile.m_pos, p11_b - inTile.m_pos,
Toshihiro Shimizu 890ddd
			p00_a, p10_a, p01_a, p11_a);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		BilinearDistorter bilDistorter(
Toshihiro Shimizu 890ddd
			p00_b - inTile.m_pos, p10_b - inTile.m_pos, p01_b - inTile.m_pos, p11_b - inTile.m_pos,
Toshihiro Shimizu 890ddd
			p00_a, p10_a, p01_a, p11_a);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TDistorter *distorter;
Toshihiro Shimizu 890ddd
		if (m_distortType->getValue() == PERSPECTIVE)
Toshihiro Shimizu 890ddd
			distorter = &perpDistorter;
Toshihiro Shimizu 890ddd
		else if (m_distortType->getValue() == BILINEAR)
Toshihiro Shimizu 890ddd
			distorter = &bilDistorter;
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			assert(0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TRasterP textureRas(tileRas->create(tileRas->getLx(), tileRas->getLy()));
Toshihiro Shimizu 890ddd
		distort(textureRas, inTile.getRaster(), *distorter, convert(tile.m_pos), TRop::Bilinear);
Toshihiro Shimizu 890ddd
		textureTile.m_pos = tile.m_pos;
Toshihiro Shimizu 890ddd
		textureTile.setRaster(textureRas);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Then, apply the texture
Toshihiro Shimizu 890ddd
	double v = m_value->getValue(frame);
Toshihiro Shimizu 890ddd
	if (ri.m_bpp == 32) {
Toshihiro Shimizu 890ddd
		TRaster32P witheCard;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		myOver32(tile.getRaster(), invertMaskTile.getRaster(), &makeOpaque<tpixel32>, v);</tpixel32>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		switch (m_mode->getValue()) {
Toshihiro Shimizu 890ddd
		case SUBSTITUTE:
Toshihiro Shimizu 890ddd
			myOver32(tile.getRaster(), textureTile.getRaster(), &substitute<tpixel32>, v);</tpixel32>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			CASE PATTERNTYPE : witheCard = TRaster32P(textureTile.getRaster()->getSize());
Toshihiro Shimizu 890ddd
			witheCard->fill(TPixel32::White);
Toshihiro Shimizu 890ddd
			TRop::over(textureTile.getRaster(), witheCard, textureTile.getRaster());
Toshihiro Shimizu 890ddd
			myOver32(tile.getRaster(), textureTile.getRaster(), &pattern32, v);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			CASE ADD : myOver32(tile.getRaster(), textureTile.getRaster(), &textureAdd<tpixel32>, v / 100.0);</tpixel32>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			CASE SUBTRACT : myOver32(tile.getRaster(), textureTile.getRaster(), &textureSub<tpixel32>, v / 100.0);</tpixel32>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			CASE MULTIPLY : myOver32(tile.getRaster(), textureTile.getRaster(), &textureMult<tpixel32>, v);</tpixel32>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			CASE DARKEN : myOver32(tile.getRaster(), textureTile.getRaster(), &textureDarken<tpixel32>, v);</tpixel32>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			CASE LIGHTEN : myOver32(tile.getRaster(), textureTile.getRaster(), &textureLighten<tpixel32>, v);</tpixel32>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		DEFAULT:
Toshihiro Shimizu 890ddd
			assert(0);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		TRaster64P witheCard;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		myOver64(tile.getRaster(), invertMaskTile.getRaster(), &makeOpaque<tpixel64>, v);</tpixel64>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		switch (m_mode->getValue()) {
Toshihiro Shimizu 890ddd
		case SUBSTITUTE:
Toshihiro Shimizu 890ddd
			myOver64(tile.getRaster(), textureTile.getRaster(), &substitute<tpixel64>, v);</tpixel64>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			CASE PATTERNTYPE : witheCard = TRaster64P(textureTile.getRaster()->getSize());
Toshihiro Shimizu 890ddd
			witheCard->fill(TPixel64::White);
Toshihiro Shimizu 890ddd
			TRop::over(textureTile.getRaster(), witheCard, textureTile.getRaster());
Toshihiro Shimizu 890ddd
			myOver64(tile.getRaster(), textureTile.getRaster(), &pattern64, v);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			CASE ADD : myOver64(tile.getRaster(), textureTile.getRaster(), &textureAdd<tpixel64>, v / 100.0);</tpixel64>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			CASE SUBTRACT : myOver64(tile.getRaster(), textureTile.getRaster(), &textureSub<tpixel64>, v / 100.0);</tpixel64>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			CASE MULTIPLY : myOver64(tile.getRaster(), textureTile.getRaster(), &textureMult<tpixel64>, v);</tpixel64>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			CASE DARKEN : myOver64(tile.getRaster(), textureTile.getRaster(), &textureDarken<tpixel64>, v);</tpixel64>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			CASE LIGHTEN : myOver64(tile.getRaster(), textureTile.getRaster(), &textureLighten<tpixel64>, v);</tpixel64>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		DEFAULT:
Toshihiro Shimizu 890ddd
			assert(0);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRop::over(tile.getRaster(), invertMaskTile.getRaster());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int CornerPinFx::getMemoryRequirement(const TRectD &rect, double frame, const TRenderSettings &info)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_texture.isConnected())
Toshihiro Shimizu 890ddd
		return TRasterFx::memorySize(rect, info.m_bpp);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRectD inRect;
Toshihiro Shimizu 890ddd
	TRenderSettings riNew;
Toshihiro Shimizu 890ddd
	TRectD inBBox;
Toshihiro Shimizu 890ddd
	safeTransform(frame, 1, rect, info, inRect, riNew, inBBox);
Toshihiro Shimizu 890ddd
	inRect *= inBBox;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return tmax(TRasterFx::memorySize(rect, info.m_bpp), TRasterFx::memorySize(inRect, riNew.m_bpp));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
TRectD CornerPinFx::getContainingBox(const FourPoints &points)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if(points.m_p00==points.m_p01 && points.m_p01==points.m_p10 && points.m_p10==points.m_p11)
Toshihiro Shimizu 890ddd
		return TRectD(points.m_p00,points.m_p00);
Toshihiro Shimizu 890ddd
	double xMax=tmax(points.m_p00.x,points.m_p01.x,points.m_p10.x,points.m_p11.x);
Toshihiro Shimizu 890ddd
	double yMax=tmax(points.m_p00.y,points.m_p01.y,points.m_p10.y,points.m_p11.y);
Toshihiro Shimizu 890ddd
	double xMin=tmin(points.m_p00.x,points.m_p01.x,points.m_p10.x,points.m_p11.x);
Toshihiro Shimizu 890ddd
	double yMin=tmin(points.m_p00.y,points.m_p01.y,points.m_p10.y,points.m_p11.y);
Toshihiro Shimizu 890ddd
	return TRectD(xMin,yMin,xMax, yMax);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
// ------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FX_PLUGIN_IDENTIFIER(CornerPinFx, "cornerPinFx");