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