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 an attribute list where each attribute has at most `max` entries
194  GT_AttributeListHandle limitLengths(GT_Size max) const;
195 
196  /// Create a new attribute list promoted to vertex frequency by setting
197  /// the offsets in any GT_GEOElementArrays (for performance reasons)
198  /// Any non-element arrays will use createIndirect() instead.
199  GT_AttributeListHandle promoteToVertex(const GT_GEOOffsetList &off,
200  const GT_DataArrayHandle &ind) const;
201 
202  /// Merge attributes which don't already exist in this attribute list
203  GT_AttributeListHandle mergeNewAttributes(
204  const GT_AttributeListHandle &s,
205  bool replace_existing = false) const;
206 
207  /// Create the "s" and "t" attributes for the given u/v vertex count.
208  /// The attributes will only be created if @c nu or @c nv is greater than 0
209  GT_AttributeListHandle createUV(int nu, int nv,
210  fpreal64 s0=0, fpreal64 s1=1,
211  fpreal64 t0=0, fpreal64 t1=1) const;
212 
213  /// Create a merged list of the two lists. This will merge a sub-array of
214  /// the first list and an indirect mapping of the second list.
215  /// This is used to merge a vertex list (l0) with a point list (l1)
216  static GT_AttributeListHandle createMerged(
217  const GT_AttributeMerge &map,
218  const GT_AttributeListHandle &l0,
219  GT_Offset l0_offset, GT_Size l0_size,
220  const GT_AttributeListHandle &l1,
221  const GT_DataArrayHandle &l1_indirect);
222 
223  /// Merge two lists, expanding the constant list to have arrays matching
224  /// the length of the varying array.
225  static GT_AttributeListHandle expandConstantMerge(
226  const GT_AttributeMerge &map,
227  const GT_AttributeListHandle &varying,
228  const GT_AttributeListHandle &constant,
229  GT_Offset const_index=0);
230 
231  /// Merge two lists, creating a constant value list, selecting a single
232  /// element from a varying list.
233  static GT_AttributeListHandle createConstantMerge(
234  const GT_AttributeMerge &map,
235  const GT_AttributeListHandle &varying,
237  const GT_AttributeListHandle &constant);
238 
239  /// Merge an array of N lists to form a single attribute list. All the
240  /// data is concatenated in order.
241  ///
242  /// This method will fail (return an empty list) if any lists don't have
243  /// matching attributes (including motion segments & order of attributes)
244  ///
245  /// The list may have NULL handles.
246  static GT_AttributeListHandle concatenateLists(
248 
249  /// Get a 64b hash of all data ids in the list. Return false if any attribs
250  /// have an invalid data id (-1)
251  bool getDataIdHash(int64 &hash, int segment=0) const;
252 
253  /// Refresh the any detail references and data IDs on all data arrays.
254  void updateGeoDetail(const GU_ConstDetailHandle &dtl,
255  GT_Owner scope) const;
256 
257  /// Debug method to dump the list to stdout
258  void dumpList(const char *label="", bool data_too = true);
259 
260  /// Save to a JSON stream
261  bool save(UT_JSONWriter &w) const;
262 
264  {
265  public:
267  : myList(NULL), myCurr(0), mySize(0), mySegment(0) {}
268  iterator(const iterator &src)
269  { *this = src; }
271 
273  {
274  return myList->get(myCurr,
275  mySegment);
276  }
277  const UT_StringHolder &getName() const
278  {
279  return myList->getName(myCurr);
280  }
281 
282  void rewind() { myCurr = 0; }
283  void advance() { myCurr++; }
284  bool atEnd() const { return myCurr >= mySize; }
285 
286  iterator &operator++() { advance(); return *this; }
287  // No post increment as it is dangerous.
288  const iterator &operator=(const iterator &src)
289  {
290  myList = src.myList;
291  myCurr = src.myCurr;
292  mySize = src.mySize;
293  return *this;
294  }
295 
296  private:
297  iterator(const GT_AttributeList *list, int segment)
298  : myList(list),
299  mySegment(segment),
300  myCurr(0),
301  mySize(list->entries()) {}
302 
303  const GT_AttributeList *myList;
304  int myCurr, mySize, mySegment;
305  friend class GT_AttributeList;
306  };
307  /// Traverse over all attributes for a given motion segment
308  iterator begin(int segment=0) const { return iterator(this, segment); }
309 
310  // Forward declare nested class (and make it a friend)
311  class gt_CreateIndirectTask;
312  friend class gt_CreateIndirectTask;
313 
314 private:
315 
316  // Private constructor for createAttributeList() only
318  int motion_segments);
319 
320  static SYS_FORCE_INLINE int
321  gt_CountAttribs()
322  {
323  return 0;
324  }
325  template <typename DataT, typename... Pairs>
326  static int
327  gt_CountAttribs(const UT_StringRef &name, DataT&& data,
328  Pairs&&... pairs)
329  {
330  return (data ? 1 : 0) + gt_CountAttribs(std::forward<Pairs>(pairs)...);
331  }
332 
333  static SYS_FORCE_INLINE void
334  gt_CreateAttributeList(GT_AttributeList &, GT_AttributeMap &)
335  {
336  }
337  template <typename DataT, typename... Pairs>
338  static void
339  gt_CreateAttributeList(
340  GT_AttributeList &list, GT_AttributeMap &map,
341  const UT_StringHolder &name, DataT&& data,
342  Pairs&&... pairs)
343  {
344  // Ignore NULL data arrays. Makes it easier to make lists where it's
345  // not known if some of the data arrays are valid at compile time.
346  if (data)
347  {
348  int i = map.add(name, /*replace*/false);
349  UT_ASSERT_MSG(i >= 0, "Should not have duplicates!");
350  list.set(i, data);
351  }
352  gt_CreateAttributeList(list, map, std::forward<Pairs>(pairs)...);
353  }
354 
355 private:
356  /// Create a new constant data array for the i'th element
357  const GT_DataArrayHandle createConstant(int idx, GT_Offset offset,
358  GT_Size size,
359  int segment) const;
360 
361  /// Create a new sub-array data array for the i'th element
362  const GT_DataArrayHandle createSubArray(int idx, GT_Offset start,
363  GT_Size size,
364  int segment) const;
365 
366  /// Create a new sub-array data array for the i'th element
367  const GT_DataArrayHandle createIndirect(
368  int idx,
370  int segment,
371  bool flatten_nested) const;
372 
373  inline int getSegmentIndex(int index, int segment) const
374  { return index + segment*entries(); }
375 
376  // Keep the 32 bit int first in the structure. Since we inherit from
377  // GA_IntrusiveRefCounter, this alignment makes the object smaller.
378  int myMotionSegments;
379  const GT_AttributeMapHandle myMap;
380  GT_DataArrayHandle *myData;
381 
382  // For threading of creating indirect arrays
383 };
384 
385 #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
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
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