163 lines
4.5 KiB
C++
163 lines
4.5 KiB
C++
|
|
|
|
#include "stdfx.h"
|
|
#include "ttzpimagefx.h"
|
|
|
|
#include "toonz/tcolumnfx.h"
|
|
#include "toonz/txshcolumn.h"
|
|
#include "toonz/txshcell.h"
|
|
#include "toonz/txshsimplelevel.h"
|
|
#include "toonz/txshpalettelevel.h"
|
|
#include "globalcontrollablefx.h"
|
|
|
|
//===================================================================
|
|
|
|
class ExternalPaletteFx final : public GlobalControllableFx {
|
|
FX_PLUGIN_DECLARATION(ExternalPaletteFx)
|
|
|
|
TRasterFxPort m_input;
|
|
TRasterFxPort m_expalette;
|
|
|
|
public:
|
|
ExternalPaletteFx()
|
|
|
|
{
|
|
addInputPort("Source", m_input);
|
|
addInputPort("Palette", m_expalette);
|
|
}
|
|
|
|
~ExternalPaletteFx(){};
|
|
|
|
bool doGetBBox(double frame, TRectD &bBox,
|
|
const TRenderSettings &info) override {
|
|
if (m_input.isConnected()) {
|
|
bool ret = m_input->doGetBBox(frame, bBox, info);
|
|
return ret;
|
|
} else {
|
|
bBox = TRectD();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
std::string getAlias(double frame,
|
|
const TRenderSettings &info) const override;
|
|
|
|
void doDryCompute(TRectD &rect, double frame,
|
|
const TRenderSettings &info) override;
|
|
void doCompute(TTile &tile, double frame, const TRenderSettings &ri) override;
|
|
|
|
bool allowUserCacheOnPort(int port) override { return false; }
|
|
|
|
bool canHandle(const TRenderSettings &info, double frame) override {
|
|
return true;
|
|
}
|
|
};
|
|
|
|
//-------------------------------------------------------------------
|
|
|
|
namespace {
|
|
TPalette *getPalette(TXshColumn *column, int frame) {
|
|
TXshCellColumn *cellColumn = dynamic_cast<TXshCellColumn *>(column);
|
|
if (!cellColumn) return 0;
|
|
|
|
TXshCell cell = cellColumn->getCell(frame);
|
|
// This is only relevant when Implicit Holds are enabled
|
|
if (cell.isEmpty()) {
|
|
int r0, r1;
|
|
cellColumn->getRange(r0, r1);
|
|
for (int r = std::min(r1, frame); r >= r0; r--) {
|
|
cell = cellColumn->getCell(r);
|
|
if (cell.isEmpty()) continue;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (cell.isEmpty()) return 0;
|
|
|
|
TXshPaletteLevel *pl = cell.m_level->getPaletteLevel();
|
|
if (pl) return pl->getPalette();
|
|
|
|
TXshSimpleLevel *sl = cell.m_level->getSimpleLevel();
|
|
if (sl) return sl->getPalette();
|
|
|
|
return 0;
|
|
}
|
|
|
|
TPalette *getPalette(TFx *fx, double frame) {
|
|
if (!fx) return 0;
|
|
int branches;
|
|
branches = fx->getInputPortCount();
|
|
|
|
if (branches == 1) return getPalette(fx->getInputPort(0)->getFx(), frame);
|
|
|
|
if (branches > 1) return 0;
|
|
|
|
if (TColumnFx *columnFx = dynamic_cast<TColumnFx *>(fx))
|
|
return getPalette(columnFx->getXshColumn(), (int)frame);
|
|
|
|
return 0;
|
|
}
|
|
} // namespace
|
|
|
|
//-------------------------------------------------------------------
|
|
|
|
std::string ExternalPaletteFx::getAlias(double frame,
|
|
const TRenderSettings &info) const {
|
|
std::string alias(TRasterFx::getAlias(frame, info));
|
|
|
|
if (m_expalette.isConnected()) {
|
|
TFx *fx = m_expalette.getFx();
|
|
TPaletteP plt(getPalette(fx, frame));
|
|
if (plt && plt->isAnimated()) alias += std::to_string(frame);
|
|
}
|
|
|
|
return alias;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
|
|
void ExternalPaletteFx::doDryCompute(TRectD &rect, double frame,
|
|
const TRenderSettings &ri) {
|
|
if (!m_input.isConnected()) return;
|
|
|
|
if (m_expalette.isConnected()) {
|
|
TFx *fx = m_expalette.getFx();
|
|
std::string pltAlias = m_expalette->getAlias(frame, ri);
|
|
|
|
TPaletteP palette(getPalette(fx, frame));
|
|
if (palette && palette->isAnimated()) pltAlias += std::to_string(frame);
|
|
|
|
TRenderSettings ri2(ri);
|
|
ExternalPaletteFxRenderData *data =
|
|
new ExternalPaletteFxRenderData(palette, pltAlias);
|
|
ri2.m_data.push_back(data);
|
|
ri2.m_userCachable = false;
|
|
|
|
m_input->dryCompute(rect, frame, ri2);
|
|
} else
|
|
m_input->dryCompute(rect, frame, ri);
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
|
|
void ExternalPaletteFx::doCompute(TTile &tile, double frame,
|
|
const TRenderSettings &ri) {
|
|
if (!m_input.isConnected()) return;
|
|
|
|
if (m_expalette.isConnected()) {
|
|
TFx *fx = m_expalette.getFx();
|
|
std::string pltAlias = m_expalette->getAlias(frame, ri);
|
|
|
|
TPaletteP palette(getPalette(fx, frame));
|
|
if (palette && palette->isAnimated()) pltAlias += std::to_string(frame);
|
|
|
|
TRenderSettings ri2(ri);
|
|
ExternalPaletteFxRenderData *data =
|
|
new ExternalPaletteFxRenderData(palette, pltAlias);
|
|
ri2.m_data.push_back(data);
|
|
m_input->compute(tile, frame, ri2);
|
|
} else
|
|
m_input->compute(tile, frame, ri);
|
|
}
|
|
|
|
FX_PLUGIN_IDENTIFIER(ExternalPaletteFx, "externalPaletteFx");
|