HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GU_PackedImpl.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: GU_PackedImpl.h (GU Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GU_PackedImpl__
12 #define __GU_PackedImpl__
13 
14 #include "GU_API.h"
15 #include "GU_Detail.h"
16 #include "GU_DetailHandle.h"
17 #include <GEO/GEO_PackedTypes.h>
18 #include <GA/GA_SharedDataHandle.h>
19 #include <GA/GA_Types.h>
20 #include <UT/UT_IntrusivePtr.h>
21 
22 class GU_PackedFactory;
23 class GU_PrimPacked;
24 class GU_PackedContext;
25 class GEO_PackedNameMap;
27 class GA_GeometryIndex;
28 class GA_LoadMap;
29 class GA_Primitive;
30 class GA_SaveMap;
31 class STY_Styler;
32 class STY_StylerGroup;
33 class UT_MemoryCounter;
34 class UT_Options;
35 
36 /// This class is used by the deferred load primitives to provide methods to
37 /// handle the deferred geometry.
38 ///
39 /// <b>Load/save of shared primitive data</b>
40 /// If multiple instances of the packed primitive share data, it's possible to
41 /// save this data just once (instead of per primitive).
42 ///
43 /// There are two parts to saving shared data. Saving the actual data, but
44 /// also saving a "key" used to resolve the shared data. The shared data
45 /// itself is saved using @c saveSharedData(). In addition, the "key"
46 /// associated with the shared data is saved per-primitive instance.
47 /// During loading, the "key" is used to resolve the shared data.
48 ///
49 /// When generating a key, the key must be unique within all shared data blocks
50 /// for a single geometry. A simple way to do this would be to use the address
51 /// of the shared data item. More complicated ways might include using a GUID,
52 /// etc. For example, with a @c UT_SharedPtr<GU_Detail>, you might have
53 /// generate a key using: @code
54 /// @code
55 /// UT_StringHolder makeKey(const UT_SharedPtr<GU_Detail> &detail) {
56 /// UT_WorkBuffer key;
57 /// key.sprintf("sharedgeo:%p", detail.get());
58 /// return UT_StringHolder(key);
59 /// }
60 /// @endcode
61 ///
62 /// The @c saveSharedData() method writes a single JSON object to the save
63 /// stream. During loading, the loader expects to load an array containing
64 /// four items. @code
65 /// [
66 /// "string Primitive_Name",
67 /// "string Shared_Data_Type",
68 /// "string Shared_Data_Identifier",
69 /// shared_data
70 /// ]
71 /// @endcode
72 /// The @c Primitive_Name ensures that shared data resolution is tied to the
73 /// specific primitive type. Kind of like a namespace.
74 ///
75 /// The @c Shared_Data_Type is an identifier to allow primitives to store
76 /// multiple types of shared data. For example, if you have a material
77 /// definition and a geometry definition, these can be stored as separate
78 /// shared blocks rather than creating separate shared blocks for each pair.
79 ///
80 /// The @c Shared_Data_Identifier is a unique identifier used to specify a
81 /// particular instance of a shared data block. This is the "key" that can be
82 /// used to resolve the data at load time. See the @c makeKey() example above.
83 ///
84 /// Example code might be something like @code
85 /// UT_StringHolder key = makeKey(mySharedObject);
86 /// if (save_map.hasSavedSharedData(key))
87 /// return true; // Another primitive has saved the shared data
88 /// map.setSavedSharedData(key);
89 /// json.jsonStringToken(getFactory()->name());
90 /// // Used for seeking (see section on loading)
91 /// geo_index->addEntry(key, json.getNumBytesWritten());
92 ///
93 /// json.beginArray();
94 /// json.jsonString("Shared_Data_Type");
95 /// json.jsonString(key);
96 /// json.jsonBeginMap();
97 /// ...
98 /// json.jsonEndMap();
99 ///
100 /// // Provide a seek point used for loading
101 /// UT_WorkBuffer endkey(key);
102 /// endkey.append(GA_SAVEMAP_END_TOKEN);
103 /// geo_index->addEntry(endkey.buffer(), w.getNumBytesWritten());
104 /// ok = ok && w.jsonEndArray();
105 /// @endcode
106 ///
107 /// The @c save() method needs to store the key so the shared data can be
108 /// resolved at load time. The identifier you use in the save method doesn't
109 /// have to be the @c "Shared_Data_Type" string, but it does have to match the
110 /// value in the load method. For example: @code
111 /// PrimClass::save(UT_Options &options, const GA_SaveMap &map) const {
112 /// options.setOptionS("shareddata", makeKey());
113 /// }
114 /// @endcode
115 ///
116 /// Shared data loading may be deferred until the shared data is actually
117 /// required. This is done using a "handle" to the shared data (@c
118 /// GA_SharedDataHandlePtr). During the load() method, you can ask for a
119 /// handle to any shared data. @code
120 /// bool load(const UT_Options &options, const GA_LoadMap &loadmap) {
121 /// UT_StringHolder key;
122 /// if (import(options, "shareddata", key)) {
123 /// mySharedHandle = loadmap.needSharedData(key,
124 /// getFactory()->name(), nullptr);
125 /// }
126 /// @endcode
127 ///
128 /// When loading primitives, the shared data is not actually available until
129 /// later in the loading process. The primitive itself needs to hold a
130 /// reference to the shared data handle so the shared data can be resolved at a
131 /// later time.
132 ///
133 /// Resolving the handle is done by asking the handle to resolve the shared
134 /// data, and then extracting information from a sub-class of a
135 /// @c GA_SharedLoadData object. If the shared data is never resolved, it's
136 /// possible the @c GA_SharedLoadData may never read the data from the file
137 /// (if the geometry format supports seeking, the loader may be able to use the
138 /// offsets stored in the @c geo_index during writing). The code to
139 /// resolve the data might look like: @code
140 /// if (mySharedHandle)
141 /// {
142 /// const GA_SharedLoadData *item;
143 /// const CustomSharedLoadData *data;
144 /// item = mySharedHandle->resolveSharedData(packed_context);
145 /// data = dynamic_cast<const CustomSharedLoadData *>(item);
146 /// if (!data)
147 /// return false; // This really shouldn't ever happen
148 /// copySharedData(data);
149 ///
150 /// /// Clear the reference to the @c GA_SharedDataHandlePtr. When all
151 /// /// references to the shared handle are cleared, the handle will be
152 /// /// deleted.
153 /// mySharedHandle.clear();
154 /// }
155 /// @endcode
156 ///
157 /// The last piece to loading, is the actual loading of the shared data block.
158 /// Since shared data blocks must be able to be loaded without a primitive
159 /// object, the loading is handled by the @c GU_PackedFactory subclass (the @c
160 /// loadSharedData()) method. This method should create the sub-class of the
161 /// @c GA_SharedLoadData object that's used when resolving shared data. For
162 /// example @code
163 /// class CustomFactory : public GU_PackedFactory
164 /// {
165 /// // The type matches the "Shared_Data_Type" described above
166 /// // The key matches the "Shared_Data_Identifier" described above
167 /// virtual GA_SharedLoadData *loadSharedData(UT_JSONParser &p,
168 /// const char *type,
169 /// const char *key,
170 /// bool is_delayed_load) const
171 /// {
172 /// CustomSharedLoadData *data = new CustomSharedLoadData();
173 ///
174 /// // This just load the data. For example the JSON Map saved in
175 /// // the example above (not the entire array of shared data).
176 /// if (!data->load(p))
177 /// {
178 /// delete data;
179 /// return nullptr; // Unable to load the shared data
180 /// }
181 /// return data;
182 /// }
183 /// };
184 /// @endcode
185 class GU_API GU_PackedImpl : public UT_IntrusiveRefCounter<GU_PackedImpl>
186 {
187 public:
188  /// @{
189  /// Typedefs for intrinsic evaluation
190  typedef fpreal (GU_PackedImpl::*FloatGetter)(const GU_PrimPacked *) const;
191  typedef void (GU_PackedImpl::*FloatSetter)(const GU_PrimPacked *, fpreal);
192  typedef GA_Size (GU_PackedImpl::*IntGetter)(const GU_PrimPacked *) const;
193  typedef void (GU_PackedImpl::*IntSetter)(GU_PrimPacked *, GA_Size);
194  typedef bool (GU_PackedImpl::*BoolGetter)(const GU_PrimPacked *) const;
195  typedef void (GU_PackedImpl::*BoolSetter)(GU_PrimPacked *, bool);
196  typedef const char *(GU_PackedImpl::*StringGetter)(const GU_PrimPacked *) const;
197  typedef void (GU_PackedImpl::*StringSetter)(GU_PrimPacked *, const char *);
198  typedef UT_OptionsHolder (GU_PackedImpl::*DictGetter)(const GU_PrimPacked *) const;
199  typedef void (GU_PackedImpl::*DictSetter)(GU_PrimPacked *, const UT_OptionsHolder &);
200  typedef std::string (GU_PackedImpl::*StdStringGetter)(const GU_PrimPacked *) const;
201  typedef void (GU_PackedImpl::*StdStringSetter)(GU_PrimPacked *, const std::string &);
202  typedef UT_StringHolder (GU_PackedImpl::*StringHolderGetter)(const GU_PrimPacked *) const;
203  typedef void (GU_PackedImpl::*StringHolderSetter)(GU_PrimPacked *, const UT_StringHolder &);
204 
205  typedef fpreal (GU_PackedImpl::*FloatTupleGetter)(const GU_PrimPacked *, exint) const;
206  typedef void (GU_PackedImpl::*FloatTupleSetter)(GU_PrimPacked *, exint, fpreal);
207  typedef GA_Size (GU_PackedImpl::*IntTupleGetter)(const GU_PrimPacked *, exint) const;
208  typedef void (GU_PackedImpl::*IntTupleSetter)(GU_PrimPacked *, exint,GA_Size);
209  typedef bool (GU_PackedImpl::*BoolTupleGetter)(const GU_PrimPacked *, exint) const;
210  typedef void (GU_PackedImpl::*BoolTupleSetter)(GU_PrimPacked *, exint,bool);
211  typedef const char *(GU_PackedImpl::*StringTupleGetter)(const GU_PrimPacked *, exint) const;
212  typedef void (GU_PackedImpl::*StringTupleSetter)(GU_PrimPacked *, exint,const char *);
213  typedef UT_OptionsHolder (GU_PackedImpl::*DictTupleGetter)(const GU_PrimPacked *, exint) const;
214  typedef void (GU_PackedImpl::*DictTupleSetter)(GU_PrimPacked *, exint,const UT_OptionsHolder &);
215  typedef const std::string &(GU_PackedImpl::*StdStringTupleGetter)(const GU_PrimPacked *, exint) const;
216  typedef void (GU_PackedImpl::*StdStringTupleSetter)(GU_PrimPacked *, exint,const std::string &);
218  typedef void (GU_PackedImpl::*StringHolderTupleSetter)(GU_PrimPacked *, exint,const UT_StringHolder &);
219 
220  typedef void (GU_PackedImpl::*F32VectorGetter)(const GU_PrimPacked *, fpreal32*, exint) const;
221  typedef void (GU_PackedImpl::*F32VectorSetter)(GU_PrimPacked *, const fpreal32*, exint);
222  typedef void (GU_PackedImpl::*F64VectorGetter)(const GU_PrimPacked *, fpreal64*, exint) const;
223  typedef void (GU_PackedImpl::*F64VectorSetter)(GU_PrimPacked *, const fpreal64*, exint);
224  typedef void (GU_PackedImpl::*I32VectorGetter)(const GU_PrimPacked *, int32 *, exint) const;
225  typedef void (GU_PackedImpl::*I32VectorSetter)(GU_PrimPacked *, const int32 *, exint);
226  typedef void (GU_PackedImpl::*I64VectorGetter)(const GU_PrimPacked *, int64 *, exint) const;
227  typedef void (GU_PackedImpl::*I64VectorSetter)(GU_PrimPacked *, const int64 *, exint);
228  typedef void (GU_PackedImpl::*BVectorGetter)(const GU_PrimPacked *, bool *, exint) const;
229  typedef void (GU_PackedImpl::*BVectorSetter)(GU_PrimPacked *, const bool *, exint);
230 
231  typedef void (GU_PackedImpl::*StringArrayGetter)(const GU_PrimPacked *, UT_StringArray &) const;
232  typedef void (GU_PackedImpl::*StringArraySetter)(GU_PrimPacked *, const UT_StringArray &);
233  typedef void (GU_PackedImpl::*DictArrayGetter)(const GU_PrimPacked *, UT_Array<UT_OptionsHolder> &) const;
234  typedef void (GU_PackedImpl::*DictArraySetter)(GU_PrimPacked *, const UT_Array<UT_OptionsHolder> &);
235  /// @}
236 
237  GU_PackedImpl();
238  virtual ~GU_PackedImpl();
239 
240  // Default copying works, UT_IntrusiveRefCounter's copy operators does NOT
241  // copy the reference counter.
242  GU_PackedImpl(const GU_PackedImpl &src) = default;
243  GU_PackedImpl &operator=(const GU_PackedImpl &src) = default;
244 
245  /// Get the factory associated with this procedural
246  virtual GU_PackedFactory *getFactory() const = 0;
247 
248  /// Create a copy of this resolver
249  virtual GU_PackedImpl *copy() const = 0;
250 
251  /// Test whether the deferred load primitive data is valid
252  virtual bool isValid() const = 0;
253 
254  /// The clearData() method is called when the primitives are stashed during
255  /// the cook of a SOP. See GA_Primitive::stashed(). This gives the
256  /// primitive to optionally clear some data during the stashing process.
257  virtual void clearData() = 0;
258 
259  /// Give a UT_Options of load data, create resolver data for the primitive
260  virtual bool load(GU_PrimPacked *prim, const UT_Options &options,
261  const GA_LoadMap &map) = 0;
262 
263  /// Determines if we support loading from a JSONParser directly
264  /// rather than just from a UT_Options. Loading from JSON is typically
265  /// more efficient than loading from a UT_Options since the file loader
266  /// doesn't have to convert the JSON map to a UT_Options.
267  virtual bool supportsJSONLoad() const { return false; }
268 
269  /// The JSONValueMap represents a UT_Options. The options may be saved in
270  /// compact form, but also may be saved in expanded form. If in expanded
271  /// form, the value for each key's value is a UT_JSONValueMap storing the
272  /// value in the "value" key. It's highly suggested you just use the
273  /// protected import() convenience method which deals with this for you.
274  virtual bool loadFromJSON(
275  GU_PrimPacked *prim,
276  const UT_JSONValueMap &options,
277  const GA_LoadMap &map)
278  { UT_ASSERT(!"JSON direct loading not supported"); return false; }
279 
280  /// Depending on the update, the procedural should call one of:
281  /// - prim->transformDirty()
282  /// - prim->attributeDirty()
283  /// - prim->topologyDirty()
284  virtual void update(GU_PrimPacked *prim, const UT_Options &options) = 0;
285 
286  /// Save shared data objects to the JSON stream. This is called directly
287  /// from GA_Primitive::saveSharedLoadData(). Please see GU_PackedFactory
288  /// for the interface to create the shared data loader.
289  virtual bool saveSharedData(UT_JSONWriter &w,
290  GA_SaveMap &map,
291  GA_GeometryIndex *geo_index) const;
292 
293  /// This method is called to resolve the shared data on load. The @c
294  /// load_data_type given is the integer passed when you called
295  /// "GA_LoadMap::needSharedData()" -- which was done in load().
296  virtual bool loadSharedData(int load_data_type,
297  const GA_SharedLoadData *item);
298 
299  /// Copy the resolver data into the UT_Options for saving
300  virtual bool save(UT_Options &options,
301  const GA_SaveMap &map) const = 0;
302 
303  /// Handle unknown token/value pairs when loading the primitive. By
304  /// default, this adds a warning and skips the next object. Return false
305  /// if there was a critical error.
306  virtual bool loadUnknownToken(const char *token, UT_JSONParser &p,
307  const GA_LoadMap &map);
308 
309  /// Get the bounding box for the geometry (not including transforms)
310  virtual bool getBounds(UT_BoundingBox &box) const = 0;
311 
312  /// Get the bounding box for the geometry (not including transforms),
313  /// using myBoxCache if it's valid, and otherwise caching the result
314  /// from getBounds(box) in myBoxCache.
315  /// NOTE: If you just want to check the cached bounds, use boxCache(), instead.
316  bool getBoundsCached(UT_BoundingBox &box) const;
317 
318  /// Get the bounding box for the visible geometry (not including transforms)
319  /// By default, merely calls getBounds()
320  virtual bool getVisibleBounds(UT_BoundingBox &box) const
321  { return getBounds(box); }
322 
323  /// Get the visible bounding box for the geometry (not including
324  /// transforms), using myVisibleBoxCache if it's valid, and otherwise
325  /// caching the result from getVisibleBounds(box) in myVisibleBoxCache.
326  /// NOTE: If you just want to check the cached bounds, use
327  /// visibleBoxCache(), instead.
328  bool getVisibleBoundsCached(UT_BoundingBox &box) const;
329 
330  /// Get the rendering bounding box for the geometry (not including
331  /// transforms). For curve and point geometry, this needs to include any
332  /// "width" attributes.
333  virtual bool getRenderingBounds(UT_BoundingBox &box) const = 0;
334 
335  /// When rendering with velocity blur, the renderer needs to know the
336  /// bounds on velocity to accurately compute the bounding box.
337  virtual void getVelocityRange(UT_Vector3 &min,
338  UT_Vector3 &max) const = 0;
339 
340  /// When rendering points or curves, the renderer needs to know the bounds
341  /// on the width attribute to accurately compute the bounding box.
342  virtual void getWidthRange(fpreal &wmin, fpreal &wmax) const = 0;
343 
344  /// Return the primitive's "description". This should be a unique
345  /// identifier for the primitive and defaults to:
346  /// <tt>"%s.%d" % (getFactory()->name(), getPrim()->getNum()) </tt>
347  virtual void getPrimitiveName(const GU_PrimPacked *prim, UT_WorkBuffer &wbuf) const;
348 
349  /// Return the number of Packed Prims contained in this Packed Prim.
350  /// Returns nullopt if the packedPrim does not support a reliable or fast way to
351  /// get the number of sub-packed prims
352  UT_Optional<exint> getNumPackedPrims(const GU_PrimPacked *prim) const;
353 
354  /// @{
355  /// Intrinsic functions
356  int64 intrinsic3Tuple(const GU_PrimPacked *prim) const { return 3; }
357  int64 intrinsic6Tuple(const GU_PrimPacked *prim) const { return 6; }
358  int64 intrinsic9Tuple(const GU_PrimPacked *prim) const { return 9; }
359  int64 intrinsic16Tuple(const GU_PrimPacked *prim) const { return 16; }
360  std::string intrinsicPrimitiveName(const GU_PrimPacked *prim) const;
361  const char *intrinsicFactoryName(const GU_PrimPacked *prim) const;
362  const char *intrinsicFactoryLabel(const GU_PrimPacked *prim) const;
363  void intrinsicPackedBox(const GU_PrimPacked *prim, fpreal64 *vals, exint sz) const;
364  void intrinsicPackedRenderBox(const GU_PrimPacked *prim, fpreal64 *vals, exint sz) const;
365  void intrinsicPivot(const GU_PrimPacked *prim, fpreal64 *vals, exint sz) const;
366  void intrinsicSetPivot(GU_PrimPacked *prim, const fpreal64 *vals, exint sz);
367  void intrinsicPrimTransform(const GU_PrimPacked *prim, fpreal64 *vals, exint sz) const;
368  void intrinsicSetPrimTransform(GU_PrimPacked *prim, const fpreal64 *v, exint sz);
369  void intrinsicPackedTransform(const GU_PrimPacked *prim, fpreal64 *v, exint sz) const;
370  void intrinsicFullTransform(const GU_PrimPacked *prim, fpreal64 *v, exint sz) const;
371  const char *intrinsicViewportLOD(const GU_PrimPacked *prim) const;
372  void intrinsicSetViewportLOD(GU_PrimPacked *prim, const char *lod);
373  /// @}
374 
375  /// Some procedurals have an "intrinsic" transform. These are combined
376  /// with the local transform on the geometry primitive.
377  ///
378  /// The default method returns false and leaves the transform unchanged.
379  virtual bool getLocalTransform(UT_Matrix4D &m) const;
380 
381  /// Unpack the procedural into a GU_Detail. By default, this calls
382  /// getGTFull() and converts the GT geometry to a GU_Detail.
383  virtual bool unpackWithContext(
384  GU_Detail &destgdp,
385  GU_PackedContext &context,
386  const GU_PrimPacked *prim) const
387  { return unpack(destgdp, prim); }
388 
389  /// Unpacks this into destgdp, transforming the new geometry by
390  /// the transform of prim. If prim is nullptr, no transform will be applied.
391  bool unpack(GU_Detail &destgdp, const GU_PrimPacked *prim) const;
392 
393  /// Unpacks this into destgdp, transforming the new geometry by
394  /// the given transform. If transform is nullptr, no transform will be applied.
395  virtual bool unpack(GU_Detail &destgdp, const UT_Matrix4D *transform) const = 0;
396 
397 protected:
398  /// Most implementations don't require the primitive once they have the transform,
399  /// so the default implementation just calls the signature without the primitive.
400  /// This function may be removed in the future, since it was only added
401  /// because Alembic packed primitives copy primitive group membership from
402  /// the original packed prim, which may not be advisable in all cases.
403  virtual bool unpackWithPrim(
404  GU_Detail &destgdp,
405  const UT_Matrix4D *transform,
406  const GU_PrimPacked *prim) const
407  {
408  return unpack(destgdp, transform);
409  }
410 public:
411 
412  /// Unpack into a GU_Detail, and generate stylers for each primitive.
413  /// By default calls unpack, prunes the supplied styler for each generated
414  /// primitive, and adds the styles in the material_stylesheet attribute
415  /// for each primitive.
416  virtual bool unpackWithStyler(
417  GU_Detail &destgdp,
418  STY_StylerGroup &prim_styler_group,
419  const STY_Styler &parent_styler,
420  const GU_PrimPacked *prim) const;
421 
422  /// Forces a load of all shared data the primitive has access to
423  /// this should leave no data on disk
424  virtual void forceLoad() const {}
425 
426  /// Checks if this packed implementation has loaded its shared data
427  /// Default implementation returns true.
428  virtual bool isLoaded() const { return true; }
429 
430  /// Unpack the procedural into a GU_Detail using polygons instead of
431  /// polygon soups. The default method just unpacks, then converts polygon
432  /// soups to polygons.
433  virtual bool unpackUsingPolygons(
434  GU_Detail &destgdp,
435  const GU_PrimPacked *prim) const;
436 
437  /// Get a reference to a const GU_Detail for the packed geometry. Not all
438  /// implementations need to provide this. If this isn't implemented, the
439  /// method should return an empty detail handle. This is meant as a quick
440  /// short-cut instead of having to call unpack() which performs a full
441  /// merge.
442  virtual GU_ConstDetailHandle getPackedDetail(GU_PackedContext *context = 0) const;
443 
444  /// If @c pointInstanceTransform() returns false, @c getFullTransform4()
445  /// method will only use the point position as a translate. If true, @c
446  /// getFullTransform4() will perform the standard "houdini instancing"
447  /// (i.e. use the "N", "v", "rot" and other attributes to compute an
448  /// orientation and translation).
449  ///
450  /// The default method returns false, so only "P" is used to apply
451  /// translates.
453  { return myPointInstanceTransform; }
455  { return pointInstanceTransform(); }
456 
457  /// Set whether point instancing should be used.
458  void setPointInstanceTransform(GU_PrimPacked *prim, bool b);
459 
460  /// Convenience method to compute the velocity bounds for a given geometry.
461  /// The geometry may be a NULL pointer.
462  static bool computeVelocityRange(const GU_Detail *gdp,
463  UT_Vector3 &vmin, UT_Vector3 &vmax);
464  static bool computeWidthRange(const GU_Detail *gdp,
465  fpreal &wmin, fpreal &wmax);
466 
467  /// Report memory usage (includes all shared memory)
468  virtual int64 getMemoryUsage(bool inclusive) const = 0;
469 
470  /// Count memory usage using a UT_MemoryCounter in order to count
471  /// shared memory correctly.
472  /// NOTE: There's nothing outside of sizeof(*this) to count in the
473  /// base class, so it can be pure virtual.
474  virtual void countMemory(UT_MemoryCounter &counter, bool inclusive) const = 0;
475 
476  /// Determines if we should save the bounding box to the metadata, this
477  /// makes sense for fully embedded primitives, but if the primitive
478  /// can be swapped out without the owner knowing, it should be
479  /// avoided.
480  virtual bool saveCachedBBox() const { return false; }
481 
482  /// Default implementation does nothing and asserts, since
483  /// only relevant subclasses (GABC_PackedImpl) should be
484  /// getting a faceset attribute string.
485  virtual void setFacesetAttribute(const UT_StringHolder &s)
486  {
487  UT_ASSERT_MSG(0, "Subclass should implement setFacesetAttribute, when applicable.");
488  }
489 
490  /// Default implementation just returns the default value of
491  /// GEO_PrimPacked::theDefaultFacesetAttribute
492  virtual const UT_StringHolder &facesetAttribute() const;
493 
494  /// Default implementation does nothing and asserts, since
495  /// only relevant subclasses (GABC_PackedImpl) should be
496  /// getting an attribute name map.
498  {
499  UT_ASSERT_MSG(0, "Subclass should implement setAttributeNameMap, when applicable.");
500  }
501 
502  /// Default implementation just returns the default
503  /// null name map.
504  virtual const GEO_PackedNameMapPtr &attributeNameMap() const
505  {
506  return theNullPackedNameMapPtr;
507  }
508 
509  /// Default implementation does nothing and asserts, since
510  /// only relevant subclasses should be getting shared name map data.
512  {
513  UT_ASSERT_MSG(0, "Subclass should implement setSharedNameMapData, when applicable.");
514  }
515 
517  bool isShared() const
518  {
519  return (use_count() > 1);
520  }
521 
524  {
525  if (isShared())
526  return copy();
527  return this;
528  }
529 
530 protected:
532 
533  /// The box cache can be used by the implementation to store the
534  /// untransformed bounding box. It should @b not store the transformed
535  /// box.
536  const UT_BoundingBox &boxCache() const { return myBoxCache; }
537 
539  {
540  myBoxCache = b;
541  myVisibleBoxCache.makeInvalid();
542  }
543  template<typename T>
544  void setBoxCache(const T b[6])
545  {
546  myBoxCache.setSerialized(b);
547  myVisibleBoxCache.makeInvalid();
548  }
550  {
551  myBoxCache.makeInvalid();
552  myVisibleBoxCache.makeInvalid();
553  }
554 
555  /// For all the groups that this primitive belongs to, create groups on the
556  /// destination detail and place all primitives in the given range into the
557  /// groups. If the group already exists on the destination detail, then
558  /// nothing is done (unless @c force is set).
559  static void copyPrimitiveGroups(GU_Detail &dest,
560  const GU_Detail &src,
561  GA_Offset src_offset,
562  bool force=false);
563 
564  /// Unpack the source detail into the destination detail. The source
565  /// detail *may* be modified (attributes may be promoted)
566  ///
567  /// The @c src detail is not deleted by unpackToDetail.
568  bool unpackToDetail(GU_Detail &destgdp,
569  GU_Detail *src,
570  const UT_Matrix4D *transform) const;
571  /// Unpack the source detail into the destination detail. The source
572  /// detail is const and will not be modified. However, this may be more
573  /// expensive than the non-const version.
574  bool unpackToDetail(GU_Detail &destgdp,
575  const GU_Detail *src,
576  const UT_Matrix4D *transform) const;
577  /// Unpack the source detail handle
578  bool unpackToDetail(GU_Detail &destgdp,
579  const GU_ConstDetailHandle &gdh,
580  const UT_Matrix4D *transform) const
581  {
582  GU_DetailHandleAutoReadLock rlock(gdh);
583  return unpackToDetail(destgdp, rlock.getGdp(), transform);
584  }
585  /// Optional method to compute centroid (default uses bounding box)
586  virtual UT_Vector3 getBaryCenter() const;
587  /// Optional method to calculate volume (default uses bounding box)
588  virtual fpreal computeVolume(const UT_Vector3 &refpt) const;
589  /// Optional method to calculate surface area (default uses bounding box)
590  virtual fpreal computeArea() const;
591  /// Optional method to calculate perimeter (default uses bounding box)
592  virtual fpreal computePerimeter() const;
593 
594  /// @{
595  /// Import a value from a UT_JSONValueMap or a UT_Options. This handles
596  /// both the compact and expanded options and is valid for the same types
597  /// as UT_JSONValueMap::import()
598  ///
599  /// These import() methods can be used in the @c load() and @c
600  /// loadFromJSON() methods to simplify importing code. For example, you
601  /// should be able to implement a generic @c loadFrom() method, templated
602  /// on either @c UT_Options or @c UT_JSONValueMap. You can then just @code
603  /// virtual bool load(const UT_Options &options, const GA_LoadMap &map)
604  /// { return loadFrom<UT_Options>(options, map); }
605  /// virtual bool loadFromJSONValueMap(const UT_JSONValueMap &options,
606  /// const GA_LoadMap &map)
607  /// { return loadFrom<UT_Options>(options, map); }
608  /// @endcode
609  template <typename T>
610  static bool import(const UT_JSONValueMap &options,
611  const UT_StringRef &key,
612  T &value);
613  template <typename T>
614  static bool import(const UT_Options &options,
615  const UT_StringRef &key,
616  T &value);
617  /// @}
618 
619 private:
620  mutable UT_BoundingBox myBoxCache;
621  mutable UT_BoundingBox myVisibleBoxCache;
622  bool myPointInstanceTransform;
623 
624  friend class GU_PrimPacked;
625 };
626 
627 #endif
virtual bool saveCachedBBox() const
SYS_FORCE_INLINE GU_PackedImpl * copyIfShared()
UT_JSONValueMap stores a map/dictionary of UT_JSONValue objects.
virtual bool unpackWithPrim(GU_Detail &destgdp, const UT_Matrix4D *transform, const GU_PrimPacked *prim) const
int int32
Definition: SYS_Types.h:39
Used to pass options and map offset values during saving.
Definition: GA_SaveMap.h:48
void
Definition: png.h:1083
const GLdouble * v
Definition: glcorearb.h:837
GLsizei const GLfloat * value
Definition: glcorearb.h:824
static const GEO_PackedNameMapPtr theNullPackedNameMapPtr
virtual bool unpackWithContext(GU_Detail &destgdp, GU_PackedContext &context, const GU_PrimPacked *prim) const
int64 exint
Definition: SYS_Types.h:125
bool unpackToDetail(GU_Detail &destgdp, const GU_ConstDetailHandle &gdh, const UT_Matrix4D *transform) const
Unpack the source detail handle.
GLdouble s
Definition: glad.h:3009
JSON reader class which handles parsing of JSON or bJSON files.
Definition: UT_JSONParser.h:87
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:39
A reference counter base class for use with UT_IntrusivePtr.
UT_SharedPtr< GA_SharedDataHandle > GA_SharedDataHandlePtr
float fpreal32
Definition: SYS_Types.h:200
virtual bool loadFromJSON(GU_PrimPacked *prim, const UT_JSONValueMap &options, const GA_LoadMap &map)
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:243
OutGridT const XformOp bool bool
std::optional< T > UT_Optional
Definition: UT_Optional.h:26
const char *(GU_PackedImpl::* StringGetter)(const GU_PrimPacked *) const
void setBoxCache(const T b[6])
double fpreal64
Definition: SYS_Types.h:201
#define UT_ASSERT_MSG(ZZ,...)
Definition: UT_Assert.h:168
virtual bool isLoaded() const
GA_Size GA_Offset
Definition: GA_Types.h:653
UT_IntrusiveRefCounter & operator=(const UT_IntrusiveRefCounter &) noexcept
Assignment operator: Does not modify counter.
SYS_FORCE_INLINE uint32 use_count() const noexcept
Return current counter.
Map to translate from Alembic attribute names to Houdini names.
SYS_FORCE_INLINE bool isShared() const
virtual bool getVisibleBounds(UT_BoundingBox &box) const
int64 intrinsic16Tuple(const GU_PrimPacked *prim) const
void setBoxCache(const UT_BoundingBox &b)
virtual void forceLoad() const
const UT_BoundingBox & boxCache() const
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
bool intrinsicPointInstanceTransform(const GU_PrimPacked *prim) const
long long int64
Definition: SYS_Types.h:116
virtual void setFacesetAttribute(const UT_StringHolder &s)
Options during loading.
Definition: GA_LoadMap.h:42
const char *(GU_PackedImpl::* StringTupleGetter)(const GU_PrimPacked *, exint) const
#define GU_API
Definition: GU_API.h:14
const UT_StringHolder &(GU_PackedImpl::* StringHolderTupleGetter)(const GU_PrimPacked *, exint) const
virtual void setSharedNameMapData(GA_SharedDataHandlePtr s)
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
GA_API const UT_StringHolder transform
void clearBoxCache()
int64 intrinsic9Tuple(const GU_PrimPacked *prim) const
virtual void setAttributeNameMap(const GEO_PackedNameMapPtr &m)
A map of string to various well defined value types.
Definition: UT_Options.h:87
SIM_API const UT_StringHolder force
fpreal64 fpreal
Definition: SYS_Types.h:283
bool pointInstanceTransform() const
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:165
const std::string &(GU_PackedImpl::* StdStringTupleGetter)(const GU_PrimPacked *, exint) const
int64 intrinsic6Tuple(const GU_PrimPacked *prim) const
int64 intrinsic3Tuple(const GU_PrimPacked *prim) const
virtual bool supportsJSONLoad() const
const GU_Detail * getGdp() const
GLint lod
Definition: glcorearb.h:2765
virtual const GEO_PackedNameMapPtr & attributeNameMap() const
GLenum src
Definition: glcorearb.h:1793