27 #include <type_traits>
29 #include <FnAttribute/FnAttribute.h>
31 #include "pxr/base/tf/envSetting.h"
32 #include "pxr/base/vt/array.h"
34 #include "vtKatana/internalTraits.h"
36 PXR_NAMESPACE_OPEN_SCOPE
38 namespace VtKatana_Internal {
42 template <
typename AttributeType>
44 typedef typename AttributeType::array_type SampleType;
48 : Vt_ArrayForeignDataSource(VtKatana_SampleSource::_Detached),
49 _dataAttribute(attribute) {}
50 SampleType _GetNearestSample(
float sample) {
51 return _dataAttribute.getNearestSample(sample);
55 static void _Detached(Vt_ArrayForeignDataSource* selfBase) {
61 AttributeType _dataAttribute;
65 template <
typename ElementType>
67 typedef typename VtKatana_GetKatanaAttrType<ElementType>::type AttrType;
69 typename VtKatana_GetKatanaAttrValueType<ElementType>::type ValueType;
70 typedef typename AttrType::array_type SampleType;
73 template <
typename T = ElementType>
75 typename std::enable_if<VtKatana_IsNumericScalar<T>::value,
void>::type
76 _CheckAndWarnSize(
size_t size) {
80 template <
typename T = ElementType>
82 typename std::enable_if<VtKatana_IsNumericTuple<T>::value,
void>::type
83 _CheckAndWarnSize(
size_t size) {
86 "Elements sequence will be truncated because size '%zu' is "
87 "not divisible by element tuple size '%zu'.",
92 template <
typename T = ElementType>
93 static typename std::enable_if<VtKatana_IsNumericCastableTuple<T>::value,
95 _CopyUnaligned(
const SampleType& sample) {
98 for (
size_t i = 0; i < size;
106 template <
typename T = ElementType>
107 static typename std::enable_if<VtKatana_IsNumericCastableScalar<T>::value,
109 _CopyUnaligned(
const SampleType& sample) {
111 result.
assign(sample.begin(), sample.end());
119 template <
typename T = ElementType>
120 static typename std::enable_if<VtKatana_IsNumericCastable<T>::value,
123 typedef typename VtKatana_GetNumericScalarType<ElementType>::type
125 std::unique_ptr<ZeroCopySource> source(
new ZeroCopySource(attribute));
126 auto sample = source->_GetNearestSample(time);
127 _CheckAndWarnSize<T>(sample.size());
130 if (VtKatana_IsSampleAligned<T>(sample)) {
132 data =
const_cast<T*
>(VtKatana_GetVtPtr<T>(sample));
133 VtArray<T> result(source.release(), data, size);
136 return _CopyUnaligned(sample);
142 template <
typename T = ElementType>
143 static typename std::enable_if<VtKatana_IsNumericCastable<T>::value,
145 Copy(
const SampleType& sample) {
146 _CheckAndWarnSize<T>(sample.size());
148 if (VtKatana_IsSampleAligned<T>(sample)) {
149 auto dataBegin = VtKatana_GetVtPtr<T>(sample);
150 auto dataEnd = dataBegin + size;
152 result.
assign(dataBegin, dataEnd);
155 return _CopyUnaligned(sample);
161 template <
typename T = ElementType>
163 typename std::enable_if<VtKatana_IsNumericCopyRequiredScalar<T>::value,
165 Copy(
const SampleType& array) {
166 typedef typename VtKatana_GetNumericScalarType<ElementType>::type
169 result.
assign(array.begin(), array.end());
175 template <
typename T = ElementType>
177 typename std::enable_if<VtKatana_IsNumericCopyRequiredTuple<T>::value,
179 Copy(
const SampleType& array) {
181 typename VtKatana_GetNumericCopyTuplePeer<T>::type TupleCopyPeer;
182 typedef typename VtKatana_GetNumericScalarType<ElementType>::type
186 static_assert(std::is_same<ScalarType, GfHalf>::value,
"");
190 _CheckAndWarnSize<T>(array.size());
192 auto data =
reinterpret_cast<const TupleCopyPeer*
>(array.data());
194 std::transform(data, data + size, result.
begin(),
195 [](
const TupleCopyPeer& peer) {
return T(peer); });
200 template <
typename T = ElementType>
202 typename std::enable_if<VtKatana_IsString<T>::value,
VtArray<T>>::type
203 Copy(
const SampleType& sample) {
205 result.
assign(sample.begin(), sample.end());
215 template <
typename T = ElementType>
216 static typename std::enable_if<VtKatana_HoldsString<T>::value,
218 Copy(
const SampleType& sample) {
220 std::transform(sample.begin(), sample.end(), result.begin(),
221 [](
const std::string& element) {
return T(element); });
228 template <
typename T = ElementType>
229 static typename std::enable_if<VtKatana_IsNumericCopyRequired<T>::value ||
233 auto nearestSample = attribute.getNearestSample(sample);
234 return Copy(nearestSample);
240 template <
typename T = ElementType>
241 static typename std::enable_if<VtKatana_IsNumericCastable<T>::value,
244 static bool zeroCopyEnabled =
246 if (zeroCopyEnabled) {
249 auto nearestSample = attribute.getNearestSample(sample);
250 return Copy(nearestSample);
254 template <
typename T = ElementType>
255 static typename std::enable_if<VtKatana_IsNumericScalar<T>::value, T>::type
256 CopyElement(
const AttrType& attr,
float time) {
257 auto nearestSample = attr.getNearestSample(time);
258 return nearestSample.data()[0];
261 template <
typename T = ElementType>
263 CopyElement(
const AttrType& attr,
float time) {
264 auto nearestSample = attr.getNearestSample(time);
265 return T(nearestSample.data());
268 template <
typename T = ElementType>
270 CopyElement(
const AttrType& attr) {
272 typename VtKatana_GetNumericCopyTuplePeer<T>::type TupleCopyPeer;
273 typedef typename VtKatana_GetNumericScalarType<ElementType>::type
277 static_assert(std::is_same<ScalarType, GfHalf>::value,
"");
281 auto nearestSample = attr.getNearestSample(0.0f);
282 const TupleCopyPeer* peer =
reinterpret_cast<const TupleCopyPeer*
>(nearestSample.data());
286 template <
typename T = ElementType>
287 static typename std::enable_if<GfIsGfMatrix<T>::value, T>::type
288 CopyElement(
const AttrType& attr) {
289 typedef typename VtKatana_GetNumericScalarType<ElementType>::type
291 auto nearestSample = attr.getNearestSample(0.0f);
292 auto data =
reinterpret_cast<const ScalarType(*)[T::numRows]
>(
293 nearestSample.data());
297 template <
typename T = ElementType>
298 static typename std::enable_if<VtKatana_IsString<T>::value, T>::type
299 CopyElement(
const AttrType& attr) {
300 static const std::string defValue;
301 return attr.getValue(defValue,
false);
304 template <
typename T = ElementType>
305 static typename std::enable_if<VtKatana_HoldsString<T>::value, T>::type
306 CopyElement(
const AttrType& attr) {
307 static const std::string defValue;
308 std::string value = attr.getValue(defValue,
false);
314 PXR_NAMESPACE_CLOSE_SCOPE
Gets the 'tuple size' of T, or number of elements a numeric type contains.
static std::enable_if< VtKatana_IsNumericCopyRequiredTuple< T >::value, VtArray< T > >::type Copy(const SampleType &array)
Copy utility for numeric tuple types require an intermediate copy to construct a VtArray (ie...
T const & TfGetEnvSetting(TfEnvSetting< T > &setting)
Returns the value of the specified env setting, registered using TF_DEFINE_ENV_SETTING.
static std::enable_if< VtKatana_IsNumericCopyRequiredScalar< T >::value, VtArray< T > >::type Copy(const SampleType &array)
Copy utility for numeric scalar types require an intermediate copy to construct a VtArray (ie...
#define TF_WARN(...)
Issue a warning, but continue execution.
static std::enable_if< VtKatana_IsNumericCastable< T >::value, const VtArray< T > >::type ZeroCopy(const AttrType &attribute, float time)
Zero copy utility for numeric types (GfVec3f, GfMatrix4d, ...).
iterator begin()
Return a non-const iterator to the start of the array.
static std::enable_if< VtKatana_IsNumericCastable< T >::value, VtArray< T > >::type Copy(const SampleType &sample)
Copy utility for numeric types that don't require an intermediate copy to construct a VtArray (ie...
The VtKatana_SampleSource holds a reference to the katana attribute to preserve the lifetime of all i...
static std::enable_if< VtKatana_IsNumericCopyRequired< T >::value||VtKatana_IsOrHoldsString< T >::value, const VtArray< T > >::type MapInternal(const AttrType &attribute, float sample=0.0f)
Maps a given attribute sample to a VtArray.
size_t size() const
Return the total number of elements in this array.
static std::enable_if< VtKatana_IsNumericCastable< T >::value, const VtArray< T > >::type MapInternal(const AttrType &attribute, float sample=0.0f)
Maps a given attribute sample to a VtArray.
static std::enable_if< VtKatana_HoldsString< T >::value, VtArray< T > >::type Copy(const SampleType &sample)
Copy utility for holders of std::string (This assumes that the holder can be constructed from a strin...
Castable numeric types don't require intermediate copies, and allows for ZeroCopy behavior...
Conversion utilities for Katana attributes to VtArrays containing type T.
static std::enable_if< VtKatana_IsString< T >::value, VtArray< T > >::type Copy(const SampleType &sample)
Copy utility for std::string.
void assign(ForwardIter first, ForwardIter last)
Assign array contents.