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  uint tri0 : 1; // s+t < 1 in triangulated quad
79 
80  // @{
81  // A convenience method to get a reference to a sub-class type
82  // For example: @code
83  // MyHit &hit = src_hit.castTo<MyHit>();
84  // const MyHit &hit2 = src_hit.castTo<const MyHit>();
85  // @endcode
86  template <typename T>
87  T &castTo() { return *reinterpret_cast<T *>(this); }
88  template <typename T>
89  const T &castTo() const { return *reinterpret_cast<T *>(this); }
90  // @}
91 
92 
93  private:
94  // Private data for internal use only.
95  void inc_ref() { ++ref_count; }
96  void dec_ref()
97  {
98  --ref_count;
99  if (!ref_count)
100  releaseHit();
101  }
102  void releaseHit(); // Private method
103  int ref_count; // Order before pointer for alignment
104  friend class HitPtr;
105  friend class BRAY_Procedural;
106  };
107 
108  // Smart pointer for hits
110  {
111  public:
112  HitPtr() noexcept
113  : myHit(nullptr)
114  {
115  }
116  HitPtr(Hit *ptr) noexcept
117  : myHit(ptr)
118  {
119  if (myHit)
120  myHit->inc_ref();
121  }
122  HitPtr(const HitPtr &src) noexcept
123  : myHit(src.myHit)
124  {
125  if (myHit)
126  myHit->inc_ref();
127  }
128  HitPtr(HitPtr &&src) noexcept
129  : myHit(src.myHit)
130  {
131  src.myHit = nullptr;
132  }
134  {
135  reset();
136  }
138  {
139  reset(src.myHit);
140  return *this;
141  }
143  {
144  swap(src);
145  src.reset();
146  return *this;
147  }
148 
149  Hit &operator*() const noexcept { return *myHit; }
150  Hit *operator->() const noexcept { return myHit; }
151  Hit *get() const noexcept { return myHit; }
152  SYS_SAFE_BOOL operator bool() const noexcept { return myHit != nullptr; }
153  void swap(HitPtr &s) noexcept { UTswap(myHit, s.myHit); }
154  void reset() noexcept
155  {
156  if (myHit)
157  {
158  myHit->dec_ref();
159  myHit = nullptr;
160  }
161  }
162  void reset(Hit *hit) noexcept
163  {
164  if (hit)
165  hit->inc_ref();
166  if (myHit)
167  myHit->dec_ref();
168  myHit = hit;
169  }
170 
171  private:
172  Hit *myHit;
173  };
174 
175  BRAY_Procedural();
176  virtual ~BRAY_Procedural();
177 
178  /// Return a name for this procedural. This defaults to factory()->name();
179  const UT_StringHolder &className() const { return myFactory->name(); }
180 
181  /// Return the factory definition
182  const BRAY_ProceduralFactory *factory() const { return myFactory; }
183 
184  /// Return an attribute list for the attributes supported by this primitive.
185  virtual const BRAY_AttribList *attribList() const = 0;
186 
187  /// Return a parameter list that the procedural exposes to the outside
188  /// world that could be set using the @c setParameter() methods
189  /// The default implementation calls factory()->paramList();
190  virtual const BRAY_AttribList *paramList() const
191  {
192  return myFactory->paramList();
193  }
194 
195  /// Return the bounding box for the object at a given time
196  virtual void bounds(UT_BoundingBox &bounds, BRAYtime time) const = 0;
197 
198  /// @{
199  /// Set parameters on procedurals in addition to attributes that the
200  /// procedural might provide. One way to think of parameters and attributes
201  /// is that attributes are what procedurals bring to the table internally,
202  /// where as parameters are something that can be applied onto procedurals.
203  /// For example, a 'Sphere' object is a procedural. It's attributes could
204  /// be like 'color', 'normal' on vertices. whereas 'parameters' could be
205  /// 'radius', etc. Depending upon the procedural the meaning of these two
206  /// terms change contextually.
207  ///
208  /// The templates are specialized for:
209  /// - int32, int64, fpreal32, fpreal64, UT_StringHolder
210  template <typename T>
211  void setParameter(const UT_StringRef &key, const T &val)
212  {
213  doSetParameter(key, &val, 1);
214  }
215 
216  template <typename T>
217  void setParameter(const UT_StringRef& key, const T* values, int n)
218  {
219  doSetParameter(key, values, n);
220  }
221  /// @}
222 
223  /// @{
224  /// Signal the procedural
225  ///
226  /// We allow for the Procedural to update itself and do any further
227  /// processing in case any parameters have been set. The set parameter
228  /// methods are generally invoked on the procedural, which might be
229  /// implemented by the procedural to copy data, precompute stuff, validate
230  /// parameter ranges etc. Once these have been set, the begin/end update
231  /// methods can be used by the procedural to perform operations that can be
232  /// performed only when there's nothing more to set as parameters to the
233  /// procedural. The procedural can now start working on doing other things
234  /// with the set parameters because it can be sure that the parameters now
235  /// have become immutable.
236  void beginUpdate()
237  {
238  doBeginUpdate();
239  }
240 
241  void endUpdate()
242  {
243  doEndUpdate();
244  }
245  /// @}
246 
247  /// Check whether the procedural is valid
248  bool isValid() const
249  {
250  return checkIsValid();
251  }
252 
253  /// @{
254  /// Perform ray-intersection
255  ///
256  /// If the distanct to the closest intersection point for the procedural
257  /// object is closer than the @c distance already stored in the @c
258  /// hit_info, the hit information should be replaced and the @c intersect()
259  /// method should return @c true.
260  ///
261  /// If the distance to the closest intersection point is farther than the
262  /// existing @c distance, then the @c hit_info should remain unchanged.
263  ///
264  /// NOTE:
265  /// The ray's direction vector CANNOT be expected to be unit length
266  /// Hence the procedural is responsible for accounting and returning
267  /// the correct 't' in the hit_info struct if it ever scaled
268  /// it internally to unit length.
269  virtual HitPtr intersect(const Ray32 &ray) const = 0;
270  virtual HitPtr intersect(const Ray64 &ray) const = 0;
271  /// @}
272 
273  /// Return a display color for low-quality rendering
274  virtual UT_Vector3 displayColor() const { return UT_Vector3(1, 1, 1); }
275 
276  /// @{
277  /// Evaluate an attribute on this primitive. The methods should return a
278  /// pointer to the attribute data. If there isn't a direct raw pointer to
279  /// the data, the buffer passed in can be used to store the data and that
280  /// pointer can be returned.
281  /// The @c element is the element
282  virtual const int32 *attribVal(int attrib, BRAYtime time,
283  const Hit &hit_info,
284  int32 *buf, int size) const = 0;
285  virtual const int64 *attribVal(int attrib, BRAYtime time,
286  const Hit &hit_info,
287  int64 *buf, int size) const = 0;
288  virtual const fpreal32 *attribVal(int attrib, BRAYtime time,
289  const Hit &hit_info,
290  fpreal32 *buf, int size) const = 0;
291  virtual const fpreal64 *attribVal(int attrib, BRAYtime time,
292  const Hit &hit_info,
293  fpreal64 *buf, int size) const = 0;
294  virtual const UT_StringHolder *attribVal(int attrib, BRAYtime time,
295  const Hit &hit_info,
296  UT_StringHolder *buf, int size) const = 0;
297 
298 
299  /// @}
300 
301  /// @{
302  /// Evaluation of array attributes (each attribute can have an arbitrary
303  /// number of entries. By default, the array attribute evaluators set the
304  /// arrays to a size of 0 and return the storage array.
305  virtual const UT_ValArray<int32> *attribVal(int attrib,
306  BRAYtime time,
307  const Hit &hit_info,
309  int size) const;
310  virtual const UT_ValArray<int64> *attribVal(int attrib,
311  BRAYtime time,
312  const Hit &hit_info,
314  int size) const;
315  virtual const UT_ValArray<fpreal32> *attribVal(int attrib,
316  BRAYtime time,
317  const Hit &hit_info,
319  int size) const;
320  virtual const UT_ValArray<fpreal64> *attribVal(int attrib,
321  BRAYtime time,
322  const Hit &hit_info,
324  int size) const;
325  virtual const UT_StringArray *attribVal(int attrib,
326  BRAYtime time,
327  const Hit &hit_info,
329  int size) const;
330  /// @}
331 
332  /// This method can be used to be notified of changes to the object
333  virtual void update(BRAY_EventType event) = 0;
334 
335  /// Dump out information about the procedural for debugging. By default, a
336  /// null is written to the stream.
337  virtual void dumpInfo(UT_JSONWriter &w) const;
338 
339  /// @private
340  void setFactory(BRAY_ProceduralFactory *f) { myFactory = f; }
341 
342 protected:
343  /// @c Hit objects are virtual which allows you to create a sub-class that
344  /// stores information specific to your procedural type. The Hit structure
345  /// should be kept relatively small if possible. When you need to allocate
346  /// a Hit object for your intersect method, you should call @c getHit().
347  ///
348  /// To implement the actual allocation of the custom @c Hit object, you
349  /// need to implement @c newHit().
350  HitPtr getHit() const;
351 
352  /// The @c newHit() method is used to allocate a custom @c Hit type. The
353  /// typical way this is done is: @code
354  /// class MyHit : public Hit { };
355  /// HitPtr newHit() const override { return HitPtr(new MyHit(...)); }
356  /// @endcode
357  virtual HitPtr newHit() const;
358 
359  /// This method will be called to print out an error if the procedural isn't
360  /// set up properly. You can override it to silence the errors.
361  virtual void errorMessage(const char *fmt, ...)
363 
364  /// These functions are the ones that each procedural will override
365  /// for doing preupdate/post update operations.
366  virtual void doBeginUpdate() = 0;
367  virtual void doEndUpdate() = 0;
368 
369  /// Check to see whether the procedural is valid
370  virtual bool checkIsValid() const = 0;
371 
372  /// These methods will be used by the implementing classes to set
373  /// parameters that the procedural will support
374  virtual void doSetParameter(const UT_StringRef& key,
375  const int32* values, int n = 1) = 0;
376  virtual void doSetParameter(const UT_StringRef& key,
377  const int64* values, int n = 1) = 0;
378  virtual void doSetParameter(const UT_StringRef& key,
379  const fpreal32* values, int n = 1) = 0;
380  virtual void doSetParameter(const UT_StringRef& key,
381  const fpreal64* value, int n = 1) = 0;
382  virtual void doSetParameter(const UT_StringRef& key,
383  const UT_StringHolder* value, int n = 1) = 0;
384 
385 private:
386  const BRAY_ProceduralFactory *myFactory;
387 };
388 
389 #endif
BRAY_EventType
Types of events that can be sent as updates to the renderer.
Definition: BRAY_Types.h:39
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2540
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:748
GT_API const UT_StringHolder time
void setParameter(const UT_StringRef &key, const T &val)
const GLdouble * v
Definition: glcorearb.h:837
const BRAY_ProceduralFactory * factory() const
Return the factory definition.
UT_Vector3T< float > UT_Vector3
bool isValid() const
Check whether the procedural is valid.
GLdouble s
Definition: glad.h:3009
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:37
float fpreal32
Definition: SYS_Types.h:200
virtual UT_Vector3 displayColor() const
Return a display color for low-quality rendering.
void reset(Hit *hit) noexcept
const T & castTo() const
struct _cl_event * event
Definition: glcorearb.h:2961
double fpreal64
Definition: SYS_Types.h:201
GLdouble n
Definition: glcorearb.h:2008
GLfloat f
Definition: glcorearb.h:1926
GLboolean reset
Definition: glad.h:5138
#define SYS_SAFE_BOOL
Definition: SYS_Compiler.h:55
#define SYS_PRINTF_CHECK_ATTRIBUTE(string_index, first_to_check)
Definition: SYS_Types.h:447
const UT_Vector3T< PREC > & org
HitPtr & operator=(const HitPtr &src)
long long int64
Definition: SYS_Types.h:116
HitPtr(Hit *ptr) noexcept
const UT_Vector3T< PREC > & dir
HitPtr(HitPtr &&src) noexcept
#define SYS_FPREAL_MAX
Definition: SYS_Types.h:286
GLsizeiptr size
Definition: glcorearb.h:664
Each BRAY_Object can define a list of attributes that it can evaluate.
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1602
fpreal64 fpreal
Definition: SYS_Types.h:277
IMATH_CONSTEXPR14 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) IMATH_NOEXCEPT
Definition: ImathLineAlgo.h:80
auto ptr(T p) -> const void *
Definition: format.h:2448
GLuint GLfloat * val
Definition: glcorearb.h:1608
#define BRAY_API
Definition: BRAY_API.h:12
HitPtr & operator=(HitPtr &&src)
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
Definition: core.h:1131
void swap(HitPtr &s) noexcept
SIM_API const UT_StringHolder distance
Hit & operator*() const noexcept
unsigned int uint
Definition: SYS_Types.h:45
GLenum src
Definition: glcorearb.h:1793
Hit(fpreal d=SYS_FPREAL_MAX)