All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
fileIO_Common.h
Go to the documentation of this file.
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 #ifndef SDF_FILEIO_COMMON_H
25 #define SDF_FILEIO_COMMON_H
26 
28 
29 #include "pxr/pxr.h"
30 #include "pxr/usd/sdf/attributeSpec.h"
31 #include "pxr/usd/sdf/declareHandles.h"
32 #include "pxr/usd/sdf/layer.h"
33 #include "pxr/usd/sdf/layerOffset.h"
34 #include "pxr/usd/sdf/path.h"
35 #include "pxr/usd/sdf/primSpec.h"
36 #include "pxr/usd/sdf/reference.h"
37 #include "pxr/usd/sdf/relationshipSpec.h"
38 #include "pxr/usd/sdf/schema.h"
39 #include "pxr/usd/sdf/types.h"
40 #include "pxr/usd/sdf/variantSetSpec.h"
41 
42 #include "pxr/base/vt/dictionary.h"
43 #include "pxr/base/vt/value.h"
44 
45 #include "pxr/base/tf/stringUtils.h"
46 #include "pxr/base/tf/token.h"
47 
48 #include <algorithm>
49 #include <iosfwd>
50 #include <map>
51 #include <set>
52 #include <string>
53 #include <vector>
54 
55 PXR_NAMESPACE_OPEN_SCOPE
56 
58 // Simple FileIO Utilities
59 
60 class Sdf_FileIOUtility {
61 
62 public:
63 
64  // === Stream output helpers
65 
66  // Non-formatted string output
67  static void Puts(std::ostream &out,
68  size_t indent, const std::string &str);
69  // Printf-style formatted string output
70  static void Write(std::ostream &out,
71  size_t indent, const char *fmt, ...);
72 
73  static bool OpenParensIfNeeded(std::ostream &out,
74  bool didParens, bool multiLine);
75  static void CloseParensIfNeeded(std::ostream &out,
76  size_t indent, bool didParens, bool multiLine);
77 
78  static void WriteQuotedString(std::ostream &out,
79  size_t indent, const std::string &str);
80 
81  static void WriteAssetPath(std::ostream &out,
82  size_t indent, const std::string &str);
83 
84  static void WriteDefaultValue(std::ostream &out,
85  size_t indent, VtValue value);
86 
87  static void WriteSdfPath(std::ostream &out,
88  size_t indent, const SdfPath &path);
89 
90  static bool WriteNameVector(std::ostream &out,
91  size_t indent, const std::vector<std::string> &vec);
92  static bool WriteNameVector(std::ostream &out,
93  size_t indent, const std::vector<TfToken> &vec);
94 
95  static bool WriteTimeSamples(std::ostream &out,
96  size_t indent, const SdfPropertySpec &);
97 
98  static bool WriteRelocates(std::ostream &out,
99  size_t indent, bool multiLine,
100  const SdfRelocatesMap &reloMap);
101 
102  static void WriteDictionary(std::ostream &out,
103  size_t indent, bool multiLine,
104  const VtDictionary &dictionary,
105  bool stringValuesOnly=false);
106 
107  template <class T>
108  static void WriteListOp(std::ostream &out,
109  size_t indent,
110  const TfToken& fieldName,
111  const SdfListOp<T>& listOp);
112 
113  static void WriteLayerOffset(std::ostream &out,
114  size_t indent, bool multiline,
115  const SdfLayerOffset& offset);
116 
117  // === String production and transformation helpers
118 
123  static std::string Quote(const std::string &str);
124  static std::string Quote(const TfToken &token);
125 
126  // Create a string from a value
127  static std::string StringFromVtValue(const VtValue &value);
128 
129  // Convert enums to a strings for use in menva syntax.
130  // Note that in some cases we use empty strings to represent the
131  // default values of these enums.
132  static const char* Stringify( SdfPermission val );
133  static const char* Stringify( SdfSpecifier val );
134  static const char* Stringify( SdfVariability val );
135 
136 private:
137 
138  // Helper types to write a VtDictionary so that its keys are ordered.
139  struct _StringLessThan {
140  bool operator()(const std::string *lhs, const std::string *rhs) const {
141  return *lhs < *rhs;
142  }
143  };
144  typedef std::map<const std::string *, const VtValue *, _StringLessThan>
145  _OrderedDictionary;
146 
147  static void _WriteDictionary(std::ostream &out,
148  size_t indent, bool multiLine, _OrderedDictionary &dictionary,
149  bool stringValuesOnly);
150 };
151 
153 // Helpers for determining if a field should be included in a spec's
154 // metadata section.
155 
156 struct Sdf_IsMetadataField
157 {
158  Sdf_IsMetadataField(const SdfSpecType specType)
159  : _specDef(SdfSchema::GetInstance().GetSpecDefinition(specType))
160  { }
161 
162  bool operator()(const TfToken& field) const
163  {
164  // Allow fields tagged explicitly as metadata, or fields
165  // that are invalid, as these may be unrecognized plugin
166  // metadata fields. In this case, there may be a string
167  // representation that needs to be written out.
168  return (!_specDef->IsValidField(field) ||
169  _specDef->IsMetadataField(field));
170  }
171 
172  const SdfSchema::SpecDefinition* _specDef;
173 };
174 
176 
177 static bool
178 Sdf_WritePrimPreamble(
179  const SdfPrimSpec &prim, std::ostream &out, size_t indent)
180 {
181  SdfSpecifier spec = prim.GetSpecifier();
182  bool writeTypeName = true;
183  if (!SdfIsDefiningSpecifier(spec)) {
184  // For non-defining specifiers, we write typeName only if we have
185  // a setting.
186  writeTypeName = prim.HasField(SdfFieldKeys->TypeName);
187  }
188 
189  TfToken typeName;
190  if (writeTypeName) {
191  typeName = prim.GetTypeName();
192  if (typeName == SdfTokens->AnyTypeToken){
193  typeName = TfToken();
194  }
195  }
196 
197  Sdf_FileIOUtility::Write( out, indent, "%s%s%s ",
198  Sdf_FileIOUtility::Stringify(spec),
199  !typeName.IsEmpty() ? " " : "",
200  !typeName.IsEmpty() ? typeName.GetText() : "" );
201  Sdf_FileIOUtility::WriteQuotedString( out, 0, prim.GetName().c_str() );
202 
203  return true;
204 }
205 
206 template <class ListOpType>
207 static bool
208 Sdf_WriteIfListOp(
209  std::ostream& out, size_t indent,
210  const TfToken& field, const VtValue& value)
211 {
212  if (value.IsHolding<ListOpType>()) {
213  Sdf_FileIOUtility::WriteListOp(
214  out, indent, field, value.UncheckedGet<ListOpType>());
215  return true;
216  }
217  return false;
218 }
219 
220 static void
221 Sdf_WriteSimpleField(
222  std::ostream &out, size_t indent,
223  const SdfSpec& spec, const TfToken& field)
224 {
225  const VtValue& value = spec.GetField(field);
226 
227  if (Sdf_WriteIfListOp<SdfIntListOp>(out, indent, field, value) ||
228  Sdf_WriteIfListOp<SdfInt64ListOp>(out, indent, field, value) ||
229  Sdf_WriteIfListOp<SdfUIntListOp>(out, indent, field, value) ||
230  Sdf_WriteIfListOp<SdfUInt64ListOp>(out, indent, field, value) ||
231  Sdf_WriteIfListOp<SdfStringListOp>(out, indent, field, value) ||
232  Sdf_WriteIfListOp<SdfTokenListOp>(out, indent, field, value)) {
233  return;
234  }
235 
236  bool isUnregisteredValue = value.IsHolding<SdfUnregisteredValue>();
237 
238  if (isUnregisteredValue) {
239  // The value boxed inside a SdfUnregisteredValue can either be a
240  // std::string, a VtDictionary, or an SdfUnregisteredValueListOp.
241  const VtValue &boxedValue = value.Get<SdfUnregisteredValue>().GetValue();
242  if (boxedValue.IsHolding<SdfUnregisteredValueListOp>()) {
243  Sdf_FileIOUtility::WriteListOp(
244  out, indent, field,
245  boxedValue.UncheckedGet<SdfUnregisteredValueListOp>());
246  }
247  else {
248  Sdf_FileIOUtility::Write(out, indent, "%s = ", field.GetText());
249  if (boxedValue.IsHolding<VtDictionary>()) {
250  Sdf_FileIOUtility::WriteDictionary(out, indent, true, boxedValue.Get<VtDictionary>());
251  }
252  else if (boxedValue.IsHolding<std::string>()) {
253  Sdf_FileIOUtility::Write(out, 0, "%s\n", boxedValue.Get<std::string>().c_str());
254  }
255  }
256  return;
257  }
258 
259  Sdf_FileIOUtility::Write(out, indent, "%s = ", field.GetText());
260  if (value.IsHolding<VtDictionary>()) {
261  Sdf_FileIOUtility::WriteDictionary(out, indent, true, value.Get<VtDictionary>());
262  }
263  else if (value.IsHolding<bool>()) {
264  Sdf_FileIOUtility::Write(out, 0, "%s\n", TfStringify(value.Get<bool>()).c_str());
265  }
266  else {
267  Sdf_FileIOUtility::Write(out, 0, "%s\n", Sdf_FileIOUtility::StringFromVtValue(value).c_str());
268  }
269 }
270 
271 // Predicate for determining fields that should be included in a
272 // prim's metadata section.
273 struct Sdf_IsPrimMetadataField : public Sdf_IsMetadataField
274 {
275  Sdf_IsPrimMetadataField() : Sdf_IsMetadataField(SdfSpecTypePrim) { }
276 
277  bool operator()(const TfToken& field) const
278  {
279  // Typename is registered as metadata for a prim, but is written
280  // outside the metadata section.
281  if (field == SdfFieldKeys->TypeName) {
282  return false;
283  }
284 
285  return (Sdf_IsMetadataField::operator()(field) ||
286  field == SdfFieldKeys->Payload ||
287  field == SdfFieldKeys->References ||
288  field == SdfFieldKeys->Relocates ||
289  field == SdfFieldKeys->InheritPaths ||
290  field == SdfFieldKeys->Specializes ||
291  field == SdfFieldKeys->VariantSetNames ||
292  field == SdfFieldKeys->VariantSelection);
293  }
294 };
295 
296 static bool
297 Sdf_WritePrimMetadata(
298  const SdfPrimSpec &prim, std::ostream &out, size_t indent)
299 {
300  // Partition this prim's fields so that all fields to write out are
301  // in the range [fields.begin(), metadataFieldsEnd).
302  TfTokenVector fields = prim.ListFields();
303  TfTokenVector::iterator metadataFieldsEnd =
304  std::partition(fields.begin(), fields.end(), Sdf_IsPrimMetadataField());
305 
306  // Comment isn't tagged as a metadata field but gets special cased
307  // because it wants to be at the top of the metadata section.
308  std::string comment = prim.GetComment();
309  bool hasComment = !comment.empty();
310 
311  bool didParens = false;
312 
313  // As long as there's anything to write in the metadata section, we'll
314  // always use the multi-line format.
315  bool multiLine = hasComment || (fields.begin() != metadataFieldsEnd);
316 
317  // Write comment at the top of the metadata section for readability.
318  if (hasComment) {
319  didParens =
320  Sdf_FileIOUtility::OpenParensIfNeeded(out, didParens, multiLine);
321  Sdf_FileIOUtility::WriteQuotedString(out, indent+1, comment);
322  Sdf_FileIOUtility::Puts(out, 0, "\n");
323  }
324 
325  // Write out remaining fields in the metadata section in dictionary-sorted
326  // order.
327  std::sort(fields.begin(), metadataFieldsEnd, TfDictionaryLessThan());
328  for (TfTokenVector::const_iterator fieldIt = fields.begin();
329  fieldIt != metadataFieldsEnd; ++fieldIt) {
330 
331  didParens =
332  Sdf_FileIOUtility::OpenParensIfNeeded(out, didParens, multiLine);
333 
334  const TfToken& field = *fieldIt;
335 
336  if (field == SdfFieldKeys->Documentation) {
337  Sdf_FileIOUtility::Puts(out, indent+1, "doc = ");
338  Sdf_FileIOUtility::WriteQuotedString(out, 0, prim.GetDocumentation());
339  Sdf_FileIOUtility::Puts(out, 0, "\n");
340  }
341  else if (field == SdfFieldKeys->Permission) {
342  if (multiLine) {
343  Sdf_FileIOUtility::Write(out, indent+1, "permission = %s\n",
344  Sdf_FileIOUtility::Stringify(prim.GetPermission()) );
345  } else {
346  Sdf_FileIOUtility::Write(out, 0, "permission = %s",
347  Sdf_FileIOUtility::Stringify(prim.GetPermission()) );
348  }
349  }
350  else if (field == SdfFieldKeys->SymmetryFunction) {
351  Sdf_FileIOUtility::Write(out, multiLine ? indent+1 : 0, "symmetryFunction = %s%s",
352  prim.GetSymmetryFunction().GetText(),
353  multiLine ? "\n" : "");
354  }
355  else if (field == SdfFieldKeys->Payload) {
356  const VtValue v = prim.GetField(field);
357  if (!Sdf_WriteIfListOp<SdfPayloadListOp>(
358  out, indent+1, TfToken("payload"), v)) {
360  "'%s' field holding unexpected type '%s'",
361  field.GetText(), v.GetTypeName().c_str());
362  }
363  }
364  else if (field == SdfFieldKeys->References) {
365  const VtValue v = prim.GetField(field);
366  if (!Sdf_WriteIfListOp<SdfReferenceListOp>(
367  out, indent+1, TfToken("references"), v)) {
369  "'%s' field holding unexpected type '%s'",
370  field.GetText(), v.GetTypeName().c_str());
371  }
372  }
373  else if (field == SdfFieldKeys->VariantSetNames) {
374  SdfVariantSetNamesProxy variantSetNameList = prim.GetVariantSetNameList();
375  if (variantSetNameList.IsExplicit()) {
376  // Explicit list
377  SdfVariantSetNamesProxy::ListProxy setNames = variantSetNameList.GetExplicitItems();
378  Sdf_FileIOUtility::Puts(out, indent+1, "variantSets = ");
379  Sdf_FileIOUtility::WriteNameVector(out, indent+1, setNames);
380  Sdf_FileIOUtility::Puts(out, 0, "\n");
381  } else {
382  // List operations
383  SdfVariantSetNamesProxy::ListProxy setNames = variantSetNameList.GetDeletedItems();
384  if (!setNames.empty()) {
385  Sdf_FileIOUtility::Puts(out, indent+1, "delete variantSets = ");
386  Sdf_FileIOUtility::WriteNameVector(out, indent+1, setNames);
387  Sdf_FileIOUtility::Puts(out, 0, "\n");
388  }
389  setNames = variantSetNameList.GetAddedItems();
390  if (!setNames.empty()) {
391  Sdf_FileIOUtility::Puts(out, indent+1, "add variantSets = ");
392  Sdf_FileIOUtility::WriteNameVector(out, indent+1, setNames);
393  Sdf_FileIOUtility::Puts(out, 0, "\n");
394  }
395  setNames = variantSetNameList.GetPrependedItems();
396  if (!setNames.empty()) {
397  Sdf_FileIOUtility::Puts(out, indent+1, "prepend variantSets = ");
398  Sdf_FileIOUtility::WriteNameVector(out, indent+1, setNames);
399  Sdf_FileIOUtility::Puts(out, 0, "\n");
400  }
401  setNames = variantSetNameList.GetAppendedItems();
402  if (!setNames.empty()) {
403  Sdf_FileIOUtility::Puts(out, indent+1, "append variantSets = ");
404  Sdf_FileIOUtility::WriteNameVector(out, indent+1, setNames);
405  Sdf_FileIOUtility::Puts(out, 0, "\n");
406  }
407  setNames = variantSetNameList.GetOrderedItems();
408  if (!setNames.empty()) {
409  Sdf_FileIOUtility::Puts(out, indent+1, "reorder variantSets = ");
410  Sdf_FileIOUtility::WriteNameVector(out, indent+1, setNames);
411  Sdf_FileIOUtility::Puts(out, 0, "\n");
412  }
413  }
414  }
415  else if (field == SdfFieldKeys->InheritPaths) {
416  const VtValue v = prim.GetField(field);
417  if (!Sdf_WriteIfListOp<SdfPathListOp>(
418  out, indent+1, TfToken("inherits"), v)) {
420  "'%s' field holding unexpected type '%s'",
421  field.GetText(), v.GetTypeName().c_str());
422  }
423  }
424  else if (field == SdfFieldKeys->Specializes) {
425  const VtValue v = prim.GetField(field);
426  if (!Sdf_WriteIfListOp<SdfPathListOp>(
427  out, indent+1, TfToken("specializes"), v)) {
429  "'%s' field holding unexpected type '%s'",
430  field.GetText(), v.GetTypeName().c_str());
431  }
432  }
433  else if (field == SdfFieldKeys->Relocates) {
434 
435  // Relativize all paths in the relocates.
436  SdfRelocatesMap result;
437  SdfPath primPath = prim.GetPath();
438 
439  SdfRelocatesMap finalRelocates;
440  const SdfRelocatesMapProxy relocates = prim.GetRelocates();
441  TF_FOR_ALL(mapIt, relocates) {
442  finalRelocates[mapIt->first.MakeRelativePath(primPath)] =
443  mapIt->second.MakeRelativePath(primPath);
444  }
445 
446  Sdf_FileIOUtility::WriteRelocates(
447  out, indent+1, multiLine, finalRelocates);
448  }
449  else if (field == SdfFieldKeys->PrefixSubstitutions) {
450  VtDictionary prefixSubstitutions = prim.GetPrefixSubstitutions();
451  Sdf_FileIOUtility::Puts(out, indent+1, "prefixSubstitutions = ");
452  Sdf_FileIOUtility::WriteDictionary(out, indent+1, multiLine,
453  prefixSubstitutions, /* stringValuesOnly = */ true );
454  }
455  else if (field == SdfFieldKeys->SuffixSubstitutions) {
456  VtDictionary suffixSubstitutions = prim.GetSuffixSubstitutions();
457  Sdf_FileIOUtility::Puts(out, indent+1, "suffixSubstitutions = ");
458  Sdf_FileIOUtility::WriteDictionary(out, indent+1, multiLine,
459  suffixSubstitutions, /* stringValuesOnly = */ true );
460  }
461  else if (field == SdfFieldKeys->VariantSelection) {
462  SdfVariantSelectionMap refVariants = prim.GetVariantSelections();
463  if (refVariants.size() > 0) {
464  VtDictionary dictionary;
465  TF_FOR_ALL(it, refVariants) {
466  dictionary[it->first] = VtValue(it->second);
467  }
468  Sdf_FileIOUtility::Puts(out, indent+1, "variants = ");
469  Sdf_FileIOUtility::WriteDictionary(out, indent+1, multiLine, dictionary);
470  }
471  }
472  else {
473  Sdf_WriteSimpleField(out, indent+1, prim, field);
474  }
475 
476  } // end for each field
477 
478  Sdf_FileIOUtility::CloseParensIfNeeded(out, indent, didParens, multiLine);
479 
480  return true;
481 }
482 
483 namespace {
484 struct _SortByNameThenType {
485  template <class T>
486  bool operator()(T const &lhs, T const &rhs) const {
487  // If the names are identical, order by spectype. This puts Attributes
488  // before Relationships (if identically named).
489  std::string const &lhsName = lhs->GetName();
490  std::string const &rhsName = rhs->GetName();
491  return (lhsName == rhsName && lhs->GetSpecType() < rhs->GetSpecType())
492  || TfDictionaryLessThan()(lhsName, rhsName);
493  }
494 };
495 }
496 
497 static bool
498 Sdf_WritePrimProperties(
499  const SdfPrimSpec &prim, std::ostream &out, size_t indent)
500 {
501  std::vector<SdfPropertySpecHandle> properties =
502  prim.GetProperties().values_as<std::vector<SdfPropertySpecHandle> >();
503  std::sort(properties.begin(), properties.end(), _SortByNameThenType());
504  TF_FOR_ALL(it, properties) {
505  (*it)->WriteToStream(out, indent+1);
506  }
507 
508  return true;
509 }
510 
511 static bool
512 Sdf_WritePrimNamespaceReorders(
513  const SdfPrimSpec &prim, std::ostream &out, size_t indent)
514 {
515  const std::vector<TfToken>& propertyNames = prim.GetPropertyOrder();
516 
517  if ( propertyNames.size() > 1 ) {
518  Sdf_FileIOUtility::Puts( out, indent+1, "reorder properties = " );
519  Sdf_FileIOUtility::WriteNameVector( out, indent+1, propertyNames );
520  Sdf_FileIOUtility::Puts( out, 0, "\n" );
521  }
522 
523  const std::vector<TfToken>& childrenNames = prim.GetNameChildrenOrder();
524 
525  if ( childrenNames.size() > 1 ) {
526 
527  Sdf_FileIOUtility::Puts( out, indent+1, "reorder nameChildren = " );
528  Sdf_FileIOUtility::WriteNameVector( out, indent+1, childrenNames );
529  Sdf_FileIOUtility::Puts( out, 0, "\n" );
530  }
531 
532  return true;
533 }
534 
535 static bool
536 Sdf_WritePrimChildren(
537  const SdfPrimSpec &prim, std::ostream &out, size_t indent)
538 {
539  bool newline = false;
540  TF_FOR_ALL(i, prim.GetNameChildren()) {
541  if (newline)
542  Sdf_FileIOUtility::Puts(out, 0, "\n");
543  else
544  newline = true;
545  (*i)->WriteToStream(out, indent+1);
546  }
547 
548  return true;
549 }
550 
551 static bool
552 Sdf_WritePrimVariantSets(
553  const SdfPrimSpec &prim, std::ostream &out, size_t indent)
554 {
555  SdfVariantSetsProxy variantSets = prim.GetVariantSets();
556  if (variantSets) {
557  TF_FOR_ALL(it, variantSets) {
558  SdfVariantSetSpecHandle variantSet = it->second;
559  variantSet->WriteToStream(out, indent+1);
560  }
561  }
562  return true;
563 }
564 
565 static bool
566 Sdf_WritePrimBody(
567  const SdfPrimSpec &prim, std::ostream &out, size_t indent)
568 {
569  Sdf_WritePrimNamespaceReorders( prim, out, indent );
570 
571  Sdf_WritePrimProperties( prim, out, indent );
572 
573  if (!prim.GetProperties().empty() && !prim.GetNameChildren().empty())
574  Sdf_FileIOUtility::Puts(out, 0, "\n");
575 
576  Sdf_WritePrimChildren( prim, out, indent );
577 
578  Sdf_WritePrimVariantSets( prim, out, indent );
579 
580  return true;
581 }
582 
583 static inline bool
584 Sdf_WritePrim(
585  const SdfPrimSpec &prim, std::ostream &out, size_t indent)
586 {
587  Sdf_WritePrimPreamble( prim, out, indent );
588  Sdf_WritePrimMetadata( prim, out, indent );
589 
590  Sdf_FileIOUtility::Puts(out, 0, "\n");
591  Sdf_FileIOUtility::Puts(out, indent, "{\n");
592 
593  Sdf_WritePrimBody( prim, out, indent );
594 
595  Sdf_FileIOUtility::Puts(out, indent, "}\n");
596 
597  return true;
598 }
599 
600 static bool
601 Sdf_WriteConnectionStatement(
602  std::ostream &out,
603  size_t indent, const SdfConnectionsProxy::ListProxy &connections,
604  const std::string &opStr,
605  const std::string &variabilityStr,
606  const std::string &typeStr, const std::string &nameStr,
607  const SdfAttributeSpec* attrOwner)
608 {
609  Sdf_FileIOUtility::Write(out, indent, "%s%s%s %s.connect = ",
610  opStr.c_str(),
611  variabilityStr.c_str(),
612  typeStr.c_str(), nameStr.c_str());
613 
614  if (connections.size() == 0) {
615  Sdf_FileIOUtility::Puts(out, 0, "None\n");
616  }
617  else if (connections.size() == 1) {
618  Sdf_FileIOUtility::WriteSdfPath(out, 0, connections.front());
619  Sdf_FileIOUtility::Puts(out, 0, "\n");
620  }
621  else {
622  Sdf_FileIOUtility::Puts(out, 0, "[\n");
623  TF_FOR_ALL(it, connections) {
624  Sdf_FileIOUtility::WriteSdfPath(out, indent+1, (*it));
625  Sdf_FileIOUtility::Puts(out, 0, ",\n");
626  }
627  Sdf_FileIOUtility::Puts(out, indent, "]\n");
628  }
629  return true;
630 }
631 
632 static bool
633 Sdf_WriteConnectionList(
634  std::ostream &out,
635  size_t indent, const SdfConnectionsProxy &connList,
636  const std::string &variabilityStr,
637  const std::string &typeStr, const std::string &nameStr,
638  const SdfAttributeSpec *attrOwner)
639 {
640  if (connList.IsExplicit()) {
642  Sdf_WriteConnectionStatement(out, indent, vec, "",
643  variabilityStr,
644  typeStr, nameStr, attrOwner);
645  } else {
647  if (!vec.empty()) {
648  Sdf_WriteConnectionStatement(out, indent, vec, "delete ",
649  variabilityStr, typeStr, nameStr,
650  NULL);
651  }
652  vec = connList.GetAddedItems();
653  if (!vec.empty()) {
654  Sdf_WriteConnectionStatement(out, indent, vec, "add ",
655  variabilityStr, typeStr,
656  nameStr, attrOwner);
657  }
658  vec = connList.GetPrependedItems();
659  if (!vec.empty()) {
660  Sdf_WriteConnectionStatement(out, indent, vec, "prepend ",
661  variabilityStr, typeStr,
662  nameStr, attrOwner);
663  }
664  vec = connList.GetAppendedItems();
665  if (!vec.empty()) {
666  Sdf_WriteConnectionStatement(out, indent, vec, "append ",
667  variabilityStr, typeStr,
668  nameStr, attrOwner);
669  }
670  vec = connList.GetOrderedItems();
671  if (!vec.empty()) {
672  Sdf_WriteConnectionStatement(out, indent, vec, "reorder ",
673  variabilityStr, typeStr, nameStr,
674  NULL);
675  }
676  }
677  return true;
678 }
679 
680 // Predicate for determining fields that should be included in an
681 // attribute's metadata section.
682 struct Sdf_IsAttributeMetadataField : public Sdf_IsMetadataField
683 {
684  Sdf_IsAttributeMetadataField() : Sdf_IsMetadataField(SdfSpecTypeAttribute)
685  { }
686 
687  bool operator()(const TfToken& field) const
688  {
689  return (Sdf_IsMetadataField::operator()(field) ||
690  field == SdfFieldKeys->DisplayUnit);
691  }
692 };
693 
694 static inline bool
695 Sdf_WriteAttribute(
696  const SdfAttributeSpec &attr, std::ostream &out, size_t indent)
697 {
698  std::string variabilityStr =
699  Sdf_FileIOUtility::Stringify( attr.GetVariability() );
700  if (!variabilityStr.empty())
701  variabilityStr += ' ';
702 
703  bool hasComment = !attr.GetComment().empty();
704  bool hasDefault = attr.HasField(SdfFieldKeys->Default);
705  bool hasCustomDeclaration = attr.IsCustom();
706  bool hasConnections = attr.HasField(SdfFieldKeys->ConnectionPaths);
707  bool hasTimeSamples = attr.HasField(SdfFieldKeys->TimeSamples);
708 
709  std::string typeName =
710  SdfValueTypeNames->GetSerializationName(attr.GetTypeName()).GetString();
711 
712  // Partition this attribute's fields so that all fields to write in the
713  // metadata section are in the range [fields.begin(), metadataFieldsEnd).
714  TfTokenVector fields = attr.ListFields();
715  TfTokenVector::iterator metadataFieldsEnd = std::partition(
716  fields.begin(), fields.end(), Sdf_IsAttributeMetadataField());
717 
718  // As long as there's anything to write in the metadata section, we'll
719  // always use the multi-line format.
720  bool hasInfo = hasComment || (fields.begin() != metadataFieldsEnd);
721  bool multiLine = hasInfo;
722 
723  bool didParens = false;
724 
725  // Write the basic line if we have info or a default or if we
726  // have nothing else to write.
727  if (hasInfo || hasDefault || hasCustomDeclaration ||
728  (!hasConnections && !hasTimeSamples))
729  {
730  VtValue value;
731 
732  if(hasDefault)
733  value = attr.GetDefaultValue();
734 
735  Sdf_FileIOUtility::Write( out, indent, "%s%s%s %s",
736  (hasCustomDeclaration ? "custom " : ""),
737  variabilityStr.c_str(),
738  typeName.c_str(),
739  attr.GetName().c_str() );
740 
741  // If we have a default value, write it...
742  if (!value.IsEmpty()) {
743  Sdf_FileIOUtility::WriteDefaultValue(out, indent, value);
744  }
745 
746  // Write comment at the top of the metadata section for readability.
747  if (hasComment) {
748  didParens = Sdf_FileIOUtility::OpenParensIfNeeded(out, didParens, multiLine);
749  Sdf_FileIOUtility::WriteQuotedString(out, indent+1, attr.GetComment());
750  Sdf_FileIOUtility::Puts(out, 0, "\n");
751  }
752 
753  // Write out remaining fields in the metadata section in
754  // dictionary-sorted order.
755  std::sort(fields.begin(), metadataFieldsEnd, TfDictionaryLessThan());
756  for (TfTokenVector::const_iterator fieldIt = fields.begin();
757  fieldIt != metadataFieldsEnd; ++fieldIt) {
758 
759  didParens =
760  Sdf_FileIOUtility::OpenParensIfNeeded(out, didParens, multiLine);
761 
762  const TfToken& field = *fieldIt;
763 
764  if (field == SdfFieldKeys->Documentation) {
765  Sdf_FileIOUtility::Puts(out, indent+1, "doc = ");
766  Sdf_FileIOUtility::WriteQuotedString(out, 0, attr.GetDocumentation());
767  Sdf_FileIOUtility::Puts(out, 0, "\n");
768  }
769  else if (field == SdfFieldKeys->Permission) {
770  Sdf_FileIOUtility::Write(out, multiLine ? indent+1 : 0, "permission = %s%s",
771  Sdf_FileIOUtility::Stringify(attr.GetPermission()),
772  multiLine ? "\n" : "");
773  }
774  else if (field == SdfFieldKeys->SymmetryFunction) {
775  Sdf_FileIOUtility::Write(out, multiLine ? indent+1 : 0, "symmetryFunction = %s%s",
776  attr.GetSymmetryFunction().GetText(),
777  multiLine ? "\n" : "");
778  }
779  else if (field == SdfFieldKeys->DisplayUnit) {
780  Sdf_FileIOUtility::Write(out, multiLine ? indent+1 : 0, "displayUnit = %s%s",
781  SdfGetNameForUnit(attr.GetDisplayUnit()).c_str(),
782  multiLine ? "\n" : "");
783  }
784  else {
785  Sdf_WriteSimpleField(out, indent+1, attr, field);
786  }
787 
788  } // end for each field
789 
790  Sdf_FileIOUtility::CloseParensIfNeeded(out, indent, didParens, multiLine);
791  Sdf_FileIOUtility::Puts(out, 0, "\n");
792  }
793 
794  if (hasTimeSamples) {
795  Sdf_FileIOUtility::Write(out, indent, "%s%s %s.timeSamples = {\n",
796  variabilityStr.c_str(),
797  typeName.c_str(), attr.GetName().c_str() );
798  Sdf_FileIOUtility::WriteTimeSamples(out, indent, attr);
799  Sdf_FileIOUtility::Puts(out, indent, "}\n");
800  }
801 
802  if (hasConnections) {
803  Sdf_WriteConnectionList(out, indent, attr.GetConnectionPathList(),
804  variabilityStr, typeName,
805  attr.GetName(), &attr);
806  }
807 
808  return true;
809 }
810 
811 enum Sdf_WriteFlag {
812  Sdf_WriteFlagDefault = 0,
813  Sdf_WriteFlagAttributes = 1,
814  Sdf_WriteFlagNoLastNewline = 2,
815 };
816 
817 inline Sdf_WriteFlag operator |(Sdf_WriteFlag a, Sdf_WriteFlag b)
818 {
819  return (Sdf_WriteFlag)(static_cast<int>(a) | static_cast<int>(b));
820 }
821 
822 static bool
823 Sdf_WriteRelationshipTargetList(
824  const SdfRelationshipSpec &rel,
825  const SdfTargetsProxy::ListProxy &targetPaths,
826  std::ostream &out, size_t indent, Sdf_WriteFlag flags)
827 {
828  if (targetPaths.size() > 1) {
829  Sdf_FileIOUtility::Write(out, 0," = [\n");
830  ++indent;
831  } else {
832  Sdf_FileIOUtility::Write(out, 0," = ");
833  }
834 
835  for (size_t i=0; i < targetPaths.size(); ++i) {
836  if (targetPaths.size() > 1) {
837  Sdf_FileIOUtility::Write(out, indent, "");
838  }
839  Sdf_FileIOUtility::WriteSdfPath( out, 0, targetPaths[i] );
840  if (targetPaths.size() > 1) {
841  Sdf_FileIOUtility::Write(out, 0,",\n");
842  }
843  }
844 
845  if (targetPaths.size() > 1) {
846  --indent;
847  Sdf_FileIOUtility::Write(out, indent, "]");
848  }
849  if (!(flags & Sdf_WriteFlagNoLastNewline)) {
850  Sdf_FileIOUtility::Write(out, 0,"\n");
851  }
852  return true;
853 }
854 
855 // Predicate for determining fields that should be included in an
856 // relationship's metadata section.
857 struct Sdf_IsRelationshipMetadataField : public Sdf_IsMetadataField
858 {
859  Sdf_IsRelationshipMetadataField()
860  : Sdf_IsMetadataField(SdfSpecTypeRelationship) { }
861 
862  bool operator()(const TfToken& field) const
863  {
864  return Sdf_IsMetadataField::operator()(field);
865  }
866 };
867 
868 static inline bool
869 Sdf_WriteRelationship(
870  const SdfRelationshipSpec &rel, std::ostream &out, size_t indent)
871 {
872  // When a new metadata field is added to the spec, it will be automatically
873  // written out generically, so you probably don't need to add a special case
874  // here. If you need to special-case the output of a metadata field, you will
875  // also need to prevent the automatic output by adding the token inside
876  // Sdf_GetGenericRelationshipMetadataFields().
877  //
878  // These special cases below were all kept to prevent reordering in existing
879  // menva files, which would create noise in file diffs.
880  bool hasComment = !rel.GetComment().empty();
881  bool hasTargets = rel.HasField(SdfFieldKeys->TargetPaths);
882  bool hasDefaultValue = rel.HasField(SdfFieldKeys->Default);
883  bool hasTimeSamples = rel.HasField(SdfFieldKeys->TimeSamples);
884 
885  bool hasCustom = rel.IsCustom();
886 
887  // Partition this attribute's fields so that all fields to write in the
888  // metadata section are in the range [fields.begin(), metadataFieldsEnd).
889  TfTokenVector fields = rel.ListFields();
890  TfTokenVector::iterator metadataFieldsEnd = std::partition(
891  fields.begin(), fields.end(), Sdf_IsRelationshipMetadataField());
892 
893  bool hasInfo = hasComment || (fields.begin() != metadataFieldsEnd);
894  bool multiLine = hasInfo;
895 
896  bool didParens = false;
897 
898  bool hasExplicitTargets = false;
899  bool hasTargetListOps = false;
900  if (hasTargets) {
901  SdfTargetsProxy targetPathList = rel.GetTargetPathList();
902  hasExplicitTargets = targetPathList.IsExplicit() &&
903  targetPathList.HasKeys();
904  hasTargetListOps = !targetPathList.IsExplicit() &&
905  targetPathList.HasKeys();
906  }
907 
908  // If relationship is a varying relationship, use varying keyword.
909  bool isVarying = (rel.GetVariability() == SdfVariabilityVarying);
910  std::string varyingStr = isVarying ? "varying " : ""; // the space in "varying " is required...
911 
912 
913  // Write the basic line if we have info or a default (i.e. explicit
914  // targets) or if we have nothing else to write and we're not custom
915  if (hasInfo || (hasTargets && hasExplicitTargets) ||
916  (!hasTargetListOps && !rel.IsCustom()))
917  {
918 
919  if (hasCustom) {
920  Sdf_FileIOUtility::Write( out, indent, "custom %srel %s",
921  varyingStr.c_str(),
922  rel.GetName().c_str() );
923  } else {
924  Sdf_FileIOUtility::Write( out, indent, "%srel %s",
925  varyingStr.c_str(),
926  rel.GetName().c_str() );
927  }
928 
929  if (hasTargets && hasExplicitTargets) {
930  SdfTargetsProxy targetPathList = rel.GetTargetPathList();
931  SdfTargetsProxy::ListProxy targetPaths = targetPathList.GetExplicitItems();
932  if (targetPaths.size() == 0) {
933  Sdf_FileIOUtility::Write(out, 0, " = None");
934  } else {
935  // Write explicit targets
936  Sdf_WriteRelationshipTargetList(rel, targetPaths, out, indent,
937  Sdf_WriteFlagAttributes | Sdf_WriteFlagNoLastNewline);
938  }
939  }
940 
941  // Write comment at the top of the metadata section for readability.
942  if (hasComment) {
943  didParens = Sdf_FileIOUtility::OpenParensIfNeeded(out, didParens, multiLine);
944  Sdf_FileIOUtility::WriteQuotedString(out, indent+1, rel.GetComment());
945  Sdf_FileIOUtility::Write(out, 0, "\n");
946  }
947 
948  // Write out remaining fields in the metadata section in
949  // dictionary-sorted order.
950  std::sort(fields.begin(), metadataFieldsEnd, TfDictionaryLessThan());
951  for (TfTokenVector::const_iterator fieldIt = fields.begin();
952  fieldIt != metadataFieldsEnd; ++fieldIt) {
953 
954  didParens =
955  Sdf_FileIOUtility::OpenParensIfNeeded(out, didParens, multiLine);
956 
957  const TfToken& field = *fieldIt;
958 
959  if (field == SdfFieldKeys->Documentation) {
960  Sdf_FileIOUtility::Write(out, indent+1, "doc = ");
961  Sdf_FileIOUtility::WriteQuotedString(out, 0, rel.GetDocumentation());
962  Sdf_FileIOUtility::Write(out, 0, "\n");
963  }
964  else if (field == SdfFieldKeys->Permission) {
965  if (multiLine) {
966  Sdf_FileIOUtility::Write(out, indent+1, "permission = %s\n",
967  Sdf_FileIOUtility::Stringify(rel.GetPermission()));
968  } else {
969  Sdf_FileIOUtility::Write(out, 0, "permission = %s",
970  Sdf_FileIOUtility::Stringify(rel.GetPermission()));
971  }
972  }
973  else if (field == SdfFieldKeys->SymmetryFunction) {
974  Sdf_FileIOUtility::Write(out, multiLine ? indent+1 : 0, "symmetryFunction = %s%s",
976  multiLine ? "\n" : "");
977  }
978  else {
979  Sdf_WriteSimpleField(out, indent+1, rel, field);
980  }
981 
982  } // end for each field
983 
984  Sdf_FileIOUtility::CloseParensIfNeeded(out, indent, didParens, multiLine);
985  Sdf_FileIOUtility::Write(out, 0,"\n");
986  }
987  else if (hasCustom) {
988  // If we did not write out the "basic" line AND we are custom,
989  // we need to add a custom decl line, because we won't include
990  // custom in any of the output below
991  Sdf_FileIOUtility::Write( out, indent, "custom %srel %s\n",
992  varyingStr.c_str(),
993  rel.GetName().c_str() );
994  }
995 
996  if (hasTargets && hasTargetListOps) {
997  // Write deleted targets
998  SdfTargetsProxy targetPathList = rel.GetTargetPathList();
999  SdfTargetsProxy::ListProxy targetPaths = targetPathList.GetDeletedItems();
1000  if (!targetPaths.empty()) {
1001  Sdf_FileIOUtility::Write( out, indent, "delete %srel %s",
1002  varyingStr.c_str(), rel.GetName().c_str());
1003  Sdf_WriteRelationshipTargetList(rel, targetPaths, out, indent, Sdf_WriteFlagDefault);
1004  }
1005 
1006  // Write added targets
1007  targetPaths = targetPathList.GetAddedItems();
1008  if (!targetPaths.empty()) {
1009  Sdf_FileIOUtility::Write( out, indent, "add %srel %s",
1010  varyingStr.c_str(), rel.GetName().c_str());
1011  Sdf_WriteRelationshipTargetList(rel, targetPaths, out, indent, Sdf_WriteFlagAttributes);
1012  }
1013  targetPaths = targetPathList.GetPrependedItems();
1014  if (!targetPaths.empty()) {
1015  Sdf_FileIOUtility::Write( out, indent, "prepend %srel %s",
1016  varyingStr.c_str(), rel.GetName().c_str());
1017  Sdf_WriteRelationshipTargetList(rel, targetPaths, out, indent, Sdf_WriteFlagAttributes);
1018  }
1019  targetPaths = targetPathList.GetAppendedItems();
1020  if (!targetPaths.empty()) {
1021  Sdf_FileIOUtility::Write( out, indent, "append %srel %s",
1022  varyingStr.c_str(), rel.GetName().c_str());
1023  Sdf_WriteRelationshipTargetList(rel, targetPaths, out, indent, Sdf_WriteFlagAttributes);
1024  }
1025 
1026  // Write ordered targets
1027  targetPaths = targetPathList.GetOrderedItems();
1028  if (!targetPaths.empty()) {
1029  Sdf_FileIOUtility::Write( out, indent, "reorder %srel %s",
1030  varyingStr.c_str(), rel.GetName().c_str());
1031  Sdf_WriteRelationshipTargetList(rel, targetPaths, out, indent, Sdf_WriteFlagDefault);
1032  }
1033  }
1034 
1035  if (hasTimeSamples) {
1036  Sdf_FileIOUtility::Write(out, indent, "%srel %s.timeSamples = {\n",
1037  varyingStr.c_str(),
1038  rel.GetName().c_str());
1039  Sdf_FileIOUtility::WriteTimeSamples(out, indent, rel);
1040  Sdf_FileIOUtility::Puts(out, indent, "}\n");
1041  }
1042 
1043  // Write out the default value for the relationship if we have one...
1044  if (hasDefaultValue)
1045  {
1046  VtValue value = rel.GetDefaultValue();
1047  if (!value.IsEmpty())
1048  {
1049  Sdf_FileIOUtility::Write(out, indent, "%srel %s.default = ",
1050  varyingStr.c_str(),
1051  rel.GetName().c_str());
1052  Sdf_FileIOUtility::WriteDefaultValue(out, 0, value);
1053  Sdf_FileIOUtility::Puts(out, indent, "\n");
1054  }
1055  }
1056 
1057  return true;
1058 }
1059 
1060 PXR_NAMESPACE_CLOSE_SCOPE
1061 
1062 #endif // SDF_FILEIO_COMMON_H
ListProxy GetDeletedItems() const
Returns the items deleted by this list editor.
SDF_API TfToken GetSymmetryFunction() const
Returns the property&#39;s symmetry function.
SDF_API std::string GetComment() const
Returns the comment string for this property spec.
ListProxy GetOrderedItems() const
Returns the items reordered by this list editor.
T const & UncheckedGet() const
Returns a const reference to the held object if the held object is of type T.
Definition: value.h:836
std::map< std::string, std::string > SdfVariantSelectionMap
A map of reference variant set names to variants in those sets.
Definition: types.h:268
Provides dictionary ordering binary predicate function on strings.
Definition: stringUtils.h:500
Base class for SdfAttributeSpec and SdfRelationshipSpec.
Definition: propertySpec.h:59
SDF_API SdfTargetsProxy GetTargetPathList() const
Returns the relationship&#39;s target path list editor.
ListProxy GetAppendedItems() const
Returns the items appended by this list editor.
SDF_API SdfPath GetPath() const
Returns the scene path of this object.
bool SdfIsDefiningSpecifier(SdfSpecifier spec)
Returns true if the specifier defines a prim.
Definition: types.h:133
Represents a set of list editing operations.
SDF_API TfEnum GetDisplayUnit() const
Returns the display unit of the attribute.
SDF_API bool IsCustom() const
Returns true if this spec declares a custom property.
SDF_API SdfPermission GetPermission() const
Returns the property&#39;s permission restriction.
A map with string keys and VtValue values.
Definition: dictionary.h:61
reference front()
Return a reference to the item at the front of the sequence.
Definition: listProxy.h:279
SDF_API SdfConnectionsProxy GetConnectionPathList() const
Returns a proxy for editing the attribute&#39;s connection paths.
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
Definition: diagnostic.h:87
bool IsExplicit() const
Returns true if the editor has an explicit list, false if it has list operations. ...
Base class for all Sdf spec classes.
Definition: spec.h:51
bool IsHolding() const
Return true if this value is holding an object of type T, false otherwise.
Definition: value.h:808
SDF_API SdfVariantSelectionProxy GetVariantSelections() const
Returns an editable map whose keys are variant set names and whose values are the variants selected f...
SDF_API std::string GetDocumentation() const
Returns the documentation string for this property spec.
SdfSpecType
An enum that specifies the type of an object.
Definition: types.h:91
SDF_API std::string GetDocumentation() const
Returns the documentation string for this prim spec.
bool HasKeys() const
Returns true if the editor has an explicit list (even if it&#39;s empty) or it has any added...
SDF_API VtValue GetField(const TfToken &name) const
Returns a field value by name.
T const & Get() const
Returns a const reference to the held object if the held object is of type T.
Definition: value.h:847
SDF_API VtDictionary GetSuffixSubstitutions() const
Returns the suffixSubstitutions dictionary for this prim spec.
SDF_API TfToken GetTypeName() const
Returns the typeName of the model prim.
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:89
Stores a representation of the value for an unregistered metadata field encountered during text layer...
Definition: types.h:453
SdfSpecifier
An enum that identifies the possible specifiers for an SdfPrimSpec.
Definition: types.h:123
SDF_API SdfRelocatesMapProxy GetRelocates() const
Get an editing proxy for the map of namespace relocations specified on this prim. ...
SDF_API SdfVariantSetsProxy GetVariantSets() const
Returns the variant sets.
A subclass of SdfPropertySpec that holds typed data.
Definition: attributeSpec.h:56
#define TF_FOR_ALL(iter, c)
Macro for iterating over a container.
Definition: iterator.h:390
Represents a single list of list editing operations.
Definition: listProxy.h:57
SDF_API PropertySpecView GetProperties() const
Returns the prim&#39;s properties.
SDF_API std::vector< TfToken > ListFields() const
Returns all fields with values.
ListProxy GetAddedItems() const
Returns the items added by this list editor.
SDF_API SdfNameChildrenOrderProxy GetNameChildrenOrder() const
Returns the list of child names for this prim&#39;s reorder.
SdfVariability
An enum that identifies variability types for attributes.
Definition: types.h:182
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:438
A proxy for editing map-like values.
Definition: mapEditProxy.h:120
Class representing fields and other information for a spec type.
Definition: schema.h:177
Value type representing a list-edit operation.
Definition: listOp.h:75
SDF_API SdfPermission GetPermission() const
Returns the prim&#39;s permission restriction.
SDF_API const std::string & SdfGetNameForUnit(const TfEnum &unit)
Gets the name for a given /a unit.
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:287
SDF_API NameChildrenView GetNameChildren() const
Returns a keyed vector view of the prim&#39;s namespace children.
VT_API std::string GetTypeName() const
Return the type name of the held typeid.
SDF_API const std::string & GetName() const
Returns the prim&#39;s name.
bool empty() const
Returns true if the vector is empty.
Definition: childrenView.h:322
V values_as() const
Returns the elements, in order.
Definition: childrenView.h:379
ListProxy GetPrependedItems() const
Returns the items prepended by this list editor.
SDF_API VtDictionary GetPrefixSubstitutions() const
Returns the prefixSubstitutions dictionary for this prim spec.
bool empty() const
Return true if size() == 0.
Definition: listProxy.h:264
SDF_API SdfSpecifier GetSpecifier() const
Returns the spec specifier (def, over or class).
Represents a prim description in an SdfLayer object.
Definition: primSpec.h:74
A property that contains a reference to one or more SdfPrimSpec instances.
ListProxy GetExplicitItems() const
Returns the explicitly set items.
SDF_API SdfPropertyOrderProxy GetPropertyOrder() const
Returns the list of property names for this prim&#39;s reorder properties statement.
SDF_API SdfVariability GetVariability() const
Returns the variability of the property.
bool IsEmpty() const
Returns true iff this token contains the empty string &quot;&quot;.
Definition: token.h:311
SDF_API SdfValueTypeName GetTypeName() const
Returns the name of the value type that this property holds.
SDF_API std::string GetComment() const
Returns the comment string for this prim spec.
std::map< SdfPath, SdfPath > SdfRelocatesMap
A map of source SdfPaths to target SdfPaths for relocation.
Definition: types.h:277
SDF_API VtValue GetDefaultValue() const
Returns the attribute&#39;s default value.
SDF_API SdfVariantSetNamesProxy GetVariantSetNameList() const
Returns a proxy for the prim&#39;s variant sets.
Represents a time offset and scale between layers.
Definition: layerOffset.h:61
std::enable_if<!std::is_enum< T >::value, std::string >::type TfStringify(const T &v)
Convert an arbitrary type into a string.
Definition: stringUtils.h:523
SdfPermission
An enum that defines permission levels.
Definition: types.h:155
Class that provides information about the various scene description fields.
Definition: schema.h:532
SDF_API bool HasField(const TfToken &name) const
Returns true if the spec has a non-empty value with field name name.
size_t size() const
Return the size of the sequence.
Definition: listProxy.h:259
SDF_API const std::string & GetName() const
Returns the property&#39;s name.
bool IsEmpty() const
Returns true iff this value is empty.
Definition: value.h:990
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Definition: value.h:182
SDF_API TfToken GetSymmetryFunction() const
Returns the symmetry function for this prim.
char const * GetText() const
Return the text that this token represents.
Definition: token.h:198