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