CC-Fractal-Suite
FractalNode.h
Go to the documentation of this file.
1 
8 #pragma once
9 
10  // Local
11 #include "typedefs.h"
12 
13 // STL
14 #include <string>
15 #include <sstream>
16 #include <iomanip>
17 
18 // HDK
19 #include <PRM/PRM_Include.h>
20 #include <PRM/PRM_ChoiceList.h>
21 #include <OP/OP_Network.h>
22 #include <CH/CH_Manager.h>
23 #include <COP2/COP2_Common.h>
24 
25 
26 // Fractal Xform Name Data
27 static PRM_Name nameScale(SCALE_NAME.first, SCALE_NAME.second);
28 static PRM_Name nameOffset(TRANSLATE_NAME.first, TRANSLATE_NAME.second);
29 static PRM_Name nameRotate(ROTATE_NAME.first, ROTATE_NAME.second);
30 static PRM_Name nameXOrd(XORD_NAME.first, XORD_NAME.second);
31 
32 // Fractal Xform Multi Name Data
33 static PRM_Name nameXforms{ XFORMS_NAME.first, XFORMS_NAME.second };
34 static PRM_Name nameMultiScale(SCALE_M_NAME.first, SCALE_M_NAME.second);
35 
36 static PRM_Name nameMultiOffset(
37  TRANSLATE_M_NAME.first,
38  TRANSLATE_M_NAME.second);
39 
40 static PRM_Name nameMultiRotate(ROTATE_M_NAME.first, ROTATE_M_NAME.second);
41 static PRM_Name nameMultiXOrd(XORD_M_NAME.first, XORD_M_NAME.second);
42 
43 // Mandelbrot Name Data
44 static PRM_Name nameIter{ ITERS_NAME.first, ITERS_NAME.second };
45 static PRM_Name namePower{ POWER_NAME.first, POWER_NAME.second };
46 static PRM_Name nameBailout{ BAILOUT_NAME.first, BAILOUT_NAME.second };
47 static PRM_Name nameJDepth{ JDEPTH_NAME.first, JDEPTH_NAME.second };
48 static PRM_Name nameJOffset{ JOFFSET_NAME.first, JOFFSET_NAME.second };
49 static PRM_Name nameBlackhole{ BLACKHOLE_NAME.first, BLACKHOLE_NAME.second };
50 
51 // Pickover Name Data
52 static PRM_Name namePoPoint(
53  POPOINT_NAME.first,
54  POPOINT_NAME.second);
55 
56 static PRM_Name namePoMode(
57  POMODE_NAME.first,
58  POMODE_NAME.second);
59 
60 static PRM_Name namePoLineRotate(
61  POROTATE_NAME.first,
62  POROTATE_NAME.second);
63 
64 static PRM_Name namePoReference(
65  POREFERENCE_NAME.first,
66  POREFERENCE_NAME.second);
67 
68 static PRM_Name namePoRefSize(
69  POREFSIZE_NAME.first,
70  POREFSIZE_NAME.second);
71 
72 // Declare Lyapunov Parm Names
73 static PRM_Name nameLyaSeq(
74  LYASEQ_NAME.first,
75  LYASEQ_NAME.second);
76 
77 static PRM_Name nameLyaSeqWeights(
78  LYASEQWEIGHTS_NAME.first,
79  LYASEQWEIGHTS_NAME.second);
80 
81 static PRM_Name nameLyaStart(
82  LYASTART_NAME.first,
83  LYASTART_NAME.second);
84 
85 static PRM_Name nameLyaMaxValue(
86  LYACEILVALUE_NAME.first,
87  LYACEILVALUE_NAME.second);
88 
89 static PRM_Name nameLyaInvertNegative(
90  LYAINVERTNEGATIVE_NAME.first,
91  LYAINVERTNEGATIVE_NAME.second);
92 
93 
94 // ChoiceList Lists
95 static PRM_Name xordMenuNames[] =
96 {
97  PRM_Name("TRS", "Translate Rotate Scale"),
98  PRM_Name("TSR", "Translate Scale Rotate"),
99  PRM_Name("RTS", "Rotate Translate Scale"),
100  PRM_Name("RST", "Rotate Scale Translate"),
101  PRM_Name("STR", "Scale Translate Rotate"),
102  PRM_Name("SRT", "Scale Rotate Translate"),
103  PRM_Name(0)
104 };
105 
106 static PRM_ChoiceList xOrdMenu
107 (
108 (PRM_ChoiceListType)(PRM_CHOICELIST_EXCLUSIVE | PRM_CHOICELIST_REPLACE),
109 ::xordMenuNames
110 );
111 
113 static PRM_Name poModeMenuNames[] =
114 {
115  PRM_Name("point", "Point"),
116  PRM_Name("line", "Line"),
117  PRM_Name(0)
118 };
119 
120 static PRM_ChoiceList poModeMenu
121 (
122 (PRM_ChoiceListType)(PRM_CHOICELIST_EXCLUSIVE | PRM_CHOICELIST_REPLACE),
123 ::poModeMenuNames
124 );
125 
126 // Xform Defaults Data
128 static PRM_Default defaultScale{ 5 };
130 static PRM_Default defaultOffset[] = { -0.6, -0.28125 };
131 static PRM_Default defaultRotate{ 0.0f };
132 static PRM_Default defaultXOrd{ RSTORDER::TRS };
133 
135 static PRM_Default defaultMultiXOrd{ RSTORDER::RST };
136 
140 static PRM_Default defaultOffsetBuddhabrot[] = { -3.0, -1.3 };
141 
142 // Mandelbrot Defaults Data
143 static PRM_Default defaultIter{ 50 };
144 static PRM_Default defaultPower{ 2 };
145 
147 static PRM_Default defaultBailout{ 4 };
148 static PRM_Default defaultJDepth{ 0 };
149 static PRM_Default defaultJOffset[] = { 0, 0 };
150 static PRM_Default defaultBlackhole{ false };
151 
152 // Define Pickover Defaults
153 static PRM_Default defaultPoRefSize{ 10.0 };
154 
155 // Declare Lyapunov Defaults
156 static PRM_Default defaultLyaMaxValue(5.0f);
157 
159 static PRM_Default defaultLyaStart(0.5);
160 
161 // Xform Parm Ranges
162 static PRM_Range rangeScale
163 {
164  PRM_RangeFlag::PRM_RANGE_RESTRICTED, 0,
165  PRM_RangeFlag::PRM_RANGE_UI, defaultScale.getFloat()
166 };
167 
168 static PRM_Range rangeRotate
169 {
170  PRM_RangeFlag::PRM_RANGE_UI, -180,
171  PRM_RangeFlag::PRM_RANGE_UI, 180
172 };
173 
174 // Mandelbrot Parm Ranges
175 static PRM_Range rangeIter
176 {
177  PRM_RangeFlag::PRM_RANGE_RESTRICTED, 1,
178  PRM_RangeFlag::PRM_RANGE_UI, 200
179 };
180 
181 
182 static PRM_Range rangePower
183 {
184  PRM_RangeFlag::PRM_RANGE_RESTRICTED, 0,
185  PRM_RangeFlag::PRM_RANGE_UI, 10
186 };
187 
188 static PRM_Range rangeBailout
189 {
190  PRM_RangeFlag::PRM_RANGE_RESTRICTED, 0,
191  PRM_RangeFlag::PRM_RANGE_UI, 4
192 };
193 
194 static PRM_Range rangeJDepth
195 {
196  PRM_RangeFlag::PRM_RANGE_RESTRICTED, 0,
197  PRM_RangeFlag::PRM_RANGE_UI, 5
198 };
199 
200 // Lyapunov Ranges
201 
202 static PRM_Range rangeLyaStartValue
203 {
204  PRM_RangeFlag::PRM_RANGE_UI, 0.001f,
205  PRM_RangeFlag::PRM_RANGE_UI, 0.999f
206 };
207 
208 static PRM_Range rangeLyaMaxValue
209 {
210  PRM_RangeFlag::PRM_RANGE_RESTRICTED, 1,
211  PRM_RangeFlag::PRM_RANGE_UI, defaultLyaMaxValue.getFloat()
212 };
213 
214 static PRM_Range rangeLyaSeq
215 {
216  PRM_RangeFlag::PRM_RANGE_RESTRICTED, 1,
217  PRM_RangeFlag::PRM_RANGE_RESTRICTED, 40
218 };
219 
220 static PRM_Range rangeLyaIters
221 {
222  PRM_RangeFlag::PRM_RANGE_RESTRICTED, 1,
223  PRM_RangeFlag::PRM_RANGE_RESTRICTED, 40
224 };
225 
226 // Define Pickover ranges
227 static PRM_Range rangePoRotate
228 {
229  PRM_RangeFlag::PRM_RANGE_UI, -180,
230  PRM_RangeFlag::PRM_RANGE_UI, 180
231 };
232 
233 static PRM_Range rangePoRefSize
234 {
235  PRM_RangeFlag::PRM_RANGE_RESTRICTED, 0.0,
236  PRM_RangeFlag::PRM_RANGE_FREE, 25
237 };
238 
239 // Multiparm Templates
240 static PRM_Template multiparmSeqTemps[] =
241 {
242  PRM_Template(PRM_FLT_J, TOOL_PARM, 1, &nameLyaSeqWeights, PRMzeroDefaults),
243  PRM_Template()
244 };
245 
246 static PRM_Template multiparmXformTemps[] =
247 {
248  PRM_Template(PRM_INT_J, TOOL_PARM, 1,
249  &nameMultiXOrd, &defaultMultiXOrd, &xOrdMenu),
250  PRM_Template(PRM_FLT_LOG, TOOL_PARM, 1,
251  &nameMultiScale, PRMoneDefaults, 0, &rangeScale),
252  PRM_Template(PRM_FLT_J, TOOL_PARM, 2,
253  &nameMultiOffset, PRMzeroDefaults),
254  PRM_Template(PRM_FLT_J, TOOL_PARM, 1,
255  &nameMultiRotate, PRMzeroDefaults, 0, &rangeRotate),
256  PRM_Template()
257 };
258 
259 // Create separator names. These are shared across the CCFS
260 static PRM_Name nameSeparatorMandelbrot("sep_mandelbrot", "Sep Mandelbrot");
261 static PRM_Name nameSepA("sep_A", "Sep A");
262 static PRM_Name nameSepB("sep_B", "Sep B");
263 static PRM_Name nameSepC("sep_C", "Sep C");
264 
265 // Macro for creating the Switcher
266 #define TEMPLATE_SWITCHER PRM_Template(PRM_SWITCHER, 4, \
267  &PRMswitcherName, switcher)
268 
271 #define TEMPLATES_XFORM \
272  PRM_Template(PRM_INT_J, TOOL_PARM, 1, \
273  &nameXOrd, &defaultXOrd, &xOrdMenu), \
274  PRM_Template(PRM_FLT_LOG, TOOL_PARM, 1, \
275  &nameScale, &defaultScale, 0, &rangeScale), \
276  PRM_Template(PRM_FLT_J, TOOL_PARM, 2, \
277  &nameOffset, defaultOffset), \
278  PRM_Template(PRM_FLT_J, TOOL_PARM, 1, \
279  &nameRotate, PRMzeroDefaults, 0, &rangeRotate)
280 
283 #define TEMPLATES_XFORM_MULTI \
284  PRM_Template(PRM_MULTITYPE_LIST, multiparmXformTemps, 1, \
285  &nameXforms, PRMzeroDefaults)
286 
289 #define TEMPLATES_XFORM_BUDDHABROT \
290  PRM_Template(PRM_FLT_LOG, TOOL_PARM, 1, \
291  &nameScale, &defaultScale, 0, &rangeScale), \
292  PRM_Template(PRM_FLT_J, TOOL_PARM, 2, \
293  &nameOffset, defaultOffsetBuddhabrot), \
294  PRM_Template(PRM_FLT_J, TOOL_PARM, 1, \
295  &nameRotate, PRMzeroDefaults, 0, &rangeRotate)
296 
300 #define TEMPLATES_MANDELBROT \
301  PRM_Template(PRM_INT_J, TOOL_PARM, 1, \
302  &nameIter, &defaultIter, 0, &rangeIter), \
303  PRM_Template(PRM_FLT_J, TOOL_PARM, 1, \
304  &namePower, &defaultPower, 0, &rangePower), \
305  PRM_Template(PRM_FLT_J, TOOL_PARM, 1, \
306  &nameBailout, &defaultBailout, 0, &rangeBailout), \
307  PRM_Template(PRM_TOGGLE_J, TOOL_PARM, 1, \
308  &nameBlackhole, PRMzeroDefaults), \
309  PRM_Template(PRM_SEPARATOR, TOOL_PARM, 1, \
310  &nameSeparatorMandelbrot, PRMzeroDefaults), \
311  PRM_Template(PRM_INT_J, TOOL_PARM, 1, \
312  &nameJDepth, PRMzeroDefaults, 0, &rangeJDepth), \
313  PRM_Template(PRM_FLT_J, TOOL_PARM, 2, \
314  &nameJOffset, PRMzeroDefaults)
315 
321 #define TEMPLATES_PICKOVER \
322  PRM_Template(PRM_SEPARATOR, TOOL_PARM, 1, &nameSepB), \
323  PRM_Template(PRM_INT_J, TOOL_PARM, 1, \
324  &namePoMode, PRMoneDefaults, &poModeMenu), \
325  PRM_Template(PRM_FLT_J, TOOL_PARM, 2, \
326  &namePoPoint, PRMzeroDefaults), \
327  PRM_Template(PRM_FLT_J, TOOL_PARM, 1, \
328  &namePoLineRotate, PRMzeroDefaults, 0, &rangePoRotate), \
329  PRM_Template(PRM_TOGGLE_J, TOOL_PARM, 1, \
330  &namePoReference, PRMzeroDefaults), \
331  PRM_Template(PRM_FLT_J, TOOL_PARM, 1, \
332  &namePoRefSize, &defaultPoRefSize, 0, &rangePoRefSize)
333 
334 
338 #define TEMPLATES_LYAPUNOV \
339  PRM_Template(PRM_INT_J, TOOL_PARM, 1, \
340  &nameIter, &defaultIter, 0, &rangeLyaIters), \
341  PRM_Template(PRM_FLT_J, TOOL_PARM, 1, \
342  &nameLyaStart, &defaultLyaStart, 0, &rangeLyaStartValue), \
343  PRM_Template(PRM_FLT_J, TOOL_PARM, 1, \
344  &nameLyaMaxValue, &defaultLyaMaxValue, 0, &rangeLyaMaxValue), \
345  PRM_Template(PRM_TOGGLE_J, TOOL_PARM, 1, \
346  &nameLyaInvertNegative, PRMoneDefaults), \
347  PRM_Template(PRM_MULTITYPE_LIST, multiparmSeqTemps, 1, \
348  &nameLyaSeq, PRMoneDefaults, &rangeLyaSeq)
349 
350 
351 namespace CC
352 {
359 class OP
360 {
361 public:
364  template <typename T>
365  static OP_Node* get_new_op(
366  OP_Network* net,
367  const char* name,
368  OP_Operator* op)
369  {
370  return new T(net, name, op);
371  }
372 };
373 
378 {
379  fpreal scale{ 1.0 };
380  COMPLEX offset{ 0.0, 0.0 };
381  fpreal rotate{ 0.0 };
382 };
383 
384 
388 static MultiXformData
389 get_multi_xform_sums(OP_Node* node)
390 {
391  MultiXformData data;
392 
393  fpreal t = CHgetEvalTime();
394 
395  int numXforms = node->evalInt(XFORMS_NAME.first, 0, t);
396  for (int i = 1; i <= numXforms; ++i)
397  {
398  data.scale *= node->evalFloatInst(
399  SCALE_M_NAME.first, &i, 0, t);
400 
401  data.offset += (
402  node->evalFloatInst(TRANSLATE_M_NAME.first, &i, 0, t),
403  node->evalFloatInst(TRANSLATE_M_NAME.first, &i, 1, t));
404 
405  data.rotate += node->evalFloatInst(
406  ROTATE_M_NAME.first, &i, 0, t);
407  }
408 
409  return data;
410 };
411 
414 static std::string
415 formatMultiXformData(MultiXformData data)
416 {
417  std::ostringstream oss;
418 
419  oss << std::setprecision(2);
420  oss << "Fractal Transformation:" << std::endl;
421  oss << "Scale: " << data.scale << std::endl;
422  oss << "Transform: " << data.offset.real() << " "
423  << data.offset.imag() << std::endl;
424  oss << "Rotate: " << data.rotate << std::endl;
425 
426  return oss.str();
427 }
428 } // End of CC Namespace
OP is meant to remove the need to write public &#39;myConstructor&#39; methods in every class like the exampl...
Definition: FractalNode.h:359
static OP_Node * get_new_op(OP_Network *net, const char *name, OP_Operator *op)
Method that calls a node&#39;s constructor, if added as a friend of the given node&#39;s class.
Definition: FractalNode.h:365
std::complex< fpreal64 > COMPLEX
Double precision complex numbers, as defined by the HDK.
Definition: typedefs.h:25
A simple container struct that represents the total output of a MultiXform transformation.
Definition: FractalNode.h:377
Header with shared typedefs and parameter name declarations.
Definition: COP2_Buddhabrot.h:17