1 //
2 // Copyright 2016 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 /// \file alembicUtil.cpp
25
26 #include "pxr/pxr.h"
27 #include "pxr/usd/plugin/usdAbc/alembicUtil.h"
28 #include "pxr/base/tf/ostreamMethods.h"
29 #include <Alembic/Abc/IArrayProperty.h>
30 #include <Alembic/Abc/IScalarProperty.h>
31
32 PXR_NAMESPACE_OPEN_SCOPE
33
34
35 TF_DEFINE_PUBLIC_TOKENS(UsdAbc_AlembicContextFlagNames,
36 USDABC_ALEMBIC_CONTEXT_FLAG_NAMES);
37
38 namespace UsdAbc_AlembicUtil {
39
40 using namespace ::Alembic::Abc;
41
42 //
43 // Usd property value types.
44 //
45
46 TF_DEFINE_PUBLIC_TOKENS(UsdAbcPrimTypeNames, USD_ABC_PRIM_TYPE_NAMES);
47 TF_DEFINE_PUBLIC_TOKENS(UsdAbcPropertyNames, USD_ABC_PROPERTY_NAMES);
48 TF_DEFINE_PUBLIC_TOKENS(UsdAbcCustomMetadata, USD_ABC_CUSTOM_METADATA);
49
50 //
51 // UsdAbc_AlembicType
52 //
53
54 std::string
Stringify() const55 UsdAbc_AlembicType::Stringify() const
56 {
57 if (extent == 1) {
58 return TfStringPrintf("%s%s", PODName(pod), array ? "[]" : "");
59 }
60 else {
61 return TfStringPrintf("%s[%d]%s",
62 PODName(pod), extent, array ? "[]" : "");
63 }
64 }
65
66 bool
operator ==(const UsdAbc_AlembicType & rhs) const67 UsdAbc_AlembicType::operator==(const UsdAbc_AlembicType& rhs) const
68 {
69 return pod == rhs.pod &&
70 extent == rhs.extent &&
71 array == rhs.array;
72 }
73
74 bool
operator <(const UsdAbc_AlembicType & rhs) const75 UsdAbc_AlembicType::operator<(const UsdAbc_AlembicType& rhs) const
76 {
77 if (pod < rhs.pod) {
78 return true;
79 }
80 if (rhs.pod < pod) {
81 return false;
82 }
83 if (extent < rhs.extent) {
84 return true;
85 }
86 if (rhs.extent < extent) {
87 return false;
88 }
89 return array < rhs.array;
90 }
91
92 //
93 // Utilities
94 //
95
96 /// Format an Alembic version number as a string.
97 std::string
UsdAbc_FormatAlembicVersion(int32_t n)98 UsdAbc_FormatAlembicVersion(int32_t n)
99 {
100 return TfStringPrintf("%d.%d.%d", n / 10000, (n / 100) % 100, n % 100);
101 }
102
103 //
104 // POD property to/from Usd.
105 //
106
107 template <class UsdType, class AlembicType, size_t extent>
108 struct _ConvertPODScalar {
operator ()UsdAbc_AlembicUtil::_ConvertPODScalar109 bool operator()(const ICompoundProperty& parent, const std::string& name,
110 const ISampleSelector& iss,
111 const UsdAbc_AlembicDataAny& dst) const
112 {
113 // Something to hold the sample.
114 AlembicType sample[extent];
115
116 // Get the sample.
117 IScalarProperty property(parent, name);
118 property.get(sample, iss);
119
120 // Copy to dst.
121 return dst.Set(_ConvertPODToUsd<UsdType, AlembicType,extent>()(sample));
122 }
123
operator ()UsdAbc_AlembicUtil::_ConvertPODScalar124 _SampleForAlembic operator()(const VtValue& src) const
125 {
126 return _ConvertPODFromUsdScalar<UsdType, AlembicType, extent>()(src);
127 }
128 };
129
130 template <class UsdType, class AlembicType, size_t extent>
131 struct _ConvertPODArray {
operator ()UsdAbc_AlembicUtil::_ConvertPODArray132 bool operator()(const ICompoundProperty& parent, const std::string& name,
133 const ISampleSelector& iss,
134 const UsdAbc_AlembicDataAny& dst) const
135 {
136 // Something to hold the sample.
137 ArraySamplePtr sample;
138
139 // Get the sample.
140 IArrayProperty property(parent, name);
141 property.get(sample, iss);
142
143 // Copy each element.
144 VtArray<UsdType> result(sample->size());
145 _ConvertPODToUsdArray<UsdType, AlembicType, extent>()(
146 result.data(), sample->getData(), sample->size());
147
148 // Copy to dst.
149 return dst.Set(result);
150 }
151
operator ()UsdAbc_AlembicUtil::_ConvertPODArray152 _SampleForAlembic operator()(const VtValue& src) const
153 {
154 return _ConvertPODFromUsdArray<UsdType, AlembicType, extent>()(src);
155 }
156 };
157
158 //
159 // _SampleForAlembic
160 //
161
~_Holder()162 _SampleForAlembic::_Holder::~_Holder()
163 {
164 // Do nothing
165 }
166
167 bool
Error(std::string * message) const168 _SampleForAlembic::_Holder::Error(std::string* message) const
169 {
170 if (message) {
171 message->clear();
172 }
173 return false;
174 }
175
_EmptyHolder()176 _SampleForAlembic::_EmptyHolder::_EmptyHolder()
177 {
178 // Do nothing
179 }
180
~_EmptyHolder()181 _SampleForAlembic::_EmptyHolder::~_EmptyHolder()
182 {
183 // Do nothing
184 }
185
_ErrorHolder(const std::string & message)186 _SampleForAlembic::_ErrorHolder::_ErrorHolder(const std::string& message) :
187 _message(message)
188 {
189 // Do nothing
190 }
191
192 bool
Error(std::string * message) const193 _SampleForAlembic::_ErrorHolder::Error(std::string* message) const
194 {
195 if (message) {
196 *message = _message;
197 }
198 return true;
199 }
200
~_ErrorHolder()201 _SampleForAlembic::_ErrorHolder::~_ErrorHolder()
202 {
203 // Do nothing
204 }
205
~_VtValueHolder()206 _SampleForAlembic::_VtValueHolder::~_VtValueHolder()
207 {
208 // Do nothing
209 }
210
211 _SampleForAlembic
_ErrorSampleForAlembic(const std::string & msg)212 _ErrorSampleForAlembic(const std::string& msg)
213 {
214 return _SampleForAlembic(_SampleForAlembic::Error(msg));
215 }
216
217 //
218 // Alembic <-> Usd conversion registries.
219 //
220
221 //
222 // UsdAbc_AlembicDataConversion
223 //
224
UsdAbc_AlembicDataConversion()225 UsdAbc_AlembicDataConversion::UsdAbc_AlembicDataConversion()
226 {
227 // Do nothing
228 }
229
230 SdfValueTypeName
FindConverter(const UsdAbc_AlembicType & alembicType) const231 UsdAbc_AlembicDataConversion::FindConverter(
232 const UsdAbc_AlembicType& alembicType) const
233 {
234 for (const auto& c : _typeConverters) {
235 if (c.abcType == alembicType) {
236 return c.usdType;
237 }
238 }
239 return SdfValueTypeName();
240 }
241
242 const UsdAbc_AlembicDataConversion::ToUsdConverter&
GetToUsdConverter(const UsdAbc_AlembicType & alembicType,const SdfValueTypeName & usdType) const243 UsdAbc_AlembicDataConversion::GetToUsdConverter(
244 const UsdAbc_AlembicType& alembicType,
245 const SdfValueTypeName &usdType) const
246 {
247 for (const auto& c : _typeConverters) {
248 if (c.usdType == usdType && c.abcType == alembicType) {
249 return c.toUsdFn;
250 }
251 }
252 static const ToUsdConverter empty;
253 return empty;
254 }
255
256 UsdAbc_AlembicType
FindConverter(const SdfValueTypeName & usdType) const257 UsdAbc_AlembicDataConversion::FindConverter(
258 const SdfValueTypeName& usdType) const
259 {
260 for (const auto& c : _typeConverters) {
261 if (c.usdType == usdType) {
262 return c.abcType;
263 }
264 }
265 return UsdAbc_AlembicType();
266 }
267
268 const UsdAbc_AlembicDataConversion::FromUsdConverter&
GetConverter(const SdfValueTypeName & usdType) const269 UsdAbc_AlembicDataConversion::GetConverter(
270 const SdfValueTypeName& usdType) const
271 {
272 for (const auto& c : _typeConverters) {
273 if (c.usdType == usdType) {
274 return c.fromUsdFn;
275 }
276 }
277
278 static const FromUsdConverter empty;
279 return empty;
280 }
281
282 void
_AddConverter(const UsdAbc_AlembicType & alembicType,const SdfValueTypeName & usdType,const ToUsdConverter & usdConverter,const FromUsdConverter & abcConverter)283 UsdAbc_AlembicDataConversion::_AddConverter(
284 const UsdAbc_AlembicType& alembicType,
285 const SdfValueTypeName& usdType,
286 const ToUsdConverter& usdConverter,
287 const FromUsdConverter& abcConverter)
288 {
289 _typeConverters.push_back(
290 _ConverterData(usdType, alembicType, usdConverter, abcConverter)
291 );
292 }
293
UsdAbc_AlembicConversions()294 UsdAbc_AlembicConversions::UsdAbc_AlembicConversions()
295 {
296 // Preferred conversions.
297 data.AddConverter<bool, bool_t>();
298 data.AddConverter<uint8_t, uint8_t>();
299 data.AddConverter<int32_t, int32_t>();
300 data.AddConverter<uint32_t, uint32_t>();
301 data.AddConverter<int64_t, int64_t>();
302 data.AddConverter<uint64_t, uint64_t>();
303 data.AddConverter<GfHalf, ::half>();
304 data.AddConverter<float, float32_t>();
305 data.AddConverter<double, float64_t>();
306 data.AddConverter<std::string, std::string>();
307 data.AddConverter<GfVec2i, int32_t, 2>();
308 data.AddConverter<GfVec2h, GfHalf, 2>();
309 data.AddConverter<GfVec2f, float32_t, 2>();
310 data.AddConverter<GfVec2d, float64_t, 2>();
311 data.AddConverter<GfVec3i, int32_t, 3>();
312 data.AddConverter<GfVec3h, GfHalf, 3>();
313 data.AddConverter<GfVec3f, float32_t, 3>();
314 data.AddConverter<GfVec3d, float64_t, 3>();
315 data.AddConverter<GfVec4i, int32_t, 4>();
316 data.AddConverter<GfVec4h, GfHalf, 4>();
317 data.AddConverter<GfVec4f, float32_t, 4>();
318 data.AddConverter<GfVec4d, float64_t, 4>();
319 data.AddConverter<GfQuatf, float32_t, 4>();
320 data.AddConverter<GfQuatd, float64_t, 4>();
321 data.AddConverter<GfMatrix4d, float64_t, 16>();
322
323 // Other conversions.
324 data.AddConverter<int, int8_t>();
325 data.AddConverter<int, int16_t>();
326 data.AddConverter<unsigned int, uint16_t>();
327 data.AddConverter<TfToken, std::string>();
328 data.AddConverter<GfMatrix4d, float32_t, 16>();
329
330 // Role conversions.
331 data.AddConverter<GfVec3h, GfHalf, 3>(SdfValueTypeNames->Point3h);
332 data.AddConverter<GfVec3f, float32_t, 3>(SdfValueTypeNames->Point3f);
333 data.AddConverter<GfVec3d, float64_t, 3>(SdfValueTypeNames->Point3d);
334 data.AddConverter<GfVec3h, GfHalf, 3>(SdfValueTypeNames->Normal3h);
335 data.AddConverter<GfVec3f, float32_t, 3>(SdfValueTypeNames->Normal3f);
336 data.AddConverter<GfVec3d, float64_t, 3>(SdfValueTypeNames->Normal3d);
337 data.AddConverter<GfVec3h, GfHalf, 3>(SdfValueTypeNames->Vector3h);
338 data.AddConverter<GfVec3f, float32_t, 3>(SdfValueTypeNames->Vector3f);
339 data.AddConverter<GfVec3d, float64_t, 3>(SdfValueTypeNames->Vector3d);
340 data.AddConverter<GfVec3h, GfHalf, 3>(SdfValueTypeNames->Color3h);
341 data.AddConverter<GfVec3f, float32_t, 3>(SdfValueTypeNames->Color3f);
342 data.AddConverter<GfVec3d, float64_t, 3>(SdfValueTypeNames->Color3d);
343 data.AddConverter<GfMatrix4d, float64_t, 16>(SdfValueTypeNames->Frame4d);
344 data.AddConverter<GfVec2f, float32_t, 2>(SdfValueTypeNames->TexCoord2f);
345 }
346
347 } // namespace UsdAbc_AlembicUtil
348
349 PXR_NAMESPACE_CLOSE_SCOPE
350
351