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