HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_Gf.h
Go to the documentation of this file.
1 //
2 // Copyright 2017 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef _GUSD_UT_GF_H_
25 #define _GUSD_UT_GF_H_
26 
27 #include "pxr/pxr.h"
28 
29 #include "UT_TypeTraits.h"
30 
31 // Conversion specializations require full defs for some types.
32 #include "pxr/base/gf/quaternion.h"
33 #include "pxr/base/gf/quatd.h"
34 #include "pxr/base/gf/quatf.h"
35 #include "pxr/base/gf/quath.h"
36 #include "pxr/base/gf/vec4d.h"
37 #include "pxr/base/gf/vec4f.h"
38 
39 #include <SYS/SYS_TypeTraits.h>
40 #include <SYS/SYS_Version.h>
41 #include <UT/UT_VectorTypes.h>
42 
44 
45 /// Helpers for working with Gf types (vectors, matrices, etc.) within the HDK.
46 struct GusdUT_Gf
47 {
48  /// Struct providing info about type equivalence between
49  /// UT and Gf types. Each struct defines:
50  ///
51  /// \code
52  /// static const bool isSpecialized = true;
53  /// typedef ... GfType;
54  /// typedef ... UtType;
55  /// typedef ... AltType; // Type from the alternate API.
56  /// // Eg., if this is a UT type, it will be the Gf
57  /// // type, and vice versa.
58  /// \endcode
59  template <class GF_OR_UT_TYPE>
61  {
62  static const bool isSpecialized = false;
63  };
64 
65  /// Struct defining whether or not a type is valid for direct casting to
66  /// other types. We explicitly disable casting for types that require some
67  /// kind of data manipulation when going in-between UT and Gf.
68  template <class GF_OR_UT_TYPE>
69  struct Castable
70  {
71  static const bool value = true;
72  };
73 
74  /// Helpers for casting between UT and Gf types. The cast can go either way.
75  /// This can be done with a reinterpret cast, but this cast adds a bit of
76  /// extra compile-time checks to make sure that this really is safe.
77  ///
78  /// These cast methods only take a single template argument. The output
79  /// is cast to the equivalent type from the alternate API. For example,
80  /// if given a UT_Matrix4D, the cast is to a GfMatrix4d, and vice versa.
81  ///
82  /// \note Any type used here must be declared with a specialization of
83  /// GusdUT_TypeTraits::PODTuple (see GUSD_DECLARE_POD_TUPLE).
84  ///
85  /// Examples:
86  ///
87  /// \code
88  /// // implicit cast of Gf->UT
89  /// UT_Matrix4D& mx = GusdUT_Gf::Cast(gfMatrix4dInstance);
90  /// UT_Matrix4D* mx = GusdUT_Gf::Cast(gfMatrix4dInstancePtr);
91  /// const UT_Matrix4D& mx = GusdUT_Gf::Cast(gfMatrix4dInstanceConst);
92  /// const UT_Matrix4D* mx = GusdUT_Gf::Cast(gfMatrix4dInstancePtrConst);
93  ///
94  /// // implicit cast of UT->Gf
95  /// GfMatrix4d& mx = GusdUT_Gf::Cast(utMatrix4dInstance);
96  /// GfMatrix4d* mx = GusdUT_Gf::Cast(utMatrix4dInstancePtr);
97  /// const GfMatrix4d& mx = GusdUT_Gf::Cast(utMatrix4dInstanceConst);
98  /// const GfMatrix4d* mx = GusdUT_Gf::Cast(utMatrix4dInstancePtrConst);
99  ///
100  /// // compile error! types are not bitwise compatible
101  /// UT_Matrix4D src;
102  /// GfMatrix4f& mx = GusdUT_Gf::Cast(src);
103  ///
104  /// // compile error! discards cv-qualifier.
105  /// const UT_Matrix4F& src = ...;
106  /// GfMatrix4f& mx = GusdUT_Gf::Cast(src);
107  /// \endcode
108  /// @{
109  template <class T>
110  static inline const typename
112 
113  template <class T>
114  static inline typename
116 
117  template <class T>
118  static inline const typename
120 
121  template <class T>
122  static inline typename
124  /// @}
125 
126  /// Explicit casts between UT and Gf types.
127  /// This is just like the implicit cast methods, except that the source and
128  /// target types are explicitly specified via template arguments.
129  /// This can be used for casting between types when the types aren't exact
130  /// counterparts. For instance, we can safely cast a GfMatrix2d to a
131  /// UT_Vector4D, even though UT_Vector4D is not UT's equivalence type for
132  /// GfMatrix2d.
133  ///
134  /// @{
135  template <class FROM, class TO>
136  static inline const TO* Cast(const FROM* val);
137 
138  template <class FROM, class TO>
139  static inline TO* Cast(FROM* val);
140 
141  template <class FROM, class TO>
142  static inline const TO& Cast(const FROM& val);
143 
144  template <class FROM, class TO>
145  static inline TO& Cast(FROM& val);
146  /// @}
147 
148 
149  /// Convert between UT and Gf types. This works for any pod tuples that have
150  /// equivalent tuple sizes, even if their underlying precision differs.
151  ///
152  /// \note Any type used here must be declared with a specialization of
153  /// GusdUT_TypeTraits::PODTuple (see GUSD_DECLARE_POD_TUPLE).
154  template <class FROM, class TO>
155  static inline void Convert(const FROM& from, TO& to);
156 
157 
158  /// Conversions between GF and UT quaternions.
159  /// Gf and UT have a different ordering of the real component,
160  /// hence the need for speciailized converters.
161  ///
162  /// XXX: 4d vector types are sometimes used in place of GfQuaternion,
163  /// hence their inclusion here. That is primarily the fault of USD:
164  /// if USD gets a real quaternion type, we can clean these up.
165  /// @{
166  template <class T>
167  static inline void Convert(const GfQuaternion& from, UT_QuaternionT<T>& to);
168 
169  template <class T>
170  static inline void Convert(const GfQuatd& from, UT_QuaternionT<T>& to);
171 
172  template <class T>
173  static inline void Convert(const GfQuatf& from, UT_QuaternionT<T>& to);
174 
175  template <class T>
176  static inline void Convert(const GfQuath& from, UT_QuaternionT<T>& to);
177 
178  template <class T>
179  static inline void Convert(const GfVec4d& from, UT_QuaternionT<T>& to);
180 
181  template <class T>
182  static inline void Convert(const GfVec4f& from, UT_QuaternionT<T>& to);
183 
184  template <class T>
185  static inline void Convert(const UT_QuaternionT<T>& from, GfQuaternion& to);
186 
187  template <class T>
188  static inline void Convert(const UT_QuaternionT<T>& from, GfQuatd& to);
189 
190  template <class T>
191  static inline void Convert(const UT_QuaternionT<T>& from, GfQuatf& to);
192 
193  template <class T>
194  static inline void Convert(const UT_QuaternionT<T>& from, GfQuath& to);
195 
196  template <class T>
197  static inline void Convert(const UT_QuaternionT<T>& from, GfVec4d& to);
198 
199  template <class T>
200  static inline void Convert(const UT_QuaternionT<T>& from, GfVec4f& to);
201  /// @}
202 
203 private:
204  template <class T, class GFQUAT>
205  static inline void _ConvertQuat(const GFQUAT& from, UT_QuaternionT<T>& to);
206 
207  template <class T>
208  static inline void _AssertIsPodTuple();
209 
210  template <class FROM, class TO>
211  static inline void _AssertCanCast();
212 
213  // Our casting tricks assume that the typedefs set in SYS_Types are
214  // referencing the types we think they are. Verify our assumptions.
216  "std::is_same<fpreal32,float>::value");
218  "std::is_same<fpreal64,double>::value");
219 };
220 
221 
222 /// Declare a type as being uncastable.
223 #define _GUSDUT_DECLARE_UNCASTABLE(TYPE) \
224  template <> \
225  struct GusdUT_Gf::Castable<TYPE> \
226  { \
227  static const bool value = false; \
228  };
229 
230 
231 /// Declare a partial type equivalence. This specifies a one-way
232 /// type equivalence.
233 #define _GUSDUT_DECLARE_PARTIAL_EQUIVALENCE(TYPE,GFTYPE,UTTYPE,ALTTYPE) \
234  template <> \
235  struct GusdUT_Gf::TypeEquivalence<TYPE> { \
236  static const bool isSpecialized = true; \
237  typedef GFTYPE GfType; \
238  typedef UTTYPE UtType; \
239  typedef ALTTYPE AltType; \
240  };
241 
242 /// Declare type equivalent between UT and Gf types.
243 /// Only a single equivalence relationship may be defined per type.
244 ///
245 /// The type info for both types must be declared first!
246 #define _GUSDUT_DECLARE_EQUIVALENCE(GFTYPE,UTTYPE) \
247  _GUSDUT_DECLARE_PARTIAL_EQUIVALENCE(GFTYPE,GFTYPE,UTTYPE,UTTYPE); \
248  _GUSDUT_DECLARE_PARTIAL_EQUIVALENCE(UTTYPE,GFTYPE,UTTYPE,GFTYPE);
249 
250 /// Declare POD tuples for Gf types.
254 
258 
262 
266 
270 
274 
278 
280 
281 /// Declare types as PODs, so that UT_Arrays of the types can be optimized.
282 /// This is done to ensure that Gf types are handled in the same manner as
283 /// UT types: the same is done for UT types as well (see UT/UT_VectorTypes.h).
284 
286 
287 SYS_DECLARE_IS_POD(PXR_NS::GfVec2h);
288 SYS_DECLARE_IS_POD(PXR_NS::GfVec3h);
289 SYS_DECLARE_IS_POD(PXR_NS::GfVec4h);
290 
291 SYS_DECLARE_IS_POD(PXR_NS::GfVec2f);
292 SYS_DECLARE_IS_POD(PXR_NS::GfVec3f);
293 SYS_DECLARE_IS_POD(PXR_NS::GfVec4f);
294 
295 SYS_DECLARE_IS_POD(PXR_NS::GfVec2d);
296 SYS_DECLARE_IS_POD(PXR_NS::GfVec3d);
297 SYS_DECLARE_IS_POD(PXR_NS::GfVec4d);
298 
299 SYS_DECLARE_IS_POD(PXR_NS::GfVec2i);
300 SYS_DECLARE_IS_POD(PXR_NS::GfVec3i);
301 SYS_DECLARE_IS_POD(PXR_NS::GfVec4i);
302 
303 SYS_DECLARE_IS_POD(PXR_NS::GfQuath);
304 SYS_DECLARE_IS_POD(PXR_NS::GfQuatf);
305 SYS_DECLARE_IS_POD(PXR_NS::GfQuatd);
306 
307 SYS_DECLARE_IS_POD(PXR_NS::GfMatrix2f);
308 SYS_DECLARE_IS_POD(PXR_NS::GfMatrix3f);
309 SYS_DECLARE_IS_POD(PXR_NS::GfMatrix4f);
310 
311 SYS_DECLARE_IS_POD(PXR_NS::GfMatrix2d);
312 SYS_DECLARE_IS_POD(PXR_NS::GfMatrix3d);
313 SYS_DECLARE_IS_POD(PXR_NS::GfMatrix4d);
314 
316 
317 // No casting on quaternions; real component is ordered
318 // in a different way between UT and Gf.
325 
326 // Declare type correspondances between Gf and UT.
330 
334 
338 
342 
346 
350 
354 
355 
356 template <class T>
357 void
358 GusdUT_Gf::_AssertIsPodTuple()
359 {
360  static_assert(GusdIsPodTuple<T>(), "Type is not declared as a POD-tuple");
361 }
362 
363 
364 template <class FROM, class TO>
365 void
366 GusdUT_Gf::_AssertCanCast()
367 {
368  _AssertIsPodTuple<FROM>();
369  _AssertIsPodTuple<TO>();
370  static_assert(Castable<FROM>::value, "Source is not castable");
371  static_assert(Castable<TO>::value, "Output is not castable");
372  static_assert(GusdPodTuplesAreBitwiseCompatible<FROM,TO>(),
373  "Types in cast are not bitwise compatible");
374 }
375 
376 
377 template <class FROM, class TO>
378 const TO*
379 GusdUT_Gf::Cast(const FROM* val)
380 {
381  _AssertCanCast<FROM,TO>();
382  return reinterpret_cast<const TO*>(val);
383 }
384 
385 
386 template <class FROM, class TO>
387 TO*
389 {
390  _AssertCanCast<FROM,TO>();
391  return reinterpret_cast<TO*>(val);
392 }
393 
394 
395 template <class FROM, class TO>
396 const TO&
397 GusdUT_Gf::Cast(const FROM& val)
398 {
399  _AssertCanCast<FROM,TO>();
400  return reinterpret_cast<const TO&>(val);
401 }
402 
403 
404 template <class FROM, class TO>
405 TO&
407 {
408  _AssertCanCast<FROM,TO>();
409  return reinterpret_cast<TO&>(val);
410 }
411 
412 
413 template <class T>
416 {
417  _AssertIsPodTuple<T>();
418  return Cast<T,typename TypeEquivalence<T>::AltType>(val);
419 }
420 
421 
422 template <class T>
425 {
426  _AssertIsPodTuple<T>();
427  return Cast<T, typename TypeEquivalence<T>::AltType>(val);
428 }
429 
430 
431 template <class T>
434 {
435  _AssertIsPodTuple<T>();
436  return Cast<T, typename TypeEquivalence<T>::AltType>(val);
437 }
438 
439 
440 template <class T>
443 {
444  _AssertIsPodTuple<T>();
445  return Cast<T, typename TypeEquivalence<T>::AltType>(val);
446 }
447 
448 
449 template <class FROM, class TO>
450 void
451 GusdUT_Gf::Convert(const FROM& from, TO& to)
452 {
453  using FromPodType = typename GusdPodTupleTraits<FROM>::ValueType;
454  using ToPodType = typename GusdPodTupleTraits<TO>::ValueType;
455 
456  _AssertIsPodTuple<FROM>();
457  _AssertIsPodTuple<TO>();
458  static_assert(GusdPodTuplesAreCompatible<FROM,TO>(),
459  "Types are not compatible (mismatched tuple sizes)");
460 
461  const auto* src = reinterpret_cast<const FromPodType*>(&from);
462  ToPodType* dst = reinterpret_cast<ToPodType*>(&to);
463 
464  for (int i = 0; i < GusdGetTupleSize<FROM>(); ++i) {
465  dst[i] = static_cast<ToPodType>(src[i]);
466  }
467 }
468 
469 
470 template <class T, class GFQUAT>
471 void
472 GusdUT_Gf::_ConvertQuat(const GFQUAT& from, UT_QuaternionT<T>& to)
473 {
474  reinterpret_cast<UT_Vector3T<T>&>(to) = Cast(from.GetImaginary());
475  to(3) = from.GetReal();
476 }
477 
478 
479 template <class T>
480 void
482 {
483  return _ConvertQuat(from, to);
484 }
485 
486 
487 template <class T>
488 void
490 {
491  return _ConvertQuat(from, to);
492 }
493 
494 
495 template <class T>
496 void
498 {
499  return _ConvertQuat(from, to);
500 }
501 
502 
503 template <class T>
504 void
506 {
507  return _ConvertQuat(from, to);
508 }
509 
510 
511 template <class T>
512 void
514 {
515  to = UT_QuaternionT<T>(from[1],from[2],from[3],from[0]);
516 }
517 
518 
519 template <class T>
520 void
522 {
523  to = UT_QuaternionT<T>(from[1],from[2],from[3],from[0]);
524 }
525 
526 
527 template <class T>
528 void
530 {
531  to.SetReal(from.w());
532  to.SetImaginary(GfVec3d(from.x(), from.y(), from.z()));
533 }
534 
535 
536 template <class T>
537 void
539 {
540  to.SetReal(from.w());
541  to.SetImaginary(GfVec3d(from.x(), from.y(), from.z()));
542 }
543 
544 
545 template <class T>
546 void
548 {
549  to.SetReal(from.w());
550  to.SetImaginary(GfVec3f(from.x(), from.y(), from.z()));
551 }
552 
553 
554 template <class T>
555 void
557 {
558  to.SetReal(GfHalf(from.w()));
559  to.SetImaginary(
560  GfVec3h(GfHalf(from.x()), GfHalf(from.y()), GfHalf(from.z())));
561 }
562 
563 
564 template <class T>
565 void
567 {
568  to = GfVec4d(from.w(), from.x(), from.y(), from.z());
569 }
570 
571 
572 template <class T>
573 void
575 {
576  to = GfVec4f(from.w(), from.x(), from.y(), from.z());
577 }
578 
579 
580 #undef _GUSDUT_DECLARE_UNCASTABLE
581 #undef _GUSDUT_DECLARE_PARTIAL_EQUIVALENCE
582 #undef _GUSDUT_DECLARE_EQUIVALENCE
583 
585 
586 #endif /*_GUSD_UT_GF_H_*/
Definition: quath.h:61
Definition: vec4i.h:61
GLenum src
Definition: glew.h:2410
Helpers for working with Gf types (vectors, matrices, etc.) within the HDK.
Definition: UT_Gf.h:46
void SetReal(double real)
Sets the real part of the quaternion.
Definition: quaternion.h:75
Definition: vec2i.h:61
#define _GUSDUT_DECLARE_EQUIVALENCE(GFTYPE, UTTYPE)
Definition: UT_Gf.h:246
GLuint const GLfloat * val
Definition: glew.h:2794
void SetImaginary(const GfVec3h &imaginary)
Set the imaginary coefficients.
Definition: quath.h:112
Definition: vec3f.h:63
static const bool isSpecialized
Definition: UT_Gf.h:62
static const TypeEquivalence< T >::AltType * Cast(const T *val)
Definition: UT_Gf.h:442
Definition: vec4d.h:63
3D Vector class.
4D Vector class.
Definition: UT_Vector4.h:163
2D Vector class.
Definition: UT_Vector2.h:145
Definition: quatf.h:60
Definition: vec2d.h:63
Definition: vec4h.h:64
void SetImaginary(const GfVec3f &imaginary)
Set the imaginary coefficients.
Definition: quatf.h:111
Definition: vec2h.h:64
double fpreal64
Definition: SYS_Types.h:196
void SetReal(float real)
Set the real coefficient.
Definition: quatf.h:105
GLenum GLenum dst
Definition: glew.h:2410
Definition: vec3i.h:61
int int32
Definition: SYS_Types.h:39
void SetImaginary(const GfVec3d &imaginary)
Sets the imaginary part of the quaternion.
Definition: quaternion.h:80
pxr_half::half GfHalf
A 16-bit floating point data type.
Definition: half.h:42
Definition: vec4f.h:63
Quaternion class.
Definition: UT_Quaternion.h:51
GUSDUT_DECLARE_POD_TUPLE(class GfVec2h, fpreal16, 2)
Declare POD tuples for Gf types.
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1245
void SetImaginary(const GfVec3d &imaginary)
Set the imaginary coefficients.
Definition: quatd.h:111
Definition: vec2f.h:63
void SetReal(double real)
Set the real coefficient.
Definition: quatd.h:105
Definition: vec3d.h:63
void SetReal(GfHalf real)
Set the real coefficient.
Definition: quath.h:106
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:83
PXR_NAMESPACE_CLOSE_SCOPE SYS_DECLARE_IS_POD(PXR_NS::GfHalf)
Definition: quatd.h:60
#define _GUSDUT_DECLARE_UNCASTABLE(TYPE)
Declare a type as being uncastable.
Definition: UT_Gf.h:223
Definition: vec3h.h:64
GLsizei const GLfloat * value
Definition: glew.h:1849
float fpreal32
Definition: SYS_Types.h:195
static void Convert(const FROM &from, TO &to)
Definition: UT_Gf.h:451