Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tfxparam.h"
Toshihiro Shimizu 890ddd
#include "tparamset.h"
Toshihiro Shimizu 890ddd
#include "stdfx.h"
Toshihiro Shimizu 890ddd
#include "time.h"
Toshihiro Shimizu 890ddd
#include "trop.h"
Toshihiro Shimizu 890ddd
#include "trasterfx.h"
Toshihiro Shimizu 890ddd
#include "ttzpimagefx.h"
Toshihiro Shimizu 890ddd
#include "toonz/tdistort.h"
Toshihiro Shimizu 890ddd
#include "texturefxP.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
inline bool myIsEmpty(const TRectD &r) { return r.x0 >= r.x1 || r.y0 >= r.y1; }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class CornerPinFx final : public TStandardRasterFx {
Shinya Kitaoka 120a6e
  FX_PLUGIN_DECLARATION(CornerPinFx)
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  enum { PERSPECTIVE, BILINEAR };
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  CornerPinFx();
Shinya Kitaoka 120a6e
  ~CornerPinFx();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 38fd86
  bool doGetBBox(double frame, TRectD &bBox,
Shinya Kitaoka 38fd86
                 const TRenderSettings &info) override;
Shinya Kitaoka 473e70
  void doCompute(TTile &tile, double frame, const TRenderSettings &ri) override;
Shinya Kitaoka 38fd86
  void doDryCompute(TRectD &rect, double frame,
Shinya Kitaoka 38fd86
                    const TRenderSettings &info) override;
Shinya Kitaoka 120a6e
  int getMemoryRequirement(const TRectD &rect, double frame,
Shinya Kitaoka 473e70
                           const TRenderSettings &info) override;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void onPortConnected(TFxPort *port);
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
Shinya Kitaoka 473e70
  bool allowUserCacheOnPort(int port) override { return port != 0; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void transform(double frame, int port, const TRectD &rectOnOutput,
Shinya Kitaoka 120a6e
                 const TRenderSettings &infoOnOutput, TRectD &rectOnInput,
Shinya Kitaoka 473e70
                 TRenderSettings &infoOnInput) override;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void safeTransform(double frame, int port, const TRectD &rectOnOutput,
Shinya Kitaoka 120a6e
                     const TRenderSettings &infoOnOutput, TRectD &rectOnInput,
Shinya Kitaoka 120a6e
                     TRenderSettings &infoOnInput, TRectD &inBBox);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  TRasterFxPort m_input;
Shinya Kitaoka 120a6e
  TRasterFxPort m_texture;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TIntEnumParamP m_distortType;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TPointParamP m_p00_a;
Shinya Kitaoka 120a6e
  TPointParamP m_p00_b;
Shinya Kitaoka 120a6e
  TPointParamP m_p01_a;
Shinya Kitaoka 120a6e
  TPointParamP m_p01_b;
Shinya Kitaoka 120a6e
  TPointParamP m_p11_a;
Shinya Kitaoka 120a6e
  TPointParamP m_p11_b;
Shinya Kitaoka 120a6e
  TPointParamP m_p10_a;
Shinya Kitaoka 120a6e
  TPointParamP m_p10_b;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TBoolParamP m_deactivate;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TStringParamP m_string;
Shinya Kitaoka 120a6e
  TIntEnumParamP m_mode;
Shinya Kitaoka 120a6e
  TIntEnumParamP m_keep;
Shinya Kitaoka 120a6e
  TDoubleParamP m_value;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TAffine getPort1Affine(double frame) const;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
CornerPinFx::CornerPinFx()
Shinya Kitaoka 120a6e
    : m_distortType(new TIntEnumParam(PERSPECTIVE, "Perspective"))
Shinya Kitaoka 120a6e
    , m_deactivate(false)
Shinya Kitaoka 120a6e
    , m_string(L"1,2,3")
Shinya Kitaoka 120a6e
    , m_mode(new TIntEnumParam(SUBSTITUTE, "Texture"))
Shinya Kitaoka 120a6e
    , m_keep(new TIntEnumParam(0, "Delete"))
Shinya Kitaoka 120a6e
    , m_value(100) {
Shinya Kitaoka 120a6e
  double ext = 400.;
Shinya Kitaoka 120a6e
  double inn = 400.;
Shinya Kitaoka 120a6e
  m_p00_a    = TPointD(-ext, -ext);
Shinya Kitaoka 120a6e
  m_p00_b    = TPointD(-inn, -inn);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_p01_a = TPointD(-ext, ext);
Shinya Kitaoka 120a6e
  m_p01_b = TPointD(-inn, inn);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_p11_a = TPointD(ext, ext);
Shinya Kitaoka 120a6e
  m_p11_b = TPointD(inn, inn);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_p10_a = TPointD(ext, -ext);
Shinya Kitaoka 120a6e
  m_p10_b = TPointD(inn, -inn);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_p00_b->getX()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  m_p00_b->getY()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  m_p10_b->getX()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  m_p10_b->getY()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  m_p01_b->getX()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  m_p01_b->getY()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  m_p11_b->getX()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  m_p11_b->getY()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_p00_a->getX()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  m_p00_a->getY()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  m_p10_a->getX()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  m_p10_a->getY()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  m_p01_a->getX()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  m_p01_a->getY()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  m_p11_a->getX()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  m_p11_a->getY()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bindParam(this, "distort_type", m_distortType);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bindParam(this, "bottom_left_b", m_p00_b);
Shinya Kitaoka 120a6e
  bindParam(this, "bottom_right_b", m_p10_b);
Shinya Kitaoka 120a6e
  bindParam(this, "top_left_b", m_p01_b);
Shinya Kitaoka 120a6e
  bindParam(this, "top_right_b", m_p11_b);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bindParam(this, "bottom_left_a", m_p00_a);
Shinya Kitaoka 120a6e
  bindParam(this, "bottom_right_a", m_p10_a);
Shinya Kitaoka 120a6e
  bindParam(this, "top_left_a", m_p01_a);
Shinya Kitaoka 120a6e
  bindParam(this, "top_right_a", m_p11_a);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bindParam(this, "deactivate", m_deactivate);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bindParam(this, "indexes", m_string);
Shinya Kitaoka 120a6e
  bindParam(this, "mode", m_mode);
Shinya Kitaoka 120a6e
  bindParam(this, "keep", m_keep);
Shinya Kitaoka 120a6e
  bindParam(this, "value", m_value);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  addInputPort("source", m_input);
Shinya Kitaoka 120a6e
  addInputPort("Texture", m_texture);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_value->setValueRange(0, 100);
Shinya Kitaoka 120a6e
  m_keep->addItem(1, "Keep");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_mode->addItem(PATTERNTYPE, "Pattern");
Shinya Kitaoka 120a6e
  m_mode->addItem(ADD, "Add");
Shinya Kitaoka 120a6e
  m_mode->addItem(SUBTRACT, "Subtract");
Shinya Kitaoka 120a6e
  m_mode->addItem(MULTIPLY, "Multiply");
Shinya Kitaoka 120a6e
  m_mode->addItem(LIGHTEN, "Lighten");
Shinya Kitaoka 120a6e
  m_mode->addItem(DARKEN, "Darken");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_p00_a->getX()->setValueRange(-1000, 1000);
Shinya Kitaoka 120a6e
  m_p00_b->getX()->setValueRange(-1000, 1000);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_p00_a->getY()->setValueRange(-1000, 1000);
Shinya Kitaoka 120a6e
  m_p00_b->getY()->setValueRange(-1000, 1000);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_p01_a->getX()->setValueRange(-1000, 1000);
Shinya Kitaoka 120a6e
  m_p01_b->getX()->setValueRange(-1000, 1000);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_p01_a->getY()->setValueRange(-1000, 1000);
Shinya Kitaoka 120a6e
  m_p01_b->getY()->setValueRange(-1000, 1000);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_p11_a->getX()->setValueRange(-1000, 1000);
Shinya Kitaoka 120a6e
  m_p11_b->getX()->setValueRange(-1000, 1000);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_p11_a->getY()->setValueRange(-1000, 1000);
Shinya Kitaoka 120a6e
  m_p11_b->getY()->setValueRange(-1000, 1000);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_p10_a->getX()->setValueRange(-1000, 1000);
Shinya Kitaoka 120a6e
  m_p10_b->getX()->setValueRange(-1000, 1000);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_p10_a->getY()->setValueRange(-1000, 1000);
Shinya Kitaoka 120a6e
  m_p10_b->getY()->setValueRange(-1000, 1000);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_distortType->addItem(BILINEAR, "Bilinear");
Shinya Kitaoka 120a6e
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// ------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
CornerPinFx::~CornerPinFx() {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// ------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool CornerPinFx::doGetBBox(double frame, TRectD &bBox,
Shinya Kitaoka 120a6e
                            const TRenderSettings &info) {
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
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// ------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TAffine CornerPinFx::getPort1Affine(double frame) const {
Shinya Kitaoka 120a6e
  // Explanation: Fxs tree decomposition on n-ary fxs (n>1) works the following
Shinya Kitaoka 120a6e
  // way.
Shinya Kitaoka 120a6e
  // Fxs on port 0 are considered 'column representants' - so affines found on
Shinya Kitaoka 120a6e
  // them
Shinya Kitaoka 120a6e
  // must be passed throughout the tree hierarchy. Therefore, their inverses are
Shinya Kitaoka 120a6e
  // multiplied
Shinya Kitaoka 120a6e
  // just below the other input ports in order to push the former affine above.
Shinya Kitaoka 120a6e
  // In other words:
Shinya Kitaoka 120a6e
  //  port  0:  A -|                  ---|
Shinya Kitaoka 120a6e
  //               +--   =>              + A --
Shinya Kitaoka 120a6e
  //  port >0:  B -|         B - (Ainv) -|
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Retrieve the affine that lies just below texture's port.
Shinya Kitaoka 120a6e
  TGeometryFx *AinvFx = dynamic_cast<tgeometryfx *="">(m_texture.getFx());</tgeometryfx>
Shinya Kitaoka 120a6e
  if (!AinvFx) return TAffine();
Shinya Kitaoka 120a6e
  TGeometryFx *BFx =
Shinya Kitaoka 120a6e
      dynamic_cast<tgeometryfx *="">(AinvFx->getInputPort(0)->getFx());</tgeometryfx>
Shinya Kitaoka 120a6e
  if (!BFx) return AinvFx->getPlacement(frame);
Shinya Kitaoka 120a6e
  return AinvFx->getPlacement(frame) * BFx->getPlacement(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// ------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void CornerPinFx::transform(double frame, int port, const TRectD &rectOnOutput,
Shinya Kitaoka 120a6e
                            const TRenderSettings &infoOnOutput,
Shinya Kitaoka 120a6e
                            TRectD &rectOnInput, TRenderSettings &infoOnInput) {
Shinya Kitaoka 120a6e
  // Build the input affine
Shinya Kitaoka 120a6e
  infoOnInput = infoOnOutput;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPointD p00_b = m_p00_b->getValue(frame);
Shinya Kitaoka 120a6e
  TPointD p10_b = m_p10_b->getValue(frame);
Shinya Kitaoka 120a6e
  TPointD p01_b = m_p01_b->getValue(frame);
Shinya Kitaoka 120a6e
  TPointD p11_b = m_p11_b->getValue(frame);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPointD p00_a = m_p00_a->getValue(frame);
Shinya Kitaoka 120a6e
  TPointD p10_a = m_p10_a->getValue(frame);
Shinya Kitaoka 120a6e
  TPointD p01_a = m_p01_a->getValue(frame);
Shinya Kitaoka 120a6e
  TPointD p11_a = m_p11_a->getValue(frame);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // NOTE 1: An appropriate scale factor is sent below in the schematic,
Shinya Kitaoka 120a6e
  // depending
Shinya Kitaoka 120a6e
  // on the image distortion. For example, if the distortion brings a 2 scale
Shinya Kitaoka 120a6e
  // factor,
Shinya Kitaoka 120a6e
  // we want the same factor applied on image levels, so that their detail is
Shinya Kitaoka 120a6e
  // appropriate
Shinya Kitaoka 120a6e
  //(especially for vector images).
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double scale = 0;
Shinya Kitaoka 120a6e
  scale        = std::max(scale, norm(p10_a - p00_a) / norm(p10_b - p00_b));
Shinya Kitaoka 120a6e
  scale        = std::max(scale, norm(p01_a - p00_a) / norm(p01_b - p00_b));
Shinya Kitaoka 120a6e
  scale        = std::max(scale, norm(p11_a - p10_a) / norm(p11_b - p10_b));
Shinya Kitaoka 120a6e
  scale        = std::max(scale, norm(p11_a - p01_a) / norm(p11_b - p01_b));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TAffine A_1B(getPort1Affine(frame));
Shinya Kitaoka 120a6e
  TAffine B(infoOnOutput.m_affine * A_1B);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  scale *= sqrt(fabs(B.det()));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (infoOnOutput.m_isSwatch) {
Shinya Kitaoka 120a6e
    // Swatch viewers work out a lite version of the distort: only contractions
Shinya Kitaoka 120a6e
    // are passed below in the schematic - so that input memory load is always
Shinya Kitaoka 120a6e
    // at minimum.
Shinya Kitaoka 120a6e
    // This is allowed in order to make fx adjusts the less frustrating as
Shinya Kitaoka 120a6e
    // possible.
Shinya Kitaoka 120a6e
    if (scale > 1) scale = 1;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // NOTE 2: We further include A_1B.inv() to be applied on the level. This is
Shinya Kitaoka 120a6e
  // done to
Shinya Kitaoka 120a6e
  // counter the presence of A_1B just below this node - since it is preferable
Shinya Kitaoka 120a6e
  // to place A_1B
Shinya Kitaoka 120a6e
  // directly in the distort.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  infoOnInput.m_affine = TScale(scale) * A_1B.inv();
Shinya Kitaoka 120a6e
  // rectOnInput = (TScale(scale) * B.inv()) * rectOnOutput;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // NOTE 3: The original distortion points are intended on the source port
Shinya Kitaoka 120a6e
  // *before* applying A.
Shinya Kitaoka 120a6e
  // But we want to have them on texture port *before* applying B; so, the
Shinya Kitaoka 120a6e
  // following ref change arises:
Shinya Kitaoka 120a6e
  //  p_b = (TScale(scale) * A_1B.inv()) * p_b == infoOnInput.m_aff * p_b;
Shinya Kitaoka 120a6e
  //  p_a = (B * A_1B.inv()) * p_a == infoOnOutput.m_aff * p_a;
Shinya Kitaoka 120a6e
  // Observe that scale and B are here due to NOTES 1 and 2.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Build rectOnInput
Shinya Kitaoka 120a6e
  p00_a = infoOnOutput.m_affine * p00_a;
Shinya Kitaoka 120a6e
  p10_a = infoOnOutput.m_affine * p10_a;
Shinya Kitaoka 120a6e
  p01_a = infoOnOutput.m_affine * p01_a;
Shinya Kitaoka 120a6e
  p11_a = infoOnOutput.m_affine * p11_a;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  p00_b = infoOnInput.m_affine * p00_b;
Shinya Kitaoka 120a6e
  p10_b = infoOnInput.m_affine * p10_b;
Shinya Kitaoka 120a6e
  p01_b = infoOnInput.m_affine * p01_b;
Shinya Kitaoka 120a6e
  p11_b = infoOnInput.m_affine * p11_b;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_distortType->getValue() == PERSPECTIVE) {
Shinya Kitaoka 120a6e
    PerspectiveDistorter pd(p00_b, p10_b, p01_b, p11_b, p00_a, p10_a, p01_a,
Shinya Kitaoka 120a6e
                            p11_a);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    rectOnInput = ((TQuadDistorter *)&pd)->invMap(rectOnOutput);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    BilinearDistorter bd(p00_b, p10_b, p01_b, p11_b, p00_a, p10_a, p01_a,
Shinya Kitaoka 120a6e
                         p11_a);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    rectOnInput = ((TQuadDistorter *)&bd)->invMap(rectOnOutput);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (rectOnInput.x0 != TConsts::infiniteRectD.x0)
Shinya Kitaoka 120a6e
    rectOnInput.x0 = tfloor(rectOnInput.x0);
Shinya Kitaoka 120a6e
  if (rectOnInput.y0 != TConsts::infiniteRectD.y0)
Shinya Kitaoka 120a6e
    rectOnInput.y0 = tfloor(rectOnInput.y0);
Shinya Kitaoka 120a6e
  if (rectOnInput.x1 != TConsts::infiniteRectD.x1)
Shinya Kitaoka 120a6e
    rectOnInput.x1 = tceil(rectOnInput.x1);
Shinya Kitaoka 120a6e
  if (rectOnInput.y1 != TConsts::infiniteRectD.y1)
Shinya Kitaoka 120a6e
    rectOnInput.y1 = tceil(rectOnInput.y1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// ------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void CornerPinFx::safeTransform(double frame, int port,
Shinya Kitaoka 120a6e
                                const TRectD &rectOnOutput,
Shinya Kitaoka 120a6e
                                const TRenderSettings &infoOnOutput,
Shinya Kitaoka 120a6e
                                TRectD &rectOnInput,
Shinya Kitaoka 120a6e
                                TRenderSettings &infoOnInput, TRectD &inBBox) {
Shinya Kitaoka 120a6e
  assert(port == 1 && m_texture.isConnected());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_deactivate->getValue()) {
Shinya Kitaoka 120a6e
    infoOnInput = infoOnOutput;
Shinya Kitaoka 120a6e
    rectOnInput = rectOnOutput;
Shinya Kitaoka 120a6e
    m_texture->getBBox(frame, inBBox, infoOnInput);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Avoid the singular matrix cases
Shinya Kitaoka 120a6e
  if (fabs(infoOnOutput.m_affine.det()) < 1.e-3) {
Shinya Kitaoka 120a6e
    infoOnInput = infoOnOutput;
Shinya Kitaoka 120a6e
    rectOnInput.empty();
Shinya Kitaoka 120a6e
    m_texture->getBBox(frame, inBBox, infoOnInput);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  transform(frame, port, rectOnOutput, infoOnOutput, rectOnInput, infoOnInput);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_texture->getBBox(frame, inBBox, infoOnInput);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // In case inBBox is infinite, such as with gradients, also intersect with the
Shinya Kitaoka 120a6e
  // input quadrilateral's bbox
Shinya Kitaoka 120a6e
  if (inBBox == TConsts::infiniteRectD) {
Shinya Kitaoka 120a6e
    TPointD affP00_b(infoOnInput.m_affine * m_p00_b->getValue(frame));
Shinya Kitaoka 120a6e
    TPointD affP10_b(infoOnInput.m_affine * m_p10_b->getValue(frame));
Shinya Kitaoka 120a6e
    TPointD affP01_b(infoOnInput.m_affine * m_p01_b->getValue(frame));
Shinya Kitaoka 120a6e
    TPointD affP11_b(infoOnInput.m_affine * m_p11_b->getValue(frame));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TRectD source;
Shinya Kitaoka 120a6e
    source.x0 = std::min({affP00_b.x, affP10_b.x, affP01_b.x, affP11_b.x});
Shinya Kitaoka 120a6e
    source.y0 = std::min({affP00_b.y, affP10_b.y, affP01_b.y, affP11_b.y});
Shinya Kitaoka 120a6e
    source.x1 = std::max({affP00_b.x, affP10_b.x, affP01_b.x, affP11_b.x});
Shinya Kitaoka 120a6e
    source.y1 = std::max({affP00_b.y, affP10_b.y, affP01_b.y, affP11_b.y});
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    rectOnInput *= source;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// ------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void CornerPinFx::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
  std::vector<std::string> items;</std::string>
Shinya Kitaoka 120a6e
  std::string indexes = ::to_string(m_string->getValue());
Shinya Kitaoka 120a6e
  parseIndexes(indexes, items);
Shinya Kitaoka 120a6e
  TRenderSettings ri2(ri);
Shinya Kitaoka 120a6e
  PaletteFilterFxRenderData *PaletteFilterData = new PaletteFilterFxRenderData;
Shinya Kitaoka 120a6e
  TRasterFxRenderDataP smartP(PaletteFilterData);
Shinya Kitaoka 120a6e
  insertIndexes(items, PaletteFilterData);
Shinya Kitaoka 120a6e
  PaletteFilterData->m_keep = (m_keep->getValue() == 1);
Shinya Kitaoka 120a6e
  ri2.m_data.push_back(PaletteFilterData);
Shinya Kitaoka 120a6e
  ri2.m_userCachable = false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // First child compute: part of output that IS NOT texturized
Shinya Kitaoka 120a6e
  m_input->dryCompute(rect, frame, ri2);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!m_texture.isConnected()) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool isSwatch                = ri2.m_isSwatch;
Shinya Kitaoka 120a6e
  if (isSwatch) ri2.m_isSwatch = false;
Shinya Kitaoka 120a6e
  PaletteFilterData->m_keep    = !(m_keep->getValue() == 1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Second child compute: part of output that IS to be texturized
Shinya Kitaoka 120a6e
  m_input->dryCompute(rect, frame, ri2);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Deal with the texture
Shinya Kitaoka 120a6e
  if (m_deactivate->getValue())
Shinya Kitaoka 120a6e
    m_texture->dryCompute(rect, frame, ri);
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    TRectD inRect;
Shinya Kitaoka 120a6e
    TRenderSettings riNew;
Shinya Kitaoka 120a6e
    TRectD inBBox;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    safeTransform(frame, 1, rect, ri, inRect, riNew, inBBox);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    inRect *= inBBox;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (myIsEmpty(inRect)) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_texture->dryCompute(inRect, frame, riNew);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// ------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void CornerPinFx::doCompute(TTile &tile, double frame,
Shinya Kitaoka 120a6e
                            const TRenderSettings &ri) {
Shinya Kitaoka 120a6e
  if (!m_input.isConnected()) {
Shinya Kitaoka 120a6e
    tile.getRaster()->clear();
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TTile invertMaskTile;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // carico il vettore items con gli indici dei colori
Shinya Kitaoka 120a6e
  std::vector<std::string> items;</std::string>
Shinya Kitaoka 120a6e
  std::string indexes = ::to_string(m_string->getValue());
Shinya Kitaoka 120a6e
  parseIndexes(indexes, items);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // genero il tile il cui raster contiene l'immagine in input a cui sono stati
Shinya Kitaoka 120a6e
  // tolti i pixel
Shinya Kitaoka 120a6e
  // colorati con gli indici contenuti nel vettore items
Shinya Kitaoka 120a6e
  TRenderSettings ri2(ri);
Shinya Kitaoka 120a6e
  PaletteFilterFxRenderData *PaletteFilterData = new PaletteFilterFxRenderData;
Shinya Kitaoka 120a6e
  TRasterFxRenderDataP smartP(PaletteFilterData);
Shinya Kitaoka 120a6e
  insertIndexes(items, PaletteFilterData);
Shinya Kitaoka 120a6e
  PaletteFilterData->m_keep = (m_keep->getValue() == 1);
Shinya Kitaoka 120a6e
  ri2.m_data.push_back(PaletteFilterData);
Shinya Kitaoka 120a6e
  ri2.m_userCachable = false;
Shinya Kitaoka 120a6e
  m_input->allocateAndCompute(invertMaskTile, tile.m_pos,
Shinya Kitaoka 120a6e
                              tile.getRaster()->getSize(), tile.getRaster(),
Shinya Kitaoka 120a6e
                              frame, ri2);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!m_texture.isConnected()) {
Shinya Kitaoka 120a6e
    tile.getRaster()->copy(invertMaskTile.getRaster());
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // genero il tile il cui raster contiene l'immagine in input a cui sono stati
Shinya Kitaoka 120a6e
  // tolti i pixel
Shinya Kitaoka 120a6e
  // colorati con indici diversi da quelli contenuti nel vettore items
Shinya Kitaoka 120a6e
  bool isSwatch                = ri2.m_isSwatch;
Shinya Kitaoka 120a6e
  if (isSwatch) ri2.m_isSwatch = false;
Shinya Kitaoka 120a6e
  PaletteFilterData->m_keep    = !(m_keep->getValue() == 1);
Shinya Kitaoka 120a6e
  m_input->compute(tile, frame, ri2);
Shinya Kitaoka 120a6e
  if (isSwatch) ri2.m_isSwatch = true;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // controllo se ho ottenuto quaclosa su cui si possa lavorare.
Shinya Kitaoka 120a6e
  TRect saveBox;
Shinya Kitaoka 120a6e
  TRop::computeBBox(tile.getRaster(), saveBox);
Shinya Kitaoka 120a6e
  if (saveBox.isEmpty()) {
Shinya Kitaoka 120a6e
    // I guess that this case should be wiped out...
Shinya Kitaoka 120a6e
    m_input->compute(tile, frame, ri);  // Could the invertMask be copied??
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Then, generate the texture tile and make its distortion
Shinya Kitaoka 120a6e
  TTile textureTile;
Shinya Kitaoka 120a6e
  if (m_deactivate->getValue()) {
Shinya Kitaoka 120a6e
    TDimension size = tile.getRaster()->getSize();
Shinya Kitaoka 120a6e
    TPointD pos     = tile.m_pos;
Shinya Kitaoka 120a6e
    m_texture->allocateAndCompute(textureTile, pos, size, tile.getRaster(),
Shinya Kitaoka 120a6e
                                  frame, ri);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    // Build the interesting texture region
Shinya Kitaoka 120a6e
    TRasterP tileRas(tile.getRaster());
Shinya Kitaoka 120a6e
    TRectD tileRect(convert(tileRas->getBounds()) + tile.m_pos);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TRectD inRect;
Shinya Kitaoka 120a6e
    TRenderSettings riNew;
Shinya Kitaoka 120a6e
    TRectD inBBox;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    safeTransform(frame, 1, tileRect, ri, inRect, riNew, inBBox);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    inRect *= inBBox;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (myIsEmpty(inRect)) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TDimension inRectSize(tceil(inRect.getLx()), tceil(inRect.getLy()));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TTile inTile;
Shinya Kitaoka 120a6e
    m_texture->allocateAndCompute(inTile, inRect.getP00(), inRectSize, tileRas,
Shinya Kitaoka 120a6e
                                  frame, riNew);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Get the source quad
Shinya Kitaoka 120a6e
    TPointD p00_b = m_p00_b->getValue(frame);
Shinya Kitaoka 120a6e
    TPointD p10_b = m_p10_b->getValue(frame);
Shinya Kitaoka 120a6e
    TPointD p01_b = m_p01_b->getValue(frame);
Shinya Kitaoka 120a6e
    TPointD p11_b = m_p11_b->getValue(frame);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Get destination quad
Shinya Kitaoka 120a6e
    TPointD p00_a = m_p00_a->getValue(frame);
Shinya Kitaoka 120a6e
    TPointD p10_a = m_p10_a->getValue(frame);
Shinya Kitaoka 120a6e
    TPointD p01_a = m_p01_a->getValue(frame);
Shinya Kitaoka 120a6e
    TPointD p11_a = m_p11_a->getValue(frame);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    double scale = 0;
Shinya Kitaoka 120a6e
    scale        = std::max(scale, norm(p10_a - p00_a) / norm(p10_b - p00_b));
Shinya Kitaoka 120a6e
    scale        = std::max(scale, norm(p01_a - p00_a) / norm(p01_b - p00_b));
Shinya Kitaoka 120a6e
    scale        = std::max(scale, norm(p11_a - p10_a) / norm(p11_b - p10_b));
Shinya Kitaoka 120a6e
    scale        = std::max(scale, norm(p11_a - p01_a) / norm(p11_b - p01_b));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TAffine A_1B(getPort1Affine(frame));
Shinya Kitaoka 120a6e
    TAffine B(ri.m_affine * A_1B);
Shinya Kitaoka 120a6e
    scale *= sqrt(fabs(B.det()));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (ri.m_isSwatch)
Shinya Kitaoka 120a6e
      if (scale > 1) scale = 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    p00_b = riNew.m_affine * p00_b;
Shinya Kitaoka 120a6e
    p10_b = riNew.m_affine * p10_b;
Shinya Kitaoka 120a6e
    p01_b = riNew.m_affine * p01_b;
Shinya Kitaoka 120a6e
    p11_b = riNew.m_affine * p11_b;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    p00_a = ri.m_affine * p00_a;
Shinya Kitaoka 120a6e
    p10_a = ri.m_affine * p10_a;
Shinya Kitaoka 120a6e
    p01_a = ri.m_affine * p01_a;
Shinya Kitaoka 120a6e
    p11_a = ri.m_affine * p11_a;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    PerspectiveDistorter perpDistorter(
Shinya Kitaoka 120a6e
        p00_b - inTile.m_pos, p10_b - inTile.m_pos, p01_b - inTile.m_pos,
Shinya Kitaoka 120a6e
        p11_b - inTile.m_pos, p00_a, p10_a, p01_a, p11_a);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    BilinearDistorter bilDistorter(p00_b - inTile.m_pos, p10_b - inTile.m_pos,
Shinya Kitaoka 120a6e
                                   p01_b - inTile.m_pos, p11_b - inTile.m_pos,
Shinya Kitaoka 120a6e
                                   p00_a, p10_a, p01_a, p11_a);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TDistorter *distorter;
Shinya Kitaoka 120a6e
    if (m_distortType->getValue() == PERSPECTIVE)
Shinya Kitaoka 120a6e
      distorter = &perpDistorter;
Shinya Kitaoka 120a6e
    else if (m_distortType->getValue() == BILINEAR)
Shinya Kitaoka 120a6e
      distorter = &bilDistorter;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      assert(0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TRasterP textureRas(tileRas->create(tileRas->getLx(), tileRas->getLy()));
Shinya Kitaoka 120a6e
    distort(textureRas, inTile.getRaster(), *distorter, convert(tile.m_pos),
Shinya Kitaoka 120a6e
            TRop::Bilinear);
Shinya Kitaoka 120a6e
    textureTile.m_pos = tile.m_pos;
Shinya Kitaoka 120a6e
    textureTile.setRaster(textureRas);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Then, apply the texture
Shinya Kitaoka 120a6e
  double v = m_value->getValue(frame);
Shinya Kitaoka 120a6e
  if (ri.m_bpp == 32) {
Shinya Kitaoka 120a6e
    TRaster32P witheCard;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    myOver32(tile.getRaster(), invertMaskTile.getRaster(),
Shinya Kitaoka 120a6e
             &makeOpaque<tpixel32>, v);</tpixel32>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    switch (m_mode->getValue()) {
Shinya Kitaoka 120a6e
    case SUBSTITUTE:
Shinya Kitaoka 120a6e
      myOver32(tile.getRaster(), textureTile.getRaster(), &substitute<tpixel32>,</tpixel32>
Shinya Kitaoka 120a6e
               v);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case PATTERNTYPE:
Shinya Kitaoka 120a6e
      witheCard = TRaster32P(textureTile.getRaster()->getSize());
Shinya Kitaoka 120a6e
      witheCard->fill(TPixel32::White);
Shinya Kitaoka 120a6e
      TRop::over(textureTile.getRaster(), witheCard, textureTile.getRaster());
Shinya Kitaoka 120a6e
      myOver32(tile.getRaster(), textureTile.getRaster(), &pattern32, v);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case ADD:
Shinya Kitaoka 120a6e
      myOver32(tile.getRaster(), textureTile.getRaster(), &textureAdd<tpixel32>,</tpixel32>
Shinya Kitaoka 120a6e
               v / 100.0);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case SUBTRACT:
Shinya Kitaoka 120a6e
      myOver32(tile.getRaster(), textureTile.getRaster(), &textureSub<tpixel32>,</tpixel32>
Shinya Kitaoka 120a6e
               v / 100.0);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case MULTIPLY:
Shinya Kitaoka 120a6e
      myOver32(tile.getRaster(), textureTile.getRaster(),
Shinya Kitaoka 120a6e
               &textureMult<tpixel32>, v);</tpixel32>
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case DARKEN:
Shinya Kitaoka 120a6e
      myOver32(tile.getRaster(), textureTile.getRaster(),
Shinya Kitaoka 120a6e
               &textureDarken<tpixel32>, v);</tpixel32>
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case LIGHTEN:
Shinya Kitaoka 120a6e
      myOver32(tile.getRaster(), textureTile.getRaster(),
Shinya Kitaoka 120a6e
               &textureLighten<tpixel32>, v);</tpixel32>
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    default:
Shinya Kitaoka 120a6e
      assert(0);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    TRaster64P witheCard;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    myOver64(tile.getRaster(), invertMaskTile.getRaster(),
Shinya Kitaoka 120a6e
             &makeOpaque<tpixel64>, v);</tpixel64>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    switch (m_mode->getValue()) {
Shinya Kitaoka 120a6e
    case SUBSTITUTE:
Shinya Kitaoka 120a6e
      myOver64(tile.getRaster(), textureTile.getRaster(), &substitute<tpixel64>,</tpixel64>
Shinya Kitaoka 120a6e
               v);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case PATTERNTYPE:
Shinya Kitaoka 120a6e
      witheCard = TRaster64P(textureTile.getRaster()->getSize());
Shinya Kitaoka 120a6e
      witheCard->fill(TPixel64::White);
Shinya Kitaoka 120a6e
      TRop::over(textureTile.getRaster(), witheCard, textureTile.getRaster());
Shinya Kitaoka 120a6e
      myOver64(tile.getRaster(), textureTile.getRaster(), &pattern64, v);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case ADD:
Shinya Kitaoka 120a6e
      myOver64(tile.getRaster(), textureTile.getRaster(), &textureAdd<tpixel64>,</tpixel64>
Shinya Kitaoka 120a6e
               v / 100.0);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case SUBTRACT:
Shinya Kitaoka 120a6e
      myOver64(tile.getRaster(), textureTile.getRaster(), &textureSub<tpixel64>,</tpixel64>
Shinya Kitaoka 120a6e
               v / 100.0);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case MULTIPLY:
Shinya Kitaoka 120a6e
      myOver64(tile.getRaster(), textureTile.getRaster(),
Shinya Kitaoka 120a6e
               &textureMult<tpixel64>, v);</tpixel64>
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case DARKEN:
Shinya Kitaoka 120a6e
      myOver64(tile.getRaster(), textureTile.getRaster(),
Shinya Kitaoka 120a6e
               &textureDarken<tpixel64>, v);</tpixel64>
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case LIGHTEN:
Shinya Kitaoka 120a6e
      myOver64(tile.getRaster(), textureTile.getRaster(),
Shinya Kitaoka 120a6e
               &textureLighten<tpixel64>, v);</tpixel64>
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    default:
Shinya Kitaoka 120a6e
      assert(0);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRop::over(tile.getRaster(), invertMaskTile.getRaster());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int CornerPinFx::getMemoryRequirement(const TRectD &rect, double frame,
Shinya Kitaoka 120a6e
                                      const TRenderSettings &info) {
Shinya Kitaoka 120a6e
  if (!m_texture.isConnected()) return TRasterFx::memorySize(rect, info.m_bpp);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRectD inRect;
Shinya Kitaoka 120a6e
  TRenderSettings riNew;
Shinya Kitaoka 120a6e
  TRectD inBBox;
Shinya Kitaoka 120a6e
  safeTransform(frame, 1, rect, info, inRect, riNew, inBBox);
Shinya Kitaoka 120a6e
  inRect *= inBBox;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return std::max(TRasterFx::memorySize(rect, info.m_bpp),
Shinya Kitaoka 120a6e
                  TRasterFx::memorySize(inRect, riNew.m_bpp));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
TRectD CornerPinFx::getContainingBox(const FourPoints &points)
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
        if(points.m_p00==points.m_p01 && points.m_p01==points.m_p10 &&
Shinya Kitaoka 120a6e
points.m_p10==points.m_p11)
Shinya Kitaoka 120a6e
                return TRectD(points.m_p00,points.m_p00);
Shinya Kitaoka 120a6e
        double
Shinya Kitaoka 120a6e
xMax=std::max(points.m_p00.x,points.m_p01.x,points.m_p10.x,points.m_p11.x);
Shinya Kitaoka 120a6e
        double
Shinya Kitaoka 120a6e
yMax=std::max(points.m_p00.y,points.m_p01.y,points.m_p10.y,points.m_p11.y);
Shinya Kitaoka 120a6e
        double
Shinya Kitaoka 120a6e
xMin=std::min(points.m_p00.x,points.m_p01.x,points.m_p10.x,points.m_p11.x);
Shinya Kitaoka 120a6e
        double
Shinya Kitaoka 120a6e
yMin=std::min(points.m_p00.y,points.m_p01.y,points.m_p10.y,points.m_p11.y);
Shinya Kitaoka 120a6e
        return TRectD(xMin,yMin,xMax, yMax);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
// ------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FX_PLUGIN_IDENTIFIER(CornerPinFx, "cornerPinFx");