HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BRAY_Procedural.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: BRAY_Procedural.h (BRAY Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __BRAY_Procedural__
12 #define __BRAY_Procedural__
13 
14 #include "BRAY_API.h"
15 #include "BRAY_AttribList.h"
16 #include "BRAY_Interface.h"
17 #include "BRAY_ProceduralFactory.h"
18 #include <UT/UT_SmallObject.h>
19 
20 class UT_JSONWriter;
21 
23 {
24 public:
25  /// Templatized on <fpreal32> or <fpreal64>
26  /// This structure is used in the intersect() function to compute an
27  /// intersection with the procedural primitive.
28  template <typename PREC>
29  struct Ray
30  {
31  // RayType
37  };
40 
41  /// This class stores information about the hit. The information is passed
42  /// back to the procedural primitive when evaluating attributes.
43  /// The procedural object can store any data it wants in the @c u, @c v,
44  /// @c w and @c prim_id fields. These are passed through to the primitive
45  /// when looking up shading variables/attributes. At the current time,
46  /// @c prim_id must be >= 0.
47  ///
48  /// If a custom procedural needs to store information, the procedural can
49  /// subclass from this class. In the attribute evaluation methods, you can
50  /// safely cast to your subclass.
51  ///
52  /// When the ray hits, the procedural should fill out
53  /// - @c distance : the distance from the origin to the hit point
54  /// - @c zback : For volume primitives, @c distance represents the start of
55  /// the shading interval while @c zback represents the farthest extent of
56  /// the shading sample, so for volumes, @zback should be >= @distance.
57  /// For non-volume shading information, @zback should be left at 0.
58  /// - @c Ng : The geometric normal at the hit surface
59  class HitPtr;
60  class BRAY_API Hit
61  : public UT_SmallObject<Hit>
62  {
63  public:
65  : distance(d)
66  , zback(0)
67  , prim_id(0)
68  , ref_count(0)
69  {
70  }
71  virtual ~Hit();
72 
73  fpreal distance; // Distance to hit
74  fpreal zback; // Distance to zback (0=solid surface)
75  fpreal u, v, w; // Parametric coordinates
76  UT_Vector3 Ng; // Geometric normal
77  uint prim_id; // ID of primitive in procedural
78 
79  // @{
80  // A convenience method to get a reference to a sub-class type
81  // For example: @code
82  // MyHit &hit = src_hit.castTo<MyHit>();
83  // const MyHit &hit2 = src_hit.castTo<const MyHit>();
84  // @endcode
85  template <typename T>
86  T &castTo() { return *reinterpret_cast<T *>(this); }
87  template <typename T>
88  const T &castTo() const { return *reinterpret_cast<T *>(this); }
89  // @}
90 
91 
92  private:
93  // Private data for internal use only.
94  void inc_ref() { ++ref_count; }
95  void dec_ref()
96  {
97  --ref_count;
98  if (!ref_count)
99  releaseHit();
100  }
101  void releaseHit(); // Private method
102  int ref_count; // Order before pointer for alignment
103  friend class HitPtr;
104  friend class BRAY_Procedural;
105  };
106 
107  // Smart pointer for hits
109  {
110  public:
111  HitPtr() noexcept
112  : myHit(nullptr)
113  {
114  }
115  HitPtr(Hit *ptr) noexcept
116  : myHit(ptr)
117  {
118  if (myHit)
119  myHit->inc_ref();
120  }
121  HitPtr(const HitPtr &src) noexcept
122  : myHit(src.myHit)
123  {
124  if (myHit)
125  myHit->inc_ref();
126  }
127  HitPtr(HitPtr &&src) noexcept
128  : myHit(src.myHit)
129  {
130  src.myHit = nullptr;
131  }
133  {
134  reset();
135  }
137  {
138  reset(src.myHit);
139  return *this;
140  }
142  {
143  swap(src);
144  src.reset();
145  return *this;
146  }
147 
148  Hit &operator*() const noexcept { return *myHit; }
149  Hit *operator->() const noexcept { return myHit; }
150  Hit *get() const noexcept { return myHit; }
151  SYS_SAFE_BOOL operator bool() const noexcept { return myHit != nullptr; }
152  void swap(HitPtr &s) noexcept { UTswap(myHit, s.myHit); }
153  void reset() noexcept
154  {
155  if (myHit)
156  {
157  myHit->dec_ref();
158  myHit = nullptr;
159  }
160  }
161  void reset(Hit *hit) noexcept
162  {
163  if (hit)
164  hit->inc_ref();
165  if (myHit)
166  myHit->dec_ref();
167  myHit = hit;
168  }
169 
170  private:
171  Hit *myHit;
172  };
173 
174  BRAY_Procedural();
175  virtual ~BRAY_Procedural();
176 
177  /// Return a name for this procedural. This defaults to factory()->name();
178  const UT_StringHolder &className() const { return myFactory->name(); }
179 
180  /// Return the factory definition
181  const BRAY_ProceduralFactory *factory() const { return myFactory; }
182 
183  /// Return an attribute list for the attributes supported by this primitive.
184  virtual const BRAY_AttribList *attribList() const = 0;
185 
186  /// Return a parameter list that the procedural exposes to the outside
187  /// world that could be set using the @c setParameter() methods
188  /// The default implementation calls factory()->paramList();
189  virtual const BRAY_AttribList *paramList() const
190  {
191  return myFactory->paramList();
192  }
193 
194  /// Return the bounding box for the object at a given time
195  virtual void bounds(UT_BoundingBox &bounds, BRAYtime time) const = 0;
196 
197  /// @{
198  /// Set parameters on procedurals in addition to attributes that the
199  /// procedural might provide. One way to think of parameters and attributes
200  /// is that attributes are what procedurals bring to the table internally,
201  /// where as parameters are something that can be applied onto procedurals.
202  /// For example, a 'Sphere' object is a procedural. It's attributes could
203  /// be like 'color', 'normal' on vertices. whereas 'parameters' could be
204  /// 'radius', etc. Depending upon the procedural the meaning of these two
205  /// terms change contextually.
206  ///
207  /// The templates are specialized for:
208  /// - int32, int64, fpreal32, fpreal64, UT_StringHolder
209  template <typename T>
210  void setParameter(const UT_StringRef &key, const T &val)
211  {
212  doSetParameter(key, &val, 1);
213  }
214 
215  template <typename T>
216  void setParameter(const UT_StringRef& key, const T* values, int n)
217  {
218  doSetParameter(key, values, n);
219  }
220  /// @}
221 
222  /// @{
223  /// Signal the procedural
224  ///
225  /// We allow for the Procedural to update itself and do any further
226  /// processing in case any parameters have been set. The set parameter
227  /// methods are generally invoked on the procedural, which might be
228  /// implemented by the procedural to copy data, precompute stuff, validate
229  /// parameter ranges etc. Once these have been set, the begin/end update
230  /// methods can be used by the procedural to perform operations that can be
231  /// performed only when there's nothing more to set as parameters to the
232  /// procedural. The procedural can now start working on doing other things
233  /// with the set parameters because it can be sure that the parameters now
234  /// have become immutable.
235  void beginUpdate()
236  {
237  doBeginUpdate();
238  }
239 
240  void endUpdate()
241  {
242  doEndUpdate();
243  }
244  /// @}
245 
246  /// Check whether the procedural is valid
247  bool isValid() const
248  {
249  return checkIsValid();
250  }
251 
252  /// @{
253  /// Perform ray-intersection
254  ///
255  /// If the distanct to the closest intersection point for the procedural
256  /// object is closer than the @c distance already stored in the @c
257  /// hit_info, the hit information should be replaced and the @c intersect()
258  /// method should return @c true.
259  ///
260  /// If the distance to the closest intersection point is farther than the
261  /// existing @c distance, then the @c hit_info should remain unchanged.
262  ///
263  /// NOTE:
264  /// The ray's direction vector CANNOT be expected to be unit length
265  /// Hence the procedural is responsible for accounting and returning
266  /// the correct 't' in the hit_info struct if it ever scaled
267  /// it internally to unit length.
268  virtual HitPtr intersect(const Ray32 &ray) const = 0;
269  virtual HitPtr intersect(const Ray64 &ray) const = 0;
270  /// @}
271 
272  /// Return a display color for low-quality rendering
273  virtual UT_Vector3 displayColor() const { return UT_Vector3(1, 1, 1); }
274 
275  /// @{
276  /// Evaluate an attribute on this primitive. The methods should return a
277  /// pointer to the attribute data. If there isn't a direct raw pointer to
278  /// the data, the buffer passed in can be used to store the data and that
279  /// pointer can be returned.
280  /// The @c element is the element
281  virtual const int32 *attribVal(int attrib, BRAYtime time,
282  const Hit &hit_info,
283  int32 *buf, int size) const = 0;
284  virtual const int64 *attribVal(int attrib, BRAYtime time,
285  const Hit &hit_info,
286  int64 *buf, int size) const = 0;
287  virtual const fpreal32 *attribVal(int attrib, BRAYtime time,
288  const Hit &hit_info,
289  fpreal32 *buf, int size) const = 0;
290  virtual const fpreal64 *attribVal(int attrib, BRAYtime time,
291  const Hit &hit_info,
292  fpreal64 *buf, int size) const = 0;
293  virtual const UT_StringHolder *attribVal(int attrib, BRAYtime time,
294  const Hit &hit_info,
295  UT_StringHolder *buf, int size) const = 0;
296 
297 
298  /// @}
299 
300  /// @{
301  /// Evaluation of array attributes (each attribute can have an arbitrary
302  /// number of entries. By default, the array attribute evaluators set the
303  /// arrays to a size of 0 and return the storage array.
304  virtual const UT_ValArray<int32> *attribVal(int attrib,
305  BRAYtime time,
306  const Hit &hit_info,
308  int size) const;
309  virtual const UT_ValArray<int64> *attribVal(int attrib,
310  BRAYtime time,
311  const Hit &hit_info,
313  int size) const;
314  virtual const UT_ValArray<fpreal32> *attribVal(int attrib,
315  BRAYtime time,
316  const Hit &hit_info,
318  int size) const;
319  virtual const UT_ValArray<fpreal64> *attribVal(int attrib,
320  BRAYtime time,
321  const Hit &hit_info,
323  int size) const;
324  virtual const UT_StringArray *attribVal(int attrib,
325  BRAYtime time,
326  const Hit &hit_info,
328  int size) const;
329  /// @}
330 
331  /// This method can be used to be notified of changes to the object
332  virtual void update(BRAY_EventType event) = 0;
333 
334  /// Dump out information about the procedural for debugging. By default, a
335  /// null is written to the stream.
336  virtual void dumpInfo(UT_JSONWriter &w) const;
337 
338  /// @private
339  void setFactory(BRAY_ProceduralFactory *f) { myFactory = f; }
340 
341 protected:
342  /// @c Hit objects are virtual which allows you to create a sub-class that
343  /// stores information specific to your procedural type. The Hit structure
344  /// should be kept relatively small if possible. When you need to allocate
345  /// a Hit object for your intersect method, you should call @c getHit().
346  ///
347  /// To implement the actual allocation of the custom @c Hit object, you
348  /// need to implement @c newHit().
349  HitPtr getHit() const;
350 
351  /// The @c newHit() method is used to allocate a custom @c Hit type. The
352  /// typical way this is done is: @code
353  /// class MyHit : public Hit { };
354  /// HitPtr newHit() const override { return HitPtr(new MyHit(...)); }
355  /// @endcode
356  virtual HitPtr newHit() const;
357 
358  /// This method will be called to print out an error if the procedural isn't
359  /// set up properly. You can override it to silence the errors.
360  virtual void errorMessage(const char *fmt, ...)
362 
363  /// These functions are the ones that each procedural will override
364  /// for doing preupdate/post update operations.
365  virtual void doBeginUpdate() = 0;
366  virtual void doEndUpdate() = 0;
367 
368  /// Check to see whether the procedural is valid
369  virtual bool checkIsValid() const = 0;
370 
371  /// These methods will be used by the implementing classes to set
372  /// parameters that the procedural will support
373  virtual void doSetParameter(const UT_StringRef& key,
374  const int32* values, int n = 1) = 0;
375  virtual void doSetParameter(const UT_StringRef& key,
376  const int64* values, int n = 1) = 0;
377  virtual void doSetParameter(const UT_StringRef& key,
378  const fpreal32* values, int n = 1) = 0;
379  virtual void doSetParameter(const UT_StringRef& key,
380  const fpreal64* value, int n = 1) = 0;
381  virtual void doSetParameter(const UT_StringRef& key,
382  const UT_StringHolder* value, int n = 1) = 0;
383 
384 private:
385  const BRAY_ProceduralFactory *myFactory;
386 };
387 
388 #endif
BRAY_EventType
Types of events that can be sent as updates to the renderer.
Definition: BRAY_Types.h:39
virtual const BRAY_AttribList * paramList() const
int int32
Definition: SYS_Types.h:39
HitPtr(const HitPtr &src) noexcept
void UTswap(T &a, T &b)
Definition: UT_Swap.h:35
float BRAYtime
Consistent representation of time type within BRAY.
Definition: BRAY_Types.h:585
GT_API const UT_StringHolder time
void setParameter(const UT_StringRef &key, const T &val)
const BRAY_ProceduralFactory * factory() const
Return the factory definition.
UT_Vector3T< float > UT_Vector3
bool isValid() const
Check whether the procedural is valid.
void swap(T &lhs, T &rhs)
Definition: pugixml.cpp:7172
Hit * operator->() const noexcept
const UT_StringHolder & className() const
Return a name for this procedural. This defaults to factory()->name();.
void setParameter(const UT_StringRef &key, const T *values, int n)
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:35
GLenum src
Definition: glcorearb.h:1792
3D Vector class.
float fpreal32
Definition: SYS_Types.h:200
virtual UT_Vector3 displayColor() const
Return a display color for low-quality rendering.
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1601
void reset(Hit *hit) noexcept
const T & castTo() const
struct _cl_event * event
Definition: glcorearb.h:2960
GLsizeiptr size
Definition: glcorearb.h:663
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:856
double fpreal64
Definition: SYS_Types.h:201
bool intersect(const Line3< T > &line, const Vec3< T > &v0, const Vec3< T > &v1, const Vec3< T > &v2, Vec3< T > &pt, Vec3< T > &barycentric, bool &front)
#define SYS_SAFE_BOOL
Definition: SYS_Compiler.h:55
GLsizei GLsizei GLfloat distance
Definition: glew.h:13923
#define SYS_PRINTF_CHECK_ATTRIBUTE(string_index, first_to_check)
Definition: SYS_Types.h:447
const GLdouble * v
Definition: glcorearb.h:836
const UT_Vector3T< PREC > & org
HGLRC const int * attribList
Definition: wglew.h:140
HitPtr & operator=(const HitPtr &src)
long long int64
Definition: SYS_Types.h:116
HitPtr(Hit *ptr) noexcept
GLboolean reset
Definition: glew.h:4989
const UT_Vector3T< PREC > & dir
HitPtr(HitPtr &&src) noexcept
#define SYS_FPREAL_MAX
Definition: SYS_Types.h:286
GLdouble n
Definition: glcorearb.h:2007
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2539
GLuint GLfloat * val
Definition: glcorearb.h:1607
Each BRAY_Object can define a list of attributes that it can evaluate.
const void * ptr(const T *p)
Definition: format.h:3603
fpreal64 fpreal
Definition: SYS_Types.h:277
#define BRAY_API
Definition: BRAY_API.h:12
GLsizei const GLfloat * value
Definition: glcorearb.h:823
GLfloat f
Definition: glcorearb.h:1925
HitPtr & operator=(HitPtr &&src)
#define const
Definition: zconf.h:214
void swap(HitPtr &s) noexcept
Hit & operator*() const noexcept
GLdouble s
Definition: glew.h:1395
unsigned int uint
Definition: SYS_Types.h:45
Hit(fpreal d=SYS_FPREAL_MAX)