1 //******************************************************************************
2 ///
3 /// @file core/coretypes.h
4 ///
5 /// Essential types for the render core.
6 ///
7 /// @copyright
8 /// @parblock
9 ///
10 /// Persistence of Vision Ray Tracer ('POV-Ray') version 3.8.
11 /// Copyright 1991-2018 Persistence of Vision Raytracer Pty. Ltd.
12 ///
13 /// POV-Ray is free software: you can redistribute it and/or modify
14 /// it under the terms of the GNU Affero General Public License as
15 /// published by the Free Software Foundation, either version 3 of the
16 /// License, or (at your option) any later version.
17 ///
18 /// POV-Ray is distributed in the hope that it will be useful,
19 /// but WITHOUT ANY WARRANTY; without even the implied warranty of
20 /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 /// GNU Affero General Public License for more details.
22 ///
23 /// You should have received a copy of the GNU Affero General Public License
24 /// along with this program. If not, see <http://www.gnu.org/licenses/>.
25 ///
26 /// ----------------------------------------------------------------------------
27 ///
28 /// POV-Ray is based on the popular DKB raytracer version 2.12.
29 /// DKBTrace was originally written by David K. Buck.
30 /// DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
31 ///
32 /// @endparblock
33 ///
34 //******************************************************************************
35
36 #ifndef POVRAY_CORE_CORETYPES_H
37 #define POVRAY_CORE_CORETYPES_H
38
39 #include "core/configcore.h"
40
41 #include <stack>
42
43 #include "base/colour.h"
44 #include "base/types.h"
45 #include "base/textstream.h"
46
47 #include "core/math/vector.h"
48
49 namespace pov
50 {
51
52 //##############################################################################
53 ///
54 /// @addtogroup PovCore
55 ///
56 /// @{
57
58 using namespace pov_base;
59
60 // from <algorithm>; we don't want to always type the namespace for these.
61 using std::min;
62 using std::max;
63
64 // from <cmath>; we don't want to always type the namespace for these.
65 using std::abs;
66 using std::acos;
67 using std::asin;
68 using std::atan;
69 using std::atan2;
70 using std::ceil;
71 using std::cos;
72 using std::cosh;
73 using std::exp;
74 using std::fabs;
75 using std::floor;
76 using std::fmod;
77 using std::frexp;
78 using std::ldexp;
79 using std::log;
80 using std::log10;
81 using std::modf;
82 using std::pow;
83 using std::sin;
84 using std::sinh;
85 using std::sqrt;
86 using std::tan;
87 using std::tanh;
88
89 // Simple Scalar Square
90 template<typename T>
Sqr(T a)91 inline T Sqr(T a)
92 {
93 return a * a;
94 }
95
96 class ObjectBase;
97 typedef ObjectBase * ObjectPtr;
98 typedef const ObjectBase * ConstObjectPtr;
99
100 typedef struct Transform_Struct TRANSFORM;
101
102 /// @}
103 ///
104 //##############################################################################
105 ///
106 /// @addtogroup PovCoreMaterialPattern
107 ///
108 /// @{
109
110 typedef struct Pattern_Struct TPATTERN;
111 typedef struct Texture_Struct TEXTURE;
112 typedef struct Pigment_Struct PIGMENT;
113 typedef struct Tnormal_Struct TNORMAL;
114 typedef struct Finish_Struct FINISH;
115
116 typedef TEXTURE* TexturePtr;
117
118 /// @}
119 ///
120 //##############################################################################
121 ///
122 /// @addtogroup PovCoreMaterialMedia
123 ///
124 /// @{
125
126 class Media
127 {
128 public:
129 int Type;
130 int Intervals;
131 int Min_Samples;
132 int Max_Samples;
133 unsigned Sample_Method : 8;
134 bool is_constant : 1;
135 bool use_absorption : 1;
136 bool use_emission : 1;
137 bool use_extinction : 1;
138 bool use_scattering : 1;
139 bool ignore_photons : 1;
140 DBL Jitter;
141 DBL Eccentricity;
142 DBL sc_ext;
143 MathColour Absorption;
144 MathColour Emission;
145 MathColour Extinction;
146 MathColour Scattering;
147
148 DBL Ratio;
149 DBL Confidence;
150 DBL Variance;
151 DBL *Sample_Threshold;
152
153 DBL AA_Threshold;
154 int AA_Level;
155
156 vector<PIGMENT*> Density;
157
158 Media();
159 Media(const Media&);
160 ~Media();
161
162 Media& operator=(const Media&);
163
164 void Transform(const TRANSFORM *trans);
165
166 void PostProcess();
167 };
168
169 /// @}
170 ///
171 //##############################################################################
172 ///
173 /// @addtogroup PovCoreMaterialInterior
174 ///
175 /// @{
176
177 class SubsurfaceInterior;
178 class Interior
179 {
180 public:
181 int hollow, Disp_NElems;
182 SNGL IOR, Dispersion;
183 SNGL Caustics, Old_Refract;
184 SNGL Fade_Distance, Fade_Power;
185 MathColour Fade_Colour;
186 vector<Media> media;
187 shared_ptr<SubsurfaceInterior> subsurface;
188
189 Interior();
190 Interior(const Interior&);
191 ~Interior();
192
193 void Transform(const TRANSFORM *trans);
194
195 void PostProcess();
196 private:
197 Interior& operator=(const Interior&);
198 };
199
200 typedef shared_ptr<Interior> InteriorPtr;
201 typedef shared_ptr<const Interior> ConstInteriorPtr;
202
203 /// @}
204 ///
205 //##############################################################################
206 ///
207 /// @addtogroup PovCoreMaterialPattern
208 ///
209 /// @{
210
211 struct BasicPattern;
212
213 typedef shared_ptr<BasicPattern> PatternPtr;
214 typedef shared_ptr<const BasicPattern> ConstPatternPtr;
215
216
217 struct Pattern_Struct
218 {
219 unsigned short Type;
220 unsigned short Flags;
221 PatternPtr pattern;
222 };
223
224 /// @}
225 ///
226 //##############################################################################
227 ///
228 /// @addtogroup PovCore
229 ///
230 /// @{
231
232 typedef struct Material_Struct MATERIAL;
233
234 struct Material_Struct
235 {
236 TEXTURE *Texture;
237 TEXTURE *Interior_Texture;
238 InteriorPtr interior;
239 };
240
241 class LightSource;
242
243 template<typename T>
244 class RefPool
245 {
246 public:
RefPool()247 RefPool() { }
~RefPool()248 ~RefPool() { for(typename vector<T*>::iterator i(pool.begin()); i != pool.end(); i++) delete *i; pool.clear(); }
249
alloc()250 T *alloc() { if(pool.empty()) return new T(); T *ptr(pool.back()); pool.pop_back(); return ptr; }
release(T * ptr)251 void release(T *ptr) { pool.push_back(ptr); }
252 private:
253 vector<T*> pool;
254
255 RefPool(const RefPool&);
256 RefPool& operator=(RefPool&);
257 };
258
259 template<typename T>
260 struct RefClearDefault
261 {
operatorRefClearDefault262 void operator()(T&) { }
263 };
264
265 template<typename T>
266 struct RefClearContainer
267 {
operatorRefClearContainer268 void operator()(T& p) { p.clear(); }
269 };
270
271 template<typename T, class C = RefClearDefault<T> >
272 class Ref
273 {
274 public:
Ref(RefPool<T> & p)275 Ref(RefPool<T>& p) : pool(p), ptr(p.alloc()) { }
~Ref()276 ~Ref() { C c; c(*ptr); pool.release(ptr); }
277
278 T& operator*() { return *ptr; }
279 const T& operator*() const { return *ptr; }
280
281 T *operator->() { return ptr; }
282 const T *operator->() const { return ptr; }
283 private:
284 RefPool<T>& pool;
285 T *ptr;
286
287 Ref();
288 Ref(const Ref&);
289 Ref& operator=(Ref&);
290 };
291
292 class ObjectDebugHelper
293 {
294 public:
295 int Index;
296 bool IsCopy;
297 std::string Tag;
298
ObjectDebugHelper()299 ObjectDebugHelper() { Index = ObjectIndex++; IsCopy = false; }
300 ObjectDebugHelper& operator=(const ObjectDebugHelper& src) { Index = ObjectIndex++; IsCopy = true; Tag = src.Tag; return *this; }
301
302 std::string& SimpleDesc (std::string& result);
303 private:
304 static int ObjectIndex;
ObjectDebugHelper(const ObjectDebugHelper & src)305 ObjectDebugHelper(const ObjectDebugHelper& src) { Index = ObjectIndex++; IsCopy = true; Tag = src.Tag; }
306 };
307
308 typedef unsigned short HF_VAL;
309
310 /// @}
311 ///
312 //##############################################################################
313 ///
314 /// @addtogroup PovCoreRender
315 ///
316 /// @{
317
318 /// Ray-object intersection data.
319 ///
320 /// This class holds various information on a ray-object intersection.
321 ///
322 class Intersection
323 {
324 public:
325
326 /// Distance from the intersecting ray's origin.
327 DBL Depth;
328 /// Point of the intersection in global coordinate space.
329 Vector3d IPoint;
330 /// Unperturbed surface normal at the intersection point.
331 /// @attention This is not necessarily the true geometric surface normal, as it may include fake smoothing.
332 /// @note This value is invalid if haveNormal is false.
333 /// @todo We should have two distinct vectors: A true geometric one, and a separate one for faked smoothing.
334 Vector3d INormal;
335 /// Perturbed normal vector (set during texture evaluation).
336 Vector3d PNormal;
337 /// UV texture coordinate.
338 Vector2d Iuv;
339 /// Intersected object.
340 ObjectPtr Object;
341 /// Root-level parent CSG object for cutaway textures.
342 ObjectPtr Csg;
343
344 /// @name Object-Specific Auxiliary Data
345 /// These members hold information specific to particular object types, typically generated during
346 /// intersection testing, to be re-used later for normal and/or UV coordinate computation.
347 /// @note These values may be invalid or meaningless depending on the type of object intersected.
348 /// @{
349
350 /// Point of the intersection in local coordinate space (used by Blob and SpindleTorus)
351 /// @note This value is invalid in Blob if haveLocalIPoint is false.
352 Vector3d LocalIPoint;
353 /// Generic auxiliary float data #1 (used by Prism, Lathe)
354 DBL d1;
355 /// Generic auxiliary pointer data (used by Mesh)
356 const void *Pointer;
357 /// Generic auxiliary integer data #1 (used by Sor, Prism, Isosurface, Lathe, Cones, Boxes)
358 int i1;
359 /// Generic auxiliary integer data #2 (used by Sor, Prism, Isosurface)
360 int i2;
361 /// Flag to indicate whether INormal was computed during intersection testing (used by HField)
362 /// @note Objects either always or never computing INormal during intersection testing don't use this flag.
363 bool haveNormal : 1;
364 /// Flag to indicate whether LocalIPoint has already been computed.
365 bool haveLocalIPoint : 1;
366 /// Generic auxiliary boolean data #1 (used by SpindleTorus)
367 bool b1 : 1;
368
369 /// @}
370
Intersection()371 Intersection() :
372 Depth(BOUND_HUGE), Object(nullptr), Csg(nullptr),
373 d1(0.0), Pointer(nullptr), i1(0), i2(0), haveNormal(false), haveLocalIPoint(false), b1(false)
374 {}
375
Intersection(DBL d,const Vector3d & v,ObjectPtr o)376 Intersection(DBL d, const Vector3d& v, ObjectPtr o) :
377 Depth(d), IPoint(v), Iuv(v), Object(o), Csg(nullptr),
378 d1(0.0), Pointer(nullptr), i1(0), i2(0), haveNormal(false), haveLocalIPoint(false), b1(false)
379 {}
380
Intersection(DBL d,const Vector3d & v,const Vector3d & n,ObjectPtr o)381 Intersection(DBL d, const Vector3d& v, const Vector3d& n, ObjectPtr o) :
382 Depth(d), IPoint(v), INormal(n), Iuv(v), Object(o), Csg(nullptr),
383 d1(0.0), Pointer(nullptr), i1(0), i2(0), haveNormal(true), haveLocalIPoint(false), b1(false)
384 {}
385
Intersection(DBL d,const Vector3d & v,const Vector2d & uv,ObjectPtr o)386 Intersection(DBL d, const Vector3d& v, const Vector2d& uv, ObjectPtr o) :
387 Depth(d), IPoint(v), Iuv(uv), Object(o), Csg(nullptr),
388 d1(0.0), Pointer(nullptr), i1(0), i2(0), haveNormal(false), haveLocalIPoint(false), b1(false)
389 {}
390
Intersection(DBL d,const Vector3d & v,const Vector3d & n,const Vector2d & uv,ObjectPtr o)391 Intersection(DBL d, const Vector3d& v, const Vector3d& n, const Vector2d& uv, ObjectPtr o) :
392 Depth(d), IPoint(v), INormal(n), Iuv(uv), Object(o), Csg(nullptr),
393 d1(0.0), Pointer(nullptr), i1(0), i2(0), haveNormal(true), haveLocalIPoint(false), b1(false)
394 {}
395
Intersection(DBL d,const Vector3d & v,ObjectPtr o,const void * a)396 Intersection(DBL d, const Vector3d& v, ObjectPtr o, const void *a) :
397 Depth(d), IPoint(v), Iuv(v), Object(o), Csg(nullptr),
398 d1(0.0), Pointer(a), i1(0), i2(0), haveNormal(false), haveLocalIPoint(false), b1(false)
399 {}
400
Intersection(DBL d,const Vector3d & v,const Vector2d & uv,ObjectPtr o,const void * a)401 Intersection(DBL d, const Vector3d& v, const Vector2d& uv, ObjectPtr o, const void *a) :
402 Depth(d), IPoint(v), Iuv(uv), Object(o), Csg(nullptr),
403 d1(0.0), Pointer(a), i1(0), i2(0), haveNormal(false), haveLocalIPoint(false), b1(false)
404 {}
405
406 /// @todo Why does this not set Iuv=IPoint, as other constructors do?
Intersection(DBL d,const Vector3d & v,ObjectPtr o,int a)407 Intersection(DBL d, const Vector3d& v, ObjectPtr o, int a) :
408 Depth(d), IPoint(v), Object(o), Csg(nullptr),
409 d1(0.0), Pointer(nullptr), i1(a), i2(0), haveNormal(false), haveLocalIPoint(false), b1(false)
410 {}
411
412 /// @todo Why does this not set Iuv=IPoint, as other constructors do?
Intersection(DBL d,const Vector3d & v,ObjectPtr o,DBL a)413 Intersection(DBL d, const Vector3d& v, ObjectPtr o, DBL a) :
414 Depth(d), IPoint(v), Object(o), Csg(nullptr),
415 d1(a), Pointer(nullptr), i1(0), i2(0), haveNormal(false), haveLocalIPoint(false), b1(false)
416 {}
417
418 /// @todo Why does this not set Iuv=IPoint, as other constructors do?
Intersection(DBL d,const Vector3d & v,ObjectPtr o,int a,int b)419 Intersection(DBL d, const Vector3d& v, ObjectPtr o, int a, int b) :
420 Depth(d), IPoint(v), Object(o), Csg(nullptr),
421 d1(0.0), Pointer(nullptr), i1(a), i2(b), haveNormal(false), haveLocalIPoint(false), b1(false)
422 {}
423
424 /// @todo Why does this not set Iuv=IPoint, as other constructors do?
Intersection(DBL d,const Vector3d & v,ObjectPtr o,int a,DBL b)425 Intersection(DBL d, const Vector3d& v, ObjectPtr o, int a, DBL b) :
426 Depth(d), IPoint(v), Object(o), Csg(nullptr),
427 d1(b), Pointer(nullptr), i1(a), i2(0), haveNormal(false), haveLocalIPoint(false), b1(false)
428 {}
429
430 /// @todo Why does this not set Iuv=IPoint, as other constructors do?
Intersection(DBL d,const Vector3d & v,ObjectPtr o,int a,int b,DBL c)431 Intersection(DBL d, const Vector3d& v, ObjectPtr o, int a, int b, DBL c) :
432 Depth(d), IPoint(v), Object(o), Csg(nullptr),
433 d1(c), Pointer(nullptr), i1(a), i2(b), haveNormal(false), haveLocalIPoint(false), b1(false)
434 {}
435
436 /// @todo Why does this not set Iuv=IPoint, as other constructors do?
Intersection(DBL d,const Vector3d & v,ObjectPtr o,const Vector3d & lv,bool a)437 Intersection(DBL d, const Vector3d& v, ObjectPtr o, const Vector3d& lv, bool a) :
438 Depth(d), IPoint(v), Object(o), Csg(nullptr),
439 LocalIPoint(lv), d1(0.0), Pointer(nullptr), i1(0), i2(0), haveNormal(false), haveLocalIPoint(true), b1(a)
440 {}
441
~Intersection()442 ~Intersection() { }
443 };
444
445 typedef std::stack<Intersection, vector<Intersection> > IStackData;
446 typedef RefPool<IStackData> IStackPool;
447 typedef Ref<IStackData> IStack;
448
449 struct BasicRay
450 {
451 Vector3d Origin;
452 Vector3d Direction;
453
BasicRayBasicRay454 inline BasicRay() {}
BasicRayBasicRay455 inline BasicRay(const BasicRay& obj) : Origin(obj.Origin), Direction(obj.Direction) {}
BasicRayBasicRay456 inline BasicRay(const Vector3d& ov, const Vector3d& dv) : Origin(ov), Direction(dv) {}
EvaluateBasicRay457 inline Vector3d Evaluate(double depth) const { return Origin + Direction * depth; }
458
459 /// Make sure the ray's direction is normalized.
460 /// @return The length of the direction vector before normalization.
NormalizeBasicRay461 inline DBL Normalize() { DBL len = Direction.length(); Direction /= len; return len; }
462
GetOriginBasicRay463 inline const Vector3d& GetOrigin() const { return Origin; }
GetDirectionBasicRay464 inline const Vector3d& GetDirection() const { return Direction; }
465
GetOriginBasicRay466 inline Vector3d& GetOrigin() { return Origin; }
GetDirectionBasicRay467 inline Vector3d& GetDirection() { return Direction; }
468 };
469
470 struct TraceTicket;
471
472 class Ray;
473
474 struct RayObjectCondition
475 {
476 virtual bool operator()(const Ray& ray, ConstObjectPtr object, DBL data) const = 0;
477 };
478
479 struct TrueRayObjectCondition : public RayObjectCondition
480 {
operatorTrueRayObjectCondition481 virtual bool operator()(const Ray&, ConstObjectPtr, DBL) const { return true; }
482 };
483
484 struct PointObjectCondition
485 {
486 virtual bool operator()(const Vector3d& point, ConstObjectPtr object) const = 0;
487 };
488
489 struct TruePointObjectCondition : public PointObjectCondition
490 {
operatorTruePointObjectCondition491 virtual bool operator()(const Vector3d&, ConstObjectPtr) const { return true; }
492 };
493
494 /// @}
495 ///
496 //##############################################################################
497 ///
498 /// @addtogroup PovCore
499 ///
500 /// @{
501
502 struct FrameSettings
503 {
504 DBL Clock_Value; // May change between frames of an animation
505 int FrameNumber; // May change between frames of an animation
506
507 int InitialFrame;
508 DBL InitialClock;
509
510 int FinalFrame;
511 int FrameNumWidth;
512 DBL FinalClock;
513
514 int SubsetStartFrame;
515 DBL SubsetStartPercent;
516 int SubsetEndFrame;
517 DBL SubsetEndPercent;
518
519 bool Field_Render_Flag;
520 bool Odd_Field_Flag;
521 };
522
523 /// @}
524 ///
525 //##############################################################################
526 ///
527 /// @addtogroup PovCoreMaterialPattern
528 ///
529 /// @{
530
531 class Fractal;
532
533 class FractalRules
534 {
535 public:
~FractalRules()536 virtual ~FractalRules() {}
537 virtual void CalcNormal (Vector3d&, int, const Fractal *, DBL **) const = 0;
538 virtual bool Iterate (const Vector3d&, const Fractal *, DBL **) const = 0;
539 virtual bool Iterate (const Vector3d&, const Fractal *, const Vector3d&, DBL *, DBL **) const = 0;
540 virtual bool Bound (const BasicRay&, const Fractal *, DBL *, DBL *) const = 0;
541 };
542
543 typedef shared_ptr<FractalRules> FractalRulesPtr;
544
545 struct QualityFlags
546 {
547 bool ambientOnly : 1;
548 bool quickColour : 1;
549 bool shadows : 1;
550 bool areaLights : 1;
551 bool refractions : 1;
552 bool reflections : 1;
553 bool normals : 1;
554 bool media : 1;
555 bool radiosity : 1;
556 bool photons : 1;
557 bool subsurface : 1;
558
QualityFlagsQualityFlags559 explicit QualityFlags(int level) :
560 ambientOnly (level <= 1),
561 quickColour (level <= 5),
562 shadows (level >= 4),
563 areaLights (level >= 5),
564 refractions (level >= 6),
565 reflections (level >= 8),
566 normals (level >= 8),
567 media (level >= 9),
568 radiosity (level >= 9),
569 photons (level >= 9),
570 subsurface (level >= 9)
571 {}
572 };
573
574 /// @}
575 ///
576 //##############################################################################
577 ///
578 /// @defgroup PovCoreFunction User-Defined Functions
579 /// @ingroup PovCore
580 ///
581 /// @{
582
583 class TraceThreadData;
584
585 class GenericFunctionContext
586 {
587 public:
~GenericFunctionContext()588 virtual ~GenericFunctionContext() {}
589 };
590
591 typedef GenericFunctionContext* GenericFunctionContextPtr;
592
593 class GenericFunctionContextFactory
594 {
595 public:
GenericFunctionContextFactory()596 GenericFunctionContextFactory() : mRefCounter(0) {}
~GenericFunctionContextFactory()597 virtual ~GenericFunctionContextFactory() {}
598 virtual GenericFunctionContextPtr CreateFunctionContext(TraceThreadData* pTd) = 0;
599
600 private:
601 mutable size_t mRefCounter;
602 friend void intrusive_ptr_add_ref(GenericFunctionContextFactory* f);
603 friend void intrusive_ptr_release(GenericFunctionContextFactory* f);
604 };
605
intrusive_ptr_add_ref(GenericFunctionContextFactory * f)606 inline void intrusive_ptr_add_ref(GenericFunctionContextFactory* f) { ++f->mRefCounter; }
intrusive_ptr_release(GenericFunctionContextFactory * f)607 inline void intrusive_ptr_release(GenericFunctionContextFactory* f) { if (!(--f->mRefCounter)) delete f; }
608
609 typedef intrusive_ptr<GenericFunctionContextFactory> GenericFunctionContextFactoryIPtr;
610 typedef GenericFunctionContextFactory* GenericFunctionContextFactoryTPtr;
611
612 struct SourceInfo
613 {
614 char* name;
615 UCS2* filename;
616 pov_base::ITextStream::FilePos filepos;
617 int col;
618 };
619
620 template<typename RETURN_T, typename ARG_T>
621 class GenericCustomFunction
622 {
623 public:
~GenericCustomFunction()624 virtual ~GenericCustomFunction() {}
625 virtual GenericFunctionContextPtr AcquireContext(TraceThreadData* pThreadData) = 0;
626 virtual void ReleaseContext(GenericFunctionContextPtr pContext) = 0;
627 virtual void InitArguments(GenericFunctionContextPtr pContext) = 0;
628 virtual void PushArgument(GenericFunctionContextPtr pContext, ARG_T arg) = 0;
629 virtual RETURN_T Execute(GenericFunctionContextPtr pContext) = 0;
630 virtual GenericCustomFunction* Clone() const = 0;
GetSourceInfo()631 virtual const SourceInfo* GetSourceInfo() const { return nullptr; }
632 };
633
634 typedef GenericCustomFunction<double, double> GenericScalarFunction;
635 typedef GenericScalarFunction* GenericScalarFunctionPtr;
636
637 template<typename RETURN_T, typename ARG_T>
638 class GenericCustomFunctionInstance
639 {
640 public:
GenericCustomFunctionInstance(GenericCustomFunction<RETURN_T,ARG_T> * pFn,TraceThreadData * pThreadData)641 inline GenericCustomFunctionInstance(GenericCustomFunction<RETURN_T,ARG_T>* pFn, TraceThreadData* pThreadData) :
642 mpFunction(pFn), mpContext(pFn->AcquireContext(pThreadData)), mReInit(true)
643 {
644 POV_ASSERT(mpFunction != nullptr);
645 POV_ASSERT(mpContext != nullptr);
646 }
647
~GenericCustomFunctionInstance()648 inline ~GenericCustomFunctionInstance()
649 {
650 mpFunction->ReleaseContext(mpContext);
651 }
652
PushArgument(ARG_T arg)653 inline void PushArgument(ARG_T arg)
654 {
655 if (mReInit)
656 {
657 mpFunction->InitArguments(mpContext);
658 mReInit = false;
659 }
660 mpFunction->PushArgument(mpContext, arg);
661 }
662
Evaluate()663 inline RETURN_T Evaluate()
664 {
665 RETURN_T result = mpFunction->Execute(mpContext);
666 mReInit = true;
667 return result;
668 }
669
670 template<typename T1>
Evaluate(T1 arg1)671 inline RETURN_T Evaluate(T1 arg1)
672 {
673 PushArgument(arg1);
674 return Evaluate();
675 }
676
677 template<typename T1, typename T2>
Evaluate(T1 arg1,T2 arg2)678 inline RETURN_T Evaluate(T1 arg1, T2 arg2)
679 {
680 PushArgument(arg1);
681 PushArgument(arg2);
682 return Evaluate();
683 }
684
685 template<typename T1, typename T2, typename T3>
Evaluate(T1 arg1,T2 arg2,T3 arg3)686 inline RETURN_T Evaluate(T1 arg1, T2 arg2, T3 arg3)
687 {
688 PushArgument(arg1);
689 PushArgument(arg2);
690 PushArgument(arg3);
691 return Evaluate();
692 }
693
Evaluate(const Vector2d & argV)694 inline RETURN_T Evaluate(const Vector2d& argV)
695 {
696 return Evaluate(argV.u(), argV.v());
697 }
698
Evaluate(const Vector3d & argV)699 inline RETURN_T Evaluate(const Vector3d& argV)
700 {
701 return Evaluate(argV.x(), argV.y(), argV.z());
702 }
703
704 protected:
705 GenericCustomFunction<RETURN_T,ARG_T>* mpFunction;
706 GenericFunctionContextPtr mpContext;
707 bool mReInit;
708
709 private:
710 GenericCustomFunctionInstance();
711 };
712
713 typedef GenericCustomFunctionInstance<double, double> GenericScalarFunctionInstance;
714 typedef GenericScalarFunctionInstance* GenericScalarFunctionInstancePtr;
715
716 /// @}
717 ///
718 //##############################################################################
719
720 }
721
722 #endif // POVRAY_CORE_CORETYPES_H
723