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
25 #include "pxr/pxr.h"
26 #include "pxr/usd/sdf/schema.h"
27 #include "pxr/usd/sdf/layer.h"
28 #include "pxr/usd/sdf/layerOffset.h"
29 #include "pxr/usd/sdf/parserValueContext.h"
30 #include "pxr/usd/sdf/payload.h"
31 #include "pxr/usd/sdf/reference.h"
32 #include "pxr/usd/sdf/schemaTypeRegistration.h"
33 #include "pxr/usd/sdf/tokens.h"
34 #include "pxr/usd/sdf/types.h"
35 #include "pxr/usd/sdf/valueTypeRegistry.h"
36
37 #include "pxr/base/plug/plugin.h"
38 #include "pxr/base/plug/registry.h"
39 #include "pxr/base/tf/diagnostic.h"
40 #include "pxr/base/tf/instantiateSingleton.h"
41 #include "pxr/base/trace/trace.h"
42 #include "pxr/base/vt/dictionary.h"
43
44 #include <deque>
45 #include <map>
46 #include <set>
47 #include <vector>
48
49 using std::map;
50 using std::set;
51 using std::string;
52 using std::vector;
53
54 PXR_NAMESPACE_OPEN_SCOPE
55
56 TF_DEFINE_PRIVATE_TOKENS(
57 _tokens,
58
59 ((Default, "default"))
60 ((DisplayGroup,"displayGroup"))
61 ((Type,"type"))
62 ((AppliesTo,"appliesTo"))
63 );
64
65 //
66 // SdfSchemaBase::FieldDefinition
67 //
68
FieldDefinition(const SdfSchemaBase & schema,const TfToken & name,const VtValue & fallbackValue)69 SdfSchemaBase::FieldDefinition::FieldDefinition(
70 const SdfSchemaBase& schema,
71 const TfToken& name,
72 const VtValue& fallbackValue)
73 : _schema(schema),
74 _name(name),
75 _fallbackValue(fallbackValue),
76 _isPlugin(false),
77 _isReadOnly(false),
78 _holdsChildren(false),
79 _valueValidator(nullptr),
80 _listValueValidator(nullptr),
81 _mapKeyValidator(nullptr),
82 _mapValueValidator(nullptr)
83 {
84 }
85
86 const TfToken&
GetName() const87 SdfSchemaBase::FieldDefinition::GetName() const
88 {
89 return _name;
90 }
91
92 const VtValue&
GetFallbackValue() const93 SdfSchemaBase::FieldDefinition::GetFallbackValue() const
94 {
95 return _fallbackValue;
96 }
97
98 const SdfSchemaBase::FieldDefinition::InfoVec&
GetInfo() const99 SdfSchemaBase::FieldDefinition::GetInfo() const {
100 return _info;
101 }
102
103 bool
IsPlugin() const104 SdfSchemaBase::FieldDefinition::IsPlugin() const
105 {
106 return _isPlugin;
107 }
108
109 bool
IsReadOnly() const110 SdfSchemaBase::FieldDefinition::IsReadOnly() const
111 {
112 return _isReadOnly;
113 }
114
115 bool
HoldsChildren() const116 SdfSchemaBase::FieldDefinition::HoldsChildren() const
117 {
118 return _holdsChildren;
119 }
120
121 SdfSchemaBase::FieldDefinition&
FallbackValue(const VtValue & v)122 SdfSchemaBase::FieldDefinition::FallbackValue(const VtValue& v)
123 {
124 _fallbackValue = v;
125 return *this;
126 }
127
128 SdfSchemaBase::FieldDefinition&
Plugin()129 SdfSchemaBase::FieldDefinition::Plugin()
130 {
131 _isPlugin = true;
132 return *this;
133 }
134
135 SdfSchemaBase::FieldDefinition&
ReadOnly()136 SdfSchemaBase::FieldDefinition::ReadOnly()
137 {
138 _isReadOnly = true;
139 return *this;
140 }
141
142 SdfSchemaBase::FieldDefinition&
Children()143 SdfSchemaBase::FieldDefinition::Children()
144 {
145 _holdsChildren = true;
146 _isReadOnly = true;
147 return *this;
148 }
149
150 SdfSchemaBase::FieldDefinition&
AddInfo(const TfToken & tok,const JsValue & val)151 SdfSchemaBase::FieldDefinition::AddInfo(const TfToken& tok, const JsValue& val) {
152 _info.push_back(std::make_pair(tok, val));
153 return *this;
154 }
155
156 SdfSchemaBase::FieldDefinition&
ValueValidator(Validator v)157 SdfSchemaBase::FieldDefinition::ValueValidator(Validator v)
158 {
159 _valueValidator = v;
160 return *this;
161 }
162
163 SdfSchemaBase::FieldDefinition&
ListValueValidator(Validator v)164 SdfSchemaBase::FieldDefinition::ListValueValidator(Validator v)
165 {
166 _listValueValidator = v;
167 return *this;
168 }
169
170 SdfSchemaBase::FieldDefinition&
MapKeyValidator(Validator v)171 SdfSchemaBase::FieldDefinition::MapKeyValidator(Validator v)
172 {
173 _mapKeyValidator = v;
174 return *this;
175 }
176
177 SdfSchemaBase::FieldDefinition&
MapValueValidator(Validator v)178 SdfSchemaBase::FieldDefinition::MapValueValidator(Validator v)
179 {
180 _mapValueValidator = v;
181 return *this;
182 }
183
184 //
185 // SdfSchemaBase::SpecDefinition
186 //
187
188 TfTokenVector
GetFields() const189 SdfSchemaBase::SpecDefinition::GetFields() const
190 {
191 TRACE_FUNCTION();
192
193 TfTokenVector rval(_fields.size());
194 TfToken *cur = rval.data();
195 for (auto const &p: _fields) {
196 *cur++ = p.first;
197 }
198 return rval;
199 }
200
201 TfTokenVector
GetMetadataFields() const202 SdfSchemaBase::SpecDefinition::GetMetadataFields() const
203 {
204 TRACE_FUNCTION();
205
206 TfTokenVector rval;
207 TF_FOR_ALL(field, _fields) {
208 if (field->second.metadata) {
209 rval.push_back(field->first);
210 }
211 }
212
213 return rval;
214 }
215
216 bool
IsMetadataField(const TfToken & name) const217 SdfSchemaBase::SpecDefinition::IsMetadataField(const TfToken& name) const
218 {
219 if (const _FieldInfo* fieldInfo = TfMapLookupPtr(_fields, name)) {
220 return fieldInfo->metadata;
221 }
222 return false;
223 }
224
225 TfToken
226 SdfSchemaBase::SpecDefinition
GetMetadataFieldDisplayGroup(const TfToken & name) const227 ::GetMetadataFieldDisplayGroup(const TfToken& name) const
228 {
229 if (const _FieldInfo* fieldInfo = TfMapLookupPtr(_fields, name)) {
230 return fieldInfo->metadata ?
231 fieldInfo->metadataDisplayGroup : TfToken();
232 }
233 return TfToken();
234 }
235
236 bool
IsRequiredField(const TfToken & name) const237 SdfSchemaBase::SpecDefinition::IsRequiredField(const TfToken& name) const
238 {
239 if (const _FieldInfo* fieldInfo = TfMapLookupPtr(_fields, name)) {
240 return fieldInfo->required;
241 }
242 return false;
243 }
244
245 bool
IsValidField(const TfToken & name) const246 SdfSchemaBase::SpecDefinition::IsValidField(const TfToken& name) const
247 {
248 return _fields.find(name) != _fields.end();
249 }
250
251 SdfSchemaBase::_SpecDefiner&
MetadataField(const TfToken & name,bool required)252 SdfSchemaBase::_SpecDefiner::MetadataField(const TfToken& name, bool required)
253 {
254 return MetadataField(name, TfToken(), required);
255 }
256
257 SdfSchemaBase::_SpecDefiner&
MetadataField(const TfToken & name,const TfToken & displayGroup,bool required)258 SdfSchemaBase::_SpecDefiner::MetadataField(const TfToken& name,
259 const TfToken& displayGroup,
260 bool required)
261 {
262 _FieldInfo fieldInfo;
263 fieldInfo.metadata = true;
264 fieldInfo.metadataDisplayGroup = displayGroup;
265 fieldInfo.required = required;
266
267 _definition->_AddField(name, fieldInfo);
268 if (required)
269 _schema->_AddRequiredFieldName(name);
270 return *this;
271 }
272
273 SdfSchemaBase::_SpecDefiner&
Field(const TfToken & name,bool required)274 SdfSchemaBase::_SpecDefiner::Field(const TfToken& name, bool required)
275 {
276 _FieldInfo fieldInfo;
277 fieldInfo.required = required;
278
279 _definition->_AddField(name, fieldInfo);
280 if (required)
281 _schema->_AddRequiredFieldName(name);
282 return *this;
283 }
284
285 void
_AddField(const TfToken & name,const _FieldInfo & fieldInfo)286 SdfSchemaBase::SpecDefinition::_AddField(
287 const TfToken& name, const _FieldInfo& fieldInfo)
288 {
289 std::pair<_FieldMap::iterator, bool> insertStatus =
290 _fields.insert(std::make_pair(name, fieldInfo));
291 if (!insertStatus.second) {
292 TF_CODING_ERROR("Duplicate registration for field '%s'",
293 name.GetText());
294 return;
295 }
296 if (fieldInfo.required) {
297 _requiredFields.insert(
298 std::lower_bound(_requiredFields.begin(),
299 _requiredFields.end(), name), name);
300 }
301 }
302
303 SdfSchemaBase::_SpecDefiner &
CopyFrom(const SpecDefinition & other)304 SdfSchemaBase::_SpecDefiner::CopyFrom(const SpecDefinition &other)
305 {
306 *_definition = other;
307 return *this;
308 }
309
310
311 //
312 // Validation helpers
313 //
314
315 static
316 SdfAllowed
_ValidateFramesPerSecond(const SdfSchemaBase &,const VtValue & value)317 _ValidateFramesPerSecond(const SdfSchemaBase&, const VtValue& value)
318 {
319 if (!value.IsHolding<double>()) {
320 return SdfAllowed("Expected value of type double");
321 }
322
323 return SdfAllowed(value.Get<double>() > 0.0,
324 "Value must be greater than 0");
325 }
326
327 static SdfAllowed
_ValidateIsString(const SdfSchemaBase &,const VtValue & value)328 _ValidateIsString(const SdfSchemaBase&, const VtValue& value)
329 {
330 if (!value.IsHolding<std::string>()) {
331 return SdfAllowed("Expected value of type string");
332 }
333 return true;
334 }
335
336 static SdfAllowed
_ValidateIsNonEmptyString(const SdfSchemaBase & schema,const VtValue & value)337 _ValidateIsNonEmptyString(const SdfSchemaBase& schema, const VtValue& value)
338 {
339 SdfAllowed result = _ValidateIsString(schema, value);
340 if (result && value.Get<std::string>().empty()) {
341 result = SdfAllowed("Expected non-empty string");
342 }
343 return result;
344 }
345
346 static SdfAllowed
_ValidateIdentifierToken(const SdfSchemaBase &,const VtValue & value)347 _ValidateIdentifierToken(const SdfSchemaBase&, const VtValue& value)
348 {
349 if (!value.IsHolding<TfToken>()) {
350 return SdfAllowed("Expected value of type TfToken");
351 }
352 return SdfSchemaBase::IsValidIdentifier(value.Get<TfToken>());
353 }
354
355 static SdfAllowed
_ValidateNamespacedIdentifierToken(const SdfSchemaBase &,const VtValue & value)356 _ValidateNamespacedIdentifierToken(const SdfSchemaBase&, const VtValue& value)
357 {
358 if (!value.IsHolding<TfToken>()) {
359 return SdfAllowed("Expected value of type TfToken");
360 }
361 return SdfSchemaBase::IsValidNamespacedIdentifier(value.Get<TfToken>());
362 }
363
364 static SdfAllowed
_ValidateIsSceneDescriptionValue(const SdfSchemaBase & schema,const VtValue & value)365 _ValidateIsSceneDescriptionValue(const SdfSchemaBase& schema, const VtValue& value)
366 {
367 return schema.IsValidValue(value);
368 }
369
370 #define SDF_VALIDATE_WRAPPER(name_, expectedType_) \
371 static SdfAllowed \
372 _Validate ## name_(const SdfSchemaBase& schema, const VtValue& value) \
373 { \
374 if (!value.IsHolding<expectedType_>()) { \
375 return SdfAllowed("Expected value of type " # expectedType_); \
376 } \
377 return SdfSchemaBase::IsValid ## name_(value.Get<expectedType_>()); \
378 }
379
380 SDF_VALIDATE_WRAPPER(AttributeConnectionPath, SdfPath);
381 SDF_VALIDATE_WRAPPER(Identifier, std::string);
382 SDF_VALIDATE_WRAPPER(InheritPath, SdfPath);
383 SDF_VALIDATE_WRAPPER(Payload, SdfPayload);
384 SDF_VALIDATE_WRAPPER(Reference, SdfReference);
385 SDF_VALIDATE_WRAPPER(RelationshipTargetPath, SdfPath);
386 SDF_VALIDATE_WRAPPER(RelocatesPath, SdfPath);
387 SDF_VALIDATE_WRAPPER(SpecializesPath, SdfPath);
388 SDF_VALIDATE_WRAPPER(SubLayer, std::string);
389 SDF_VALIDATE_WRAPPER(VariantIdentifier, std::string);
390
391 TF_DEFINE_PUBLIC_TOKENS(SdfChildrenKeys, SDF_CHILDREN_KEYS);
392 TF_DEFINE_PUBLIC_TOKENS(SdfFieldKeys, SDF_FIELD_KEYS);
393
394 //
395 // Registration for built-in fields for various spec types.
396 //
397
398 struct Sdf_SchemaFieldTypeRegistrar
399 {
400 public:
Sdf_SchemaFieldTypeRegistrarSdf_SchemaFieldTypeRegistrar401 Sdf_SchemaFieldTypeRegistrar(SdfSchemaBase* schema) : _schema(schema) { }
402
403 template <class T>
RegisterFieldSdf_SchemaFieldTypeRegistrar404 void RegisterField(const TfToken& fieldName)
405 {
406 _schema->_CreateField(fieldName, VtValue(T()));
407 }
408
409 private:
410 SdfSchemaBase* _schema;
411 };
412
413 //
414 // Registration for built-in attribute value types.
415 //
416
417 static void
_AddStandardTypesToRegistry(Sdf_ValueTypeRegistry * r)418 _AddStandardTypesToRegistry(Sdf_ValueTypeRegistry* r)
419 {
420 using T = Sdf_ValueTypeRegistry::Type;
421 const TfEnum& length = SdfDefaultUnit(TfEnum(SdfLengthUnit(0)));
422 const TfToken& point = SdfValueRoleNames->Point;
423 const TfToken& vector = SdfValueRoleNames->Vector;
424 const TfToken& normal = SdfValueRoleNames->Normal;
425 const TfToken& color = SdfValueRoleNames->Color;
426 const TfToken& texCoord = SdfValueRoleNames->TextureCoordinate;
427
428 // Make sure TfTypes are registered.
429 TfRegistryManager::GetInstance().SubscribeTo<TfType>();
430
431 // Simple types.
432 r->AddType(T("bool", bool()));
433 // XXX: We also need to fix the VT_INTEGRAL_BUILTIN_VALUE_TYPES
434 // macro to use 'int8_t' if we add 'char'.
435 //r->AddType(T("char", int8_t());
436 r->AddType(T("uchar", uint8_t()).CPPTypeName("unsigned char"));
437 //r->AddType(T("short", int16_t());
438 //r->AddType(T("ushort", uint16_t());
439 r->AddType(T("int", int32_t()).CPPTypeName("int"));
440 r->AddType(T("uint", uint32_t()).CPPTypeName("unsigned int"));
441 r->AddType(T("int64", int64_t()).CPPTypeName("int64_t"));
442 r->AddType(T("uint64", uint64_t()).CPPTypeName("uint64_t"));
443 r->AddType(T("half", GfHalf(0.0)).CPPTypeName("GfHalf"));
444 r->AddType(T("float", float()));
445 r->AddType(T("double", double()));
446 r->AddType(T("timecode", SdfTimeCode()));
447 // TfType reports "string" as the typename for "std::string", but we want
448 // the fully-qualified name for documentation purposes.
449 r->AddType(T("string", std::string()).CPPTypeName("std::string"));
450 r->AddType(T("token", TfToken()));
451 r->AddType(T("asset", SdfAssetPath()));
452
453 // Compound types.
454 r->AddType(T("double2", GfVec2d(0.0)).Dimensions(2));
455 r->AddType(T("double3", GfVec3d(0.0)).Dimensions(3));
456 r->AddType(T("double4", GfVec4d(0.0)).Dimensions(4));
457 r->AddType(T("float2", GfVec2f(0.0)).Dimensions(2));
458 r->AddType(T("float3", GfVec3f(0.0)).Dimensions(3));
459 r->AddType(T("float4", GfVec4f(0.0)).Dimensions(4));
460 r->AddType(T("half2", GfVec2h(0.0)).Dimensions(2));
461 r->AddType(T("half3", GfVec3h(0.0)).Dimensions(3));
462 r->AddType(T("half4", GfVec4h(0.0)).Dimensions(4));
463 r->AddType(T("int2", GfVec2i(0.0)).Dimensions(2));
464 r->AddType(T("int3", GfVec3i(0.0)).Dimensions(3));
465 r->AddType(T("int4", GfVec4i(0.0)).Dimensions(4));
466 r->AddType(T("point3h", GfVec3h(0.0)).DefaultUnit(length).Role(point)
467 .Dimensions(3));
468 r->AddType(T("point3f", GfVec3f(0.0)).DefaultUnit(length).Role(point)
469 .Dimensions(3));
470 r->AddType(T("point3d", GfVec3d(0.0)).DefaultUnit(length).Role(point)
471 .Dimensions(3));
472 r->AddType(T("vector3h", GfVec3h(0.0)).DefaultUnit(length).Role(vector)
473 .Dimensions(3));
474 r->AddType(T("vector3f", GfVec3f(0.0)).DefaultUnit(length).Role(vector)
475 .Dimensions(3));
476 r->AddType(T("vector3d", GfVec3d(0.0)).DefaultUnit(length).Role(vector)
477 .Dimensions(3));
478 r->AddType(T("normal3h", GfVec3h(0.0)).DefaultUnit(length).Role(normal)
479 .Dimensions(3));
480 r->AddType(T("normal3f", GfVec3f(0.0)).DefaultUnit(length).Role(normal)
481 .Dimensions(3));
482 r->AddType(T("normal3d", GfVec3d(0.0)).DefaultUnit(length).Role(normal)
483 .Dimensions(3));
484 r->AddType(T("color3h", GfVec3h(0.0)).Role(color).Dimensions(3));
485 r->AddType(T("color3f", GfVec3f(0.0)).Role(color).Dimensions(3));
486 r->AddType(T("color3d", GfVec3d(0.0)).Role(color).Dimensions(3));
487 r->AddType(T("color4h", GfVec4h(0.0)).Role(color).Dimensions(4));
488 r->AddType(T("color4f", GfVec4f(0.0)).Role(color).Dimensions(4));
489 r->AddType(T("color4d", GfVec4d(0.0)).Role(color).Dimensions(4));
490 r->AddType(T("quath", GfQuath(1.0)).Dimensions(4));
491 r->AddType(T("quatf", GfQuatf(1.0)).Dimensions(4));
492 r->AddType(T("quatd", GfQuatd(1.0)).Dimensions(4));
493 r->AddType(T("matrix2d", GfMatrix2d(1.0)).Dimensions({2, 2}));
494 r->AddType(T("matrix3d", GfMatrix3d(1.0)).Dimensions({3, 3}));
495 r->AddType(T("matrix4d", GfMatrix4d(1.0)).Dimensions({4, 4}));
496 r->AddType(T("frame4d", GfMatrix4d(1.0)).Role(SdfValueRoleNames->Frame)
497 .Dimensions({4, 4}));
498 r->AddType(T("texCoord2f", GfVec2f(0.0)).Role(texCoord).Dimensions(2));
499 r->AddType(T("texCoord2d", GfVec2d(0.0)).Role(texCoord).Dimensions(2));
500 r->AddType(T("texCoord2h", GfVec2h(0.0)).Role(texCoord).Dimensions(2));
501 r->AddType(T("texCoord3f", GfVec3f(0.0)).Role(texCoord).Dimensions(3));
502 r->AddType(T("texCoord3d", GfVec3d(0.0)).Role(texCoord).Dimensions(3));
503 r->AddType(T("texCoord3h", GfVec3h(0.0)).Role(texCoord).Dimensions(3));
504 }
505
506 static void
_AddLegacyTypesToRegistry(Sdf_ValueTypeRegistry * r)507 _AddLegacyTypesToRegistry(Sdf_ValueTypeRegistry* r)
508 {
509 using T = Sdf_ValueTypeRegistry::Type;
510 const TfEnum& length = SdfDefaultUnit(TfEnum(SdfLengthUnit(0)));
511 const TfToken& point = SdfValueRoleNames->Point;
512 const TfToken& vector = SdfValueRoleNames->Vector;
513 const TfToken& normal = SdfValueRoleNames->Normal;
514 const TfToken& color = SdfValueRoleNames->Color;
515
516 // XXX: Legacy types. We can remove these when assets are
517 // updated. parserHelpers.cpp adds support for reading
518 // old text Usd files but we also need support for binary
519 // files. We also need these for places we confuse Sdf
520 // and Sd.
521 r->AddType(T("Vec2i", GfVec2i(0.0)).Dimensions(2));
522 r->AddType(T("Vec2h", GfVec2h(0.0)).Dimensions(2));
523 r->AddType(T("Vec2f", GfVec2f(0.0)).Dimensions(2));
524 r->AddType(T("Vec2d", GfVec2d(0.0)).Dimensions(2));
525 r->AddType(T("Vec3i", GfVec3i(0.0)).Dimensions(3));
526 r->AddType(T("Vec3h", GfVec3h(0.0)).Dimensions(3));
527 r->AddType(T("Vec3f", GfVec3f(0.0)).Dimensions(3));
528 r->AddType(T("Vec3d", GfVec3d(0.0)).Dimensions(3));
529 r->AddType(T("Vec4i", GfVec4i(0.0)).Dimensions(4));
530 r->AddType(T("Vec4h", GfVec4h(0.0)).Dimensions(4));
531 r->AddType(T("Vec4f", GfVec4f(0.0)).Dimensions(4));
532 r->AddType(T("Vec4d", GfVec4d(0.0)).Dimensions(4));
533 r->AddType(T("Point", GfVec3d(0.0)).DefaultUnit(length).Role(point)
534 .Dimensions(3));
535 r->AddType(T("PointFloat", GfVec3f(0.0)).DefaultUnit(length).Role(point)
536 .Dimensions(3));
537 r->AddType(T("Normal", GfVec3d(0.0)).DefaultUnit(length).Role(normal)
538 .Dimensions(3));
539 r->AddType(T("NormalFloat",GfVec3f(0.0)).DefaultUnit(length).Role(normal)
540 .Dimensions(3));
541 r->AddType(T("Vector", GfVec3d(0.0)).DefaultUnit(length).Role(vector)
542 .Dimensions(3));
543 r->AddType(T("VectorFloat",GfVec3f(0.0)).DefaultUnit(length).Role(vector)
544 .Dimensions(3));
545 r->AddType(T("Color", GfVec3d(0.0)).Role(color).Dimensions(3));
546 r->AddType(T("ColorFloat", GfVec3f(0.0)).Role(color).Dimensions(3));
547 r->AddType(T("Quath", GfQuath(1.0)).Dimensions(4));
548 r->AddType(T("Quatf", GfQuatf(1.0)).Dimensions(4));
549 r->AddType(T("Quatd", GfQuatd(1.0)).Dimensions(4));
550 r->AddType(T("Matrix2d", GfMatrix2d(1.0)).Dimensions({2, 2}));
551 r->AddType(T("Matrix3d", GfMatrix3d(1.0)).Dimensions({3, 3}));
552 r->AddType(T("Matrix4d", GfMatrix4d(1.0)).Dimensions({4, 4}));
553 r->AddType(T("Frame", GfMatrix4d(1.0)).Role(SdfValueRoleNames->Frame)
554 .Dimensions({4, 4}));
555 r->AddType(T("Transform", GfMatrix4d(1.0)).Role(SdfValueRoleNames->Transform)
556 .Dimensions({4, 4}));
557 r->AddType(T("PointIndex", int()).Role(SdfValueRoleNames->PointIndex));
558 r->AddType(T("EdgeIndex", int()).Role(SdfValueRoleNames->EdgeIndex));
559 r->AddType(T("FaceIndex", int()).Role(SdfValueRoleNames->FaceIndex));
560 }
561
562 class SdfSchemaBase::_ValueTypeRegistrar::Type::_Impl
563 {
564 public:
_Impl(const TfToken & name,const VtValue & defaultValue,const VtValue & defaultArrayValue)565 _Impl(const TfToken& name,
566 const VtValue& defaultValue,
567 const VtValue& defaultArrayValue)
568 : type(name, defaultValue, defaultArrayValue)
569 { }
570
_Impl(const TfToken & name,const TfType & type_)571 _Impl(const TfToken& name, const TfType& type_)
572 : type(name, type_)
573 { }
574
575 Sdf_ValueTypeRegistry::Type type;
576 };
577
Type(const TfToken & name,const VtValue & defaultValue,const VtValue & defaultArrayValue)578 SdfSchemaBase::_ValueTypeRegistrar::Type::Type(
579 const TfToken& name,
580 const VtValue& defaultValue,
581 const VtValue& defaultArrayValue)
582 : _impl(new _Impl(name, defaultValue, defaultArrayValue))
583 {
584 }
585
Type(const TfToken & name,const TfType & type)586 SdfSchemaBase::_ValueTypeRegistrar::Type::Type(
587 const TfToken& name,
588 const TfType& type)
589 : _impl(new _Impl(name, type))
590 {
591 }
592
593 SdfSchemaBase::_ValueTypeRegistrar::Type::~Type() = default;
594
595 SdfSchemaBase::_ValueTypeRegistrar::Type&
CPPTypeName(const std::string & cppTypeName)596 SdfSchemaBase::_ValueTypeRegistrar::Type::CPPTypeName(
597 const std::string& cppTypeName)
598 {
599 _impl->type.CPPTypeName(cppTypeName);
600 return *this;
601 }
602
603 SdfSchemaBase::_ValueTypeRegistrar::Type&
Dimensions(const SdfTupleDimensions & dims)604 SdfSchemaBase::_ValueTypeRegistrar::Type::Dimensions(
605 const SdfTupleDimensions& dims)
606 {
607 _impl->type.Dimensions(dims);
608 return *this;
609 }
610
611 SdfSchemaBase::_ValueTypeRegistrar::Type&
DefaultUnit(TfEnum unit)612 SdfSchemaBase::_ValueTypeRegistrar::Type::DefaultUnit(TfEnum unit)
613 {
614 _impl->type.DefaultUnit(unit);
615 return *this;
616 }
617
618 SdfSchemaBase::_ValueTypeRegistrar::Type&
Role(const TfToken & role)619 SdfSchemaBase::_ValueTypeRegistrar::Type::Role(const TfToken& role)
620 {
621 _impl->type.Role(role);
622 return *this;
623 }
624
625 SdfSchemaBase::_ValueTypeRegistrar::Type&
NoArrays()626 SdfSchemaBase::_ValueTypeRegistrar::Type::NoArrays()
627 {
628 _impl->type.NoArrays();
629 return *this;
630 }
631
_ValueTypeRegistrar(Sdf_ValueTypeRegistry * registry)632 SdfSchemaBase::_ValueTypeRegistrar::_ValueTypeRegistrar(
633 Sdf_ValueTypeRegistry* registry) :
634 _registry(registry)
635 {
636 // Do nothing
637 }
638
639 void
AddType(const Type & type)640 SdfSchemaBase::_ValueTypeRegistrar::AddType(const Type& type)
641 {
642 _registry->AddType(type._impl->type);
643 }
644
TF_REGISTRY_FUNCTION(TfType)645 TF_REGISTRY_FUNCTION(TfType)
646 {
647 TfType::Define<SdfSchemaBase>();
648 }
649
SdfSchemaBase()650 SdfSchemaBase::SdfSchemaBase()
651 : _valueTypeRegistry(new Sdf_ValueTypeRegistry)
652 {
653 _RegisterStandardTypes();
654 _RegisterLegacyTypes();
655
656 _RegisterStandardFields();
657 _RegisterPluginFields();
658 }
659
SdfSchemaBase(EmptyTag)660 SdfSchemaBase::SdfSchemaBase(EmptyTag)
661 : _valueTypeRegistry(new Sdf_ValueTypeRegistry)
662 {
663 }
664
~SdfSchemaBase()665 SdfSchemaBase::~SdfSchemaBase()
666 {
667 // Do nothing
668 }
669
670 void
_RegisterStandardTypes()671 SdfSchemaBase::_RegisterStandardTypes()
672 {
673 _AddStandardTypesToRegistry(_valueTypeRegistry.get());
674 }
675
676 void
_RegisterLegacyTypes()677 SdfSchemaBase::_RegisterLegacyTypes()
678 {
679 _AddLegacyTypesToRegistry(_valueTypeRegistry.get());
680 }
681
682 void
_RegisterStandardFields()683 SdfSchemaBase::_RegisterStandardFields()
684 {
685 // Ensure that entries for all scene description fields
686 // are created with an appropriately-typed fallback value.
687 // Then register additional information for each field; doing so
688 // for a field that hasn't been created will cause a fatal error
689 // to be emitted.
690 //
691 // This ensures that the field registration stays in sync with
692 // the field types defined in SchemaTypeRegistration.h
693 Sdf_SchemaFieldTypeRegistrar r(this);
694 SdfRegisterFields(&r);
695
696 // Regular Fields
697 _DoRegisterField(SdfFieldKeys->Active, true);
698 _DoRegisterField(SdfFieldKeys->AllowedTokens, VtTokenArray());
699 _DoRegisterField(SdfFieldKeys->AssetInfo, VtDictionary())
700 .MapKeyValidator(&_ValidateIdentifier)
701 .MapValueValidator(&_ValidateIsSceneDescriptionValue);
702 _DoRegisterField(SdfFieldKeys->TimeSamples, SdfTimeSampleMap());
703 _DoRegisterField(SdfFieldKeys->ColorConfiguration, SdfAssetPath());
704 _DoRegisterField(SdfFieldKeys->ColorManagementSystem, TfToken());
705 _DoRegisterField(SdfFieldKeys->ColorSpace, TfToken());
706 _DoRegisterField(SdfFieldKeys->Comment, "");
707
708 // Connection paths are marked read-only because adding/removing
709 // connections requires adding/removing children specs, which we are
710 // disallowing via the Info API.
711 _DoRegisterField(SdfFieldKeys->ConnectionPaths, SdfPathListOp())
712 .ReadOnly()
713 .ListValueValidator(&_ValidateAttributeConnectionPath);
714
715 _DoRegisterField(SdfFieldKeys->Custom, false);
716 _DoRegisterField(SdfFieldKeys->CustomData, VtDictionary())
717 .MapKeyValidator(&_ValidateIdentifier)
718 .MapValueValidator(&_ValidateIsSceneDescriptionValue);
719 _DoRegisterField(SdfFieldKeys->CustomLayerData, VtDictionary())
720 .MapKeyValidator(&_ValidateIdentifier)
721 .MapValueValidator(&_ValidateIsSceneDescriptionValue);
722 _DoRegisterField(SdfFieldKeys->Default, VtValue())
723 .ValueValidator(&_ValidateIsSceneDescriptionValue);
724 _DoRegisterField(SdfFieldKeys->DisplayGroup, "");
725 _DoRegisterField(SdfFieldKeys->DisplayGroupOrder, VtStringArray());
726 _DoRegisterField(SdfFieldKeys->DisplayName, "");
727 _DoRegisterField(SdfFieldKeys->DisplayUnit,
728 TfEnum(SdfDimensionlessUnitDefault));
729 _DoRegisterField(SdfFieldKeys->Documentation, "");
730 _DoRegisterField(SdfFieldKeys->DefaultPrim, TfToken());
731 _DoRegisterField(SdfFieldKeys->EndFrame, 0.0);
732 _DoRegisterField(SdfFieldKeys->EndTimeCode, 0.0);
733 _DoRegisterField(SdfFieldKeys->FramePrecision, 3);
734 _DoRegisterField(SdfFieldKeys->FramesPerSecond, 24.0)
735 .ValueValidator(&_ValidateFramesPerSecond);
736 _DoRegisterField(SdfFieldKeys->Hidden, false);
737 _DoRegisterField(SdfFieldKeys->HasOwnedSubLayers, false);
738 _DoRegisterField(SdfFieldKeys->Instanceable, false);
739 _DoRegisterField(SdfFieldKeys->InheritPaths, SdfPathListOp())
740 .ListValueValidator(&_ValidateInheritPath);
741 _DoRegisterField(SdfFieldKeys->Kind, TfToken());
742 _DoRegisterField(SdfFieldKeys->Owner, "");
743 _DoRegisterField(SdfFieldKeys->PrimOrder, std::vector<TfToken>())
744 .ListValueValidator(&_ValidateIdentifierToken);
745 _DoRegisterField(SdfFieldKeys->NoLoadHint, false);
746 _DoRegisterField(SdfFieldKeys->Payload, SdfPayloadListOp())
747 .ListValueValidator(&_ValidatePayload);
748 _DoRegisterField(SdfFieldKeys->Permission, SdfPermissionPublic);
749 _DoRegisterField(SdfFieldKeys->Prefix, "");
750 _DoRegisterField(SdfFieldKeys->PrefixSubstitutions, VtDictionary())
751 .MapKeyValidator(&_ValidateIsNonEmptyString)
752 .MapValueValidator(&_ValidateIsString);
753 _DoRegisterField(SdfFieldKeys->PropertyOrder, std::vector<TfToken>())
754 .ListValueValidator(&_ValidateNamespacedIdentifierToken);
755 _DoRegisterField(SdfFieldKeys->References, SdfReferenceListOp())
756 .ListValueValidator(&_ValidateReference);
757 _DoRegisterField(SdfFieldKeys->SessionOwner, "");
758 _DoRegisterField(SdfFieldKeys->Specializes, SdfPathListOp())
759 .ListValueValidator(&_ValidateSpecializesPath);
760 _DoRegisterField(SdfFieldKeys->Suffix, "");
761 _DoRegisterField(SdfFieldKeys->SuffixSubstitutions, VtDictionary())
762 .MapKeyValidator(&_ValidateIsNonEmptyString)
763 .MapValueValidator(&_ValidateIsString);
764
765 // See comment on SdfFieldKeys->ConnectionPaths for why this is read-only.
766 _DoRegisterField(SdfFieldKeys->TargetPaths, SdfPathListOp())
767 .ReadOnly()
768 .ListValueValidator(&_ValidateRelationshipTargetPath);
769
770 _DoRegisterField(SdfFieldKeys->Relocates, SdfRelocatesMap())
771 .MapKeyValidator(&_ValidateRelocatesPath)
772 .MapValueValidator(&_ValidateRelocatesPath);
773 _DoRegisterField(SdfFieldKeys->Specifier, SdfSpecifierOver);
774 _DoRegisterField(SdfFieldKeys->StartFrame, 0.0);
775 _DoRegisterField(SdfFieldKeys->StartTimeCode, 0.0);
776 _DoRegisterField(SdfFieldKeys->SubLayers, std::vector<std::string>())
777 .ListValueValidator(&_ValidateSubLayer);
778 _DoRegisterField(SdfFieldKeys->SubLayerOffsets, std::vector<SdfLayerOffset>());
779 _DoRegisterField(SdfFieldKeys->SymmetricPeer, "");
780 _DoRegisterField(SdfFieldKeys->SymmetryArgs, VtDictionary())
781 .MapKeyValidator(&_ValidateIdentifier)
782 .MapValueValidator(&_ValidateIsSceneDescriptionValue);
783 _DoRegisterField(SdfFieldKeys->SymmetryArguments, VtDictionary())
784 .MapKeyValidator(&_ValidateIdentifier)
785 .MapValueValidator(&_ValidateIsSceneDescriptionValue);
786 _DoRegisterField(SdfFieldKeys->SymmetryFunction, TfToken());
787 _DoRegisterField(SdfFieldKeys->TimeCodesPerSecond, 24.0);
788 _DoRegisterField(SdfFieldKeys->TypeName, TfToken());
789 _DoRegisterField(SdfFieldKeys->VariantSetNames, SdfStringListOp())
790 .ListValueValidator(&_ValidateIdentifier);
791 _DoRegisterField(SdfFieldKeys->VariantSelection, SdfVariantSelectionMap())
792 .MapValueValidator(&_ValidateVariantIdentifier);
793 _DoRegisterField(SdfFieldKeys->Variability, SdfVariabilityVarying);
794
795 // Children fields.
796 _DoRegisterField(SdfChildrenKeys->ConnectionChildren, std::vector<SdfPath>())
797 .Children()
798 .ListValueValidator(&_ValidateAttributeConnectionPath);
799 _DoRegisterField(SdfChildrenKeys->ExpressionChildren, std::vector<TfToken>())
800 .Children();
801 _DoRegisterField(SdfChildrenKeys->MapperArgChildren, std::vector<TfToken>())
802 .Children()
803 .ListValueValidator(&_ValidateIdentifier);
804 _DoRegisterField(SdfChildrenKeys->MapperChildren, std::vector<SdfPath>())
805 .Children()
806 .ListValueValidator(&_ValidateAttributeConnectionPath);
807 _DoRegisterField(SdfChildrenKeys->PrimChildren, std::vector<TfToken>())
808 .Children()
809 .ListValueValidator(&_ValidateIdentifier);
810 _DoRegisterField(SdfChildrenKeys->PropertyChildren, std::vector<TfToken>())
811 .Children()
812 .ListValueValidator(&_ValidateIdentifier);
813 _DoRegisterField(SdfChildrenKeys->RelationshipTargetChildren,
814 std::vector<SdfPath>())
815 .Children()
816 .ListValueValidator(&_ValidateRelationshipTargetPath);
817 _DoRegisterField(SdfChildrenKeys->VariantChildren, std::vector<TfToken>())
818 .Children()
819 .ListValueValidator(&_ValidateVariantIdentifier);
820 _DoRegisterField(SdfChildrenKeys->VariantSetChildren, std::vector<TfToken>())
821 .Children()
822 .ListValueValidator(&_ValidateIdentifier);
823
824 //
825 // Spec definitions
826 //
827
828 _Define(SdfSpecTypePseudoRoot)
829 .MetadataField(SdfFieldKeys->ColorConfiguration)
830 .MetadataField(SdfFieldKeys->ColorManagementSystem)
831 .Field(SdfFieldKeys->Comment)
832 .MetadataField(SdfFieldKeys->CustomLayerData)
833 .MetadataField(SdfFieldKeys->DefaultPrim)
834 .MetadataField(SdfFieldKeys->Documentation)
835 .MetadataField(SdfFieldKeys->EndTimeCode)
836 .MetadataField(SdfFieldKeys->FramesPerSecond)
837 .MetadataField(SdfFieldKeys->FramePrecision)
838 .MetadataField(SdfFieldKeys->HasOwnedSubLayers)
839 .MetadataField(SdfFieldKeys->Owner)
840 .MetadataField(SdfFieldKeys->SessionOwner)
841 .MetadataField(SdfFieldKeys->StartTimeCode)
842 .MetadataField(SdfFieldKeys->TimeCodesPerSecond)
843 .MetadataField(SdfFieldKeys->EndFrame)
844 .MetadataField(SdfFieldKeys->StartFrame)
845
846 .Field(SdfChildrenKeys->PrimChildren)
847 .Field(SdfFieldKeys->PrimOrder)
848 .Field(SdfFieldKeys->SubLayers)
849 .Field(SdfFieldKeys->SubLayerOffsets);
850
851 _Define(SdfSpecTypePrim)
852 .Field(SdfFieldKeys->Specifier, /* required = */ true)
853
854 .Field(SdfFieldKeys->Comment)
855 .Field(SdfFieldKeys->InheritPaths)
856 .Field(SdfFieldKeys->Specializes)
857 .Field(SdfChildrenKeys->PrimChildren)
858 .Field(SdfFieldKeys->PrimOrder)
859 .Field(SdfChildrenKeys->PropertyChildren)
860 .Field(SdfFieldKeys->PropertyOrder)
861 .Field(SdfFieldKeys->References)
862 .Field(SdfFieldKeys->Relocates)
863 .Field(SdfFieldKeys->VariantSelection)
864 .Field(SdfChildrenKeys->VariantSetChildren)
865 .Field(SdfFieldKeys->VariantSetNames)
866
867 .MetadataField(SdfFieldKeys->Active,
868 SdfMetadataDisplayGroupTokens->core)
869 .MetadataField(SdfFieldKeys->AssetInfo,
870 SdfMetadataDisplayGroupTokens->core)
871 .MetadataField(SdfFieldKeys->CustomData,
872 SdfMetadataDisplayGroupTokens->core)
873 .MetadataField(SdfFieldKeys->DisplayGroupOrder,
874 SdfMetadataDisplayGroupTokens->core)
875 .MetadataField(SdfFieldKeys->Documentation,
876 SdfMetadataDisplayGroupTokens->core)
877 .MetadataField(SdfFieldKeys->Hidden,
878 SdfMetadataDisplayGroupTokens->core)
879 .MetadataField(SdfFieldKeys->Instanceable,
880 SdfMetadataDisplayGroupTokens->core)
881 .MetadataField(SdfFieldKeys->Kind,
882 SdfMetadataDisplayGroupTokens->core)
883 .MetadataField(SdfFieldKeys->Payload,
884 SdfMetadataDisplayGroupTokens->core)
885 .MetadataField(SdfFieldKeys->Permission,
886 SdfMetadataDisplayGroupTokens->core)
887 .MetadataField(SdfFieldKeys->Prefix,
888 SdfMetadataDisplayGroupTokens->core)
889 .MetadataField(SdfFieldKeys->PrefixSubstitutions,
890 SdfMetadataDisplayGroupTokens->core)
891 .MetadataField(SdfFieldKeys->Suffix,
892 SdfMetadataDisplayGroupTokens->core)
893 .MetadataField(SdfFieldKeys->SuffixSubstitutions,
894 SdfMetadataDisplayGroupTokens->core)
895 .MetadataField(SdfFieldKeys->SymmetricPeer,
896 SdfMetadataDisplayGroupTokens->symmetry)
897 .MetadataField(SdfFieldKeys->SymmetryArguments,
898 SdfMetadataDisplayGroupTokens->symmetry)
899 .MetadataField(SdfFieldKeys->SymmetryFunction,
900 SdfMetadataDisplayGroupTokens->symmetry)
901 .MetadataField(SdfFieldKeys->TypeName,
902 SdfMetadataDisplayGroupTokens->core)
903 ;
904
905 // The property spec definition will be used as the basis for the
906 // attribute and relationship spec definitions.
907 SpecDefinition property;
908 _Define(&property)
909 .Field(SdfFieldKeys->Custom, /* required = */ true)
910 .Field(SdfFieldKeys->Variability, /* required = */ true)
911
912 .Field(SdfFieldKeys->Comment)
913 .Field(SdfFieldKeys->Default)
914 .Field(SdfFieldKeys->TimeSamples)
915
916 .MetadataField(SdfFieldKeys->AssetInfo,
917 SdfMetadataDisplayGroupTokens->core)
918 .MetadataField(SdfFieldKeys->CustomData,
919 SdfMetadataDisplayGroupTokens->core)
920 .MetadataField(SdfFieldKeys->DisplayGroup,
921 SdfMetadataDisplayGroupTokens->core)
922 .MetadataField(SdfFieldKeys->DisplayName,
923 SdfMetadataDisplayGroupTokens->core)
924 .MetadataField(SdfFieldKeys->Documentation,
925 SdfMetadataDisplayGroupTokens->core)
926 .MetadataField(SdfFieldKeys->Hidden,
927 SdfMetadataDisplayGroupTokens->core)
928 .MetadataField(SdfFieldKeys->Permission,
929 SdfMetadataDisplayGroupTokens->core)
930 .MetadataField(SdfFieldKeys->Prefix,
931 SdfMetadataDisplayGroupTokens->core)
932 .MetadataField(SdfFieldKeys->Suffix,
933 SdfMetadataDisplayGroupTokens->core)
934 .MetadataField(SdfFieldKeys->SymmetricPeer,
935 SdfMetadataDisplayGroupTokens->symmetry)
936 .MetadataField(SdfFieldKeys->SymmetryArguments,
937 SdfMetadataDisplayGroupTokens->symmetry)
938 .MetadataField(SdfFieldKeys->SymmetryFunction,
939 SdfMetadataDisplayGroupTokens->symmetry)
940 ;
941
942 _Define(SdfSpecTypeAttribute)
943 .CopyFrom(property)
944 .Field(SdfFieldKeys->TypeName, /* required = */ true)
945
946 .Field(SdfChildrenKeys->ConnectionChildren)
947 .Field(SdfFieldKeys->ConnectionPaths)
948 .Field(SdfFieldKeys->DisplayUnit)
949 .MetadataField(SdfFieldKeys->AllowedTokens,
950 SdfMetadataDisplayGroupTokens->core)
951 .MetadataField(SdfFieldKeys->ColorSpace,
952 SdfMetadataDisplayGroupTokens->core)
953 ;
954
955 _Define(SdfSpecTypeConnection);
956
957 _Define(SdfSpecTypeRelationship)
958 .CopyFrom(property)
959 .Field(SdfChildrenKeys->RelationshipTargetChildren)
960 .Field(SdfFieldKeys->TargetPaths)
961
962 .MetadataField(SdfFieldKeys->NoLoadHint,
963 SdfMetadataDisplayGroupTokens->core);
964
965 _Define(SdfSpecTypeRelationshipTarget);
966
967 _Define(SdfSpecTypeVariantSet)
968 .Field(SdfChildrenKeys->VariantChildren);
969
970 _Define(SdfSpecTypeVariant)
971 .CopyFrom(*GetSpecDefinition(SdfSpecTypePrim));
972
973 }
974
975 void
_RegisterPluginFields()976 SdfSchemaBase::_RegisterPluginFields()
977 {
978 // Update generic metadata fields from all currently-registered plugins.
979 // Set up notice handling so we'll check for new generic metadata as more
980 // plugins are registered.
981 _UpdateMetadataFromPlugins(PlugRegistry::GetInstance().GetAllPlugins());
982 TfNotice::Register(
983 TfCreateWeakPtr(this), &SdfSchemaBase::_OnDidRegisterPlugins);
984 }
985
986 void
_OnDidRegisterPlugins(const PlugNotice::DidRegisterPlugins & n)987 SdfSchemaBase::_OnDidRegisterPlugins(const PlugNotice::DidRegisterPlugins& n)
988 {
989 _UpdateMetadataFromPlugins(n.GetNewPlugins());
990 }
991
992 SdfSchemaBase::FieldDefinition&
_CreateField(const TfToken & key,const VtValue & value,bool plugin)993 SdfSchemaBase::_CreateField(const TfToken &key, const VtValue &value, bool plugin)
994 {
995 FieldDefinition def(*this, key, value);
996 if (plugin) {
997 def.Plugin();
998 }
999
1000 const std::pair<_FieldDefinitionMap::iterator, bool> insertStatus =
1001 _fieldDefinitions.insert(std::make_pair(key, def));
1002 if (!insertStatus.second) {
1003 TF_CODING_ERROR("Duplicate creation for field '%s'", key.GetText());
1004 }
1005
1006 return insertStatus.first->second;
1007 }
1008
1009 SdfSchemaBase::FieldDefinition&
_DoRegisterField(const TfToken & key,const VtValue & v)1010 SdfSchemaBase::_DoRegisterField(const TfToken &key, const VtValue &v)
1011 {
1012 // The field for which we're trying to register extra schema
1013 // information must have already been created with a call to
1014 // _CreateField. See comment in SdfSchemaBase::_RegisterStandardFields.
1015 _FieldDefinitionMap::iterator fieldIt = _fieldDefinitions.find(key);
1016 if (fieldIt == _fieldDefinitions.end()) {
1017 TF_FATAL_ERROR("Field '%s' has not been created.", key.GetText());
1018 }
1019
1020 FieldDefinition& fieldDef = fieldIt->second;
1021
1022 // The new fallback value's type must match the type of
1023 // the fallback value the field was created with. This ensures
1024 // we stay in sync with the fields in SchemaTypeRegistration.h.
1025 if (!TfSafeTypeCompare(fieldDef.GetFallbackValue().GetTypeid(),
1026 v.GetTypeid())) {
1027 TF_FATAL_ERROR("Registered fallback value for field '%s' does "
1028 "not match field type definition. "
1029 "(expected: %s, got: %s)",
1030 key.GetText(),
1031 fieldDef.GetFallbackValue().GetTypeName().c_str(),
1032 v.GetTypeName().c_str());
1033 }
1034
1035 fieldDef.FallbackValue(v);
1036 return fieldDef;
1037 }
1038
1039 SdfSchemaBase::_SpecDefiner
_ExtendSpecDefinition(SdfSpecType specType)1040 SdfSchemaBase::_ExtendSpecDefinition(SdfSpecType specType)
1041 {
1042 if (!_specDefinitions[specType].second) {
1043 TF_FATAL_ERROR("No definition for spec type %s",
1044 TfEnum::GetName(specType).c_str());
1045 }
1046 return _SpecDefiner(this, &_specDefinitions[specType].first);
1047 }
1048
1049 const SdfSchemaBase::FieldDefinition*
GetFieldDefinition(const TfToken & fieldKey) const1050 SdfSchemaBase::GetFieldDefinition(const TfToken &fieldKey) const
1051 {
1052 return TfMapLookupPtr(_fieldDefinitions, fieldKey);
1053 }
1054
1055 const VtValue&
GetFallback(const TfToken & fieldKey) const1056 SdfSchemaBase::GetFallback(const TfToken &fieldKey) const
1057 {
1058 static VtValue empty;
1059
1060 const FieldDefinition* def = GetFieldDefinition(fieldKey);
1061 return def ? def->GetFallbackValue() : empty;
1062 }
1063
1064 bool
IsRegistered(const TfToken & fieldKey,VtValue * fallback) const1065 SdfSchemaBase::IsRegistered(const TfToken &fieldKey, VtValue *fallback) const
1066 {
1067 const FieldDefinition* def = GetFieldDefinition(fieldKey);
1068 if (!def) {
1069 return false;
1070 }
1071
1072 if (fallback) {
1073 *fallback = def->GetFallbackValue();
1074 }
1075
1076 return true;
1077 }
1078
1079 bool
HoldsChildren(const TfToken & fieldKey) const1080 SdfSchemaBase::HoldsChildren(const TfToken &fieldKey) const
1081 {
1082 const FieldDefinition* def = GetFieldDefinition(fieldKey);
1083 return (def ? def->HoldsChildren() : false);
1084 }
1085
1086 VtValue
CastToTypeOf(const TfToken & fieldKey,const VtValue & value) const1087 SdfSchemaBase::CastToTypeOf(const TfToken &fieldKey, const VtValue &value) const
1088 {
1089 VtValue fallback;
1090 if (!SdfSchemaBase::IsRegistered(fieldKey, &fallback)) {
1091 return VtValue();
1092 }
1093
1094 if (fallback.IsEmpty()) {
1095 return value;
1096 }
1097
1098 return VtValue::CastToTypeOf(value, fallback);
1099 }
1100
1101 const SdfSchemaBase::SpecDefinition*
_CheckAndGetSpecDefinition(SdfSpecType specType) const1102 SdfSchemaBase::_CheckAndGetSpecDefinition(SdfSpecType specType) const
1103 {
1104 const SpecDefinition* def = GetSpecDefinition(specType);
1105 if (!def) {
1106 TF_CODING_ERROR("No definition for spec type %s",
1107 TfStringify(specType).c_str());
1108 }
1109
1110 return def;
1111 }
1112
1113 bool
IsValidFieldForSpec(const TfToken & fieldKey,SdfSpecType specType) const1114 SdfSchemaBase::IsValidFieldForSpec(const TfToken &fieldKey,
1115 SdfSpecType specType) const
1116 {
1117 const SpecDefinition* def = _CheckAndGetSpecDefinition(specType);
1118 return (def ? def->IsValidField(fieldKey) : false);
1119 }
1120
1121 TfTokenVector
GetFields(SdfSpecType specType) const1122 SdfSchemaBase::GetFields(SdfSpecType specType) const
1123 {
1124 const SpecDefinition* def = _CheckAndGetSpecDefinition(specType);
1125 return (def ? def->GetFields() : TfTokenVector());
1126 }
1127
1128 TfTokenVector
GetMetadataFields(SdfSpecType specType) const1129 SdfSchemaBase::GetMetadataFields(SdfSpecType specType) const
1130 {
1131 const SpecDefinition* def = _CheckAndGetSpecDefinition(specType);
1132 return (def ? def->GetMetadataFields() : TfTokenVector());
1133 }
1134
1135 TfToken
GetMetadataFieldDisplayGroup(SdfSpecType specType,TfToken const & metadataField) const1136 SdfSchemaBase::GetMetadataFieldDisplayGroup(SdfSpecType specType,
1137 TfToken const &metadataField) const
1138 {
1139 const SpecDefinition* def = _CheckAndGetSpecDefinition(specType);
1140 return (def ? def->GetMetadataFieldDisplayGroup(metadataField) : TfToken());
1141 }
1142
1143 const TfTokenVector &
GetRequiredFields(SdfSpecType specType) const1144 SdfSchemaBase::GetRequiredFields(SdfSpecType specType) const
1145 {
1146 if (const SpecDefinition* def = _CheckAndGetSpecDefinition(specType)) {
1147 return def->GetRequiredFields();
1148 }
1149 // Intentionally leak to avoid static destruction issues.
1150 static TfTokenVector *theEmptyVector = new TfTokenVector;
1151 return *theEmptyVector;
1152 }
1153
1154 SdfAllowed
IsValidValue(const VtValue & value) const1155 SdfSchemaBase::IsValidValue(const VtValue& value) const
1156 {
1157 if (value.IsEmpty()) {
1158 return true;
1159 }
1160
1161 if (value.IsHolding<VtDictionary>()) {
1162 // Although dictionaries are not explicitly registered as a value
1163 // type, they are valid scene description and can be written/read
1164 // to/from layers as long as each individual value is valid scene
1165 // description. Note that we don't have to check keys because
1166 // VtDictionary's keys are always strings.
1167 //
1168 TF_FOR_ALL(it, value.UncheckedGet<VtDictionary>()) {
1169 if (SdfAllowed valueStatus = IsValidValue(it->second)) {
1170 // Value is OK, so do nothing.
1171 }
1172 else {
1173 const std::string error = TfStringPrintf(
1174 "Value for key '%s' does not have a valid scene "
1175 "description type (%s)",
1176 it->first.c_str(), it->second.GetTypeName().c_str());
1177 return SdfAllowed(error);
1178 }
1179 }
1180 }
1181 else if (!FindType(value)) {
1182 return SdfAllowed(
1183 "Value does not have a valid scene description type "
1184 "(" + value.GetTypeName() + ")");
1185 }
1186
1187 return true;
1188 }
1189
1190 std::vector<SdfValueTypeName>
GetAllTypes() const1191 SdfSchemaBase::GetAllTypes() const
1192 {
1193 return _valueTypeRegistry->GetAllTypes();
1194 }
1195
1196 SdfValueTypeName
FindType(const TfToken & typeName) const1197 SdfSchemaBase::FindType(const TfToken& typeName) const
1198 {
1199 return _valueTypeRegistry->FindType(typeName);
1200 }
1201
1202 SdfValueTypeName
FindType(const char * typeName) const1203 SdfSchemaBase::FindType(const char *typeName) const
1204 {
1205 return _valueTypeRegistry->FindType(TfToken(typeName));
1206 }
1207
1208 SdfValueTypeName
FindType(const std::string & typeName) const1209 SdfSchemaBase::FindType(const std::string &typeName) const
1210 {
1211 return _valueTypeRegistry->FindType(TfToken(typeName));
1212 }
1213
1214 SdfValueTypeName
FindType(const TfType & type,const TfToken & role) const1215 SdfSchemaBase::FindType(const TfType& type, const TfToken& role) const
1216 {
1217 return _valueTypeRegistry->FindType(type, role);
1218 }
1219
1220 SdfValueTypeName
FindType(const VtValue & value,const TfToken & role) const1221 SdfSchemaBase::FindType(const VtValue& value, const TfToken& role) const
1222 {
1223 return _valueTypeRegistry->FindType(value, role);
1224 }
1225
1226 SdfValueTypeName
FindOrCreateType(const TfToken & typeName) const1227 SdfSchemaBase::FindOrCreateType(const TfToken& typeName) const
1228 {
1229 return _valueTypeRegistry->FindOrCreateTypeName(typeName);
1230 }
1231
1232 SdfSchemaBase::_ValueTypeRegistrar
_GetTypeRegistrar() const1233 SdfSchemaBase::_GetTypeRegistrar() const
1234 {
1235 return _ValueTypeRegistrar(_valueTypeRegistry.get());
1236 }
1237
1238 SdfAllowed
IsValidIdentifier(const std::string & identifier)1239 SdfSchemaBase::IsValidIdentifier(const std::string& identifier)
1240 {
1241 if (!SdfPath::IsValidIdentifier(identifier)) {
1242 return SdfAllowed("\"" + identifier +
1243 "\" is not a valid identifier");
1244 }
1245 return true;
1246 }
1247
1248 SdfAllowed
IsValidNamespacedIdentifier(const std::string & identifier)1249 SdfSchemaBase::IsValidNamespacedIdentifier(const std::string& identifier)
1250 {
1251 if (!SdfPath::IsValidNamespacedIdentifier(identifier)) {
1252 return SdfAllowed("\"" + identifier +
1253 "\" is not a valid identifier");
1254 }
1255 return true;
1256 }
1257
1258 SdfAllowed
IsValidVariantIdentifier(const std::string & identifier)1259 SdfSchemaBase::IsValidVariantIdentifier(const std::string& identifier)
1260 {
1261 // Allow [[:alnum:]_|\-]+ with an optional leading dot.
1262
1263 std::string::const_iterator first = identifier.begin();
1264 std::string::const_iterator last = identifier.end();
1265
1266 // Allow optional leading dot.
1267 if (first != last && *first == '.') {
1268 ++first;
1269 }
1270
1271 for (; first != last; ++first) {
1272 char c = *first;
1273 if (!(isalnum(c) || (c == '_') || (c == '|') || (c == '-'))) {
1274 return SdfAllowed(TfStringPrintf(
1275 "\"%s\" is not a valid variant "
1276 "name due to '%c' at index %d",
1277 identifier.c_str(),
1278 c,
1279 (int)(first - identifier.begin())));
1280 }
1281 }
1282
1283 return true;
1284 }
1285
1286 SdfAllowed
IsValidRelocatesPath(const SdfPath & path)1287 SdfSchemaBase::IsValidRelocatesPath(const SdfPath& path)
1288 {
1289 if (path == SdfPath::AbsoluteRootPath()) {
1290 return SdfAllowed("Root paths not allowed in relocates map");
1291 }
1292
1293 return true;
1294 }
1295
1296 SdfAllowed
IsValidInheritPath(const SdfPath & path)1297 SdfSchemaBase::IsValidInheritPath(const SdfPath& path)
1298 {
1299 if (!(path.IsAbsolutePath() && path.IsPrimPath())) {
1300 return SdfAllowed("Inherit paths must be an absolute prim path");
1301 }
1302 return true;
1303 }
1304
1305 SdfAllowed
IsValidSpecializesPath(const SdfPath & path)1306 SdfSchemaBase::IsValidSpecializesPath(const SdfPath& path)
1307 {
1308 if (!(path.IsAbsolutePath() && path.IsPrimPath())) {
1309 return SdfAllowed("Specializes paths must be absolute prim path");
1310 }
1311 return true;
1312 }
1313
1314 SdfAllowed
IsValidAttributeConnectionPath(const SdfPath & path)1315 SdfSchemaBase::IsValidAttributeConnectionPath(const SdfPath& path)
1316 {
1317 if (path.ContainsPrimVariantSelection()) {
1318 return SdfAllowed("Attribute connection paths cannot contain "
1319 "variant selections");
1320 }
1321 if (path.IsAbsolutePath() && (path.IsPropertyPath() || path.IsPrimPath())) {
1322 return true;
1323 }
1324 else {
1325 return SdfAllowed(
1326 TfStringPrintf("Connection paths must be absolute prim or "
1327 "property paths: <%s>", path.GetText()));
1328 }
1329 }
1330
1331 SdfAllowed
IsValidRelationshipTargetPath(const SdfPath & path)1332 SdfSchemaBase::IsValidRelationshipTargetPath(const SdfPath& path)
1333 {
1334 if (path.ContainsPrimVariantSelection()) {
1335 return SdfAllowed("Relationship target paths cannot contain "
1336 "variant selections");
1337 }
1338 if (path.IsAbsolutePath() &&
1339 (path.IsPropertyPath() || path.IsPrimPath() || path.IsMapperPath())) {
1340 return true;
1341 }
1342 else {
1343 return SdfAllowed("Relationship target paths must be absolute prim, "
1344 "property or mapper paths");
1345 }
1346 }
1347
1348 SdfAllowed
IsValidReference(const SdfReference & ref)1349 SdfSchemaBase::IsValidReference(const SdfReference& ref)
1350 {
1351 const SdfPath& path = ref.GetPrimPath();
1352 if (!path.IsEmpty() &&
1353 !(path.IsAbsolutePath() && path.IsPrimPath())) {
1354 return SdfAllowed("Reference prim path <" + path.GetString() +
1355 "> must be either empty or an absolute prim path");
1356 }
1357
1358 return true;
1359 }
1360
1361 SdfAllowed
IsValidPayload(const SdfPayload & p)1362 SdfSchemaBase::IsValidPayload(const SdfPayload& p)
1363 {
1364 const SdfPath& path = p.GetPrimPath();
1365 if (!path.IsEmpty() &&
1366 !(path.IsAbsolutePath() && path.IsPrimPath())) {
1367 return SdfAllowed("Payload prim path <" + path.GetString() +
1368 "> must be either empty or an absolute prim path");
1369 }
1370
1371 return true;
1372 }
1373
1374 SdfAllowed
IsValidSubLayer(const std::string & sublayer)1375 SdfSchemaBase::IsValidSubLayer(const std::string& sublayer)
1376 {
1377 if (sublayer.empty()) {
1378 return SdfAllowed("Sublayer paths must not be empty");
1379 }
1380
1381 // 'sublayer' must be a valid asset path as well, attempt to construct one
1382 // to check.
1383 TfErrorMark m;
1384 SdfAssetPath test(sublayer);
1385 if (!m.IsClean()) {
1386 std::vector<std::string> errs;
1387 for (TfError const &err: m) {
1388 errs.push_back(err.GetCommentary());
1389 }
1390 m.Clear();
1391 return SdfAllowed(
1392 TfStringPrintf("Invalid sublayer path: %s",
1393 TfStringJoin(errs, "; ").c_str()));
1394 }
1395 return true;
1396 }
1397
1398 typedef Sdf_ParserHelpers::Value Value;
1399
1400 // Helper function that adds values of type T to the value list that are
1401 // either stored directly or stored as elements of a vector<T>. Returns true
1402 // on success and false on failure.
1403 template <typename T>
1404 static bool
_AccumulateTypedValues(const JsValue & value,std::deque<Value> * values)1405 _AccumulateTypedValues(const JsValue &value, std::deque<Value> *values) {
1406 if (value.IsArrayOf<T>()) {
1407 for (const T& v : value.GetArrayOf<T>()) {
1408 values->push_back(v);
1409 }
1410 return true;
1411 } else if (value.Is<T>()) {
1412 values->push_back(value.Get<T>());
1413 return true;
1414 }
1415 return false;
1416 }
1417
1418 // Recursive helper function to feed the ParserValueContext with the correct
1419 // calls to BeginTuple(), EndTuple(), and TupleItem() in between calls to
1420 // AppendValue().
1421 static void
_AddValuesToValueContext(std::deque<Value> * values,Sdf_ParserValueContext * context,int level=0)1422 _AddValuesToValueContext(std::deque<Value> *values, Sdf_ParserValueContext *context, int level = 0) {
1423 if (context->valueTupleDimensions.size == 0) {
1424 while (!values->empty()) {
1425 context->AppendValue(values->front());
1426 values->pop_front();
1427 }
1428 } else if (static_cast<size_t>(level) < context->valueTupleDimensions.size) {
1429 context->BeginTuple();
1430 for (size_t i = 0; i < context->valueTupleDimensions.d[level]; i++) {
1431 _AddValuesToValueContext(values, context, level + 1);
1432 }
1433 context->EndTuple();
1434 } else if (!values->empty()) {
1435 context->AppendValue(values->front());
1436 values->pop_front();
1437 }
1438 }
1439
1440 // Uses the ParserValueContext to manufacture a VtValue of the correct type
1441 // from a JsValue and a value typename. For example, this can manufacture a
1442 // "Vec3d[]" from a JsValue containing vector<double>(1, 2, 3, 4, 5, 6) into
1443 // VtValue(VtArray([2], Vec3d(1, 2, 3), Vec3d(4, 5, 6))). If an error occurs,
1444 // an empty VtValue is returned and the error text is stored in *errorText.
1445 static VtValue
_ParseValue(const std::string & valueTypeName,const JsValue & value,std::string * errorText)1446 _ParseValue(const std::string &valueTypeName, const JsValue &value,
1447 std::string *errorText)
1448 {
1449 // Checks for strings, ints, doubles, and vectors of those types because
1450 // that's what _ConvertDict() in Plugin.cpp parses out of plugInfo.json
1451 std::deque<Value> values;
1452 if (!_AccumulateTypedValues<std::string>(value, &values) &&
1453 !_AccumulateTypedValues<int>(value, &values) &&
1454 !_AccumulateTypedValues<double>(value, &values)) {
1455 *errorText = "Value was not a string, an int, a double, or a "
1456 "vector of those types";
1457 return VtValue();
1458 }
1459
1460 // Initialize the ParserValueContext
1461 Sdf_ParserValueContext context;
1462 if (!context.SetupFactory(valueTypeName)) {
1463 *errorText = TfStringPrintf("\"%s\" is not a valid type",
1464 valueTypeName.c_str());
1465 return VtValue();
1466 }
1467
1468 // Feed the ParserValueContext the values in the correct format.
1469 // A better solution would be to have the default value be a string,
1470 // which is parsed using the menva file format syntax for typed values.
1471 // This would involve extracting the typed value rule out of the parser
1472 // and into a new parser.
1473 if (context.valueIsShaped)
1474 context.BeginList();
1475 while (!values.empty())
1476 _AddValuesToValueContext(&values, &context);
1477 if (context.valueIsShaped)
1478 context.EndList();
1479
1480 // Return the produced value, or fill in errorText and return VtValue()
1481 // on failure
1482 return context.ProduceValue(errorText);
1483 }
1484
1485 // Helper function to make reading from dictionaries easier
1486 template <typename T>
1487 static bool
_GetKey(const JsObject & dict,const std::string & key,T * value)1488 _GetKey(const JsObject &dict, const std::string &key, T *value)
1489 {
1490 JsObject::const_iterator i = dict.find(key);
1491 if (i != dict.end() && i->second.Is<T>()) {
1492 *value = i->second.Get<T>();
1493 return true;
1494 }
1495 return false;
1496 }
1497
1498 // Helper function to read and extract from dictionaries
1499 template <typename T>
1500 static bool
_ExtractKey(JsObject & dict,const std::string & key,T * value)1501 _ExtractKey(JsObject &dict, const std::string &key, T *value)
1502 {
1503 JsObject::const_iterator i = dict.find(key);
1504 if (i != dict.end() && i->second.Is<T>()) {
1505 *value = i->second.Get<T>();
1506 dict.erase(i);
1507 return true;
1508 }
1509 return false;
1510 }
1511
1512 static VtValue
_GetDefaultValueForListOp(const std::string & valueTypeName)1513 _GetDefaultValueForListOp(const std::string& valueTypeName)
1514 {
1515 if (valueTypeName == "intlistop") {
1516 return VtValue(SdfIntListOp());
1517 }
1518 else if (valueTypeName == "int64listop") {
1519 return VtValue(SdfInt64ListOp());
1520 }
1521 if (valueTypeName == "uintlistop") {
1522 return VtValue(SdfUIntListOp());
1523 }
1524 else if (valueTypeName == "uint64listop") {
1525 return VtValue(SdfUInt64ListOp());
1526 }
1527 if (valueTypeName == "stringlistop") {
1528 return VtValue(SdfStringListOp());
1529 }
1530 else if (valueTypeName == "tokenlistop") {
1531 return VtValue(SdfTokenListOp());
1532 }
1533 return VtValue();
1534 }
1535
1536 static VtValue
_GetDefaultMetadataValue(const SdfSchemaBase & schema,const std::string & valueTypeName,const JsValue & defaultValue)1537 _GetDefaultMetadataValue(const SdfSchemaBase& schema,
1538 const std::string& valueTypeName,
1539 const JsValue& defaultValue)
1540 {
1541 if (valueTypeName == "dictionary") {
1542 if (!defaultValue.IsNull()) {
1543 // Defaults aren't allowed for dictionaries because we have
1544 // no way of parsing them at the moment
1545 TF_CODING_ERROR("Default values are not allowed on fields "
1546 "of type \"dictionary\", which will "
1547 "always default to an empty dictionary.");
1548 return VtValue();
1549 }
1550 return VtValue(VtDictionary());
1551 }
1552
1553 const VtValue listOpValue = _GetDefaultValueForListOp(valueTypeName);
1554 if (!listOpValue.IsEmpty()) {
1555 if (!defaultValue.IsNull()) {
1556 // Defaults aren't allowed for list ops because we have
1557 // no way of parsing them at the moment
1558 TF_CODING_ERROR("Default values are not allowed on fields "
1559 "of type \"%s\", which will always"
1560 "default to an empty list op.",
1561 valueTypeName.c_str());
1562 return VtValue();
1563 }
1564 return listOpValue;
1565 }
1566
1567 if (const SdfValueTypeName valueType = schema.FindType(valueTypeName)) {
1568 if (defaultValue.IsNull()) {
1569 return valueType.GetDefaultValue();
1570 }
1571 else {
1572 std::string errorText;
1573 const VtValue parsedValue = _ParseValue(
1574 valueTypeName, defaultValue, &errorText);
1575 if (parsedValue.IsEmpty()) {
1576 TF_CODING_ERROR("Could not parse default value: %s",
1577 errorText.c_str());
1578 }
1579 return parsedValue;
1580 }
1581 }
1582
1583 TF_CODING_ERROR("\"%s\" is not a registered value type",
1584 valueTypeName.c_str());
1585 return VtValue();
1586 }
1587
1588 // Reads and registers new fields from plugInfo.json files
1589 const std::vector<const SdfSchemaBase::FieldDefinition *>
_UpdateMetadataFromPlugins(const PlugPluginPtrVector & plugins,const std::string & tag,const _DefaultValueFactoryFn & defFactory)1590 SdfSchemaBase::_UpdateMetadataFromPlugins(
1591 const PlugPluginPtrVector& plugins,
1592 const std::string& tag,
1593 const _DefaultValueFactoryFn& defFactory)
1594 {
1595 static const std::string sdfMetadataTag = "SdfMetadata";
1596 const std::string& metadataTag = (tag.empty() ? sdfMetadataTag : tag);
1597 std::vector<const SdfSchemaBase::FieldDefinition *> metadataFieldsParsed;
1598
1599 // Update the schema with new metadata fields from each plugin, if they
1600 // contain any
1601 for (const PlugPluginPtr & plug : plugins) {
1602 // Get the top-level dictionary key specified by the metadata tag.
1603 JsObject fields;
1604 const JsObject &metadata = plug->GetMetadata();
1605 if (!_GetKey(metadata, metadataTag, &fields))
1606 continue;
1607
1608 // Register new fields
1609 for (const std::pair<const std::string, JsValue>& field : fields) {
1610 const TfToken fieldName(field.first);
1611
1612 // Validate field
1613 JsObject fieldInfo;
1614 if (!_GetKey(fields, fieldName, &fieldInfo)) {
1615 TF_CODING_ERROR("Value must be a dictionary (at \"%s\" in "
1616 "plugin \"%s\")",
1617 fieldName.GetText(),
1618 plug->GetPath().c_str());
1619 continue;
1620 }
1621
1622 std::string valueTypeName;
1623 if (!_ExtractKey(
1624 fieldInfo, _tokens->Type.GetString(), &valueTypeName)) {
1625 TF_CODING_ERROR("Could not read a string for \"type\" "
1626 "(at \"%s\" in plugin \"%s\")",
1627 fieldName.GetText(), plug->GetPath().c_str());
1628 continue;
1629 }
1630
1631 if (IsRegistered(fieldName)) {
1632 TF_CODING_ERROR("\"%s\" is already a registered field "
1633 "(in plugin \"%s\")",
1634 fieldName.GetText(),
1635 plug->GetPath().c_str());
1636 continue;
1637 }
1638
1639 // Parse plugin-defined default value for this field.
1640 VtValue defaultValue;
1641 {
1642 const JsValue pluginDefault =
1643 TfMapLookupByValue(fieldInfo,
1644 _tokens->Default.GetString(), JsValue());
1645
1646 TfErrorMark m;
1647
1648 defaultValue = _GetDefaultMetadataValue(
1649 *this, valueTypeName, pluginDefault);
1650 if (defaultValue.IsEmpty() && defFactory) {
1651 defaultValue = defFactory(valueTypeName, pluginDefault);
1652 }
1653
1654 if (defaultValue.IsEmpty()) {
1655 // If an error wasn't emitted but we still don't have a
1656 // default value, emit an error indicating this.
1657 //
1658 // If an error was emitted, post a follow-up error that
1659 // provides more context about where that error was
1660 // encountered, since the default value factory isn't
1661 // given enough info to do this itself.
1662 if (m.IsClean()) {
1663 TF_CODING_ERROR("No default value for metadata "
1664 "(at \"%s\" in plugin \"%s\")",
1665 fieldName.GetText(),
1666 plug->GetPath().c_str());
1667 }
1668 else {
1669 TF_CODING_ERROR("Error parsing default value for "
1670 "metadata (at \"%s\" in plugin \"%s\")",
1671 fieldName.GetText(),
1672 plug->GetPath().c_str());
1673 }
1674 continue;
1675 }
1676 else {
1677 // We can drop errors that had been issued from
1678 // _GetDefaultMetadataValue (e.g., due to this metadata
1679 // type not being recognized) if the passed-in factory
1680 // was able to produce a default value.
1681 m.Clear();
1682 }
1683 }
1684
1685 // Use the supplied displayGroup, if set, otherwise 'uncategorized'.
1686 TfToken displayGroup;
1687 {
1688 std::string displayGroupString;
1689 if (_ExtractKey(fieldInfo,
1690 _tokens->DisplayGroup.GetString(), &displayGroupString))
1691 displayGroup = TfToken(displayGroupString);
1692 }
1693
1694 FieldDefinition& fieldDef =
1695 _RegisterField(fieldName, defaultValue, /* plugin = */ true);
1696
1697 // Look for 'appliesTo', either a single string or a list of strings
1698 // specifying which spec types this metadatum should be registered
1699 // for.
1700 set<string> appliesTo;
1701 {
1702 const JsValue val =
1703 TfMapLookupByValue(fieldInfo,
1704 _tokens->AppliesTo.GetString(), JsValue());
1705 if (val.IsArrayOf<string>()) {
1706 const vector<string> vec = val.GetArrayOf<string>();
1707 appliesTo.insert(vec.begin(), vec.end());
1708 } else if (val.Is<string>()) {
1709 appliesTo.insert(val.Get<string>());
1710 }
1711
1712 // this is so appliesTo does not show up in fieldDef's info
1713 fieldInfo.erase(_tokens->AppliesTo.GetString());
1714 }
1715 if (appliesTo.empty() || appliesTo.count("layers")) {
1716 _ExtendSpecDefinition(SdfSpecTypePseudoRoot)
1717 .MetadataField(fieldName, displayGroup);
1718 }
1719
1720 if (appliesTo.empty() || appliesTo.count("prims")) {
1721 _ExtendSpecDefinition(SdfSpecTypePrim)
1722 .MetadataField(fieldName, displayGroup);
1723 }
1724
1725 if (appliesTo.empty() || appliesTo.count("properties") ||
1726 appliesTo.count("attributes")) {
1727 _ExtendSpecDefinition(SdfSpecTypeAttribute)
1728 .MetadataField(fieldName, displayGroup);
1729 }
1730
1731 if (appliesTo.empty() || appliesTo.count("properties") ||
1732 appliesTo.count("relationships")) {
1733 _ExtendSpecDefinition(SdfSpecTypeRelationship)
1734 .MetadataField(fieldName, displayGroup);
1735 }
1736
1737 // All metadata on prims should also apply to variants.
1738 // This matches how the variant spec definition is copied
1739 // from the prim spec definition in _RegisterStandardFields.
1740 if (appliesTo.empty() || appliesTo.count("variants") ||
1741 appliesTo.count("prims")) {
1742 _ExtendSpecDefinition(SdfSpecTypeVariant)
1743 .MetadataField(fieldName, displayGroup);
1744 }
1745
1746 // All remaining values in the fieldInfo will are unknown to sdf,
1747 // so store them off in our field definitions for other libraries
1748 // to use.
1749 for (const std::pair<const std::string, JsValue>& it : fieldInfo) {
1750 const std::string& metadataInfoName = it.first;
1751 const JsValue& metadataInfoValue = it.second;
1752
1753 TfToken metadataInfo (metadataInfoName);
1754 fieldDef.AddInfo(metadataInfo, metadataInfoValue);
1755 }
1756 metadataFieldsParsed.push_back(&fieldDef);
1757 }
1758 }
1759 return metadataFieldsParsed;
1760 }
1761
1762 void
_AddRequiredFieldName(const TfToken & fieldName)1763 SdfSchemaBase::_AddRequiredFieldName(const TfToken &fieldName)
1764 {
1765 if (find(_requiredFieldNames.begin(),
1766 _requiredFieldNames.end(), fieldName) == _requiredFieldNames.end())
1767 _requiredFieldNames.push_back(fieldName);
1768 }
1769
1770 //
1771 // SdfSchema
1772 //
1773
1774 TF_INSTANTIATE_SINGLETON(SdfSchema);
1775
TF_REGISTRY_FUNCTION(TfType)1776 TF_REGISTRY_FUNCTION(TfType)
1777 {
1778 TfType::Define<SdfSchema, TfType::Bases<SdfSchemaBase> >();
1779 }
1780
SdfSchema()1781 SdfSchema::SdfSchema()
1782 {
1783 }
1784
~SdfSchema()1785 SdfSchema::~SdfSchema()
1786 {
1787 // Do nothing
1788 }
1789
1790 //
1791 // Sdf_InitializeValueTypeNames
1792 //
1793 // This function is used in types.cpp to initialize the SdfValueTypeNames
1794 // static data object. This is defined here so that we can share code and
1795 // co-locate the typename strings with _AddStandardTypesToRegistry.
1796 //
1797 const Sdf_ValueTypeNamesType*
Sdf_InitializeValueTypeNames()1798 Sdf_InitializeValueTypeNames()
1799 {
1800 struct _Registry {
1801 _Registry()
1802 {
1803 _AddStandardTypesToRegistry(®istry);
1804 _AddLegacyTypesToRegistry(®istry);
1805 }
1806 Sdf_ValueTypeRegistry registry;
1807 };
1808 static const _Registry registry;
1809
1810 const Sdf_ValueTypeRegistry& r = registry.registry;
1811 Sdf_ValueTypeNamesType* n = new Sdf_ValueTypeNamesType;
1812
1813 n->Bool = r.FindType("bool");
1814 n->UChar = r.FindType("uchar");
1815 n->Int = r.FindType("int");
1816 n->UInt = r.FindType("uint");
1817 n->Int64 = r.FindType("int64");
1818 n->UInt64 = r.FindType("uint64");
1819 n->Half = r.FindType("half");
1820 n->Float = r.FindType("float");
1821 n->Double = r.FindType("double");
1822 n->TimeCode = r.FindType("timecode");
1823 n->String = r.FindType("string");
1824 n->Token = r.FindType("token");
1825 n->Asset = r.FindType("asset");
1826 n->Int2 = r.FindType("int2");
1827 n->Int3 = r.FindType("int3");
1828 n->Int4 = r.FindType("int4");
1829 n->Half2 = r.FindType("half2");
1830 n->Half3 = r.FindType("half3");
1831 n->Half4 = r.FindType("half4");
1832 n->Float2 = r.FindType("float2");
1833 n->Float3 = r.FindType("float3");
1834 n->Float4 = r.FindType("float4");
1835 n->Double2 = r.FindType("double2");
1836 n->Double3 = r.FindType("double3");
1837 n->Double4 = r.FindType("double4");
1838 n->Point3h = r.FindType("point3h");
1839 n->Point3f = r.FindType("point3f");
1840 n->Point3d = r.FindType("point3d");
1841 n->Vector3h = r.FindType("vector3h");
1842 n->Vector3f = r.FindType("vector3f");
1843 n->Vector3d = r.FindType("vector3d");
1844 n->Normal3h = r.FindType("normal3h");
1845 n->Normal3f = r.FindType("normal3f");
1846 n->Normal3d = r.FindType("normal3d");
1847 n->Color3h = r.FindType("color3h");
1848 n->Color3f = r.FindType("color3f");
1849 n->Color3d = r.FindType("color3d");
1850 n->Color4h = r.FindType("color4h");
1851 n->Color4f = r.FindType("color4f");
1852 n->Color4d = r.FindType("color4d");
1853 n->Quath = r.FindType("quath");
1854 n->Quatf = r.FindType("quatf");
1855 n->Quatd = r.FindType("quatd");
1856 n->Matrix2d = r.FindType("matrix2d");
1857 n->Matrix3d = r.FindType("matrix3d");
1858 n->Matrix4d = r.FindType("matrix4d");
1859 n->Frame4d = r.FindType("frame4d");
1860 n->TexCoord2f = r.FindType("texCoord2f");
1861 n->TexCoord2d = r.FindType("texCoord2d");
1862 n->TexCoord2h = r.FindType("texCoord2h");
1863 n->TexCoord3f = r.FindType("texCoord3f");
1864 n->TexCoord3d = r.FindType("texCoord3d");
1865 n->TexCoord3h = r.FindType("texCoord3h");
1866
1867 n->BoolArray = r.FindType("bool[]");
1868 n->UCharArray = r.FindType("uchar[]");
1869 n->IntArray = r.FindType("int[]");
1870 n->UIntArray = r.FindType("uint[]");
1871 n->Int64Array = r.FindType("int64[]");
1872 n->UInt64Array = r.FindType("uint64[]");
1873 n->HalfArray = r.FindType("half[]");
1874 n->FloatArray = r.FindType("float[]");
1875 n->DoubleArray = r.FindType("double[]");
1876 n->TimeCodeArray = r.FindType("timecode[]");
1877 n->StringArray = r.FindType("string[]");
1878 n->TokenArray = r.FindType("token[]");
1879 n->AssetArray = r.FindType("asset[]");
1880 n->Int2Array = r.FindType("int2[]");
1881 n->Int3Array = r.FindType("int3[]");
1882 n->Int4Array = r.FindType("int4[]");
1883 n->Half2Array = r.FindType("half2[]");
1884 n->Half3Array = r.FindType("half3[]");
1885 n->Half4Array = r.FindType("half4[]");
1886 n->Float2Array = r.FindType("float2[]");
1887 n->Float3Array = r.FindType("float3[]");
1888 n->Float4Array = r.FindType("float4[]");
1889 n->Double2Array = r.FindType("double2[]");
1890 n->Double3Array = r.FindType("double3[]");
1891 n->Double4Array = r.FindType("double4[]");
1892 n->Point3hArray = r.FindType("point3h[]");
1893 n->Point3fArray = r.FindType("point3f[]");
1894 n->Point3dArray = r.FindType("point3d[]");
1895 n->Vector3hArray = r.FindType("vector3h[]");
1896 n->Vector3fArray = r.FindType("vector3f[]");
1897 n->Vector3dArray = r.FindType("vector3d[]");
1898 n->Normal3hArray = r.FindType("normal3h[]");
1899 n->Normal3fArray = r.FindType("normal3f[]");
1900 n->Normal3dArray = r.FindType("normal3d[]");
1901 n->Color3hArray = r.FindType("color3h[]");
1902 n->Color3fArray = r.FindType("color3f[]");
1903 n->Color3dArray = r.FindType("color3d[]");
1904 n->Color4hArray = r.FindType("color4h[]");
1905 n->Color4fArray = r.FindType("color4f[]");
1906 n->Color4dArray = r.FindType("color4d[]");
1907 n->QuathArray = r.FindType("quath[]");
1908 n->QuatfArray = r.FindType("quatf[]");
1909 n->QuatdArray = r.FindType("quatd[]");
1910 n->Matrix2dArray = r.FindType("matrix2d[]");
1911 n->Matrix3dArray = r.FindType("matrix3d[]");
1912 n->Matrix4dArray = r.FindType("matrix4d[]");
1913 n->Frame4dArray = r.FindType("frame4d[]");
1914 n->TexCoord2fArray = r.FindType("texCoord2f[]");
1915 n->TexCoord2dArray = r.FindType("texCoord2d[]");
1916 n->TexCoord2hArray = r.FindType("texCoord2h[]");
1917 n->TexCoord3fArray = r.FindType("texCoord3f[]");
1918 n->TexCoord3dArray = r.FindType("texCoord3d[]");
1919 n->TexCoord3hArray = r.FindType("texCoord3h[]");
1920
1921 return n;
1922 }
1923
1924 PXR_NAMESPACE_CLOSE_SCOPE
1925