Blob Blame Raw


#include "stdfx.h"
#include "ttzpimagefx.h"

#include "toonz/tcolumnfx.h"
#include "toonz/txshcolumn.h"
#include "toonz/txshcell.h"
#include "toonz/txshsimplelevel.h"
#include "toonz/txshpalettelevel.h"

//===================================================================

class ExternalPaletteFx : public TStandardRasterFx
{
	FX_PLUGIN_DECLARATION(ExternalPaletteFx)

	TRasterFxPort m_input;
	TRasterFxPort m_expalette;

public:
	ExternalPaletteFx()

	{

		addInputPort("Source", m_input);
		addInputPort("Palette", m_expalette);
	}

	~ExternalPaletteFx(){};

	bool doGetBBox(double frame, TRectD &bBox, const TRenderSettings &info)
	{
		if (m_input.isConnected()) {
			bool ret = m_input->doGetBBox(frame, bBox, info);
			return ret;
		} else {
			bBox = TRectD();
			return false;
		}
	}

	std::string getAlias(double frame, const TRenderSettings &info) const;

	void doDryCompute(TRectD &rect, double frame, const TRenderSettings &info);
	void doCompute(TTile &tile, double frame, const TRenderSettings &ri);

	bool allowUserCacheOnPort(int port) { return false; }

	bool canHandle(const TRenderSettings &info, double frame) { return true; }
};

//-------------------------------------------------------------------

namespace
{
TPalette *getPalette(TXshColumn *column, int frame)
{
	TXshCellColumn *cellColumn = dynamic_cast<TXshCellColumn *>(column);
	if (!cellColumn)
		return 0;

	TXshCell cell = cellColumn->getCell(frame);
	if (cell.isEmpty())
		return 0;

	TXshPaletteLevel *pl = cell.m_level->getPaletteLevel();
	if (pl)
		return pl->getPalette();

	TXshSimpleLevel *sl = cell.m_level->getSimpleLevel();
	if (sl)
		return sl->getPalette();

	return 0;
}

TPalette *getPalette(TFx *fx, double frame)
{
	if (!fx)
		return 0;
	int branches;
	branches = fx->getInputPortCount();

	if (branches == 1)
		return getPalette(fx->getInputPort(0)->getFx(), frame);

	if (branches > 1)
		return 0;

	if (TColumnFx *columnFx = dynamic_cast<TColumnFx *>(fx))
		return getPalette(columnFx->getXshColumn(), (int)frame);

	return 0;
}
}

//-------------------------------------------------------------------

std::string ExternalPaletteFx::getAlias(double frame, const TRenderSettings &info) const
{
	std::string alias(TRasterFx::getAlias(frame, info));

	if (m_expalette.isConnected()) {
		TFx *fx = m_expalette.getFx();
		TPaletteP plt(getPalette(fx, frame));
		if (plt && plt->isAnimated())
			alias += toString(frame);
	}

	return alias;
}

//-------------------------------------------------------------------

void ExternalPaletteFx::doDryCompute(TRectD &rect, double frame, const TRenderSettings &ri)
{
	if (!m_input.isConnected())
		return;

	if (m_expalette.isConnected()) {
		TFx *fx = m_expalette.getFx();
		std::string pltAlias = m_expalette->getAlias(frame, ri);

		TPaletteP palette(getPalette(fx, frame));
		if (palette && palette->isAnimated())
			pltAlias += toString(frame);

		TRenderSettings ri2(ri);
		ExternalPaletteFxRenderData *data =
			new ExternalPaletteFxRenderData(palette, pltAlias);
		ri2.m_data.push_back(data);
		ri2.m_userCachable = false;

		m_input->dryCompute(rect, frame, ri2);
	} else
		m_input->dryCompute(rect, frame, ri);
}

//-------------------------------------------------------------------

void ExternalPaletteFx::doCompute(TTile &tile, double frame, const TRenderSettings &ri)
{
	if (!m_input.isConnected())
		return;

	if (m_expalette.isConnected()) {
		TFx *fx = m_expalette.getFx();
		std::string pltAlias = m_expalette->getAlias(frame, ri);

		TPaletteP palette(getPalette(fx, frame));
		if (palette && palette->isAnimated())
			pltAlias += toString(frame);

		TRenderSettings ri2(ri);
		ExternalPaletteFxRenderData *data =
			new ExternalPaletteFxRenderData(palette, pltAlias);
		ri2.m_data.push_back(data);
		m_input->compute(tile, frame, ri2);
	} else
		m_input->compute(tile, frame, ri);
}

FX_PLUGIN_IDENTIFIER(ExternalPaletteFx, "externalPaletteFx");