HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GA_ElementWrangler.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_ElementWrangler.h ( GA Library, C++)
7  *
8  * COMMENTS: A utility class to abstract common preamble from GA_GBElement
9  * methods to a higher level.
10  */
11 
12 #ifndef __GA_ElementWrangler__
13 #define __GA_ElementWrangler__
14 
15 #include "GA_API.h"
16 #include "GA_AttributeFilter.h"
17 #include "GA_AttributeRefMap.h"
18 #include "GA_Types.h"
19 
20 #include <UT/UT_NonCopyable.h>
21 #include <SYS/SYS_Types.h>
22 
23 
24 class GA_Attribute;
25 class GA_Detail;
26 class GA_Range;
27 
28 
29 /// @brief A utility class to amortize overhead from GA_GBElement attribute
30 /// handling methods.
31 ///
32 /// The GA_ElementWrangler class provides a simplified interface for common
33 /// attribute operations as elements are added or removed.
34 ///
35 /// This class is not thread-safe, so each thread should have its own copy,
36 /// and any attributes added after its instantiation will not be processed.
37 
39 {
40 public:
41  // This builds a write-cache. This accelerates string and
42  // dictionary writes, but means that you can't necessarily read
43  // from stuff that has been written.
44  void buildCache()
45  { myCache = UTmakeUnique<GA_AttributeRefMap::Cache>(); }
46  // Clear and flush the write cache.
47  void clearCache()
48  { myCache.reset(); }
50  {
51  myMap.copyValue(myOwner, dest, myOwner, src,
52  cache());
53  }
54  void copyAttributeValues(const GA_Range &dest, GA_Offset src);
56  {
57  myMap.multiply(myOwner, dest, scale);
58  }
60  fpreal scale=1)
61  {
62  myMap.addValue(myOwner, dest, myOwner, src, scale);
63  }
65  GA_Offset src1, fpreal bias)
66  {
67  myMap.lerpValue(myOwner, dest, myOwner, src0, src1, bias);
68  }
69 
70  bool isValid(GA_Detail &dest) const
71  {
72  return myMap.getDestDetail() == &dest &&
73  myMap.getSourceDetail() == &dest;
74  }
75  bool isValid(GA_Detail &dest, const GA_Detail &src) const
76  {
77  return myMap.getDestDetail() == &dest &&
78  myMap.getSourceDetail() == &src;
79  }
80  int getNumAttributes() const
81  { return myMap.entries(); }
83  {
84  myMap.bumpAllDestDataIds();
85  }
86 
87  /// Harden data pages in destination attributes.
88  /// Will harden *all* pages overlapping the specified offset range.
89  /// Once this is done, multiple threads can write to an attribute in
90  /// parallel at a finer granularity than pages.
91  /// Note groups are not threadsafe even if hardened.
92  void hardenAllPages(GA_Offset start_offset = GA_Offset(0),
93  GA_Offset end_offset = GA_INVALID_OFFSET);
94 
95  GA_AttributeRefMap &getMap() { return myMap; }
96 
97 protected:
99  const GA_Attribute *exclude = nullptr);
101  const GA_Detail &src, const GA_Attribute *exclude = nullptr);
102 
104  const GA_AttributeFilter &filter);
106  const GA_Detail &src, const GA_AttributeFilter &filter);
107 
108  /// Protected destructor as we don't support polymorphic destruction.
110 
111  GA_AttributeRefMap::Cache *cache() { return myCache.get(); }
112 
113 private:
115  GA_AttributeOwner myOwner;
116  GA_AttributeRefMap myMap;
117 };
118 
119 /// By default, operations on "P" are performed as with any other attribute.
120 /// However, it's possible to turn on the homogeneous flag which will ensure
121 /// that operations are done using homogeneous coordinates.
123 {
124 public:
125  enum IncludeP { EXCLUDE_P, INCLUDE_P };
126 
127  /// The GA_PointWrangler::IncludeP argument passed to the constructor
128  /// determines whether the base class operations include "P".
129  GA_PointWrangler(GA_Detail &dest, IncludeP p);
130  GA_PointWrangler(GA_Detail &dest, const GA_Detail &src, IncludeP p);
131 
133  GA_PointWrangler(GA_Detail &dest, const GA_Detail &src,
134  const GA_AttributeFilter &filter);
135 
137  {
138  delete myAlternateMap;
139  }
140 
141  bool includesP() const { return myBaseIncludeP == INCLUDE_P; }
142 
147 
149  IncludeP copy_p)
150  {
151  if (copy_p == myBaseIncludeP)
152  copyAttributeValues(dest, src);
153  else
154  {
155  initAlternateHandle();
156  myAlternateMap->copyValue(
157  GA_ATTRIB_POINT, dest,
158  GA_ATTRIB_POINT, src,
159  cache());
160  }
161  }
163  IncludeP scale_p)
164  {
165  if (scale_p == myBaseIncludeP)
166  scaleAttributeValues(dest, scale);
167  else
168  {
169  initAlternateHandle();
170  myAlternateMap->multiply(
171  GA_ATTRIB_POINT, dest, scale);
172  }
173  }
175  fpreal scale, IncludeP add_p)
176  {
177  if (add_p == myBaseIncludeP)
178  addAttributeValues(dest, src, scale);
179  else
180  {
181  initAlternateHandle();
182  myAlternateMap->addValue(
183  GA_ATTRIB_POINT, dest,
184  GA_ATTRIB_POINT, src, scale);
185  }
186  }
188  GA_Offset src1, fpreal bias,
189  IncludeP lerp_p)
190  {
191  if (lerp_p == myBaseIncludeP)
192  lerpAttributeValues(dest, src0, src1, bias);
193  else
194  {
195  initAlternateHandle();
196  myAlternateMap->lerpValue(
197  GA_ATTRIB_POINT, dest,
198  GA_ATTRIB_POINT, src0, src1, bias);
199  }
200  }
201 private:
202  void initAlternateHandle()
203  {
204  if (!myAlternateMap)
205  allocAlternateHandle();
206  }
207  void allocAlternateHandle();
208 
209  // We keep track of whether the base class handle includes "P" since we
210  // may need to allocate an alternate handle when an operation requests
211  // the opposite behavior.
212  IncludeP myBaseIncludeP;
213  GA_AttributeFilter myFilter;
214  GA_AttributeRefMap *myAlternateMap;
215 };
216 
218 {
219 public:
223  : GA_ElementWrangler(GA_ATTRIB_VERTEX, dest, src) {}
224 
226  : GA_ElementWrangler(GA_ATTRIB_VERTEX, dest, filter) {}
228  const GA_AttributeFilter &filter)
229  : GA_ElementWrangler(GA_ATTRIB_VERTEX, dest, src, filter) {}
230 private:
231 };
232 
234 {
235 public:
239  : GA_ElementWrangler(GA_ATTRIB_PRIMITIVE, dest, src) {}
240 
242  : GA_ElementWrangler(GA_ATTRIB_PRIMITIVE, dest, filter) {}
244  const GA_AttributeFilter &filter)
245  : GA_ElementWrangler(GA_ATTRIB_PRIMITIVE, dest, src, filter) {}
246 private:
247 };
248 
250 {
251 public:
255  : GA_ElementWrangler(GA_ATTRIB_GLOBAL, dest, src) {}
256 
258  : GA_ElementWrangler(GA_ATTRIB_GLOBAL, dest, filter) {}
260  const GA_AttributeFilter &filter)
261  : GA_ElementWrangler(GA_ATTRIB_GLOBAL, dest, src, filter) {}
262 private:
263 };
264 
266 {
267 public:
269  GA_PointWrangler::IncludeP include_p)
270  : myDestGdp(&dest), mySrcGdp(&dest), myPrimitiveWrangler(nullptr),
271  myVertexWrangler(nullptr), myPointWrangler(nullptr),
272  myIncludeP(include_p) {}
274  GA_PointWrangler::IncludeP include_p)
275  : myDestGdp(&dest), mySrcGdp(&src), myPrimitiveWrangler(nullptr),
276  myVertexWrangler(nullptr), myPointWrangler(nullptr),
277  myIncludeP(include_p) {}
278 
280  const GA_AttributeFilter &filter)
281  : myDestGdp(&dest), mySrcGdp(&dest), myPrimitiveWrangler(nullptr),
282  myVertexWrangler(nullptr), myPointWrangler(nullptr),
283  myFilter(filter) {}
285  const GA_AttributeFilter &filter)
286  : myDestGdp(&dest), mySrcGdp(&src), myPrimitiveWrangler(nullptr),
287  myVertexWrangler(nullptr), myPointWrangler(nullptr),
288  myFilter(filter) {}
289 
291  {
292  if (myPrimitiveWrangler)
293  delete myPrimitiveWrangler;
294  if (myVertexWrangler)
295  delete myVertexWrangler;
296  if (myPointWrangler)
297  delete myPointWrangler;
298  }
299 
300  void clear()
301  {
302  if (myPrimitiveWrangler)
303  {
304  delete myPrimitiveWrangler;
305  myPrimitiveWrangler = nullptr;
306  }
307  if (myVertexWrangler)
308  {
309  delete myVertexWrangler;
310  myVertexWrangler = nullptr;
311  }
312  if (myPointWrangler)
313  {
314  delete myPointWrangler;
315  myPointWrangler = nullptr;
316  }
317  }
318 
319  void reset(GA_Detail &dest)
320  {
321  myDestGdp = &dest;
322  mySrcGdp = &dest;
323  clear();
324  }
325  void reset(GA_Detail &dest, const GA_Detail &src)
326  {
327  myDestGdp = &dest;
328  mySrcGdp = &src;
329  clear();
330  }
331  bool isValid(const GA_Detail &dest) const
332  {
333  return myDestGdp == &dest &&
334  mySrcGdp == &dest;
335  }
336  bool isValid(const GA_Detail &dest,
337  const GA_Detail &src) const
338  {
339  return myDestGdp == &dest &&
340  mySrcGdp == &src;
341  }
342 
344  {
345  if (!myPrimitiveWrangler)
346  {
347  if (myFilter.isValid())
348  myPrimitiveWrangler = new GA_PrimitiveWrangler(*myDestGdp,
349  *mySrcGdp,
350  myFilter);
351  else
352  myPrimitiveWrangler = new GA_PrimitiveWrangler(*myDestGdp,
353  *mySrcGdp);
354  }
355  return *myPrimitiveWrangler;
356  }
358  {
359  if (!myVertexWrangler)
360  {
361  if (myFilter.isValid())
362  myVertexWrangler = new GA_VertexWrangler(*myDestGdp,
363  *mySrcGdp,
364  myFilter);
365  else
366  myVertexWrangler = new GA_VertexWrangler(*myDestGdp,
367  *mySrcGdp);
368  }
369  return *myVertexWrangler;
370  }
372  {
373  if (!myPointWrangler)
374  {
375  if (myFilter.isValid())
376  myPointWrangler = new GA_PointWrangler(*myDestGdp, *mySrcGdp,
377  myFilter);
378  else
379  myPointWrangler = new GA_PointWrangler(*myDestGdp, *mySrcGdp,
380  myIncludeP);
381  }
382  return *myPointWrangler;
383  }
384 
385 private:
386  GA_Detail *myDestGdp;
387  const GA_Detail *mySrcGdp;
388  GA_PrimitiveWrangler *myPrimitiveWrangler;
389  GA_VertexWrangler *myVertexWrangler;
390  GA_PointWrangler *myPointWrangler;
391  GA_PointWrangler::IncludeP myIncludeP;
392  GA_AttributeFilter myFilter;
393 };
394 
395 #endif
GA_DetailWrangler(GA_Detail &dest, const GA_Detail &src, const GA_AttributeFilter &filter)
void scaleAttributeValues(GA_Offset dest, fpreal scale)
GA_VertexWrangler & getVertex()
void addAttributeValues(GA_Offset dest, GA_Offset src, fpreal scale, IncludeP add_p)
Definition of a geometry attribute.
Definition: GA_Attribute.h:198
void copyAttributeValues(GA_Offset dest, GA_Offset src)
GA_PrimitiveWrangler(GA_Detail &dest, const GA_Detail &src, const GA_AttributeFilter &filter)
bool includesP() const
GA_DetailWrangler(GA_Detail &dest)
void addAttributeValues(GA_Offset dest, GA_Offset src, fpreal scale=1)
GA_ElementWranglerCache(GA_Detail &dest, const GA_AttributeFilter &filter)
bool isValid(GA_Detail &dest, const GA_Detail &src) const
~GA_ElementWrangler()
Protected destructor as we don't support polymorphic destruction.
bool isValid(GA_Detail &dest) const
A utility class to amortize overhead from GA_GBElement attribute handling methods.
#define GA_API
Definition: GA_API.h:14
GA_ElementWranglerCache(GA_Detail &dest, const GA_Detail &src, const GA_AttributeFilter &filter)
GA_VertexWrangler(GA_Detail &dest)
#define GA_INVALID_OFFSET
Definition: GA_Types.h:678
void reset(GA_Detail &dest)
A range of elements in an index-map.
Definition: GA_Range.h:42
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
GA_Size GA_Offset
Definition: GA_Types.h:641
GA_API const UT_StringHolder scale
GA_DetailWrangler(GA_Detail &dest, const GA_AttributeFilter &filter)
GA_DetailWrangler(GA_Detail &dest, const GA_Detail &src)
GA_AttributeRefMap::Cache * cache()
void lerpAttributeValues(GA_Offset dest, GA_Offset src0, GA_Offset src1, fpreal bias, IncludeP lerp_p)
void reset(GA_Detail &dest, const GA_Detail &src)
GA_ElementWranglerCache(GA_Detail &dest, GA_PointWrangler::IncludeP include_p)
A handle to simplify manipulation of multiple attributes.
bool isValid(const GA_Detail &dest, const GA_Detail &src) const
GA_VertexWrangler(GA_Detail &dest, const GA_Detail &src)
GA_PointWrangler & getPoint()
GA_PrimitiveWrangler(GA_Detail &dest, const GA_Detail &src)
GA_AttributeOwner
Definition: GA_Types.h:34
GA_VertexWrangler(GA_Detail &dest, const GA_Detail &src, const GA_AttributeFilter &filter)
GA_ElementWranglerCache(GA_Detail &dest, const GA_Detail &src, GA_PointWrangler::IncludeP include_p)
GA_AttributeRefMap & getMap()
void scaleAttributeValues(GA_Offset dest, fpreal scale, IncludeP scale_p)
fpreal64 fpreal
Definition: SYS_Types.h:277
GA_PrimitiveWrangler(GA_Detail &dest)
void lerpAttributeValues(GA_Offset dest, GA_Offset src0, GA_Offset src1, fpreal bias)
GA_VertexWrangler(GA_Detail &dest, const GA_AttributeFilter &filter)
Container class for all geometry.
Definition: GA_Detail.h:96
void copyAttributeValues(GA_Offset dest, GA_Offset src, IncludeP copy_p)
GA_PrimitiveWrangler(GA_Detail &dest, const GA_AttributeFilter &filter)
GA_PrimitiveWrangler & getPrimitive()
int getNumAttributes() const
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glcorearb.h:1297
GLenum src
Definition: glcorearb.h:1793
bool isValid(const GA_Detail &dest) const