Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
#pragma warning(disable : 4996)
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "ttzpimagefx.h"
Toshihiro Shimizu 890ddd
#include "texception.h"
Toshihiro Shimizu 890ddd
#include "tfxparam.h"
Toshihiro Shimizu 890ddd
#include "stdfx.h"
Toshihiro Shimizu 890ddd
#include "trasterfx.h"
Toshihiro Shimizu 890ddd
#include "tspectrumparam.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class ArtContourFx : public TStandardRasterFx
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	FX_PLUGIN_DECLARATION(ArtContourFx)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRasterFxPort m_input;
Toshihiro Shimizu 890ddd
	TRasterFxPort m_controller;
Toshihiro Shimizu 890ddd
	TStringParamP m_colorIndex;
Toshihiro Shimizu 890ddd
	TBoolParamP m_keepColor;
Toshihiro Shimizu 890ddd
	TBoolParamP m_keepLine;
Toshihiro Shimizu 890ddd
	TBoolParamP m_includeAlpha;
Toshihiro Shimizu 890ddd
	TDoubleParamP m_density;
Toshihiro Shimizu 890ddd
	TRangeParamP m_distance;
Toshihiro Shimizu 890ddd
	TBoolParamP m_randomness;
Toshihiro Shimizu 890ddd
	TRangeParamP m_orientation;
Toshihiro Shimizu 890ddd
	TRangeParamP m_size;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	ArtContourFx()
Toshihiro Shimizu 890ddd
		: m_colorIndex(L"1,2,3"), m_keepColor(false), m_keepLine(false), m_includeAlpha(true), m_density(0.0), m_distance(DoublePair(30.0, 30.0)), m_randomness(true), m_orientation(DoublePair(0.0, 180.0)), m_size(DoublePair(30.0, 30.0))
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		bindParam(this, "Color_Index", m_colorIndex);
Toshihiro Shimizu 890ddd
		bindParam(this, "Keep_color", m_keepColor);
Toshihiro Shimizu 890ddd
		bindParam(this, "Keep_Line", m_keepLine);
Toshihiro Shimizu 890ddd
		bindParam(this, "Include_Alpha", m_includeAlpha);
Toshihiro Shimizu 890ddd
		bindParam(this, "Density", m_density);
Toshihiro Shimizu 890ddd
		bindParam(this, "Distance", m_distance);
Toshihiro Shimizu 890ddd
		bindParam(this, "Randomness", m_randomness);
Toshihiro Shimizu 890ddd
		bindParam(this, "Orientation", m_orientation);
Toshihiro Shimizu 890ddd
		bindParam(this, "Size", m_size);
Toshihiro Shimizu 890ddd
		addInputPort("Source", m_input);
Toshihiro Shimizu 890ddd
		addInputPort("Controller", m_controller);
Toshihiro Shimizu 890ddd
		m_density->setValueRange(0.0, 100.0);
Toshihiro Shimizu 890ddd
		m_distance->getMin()->setValueRange(0.0, 1000.0);
Toshihiro Shimizu 890ddd
		m_distance->getMax()->setValueRange(0.0, 1000.0);
Toshihiro Shimizu 890ddd
		m_orientation->getMin()->setValueRange(-180.0, 180.0);
Toshihiro Shimizu 890ddd
		m_orientation->getMax()->setValueRange(-180.0, 180.0);
Toshihiro Shimizu 890ddd
		m_orientation->getMin()->setMeasureName("angle");
Toshihiro Shimizu 890ddd
		m_orientation->getMax()->setMeasureName("angle");
Toshihiro Shimizu 890ddd
		m_size->getMin()->setValueRange(0.0, 1000.0);
Toshihiro Shimizu 890ddd
		m_size->getMax()->setValueRange(0.0, 1000.0);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	~ArtContourFx()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	SandorFxRenderData *buildRenderData(double frame, int shrink, const TRectD &controlBox,
Shinya Kitaoka 3bfa54
										const std::string &controllerAlias)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		int argc = 12;
Toshihiro Shimizu 890ddd
		const char *argv[12];
Shinya Kitaoka 9eb50d
		argv[0] = strsave(::to_string(m_colorIndex->getValue()).c_str());
