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