1 #ifdef _MSC_VER
2 #pragma warning(disable : 4996)
3 #endif
4
5 #include "ttzpimagefx.h"
6 #include "texception.h"
7 #include "tfxparam.h"
8 #include "stdfx.h"
9 #include "trasterfx.h"
10 #include "tspectrumparam.h"
11
12 class ArtContourFx final : public TStandardRasterFx {
13 FX_PLUGIN_DECLARATION(ArtContourFx)
14
15 TRasterFxPort m_input;
16 TRasterFxPort m_controller;
17 TStringParamP m_colorIndex;
18 TBoolParamP m_keepColor;
19 TBoolParamP m_keepLine;
20 TBoolParamP m_includeAlpha;
21 TDoubleParamP m_density;
22 TRangeParamP m_distance;
23 TBoolParamP m_randomness;
24 TRangeParamP m_orientation;
25 TRangeParamP m_size;
26
27 public:
ArtContourFx()28 ArtContourFx()
29 : m_colorIndex(L"1,2,3")
30 , m_keepColor(false)
31 , m_keepLine(false)
32 , m_includeAlpha(true)
33 , m_density(0.0)
34 , m_distance(DoublePair(30.0, 30.0))
35 , m_randomness(true)
36 , m_orientation(DoublePair(0.0, 180.0))
37 , m_size(DoublePair(30.0, 30.0)) {
38 bindParam(this, "Color_Index", m_colorIndex);
39 bindParam(this, "Keep_color", m_keepColor);
40 bindParam(this, "Keep_Line", m_keepLine);
41 bindParam(this, "Include_Alpha", m_includeAlpha);
42 bindParam(this, "Density", m_density);
43 bindParam(this, "Distance", m_distance);
44 bindParam(this, "Randomness", m_randomness);
45 bindParam(this, "Orientation", m_orientation);
46 bindParam(this, "Size", m_size);
47 addInputPort("Source", m_input);
48 addInputPort("Controller", m_controller);
49 m_density->setValueRange(0.0, 100.0);
50 m_distance->getMin()->setValueRange(0.0, 1000.0);
51 m_distance->getMax()->setValueRange(0.0, 1000.0);
52 m_orientation->getMin()->setValueRange(-180.0, 180.0);
53 m_orientation->getMax()->setValueRange(-180.0, 180.0);
54 m_orientation->getMin()->setMeasureName("angle");
55 m_orientation->getMax()->setMeasureName("angle");
56 m_size->getMin()->setValueRange(0.0, 1000.0);
57 m_size->getMax()->setValueRange(0.0, 1000.0);
58 }
59
~ArtContourFx()60 ~ArtContourFx() {}
61
62 //----------------------------------------------------------------------------
63
buildRenderData(double frame,int shrink,const TRectD & controlBox,const std::string & controllerAlias)64 SandorFxRenderData *buildRenderData(double frame, int shrink,
65 const TRectD &controlBox,
66 const std::string &controllerAlias) {
67 int argc = 12;
68 const char *argv[12];
69 argv[0] = strsave(::to_string(m_colorIndex->getValue()).c_str());
70 getValues(argv, argc, frame);
71
72 SandorFxRenderData *artContourData =
73 new SandorFxRenderData(ArtAtContour, argc, argv, 0, shrink, controlBox);
74 ArtAtContourParams ¶ms = artContourData->m_contourParams;
75 params.m_density = m_density->getValue(frame) / 100;
76 params.m_colorIndex = m_colorIndex->getValue();
77 params.m_keepLine = m_keepLine->getValue();
78 params.m_includeAlpha = m_includeAlpha->getValue();
79 params.m_maxOrientation = m_orientation->getValue(frame).second;
80 params.m_maxDistance = m_distance->getValue(frame).second / 10;
81 params.m_maxSize = m_size->getValue(frame).second / 100;
82 params.m_minOrientation = m_orientation->getValue(frame).first;
83 params.m_minDistance = m_distance->getValue(frame).first / 10;
84 params.m_minSize = m_size->getValue(frame).first / 100;
85 params.m_randomness = m_randomness->getValue();
86 params.m_keepColor = m_keepColor->getValue();
87 artContourData->m_controllerAlias = controllerAlias;
88
89 return artContourData;
90 }
91
92 //----------------------------------------------------------------------------
93
doGetBBox(double frame,TRectD & bBox,const TRenderSettings & ri)94 bool doGetBBox(double frame, TRectD &bBox,
95 const TRenderSettings &ri) override {
96 if (m_input.isConnected() && m_controller.isConnected()) {
97 TRectD controlBox, inputBox;
98
99 TRenderSettings ri2(ri);
100 ri2.m_affine = TAffine();
101
102 m_controller->getBBox(frame, controlBox, ri2);
103
104 TRenderSettings ri3(ri);
105
106 int shrink = tround((ri.m_shrinkX + ri.m_shrinkY) / 2.0);
107 // Should be there no need for the alias...
108 SandorFxRenderData *artContourData =
109 buildRenderData(frame, shrink, controlBox, "");
110 ri3.m_data.push_back(artContourData);
111
112 return m_input->doGetBBox(frame, bBox, ri3);
113 } else if (m_input.isConnected()) {
114 m_input->doGetBBox(frame, bBox, ri);
115 return false;
116 }
117 bBox = TRectD();
118 return false;
119 }
120
121 //-----------------------------------------------------------------------------
122
canHandle(const TRenderSettings & info,double frame)123 bool canHandle(const TRenderSettings &info, double frame) override {
124 return true;
125 }
126
127 //-----------------------------------------------------------------------------
128
allowUserCacheOnPort(int port)129 bool allowUserCacheOnPort(int port) override { return port != 0; }
130
131 //-----------------------------------------------------------------------------
132
133 void doDryCompute(TRectD &rect, double frame,
134 const TRenderSettings &ri) override;
135
136 //-----------------------------------------------------------------------------
137
138 void doCompute(TTile &tile, double frame, const TRenderSettings &ri) override;
139
140 //-----------------------------------------------------------------------------
141
142 private:
getValues(const char * argv[],int argc,double frame)143 void getValues(const char *argv[], int argc, double frame) {
144 double values[12];
145 values[1] = m_size->getValue(frame).second / 100;
146 values[2] = m_size->getValue(frame).first / 100;
147 values[3] = m_orientation->getValue(frame).second;
148 values[4] = m_orientation->getValue(frame).first;
149 values[5] = m_randomness->getValue() ? 1.0 : 0.0;
150 values[6] = m_distance->getValue(frame).second / 10;
151 values[7] = m_distance->getValue(frame).first / 10;
152 values[8] = m_density->getValue(frame) / 100;
153 values[9] = m_keepLine->getValue() ? 1.0 : 0.0;
154 values[10] = m_keepColor->getValue() ? 1.0 : 0.0;
155 values[11] = m_includeAlpha->getValue() ? 1.0 : 0.0;
156 convertParam(values, argv, argc);
157 }
158 //----------------------------------------------------------------------
159
strsave(const char * t)160 char *strsave(const char *t) {
161 char *s;
162 s = (char *)malloc(strlen(t) + 1);
163 strcpy(s, t);
164 return s;
165 }
166
167 //-----------------------------------------------------------------------
168
convertParam(double param[],const char * cParam[],int cParamLen)169 void convertParam(double param[], const char *cParam[], int cParamLen) {
170 std::string app;
171 for (int i = 1; i <= 11; i++) {
172 app = std::to_string(param[i]);
173 cParam[i] = strsave(app.c_str());
174 }
175 }
176 };
177
178 FX_PLUGIN_IDENTIFIER(ArtContourFx, "artContourFx");
179
180 //-----------------------------------------------------------------------------
181
doDryCompute(TRectD & rect,double frame,const TRenderSettings & ri)182 void ArtContourFx::doDryCompute(TRectD &rect, double frame,
183 const TRenderSettings &ri) {
184 if (!m_input.isConnected()) return;
185 if (!m_controller.isConnected()) return;
186
187 TRenderSettings ri2(ri);
188 ri2.m_affine = TAffine();
189
190 TRectD controlBox;
191 m_controller->getBBox(frame, controlBox, ri2);
192
193 TDimension dim = convert(controlBox).getSize();
194 TRectD controlRect(controlBox.getP00(), TDimensionD(dim.lx, dim.ly));
195
196 m_controller->dryCompute(controlRect, frame, ri2);
197
198 TRenderSettings ri3(ri);
199
200 int shrink = tround((ri.m_shrinkX + ri.m_shrinkY) / 2.0);
201 std::string controlAlias = m_controller->getAlias(frame, ri2);
202 SandorFxRenderData *artContourData =
203 buildRenderData(frame, shrink, controlBox, controlAlias);
204 ri3.m_data.push_back(artContourData);
205 ri3.m_userCachable = false;
206
207 m_input->dryCompute(rect, frame, ri3);
208 }
209
210 //-----------------------------------------------------------------------------
211
doCompute(TTile & tile,double frame,const TRenderSettings & ri)212 void ArtContourFx::doCompute(TTile &tile, double frame,
213 const TRenderSettings &ri) {
214 if (!m_input.isConnected()) return;
215
216 if (!m_controller.isConnected()) {
217 m_input->compute(tile, frame, ri);
218 return;
219 }
220
221 TRenderSettings ri2(ri);
222 ri2.m_affine = TAffine();
223
224 TRectD controlBox;
225 m_controller->getBBox(frame, controlBox, ri2);
226 TTile ctrTile;
227 ctrTile.m_pos = controlBox.getP00();
228 TDimension dim = convert(controlBox).getSize();
229
230 m_controller->allocateAndCompute(ctrTile, ctrTile.m_pos, dim,
231 tile.getRaster(), frame, ri2);
232
233 TRenderSettings ri3(ri);
234
235 // Build the render data
236 int shrink = tround((ri.m_shrinkX + ri.m_shrinkY) / 2.0);
237 std::string controlAlias = m_controller->getAlias(frame, ri2);
238 SandorFxRenderData *artContourData =
239 buildRenderData(frame, shrink, controlBox, controlAlias);
240
241 // Add the controller raster
242 artContourData->m_controller = ctrTile.getRaster();
243
244 // Push the data among the others
245 ri3.m_data.push_back(artContourData);
246 ri3.m_userCachable = false;
247
248 m_input->compute(tile, frame, ri3);
249 }
250