HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RAY_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: RAY_Procedural.h ( RAY Library, C++)
7  *
8  * COMMENTS: RAY Procedural Primitive
9  *
10  * This primitive is used to generate procedural geometry during the
11  * rendering process.
12  *
13  * The procedural primitive can generate further procedural primitives, or
14  * as a leaf node, generate a GU_Detail.
15  *
16  * Shaders for the geometry are inherited from the instance of the detail
17  * unless additional shaders are specified using the vm_surface or
18  * vm_displace attributes.
19  */
20 
21 #ifndef __RAY_Procedural__
22 #define __RAY_Procedural__
23 
24 #include "RAY_API.h"
25 #include <SYS/SYS_Types.h>
26 #include <GA/GA_Handle.h>
27 #include <GU/GU_DetailHandle.h>
28 #include <UT/UT_BoundingBox.h>
29 #include <UT/UT_String.h>
30 #include <UT/UT_StringHolder.h>
31 #include <UT/UT_SharedPtr.h>
32 #include <UT/UT_IntrusivePtr.h>
33 
34 class UT_Options;
35 class GU_Detail;
36 class GEO_Detail;
37 class GEO_Primitive;
38 class GA_Attribute;
39 class ray_ProcInstance;
40 class RAY_Procedural;
41 class RAY_ProceduralArg;
42 class VGEO_Volume;
43 class STY_Styler;
44 class RAY_StylerInfo;
45 class RAY_ProceduralData;
46 class RAY_PackedQuery;
48 
49 /// @brief Mantra procedural primitives
50 ///
51 /// When a procedural is defined as a dynamic object, the allocProcedural()
52 /// function is called to build a new instance of the procedural. The name
53 /// passed in will be the name defined by the table entry. This can be used
54 /// for:
55 /// a) Error checking -- you can verify that you're name is what you
56 /// expect. However, this isn't mandatory.
57 /// b) To have more than one procedural defined per C++ class. Using
58 /// the name, you can create procedurals of different types.
59 ///
60 /// The argument list for the procedural is specified by a list of arguments.
61 /// The getProceduralArgs() method should return a pointer to an array of
62 /// RAY_ProceduralArg's. The list should be terminated by an entry with
63 /// default arguments (i.e. null pointers). For example:
64 /// Arguments can then be queried using the argValue() methods in the procedural
65 ///
66 extern "C" {
67  /// Dynamic load entry point to create an instance
69  /// Dynamic load entry point to query arguments for a procedural
71 
72  /// Modern interface to register procedurals
74  RAY_ProceduralFactory *factory);
75 }
76 
77 /// @brief Aliases for different handle types
78 
79 /// A generic handle that can be used by RAY_Procedural::import and
80 /// RAY_Procedural::importAll.
81 typedef void *RAY_Handle;
82 
83 /// A handle for objects. Can also be used anywhere a RAY_Handle is expected.
84 typedef void *RAY_ObjectHandle;
85 
86 /// A handle for materials. Can also be used anywhere a RAY_Handle is expected.
87 typedef void *RAY_MaterialHandle;
88 
89 /// A handle for lights. Can also be used anywhere a RAY_Handle is expected.
90 typedef void *RAY_LightHandle;
91 
92 /// @brief Parameter definition for arguments to RAY_Procedural
93 ///
94 /// Each RAY_Procedural has its arguments defined by a table of
95 /// RAY_ProceduralArg objects. The procedural can query the value of these
96 /// parameters using RAY_Procedural::import() at run time (without having to
97 /// parse argument lists). The list of arguments should be terminated by an
98 /// entry constructed with default arguments. For example:
99 /// @code
100 /// static RAY_ProceduralArg theArgs[] = {
101 /// RAY_ProceduralArg("intarg", "int", "0" ),
102 /// RAY_ProceduralArg("realarg", "real", "3.1415" ),
103 /// RAY_ProceduralArg("stringarg", "string", "foo bar" ),
104 /// RAY_ProceduralArg("vectorarg", "real", "1 2 3" ),
105 /// RAY_ProceduralArg()
106 /// }
107 /// const RAY_ProceduralArg *getProceduralArgs() { return theArgs; }
108 /// @endcode
110 {
111 public:
112  /// @param name @n The name of the parameter (must be unique)
113  /// @param type @n
114  /// The storage type of the parameter. This should be one of
115  /// - @c int = Integer
116  /// - @c real = Floating point (fpreal) value
117  /// - @c string = String value
118  /// @param value @n A @b string representing the default values for the
119  /// argument. For @c int and @c real types, the string is tokenized and
120  /// the number of tokens in the trin determines the vector/tuple size of
121  /// the argument. For example @code
122  /// RAY_ProceduralArg("a", "int", "1 2 3 4")
123  /// @endcode
124  /// would specify a parameter named "a" which consists of 4 integers,
125  /// and has a default value of {1,2,3,4}. @n
126  /// For string types, the vector size is always 1, and the string is
127  /// used as the default value.
128  ///
129  /// @warning The procedural keeps shallow references to the
130  /// <tt>const char *</tt> passed in.
131  RAY_ProceduralArg(const char *name=0, const char *type=0,
132  const char *value=0)
133  {
134  myName = name;
135  myType = type;
136  myValue = value;
137  }
139  {
140  }
141 
142  /// Return the name of the argument
143  const char *getName() const { return myName; }
144  /// Return the storage type of the argument
145  const char *getType() const { return myType; }
146  /// Return the default value
147  const char *getValue() const { return myValue; }
148 
149 private:
150  const char *myName;
151  const char *myType;
152  const char *myValue;
153 };
154 
155 class RAY_ProceduralGeo;
156 
157 /// @brief Reference counted geometry handle for procedurals
158 ///
159 /// Mantra has internal reference counted "smart" pointers for geometry.
160 /// The interface for managing these reference counts manually
161 /// (referenceGeometry()/freeGeometry() was obfuscated and is now deprecated
162 /// in favour of using the VGEO_ProceduralGeo class).
163 ///
164 /// The @c RAY_ROProceduralGeo provides a read-only handle to geometry. This
165 /// is typically used to access geometry that exists in mantra already (i.e.
166 /// geometry returned by <tt>queryGeometry()</tt>).
167 ///
168 /// @c RAY_ProceduralGeo is a read-write handle on mantra geometry.
169 ///
170 /// Each geometry object can have multiple deformation segments.
172 {
173 public:
175 
176  /// Copy c-tor
178  /// Destructor
179  virtual ~RAY_ROProceduralGeo();
180 
181  RAY_ROProceduralGeo& operator=(const RAY_ROProceduralGeo &src);
182 
183  /// Clear the geometry
184  void clear();
185 
186  /// @{
187  /// Equivalence
188  bool operator==(const RAY_ROProceduralGeo &g) const
189  { return get() == g.get(); }
190  bool operator!=(const RAY_ROProceduralGeo &g) const
191  { return get() != g.get(); }
192  /// @}
193 
194  /// @{
195  /// Standard "pointer" operations
196  const GU_Detail *operator->() const { return get(); }
197  const GU_Detail &operator*() const { return *get(); }
198  const GU_Detail *get(int segment=0) const;
199  /// @}
200 
201  /// Access the GU_ConstDetailHandle for a given segment
202  GU_ConstDetailHandle handle(int segment=0) const;
203 
204  /// Test validity
205  bool isValid() const;
206 
207  /// Bool operator on handle
208  SYS_SAFE_BOOL operator bool() const { return isValid(); }
209 
210  /// Return the maximum velocity displacement (so bounding boxes can be
211  /// computed).
212  fpreal velocityBounds() const;
213 
214  /// Return the number of motion segments
215  int motionSegments() const;
216 
217  /// Return reference count on the underlying geometry
218  int getRef() const;
219 
220 protected:
221  friend class RAY_Procedural;
222  friend class RAY_ProceduralChild;
223  class Data;
224 
225  /// @{
226  /// Create a read handle with a geometry.
227  /// @note This method will fail if the handle isn't currently empty
228  bool setGeometry(const GU_ConstDetailHandle &gdh);
229  bool setGeometry(const GU_ConstDetailHandle *gdh, int nsegments);
230  /// @}
231 
232  // Internal method to create read-only geometry from a procedural
234  bool writeable);
236  const GU_ConstDetailHandle *gdh,
237  int nsegments,
238  const fpreal *shutter_times,
239  bool writeable);
240 
242 };
243 
244 /// RAY_ProceduralGeo is a read-write handle on mantra's geometry.
245 ///
246 /// You can create these handles by calling RAY_Procedural::createGeometry()
247 /// and then access the underlying GU_Detail, creating or manipulating
248 /// geometry.
249 ///
250 /// It's also possible to add motion segments to the geometry in one of three
251 /// ways:
252 /// - Pass in a reference to another VGEO_ROProceduralGeo object. This
253 /// will add a motion segment, capturing transform changes on quadric and
254 /// packed primitives as well as motion of points.
255 /// - You can add a "motion segment" attribute. This method returns an
256 /// attribute which you can fill out for the given segment. This method
257 /// is fine in most cases, but doesn't caputre transforms on primitives.
258 /// - Compute velocity blur.
260 {
261 public:
262  /// Default constructor
264 
265  /// Copy c-tor
267  : RAY_ROProceduralGeo(src)
268  {
269  }
270  /// Destructor
272 
274  {
276  return *this;
277  }
278 
279  /// @{
280  /// Standard "pointer" operations
281  GU_Detail *operator->() const { return get(); }
282  GU_Detail &operator*() const { return *get(); }
283  GU_Detail *get(int segment=0) const;
284  /// @}
285 
286  /// Access the geometry using a GU_DetailHandle. If the geometry is
287  /// locked, this method will return an invalid handle. The geometry will
288  /// be locked if it's already been passed to mantra.
289  GU_DetailHandle handle(int segment=0) const;
290 
291  /// Set the geometry for the first motion segment. This method will fail if
292  /// there are any motion segments already. This will delete any geometry
293  /// already assigned to the object.
294  bool setHandle(GU_ConstDetailHandle &gdh);
295 
296  /// Set the shutter start value. This should be set @b before any motion
297  /// segments are added to the geometry. The default shutter open is 0.
298  void setShutterOpen(fpreal shutter);
299 
300  /// Append a motion segment.
301  ///
302  /// The shutter times for all segments should be sequential and added in
303  /// increasing order. A warning will be printed if the segments are added
304  /// out of order.
305  ///
306  /// The method will return an invalid GU_DetailHandle if the geometry has
307  /// been locked (passed to mantra).
308  GU_DetailHandle appendSegmentGeometry(fpreal shutter);
309 
310  /// Remove a motion segment that was added with appendSegmentGeometry()
311  ///
312  /// The method will return an invalid GU_DetailHandle if the geometry has
313  /// been locked (passed to mantra).
314  bool removeSegmentGeometry(const GU_ConstDetailHandle &geo);
315 
316  /// Add a motion segment for the given attribute. This returns the motion
317  /// segment. Note that adding motion segments this way doesn't capture
318  /// per-primitive transforms (i.e. quadrics, packed primitives, etc.)
319  ///
320  /// The shutter times for all segments should be sequential and added in
321  /// increasing order. A warning will be printed if the segments are added
322  /// out of order.
323  ///
324  /// The method will return a @c nullptr if the geometry has been locked
325  /// (passed to mantra).
326  ///
327  /// This method may return a "detached" attribute. The method should be
328  /// called @b after the original geometry attributes have been created so
329  /// the length of the segment attribute is the correct length.
330  GA_Attribute *appendSegmentAttribute(fpreal shutter,
331  const char *name="P");
332 
333  /// Add motion blur based on the velocity attribute. This returns the
334  /// maximum velocity displacement (for bounding box computation). The
335  /// displacement is cached and can be retrieved by calling @c
336  /// velocityBounds().
337  ///
338  /// The method will returns -1 if the geometry has been locked (passed to
339  /// mantra). This should be considered an error.
340  fpreal addVelocityBlur(fpreal pre_blur, fpreal post_blur,
341  const UT_StringHolder &velocity_attribute = UTmakeUnsafeRef("v"),
342  int acceleration_segments = 1,
343  const UT_StringHolder &acceleration_attribute = UT_StringHolder());
344 
345  /// @{
346  /// Change a geometry setting:
347  /// - <tt>changeSetting(const char *name, int argc, char **argv)</tt>
348  /// - <tt>changeSetting(const char *name, int argc, int *argv)</tt>
349  /// - <tt>changeSetting(const char *name, int argc, fpreal *argv)</tt>
350  /// If the setting specified by "name" isn't found, the function will fail
351  /// (return false).
352  ///
353  /// Some settings which can be changed on geometry include:
354  /// - "timescale": The time scale for velocity motion blur
355  /// - "segmentattrs": The attributes to keep on motion segments
356  /// - "volumevelocitynames": Names for velocity attributes on volume prims
357  bool changeSetting(const UT_StringRef &name,
358  int argc, const char *const*argv);
359  bool changeSetting(const UT_StringRef &name,
360  int argc, const UT_StringHolder *argv);
361  bool changeSetting(const UT_StringRef &name,
362  int argc, const int *argv);
363  bool changeSetting(const UT_StringRef &name,
364  int argc, const fpreal *argv);
365  /// @}
366 
367 private:
368  /// Create new geometry for a procedural. Internal method.
371  const GU_ConstDetailHandle *geo,
372  int nsegments,
373  const fpreal *shutter_times,
374  bool writeable);
375 
376  friend class RAY_Procedural;
377  friend class RAY_ProceduralChild;
378 };
379 
380 /// Simple struct to capture the standard attributes for material
381 /// specifications on procedural geometry.
383 {
390 };
391 
392 /// @brief Class representing a child object of the current procedural
393 ///
394 /// When a RAY_Procedural is rendered, the procedural can create child
395 /// geometry objects, further procedurals, or even a mix of the two.
396 ///
397 /// When creating geometry to be rendered, the code would look something along
398 /// the lines of: @code
399 /// // Create geometry by loading geometry from disk.
400 /// RAY_ProceduralGeo geo = createGeometry();
401 /// geo->load("defgeo.bgeo");
402 ///
403 /// // Add the geometry to the render
404 /// RAY_ProceduralChildPtr obj = createChild();
405 /// obj->addGeometry(geo);
406 /// @endcode
407 ///
408 /// When adding further procedural children, the code might look something
409 /// like: @code
410 /// RAY_ProceduralChildPtr obj = createChild();
411 /// child->addProcedural(new procedural_subclass(parameters));
412 /// @endcode
413 ///
414 /// @note: RAY_ProceduralChildPtr's are thread safe. So, unlike the
415 /// deprecated addGeometry()/addProcedural() methods, multiple child objects
416 /// can be created in a threaded fashion within a render() method. @code
417 /// // Create geometry by loading geometry from disk.
418 /// RAY_ProceduralGeo geo = createGeometry();
419 /// geo->load("defgeo.bgeo");
420 ///
421 /// UTparallelFor(UT_BlockedRange<int>(0, 100),
422 /// [=](const UT_BlockedRange<int> &r)) {
423 /// for (auto it = r.begin(); it != r.end(); ++it) {
424 /// RAY_ProceduralChildPtr obj = createChild();
425 /// obj->addGeometry(geo);
426 /// }
427 /// }
428 /// @endcode
429 ///
430 /// See the HDK examples RAY_DemoMountain or RAY_DemoBox for concrete
431 /// examples.
433  : public UT_IntrusiveRefCounter<RAY_ProceduralChild>
434 {
435 public:
438 
439  /// Test whether the child is valid. This checks to see whether there's a
440  /// valid geometry, child procedural or a volume attached.
441  bool isValid() const;
442 
443  /// Bool operator on handle
444  SYS_SAFE_BOOL operator bool() const { return isValid(); }
445 
446  /// Return parent procedural
447  const RAY_Procedural *parent() const { return myParent; }
448 
449  /// Set the geometry for the child procedural. This is the preferred
450  /// interface for setting a child's geometry.
451  void addGeometry(const RAY_ROProceduralGeo &geo);
452 
453  /// When rendering geometry with packed prims or heightfields, mantra will
454  /// normally create special procedurals to handle each type of primitive
455  /// automatically. However, care must be taken when there are a mix of
456  /// special primitives and other primitives. For example, if there are
457  /// agent primitives, they are also considered as packed primitives, so the
458  /// packed procedural shouldn't double render them. The AutoProcType is
459  /// used internally to indicate what types of geometry should be allowed to
460  /// show up when creating procedurals. Note that this list may change in
461  /// future versions.
463  {
464  AUTOPROCEDURAL_ANY, // Create any special procedural types
465  AUTOPROCEDURAL_AGENT, // Create procedural for agents
466  AUTOPROCEDURAL_PACK, // Create procedural for packed
467  AUTOPROCEDURAL_HEIGHTFIELD, // Create procedural for heightfields
468  AUTOPROCEDURAL_NONE, // Just render geometry
469  };
470  /// Limit the types of procedurals which can be automatically created to
471  /// handle special primitive types. For example, if setting to
472  /// AUTOPROCEDURAL_PACK, no special agent primitives will be created (but
473  /// heightfields will).
474  void limitAutoProcedural(AutoProceduralType aproc);
475 
476  /// Set a child procedural. There are two ways to add a procedural.
477  ///
478  /// The first process is to call with an argc/argv and an optional bounding
479  /// box. This invokes the standard mantra process of creating a procedural
480  /// object. Using this interface will cause the initialize() method to be
481  /// called on the created procedural. The creation status is returned.
482  bool addProcedural(int argc, char *argv[],
483  const UT_BoundingBox *box=0);
484  /// The second process for adding a procedural is to add the procedural
485  /// directly. Using this process bypasses the standard mantra
486  /// initialization proces (i.e. the initialize() virtual will not be
487  /// called). This can be used to add procedural objects which aren't
488  /// registered with mantra (i.e. private classes).
489  void addProcedural(RAY_Procedural *proc);
490 
491  /// Add a volume primitive to the currently open volume object. Volume
492  /// objects are reference counted, so if you need to keep a reference
493  /// to the volume after calling addVolume(), use the incref()/decref()
494  /// interface to retain a reference. An easy way to do this is to own
495  /// a UT_IntrusivePtr<VGEO_Volume> object. If you do not own a reference,
496  /// it's possible the VGEO_Volume pointer will be invalid after this call.
497  void addVolume(VGEO_Volume *volume, fpreal shutter);
498 
499  /// Transform the currently open object (geometry, procedural, volume) at
500  /// the shutter time specified. The transform is a pre-transform that
501  /// acts on the parent procedural's existing transform. This interface
502  /// should be used to achieve the expected parenting behavior for
503  /// procedurals, in which the transform is an object space transform
504  /// inside the parent space.
505  void setPreTransform(const UT_Matrix4D &transform, fpreal shutter);
506 
507  /// Assign new style sheet node to the currently open object.
508  /// Procedurals often prune the style sheet of entries that no longer
509  /// apply to the geometry hierarchy.
510  void setStylerInfo(const RAY_StylerInfo &styler_info);
511 
512  /// Transform the currently open object (geometry, procedural, volume) at
513  /// the shutter time specified. The transform is a post-transform that
514  /// acts on the parent procedural's existing transform. This method is
515  /// preferred when you need to change the world transform from within
516  /// the procedural. In most cases, setPreTransform() is preferred
517  /// over setTransform().
518  void setTransform(const UT_Matrix4D &transform, fpreal shutter);
519 
520  /// @{
521  /// Change any setting on the object (geometry, procedural, volume)
522  /// - <tt>changeSetting(const char *name, const char *value)</tt> @n
523  /// Parses the string into arguments and changes the setting If you want
524  /// to change a setting to a single string value, it is better to call:
525  /// changeSettings(name, 1, &value);
526  /// - <tt>changeSetting(const char *name, int argc, char **argv)</tt>
527  /// - <tt>changeSetting(const char *name, int argc, int *argv)</tt>
528  /// - <tt>changeSetting(const char *name, int argc, fpreal *argv)</tt>
529  /// If the setting specified by "name" isn't found, the function will fail
530  /// (return false).
531  bool changeSetting(const char *name, const char *value,
532  const char *style = "object");
533  bool changeSetting(const char *name, int argc,
534  const char *const*argv,
535  const char *style = "object");
536  bool changeSetting(const char *name, int argc,
537  const UT_StringHolder *argv,
538  const char *style = "object");
539  bool changeSetting(const char *name, int argc, const int *argv,
540  const char *style = "object");
541  bool changeSetting(const char *name, int argc, const fpreal *argv,
542  const char *style = "object");
543  /// @}
544 
545  /// @{
546  /// It's possible to add new settings to a child object. These settings
547  /// can be accessed in shaders using the VEX renderstate() function.
548  ///
549  /// It is illegal to:
550  /// - redefine a built-in property
551  /// - change the type of an existing property
552  /// - change the tuple size of an existing property
553  ///
554  /// This is equivalent to the ray_declare command in IFDs.
555  bool declareSetting(const char *name, const char *value);
556  bool declareSetting(const char *name, int argc,
557  const char *const*argv);
558  bool declareSetting(const char *name, int argc, const int *argv);
559  bool declareSetting(const char *name, int argc, const fpreal *argv);
560  /// @}
561 
562  /// Print out the object's settings to stderr
563  void debugSettings(const char *style="object") const;
564 
565  /// Convenience method that declares settings for all attributes associated
566  /// with a given primitive, including the corresponding vertices, points,
567  /// and parent detail. This is primarily used for packed primitives.
568  /// The name of the setting will be the same as the attribute name prefixed
569  /// with the given prefix.
570  SYS_DEPRECATED_REPLACE(16.0, setPackedQuery)
571  void declarePrimitiveAttributeSettings(
572  const GEO_Primitive &prim,
573  const char *prefix);
574 
575  /// Calling @c setShopMaterialPath() will simulate adding the
576  /// "shop_materialpath" and optionally the "material_override" and
577  /// attributes on the geometry.
578  /// This must be called after the @c openGeometryObject() and
579  /// before the corresponding @c closeObject() calls.
580  /// The @c property_map string is used to map the Houdini parameter names
581  /// in the @c material_override string to mantra property names. Without
582  /// this map, properties will not be overridden properly.
583  bool setShopMaterialPath(const UT_StringHolder &shop_materialpath,
585  const UT_StringHolder &property_map=UT_StringHolder());
586 
587  /// Convenience method to check for the following attributes on a primitive
588  /// This method will check for the following attributes:
589  /// - shop_materialpath
590  /// - material_override
591  /// - property_override
592  /// - lightcategories
593  /// - lightmask
594  /// - categories
595  /// @{
596  void processPrimitiveMaterial(const GEO_Primitive *prim);
597 
598  /// This version takes a set of cached attributes for faster processing.
599  void processPrimitiveMaterial(
600  const GEO_Primitive *prim,
602  /// @}
603 
604  /// This function has no implementation in H16.0 and beyond.
605  /// Please use @c setPackedQuery();
606  SYS_DEPRECATED_REPLACE(16.0, setPackedQuery)
607  void declarePackedPrimRenderStateSetting(const GEO_Primitive &)
608  { return; }
609 
610  /// Set the packed query lookup for this procedural. This method takes
611  /// ownership of the query passed in.
612  void setPackedQuery(RAY_PackedQuery *q);
613 
614  /// @{
615  /// @private
616  /// Only called by RAY_Procedural
617  ray_ProcInstance *handle() { return myHandle; }
618  /// @}
619 
620 private:
621  RAY_Procedural *myParent;
622  ray_ProcInstance *myHandle;
623 };
624 
626 
627 /// @brief Procedural primitive for mantra (RAY)
628 ///
629 /// The RAY_Procedural class provides a means to create procedural geometry
630 /// during the rendering process.
632 {
633 public:
634  RAY_Procedural();
635  virtual ~RAY_Procedural();
636 
637  /// The class name is used in diagnostic messages. It can simply be the
638  /// name of the class, or alternatively, you can choose a unique name for
639  /// each procedural instance.
640  virtual const char *className() const = 0;
641 
642  /// The initialize method is called when the procedural is created.
643  /// Returning zero (failure) will abort the rendering of this procedural.
644  ///
645  /// The bounding box passed in is the user defined bounding box. If the
646  /// user didn't specify a bounding box, then the box will be NULL.
647  virtual int initialize(const UT_BoundingBox *box) = 0;
648 
649  /// The bounding box is the "object space" bounds of the procedural.
650  virtual void getBoundingBox(UT_BoundingBox &box) = 0;
651 
652  /// The render method is called when the procedural is required to either
653  /// generate geometry or split into more procedurals. Inside the
654  /// render() method you should make calls to open/add/close geometry or
655  /// sub-procedurals.
656  ///
657  /// The way that a procedural splits is critical to the performance of
658  /// mantra's ray tracer. For optimal performance, make sure that
659  /// sub-procedural bounding boxes overlap as little as possible - which
660  /// allows mantra to build more optimal trees for ray tracing.
661  ///
662  /// In multi-threaded renders, the render() method needs to be reentrant
663  /// - that is, the render() method on different RAY_Procedural objects
664  /// may be called simultaneously by different threads. This means that
665  /// you should design the code in your procedural such that global data
666  /// structures are protected by a thread lock (for example, a UT_Lock).
667  /// @note The render method may be called more than once during a render to
668  /// regenerate the geometry.
669  virtual void render() = 0;
670 
671  /// Called by IPR so that the procedural can determine whether it is
672  /// equal to the updated procedural. This is useful if the procedural
673  /// is dependent on object properties other than the its arguments.
674  virtual bool isEqual( const RAY_Procedural *) const { return true; }
675 
676 
677  /// This is a stop-gap measure to help improve LOD computation when the
678  /// procedural generates multiple instances of the same underlying
679  /// geometry. If this method returns false, the procedural will not be
680  /// processed when flattenprocedural is set.
681  virtual bool canGenerateInstancedGeometry() const { return false; }
682 
683  /// The getParm() methods evaluate parameters attached to the procedural.
684  /// The lookup may be performed by name or by token. Each parameter has a
685  /// unique token associated with it. The token lookup methods are more
686  /// efficient than the name lookups and should be almost as efficient as
687  /// accessing member data.
688 
689  /// Parameters to the procedural are stored as a list of RAY_ProceduralArg
690  /// objects. Each parameter is given a unique integer. This allows for
691  /// more efficient evaluation (avoiding comparing strings).
692  int lookupParmToken(const char *name) const;
693 
694  /// @{
695  /// Get the raw data pointers for a parameter by either name or value.
696  /// These functions return the size of the array in @c size, and will fail
697  /// if the type requested doesn't match the storage type.
698  /// @see import()
699  ///
700  const int64 *getIParm(int token, size_t &size) const;
701  const fpreal *getFParm(int token, size_t &size) const;
702  const UT_StringHolder *getSParm(int token, size_t &size) const;
703 
704  const int64 *getIParm(const char *name, size_t &size) const
705  {
706  auto &&id = lookupParmToken(name);
707  return id >= 0 ? getIParm(id, size) : nullptr;
708  }
709  const fpreal *getFParm(const char *name, size_t &size) const
710  {
711  auto &&id = lookupParmToken(name);
712  return id >= 0 ? getFParm(id, size) : nullptr;
713  }
714  const UT_StringHolder *getSParm(const char *name, size_t &size) const
715  {
716  auto &&id = lookupParmToken(name);
717  return id >= 0 ? getSParm(id, size) : nullptr;
718  }
719  /// @}
720 
721  /// @{
722  /// The import functions can be used as a general purpose query mechanism.
723  /// This will import values from:
724  /// - The argument list for the procedural
725  /// - The argument list for the object defining the procedural
726  /// - A global rendering setting.
727  /// Aside from a parameter name, the name could be "object:name",
728  /// "object:shadingquality", "camera:pixelaspect", or any of the other
729  /// setting defined in mantra.
730  bool import(const char *name, int32 *value, int vectorsize) const;
731  bool import(const char *name, int64 *value, int vectorsize) const;
732  bool import(const char *name, fpreal32 *value, int vectorsize) const;
733  bool import(const char *name, fpreal64 *value, int vectorsize) const;
734  SYS_DEPRECATED(16.0) bool import(const char *name, UT_String &result, int idx=0) const;
735  bool import(const char *name, UT_StringHolder &result, int idx=0) const;
736  /// @}
737 
738  /// @{
739  /// If you've opened a handle using queryObject(), queryLight() or
740  /// queryMaterial(), it's possible to query the settings of that object.
741  /// This makes it possible to query the parameters/values/settings of other
742  /// objects in the scene.
743  bool import(RAY_Handle handle, const char *name,
744  int32 *value, int vectorsize) const;
745  bool import(RAY_Handle handle, const char *name,
746  int64 *value, int vectorsize) const;
747  bool import(RAY_Handle handle, const char *name,
748  fpreal32 *value, int vectorsize) const;
749  bool import(RAY_Handle handle, const char *name,
750  fpreal64 *value, int vectorsize) const;
751  SYS_DEPRECATED(16.0) bool import(RAY_Handle handle, const char *name,
752  UT_String &result, int idx = 0) const;
753  bool import(RAY_Handle handle, const char *name,
754  UT_StringHolder &result, int idx = 0) const;
755 
756  /// Using a handle, import all settings on the object. By default this
757  /// includes settings at default values. However, by setting local_only
758  /// to true, it's possible to query only values from the handle that were
759  /// explicitly set on that object/light/material.
760  bool importAll(RAY_Handle handle, UT_Options &settings,
761  bool local_only = false) const;
762  /// @}
763 
764  /// Allocate geometry for this procedural
765  RAY_ProceduralGeo createGeometry() const
766  {
767  return RAY_ProceduralGeo(SYSconst_cast(this));
768  }
769 
770  /// When passed a GU_DetailHandle, mantra will run some internal
771  /// optimizations on the geometry. These include, but are not limited to:
772  /// - Optimizing layout of polygon soups
773  /// - Conversion of closed Bezier/NURBS curves
774  /// - Clearing DAGS on pasted surfaces
775  /// - Creation of the N attribute for smooth shading of polygons
776  /// However, when passed a GU_ConstDetailHandle, mantra assumes that it's
777  /// not allowed to alter the geometry and thus does not run these
778  /// optimizations. Some of these "optimizations" will change behaviour
779  /// (i.e. without optimization, closed Bezier/NURBS will not render). This
780  /// hook allows you to run the internal optimizations on the geometry
781  /// before passing the GU_ConstDetailHandle to mantra.
782  /// This is typically called: @code
783  /// int computeN;
784  /// if (!import("geometry:computeN", &computeN, 1))
785  /// computeN = 1;
786  /// optimizeGeometry(gdh, computeN != 0);
787  /// @endcode
788  static void optimizeGeometry(GU_Detail &gdp,
789  bool create_normals_if_needed);
790  static void optimizeGeometry(GU_DetailHandle &gdp,
791  bool create_normals_if_needed);
792 
793  /// @{
794  /// Allocate geometry given a GU_DetailHandle/GU_ConstDetailHandle
795  RAY_ROProceduralGeo createGeometry(GU_DetailHandle &gdh) const;
796  RAY_ROProceduralGeo createGeometry(GU_ConstDetailHandle &gdh) const;
797  /// @}
798 
799  /// @{
800  /// Allocate geometry given an array of GU_DetailHandle's, one for each
801  /// motion segment.
802  RAY_ROProceduralGeo createGeometry(const GU_DetailHandle *gdh,
803  int nsegments,
804  const fpreal *shutter_times=nullptr
805  ) const;
806  RAY_ROProceduralGeo createGeometry(const GU_ConstDetailHandle *gdh,
807  int nsegments,
808  const fpreal *shutter_times=nullptr
809  ) const;
810  /// @}
811 
812  /// @private: Forward declaration of handle map
813  class HandleMap;
814 
815  /// @{
816  /// @private: Access data internals
817  const RAY_ProceduralData *data() const { return myData; }
818  RAY_ProceduralData *data() { return myData; }
819  /// @}
820 
821 protected:
822  /// Query a geometry attribute segment for the given segment index.
823  /// For seg == 0, this method simply returns attr. For example: @code
824  /// const GA_Attribute *p1 = queryGeometrySegment(gdp->getP(), 1);
825  /// @endcode
826  const GA_Attribute *queryGeometrySegment(
827  const GA_Attribute *attr, int seg) const;
828 
829  /// Delete existing geometry segments and prepare the detail for
830  /// addition of new motion blur segments. This method can be useful if
831  /// you want to reuse geometry between renders but change the motion
832  /// blur. Do not call this method on geometry that has already been
833  /// added to the current render.
834  void clearGeometrySegments(GA_Attribute *attr);
835 
836  // The following methods are now obsolete. The settings/flags should be
837  // set by calling changeSetting()
838  // - setGeometryFlag()
839  // - copyGeometryFlags()
840 
841  /// This method allows you to compute the level of detail (LOD) of an
842  /// arbitrary bounding box. The LOD indicates the rough screen space
843  /// size of the bounding box, as an average projected length in
844  /// micropolygons.
845  ///
846  /// For example, if the box occupies 10 horizontal pixels and 20
847  /// vertical pixels, at a shading quality of 1.0 the LOD will be around
848  /// 15. At a shading quality of 2.0, the LOD would be around 30. If the
849  /// box surrounds the camera, the LOD will be clamped at a large
850  /// number.
851  fpreal getLevelOfDetail(const UT_BoundingBox &box) const;
852 
853  /// Create a child object. Each child can be operated upon in separate
854  /// threads. This allows a single procedural to create multiple child
855  /// objects in a threaded fashion.
857  {
858  return RAY_ProceduralChildPtr(
860  }
861 
862  /// When the render method is called, the procedural can add objects to
863  /// the scene. It is possible for the render() method to add multiple
864  /// objects.
865  ///
866  /// The process for adding a geometry object:
867  /// - open a geometry object (openGeometryObject())
868  /// - add geometry to the object (addGeometry())
869  /// - modify any settings (changeSetting())
870  /// - close the object (closeObject())
871  ///
872  /// The process for adding a new procedural is fairly similar:
873  /// - open a procedural object (openProcecuralObject())
874  /// - add procedural(s) to the object (addProcedural())
875  /// - modify any settings (changeSetting())
876  /// - close the object (closeObject())
877  ///
878  /// For a geometry object, deformation motion blur is done by adding
879  /// multiple geometry objects or by using appendGeometrySegment() to
880  /// append motion blur segments without allocating new GU_Detail
881  /// objects.
882  ///
883  /// If settings are not overridden by the procedural, they will be
884  /// inherited from the object defining the procedural.
885  ///
886  /// The shutter time should be between 0 and 1. Shutter values are
887  /// used to order the geometry objects added to the procedural, so that
888  /// the order of calls to addGeometry() will not affect the resulting
889  /// motion blur. Additionally, the distribution and offset of shutter
890  /// values are currently ignored. For example, shutters of (0, 0.9, 1)
891  /// and (0, 0.5, 1) will produce identical motion blur, as will
892  /// shutters of (0, 0.5) and (0.5, 1). The difference between the
893  /// largest and smallest shutter value will be used to scale the
894  /// positions of additional motion segments toward the initial
895  /// position. For example, if a shutter of (0, 0.4) is specified, with
896  /// P0 and P1 being points on the first and second segment, the
897  /// rendered motion end points will be P0 and P0+0.4*(P1-P0).
898  ///
899  /// The renderer assumes ownership of any geometry or procedurals written
900  /// to objects. Thus, the geometry and procedurals should not be free'd
901  /// by the user.
902  SYS_DEPRECATED(16.0) void openGeometryObject();
903 
904  /// Before adding the geometry, you can change @b geometry settings by
905  /// calling changeSettings(). For example, if you want to force
906  /// computation of N, you can call:
907  /// changeSetting("computeN", "true", "geometry");
908  /// This needs to be done @b BEFORE the addGeometry() call is made.
909  /// Object settings can be changed after the geometry has been added.
910  ///
911  /// @warning The @c addGeometry(GU_Detail *) method was originally
912  /// deprecated in H14.0, and you should seriously consider modernizing your
913  /// code. The current implementation looks like this and doesn't properly
914  /// handle motion blur (since the modern implementation stores motion
915  /// segments on the RAY_ProceduralGeo object): @code
916  /// void RAY_Procedural::addGeometry(GU_Detail *gdp, fpreal)
917  /// {
918  /// GU_DetailHandle gdh;
919  /// gdh.allocateAndSet(gdp, false); // User must delete gdp
920  /// myChild->addGeometry(createGeometry(gdh));
921  /// }
922  /// @endcode
923  SYS_DEPRECATED(16.0) void addGeometry(GU_Detail *gdp, fpreal shutter);
924 
925  /// Open a procedural object
926  SYS_DEPRECATED(16.0) int openProceduralObject();
927  /// Add a procedural to the opened procedural object. Use this method
928  /// when splitting a procedural into multiple sub-procedurals. This can
929  /// be useful when it would be prohibitive (memory-wise) to generate
930  /// geometry immediately, and allows mantra to delay generation of
931  /// geometry for the sub-procedural until its bounding box is hit.
932  ///
933  /// If you've allocated the procedural yourself, mantra assumes that the
934  /// procedural is fully initialized. The initialize() method will not be
935  /// called.
936  /// @see openProceduralObject()
937  SYS_DEPRECATED(16.0) void addProcedural(RAY_Procedural *proc);
938  /// Add a procedural the the opened procedural object. This method allows
939  /// you to create any registered procedural by passing @c argc and @c argv
940  /// arguments to initialize the procedural.
941  ///
942  /// When allocating a procedural with arguments, mantra will call the
943  /// initialize() method.
944  ///
945  /// @return 0 or 1 for failure/success
946  /// @see openProceduralObject()
947  SYS_DEPRECATED(16.0) int addProcedural(int argc, char *argv[],
948  const UT_BoundingBox *box=0);
949 
950  /// Open a volume object
951  SYS_DEPRECATED(16.0) void openVolumeObject();
952  /// Add a volume primitive to the currently open volume object. Volume
953  /// objects are reference counted, so if you need to keep a reference
954  /// to the volume after calling addVolume(), use the incref()/decref()
955  /// interface to retain a reference. An easy way to do this is to own
956  /// a UT_IntrusivePtr<VGEO_Volume> object .
957  SYS_DEPRECATED(16.0) void addVolume(VGEO_Volume *volume, fpreal shutter);
958 
959  /// Transform the currently open object (geometry, procedural, volume) at
960  /// the shutter time specified. The transform is a pre-transform that
961  /// acts on the parent procedural's existing transform. This interface
962  /// should be used to achieve the expected parenting behavior for
963  /// procedurals, in which the transform is an object space transform
964  /// inside the parent space.
965  SYS_DEPRECATED(16.0) void setPreTransform(const UT_Matrix4D &transform, fpreal shutter);
966 
967  /// Transform the currently open object (geometry, procedural, volume) at
968  /// the shutter time specified. The transform is a post-transform that
969  /// acts on the parent procedural's existing transform. This method is
970  /// preferred when you need to change the world transform from within
971  /// the procedural. In most cases, setPreTransform() is preferred
972  /// over setTransform().
973  SYS_DEPRECATED(16.0) void setTransform(const UT_Matrix4D &transform, fpreal shutter);
974 
975  /// Assign new style information to the currently open object.
976  /// Procedurals often prune the style sheet of entries that no longer
977  /// apply to the geometry hierarchy.
978  SYS_DEPRECATED(16.0) void setStylerInfo(const RAY_StylerInfo &styler_info);
979 
980  /// @{
981  /// Change any setting on the object (geometry, procedural, volume)
982  /// - <tt>changeSetting(const char *name, const char *value)</tt> @n
983  /// Parses the string into arguments and changes the setting If you want
984  /// to change a setting to a single string value, it is better to call:
985  /// changeSettings(name, 1, &value);
986  /// - <tt>changeSetting(const char *name, int argc, char **argv)</tt>
987  /// - <tt>changeSetting(const char *name, int argc, int *argv)</tt>
988  /// - <tt>changeSetting(const char *name, int argc, fpreal *argv)</tt>
989  /// If the setting specified by "name" isn't found, the function will fail
990  /// (return false).
991  SYS_DEPRECATED(16.0) bool changeSetting(const char *name, const char *value,
992  const char *style = "object")
993  {
994  if (!checkChild("changeSetting"))
995  return false;
996  return myChild->changeSetting(name, value, style);
997  }
998  SYS_DEPRECATED(16.0) bool changeSetting(const char *name, int argc,
999  const char *const*argv,
1000  const char *style = "object")
1001  {
1002  if (!checkChild("changeSetting"))
1003  return false;
1004  return myChild->changeSetting(name, argc, argv, style);
1005  }
1006  SYS_DEPRECATED(16.0) bool changeSetting(const char *name, int argc, const int *argv,
1007  const char *style = "object")
1008  {
1009  if (!checkChild("changeSetting"))
1010  return false;
1011  return myChild->changeSetting(name, argc, argv, style);
1012  }
1013  SYS_DEPRECATED(16.0) bool changeSetting(const char *name, int argc, const fpreal *argv,
1014  const char *style = "object")
1015  {
1016  if (!checkChild("changeSetting"))
1017  return false;
1018  return myChild->changeSetting(name, argc, argv, style);
1019  }
1020  /// @}
1021 
1022  /// @{
1023  /// Once an object is open for processing, it's possible to add settings
1024  /// specifically for that individual object. These properties can be
1025  /// accessed using the VEX renderstate() function.
1026  ///
1027  /// It is illegal to:
1028  /// - redefine a built-in property
1029  /// - change the type of an existing property
1030  /// - change the tuple size of an existing property
1031  ///
1032  /// This is equivalent to the ray_declare command in IFDs.
1033  SYS_DEPRECATED(16.0) bool declareSetting(const char *name, const char *value)
1034  {
1035  if (!checkChild("declareSetting"))
1036  return false;
1037  return myChild->declareSetting(name, value);
1038  }
1039  SYS_DEPRECATED(16.0) bool declareSetting(const char *name, int argc,
1040  const char *const*argv)
1041  {
1042  if (!checkChild("declareSetting"))
1043  return false;
1044  return myChild->declareSetting(name, argc, argv);
1045  }
1046  SYS_DEPRECATED(16.0) bool declareSetting(const char *name, int argc, const int *argv)
1047  {
1048  if (!checkChild("declareSetting"))
1049  return false;
1050  return myChild->declareSetting(name, argc, argv);
1051  }
1052  SYS_DEPRECATED(16.0) bool declareSetting(const char *name, int argc, const fpreal *argv)
1053  {
1054  if (!checkChild("declareSetting"))
1055  return false;
1056  return myChild->declareSetting(name, argc, argv);
1057  }
1058  /// @}
1059 
1060  /// Calling @c setShopMaterialPath() will simulate adding the
1061  /// "shop_materialpath" and optionally the "material_override" and
1062  /// attributes on the geometry.
1063  /// This must be called after the @c openGeometryObject() and
1064  /// before the corresponding @c closeObject() calls.
1065  /// The @c property_map string is used to map the Houdini parameter names
1066  /// in the @c material_override string to mantra property names. Without
1067  /// this map, properties will not be overridden properly.
1068  SYS_DEPRECATED(16.0) bool setShopMaterialPath(
1069  const char *shop_materialpath,
1070  const char *material_override=nullptr,
1071  const char *property_map=nullptr);
1072 
1073  /// Print out the object's settings to stderr
1074  void debugSettings(const char *style="object") const;
1075 
1076  /// Cache the set of attributes to be used by
1077  /// RAY_ProceduralChild::processPrimitiveMaterial()
1078  static void lookupPrimitiveMaterialAttributes(
1079  const GEO_Detail &geo,
1081 
1082  /// Convenience method to check for the following attributes on a primitive
1083  /// This method will check for the following attributes:
1084  /// - shop_materialpath
1085  /// - material_override
1086  /// - property_override
1087  /// - lightcategories
1088  /// - lightmask
1089  /// - categories
1090  SYS_DEPRECATED(16.0) void processPrimitiveMaterial(const GEO_Primitive *prim);
1091 
1092  /// The following methods are for backwards compatibility and are
1093  /// simply wrappers around changeSettings().
1094  /// @private
1095  SYS_DEPRECATED(16.0) void setSurface(const char *shader, fpreal=0);
1096  /// @private
1097  SYS_DEPRECATED(16.0) void setDisplacement(const char *shader, fpreal=0);
1098  /// @private
1099  SYS_DEPRECATED(16.0) void setDisplacementBounds(fpreal bounds);
1100  /// @private
1101  SYS_DEPRECATED(16.0) void setComputeN(int value);
1102 
1103  /// After all geometry, procedurals, volumes have been added and all the
1104  /// attributes have been set, the object can be closed.
1105  SYS_DEPRECATED(16.0) void closeObject();
1106 
1107  /// Load materials from an IFD stream. This is the code used by the file
1108  /// procedural to load material definitions. Using this to load data other
1109  /// than material statements will likely cause bad things to happen.
1110  bool parseMaterialIFD(const char *filename);
1111 
1112 protected:
1113  /// Query the number of transform samples for the world.
1114  int queryWorldTransformSamples() const;
1115 
1116  /// Get the world transform.
1117  UT_Matrix4D queryWorldTransform(int sample) const;
1118 
1119  /// It is possible to query information about other objects in the scene to
1120  /// some extent. This is done using the following query methods.
1121 
1122  /// Find a handle to a given object in the scene. Note that for objects
1123  /// which are rendered using point instances, the object handle will be a
1124  /// single instance rather than all of the instances.
1125  ///
1126  /// If a null pointer is passed in for the name, then the object refers to
1127  /// the object containing this procedural. The object handle does not need
1128  /// to be closed.
1129  ///
1130  /// Note that the initialize() method on procedurals is called as the IFD
1131  /// is parsed, so not all objects may be available at this time (depending
1132  /// on the order of objects in the IFD). The render() method is called
1133  /// after the entire scene has been parsed, so other objects should be
1134  /// available at that point. You should always get a valid handle when
1135  /// querying your own object (passing an empty string for the name) in the
1136  /// initialize method.
1137  RAY_ObjectHandle queryObject(const char *name) const;
1138 
1139  /// Find a handle to a given material in the scene. The material handle does
1140  /// not need to be closed.
1141  RAY_MaterialHandle queryMaterial(const char *name) const;
1142 
1143  /// Find a handle to a given light in the scene. The light handle does
1144  /// not need to be closed.
1145  RAY_LightHandle queryLight(const char *name) const;
1146 
1147  //
1148  // Given an object handle, it is now possible to query information about
1149  // the object.
1150  //
1151 
1152  /// Query the number of transform samples for a given query object
1153  /// @see queryObject()
1154  int queryTransformSamples(RAY_Handle handle) const;
1155  /// Get the transform associated with an object in the scene
1156  /// @see queryObject()
1157  const UT_Matrix4D &queryTransform(RAY_Handle handle, int sample) const;
1158 
1159  /// Get the shading transform associated with an object in the scene
1160  /// @see queryObject()
1161  const UT_Matrix4D &queryShaderTransform(RAY_ObjectHandle handle,
1162  int sample) const;
1163 
1164  /// Get the style sheet associated with an object in the scene.
1165  /// @see queryObject()
1166  const STY_Styler &queryStyler(RAY_ObjectHandle handle) const;
1167 
1168  /// Find out the name of the object queried. This is useful when trying to
1169  /// find out which object the procedural belongs to (i.e. queryObject(0))
1170  /// @see queryObject()
1171  const char *queryName(RAY_Handle handle) const;
1172 
1173  /// @private Use queryName instead.
1174  const char *queryObjectName(RAY_Handle handle) const;
1175 
1176  /// Get the name of the object which owns this procedural.
1177  const char *queryRootName() const;
1178 
1179  /// Find out how many geometry samples associated with the object.
1180  /// @see queryObject()
1181  int queryGeometrySamples(RAY_ObjectHandle handle) const;
1182 
1183  /// Access the geometry from another object (or the geometry passed to this
1184  /// object in the IFD). This method will return all segments of geometry
1185  /// for the handle's object.
1186  RAY_ROProceduralGeo queryGeometry(RAY_ObjectHandle handle) const;
1187 
1188  /// Find out shader information about the object. This information is only
1189  /// roughly accurate since the object shaders may be overridden by geometry
1190  /// attributes. The shader information returned is the object level
1191  /// shaders. The shaders returned are simply the setting bound at the
1192  /// instance level (including arguments).
1193  /// @private: Use import()
1194  SYS_DEPRECATED(16.0) void querySurfaceShader(RAY_ObjectHandle handle,
1195  UT_String &shader) const
1196  {
1197  UT_StringHolder tmp;
1198  if (!import(handle, "object:surface", tmp, 0))
1199  tmp.clear();
1200  shader = tmp;
1201  }
1202  /// @private: Use import()
1203  SYS_DEPRECATED(16.0) void queryDisplacementShader(RAY_ObjectHandle h,
1204  UT_String &shader) const
1205  {
1206  UT_StringHolder tmp;
1207  if (!import(h, "object:displace", tmp, 0))
1208  tmp.clear();
1209  shader = tmp;
1210  }
1211  /// @private: Use import()
1212  SYS_DEPRECATED(16.0) fpreal queryDisplacementBounds(RAY_ObjectHandle handle)
1213  {
1214  fpreal dbound;
1215  if (!import(handle, "object:displacebound",
1216  &dbound, 1))
1217  dbound = 0;
1218  return dbound;
1219  }
1220  /// @private: Use import()
1221  SYS_DEPRECATED(16.0) int queryPhantom(RAY_ObjectHandle handle)
1222  {
1223  int phantom;
1224  if (!import(handle, "object:phantom", &phantom, 1))
1225  phantom = 0;
1226  return phantom;
1227  }
1228  /// @private: Use import()
1229  SYS_DEPRECATED(16.0) int queryReflectBounce(RAY_ObjectHandle handle)
1230  {
1231  int bounce;
1232  if (!import(handle, "object:reflectbounce", &bounce, 1))
1233  bounce = 0;
1234  return bounce;
1235  }
1236  /// @private: Use import()
1237  SYS_DEPRECATED(16.0) int queryRefractBounce(RAY_ObjectHandle handle)
1238  {
1239  int bounce;
1240  if (!import(handle, "object:refractbounce", &bounce, 1))
1241  bounce = 0;
1242  return bounce;
1243  }
1244  /// @private: Use import()
1245  SYS_DEPRECATED(16.0)
1246  void queryReflectScope(RAY_ObjectHandle handle, UT_String &mask)
1247  {
1248  UT_StringHolder tmp;
1249  if (!import(handle, "object:reflectmask", tmp, 0))
1250  tmp.clear();
1251  mask = tmp;
1252  }
1253  /// @private: Use import()
1254  SYS_DEPRECATED(16.0)
1255  void queryRefractScope(RAY_ObjectHandle handle, UT_String &mask)
1256  {
1257  UT_StringHolder tmp;
1258  if (!import(handle, "object:refractmask", tmp, 0))
1259  tmp.clear();
1260  mask = tmp;
1261  }
1262 
1263 private:
1264  RAY_ROProceduralGeo makeGeometry(const GU_ConstDetailHandle *gdh,
1265  int nsegments,
1266  const fpreal *shutter_times,
1267  bool writeable) const;
1268 
1269  template <typename T>
1270  bool importType(RAY_Handle handle, const char *name,
1271  T &value, int vectorsize) const;
1272 
1273  bool checkChild(const char *method) const;
1274  void processChild(RAY_ProceduralChild *kid);
1275 
1276 private:
1277  RAY_ProceduralData *myData;
1278  RAY_ProceduralChildPtr myChild;
1279  friend class RAY_ProceduralChild;
1280 };
1281 
1282 #endif
RAY_ProceduralData * data()
const char * getValue() const
Return the default value.
bool operator==(const RAY_ROProceduralGeo &g) const
Definition of a geometry attribute.
Definition: GA_Attribute.h:190
GU_ConstDetailHandle handle(int segment=0) const
Access the GU_ConstDetailHandle for a given segment.
const GU_Detail * operator->() const
GT_API const UT_StringHolder filename
#define SYS_DEPRECATED(__V__)
void * RAY_LightHandle
A handle for lights. Can also be used anywhere a RAY_Handle is expected.
virtual bool isEqual(const RAY_Procedural *) const
SYS_VISIBILITY_EXPORT RAY_Procedural * allocProcedural(const char *name)
Mantra procedural primitives.
#define SYS_VISIBILITY_EXPORT
Class representing a child object of the current procedural.
SYS_FORCE_INLINE void clear()
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
const RAY_Procedural * parent() const
Return parent procedural.
SYS_FORCE_INLINE T * SYSconst_cast(const T *foo)
Definition: SYS_Types.h:127
GLboolean GLboolean g
Definition: glcorearb.h:1221
Reference counted geometry handle for procedurals.
Base class for volume primitives in mantra.
Definition: VGEO_Volume.h:41
RAY_ProceduralGeo & operator=(const RAY_ProceduralGeo &src)
virtual bool canGenerateInstancedGeometry() const
Procedural primitive for mantra (RAY)
GLint GLuint mask
Definition: glcorearb.h:123
RAY_ProceduralArg(const char *name=0, const char *type=0, const char *value=0)
const char * getType() const
Return the storage type of the argument.
bool operator!=(const RAY_ROProceduralGeo &g) const
GU_Detail & operator*() const
A reference counter base class for use with UT_IntrusivePtr.
const UT_StringHolder * getSParm(const char *name, size_t &size) const
const GU_Detail & operator*() const
IFDmantra you can see code vm_image_mplay_direction endcode When SOHO starts a render
Definition: HDK_Image.dox:266
const char * getName() const
Return the name of the argument.
GLsizeiptr size
Definition: glcorearb.h:663
#define SYS_DEPRECATED_REPLACE(__V__, __R__)
long long int64
Definition: SYS_Types.h:107
GLdouble n
Definition: glcorearb.h:2007
void * RAY_ObjectHandle
A handle for objects. Can also be used anywhere a RAY_Handle is expected.
const fpreal * getFParm(const char *name, size_t &size) const
GA_API const UT_StringHolder material_override
void * RAY_Handle
Aliases for different handle types.
#define SYS_SAFE_BOOL
Definition: SYS_Compiler.h:62
std::shared_ptr< T > UT_SharedPtr
Wrapper around std::shared_ptr.
Definition: UT_SharedPtr.h:28
double fpreal64
Definition: SYS_Types.h:192
SYS_FORCE_INLINE const UT_StringHolder & UTmakeUnsafeRef(const UT_StringRef &ref)
Convert a UT_StringRef into a UT_StringHolder that is a shallow reference.
int method
Definition: png.h:1924
GLboolean * data
Definition: glcorearb.h:130
OPENVDB_API void initialize()
Global registration of basic types.
Definition: logging.h:318
GLuint const GLchar * name
Definition: glcorearb.h:785
int int32
Definition: SYS_Types.h:35
const int64 * getIParm(const char *name, size_t &size) const
RAY_ProceduralChildPtr createChild() const
GA_API const UT_StringHolder transform
RAY_ProceduralGeo(const RAY_ProceduralGeo &src)
Copy c-tor.
Parameter definition for arguments to RAY_Procedural.
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2001
GLuint shader
Definition: glcorearb.h:784
GLsizei const GLfloat * value
Definition: glcorearb.h:823
double fpreal
Definition: SYS_Types.h:270
A map of string to various well defined value types.
Definition: UT_Options.h:42
typedef int
Definition: png.h:1175
#define RAY_API
Definition: RAY_API.h:12
RAY_ROProceduralGeo & operator=(const RAY_ROProceduralGeo &src)
GU_Detail * operator->() const
SYS_VISIBILITY_EXPORT void registerProcedural(RAY_ProceduralFactory *factory)
Modern interface to register procedurals.
Definition: RAY_DemoBox.C:56
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
UT_IntrusivePtr< RAY_ProceduralChild > RAY_ProceduralChildPtr
SYS_VISIBILITY_EXPORT const RAY_ProceduralArg * getProceduralArgs(const char *n)
Dynamic load entry point to query arguments for a procedural.
const GU_Detail * get(int segment=0) const
#define const
Definition: zconf.h:214
Read-only handle for string attribute data.
Definition: GA_Handle.h:756
UT_SharedPtr< Data > myData
float fpreal32
Definition: SYS_Types.h:191
GA_API const UT_StringHolder shop_materialpath
RAY_ProceduralGeo()
Default constructor.
void * RAY_MaterialHandle
A handle for materials. Can also be used anywhere a RAY_Handle is expected.
GLenum src
Definition: glcorearb.h:1792