HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
valueTransform.h
Go to the documentation of this file.
1 //
2 // Copyright 2025 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 
8 #ifndef PXR_BASE_VT_VALUE_TRANSFORM_H
9 #define PXR_BASE_VT_VALUE_TRANSFORM_H
10 
11 #include "pxr/pxr.h"
12 
13 #include "pxr/base/vt/dictionary.h"
14 #include "pxr/base/vt/types.h"
15 #include "pxr/base/vt/value.h"
16 #include "pxr/base/vt/valueRef.h"
17 
18 #include <optional>
19 
21 
23 {
24 private:
25  template <class Xf>
26  friend bool
27  VtValueCanTransform(VtValueRef obj, Xf const &xfObj);
28 
29  template <class Xf>
30  friend VtValue
31  VtValueTryTransform(VtValueRef obj, Xf const &xfObj);
32 
33  VT_API
34  static bool
35  Can(VtValueRef obj, std::type_info const &xfType);
36 
37  VT_API
38  static VtValue
39  Try(VtValueRef x, std::type_info const &xfType, void const *xfObj,
41 };
42 
43 /// Return true if `obj` is not empty, views an object that supports value
44 /// transforms, and has value transform support registered for transforms of
45 /// type `Xf`. Note that the type `Xf` does not have specific requirements, but
46 /// typically represents a possibly "polymorphic" transform that can apply to
47 /// many types. For example, "Transpose" may apply to many matrix types. Or
48 /// "Normalize" to many vector types.
49 template <class Xf>
50 bool
51 VtValueCanTransform(VtValueRef obj, Xf const &xfObj)
52 {
53  if (obj.IsEmpty() || !obj.CanTransform()) {
54  return false;
55  }
56  return Vt_TransformImpl::Can(obj, typeid(xfObj));
57 }
58 
59 /// Attempt to transform `obj` by `xfObj` and return the result. If no
60 /// transformation is done, return an empty value. Strongly typed transforms
61 /// are preferred to type-erased transforms.
62 template <class Xf>
63 VtValue
64 VtValueTryTransform(VtValueRef obj, Xf const &xfObj)
65 {
66  if (obj.IsEmpty() || !obj.CanTransform()) {
67  return {};
68  }
69  // Helper for type-erased transforms.
70  auto erasedXf = [&xfObj](VtValueRef in) -> VtValue {
71  return VtValueTryTransform(in, xfObj);
72  };
73  return Vt_TransformImpl
74  ::Try(obj, typeid(xfObj),
75  static_cast<void const *>(std::addressof(xfObj)), erasedXf);
76 }
77 
78 // Registration helper.
79 VT_API void
81  std::type_info const &objType,
82  std::type_info const &xfType,
83  void (*voidFn)(),
84  VtValue (*xform)(VtValueRef, void const *, void (*)()));
85 
86 template <bool RegisterForArrays, class T, class Xf>
87 void
88 Vt_RegisterTransformImpl(T (*fn)(T const &obj, Xf const &xform))
89 {
90  static_assert(!VtIsKnownValueType<T>(),
91  "Unexpected transform registration for one of the "
92  "known value types");
93 
95  "Use VT_VALUE_TYPE_CAN_TRANSFORM or directly specialize "
96  "VtValueTypeCanTransform<> before registering transform "
97  "functionality");
98 
99  using TypedFn = T (*)(T const &, Xf const &);
100  using VoidFn = void (*)();
101 
102  VoidFn voidFn = reinterpret_cast<VoidFn>(fn);
104  typeid(T), typeid(Xf), voidFn,
105  [](VtValueRef obj, void const *xf, void (*vFn)()) {
106  TypedFn tFn = reinterpret_cast<TypedFn>(vFn);
107  TF_DEV_AXIOM(obj.IsHolding<T>());
108  return VtValue {
109  tFn(obj.UncheckedGet<T>(), *static_cast<Xf const *>(xf))
110  };
111  });
112 
113  // Register array & array edit xforms of the same, if requested.
114  if constexpr (RegisterForArrays) {
115  // Arrays.
117  typeid(VtArray<T>), typeid(Xf), voidFn,
118  [](VtValueRef obj, void const *xf, void (*vFn)()) {
119  TypedFn tFn = reinterpret_cast<TypedFn>(vFn);
121  VtArray<T> const &src = obj.UncheckedGet<VtArray<T>>();
122  VtArray<T> xformed;
123  T const *srcPtr = src.cdata();
124  Xf const &xform = *static_cast<Xf const *>(xf);
125  xformed.resize(src.size(), [&](T *first, T *last) {
126  while (first != last) {
127  new (first++) T { tFn(*srcPtr++, xform) };
128  }
129  });
130  return VtValue::Take(xformed);
131  });
132 
133  // Array Edits.
135  typeid(VtArrayEdit<T>), typeid(Xf), voidFn,
136  [](VtValueRef obj, void const *xf, void (*vFn)()) {
137  TypedFn tFn = reinterpret_cast<TypedFn>(vFn);
140  VtArrayEdit<T> xformed = src;
141  Xf const &xform = *static_cast<Xf const *>(xf);
142  for (T &elem: xformed.GetMutableLiterals()) {
143  elem = tFn(elem, xform);
144  }
145  return VtValue::Take(xformed);
146  });
147  }
148 }
149 
150 /// Register a strongly-typed transformation of `T` by `Xf` but do not register
151 /// transforms for `VtArray<T>` and `VtArrayEdit<T>`. Call
152 /// VtRegisterTransform() to include arrays & array edits.
153 template <class T, class Xf>
154 void
155 VtRegisterTransformNoArrays(T (*fn)(T const &obj, Xf const &xform))
156 {
157  Vt_RegisterTransformImpl</*RegisterForArrays=*/false>(fn);
158 }
159 
160 /// Register a strongly-typed transformation of `T` by `Xf`, plus `VtArray<T>`
161 /// and `VtArrayEdit<T>`, transforming their elements and literals respectively.
162 /// Call VtRegisterTransformNoArrays() to avoid registering for arrays & array
163 /// edits.
164 template <class T, class Xf>
165 void
166 VtRegisterTransform(T (*fn)(T const &obj, Xf const &xform))
167 {
168  Vt_RegisterTransformImpl</*RegisterForArrays=*/true>(fn);
169 }
170 
171 VT_API void
173  std::type_info const &objType,
174  void (*voidFn)(),
175  VtValue (*xform)(VtValueRef, void (*)(),
177 
178 /// Register a type-erased transform-forwarder for objects of type `T` that may
179 /// contain `VtValue`s (directly or indirectly). For example, `VtDictionary`,
180 /// which is a map from string keys to `VtValue`s, registers type-erased
181 /// transform support to forward a transform to all of its values.
182 template <class T>
183 void
185  std::optional<T> (*fn)(T const &obj, TfFunctionRef<VtValue (VtValueRef)>))
186 {
187  static_assert(!VtIsKnownValueType<T>(),
188  "Unexpected transform registration for one of the "
189  "known value types");
190 
191  static_assert(VtValueTypeCanTransform<T>::value,
192  "Use VT_VALUE_TYPE_CAN_TRANSFORM or specialize "
193  "VtValueTypeCanTransform<> before registering transform "
194  "functionality");
195 
196  using TypedFn = std::optional<T> (*)(
198  using VoidFn = void (*)();
199 
200  VoidFn voidFn = reinterpret_cast<VoidFn>(fn);
202  typeid(T), voidFn,
203  [](VtValueRef obj, VoidFn vFn,
205  TypedFn tFn = reinterpret_cast<TypedFn>(vFn);
206  TF_DEV_AXIOM(obj.IsHolding<T>());
207  std::optional<T> optT = tFn(obj.UncheckedGet<T>(), xform);
208  VtValue ret;
209  if (optT) {
210  ret = std::move(*optT);
211  }
212  return ret;
213  });
214 }
215 
217 
218 #endif // PXR_BASE_VT_VALUE_TRANSFORM_H
void Vt_RegisterTransformImpl(T(*fn)(T const &obj, Xf const &xform))
GLint first
Definition: glcorearb.h:405
friend bool VtValueCanTransform(VtValueRef obj, Xf const &xfObj)
bool VtValueCanTransform(VtValueRef obj, Xf const &xfObj)
static VtValue Take(T &obj)
Definition: value.h:869
void
Definition: png.h:1083
#define PXR_NAMESPACE_OPEN_SCOPE
Definition: pxr.h:73
void VtRegisterTransformNoArrays(T(*fn)(T const &obj, Xf const &xform))
#define VT_API
Definition: api.h:23
VT_API void Vt_RegisterTypedTransform(std::type_info const &objType, std::type_info const &xfType, void(*voidFn)(), VtValue(*xform)(VtValueRef, void const *, void(*)()))
bool CanTransform() const
Definition: valueRef.h:544
void VtRegisterErasedTransform(std::optional< T >(*fn)(T const &obj, TfFunctionRef< VtValue(VtValueRef)>))
VtValue VtValueTryTransform(VtValueRef obj, Xf const &xfObj)
constexpr auto in(type t, int set) -> bool
Definition: core.h:611
bool IsHolding() const
Definition: valueRef.h:403
#define TF_DEV_AXIOM(cond)
void VtRegisterTransform(T(*fn)(T const &obj, Xf const &xform))
bool IsEmpty() const
Returns true iff this value is empty.
Definition: valueRef.h:515
Definition: types.h:152
GLint GLenum GLint x
Definition: glcorearb.h:409
__hostdev__ uint64_t last(uint32_t i) const
Definition: NanoVDB.h:5976
_TypeInfoFor< T >::GetObjResultType UncheckedGet() const
Definition: valueRef.h:452
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
GU_API void xform(CE_Context &context, bool recompile, int npts, const cl::Buffer &outPos, const cl::Buffer &inPos, const cl::Buffer &surfacexform, const cl::Buffer *grp=nullptr)
VT_API void Vt_RegisterErasedTransform(std::type_info const &objType, void(*voidFn)(), VtValue(*xform)(VtValueRef, void(*)(), TfFunctionRef< VtValue(VtValueRef)>))
Definition: value.h:89
friend VtValue VtValueTryTransform(VtValueRef obj, Xf const &xfObj)
GLenum src
Definition: glcorearb.h:1793