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