Toshihiro Shimizu 890ddd
		getValues(argv, argc, frame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		SandorFxRenderData *artContourData = new SandorFxRenderData(ArtAtContour, argc, argv,
Toshihiro Shimizu 890ddd
																	0, shrink, controlBox);
Toshihiro Shimizu 890ddd
		ArtAtContourParams ¶ms = artContourData->m_contourParams;
Toshihiro Shimizu 890ddd
		params.m_density = m_density->getValue(frame) / 100;
Toshihiro Shimizu 890ddd
		params.m_colorIndex = m_colorIndex->getValue();
Toshihiro Shimizu 890ddd
		params.m_keepLine = m_keepLine->getValue();
Toshihiro Shimizu 890ddd
		params.m_includeAlpha = m_includeAlpha->getValue();
Toshihiro Shimizu 890ddd
		params.m_maxOrientation = m_orientation->getValue(frame).second;
Toshihiro Shimizu 890ddd
		params.m_maxDistance = m_distance->getValue(frame).second / 10;
Toshihiro Shimizu 890ddd
		params.m_maxSize = m_size->getValue(frame).second / 100;
Toshihiro Shimizu 890ddd
		params.m_minOrientation = m_orientation->getValue(frame).first;
Toshihiro Shimizu 890ddd
		params.m_minDistance = m_distance->getValue(frame).first / 10;
Toshihiro Shimizu 890ddd
		params.m_minSize = m_size->getValue(frame).first / 100;
Toshihiro Shimizu 890ddd
		params.m_randomness = m_randomness->getValue();
Toshihiro Shimizu 890ddd
		params.m_keepColor = m_keepColor->getValue();
Toshihiro Shimizu 890ddd
		artContourData->m_controllerAlias = controllerAlias;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		return artContourData;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool doGetBBox(double frame, TRectD &bBox, const TRenderSettings &ri)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (m_input.isConnected() && m_controller.isConnected()) {
Toshihiro Shimizu 890ddd
			TRectD controlBox, inputBox;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TRenderSettings ri2(ri);
Toshihiro Shimizu 890ddd
			ri2.m_affine = TAffine();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			m_controller->getBBox(frame, controlBox, ri2);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TRenderSettings ri3(ri);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			int shrink = tround((ri.m_shrinkX + ri.m_shrinkY) / 2.0);
Toshihiro Shimizu 890ddd
			//Should be there no need for the alias...
Toshihiro Shimizu 890ddd
			SandorFxRenderData *artContourData = buildRenderData(frame, shrink, controlBox, "");
Toshihiro Shimizu 890ddd
			ri3.m_data.push_back(artContourData);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			return m_input->doGetBBox(frame, bBox, ri3);
Toshihiro Shimizu 890ddd
		} else if (m_input.isConnected()) {
Toshihiro Shimizu 890ddd
			m_input->doGetBBox(frame, bBox, ri);
Toshihiro Shimizu 890ddd
			return false;
Toshihiro Shimizu 890ddd
		}
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
	bool canHandle(const TRenderSettings &info, double frame)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return true;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool allowUserCacheOnPort(int port) { return port != 0; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void doDryCompute(TRectD &rect, double frame, const TRenderSettings &ri);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void doCompute(TTile &tile, double frame, const TRenderSettings &ri);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	void getValues(const char *argv[], int argc, double frame)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		double values[12];
Toshihiro Shimizu 890ddd
		values[1] = m_size->getValue(frame).second / 100;
Toshihiro Shimizu 890ddd
		values[2] = m_size->getValue(frame).first / 100;
Toshihiro Shimizu 890ddd
		values[3] = m_orientation->getValue(frame).second;
Toshihiro Shimizu 890ddd
		values[4] = m_orientation->getValue(frame).first;
Toshihiro Shimizu 890ddd
		values[5] = m_randomness->getValue() ? 1.0 : 0.0;
Toshihiro Shimizu 890ddd
		values[6] = m_distance->getValue(frame).second / 10;
Toshihiro Shimizu 890ddd
		values[7] = m_distance->getValue(frame).first / 10;
Toshihiro Shimizu 890ddd
		values[8] = m_density->getValue(frame) / 100;
Toshihiro Shimizu 890ddd
		values[9] = m_keepLine->getValue() ? 1.0 : 0.0;
Toshihiro Shimizu 890ddd
		values[10] = m_keepColor->getValue() ? 1.0 : 0.0;
Toshihiro Shimizu 890ddd
		values[11] = m_includeAlpha->getValue() ? 1.0 : 0.0;
Toshihiro Shimizu 890ddd
		convertParam(values, argv, argc);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	//----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	char *strsave(const char *t)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		char *s;
Toshihiro Shimizu 890ddd
		s = (char *)malloc(strlen(t) + 1);
Toshihiro Shimizu 890ddd
		strcpy(s, t);
Toshihiro Shimizu 890ddd
		return s;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//-----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void convertParam(double param[], const char *cParam[], int cParamLen)
Toshihiro Shimizu 890ddd
	{
Shinya Kitaoka 3bfa54
		std::string app;
Toshihiro Shimizu 890ddd
		for (int i = 1; i <= 11; i++) {
Shinya Kitaoka 9eb50d
			app = std::to_string(param[i]);
Toshihiro Shimizu 890ddd
			cParam[i] = strsave(app.c_str());
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FX_PLUGIN_IDENTIFIER(ArtContourFx, "artContourFx");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ArtContourFx::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
	if (!m_controller.isConnected())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRenderSettings ri2(ri);
Toshihiro Shimizu 890ddd
	ri2.m_affine = TAffine();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRectD controlBox;
Toshihiro Shimizu 890ddd
	m_controller->getBBox(frame, controlBox, ri2);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TDimension dim = convert(controlBox).getSize();
Toshihiro Shimizu 890ddd
	TRectD controlRect(controlBox.getP00(), TDimensionD(dim.lx, dim.ly));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_controller->dryCompute(controlRect, frame, ri2);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRenderSettings ri3(ri);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int shrink = tround((ri.m_shrinkX + ri.m_shrinkY) / 2.0);
Shinya Kitaoka 3bfa54
	std::string controlAlias = m_controller->getAlias(frame, ri2);
Toshihiro Shimizu 890ddd
	SandorFxRenderData *artContourData = buildRenderData(frame, shrink, controlBox, controlAlias);
Toshihiro Shimizu 890ddd
	ri3.m_data.push_back(artContourData);
Toshihiro Shimizu 890ddd
	ri3.m_userCachable = false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_input->dryCompute(rect, frame, ri3);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ArtContourFx::doCompute(TTile &tile, 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
	if (!m_controller.isConnected()) {
Toshihiro Shimizu 890ddd
		m_input->compute(tile, frame, ri);
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRenderSettings ri2(ri);
Toshihiro Shimizu 890ddd
	ri2.m_affine = TAffine();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRectD controlBox;
Toshihiro Shimizu 890ddd
	m_controller->getBBox(frame, controlBox, ri2);
Toshihiro Shimizu 890ddd
	TTile ctrTile;
Toshihiro Shimizu 890ddd
	ctrTile.m_pos = controlBox.getP00();
Toshihiro Shimizu 890ddd
	TDimension dim = convert(controlBox).getSize();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_controller->allocateAndCompute(ctrTile, ctrTile.m_pos, dim, tile.getRaster(), frame, ri2);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRenderSettings ri3(ri);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Build the render data
Toshihiro Shimizu 890ddd
	int shrink = tround((ri.m_shrinkX + ri.m_shrinkY) / 2.0);
Shinya Kitaoka 3bfa54
	std::string controlAlias = m_controller->getAlias(frame, ri2);
Toshihiro Shimizu 890ddd
	SandorFxRenderData *artContourData = buildRenderData(frame, shrink, controlBox, controlAlias);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Add the controller raster
Toshihiro Shimizu 890ddd
	artContourData->m_controller = ctrTile.getRaster();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Push the data among the others
Toshihiro Shimizu 890ddd
	ri3.m_data.push_back(artContourData);
Toshihiro Shimizu 890ddd
	ri3.m_userCachable = false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_input->compute(tile, frame, ri3);
Toshihiro Shimizu 890ddd
}