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 &);
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  /// @{
350  /// Intrinsic functions
351  int64 intrinsic3Tuple(const GU_PrimPacked *prim) const { return 3; }
352  int64 intrinsic6Tuple(const GU_PrimPacked *prim) const { return 6; }
353  int64 intrinsic9Tuple(const GU_PrimPacked *prim) const { return 9; }
354  int64 intrinsic16Tuple(const GU_PrimPacked *prim) const { return 16; }
355  std::string intrinsicPrimitiveName(const GU_PrimPacked *prim) const;
356  const char *intrinsicFactoryName(const GU_PrimPacked *prim) const;
357  const char *intrinsicFactoryLabel(const GU_PrimPacked *prim) const;
358  void intrinsicPackedBox(const GU_PrimPacked *prim, fpreal64 *vals, exint sz) const;
359  void intrinsicPackedRenderBox(const GU_PrimPacked *prim, fpreal64 *vals, exint sz) const;
360  void intrinsicPivot(const GU_PrimPacked *prim, fpreal64 *vals, exint sz) const;
361  void intrinsicSetPivot(GU_PrimPacked *prim, const fpreal64 *vals, exint sz);
362  void intrinsicPrimTransform(const GU_PrimPacked *prim, fpreal64 *vals, exint sz) const;
363  void intrinsicSetPrimTransform(GU_PrimPacked *prim, const fpreal64 *v, exint sz);
364  void intrinsicPackedTransform(const GU_PrimPacked *prim, fpreal64 *v, exint sz) const;
365  void intrinsicFullTransform(const GU_PrimPacked *prim, fpreal64 *v, exint sz) const;
366  const char *intrinsicViewportLOD(const GU_PrimPacked *prim) const;
367  void intrinsicSetViewportLOD(GU_PrimPacked *prim, const char *lod);
368  /// @}
369 
370  /// Some procedurals have an "intrinsic" transform. These are combined
371  /// with the local transform on the geometry primitive.
372  ///
373  /// The default method returns false and leaves the transform unchanged.
374  virtual bool getLocalTransform(UT_Matrix4D &m) const;
375 
376  /// Unpack the procedural into a GU_Detail. By default, this calls
377  /// getGTFull() and converts the GT geometry to a GU_Detail.
378  virtual bool unpackWithContext(
379  GU_Detail &destgdp,
380  GU_PackedContext &context,
381  const GU_PrimPacked *prim) const
382  { return unpack(destgdp, prim); }
383 
384  /// Unpacks this into destgdp, transforming the new geometry by
385  /// the transform of prim. If prim is nullptr, no transform will be applied.
386  bool unpack(GU_Detail &destgdp, const GU_PrimPacked *prim) const;
387 
388  /// Unpacks this into destgdp, transforming the new geometry by
389  /// the given transform. If transform is nullptr, no transform will be applied.
390  virtual bool unpack(GU_Detail &destgdp, const UT_Matrix4D *transform) const = 0;
391 
392 protected:
393  /// Most implementations don't require the primitive once they have the transform,
394  /// so the default implementation just calls the signature without the primitive.
395  /// This function may be removed in the future, since it was only added
396  /// because Alembic packed primitives copy primitive group membership from
397  /// the original packed prim, which may not be advisable in all cases.
398  virtual bool unpackWithPrim(
399  GU_Detail &destgdp,
400  const UT_Matrix4D *transform,
401  const GU_PrimPacked *prim) const
402  {
403  return unpack(destgdp, transform);
404  }
405 public:
406 
407  /// Unpack into a GU_Detail, and generate stylers for each primitive.
408  /// By default calls unpack, prunes the supplied styler for each generated
409  /// primitive, and adds the styles in the material_stylesheet attribute
410  /// for each primitive.
411  virtual bool unpackWithStyler(
412  GU_Detail &destgdp,
413  STY_StylerGroup &prim_styler_group,
414  const STY_Styler &parent_styler,
415  const GU_PrimPacked *prim) const;
416 
417  /// Forces a load of all shared data the primitive has access to
418  /// this should leave no data on disk
419  virtual void forceLoad() const {}
420 
421  /// Checks if this packed implementation has loaded its shared data
422  /// Default implementation returns true.
423  virtual bool isLoaded() const { return true; }
424 
425  /// Unpack the procedural into a GU_Detail using polygons instead of
426  /// polygon soups. The default method just unpacks, then converts polygon
427  /// soups to polygons.
428  virtual bool unpackUsingPolygons(
429  GU_Detail &destgdp,
430  const GU_PrimPacked *prim) const;
431 
432  /// Get a reference to a const GU_Detail for the packed geometry. Not all
433  /// implementations need to provide this. If this isn't implemented, the
434  /// method should return an empty detail handle. This is meant as a quick
435  /// short-cut instead of having to call unpack() which performs a full
436  /// merge.
437  virtual GU_ConstDetailHandle getPackedDetail(GU_PackedContext *context = 0) const;
438 
439  /// If @c pointInstanceTransform() returns false, @c getFullTransform4()
440  /// method will only use the point position as a translate. If true, @c
441  /// getFullTransform4() will perform the standard "houdini instancing"
442  /// (i.e. use the "N", "v", "rot" and other attributes to compute an
443  /// orientation and translation).
444  ///
445  /// The default method returns false, so only "P" is used to apply
446  /// translates.
448  { return myPointInstanceTransform; }
450  { return pointInstanceTransform(); }
451 
452  /// Set whether point instancing should be used.
453  void setPointInstanceTransform(GU_PrimPacked *prim, bool b);
454 
455  /// Convenience method to compute the velocity bounds for a given geometry.
456  /// The geometry may be a NULL pointer.
457  static bool computeVelocityRange(const GU_Detail *gdp,
458  UT_Vector3 &vmin, UT_Vector3 &vmax);
459  static bool computeWidthRange(const GU_Detail *gdp,
460  fpreal &wmin, fpreal &wmax);
461 
462  /// Report memory usage (includes all shared memory)
463  virtual int64 getMemoryUsage(bool inclusive) const = 0;
464 
465  /// Count memory usage using a UT_MemoryCounter in order to count
466  /// shared memory correctly.
467  /// NOTE: There's nothing outside of sizeof(*this) to count in the
468  /// base class, so it can be pure virtual.
469  virtual void countMemory(UT_MemoryCounter &counter, bool inclusive) const = 0;
470 
471  /// Determines if we should save the bounding box to the metadata, this
472  /// makes sense for fully embedded primitives, but if the primitive
473  /// can be swapped out without the owner knowing, it should be
474  /// avoided.
475  virtual bool saveCachedBBox() const { return false; }
476 
477  /// Default implementation does nothing and asserts, since
478  /// only relevant subclasses (GABC_PackedImpl) should be
479  /// getting a faceset attribute string.
480  virtual void setFacesetAttribute(const UT_StringHolder &s)
481  {
482  UT_ASSERT_MSG(0, "Subclass should implement setFacesetAttribute, when applicable.");
483  }
484 
485  /// Default implementation just returns the default value of
486  /// GEO_PrimPacked::theDefaultFacesetAttribute
487  virtual const UT_StringHolder &facesetAttribute() const;
488 
489  /// Default implementation does nothing and asserts, since
490  /// only relevant subclasses (GABC_PackedImpl) should be
491  /// getting an attribute name map.
493  {
494  UT_ASSERT_MSG(0, "Subclass should implement setAttributeNameMap, when applicable.");
495  }
496 
497  /// Default implementation just returns the default
498  /// null name map.
499  virtual const GEO_PackedNameMapPtr &attributeNameMap() const
500  {
501  return theNullPackedNameMapPtr;
502  }
503 
504  /// Default implementation does nothing and asserts, since
505  /// only relevant subclasses should be getting shared name map data.
507  {
508  UT_ASSERT_MSG(0, "Subclass should implement setSharedNameMapData, when applicable.");
509  }
510 
512  bool isShared() const
513  {
514  return (use_count() > 1);
515  }
516 
519  {
520  if (isShared())
521  return copy();
522  return this;
523  }
524 
525 protected:
527 
528  /// The box cache can be used by the implementation to store the
529  /// untransformed bounding box. It should @b not store the transformed
530  /// box.
531  const UT_BoundingBox &boxCache() const { return myBoxCache; }
532 
534  {
535  myBoxCache = b;
536  myVisibleBoxCache.makeInvalid();
537  }
538  template<typename T>
539  void setBoxCache(const T b[6])
540  {
541  myBoxCache.setSerialized(b);
542  myVisibleBoxCache.makeInvalid();
543  }
545  {
546  myBoxCache.makeInvalid();
547  myVisibleBoxCache.makeInvalid();
548  }
549 
550  /// For all the groups that this primitive belongs to, create groups on the
551  /// destination detail and place all primitives in the given range into the
552  /// groups. If the group already exists on the destination detail, then
553  /// nothing is done (unless @c force is set).
554  static void copyPrimitiveGroups(GU_Detail &dest,
555  const GU_Detail &src,
556  GA_Offset src_offset,
557  bool force=false);
558 
559  /// Unpack the source detail into the destination detail. The source
560  /// detail *may* be modified (attributes may be promoted)
561  ///
562  /// The @c src detail is not deleted by unpackToDetail.
563  bool unpackToDetail(GU_Detail &destgdp,
564  GU_Detail *src,
565  const UT_Matrix4D *transform) const;
566  /// Unpack the source detail into the destination detail. The source
567  /// detail is const and will not be modified. However, this may be more
568  /// expensive than the non-const version.
569  bool unpackToDetail(GU_Detail &destgdp,
570  const GU_Detail *src,
571  const UT_Matrix4D *transform) const;
572  /// Unpack the source detail handle
573  bool unpackToDetail(GU_Detail &destgdp,
574  const GU_ConstDetailHandle &gdh,
575  const UT_Matrix4D *transform) const
576  {
577  GU_DetailHandleAutoReadLock rlock(gdh);
578  return unpackToDetail(destgdp, rlock.getGdp(), transform);
579  }
580  /// Optional method to compute centroid (default uses bounding box)
581  virtual UT_Vector3 getBaryCenter() const;
582  /// Optional method to calculate volume (default uses bounding box)
583  virtual fpreal computeVolume(const UT_Vector3 &refpt) const;
584  /// Optional method to calculate surface area (default uses bounding box)
585  virtual fpreal computeArea() const;
586  /// Optional method to calculate perimeter (default uses bounding box)
587  virtual fpreal computePerimeter() const;
588 
589  /// @{
590  /// Import a value from a UT_JSONValueMap or a UT_Options. This handles
591  /// both the compact and expanded options and is valid for the same types
592  /// as UT_JSONValueMap::import()
593  ///
594  /// These import() methods can be used in the @c load() and @c
595  /// loadFromJSON() methods to simplify importing code. For example, you
596  /// should be able to implement a generic @c loadFrom() method, templated
597  /// on either @c UT_Options or @c UT_JSONValueMap. You can then just @code
598  /// virtual bool load(const UT_Options &options, const GA_LoadMap &map)
599  /// { return loadFrom<UT_Options>(options, map); }
600  /// virtual bool loadFromJSONValueMap(const UT_JSONValueMap &options,
601  /// const GA_LoadMap &map)
602  /// { return loadFrom<UT_Options>(options, map); }
603  /// @endcode
604  template <typename T>
605  static bool import(const UT_JSONValueMap &options,
606  const UT_StringRef &key,
607  T &value);
608  template <typename T>
609  static bool import(const UT_Options &options,
610  const UT_StringRef &key,
611  T &value);
612  /// @}
613 
614 private:
615  mutable UT_BoundingBox myBoxCache;
616  mutable UT_BoundingBox myVisibleBoxCache;
617  bool myPointInstanceTransform;
618 
619  friend class GU_PrimPacked;
620 };
621 
622 #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
OIIO_UTIL_API bool copy(string_view from, string_view to, std::string &err)
const GLdouble * v
Definition: glcorearb.h:837
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
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:37
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:235
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:159
virtual bool isLoaded() const
GA_Size GA_Offset
Definition: GA_Types.h:641
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:84
SIM_API const UT_StringHolder force
fpreal64 fpreal
Definition: SYS_Types.h:277
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:156
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