HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GT_AttributeList.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: GT_AttributeList.h ( GT Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GT_AttributeList__
12 #define __GT_AttributeList__
13 
14 #include "GT_API.h"
15 #include "GT_AttributeMap.h"
16 #include "GT_DataArray.h"
17 #include "GT_Handles.h"
18 #include "GT_Types.h"
19 
20 #include <UT/UT_Assert.h>
21 #include <UT/UT_IntrusivePtr.h>
22 #include <UT/UT_StringHolder.h>
23 #include <SYS/SYS_Inline.h>
24 
25 #include <utility>
26 
27 
28 class GT_DataArray;
29 class GT_AttributeMerge;
30 class GT_GEOOffsetList;
31 class UT_JSONWriter;
32 class GU_Detail;
33 
35  : public UT_IntrusiveRefCounter<GT_AttributeList>
36 {
37 public:
38  /// An attribute list stores a list of GT_DataArray values for each
39  /// attribute defined in the map. @c motion_segments specifies the number
40  /// of different motion segments.
41  GT_AttributeList(const GT_AttributeMapHandle &map, int motion_segments=1);
44 
45  /// Create an attribute list using varying number of
46  /// (const UT_StringHolder &name, const GT_DataArrayHandle &data) pairs.
47  /// For example: @code
48  /// GT_AttributeList::createAttributeList(
49  /// "P", new GT_Real32Array(...),
50  /// "N", new GT_Real32Array(...),
51  /// "uv", new GT_Real32Array(...));
52  /// @endcode
53  template <typename... Pairs>
55  {
56  int n = gt_CountAttribs(std::forward<Pairs>(pairs)...);
58  list(new GT_AttributeList(n, new GT_AttributeMap(n), 1));
59  gt_CreateAttributeList(*list, *list->getMap(),
60  std::forward<Pairs>(pairs)...);
61  return list;
62  }
63 
64  /// Test whether two attribute lists match in their definition. If both
65  /// attribute lists are empty, this will count as a match.
66  static bool matchDefinition(const GT_AttributeListHandle &a,
67  const GT_AttributeListHandle &b);
68 
69 
70  /// Create a new attribute list, adding a new attribute in the process.
71  GT_AttributeListHandle addAttribute(const UT_StringHolder &name,
72  const GT_DataArrayHandle *handles,
73  int num_segments,
74  bool replace_existing) const;
76  const GT_DataArrayHandle &h,
77  bool replace_existing) const
78  {
79  return addAttribute(name, &h, 1, replace_existing);
80  }
81 
82  /// Remove an attribute from this list, returning a new attribute list.
83  GT_AttributeListHandle removeAttribute(const UT_StringRef &name) const;
84 
85  /// Remove multiple attributes from this, returning a new attribute list.
86  GT_AttributeListHandle removeAttributes(const UT_StringArray &name) const;
87 
88 
89  /// Harden all the attribute lists
90  void harden();
91 
92  /// Harden a single attribute
93  void harden(int idx);
94 
95  /// Get a handle to the name map for this list.
96  const GT_AttributeMapHandle &getMap() const { return myMap; }
97 
98  /// Return the number of attributes in the list.
99  int entries() const
100  { return myMap->entries(); }
101 
102  /// Return the approximate memory usage. Because data can be shared, this
103  /// may not reflect the usage accurately.
104  int64 getMemoryUsage() const;
105 
106  /// Return the number of motion segements
107  int getSegments() const
108  { return myMotionSegments; }
109 
110  /// Return the list of names
111  const UT_StringArray &getNames() const
112  { return myMap->getNames(); }
113 
114  /// Return the data for the named array
116  int segment=0) const
117  {
118  return get(myMap->get(name), segment);
119  }
120  /// Return the data for a given index
121  const GT_DataArrayHandle &get(int index, int motion_segment=0) const;
122 
123  /// Return the name for a given index
124  const UT_StringHolder &getName(int index) const
125  { return myMap->getName(index); }
126 
127  /// Return the export name for a given index.
129  { return myMap->getExportName(index); }
130 
131  /// Get original attribute owner for the given attribute.
132  GT_Owner getOriginalOwner(int idx) const
133  { return myMap->getOriginalOwner(idx); }
134 
135  /// Return the index for a given name (returns -1 if miss)
136  int getIndex(const UT_StringRef &name) const
137  { return myMap->get(name); }
138 
139  /// Test of an attribute name exists
140  bool hasName(const UT_StringRef &name) const
141  { return myMap->hasName(name); }
142 
143  /// Assign an array to a given index in the list.
144  void set(int idx, const GT_DataArrayHandle &h,
145  int motion_segment=0);
146 
147  /// Assign an array to a given index in the list for @b all motion segments
148  void setAllSegments(int idx,
149  const GT_DataArrayHandle &h);
150 
151  /// Copies an entire segment of data arrays from a source list to this list.
152  /// This is useful when combining multiple primitives into a single motion
153  /// blurred primitive for example.
154  /// @param dest_segment @n
155  /// Data arrays are copied to this segment in this list
156  /// @param source_list @n
157  /// Data arrays are copied from this source list
158  /// @param source_segment @n
159  /// Data arrays are copied from this segment in the source_list
160  /// @warning The source attribute list @b must have the same maps. The
161  /// code does @b not verify that the maps are the same.
162  bool copySegment(int dest_segment,
163  const GT_AttributeListHandle &source_list,
164  int source_segment=0);
165 
166  /// Create a transformed version of the attributes
168 
169  /// Create a new attribute list containing
170  GT_AttributeListHandle createConstant(GT_Offset offset,
171  GT_Size size) const;
172 
173  /// Create an attribute list of a subset of the contents
174  GT_AttributeListHandle createSubArray(GT_Offset start,
175  GT_Size size) const;
176 
177  /// Create a new attribute list based on the indirect indicies in the
178  /// @c list
179  GT_AttributeListHandle createIndirect(
181  bool flatten_nested = true) const;
182 
183  /// Create a new attribute list promoted to vertex frequency by setting
184  /// the offsets in any GT_GEOElementArrays (for performance reasons)
185  /// Any non-element arrays will use createIndirect() instead.
186  GT_AttributeListHandle promoteToVertex(const GT_GEOOffsetList &off,
187  const GT_DataArrayHandle &ind) const;
188 
189  /// Merge attributes which don't already exist in this attribute list
190  GT_AttributeListHandle mergeNewAttributes(
191  const GT_AttributeListHandle &s,
192  bool replace_existing = false) const;
193 
194  /// Create the "s" and "t" attributes for the given u/v vertex count.
195  /// The attributes will only be created if @c nu or @c nv is greater than 0
196  GT_AttributeListHandle createUV(int nu, int nv,
197  fpreal64 s0=0, fpreal64 s1=1,
198  fpreal64 t0=0, fpreal64 t1=1) const;
199 
200  /// Create a merged list of the two lists. This will merge a sub-array of
201  /// the first list and an indirect mapping of the second list.
202  /// This is used to merge a vertex list (l0) with a point list (l1)
203  static GT_AttributeListHandle createMerged(
204  const GT_AttributeMerge &map,
205  const GT_AttributeListHandle &l0,
206  GT_Offset l0_offset, GT_Size l0_size,
207  const GT_AttributeListHandle &l1,
208  const GT_DataArrayHandle &l1_indirect);
209 
210  /// Merge two lists, expanding the constant list to have arrays matching
211  /// the length of the varying array.
212  static GT_AttributeListHandle expandConstantMerge(
213  const GT_AttributeMerge &map,
214  const GT_AttributeListHandle &varying,
215  const GT_AttributeListHandle &constant,
216  GT_Offset const_index=0);
217 
218  /// Merge two lists, creating a constant value list, selecting a single
219  /// element from a varying list.
220  static GT_AttributeListHandle createConstantMerge(
221  const GT_AttributeMerge &map,
222  const GT_AttributeListHandle &varying,
224  const GT_AttributeListHandle &constant);
225 
226  /// Merge an array of N lists to form a single attribute list. All the
227  /// data is concatenated in order.
228  ///
229  /// This method will fail (return an empty list) if any lists don't have
230  /// matching attributes (including motion segments & order of attributes)
231  ///
232  /// The list may have NULL handles.
233  static GT_AttributeListHandle concatenateLists(
235 
236  /// Get a 64b hash of all data ids in the list. Return false if any attribs
237  /// have an invalid data id (-1)
238  bool getDataIdHash(int64 &hash, int segment=0) const;
239 
240  /// Refresh the any detail references and data IDs on all data arrays.
241  void updateGeoDetail(const GU_ConstDetailHandle &dtl,
242  GT_Owner scope) const;
243 
244  /// Debug method to dump the list to stdout
245  void dumpList(const char *label="", bool data_too = true);
246 
247  /// Save to a JSON stream
248  bool save(UT_JSONWriter &w) const;
249 
251  {
252  public:
254  : myList(NULL), myCurr(0), mySize(0), mySegment(0) {}
255  iterator(const iterator &src)
256  { *this = src; }
258 
260  {
261  return myList->get(myCurr,
262  mySegment);
263  }
264  const UT_StringHolder &getName() const
265  {
266  return myList->getName(myCurr);
267  }
268 
269  void rewind() { myCurr = 0; }
270  void advance() { myCurr++; }
271  bool atEnd() const { return myCurr >= mySize; }
272 
273  iterator &operator++() { advance(); return *this; }
274  // No post increment as it is dangerous.
275  const iterator &operator=(const iterator &src)
276  {
277  myList = src.myList;
278  myCurr = src.myCurr;
279  mySize = src.mySize;
280  return *this;
281  }
282 
283  private:
284  iterator(const GT_AttributeList *list, int segment)
285  : myList(list),
286  mySegment(segment),
287  myCurr(0),
288  mySize(list->entries()) {}
289 
290  const GT_AttributeList *myList;
291  int myCurr, mySize, mySegment;
292  friend class GT_AttributeList;
293  };
294  /// Traverse over all attributes for a given motion segment
295  iterator begin(int segment=0) const { return iterator(this, segment); }
296 
297  // Forward declare nested class (and make it a friend)
298  class gt_CreateIndirectTask;
299  friend class gt_CreateIndirectTask;
300 
301 private:
302 
303  // Private constructor for createAttributeList() only
305  int motion_segments);
306 
307  static SYS_FORCE_INLINE int
308  gt_CountAttribs()
309  {
310  return 0;
311  }
312  template <typename DataT, typename... Pairs>
313  static int
314  gt_CountAttribs(const UT_StringRef &name, DataT&& data,
315  Pairs&&... pairs)
316  {
317  return (data ? 1 : 0) + gt_CountAttribs(std::forward<Pairs>(pairs)...);
318  }
319 
320  static SYS_FORCE_INLINE void
321  gt_CreateAttributeList(GT_AttributeList &, GT_AttributeMap &)
322  {
323  }
324  template <typename DataT, typename... Pairs>
325  static void
326  gt_CreateAttributeList(
327  GT_AttributeList &list, GT_AttributeMap &map,
328  const UT_StringHolder &name, DataT&& data,
329  Pairs&&... pairs)
330  {
331  // Ignore NULL data arrays. Makes it easier to make lists where it's
332  // not known if some of the data arrays are valid at compile time.
333  if (data)
334  {
335  int i = map.add(name, /*replace*/false);
336  UT_ASSERT_MSG(i >= 0, "Should not have duplicates!");
337  list.set(i, data);
338  }
339  gt_CreateAttributeList(list, map, std::forward<Pairs>(pairs)...);
340  }
341 
342 private:
343  /// Create a new constant data array for the i'th element
344  const GT_DataArrayHandle createConstant(int idx, GT_Offset offset,
345  GT_Size size,
346  int segment) const;
347 
348  /// Create a new sub-array data array for the i'th element
349  const GT_DataArrayHandle createSubArray(int idx, GT_Offset start,
350  GT_Size size,
351  int segment) const;
352 
353  /// Create a new sub-array data array for the i'th element
354  const GT_DataArrayHandle createIndirect(
355  int idx,
357  int segment,
358  bool flatten_nested) const;
359 
360  inline int getSegmentIndex(int index, int segment) const
361  { return index + segment*entries(); }
362 
363  // Keep the 32 bit int first in the structure. Since we inherit from
364  // GA_IntrusiveRefCounter, this alignment makes the object smaller.
365  int myMotionSegments;
366  const GT_AttributeMapHandle myMap;
367  GT_DataArrayHandle *myData;
368 
369  // For threading of creating indirect arrays
370 };
371 
372 #endif
Keep track of merging of attribute maps.
GLuint GLsizei const GLchar * label
Definition: glcorearb.h:2545
GLenum const void * lists
Definition: glad.h:2100
void set(int idx, const GT_DataArrayHandle &h, int motion_segment=0)
Assign an array to a given index in the list.
A symbol table for attribute data.
const void * indirect
Definition: glcorearb.h:1795
const GT_DataArrayHandle & getData() const
GLuint start
Definition: glcorearb.h:475
#define GT_API
Definition: GT_API.h:13
int getIndex(const UT_StringRef &name) const
Return the index for a given name (returns -1 if miss)
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
GLdouble s
Definition: glad.h:3009
const GT_AttributeMapHandle & getMap() const
Get a handle to the name map for this list.
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:37
A reference counter base class for use with UT_IntrusivePtr.
const UT_StringHolder & getName(int index) const
Return the name for a given index.
int add(const UT_StringHolder &name, bool replace_existing)
iterator(const iterator &src)
double fpreal64
Definition: SYS_Types.h:201
#define UT_ASSERT_MSG(ZZ,...)
Definition: UT_Assert.h:159
const UT_StringArray & getNames() const
Return the list of names.
const UT_StringHolder & getExportName(int index) const
Return the export name for a given index.
GLdouble n
Definition: glcorearb.h:2008
GLintptr offset
Definition: glcorearb.h:665
Abstract data class for an array of float, int or string data.
Definition: GT_DataArray.h:40
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
int64 GT_Offset
Definition: GT_Types.h:129
long long int64
Definition: SYS_Types.h:116
static GT_AttributeListHandle createAttributeList(Pairs &&...pairs)
GLuint const GLchar * name
Definition: glcorearb.h:786
int entries() const
Return the number of attributes in the list.
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
GA_API const UT_StringHolder transform
GLint GLenum GLint x
Definition: glcorearb.h:409
const UT_StringHolder & getName() const
GT_Owner
Definition: GT_Types.h:90
GT_AttributeListHandle addAttribute(const UT_StringHolder &name, const GT_DataArrayHandle &h, bool replace_existing) const
int64 GT_Size
Definition: GT_Types.h:128
GLsizeiptr size
Definition: glcorearb.h:664
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
GLuint index
Definition: glcorearb.h:786
int getSegments() const
Return the number of motion segements.
iterator begin(int segment=0) const
Traverse over all attributes for a given motion segment.
GT_Owner getOriginalOwner(int idx) const
Get original attribute owner for the given attribute.
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
const iterator & operator=(const iterator &src)
bool hasName(const UT_StringRef &name) const
Test of an attribute name exists.
Definition: format.h:895
GLenum src
Definition: glcorearb.h:1793