Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tsystem.h"
Toshihiro Shimizu 890ddd
#include "tstream.h"
Toshihiro Shimizu 890ddd
#include "tthreadmessage.h"
Toshihiro Shimizu 890ddd
#include "tconvert.h"
Toshihiro Shimizu 890ddd
#include "tstopwatch.h"
Toshihiro Shimizu 890ddd
#include "tlevel_io.h"
Toshihiro Shimizu 890ddd
#include "tflash.h"
Toshihiro Shimizu 890ddd
#include "trasterimage.h"
Toshihiro Shimizu 890ddd
#include "ttoonzimage.h"
Toshihiro Shimizu 890ddd
#include "tvectorimage.h"
Toshihiro Shimizu 890ddd
#include "timagecache.h"
Toshihiro Shimizu 890ddd
#include "timageinfo.h"
Toshihiro Shimizu 890ddd
#include "tropcm.h"
Toshihiro Shimizu 890ddd
#include "tofflinegl.h"
Toshihiro Shimizu 890ddd
#include "tvectorrenderdata.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzBase includes
Toshihiro Shimizu 890ddd
#include "ttzpimagefx.h"
Toshihiro Shimizu 890ddd
#include "trasterfx.h"
Toshihiro Shimizu 890ddd
#include "tzeraryfx.h"
Toshihiro Shimizu 890ddd
#include "trenderer.h"
Toshihiro Shimizu 890ddd
#include "tfxcachemanager.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/toonzscene.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheet.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevelcolumn.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshpalettecolumn.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshzeraryfxcolumn.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshcell.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshsimplelevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshpalettelevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshleveltypes.h"
Toshihiro Shimizu 890ddd
#include "toonz/levelset.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshchildlevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/fxdag.h"
Toshihiro Shimizu 890ddd
#include "toonz/tcolumnfxset.h"
Toshihiro Shimizu 890ddd
#include "toonz/stage.h"
Toshihiro Shimizu 890ddd
#include "toonz/fill.h"
Toshihiro Shimizu 890ddd
#include "toonz/tstageobjectid.h"
Toshihiro Shimizu 890ddd
#include "toonz/tstageobject.h"
Toshihiro Shimizu 890ddd
#include "toonz/levelproperties.h"
Toshihiro Shimizu 890ddd
#include "toonz/imagemanager.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzimageutils.h"
Toshihiro Shimizu 890ddd
#include "toonz/tvectorimageutils.h"
Toshihiro Shimizu 890ddd
#include "toonz/preferences.h"
Toshihiro Shimizu 890ddd
#include "toonz/dpiscale.h"
Toshihiro Shimizu 890ddd
#include "imagebuilders.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// 4.6 compatibility - sandor fxs
Toshihiro Shimizu 890ddd
#include "toonz4.6/raster.h"
Toshihiro Shimizu 890ddd
#include "sandor_fxs/blend.h"
Toshihiro Shimizu 890ddd
extern "C" {
Toshihiro Shimizu 890ddd
#include "sandor_fxs/calligraph.h"
Toshihiro Shimizu 890ddd
#include "sandor_fxs/patternmap.h"
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/tcolumnfx.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
//    Preliminaries
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
template class DV_EXPORT_API TFxDeclarationT<tlevelcolumnfx>;</tlevelcolumnfx>
Toshihiro Shimizu 890ddd
template class DV_EXPORT_API TFxDeclarationT<tzerarycolumnfx>;</tzerarycolumnfx>
Toshihiro Shimizu 890ddd
template class DV_EXPORT_API TFxDeclarationT<txsheetfx>;</txsheetfx>
Toshihiro Shimizu 890ddd
template class DV_EXPORT_API TFxDeclarationT<toutputfx>;</toutputfx>
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFxDeclarationT<tlevelcolumnfx> columnFxInfo(TFxInfo("Toonz_columnFx", true));</tlevelcolumnfx>
Toshihiro Shimizu 890ddd
TFxDeclarationT<tpalettecolumnfx> paletteColumnFxInfo(TFxInfo("Toonz_paletteColumnFx", true));</tpalettecolumnfx>
Toshihiro Shimizu 890ddd
TFxDeclarationT<tzerarycolumnfx> zeraryColumnFxInfo(TFxInfo("Toonz_zeraryColumnFx", true));</tzerarycolumnfx>
Toshihiro Shimizu 890ddd
TFxDeclarationT<txsheetfx> infoTXsheetFx(TFxInfo("Toonz_xsheetFx", true));</txsheetfx>
Toshihiro Shimizu 890ddd
TFxDeclarationT<toutputfx> infoTOutputFx(TFxInfo("Toonz_outputFx", true));</toutputfx>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
//    Local namespace  -  misc functions
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void setMaxMatte(TRasterP r)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRaster32P r32 = (TRaster32P)r;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRaster64P r64 = (TRaster64P)r;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (r32)
Toshihiro Shimizu 890ddd
		for (int i = 0; i < r32->getLy(); i++) {
Toshihiro Shimizu 890ddd
			TPixel *pix = r32->pixels(i);
Toshihiro Shimizu 890ddd
			for (int j = 0; j < r32->getLx(); j++, pix++)
Toshihiro Shimizu 890ddd
				pix->m = 255;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	else if (r64)
Toshihiro Shimizu 890ddd
		for (int i = 0; i < r64->getLy(); i++) {
Toshihiro Shimizu 890ddd
			TPixel64 *pix = r64->pixels(i);
Toshihiro Shimizu 890ddd
			for (int j = 0; j < r64->getLx(); j++, pix++)
Toshihiro Shimizu 890ddd
				pix->m = 65535;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
}
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); // I'm almost sure that this malloc is LEAKED! Please, check that !
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
inline TRect myConvert(const TRectD &r)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return TRect(tfloor(r.x0), tfloor(r.y0), tceil(r.x1), tceil(r.y1));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline TRect myConvert(const TRectD &r, TPointD &dp)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRect ri(tfloor(r.x0), tfloor(r.y0), tceil(r.x1), tceil(r.y1));
Toshihiro Shimizu 890ddd
	dp.x = r.x0 - ri.x0;
Toshihiro Shimizu 890ddd
	dp.y = r.y0 - ri.y0;
Toshihiro Shimizu 890ddd
	assert(dp.x >= 0 && dp.y >= 0);
Toshihiro Shimizu 890ddd
	return ri;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Currently used on debug only
Toshihiro Shimizu 890ddd
inline QString traduce(const TRectD &rect)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return "[" + QString::number(rect.x0) + " " + QString::number(rect.y0) + " " +
Toshihiro Shimizu 890ddd
		   QString::number(rect.x1) + " " + QString::number(rect.y1) + "]";
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Currently used on debug only
Toshihiro Shimizu 890ddd
inline QString traduce(const TRectD &rect, const TRenderSettings &info)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return "[" + QString::number(rect.x0) + " " + QString::number(rect.y0) + " " +
Toshihiro Shimizu 890ddd
		   QString::number(rect.x1) + " " + QString::number(rect.y1) + "]; aff = (" +
Toshihiro Shimizu 890ddd
		   QString::number(info.m_affine.a11, 'f') + " " +
Toshihiro Shimizu 890ddd
		   QString::number(info.m_affine.a12, 'f') + " " +
Toshihiro Shimizu 890ddd
		   QString::number(info.m_affine.a13, 'f') + " " +
Toshihiro Shimizu 890ddd
		   QString::number(info.m_affine.a21, 'f') + " " +
Toshihiro Shimizu 890ddd
		   QString::number(info.m_affine.a22, 'f') + " " +
Toshihiro Shimizu 890ddd
		   QString::number(info.m_affine.a23, 'f') + ")";
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline int colorDistance(const TPixel32 &c0, const TPixel32 &c1)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return (c0.r - c1.r) * (c0.r - c1.r) + (c0.g - c1.g) * (c0.g - c1.g) + (c0.b - c1.b) * (c0.b - c1.b);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
std::string getAlias(TXsheet *xsh, double frame, const TRenderSettings &info)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TFxSet *fxs = xsh->getFxDag()->getTerminalFxs();
Toshihiro Shimizu 890ddd
	std::string alias;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Add the alias for each
Toshihiro Shimizu 890ddd
	for (int i = 0; i < fxs->getFxCount(); ++i) {
Toshihiro Shimizu 890ddd
		TRasterFx *fx = dynamic_cast<trasterfx *="">(fxs->getFx(i));</trasterfx>
Toshihiro Shimizu 890ddd
		assert(fx);
Toshihiro Shimizu 890ddd
		if (!fx)
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		alias += fx->getAlias(frame, info) + ";";
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return alias;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
//    Local namespace  -  Colormap (Sandor) Fxs stuff
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
bool vectorMustApplyCmappedFx(const std::vector<trasterfxrenderdatap> &fxs)</trasterfxrenderdatap>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	std::vector<trasterfxrenderdatap>::const_iterator ft, fEnd(fxs.end());</trasterfxrenderdatap>
Toshihiro Shimizu 890ddd
	for (ft = fxs.begin(); ft != fEnd; ++ft) {
Toshihiro Shimizu 890ddd
		PaletteFilterFxRenderData *paletteFilterData = dynamic_cast<palettefilterfxrenderdata *="">(ft->getPointer());</palettefilterfxrenderdata>
Toshihiro Shimizu 890ddd
		SandorFxRenderData *sandorData = dynamic_cast<sandorfxrenderdata *="">(ft->getPointer());</sandorfxrenderdata>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// (Daniele) Sandor fxs perform on raster colormaps *only* - while texture fxs use palette filters to work.
Toshihiro Shimizu 890ddd
		// In the latter case, vector-to-colormap conversion makes sure that regions are not rendered under full ink
Toshihiro Shimizu 890ddd
		// pixels (which causes problems**).
Toshihiro Shimizu 890ddd
		if (sandorData || (paletteFilterData && paletteFilterData->m_type != ::eApplyToInksAndPaints))
Toshihiro Shimizu 890ddd
			return true;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/*
Toshihiro Shimizu 890ddd
      (Daniele) Disregarding the above reasons - palette filter fxs do not forcibly return true.
Toshihiro Shimizu 890ddd
      
Toshihiro Shimizu 890ddd
      Err... ok, my fault - when I wrote that, I forgot to specify WHICH problems** occurred. Whops!
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
      Now, it happens that if palette filters DO NOT convert to colormapped forcedly, special styles can be
Toshihiro Shimizu 890ddd
      retained... so, let's see what happens.
Toshihiro Shimizu 890ddd
      
Toshihiro Shimizu 890ddd
      Will have to inquire further, though...
Toshihiro Shimizu 890ddd
    */
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
bool mustApplySandorFx(const std::vector<trasterfxrenderdatap> &fxs)</trasterfxrenderdatap>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	std::vector<trasterfxrenderdatap>::const_iterator ft, fEnd(fxs.end());</trasterfxrenderdatap>
Toshihiro Shimizu 890ddd
	for (ft = fxs.begin(); ft != fEnd; ++ft) {
Toshihiro Shimizu 890ddd
		SandorFxRenderData *sandorData = dynamic_cast<sandorfxrenderdata *="">(ft->getPointer());</sandorfxrenderdata>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (sandorData)
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
Shinya Kitaoka 3bfa54
int getEnlargement(const std::vector<trasterfxrenderdatap> &fxs, double scale)</trasterfxrenderdatap>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int enlargement = 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::vector<trasterfxrenderdatap>::const_iterator ft, fEnd(fxs.end());</trasterfxrenderdatap>
Toshihiro Shimizu 890ddd
	for (ft = fxs.begin(); ft != fEnd; ++ft) {
Toshihiro Shimizu 890ddd
		SandorFxRenderData *sandorData = dynamic_cast<sandorfxrenderdata *="">(ft->getPointer());</sandorfxrenderdata>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (sandorData) {
Toshihiro Shimizu 890ddd
			switch (sandorData->m_type) {
Toshihiro Shimizu 890ddd
			case BlendTz: {
Toshihiro Shimizu 890ddd
				//Nothing happen, unless we have color 0 among the blended ones. In such case,
Toshihiro Shimizu 890ddd
				//we have to enlarge the bbox proportionally to the amount param.
Shinya Kitaoka 3bfa54
				std::vector<std::string> items;</std::string>
Shinya Kitaoka 3bfa54
				std::string indexes = std::string(sandorData->m_argv[0]);
Toshihiro Shimizu 890ddd
				parseIndexes(indexes, items);
Toshihiro Shimizu 890ddd
				PaletteFilterFxRenderData paletteFilterData;
Toshihiro Shimizu 890ddd
				insertIndexes(items, &paletteFilterData);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				if (!paletteFilterData.m_colors.empty() && *paletteFilterData.m_colors.begin() == 0) {
Toshihiro Shimizu 890ddd
					BlendTzParams ¶ms = sandorData->m_blendParams;
Toshihiro Shimizu 890ddd
					enlargement = params.m_amount * scale;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				CASE Calligraphic : __OR OutBorder:
Toshihiro Shimizu 890ddd
				{
Toshihiro Shimizu 890ddd
					CalligraphicParams ¶ms = sandorData->m_callParams;
Toshihiro Shimizu 890ddd
					enlargement = params.m_thickness * scale;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				CASE ArtAtContour:
Toshihiro Shimizu 890ddd
				{
Toshihiro Shimizu 890ddd
					ArtAtContourParams ¶ms = sandorData->m_contourParams;
Toshihiro Shimizu 890ddd
					enlargement =
Toshihiro Shimizu 890ddd
						tmax(tceil(sandorData->m_controllerBBox.getLx()), tceil(sandorData->m_controllerBBox.getLy())) *
Toshihiro Shimizu 890ddd
						params.m_maxSize;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return enlargement;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void applyPaletteFilter(TPalette *&plt, bool keep, const set<int> &colors, const TPalette *srcPlt)</int>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (colors.empty())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!plt)
Toshihiro Shimizu 890ddd
		plt = srcPlt->clone();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (keep) {
Toshihiro Shimizu 890ddd
		for (int i = 0; i < plt->getStyleCount(); ++i) {
Toshihiro Shimizu 890ddd
			if (colors.find(i) == colors.end())
Toshihiro Shimizu 890ddd
				plt->setStyle(i, TPixel32::Transparent);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		std::set<int>::const_iterator ct, cEnd(colors.end());</int>
Toshihiro Shimizu 890ddd
		for (ct = colors.begin(); ct != cEnd; ++ct) {
Toshihiro Shimizu 890ddd
			TColorStyle *style = plt->getStyle(*ct);
Toshihiro Shimizu 890ddd
			if (style)
Toshihiro Shimizu 890ddd
				plt->setStyle(*ct, TPixel32::Transparent);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPalette *getPliPalette(const TFilePath &path)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TLevelReaderP levelReader = TLevelReaderP(path);
Toshihiro Shimizu 890ddd
	if (!levelReader.getPointer())
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TLevelP level = levelReader->loadInfo();
Toshihiro Shimizu 890ddd
	TPalette *plt = level->getPalette();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return plt ? plt->clone() : (TPalette *)0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline bool fxLess(TRasterFxRenderDataP a, TRasterFxRenderDataP b)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	SandorFxRenderData *sandorDataA = dynamic_cast<sandorfxrenderdata *="">(a.getPointer());</sandorfxrenderdata>
Toshihiro Shimizu 890ddd
	if (!sandorDataA)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	SandorFxRenderData *sandorDataB = dynamic_cast<sandorfxrenderdata *="">(b.getPointer());</sandorfxrenderdata>
Toshihiro Shimizu 890ddd
	if (!sandorDataB)
Toshihiro Shimizu 890ddd
		return true;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int aIndex =
Toshihiro Shimizu 890ddd
		sandorDataA->m_type == OutBorder ? 2 : sandorDataA->m_type == BlendTz ? 1 : 0;
Toshihiro Shimizu 890ddd
	int bIndex =
Toshihiro Shimizu 890ddd
		sandorDataB->m_type == OutBorder ? 2 : sandorDataB->m_type == BlendTz ? 1 : 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return aIndex < bIndex;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
inline void sortCmappedFxs(std::vector<trasterfxrenderdatap> &fxs)</trasterfxrenderdatap>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	std::stable_sort(fxs.begin(), fxs.end(), fxLess);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
std::vector<int> getAllBut(std::vector<int> &colorIds)</int></int>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(TPixelCM32::getMaxInk() == TPixelCM32::getMaxPaint());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	std::vector<int> curColorIds;</int>
Toshihiro Shimizu 890ddd
	std::sort(colorIds.begin(), colorIds.end());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Taking all colors EXCEPT those in colorIds
Toshihiro Shimizu 890ddd
	unsigned int count1 = 0, count2 = 0;
Toshihiro Shimizu 890ddd
	int size = TPixelCM32::getMaxInk();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	curColorIds.resize(size + 1 - colorIds.size());
Toshihiro Shimizu 890ddd
	for (int i = 0; i < size; i++)
Toshihiro Shimizu 890ddd
		if (count1 < colorIds.size() && colorIds[count1] == i)
Toshihiro Shimizu 890ddd
			count1++;
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			curColorIds[count2++] = i;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return curColorIds;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! \b IMPORTANT \b NOTE: This function is now written so that the passed Toonz Image
Toshihiro Shimizu 890ddd
//! will be destroyed at the most appropriate time. You should definitely *COPY* all
Toshihiro Shimizu 890ddd
//! necessary informations before calling it - however, since the intent was that of
Toshihiro Shimizu 890ddd
//! optimizing memory usage, please avoid copying the entire image buffer...
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
TImageP applyCmappedFx(TToonzImageP &ti, const std::vector<trasterfxrenderdatap> &fxs, int frame, double scale)</trasterfxrenderdatap>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TImageP result = ti;
Toshihiro Shimizu 890ddd
	TTile resultTile; //Just a quick wrapper to the ImageCache
Toshihiro Shimizu 890ddd
	TPalette *inPalette, *tempPlt;
Toshihiro Shimizu 890ddd
	TPaletteP filteredPalette;
Toshihiro Shimizu 890ddd
	TRasterCM32P copyRas;
Shinya Kitaoka 3bfa54
	std::string cmRasCacheId;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Retrieve the image dpi
Toshihiro Shimizu 890ddd
	double dpiX, dpiY;
Toshihiro Shimizu 890ddd
	ti->getDpi(dpiX, dpiY);
Toshihiro Shimizu 890ddd
	double dpi = (dpiX > 0) ? dpiX / Stage::inch : 1.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//First, sort the fxs.
Toshihiro Shimizu 890ddd
	std::vector<trasterfxrenderdatap> fxsCopy = fxs;</trasterfxrenderdatap>
Toshihiro Shimizu 890ddd
	sortCmappedFxs(fxsCopy);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//First, let's deal with all fxs working on palettes
Toshihiro Shimizu 890ddd
	inPalette = ti->getPalette();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::vector<trasterfxrenderdatap>::reverse_iterator it;</trasterfxrenderdatap>
Toshihiro Shimizu 890ddd
	for (it = fxsCopy.rbegin(); it != fxsCopy.rend(); ++it) {
Toshihiro Shimizu 890ddd
		ExternalPaletteFxRenderData *extpltData = dynamic_cast<externalpalettefxrenderdata *="">((*it).getPointer());</externalpalettefxrenderdata>
Toshihiro Shimizu 890ddd
		PaletteFilterFxRenderData *PaletteFilterData = dynamic_cast<palettefilterfxrenderdata *="">((*it).getPointer());</palettefilterfxrenderdata>
Toshihiro Shimizu 890ddd
		if (extpltData && extpltData->m_palette) {
Toshihiro Shimizu 890ddd
			filteredPalette = extpltData->m_palette->clone();
Toshihiro Shimizu 890ddd
			filteredPalette->setFrame(frame);
Toshihiro Shimizu 890ddd
		} else if (PaletteFilterData && PaletteFilterData->m_type == eApplyToInksAndPaints) {
Toshihiro Shimizu 890ddd
			bool keep = PaletteFilterData->m_keep;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			set<int> colors;</int>
Toshihiro Shimizu 890ddd
			colors.insert(PaletteFilterData->m_colors.begin(), PaletteFilterData->m_colors.end());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			//Apply the palette filters
Toshihiro Shimizu 890ddd
			tempPlt = filteredPalette.getPointer();
Toshihiro Shimizu 890ddd
			applyPaletteFilter(tempPlt, keep, colors, inPalette);
Toshihiro Shimizu 890ddd
			filteredPalette = tempPlt;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			inPalette = filteredPalette.getPointer();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (filteredPalette) {
Toshihiro Shimizu 890ddd
		//result= ti = ti->clone();   //Is copying truly necessary??
Toshihiro Shimizu 890ddd
		result = ti = TToonzImageP(ti->getRaster(), ti->getSavebox());
Toshihiro Shimizu 890ddd
		filteredPalette->setFrame(frame);
Toshihiro Shimizu 890ddd
		ti->setPalette(filteredPalette.getPointer());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Next, deal with fxs working on colormaps themselves
Toshihiro Shimizu 890ddd
	bool firstSandorFx = true;
Toshihiro Shimizu 890ddd
	TRasterCM32P cmRas = ti->getRaster();
Toshihiro Shimizu 890ddd
	TRect tiSaveBox(ti->getSavebox());
Toshihiro Shimizu 890ddd
	TPaletteP tiPalette(ti->getPalette());
Toshihiro Shimizu 890ddd
	ti = 0; //Release the reference to colormap
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Now, apply cmapped->cmapped fxs
Toshihiro Shimizu 890ddd
	for (it = fxsCopy.rbegin(); it != fxsCopy.rend(); ++it) {
Toshihiro Shimizu 890ddd
		PaletteFilterFxRenderData *PaletteFilterData = dynamic_cast<palettefilterfxrenderdata *="">(it->getPointer());</palettefilterfxrenderdata>
Toshihiro Shimizu 890ddd
		if (PaletteFilterData && PaletteFilterData->m_type != eApplyToInksAndPaints) {
Shinya Kitaoka 3bfa54
			std::vector<int> indexes;</int>
Toshihiro Shimizu 890ddd
			indexes.resize(PaletteFilterData->m_colors.size());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			set<int>::const_iterator jt = PaletteFilterData->m_colors.begin();</int>
Toshihiro Shimizu 890ddd
			for (int j = 0; j < (int)indexes.size(); ++j, ++jt)
Toshihiro Shimizu 890ddd
				indexes[j] = *jt;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (copyRas == TRasterCM32P())
Toshihiro Shimizu 890ddd
				copyRas = cmRas->clone(); //Pixels are literally cleared on a copy buffer
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			/*-- 処理するIndexを反転 --*/
Toshihiro Shimizu 890ddd
			if (PaletteFilterData->m_keep)
Toshihiro Shimizu 890ddd
				indexes = getAllBut(indexes);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			/*-- Paintの消去("Lines Including All Areas"のみ、Areaに何も操作をしない) --*/
Toshihiro Shimizu 890ddd
			if (PaletteFilterData->m_type != eApplyToInksKeepingAllPaints) //se non e' eApplyToInksKeepingAllPaints, sicuramente devo cancellare dei paint
Toshihiro Shimizu 890ddd
				TRop::eraseColors(copyRas, PaletteFilterData->m_type == eApplyToInksDeletingAllPaints ? 0 : &indexes, false);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			/*-- Inkの消去 --*/
Toshihiro Shimizu 890ddd
			if (PaletteFilterData->m_type != eApplyToPaintsKeepingAllInks) //se non e' eApplyToPaintsKeepingAllInks, sicuramente devo cancellare degli ink
Toshihiro Shimizu 890ddd
				TRop::eraseColors(copyRas, PaletteFilterData->m_type == eApplyToPaintsDeletingAllInks ? 0 : &indexes, true);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (copyRas) {
Toshihiro Shimizu 890ddd
		cmRas = copyRas;
Toshihiro Shimizu 890ddd
		result = TToonzImageP(cmRas, tiSaveBox);
Toshihiro Shimizu 890ddd
		result->setPalette(tiPalette.getPointer());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Finally, apply cmapped->fullcolor fxs
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Prefetch all Blend fxs
Toshihiro Shimizu 890ddd
	std::vector<blendparam> blendParams;</blendparam>
Toshihiro Shimizu 890ddd
	for (it = fxsCopy.rbegin(); it != fxsCopy.rend(); ++it) {
Toshihiro Shimizu 890ddd
		SandorFxRenderData *sandorData = dynamic_cast<sandorfxrenderdata *="">(it->getPointer());</sandorfxrenderdata>
Toshihiro Shimizu 890ddd
		if (sandorData && sandorData->m_type == BlendTz) {
Toshihiro Shimizu 890ddd
			BlendParam param;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			param.intensity = toDouble(std::string(sandorData->m_argv[3])) * scale * dpi;
Toshihiro Shimizu 890ddd
			param.smoothness = sandorData->m_blendParams.m_smoothness;
Toshihiro Shimizu 890ddd
			param.stopAtCountour = sandorData->m_blendParams.m_noBlending;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			param.superSampling = sandorData->m_blendParams.m_superSampling;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			//Build the color indexes
Shinya Kitaoka 3bfa54
			std::vector<std::string> items;</std::string>
Shinya Kitaoka 3bfa54
			std::string indexes = std::string(sandorData->m_argv[0]);
Toshihiro Shimizu 890ddd
			parseIndexes(indexes, items);
Toshihiro Shimizu 890ddd
			PaletteFilterFxRenderData paletteFilterData;
Toshihiro Shimizu 890ddd
			insertIndexes(items, &paletteFilterData);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			param.colorsIndexes.reserve(paletteFilterData.m_colors.size());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			std::set<int>::iterator it;</int>
Toshihiro Shimizu 890ddd
			for (it = paletteFilterData.m_colors.begin(); it != paletteFilterData.m_colors.end(); ++it)
Toshihiro Shimizu 890ddd
				param.colorsIndexes.push_back(*it);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			blendParams.push_back(param);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Apply each sandor
Toshihiro Shimizu 890ddd
	for (it = fxsCopy.rbegin(); it != fxsCopy.rend(); ++it) {
Toshihiro Shimizu 890ddd
		SandorFxRenderData *sandorData = dynamic_cast<sandorfxrenderdata *="">(it->getPointer());</sandorfxrenderdata>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (sandorData) {
Toshihiro Shimizu 890ddd
			//Avoid dealing with specific cases
Toshihiro Shimizu 890ddd
			if ((sandorData->m_type == BlendTz && blendParams.empty()) ||
Toshihiro Shimizu 890ddd
				(sandorData->m_type == OutBorder && !firstSandorFx))
Toshihiro Shimizu 890ddd
				continue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (!firstSandorFx) {
Toshihiro Shimizu 890ddd
				//Retrieve the colormap from cache
Toshihiro Shimizu 890ddd
				cmRas = TToonzImageP(TImageCache::instance()->get(cmRasCacheId, true))->getRaster();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				//Apply a palette filter in order to keep only the colors specified in the sandor argv
Shinya Kitaoka 3bfa54
				std::vector<std::string> items;</std::string>
Shinya Kitaoka 3bfa54
				std::string indexes = std::string(sandorData->m_argv[0]);
Toshihiro Shimizu 890ddd
				parseIndexes(indexes, items);
Toshihiro Shimizu 890ddd
				PaletteFilterFxRenderData paletteFilterData;
Toshihiro Shimizu 890ddd
				insertIndexes(items, &paletteFilterData);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				filteredPalette = tempPlt = 0;
Toshihiro Shimizu 890ddd
				applyPaletteFilter(tempPlt, true, paletteFilterData.m_colors, tiPalette.getPointer());
Toshihiro Shimizu 890ddd
				filteredPalette = tempPlt;
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				//Pass the input colormap to the cache and release its reference as final result
Toshihiro Shimizu 890ddd
				cmRasCacheId = TImageCache::instance()->getUniqueId();
Toshihiro Shimizu 890ddd
				TImageCache::instance()->add(cmRasCacheId, TToonzImageP(cmRas, tiSaveBox));
Toshihiro Shimizu 890ddd
				result = 0;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			//Convert current smart pointers to a 4.6 'fashion'. The former ones are released - so they
Toshihiro Shimizu 890ddd
			//do not occupy smart object references.
Toshihiro Shimizu 890ddd
			RASTER *oldRasterIn, *oldRasterOut;
Toshihiro Shimizu 890ddd
			oldRasterIn = TRop::convertRaster50to46(cmRas, filteredPalette ? filteredPalette : tiPalette.getPointer());
Toshihiro Shimizu 890ddd
			cmRas = TRasterCM32P(0);
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
				TRaster32P rasterOut(TDimension(oldRasterIn->lx, oldRasterIn->ly));
Toshihiro Shimizu 890ddd
				oldRasterOut = TRop::convertRaster50to46(rasterOut, 0);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			switch (sandorData->m_type) {
Toshihiro Shimizu 890ddd
			case BlendTz: {
Toshihiro Shimizu 890ddd
				if (blendParams.empty())
Toshihiro Shimizu 890ddd
					continue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				//Retrieve the colormap from cache
Toshihiro Shimizu 890ddd
				cmRas = TToonzImageP(TImageCache::instance()->get(cmRasCacheId, true))->getRaster();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				TToonzImageP ti(cmRas, tiSaveBox);
Toshihiro Shimizu 890ddd
				ti->setPalette(filteredPalette ? filteredPalette.getPointer() : tiPalette.getPointer());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				TRasterImageP riOut(TImageCache::instance()->get(std::string(oldRasterOut->cacheId, oldRasterOut->cacheIdLength), true));
Toshihiro Shimizu 890ddd
				TRaster32P rasterOut = riOut->getRaster();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				blend(ti, rasterOut, blendParams);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				blendParams.clear();
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
				CASE Calligraphic : __OR OutBorder:
Toshihiro Shimizu 890ddd
				{
Toshihiro Shimizu 890ddd
					if (sandorData->m_type == OutBorder && !firstSandorFx)
Toshihiro Shimizu 890ddd
						continue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					const char *argv[12];
Toshihiro Shimizu 890ddd
					memcpy(argv, sandorData->m_argv, 12 * sizeof(const char *));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					double thickness = toDouble(std::string(sandorData->m_argv[7])) * scale * dpi;
Toshihiro Shimizu 890ddd
					argv[7] = strsave(toString(thickness).c_str());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					calligraph(oldRasterIn, oldRasterOut, sandorData->m_border, sandorData->m_argc,
Toshihiro Shimizu 890ddd
							   argv, sandorData->m_shrink, sandorData->m_type == OutBorder);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
				CASE ArtAtContour:
Toshihiro Shimizu 890ddd
				{
Toshihiro Shimizu 890ddd
					const char *argv[12];
Toshihiro Shimizu 890ddd
					memcpy(argv, sandorData->m_argv, 12 * sizeof(const char *));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					double distance = toDouble(std::string(sandorData->m_argv[6])) * scale * dpi;
Toshihiro Shimizu 890ddd
					argv[6] = strsave(toString(distance).c_str());
Toshihiro Shimizu 890ddd
					distance = toDouble(std::string(sandorData->m_argv[7])) * scale * dpi;
Toshihiro Shimizu 890ddd
					argv[7] = strsave(toString(distance).c_str());
Toshihiro Shimizu 890ddd
					double density = toDouble(std::string(sandorData->m_argv[8])) / sq(scale * dpi);
Toshihiro Shimizu 890ddd
					argv[8] = strsave(toString(density).c_str());
Toshihiro Shimizu 890ddd
					double size = toDouble(std::string(sandorData->m_argv[1])) * scale * dpi;
Toshihiro Shimizu 890ddd
					argv[1] = strsave(toString(size).c_str());
Toshihiro Shimizu 890ddd
					size = toDouble(std::string(sandorData->m_argv[2])) * scale * dpi;
Toshihiro Shimizu 890ddd
					argv[2] = strsave(toString(size).c_str());
Toshihiro Shimizu 890ddd
					RASTER *imgContour = TRop::convertRaster50to46(sandorData->m_controller, 0);
Toshihiro Shimizu 890ddd
					patternmap(oldRasterIn, oldRasterOut, sandorData->m_border, sandorData->m_argc,
Toshihiro Shimizu 890ddd
							   argv, sandorData->m_shrink, imgContour);
Toshihiro Shimizu 890ddd
					TRop::releaseRaster46(imgContour);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			DEFAULT:
Toshihiro Shimizu 890ddd
				assert(false);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TRasterImageP riOut(TImageCache::instance()->get(std::string(oldRasterOut->cacheId, oldRasterOut->cacheIdLength), true));
Toshihiro Shimizu 890ddd
			TRaster32P rasterOut = riOut->getRaster();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TRop::releaseRaster46(oldRasterIn);
Toshihiro Shimizu 890ddd
			TRop::releaseRaster46(oldRasterOut);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (firstSandorFx) {
Toshihiro Shimizu 890ddd
				resultTile.setRaster(rasterOut);
Toshihiro Shimizu 890ddd
				firstSandorFx = false;
Toshihiro Shimizu 890ddd
			} else
Toshihiro Shimizu 890ddd
				TRop::over(resultTile.getRaster(), rasterOut);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Release cmRas cache identifier if any
Toshihiro Shimizu 890ddd
	TImageCache::instance()->remove(cmRasCacheId);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!result)
Toshihiro Shimizu 890ddd
		result = TRasterImageP(resultTile.getRaster());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return result;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
void applyCmappedFx(TVectorImageP &vi, const std::vector<trasterfxrenderdatap> &fxs, int frame)</trasterfxrenderdatap>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRasterP ras;
Toshihiro Shimizu 890ddd
	bool keep = false;
Toshihiro Shimizu 890ddd
	TPaletteP modPalette;
Toshihiro Shimizu 890ddd
	set<int> colors;</int>
Toshihiro Shimizu 890ddd
	std::vector<trasterfxrenderdatap>::const_iterator it = fxs.begin();</trasterfxrenderdatap>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//prima tutti gli effetti che agiscono sulla paletta....
Toshihiro Shimizu 890ddd
	for (; it != fxs.end(); ++it) {
Toshihiro Shimizu 890ddd
		ExternalPaletteFxRenderData *extpltData = dynamic_cast<externalpalettefxrenderdata *="">((*it).getPointer());</externalpalettefxrenderdata>
Toshihiro Shimizu 890ddd
		PaletteFilterFxRenderData *pltFilterData = dynamic_cast<palettefilterfxrenderdata *="">((*it).getPointer());</palettefilterfxrenderdata>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (extpltData && extpltData->m_palette)
Toshihiro Shimizu 890ddd
			modPalette = extpltData->m_palette->clone();
Toshihiro Shimizu 890ddd
		else if (pltFilterData) {
Toshihiro Shimizu 890ddd
			assert(pltFilterData->m_type == eApplyToInksAndPaints); // Must have been converted to CM32 otherwise
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			keep = pltFilterData->m_keep;
Toshihiro Shimizu 890ddd
			colors.insert(pltFilterData->m_colors.begin(), pltFilterData->m_colors.end());
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPalette *tempPlt = modPalette.getPointer();
Toshihiro Shimizu 890ddd
	applyPaletteFilter(tempPlt, keep, colors, vi->getPalette());
Toshihiro Shimizu 890ddd
	modPalette = tempPlt;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (modPalette) {
Toshihiro Shimizu 890ddd
		vi = vi->clone();
Toshihiro Shimizu 890ddd
		vi->setPalette(modPalette.getPointer());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
//    LevelFxResourceBuilder  definition
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class LevelFxBuilder : public ResourceBuilder
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRasterP m_loadedRas;
Toshihiro Shimizu 890ddd
	TPaletteP m_palette;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshSimpleLevel *m_sl;
Toshihiro Shimizu 890ddd
	TFrameId m_fid;
Toshihiro Shimizu 890ddd
	TRectD m_tileGeom;
Toshihiro Shimizu 890ddd
	bool m_64bit;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRect m_rasBounds;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 3bfa54
	LevelFxBuilder(const std::string &resourceName, double frame, const TRenderSettings &rs,
Toshihiro Shimizu 890ddd
				   TXshSimpleLevel *sl, TFrameId fid)
Toshihiro Shimizu 890ddd
		: ResourceBuilder(resourceName, 0, frame, rs), m_loadedRas(), m_palette(), m_sl(sl), m_fid(fid), m_64bit(rs.m_bpp == 64) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void setRasBounds(const TRect &rasBounds)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_rasBounds = rasBounds;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void compute(const TRectD &tileRect)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		//Load the image
Toshihiro Shimizu 890ddd
		TImageP img(m_sl->getFullsampledFrame(m_fid, (m_64bit ? ImageManager::is64bitEnabled : 0) |
Toshihiro Shimizu 890ddd
														 ImageManager::dontPutInCache));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (!img)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TRasterImageP rimg(img);
Toshihiro Shimizu 890ddd
		TToonzImageP timg(img);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_loadedRas = rimg ? (TRasterP)rimg->getRaster() : timg ? (TRasterP)timg->getRaster() : TRasterP();
Toshihiro Shimizu 890ddd
		assert(m_loadedRas);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (timg)
Toshihiro Shimizu 890ddd
			m_palette = timg->getPalette();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		assert(tileRect == TRectD(0, 0, m_loadedRas->getLx(), m_loadedRas->getLy()));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void simCompute(const TRectD &rect) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void upload(TCacheResourceP &resource)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		assert(m_loadedRas);
Toshihiro Shimizu 890ddd
		resource->upload(TPoint(), m_loadedRas);
Toshihiro Shimizu 890ddd
		if (m_palette)
Toshihiro Shimizu 890ddd
			resource->uploadPalette(m_palette);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool download(TCacheResourceP &resource)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		//If the image has been loaded in this builder, just use it
Toshihiro Shimizu 890ddd
		if (m_loadedRas)
Toshihiro Shimizu 890ddd
			return true;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//If the image has yet to be loaded by this builder, skip without
Toshihiro Shimizu 890ddd
		//allocating anything
Toshihiro Shimizu 890ddd
		if (resource->canDownloadAll(m_rasBounds)) {
Toshihiro Shimizu 890ddd
			m_loadedRas = resource->buildCompatibleRaster(m_rasBounds.getSize());
Toshihiro Shimizu 890ddd
			resource->downloadPalette(m_palette);
Toshihiro Shimizu 890ddd
			return resource->downloadAll(TPoint(), m_loadedRas);
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			return false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TImageP getImage() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (!m_loadedRas)
Toshihiro Shimizu 890ddd
			return TImageP();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TRasterCM32P cm(m_loadedRas);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TImageP result(cm ? TImageP(TToonzImageP(cm, cm->getBounds())) : TImageP(TRasterImageP(m_loadedRas)));
Toshihiro Shimizu 890ddd
		if (m_palette)
Toshihiro Shimizu 890ddd
			result->setPalette(m_palette.getPointer());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		return result;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
//    TLevelColumnFx  implementation
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TLevelColumnFx::TLevelColumnFx()
Toshihiro Shimizu 890ddd
	: m_levelColumn(0), m_isCachable(true), m_mutex(), m_offlineContext(0)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	setName(L"LevelColumn");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TLevelColumnFx::~TLevelColumnFx()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_offlineContext)
Toshihiro Shimizu 890ddd
		delete m_offlineContext;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TLevelColumnFx::canHandle(const TRenderSettings &info, double frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//NOTE 1: Currently, it is necessary that level columns return FALSE for
Toshihiro Shimizu 890ddd
	//raster levels - just a quick way to tell the cache functions that they
Toshihiro Shimizu 890ddd
	//have to be cached.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!m_levelColumn)
Toshihiro Shimizu 890ddd
		return true;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshCell cell = m_levelColumn->getCell(m_levelColumn->getFirstRow());
Toshihiro Shimizu 890ddd
	if (cell.isEmpty())
Toshihiro Shimizu 890ddd
		return true;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshSimpleLevel *sl = cell.m_level->getSimpleLevel();
Toshihiro Shimizu 890ddd
	if (!sl)
Toshihiro Shimizu 890ddd
		return true;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return (sl->getType() == PLI_XSHLEVEL && !vectorMustApplyCmappedFx(info.m_data));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TAffine TLevelColumnFx::handledAffine(const TRenderSettings &info, double frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_levelColumn)
Toshihiro Shimizu 890ddd
		return TAffine();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshCell cell = m_levelColumn->getCell(m_levelColumn->getFirstRow());
Toshihiro Shimizu 890ddd
	if (cell.isEmpty())
Toshihiro Shimizu 890ddd
		return TAffine();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshSimpleLevel *sl = cell.m_level->getSimpleLevel();
Toshihiro Shimizu 890ddd
	if (!sl)
Toshihiro Shimizu 890ddd
		return TAffine();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (sl->getType() == PLI_XSHLEVEL)
Toshihiro Shimizu 890ddd
		return vectorMustApplyCmappedFx(info.m_data) ? TRasterFx::handledAffine(info, frame) : info.m_affine;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Accept any translation consistent with the image's pixels geometry
Toshihiro Shimizu 890ddd
	TImageInfo imageInfo;
Toshihiro Shimizu 890ddd
	getImageInfo(imageInfo, sl, cell.m_frameId);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPointD pixelsOrigin(-0.5 * imageInfo.m_lx, -0.5 * imageInfo.m_ly);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const TAffine &aff = info.m_affine;
Toshihiro Shimizu 890ddd
	if (aff.a11 != 1.0 || aff.a22 != 1.0 || aff.a12 != 0.0 || aff.a21 != 0.0)
Toshihiro Shimizu 890ddd
		return TTranslation(-pixelsOrigin);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// This is a translation, ok. Just ensure it is consistent.
Toshihiro Shimizu 890ddd
	TAffine consistentAff(aff);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	consistentAff.a13 -= pixelsOrigin.x, consistentAff.a23 -= pixelsOrigin.y;
Toshihiro Shimizu 890ddd
	consistentAff.a13 = tfloor(consistentAff.a13), consistentAff.a23 = tfloor(consistentAff.a23);
Toshihiro Shimizu 890ddd
	consistentAff.a13 += pixelsOrigin.x, consistentAff.a23 += pixelsOrigin.y;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return consistentAff;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFilePath TLevelColumnFx::getPalettePath(int frame) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_levelColumn)
Toshihiro Shimizu 890ddd
		return TFilePath();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshCell cell = m_levelColumn->getCell(frame);
Toshihiro Shimizu 890ddd
	if (cell.isEmpty())
Toshihiro Shimizu 890ddd
		return TFilePath();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshSimpleLevel *sl = cell.m_level->getSimpleLevel();
Toshihiro Shimizu 890ddd
	if (!sl)
Toshihiro Shimizu 890ddd
		return TFilePath();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (sl->getType() == TZP_XSHLEVEL)
Toshihiro Shimizu 890ddd
		return sl->getScene()->decodeFilePath(sl->getPath().withNoFrame().withType("tpl"));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (sl->getType() == PLI_XSHLEVEL)
Toshihiro Shimizu 890ddd
		return sl->getScene()->decodeFilePath(sl->getPath());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return TFilePath();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPalette *TLevelColumnFx::getPalette(int frame) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_levelColumn)
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshCell cell = m_levelColumn->getCell(frame);
Toshihiro Shimizu 890ddd
	if (cell.isEmpty())
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshSimpleLevel *sl = cell.m_level->getSimpleLevel();
Toshihiro Shimizu 890ddd
	if (!sl)
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return sl->getPalette();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFx *TLevelColumnFx::clone(bool recursive) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TLevelColumnFx *clonedFx = dynamic_cast<tlevelcolumnfx *="">(TFx::clone(recursive));</tlevelcolumnfx>
Toshihiro Shimizu 890ddd
	assert(clonedFx);
Toshihiro Shimizu 890ddd
	clonedFx->m_levelColumn = m_levelColumn;
Toshihiro Shimizu 890ddd
	clonedFx->m_isCachable = m_isCachable;
Toshihiro Shimizu 890ddd
	return clonedFx;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TLevelColumnFx::doDryCompute(TRectD &rect, double frame, const TRenderSettings &info)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_levelColumn)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int row = (int)frame;
Toshihiro Shimizu 890ddd
	TXshCell cell = m_levelColumn->getCell(row);
Toshihiro Shimizu 890ddd
	if (cell.isEmpty())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshSimpleLevel *sl = cell.m_level->getSimpleLevel();
Toshihiro Shimizu 890ddd
	if (!sl)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//In case this is a vector level, the image is renderized quickly and directly at the
Toshihiro Shimizu 890ddd
	//correct resolution. Caching is disabled in such case, at the moment.
Toshihiro Shimizu 890ddd
	if (sl->getType() == PLI_XSHLEVEL)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int renderStatus = TRenderer::instance().getRenderStatus(TRenderer::renderId());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	std::string alias = getAlias(frame, TRenderSettings()) + "_image";
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TImageInfo imageInfo;
Toshihiro Shimizu 890ddd
	getImageInfo(imageInfo, sl, cell.m_frameId);
Toshihiro Shimizu 890ddd
	TRectD imgRect(0, 0, imageInfo.m_lx, imageInfo.m_ly);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (renderStatus == TRenderer::FIRSTRUN) {
Toshihiro Shimizu 890ddd
		ResourceBuilder::declareResource(alias, 0, imgRect, frame, info, false);
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		LevelFxBuilder builder(alias, frame, info, sl, cell.m_frameId);
Toshihiro Shimizu 890ddd
		builder.setRasBounds(TRect(0, 0, imageInfo.m_lx - 1, imageInfo.m_ly - 1));
Toshihiro Shimizu 890ddd
		builder.simBuild(imgRect);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool isSubsheetChainOnColumn0(TXsheet *topXsheet, TXsheet *subsheet, int frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (topXsheet == subsheet)
Toshihiro Shimizu 890ddd
		return true;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const TXshCell cell = topXsheet->getCell(frame, 0);
Toshihiro Shimizu 890ddd
	if (!cell.m_level)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	TXshChildLevel *cl = cell.m_level->getChildLevel();
Toshihiro Shimizu 890ddd
	if (!cl)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	return isSubsheetChainOnColumn0(cl->getXsheet(), subsheet, frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TLevelColumnFx::doCompute(TTile &tile, double frame, const TRenderSettings &info)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_levelColumn)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Ensure that a corresponding cell and level exists
Toshihiro Shimizu 890ddd
	int row = (int)frame;
Toshihiro Shimizu 890ddd
	TXshCell cell = m_levelColumn->getCell(row);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (cell.isEmpty())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshSimpleLevel *sl = cell.m_level->getSimpleLevel();
Toshihiro Shimizu 890ddd
	if (!sl)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TFrameId fid = cell.m_frameId;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TImageP img;
Toshihiro Shimizu 890ddd
	TImageInfo imageInfo;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Now, fetch the image
Toshihiro Shimizu 890ddd
	if (sl->getType() != PLI_XSHLEVEL) {
Toshihiro Shimizu 890ddd
		// Raster case
Toshihiro Shimizu 890ddd
		LevelFxBuilder builder(getAlias(frame, TRenderSettings()) + "_image",
Toshihiro Shimizu 890ddd
							   frame, info, sl, fid);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		getImageInfo(imageInfo, sl, fid);
Toshihiro Shimizu 890ddd
		TRectD imgRect(0, 0, imageInfo.m_lx, imageInfo.m_ly);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		builder.setRasBounds(TRect(0, 0, imageInfo.m_lx - 1, imageInfo.m_ly - 1));
Toshihiro Shimizu 890ddd
		builder.build(imgRect);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		img = builder.getImage();
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		// Vector case (loading is immediate)
Toshihiro Shimizu 890ddd
		if (!img) {
Toshihiro Shimizu 890ddd
			img = sl->getFullsampledFrame(fid, ((info.m_bpp == 64) ? ImageManager::is64bitEnabled : 0) |
Toshihiro Shimizu 890ddd
												   ImageManager::dontPutInCache);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Extract the required geometry
Toshihiro Shimizu 890ddd
	TRect tileBounds(tile.getRaster()->getBounds());
Toshihiro Shimizu 890ddd
	TRectD tileRectD = TRectD(tileBounds.x0, tileBounds.y0, tileBounds.x1 + 1, tileBounds.y1 + 1) + tile.m_pos;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//To be sure, if there is no image, return.
Toshihiro Shimizu 890ddd
	if (!img)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRectD bBox = img->getBBox();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Discriminate image type
Toshihiro Shimizu 890ddd
	if (TVectorImageP vectorImage = img) {
Toshihiro Shimizu 890ddd
		// Vector case
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (vectorMustApplyCmappedFx(info.m_data)) {
Toshihiro Shimizu 890ddd
			// Deal separately
Toshihiro Shimizu 890ddd
			applyTzpFxsOnVector(vectorImage, tile, frame, info);
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			QMutexLocker m(&m_mutex);
Toshihiro Shimizu 890ddd
			bBox = info.m_affine * vectorImage->getBBox();
Toshihiro Shimizu 890ddd
			TDimension size(tile.getRaster()->getSize());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TAffine aff =
Toshihiro Shimizu 890ddd
				TTranslation(-tile.m_pos.x, -tile.m_pos.y) *
Toshihiro Shimizu 890ddd
				TScale(1.0 / info.m_shrinkX, 1.0 / info.m_shrinkY) *
Toshihiro Shimizu 890ddd
				info.m_affine;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			applyCmappedFx(vectorImage, info.m_data, (int)frame);
Toshihiro Shimizu 890ddd
			TPalette *vpalette = vectorImage->getPalette();
Toshihiro Shimizu 890ddd
			assert(vpalette);
Toshihiro Shimizu 890ddd
			m_isCachable = !vpalette->isAnimated();
Toshihiro Shimizu 890ddd
			int oldFrame = vpalette->getFrame();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TVectorRenderData rd(TVectorRenderData::ProductionSettings(),
Toshihiro Shimizu 890ddd
								 aff, TRect(size), vpalette);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (!m_offlineContext || m_offlineContext->getLx() < size.lx || m_offlineContext->getLy() < size.ly) {
Toshihiro Shimizu 890ddd
				if (m_offlineContext)
Toshihiro Shimizu 890ddd
					delete m_offlineContext;
Toshihiro Shimizu 890ddd
				m_offlineContext = new TOfflineGL(size);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			m_offlineContext->makeCurrent();
Toshihiro Shimizu 890ddd
			m_offlineContext->clear(TPixel32(0, 0, 0, 0));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			//If level has animated palette, it is necessary to lock palette's color against
Toshihiro Shimizu 890ddd
			//concurrents TPalette::setFrame.
Toshihiro Shimizu 890ddd
			if (!m_isCachable)
Toshihiro Shimizu 890ddd
				vpalette->mutex()->lock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			vpalette->setFrame((int)frame);
Toshihiro Shimizu 890ddd
			m_offlineContext->draw(vectorImage, rd, true);
Toshihiro Shimizu 890ddd
			vpalette->setFrame(oldFrame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (!m_isCachable)
Toshihiro Shimizu 890ddd
				vpalette->mutex()->unlock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			m_offlineContext->getRaster(tile.getRaster());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			m_offlineContext->doneCurrent();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		// Raster case
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TRasterP ras;
Toshihiro Shimizu 890ddd
		TAffine aff;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TRasterImageP ri = img;
Toshihiro Shimizu 890ddd
		TToonzImageP ti = img;
Toshihiro Shimizu 890ddd
		img = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (ri) {
Toshihiro Shimizu 890ddd
			// Fullcolor case
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			ras = ri->getRaster();
Toshihiro Shimizu 890ddd
			ri = 0;
Toshihiro Shimizu 890ddd
			TRaster32P ras32(ras);
Toshihiro Shimizu 890ddd
			TRaster64P ras64(ras);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			//Ensure that ras is either a 32 or 64 fullcolor.
Toshihiro Shimizu 890ddd
			//Otherwise, we have to convert it.
Toshihiro Shimizu 890ddd
			if (!ras32 && !ras64) {
Toshihiro Shimizu 890ddd
				TRasterP tileRas(tile.getRaster());
Toshihiro Shimizu 890ddd
				TRaster32P tileRas32(tileRas);
Toshihiro Shimizu 890ddd
				TRaster64P tileRas64(tileRas);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				if (tileRas32) {
Toshihiro Shimizu 890ddd
					ras32 = TRaster32P(ras->getLx(), ras->getLy());
Toshihiro Shimizu 890ddd
					TRop::convert(ras32, ras);
Toshihiro Shimizu 890ddd
					ras = ras32;
Toshihiro Shimizu 890ddd
				} else if (tileRas64) {
Toshihiro Shimizu 890ddd
					ras64 = TRaster64P(ras->getLx(), ras->getLy());
Toshihiro Shimizu 890ddd
					TRop::convert(ras64, ras);
Toshihiro Shimizu 890ddd
					ras = ras64;
Toshihiro Shimizu 890ddd
				} else
Toshihiro Shimizu 890ddd
					assert(0);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			TXsheet *xsh = m_levelColumn->getLevelColumn()->getXsheet();
Toshihiro Shimizu 890ddd
			TXsheet *txsh = sl->getScene()->getTopXsheet();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			LevelProperties *levelProp = sl->getProperties();
Toshihiro Shimizu 890ddd
			if (Preferences::instance()->isIgnoreAlphaonColumn1Enabled() && m_levelColumn->getIndex() == 0 && isSubsheetChainOnColumn0(txsh, xsh, frame)) {
Toshihiro Shimizu 890ddd
				TRasterP appRas(ras->clone());
Toshihiro Shimizu 890ddd
				setMaxMatte(appRas);
Toshihiro Shimizu 890ddd
				ras = appRas;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			if (levelProp->doPremultiply()) {
Toshihiro Shimizu 890ddd
				TRasterP appRas = ras->clone();
Toshihiro Shimizu 890ddd
				TRop::premultiply(appRas);
Toshihiro Shimizu 890ddd
				ras = appRas;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			if (levelProp->whiteTransp()) {
Toshihiro Shimizu 890ddd
				TRasterP appRas(ras->clone());
Toshihiro Shimizu 890ddd
				TRop::whiteTransp(appRas);
Toshihiro Shimizu 890ddd
				ras = appRas;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			if (levelProp->antialiasSoftness() > 0) {
Toshihiro Shimizu 890ddd
				TRasterP appRas = ras->create(ras->getLx(), ras->getLy());
Toshihiro Shimizu 890ddd
				TRop::antialias(ras, appRas, 10, levelProp->antialiasSoftness());
Toshihiro Shimizu 890ddd
				ras = appRas;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (TXshSimpleLevel::m_fillFullColorRaster) {
Toshihiro Shimizu 890ddd
				TRasterP appRas(ras->clone());
Toshihiro Shimizu 890ddd
				FullColorAreaFiller filler(appRas);
Toshihiro Shimizu 890ddd
				TPaletteP palette = new TPalette();
Toshihiro Shimizu 890ddd
				int styleId = palette->getPage(0)->addStyle(TPixel32::White);
Toshihiro Shimizu 890ddd
				FillParameters params;
Toshihiro Shimizu 890ddd
				params.m_palette = palette.getPointer();
Toshihiro Shimizu 890ddd
				params.m_styleId = styleId;
Toshihiro Shimizu 890ddd
				params.m_minFillDepth = 0;
Toshihiro Shimizu 890ddd
				params.m_maxFillDepth = 15;
Toshihiro Shimizu 890ddd
				filler.rectFill(appRas->getBounds(), params, false);
Toshihiro Shimizu 890ddd
				ras = appRas;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		} else if (ti) {
Toshihiro Shimizu 890ddd
			// Colormap case
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			//Use the imageInfo's dpi
Toshihiro Shimizu 890ddd
			ti->setDpi(imageInfo.m_dpix, imageInfo.m_dpiy);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TImageP newImg = applyTzpFxs(ti, frame, info);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			ri = newImg;
Toshihiro Shimizu 890ddd
			ti = newImg;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (ri)
Toshihiro Shimizu 890ddd
				ras = ri->getRaster();
Toshihiro Shimizu 890ddd
			else
Toshihiro Shimizu 890ddd
				ras = ti->getRaster();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (sl->getProperties()->antialiasSoftness() > 0) {
Toshihiro Shimizu 890ddd
				TRasterP appRas = ras->create(ras->getLx(), ras->getLy());
Toshihiro Shimizu 890ddd
				TRop::antialias(ras, appRas, 10, sl->getProperties()->antialiasSoftness());
Toshihiro Shimizu 890ddd
				ras = appRas;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			ri = 0;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (ras) {
Toshihiro Shimizu 890ddd
			double lx_2 = ras->getLx() / 2.0;
Toshihiro Shimizu 890ddd
			double ly_2 = ras->getLy() / 2.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TRenderSettings infoAux(info);
Toshihiro Shimizu 890ddd
			assert(info.m_affine.isTranslation());
Toshihiro Shimizu 890ddd
			infoAux.m_data.clear();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			//Place the output rect in the image's reference
Toshihiro Shimizu 890ddd
			tileRectD += TPointD(lx_2 - info.m_affine.a13, ly_2 - info.m_affine.a23);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			//Then, retrieve loaded image's interesting region
Toshihiro Shimizu 890ddd
			TRectD inTileRectD;
Toshihiro Shimizu 890ddd
			if (ti) {
Toshihiro Shimizu 890ddd
				TRect saveBox(ti->getSavebox());
Toshihiro Shimizu 890ddd
				inTileRectD = TRectD(saveBox.x0, saveBox.y0, saveBox.x1 + 1, saveBox.y1 + 1);
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				TRect rasBounds(ras->getBounds());
Toshihiro Shimizu 890ddd
				inTileRectD = TRectD(rasBounds.x0, rasBounds.y0, rasBounds.x1 + 1, rasBounds.y1 + 1);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			//And intersect the two
Toshihiro Shimizu 890ddd
			inTileRectD *= tileRectD;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			//Should the intersection be void, return
Toshihiro Shimizu 890ddd
			if (inTileRectD.x0 >= inTileRectD.x1 || inTileRectD.y0 >= inTileRectD.y1)
Toshihiro Shimizu 890ddd
				return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			//Output that intersection in the requested tile
Toshihiro Shimizu 890ddd
			TRect inTileRect(tround(inTileRectD.x0), tround(inTileRectD.y0), tround(inTileRectD.x1) - 1, tround(inTileRectD.y1) - 1);
Toshihiro Shimizu 890ddd
			TTile inTile(ras->extract(inTileRect), inTileRectD.getP00() + TPointD(-lx_2, -ly_2));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			//Observe that inTile is in the standard reference, ie image's minus the center coordinates
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (ti) {
Toshihiro Shimizu 890ddd
				//In the colormapped case, we have to convert the cmap to fullcolor
Toshihiro Shimizu 890ddd
				TPalette *palette = ti->getPalette();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				if (!m_isCachable)
Toshihiro Shimizu 890ddd
					palette->mutex()->lock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				int prevFrame = palette->getFrame();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				palette->setFrame((int)frame);
Toshihiro Shimizu 890ddd
				TTile auxtile(TRaster32P(inTile.getRaster()->getSize()), inTile.m_pos);
Toshihiro Shimizu 890ddd
				TRop::convert(auxtile, inTile, palette, false, true);
Toshihiro Shimizu 890ddd
				palette->setFrame(prevFrame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				if (!m_isCachable)
Toshihiro Shimizu 890ddd
					palette->mutex()->unlock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				inTile.setRaster(auxtile.getRaster());
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TRasterFx::applyAffine(tile, inTile, infoAux);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TImageP TLevelColumnFx::applyTzpFxs(TToonzImageP &ti, double frame, const TRenderSettings &info)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double scale = sqrt(fabs(info.m_affine.det()));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int prevFrame = ti->getPalette()->getFrame();
Toshihiro Shimizu 890ddd
	m_isCachable = !ti->getPalette()->isAnimated();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!m_isCachable)
Toshihiro Shimizu 890ddd
		ti->getPalette()->mutex()->lock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPaletteP palette(ti->getPalette());
Toshihiro Shimizu 890ddd
	palette->setFrame((int)frame);
Toshihiro Shimizu 890ddd
	TImageP newImg = applyCmappedFx(ti, info.m_data, (int)frame, scale);
Toshihiro Shimizu 890ddd
	palette->setFrame(prevFrame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!m_isCachable)
Toshihiro Shimizu 890ddd
		palette->mutex()->unlock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return newImg;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TLevelColumnFx::applyTzpFxsOnVector(
Toshihiro Shimizu 890ddd
	const TVectorImageP &vi,
Toshihiro Shimizu 890ddd
	TTile &tile, double frame, const TRenderSettings &info)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRect tileBounds(tile.getRaster()->getBounds());
Toshihiro Shimizu 890ddd
	TRectD tileRectD = TRectD(tileBounds.x0, tileBounds.y0, tileBounds.x1 + 1, tileBounds.y1 + 1) + tile.m_pos;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Info's affine is not the identity only in case the loaded image is a vector one.
Toshihiro Shimizu 890ddd
	double scale = sqrt(fabs(info.m_affine.det()));
Toshihiro Shimizu 890ddd
	int enlargement = getEnlargement(info.m_data, scale);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Extract the vector image's groups
Toshihiro Shimizu 890ddd
	std::vector<tvectorimagep> groupsList;</tvectorimagep>
Toshihiro Shimizu 890ddd
	getGroupsList(vi, groupsList);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//For each group, apply the tzp fxs stored in info. The result is immediately converted
Toshihiro Shimizu 890ddd
	//to a raster image if necessary.
Toshihiro Shimizu 890ddd
	unsigned int i;
Toshihiro Shimizu 890ddd
	for (i = 0; i < groupsList.size(); ++i) {
Toshihiro Shimizu 890ddd
		TVectorImageP &groupVi = groupsList[i];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Extract the group's bbox.
Toshihiro Shimizu 890ddd
		TRectD groupBBox(info.m_affine * groupVi->getBBox());
Toshihiro Shimizu 890ddd
		if (!mustApplySandorFx(info.m_data))
Toshihiro Shimizu 890ddd
			groupBBox *= tileRectD;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		groupBBox = groupBBox.enlarge(enlargement);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (groupBBox.x0 >= groupBBox.x1 || groupBBox.y0 >= groupBBox.y1)
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Ensure that groupBBox and tile have the same integer geometry
Toshihiro Shimizu 890ddd
		groupBBox -= tile.m_pos;
Toshihiro Shimizu 890ddd
		groupBBox.x0 = tfloor(groupBBox.x0);
Toshihiro Shimizu 890ddd
		groupBBox.y0 = tfloor(groupBBox.y0);
Toshihiro Shimizu 890ddd
		groupBBox.x1 = tceil(groupBBox.x1);
Toshihiro Shimizu 890ddd
		groupBBox.y1 = tceil(groupBBox.y1);
Toshihiro Shimizu 890ddd
		groupBBox += tile.m_pos;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Build groupBBox's relative position to the tile
Toshihiro Shimizu 890ddd
		TPoint groupRelativePosToTile(groupBBox.x0 - tile.m_pos.x, groupBBox.y0 - tile.m_pos.y);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Convert the group to a strictly sufficient Toonz image
Toshihiro Shimizu 890ddd
		TToonzImageP groupTi = ToonzImageUtils::vectorToToonzImage(
Toshihiro Shimizu 890ddd
			groupVi, info.m_affine, groupVi->getPalette(),
Toshihiro Shimizu 890ddd
			groupBBox.getP00(), TDimension(groupBBox.getLx(), groupBBox.getLy()),
Toshihiro Shimizu 890ddd
			&info.m_data, true);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Apply the tzp fxs to the converted Toonz image
Toshihiro Shimizu 890ddd
		TImageP groupResult = applyTzpFxs(groupTi, frame, info);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//If necessary, convert the result to fullcolor
Toshihiro Shimizu 890ddd
		TRasterImageP groupRi = groupResult;
Toshihiro Shimizu 890ddd
		if (!groupRi) {
Toshihiro Shimizu 890ddd
			groupTi = groupResult;
Toshihiro Shimizu 890ddd
			assert(groupTi);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TRasterP groupTiRas(groupTi->getRaster());
Toshihiro Shimizu 890ddd
			TRaster32P tempRas(groupTiRas->getSize());
Toshihiro Shimizu 890ddd
			groupRi = TRasterImageP(tempRas);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TRop::convert(tempRas, groupTiRas, groupTi->getPalette());
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Over the group image on the output
Toshihiro Shimizu 890ddd
		TRasterP tileRas(tile.getRaster());
Toshihiro Shimizu 890ddd
		TRop::over(tileRas, groupRi->getRaster(), groupRelativePosToTile);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TLevelColumnFx::getMemoryRequirement(const TRectD &rect, double frame, const TRenderSettings &info)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//Sandor fxs are currently considered *VERY* inefficient upon tile subdivision
Toshihiro Shimizu 890ddd
	if (mustApplySandorFx(info.m_data)) {
Toshihiro Shimizu 890ddd
		return -1;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TLevelColumnFx::getImageInfo(TImageInfo &info, TXshSimpleLevel *sl, TFrameId frameId)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int type = sl->getType();
Toshihiro Shimizu 890ddd
	assert(type != PLI_XSHLEVEL);
Toshihiro Shimizu 890ddd
	if (type == PLI_XSHLEVEL)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	std::string imageId = sl->getImageId(frameId);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const TImageInfo *storedInfo = ImageManager::instance()->getInfo(imageId, ImageManager::none, 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!storedInfo) //sulle pict caricate info era nullo, ma l'immagine c'e'!
Toshihiro Shimizu 890ddd
					 // con la getFullSampleFrame riprendo   l'immagine e ricalcolo la savebox...
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		TImageP img;
Toshihiro Shimizu 890ddd
		if (!(img = sl->getFullsampledFrame(frameId, ImageManager::dontPutInCache))) {
Toshihiro Shimizu 890ddd
			assert(false);
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		info.m_lx = (int)img->getBBox().getLx();
Toshihiro Shimizu 890ddd
		info.m_ly = (int)img->getBBox().getLy();
Toshihiro Shimizu 890ddd
		info.m_x0 = info.m_y0 = 0;
Toshihiro Shimizu 890ddd
		info.m_x1 = (int)img->getBBox().getP11().x;
Toshihiro Shimizu 890ddd
		info.m_y1 = (int)img->getBBox().getP11().y;
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		info = *storedInfo;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TLevelColumnFx::doGetBBox(double frame, TRectD &bBox, const TRenderSettings &info)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//Usual preliminaries (make sure a level/cell exists, etc...)
Toshihiro Shimizu 890ddd
	if (!m_levelColumn)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int row = (int)frame;
Toshihiro Shimizu 890ddd
	const TXshCell &cell = m_levelColumn->getCell(row);
Toshihiro Shimizu 890ddd
	if (cell.isEmpty())
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshLevelP xshl = cell.m_level;
Toshihiro Shimizu 890ddd
	if (!xshl)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshSimpleLevel *sl = xshl->getSimpleLevel();
Toshihiro Shimizu 890ddd
	if (!sl)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double dpi = 1.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Discriminate for level type
Toshihiro Shimizu 890ddd
	int type = xshl->getType();
Toshihiro Shimizu 890ddd
	if (type != PLI_XSHLEVEL) {
Toshihiro Shimizu 890ddd
		TImageInfo imageInfo;
Toshihiro Shimizu 890ddd
		getImageInfo(imageInfo, sl, cell.m_frameId);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TRect imageSavebox(imageInfo.m_x0, imageInfo.m_y0, imageInfo.m_x1, imageInfo.m_y1);
Toshihiro Shimizu 890ddd
		double cx = 0.5 * imageInfo.m_lx;
Toshihiro Shimizu 890ddd
		double cy = 0.5 * imageInfo.m_ly;
Toshihiro Shimizu 890ddd
		double x0 = (imageSavebox.x0 - cx);
Toshihiro Shimizu 890ddd
		double y0 = (imageSavebox.y0 - cy);
Toshihiro Shimizu 890ddd
		double x1 = x0 + imageSavebox.getLx();
Toshihiro Shimizu 890ddd
		double y1 = y0 + imageSavebox.getLy();
Toshihiro Shimizu 890ddd
		bBox = TRectD(x0, y0, x1, y1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		dpi = imageInfo.m_dpix / Stage::inch;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		TImageP img = m_levelColumn->getCell(row).getImage(false);
Toshihiro Shimizu 890ddd
		if (!img)
Toshihiro Shimizu 890ddd
			return false;
Toshihiro Shimizu 890ddd
		bBox = img->getBBox();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Add the enlargement of the bbox due to Tzp render datas
Toshihiro Shimizu 890ddd
	if (info.m_data.size()) {
Toshihiro Shimizu 890ddd
		TRectD imageBBox(bBox);
Toshihiro Shimizu 890ddd
		for (unsigned int i = 0; i < info.m_data.size(); ++i) {
Toshihiro Shimizu 890ddd
			TRectD enlargedImageBBox = info.m_data[i]->getBBoxEnlargement(imageBBox);
Toshihiro Shimizu 890ddd
			double enlargement = enlargedImageBBox.x1 - imageBBox.x1;
Toshihiro Shimizu 890ddd
			bBox += imageBBox.enlarge(enlargement * dpi);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const TPersistDeclaration *TLevelColumnFx::getDeclaration() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return &columnFxInfo;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
std::string TLevelColumnFx::getPluginId() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return "Toonz_";
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFxTimeRegion TLevelColumnFx::getTimeRegion() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_levelColumn)
Toshihiro Shimizu 890ddd
		return TFxTimeRegion();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int first = m_levelColumn->getFirstRow();
Toshihiro Shimizu 890ddd
	int last = m_levelColumn->getRowCount();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return TFxTimeRegion(first, last);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TLevelColumnFx::setColumn(TXshLevelColumn *column)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_levelColumn = column;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
std::wstring TLevelColumnFx::getColumnId() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_levelColumn)
Toshihiro Shimizu 890ddd
		return L"Col?";
Toshihiro Shimizu 890ddd
	return L"Col" + toWideString(m_levelColumn->getIndex() + 1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
std::wstring TLevelColumnFx::getColumnName() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_levelColumn)
Toshihiro Shimizu 890ddd
		return L"";
Toshihiro Shimizu 890ddd
	int idx = getColumnIndex();
Toshihiro Shimizu 890ddd
	return toWideString(m_levelColumn->getXsheet()->getStageObject(TStageObjectId::ColumnId(idx))->getName());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
std::string TLevelColumnFx::getAlias(double frame, const TRenderSettings &info) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_levelColumn || m_levelColumn->getCell((int)frame).isEmpty())
Shinya Kitaoka 3bfa54
		return std::string();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const TXshCell &cell = m_levelColumn->getCell((int)frame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TFilePath fp;
Toshihiro Shimizu 890ddd
	TXshSimpleLevel *sl = cell.getSimpleLevel();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!sl) {
Toshihiro Shimizu 890ddd
		//Try with the sub-xsheet case
Toshihiro Shimizu 890ddd
		TXshChildLevel *childLevel = cell.m_level->getChildLevel();
Toshihiro Shimizu 890ddd
		if (childLevel)
Toshihiro Shimizu 890ddd
			return ::getAlias(childLevel->getXsheet(), frame, info);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
		return std::string();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TFilePath path = sl->getPath();
Toshihiro Shimizu 890ddd
	if (!cell.m_frameId.isNoFrame())
Toshihiro Shimizu 890ddd
		fp = path.withFrame(cell.m_frameId);
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		fp = path;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	std::string rdata;
Toshihiro Shimizu 890ddd
	std::vector<trasterfxrenderdatap>::const_iterator it = info.m_data.begin();</trasterfxrenderdatap>
Toshihiro Shimizu 890ddd
	for (; it != info.m_data.end(); ++it) {
Toshihiro Shimizu 890ddd
		TRasterFxRenderDataP data = *it;
Toshihiro Shimizu 890ddd
		if (data)
Toshihiro Shimizu 890ddd
			rdata += data->toString();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (sl->getType() == PLI_XSHLEVEL || sl->getType() == TZP_XSHLEVEL) {
Toshihiro Shimizu 890ddd
		TPalette *palette = cell.getPalette();
Toshihiro Shimizu 890ddd
		if (palette && palette->isAnimated())
Toshihiro Shimizu 890ddd
			rdata += "animatedPlt" + toString(frame);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (Preferences::instance()->isIgnoreAlphaonColumn1Enabled()) {
Toshihiro Shimizu 890ddd
		TXsheet *xsh = m_levelColumn->getLevelColumn()->getXsheet();
Toshihiro Shimizu 890ddd
		TXsheet *txsh = sl->getScene()->getTopXsheet();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (m_levelColumn->getIndex() == 0 && isSubsheetChainOnColumn0(txsh, xsh, frame))
Toshihiro Shimizu 890ddd
			rdata += "column_0";
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return getFxType() + "[" + toString(fp.getWideString()) + "," + rdata + "]";
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TLevelColumnFx::getColumnIndex() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_levelColumn ? m_levelColumn->getIndex() : -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TXshColumn *TLevelColumnFx::getXshColumn() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_levelColumn;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TLevelColumnFx::compute(TFlash &flash, int frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_levelColumn)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TImageP img = m_levelColumn->getCell(frame).getImage(false);
Toshihiro Shimizu 890ddd
	if (!img)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	flash.draw(img, 0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TAffine TLevelColumnFx::getDpiAff(int frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_levelColumn)
Toshihiro Shimizu 890ddd
		return TAffine();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshCell cell = m_levelColumn->getCell(frame);
Toshihiro Shimizu 890ddd
	if (cell.isEmpty())
Toshihiro Shimizu 890ddd
		return TAffine();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshSimpleLevel *sl = cell.m_level->getSimpleLevel();
Toshihiro Shimizu 890ddd
	TFrameId fid = cell.m_frameId;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (sl)
Toshihiro Shimizu 890ddd
		return ::getDpiAffine(sl, cell.m_frameId, true);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return TAffine();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TLevelColumnFx::saveData(TOStream &os)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(m_levelColumn);
Toshihiro Shimizu 890ddd
	TFx::saveData(os);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TLevelColumnFx::loadData(TIStream &is)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	// The internal numeric identifier is set here but not in constructors.
Toshihiro Shimizu 890ddd
	// This is *intended* as fx cloning needs to retain the original id
Toshihiro Shimizu 890ddd
	// through the fxs tree deployment procedure happening just before a
Toshihiro Shimizu 890ddd
	// render process (see scenefx.cpp).
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TFx::loadData(is);
Toshihiro Shimizu 890ddd
	setNewIdentifier();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
//    TPaletteColumnFx  implementation
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPaletteColumnFx::TPaletteColumnFx()
Toshihiro Shimizu 890ddd
	: m_paletteColumn(0)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPaletteColumnFx::~TPaletteColumnFx()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFx *TPaletteColumnFx::clone(bool recursive) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TPaletteColumnFx *clonedFx = dynamic_cast<tpalettecolumnfx *="">(TFx::clone(recursive));</tpalettecolumnfx>
Toshihiro Shimizu 890ddd
	assert(clonedFx);
Toshihiro Shimizu 890ddd
	clonedFx->m_paletteColumn = m_paletteColumn;
Toshihiro Shimizu 890ddd
	return clonedFx;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TPaletteColumnFx::doCompute(TTile &tile, double frame, const TRenderSettings &)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TPaletteColumnFx::doGetBBox(double frame, TRectD &bBox, const TRenderSettings &info)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TAffine TPaletteColumnFx::getDpiAff(int frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return TAffine();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TPaletteColumnFx::canHandle(const TRenderSettings &info, double frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFilePath TPaletteColumnFx::getPalettePath(int frame) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_paletteColumn)
Toshihiro Shimizu 890ddd
		return TFilePath();
Toshihiro Shimizu 890ddd
	TXshCell cell = m_paletteColumn->getCell(frame);
Toshihiro Shimizu 890ddd
	if (cell.isEmpty() || cell.m_level->getPaletteLevel() == 0)
Toshihiro Shimizu 890ddd
		return TFilePath();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshPaletteLevel *paletteLevel = cell.m_level->getPaletteLevel();
Toshihiro Shimizu 890ddd
	TFilePath path = paletteLevel->getPath();
Toshihiro Shimizu 890ddd
	path = paletteLevel->getScene()->decodeFilePath(path);
Toshihiro Shimizu 890ddd
	return path;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPalette *TPaletteColumnFx::getPalette(int frame) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_paletteColumn)
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
	TXshCell cell = m_paletteColumn->getCell(frame);
Toshihiro Shimizu 890ddd
	if (cell.isEmpty() || cell.m_level->getPaletteLevel() == 0)
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshPaletteLevel *paletteLevel = cell.m_level->getPaletteLevel();
Toshihiro Shimizu 890ddd
	return paletteLevel->getPalette();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const TPersistDeclaration *TPaletteColumnFx::getDeclaration() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return &paletteColumnFxInfo;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
std::string TPaletteColumnFx::getPluginId() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return "Toonz_";
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFxTimeRegion TPaletteColumnFx::getTimeRegion() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int first = 0;
Toshihiro Shimizu 890ddd
	int last = 11;
Toshihiro Shimizu 890ddd
	return TFxTimeRegion(first, last);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
std::wstring TPaletteColumnFx::getColumnName() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_paletteColumn)
Toshihiro Shimizu 890ddd
		return L"Col?";
Toshihiro Shimizu 890ddd
	return L"Col" + toWideString(m_paletteColumn->getIndex() + 1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
std::wstring TPaletteColumnFx::getColumnId() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_paletteColumn)
Toshihiro Shimizu 890ddd
		return L"Col?";
Toshihiro Shimizu 890ddd
	return L"Col" + toWideString(m_paletteColumn->getIndex() + 1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
std::string TPaletteColumnFx::getAlias(double frame, const TRenderSettings &info) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TFilePath palettePath = getPalettePath(frame);
Toshihiro Shimizu 890ddd
	return "TPaletteColumnFx[" + toString(palettePath.getWideString()) + "]";
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TPaletteColumnFx::compute(TFlash &flash, int frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TPaletteColumnFx::getColumnIndex() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_paletteColumn ? m_paletteColumn->getIndex() : -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TXshColumn *TPaletteColumnFx::getXshColumn() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_paletteColumn;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
//    TZeraryColumnFx  implementation
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TZeraryColumnFx::TZeraryColumnFx()
Toshihiro Shimizu 890ddd
	: m_zeraryFxColumn(0), m_fx(0)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	setName(L"ZeraryColumn");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TZeraryColumnFx::~TZeraryColumnFx()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_zeraryFxColumn)
Toshihiro Shimizu 890ddd
		m_zeraryFxColumn->release();
Toshihiro Shimizu 890ddd
	if (m_fx) {
Toshihiro Shimizu 890ddd
		m_fx->m_columnFx = 0;
Toshihiro Shimizu 890ddd
		m_fx->release();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TZeraryColumnFx::doCompute(TTile &tile, double frame, const TRenderSettings &info)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_zeraryFxColumn) {
Toshihiro Shimizu 890ddd
		TRasterFx *fx = dynamic_cast<trasterfx *="">(m_fx);</trasterfx>
Toshihiro Shimizu 890ddd
		if (fx)
Toshihiro Shimizu 890ddd
			fx->compute(tile, frame, info);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TZeraryColumnFx::doGetBBox(double frame, TRectD &bBox, const TRenderSettings &info)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_zeraryFxColumn) {
Toshihiro Shimizu 890ddd
		TRasterFx *fx = dynamic_cast<trasterfx *="">(m_fx);</trasterfx>
Toshihiro Shimizu 890ddd
		if (fx)
Toshihiro Shimizu 890ddd
			return fx->doGetBBox(frame, bBox, info);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const TPersistDeclaration *TZeraryColumnFx::getDeclaration() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return &zeraryColumnFxInfo;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
std::string TZeraryColumnFx::getPluginId() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return "Toonz_";
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFxTimeRegion TZeraryColumnFx::getTimeRegion() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return TFxTimeRegion(0, (std::numeric_limits<double>::max)());</double>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TZeraryColumnFx::setColumn(TXshZeraryFxColumn *column)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_zeraryFxColumn = column;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
std::wstring TZeraryColumnFx::getColumnName() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return getZeraryFx()->getName();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
std::wstring TZeraryColumnFx::getColumnId() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return getZeraryFx()->getFxId();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TZeraryColumnFx::setZeraryFx(TFx *fx)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TZeraryFx *zfx = static_cast<tzeraryfx *="">(fx);</tzeraryfx>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (fx) {
Toshihiro Shimizu 890ddd
		assert(dynamic_cast<tzeraryfx *="">(fx));</tzeraryfx>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		fx->addRef();
Toshihiro Shimizu 890ddd
		fx->setNewIdentifier(); // When adopting zerary fxs, ensure that they
Toshihiro Shimizu 890ddd
								// have a new numeric identifier
Toshihiro Shimizu 890ddd
		zfx->m_columnFx = this;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_fx) {
Toshihiro Shimizu 890ddd
		m_fx->m_columnFx = 0;
Toshihiro Shimizu 890ddd
		m_fx->release();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_fx = zfx;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
std::string TZeraryColumnFx::getAlias(double frame, const TRenderSettings &info) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return "TZeraryColumnFx[" + m_fx->getAlias(frame, info) + "]";
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TZeraryColumnFx::loadData(TIStream &is)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_fx)
Toshihiro Shimizu 890ddd
		m_fx->release();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_fx = 0;
Toshihiro Shimizu 890ddd
	TPersist *p = 0;
Toshihiro Shimizu 890ddd
	is >> p;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_fx = dynamic_cast<tzeraryfx *="">(p);</tzeraryfx>
Toshihiro Shimizu 890ddd
	if (m_fx) {
Toshihiro Shimizu 890ddd
		m_fx->addRef();
Toshihiro Shimizu 890ddd
		m_fx->m_columnFx = this;
Toshihiro Shimizu 890ddd
		m_fx->setNewIdentifier();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TFx::loadData(is);
Toshihiro Shimizu 890ddd
	setNewIdentifier(); // Same as with TColumnFx
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TZeraryColumnFx::saveData(TOStream &os)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(m_fx);
Toshihiro Shimizu 890ddd
	os << m_fx;
Toshihiro Shimizu 890ddd
	TFx::saveData(os);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TZeraryColumnFx::getColumnIndex() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_zeraryFxColumn ? m_zeraryFxColumn->getIndex() : -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TXshColumn *TZeraryColumnFx::getXshColumn() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_zeraryFxColumn;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
//    TXSheetFx  implementation
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const TPersistDeclaration *TXsheetFx::getDeclaration() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return &infoTXsheetFx;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TXsheetFx::TXsheetFx()
Toshihiro Shimizu 890ddd
	: m_fxDag(0)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	setName(L"Xsheet");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TXsheetFx::doCompute(TTile &tile, double frame, const TRenderSettings &)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TXsheetFx::doGetBBox(double frame, TRectD &bBox, const TRenderSettings &info)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
std::string TXsheetFx::getPluginId() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return "Toonz_";
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
std::string TXsheetFx::getAlias(double frame, const TRenderSettings &info) const
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 3bfa54
	std::string alias = getFxType();
Toshihiro Shimizu 890ddd
	alias += "[";
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Add each terminal fx's alias
Toshihiro Shimizu 890ddd
	TFxSet *terminalFxs = m_fxDag->getTerminalFxs();
Toshihiro Shimizu 890ddd
	int i, fxsCount = terminalFxs->getFxCount();
Toshihiro Shimizu 890ddd
	for (i = 0; i < fxsCount; ++i) {
Toshihiro Shimizu 890ddd
		alias += static_cast<trasterfx *="">(terminalFxs->getFx(i))->getAlias(frame, info) + ",";</trasterfx>
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return alias + "]";
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TXsheetFx::setFxDag(FxDag *fxDag)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_fxDag = fxDag;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
//    TOutputFx  implementation
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TOutputFx::TOutputFx()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	addInputPort("source", m_input);
Toshihiro Shimizu 890ddd
	setName(L"Output");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const TPersistDeclaration *TOutputFx::getDeclaration() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return &infoTOutputFx;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TOutputFx::doCompute(TTile &tile, double frame, const TRenderSettings &)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TOutputFx::doGetBBox(double frame, TRectD &bBox, const TRenderSettings &info)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
std::string TOutputFx::getPluginId() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return "Toonz_";
Toshihiro Shimizu 890ddd
}