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 <UT/UT_VectorTypes.h>
41 
43 
44 /// Helpers for working with Gf types (vectors, matrices, etc.) within the HDK.
45 struct GusdUT_Gf
46 {
47  /// Struct providing info about type equivalence between
48  /// UT and Gf types. Each struct defines:
49  ///
50  /// \code
51  /// static const bool isSpecialized = true;
52  /// typedef ... GfType;
53  /// typedef ... UtType;
54  /// typedef ... AltType; // Type from the alternate API.
55  /// // Eg., if this is a UT type, it will be the Gf
56  /// // type, and vice versa.
57  /// \endcode
58  template <class GF_OR_UT_TYPE>
60  {
61  static const bool isSpecialized = false;
62  };
63 
64  /// Struct defining whether or not a type is valid for direct casting to
65  /// other types. We explicitly disable casting for types that require some
66  /// kind of data manipulation when going in-between UT and Gf.
67  template <class GF_OR_UT_TYPE>
68  struct Castable
69  {
70  static const bool value = true;
71  };
72 
73  /// Helpers for casting between UT and Gf types. The cast can go either way.
74  /// This can be done with a reinterpret cast, but this cast adds a bit of
75  /// extra compile-time checks to make sure that this really is safe.
76  ///
77  /// These cast methods only take a single template argument. The output
78  /// is cast to the equivalent type from the alternate API. For example,
79  /// if given a UT_Matrix4D, the cast is to a GfMatrix4d, and vice versa.
80  ///
81  /// \note Any type used here must be declared with a specialization of
82  /// GusdUT_TypeTraits::PODTuple (see GUSD_DECLARE_POD_TUPLE).
83  ///
84  /// Examples:
85  ///
86  /// \code
87  /// // implicit cast of Gf->UT
88  /// UT_Matrix4D& mx = GusdUT_Gf::Cast(gfMatrix4dInstance);
89  /// UT_Matrix4D* mx = GusdUT_Gf::Cast(gfMatrix4dInstancePtr);
90  /// const UT_Matrix4D& mx = GusdUT_Gf::Cast(gfMatrix4dInstanceConst);
91  /// const UT_Matrix4D* mx = GusdUT_Gf::Cast(gfMatrix4dInstancePtrConst);
92  ///
93  /// // implicit cast of UT->Gf
94  /// GfMatrix4d& mx = GusdUT_Gf::Cast(utMatrix4dInstance);
95  /// GfMatrix4d* mx = GusdUT_Gf::Cast(utMatrix4dInstancePtr);
96  /// const GfMatrix4d& mx = GusdUT_Gf::Cast(utMatrix4dInstanceConst);
97  /// const GfMatrix4d* mx = GusdUT_Gf::Cast(utMatrix4dInstancePtrConst);
98  ///
99  /// // compile error! types are not bitwise compatible
100  /// UT_Matrix4D src;
101  /// GfMatrix4f& mx = GusdUT_Gf::Cast(src);
102  ///
103  /// // compile error! discards cv-qualifier.
104  /// const UT_Matrix4F& src = ...;
105  /// GfMatrix4f& mx = GusdUT_Gf::Cast(src);
106  /// \endcode
107  /// @{
108  template <class T>
109  static inline const typename
111 
112  template <class T>
113  static inline typename
115 
116  template <class T>
117  static inline const typename
119 
120  template <class T>
121  static inline typename
123  /// @}
124 
125  /// Explicit casts between UT and Gf types.
126  /// This is just like the implicit cast methods, except that the source and
127  /// target types are explicitly specified via template arguments.
128  /// This can be used for casting between types when the types aren't exact
129  /// counterparts. For instance, we can safely cast a GfMatrix2d to a
130  /// UT_Vector4D, even though UT_Vector4D is not UT's equivalence type for
131  /// GfMatrix2d.
132  ///
133  /// @{
134  template <class FROM, class TO>
135  static inline const TO* Cast(const FROM* val);
136 
137  template <class FROM, class TO>
138  static inline TO* Cast(FROM* val);
139 
140  template <class FROM, class TO>
141  static inline const TO& Cast(const FROM& val);
142 
143  template <class FROM, class TO>
144  static inline TO& Cast(FROM& val);
145  /// @}
146 
147 
148  /// Convert between UT and Gf types. This works for any pod tuples that have
149  /// equivalent tuple sizes, even if their underlying precision differs.
150  ///
151  /// \note Any type used here must be declared with a specialization of
152  /// GusdUT_TypeTraits::PODTuple (see GUSD_DECLARE_POD_TUPLE).
153  template <class FROM, class TO>
154  static inline void Convert(const FROM& from, TO& to);
155 
156 
157  /// Conversions between GF and UT quaternions.
158  /// Gf and UT have a different ordering of the real component,
159  /// hence the need for speciailized converters.
160  ///
161  /// XXX: 4d vector types are sometimes used in place of GfQuaternion,
162  /// hence their inclusion here. That is primarily the fault of USD:
163  /// if USD gets a real quaternion type, we can clean these up.
164  /// @{
165  template <class T>
166  static inline void Convert(const GfQuaternion& from, UT_QuaternionT<T>& to);
167 
168  template <class T>
169  static inline void Convert(const GfQuatd& from, UT_QuaternionT<T>& to);
170 
171  template <class T>
172  static inline void Convert(const GfQuatf& from, UT_QuaternionT<T>& to);
173 
174  template <class T>
175  static inline void Convert(const GfQuath& from, UT_QuaternionT<T>& to);
176 
177  template <class T>
178  static inline void Convert(const GfVec4d& from, UT_QuaternionT<T>& to);
179 
180  template <class T>
181  static inline void Convert(const GfVec4f& from, UT_QuaternionT<T>& to);
182 
183  template <class T>
184  static inline void Convert(const UT_QuaternionT<T>& from, GfQuaternion& to);
185 
186  template <class T>
187  static inline void Convert(const UT_QuaternionT<T>& from, GfQuatd& to);
188 
189  template <class T>
190  static inline void Convert(const UT_QuaternionT<T>& from, GfQuatf& to);
191 
192  template <class T>
193  static inline void Convert(const UT_QuaternionT<T>& from, GfQuath& to);
194 
195  template <class T>
196  static inline void Convert(const UT_QuaternionT<T>& from, GfVec4d& to);
197 
198  template <class T>
199  static inline void Convert(const UT_QuaternionT<T>& from, GfVec4f& to);
200  /// @}
201 
202 private:
203  template <class T, class GFQUAT>
204  static inline void _ConvertQuat(const GFQUAT& from, UT_QuaternionT<T>& to);
205 
206  template <class T>
207  static inline void _AssertIsPodTuple();
208 
209  template <class FROM, class TO>
210  static inline void _AssertCanCast();
211 
212  // Our casting tricks assume that the typedefs set in SYS_Types are
213  // referencing the types we think they are. Verify our assumptions.
215  "std::is_same<fpreal32,float>::value");
217  "std::is_same<fpreal64,double>::value");
218 };
219 
220 
221 /// Declare a type as being uncastable.
222 #define _GUSDUT_DECLARE_UNCASTABLE(TYPE) \
223  template <> \
224  struct GusdUT_Gf::Castable<TYPE> \
225  { \
226  static const bool value = false; \
227  };
228 
229 
230 /// Declare a partial type equivalence. This specifies a one-way
231 /// type equivalence.
232 #define _GUSDUT_DECLARE_PARTIAL_EQUIVALENCE(TYPE,GFTYPE,UTTYPE,ALTTYPE) \
233  template <> \
234  struct GusdUT_Gf::TypeEquivalence<TYPE> { \
235  static const bool isSpecialized = true; \
236  typedef GFTYPE GfType; \
237  typedef UTTYPE UtType; \
238  typedef ALTTYPE AltType; \
239  };
240 
241 /// Declare type equivalent between UT and Gf types.
242 /// Only a single equivalence relationship may be defined per type.
243 ///
244 /// The type info for both types must be declared first!
245 #define _GUSDUT_DECLARE_EQUIVALENCE(GFTYPE,UTTYPE) \
246  _GUSDUT_DECLARE_PARTIAL_EQUIVALENCE(GFTYPE,GFTYPE,UTTYPE,UTTYPE); \
247  _GUSDUT_DECLARE_PARTIAL_EQUIVALENCE(UTTYPE,GFTYPE,UTTYPE,GFTYPE);
248 
249 /// Declare POD tuples for Gf types.
253 
257 
261 
265 
269 
273 
277 
279 
280 /// Declare types as PODs, so that UT_Arrays of the types can be optimized.
281 /// This is done to ensure that Gf types are handled in the same manner as
282 /// UT types: the same is done for UT types as well (see UT/UT_VectorTypes.h).
283 
285 
286 SYS_DECLARE_IS_POD(PXR_NS::GfVec2h);
287 SYS_DECLARE_IS_POD(PXR_NS::GfVec3h);
288 SYS_DECLARE_IS_POD(PXR_NS::GfVec4h);
289 
290 SYS_DECLARE_IS_POD(PXR_NS::GfVec2f);
291 SYS_DECLARE_IS_POD(PXR_NS::GfVec3f);
292 SYS_DECLARE_IS_POD(PXR_NS::GfVec4f);
293 
294 SYS_DECLARE_IS_POD(PXR_NS::GfVec2d);
295 SYS_DECLARE_IS_POD(PXR_NS::GfVec3d);
296 SYS_DECLARE_IS_POD(PXR_NS::GfVec4d);
297 
298 SYS_DECLARE_IS_POD(PXR_NS::GfVec2i);
299 SYS_DECLARE_IS_POD(PXR_NS::GfVec3i);
300 SYS_DECLARE_IS_POD(PXR_NS::GfVec4i);
301 
302 SYS_DECLARE_IS_POD(PXR_NS::GfQuath);
303 SYS_DECLARE_IS_POD(PXR_NS::GfQuatf);
304 SYS_DECLARE_IS_POD(PXR_NS::GfQuatd);
305 
306 SYS_DECLARE_IS_POD(PXR_NS::GfMatrix2f);
307 SYS_DECLARE_IS_POD(PXR_NS::GfMatrix3f);
308 SYS_DECLARE_IS_POD(PXR_NS::GfMatrix4f);
309 
310 SYS_DECLARE_IS_POD(PXR_NS::GfMatrix2d);
311 SYS_DECLARE_IS_POD(PXR_NS::GfMatrix3d);
312 SYS_DECLARE_IS_POD(PXR_NS::GfMatrix4d);
313 
315 
316 // No casting on quaternions; real component is ordered
317 // in a different way between UT and Gf.
324 
325 // Declare type correspondances between Gf and UT.
329 
333 
337 
341 
345 
349 
353 
354 
355 template <class T>
356 void
357 GusdUT_Gf::_AssertIsPodTuple()
358 {
359  static_assert(GusdIsPodTuple<T>(), "Type is not declared as a POD-tuple");
360 }
361 
362 
363 template <class FROM, class TO>
364 void
365 GusdUT_Gf::_AssertCanCast()
366 {
367  _AssertIsPodTuple<FROM>();
368  _AssertIsPodTuple<TO>();
369  static_assert(Castable<FROM>::value, "Source is not castable");
370  static_assert(Castable<TO>::value, "Output is not castable");
371  static_assert(GusdPodTuplesAreBitwiseCompatible<FROM,TO>(),
372  "Types in cast are not bitwise compatible");
373 }
374 
375 
376 template <class FROM, class TO>
377 const TO*
378 GusdUT_Gf::Cast(const FROM* val)
379 {
380  _AssertCanCast<FROM,TO>();
381  return reinterpret_cast<const TO*>(val);
382 }
383 
384 
385 template <class FROM, class TO>
386 TO*
388 {
389  _AssertCanCast<FROM,TO>();
390  return reinterpret_cast<TO*>(val);
391 }
392 
393 
394 template <class FROM, class TO>
395 const TO&
396 GusdUT_Gf::Cast(const FROM& val)
397 {
398  _AssertCanCast<FROM,TO>();
399  return reinterpret_cast<const TO&>(val);
400 }
401 
402 
403 template <class FROM, class TO>
404 TO&
406 {
407  _AssertCanCast<FROM,TO>();
408  return reinterpret_cast<TO&>(val);
409 }
410 
411 
412 template <class T>
415 {
416  _AssertIsPodTuple<T>();
417  return Cast<T,typename TypeEquivalence<T>::AltType>(val);
418 }
419 
420 
421 template <class T>
424 {
425  _AssertIsPodTuple<T>();
426  return Cast<T, typename TypeEquivalence<T>::AltType>(val);
427 }
428 
429 
430 template <class T>
433 {
434  _AssertIsPodTuple<T>();
435  return Cast<T, typename TypeEquivalence<T>::AltType>(val);
436 }
437 
438 
439 template <class T>
442 {
443  _AssertIsPodTuple<T>();
444  return Cast<T, typename TypeEquivalence<T>::AltType>(val);
445 }
446 
447 
448 template <class FROM, class TO>
449 void
450 GusdUT_Gf::Convert(const FROM& from, TO& to)
451 {
452  using FromPodType = typename GusdPodTupleTraits<FROM>::ValueType;
453  using ToPodType = typename GusdPodTupleTraits<TO>::ValueType;
454 
455  _AssertIsPodTuple<FROM>();
456  _AssertIsPodTuple<TO>();
457  static_assert(GusdPodTuplesAreCompatible<FROM,TO>(),
458  "Types are not compatible (mismatched tuple sizes)");
459 
460  const auto* src = reinterpret_cast<const FromPodType*>(&from);
461  ToPodType* dst = reinterpret_cast<ToPodType*>(&to);
462 
463  for (int i = 0; i < GusdGetTupleSize<FROM>(); ++i) {
464  dst[i] = static_cast<ToPodType>(src[i]);
465  }
466 }
467 
468 
469 template <class T, class GFQUAT>
470 void
471 GusdUT_Gf::_ConvertQuat(const GFQUAT& from, UT_QuaternionT<T>& to)
472 {
473  reinterpret_cast<UT_Vector3T<T>&>(to) = Cast(from.GetImaginary());
474  to(3) = from.GetReal();
475 }
476 
477 
478 template <class T>
479 void
481 {
482  return _ConvertQuat(from, to);
483 }
484 
485 
486 template <class T>
487 void
489 {
490  return _ConvertQuat(from, to);
491 }
492 
493 
494 template <class T>
495 void
497 {
498  return _ConvertQuat(from, to);
499 }
500 
501 
502 template <class T>
503 void
505 {
506  return _ConvertQuat(from, to);
507 }
508 
509 
510 template <class T>
511 void
513 {
514  to = UT_QuaternionT<T>(from[1],from[2],from[3],from[0]);
515 }
516 
517 
518 template <class T>
519 void
521 {
522  to = UT_QuaternionT<T>(from[1],from[2],from[3],from[0]);
523 }
524 
525 
526 template <class T>
527 void
529 {
530  to.SetReal(from.w());
531  to.SetImaginary(GfVec3d(from.x(), from.y(), from.z()));
532 }
533 
534 
535 template <class T>
536 void
538 {
539  to.SetReal(from.w());
540  to.SetImaginary(GfVec3d(from.x(), from.y(), from.z()));
541 }
542 
543 
544 template <class T>
545 void
547 {
548  to.SetReal(from.w());
549  to.SetImaginary(GfVec3f(from.x(), from.y(), from.z()));
550 }
551 
552 
553 template <class T>
554 void
556 {
557  to.SetReal(GfHalf(from.w()));
558  to.SetImaginary(
559  GfVec3h(GfHalf(from.x()), GfHalf(from.y()), GfHalf(from.z())));
560 }
561 
562 
563 template <class T>
564 void
566 {
567  to = GfVec4d(from.w(), from.x(), from.y(), from.z());
568 }
569 
570 
571 template <class T>
572 void
574 {
575  to = GfVec4f(from.w(), from.x(), from.y(), from.z());
576 }
577 
578 
579 #undef _GUSDUT_DECLARE_UNCASTABLE
580 #undef _GUSDUT_DECLARE_PARTIAL_EQUIVALENCE
581 #undef _GUSDUT_DECLARE_EQUIVALENCE
582 
584 
585 #endif /*_GUSD_UT_GF_H_*/
Definition: quath.h:60
Definition: vec4i.h:60
int int32
Definition: SYS_Types.h:39
Helpers for working with Gf types (vectors, matrices, etc.) within the HDK.
Definition: UT_Gf.h:45
void SetReal(double real)
Sets the real part of the quaternion.
Definition: quaternion.h:74
Definition: vec2i.h:60
#define _GUSDUT_DECLARE_EQUIVALENCE(GFTYPE, UTTYPE)
Definition: UT_Gf.h:245
GLsizei const GLfloat * value
Definition: glcorearb.h:824
void SetImaginary(const GfVec3h &imaginary)
Set the imaginary coefficients.
Definition: quath.h:115
Definition: vec3f.h:62
static const bool isSpecialized
Definition: UT_Gf.h:61
static const TypeEquivalence< T >::AltType * Cast(const T *val)
Definition: UT_Gf.h:441
Definition: vec4d.h:62
3D Vector class.
4D Vector class.
Definition: UT_Vector4.h:174
2D Vector class.
Definition: UT_Vector2.h:159
float fpreal32
Definition: SYS_Types.h:200
Definition: quatf.h:59
Definition: vec2d.h:62
double fpreal64
Definition: SYS_Types.h:201
Definition: vec4h.h:63
void SetImaginary(const GfVec3f &imaginary)
Set the imaginary coefficients.
Definition: quatf.h:114
Definition: vec2h.h:63
void SetReal(float real)
Set the real coefficient.
Definition: quatf.h:108
Definition: vec3i.h:60
void SetImaginary(const GfVec3d &imaginary)
Sets the imaginary part of the quaternion.
Definition: quaternion.h:79
pxr_half::half GfHalf
A 16-bit floating point data type.
Definition: half.h:41
Definition: vec4f.h:62
GLenum GLenum dst
Definition: glcorearb.h:1793
Quaternion class.
Definition: GEO_Detail.h:48
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:1441
void SetImaginary(const GfVec3d &imaginary)
Set the imaginary coefficients.
Definition: quatd.h:114
Definition: vec2f.h:62
void SetReal(double real)
Set the real coefficient.
Definition: quatd.h:108
Definition: vec3d.h:62
void SetReal(GfHalf real)
Set the real coefficient.
Definition: quath.h:109
GLuint GLfloat * val
Definition: glcorearb.h:1608
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
PXR_NAMESPACE_CLOSE_SCOPE SYS_DECLARE_IS_POD(PXR_NS::GfHalf)
Definition: core.h:1131
Definition: quatd.h:59
#define _GUSDUT_DECLARE_UNCASTABLE(TYPE)
Declare a type as being uncastable.
Definition: UT_Gf.h:222
Definition: vec3h.h:63
static void Convert(const FROM &from, TO &to)
Definition: UT_Gf.h:450
GLenum src
Definition: glcorearb.h:1793