Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "stdfx.h"
Toshihiro Shimizu 890ddd
#include "ttzpimagefx.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/tcolumnfx.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshcolumn.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
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class ExternalPaletteFx final : public TStandardRasterFx {
Shinya Kitaoka 120a6e
  FX_PLUGIN_DECLARATION(ExternalPaletteFx)
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRasterFxPort m_input;
Shinya Kitaoka 120a6e
  TRasterFxPort m_expalette;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  ExternalPaletteFx()
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    addInputPort("Source", m_input);
Shinya Kitaoka 120a6e
    addInputPort("Palette", m_expalette);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ~ExternalPaletteFx(){};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 38fd86
  bool doGetBBox(double frame, TRectD &bBox,
Shinya Kitaoka 38fd86
                 const TRenderSettings &info) override {
Shinya Kitaoka 120a6e
    if (m_input.isConnected()) {
Shinya Kitaoka 120a6e
      bool ret = m_input->doGetBBox(frame, bBox, info);
Shinya Kitaoka 120a6e
      return ret;
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      bBox = TRectD();
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 38fd86
  std::string getAlias(double frame,
Shinya Kitaoka 38fd86
                       const TRenderSettings &info) const override;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 38fd86
  void doDryCompute(TRectD &rect, double frame,
Shinya Kitaoka 38fd86
                    const TRenderSettings &info) override;
Shinya Kitaoka 473e70
  void doCompute(TTile &tile, double frame, const TRenderSettings &ri) override;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  bool allowUserCacheOnPort(int port) override { return false; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 38fd86
  bool canHandle(const TRenderSettings &info, double frame) override {
Shinya Kitaoka 38fd86
    return true;
Shinya Kitaoka 38fd86
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
TPalette *getPalette(TXshColumn *column, int frame) {
Shinya Kitaoka 120a6e
  TXshCellColumn *cellColumn = dynamic_cast<txshcellcolumn *="">(column);</txshcellcolumn>
Shinya Kitaoka 120a6e
  if (!cellColumn) return 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TXshCell cell = cellColumn->getCell(frame);
Shinya Kitaoka 120a6e
  if (cell.isEmpty()) return 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TXshPaletteLevel *pl = cell.m_level->getPaletteLevel();
Shinya Kitaoka 120a6e
  if (pl) return pl->getPalette();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TXshSimpleLevel *sl = cell.m_level->getSimpleLevel();
Shinya Kitaoka 120a6e
  if (sl) return sl->getPalette();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPalette *getPalette(TFx *fx, double frame) {
Shinya Kitaoka 120a6e
  if (!fx) return 0;
Shinya Kitaoka 120a6e
  int branches;
Shinya Kitaoka 120a6e
  branches = fx->getInputPortCount();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (branches == 1) return getPalette(fx->getInputPort(0)->getFx(), frame);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (branches > 1) return 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (TColumnFx *columnFx = dynamic_cast<tcolumnfx *="">(fx))</tcolumnfx>
Shinya Kitaoka 120a6e
    return getPalette(columnFx->getXshColumn(), (int)frame);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
std::string ExternalPaletteFx::getAlias(double frame,
Shinya Kitaoka 120a6e
                                        const TRenderSettings &info) const {
Shinya Kitaoka 120a6e
  std::string alias(TRasterFx::getAlias(frame, info));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_expalette.isConnected()) {
Shinya Kitaoka 120a6e
    TFx *fx = m_expalette.getFx();
Shinya Kitaoka 120a6e
    TPaletteP plt(getPalette(fx, frame));
Shinya Kitaoka 120a6e
    if (plt && plt->isAnimated()) alias += std::to_string(frame);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return alias;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ExternalPaletteFx::doDryCompute(TRectD &rect, double frame,
Shinya Kitaoka 120a6e
                                     const TRenderSettings &ri) {
Shinya Kitaoka 120a6e
  if (!m_input.isConnected()) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_expalette.isConnected()) {
Shinya Kitaoka 120a6e
    TFx *fx              = m_expalette.getFx();
Shinya Kitaoka 120a6e
    std::string pltAlias = m_expalette->getAlias(frame, ri);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TPaletteP palette(getPalette(fx, frame));
Shinya Kitaoka 120a6e
    if (palette && palette->isAnimated()) pltAlias += std::to_string(frame);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TRenderSettings ri2(ri);
Shinya Kitaoka 120a6e
    ExternalPaletteFxRenderData *data =
Shinya Kitaoka 120a6e
        new ExternalPaletteFxRenderData(palette, pltAlias);
Shinya Kitaoka 120a6e
    ri2.m_data.push_back(data);
Shinya Kitaoka 120a6e
    ri2.m_userCachable = false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    m_input->dryCompute(rect, frame, ri2);
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    m_input->dryCompute(rect, frame, ri);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ExternalPaletteFx::doCompute(TTile &tile, double frame,
Shinya Kitaoka 120a6e
                                  const TRenderSettings &ri) {
Shinya Kitaoka 120a6e
  if (!m_input.isConnected()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_expalette.isConnected()) {
Shinya Kitaoka 120a6e
    TFx *fx              = m_expalette.getFx();
Shinya Kitaoka 120a6e
    std::string pltAlias = m_expalette->getAlias(frame, ri);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TPaletteP palette(getPalette(fx, frame));
Shinya Kitaoka 120a6e
    if (palette && palette->isAnimated()) pltAlias += std::to_string(frame);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TRenderSettings ri2(ri);
Shinya Kitaoka 120a6e
    ExternalPaletteFxRenderData *data =
Shinya Kitaoka 120a6e
        new ExternalPaletteFxRenderData(palette, pltAlias);
Shinya Kitaoka 120a6e
    ri2.m_data.push_back(data);
Shinya Kitaoka 120a6e
    m_input->compute(tile, frame, ri2);
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    m_input->compute(tile, frame, ri);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FX_PLUGIN_IDENTIFIER(ExternalPaletteFx, "externalPaletteFx");