HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GA_Attribute.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: GA_Attribute.h ( GA Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #pragma once
12 
13 #ifndef __GA_Attribute__
14 #define __GA_Attribute__
15 
16 #include "GA_API.h"
17 #include "GA_AttributeProxy.h"
18 #include "GA_AttributeType.h"
19 #include "GA_Types.h"
20 
21 #include <UT/UT_Assert.h>
22 #include <UT/UT_StringHolder.h>
23 #include <UT/UT_UniquePtr.h>
24 
25 #include <SYS/SYS_StaticAssert.h>
26 #include <SYS/SYS_Inline.h>
27 #include <SYS/SYS_Types.h>
28 
29 #include <string>
30 #include <string.h>
31 
32 class GA_AIFBlindData;
33 class GA_AIFBlob;
34 class GA_AIFBlobArray;
35 class GA_AIFCompare;
36 class GA_AIFCopyData;
37 class GA_AIFDelta;
38 class GA_AIFEdit;
39 class GA_AIFIndexPair;
40 class GA_AIFInterp;
41 class GA_AIFJSON;
42 class GA_AIFMath;
43 class GA_AIFMerge;
44 class GA_AIFNumericArray;
49 class GA_AIFStat;
50 class GA_AIFStringTuple;
51 class GA_AIFTuple;
52 class GA_Attribute;
53 class GA_CEAttribute;
54 class GA_Defragment;
55 class GA_Detail;
56 class GA_IndexMap;
57 class GA_Range;
58 class GA_MergeMap;
59 
60 class UT_JSONParser;
61 class UT_JSONWriter;
62 class UT_MemoryCounter;
63 class UT_OptionEntry;
64 class UT_Options;
65 class UT_String;
66 class UT_WorkBuffer;
67 
69 {
70 public:
73 
75 
76  GA_AttributeOptions &operator=(const GA_AttributeOptions &src);
77 
78  /// Reset to default.
79  void clear();
80 
81  /// Constructs a full UT_Options that includes all symbols that
82  /// are otherwise handled with member variables.
83  void buildFullOptions(UT_Options &fulloptions) const;
84 
85  /// Removes from our myOptions list any options that aren't custom
86  /// and assigns them to local variables. May then delete myOptions
87  /// if it is empty.
88  void extractBuiltinOptions();
89 
90  /// If no custom options are present, create it.
91  UT_Options &createOptions();
92 
93  /// Merges option list on top of our own
94  void mergeOptions(const GA_AttributeOptions &src);
95 
96  /// @{
97  /// Accessors
98  GA_TypeInfo typeInfo() const { return myTypeInfo; }
99  void setTypeInfo(GA_TypeInfo t) { myTypeInfo = t; }
100  bool isNonTransforming() const { return myIsNonTransforming; }
101  void setIsNonTransforming(bool v) { myIsNonTransforming = v; }
102  bool exportToInfoBlock() const { return myExportToInfoBlock; }
103  void setExportToInfoBlock(bool v) { myExportToInfoBlock = v; }
104  bool leaveOnGPU() const { return myLeaveOnGPU; }
105  void setLeaveOnGPU(bool v) { myLeaveOnGPU = v; }
106  /// @}
107 
108  /// Check whether the exportOnMerge() flag has been set, or whether it's at
109  /// its default.
110  bool exportOnMergeSet() const { return myExportOnMergeValid; }
111  /// Check to see whether the export on merge is enabled. If the flag
112  /// hasn't been set, the default value will be used.
113  bool exportOnMerge(bool defval=false) const
114  { return myExportOnMergeValid ? myExportOnMerge : defval; }
115  /// Set the export on merge flag
116  void setExportOnMerge(bool v)
117  {
118  myExportOnMergeValid = true;
119  myExportOnMerge = v;
120  }
121 
122  /// Check whether the exportOnSave() flag has been set, or whether it's at
123  /// its default.
124  bool exportOnSaveSet() const { return myExportOnSaveValid; }
125  /// Check to see whether the export on save is enabled. If the flag
126  /// hasn't been set, the default value will be used.
127  bool exportOnSave(bool defval=false) const
128  { return myExportOnSaveValid ? myExportOnSave : defval; }
129  /// Set the export on save flag
130  void setExportOnSave(bool v)
131  {
132  myExportOnSaveValid = true;
133  myExportOnSave = v;
134  }
135 
136  /// Check to see whether the attribute is a "string set". If the flag
137  /// hasn't been set, the default value will be used.
138  bool isStringSet(bool defval=false) const
139  { return myIsStringSetValid ? myIsStringSet : defval; }
140  /// Set the "string set" flag
141  void setIsStringSet(bool v)
142  {
143  myIsStringSetValid = true;
144  myIsStringSet = v;
145  }
146 
147  /// @{
148  /// Access to options
149  const UT_Options *options() const { return myOptions; }
150  void setOptions(const UT_Options &o);
151  void mergeOptions(const UT_Options &o);
152  void mergeOptions(const UT_Options &o,
153  bool (*match)(const UT_StringHolder &name,
154  const UT_OptionEntry *, void *),
155  void *data);
156  void clearOptions();
157  bool removeOption(const char *name);
158  /// @}
159 
160 private:
161  // Our custom options.
162  UT_Options *myOptions;
163 
164  GA_TypeInfo myTypeInfo;
165 
166  bool myIsNonTransforming : 1;
167  bool myExportOnMergeValid : 1, myExportOnMerge : 1;
168  bool myExportOnSaveValid : 1, myExportOnSave : 1;
169 
170  bool myIsStringSetValid : 1, myIsStringSet : 1;
171 
172  bool myExportToInfoBlock : 1;
173  bool myLeaveOnGPU : 1;
174 
175  bool myDetached : 1;
176 
177  friend class GA_Attribute;
178 };
179 
180 template<typename T>
181 static inline const T *GAgetAIF(const GA_Attribute &attrib)
182 {
184  return NULL;
185 }
186 
187 
188 /// @brief Definition of a geometry attribute
189 ///
190 /// An attribute can be attached to points, vertices, primitives or the detail
191 /// itself. The attribute is responsible for maintaining the data array.
192 ///
193 /// @see @ref Iterators for implications of paged allocation strategies.
194 ///
195 /// The attribute is responsible for providing interfaces (@ref AIF).
196 ///
198 {
199 public:
200  GA_Attribute(
201  const GA_AttributeType &type, const GA_IndexMap &index_map,
202  GA_AttributeScope scope, const UT_StringHolder &name);
203  virtual ~GA_Attribute();
204 
205  const GA_AttributeType &getType() const { return myType; }
206  const GA_IndexMap &getIndexMap() const { return myIndexMap; }
207  const GA_Detail &getDetail() const;
208  GA_Detail &getDetail();
209  GA_AttributeOwner getOwner() const;
210 
211  GA_AttributeScope getScope() const { return myScope; }
212  bool isGroup() const { return myScope == GA_SCOPE_GROUP; }
213 
214  /// @{
215  /// Obtains the proxy representative used as a reference holder to this
216  /// attribute. This proxy gets invalidated when the attribute gets deleted.
217  /// Invalidation clears the proxy's pointer to NULL, but the proxy's memory
218  /// stays valid, unlike the memory of the attribute object.
220  { return GA_AttributeProxyHandle(myProxy); }
222  { return GA_ConstAttributeProxyHandle(myProxy); }
223  /// @}
224 
225  /// @{
226  /// Attribute flags store certain mutable properties of the attribute,
227  /// largely used for internal book keeping and semantic error detection
228 
229  enum AttribFlag {
230  FLAG_TAIL_INITIALIZE = 1,
231  FLAG_STREAM_ACTIVE = 2,
232  FLAG_STREAM_NOPREEXIST = 4 // Note inversion of sense!
233  };
234 
235  bool hasFlag(AttribFlag flag) const
236  { return (myAttribFlags & flag) ? true : false; }
237 
238  void setFlag(AttribFlag flag, bool onoff)
239  {
240  if (onoff)
241  myAttribFlags |= (int)flag;
242  else
243  myAttribFlags &= ~(int)flag;
244  }
245 
246  /// @}
247 
248  /// Uses the "type" option to determine type information
249  /// @see getOptions()
252  {
253  return myOptions.myTypeInfo;
254  }
255 
256  /// Set the option. This sets the "type" option on the attribute
257  /// @see getOptions()
260  {
261  myOptions.myTypeInfo = type;
262  }
263 
264  /// Checks if an attribute should be treated as a texture coordinate attribute.
265  /// Ideally, we could rely on the type info being GA_TYPE_TEXTURE_COORD,
266  /// but old files don't have this, and various importers don't set this.
267  /// If a float[3] (optionnally float[2]) attribute's name starts with "uv"
268  /// and is followed by zero or more digits (and nothing else), it's probably
269  /// safe to assume that it should be treated as a texture attribute.
270  bool shouldInterpretAsTexCoord(bool allow_float2=false) const;
271 
272  /// Returns the approximate type of the attribute
273  GA_StorageClass getStorageClass() const;
274 
275  /// Size of the AIFTuple, if it exists. If it doesn't, 1.
276  int getTupleSize() const;
277 
278  // Methods to get intrinsic data
279  // getName() returns the unprefixed name (as opposed to getFullName())
280  // We have separate const char * versions as this is often passed
281  // to sprintf().
282  const UT_StringHolder &getName() const { return myName; }
283  const UT_StringHolder &getFullName() const { return myName; }
284 
285  /// The data ID is shared by attributes that represent the same underlying
286  /// data and is used by cache mechanisms to avoid rebuilding when data has
287  /// not really changed. An ID of -1 indicates that this attribute is not
288  /// going to get a new ID when its data is changed, and therefore is not
289  /// participating in this scheme.
290  ///
291  /// Two attributes can share the same data ID even when they don't share
292  /// the same internal data pages or even fragmentation patterns. Note
293  /// however that the data ID is not necessarily changed for topology
294  /// changes, so it is necessary to also compare topology data IDs in order
295  /// to be absolutely sure that two attributes sharing the same data ID
296  /// represent the same data (taking into account defragmentation).
298  GA_DataId getDataId() const { return myDataId; }
301  {
302  myDataId = nextDataId();
303  }
305  void bumpDataId()
306  {
307  if (myDataId != GA_INVALID_DATAID)
308  assignNewDataId();
309  }
311  void clearDataId() { myDataId = GA_INVALID_DATAID; }
312 
313  /// This clones the data ID from src. If src has an invalid data ID,
314  /// which can be the case for details not created by SOP_Node or
315  /// SIM_GeometryCopy, we default to bumping the destination data ID.
316  /// This should be used by functions like GA_Attribute::replace()
317  /// when an attribute's data is replaced with that of src.
318  ///
319  /// NOTE: We must always either clone or bump the data ID if we've
320  /// copied from another attribute, even if that src attribute
321  /// has an invalid data ID. See Bug 79446 and 79438.
323  void cloneDataId(const GA_Attribute &src,
324  bool allow_clear = false)
325  {
326  if (allow_clear || src.myDataId != -1)
327  myDataId = src.myDataId;
328  else
329  bumpDataId();
330  }
331  /// NOTE: Just call cloneDataId(src).
334  bool allow_clear = false)
335  {
336  cloneDataId(src, allow_clear);
337  }
338 
339  /// The method to set array size
340  /// *Must* be implemented in subclasses
341  /// Return true if the attribute was resized.
342  virtual bool setArraySize(GA_Offset size) = 0;
343 
344  /// Try to compress data pages
345  /// Will try to compress *all* pages overlapping the specified offset range.
346  /// *Must* be implemented in subclasses
347  virtual void tryCompressAllPages(
348  GA_Offset start_offset = GA_Offset(0),
349  GA_Offset end_offset = GA_INVALID_OFFSET) = 0;
350 
351  /// Harden data pages
352  /// Will harden *all* pages overlapping the specified offset range.
353  /// Once this is done, multiple threads can write to an attribute in
354  /// parallel at a finer granularity than pages.
355  /// *Must* be implemented in subclasses
356  virtual void hardenAllPages(
357  GA_Offset start_offset = GA_Offset(0),
358  GA_Offset end_offset = GA_INVALID_OFFSET) = 0;
359 
360  /// The various concurrency levels supported by attributes for writing
361  /// per-element data.
363  /// No concurrent writes supported.
365  /// Concurrent writes to separate pages supported.
367  /// Concurrent writes to separate elements supported.
368  WRITE_CONCURRENCE_ELEMENT
369  };
370 
371  virtual WriteConcurrence getSupportedWriteConcurrence() const = 0;
372 
373  /// Return the attribute's copy interface or NULL
374  virtual const GA_AIFCopyData *getAIFCopyData() const;
375  /// Return the attribute's delta interface or NULL
376  virtual const GA_AIFDelta *getAIFDelta() const;
377  /// Return the attribute's tuple interface or NULL
378  virtual const GA_AIFTuple *getAIFTuple() const;
379  /// Return the attribute's math interface or NULL
380  virtual const GA_AIFMath *getAIFMath() const;
381  /// Return the attribute's merge interface or NULL
382  virtual const GA_AIFMerge *getAIFMerge() const;
383  /// Return the attribute's interpolation interface or NULL
384  virtual const GA_AIFInterp *getAIFInterp() const;
385  /// Return the attribute's blob interface or NULL
386  virtual const GA_AIFBlob *getAIFBlob() const;
387  /// Return the attribute's blob array interface or NULL
388  virtual const GA_AIFBlobArray *getAIFBlobArray() const;
389  /// Return the attribute's string tuple interface or NULL
390  virtual const GA_AIFStringTuple *getAIFStringTuple() const;
391  /// Return the attribute's shared string tuple interface or NULL
392  virtual const GA_AIFSharedStringTuple *getAIFSharedStringTuple() const;
393  /// Return the attribute's shared string array interface or NULL
394  virtual const GA_AIFSharedStringArray *getAIFSharedStringArray() const;
395  /// Return the attribute's shared options tuple interface or NULL
396  virtual const GA_AIFSharedDictTuple *getAIFSharedDictTuple() const;
397  /// Return the attribute's shared options tuple interface or NULL
398  virtual const GA_AIFSharedDictArray *getAIFSharedDictArray() const;
399  /// Return the attribute's index pair interface or NULL
400  virtual const GA_AIFIndexPair *getAIFIndexPair() const;
401  /// Return the attribute's blind data interface or NULL
402  virtual const GA_AIFBlindData *getAIFBlindData() const;
403  /// Return the attribute's edit interface or NULL
404  virtual const GA_AIFEdit *getAIFEdit() const;
405  /// Return the attribute's comparison interface or NULL
406  virtual const GA_AIFCompare *getAIFCompare() const;
407  /// Return the attribute's arraydata interface or NULL
408  virtual const GA_AIFNumericArray *getAIFNumericArray() const;
409 
410  /// Return the attribute's stat interface. Unlike other interfaces, this
411  /// method has default behaviour.
412  virtual const GA_AIFStat *getAIFStat() const;
413 
414  /// Generic method for getting an AIF by type
415  template <typename T> const T *getAIF() const { return GAgetAIF<T>(*this); }
416 
417  // Options can be used to associated arbitrary data with an attribute.
418  // Common options are defined in GA_Options.h
419  const GA_AttributeOptions &getOptions() const { return myOptions; }
420  GA_AttributeOptions &getOptions() { return myOptions; }
421 
422  /// Although an attribute may be a "point" or "normal", we may not want to
423  /// transform the point. This is the case with "rest" for example.
424  /// At the current time, this sets the flag corresponding with
425  /// "attribute:non_transforming" in the options.
426  /// @see needsTransform()
427  /// @see getTypeInfo()
429  {
430  myOptions.setIsNonTransforming(val);
431  }
432 
433  /// needTransform() checks whether the attribute is a
434  /// floating-point attribute whose type info is a transforming
435  /// type and whose non-transforming flag is false.
436  bool needsTransform(bool include_P = true) const
437  {
438  return getStorageClass() == GA_STORECLASS_FLOAT
439  && !myOptions.isNonTransforming()
440  && GAisTransformingType(getTypeInfo())
441  && (include_P || strcmp(getName(), "P") != 0);
442  }
443 
444  bool isDetached() const
445  {
446  return myOptions.myDetached;
447  }
448 
449  /// @{
450  /// Houdini forces certain restrictions on attribute names. However,
451  /// external software doesn't always have these restrictions. When
452  /// importing attributes, you can store the "real" attribute name, or use
453  /// the "export" name when exporting.
454  ///
455  /// @c getExportName() will return the attribute name if there's no export
456  /// name set.
457  void setExportName(const char *external_name);
458  bool hasExportName() const;
459  std::string getExportName() const;
460  /// @}
461 
462  /// Merge the options passed in with the options in the attribute
464  { myOptions.mergeOptions(src); }
465 
466  // Check to see the value of a specific option
467  bool importOption(const char *name, int &v) const;
468  bool importOption(const char *name, bool &v) const;
469  bool importOption(const char *name, fpreal32 &v) const;
470  bool importOption(const char *name, fpreal64 &v) const;
471  bool importOption(const char *name, UT_String &v) const;
472 
473  /// Methods which can be overridden from GA_Attribute
474 
475  /// Element destruction event. When an element is destroyed, the attribute
476  /// may be notified of this event.
477  virtual bool needDestruction() const;
478  /// Callback invoked if needsDestruction() returns true
479  virtual void destructElement(GA_Offset offset);
480 
481  /// The GA library expects any elements allocated at the end of the array
482  /// to be set to their default values. If this is not the case, then the
483  /// attribute can register itself for special initialization.
484  void setTailInitialization(bool onoff);
485 
486  /// Check whether the attribute is set to tail initialization
487  bool isTailInitialization() const
488  { return hasFlag(FLAG_TAIL_INITIALIZE); }
489 
490  /// When the array size is grown, attributes should initialize the value
491  /// appropriately. When an element is reused, however, the
492  /// reconstructElement is called. This happens if an element is deleted
493  /// then a new element is allocated (using the existing slot)
495  { reconstructElementBlock(offset, GA_Offset(1)); }
496 
497  /// When the array size is grown, attributes should initialize the value
498  /// appropriately. When elements are reused, however,
499  /// reconstructElementBlock is called. This happens if an element is
500  /// deleted and then a new element is allocated (using the existing slot)
501  virtual void reconstructElementBlock(GA_Offset offset, GA_Offset nelements) = 0;
502 
503  /// A method to "compact" any storage. For example, if there's a string
504  /// table associated with the attribute, this gives the attribute the option
505  /// to adjust the table to be more compact.
506  virtual void compactStorage();
507 
508  /// This method is called before a batch deletion operation. It allows the
509  /// attribute to mark objects as dirty so that there can be lazy computation
510  /// of data. For example, re-computing the number of elements in a group.
511  /// This method may be called multiple times, and so should typically just
512  /// set a flag (not perform a lot of computation).
513  virtual void batchDeletion();
514 
515  /// This method returns a new attribute of the same type with identical
516  /// settings. Attribute data is not copied. Derived classes implement
517  /// this method by overriding the virtual doClone(). Those classes not
518  /// supporting cloning are permitted to return NULL.
519  GA_Attribute *clone(const GA_IndexMap &index_map,
520  const UT_StringHolder &name,
521  bool clone_options) const;
522 
523  /// @section JSON-GA_Attribute JSON Schema: GA_Attribute
524  ///
525  /// The schema for an attribute consists of an array of two items. The
526  /// first entry contains of the definition of the attribute. The second
527  /// entry is the "private" data for the attribute. If there is no data for
528  /// the attribute (i.e. the attribute doesn't provide an AIFJSON), then a
529  /// null will be saved as the second element.
530  ///
531  /// The private data is saved/loaded by the GA_AIFJSON class for the
532  /// attribute.
533  ///
534  /// @code
535  /// [
536  /// "name" : "GA_Attribute",
537  /// "description" :
538  /// "An attribute is defined by an array with two items. The
539  /// first item is the definition of the attribute, the second
540  /// is private data associated with the attribute (may be null).",
541  /// "type" : "array",
542  /// "items" : [
543  /// { "$ref" : "GA_Attribute-Definition" }, // Attribute Definition
544  /// { "$ref" : "GA_Attribute-Data" }, // Specific type data
545  /// ],
546  /// ]
547  /// @endcode
548  ///
549  /// @section JSON-GA_Attribute-Definition JSON Schema: GA_Attribute-Definition
550  /// The attribute definition is a map containing the fields required to
551  /// recreate the attribute.
552  /// @code
553  /// {
554  /// "name" : "GA_Attribute-Definition",
555  /// "description" : "An map defining the attribute",
556  /// "type" : "orderedmap",
557  /// "properties": {
558  /// "scope": {
559  /// "type" : "string",
560  /// "optional" : true,
561  /// "default" : "public",
562  /// "description" : "Scope of the attribute",
563  /// },
564  /// "type": {
565  /// "type" : "string",
566  /// "description" : "Attribute type (ATI name)",
567  /// },
568  /// "name": {
569  /// "type" : "string",
570  /// "description" : "Name of the attribute",
571  /// },
572  /// "version": {
573  /// "type" : "integer",
574  /// "optional" : true,
575  /// "description" : "Version level for save",
576  /// },
577  /// "options": {
578  /// "type" : { "$ref" : "UT_Options" }
579  /// "description" : "Arbitrary options on the attribute",
580  /// },
581  /// },
582  /// }
583  /// @endcode
584  /// @see @ref JSON_FileFormat, GA_AttributeSet, GA_AttributeType
585 
586  /// Save the GA_Attribute-Definition section
587  bool jsonSaveDefinition(UT_JSONWriter &w) const;
588 
589  /// Load the GA_Attribute-Definition section
590  static bool jsonLoadDefinition(UT_JSONParser &p,
591  GA_AttributeScope &scope,
592  UT_WorkBuffer &type,
593  UT_WorkBuffer &name,
594  int64 &version,
595  GA_AttributeOptions &options);
596 
597  /// Return the AIF to handle saving/loading of the private data section
598  virtual const GA_AIFJSON *getAIFJSON() const;
599 
600  /// Return the optional "save" version number. This is passed to the JSON
601  /// attribute loader. If the version is <= 0, the version is not saved to
602  /// the file and 0 will be passed to the loader.
603  virtual int getSaveVersion() const;
604 
605  /// Debug validation of allocated array size
606  virtual bool debugValidateArrayCapacity(GA_Offset sz) const;
607 
608  /// Report the memory usage
609  ///
610  /// NOTE: If you're implementing this in a direct subclass of GA_Attribute,
611  /// call getBaseMemoryUsage() to get the amount of memory in the base
612  /// class. If in a more distant descendant class, call
613  /// Base::getMemoryUsage(false) to count the memory in Base and
614  /// above, excluding sizeof(Base).
615  virtual int64 getMemoryUsage(bool inclusive) const = 0;
616 
617  /// Count memory usage using a UT_MemoryCounter in order to count
618  /// shared memory correctly.
619  /// If inclusive is true, the size of this object is counted,
620  /// else only memory owned by this object is counted.
621  /// If this is pointed to by the calling object, inclusive should be true.
622  /// If this is contained in the calling object, inclusive should be false.
623  /// (Its memory was already counted in the size of the calling object.)
624  ///
625  /// NOTE: If you're implementing this in a direct subclass of GA_Attribute,
626  /// call getBaseMemoryUsage() to get the amount of memory in the base
627  /// class. If in a more distant descendant class, call
628  /// Base::countMemory(counter, false) to count the memory in Base and
629  /// above, excluding sizeof(Base).
630  virtual void countMemory(UT_MemoryCounter &counter, bool inclusive) const = 0;
631 
632  /// @{
633  /// @c defragment() defragments the memory used to store data elements
634  virtual void defragment(const GA_Defragment &defrag) = 0;
635  /// @}
636 
637  /// @private
638  /// Used only for optimizing merging of attributes
639  const GA_Attribute *getMergeSource() const { return myMergeSource; }
640 
641  /// This is only here so that select data outside of GA_Attribute
642  /// can also have data IDs, like GA_PrimitiveList and GA_EdgeGroup.
643  static GA_DataId nextDataId();
644 
645  /// @{
646  /// The attribute data may be moved to the GPU, and hence backed
647  /// by a compute buffer (GA_CEAttribute). Flushing will delete
648  /// our buffer & copy it back from the GPU if it has been marked
649  /// as modified.
650 
651  /// Caches a CE Attribute. If a cache already exists, the cached
652  /// data is returned and the write flag updated. If the cache
653  /// does not exist, an attempt is made to build a buffer. If
654  /// read is true, the buffer is initialized with the geometry data.
655  /// This can return NULL if a failure to build an attribute occurs
656  /// (for example, unsupported type or no GPU)
657  GA_CEAttribute *getCEAttribute(GA_StorageClass storage, int &tuplesize, bool isarray, bool read, bool write)
658  { return getCEAttribute(storage, GA_PRECISION_32, tuplesize, isarray, read, write); }
659  GA_CEAttribute *getCEAttribute(GA_StorageClass storage, GA_Precision precision, int &tuplesize, bool isarray, bool read, bool write);
660 
661  void setCEAttribute(GA_CEAttribute *ceattrib, bool leaveOnGPU=false);
662 
663  /// Any CE cache which was marked as written to will be copied
664  /// back to the CPU. It will be left on the GPU, however.
665  void flushCEWriteCaches(bool clearwriteback=true);
666  bool hasPendingCEWriteBack() const;
667 
668  /// Remove all CE Caches, copying back any marked as written to.
669  void flushCECaches();
670 
671  /// Steal the CE attribute from the source attribute, leaving the
672  /// src with a null CE attribute.
673  void stealCEAttribute(const GA_Attribute &src);
674  /// @}
675 
676  /// @{
677  /// During streaming operations it can be important to flag which
678  /// attributes are in the process of being modified. This way
679  /// attempts to random-access read them can be detected and thwarted
680  /// as they won't be valid.
681 
682  /// Is this attribute is currently being streamed? No random
683  /// reads should be done to this attribute. Default is that
684  /// it is not streaming.
685  bool isActivelyStreamed() const
686  { return hasFlag(FLAG_STREAM_ACTIVE); }
687 
688  void setActivelyStreamed(bool isstreaming)
689  { setFlag(FLAG_STREAM_ACTIVE, isstreaming); }
690 
691  /// Was this attribute created as a result of the stream operation?
692  /// This allows detection of attributes that only exist as a result
693  /// of the stream beginning. Default is that it existed.
694  bool existedPriorToStream() const
695  { return !hasFlag(FLAG_STREAM_NOPREEXIST); }
696 
697  void setExistedPriorToStream(bool preexisted)
698  { setFlag(FLAG_STREAM_NOPREEXIST, !preexisted); }
699  /// @}
700 
701 protected:
702  /// For use by getMemoryUsage and countMemory in subclasses to count the
703  /// amount of memory used by this base class (NOTE: *always* exclusive)
704  int64 getBaseMemoryUsage() const;
705 
706  /// Only called by GA_AttributeSet and GA_ElementGroup
707  void setDetached(bool detached)
708  {
709  myOptions.myDetached = detached;
710  }
711 
712  /// Determine if we should overwrite our attribute on merge, off for
713  /// detail attributes so the first will win.
714  static bool checkGlobalOverwrite(const GA_MergeMap &map, const GA_Attribute *attrib);
715 
716 private:
717  /// Method called by the GA_AttributeType::create() factory method to
718  /// initialize the object by calling virtual overrides not accessible
719  /// in our constructor.
720  void initialize();
721 
722  /// Create a new attribute of this type.
723  virtual GA_Attribute *doClone(const GA_IndexMap &index_map,
724  const UT_StringHolder &name) const;
725 
728  const UT_StringHolder &,
729  const UT_Options *,
730  const GA_AttributeOptions *) const;
731 
732  /// @{
733  /// @private
734  /// Only called by GA_AttributeSet and GA_ElementGroup.
735  bool setName(const UT_StringHolder &newname);
736  void setProxy(GA_AttributeProxy *proxy);
737  friend class GA_AttributeSet;
738  friend class GA_ElementGroup;
739  friend class GA_MergeMap;
740  /// @}
741 
742 public:
743 
744  /// Returns true iff that is an attribute whose content can be copied
745  /// from this without any type conversions. This is important to
746  /// avoid reallocation of an attribute if its storage type,
747  /// including tuple size, matches the source attribute exactly.
748  /// Subclasses should call this first and return false if
749  /// this returns false.
750  virtual bool matchesStorage(const GA_Attribute *that) const
751  {
752  if (that == NULL)
753  return false;
754  if (getType().getTypeId() != that->getType().getTypeId())
755  return false;
756  return true;
757  }
758  /// In the case that we're copying from an attribute whose storage
759  /// type matches this exactly, this function copies the metadata
760  /// not associated with the storage, e.g. myOptions,
761  /// *excluding* the name and the data ID.
762  /// The attribute class of that must match the attribute class of that.
763  /// Subclasses must call this.
764  virtual void copyNonStorageMetadata(const GA_Attribute *that)
765  {
766  // NOTE: We shouldn't change myScope or myOptions.myDetached.
767  // For example, if we replace the contents of a private or
768  // detached attribute with those of a public one, it shouldn't
769  // (and can't) become public.
770  // myScope is more an indication of where the *detail* is keeping
771  // track of this attribute, (or not tracking, for detached.)
772  bool detached = myOptions.myDetached;
773  myOptions = that->myOptions;
774  myOptions.myDetached = detached;
775 
776  // NOTE: DO NOT set tail initialization here! This is just an
777  // indication of whether there may be data at non-default values
778  // past myIndexMap.myMaxTouchedOffset.
779  // This should be copied in the implementations of replace(),
780  // instead, since that's associated with referencing the data.
781  //setTailInitialization(that->isTailInitialize());
782  }
783 
784  /// This replaces the entirety of this attribute's content and non-
785  /// storage metadata (except the name) with that of the src attribute.
786  /// matchesStorage(src) should already return true.
787  /// This is primarily for use by GA_AttributeSet::replace().
788  /// NOTE: The internal content sizes may not match exactly if the
789  /// attribute type may overallocate, but the sizes should be such
790  /// that any real data will fit in the destination, so be careful
791  /// and deal with the myTailInitialize flag appropriately if
792  /// any extra elements aren't equal to the default.
793  virtual void replace(const GA_Attribute &src) = 0;
794 
795  /// Copy attribute values for a single element.
796  /// NOTE: The default implementation just tries to use GA_AIFCopyData,
797  /// incurring 2 more virtual calls!
798  /// @{
799  virtual bool copy(GA_Offset desti, GA_Offset srci)
800  { return copy(desti, *this, srci); }
801  virtual bool copy(GA_Offset desti, const GA_Attribute &src, GA_Offset srci);
802  /// @}
803 
804  /// Copy attribute values for a range of elements.
805  /// NOTE: The default implementation just tries to use GA_AIFCopyData,
806  /// incurring 2 more virtual calls!
807  /// WARNING: These do not support overlapping ranges within a single attribute!
808  /// @{
809  virtual bool copy(const GA_Range &destrange, const GA_Range &srcrange)
810  { return copy(destrange, *this, srcrange); }
811  virtual bool copy(const GA_Range &destrange, const GA_Attribute &src, const GA_Range &srcrange);
812  /// @}
813 
814  /// Assign all elements of a range from a single attribute value.
815  /// NOTE: The default implementation just tries to use GA_AIFCopyData,
816  /// incurring 2 more virtual calls, falling back on calling copy() for
817  /// each element in the destination range, which incurs the cost of the
818  /// virtual call for each!
819  /// @{
820  virtual bool fill(const GA_Range &destrange, GA_Offset srci)
821  { return fill(destrange, *this, srci); }
822  virtual bool fill(const GA_Range &destrange, const GA_Attribute &src, GA_Offset srci);
823  /// @}
824 private:
825  const GA_AttributeType &myType;
826  const GA_IndexMap &myIndexMap; // For mapping
827  UT_StringHolder myName; // Unprefixed name
828  GA_AttributeScope myScope; // Public or private
829  GA_AttributeOptions myOptions; // Attribute options
830  GA_AttributeProxy *myProxy; // representative referencer
831  int64 myDataId;
832  const GA_Attribute *myMergeSource; // Needed to optimize merging
833  int myAttribFlags;
834  mutable GA_CEAttribute *myCEAttribute; // OpenCL Backing.
835 };
836 
837 #define GA_GET_AIF_SPECIALIZATION(AIF_NAME) \
838  template <> SYS_STATIC_INLINE const GA_##AIF_NAME * \
839  GAgetAIF(const GA_Attribute &attrib) { return attrib.get##AIF_NAME(); } \
840  /**/
841 GA_GET_AIF_SPECIALIZATION(AIFCopyData)
846 GA_GET_AIF_SPECIALIZATION(AIFInterp)
848 GA_GET_AIF_SPECIALIZATION(AIFBlobArray)
849 GA_GET_AIF_SPECIALIZATION(AIFStringTuple)
850 GA_GET_AIF_SPECIALIZATION(AIFSharedDictTuple)
851 GA_GET_AIF_SPECIALIZATION(AIFSharedDictArray)
852 GA_GET_AIF_SPECIALIZATION(AIFSharedStringTuple)
853 GA_GET_AIF_SPECIALIZATION(AIFSharedStringArray)
854 GA_GET_AIF_SPECIALIZATION(AIFIndexPair)
855 GA_GET_AIF_SPECIALIZATION(AIFBlindData)
857 GA_GET_AIF_SPECIALIZATION(AIFCompare)
858 GA_GET_AIF_SPECIALIZATION(AIFNumericArray)
859 #undef GA_GET_AIF_SPECIALIZATION
860 
861 /// @brief Automatically expand attribute data pages for threading
862 ///
863 /// Normally, threading is allowed only if each thread is guaranteed to write
864 /// to an individual page of data. Not all algorithms are amenable to this
865 /// constraint. Using the GA_AutoThreadExpand class will force the attribute
866 /// to harden all its data pages so that multiple threads can write across page
867 /// boundaries. Multiple threads are still prohibited from writing to the same
868 /// offset. In its destructor, the class will automatically call the compress
869 /// method to regain memory efficiency. For example: @code
870 /// void process(GA_RWAttributeRef &write, GA_ROAttributeRef &read)
871 /// {
872 /// GA_AutoHardenForThreading thread_write(*write.getAttribute());
873 /// // There's no need to harden the read-only attribute, but now that
874 /// // we've hardened the write attribute, our threaded algorithm is able
875 /// // to write data across page boundaries.
876 /// UTparallelFor(range, functor(write, read));
877 /// }
878 /// @endcode
880 {
881 public:
883  GA_Offset start_offset = GA_Offset(0),
884  GA_Offset end_offset = GA_INVALID_OFFSET)
885  : myAttribute(attribute)
886  , myStart(start_offset)
887  , myEnd(end_offset)
888  {
889  // Group-scoped attributes aren't thread safe even if hardened,
890  // so if someone is using this "For Threading" they are likely
891  // in trouble.
892  UT_ASSERT(!myAttribute.isGroup());
893  myAttribute.hardenAllPages(myStart, myEnd);
894  }
896  {
897  myAttribute.tryCompressAllPages(myStart, myEnd);
898  }
899 private:
900  GA_Attribute &myAttribute;
901  GA_Offset myStart;
902  GA_Offset myEnd;
903 };
904 
905 /// Utility for updating a data id by combining it with another.
906 /// If 'other' is negative then false is returned without any updates.
907 /// To use this for combining multiple data id's, initialize id with
908 /// -1. For example: @code
909 /// GA_DataId getDataId()
910 /// {
911 /// GA_DataId id = -1;
912 /// if (!mixDataId(id, myDataId0))
913 /// return -1;
914 /// if (!mixDataId(id, myDataId1))
915 /// return -1;
916 /// return id;
917 /// }
918 /// @endcode
919 static inline bool
920 GAcombineDataId(GA_DataId &id, GA_DataId other)
921 {
922  if (other < 0)
923  return false;
924  if (other > id)
925  id = other;
926  return true;
927 }
928 
930 
932 
933 #endif
A class to manage an ordered array which has fixed offset handles.
Definition: GA_IndexMap.h:63
GA_CEAttribute * getCEAttribute(GA_StorageClass storage, int &tuplesize, bool isarray, bool read, bool write)
Definition: GA_Attribute.h:657
UT_UniquePtr< const GA_Attribute > GA_ConstAttributeUPtr
Definition: GA_Attribute.h:931
SYS_FORCE_INLINE void bumpDataId()
Definition: GA_Attribute.h:305
Definition of a geometry attribute.
Definition: GA_Attribute.h:197
GLuint counter
Definition: glew.h:2745
Generic Attribute Interface class to access an attribute as a array.
Generic Attribute Interface class to get/set data as index pairs.
virtual bool copy(const GA_Range &destrange, const GA_Range &srcrange)
Definition: GA_Attribute.h:809
void setTypeInfo(GA_TypeInfo t)
Definition: GA_Attribute.h:99
UT_IntrusivePtr< GA_AttributeProxy > GA_AttributeProxyHandle
UT_IntrusivePtr< const GA_AttributeProxy > GA_ConstAttributeProxyHandle
A specialization of GA_AIFDictTuple to access "shared strings".
bool exportOnSave(bool defval=false) const
Definition: GA_Attribute.h:127
GA_StorageClass
Definition: GA_Types.h:71
Attribute Interface class to perform numeric operations on attributes.
Definition: GA_AIFMath.h:88
OIIO_UTIL_API bool copy(string_view from, string_view to, std::string &err)
int64 GA_DataId
Definition: GA_Types.h:686
GA_Precision
Definition: GA_Types.h:86
GA_Attribute * create(const GA_IndexMap &index_map, GA_AttributeScope scope, const UT_StringHolder &name, const UT_Options *creation_options, const GA_AttributeOptions *attribute_options) const
Attribute Interface for accessing generic blob data.
GA_ConstAttributeProxyHandle getProxy() const
Definition: GA_Attribute.h:221
The merge map keeps track of information when merging details.
Definition: GA_MergeMap.h:53
void setExportOnMerge(bool v)
Set the export on merge flag.
Definition: GA_Attribute.h:116
void setExportOnSave(bool v)
Set the export on save flag.
Definition: GA_Attribute.h:130
bool hasFlag(AttribFlag flag) const
Definition: GA_Attribute.h:235
void setExportToInfoBlock(bool v)
Definition: GA_Attribute.h:103
JSON reader class which handles parsing of JSON or bJSON files.
Definition: UT_JSONParser.h:88
#define GA_API
Definition: GA_API.h:14
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:35
void setExistedPriorToStream(bool preexisted)
Definition: GA_Attribute.h:697
GLuint const GLchar * name
Definition: glcorearb.h:786
#define GA_INVALID_DATAID
Definition: GA_Types.h:687
virtual bool matchesStorage(const GA_Attribute *that) const
Definition: GA_Attribute.h:750
GLenum src
Definition: glcorearb.h:1793
const UT_StringHolder & getName() const
Definition: GA_Attribute.h:282
SYS_FORCE_INLINE int getTypeId() const
float fpreal32
Definition: SYS_Types.h:200
void read(T &in, bool &v)
Definition: ImfXdr.h:502
GLdouble GLdouble t
Definition: glew.h:1403
FMT_NOINLINE FMT_CONSTEXPR auto fill(OutputIt it, size_t n, const fill_t< Char > &fill) -> OutputIt
Definition: format.h:1262
No concurrent writes supported.
Definition: GA_Attribute.h:364
#define GA_INVALID_OFFSET
Definition: GA_Types.h:677
A range of elements in an index-map.
Definition: GA_Range.h:42
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
GLsizeiptr size
Definition: glcorearb.h:664
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
double fpreal64
Definition: SYS_Types.h:201
GA_Size GA_Offset
Definition: GA_Types.h:640
SYS_FORCE_INLINE void cloneDataId(const GA_Attribute &src, bool allow_clear=false)
Definition: GA_Attribute.h:323
virtual bool fill(const GA_Range &destrange, GA_Offset srci)
Definition: GA_Attribute.h:820
void setFlag(AttribFlag flag, bool onoff)
Definition: GA_Attribute.h:238
GA_AttributeScope
Definition: GA_Types.h:141
Attribute Interface for accessing generic blob data.
Definition: GA_AIFBlob.h:39
Automatically expand attribute data pages for threading.
Definition: GA_Attribute.h:879
const UT_StringHolder & getFullName() const
Definition: GA_Attribute.h:283
Attribute Interface for merging attribute data between details.
Definition: GA_AIFMerge.h:56
bool isGroup() const
Definition: GA_Attribute.h:212
This class holds a reference to an attribute. Such an indirection level allows an easy way to invalid...
const GLdouble * v
Definition: glcorearb.h:837
const UT_Options * options() const
Definition: GA_Attribute.h:149
std::string OIIO_UTIL_API replace(string_view str, string_view pattern, string_view replacement, bool global=false)
bool needsTransform(bool include_P=true) const
Definition: GA_Attribute.h:436
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
Class to fill GA_Stat information about an attribute. This AIF is used to fill GA_Stat type informati...
Definition: GA_AIFStat.h:30
A specialization of GA_AIFStringArray to access "shared strings".
GA_AutoHardenForThreading(GA_Attribute &attribute, GA_Offset start_offset=GA_Offset(0), GA_Offset end_offset=GA_INVALID_OFFSET)
Definition: GA_Attribute.h:882
void mergeOptions(const GA_AttributeOptions &src)
Merge the options passed in with the options in the attribute.
Definition: GA_Attribute.h:463
long long int64
Definition: SYS_Types.h:116
Attribute Interface class to perform comparisons on attributes.
Definition: GA_AIFCompare.h:27
GLfloat GLfloat p
Definition: glew.h:16656
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
Defragmentation of IndexMaps.
Definition: GA_Defragment.h:45
void setLeaveOnGPU(bool v)
Definition: GA_Attribute.h:105
OPENVDB_API void initialize()
Global registration of native Grid, Transform, Metadata and Point attribute types. Also initializes blosc (if enabled).
Definition: logging.h:294
SYS_FORCE_INLINE GA_DataId getDataId() const
Definition: GA_Attribute.h:298
GA_AttributeOptions & getOptions()
Definition: GA_Attribute.h:420
GA_AttributeScope getScope() const
Definition: GA_Attribute.h:211
virtual void copyNonStorageMetadata(const GA_Attribute *that)
Definition: GA_Attribute.h:764
GA_TypeInfo
Definition: GA_Types.h:99
UT_UniquePtr< GA_Attribute > GA_AttributeUPtr
Definition: GA_Attribute.h:929
#define GA_GET_AIF_SPECIALIZATION(AIF_NAME)
Definition: GA_Attribute.h:837
const GA_AttributeType & getType() const
Definition: GA_Attribute.h:205
bool exportToInfoBlock() const
Definition: GA_Attribute.h:102
GT_API const UT_StringHolder version
GLenum GLint GLint * precision
Definition: glcorearb.h:1925
SYS_FORCE_INLINE void clearDataId()
Definition: GA_Attribute.h:311
GLuint GLfloat * val
Definition: glcorearb.h:1608
GA_AttributeOwner
Definition: GA_Types.h:33
A map of string to various well defined value types.
Definition: UT_Options.h:84
bool exportOnMergeSet() const
Definition: GA_Attribute.h:110
void setDetached(bool detached)
Only called by GA_AttributeSet and GA_ElementGroup.
Definition: GA_Attribute.h:707
void setActivelyStreamed(bool isstreaming)
Definition: GA_Attribute.h:688
SYS_FORCE_INLINE GA_TypeInfo getTypeInfo() const
Definition: GA_Attribute.h:251
bool leaveOnGPU() const
Definition: GA_Attribute.h:104
const GA_IndexMap & getIndexMap() const
Definition: GA_Attribute.h:206
virtual bool copy(GA_Offset desti, GA_Offset srci)
Definition: GA_Attribute.h:799
void reconstructElement(GA_Offset offset)
Definition: GA_Attribute.h:494
const T * getAIF() const
Generic method for getting an AIF by type.
Definition: GA_Attribute.h:415
GA_TypeInfo typeInfo() const
Definition: GA_Attribute.h:98
bool isStringSet(bool defval=false) const
Definition: GA_Attribute.h:138
const GA_AttributeOptions & getOptions() const
Definition: GA_Attribute.h:419
A specialization of GA_AIFDictArray to access "shared strings".
A specialization of GA_AIFStringTuple to access "shared strings".
Concurrent writes to separate pages supported.
Definition: GA_Attribute.h:366
Attribute Interface for blind data per element.
bool isNonTransforming() const
Definition: GA_Attribute.h:100
#define SYS_UNIMPLEMENTED_TEMPLATE(T)
OIIO_API bool attribute(string_view name, TypeDesc type, const void *val)
bool exportOnSaveSet() const
Definition: GA_Attribute.h:124
bool isDetached() const
Definition: GA_Attribute.h:444
getOption("OpenEXR.storage") storage
Definition: HDK_Image.dox:276
Container class for all geometry.
Definition: GA_Detail.h:95
Attribute Interface class to copy attribute data.
void setNonTransforming(bool val)
Definition: GA_Attribute.h:428
bool isTailInitialization() const
Check whether the attribute is set to tail initialization.
Definition: GA_Attribute.h:487
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:153
GLintptr offset
Definition: glcorearb.h:665
bool existedPriorToStream() const
Definition: GA_Attribute.h:694
SYS_FORCE_INLINE void assignNewDataId()
Definition: GA_Attribute.h:300
Attribute Interface for file I/O.
Definition: GA_AIFJSON.h:39
void setIsNonTransforming(bool v)
Definition: GA_Attribute.h:101
SYS_FORCE_INLINE void setTypeInfo(GA_TypeInfo type)
Definition: GA_Attribute.h:259
type
Definition: core.h:1059
bool exportOnMerge(bool defval=false) const
Definition: GA_Attribute.h:113
void write(T &out, bool v)
Definition: ImfXdr.h:287
AIF to record changes to attribute values.
Definition: GA_AIFEdit.h:397
SYS_FORCE_INLINE void cloneOrBumpDataId(const GA_Attribute &src, bool allow_clear=false)
NOTE: Just call cloneDataId(src).
Definition: GA_Attribute.h:333
Generic Attribute Interface class to access an attribute as a tuple.
Definition: GA_AIFTuple.h:32
Definition: format.h:895
bool isActivelyStreamed() const
Definition: GA_Attribute.h:685
Generic Attribute Interface class to work with string indices directly, rather than string values...
void setIsStringSet(bool v)
Set the "string set" flag.
Definition: GA_Attribute.h:141
GA_AttributeProxyHandle getProxy()
Definition: GA_Attribute.h:219