SeExpr
ExprBuiltins.cpp
Go to the documentation of this file.
1 /*
2 * Copyright Disney Enterprises, Inc. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License
6 * and the following modification to it: Section 6 Trademarks.
7 * deleted and replaced with:
8 *
9 * 6. Trademarks. This License does not grant permission to use the
10 * trade names, trademarks, service marks, or product names of the
11 * Licensor and its affiliates, except as required for reproducing
12 * the content of the NOTICE file.
13 *
14 * You may obtain a copy of the License at
15 * http://www.apache.org/licenses/LICENSE-2.0
16 */
17 
18 #include <cassert>
19 #include <cmath>
20 #include <cstdlib>
21 #include <limits>
22 #include <algorithm>
23 #include <cfloat>
24 
25 #include "ExprFunc.h"
26 #include "ExprNode.h"
27 #include "Vec.h"
28 #include "Curve.h"
29 #include "ExprBuiltins.h"
30 #include "Platform.h"
31 #include "Noise.h"
32 #include "Interpreter.h"
33 
34 namespace SeExpr2 {
35 
36 static const char* fabs_docstring = "float abs(float x)\nabsolute value of x";
37 
38 // angle conversion functions
39 static const char* deg_docstring = "float deg(float angle)\nradians to degrees";
40 static const char* rad_docstring = "float deg(float angle)\ndegrees to radians";
41 // trig in degrees
42 static const char* cosd_docstring = "float cosd(float angle)\ncosine in degrees";
43 static const char* sind_docstring = "float sind(float angle)\nsine in degrees";
44 static const char* tand_docstring = "float tand(float angle)\ntangent in degrees";
45 static const char* acosd_docstring = "float acosd(float angle)\narc cosine in degrees";
46 static const char* asind_docstring = "float asind(float angle)\narc sine in degrees";
47 static const char* atand_docstring = "float atand(float angle)\narc tangent in degrees";
48 static const char* atan2d_docstring =
49  "float atan2d(float y,float x)\narc tangent in degrees of y/x between -180 and 180";
50 // trig in radians
51 static const char* cos_docstring = "float cos(float angle)\ncosine in radians";
52 static const char* sin_docstring = "float sin(float angle)\nsine in radians";
53 static const char* tan_docstring = "float tan(float angle)\ntangent in radians";
54 static const char* acos_docstring = "float acos(float angle)\narc cosine in radians";
55 static const char* asin_docstring = "float asin(float angle)\narc sine in radians";
56 static const char* atan_docstring = "float atan(float angle)\narc tangent in radians";
57 static const char* atan2_docstring = "float atan2(float y,float x)\narc tangent in radians of y/x between -PI and PI";
58 // hyperbolic trig
59 static const char* cosh_docstring = "float cosh(float angle)\nhyperbolic cosine in radians";
60 static const char* sinh_docstring = "float sinh(float angle)\nhyperbolic sine in radians";
61 static const char* tanh_docstring = "float tanh(float angle)\nhyperbolic tangent in radians";
62 static const char* acosh_docstring = "float acosh(float angle)\nhyperbolic arc cosine in radians";
63 static const char* asinh_docstring = "float asinh(float angle)\nhyperbolic arc sine in radians";
64 static const char* atanh_docstring = "float atanh(float angle)\nhyperbolic arc tangent in radians";
65 // clamping/rounding
66 static const char* clamp_docstring = "float clamp(float x,float lo,float hi)\nconstrain x to range [lo,hi]";
67 static const char* round_docstring = "float round(float x)\nconstrain x to range [lo,hi]";
68 static const char* max_docstring = "float max(float a,float b)\ngreater of a and b";
69 static const char* min_docstring = "float min(float a,float b)\nlesser of a and b";
70 static const char* trunc_docstring = "float trunc(float a)\nnearest integer towards zero";
71 static const char* floor_docstring = "float floor(float a)\nnext lower integer";
72 static const char* ceil_docstring = "float ceil(float a)\nnext higher integer";
73 // misc math
74 static const char* invert_docstring = "float invert(float a)\nDefined as 1-x";
75 static const char* cbrt_docstring = "float cbrt(float x)\ncube root";
76 static const char* sqrt_docstring = "float sqrt(float x)\nsquare root";
77 static const char* exp_docstring = "float exp(float x)\nE raised to the x power";
78 static const char* pow_docstring = "float pow(float x)\nx to the y power, also available as ^";
79 static const char* log_docstring = "float log(float x)\nNatural logarithm";
80 static const char* log10_docstring = "float log10(float x)\nBase 10 logarithm";
81 static const char* fmod_docstring = "float fmod(float x,float y)\nremainder of x/y (also available as % operator)";
82 static const char* turbulence_docstring =
83  "float turbulence(vector v,int octaves=6,float lacunarity=2,float gain=.5)\nAbsolute value of each noise term is "
84  "taken. This gives billowy appearance";
85 static const char* cturbulence_docstring =
86  "color cturbulence(vector v,int octaves=6,float lacunarity=2,float gain=.5)\nAbsolute value of each noise term is "
87  "taken. This gives billowy appearance";
88 static const char* vturbulence_docstring =
89  "vector vturbulence(vector v,int octaves=6,float lacunarity=2,float gain=.5)\nAbsolute value of each noise term is "
90  "taken. This gives billowy appearance";
91 
92 double compress(double x, double lo, double hi) { return (hi - lo) * x + lo; }
93 static const char* compress_docstring = "float compress(float x,float lo,float hi)\nRemaps x in [0,1] to [lo,hi]";
94 
95 double expand(double x, double lo, double hi) {
96  if (lo == hi) return x < lo ? 0 : 1;
97  return (x - lo) / (hi - lo);
98 }
99 static const char* expand_docstring = "float expand(float x,float lo,float hi)\nRemaps x in [lo,hi] to [0,1]";
100 
101 double fit(double x, double a1, double b1, double a2, double b2) {
102  return (x * (b2 - a2) - a1 * b2 + b1 * a2) / (b1 - a1);
103 }
104 static const char* fit_docstring =
105  "float fit(float x,float a1,float b1,float a2,float b2)\nLinearly remaps x in [a1,b1] to [a2,b2]";
106 
107 double gamma(double x, double g) { return pow(x, 1 / g); }
108 static const char* gamma_docstring = "float gamma(float x, float g)\nGamma correction of x with gamma factor g";
109 
110 double bias(double x, double b) {
111  static double C = 1 / log(0.5);
112  return pow(x, log(b) * C);
113 }
114 static const char* bias_docstring =
115  "float bias(float x, float g)\nVariation of gamma where values less than 0.5 pull the curve down\nand values "
116  "greater than 0.5 pull the curve up\npow(x,log(b)/log(0.5))";
117 
118 double contrast(double x, double c) {
119  if (x < 0.5)
120  return 0.5 * bias(1 - c, 2 * x);
121  else
122  return 1 - 0.5 * bias(1 - c, 2 - 2 * x);
123 }
124 static const char* contrast_docstring =
125  "float contrast(float x,float x)\nAdjust the contrast.&nbsp; For c from 0 to 0.5, the contrast is decreased.&nbsp; "
126  "For c &gt; 0.5, the contrast is increased.";
127 
128 double boxstep(double x, double a) { return x < a ? 0.0 : 1.0; }
129 static const char* boxstep_docstring = "float boxstep(float x,float a)\n if x < a then 0 otherwise 1";
130 
131 double linearstep(double x, double a, double b) {
132  if (a < b) {
133  return x < a ? 0 : (x > b ? 1 : (x - a) / (b - a));
134  } else if (a > b) {
135  return 1 - (x < b ? 0 : (x > a ? 1 : (x - b) / (a - b)));
136  }
137  return boxstep(x, a);
138 }
139 static const char* linearstep_docstring =
140  "float linearstep(float x,float a,float b)\n if x &lt; a then 0, if x &gt; b then 1, and\nx transitions linearly "
141  "when &lt; x &lt; b ";
142 
143 double smoothstep(double x, double a, double b) {
144  if (a < b) {
145  if (x < a) return 0;
146  if (x >= b) return 1;
147  x = (x - a) / (b - a);
148  } else if (a > b) {
149  if (x <= b) return 1;
150  if (x > a) return 0;
151  x = 1 - (x - b) / (a - b);
152  } else
153  return boxstep(x, a);
154  return x * x * (3 - 2 * x);
155 }
156 static const char* smoothstep_docstring =
157  "float smoothstep(float x,float a,float b)\n if x &lt; a then 0, if x &gt; b then 1, and\nx transitions smoothly "
158  "(cubic) when &lt; x &lt; b";
159 
160 double gaussstep(double x, double a, double b) {
161  if (a < b) {
162  if (x < a) return 0;
163  if (x >= b) return 1;
164  x = 1 - (x - a) / (b - a);
165  } else if (a > b) {
166  if (x <= b) return 1;
167  if (x > a) return 0;
168  x = (x - b) / (a - b);
169  } else
170  return boxstep(x, a);
171  return pow(2, -8 * x * x);
172 }
173 static const char* gaussstep_docstring =
174  "float gasussstep(float x,float a,float b)\n if x &lt; a then 0, if x &gt; b then 1, and\nx transitions smoothly "
175  "(exponentially) when &lt; x &lt; b";
176 
177 double remap(double x, double source, double range, double falloff, double interp) {
178  range = fabs(range);
179  falloff = fabs(falloff);
180 
181  if (falloff == 0) return fabs(x - source) < range;
182 
183  double a, b;
184  if (x > source) {
185  a = source + range;
186  b = a + falloff;
187  } else {
188  a = source - range;
189  b = a - falloff;
190  }
191 
192  switch (int(interp)) {
193  case 0:
194  return linearstep(x, b, a);
195  case 1:
196  return smoothstep(x, b, a);
197  default:
198  return gaussstep(x, b, a);
199  }
200 }
201 static const char* remap_docstring =
202  "remap(float x, float\n"
203  "source, float range, float falloff, float interp)\nGeneral remapping function.\n"
204  "When x is within +/- <i>range</i> of source, the result is one.\n"
205  "The result falls to zero beyond that range over <i>falloff</i> distance.\n"
206  "The falloff shape is controlled by <i>interp</i>. Numeric values\n"
207  "or named constants may be used:\n"
208  "&nbsp;&nbsp;&nbsp;&nbsp;int <b>linear</b>\n"
209  "= 0\n"
210  "&nbsp;&nbsp;&nbsp;&nbsp;int <b>smooth</b> = 1\n"
211  "&nbsp;&nbsp;&nbsp;&nbsp;int <b>gaussian</b> = 2\n";
212 
213 double mix(double x, double y, double alpha) { return x * (1 - alpha) + y * alpha; }
214 static const char* mix_docstring = "mix(float a,float b,float alpha)\nBlend of a and b according to alpha.";
215 
216 Vec3d hsiAdjust(const Vec3d& rgb, double h, double s, double i) {
217  Vec3d hsl = rgbtohsl(rgb);
218  hsl[0] += h * (1.0 / 360);
219  hsl[1] *= s;
220  return hsltorgb(hsl) * i;
221 }
222 
223 Vec3d hsi(int n, const Vec3d* args) {
224  if (n < 4) return 0.0;
225 
226  double h = args[1][0];
227  double s = args[2][0];
228  double i = args[3][0];
229  if (n >= 5) {
230  // apply mask
231  double m = args[4][0];
232  h *= m;
233  s = (s - 1) * m + 1;
234  i = (i - 1) * m + 1;
235  }
236  return hsiAdjust(args[0], h, s, i);
237 }
238 static const char* hsi_docstring =
239  "color hsi(color x, float h, float s, float i, float map=1)\n"
240  "The hsi function shifts the hue by h\n"
241  "(in degrees) and scales the saturation and intensity by s and i\n"
242  "respectively.&nbsp; An map may be supplied which will control the shift\n"
243  "- the full shift will happen when the map is one and no shift will\n"
244  "happen when the map is zero.&nbsp; The shift will be scaled back for\n"
245  "values between zero and one.";
246 
247 Vec3d midhsi(int n, const Vec3d* args) {
248  if (n < 4) return 0.0;
249 
250  double h = args[1][0];
251  double s = args[2][0];
252  double i = args[3][0];
253  if (n >= 5) {
254  // apply mask
255  double m = args[4][0];
256  // remap from [0..1] to [-1..1]
257  m = m * 2 - 1;
258  // add falloff (if specified)
259  double falloff = 1, interp = 0;
260  if (n >= 6) falloff = args[5][0];
261  if (n >= 7) interp = args[6][0];
262  if (m < 0)
263  m = -remap(-m, 1, 0, falloff, interp);
264  else
265  m = remap(m, 1, 0, falloff, interp);
266 
267  // scale hsi values according to mask (both directions)
268  h *= m;
269  float absm = fabs(static_cast<float>(m));
270  s = s * absm + 1 - absm;
271  i = i * absm + 1 - absm;
272  if (m < 0) {
273  s = 1 / s;
274  i = 1 / i;
275  }
276  }
277  return hsiAdjust(args[0], h, s, i);
278 }
279 static const char* midhsi_docstring =
280  "color midhsi(color x, float h, float s, float i, float map, float falloff=1, int interp=0)\n"
281  "The midhsi function is just like the hsi function except that\n"
282  "the control map is centered around the mid point (value of 0.5)\n"
283  "and can scale the shift in both directions.";
284 
285 Vec3d rgbtohsl(const Vec3d& rgb) {
286  // RGB to HSL color space conversion
287  // This is based on Foley, Van Dam (2nd ed; p. 595)
288  // but extended to allow rgb values outside of 0..1
289  double R, G, B, H, S, L, x, y, sum, diff;
290  R = rgb[0];
291  G = rgb[1];
292  B = rgb[2];
293  x = R < G ? (R < B ? R : B) : (G < B ? G : B); // min(R,G,B)
294  y = R > G ? (R > B ? R : B) : (G > B ? G : B); // max(R,G,B)
295 
296  // compute lightness = avg of min and max rgb vals
297  sum = x + y;
298  diff = y - x;
299  L = sum / 2;
300  if (diff < 1e-6) // achromatic
301  return Vec3d(0, 0, L);
302 
303  // compute saturation
304  if (L <= .5) {
305  if (x < 0)
306  S = 1 - x;
307  else
308  S = diff / sum;
309  } else {
310  if (y > 1)
311  S = y;
312  else
313  S = diff / (2 - sum);
314  }
315 
316  // compute hue
317  if (R == y)
318  H = (G - B) / diff;
319  else if (G == y)
320  H = (B - R) / diff + 2;
321  else
322  H = (R - G) / diff + 4;
323  H *= 1 / 6.;
324  H -= floor(H); // make sure hue is in range 0..1
325 
326  return Vec3d(H, S, L);
327 }
328 static const char* rgbtohsl_docstring =
329  "color rgbtohsl(color rgb)\n"
330  "RGB to HSL color space conversion.\n"
331  "HSL is Hue, Saturation, Lightness (all in range [0..1] )\n"
332  "These functions have also been extended to support rgb and hsl values\n"
333  "outside of the range [0..1] in a reasonable way.&nbsp; For any rgb or\n"
334  "hsl value (except for negative s values), the conversion is\n"
335  "well-defined and reversible.";
336 
337 static double hslvalue(double x, double y, double H) {
338  H -= floor(H); // make sure hue is in range 0..1
339 
340  if (H < 1 / 6.)
341  return x + (y - x) * H * 6;
342  else if (H < 3 / 6.)
343  return y;
344  else if (H < 4 / 6.)
345  return x + (y - x) * (4 / 6. - H) * 6;
346  else
347  return x;
348 }
349 
350 Vec3d hsltorgb(const Vec3d& hsl) {
351  // HSL to RGB color space conversion
352  // This is based on Foley, Van Dam (2nd ed; p. 596)
353  // but extended to allow rgb values outside of 0..1
354  double H, S, L, R, G, B, x, y;
355  H = hsl[0];
356  S = hsl[1];
357  L = hsl[2];
358  if (S <= 0) // achromatic
359  return Vec3d(L, L, L);
360 
361  // find min/max rgb values
362  if (L < 0.5) {
363  if (S > 1)
364  y = 2 * L + S - 1;
365  else
366  y = L + L * S;
367  } else {
368  if (S > 1)
369  y = S;
370  else
371  y = L + S - L * S;
372  }
373  x = 2 * L - y;
374 
375  // reconstruct rgb from min,max,hue
376  R = hslvalue(x, y, H + (1 / 3.));
377  G = hslvalue(x, y, H);
378  B = hslvalue(x, y, H - (1 / 3.));
379  return Vec3d(R, G, B);
380 }
381 static const char* hsltorgb_docstring =
382  "color hsltorgb(color hsl)\n"
383  "RGB to HSL color space conversion.\n"
384  "HSL is Hue, Saturation, Lightness (all in range [0..1] )\n"
385  "These functions have also been extended to support rgb and hsl values\n"
386  "outside of the range [0..1] in a reasonable way.&nbsp; For any rgb or\n"
387  "hsl value (except for negative s values), the conversion is\n"
388  "well-defined and reversible.";
389 
390 static Vec3d saturate(const Vec3d& Cin, double amt) {
391  const Vec3d lum(.2126, .7152, .0722); // rec709 luminance
392  Vec3d result = Vec3d(Cin.dot(lum) * (1 - amt)) + Cin * amt;
393  if (result[0] < 0) result[0] = 0;
394  if (result[1] < 0) result[1] = 0;
395  if (result[2] < 0) result[2] = 0;
396  return result;
397 }
398 
399 Vec3d saturate(int n, const Vec3d* args) {
400  if (n < 2) return 0.0;
401  return saturate(args[0], args[1][0]);
402 }
403 static const char* saturate_docstring =
404  "color saturate(color val, float amt)\n"
405  "Scale saturation of color by amt.\n"
406  "The color is scaled around the rec709 luminance value,\n"
407  "and negative results are clamped at zero.\n";
408 
409 double hash(int n, double* args) {
410  // combine args into a single seed
411  uint32_t seed = 0;
412  for (int i = 0; i < n; i++) {
413  // make irrational to generate fraction and combine xor into 32 bits
414  int exp = 0;
415  double frac = frexp(args[i] * double(M_E * M_PI), &exp);
416  uint32_t s = (uint32_t)(frac * UINT32_MAX) ^ (uint32_t)exp;
417 
418  // blend with seed (constants from Numerical Recipes, attrib. from Knuth)
419  static const uint32_t M = 1664525, C = 1013904223;
420  seed = seed * M + s + C;
421  }
422 
423  // tempering (from Matsumoto)
424  seed ^= (seed >> 11);
425  seed ^= (seed << 7) & 0x9d2c5680UL;
426  seed ^= (seed << 15) & 0xefc60000UL;
427  seed ^= (seed >> 18);
428 
429  // permute
430  static unsigned char p[256] = {
431  148, 201, 203, 34, 85, 225, 163, 200, 174, 137, 51, 24, 19, 252, 107, 173, 110, 251, 149, 69, 180, 152,
432  141, 132, 22, 20, 147, 219, 37, 46, 154, 114, 59, 49, 155, 161, 239, 77, 47, 10, 70, 227, 53, 235,
433  30, 188, 143, 73, 88, 193, 214, 194, 18, 120, 176, 36, 212, 84, 211, 142, 167, 57, 153, 71, 159, 151,
434  126, 115, 229, 124, 172, 101, 79, 183, 32, 38, 68, 11, 67, 109, 221, 3, 4, 61, 122, 94, 72, 117,
435  12, 240, 199, 76, 118, 5, 48, 197, 128, 62, 119, 89, 14, 45, 226, 195, 80, 50, 40, 192, 60, 65,
436  166, 106, 90, 215, 213, 232, 250, 207, 104, 52, 182, 29, 157, 103, 242, 97, 111, 17, 8, 175, 254, 108,
437  208, 224, 191, 112, 105, 187, 43, 56, 185, 243, 196, 156, 246, 249, 184, 7, 135, 6, 158, 82, 130, 234,
438  206, 255, 160, 236, 171, 230, 42, 98, 54, 74, 209, 205, 33, 177, 15, 138, 178, 44, 116, 96, 140, 253,
439  233, 125, 21, 133, 136, 86, 245, 58, 23, 1, 75, 165, 92, 217, 39, 0, 218, 91, 179, 55, 238, 170,
440  134, 83, 25, 189, 216, 100, 129, 150, 241, 210, 123, 99, 2, 164, 16, 220, 121, 139, 168, 64, 190, 9,
441  31, 228, 95, 247, 244, 81, 102, 145, 204, 146, 26, 87, 113, 198, 181, 127, 237, 169, 28, 93, 27, 41,
442  231, 248, 78, 162, 13, 186, 63, 66, 131, 202, 35, 144, 222, 223};
443  union {
444  uint32_t i;
445  unsigned char c[4];
446  } u1, u2;
447  u1.i = seed;
448  u2.c[3] = p[u1.c[0]];
449  u2.c[2] = p[(u1.c[1] + u2.c[3]) & 0xff];
450  u2.c[1] = p[(u1.c[2] + u2.c[2]) & 0xff];
451  u2.c[0] = p[(u1.c[3] + u2.c[1]) & 0xff];
452 
453  // scale to [0.0 .. 1.0]
454  return u2.i * (1.0 / UINT32_MAX);
455 }
456 static const char* hash_docstring =
457  "float hash(float seed1,[float seed2, ...])\n"
458  "Like rand, but with no internal seeds. Any number of seeds may be given\n"
459  "and the result will be a random function based on all the seeds.";
460 
461 double noise(int n, const Vec3d* args) {
462  if (n < 1) return 0;
463  if (n == 1) {
464  // 1 arg = vector arg
465  double result;
466  double p[3] = {args[0][0], args[0][1], args[0][2]};
467  Noise<3, 1>(p, &result);
468  return .5 * result + .5;
469  }
470  // scalar args
471  if (n > 4) n = 4;
472  double p[4];
473  for (int i = 0; i < n; i++) p[i] = args[i][0];
474  double result;
475  switch (n) {
476  case 1:
477  Noise<1, 1>(p, &result);
478  break;
479  case 2:
480  Noise<2, 1>(p, &result);
481  break;
482  case 3:
483  Noise<3, 1>(p, &result);
484  break;
485  case 4:
486  Noise<4, 1>(p, &result);
487  break;
488  default:
489  result = 0;
490  break;
491  }
492  return .5 * result + .5;
493 }
494 static const char* noise_docstring =
495  "float noise ( vector v ) <br>\n"
496  "float noise ( float x, float y )\n"
497  "float noise ( float x, float y, float z )\n"
498  "float noise ( float x, float y, float z, float w )\n"
499  "Original perlin noise at location (C2 interpolant)";
500 
501 double snoise(const Vec3d& p) {
502  double result;
503  double args[3] = {p[0], p[1], p[2]};
504  Noise<3, 1>(args, &result);
505  return result;
506 }
507 static const char* snoise_docstring =
508  "float snoise ( vector v)\n"
509  "signed noise w/ range -1 to 1 formed with original perlin noise at location (C2 interpolant)";
510 
511 Vec3d vnoise(const Vec3d& p) {
512  Vec3d result;
513  double args[3] = {p[0], p[1], p[2]};
514  Noise<3, 3>(args, &result[0]);
515  return result;
516 }
517 static const char* vnoise_docstring =
518  "vector vnoise ( vector v)\n"
519  "vector noise formed with original perlin noise at location (C2 interpolant)";
520 
521 Vec3d cnoise(const Vec3d& p) { return .5 * vnoise(p) + Vec3d(.5); }
522 static const char* cnoise_docstring =
523  "color cnoise ( vector v)\n"
524  "color noise formed with original perlin noise at location (C2 interpolant)";
525 
526 double snoise4(int n, const Vec3d* args) {
527  double result;
528  double procargs[4] = {args[0][0], args[0][1], args[0][2], args[1][0]};
529  Noise<4, 1>(procargs, &result);
530  return result;
531 }
532 static const char* snoise4_docstring =
533  "float snoise4 ( vector v,float t)\n"
534  "4D signed noise w/ range -1 to 1 formed with original perlin noise at location (C2 interpolant)";
535 
536 Vec3d vnoise4(int n, const Vec3d* args) {
537  Vec3d result;
538  double procargs[4] = {args[0][0], args[0][1], args[0][2], args[1][0]};
539  Noise<4, 3>(procargs, &result[0]);
540  return result;
541 }
542 static const char* vnoise4_docstring =
543  "vector vnoise4 ( vector v,float t)\n"
544  "4D vector noise formed with original perlin noise at location (C2 interpolant)";
545 
546 Vec3d cnoise4(int n, const Vec3d* args) { return .5 * vnoise4(n, args) + Vec3d(.5); }
547 static const char* cnoise4_docstring =
548  "color cnoise4 ( vector v,float t)\n"
549  "4D color noise formed with original perlin noise at location (C2 interpolant)";
550 
551 double turbulence(int n, const Vec3d* args) {
552  // args: octaves, lacunarity, gain
553  int octaves = 6;
554  double lacunarity = 2;
555  double gain = 0.5;
556  Vec3d p = 0.0;
557 
558  switch (n) {
559  case 4:
560  gain = args[3][0];
561  case 3:
562  lacunarity = args[2][0];
563  case 2:
564  octaves = int(clamp(args[1][0], 1, 8));
565  case 1:
566  p = args[0];
567  }
568 
569  double result = 0;
570  double P[3] = {p[0], p[1], p[2]};
571  FBM<3, 1, true>(P, &result, octaves, lacunarity, gain);
572  return .5 * result + .5;
573 }
574 
575 Vec3d vturbulence(int n, const Vec3d* args) {
576  // args: octaves, lacunarity, gain
577  int octaves = 6;
578  double lacunarity = 2;
579  double gain = 0.5;
580  Vec3d p = 0.0;
581 
582  switch (n) {
583  case 4:
584  gain = args[3][0];
585  case 3:
586  lacunarity = args[2][0];
587  case 2:
588  octaves = int(clamp(args[1][0], 1, 8));
589  case 1:
590  p = args[0];
591  }
592 
593  Vec3d result;
594  double P[3] = {p[0], p[1], p[2]};
595  FBM<3, 3, true>(P, &result[0], octaves, lacunarity, gain);
596  return result;
597 }
598 
599 Vec3d cturbulence(int n, const Vec3d* args) { return vturbulence(n, args) * .5 + Vec3d(.5); }
600 
601 double fbm(int n, const Vec3d* args) {
602  // args: octaves, lacunarity, gain
603  int octaves = 6;
604  double lacunarity = 2;
605  double gain = 0.5;
606  Vec3d p = 0.0;
607 
608  switch (n) {
609  case 4:
610  gain = args[3][0];
611  case 3:
612  lacunarity = args[2][0];
613  case 2:
614  octaves = int(clamp(args[1][0], 1, 8));
615  case 1:
616  p = args[0];
617  }
618 
619  double result = 0.0;
620  double P[3] = {p[0], p[1], p[2]};
621  FBM<3, 1, false>(P, &result, octaves, lacunarity, gain);
622  return .5 * result + .5;
623 }
624 static const char* fbm_docstring =
625  "float fbm(vector v,int octaves=6,float lacunarity=2,float gain=.5)\n"
626  "fbm (Fractal Brownian Motion) is a multi-frequency noise function. \n"
627  "The base frequency is the same as the \"noise\" function. The total \n"
628  "number of frequencies is controlled by octaves. The lacunarity is the \n"
629  "spacing between the frequencies - a value of 2 means each octave is \n"
630  "twice the previous frequency. The gain< controls how much each \n"
631  "frequency is scaled relative to the previous frequency.";
632 
633 Vec3d vfbm(int n, const Vec3d* args) {
634  // args: octaves, lacunarity, gain
635  int octaves = 6;
636  double lacunarity = 2;
637  double gain = 0.5;
638  Vec3d p = 0.0;
639 
640  switch (n) {
641  case 4:
642  gain = args[3][0];
643  case 3:
644  lacunarity = args[2][0];
645  case 2:
646  octaves = int(clamp(args[1][0], 1, 8));
647  case 1:
648  p = args[0];
649  }
650 
651  Vec3d result = 0.0;
652  double P[3] = {p[0], p[1], p[2]};
653  FBM<3, 3, false>(P, &result[0], octaves, lacunarity, gain);
654  return result;
655 }
656 static const char* vfbm_docstring = "vector vfbm(vector vint octaves=6,float lacunarity=2,float gain=.5)";
657 
658 double fbm4(int n, const Vec3d* args) {
659  // args: octaves, lacunarity, gain
660  int octaves = 6;
661  double lacunarity = 2;
662  double gain = 0.5;
663  Vec3d p = 0.0;
664  float time = 0.0;
665 
666  switch (n) {
667  case 5:
668  gain = args[4][0];
669  case 4:
670  lacunarity = args[3][0];
671  case 3:
672  octaves = int(clamp(args[2][0], 1, 8));
673  case 2:
674  time = static_cast<float>(args[1][0]);
675  case 1:
676  p = args[0];
677  }
678 
679  double result = 0.0;
680  double P[4] = {p[0], p[1], p[2], time};
681  FBM<4, 1, false>(P, &result, octaves, lacunarity, gain);
682  return .5 * result + .5;
683 }
684 static const char* fbm4_docstring =
685  "float fbm4(vector v,float time,int octaves=6,float lacunarity=2,float gain=.5)\n"
686  "fbm (Fractal Brownian Motion) is a multi-frequency noise function. \n"
687  "The base frequency is the same as the \"noise\" function. The total \n"
688  "number of frequencies is controlled by octaves. The lacunarity is the \n"
689  "spacing between the frequencies - a value of 2 means each octave is \n"
690  "twice the previous frequency. The gain< controls how much each \n"
691  "frequency is scaled relative to the previous frequency.";
692 
693 Vec3d vfbm4(int n, const Vec3d* args) {
694  // args: octaves, lacunarity, gain
695  int octaves = 6;
696  double lacunarity = 2;
697  double gain = 0.5;
698  Vec3d p = 0.0;
699  float time = 0.0;
700 
701  switch (n) {
702  case 5:
703  gain = args[4][0];
704  case 4:
705  lacunarity = args[3][0];
706  case 3:
707  octaves = int(clamp(args[2][0], 1, 8));
708  case 2:
709  time = static_cast<float>(args[1][0]);
710  case 1:
711  p = args[0];
712  }
713 
714  Vec3d result = 0.0;
715  double P[4] = {p[0], p[1], p[2], time};
716  FBM<4, 3, false>(P, &result[0], octaves, lacunarity, gain);
717  return result;
718 }
719 static const char* vfbm4_docstring = "vector vfbm4(vector v,float time,int octaves=6,float lacunarity=2,float gain=.5)";
720 
721 Vec3d cfbm(int n, const Vec3d* args) { return vfbm(n, args) * .5 + Vec3d(.5); }
722 static const char* cfbm_docstring = "color cfbm(vector vint octaves=6,float lacunarity=2,float gain=.5)";
723 
724 Vec3d cfbm4(int n, const Vec3d* args) { return vfbm4(n, args) * .5 + Vec3d(.5); }
725 static const char* cfbm4_docstring = "color cfbm4(vector v,float time,int octaves=6,float lacunarity=2,float gain=.5)";
726 
727 double cellnoise(const Vec3d& p) {
728  double result;
729  double args[3] = {p[0], p[1], p[2]};
730  CellNoise<3, 1>(args, &result);
731  return result;
732 }
733 static const char* cellnoise_docstring =
734  "float cellnoise(vector v)\n"
735  "cellnoise generates a field of constant colored cubes based on the integer location.\n"
736  "This is the same as the prman cellnoise function.";
737 
739  Vec3d result;
740  double args[3] = {p[0], p[1], p[2]};
741  CellNoise<3, 3>(args, &result[0]);
742  return result;
743 }
744 static const char* ccellnoise_docstring =
745  "color cellnoise(vector v)\n"
746  "cellnoise generates a field of constant colored cubes based on the integer location.\n"
747  "This is the same as the prman cellnoise function.";
748 
749 double pnoise(const Vec3d& p, const Vec3d& period) {
750  double result;
751  double args[3] = {p[0], p[1], p[2]};
752  int pargs[3] = {std::max((int)1, (int)period[0]),
753  std::max((int)1, (int)period[1]),
754  std::max((int)1, (int)period[2])};
755  PNoise<3, 1>(args, pargs, &result);
756  return result;
757 }
758 static const char* pnoise_docstring =
759  "float pnoise ( vector v, vector period )\n"
760  "periodic noise";
764  double jitter;
766 };
767 
768 static Vec3d* voronoi_points(VoronoiPointData& data, const Vec3d& cell, double jitter) {
769  if (cell == data.cell && jitter == data.jitter) return data.points;
770  data.cell = cell;
771  data.jitter = jitter;
772 
773  int n = 0;
774  for (double i = -1; i <= 1; i++) {
775  for (double j = -1; j <= 1; j++) {
776  for (double k = -1; k <= 1; k++, n++) {
777  Vec3d testcell = cell + Vec3d(i, j, k);
778  data.points[n] = testcell + jitter * (ccellnoise(testcell) - Vec3d(.5));
779  }
780  }
781  }
782  return data.points;
783 }
784 
785 static void voronoi_f1_3d(VoronoiPointData& data, const Vec3d& p, double jitter, double& f1, Vec3d& pos1) {
786  // from Advanced Renderman, page 257
787  Vec3d thiscell(floor(p[0]) + 0.5, floor(p[1]) + 0.5, floor(p[2]) + 0.5);
788 
789  f1 = 1000;
790  Vec3d* pos = voronoi_points(data, thiscell, jitter);
791  Vec3d* end = pos + 27;
792 
793  for (; pos != end; pos++) {
794  Vec3d offset = *pos - p;
795  double dist = offset.dot(offset);
796  if (dist < f1) {
797  f1 = dist;
798  pos1 = *pos;
799  }
800  }
801  f1 = sqrt(f1);
802 }
803 
805  const Vec3d& p,
806  double jitter,
807  double& f1,
808  Vec3d& pos1,
809  double& f2,
810  Vec3d& pos2) {
811  // from Advanced Renderman, page 258
812  Vec3d thiscell(floor(p[0]) + 0.5, floor(p[1]) + 0.5, floor(p[2]) + 0.5);
813  f1 = f2 = 1000;
814  Vec3d* pos = voronoi_points(data, thiscell, jitter);
815  Vec3d* end = pos + 27;
816 
817  for (; pos != end; pos++) {
818  Vec3d offset = *pos - p;
819  double dist = offset.dot(offset);
820  if (dist < f1) {
821  f2 = f1;
822  pos2 = pos1;
823  f1 = dist;
824  pos1 = *pos;
825  } else if (dist < f2) {
826  f2 = dist;
827  pos2 = *pos;
828  }
829  }
830  f1 = sqrt(f1);
831  f2 = sqrt(f2);
832 }
833 
834 Vec3d voronoiFn(VoronoiPointData& data, int n, const Vec3d* args) {
835  // args = p, type, jitter,
836  // fbmScale, fbmOctaves, fbmLacunarity, fbmGain
837  Vec3d p;
838  int type = 1;
839  double jitter = 0.5;
840  double fbmScale = 0;
841  double fbmOctaves = 4;
842  double fbmLacunarity = 2;
843  double fbmGain = 0.5;
844  switch (n) {
845  case 7:
846  fbmGain = args[6][0];
847  case 6:
848  fbmLacunarity = args[5][0];
849  case 5:
850  fbmOctaves = args[4][0];
851  case 4:
852  fbmScale = args[3][0];
853  case 3:
854  jitter = clamp(args[2][0], 1e-3, 1);
855  case 2:
856  type = int(args[1][0]);
857  case 1:
858  p = args[0];
859  }
860 
861  if (fbmScale > 0) {
862  Vec3d fbmArgs[4];
863  fbmArgs[0] = 2 * p;
864  fbmArgs[1] = fbmOctaves;
865  fbmArgs[2] = fbmLacunarity;
866  fbmArgs[3] = fbmGain;
867  p += fbmScale * vfbm(4, fbmArgs);
868  }
869 
870  double f1, f2;
871  Vec3d pos1, pos2;
872  if (type >= 3)
873  voronoi_f1f2_3d(data, p, jitter, f1, pos1, f2, pos2);
874  else
875  voronoi_f1_3d(data, p, jitter, f1, pos1);
876 
877  switch (type) {
878  case 1:
879  pos1[0] += 10;
880  return cellnoise(pos1);
881  case 2:
882  return f1;
883  case 3:
884  return f2;
885  case 4:
886  return f2 - f1;
887  case 5: {
888  float scalefactor = static_cast<float>((pos2 - pos1).length() / ((pos1 - p).length() + (pos2 - p).length()));
889  return smoothstep(f2 - f1, 0, 0.1 * scalefactor);
890  }
891  }
892 
893  return 0.0;
894 }
895 const static char* voronoi_docstring =
896  "float voronoi(vector v, int type=1,float jitter=0.5, float fbmScale=0, int fbmOctaves=4,float fbmLacunarity=2, "
897  "float fbmGain=.5)\n"
898  "voronoi is a cellular noise pattern. It is a jittered variant of cellnoise.";
899 
900 Vec3d cvoronoiFn(VoronoiPointData& data, int n, const Vec3d* args) {
901  // args = p, type, jitter,
902  // fbmScale, fbmOctaves, fbmLacunarity, fbmGain
903  Vec3d p;
904  int type = 1;
905  double jitter = 0.5;
906  double fbmScale = 0;
907  double fbmOctaves = 4;
908  double fbmLacunarity = 2;
909  double fbmGain = 0.5;
910  switch (n) {
911  case 7:
912  fbmGain = args[6][0];
913  case 6:
914  fbmLacunarity = args[5][0];
915  case 5:
916  fbmOctaves = args[4][0];
917  case 4:
918  fbmScale = args[3][0];
919  case 3:
920  jitter = clamp(args[2][0], 1e-3, 1);
921  case 2:
922  type = int(args[1][0]);
923  case 1:
924  p = args[0];
925  }
926 
927  if (fbmScale > 0) {
928  Vec3d fbmArgs[4];
929  fbmArgs[0] = 2 * p;
930  fbmArgs[1] = fbmOctaves;
931  fbmArgs[2] = fbmLacunarity;
932  fbmArgs[3] = fbmGain;
933  p += fbmScale * vfbm(4, fbmArgs);
934  }
935 
936  double f1, f2;
937  Vec3d pos1, pos2;
938  if (type >= 3)
939  voronoi_f1f2_3d(data, p, jitter, f1, pos1, f2, pos2);
940  else
941  voronoi_f1_3d(data, p, jitter, f1, pos1);
942 
943  Vec3d color = ccellnoise(pos1);
944  switch (type) {
945  case 1:
946  pos1[0] += 10;
947  return color;
948  case 2:
949  return f1 * color;
950  case 3:
951  return f2 * color;
952  case 4:
953  return (f2 - f1) * color;
954  case 5: {
955  float scalefactor = static_cast<float>((pos2 - pos1).length() / ((pos1 - p).length() + (pos2 - p).length()));
956  return smoothstep(f2 - f1, 0, 0.1 * scalefactor) * color;
957  }
958  }
959 
960  return 0.0;
961 }
962 const static char* cvoronoi_docstring =
963  "color cvoronoi(vector v, int type=1,float jitter=0.5, float fbmScale=0, int fbmOctaves=4,float fbmLacunarity=2, "
964  "float fbmGain=.5)\n"
965  "returns color in cellular pattern. It is a jittered variant of cellnoise.";
966 
967 Vec3d pvoronoiFn(VoronoiPointData& data, int n, const Vec3d* args) {
968  // args = p, jitter,
969  // fbmScale, fbmOctaves, fbmLacunarity, fbmGain
970  Vec3d p;
971  double jitter = 0.5;
972  double fbmScale = 0;
973  double fbmOctaves = 4;
974  double fbmLacunarity = 2;
975  double fbmGain = 0.5;
976  switch (n) {
977  case 6:
978  fbmGain = args[5][0];
979  case 5:
980  fbmLacunarity = args[4][0];
981  case 4:
982  fbmOctaves = args[3][0];
983  case 3:
984  fbmScale = args[2][0];
985  case 2:
986  jitter = clamp(args[1][0], 1e-3, 1);
987  case 1:
988  p = args[0];
989  }
990 
991  if (fbmScale > 0) {
992  Vec3d fbmArgs[4];
993  fbmArgs[0] = 2 * p;
994  fbmArgs[1] = fbmOctaves;
995  fbmArgs[2] = fbmLacunarity;
996  fbmArgs[3] = fbmGain;
997  p += fbmScale * vfbm(4, fbmArgs);
998  }
999 
1000  double f1;
1001  Vec3d pos1;
1002  voronoi_f1_3d(data, p, jitter, f1, pos1);
1003  return pos1;
1004 }
1005 const static char* pvoronoi_docstring =
1006  "color pvoronoi(vector v, int type=1,float jitter=0.5, float fbmScale=0, int fbmOctaves=4,float fbmLacunarity=2, "
1007  "float fbmGain=.5)\n"
1008  "returns center of voronoi cell.";
1009 
1011  public:
1012  typedef Vec3d VoronoiFunc(VoronoiPointData& data, int n, const Vec3d* args);
1014 
1015  virtual ExprType prep(ExprFuncNode* node, bool scalarWanted, ExprVarEnvBuilder& envBuilder) const {
1016  // check number of arguments
1017  int nargs = node->numChildren();
1018  if (nargs < 1 || nargs > 7) {
1019  node->addError("Wrong number of arguments, should be 1 to 7");
1020  return ExprType().Error();
1021  }
1022 
1023  bool valid = true;
1024  valid &= node->checkArg(0, ExprType().FP(3).Varying(), envBuilder);
1025  for (int i = 1; i < nargs; i++) valid &= node->checkArg(i, ExprType().FP(1).Constant(), envBuilder);
1026  return valid ? ExprType().FP(3).Varying() : ExprType().Error();
1027  }
1028 
1029  virtual ExprFuncNode::Data* evalConstant(const ExprFuncNode* node, ArgHandle args) const {
1030  return new VoronoiPointData();
1031  }
1032 
1033  virtual void eval(ArgHandle args) {
1034  VoronoiPointData* data = static_cast<VoronoiPointData*>(args.data);
1035  int nargs = args.nargs();
1036  Vec3d* sevArgs = (Vec3d*)alloca(sizeof(Vec3d) * nargs);
1037 
1038  for (int i = 0; i < nargs; i++)
1039  for (int j = 0; j < 3; j++) sevArgs[i][j] = args.inFp<3>(i)[j];
1040 
1041  Vec3d result = _vfunc(*data, nargs, sevArgs);
1042  double* out = &args.outFp;
1043  for (int i = 0; i < 3; i++) out[i] = result[i];
1044  }
1045 
1046  virtual ~CachedVoronoiFunc() {}
1047 
1048  private:
1051 
1052 double dist(double ax, double ay, double az, double bx, double by, double bz) {
1053  double x = ax - bx;
1054  double y = ay - by;
1055  double z = az - bz;
1056  return sqrt(x * x + y * y + z * z);
1057 }
1058 static const char* dist_docstring =
1059  "float dist(vector a, vector b)\n"
1060  "distance between two points";
1061 
1062 double length(const Vec3d& v) { return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); }
1063 static const char* length_docstring =
1064  "float length(vector v)\n"
1065  "length of vector";
1066 
1067 double hypot(double x, double y) { return sqrt(x * x + y * y); }
1068 static const char* hypot_docstring =
1069  "float hypot(vector v)\n"
1070  "length of 2d vector [x,y]";
1071 
1072 double dot(const Vec3d& a, const Vec3d& b) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; }
1073 static const char* dot_docstring =
1074  "float dot(vector a,vector b)\n"
1075  "vector dot product";
1076 
1077 Vec3d norm(const Vec3d& a) {
1078  double len = length(a);
1079  if (len == 0)
1080  return 0.0;
1081  else
1082  return a / len;
1083 }
1084 static const char* norm_docstring =
1085  "vector norm(vector v)\n"
1086  "vector scaled to unit length";
1087 
1088 Vec3d cross(const Vec3d& a, const Vec3d& b) {
1089  return Vec3d(a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]);
1090 }
1091 static const char* cross_docstring =
1092  "vector cross(vector a,vector b)\n"
1093  "vector cross product";
1094 
1095 double angle(const Vec3d& a, const Vec3d& b) {
1096  double len = length(a) * length(b);
1097  if (len == 0) return 0;
1098  return acos(dot(a, b) / len);
1099 }
1100 static const char* angle_docstring =
1101  "float angle(vector a,vector b)\n"
1102  "angle between two vectors (in radians)";
1103 
1104 Vec3d ortho(const Vec3d& a, const Vec3d& b) { return norm(cross(a, b)); }
1105 static const char* ortho_docstring =
1106  "vector angle(vector a,vector b)\n"
1107  "normalized vector orthogonal to a and b scaled to unit length";
1108 
1109 Vec3d rotate(int n, const Vec3d* args) {
1110  if (n != 3) return 0.0;
1111  const Vec3d& P = args[0];
1112  const Vec3d& axis = args[1];
1113  float angle = static_cast<float>(args[2][0]);
1114  double len = axis.length();
1115  if (!len) return P;
1116  return P.rotateBy(axis / len, angle);
1117 }
1118 static const char* rotate_docstring =
1119  "vector rotate(vector v,vector axis,float angle)\n"
1120  "rotates v around axis by given angle (in radians)";
1121 
1122 Vec3d up(const Vec3d& P, const Vec3d& upvec) {
1123  // rotate vec so y-axis points to upvec
1124  Vec3d yAxis(0, 1, 0);
1125  return P.rotateBy(ortho(upvec, yAxis), angle(upvec, yAxis));
1126 }
1127 static const char* up_docstring =
1128  "vector up(vector P,vector upvec)\n"
1129  "rotates v such that the Y axis points in the given up direction";
1130 
1131 double cycle(double index, double loRange, double hiRange) {
1132  int lo = int(loRange);
1133  int hi = int(hiRange);
1134  int range = hi - lo + 1;
1135  if (range <= 0) return lo;
1136  int result = int(index) % range;
1137  if (result < 0) result += range;
1138  return lo + result;
1139 }
1140 static const char* cycle_docstring =
1141  "int cycle(int index, int loRange, int hiRange )\n"
1142  "Cycles through values between loRange and hiRange based on supplied index.\n"
1143  "This is an offset \"mod\" function. The result is rotates v such that the\n"
1144  "Y axis points in the given up direction";
1145 
1146 double pick(int n, double* params) {
1147  if (n < 3) return 0;
1148  double index = hash(1, &params[0]);
1149  int loRange = int(params[1]);
1150  int hiRange = int(params[2]);
1151  int range = hiRange - loRange + 1;
1152  if (range <= 0) return loRange;
1153  int numWeights = n - 3;
1154  if (numWeights > range) numWeights = range;
1155 
1156  // build cutoff points based on weights
1157  double* cutoffs = (double*)alloca(sizeof(double) * range);
1158  double* weights = (double*)alloca(sizeof(double) * range);
1159  double total = 0;
1160  for (int i = 0; i < range; i++) {
1161  double weight = i < numWeights ? params[i + 3] : 1;
1162  total += weight;
1163  cutoffs[i] = total;
1164  weights[i] = weight;
1165  }
1166 
1167  if (total == 0) return loRange;
1168 
1169  // scale value from [0..1] to [0..total] range
1170  index *= total;
1171 
1172  // bsearch cutoff table to find index that spans value
1173  int lo = 0, hi = range - 1;
1174  while (lo < hi) {
1175  int m = (lo + hi) / 2;
1176  if (index <= cutoffs[m])
1177  hi = m;
1178  else
1179  lo = m + 1;
1180  }
1181 
1182  // skip zero-length intervals
1183  if (weights[lo] == 0) {
1184  if (lo > 0 && cutoffs[lo] > 0) // scan backward if possible
1185  while (--lo > 0 && weights[lo] == 0)
1186  ;
1187  else if (lo < range - 1) // else scan forward if possible
1188  while (++lo < range - 1 && weights[lo] == 0)
1189  ;
1190  }
1191 
1192  // add offset and return result
1193  return loRange + lo;
1194 }
1195 static const char* pick_docstring =
1196  "int pick(float index, int loRange, int hiRange, [float weights, ...] )\n"
1197  "Picks values randomly between loRange and hiRange based on supplied index (which is\n"
1198  "automatically hashed).&nbsp; The values will be distributed according\n"
1199  "to the supplied weights.&nbsp; Any weights not supplied are assumed to\n"
1200  "be 1.0.";
1201 
1202 double swatch(int n, double* params) { return choose(n, params); }
1203 static const char* swatch_docstring =
1204  "color swatch(float index, color choice0, color choice1, color choice2, [...])\n"
1205  "Chooses one of the supplied color choices based on the index (assumed to be in range [0..1]).";
1206 
1207 double choose(int n, double* params) {
1208  if (n < 3) return 0;
1209  double key = params[0];
1210  // NaN protection
1211  if (key != key) return 0;
1212  int nvals = n - 1;
1213  return params[1 + int(clamp(key * nvals, 0, nvals - 1))];
1214 }
1215 static const char* choose_docstring =
1216  "float choose(float index,float choice1, float choice2, [...])\n"
1217  "Chooses one of the supplied choices based on the index (assumed to be in range [0..1]).";
1218 
1219 double wchoose(int n, double* params) {
1220  if (n < 5) return 0;
1221  double key = params[0];
1222  // NaN protection
1223  if (key != key) return 0;
1224  int nvals = (n - 1) / 2; // nweights = nvals
1225 
1226  // build cutoff points based on weights
1227  double* cutoffs = (double*)alloca(sizeof(double) * nvals);
1228  double* weights = (double*)alloca(sizeof(double) * nvals);
1229  double total = 0;
1230  for (int i = 0; i < nvals; i++) {
1231  double weight = params[i * 2 + 2];
1232  total += weight;
1233  cutoffs[i] = total;
1234  weights[i] = weight;
1235  }
1236 
1237  if (total == 0) return params[1];
1238 
1239  // scale value from [0..1] to [0..total] range
1240  key *= total;
1241 
1242  // bsearch cutoff table to find index that spans value
1243  int lo = 0, hi = nvals - 1;
1244  while (lo < hi) {
1245  int m = (lo + hi) / 2;
1246  if (key <= cutoffs[m])
1247  hi = m;
1248  else
1249  lo = m + 1;
1250  }
1251 
1252  // skip zero-length intervals
1253  if (weights[lo] == 0) {
1254  if (lo > 0 && cutoffs[lo] > 0) // scan backward if possible
1255  while (--lo > 0 && weights[lo] == 0)
1256  ;
1257  else if (lo < nvals - 1) // else scan forward if possible
1258  while (++lo < nvals - 1 && weights[lo] == 0)
1259  ;
1260  }
1261 
1262  // return corresponding value
1263  return params[lo * 2 + 1];
1264 }
1265 static const char* wchoose_docstring =
1266  "float wchoose(float index,float choice1, float weight1, float choice2, float weight2, [...] )\n"
1267  "Chooses one of the supplied choices based on the index (assumed to be in range[0..1]).\n"
1268  "The values will be distributed according to the supplied weights.";
1269 
1270 double spline(int n, double* params) {
1271  if (n < 5) return 0;
1272  double u = clamp(params[0], 0, 1);
1273  if (u == 0) return params[2];
1274  if (u == 1) return params[n - 2];
1275  int nsegs = n - 4;
1276  double seg;
1277  u = modf(u * nsegs, &seg);
1278  double* p = &params[int(seg) + 1];
1279  double u2 = u * u;
1280  double u3 = u2 * u;
1281  return 0.5 * (p[0] * (-u3 + 2 * u2 - u) + p[1] * (3 * u3 - 5 * u2 + 2) + p[2] * (-3 * u3 + 4 * u2 + u) +
1282  p[3] * (u3 - u2));
1283 }
1284 static const char* spline_docstring =
1285  "float spline(float param,float y1,float y2,float y3,float y4,[...])\n\n"
1286  "Interpolates a set of values to the parameter specified where y1, ..., yn are\n"
1287  "distributed evenly from [0...1]";
1288 
1289 template <class T>
1292  virtual ~CurveData() {}
1293 };
1294 
1295 class CurveFuncX : public ExprFuncSimple {
1296  public:
1298 
1299  virtual ExprType prep(ExprFuncNode* node, bool scalarWanted, ExprVarEnvBuilder& envBuilder) const {
1300  // check number of arguments
1301  int nargs = node->numChildren();
1302  if ((nargs - 1) % 3) {
1303  node->addError("Wrong number of arguments, should be multiple of 3 plus 1");
1304  return ExprType().Error();
1305  }
1306 
1307  bool valid = true;
1308  valid &= node->checkArg(0, ExprType().FP(1).Varying(), envBuilder);
1309  for (int i = 1; i < nargs; i += 3) {
1310  valid &= node->checkArg(i, ExprType().FP(1).Constant(), envBuilder);
1311  valid &= node->checkArg(i + 1, ExprType().FP(1).Constant(), envBuilder);
1312  valid &= node->checkArg(i + 2, ExprType().FP(1).Constant(), envBuilder);
1313  }
1314  return valid ? ExprType().FP(1).Varying() : ExprType().Error();
1315  }
1316 
1317  virtual ExprFuncNode::Data* evalConstant(const ExprFuncNode* node, ArgHandle args) const {
1319  for (int i = 1; i < args.nargs() - 2; i += 3) {
1320  double pos = args.inFp<1>(i)[0];
1321  double val = args.inFp<1>(i + 1)[0];
1322  double interpDouble = args.inFp<1>(i + 2)[0];
1323  int interpInt = (int)interpDouble;
1324  Curve<double>::InterpType interpolant = (Curve<double>::InterpType)interpInt;
1325  if (!Curve<double>::interpTypeValid(interpolant)) {
1326  // TODO: fix error checking!
1327  }
1328  data->curve.addPoint(pos, val, interpolant);
1329  }
1330  data->curve.preparePoints();
1331  return data;
1332  }
1333 
1334  virtual void eval(ArgHandle args) {
1335  CurveData<double>* data = static_cast<CurveData<double>*>(args.data);
1336  double param = args.inFp<1>(0)[0];
1337  args.outFp = data->curve.getValue(param);
1338  }
1339 
1341 static const char* curve_docstring =
1342  "float curve(float param,float pos0,float val0,int interp0,float pos1,float val1,int interp1,[...])\n\n"
1343  "Interpolates a 1D ramp defined by control points at 'param'. Control points are specified \n"
1344  "by triples of parameters pos_i, val_i, and interp_i. Interpolation codes are \n"
1345  "0 - none, 1 - linear, 2 - smooth, 3 - spline, \n"
1346  "4-monotone (non oscillating spline)";
1347 
1348 class CCurveFuncX : public ExprFuncSimple {
1349  virtual ExprType prep(ExprFuncNode* node, bool wantScalar, ExprVarEnvBuilder& envBuilder) const {
1350  // check number of arguments
1351  int nargs = node->numChildren();
1352  if ((nargs - 1) % 3) {
1353  node->addError("Wrong number of arguments, should be multiple of 3 plus 1");
1354  return ExprType().Error().Varying();
1355  }
1356 
1357  bool valid = true;
1358  valid &= node->checkArg(0, ExprType().FP(1).Varying(), envBuilder);
1359  for (int i = 1; i < nargs; i += 3) {
1360  valid &= node->checkArg(i, ExprType().FP(1).Constant(), envBuilder);
1361  valid &= node->checkArg(i + 1, ExprType().FP(3).Constant(), envBuilder);
1362  valid &= node->checkArg(i + 2, ExprType().FP(1).Constant(), envBuilder);
1363  }
1364  return valid ? ExprType().FP(3).Varying() : ExprType().Error();
1365  }
1366 
1367  virtual ExprFuncNode::Data* evalConstant(const ExprFuncNode* node, ArgHandle args) const {
1368  CurveData<Vec3d>* data = new CurveData<Vec3d>;
1369  for (int i = 1; i < args.nargs() - 2; i += 3) {
1370  double pos = args.inFp<1>(i)[0];
1371  Vec3dRef val(&args.inFp<3>(i + 1)[0]);
1372  double interpDouble = args.inFp<1>(i + 2)[0];
1373  int interpInt = (int)interpDouble;
1374  Curve<Vec3d>::InterpType interpolant = (Curve<Vec3d>::InterpType)interpInt;
1375  if (!Curve<Vec3d>::interpTypeValid(interpolant)) {
1376  // TODO: fix error checking!
1377  }
1378  data->curve.addPoint(pos, val, interpolant);
1379  }
1380  data->curve.preparePoints();
1381  return data;
1382  }
1383 
1384  virtual void eval(ArgHandle args) {
1385  CurveData<Vec3d>* data = static_cast<CurveData<Vec3d>*>(args.data);
1386  double param = args.inFp<1>(0)[0];
1387  Vec3d result = data->curve.getValue(param);
1388  double* out = &args.outFp;
1389  for (int k = 0; k < 3; k++) out[k] = result[k];
1390  }
1391 
1392  public:
1393  CCurveFuncX() : ExprFuncSimple(true) {} // Thread Safe
1394  virtual ~CCurveFuncX() {}
1396 static const char* ccurve_docstring =
1397  "color curve(float param,float pos0,color val0,int interp0,float pos1,color val1,int interp1,[...])\n\n"
1398  "Interpolates color ramp given by control points at 'param'. Control points are specified \n"
1399  "by triples of parameters pos_i, val_i, and interp_i. Interpolation codes are \n"
1400  "0 - none, 1 - linear, 2 - smooth, 3 - spline, \n"
1401  "4 - monotone (non oscillating spline)";
1402 
1403 class GetVar : public ExprFuncSimple {
1404  struct Data : public ExprFuncNode::Data {
1405  typedef void (*func)(double* in, double* out);
1406  Data(func fIn, int dim) : f(fIn), dim(dim) {}
1408  int dim;
1409  };
1410 
1411  virtual ExprType prep(ExprFuncNode* node, bool wantScalar, ExprVarEnvBuilder& envBuilder) const {
1412  bool valid = true;
1413  valid &= node->checkArg(0, ExprType().String().Constant(), envBuilder);
1414  std::string varName = node->getStrArg(0);
1415  ExprVarNode* varNode = new ExprVarNode(node->expr(), varName.c_str());
1416  ExprType varType = varNode->prep(wantScalar, envBuilder);
1417  if (varType.isValid()) {
1418  node->removeLastChild(); // remove the useless default argument from the arugment list
1419  node->removeLastChild(); // remove the useless default argument from the arugment list
1420  node->addChild(varNode);
1421  } else {
1422  delete varNode;
1423  node->swapChildren(0, 1); // move the default argument in the beginning
1424  varType = node->child(0)->prep(wantScalar, envBuilder);
1425  node->removeLastChild(); // remove the useless string argument
1426  }
1427  return varType.isValid() ? varType : ExprType().Error();
1428  }
1429 
1430  virtual ExprFuncNode::Data* evalConstant(const ExprFuncNode* node, ArgHandle args) const {
1431  return new Data(node->type().isFP() ? getTemplatizedOp<Assign, Data::func>(node->type().dim()) : nullptr,
1432  node->type().dim());
1433  }
1434 
1435  template <int d>
1436  struct Assign {
1437  static void f(double* out, double* in) {
1438  for (int k = 0; k < d; k++) out[k] = in[k];
1439  }
1440  };
1441 
1442  virtual void eval(ArgHandle args) {
1443  Data* data = static_cast<Data*>(args.data);
1444  assert(data);
1445  double* out = &args.outFp;
1446  // for(int i=0;i<data->dim;i++) std::cerr<<" "<<args.inFp<1>(0)[i];
1447  // std::cerr<<std::endl;
1448  if (data->f)
1449  data->f(out, &args.inFp<1>(0)[0]);
1450  else
1451  throw std::runtime_error("getVar does not support non FP types right now got type");
1452  }
1453 
1454  public:
1455  GetVar() : ExprFuncSimple(true) {} // Thread Safe
1456  virtual ~GetVar() {}
1458 static const char* getVar_docstring =
1459  "getVar(string varName,vector defaultValue)\n"
1460  "return value of varName if variable exists, otherwise return defaultValue";
1461 
1462 class PrintFuncX : public ExprFuncSimple {
1463  struct Data : public ExprFuncNode::Data {
1464  std::vector<std::pair<int, int> > ranges;
1465  std::string format;
1466  };
1467 
1468  public:
1469  virtual ExprType prep(ExprFuncNode* node, bool wantScalar, ExprVarEnvBuilder& envBuilder) const {
1470  int nargs = node->numChildren();
1471  if (nargs < 1) {
1472  node->addError("Wrong number of arguments, should be GE 1");
1473  return ExprType().Error().Varying();
1474  }
1475 
1476  bool valid = true;
1477  valid &= node->checkArg(0, ExprType().String().Constant(), envBuilder);
1478  for (int i = 1; i < nargs; ++i)
1479  valid &=
1480  (node->checkArg(i, ExprType().FP(1), envBuilder) || node->checkArg(i, ExprType().FP(3), envBuilder));
1481  return ExprType().FP(1).Constant();
1482  }
1483 
1484  virtual ExprFuncNode::Data* evalConstant(const ExprFuncNode* node, ArgHandle args) const {
1485  // parse format string
1486  unsigned int bakeStart = 0;
1487  int searchStart = 0;
1488  int needed = 0;
1489  Data* data = new Data;
1490  data->format = args.inStr(0);
1491  std::string& format = data->format;
1492  std::vector<std::pair<int, int> >& ranges = data->ranges;
1493 
1494  int items = 0;
1495  while (1) {
1496  std::size_t percentStart = format.find('%', searchStart);
1497  if (percentStart == std::string::npos) break;
1498  if (percentStart + 1 == format.length()) {
1499  // node->addError("Unexpected end of format string");
1500  delete data;
1501  assert(false);
1502  } else if (format[percentStart + 1] == '%') {
1503  searchStart = static_cast<int>(percentStart + 2);
1504  continue;
1505  } else if (format[percentStart + 1] == 'v' || format[percentStart + 1] == 'f') {
1506  char c = format[percentStart + 1];
1507  int code = (c == 'v') ? -1 : -2;
1508  needed++;
1509  if (bakeStart != percentStart) ranges.push_back(std::pair<int, int>(bakeStart, static_cast<int>(percentStart)));
1510  ranges.push_back(std::pair<int, int>(code, code));
1511  items++;
1512  searchStart = static_cast<int>(percentStart + 2);
1513  bakeStart = searchStart;
1514  } else {
1515  // node->addError("Invalid format string, only %v is allowed");
1516  delete data;
1517  // TODO: check that this is correct
1518  // return ExprType().Error().Varying();
1519  // return false;
1520  assert(false);
1521  }
1522  }
1523  if (bakeStart != format.length()) ranges.push_back(std::pair<int, int>(bakeStart, static_cast<int>(format.length())));
1524 
1525  if (items != args.nargs() - 1) {
1526  // node->addError("Wrong number of arguments for format string");
1527  delete data;
1528  // TODO: check that this is correct
1529  // return ExprType().Error().Varying();
1530  // return false;
1531  assert(false);
1532  }
1533 
1534  return data;
1535  }
1536 
1537  virtual void eval(ArgHandle args) {
1538  Data* data = (Data*)args.data;
1539  int item = 1;
1540  for (unsigned int i = 0; i < data->ranges.size(); i++) {
1541  const std::pair<int, int>& range = data->ranges[i];
1542  if (range.first == -2) {
1543  std::cerr << args.inFp<1>(item)[0];
1544  item++;
1545  } else if (range.first == -1) {
1546  std::cerr << "[" << args.inFp<3>(item)[0] << "," << args.inFp<3>(item)[1] << ","
1547  << args.inFp<3>(item)[2] << "]";
1548  item++;
1549  } else {
1550  std::cerr << data->format.substr(range.first, range.second - range.first);
1551  }
1552  }
1553  std::cerr << std::endl;
1554 
1555  args.outFp = 0;
1556  }
1557 
1558  PrintFuncX() : ExprFuncSimple(false) {} // not thread safe
1559 
1561 static const char* printf_docstring =
1562  "printf(string format,[vec0, vec1, ...])\n"
1563  "Prints out a string to STDOUT, Format parameter allowed is %v";
1564 
1565 
1566 // Format specifier categories for SPrintFuncX
1567 static const std::string _intSpec("diouxXc");
1568 static const std::string _doubleSpec("eEfFgGaA");
1569 static const std::string _strSpec("s");
1570 
1572 {
1573  struct StringData : public SeExpr2::ExprFuncNode::Data, public std::string
1574  {
1575  };
1576 
1577 public:
1578  SPrintFuncX() : ExprFuncSimple(false) {} // not thread safe
1579 
1580  virtual ExprType prep(ExprFuncNode* node, bool wantScalar, ExprVarEnvBuilder& envBuilder) const
1581  {
1582  int nargs = node->numChildren();
1583  if (nargs < 1) {
1584  node->addError("Wrong number of arguments, should be >= 1");
1585  return ExprType().Error().Constant();
1586  }
1587  if (! node->checkArg(0, ExprType().String().Constant(), envBuilder)) {
1588  node->addError("First argument must be a string.");
1589  return ExprType().Error().Constant();
1590  }
1591 
1592  const std::string& format = static_cast<const ExprStrNode*>(node->child(0))->str();
1593 
1594  static const std::string strSpec("s");
1595  size_t searchStart = 0;
1596  size_t exprArg = 1;
1597  while (1) {
1598  const size_t specStart = format.find('%', searchStart);
1599  if (specStart == std::string::npos) break;
1600  if (specStart + 1 == format.length()) {
1601  node->addError("incomplete format specifier");
1602  return ExprType().Error().Constant();
1603  }
1604  if (format[specStart + 1] == '%') {
1605  searchStart = specStart + 2; // Skip "%%"
1606  continue;
1607  }
1608 
1609  const size_t specEnd = format.find_first_of(_intSpec + _doubleSpec + _strSpec,
1610  specStart);
1611  if (specEnd == std::string::npos) {
1612  node->addError("incomplete format specifier");
1613  return ExprType().Error().Constant();
1614  }
1615  if (_strSpec.find(format[specEnd]) != std::string::npos) {
1616  if (! node->checkArg(exprArg, ExprType().String(), envBuilder)) {
1617  return ExprType().Error().Constant();
1618  }
1619  }
1620  else {
1621  if (! node->checkArg(exprArg, ExprType().FP(1), envBuilder)) {
1622  return ExprType().Error().Constant();
1623  }
1624  }
1625  ++exprArg;
1626  searchStart = specEnd + 1;
1627  };
1628  return ExprType().String().Constant();
1629  }
1630 
1631  virtual ExprFuncNode::Data* evalConstant(const ExprFuncNode* node, ArgHandle args) const
1632  {
1633  return new StringData();
1634  }
1635 
1636  virtual void eval(ArgHandle args)
1637  {
1638  StringData& result = *reinterpret_cast<StringData*>(args.data);
1639  result.assign(args.inStr(0));
1640 
1641  char fragment[255];
1642  size_t searchStart = 0;
1643  size_t exprArg = 1;
1644  while (1) {
1645  const size_t specStart = result.find('%', searchStart);
1646  if (specStart == std::string::npos) break;
1647  if (result[specStart + 1] == '%') {
1648  result.erase(specStart, 1);
1649  searchStart = specStart + 1;
1650  continue;
1651  }
1652 
1653  const size_t specEnd = result.find_first_of(_intSpec + _doubleSpec + _strSpec,
1654  specStart);
1655  const std::string& spec = result.substr(specStart, specEnd - specStart + 1);
1656  int fragLen = -1;
1657  if (std::string::npos != _intSpec.find(result[specEnd]))
1658  fragLen = snprintf(fragment, 255, spec.c_str(),
1659  int(args.inFp<1>(exprArg++)[0]));
1660  else if (std::string::npos != _doubleSpec.find(result[specEnd]))
1661  fragLen = snprintf(fragment, 255, spec.c_str(),
1662  args.inFp<1>(exprArg++)[0]);
1663  else if (std::string::npos != _strSpec.find(result[specEnd]))
1664  fragLen = snprintf(fragment, 255, spec.c_str(),
1665  args.inStr(exprArg++));
1666  assert(fragLen >= 0);
1667 
1668  result.replace(specStart, spec.size(), fragment);
1669  searchStart += fragLen + 1;
1670  };
1671 
1672  args.outStr = const_cast<char*>(result.c_str());
1673  }
1674 
1676 static const char* sprintf_docstring =
1677  "sprintf(string format, [double|string, double|string, ...])\n"
1678  "Returns a string formatted from the given values. See 'man sprintf' for format details.";
1679 
1680 
1681 #if 0
1682 
1683 class TestFunc:public ExprFuncSimple
1684 {
1685  struct MyData:public ExprFuncNode::Data
1686  {
1687  float foo;
1688  MyData(float foo)
1689  :foo(foo)
1690  {}
1691  };
1692 public:
1693  TestFunc()
1694  :ExprFuncSimple(true)
1695  {}
1696  virtual ExprType prep(ExprFuncNode* node,bool scalarWanted,ExprVarEnvBuilder& envBuilder) const
1697  {
1698  bool valid=true;
1699  valid &= node->checkArg(0,ExprType().FP(3).Varying(),envBuilder);
1700  valid &= node->checkArg(1,ExprType().FP(1).Constant(),envBuilder);
1701  return valid ?ExprType().FP(3).Varying():ExprType().Error();
1702  }
1703  virtual ExprFuncNode::Data* evalConstant(ArgHandle args) const
1704  {
1705  //std::cerr<<"evalling const "<<args.inFp<1>(1)<<std::endl;
1706  return new MyData(args.inFp<1>(1)[0]);
1707  }
1708  virtual void eval(ArgHandle args)
1709  {
1710  MyData* data=static_cast<MyData*>(args.data);
1711 
1712  Vec<double,3,true>(&args.outFp)=args.inFp<3>(0)+Vec<double,3,false>(data->foo);
1713  }
1714 } testfunc;
1715 static const char* testfunc_docstring="fdsA";
1716 
1717 #endif
1718 
1720 // functions from math.h (global namespace)
1721 //#define FUNC(func) define(#func, ExprFunc(::func))
1722 #define FUNCADOC(name, func) define3(name, ExprFunc(::func), func##_docstring)
1723 #define FUNCDOC(func) define3(#func, ExprFunc(::func), func##_docstring)
1724  FUNCADOC("abs", fabs);
1725  FUNCDOC(acos);
1726  FUNCDOC(asin);
1727  FUNCDOC(atan);
1728  FUNCDOC(atan2);
1729  FUNCDOC(ceil);
1730  FUNCDOC(cos);
1731  FUNCDOC(cosh);
1732  FUNCDOC(exp);
1733  FUNCDOC(floor);
1734  FUNCDOC(fmod);
1735  FUNCDOC(log);
1736  FUNCDOC(log10);
1737  FUNCDOC(pow);
1738  FUNCDOC(sin);
1739  FUNCDOC(sinh);
1740  FUNCDOC(sqrt);
1741  FUNCDOC(tan);
1742  FUNCDOC(tanh);
1743 #ifndef SEEXPR_WIN32
1744  FUNCDOC(cbrt);
1745  FUNCDOC(asinh);
1746  FUNCDOC(acosh);
1747  FUNCDOC(atanh);
1748  FUNCDOC(trunc);
1749 #endif
1750 // local functions (SeExpr2 namespace)
1751 //#undef FUNC
1752 #undef FUNCDOC
1753 //#define FUNC(func) define(#func, ExprFunc(SeExpr2::func))
1754 //#define FUNCN(func, min, max) define(#func, ExprFunc(SeExpr2::func, min, max))
1755 #define FUNCDOC(func) define3(#func, ExprFunc(SeExpr2::func), func##_docstring)
1756 #define FUNCNDOC(func, min, max) define3(#func, ExprFunc(SeExpr2::func, min, max), func##_docstring)
1757 
1758  // trig
1759  FUNCDOC(deg);
1760  FUNCDOC(rad);
1761  FUNCDOC(cosd);
1762  FUNCDOC(sind);
1763  FUNCDOC(tand);
1764  FUNCDOC(acosd);
1765  FUNCDOC(asind);
1766  FUNCDOC(atand);
1767  FUNCDOC(atan2d);
1768 
1769  // clamping
1770  FUNCDOC(clamp);
1771  FUNCDOC(round);
1772  FUNCDOC(max);
1773  FUNCDOC(min);
1774 
1775  // blending / remapping
1776  FUNCDOC(invert);
1777  FUNCDOC(compress);
1778  FUNCDOC(expand);
1779  FUNCDOC(fit);
1780  FUNCDOC(gamma);
1781  FUNCDOC(bias);
1782  FUNCDOC(contrast);
1783  FUNCDOC(boxstep);
1786  FUNCDOC(gaussstep);
1787  FUNCDOC(remap);
1788  FUNCDOC(mix);
1789  FUNCNDOC(hsi, 4, 5);
1790  FUNCNDOC(midhsi, 5, 7);
1791  FUNCDOC(hsltorgb);
1792  FUNCDOC(rgbtohsl);
1793  FUNCNDOC(saturate, 2, 2);
1794 
1795  // noise
1796  FUNCNDOC(hash, 1, -1);
1797  FUNCNDOC(noise, 1, 4);
1798  FUNCDOC(snoise);
1799  FUNCDOC(vnoise);
1800  FUNCDOC(cnoise);
1801  FUNCNDOC(snoise4, 2, 2);
1802  FUNCNDOC(vnoise4, 2, 2);
1803  FUNCNDOC(cnoise4, 2, 2);
1804  FUNCNDOC(turbulence, 1, 4);
1805  FUNCNDOC(vturbulence, 1, 4);
1806  FUNCNDOC(cturbulence, 1, 4);
1807  FUNCNDOC(fbm, 1, 4);
1808  FUNCNDOC(vfbm, 1, 4);
1809  FUNCNDOC(cfbm, 1, 4);
1810  FUNCDOC(cellnoise);
1812  FUNCDOC(pnoise);
1813  FUNCNDOC(fbm4, 2, 5);
1814  FUNCNDOC(vfbm4, 2, 5);
1815  FUNCNDOC(cfbm4, 2, 5);
1816 
1817  // vectors
1818  FUNCDOC(dist);
1819  FUNCDOC(length);
1820  FUNCDOC(hypot);
1821  FUNCDOC(dot);
1822  FUNCDOC(norm);
1823  FUNCDOC(cross);
1824  FUNCDOC(angle);
1825  FUNCDOC(ortho);
1826  FUNCNDOC(rotate, 3, 3);
1827  FUNCDOC(up);
1828 
1829  // variations
1830  FUNCDOC(cycle);
1831  FUNCNDOC(pick, 3, -1);
1832  FUNCNDOC(choose, 3, -1);
1833  FUNCNDOC(wchoose, 4, -1);
1834  FUNCNDOC(swatch, 3, -1);
1835  FUNCNDOC(spline, 5, -1);
1836 
1837  // FuncX interface
1838  // noise
1839  FUNCNDOC(voronoi, 1, 7);
1840  FUNCNDOC(cvoronoi, 1, 7);
1841  FUNCNDOC(pvoronoi, 1, 6);
1842  // variations
1843  FUNCNDOC(curve, 1, -1);
1844  FUNCNDOC(ccurve, 1, -1);
1845  FUNCNDOC(getVar, 2, 2);
1846  FUNCNDOC(printf, 1, -1);
1847  // FUNCNDOC(testfunc,2,2);
1848 
1849  FUNCNDOC(sprintf, 1, -1);
1850 }
1851 }
SeExpr2::compress
double compress(double x, double lo, double hi)
Definition: ExprBuiltins.cpp:92
SeExpr2::noise_docstring
static const char * noise_docstring
Definition: ExprBuiltins.cpp:494
SeExpr2::pnoise
double pnoise(const Vec3d &p, const Vec3d &period)
Definition: ExprBuiltins.cpp:749
SeExpr2::dist_docstring
static const char * dist_docstring
Definition: ExprBuiltins.cpp:1058
SeExpr2::SPrintFuncX::SPrintFuncX
SPrintFuncX()
Definition: ExprBuiltins.cpp:1578
SeExpr2::saturate
static Vec3d saturate(const Vec3d &Cin, double amt)
Definition: ExprBuiltins.cpp:390
SeExpr2::vfbm
Vec3d vfbm(int n, const Vec3d *args)
Definition: ExprBuiltins.cpp:633
SeExpr2::dot
double dot(const Vec3d &a, const Vec3d &b)
Definition: ExprBuiltins.cpp:1072
SeExpr2::GetVar::~GetVar
virtual ~GetVar()
Definition: ExprBuiltins.cpp:1456
SeExpr2::VoronoiPointData::VoronoiPointData
VoronoiPointData()
Definition: ExprBuiltins.cpp:765
SeExpr2::CCurveFuncX::~CCurveFuncX
virtual ~CCurveFuncX()
Definition: ExprBuiltins.cpp:1394
SeExpr2::noise
double noise(int n, const Vec3d *args)
Definition: ExprBuiltins.cpp:461
SeExpr2::fit_docstring
static const char * fit_docstring
Definition: ExprBuiltins.cpp:104
index
The result is computed int int< br >< div style="margin-left: 40px;"> Picks values randomly between loRange and hiRange based on supplied index(which is automatically hashed). &nbsp
SeExpr2::spline_docstring
static const char * spline_docstring
Definition: ExprBuiltins.cpp:1284
SeExpr2::GetVar::Assign::f
static void f(double *out, double *in)
Definition: ExprBuiltins.cpp:1437
SeExpr2::dot_docstring
static const char * dot_docstring
Definition: ExprBuiltins.cpp:1073
SeExpr2::VoronoiPointData::cell
Vec3d cell
Definition: ExprBuiltins.cpp:763
FUNCADOC
#define FUNCADOC(name, func)
SeExpr2::rgbtohsl_docstring
static const char * rgbtohsl_docstring
Definition: ExprBuiltins.cpp:328
SeExpr2::ExprType::FP
ExprType & FP(int d)
Mutate this into a floating point type of dimension d.
Definition: ExprType.h:90
SeExpr2::ExprFuncNode::getStrArg
std::string getStrArg(int n) const
Definition: ExprNode.h:564
for
for(int i=0;i &lt;w;i++)
Definition: tutorial.txt:193
SeExpr2::sinh_docstring
static const char * sinh_docstring
Definition: ExprBuiltins.cpp:60
SeExpr2::GetVar
Definition: ExprBuiltins.cpp:1403
SeExpr2::rad
double rad(double angle)
Definition: ExprBuiltins.h:30
SeExpr2::expand_docstring
static const char * expand_docstring
Definition: ExprBuiltins.cpp:99
SeExpr2::ExprNode::numChildren
int numChildren() const
Number of children.
Definition: ExprNode.h:114
SeExpr2::ExprNode::type
const ExprType & type() const
The type of the node.
Definition: ExprNode.h:145
SeExpr2::getVar
SeExpr2::GetVar getVar
SeExpr2::vfbm4
Vec3d vfbm4(int n, const Vec3d *args)
Definition: ExprBuiltins.cpp:693
SeExpr2::swatch
double swatch(int n, double *params)
Definition: ExprBuiltins.cpp:1202
SeExpr2::hsi
Vec3d hsi(int n, const Vec3d *args)
Definition: ExprBuiltins.cpp:223
SeExpr2::up
Vec3d up(const Vec3d &P, const Vec3d &upvec)
Definition: ExprBuiltins.cpp:1122
SeExpr2::cturbulence
Vec3d cturbulence(int n, const Vec3d *args)
Definition: ExprBuiltins.cpp:599
SeExpr2::ExprNode::addError
void addError(const std::string &error) const
Register error. This will allow users and sophisticated editors to highlight where in code problem wa...
Definition: ExprNode.h:168
SeExpr2::hypot_docstring
static const char * hypot_docstring
Definition: ExprBuiltins.cpp:1068
SeExpr2::Vec< double, 3, false >
SeExpr2::cvoronoi_docstring
static const char * cvoronoi_docstring
Definition: ExprBuiltins.cpp:962
SeExpr2::sind_docstring
static const char * sind_docstring
Definition: ExprBuiltins.cpp:43
pos1
For applying the gamma function to a map adjusts the gamma of all three color channels< br >< br >< h4 >< a name="Curve_Functions"></a > Curve Functions</h4 >< p > Interpolation of parameter values to a set of control points is governed by the following functions</p >< p > color< b > and interp_i Interpolation codes are float float int float pos1
Definition: userdoc.txt:459
SeExpr2::atan2d
double atan2d(double y, double x)
Definition: ExprBuiltins.h:37
SeExpr2::mix_docstring
static const char * mix_docstring
Definition: ExprBuiltins.cpp:214
SeExpr2::CurveFuncX
Definition: ExprBuiltins.cpp:1295
SeExpr2::curve
SeExpr2::CurveFuncX curve
SeExpr2::pvoronoi
SeExpr2::CachedVoronoiFunc ExprFuncSimple pvoronoi(pvoronoiFn)
SeExpr2::ExprFuncSimple::ArgHandle::nargs
int nargs() const
Definition: ExprFuncX.h:89
SeExpr2::snoise4
double snoise4(int n, const Vec3d *args)
Definition: ExprBuiltins.cpp:526
SeExpr2::pnoise_docstring
static const char * pnoise_docstring
Definition: ExprBuiltins.cpp:758
SeExpr2::getVar_docstring
static const char * getVar_docstring
Definition: ExprBuiltins.cpp:1458
SeExpr2::CurveData::~CurveData
virtual ~CurveData()
Definition: ExprBuiltins.cpp:1292
SeExpr2::CachedVoronoiFunc::eval
virtual void eval(ArgHandle args)
Definition: ExprBuiltins.cpp:1033
SeExpr2::asind
double asind(double x)
Definition: ExprBuiltins.h:35
SeExpr2::cfbm_docstring
static const char * cfbm_docstring
Definition: ExprBuiltins.cpp:722
SeExpr2::vnoise4
Vec3d vnoise4(int n, const Vec3d *args)
Definition: ExprBuiltins.cpp:536
SeExpr2::atan2d_docstring
static const char * atan2d_docstring
Definition: ExprBuiltins.cpp:48
SeExpr2::voronoi_f1_3d
static void voronoi_f1_3d(VoronoiPointData &data, const Vec3d &p, double jitter, double &f1, Vec3d &pos1)
Definition: ExprBuiltins.cpp:785
SeExpr2::CurveFuncX::eval
virtual void eval(ArgHandle args)
Definition: ExprBuiltins.cpp:1334
SeExpr2::atan2_docstring
static const char * atan2_docstring
Definition: ExprBuiltins.cpp:57
SeExpr2::CachedVoronoiFunc
Definition: ExprBuiltins.cpp:1010
SeExpr2::Vec::dot
T dot(const Vec< T, d, refother > &o) const
Definition: Vec.h:330
Interpreter.h
SeExpr2::ExprType::Varying
ExprType & Varying()
Mutate this into a varying lifetime.
Definition: ExprType.h:122
SeExpr2::hsiAdjust
Vec3d hsiAdjust(const Vec3d &rgb, double h, double s, double i)
Definition: ExprBuiltins.cpp:216
SeExpr2::round
double round(double x)
Definition: ExprBuiltins.h:41
SeExpr2::CachedVoronoiFunc::evalConstant
virtual ExprFuncNode::Data * evalConstant(const ExprFuncNode *node, ArgHandle args) const
Definition: ExprBuiltins.cpp:1029
SeExpr2::trunc_docstring
static const char * trunc_docstring
Definition: ExprBuiltins.cpp:70
SeExpr2::length_docstring
static const char * length_docstring
Definition: ExprBuiltins.cpp:1063
SeExpr2::cnoise_docstring
static const char * cnoise_docstring
Definition: ExprBuiltins.cpp:522
SeExpr2::ExprFuncSimple
Definition: ExprFuncX.h:72
SeExpr2::CurveFuncX::prep
virtual ExprType prep(ExprFuncNode *node, bool scalarWanted, ExprVarEnvBuilder &envBuilder) const
Definition: ExprBuiltins.cpp:1299
SeExpr2::ExprFuncSimple::ArgHandle
Definition: ExprFuncX.h:76
SeExpr2::SPrintFuncX::eval
virtual void eval(ArgHandle args)
Definition: ExprBuiltins.cpp:1636
evalConstant
virtual ExprFuncNode::Data * evalConstant(const ExprFuncNode *node, ArgHandle args) const
Definition: ExprBuiltins.cpp:18
SeExpr2::remap
double remap(double x, double source, double range, double falloff, double interp)
Definition: ExprBuiltins.cpp:177
SeExpr2::ExprFunc::Define3
void(* Define3)(const char *name, ExprFunc f, const char *docString)
Definition: ExprFunc.h:65
SeExpr2::vnoise4_docstring
static const char * vnoise4_docstring
Definition: ExprBuiltins.cpp:542
SeExpr2::ExprFuncSimple::ArgHandle::inFp
Vec< double, d, true > inFp(int i)
Definition: ExprFuncX.h:85
SeExpr2::ExprType::Constant
ExprType & Constant()
Mutate this into a constant lifetime.
Definition: ExprType.h:112
SeExpr2::defineBuiltins
void defineBuiltins(ExprFunc::Define define, ExprFunc::Define3 define3)
Definition: ExprBuiltins.cpp:1719
SeExpr2::deg_docstring
static const char * deg_docstring
Definition: ExprBuiltins.cpp:39
SeExpr2::ortho_docstring
static const char * ortho_docstring
Definition: ExprBuiltins.cpp:1105
SeExpr2::snoise_docstring
static const char * snoise_docstring
Definition: ExprBuiltins.cpp:507
SeExpr2::atan_docstring
static const char * atan_docstring
Definition: ExprBuiltins.cpp:56
SeExpr2::ccurve
SeExpr2::CCurveFuncX ccurve
SeExpr2::choose
double choose(int n, double *params)
Definition: ExprBuiltins.cpp:1207
SeExpr2::ccellnoise
Vec3d ccellnoise(const Vec3d &p)
Definition: ExprBuiltins.cpp:738
SeExpr2::voronoiFn
Vec3d voronoiFn(VoronoiPointData &data, int n, const Vec3d *args)
Definition: ExprBuiltins.cpp:834
SeExpr2::sind
double sind(double x)
Definition: ExprBuiltins.h:32
SeExpr2::acosd_docstring
static const char * acosd_docstring
Definition: ExprBuiltins.cpp:45
SeExpr2::SPrintFuncX
Definition: ExprBuiltins.cpp:1572
SeExpr2::invert
double invert(double x)
Definition: ExprBuiltins.h:46
SeExpr2::invert_docstring
static const char * invert_docstring
Definition: ExprBuiltins.cpp:74
SeExpr2::snoise4_docstring
static const char * snoise4_docstring
Definition: ExprBuiltins.cpp:532
SeExpr2::ExprType::dim
int dim() const
Definition: ExprType.h:160
ExprFunc.h
SeExpr2::asind_docstring
static const char * asind_docstring
Definition: ExprBuiltins.cpp:46
SeExpr2::smoothstep_docstring
static const char * smoothstep_docstring
Definition: ExprBuiltins.cpp:156
SeExpr2::cycle_docstring
static const char * cycle_docstring
Definition: ExprBuiltins.cpp:1140
SeExpr2::tand
double tand(double x)
Definition: ExprBuiltins.h:33
SeExpr2::cfbm4
Vec3d cfbm4(int n, const Vec3d *args)
Definition: ExprBuiltins.cpp:724
SeExpr2::voronoi
SeExpr2::CurveData voronoi
SeExpr2::ExprType
Definition: ExprType.h:39
SeExpr2::swatch_docstring
static const char * swatch_docstring
Definition: ExprBuiltins.cpp:1203
SeExpr2::ExprFuncNode
Node that calls a function.
Definition: ExprNode.h:517
Platform.h
Platform-specific classes, functions, and includes.
SeExpr2::wchoose_docstring
static const char * wchoose_docstring
Definition: ExprBuiltins.cpp:1265
SeExpr2::asin_docstring
static const char * asin_docstring
Definition: ExprBuiltins.cpp:55
SeExpr2::pick_docstring
static const char * pick_docstring
Definition: ExprBuiltins.cpp:1195
SeExpr2::ExprFuncSimple::ArgHandle::data
ExprFuncNode::Data * data
Definition: ExprFuncX.h:99
SeExpr2::contrast
double contrast(double x, double c)
Definition: ExprBuiltins.cpp:118
SeExpr2::length
double length(const Vec3d &v)
Definition: ExprBuiltins.cpp:1062
SeExpr2::CCurveFuncX::evalConstant
virtual ExprFuncNode::Data * evalConstant(const ExprFuncNode *node, ArgHandle args) const
Definition: ExprBuiltins.cpp:1367
SeExpr2::PrintFuncX::prep
virtual ExprType prep(ExprFuncNode *node, bool wantScalar, ExprVarEnvBuilder &envBuilder) const
Definition: ExprBuiltins.cpp:1469
SeExpr2::CCurveFuncX::CCurveFuncX
CCurveFuncX()
Definition: ExprBuiltins.cpp:1393
SeExpr2::ExprType::String
ExprType & String()
Mutate this into a string type.
Definition: ExprType.h:96
SeExpr2::VoronoiPointData
Definition: ExprBuiltins.cpp:761
SeExpr2::rad_docstring
static const char * rad_docstring
Definition: ExprBuiltins.cpp:40
SeExpr2::SPrintFuncX::evalConstant
virtual ExprFuncNode::Data * evalConstant(const ExprFuncNode *node, ArgHandle args) const
Definition: ExprBuiltins.cpp:1631
SeExpr2::pick
double pick(int n, double *params)
Definition: ExprBuiltins.cpp:1146
SeExpr2::atanh_docstring
static const char * atanh_docstring
Definition: ExprBuiltins.cpp:64
y
This is the same as the prman cellnoise function< br ></div >< br > float< b > float y< br > float< b > float y
Definition: userdoc.txt:218
SeExpr2::CachedVoronoiFunc::CachedVoronoiFunc
CachedVoronoiFunc(VoronoiFunc *vfunc)
Definition: ExprBuiltins.cpp:1013
SeExpr2::tan_docstring
static const char * tan_docstring
Definition: ExprBuiltins.cpp:53
SeExpr2::ExprType::isValid
bool isValid() const
Definition: ExprType.h:167
SeExpr2::bias
double bias(double x, double b)
Definition: ExprBuiltins.cpp:110
SeExpr2::smoothstep
double smoothstep(double x, double a, double b)
Definition: ExprBuiltins.cpp:143
SeExpr2::PrintFuncX::Data::format
std::string format
Definition: ExprBuiltins.cpp:1465
SeExpr2::GetVar::GetVar
GetVar()
Definition: ExprBuiltins.cpp:1455
SeExpr2::sprintf
SeExpr2::SPrintFuncX sprintf
SeExpr2::cosd
double cosd(double x)
Definition: ExprBuiltins.h:31
SeExpr2::voronoi_docstring
static const char * voronoi_docstring
Definition: ExprBuiltins.cpp:895
SeExpr2::dist
double dist(double ax, double ay, double az, double bx, double by, double bz)
Definition: ExprBuiltins.cpp:1052
SeExpr2::cbrt_docstring
static const char * cbrt_docstring
Definition: ExprBuiltins.cpp:75
SeExpr2::hash_docstring
static const char * hash_docstring
Definition: ExprBuiltins.cpp:456
SeExpr2::CCurveFuncX
Definition: ExprBuiltins.cpp:1348
FUNCDOC
#define FUNCDOC(func)
SeExpr2::pow_docstring
static const char * pow_docstring
Definition: ExprBuiltins.cpp:78
SeExpr2::cnoise4_docstring
static const char * cnoise4_docstring
Definition: ExprBuiltins.cpp:547
hiRange
The result is computed int int hiRange
Definition: userdoc.txt:322
SeExpr2
Definition: Context.h:22
SeExpr2::GetVar::prep
virtual ExprType prep(ExprFuncNode *node, bool wantScalar, ExprVarEnvBuilder &envBuilder) const
Definition: ExprBuiltins.cpp:1411
SeExpr2::choose_docstring
static const char * choose_docstring
Definition: ExprBuiltins.cpp:1215
loRange
The result is computed int loRange
Definition: userdoc.txt:322
SeExpr2::expand
double expand(double x, double lo, double hi)
Definition: ExprBuiltins.cpp:95
a1
Defined as float g float a1
Definition: userdoc.txt:162
SeExpr2::mix
double mix(double x, double y, double alpha)
Definition: ExprBuiltins.cpp:213
SeExpr2::acosh_docstring
static const char * acosh_docstring
Definition: ExprBuiltins.cpp:62
SeExpr2::rotate_docstring
static const char * rotate_docstring
Definition: ExprBuiltins.cpp:1118
ExprNode.h
Vec.h
SeExpr2::min
double min(double x, double y)
Definition: ExprBuiltins.h:43
SeExpr2::GetVar::Data::func
void(* func)(double *in, double *out)
Definition: ExprBuiltins.cpp:1405
SeExpr2::printf_docstring
static const char * printf_docstring
Definition: ExprBuiltins.cpp:1561
SeExpr2::ccurve_docstring
static const char * ccurve_docstring
Definition: ExprBuiltins.cpp:1396
SeExpr2::boxstep_docstring
static const char * boxstep_docstring
Definition: ExprBuiltins.cpp:129
SeExpr2::ExprFuncSimple::ArgHandle::outFp
double & outFp
Definition: ExprFuncX.h:97
SeExpr2::Curve
Interpolation curve class for double->double and double->Vec3D.
Definition: Curve.h:38
SeExpr2::GetVar::Data::f
func f
Definition: ExprBuiltins.cpp:1407
SeExpr2::vturbulence
Vec3d vturbulence(int n, const Vec3d *args)
Definition: ExprBuiltins.cpp:575
SeExpr2::pvoronoi_docstring
static const char * pvoronoi_docstring
Definition: ExprBuiltins.cpp:1005
SeExpr2::CurveFuncX::evalConstant
virtual ExprFuncNode::Data * evalConstant(const ExprFuncNode *node, ArgHandle args) const
Definition: ExprBuiltins.cpp:1317
SeExpr2::cycle
double cycle(double index, double loRange, double hiRange)
Definition: ExprBuiltins.cpp:1131
SeExpr2::vfbm4_docstring
static const char * vfbm4_docstring
Definition: ExprBuiltins.cpp:719
ExprBuiltins.h
SeExpr2::ExprFuncSimple::ArgHandle::outStr
char *& outStr
Definition: ExprFuncX.h:98
SeExpr2::_strSpec
static const std::string _strSpec("s")
SeExpr2::linearstep
double linearstep(double x, double a, double b)
Definition: ExprBuiltins.cpp:131
SeExpr2::cnoise
Vec3d cnoise(const Vec3d &p)
Definition: ExprBuiltins.cpp:521
SeExpr2::tand_docstring
static const char * tand_docstring
Definition: ExprBuiltins.cpp:44
SeExpr2::ExprType::Error
ExprType & Error()
Mutate this into an error type.
Definition: ExprType.h:102
SeExpr2::hsi_docstring
static const char * hsi_docstring
Definition: ExprBuiltins.cpp:238
SeExpr2::PrintFuncX::evalConstant
virtual ExprFuncNode::Data * evalConstant(const ExprFuncNode *node, ArgHandle args) const
Definition: ExprBuiltins.cpp:1484
SeExpr2::cross
Vec3d cross(const Vec3d &a, const Vec3d &b)
Definition: ExprBuiltins.cpp:1088
SeExpr2::log_docstring
static const char * log_docstring
Definition: ExprBuiltins.cpp:79
SeExpr2::clamp
double clamp(double x, double lo, double hi)
Definition: ExprBuiltins.h:40
SeExpr2::ExprVarEnvBuilder
Variable scope builder is used by the type checking and code gen to track visiblity of variables and ...
Definition: ExprEnv.h:148
SeExpr2::PrintFuncX
Definition: ExprBuiltins.cpp:1462
SeExpr2::SPrintFuncX::prep
virtual ExprType prep(ExprFuncNode *node, bool wantScalar, ExprVarEnvBuilder &envBuilder) const
Definition: ExprBuiltins.cpp:1580
SeExpr2::ExprFuncNode::checkArg
bool checkArg(int argIndex, ExprType type, ExprVarEnvBuilder &envBuilder)
Definition: ExprNode.cpp:578
SeExpr2::curve_docstring
static const char * curve_docstring
Definition: ExprBuiltins.cpp:1341
SeExpr2::SPrintFuncX::StringData
Definition: ExprBuiltins.cpp:1574
SeExpr2::cross_docstring
static const char * cross_docstring
Definition: ExprBuiltins.cpp:1091
SeExpr2::sin_docstring
static const char * sin_docstring
Definition: ExprBuiltins.cpp:52
SeExpr2::CachedVoronoiFunc::_vfunc
VoronoiFunc * _vfunc
Definition: ExprBuiltins.cpp:1049
SeExpr2::_intSpec
static const std::string _intSpec("diouxXc")
SeExpr2::atand_docstring
static const char * atand_docstring
Definition: ExprBuiltins.cpp:47
SeExpr2::ExprType::isFP
bool isFP() const
Direct is predicate checks.
Definition: ExprType.h:164
SeExpr2::max
double max(double x, double y)
Definition: ExprBuiltins.h:42
SeExpr2::clamp_docstring
static const char * clamp_docstring
Definition: ExprBuiltins.cpp:66
SeExpr2::VoronoiPointData::points
Vec3d points[27]
Definition: ExprBuiltins.cpp:762
prep
virtual ExprType prep(ExprFuncNode *node, bool scalarWanted, ExprVarEnvBuilder &envBuilder) const
Definition: ExprBuiltins.cpp:4
SeExpr2::fbm4_docstring
static const char * fbm4_docstring
Definition: ExprBuiltins.cpp:684
SeExpr2::midhsi
Vec3d midhsi(int n, const Vec3d *args)
Definition: ExprBuiltins.cpp:247
SeExpr2::ExprVarNode
Node that references a variable.
Definition: ExprNode.h:465
SeExpr2::ExprNode::addChild
void addChild(ExprNode *child)
Add a child to the child list (for parser use only)
Definition: ExprNode.cpp:90
SeExpr2::CachedVoronoiFunc::~CachedVoronoiFunc
virtual ~CachedVoronoiFunc()
Definition: ExprBuiltins.cpp:1046
SeExpr2::midhsi_docstring
static const char * midhsi_docstring
Definition: ExprBuiltins.cpp:279
SeExpr2::exp_docstring
static const char * exp_docstring
Definition: ExprBuiltins.cpp:77
SeExpr2::ExprNode::prep
virtual ExprType prep(bool dontNeedScalar, ExprVarEnvBuilder &envBuilder)
Definition: ExprNode.cpp:104
SeExpr2::min_docstring
static const char * min_docstring
Definition: ExprBuiltins.cpp:69
SeExpr2::snoise
double snoise(const Vec3d &p)
Definition: ExprBuiltins.cpp:501
SeExpr2::round_docstring
static const char * round_docstring
Definition: ExprBuiltins.cpp:67
SeExpr2::vnoise_docstring
static const char * vnoise_docstring
Definition: ExprBuiltins.cpp:517
eval
virtual void eval(ArgHandle args)
Definition: ExprBuiltins.cpp:22
SeExpr2::CCurveFuncX::eval
virtual void eval(ArgHandle args)
Definition: ExprBuiltins.cpp:1384
SeExpr2::hypot
double hypot(double x, double y)
Definition: ExprBuiltins.cpp:1067
SeExpr2::GetVar::Data
Definition: ExprBuiltins.cpp:1404
SeExpr2::Vec::rotateBy
T_VEC_VALUE rotateBy(const Vec< T, 3, refother > &axis, T angle) const
Definition: Vec.h:366
SeExpr2::deg
double deg(double angle)
Definition: ExprBuiltins.h:29
a
Defined as a *alpha b *alpha< br ></div >< br > float< b > float a
Definition: userdoc.txt:174
SeExpr2::CurveData::curve
Curve< T > curve
Definition: ExprBuiltins.cpp:1291
SeExpr2::PrintFuncX::Data::ranges
std::vector< std::pair< int, int > > ranges
Definition: ExprBuiltins.cpp:1464
SeExpr2::rotate
Vec3d rotate(int n, const Vec3d *args)
Definition: ExprBuiltins.cpp:1109
SeExpr2::acosd
double acosd(double x)
Definition: ExprBuiltins.h:34
SeExpr2::fit
double fit(double x, double a1, double b1, double a2, double b2)
Definition: ExprBuiltins.cpp:101
SeExpr2::ExprNode::swapChildren
void swapChildren(size_t i, size_t j)
Swap children, do not use unless you know what you are doing.
Definition: ExprNode.h:123
SeExpr2::cturbulence_docstring
static const char * cturbulence_docstring
Definition: ExprBuiltins.cpp:85
SeExpr2::vnoise
Vec3d vnoise(const Vec3d &p)
Definition: ExprBuiltins.cpp:511
SeExpr2::wchoose
double wchoose(int n, double *params)
Definition: ExprBuiltins.cpp:1219
SeExpr2::cosd_docstring
static const char * cosd_docstring
Definition: ExprBuiltins.cpp:42
SeExpr2::cnoise4
Vec3d cnoise4(int n, const Vec3d *args)
Definition: ExprBuiltins.cpp:546
SeExpr2::Vec3d
Vec< double, 3, false > Vec3d
Definition: Vec.h:384
SeExpr2::fbm
double fbm(int n, const Vec3d *args)
Definition: ExprBuiltins.cpp:601
SeExpr2::CachedVoronoiFunc::VoronoiFunc
Vec3d VoronoiFunc(VoronoiPointData &data, int n, const Vec3d *args)
Definition: ExprBuiltins.cpp:1012
SeExpr2::voronoi_f1f2_3d
static void voronoi_f1f2_3d(VoronoiPointData &data, const Vec3d &p, double jitter, double &f1, Vec3d &pos1, double &f2, Vec3d &pos2)
Definition: ExprBuiltins.cpp:804
SeExpr2::gamma
double gamma(double x, double g)
Definition: ExprBuiltins.cpp:107
SeExpr2::CurveData
Definition: ExprBuiltins.cpp:1290
SeExpr2::fbm4
double fbm4(int n, const Vec3d *args)
Definition: ExprBuiltins.cpp:658
SeExpr2::asinh_docstring
static const char * asinh_docstring
Definition: ExprBuiltins.cpp:63
SeExpr2::compress_docstring
static const char * compress_docstring
Definition: ExprBuiltins.cpp:93
SeExpr2::VoronoiPointData::jitter
double jitter
Definition: ExprBuiltins.cpp:764
SeExpr2::turbulence_docstring
static const char * turbulence_docstring
Definition: ExprBuiltins.cpp:82
SeExpr2::ExprStrNode
Node that stores a string.
Definition: ExprNode.h:502
SeExpr2::linearstep_docstring
static const char * linearstep_docstring
Definition: ExprBuiltins.cpp:139
SeExpr2::PrintFuncX::eval
virtual void eval(ArgHandle args)
Definition: ExprBuiltins.cpp:1537
SeExpr2::rgbtohsl
Vec3d rgbtohsl(const Vec3d &rgb)
Definition: ExprBuiltins.cpp:285
SeExpr2::cvoronoi
SeExpr2::CachedVoronoiFunc ExprFuncSimple cvoronoi(cvoronoiFn)
SeExpr2::CCurveFuncX::prep
virtual ExprType prep(ExprFuncNode *node, bool wantScalar, ExprVarEnvBuilder &envBuilder) const
Definition: ExprBuiltins.cpp:1349
SeExpr2::cfbm4_docstring
static const char * cfbm4_docstring
Definition: ExprBuiltins.cpp:725
SeExpr2::cvoronoiFn
Vec3d cvoronoiFn(VoronoiPointData &data, int n, const Vec3d *args)
Definition: ExprBuiltins.cpp:900
SeExpr2::ExprFuncNode::Data
base class for custom instance data
Definition: ExprNode.h:570
SeExpr2::contrast_docstring
static const char * contrast_docstring
Definition: ExprBuiltins.cpp:124
SeExpr2::ExprNode::expr
const Expression * expr() const
Access expression.
Definition: ExprNode.h:102
SeExpr2::PrintFuncX::Data
Definition: ExprBuiltins.cpp:1463
SeExpr2::GetVar::evalConstant
virtual ExprFuncNode::Data * evalConstant(const ExprFuncNode *node, ArgHandle args) const
Definition: ExprBuiltins.cpp:1430
SeExpr2::ExprFuncSimple::ArgHandle::inStr
char * inStr(int i)
Definition: ExprFuncX.h:88
Curve.h
SeExpr2::sqrt_docstring
static const char * sqrt_docstring
Definition: ExprBuiltins.cpp:76
a2
Defined as float g float float float a2
Definition: userdoc.txt:162
SeExpr2::hsltorgb
Vec3d hsltorgb(const Vec3d &hsl)
Definition: ExprBuiltins.cpp:350
SeExpr2::vfbm_docstring
static const char * vfbm_docstring
Definition: ExprBuiltins.cpp:656
SeExpr2::fbm_docstring
static const char * fbm_docstring
Definition: ExprBuiltins.cpp:624
SeExpr2::ccellnoise_docstring
static const char * ccellnoise_docstring
Definition: ExprBuiltins.cpp:744
p
static const int p[514]
Definition: NoiseTables.h:20
SeExpr2::GetVar::Assign
Definition: ExprBuiltins.cpp:1436
SeExpr2::cellnoise_docstring
static const char * cellnoise_docstring
Definition: ExprBuiltins.cpp:733
SeExpr2::tanh_docstring
static const char * tanh_docstring
Definition: ExprBuiltins.cpp:61
SeExpr2::angle_docstring
static const char * angle_docstring
Definition: ExprBuiltins.cpp:1100
SeExpr2::fmod_docstring
static const char * fmod_docstring
Definition: ExprBuiltins.cpp:81
b1
Defined as float g float float b1
Definition: userdoc.txt:162
SeExpr2::GetVar::Data::dim
int dim
Definition: ExprBuiltins.cpp:1408
SeExpr2::floor_docstring
static const char * floor_docstring
Definition: ExprBuiltins.cpp:71
SeExpr2::saturate_docstring
static const char * saturate_docstring
Definition: ExprBuiltins.cpp:403
SeExpr2::GetVar::eval
virtual void eval(ArgHandle args)
Definition: ExprBuiltins.cpp:1442
SeExpr2::ortho
Vec3d ortho(const Vec3d &a, const Vec3d &b)
Definition: ExprBuiltins.cpp:1104
SeExpr2::hsltorgb_docstring
static const char * hsltorgb_docstring
Definition: ExprBuiltins.cpp:381
SeExpr2::angle
double angle(const Vec3d &a, const Vec3d &b)
Definition: ExprBuiltins.cpp:1095
SeExpr2::boxstep
double boxstep(double x, double a)
Definition: ExprBuiltins.cpp:128
SeExpr2::gamma_docstring
static const char * gamma_docstring
Definition: ExprBuiltins.cpp:108
SeExpr2::ExprFunc::Define
void(* Define)(const char *name, ExprFunc f)
Definition: ExprFunc.h:64
Noise.h
SeExpr2::printf
SeExpr2::PrintFuncX printf
SeExpr2::ExprNode::child
const ExprNode * child(size_t i) const
Get 0 indexed child.
Definition: ExprNode.h:117
SeExpr2::atand
double atand(double x)
Definition: ExprBuiltins.h:36
SeExpr2::PrintFuncX::PrintFuncX
PrintFuncX()
Definition: ExprBuiltins.cpp:1558
SeExpr2::up_docstring
static const char * up_docstring
Definition: ExprBuiltins.cpp:1127
SeExpr2::turbulence
double turbulence(int n, const Vec3d *args)
Definition: ExprBuiltins.cpp:551
SeExpr2::ceil_docstring
static const char * ceil_docstring
Definition: ExprBuiltins.cpp:72
SeExpr2::GetVar::Data::Data
Data(func fIn, int dim)
Definition: ExprBuiltins.cpp:1406
SeExpr2::remap_docstring
static const char * remap_docstring
Definition: ExprBuiltins.cpp:201
SeExpr2::Curve::InterpType
InterpType
Supported interpolation types.
Definition: Curve.h:43
SeExpr2::cos_docstring
static const char * cos_docstring
Definition: ExprBuiltins.cpp:51
SeExpr2::acos_docstring
static const char * acos_docstring
Definition: ExprBuiltins.cpp:54
SeExpr2::_doubleSpec
static const std::string _doubleSpec("eEfFgGaA")
SeExpr2::hslvalue
static double hslvalue(double x, double y, double H)
Definition: ExprBuiltins.cpp:337
SeExpr2::cosh_docstring
static const char * cosh_docstring
Definition: ExprBuiltins.cpp:59
source
When x is within< i > range</i > of source
Definition: userdoc.txt:111
sin
* sin(val)/val" </pre> we would get <pre> | | | | | </pre> or if we did <pre> ./asciiGraph "x-3" </pre> we'd get <pre> | | ------------------------------|----------------- | | | | | </pre> <h2>Implement the subclass</h2> First we subclass Expression and give it a const ructor
SeExpr2::norm_docstring
static const char * norm_docstring
Definition: ExprBuiltins.cpp:1084
z
This is the same as the prman cellnoise function< br ></div >< br > float< b > float y< br > float< b > float float z
Definition: userdoc.txt:218
SeExpr2::hash
double hash(int n, double *args)
Definition: ExprBuiltins.cpp:409
SeExpr2::CurveFuncX::CurveFuncX
CurveFuncX()
Definition: ExprBuiltins.cpp:1297
x
</pre >< h3 > A simple variable reference</h3 > This is not a very interesting subclass of expression until we add some additional variables Variables on some applications may be very dynamic In this we only need x
Definition: tutorial.txt:108
SeExpr2::max_docstring
static const char * max_docstring
Definition: ExprBuiltins.cpp:68
b
Between a and b
Definition: userdoc.txt:180
SeExpr2::cellnoise
double cellnoise(const Vec3d &p)
Definition: ExprBuiltins.cpp:727
SeExpr2::ExprNode::removeLastChild
void removeLastChild()
Remove last child and delete the entry.
Definition: ExprNode.h:129
SeExpr2::pvoronoiFn
Vec3d pvoronoiFn(VoronoiPointData &data, int n, const Vec3d *args)
Definition: ExprBuiltins.cpp:967
SeExpr2::gaussstep
double gaussstep(double x, double a, double b)
Definition: ExprBuiltins.cpp:160
pow
< br > pow($a, 0.5)+ $b< br >< br ></div > External variables can also be overridden by local assignment. &nbsp
SeExpr2::sprintf_docstring
static const char * sprintf_docstring
Definition: ExprBuiltins.cpp:1676
SeExpr2::cfbm
Vec3d cfbm(int n, const Vec3d *args)
Definition: ExprBuiltins.cpp:721
SeExpr2::fabs_docstring
static const char * fabs_docstring
Definition: ExprBuiltins.cpp:36
SeExpr2::norm
Vec3d norm(const Vec3d &a)
Definition: ExprBuiltins.cpp:1077
SeExpr2::ExprVarNode::prep
virtual ExprType prep(bool wantScalar, ExprVarEnvBuilder &envBuilder)
Definition: ExprNode.cpp:485
SeExpr2::log10_docstring
static const char * log10_docstring
Definition: ExprBuiltins.cpp:80
SeExpr2::voronoi_points
static Vec3d * voronoi_points(VoronoiPointData &data, const Vec3d &cell, double jitter)
Definition: ExprBuiltins.cpp:768
SeExpr2::gaussstep_docstring
static const char * gaussstep_docstring
Definition: ExprBuiltins.cpp:173
FUNCNDOC
#define FUNCNDOC(func, min, max)
SeExpr2::spline
double spline(int n, double *params)
Definition: ExprBuiltins.cpp:1270
SeExpr2::Vec::length
T length() const
Euclidean (2) norm.
Definition: Vec.h:211
SeExpr2::vturbulence_docstring
static const char * vturbulence_docstring
Definition: ExprBuiltins.cpp:88
SeExpr2::bias_docstring
static const char * bias_docstring
Definition: ExprBuiltins.cpp:114
SeExpr2::CachedVoronoiFunc::prep
virtual ExprType prep(ExprFuncNode *node, bool scalarWanted, ExprVarEnvBuilder &envBuilder) const
Definition: ExprBuiltins.cpp:1015