HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GA_AttributeTransformer.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_AttributeTransformer.h ( GA Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GA_Transform__
12 #define __GA_Transform__
13 
14 #include "GA_API.h"
15 
16 #include "GA_Handle.h"
17 #include "GA_PageHandle.h"
18 #include "GA_Range.h" // for GA_Range
19 #include "GA_Types.h" // for GA_Offset, etc
20 
21 #include <UT/UT_Array.h> // for UT_Array
22 #include <UT/UT_Matrix3.h> // for UT_Matrix3T
23 #include <UT/UT_Matrix4.h>
24 #include <UT/UT_Quaternion.h>
25 
26 #include <SYS/SYS_Types.h> // for fpreal32, fpreal64, exint
27 
28 
29 class GA_AIFMath;
30 class GA_AIFTuple;
31 class GA_Attribute;
32 class GA_AttributeFilter;
33 class GA_Detail;
34 
35 
36 /// @brief Class to efficiently transform multiple attributes
37 ///
38 /// This class will transform attributes as efficiently as possible, depending
39 /// on the attribute's properties. The transformer works on a single class of
40 /// attributes (i.e. GA_ATTRIB_POINT).
42 {
43 public:
44  /// @brief Class to pass transforms to GA_AttributeTransformer
45  ///
46  /// Computing inverse/quaternion transforms can be expensive. If possible,
47  /// you should reuse unchanging Transform objects rather than re-building
48  /// them when performing multiple transforms.
49  template <typename FLOAT_T>
50  class Transform
51  {
52  public:
53  typedef FLOAT_T ValueType;
55  : myM()
56  , myHasI(false)
57  , myHasQ(false)
58  {
59  }
60  template<typename FLOAT_T2>
62  : myM(m)
63  , myHasI(false)
64  , myHasQ(false)
65  {
66  }
67  /// Set the matrix
68  template<typename FLOAT_T2>
69  void set(const UT_Matrix4T<FLOAT_T2> &m)
70  {
71  myM = m;
72  myHasI = false;
73  myHasQ = false;
74  }
75  /// Compute the inverse (if required)
77  {
78  if (!myHasI)
79  {
80  UT_Matrix3T<FLOAT_T> m3(myM);
81  myM.invert(myIM);
82  myHasI = true;
83  }
84  }
85  /// Compute the quaternion transform (if required)
87  {
88  if (!myHasQ)
89  {
90  UT_Matrix3T<FLOAT_T> m3(myM);
91  myQ.updateFromArbitraryMatrix(m3);
92  myHasQ = true;
93  }
94  }
95 
96  /// @{
97  /// Accessor
98  const UT_Matrix4T<FLOAT_T> &xform() const { return myM; }
99  const UT_Matrix4T<FLOAT_T> &ixform() const { return myIM; }
100  const UT_QuaternionT<FLOAT_T> &q() const { return myQ; }
101  /// @}
102 
103  private:
107  bool myHasI;
108  bool myHasQ;
109  };
110 
111  /// @brief Handle to a transformable attribute
113  {
114  public:
115  /// @{
116  /// Handle callback functions. These perform different styles of
117  /// transformation depending on the attribute type properties.
118  typedef void (*GAtransformPageF)(const Handle &handle,
119  const Transform<fpreal32> &context,
121  typedef void (*GAtransformPageD)(const Handle &handle,
122  const Transform<fpreal64> &context,
124  typedef void (*GAtransformF)(const Handle &handle,
125  const Transform<fpreal32> &context,
126  GA_Offset offset);
127  typedef void (*GAtransformD)(const Handle &handle,
128  const Transform<fpreal64> &context,
129  GA_Offset offset);
130  /// @}
131 
132  /// Construct a handle for a given attribute
133  Handle(GA_Attribute *attrib, bool keep_length = false);
134  ~Handle() { }
135 
136  /// @{
137  /// Transform the attribute using the handle callback
139  GA_Offset start, GA_Offset end) const
140  { myTransformPageF(*this, ctx, start, end); }
142  GA_Offset start, GA_Offset end) const
143  { myTransformPageD(*this, ctx, start, end); }
145  GA_Offset offset) const
146  { myTransformF(*this, ctx, offset); }
148  GA_Offset offset) const
149  { myTransformD(*this, ctx, offset); }
150  /// @}
151 
152  /// Check to see whether the attribute is valid
153  bool isValid() const { return myType != GA_TYPE_VOID; }
154  /// Return the GA_TypeInfo for the attribute
155  GA_TypeInfo getType() const { return myType; }
156 
157  /// @{
158  /// Check whether length of vectors/normals should be preserved after
159  /// transforming.
160  bool keepLength() const { return myKeepLength; }
161  void setKeepLength(bool v) { myKeepLength = v; }
162  /// @}
163 
164  /// @{
165  /// Accessors to provide information in the callback handle functions
166  /// NOTE: Always check isDouble() before calling getV3!
167  GA_Attribute *getAttribute() const { return myAttribute; }
168  template<typename FLOAT_T>
170  {
172  UT_ASSERT_P(myIsDouble == (sizeof(FLOAT_T) == 8));
173  UT_ASSERT_P(!myIsDouble == (sizeof(FLOAT_T) == 4));
174  return (const GA_RWHandleT<UT_Vector3T<FLOAT_T> > &)myV3;
175  }
176  const GA_AIFMath *getMath() const { return myMath; }
177  const GA_AIFTuple *getTuple() const { return myTuple; }
178  /// @}
179 
180  /// @{
181  /// Check whether the inverse matrix or quaternion transform are
182  /// required
183  bool needInverse() const { return myNeedI; }
184  bool needQuaternion() const { return myNeedQ; }
185  /// @}
186 
187  /// Check if the attribute is double-precision, if can choose
188  /// between single and double-precision transformation.
189  bool isDouble() const { return myIsDouble; }
190 
191  private:
192  /// Set up the transform callback functions
193  void setupFunctions();
194 
195  GAtransformF myTransformF;
196  GAtransformD myTransformD;
197  GAtransformPageF myTransformPageF;
198  GAtransformPageD myTransformPageD;
199  GA_Attribute *myAttribute;
200  const GA_AIFMath *myMath;
201  const GA_AIFTuple *myTuple;
202  GA_RWHandleV3 myV3;
203  GA_TypeInfo myType;
204  bool myKeepLength;
205  bool myNeedI;
206  bool myNeedQ;
207  bool myIsDouble;
208  };
209 
210 public:
213 
214  /// Add all transformable attributes to the handle list. When @c
215  /// keep_length is set, normals and vectors will maintain their lengths
216  /// under scaling.
217  void addAttributes(bool keep_lengths=false);
218  /// Add a filtered selection of attributes to the handle list. The filter
219  /// should filter out non-transforming attributes. When @c keep_length is
220  /// set, normals and vectors will maintain their lengths under scaling.
221  void addAttributes(const GA_AttributeFilter &filter,
222  bool keep_lenghts=false);
223  /// Add a single transformable attributes to the handle list. When @c
224  /// keep_length is set, normals and vectors will maintain their lengths
225  /// under scaling.
226  void addAttribute(GA_Attribute *attrib,
227  bool keep_lengths=false);
228  /// Clear the list of transformable attributes.
229  void clearAttributes();
230 
231  /// Return the number of attributes which will be transformed
232  exint entries() const { return myHandles.entries(); }
233  /// Return the handle to the individual attribute
234  const Handle &getHandle(exint i) const { return myHandles(i); }
235  /// Return the bound detail
236  GA_Detail &getDetail() const { return myDetail; }
237 
238  /// @{
239  /// Perform the transformation on all attributes.
240  ///
241  /// @note The Transform reference is non-const. The methods are mostly
242  /// thread safe (provided threads access unique pages of data). However,
243  /// since the Transform object is non-const, the Transform should @b not be
244  /// shared across threads.
245  void transform(const GA_Range &range,
246  Transform<fpreal32> &m) const;
247  void transform(const GA_Range &range,
248  Transform<fpreal64> &m) const;
249  void transform(const GA_Range &range,
250  Transform<fpreal32> &m32,
251  Transform<fpreal64> &m64) const;
252  void transform(GA_Offset offset, Transform<fpreal32> &m) const;
253  void transform(GA_Offset offset, Transform<fpreal64> &m) const;
255  Transform<fpreal32> &m32,
256  Transform<fpreal64> &m64) const;
257  /// @}
258 
259  /// @{
260  /// Check whether any attributes require the inverse/quaternion transforms
261  bool needInverse() const { return myNeedI; }
262  bool needQuaternion() const { return myNeedQ; }
263  /// @}
264 
265  /// @{
266  /// Check whether any attributes are single- or double-precision
267  bool hasSingle() const { return myHasSingle; }
268  bool hasDouble() const { return myHasDouble; }
269  /// @}
270 
271 private:
272  /// Ensure the transform has its inverse/quaternion computed (if needed)
273  template <typename FLOAT_T>
274  void updateTransform(Transform<FLOAT_T> &xform) const
275  {
276  if (myNeedI)
277  xform.computeInverse();
278  if (myNeedQ)
279  xform.computeQuaternion();
280  }
281  GA_Detail &myDetail;
282  UT_Array<Handle> myHandles;
283  GA_AttributeOwner myOwner;
284  bool myNeedI;
285  bool myNeedQ;
286  bool myHasSingle;
287  bool myHasDouble;
288 };
289 
290 #endif
Definition of a geometry attribute.
Definition: GA_Attribute.h:198
Data has no numeric representation.
Definition: GA_Types.h:104
UT_ASSERT_COMPILETIME(BRAY_EVENT_MAXFLAGS<=32)
GLenum GLint * range
Definition: glcorearb.h:1925
void
Definition: png.h:1083
void transform(const Transform< fpreal32 > &ctx, GA_Offset start, GA_Offset end) const
Attribute Interface class to perform numeric operations on attributes.
Definition: GA_AIFMath.h:88
const GLdouble * v
Definition: glcorearb.h:837
Transform(const UT_Matrix4T< FLOAT_T2 > &m)
GLuint start
Definition: glcorearb.h:475
bool isValid() const
Check to see whether the attribute is valid.
void transform(const Transform< fpreal64 > &ctx, GA_Offset offset) const
GA_Detail & getDetail() const
Return the bound detail.
int64 exint
Definition: SYS_Types.h:125
Class to pass transforms to GA_AttributeTransformer.
#define GA_API
Definition: GA_API.h:14
A range of elements in an index-map.
Definition: GA_Range.h:42
void transform(const Transform< fpreal64 > &ctx, GA_Offset start, GA_Offset end) const
GA_Size GA_Offset
Definition: GA_Types.h:646
GLintptr offset
Definition: glcorearb.h:665
void set(const UT_Matrix4T< FLOAT_T2 > &m)
Set the matrix.
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:155
GLuint GLuint end
Definition: glcorearb.h:475
const UT_Matrix4T< FLOAT_T > & ixform() const
const UT_QuaternionT< FLOAT_T > & q() const
GA_TypeInfo getType() const
Return the GA_TypeInfo for the attribute.
GA_API const UT_StringHolder transform
const UT_Matrix4T< FLOAT_T > & xform() const
GA_TypeInfo
Definition: GA_Types.h:101
void transform(const Transform< fpreal32 > &ctx, GA_Offset offset) const
GA_AttributeOwner
Definition: GA_Types.h:35
const GA_RWHandleT< UT_Vector3T< FLOAT_T > > & getV3() const
Handle to a transformable attribute.
void computeInverse()
Compute the inverse (if required)
exint entries() const
Return the number of attributes which will be transformed.
Container class for all geometry.
Definition: GA_Detail.h:96
const GA_AIFTuple * getTuple() const
void computeQuaternion()
Compute the quaternion transform (if required)
const GA_AIFMath * getMath() const
Generic Attribute Interface class to access an attribute as a tuple.
Definition: GA_AIFTuple.h:32
Class to efficiently transform multiple attributes.
void * Handle
Definition: plugin.h:27
const Handle & getHandle(exint i) const
Return the handle to the individual attribute.
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glcorearb.h:1297