HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GA_ATITopology.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_ATITopology.h ( GA Library, C++)
7  *
8  * COMMENTS: Topology ATI (Attribute Type Implementation)
9  *
10  * Topology attributes are used to store information about how
11  * elements are connected together.
12  */
13 
14 #pragma once
15 
16 #ifndef __GA_ATITopology__
17 #define __GA_ATITopology__
18 
19 #define USE_PAGEARRAY_TOPOLOGY 1
20 #if USE_PAGEARRAY_TOPOLOGY
21 #include "GA_PageArray.h"
22 #else
23 #include "GA_DataArray.h"
25 #endif
26 
27 #include "GA_API.h"
28 #include "GA_Attribute.h"
29 #include "GA_AttributeType.h"
30 #include "GA_IndexMap.h"
31 #include "GA_Types.h"
32 
33 #include <UT/UT_Assert.h>
34 #include <UT/UT_StringHolder.h>
35 #include <SYS/SYS_Types.h>
36 
37 
38 class GA_AIFCopyData;
39 class GA_AIFMerge;
40 class GA_Defragment;
41 class GA_LoadMap;
42 class GA_MergeMap;
43 class GA_SaveMap;
44 class UT_JSONParser;
45 class UT_JSONWriter;
46 
48 {
49 public:
50  static void registerType();
51  static GA_ATITopology *create(
52  const GA_IndexMap &index_map,
53  GA_AttributeScope scope,
54  const UT_StringHolder &name,
55  GA_AttributeOwner linkowner);
57  static const GA_AttributeType &getType() { return *theAttributeType; }
59  static const UT_StringHolder &getTypeName()
60  { return theAttributeType->getTypeName(); }
61 
63  static bool isType(const GA_Attribute *attrib)
64  {
65  return attrib && &attrib->getType() == theAttributeType;
66  }
68  static GA_ATITopology *cast(GA_Attribute *attrib)
69  {
70  if (attrib && &attrib->getType() == theAttributeType)
71  return static_cast<GA_ATITopology *>(attrib);
72  return NULL;
73  }
75  static const GA_ATITopology *cast(const GA_Attribute *attrib)
76  {
77  if (attrib && &attrib->getType() == theAttributeType)
78  return static_cast<const GA_ATITopology *>(attrib);
79  return NULL;
80  }
81 
83  const GA_AttributeType &type,
84  const GA_IndexMap &index_map,
85  GA_AttributeScope scope,
86  const UT_StringHolder &name,
87  GA_AttributeOwner linkowner);
88  ~GA_ATITopology() override;
89 
90  /// Report memory used
91  int64 getMemoryUsage(bool inclusive) const override;
92 
93  void countMemory(UT_MemoryCounter &counter, bool inclusive) const override;
94 
95  /// We do not need to implement the reconstructElement() method as the
96  /// GA_Topology owner explicitly initializes each value as the element
97  /// is added.
98  /// TODO: Ideally we'd do so in reconstructElement() to avoid useless
99  /// work when elements are first constructed.
100 
101  /// Data is paged, so concurrent writes to separate pages supported.
103  { return WRITE_CONCURRENCE_PAGE; }
104 
105  /// Merge interface
106  const GA_AIFMerge *getAIFMerge() const override
107  { return theAIFMerge; }
108 
109  bool mergeAppendData(const GA_MergeMap &map,
110  const GA_ATITopology &sattrib);
111 
112  const GA_AIFCopyData *getAIFCopyData() const override
113  { return theAIFCopyData; }
114 
115  /// @{
116  /// Vertex references are managed via multiple coupled attributes, so
117  /// AIF_Merge cannot resolve non-trivial vertex merges. Instead, the
118  /// AIF will set this flag and let GA_Topology::mergeRebuild() handle
119  /// updating the vertex reference attributes.
120  bool getUnresolvedMergeFlag() const { return myUnresolvedMerge; }
121  void setUnresolvedMergeFlag(bool f) { myUnresolvedMerge = f; }
122  /// @}
123 
126  {
127  UT_ASSERT_P(getIndexMap().isOffsetInRange(ai));
128 
129 #if USE_PAGEARRAY_TOPOLOGY
130  return GA_Offset(myData.getGuaranteedInt(ai));
131 #else
132  if (myDataPageTableI16)
133  return GA_Offset(myDataPageTableI16->get(ai));
134  if (myDataPageTableI32)
135  return GA_Offset(myDataPageTableI32->get(ai));
136  return GA_Offset(myDataPageTableI64->get(ai));
137 #endif
138  }
139 
142  {
143  UT_ASSERT_P(getIndexMap().isOffsetInRange(ai));
144 
145 #if USE_PAGEARRAY_TOPOLOGY
146  UT_ASSERT_P(ai < myData.size());
147  myData.set(ai, int64(v));
148  UT_ASSERT_P(myData.getGuaranteedInt(ai) == int64(v));
149 #else
150  UT_ASSERT_P(ai < myData->getArraySize());
151  if (myDataPageTableI16)
152  {
153  myDataPageTableI16->set(ai, v);
154  }
155  else if (myDataPageTableI32)
156  {
157  myDataPageTableI32->set(ai, v);
158  }
159  else
160  {
161  myDataPageTableI64->set(ai, v);
162  }
163 #endif
164  }
165 
167  bool isPageConstant(GA_PageNum pageno) const
168  {
169  return myData.isPageConstant(pageno);
170  }
171 
172  /// Sets all links for offsets >= start and < end to value.
173  void setLinksConstant(GA_Offset start, GA_Offset end, GA_Offset value);
174 
175  /// Set all values to the default
176  void clear();
177 
179  {
180 #if USE_PAGEARRAY_TOPOLOGY
181  return myData.getStorage();
182 #else
183  return myData->getStorage();
184 #endif
185  }
186  bool setStorage(GA_Storage storage);
187 
188  /// Returns true iff that is an attribute whose content can be copied
189  /// from this without any type conversions. This is important to
190  /// avoid reallocation of an attribute if its storage type,
191  /// including tuple size, matches the source attribute exactly.
192  bool matchesStorage(const GA_Attribute *that) const override
193  {
194  if (!GA_Attribute::matchesStorage(that))
195  return false;
196  const GA_ATITopology *thatn = UTverify_cast<const GA_ATITopology *>(that);
197  if (getStorage() != thatn->getStorage())
198  return false;
199  return true;
200  }
201 
202  /// This replaces the entirety of this attribute's content and non-
203  /// storage metadata (except the name) with that of the src attribute.
204  /// matchesStorage(src) should already return true.
205  /// This is primarily for use by GA_AttributeSet::replace().
206  /// NOTE: The internal content sizes may not match exactly if the
207  /// attribute type may overallocate, but the sizes should be such
208  /// that any real data will fit in the destination, so be careful
209  /// and deal with the myTailInitialize flag appropriately if
210  /// any extra elements aren't equal to the default.
211  void replace(const GA_Attribute &src) override;
212 
213  /// Query the owner type of the link stored in this attribute. For
214  /// example, the vertex PointRef attribute would have:
215  /// getOwner() == GA_ATTRIB_VERTEX
216  /// getLinkOwner() == GA_ATTRIB_POINT
217  GA_AttributeOwner getLinkOwner() const { return myLinkOwner; }
218 
219  /// Save to a JSON stream.
220  /// @section JSON-GA_ATITopology JSON Schema: GA_ATITopology
221  /// @code
222  /// {
223  /// "name" : "GA_ATITopology",
224  /// "description" : "An tuple array of indexed strings",
225  /// "type" : "orderedmap",
226  /// "properties": {
227  /// "data": {
228  /// "type" : "indices",
229  /// "items" : "integer",
230  /// "description" : "Integer reference indices.",
231  /// },
232  /// },
233  /// }
234  /// @endcode
235  /// @see @ref JSON_FileFormat
236  /// @note There is no GA_AIFJSON interface for topology.
237  bool jsonSave(UT_JSONWriter &w, const GA_SaveMap &map) const;
238 
239  /// Load from a JSON stream.
240  /// @note There is no GA_AIFJSON interface for topology.
241  bool jsonLoad(UT_JSONParser &p, const GA_LoadMap &map);
242 
243 #if USE_PAGEARRAY_TOPOLOGY
245 
246  /// @{
247  /// Provide access to data
248  const DataType &getData() const { return myData; }
249  DataType &getData() { return myData; }
250  /// @}
251 #else
252  /// @{
253  /// Provide access to data
254  const GA_DataArray &getData() const { return *myData; }
255  GA_DataArray &getData() { return *myData; }
256  /// @}
257 #endif
258 
259  /// Grow or shrink the array size
260  bool setArraySize(GA_Offset new_size) override;
261 
262  /// Try to compress data pages
263  void tryCompressAllPages(
264  GA_Offset start_offset = GA_Offset(0),
265  GA_Offset end_offset = GA_INVALID_OFFSET) override;
266  /// Harden data pages
267  void hardenAllPages(
268  GA_Offset start_offset = GA_Offset(0),
269  GA_Offset end_offset = GA_INVALID_OFFSET) override;
270 
271 private:
272  // Defragmentation functions should only be called internally or from GA_Topology.
273  friend class GA_Topology;
274 
275  /// @{
276  /// Interface for defragmentation
277  /// This implementation does nothing, because defragmentation
278  /// of topology attributes must be handled separately.
279  void defragment(const GA_Defragment &defrag) override;
280  /// @}
281 
282  /// Reconstruction does nothing because topology attributes
283  /// are always handled explicitly on alloc/free
284  void reconstructElementBlock(GA_Offset offset, GA_Offset nelements) override
285  { }
286 
287  /// Swap the elements in the array
288  void swapElements(GA_Offset a, GA_Offset b, GA_Size n);
289  /// Move elements in the array from a to b
290  void moveElements(GA_Offset a, GA_Offset b, GA_Size n);
291 
292  /// Change the values in the array
293  /// This bumps the attribute's data ID iff myData != NULL
294  /// and getLinkOwner() != getOwner().
295  void swapLinks(const GA_Defragment &defrag);
296 
297  /// Set the link data type
298  void setLinkOwner(GA_AttributeOwner t) { myLinkOwner = t; }
299 
300 #if USE_PAGEARRAY_TOPOLOGY
301  DataType myData;
302 #else
303  /// Rebuild our direct page pointers.
304  /// Must be invoked if the page type changes.
305  void updatePagePointers();
306 
307  GA_DataArray *myData;
308 #endif
309  GA_AttributeOwner myLinkOwner;
310  bool myUnresolvedMerge;
311 
312 #if !USE_PAGEARRAY_TOPOLOGY
314  *myDataPageTableI16;
316  *myDataPageTableI32;
318  *myDataPageTableI64;
319 #endif
320 
321  static const GA_AIFMerge *theAIFMerge;
322  static const GA_AIFCopyData *theAIFCopyData;
323  static const GA_AttributeType *theAttributeType;
324 
325  friend class ga_TopologyCopy;
326 };
327 
328 #endif
A class to manage an ordered array which has fixed offset handles.
Definition: GA_IndexMap.h:63
static SYS_FORCE_INLINE bool isType(const GA_Attribute *attrib)
Definition of a geometry attribute.
Definition: GA_Attribute.h:198
GA_Storage getStorage() const
Used to pass options and map offset values during saving.
Definition: GA_SaveMap.h:48
const GA_AIFMerge * getAIFMerge() const override
Merge interface.
SYS_FORCE_INLINE GA_Offset getLink(GA_Offset ai) const
static SYS_FORCE_INLINE const UT_StringHolder & getTypeName()
getFileOption("OpenEXR:storage") storage
Definition: HDK_Image.dox:276
const GLdouble * v
Definition: glcorearb.h:837
SYS_FORCE_INLINE const GA_IndexMap & getIndexMap() const
Definition: GA_Attribute.h:207
GLuint start
Definition: glcorearb.h:475
SYS_FORCE_INLINE bool isPageConstant(GA_PageNum pageno) const
The merge map keeps track of information when merging details.
Definition: GA_MergeMap.h:53
virtual void reconstructElementBlock(GA_Offset offset, GA_Offset nelements)=0
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
WriteConcurrence getSupportedWriteConcurrence() const override
Data is paged, so concurrent writes to separate pages supported.
bool matchesStorage(const GA_Attribute *that) const override
JSON reader class which handles parsing of JSON or bJSON files.
Definition: UT_JSONParser.h:87
virtual bool setArraySize(GA_Offset size)=0
#define GA_API
Definition: GA_API.h:14
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:37
SYS_FORCE_INLINE TO_T UTverify_cast(FROM_T from)
Definition: UT_Assert.h:229
virtual void countMemory(UT_MemoryCounter &counter, bool inclusive) const =0
virtual int64 getMemoryUsage(bool inclusive) const =0
virtual bool matchesStorage(const GA_Attribute *that) const
Definition: GA_Attribute.h:751
static SYS_FORCE_INLINE const GA_ATITopology * cast(const GA_Attribute *attrib)
GA_PageArray< void, 1, true, false > DataType
virtual void tryCompressAllPages(GA_Offset start_offset=GA_Offset(0), GA_Offset end_offset=GA_INVALID_OFFSET)=0
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:235
SYS_FORCE_INLINE const GA_AttributeType & getType() const
Definition: GA_Attribute.h:206
#define GA_INVALID_OFFSET
Definition: GA_Types.h:678
GA_AttributeOwner getLinkOwner() const
GA_Size GA_Offset
Definition: GA_Types.h:641
DataType & getData()
GA_AttributeScope
Definition: GA_Types.h:142
GLdouble n
Definition: glcorearb.h:2008
GLfloat f
Definition: glcorearb.h:1926
void setUnresolvedMergeFlag(bool f)
GLintptr offset
Definition: glcorearb.h:665
virtual void replace(const GA_Attribute &src)=0
Attribute Interface for merging attribute data between details.
Definition: GA_AIFMerge.h:56
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:155
GLuint GLuint end
Definition: glcorearb.h:475
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
const GA_AIFCopyData * getAIFCopyData() const override
Return the attribute's copy interface or NULL.
static SYS_FORCE_INLINE GA_ATITopology * cast(GA_Attribute *attrib)
An array of numbers with various storage types.
Definition: GA_DataArray.h:49
long long int64
Definition: SYS_Types.h:116
Options during loading.
Definition: GA_LoadMap.h:42
Defragmentation of IndexMaps.
Definition: GA_Defragment.h:45
bool getUnresolvedMergeFlag() const
GLuint const GLchar * name
Definition: glcorearb.h:786
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
GLdouble t
Definition: glad.h:2397
GA_AttributeOwner
Definition: GA_Types.h:34
GA_Size GA_PageNum
Definition: GA_Types.h:644
Concurrent writes to separate pages supported.
Definition: GA_Attribute.h:367
Attribute Interface class to copy attribute data.
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
Definition: core.h:1131
const DataType & getData() const
type
Definition: core.h:1059
virtual void hardenAllPages(GA_Offset start_offset=GA_Offset(0), GA_Offset end_offset=GA_INVALID_OFFSET)=0
virtual void defragment(const GA_Defragment &defrag)=0
GA_Storage
Definition: GA_Types.h:50
static SYS_FORCE_INLINE const GA_AttributeType & getType()
GLenum src
Definition: glcorearb.h:1793
SYS_FORCE_INLINE void setLink(GA_Offset ai, GA_Offset v)