HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
VGEO_Volume.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: VGEO_Volume.h ( VGEO Library, C++)
7  *
8  * COMMENTS: Procedurally defined volumetric rendering data
9  */
10 
11 #ifndef __VGEO_Volume__
12 #define __VGEO_Volume__
13 
14 #include "VGEO_API.h"
15 #include <UT/UT_VectorTypes.h>
16 #include <UT/UT_BoundingBox.h>
17 #include <SYS/SYS_Types.h>
18 #include <SYS/SYS_AtomicInt.h>
19 
20 template <class T> class UT_Array;
21 template <bool> class VGEO_KDTree;
22 
23 // We have to include voxel array as we can't forward declare
24 // UT_VoxelArrayF, I think.
25 #include <UT/UT_VoxelArray.h>
26 #include <UT/UT_IntrusivePtr.h>
27 #include <GA/GA_Types.h>
28 
29 class UT_StringArray;
30 class UT_Filter;
31 class VEX_LateBinding;
32 class GEO_Primitive;
33 class GEO_Vertex;
34 class GU_Detail;
35 class VGEO_HitList;
36 class VGEO_RayState;
37 class VGEO_ShadeObject;
38 class VGEO_Ray;
39 
40 /// Base class for volume primitives in mantra
42  : public UT_IntrusiveRefCounter<VGEO_Volume>
43 {
44 public:
45  VGEO_Volume();
46  virtual ~VGEO_Volume();
47 
48  /// @{
49  /// Return the geometric primitive or vertex associated with the
50  /// volume. These can be used to fill in primitive and detail
51  /// attributes associated with the volume.
52  virtual GA_Offset getGeoPrimitive() const
53  { return GA_INVALID_OFFSET; }
54  virtual GA_Offset getGeoVertex() const
55  { return GA_INVALID_OFFSET; }
56  /// @}
57 
58  /// Return the object space step size to use when the volume quality is
59  /// 1 and there is no object-level scale. For primitives based on
60  /// voxel grids, this method is usually implemented by returning the
61  /// voxel size.
62  virtual float getNativeStepSize() const = 0;
63 
64  /// Return a set of bounding boxes that define the structure of the
65  /// volumetric data. The boxes are used to accelerate ray intersection
66  /// testing with the volume and to cull empty space for micropolygon
67  /// rendering. They need not be an exact representation of the volume,
68  /// though more accurate boxes will lead to more efficient renders.
69  /// Specifically, the union of the boxes returned by this method should
70  /// fully enclose the region of the volume to be rendered. If there is
71  /// volumetric data outside all boxes, the render may contain
72  /// artifacts.
73  ///
74  /// Boxes should be defined locally, and need to incorporate the
75  /// displacement bound.
76  /// @param radius Filter radius in voxels
77  /// @param dbound Displacement bound in local space
78  /// @param zerothreshold Threshold value under which the volume is considered empty.
79  virtual void getBoxes(UT_Array<UT_BoundingBox> &boxes,
80  float radius,
81  float dbound,
82  float zerothreshold) const = 0;
83 
84  /// Return a list of attributes present in this volume. These
85  /// attributes will be bound to surface shader variables when the
86  /// volume is rendered. The "idx" passed into evaluation routines will
87  /// be the array index returned by this operation.
88  /// - sizes: number of floats in each attribute
89  virtual void getAttributeBinding(UT_StringArray &names,
90  UT_IntArray &sizes) const = 0;
91 
92  /// Evaluate a volume attribute at a given position.
93  /// @param pos Evaluation position
94  /// @param filter Filter function
95  /// @param radius Filter radius in @b voxels
96  /// @param time Evaluation time (0-1)
97  /// @param idx Attribute index (based on getAttributeBinding())
98  /// @param data Storage for evaluation data
99  /// @see UT_Filter
100  virtual void evaluate(const UT_Vector3 &pos,
101  const UT_Filter &filter,
102  float radius, float time,
103  int idx, float *data) const = 0;
104 
105  /// Evaluate multiple volume attribute at given positions.
106  /// @param pos Evaluation positions
107  /// @param filter Filter function
108  /// @param radius Filter radius in @b voxels
109  /// @param time Evaluation times (0-1)
110  /// @param idx Attribute index (based on getAttributeBinding())
111  /// @param data Storage for evaluation data
112  /// @param size Number of positions to evaluate
113  /// @param stride Data size for an individual evaluation, this should match the size returned by getAttributeBinding() for the given index.
114  /// @see UT_Filter
115  virtual void evaluateMulti(const UT_Vector3 *pos,
116  const UT_Filter &filter,
117  float radius,
118  const float *time,
119  int idx, float *data,
120  int size, int stride) const;
121 
122  /// Evaluate the minimum and maximum values for an attribute within a
123  /// given box. If this operation is not supported, the caller will
124  /// assume that the interval is unbounded.
125  /// @param box Evaluation interval
126  /// @param filter Filter function
127  /// @param radius Filter radius in @b voxels
128  /// @param time Evaluation time (0-1)
129  /// @param idx Attribute index (based on getAttributeBinding())
130  /// @param minval Storage for evaluation data (minimum over box)
131  /// @param maxval Storage for evaluation data (maximum over box)
132  /// @see UT_Filter
133  virtual bool evaluateInterval(const UT_BoundingBox &box,
134  const UT_Filter &filter,
135  float radius,
136  float time, int idx,
137  float *minval,
138  float *maxval) const
139  {
140  return false;
141  }
142 
143  /// A class to transfer ray intersection hit information back to the
144  /// renderer from ray tracing callbacks. The VGEO_HitList,
145  /// VGEO_RayState, and VGEO_ShadeObject classes are internal to mantra
146  /// and are only accessible to plugins as forward declarations.
147  class HitList {
148  public:
149  /// Constructor (used internally)
150  HitList(VGEO_HitList &hits,
151  VGEO_RayState &state,
152  VGEO_ShadeObject *prim,
153  float zoff,
154  float tmin,
155  float tmax,
156  float stepsize)
157  : myHits(hits)
158  , myState(state)
159  , myPrim(prim)
160  , myZOff(zoff)
161  , myTMin(tmin)
162  , myTMax(tmax)
163  , myStepSize(stepsize) {}
164 
165  /// Return the minimum ray parameter for hit insertion
166  float tmin() const { return myTMin; }
167  /// Return the maximum ray parameter for hit insertion. When
168  /// t >= tmax(), intersection tests can be terminated.
169  float tmax() const { return myTMax; }
170  /// Return the stratified sample offset for this hit list. This
171  /// value is premultiplied by stepsize().
172  float zoff() const { return myZOff; }
173  /// Return the volume step size for ray marching algorithms
174  float stepsize() const { return myStepSize; }
175 
176  /// Insert a ray intersection hit. This method may decrease the
177  /// value returned by tmax().
178  /// @param t Ray parameter for the intersection
179  /// @param pos Intersection position in local space
180  /// @param backface Whether the hit is backfacing
181  void addHit(float t, const UT_Vector3 &pos, bool backface);
182 
183  /// Dump the hist
184  void dump() const;
185 
186  /// Size of the hit list
187  exint entries() const;
188 
189  private:
190  VGEO_HitList &myHits;
191  VGEO_RayState &myState;
192  VGEO_ShadeObject *myPrim;
193  float myZOff;
194  float myTMin;
195  float myTMax;
196  float myStepSize;
197  };
198 
199  /// Find the intersection of a ray against the isosurface defined by a
200  /// scalar field. The default implementation uses ray marching and the
201  /// evaluateMulti() method to find a zero-crossing via sampling.
202  /// @param ray Ray for intersection testing
203  /// @param filter Filter function
204  /// @param radius Filter radius in @b voxels
205  /// @param time Evaluation time (0-1)
206  /// @param idx Attribute index (based on getAttributeBinding())
207  /// @param threshold Isosurface threshold value
208  /// @param hits Callback object for insertion of ray intersection results
209  virtual void intersectIsosurface(const VGEO_Ray &ray,
210  const UT_Filter &filter,
211  float radius,
212  float time,
213  int idx,
214  float threshold,
215  HitList &hits) const;
216 
217  /// Perform ray marching through a volume. The default implementation
218  /// finds occupied intervals of the volume based on the boxes returned
219  /// by getBoxes(), and inserts evenly spaced samples within these
220  /// intervals.
221  /// @param ray Ray for intersection testing
222  /// @param hits Callback object for insertion of ray intersection results
223  virtual void intersectVolume(const VGEO_Ray &ray,
224  HitList &hits) const;
225 
226  /// Evaluate the gradient of a volume attribute at a given position.
227  /// @param pos Evaluation position
228  /// @param filter Filter function
229  /// @param radius Filter radius in @b voxels
230  /// @param time Evaluation time (0-1)
231  /// @param idx Attribute index (based on getAttributeBinding())
232  /// @see UT_Filter
233  virtual UT_Vector3 gradient(const UT_Vector3 &pos,
234  const UT_Filter &filter,
235  float radius, float time,
236  int idx) const;
237 
238  /// Returns a local distance for use in default gradient calculations.
239  virtual float getGradientDelta() const { return 1e-3F; }
240 
241  /// Returns the volume attribute index to be used for normal vector
242  /// calculations.
243  virtual int getNormalAttribute() const { return 0; }
244 
245  /// Returns the voxel size in the same space as 'pos' in evaluate.
246  virtual float getVoxelSize() const { return 0; }
247 
248  /// Returns true when the volume data should be interpreted as an SDF
249  virtual bool isSDF() const { return false; }
250 
251  /// Utility class to perform numerically safe ray marching
253  public:
254  DiscreteRayMarcher(float stepsize, float zoff)
255  : myStepSize(stepsize)
256  , myZOff(zoff) {}
257 
258  // tmin must be >= 0 for this to work correctly
259  float init(float tmin)
260  {
261  UT_ASSERT(tmin >= 0);
262  mySteps = exint((myStepSize - myZOff + tmin) / myStepSize);
263  float tval = myZOff + mySteps*myStepSize;
264 
265  if (tval <= tmin)
266  {
267  mySteps++;
268  tval = myZOff + mySteps*myStepSize;
269  }
270 
271  // If tval < tmin, the volume is invalid (i.e. 0 sized?)
272  UT_ASSERT(tval > tmin && "0 sized volume?");
273  return tval;
274  }
275 
276  float step() { mySteps++; return myZOff + mySteps*myStepSize; }
277  float stepback() { mySteps--; return myZOff + mySteps*myStepSize; }
278 
279  private:
280  float myStepSize;
281  float myZOff;
282  exint mySteps;
283  };
284 
285 public:
286  /// @private Function used internally to get an octree
287  VGEO_KDTree<false> *getTree(float radius, float zerothreshold);
288  /// @private Function used internally to get displaced octree
289  VGEO_KDTree<false> *getDisplaceTree(float radius,
290  float dbound,
291  float zerothreshold);
292 
293  /// @private Function used internally to create a late binding
294  void fillBinding(VEX_LateBinding &bind) const;
295 
296  /// Utility method to create bounding boxes for every nonzero voxel in
297  /// the voxel array.
298  static void addVoxelBoxes(const UT_VoxelArrayF &voxels,
300  float radius,
301  float dbound,
302  float zerothreshold);
303 
304  /// Utility method to create an isosurface from a voxel array
305  static GU_Detail *getVoxelIsosurface(const UT_VoxelArrayF &voxels,
306  float radius,
307  float dbound,
308  float zerothreshold);
309 
310 private:
311  VGEO_KDTree<false> *myTree;
312  VGEO_KDTree<false> *myDisplaceTree;
313 };
314 
316 
317 #endif
GLuint GLsizei const GLuint const GLintptr const GLsizeiptr * sizes
Definition: glcorearb.h:2621
virtual float getGradientDelta() const
Returns a local distance for use in default gradient calculations.
Definition: VGEO_Volume.h:239
float stepsize() const
Return the volume step size for ray marching algorithms.
Definition: VGEO_Volume.h:174
virtual bool evaluateInterval(const UT_BoundingBox &box, const UT_Filter &filter, float radius, float time, int idx, float *minval, float *maxval) const
Definition: VGEO_Volume.h:133
Utility class to perform numerically safe ray marching.
Definition: VGEO_Volume.h:252
GT_API const UT_StringHolder time
DiscreteRayMarcher(float stepsize, float zoff)
Definition: VGEO_Volume.h:254
virtual GA_Offset getGeoVertex() const
Definition: VGEO_Volume.h:54
Base class for volume primitives in mantra.
Definition: VGEO_Volume.h:41
int64 exint
Definition: SYS_Types.h:125
virtual float getVoxelSize() const
Returns the voxel size in the same space as 'pos' in evaluate.
Definition: VGEO_Volume.h:246
A reference counter base class for use with UT_IntrusivePtr.
float tmax() const
Definition: VGEO_Volume.h:169
#define GA_INVALID_OFFSET
Definition: GA_Types.h:678
float zoff() const
Definition: VGEO_Volume.h:172
GA_Size GA_Offset
Definition: GA_Types.h:641
virtual GA_Offset getGeoPrimitive() const
Definition: VGEO_Volume.h:52
GLint GLenum GLboolean GLsizei stride
Definition: glcorearb.h:872
Wrapper around hboost::intrusive_ptr.
GLdouble t
Definition: glad.h:2397
GLsizeiptr size
Definition: glcorearb.h:664
virtual int getNormalAttribute() const
Definition: VGEO_Volume.h:243
ScalarToVectorConverter< GridType >::Type::Ptr gradient(const GridType &grid, bool threaded, InterruptT *interrupt)
Compute the gradient of the given scalar grid.
#define VGEO_API
Definition: VGEO_API.h:12
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
float tmin() const
Return the minimum ray parameter for hit insertion.
Definition: VGEO_Volume.h:166
HitList(VGEO_HitList &hits, VGEO_RayState &state, VGEO_ShadeObject *prim, float zoff, float tmin, float tmax, float stepsize)
Constructor (used internally)
Definition: VGEO_Volume.h:150
Definition: format.h:895
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glcorearb.h:1297
virtual bool isSDF() const
Returns true when the volume data should be interpreted as an SDF.
Definition: VGEO_Volume.h:249