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