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