1//    Persistence of Vision Ray Tracer version 3.5 Include File
2
3#ifndef(Functions_Inc_Temp)
4#declare Functions_Inc_Temp = version;
5#version 3.5;
6
7#ifdef(View_POV_Include_Stack)
8#   debug "including function.inc\n"
9#end
10
11/*
12              Persistence of Vision Raytracer Version 3.5
13            Many pre-defined functions for use in scene files.
14*/
15
16#declare f_algbr_cyl1 = function { internal(0) }
17// Parameters: x, y, z
18    // Five extra parameters required:
19    // 1. Field Strength
20    // 2. Field Limit
21    // 3. SOR Switch
22    // 4. SOR Offset
23    // 5. SOR Angle
24
25#declare f_algbr_cyl2 = function { internal(1) }
26// Parameters: x, y, z
27    // Five extra parameters required:
28    // 1. Field Strength
29    // 2. Field Limit
30    // 3. SOR Switch
31    // 4. SOR Offset
32    // 5. SOR Angle
33
34#declare f_algbr_cyl3 = function { internal(2) }
35// Parameters: x, y, z
36    // Five extra parameters required:
37    // 1. Field Strength
38    // 2. Field Limit
39    // 3. SOR Switch
40    // 4. SOR Offset
41    // 5. SOR Angle
42
43#declare f_algbr_cyl4 = function { internal(3) }
44// Parameters: x, y, z
45    // Five extra parameters required:
46    // 1. Field Strength
47    // 2. Field Limit
48    // 3. SOR Switch
49    // 4. SOR Offset
50    // 5. SOR Angle
51
52#declare f_bicorn = function { internal(4) }
53// Parameters: x, y, z
54    // Two extra parameters required:
55    // 1. Field Strength
56    // 2. Scale. The surface is always the same shape.
57    //           Changing this parameter has the same effect as adding a scale modifier.
58    //           Setting the scale to 1 gives a surface with a radius of about 1 unit.
59
60#declare f_bifolia = function { internal(5) }
61// Parameters: x, y, z
62    // Two extra parameters required:
63    // 1. Field Strength
64    // 2. Scale. The mathematics of this surface suggest that the shape
65    //           should be different for different values of this parameter.
66    //           In practice the difference in shape is hard to spot.
67    //           Setting the scale to 3 gives a surface with a radius of about 1 unit.
68
69#declare f_blob = function { internal(6) }
70// Parameters: x, y, z
71    // Five extra parameters required:
72    // 1. x distance between the two components
73    // 2. blob strength of component 1
74    // 3. inverse blob radius of component 1
75    // 4. blob strength of component 2
76    // 5.inverse blob radius of component 2
77
78#declare f_blob2 = function { internal(7) }
79// Parameters: x, y, z
80    //Four extra parameters required:
81    // 1. Separation. One blob component is at the origin
82    //    and the other is this distance away on the x axis
83    // 2. inverse size. Increase this to decrease the size of the surface
84    // 3. blob strength
85    // 4. threshold. Setting this parameter to 1
86    //    and the threshold to zero has exactly the same effect
87    //    as setting this parameter to zero and the threshold to -1
88
89#declare f_boy_surface = function { internal(8) }
90// Parameters: x, y, z
91    // Two extra parameters required:
92    // 1. Field Strength
93    // 2. Scale. The surface is always the same shape.
94    //    Changing this parameter has the same effect as adding a scale modifier
95
96#declare f_comma = function { internal(9) }
97// Parameters: x, y, z
98    // One extra parameter required:
99    // 1. scale
100
101#declare f_cross_ellipsoids = function { internal(10) }
102// Parameters: x, y, z
103    // Four extra paraameters required
104    // 1. eccentricity. When less than 1,
105    //    the ellipsoids are oblate,
106    //    when greater than 1 the ellipsoids are prolate,
107    //    when zero the ellipsoids are spherical
108    //    (and hence the whole surface is a sphere)
109    // 2. inverse size. Increase this to decrease the size of the surface
110    // 3. Diameter. Increase this to increase the size of the ellipsoids
111    // 4. threshold. Setting this parameter to 1 and the threshold to zero
112    //    has exactly the same effect as setting this parameter to zero
113    //    and the threshold to -1
114
115#declare f_crossed_trough = function { internal(11) }
116// Parameters: x, y, z
117    // One extra parameter required:
118    // 1.  Field Strength
119
120#declare f_cubic_saddle = function { internal(12) }
121// Parameters: x, y, z
122    // One extra parameter required:
123    // 1. Field Strength
124
125#declare f_cushion = function { internal(13) }
126// Parameters: x, y, z
127    // One extra parameter required:
128    // 1. Field Strength
129
130#declare f_devils_curve = function { internal(14) }
131// Parameters: x, y, z
132    // One extra parameter required:
133    // 1. Field Strength
134
135#declare f_devils_curve_2d = function { internal(15) }
136// Parameters: x, y, z
137    // Six extra parameters required:
138    // 1. Field Strength
139    // 2. X factor
140    // 3. Y factor
141    // 4. SOR Switch
142    // 5. SOR Offset
143    // 6. SOR Angle
144
145#declare f_dupin_cyclid = function { internal(16) }
146// Parameters: x, y, z
147    // Six extra parameters required:
148    // 1. Field Strength
149    // 2. Major radius of torus
150    // 3. Minor radius of torus
151    // 4. X displacement of torus
152    // 5. Y displacement of torus
153    // 6. Radius of inversion
154
155#declare f_ellipsoid = function { internal(17) }
156// Parameters: x, y, z
157    // Three extra parameters required:
158    // 1. x scale (inverse)
159    // 2. y scale (inverse)
160    // 3. z scale (inverse)
161
162#declare f_enneper = function { internal(18) }
163// Parameters: x, y, z
164    // One extra parameter required:
165    // 1. Field strength
166
167#declare f_flange_cover = function { internal(19) }
168// Parameters: x, y, z
169    // Four extra parameters required:
170    // 1. Spikiness. Set this to very low values to increase the spikes.
171    //    Set it to 1 and you get a sphere
172    // 2. inverse size. Increase this to decrease the size of the surface.
173    //    (The other parameters also drastically affect the size,
174    //     but this parameter has no other effects)
175    // 3. Flange. Increase this to increase the flanges that appear between the spikes. Set it to 1 for no flanges
176    // 4. threshold. Setting this parameter to 1 and the threshold to zero
177    //    has exactly the same effect as setting this parameter to zero
178    //    and the threshold to -1
179
180#declare f_folium_surface = function { internal(20) }
181// Parameters: x, y, z
182    // Three extra parameters required:
183    // 1. Field Strength
184    // 2. Neck width factor -
185    //    the larger you set this,
186    //    the narrower the neck where the paraboloid meets the plane
187    // 3. Divergence -
188    //    the higher you set this value, the wider the paraboloid gets
189
190#declare f_folium_surface_2d = function { internal(21) }
191// Parameters: x, y, z
192    // Six extra parameters required:
193    // 1. Field Strength
194    // 2. Neck width factor - same as the 3d surface if you're revolving it around the Y axis
195    // 3. Divergence -
196    //    same as the 3d surface if you're revolving it around the Y axis
197    // 4. SOR Switch
198    // 5. SOR Offset
199    // 6. SOR Angle
200
201#declare f_glob = function { internal(22) }
202// Parameters: x, y, z
203    // One extra parameter required:
204    // 1. Field Strength
205
206#declare f_heart = function { internal(23) }
207// Parameters: x, y, z
208    // One extra parameter required:
209    // 1. Field Strength
210
211#declare f_helical_torus = function { internal(24) }
212// Parameters: x, y, z
213    // Ten extra parameters required:
214    // 1.Major radius
215    // 2. Number of winding loops
216    // 3. Twistiness of winding.
217    //    When zero, each winding loop is separate.
218    //    When set to one, each loop twists into the next one.
219    //    When set to two, each loop twists into the one after next
220    // 4. Fatness of winding?
221    // 5. threshold. Setting this parameter to 1 and the threshold to zero
222    //    has s similar effect as setting this parameter to zero
223    //    and the threshold to 1
224    // 6. Negative minor radius? Reducing this parameter
225    //    increases the minor radius of the central torus.
226    //    Increasing it can make the torus disappear
227    //    and be replaced by a vertical column.
228    //    The value at which the surface switches
229    //    from one form to the other depends on several other parameters
230    // 7. Another fatness of winding control?
231    // 8. Groove period. Increase this for more grooves
232    // 9. Groove amplitude. Increase this for deeper grooves
233    // 10. Groove phase. Set this to zero for symmetrical grooves
234
235#declare f_helix1 = function { internal(25) }
236// Parameters: x, y, z
237// Parameters: x, y, z
238    // Seven extra parameters required:
239    // 1. Number of helixes - e.g. 2 for a double helix
240    // 2. Period - is related to the number of turns per unit length
241    // 3. Minor radius
242    // 4. Major radius
243    // 5. Shape parameter. If this is greater than 1 then the tube becomes fatter in the y direction
244    // 6. Cross section type.
245    // 7. Cross section rotation angle (degrees). E.g. if you choose a square cross section and rotate it by 45 degrees you get a diamond cross section.
246#declare f_helix2 = function { internal(26) }
247    // Parameters: x, y, z
248    // Seven extra parameters required:
249    // 1. Not used
250    // 2. Period - is related to the number of turns per unit length
251    // 3. Minor radius
252    // 4. Major radius
253    // 5. Not used
254    // 6. Cross section type.
255    // 7. Cross section rotation angle (degrees). E.g. if you choose a square cross section and rotate it by 45 degrees you get a diamond cross section.
256
257#declare f_hex_x = function { internal(27) }
258// Parameters: x, y, z
259    // One extra parameter required:
260    // 1. Has no effect  ??????????????????????????????
261
262#declare f_hex_y = function { internal(28) }
263// Parameters: x, y, z
264    // One extra parameter required:
265    // 1. Has no effect  ??????????????????????????????
266
267#declare f_hetero_mf = function { internal(29) }
268// Parameters: x, y, z
269    // Six extra parameters required:
270    // 1. H
271    // 2. lacunarity
272    // 3. octaves
273    // 4. offset
274    // 5. T
275    // 6. noise
276
277#declare f_hunt_surface = function { internal(30) }
278// Parameters: x, y, z
279    // One extra parameter required:
280    // 1. Field Strength
281#declare f_hyperbolic_torus = function { internal(31) }
282// Parameters: x, y, z
283    // Three extra parameters required:
284    // 1. Field strength
285    // 2. Major radius: separation between the centers of the tubes at the closest point
286    // 3. Minor radius: thickness of the tubes at the closest point
287
288#declare f_isect_ellipsoids = function { internal(32) }
289// Parameters: x, y, z
290    // Four extra parameters required:
291    // 1. eccentricity. When less than 1, the ellipsoids are oblate,
292    //    when greater than 1 the ellipsoids are prolate,
293    //    when zero the ellipsoids are spherical
294    //   (and hence the whole surface is a sphere)
295    // 2. inverse size. Increase this to decrease the size of the surface
296    // 3. Diameter. Increase this to increase the size of the ellipsoids
297    // 4. threshold. Setting this parameter to 1 and the threshold to zero
298    //    has exactly the same effect as setting this parameter to zero
299    //    and the threshold to -1
300
301#declare f_kampyle_of_eudoxus = function { internal(33) }
302// Parameters: x, y, z
303    // Three extra parameters required:
304    // 1. Field strength
305    // 2. Dimple: When zero, the two dimples punch right through
306    //    and meet at the center. Non-zero values give less dimpling
307    // 3. Closeness: Higher values make the two planes become closer
308
309#declare f_kampyle_of_eudoxus_2d = function { internal(34) }
310// Parameters: x, y, z
311    // Six extra parameters required:
312    // 1. Field strength
313    // 2. Dimple: When zero, the two dimples punch right through and meet at the center. Non-zero values give less dimpling
314    // 3. loseness: Higher values make the two planes become closer
315    // 4. sor switch
316    // 5. sor offset
317    // 6. sor angle
318
319#declare f_klein_bottle = function { internal(35) }
320// Parameters: x, y, z
321    // One extra parameter required:
322    // 1. Field Strength
323
324#declare f_kummer_surface_v1 = function { internal(36) }
325// Parameters: x, y, z
326    // One extra parameter required:
327    // 1. Field Strength
328
329#declare f_kummer_surface_v2 = function { internal(37) }
330// Parameters: x, y, z
331    // Four extra parameters required:
332    // 1. Field strength
333    // 2. Rod width (negative): Setting this parameter
334    //    to larger negative values increases the diameter of the rods
335    // 3. Divergence (negative): Setting this number to -1
336    //    causes the rods to become approximately cylindrical.
337    //    Larger negative values cause the rods to become fatter further from the origin.
338    //    Smaller negative numbers cause the rods to become narrower away from the origin,
339    //    and have a finite length
340    // 4. Influences the length of half of the rods.
341    //    Changing the sign affects the other half of the rods.
342    //    0 has no effect
343
344#declare f_lemniscate_of_gerono = function { internal(38) }
345// Parameters: x, y, z
346    // One extra parameter required:
347    // 1. Field Strength
348
349#declare f_lemniscate_of_gerono_2d = function { internal(39) }
350// Parameters: x, y, z
351    // Six extra parameters required:
352    // 1. Field strength
353    // 2. size: increasing this makes the 2d curve larger and less rounded
354    // 3. width: increasing this makes the 2d curve fatter
355    // 4. sor switch
356    // 5. sor offset
357    // 6. sor angle
358
359#declare f_mesh1 = function { internal(40) }
360// Parameters: x, y, z
361    // Five extra Parameters required:
362    // 1. Distance between neighboring threads in the x direction
363    // 2. Distance between neighboring threads in the z direction
364    // 3. Relative thickness in the x and z directions
365    // 4. Amplitude of the weaving effect. Set to zero for a flat grid
366    // 5. Relative thickness in the y direction
367
368#declare f_mitre = function { internal(41) }
369// Parameters: x, y, z
370    // One extra parameter required:
371    // 1. Field Strength
372
373#declare f_nodal_cubic = function { internal(42) }
374// Parameters: x, y, z
375    // One extra parameter required:
376    // 1. Field Strength
377
378#declare f_odd = function { internal(43) }
379// Parameters: x, y, z
380    // One extra parameter required:
381    // 1. Field Strength
382
383#declare f_ovals_of_cassini = function { internal(44) }
384// Parameters: x, y, z
385    // Four parameters required:
386    // 1. Field Strength
387    // 2. Major radius - like the major radius of a torus
388    // 3. Filling. Set this to zero, and you get a torus. Set this to a higher value and the hole in the middle starts to heal up. Set it even higher and you get an ellipsoid with a dimple
389    // 4. Thickness. The higher you set this value, the plumper is the result.
390
391#declare f_paraboloid = function { internal(45) }
392// Parameters: x, y, z
393    // One extra parameter required:
394    // 1. Field Strength
395
396#declare f_parabolic_torus = function { internal(46) }
397// Parameters: x, y, z
398    // Tree extra parameters required:
399    // 1. Field Strength
400    // 2. Major radius
401    // 3. Minor radius
402
403#declare f_ph = function { internal(47) }
404// Parameters: x, y, z
405    // no extra parameters required
406
407#declare f_pillow = function { internal(48) }
408// Parameters: x, y, z
409    // One extra parameter required:
410    // 1. Field Strength
411
412#declare f_piriform = function { internal(49) }
413// Parameters: x, y, z
414    // One extra parameter required:
415    // 1. Field Strength
416
417#declare f_piriform_2d = function { internal(50) }
418// Parameters: x, y, z
419    // Seven extra parameters required:
420    // 1. Field strength
421    // 2. size factor 1: increasing this makes the curve larger
422    // 3. size factor 2: making this less negative makes the curve larger but also thinner
423    // 4. Fatness: increasing this makes the curve fatter
424    // 5. sor switch
425    // 6. sor offset
426    // 7. sor angle
427
428#declare f_poly4 = function { internal(51) }
429// Parameters: x, y, z
430    // Five extra parameters required:
431    // 1. Constant
432    // 2. y coefficient
433    // 3. Y2 coefficient
434    // 4. Y3 coefficient
435    // 5. Y4 coefficient
436
437#declare f_polytubes = function { internal(52) }
438// Parameters: x, y, z
439    // Six extra parameters required:
440    // 1. Number of tubes
441    // 2. Constant
442    // 3. y coefficient
443    // 4. Y2 coefficient
444    // 5. Y3 coefficient
445    // 6. Y4 coefficient
446
447#declare f_quantum = function { internal(53) }
448// Parameters: x, y, z
449    // One extra parameter required:
450    // 1. Has no effect  ??????????????????????????????
451
452#declare f_quartic_paraboloid = function { internal(54) }
453// Parameters: x, y, z
454    // One extra parameter required:
455    // 1. Field Strength
456
457#declare f_quartic_saddle = function { internal(55) }
458// Parameters: x, y, z
459    // One extra parameter required:
460    // 1. Field Strength
461
462#declare f_quartic_cylinder = function { internal(56) }
463// Parameters: x, y, z
464    // Three extra parameters required:
465    // 1. Field strength
466    // 2. Diameter of the "egg"
467    // 3. Controls the width of the tube and the vertical scale of the "egg"
468
469#declare f_r = function { internal(57) }
470// Parameters: x, y, z
471    // no extra parameters required
472
473#declare f_ridge = function { internal(58) }
474// Parameters: x, y, z
475    // Six extra parameters required:
476    // 1.lambda
477    // 2. octaves
478    // 3. omega
479    // 4. offset
480    // 5. Ridge
481    // 6. noise
482
483#declare f_ridged_mf = function { internal(59) }
484// Parameters: x, y, z
485    // Six extra parameters required:
486    // 1. H
487    // 2. Lacunarity
488    // 3. octaves
489    // 4. offset
490    // 5. Gain
491    // 6. noise
492
493#declare f_rounded_box = function { internal(60) }
494// Parameters: x, y, z, P0, P1, P2, P3
495    // Four extra parameters required:
496    // 1. Radius of curvature.
497    //    Zero gives square corners,
498    //    0.1 gives corners that match "sphere {0,0.1}"
499    // 2. scale x
500    // 3. scale y
501    // 4. scale z
502
503#declare f_sphere = function { internal(61) }
504// Parameters: x, y, z
505    //One extra parameter required:
506    // 1. radius of sphere
507
508#declare f_spikes = function { internal(62) }
509// Parameters: x, y, z
510    // Five extra parameters required:
511    // 1. Spikiness. Set this to very low values to increase the spikes.
512    //    Set it to 1 and you get a sphere
513    // 2. Hollowness. Increasing this causes the sides to bend in more
514    // 3. size. Increasing this increases the size of the object
515    // 4. Roundness. This parameter has a subtle effect on the roundness of the spikes
516    // 5. Fatness. Increasing this makes the spikes fatter
517
518#declare f_spikes_2d = function { internal(63) }
519// Parameters: x, y, z
520    // Four extra parameters required:
521    // 1. Height of central spike
522    // 2. frequency of spikes in the x direction
523    // 3. frequency of spikes in the z direction
524    // 4. Rate at which the spikes reduce as you move away from the center
525
526#declare f_spiral = function { internal(64) }
527// Parameters: x, y, z
528    // Six extra parameters required:
529    // 1. Distance between windings: setting this to 0.3 means that the spiral is 0.3 pov units further from the origin each time it completes one whole turn
530    // 2. Thickness
531    // 3. Outer diameter of the spiral. The surface behaves as if it is contained_by a sphere of this diameter
532    // 4. Not used
533    // 5. Not used
534    // 6. Cross section type
535
536#declare f_steiners_roman = function { internal(65) }
537// Parameters: x, y, z
538    // One extra parameter required:
539    // 1. Field Strength
540
541#declare f_strophoid = function { internal(66) }
542// Parameters: x, y, z
543    // Four extra parameters required:
544    // 1. Field strength
545    // 2. size of bulb. Larger values give larger bulbs.
546    //    Negative values give a bulb on the other side of the plane
547    // 3. Sharpness. When zero, the bulb is like a sphere that just touches the plane.
548    //    When positive, there is a crossover point.
549    //    When negative the bulb simply bulges out of the plane like a pimple
550    // 4. Fatness. Higher values make the top end of the bulb fatter
551
552#declare f_strophoid_2d = function { internal(67) }
553// Parameters: x, y, z
554    // Seven extra parameters required:
555    // 1. Field strength
556    // 2. size of bulb. Larger values give larger bulbs.
557    //    Negative values give a bulb on the other side of the plane
558    // 3. Sharpness. When zero, the bulb is like a sphere that just touches the plane.
559    //    When positive, there is a crossover point.
560    //    When negative the bulb simply bulges out of the plane like a pimple
561    // 4. Fatness. Higher values make the top end of the bulb fatter
562    // 5. sor switch
563    // 6. sor offset
564    // 7. sor angle
565
566#declare f_superellipsoid = function { internal(68) }
567// Parameters: x, y, z
568    // two extra parameters required:
569    // 1. NW
570    // 2. SW
571
572#declare f_th = function { internal(69) }
573// Parameters: x, y, z
574    // no extra parameters required
575
576#declare f_torus = function { internal(70) }
577// Parameters: x, y, z
578    // two extra parameters required:
579    // 1. Major radius
580    // 2. Minor radius
581
582#declare f_torus2 = function { internal(71) }
583// Parameters: x, y, z
584    // Three extra parameters required:
585    // 1. Field strength
586    // 2. Major radius
587    // 3. Minor radius
588
589#declare f_torus_gumdrop = function { internal(72) }
590// Parameters: x, y, z
591    // One extra parameter required:
592    // 1. Field Strength
593
594#declare f_umbrella = function { internal(73) }
595// Parameters: x, y, z
596    // One extra parameter required:
597    // 1. Field Strength
598#declare f_witch_of_agnesi = function { internal(74) }
599// Parameters: x, y, z
600    // Two extra parameters required:
601    // 1. Field Strength
602    // 2. Controls the width of the spike.
603    //    The height of the spike is always about 1 unit
604
605#declare f_witch_of_agnesi_2d = function { internal(75) }
606// Parameters: x, y, z
607    // Six extra parameters required:
608    // 1. Field strength
609    // 2. Controls the size of the spike
610    // 3. Controls the height of the spike
611    // 4. sor switch
612    // 5. sor offset
613    // 6. sor angle
614
615#declare f_noise3d = function { internal(76) }
616// Parameters: x, y, z
617//Noise in the range [-1, 1]
618#declare f_snoise3d = function {2*f_noise3d(x, y, z) - 1}
619// Parameters: x, y, z
620
621#declare f_noise_generator = function { internal(78) }
622// Parameters: x, y, z
623    // One extra parameter required:
624    // 1. noise_generator number
625
626
627#macro eval_pigment(pigm, vec)
628    #local fn = function { pigment { pigm } }
629    #local result = (fn(vec.x, vec.y, vec.z));
630    result
631#end
632
633
634// Isosurface pattern functions
635// Some of these are not implemented because they require special
636// parameters that must be specified in the definition. For this
637// reason, you probably would want to define your own versions of
638// these functions.
639#declare f_agate = function {pattern {agate}}
640// average not implemented
641#declare f_boxed = function {pattern {boxed}}
642#declare f_bozo = function {f_noise3d(x, y, z)}
643#declare f_brick = function {pattern {brick}}
644#declare f_bumps = function {f_noise3d(x, y, z)}
645#declare f_checker = function {pattern {checker}}
646#declare f_crackle = function {pattern {crackle}}
647#declare f_cylindrical = function {pattern {cylindrical}}
648// density_file not implemented
649#declare f_dents = function {pow(f_noise3d(x, y, z), 3)}
650#declare f_gradientX = function {pattern {gradient x}}
651#declare f_gradientY = function {pattern {gradient y}}
652#declare f_gradientZ = function {pattern {gradient z}}
653#declare f_granite = function {pattern {granite}}
654// image_pattern not implemented
655#declare f_hexagon = function {pigment {hexagon color rgb 0, color rgb 0.5, color rgb 1}}
656#declare f_leopard = function {pattern {leopard}}
657//only the basic mandel pattern is implemented, its variants and
658//the other fractal patterns are not implemented.
659#declare f_mandel = function {pattern {mandel 25}}
660#declare f_marble = function {pattern {marble}}
661// object not implemented
662#declare f_onion = function {pattern {onion}}
663// pigment_pattern not implemented
664#declare f_planar = function {pattern {planar}}
665// quilted not implemented
666#declare f_radial = function {pattern {radial}}
667#declare f_ripples = function {pattern {ripples}}
668#declare f_spherical = function {pattern {spherical}}
669#declare f_spiral1 = function {pattern {spiral1 2}}
670#declare f_spiral2 = function {pattern {spiral2 2}}
671#declare f_spotted = function {f_noise3d(x, y, z)}
672#declare f_waves = function {pattern {waves}}
673#declare f_wood = function {pattern {wood}}
674#declare f_wrinkles = function {pattern {wrinkles}}
675
676
677// Waveform functions
678#declare f_sine_wave = function {sin(x*z*pi)*y}
679    // f_sine_wave(val, amplitude, frequency)
680#declare f_scallop_wave = function {abs(sin(x*z*pi)*y)}
681    // f_scallop_wave(val, amplitude, frequency)
682
683#version Functions_Inc_Temp;
684#end//functions.inc
685
686