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 PXR_USD_SDF_LAYER_H
25 #define PXR_USD_SDF_LAYER_H
26 
27 /// \file sdf/layer.h
28 
29 #include "pxr/pxr.h"
30 #include "pxr/usd/sdf/api.h"
31 #include "pxr/usd/sdf/data.h"
32 #include "pxr/usd/sdf/declareHandles.h"
33 #include "pxr/usd/sdf/identity.h"
34 #include "pxr/usd/sdf/layerHints.h"
35 #include "pxr/usd/sdf/layerOffset.h"
36 #include "pxr/usd/sdf/namespaceEdit.h"
37 #include "pxr/usd/sdf/path.h"
38 #include "pxr/usd/sdf/proxyTypes.h"
39 #include "pxr/usd/sdf/spec.h"
40 #include "pxr/usd/sdf/types.h"
41 #include "pxr/usd/ar/ar.h"
42 #include "pxr/usd/ar/assetInfo.h"
43 #include "pxr/usd/ar/resolvedPath.h"
44 #include "pxr/base/tf/declarePtrs.h"
45 #include "pxr/base/vt/value.h"
46 
47 #include <boost/optional.hpp>
48 
49 #include <atomic>
50 #include <functional>
51 #include <memory>
52 #include <set>
53 #include <string>
54 #include <vector>
55 
56 PXR_NAMESPACE_OPEN_SCOPE
57 
58 TF_DECLARE_WEAK_PTRS(SdfFileFormat);
59 TF_DECLARE_WEAK_AND_REF_PTRS(SdfLayerStateDelegateBase);
60 
61 struct Sdf_AssetInfo;
62 
63 /// \class SdfLayer
64 ///
65 /// A unit of scene description that you combine with other units of scene
66 /// description to form a shot, model, set, shader, and so on.
67 ///
68 /// SdfLayer objects provide a persistent way to store layers on the
69 /// filesystem in .menva files.  Currently the supported file format is
70 /// <c>.menva</c>, the ASCII file format.
71 ///
72 /// The FindOrOpen() method returns a new SdfLayer object with scene description
73 /// from a <c>.menva</c> file. Once read, a layer remembers which asset it was
74 /// read from. The Save() method saves the layer back out to the original file.
75 /// You can use the Export() method to write the layer to a different
76 /// location. You can use the GetIdentifier() method to get the layer's Id or
77 /// GetRealPath() to get the resolved, full file path.
78 ///
79 /// Layers can have a timeCode range (startTimeCode and endTimeCode). This range
80 /// represents the suggested playback range, but has no impact on the extent of
81 /// the animation data that may be stored in the layer. The metadatum
82 /// "timeCodesPerSecond" is used to annotate how the time ordinate for samples
83 /// contained in the file scales to seconds. For example, if timeCodesPerSecond
84 /// is 24, then a sample at time ordinate 24 should be viewed exactly one second
85 /// after the sample at time ordinate 0.
86 ///
87 /// Compared to Menv2x, layers are most closely analogous to
88 /// hooksets, <c>.hook</c> files, and <c>.cue</c> files.
89 ///
90 /// \todo
91 /// \li Insert a discussion of subLayers semantics here.
92 ///
93 /// \todo
94 /// \li Should have validate... methods for rootPrims
95 ///
96 class SdfLayer
97     : public TfRefBase
98     , public TfWeakBase
99 {
100 public:
101     /// Destructor
102     SDF_API
103     virtual ~SdfLayer();
104 
105     /// Noncopyable
106     SdfLayer(const SdfLayer&) = delete;
107     SdfLayer& operator=(const SdfLayer&) = delete;
108 
109     ///
110     /// \name Primary API
111     /// @{
112 
113     /// Returns the schema this layer adheres to. This schema provides details
114     /// about the scene description that may be authored in this layer.
115     SDF_API const SdfSchemaBase& GetSchema() const;
116 
117     /// Returns the file format used by this layer.
118     SDF_API const SdfFileFormatConstPtr& GetFileFormat() const;
119 
120     /// Type for specifying additional file format-specific arguments to
121     /// layer API.
122     typedef std::map<std::string, std::string> FileFormatArguments;
123 
124     /// Returns the file format-specific arguments used during the construction
125     /// of this layer.
126     SDF_API const FileFormatArguments& GetFileFormatArguments() const;
127 
128     /// Creates a new empty layer with the given identifier.
129     ///
130     /// Additional arguments may be supplied via the \p args parameter.
131     /// These arguments may control behavior specific to the layer's
132     /// file format.
133     SDF_API
134     static SdfLayerRefPtr CreateNew(const std::string &identifier,
135                                     const FileFormatArguments &args =
136                                     FileFormatArguments());
137 
138     /// Creates a new empty layer with the given identifier for a given file
139     /// format class.
140     ///
141     /// This function has the same behavior as the other CreateNew function,
142     /// but uses the explicitly-specified \p fileFormat instead of attempting
143     /// to discern the format from \p identifier.
144     SDF_API
145     static SdfLayerRefPtr CreateNew(const SdfFileFormatConstPtr& fileFormat,
146                                     const std::string &identifier,
147                                     const FileFormatArguments &args =
148                                     FileFormatArguments());
149 
150     /// Creates a new empty layer with the given identifier for a given file
151     /// format class.
152     ///
153     /// The new layer will not be dirty and will not be saved.
154     ///
155     /// Additional arguments may be supplied via the \p args parameter.
156     /// These arguments may control behavior specific to the layer's
157     /// file format.
158     SDF_API
159     static SdfLayerRefPtr New(const SdfFileFormatConstPtr& fileFormat,
160                               const std::string &identifier,
161                               const FileFormatArguments &args =
162                               FileFormatArguments());
163 
164     /// Return an existing layer with the given \p identifier and \p args.  If
165     /// the layer can't be found, an error is posted and a null layer is
166     /// returned.
167     ///
168     /// Arguments in \p args will override any arguments specified in
169     /// \p identifier.
170     SDF_API
171     static SdfLayerHandle Find(
172         const std::string &identifier,
173         const FileFormatArguments &args = FileFormatArguments());
174 
175     /// Return an existing layer with the given \p identifier and \p args.
176     /// The given \p identifier will be resolved relative to the \p anchor
177     /// layer. If the layer can't be found, an error is posted and a null
178     /// layer is returned.
179     ///
180     /// If the \p anchor layer is invalid, a coding error is raised, and a null
181     /// handle is returned.
182     ///
183     /// Arguments in \p args will override any arguments specified in
184     /// \p identifier.
185     SDF_API
186     static SdfLayerHandle FindRelativeToLayer(
187         const SdfLayerHandle &anchor,
188         const std::string &identifier,
189         const FileFormatArguments &args = FileFormatArguments());
190 
191     /// Return an existing layer with the given \p identifier and \p args, or
192     /// else load it. If the layer can't be found or loaded, an error is posted
193     /// and a null layer is returned.
194     ///
195     /// Arguments in \p args will override any arguments specified in
196     /// \p identifier.
197     SDF_API
198     static SdfLayerRefPtr FindOrOpen(
199         const std::string &identifier,
200         const FileFormatArguments &args = FileFormatArguments());
201 
202     /// Return an existing layer with the given \p identifier and \p args, or
203     /// else load it. The given \p identifier will be resolved relative to the
204     /// \p anchor layer. If the layer can't be found or loaded, an error is
205     /// posted and a null layer is returned.
206     ///
207     /// If the \p anchor layer is invalid, issues a coding error and returns
208     /// a null handle.
209     ///
210     /// Arguments in \p args will override any arguments specified in
211     /// \p identifier.
212     SDF_API
213     static SdfLayerRefPtr FindOrOpenRelativeToLayer(
214         const SdfLayerHandle &anchor,
215         const std::string &identifier,
216         const FileFormatArguments &args = FileFormatArguments());
217 
218     /// Load the given layer from disk as a new anonymous layer. If the
219     /// layer can't be found or loaded, an error is posted and a null
220     /// layer is returned.
221     ///
222     /// The anonymous layer does not retain any knowledge of the backing
223     /// file on the filesystem.
224     ///
225     /// \p metadataOnly is a flag that asks for only the layer metadata
226     /// to be read in, which can be much faster if that is all that is
227     /// required.  Note that this is just a hint: some FileFormat readers
228     /// may disregard this flag and still fully populate the layer contents.
229     ///
230     /// An optional \p tag may be specified.  See CreateAnonymous for details.
231     SDF_API
232     static SdfLayerRefPtr OpenAsAnonymous(
233         const std::string &layerPath,
234         bool metadataOnly = false,
235         const std::string& tag = std::string());
236 
237     /// Returns the data from the absolute root path of this layer.
238     SDF_API
239     SdfDataRefPtr GetMetadata() const;
240 
241     /// Return hints about the layer's current contents.  Any operation that
242     /// dirties the layer will invalidate all hints.
243     /// \sa SdfLayerHints
244     SDF_API
245     SdfLayerHints GetHints() const;
246 
247     /// Returns handles for all layers currently held by the layer registry.
248     SDF_API
249     static SdfLayerHandleSet GetLoadedLayers();
250 
251     /// Returns whether this layer has no significant data.
252     SDF_API
253     bool IsEmpty() const;
254 
255     /// Copies the content of the given layer into this layer.
256     /// Source layer is unmodified.
257     SDF_API
258     void TransferContent(const SdfLayerHandle& layer);
259 
260     /// Creates a new \e anonymous layer with an optional \p tag. An anonymous
261     /// layer is a layer with a system assigned identifier, that cannot be
262     /// saved to disk via Save(). Anonymous layers have an identifier, but no
263     /// real path or other asset information fields.
264     ///
265     /// Anonymous layers may be tagged, which can be done to aid debugging
266     /// subsystems that make use of anonymous layers.  The tag becomes the
267     /// display name of an anonymous layer, and is also included in the
268     /// generated identifier. Untagged anonymous layers have an empty display
269     /// name.
270     ///
271     /// Additional arguments may be supplied via the \p args parameter.
272     /// These arguments may control behavior specific to the layer's
273     /// file format.
274     SDF_API
275     static SdfLayerRefPtr CreateAnonymous(
276         const std::string& tag = std::string(),
277         const FileFormatArguments& args = FileFormatArguments());
278 
279     /// Create an anonymous layer with a specific \p format.
280     SDF_API
281     static SdfLayerRefPtr CreateAnonymous(
282         const std::string &tag, const SdfFileFormatConstPtr &format,
283         const FileFormatArguments& args = FileFormatArguments());
284 
285     /// Returns true if this layer is an anonymous layer.
286     SDF_API
287     bool IsAnonymous() const;
288 
289     /// Returns true if the \p identifier is an anonymous layer unique
290     /// identifier.
291     SDF_API
292     static bool IsAnonymousLayerIdentifier(const std::string& identifier);
293 
294     /// Returns the display name for the given \p identifier, using the same
295     /// rules as GetDisplayName.
296     SDF_API
297     static std::string GetDisplayNameFromIdentifier(
298         const std::string& identifier);
299 
300     /// @}
301     /// \name File I/O
302     /// @{
303 
304     /// Returns \c true if successful, \c false if an error occurred.
305     /// Returns \c false if the layer has no remembered file name or the
306     /// layer type cannot be saved. The layer will not be overwritten if the
307     /// file exists and the layer is not dirty unless \p force is true.
308     SDF_API
309     bool Save(bool force = false) const;
310 
311     /// Exports this layer to a file.
312     /// Returns \c true if successful, \c false if an error occurred.
313     ///
314     /// If \p comment is not empty, the layer gets exported with the given
315     /// comment. Additional arguments may be supplied via the \p args parameter.
316     /// These arguments may control behavior specific to the exported layer's
317     /// file format.
318     ///
319     /// Note that the file name or comment of the original layer is not
320     /// updated. This only saves a copy of the layer to the given filename.
321     /// Subsequent calls to Save() will still save the layer to it's
322     /// previously remembered file name.
323     SDF_API
324     bool Export(const std::string& filename,
325                 const std::string& comment = std::string(),
326                 const FileFormatArguments& args = FileFormatArguments()) const;
327 
328     /// Writes this layer to the given string.
329     ///
330     /// Returns \c true if successful and sets \p result, otherwise
331     /// returns \c false.
332     SDF_API
333     bool ExportToString(std::string* result) const;
334 
335     /// Reads this layer from the given string.
336     ///
337     /// Returns \c true if successful, otherwise returns \c false.
338     SDF_API
339     bool ImportFromString(const std::string &string);
340 
341     /// Clears the layer of all content.
342     ///
343     /// This restores the layer to a state as if it had just been created
344     /// with CreateNew().  This operation is Undo-able.
345     ///
346     /// The fileName and whether journaling is enabled are not affected
347     /// by this method.
348     SDF_API
349     void Clear();
350 
351     /// Reloads the layer from its persistent representation.
352     ///
353     /// This restores the layer to a state as if it had just been created
354     /// with FindOrOpen().  This operation is Undo-able.
355     ///
356     /// The fileName and whether journaling is enabled are not affected
357     /// by this method.
358     ///
359     /// When called with force = false (the default), Reload attempts to
360     /// avoid reloading layers that have not changed on disk. It does so
361     /// by comparing the file's modification time (mtime) to when the
362     /// file was loaded. If the layer has unsaved modifications, this
363     /// mechanism is not used, and the layer is reloaded from disk. If the
364     /// layer has any
365     /// \ref GetExternalAssetDependencies "external asset dependencies"
366     /// their modification state will also be consulted when determining if
367     /// the layer needs to be reloaded.
368     ///
369     /// Passing true to the \p force parameter overrides this behavior,
370     /// forcing the layer to be reloaded from disk regardless of whether
371     /// it has changed.
372     SDF_API
373     bool Reload(bool force = false);
374 
375     /// Reloads the specified layers.
376     ///
377     /// Returns \c false if one or more layers failed to reload.
378     ///
379     /// See \c Reload() for a description of the \p force flag.
380     ///
381     SDF_API
382     static bool ReloadLayers(const std::set<SdfLayerHandle>& layers,
383                              bool force = false);
384 
385     /// Imports the content of the given layer path, replacing the content
386     /// of the current layer.
387     /// Note: If the layer path is the same as the current layer's real path,
388     /// no action is taken (and a warning occurs). For this case use
389     /// Reload().
390     SDF_API
391     bool Import(const std::string &layerPath);
392 
393     /// @}
394     /// \name External references
395     /// @{
396 
397     /// \deprecated
398     /// Use GetCompositionAssetDependencies instead.
399     SDF_API
400     std::set<std::string> GetExternalReferences() const;
401 
402     /// \deprecated
403     /// Use UpdateCompositionAssetDependency instead.
404     SDF_API
405     bool UpdateExternalReference(
406         const std::string &oldAssetPath,
407         const std::string &newAssetPath=std::string());
408 
409     /// Return paths of all assets this layer depends on due to composition
410     /// fields.
411     ///
412     /// This includes the paths of all layers referred to by reference,
413     /// payload, and sublayer fields in this layer. This function only returns
414     /// direct composition dependencies of this layer, i.e. it does not recurse
415     /// to find composition dependencies from its dependent layer assets.
416     SDF_API
417     std::set<std::string> GetCompositionAssetDependencies() const;
418 
419     /// Updates the asset path of a composation dependency in this layer.
420     ///
421     /// If \p newAssetPath is supplied, the update works as "rename", updating
422     /// any occurrence of \p oldAssetPath to \p newAssetPath in all reference,
423     /// payload, and sublayer fields.
424     ///
425     /// If \p newAssetPath is not given, this update behaves as a "delete",
426     /// removing all occurrences of \p oldAssetPath from all reference, payload,
427     /// and sublayer fields.
428     SDF_API
429     bool UpdateCompositionAssetDependency(
430         const std::string &oldAssetPath,
431         const std::string &newAssetPath=std::string());
432 
433     /// Returns a set of resolved paths to all external asset dependencies
434     /// the layer needs to generate its contents. These are additional asset
435     /// dependencies that are determined by the layer's
436     /// \ref SdfFileFormat::GetExternalAssetDependencies "file format" and
437     /// will be consulted during Reload() when determining if the layer needs
438     /// to be reloaded. This specifically does not include dependencies related
439     /// to composition, i.e. this will not include assets from references,
440     /// payloads, and sublayers.
441     SDF_API
442     std::set<std::string> GetExternalAssetDependencies() const;
443 
444     /// @}
445     /// \name Identification
446     ///
447     /// A layer's identifier is a string that uniquely identifies a layer.
448     /// At minimum, it is the string by which the layer was created, either
449     /// via FindOrOpen or CreateNew. If additional arguments were passed
450     /// to those functions, those arguments will be encoded in the identifier.
451     ///
452     /// For example:
453     ///     FindOrOpen('foo.sdf', args={'a':'b', 'c':'d'}).identifier
454     ///         => "foo.sdf?sdf_args:a=b&c=d"
455     ///
456     /// Note that this means the identifier may in general not be a path.
457     ///
458     /// The identifier format is subject to change; consumers should NOT
459     /// parse layer identifiers themselves, but should use the supplied
460     /// SplitIdentifier and CreateIdentifier helper functions.
461     ///
462     /// @{
463 
464     /// Splits the given layer identifier into its constituent layer path
465     /// and arguments.
466     SDF_API
467     static bool SplitIdentifier(
468         const std::string& identifier,
469         std::string* layerPath,
470         FileFormatArguments* arguments);
471 
472     /// Joins the given layer path and arguments into an identifier.
473     SDF_API
474     static std::string CreateIdentifier(
475         const std::string& layerPath,
476         const FileFormatArguments& arguments);
477 
478     /// Returns the layer identifier.
479     SDF_API
480     const std::string& GetIdentifier() const;
481 
482     /// Sets the layer identifier.
483     /// Note that the new identifier must have the same arguments (if any)
484     /// as the old identifier.
485     SDF_API
486     void SetIdentifier(const std::string& identifier);
487 
488     /// Update layer asset information. Calling this method re-resolves the
489     /// layer identifier, which updates asset information such as the layer's
490     /// resolved path and other asset info. This may be used to update the
491     /// layer after external changes to the underlying asset system.
492 #if AR_VERSION == 1
493     SDF_API
494     void UpdateAssetInfo(const std::string& fileVersion = std::string());
495 #else
496     SDF_API
497     void UpdateAssetInfo();
498 #endif
499 
500     /// Returns the layer's display name.
501     ///
502     /// The display name is the base filename of the identifier.
503     SDF_API
504     std::string GetDisplayName() const;
505 
506     /// Returns the resolved path for this layer. This is the path where
507     /// this layer exists or may exist after a call to Save().
508     SDF_API
509     const ArResolvedPath& GetResolvedPath() const;
510 
511     /// Returns the resolved path for this layer. This is equivalent to
512     /// GetResolvedPath().GetPathString().
513     SDF_API
514     const std::string& GetRealPath() const;
515 
516     /// Returns the file extension to use for this layer.
517     /// If this layer was loaded from disk, it should match the extension
518     /// of the file format it was loaded as; if this is an anonymous
519     /// in-memory layer it will be the default extension.
520     SDF_API
521     std::string GetFileExtension() const;
522 
523     /// Returns the asset system version of this layer. If a layer is loaded
524     /// from a location that is not version managed, or a configured asset
525     /// system is not present when the layer is loaded or created, the version
526     /// is empty. By default, asset version tracking is disabled; this method
527     /// returns empty unless asset version tracking is enabled.
528     SDF_API
529     const std::string& GetVersion() const;
530 
531     /// Returns the layer identifier in asset path form. In the presence of a
532     /// properly configured path resolver, the asset path is a double-slash
533     /// prefixed depot path. If the path resolver is not configured, the asset
534     /// path of a layer is empty.
535     SDF_API
536     const std::string& GetRepositoryPath() const;
537 
538     /// Returns the asset name associated with this layer.
539     SDF_API
540     const std::string& GetAssetName() const;
541 
542     /// Returns resolve information from the last time the layer identifier
543     /// was resolved.
544     SDF_API
545     const VtValue& GetAssetInfo() const;
546 
547     /// Returns the path to the asset specified by \p assetPath using this layer
548     /// to anchor the path if necessary. Returns \p assetPath if it's empty or
549     /// an anonymous layer identifier.
550     ///
551     /// This method can be used on asset paths that are authored in this layer
552     /// to create new asset paths that can be copied to other layers.  These new
553     /// asset paths should refer to the same assets as the original asset
554     /// paths. For example, if the underlying ArResolver is filesystem-based and
555     /// \p assetPath is a relative filesystem path, this method might return the
556     /// absolute filesystem path using this layer's location as the anchor.
557     ///
558     /// The returned path should in general not be assumed to be an absolute
559     /// filesystem path or any other specific form. It is "absolute" in that it
560     /// should resolve to the same asset regardless of what layer it's authored
561     /// in.
562     SDF_API
563     std::string ComputeAbsolutePath(const std::string& assetPath) const;
564 
565     /// @}
566 
567     /// \name Fields
568     ///
569     /// All scene description for a given object is stored as a set of
570     /// key/value pairs called fields. These methods provide direct access to
571     /// those fields, though most clients should use the Spec API to ensure
572     /// data consistency.
573     ///
574     /// These methods all take SdfPath to identify the queried spec.
575     ///
576     /// @{
577 
578     /// Return the spec type for \a path. This returns SdfSpecTypeUnknown if no
579     /// spec exists at \a path.
580     SDF_API
581     SdfSpecType GetSpecType(const SdfPath& path) const;
582 
583     /// Return whether a spec exists at \a path.
584     SDF_API
585     bool HasSpec(const SdfPath& path) const;
586 
587     /// Return the names of all the fields that are set at \p path.
588     SDF_API
589     std::vector<TfToken> ListFields(const SdfPath& path) const;
590 
591     /// Return whether a value exists for the given \a path and \a fieldName.
592     /// Optionally returns the value if it exists.
593     SDF_API
594     bool HasField(const SdfPath& path, const TfToken& fieldName,
595                   VtValue *value=NULL) const;
596     SDF_API
597     bool HasField(const SdfPath& path, const TfToken& fieldName,
598                   SdfAbstractDataValue *value) const;
599 
600     /// Returns \c true if the object has a non-empty value with name
601     /// \p name and type \p T.  If value ptr is provided, returns the
602     /// value found.
603     template <class T>
HasField(const SdfPath & path,const TfToken & name,T * value)604     bool HasField(const SdfPath& path, const TfToken &name,
605         T* value) const
606     {
607         if (!value) {
608             return HasField(path, name, static_cast<VtValue *>(NULL));
609         }
610 
611         SdfAbstractDataTypedValue<T> outValue(value);
612         const bool hasValue = HasField(
613             path, name, static_cast<SdfAbstractDataValue *>(&outValue));
614 
615         if (std::is_same<T, SdfValueBlock>::value) {
616             return hasValue && outValue.isValueBlock;
617         }
618 
619         return hasValue && (!outValue.isValueBlock);
620     }
621 
622     /// Return the type of the value for \p name on spec \p path.  If no such
623     /// field exists, return typeid(void).
GetFieldTypeid(const SdfPath & path,const TfToken & name)624     std::type_info const &GetFieldTypeid(
625         const SdfPath &path, const TfToken &name) const {
626         return _data->GetTypeid(path, name);
627     }
628 
629     /// Return whether a value exists for the given \a path and \a fieldName and
630     /// \a keyPath.  The \p keyPath is a ':'-separated path addressing an
631     /// element in sub-dictionaries.  Optionally returns the value if it exists.
632     SDF_API
633     bool HasFieldDictKey(const SdfPath& path,
634                          const TfToken &fieldName,
635                          const TfToken &keyPath,
636                          VtValue *value=NULL) const;
637     SDF_API
638     bool HasFieldDictKey(const SdfPath& path,
639                          const TfToken &fieldName,
640                          const TfToken &keyPath,
641                          SdfAbstractDataValue *value) const;
642 
643     /// Returns \c true if the object has a non-empty value with name \p name
644     /// and \p keyPath and type \p T.  If value ptr is provided, returns the
645     /// value found.  The \p keyPath is a ':'-separated path addressing an
646     /// element in sub-dictionaries.
647     template <class T>
HasFieldDictKey(const SdfPath & path,const TfToken & name,const TfToken & keyPath,T * value)648     bool HasFieldDictKey(const SdfPath& path, const TfToken &name,
649                          const TfToken &keyPath, T* value) const
650     {
651         if (!value) {
652             return HasFieldDictKey(path, name, keyPath,
653                                    static_cast<VtValue *>(NULL));
654         }
655 
656         SdfAbstractDataTypedValue<T> outValue(value);
657         return HasFieldDictKey(path, name, keyPath,
658                                static_cast<SdfAbstractDataValue *>(&outValue));
659     }
660 
661 
662     /// Return the value for the given \a path and \a fieldName. Returns an
663     /// empty value if none is set.
664     SDF_API
665     VtValue GetField(const SdfPath& path,
666                      const TfToken& fieldName) const;
667 
668     /// Return the value for the given \a path and \a fieldName. Returns the
669     /// provided \a defaultValue value if none is set.
670     template <class T>
671     inline T GetFieldAs(const SdfPath& path,
672         const TfToken& fieldName, const T& defaultValue = T()) const
673     {
674         return _data->GetAs<T>(path, fieldName, defaultValue);
675     }
676 
677     /// Return the value for the given \a path and \a fieldName at \p
678     /// keyPath. Returns an empty value if none is set.  The \p keyPath is a
679     /// ':'-separated path addressing an element in sub-dictionaries.
680     SDF_API
681     VtValue GetFieldDictValueByKey(const SdfPath& path,
682                                    const TfToken& fieldName,
683                                    const TfToken& keyPath) const;
684 
685     /// Set the value of the given \a path and \a fieldName.
686     SDF_API
687     void SetField(const SdfPath& path, const TfToken& fieldName,
688         const VtValue& value);
689     SDF_API
690     void SetField(const SdfPath& path, const TfToken& fieldName,
691         const SdfAbstractDataConstValue& value);
692 
693     /// Set the value of the given \a path and \a fieldName.
694     template <class T>
SetField(const SdfPath & path,const TfToken & fieldName,const T & val)695     void SetField(const SdfPath& path, const TfToken& fieldName,
696         const T& val)
697     {
698         // Ideally, this would make use of the SdfAbstractDataConstValue
699         // API to avoid unnecessarily copying the value into a VtValue.
700         // However, Sdf needs to create a VtValue for change processing.
701         // If the underlying SdAbstractData implementation also needs a
702         // VtValue, using the SdfAbstractDataConstValue API would cause
703         // another copy to be made. So, it's more efficient to just create
704         // the VtValue once here and push that along.
705         SetField(path, fieldName, VtValue(val));
706     }
707 
708     /// Set the value of the given \a path and \a fieldName.  The \p keyPath is a
709     /// ':'-separated path addressing an element in sub-dictionaries.
710     SDF_API
711     void SetFieldDictValueByKey(const SdfPath& path,
712                                 const TfToken& fieldName,
713                                 const TfToken& keyPath,
714                                 const VtValue& value);
715     SDF_API
716     void SetFieldDictValueByKey(const SdfPath& path,
717                                 const TfToken& fieldName,
718                                 const TfToken& keyPath,
719                                 const SdfAbstractDataConstValue& value);
720 
721     /// Set the value of the given \a path and \a fieldName.  The \p keyPath is
722     /// a ':'-separated path addressing an element in sub-dictionaries.
723     template <class T>
SetFieldDictValueByKey(const SdfPath & path,const TfToken & fieldName,const TfToken & keyPath,const T & val)724     void SetFieldDictValueByKey(const SdfPath& path,
725                                 const TfToken& fieldName,
726                                 const TfToken& keyPath,
727                                 const T& val)
728     {
729         // Ideally, this would make use of the SdfAbstractDataConstValue
730         // API to avoid unnecessarily copying the value into a VtValue.
731         // However, Sdf needs to create a VtValue for change processing.
732         // If the underlying SdAbstractData implementation also needs
733         // VtValue, using the SdfAbstractDataConstValue API would cause
734         // another copy to be made. So, it's more efficient to just create
735         // the VtValue once here and push that along.
736         SetFieldDictValueByKey(path, fieldName, keyPath, VtValue(val));
737     }
738 
739     /// Remove the field at \p path and \p fieldName, if one exists.
740     SDF_API
741     void EraseField(const SdfPath& path, const TfToken& fieldName);
742 
743     /// Remove the field at \p path and \p fieldName and \p keyPath, if one
744     /// exists.  The \p keyPath is a ':'-separated path addressing an
745     /// element in sub-dictionaries.
746     SDF_API
747     void EraseFieldDictValueByKey(const SdfPath& path,
748                                   const TfToken& fieldName,
749                                   const TfToken& keyPath);
750 
751     /// \name Traversal
752     /// @{
753 
754     /// Callback function for Traverse. This callback will be invoked with
755     /// the path of each spec that is visited.
756     /// \sa Traverse
757     typedef std::function<void(const SdfPath&)> TraversalFunction;
758 
759     // Traverse will perform a traversal of the scene description hierarchy
760     // rooted at \a path, calling \a func on each spec that it finds.
761     SDF_API
762     void Traverse(const SdfPath& path, const TraversalFunction& func);
763 
764     /// @}
765 
766     /// \name Metadata
767     /// @{
768 
769     /// Returns the color configuration asset-path for this layer.
770     ///
771     /// The default value is an empty asset-path.
772     SDF_API
773     SdfAssetPath GetColorConfiguration() const;
774 
775     /// Sets the color configuration asset-path for this layer.
776     SDF_API
777     void SetColorConfiguration(const SdfAssetPath &colorConfiguration);
778 
779     /// Returns true if color configuration metadata is set in this layer.
780     /// \sa GetColorConfiguration(), SetColorConfiguration()
781     SDF_API
782     bool HasColorConfiguration() const;
783 
784     /// Clears the color configuration metadata authored in this layer.
785     /// \sa HasColorConfiguration(), SetColorConfiguration()
786     SDF_API
787     void ClearColorConfiguration();
788 
789     /// Returns the color management system used to interpret the color
790     /// configuration asset-path authored in this layer.
791     ///
792     /// The default value is an empty token, which implies that the clients
793     /// will have to determine the color management system from the color
794     /// configuration asset path (i.e. from its file extension), if it's
795     /// specified.
796     SDF_API
797     TfToken GetColorManagementSystem() const;
798 
799     /// Sets the color management system used to interpret the color
800     /// configuration asset-path authored this layer.
801     SDF_API
802     void SetColorManagementSystem(const TfToken &cms);
803 
804     /// Returns true if colorManagementSystem metadata is set in this layer.
805     /// \sa GetColorManagementSystem(), SetColorManagementSystem()
806     SDF_API
807     bool HasColorManagementSystem() const;
808 
809     /// Clears the 'colorManagementSystem' metadata authored in this layer.
810     /// \sa HascolorManagementSystem(), SetColorManagementSystem()
811     SDF_API
812     void ClearColorManagementSystem();
813 
814     /// Returns the comment string for this layer.
815     ///
816     /// The default value for comment is "".
817     SDF_API
818     std::string GetComment() const;
819 
820     /// Sets the comment string for this layer.
821     SDF_API
822     void SetComment(const std::string &comment);
823 
824     /// Return the defaultPrim metadata for this layer.  This field
825     /// indicates the name of which root prim should be targeted by a reference
826     /// or payload to this layer that doesn't specify a prim path.
827     ///
828     /// The default value is the empty token.
829     SDF_API
830     TfToken GetDefaultPrim() const;
831 
832     /// Set the default prim metadata for this layer.  The root prim with this
833     /// name will be targeted by a reference or a payload to this layer that
834     /// doesn't specify a prim path.  Note that this must be a root prim
835     /// <b>name</b> not a path.  E.g. "rootPrim" rather than "/rootPrim".  See
836     /// GetDefaultPrim().
837     SDF_API
838     void SetDefaultPrim(const TfToken &name);
839 
840     /// Clear the default prim metadata for this layer.  See GetDefaultPrim()
841     /// and SetDefaultPrim().
842     SDF_API
843     void ClearDefaultPrim();
844 
845     /// Return true if the default prim metadata is set in this layer.  See
846     /// GetDefaultPrim() and SetDefaultPrim().
847     SDF_API
848     bool HasDefaultPrim();
849 
850     /// Returns the documentation string for this layer.
851     ///
852     /// The default value for documentation is "".
853     SDF_API
854     std::string GetDocumentation() const;
855 
856     /// Sets the documentation string for this layer.
857     SDF_API
858     void SetDocumentation(const std::string &documentation);
859 
860     /// Returns the layer's start timeCode.
861     ///
862     /// The start and end timeCodes of a layer represent the suggested playback
863     /// range.  However, time-varying content is not limited to the timeCode range
864     /// of the layer.
865     ///
866     /// The default value for startTimeCode is 0.
867     SDF_API
868     double GetStartTimeCode() const;
869 
870     /// Sets the layer's start timeCode.
871     SDF_API
872     void SetStartTimeCode(double startTimecode);
873 
874     /// Returns true if the layer has a startTimeCode opinion.
875     SDF_API
876     bool HasStartTimeCode() const;
877 
878     /// Clear the startTimeCode opinion.
879     SDF_API
880     void ClearStartTimeCode();
881 
882     /// Returns the layer's end timeCode.
883     /// The start and end timeCode of a layer represent a suggested playback range.
884     /// However, time-varying content is not limited to the timeCode range of the
885     /// layer.
886     ///
887     /// The default value for endTimeCode is 0.
888     SDF_API
889     double GetEndTimeCode() const;
890 
891     /// Sets the layer's end timeCode.
892     SDF_API
893     void SetEndTimeCode(double endTimeCode);
894 
895     /// Returns true if the layer has an endTimeCode opinion.
896     SDF_API
897     bool HasEndTimeCode() const;
898 
899     /// Clear the endTimeCode opinion.
900     SDF_API
901     void ClearEndTimeCode();
902 
903     /// Returns the layer's timeCodes per second.
904     ///
905     /// Scales the time ordinate for samples contained in the file to seconds.
906     /// If timeCodesPerSecond is 24, then a sample at time ordinate 24 should
907     /// be viewed exactly one second after the sample at time ordinate 0.
908     ///
909     /// If this layer doesn't have an authored value for timeCodesPerSecond, but
910     /// it does have an authored value for framesPerSecond, this method will
911     /// return the value of framesPerSecond.  This "dynamic fallback" allows
912     /// layers to lock framesPerSecond and timeCodesPerSecond to the same value
913     /// by specifying only framesPerSecond.
914     ///
915     /// The default value of timeCodesPerSecond (which is used only if there is
916     /// no authored value for either timeCodesPerSecond or framesPerSecond) is
917     /// 24.
918     SDF_API
919     double GetTimeCodesPerSecond() const;
920 
921     /// Sets the layer's timeCodes per second
922     SDF_API
923     void SetTimeCodesPerSecond(double timeCodesPerSecond);
924 
925     /// Returns true if the layer has a timeCodesPerSecond opinion.
926     SDF_API
927     bool HasTimeCodesPerSecond() const;
928 
929     /// Clear the timeCodesPerSecond opinion.
930     SDF_API
931     void ClearTimeCodesPerSecond();
932 
933     /// Returns the layer's frames per second.
934     ///
935     /// This makes an advisory statement about how the contained data can be
936     /// most usefully consumed and presented.  It's primarily an indication of
937     /// the expected playback rate for the data, but a timeline editing tool
938     /// might also want to use this to decide how to scale and label its
939     /// timeline.
940     ///
941     /// The default  value for framesPerSecond is 24.
942     SDF_API
943     double GetFramesPerSecond() const;
944 
945     /// Sets the layer's frames per second
946     SDF_API
947     void SetFramesPerSecond(double framesPerSecond);
948 
949     /// Returns true if the layer has a frames per second opinion.
950     SDF_API
951     bool HasFramesPerSecond() const;
952 
953     /// Clear the framesPerSecond opinion.
954     SDF_API
955     void ClearFramesPerSecond();
956 
957     /// Returns the layer's frame precision.
958     SDF_API
959     int GetFramePrecision() const;
960 
961     /// Sets the layer's frame precision.
962     SDF_API
963     void SetFramePrecision(int framePrecision);
964 
965     /// Returns true if the layer has a frames precision opinion.
966     SDF_API
967     bool HasFramePrecision() const;
968 
969     /// Clear the framePrecision opinion.
970     SDF_API
971     void ClearFramePrecision();
972 
973     /// Returns the layer's owner.
974     SDF_API
975     std::string GetOwner() const;
976 
977     /// Sets the layer's owner.
978     SDF_API
979     void SetOwner(const std::string& owner);
980 
981     /// Returns true if the layer has an owner opinion.
982     SDF_API
983     bool HasOwner() const;
984 
985     /// Clear the owner opinion.
986     SDF_API
987     void ClearOwner();
988 
989     /// Returns the layer's session owner.
990     /// Note: This should only be used by session layers.
991     SDF_API
992     std::string GetSessionOwner() const;
993 
994     /// Sets the layer's session owner.
995     /// Note: This should only be used by session layers.
996     SDF_API
997     void SetSessionOwner(const std::string& owner);
998 
999     /// Returns true if the layer has a session owner opinion.
1000     SDF_API
1001     bool HasSessionOwner() const;
1002 
1003     // Clear the session owner opinion.
1004     SDF_API
1005     void ClearSessionOwner();
1006 
1007     /// Returns true if the layer's sublayers are expected to have owners.
1008     SDF_API
1009     bool GetHasOwnedSubLayers() const;
1010 
1011     /// Sets whether the layer's sublayers are expected to have owners.
1012     SDF_API
1013     void SetHasOwnedSubLayers(bool);
1014 
1015     /// Returns the CustomLayerData dictionary associated with this layer.
1016     ///
1017     /// This is a dictionary is custom metadata that is associated with
1018     /// this layer. It allows users to encode any set of information for
1019     /// human or program consumption.
1020     SDF_API
1021     VtDictionary GetCustomLayerData() const;
1022 
1023     /// Sets the CustomLayerData dictionary associated with this layer.
1024     SDF_API
1025     void SetCustomLayerData(const VtDictionary& value);
1026 
1027     /// Returns true if CustomLayerData is authored on the layer.
1028     SDF_API
1029     bool HasCustomLayerData() const;
1030 
1031     /// Clears out the CustomLayerData dictionary associated with this layer.
1032     SDF_API
1033     void ClearCustomLayerData();
1034 
1035     /// @}
1036     /// \name Prims
1037     /// @{
1038 
1039     // Type for root prims view.
1040     typedef SdfPrimSpecView RootPrimsView;
1041 
1042     /// Returns a vector of the layer's root prims
1043     SDF_API
1044     RootPrimsView GetRootPrims() const;
1045 
1046     /// Sets a new vector of root prims.
1047     /// You can re-order, insert and remove prims but cannot
1048     /// rename them this way.  If any of the listed prims have
1049     /// an existing owner, they will be reparented.
1050     SDF_API
1051     void SetRootPrims(const SdfPrimSpecHandleVector &rootPrims);
1052 
1053     /// Adds a new root prim at the given index.
1054     /// If the index is -1, the prim is inserted at the end.
1055     /// The layer will take ownership of the prim, via a TfRefPtr.
1056     /// Returns true if successful, false if failed (for example,
1057     /// due to a duplicate name).
1058     SDF_API
1059     bool InsertRootPrim(const SdfPrimSpecHandle &prim, int index = -1);
1060 
1061     /// Remove a root prim.
1062     SDF_API
1063     void RemoveRootPrim(const SdfPrimSpecHandle &prim);
1064 
1065     /// Cause \p spec to be removed if it no longer affects the scene when the
1066     /// last change block is closed, or now if there are no change blocks.
1067     SDF_API
1068     void ScheduleRemoveIfInert(const SdfSpec& spec);
1069 
1070     /// Removes scene description that does not affect the scene in the
1071     /// layer namespace beginning with \p prim.
1072     ///
1073     /// Calling this method on a prim will only clean up prims with specifier
1074     /// 'over' that are not contributing any opinions.  The \p prim will only
1075     /// be removed if all of its nameChildren are also inert. The hierarchy
1076     /// \p prim is defined in will be pruned up to the layer root for each
1077     /// successive inert parent that has specifier 'over'.
1078     ///
1079     /// note: PrimSpecs that contain any PropertySpecs, even PropertySpecs with
1080     ///       required fields only (see PropertySpec::HasRequiredFieldsOnly)
1081     ///       are not considered inert, and thus the prim won't be removed.
1082     SDF_API
1083     void RemovePrimIfInert(SdfPrimSpecHandle prim);
1084 
1085     /// Removes prop if it has only required fields (i.e. is not
1086     /// contributing any opinions to the scene other than property
1087     /// instantiation).
1088     ///
1089     /// The hierarchy \p prop is defined in will then be pruned up to the
1090     /// layer root for each successive inert parent.
1091     SDF_API
1092     void RemovePropertyIfHasOnlyRequiredFields(SdfPropertySpecHandle prop);
1093 
1094     /// Removes all scene description in this layer that does not affect the
1095     /// scene.
1096     ///
1097     /// This method walks the layer namespace hierarchy and removes any prims
1098     /// and that are not contributing any opinions.
1099     SDF_API
1100     void RemoveInertSceneDescription();
1101 
1102     /// Returns the list of prim names for this layer's reorder rootPrims
1103     /// statement.
1104     ///
1105     /// See SetRootPrimOrder() for more info.
1106     SDF_API
1107     SdfNameOrderProxy GetRootPrimOrder() const;
1108 
1109     /// Given a list of (possible sparse) prim names, authors a reorder
1110     /// rootPrims statement for this prim.
1111     ///
1112     /// This reorder statement can modify the order of root prims that have
1113     /// already been explicitly ordered with InsertRootPrim() or SetRootPrims();
1114     /// but only during composition.  Therefore, GetRootPrims(),
1115     /// InsertRootPrim(), SetRootPrims(), etc. do not read, author, or pay any
1116     /// attention to this statement.
1117     SDF_API
1118     void SetRootPrimOrder(const std::vector<TfToken>& names);
1119 
1120     /// Adds a new root prim name in the root prim order.
1121     /// If the index is -1, the name is inserted at the end.
1122     SDF_API
1123     void InsertInRootPrimOrder(const TfToken &name, int index = -1);
1124 
1125     /// Removes a root prim name from the root prim order.
1126     SDF_API
1127     void RemoveFromRootPrimOrder(const TfToken & name);
1128 
1129     /// Removes a root prim name from the root prim order by index.
1130     SDF_API
1131     void RemoveFromRootPrimOrderByIndex(int index);
1132 
1133     /// Reorders the given list of prim names according to the reorder rootPrims
1134     /// statement for this layer.
1135     ///
1136     /// This routine employs the standard list editing operations for ordered
1137     /// items in a ListEditor.
1138     SDF_API
1139     void ApplyRootPrimOrder(std::vector<TfToken> *vec) const;
1140 
1141     /// @}
1142     /// \name Sublayers
1143     /// @{
1144 
1145     /// Returns a proxy for this layer's sublayers.
1146     ///
1147     /// Sub-layers are the weaker layers directly included by this layer.
1148     /// They're in order from strongest to weakest and they're all weaker
1149     /// than this layer.
1150     ///
1151     /// Edits through the proxy changes the sublayers.  If this layer does
1152     /// not have any sublayers the proxy is empty.
1153     ///
1154     /// Sub-layer paths are asset paths, and thus must contain valid asset path
1155     /// characters (UTF-8 without C0 and C1 controls).  See SdfAssetPath for
1156     /// more details.
1157     SDF_API
1158     SdfSubLayerProxy GetSubLayerPaths() const;
1159 
1160     /// Sets the paths of the layer's sublayers.
1161     SDF_API
1162     void SetSubLayerPaths(const std::vector<std::string>& newPaths);
1163 
1164     /// Returns the number of sublayer paths (and offsets).
1165     SDF_API
1166     size_t GetNumSubLayerPaths() const;
1167 
1168     /// Inserts new sublayer path at the given index.
1169     ///
1170     /// The default index of -1 means to insert at the end.
1171     SDF_API
1172     void InsertSubLayerPath(const std::string& path, int index = -1);
1173 
1174     /// Removes sublayer path at the given index.
1175     SDF_API
1176     void RemoveSubLayerPath(int index);
1177 
1178     /// Returns the layer offsets for all the subLayer paths.
1179     SDF_API
1180     SdfLayerOffsetVector GetSubLayerOffsets() const;
1181 
1182     /// Returns the layer offset for the subLayer path at the given index.
1183     SDF_API
1184     SdfLayerOffset GetSubLayerOffset(int index) const;
1185 
1186     /// Sets the layer offset for the subLayer path at the given index.
1187     SDF_API
1188     void SetSubLayerOffset(const SdfLayerOffset& offset, int index);
1189 
1190     /// @}
1191     /// \name Muting
1192     /// @{
1193 
1194     /// Returns the set of muted layer paths.
1195     SDF_API
1196     static std::set<std::string> GetMutedLayers();
1197 
1198     /// Returns \c true if the current layer is muted.
1199     SDF_API
1200     bool IsMuted() const;
1201 
1202     /// Returns \c true if the specified layer path is muted.
1203     SDF_API
1204     static bool IsMuted(const std::string &path);
1205 
1206     /// Mutes the current layer if \p muted is \c true, and unmutes it
1207     /// otherwise.
1208     SDF_API
1209     void SetMuted(bool muted);
1210 
1211     /// Add the specified path to the muted layers set.
1212     SDF_API
1213     static void AddToMutedLayers(const std::string &mutedPath);
1214 
1215     /// Remove the specified path from the muted layers set.
1216     SDF_API
1217     static void RemoveFromMutedLayers(const std::string &mutedPath);
1218 
1219     /// @}
1220     /// \name Lookup
1221     /// @{
1222 
1223     /// Returns the layer's pseudo-root prim.
1224     ///
1225     /// The layer's root prims are namespace children of the pseudo-root.
1226     /// The pseudo-root exists to make the namespace hierarchy a tree
1227     /// instead of a forest.  This simplifies the implementation of
1228     /// some algorithms.
1229     ///
1230     /// A layer always has a pseudo-root prim.
1231     SDF_API
1232     SdfPrimSpecHandle GetPseudoRoot() const;
1233 
1234     /// Returns the object at the given \p path.
1235     ///
1236     /// There is no distinction between an absolute and relative path
1237     /// at the SdLayer level.
1238     ///
1239     /// Returns \c NULL if there is no object at \p path.
1240     SDF_API
1241     SdfSpecHandle GetObjectAtPath(const SdfPath &path);
1242 
1243     /// Returns the prim at the given \p path.
1244     ///
1245     /// Returns \c NULL if there is no prim at \p path.
1246     /// This is simply a more specifically typed version of
1247     /// \c GetObjectAtPath().
1248     SDF_API
1249     SdfPrimSpecHandle GetPrimAtPath(const SdfPath &path);
1250 
1251     /// Returns a property at the given \p path.
1252     ///
1253     /// Returns \c NULL if there is no property at \p path.
1254     /// This is simply a more specifically typed version of
1255     /// \c GetObjectAtPath().
1256     SDF_API
1257     SdfPropertySpecHandle GetPropertyAtPath(const SdfPath &path);
1258 
1259     /// Returns an attribute at the given \p path.
1260     ///
1261     /// Returns \c NULL if there is no attribute at \p path.
1262     /// This is simply a more specifically typed version of
1263     /// \c GetObjectAtPath().
1264     SDF_API
1265     SdfAttributeSpecHandle GetAttributeAtPath(const SdfPath &path);
1266 
1267     /// Returns a relationship at the given \p path.
1268     ///
1269     /// Returns \c NULL if there is no relationship at \p path.
1270     /// This is simply a more specifically typed version of
1271     /// \c GetObjectAtPath().
1272     SDF_API
1273     SdfRelationshipSpecHandle GetRelationshipAtPath(const SdfPath &path);
1274 
1275     /// @}
1276     /// \name Permissions
1277     /// @{
1278 
1279     /// Returns true if the caller is allowed to modify the layer and
1280     /// false otherwise.  A layer may have to perform some action to acquire
1281     /// permission to be edited.
1282     SDF_API
1283     bool PermissionToEdit() const;
1284 
1285     /// Returns true if the caller is allowed to save the layer to its
1286     /// existing fileName and false otherwise.
1287     SDF_API
1288     bool PermissionToSave() const;
1289 
1290     /// Sets permission to edit.
1291     SDF_API
1292     void SetPermissionToEdit(bool allow);
1293 
1294     /// Sets permission to save.
1295     SDF_API
1296     void SetPermissionToSave(bool allow);
1297 
1298     /// @}
1299     /// \name Batch namespace editing
1300     /// @{
1301 
1302     /// Check if a batch of namespace edits will succeed.  This returns
1303     /// \c SdfNamespaceEditDetail::Okay if they will succeed as a batch,
1304     /// \c SdfNamespaceEditDetail::Unbatched if the edits will succeed but
1305     /// will be applied unbatched, and \c SdfNamespaceEditDetail::Error
1306     /// if they will not succeed.  No edits will be performed in any case.
1307     ///
1308     /// If \p details is not \c NULL and the method does not return \c Okay
1309     /// then details about the problems will be appended to \p details.  A
1310     /// problem may cause the method to return early, so \p details may not
1311     /// list every problem.
1312     ///
1313     /// Note that Sdf does not track backpointers so it's unable to fix up
1314     /// targets/connections to namespace edited objects.  Clients must fix
1315     /// those to prevent them from falling off.  In addition, this method
1316     /// will report failure if any relational attribute with a target to
1317     /// a namespace edited object is subsequently edited (in the same
1318     /// batch).  Clients should perform edits on relational attributes
1319     /// first.
1320     ///
1321     /// Clients may wish to report unbatch details to the user to confirm
1322     /// that the edits should be applied unbatched.  This will give the
1323     /// user a chance to correct any problems that cause batching to fail
1324     /// and try again.
1325     SDF_API
1326     SdfNamespaceEditDetail::Result
1327     CanApply(const SdfBatchNamespaceEdit&,
1328              SdfNamespaceEditDetailVector* details = NULL) const;
1329 
1330     /// Performs a batch of namespace edits.  Returns \c true on success
1331     /// and \c false on failure.  On failure, no namespace edits will have
1332     /// occurred.
1333     SDF_API
1334     bool Apply(const SdfBatchNamespaceEdit&);
1335 
1336     /// @}
1337     /// \name Layer state
1338     /// @{
1339 
1340     /// Returns the state delegate used to manage this layer's authoring
1341     /// state.
1342     SDF_API
1343     SdfLayerStateDelegateBasePtr GetStateDelegate() const;
1344 
1345     /// Sets the state delegate used to manage this layer's authoring
1346     /// state. The 'dirty' state of this layer will be transferred to
1347     /// the new delegate.
1348     SDF_API
1349     void SetStateDelegate(const SdfLayerStateDelegateBaseRefPtr& delegate);
1350 
1351     /// Returns \c true if the layer is dirty, i.e. has changed from
1352     /// its persistent representation.
1353     SDF_API
1354     bool IsDirty() const;
1355 
1356     /// @}
1357 
1358     /// \name Time-sample API
1359     /// @{
1360     SDF_API
1361     std::set<double> ListAllTimeSamples() const;
1362 
1363     SDF_API
1364     std::set<double>
1365     ListTimeSamplesForPath(const SdfPath& path) const;
1366 
1367     SDF_API
1368     bool GetBracketingTimeSamples(double time, double* tLower, double* tUpper);
1369 
1370     SDF_API
1371     size_t GetNumTimeSamplesForPath(const SdfPath& path) const;
1372 
1373     SDF_API
1374     bool GetBracketingTimeSamplesForPath(const SdfPath& path,
1375                                          double time,
1376                                          double* tLower, double* tUpper);
1377 
1378     SDF_API
1379     bool QueryTimeSample(const SdfPath& path, double time,
1380                          VtValue *value=NULL) const;
1381     SDF_API
1382     bool QueryTimeSample(const SdfPath& path, double time,
1383                          SdfAbstractDataValue *value) const;
1384 
1385     template <class T>
QueryTimeSample(const SdfPath & path,double time,T * data)1386     bool QueryTimeSample(const SdfPath& path, double time,
1387                          T* data) const
1388     {
1389         if (!data) {
1390             return QueryTimeSample(path, time);
1391         }
1392 
1393         SdfAbstractDataTypedValue<T> outValue(data);
1394         const bool hasValue = QueryTimeSample(
1395             path, time, static_cast<SdfAbstractDataValue *>(&outValue));
1396 
1397         if (std::is_same<T, SdfValueBlock>::value) {
1398             return hasValue && outValue.isValueBlock;
1399         }
1400 
1401         return hasValue && (!outValue.isValueBlock);
1402     }
1403 
1404     SDF_API
1405     void SetTimeSample(const SdfPath& path, double time,
1406                        const VtValue & value);
1407     SDF_API
1408     void SetTimeSample(const SdfPath& path, double time,
1409                        const SdfAbstractDataConstValue& value);
1410 
1411     template <class T>
SetTimeSample(const SdfPath & path,double time,const T & value)1412     void SetTimeSample(const SdfPath& path, double time,
1413                        const T& value)
1414     {
1415         const SdfAbstractDataConstTypedValue<T> inValue(&value);
1416         const SdfAbstractDataConstValue& untypedInValue = inValue;
1417         return SetTimeSample(path, time, untypedInValue);
1418     }
1419 
1420     SDF_API
1421     void EraseTimeSample(const SdfPath& path, double time);
1422 
1423     /// @}
1424 
1425     // Debugging
1426     // @{
1427 
1428     SDF_API
1429     static void DumpLayerInfo();
1430 
1431     // Write this layer's SdfData to a file in a simple generic format.
1432     SDF_API
1433     bool WriteDataFile(const std::string &filename);
1434 
1435     // @}
1436 
1437 protected:
1438     // Private constructor -- use New(), FindOrCreate(), etc.
1439     // Precondition: _layerRegistryMutex must be locked.
1440     SdfLayer(const SdfFileFormatConstPtr& fileFormat,
1441              const std::string &identifier,
1442              const std::string &realPath = std::string(),
1443              const ArAssetInfo& assetInfo = ArAssetInfo(),
1444              const FileFormatArguments &args = FileFormatArguments(),
1445              bool validateAuthoring = false);
1446 
1447 private:
1448     // Create a new layer.
1449     // Precondition: _layerRegistryMutex must be locked.
1450     static SdfLayerRefPtr _CreateNew(
1451         SdfFileFormatConstPtr fileFormat,
1452         const std::string& identifier,
1453         const FileFormatArguments& args);
1454 
1455     static SdfLayerRefPtr _CreateNewWithFormat(
1456         const SdfFileFormatConstPtr &fileFormat,
1457         const std::string& identifier,
1458         const std::string& realPath,
1459         const ArAssetInfo& assetInfo = ArAssetInfo(),
1460         const FileFormatArguments& args = FileFormatArguments());
1461 
1462     static SdfLayerRefPtr _CreateAnonymousWithFormat(
1463         const SdfFileFormatConstPtr &fileFormat,
1464         const std::string& tag,
1465         const FileFormatArguments& args);
1466 
1467     // Finish initializing this layer (which may have succeeded or not)
1468     // and publish the results to other threads by unlocking the mutex.
1469     // Sets _initializationWasSuccessful and unlocks _initializationMutex.
1470     void _FinishInitialization(bool success);
1471 
1472     // Layers retrieved from the layer registry may still be in the
1473     // process of having their contents initialized.  Other threads
1474     // retrieving layers from the registry must wait until initialization
1475     // is complete, using this method.  See _initializationMutex.
1476     // Returns _initializationWasSuccessful.
1477     //
1478     // Callers *must* be holding an SdfLayerRefPtr to this layer to
1479     // ensure that it is not deleted out from under them, in
1480     // case initialization fails.  (This method cannot acquire the
1481     // reference itself internally without being susceptible to a race.)
1482     bool _WaitForInitializationAndCheckIfSuccessful();
1483 
1484     // Returns whether or not this menv layer should post change
1485     // notification.  This simply returns (!_GetIsLoading())
1486     bool _ShouldNotify() const;
1487 
1488     // This function keeps track of the last state of IsDirty() before
1489     // updating it. It returns false if the last saved dirty state is the
1490     // same than the current state. It returns true if the state differs and
1491     // will update the 'last dirty state' to the current state. So, after
1492     // returning true, it would return false for subsequent calls until the
1493     // IsDirty() state would change again...
1494     bool _UpdateLastDirtinessState() const;
1495 
1496     // Returns a handle to the spec at the given path if it exists and matches
1497     // type T.
1498     template <class T>
1499     SdfHandle<T> _GetSpecAtPath(const SdfPath& path);
1500 
1501     // Returns true if a spec can be retrieved at the given path, false
1502     // otherwise. This function will return the canonicalized path to the
1503     // spec as well as the spec type.
1504     bool _CanGetSpecAtPath(const SdfPath& path,
1505                            SdfPath* canonicalPath, SdfSpecType* specType) const;
1506 
1507     /// Initialize layer internals that are based on it's path.
1508     /// This includes the asset path and show path the layer to be loaded
1509     /// reflects at the point of initialization.
1510     void _InitializeFromIdentifier(
1511         const std::string &identifier,
1512         const std::string &realPath = std::string(),
1513         const std::string &fileVersion = std::string(),
1514         const ArAssetInfo& assetInfo = ArAssetInfo());
1515 
1516     // Helper for computing the necessary information to lookup a layer
1517     // in the registry or open the layer.
1518     struct _FindOrOpenLayerInfo;
1519     static bool _ComputeInfoToFindOrOpenLayer(
1520         const std::string& identifier,
1521         const SdfLayer::FileFormatArguments& args,
1522         _FindOrOpenLayerInfo* info,
1523         bool computeAssetInfo = false);
1524 
1525     // Open a layer, adding an entry to the registry and releasing
1526     // the registry lock.
1527     // Precondition: _layerRegistryMutex must be locked.
1528     template <class Lock>
1529     static SdfLayerRefPtr _OpenLayerAndUnlockRegistry(
1530         Lock &lock,
1531         const _FindOrOpenLayerInfo& info,
1532         bool metadataOnly);
1533 
1534     // Helper function for finding a layer with \p identifier and \p args.
1535     // \p lock must be unlocked initially and will be locked by this
1536     // function when needed. See docs for \p retryAsWriter argument on
1537     // _TryToFindLayer for details on the final state of the lock when
1538     // this function returns.
1539     template <class ScopedLock>
1540     static SdfLayerRefPtr
1541     _Find(const std::string &identifier,
1542           const FileFormatArguments &args,
1543           ScopedLock &lock, bool retryAsWriter);
1544 
1545     // Helper function to try to find the layer with \p identifier and
1546     // pre-resolved path \p resolvedPath in the registry.  Caller must hold
1547     // registry \p lock for reading.  If \p retryAsWriter is false, lock is
1548     // released upon return.  Otherwise the lock is released upon return if a
1549     // layer is found successfully.  If no layer is found then the lock is
1550     // upgraded to a writer lock upon return.  Note that this upgrade may not be
1551     // atomic, but this function ensures that if upon return there does not
1552     // exist a matching layer in the registry.
1553     template <class ScopedLock>
1554     static SdfLayerRefPtr
1555     _TryToFindLayer(const std::string &identifier,
1556                     const std::string &resolvedPath,
1557                     ScopedLock &lock, bool retryAsWriter);
1558 
1559     /// Returns true if the spec at the specified path has no effect on the
1560     /// scene.
1561     ///
1562     /// If ignoreChildren is true, this will ignore prim and property
1563     /// children of prim specs. Property specs are always considered to be
1564     /// non-inert unless they have only required fields and
1565     /// requiredFieldOnlyPropertiesareInert is set to false.
1566     bool _IsInert(const SdfPath &path, bool ignoreChildren,
1567                   bool requiredFieldOnlyPropertiesAreInert = false) const;
1568 
1569     /// Return true if the entire subtree rooted at \a path does not affect the
1570     /// scene. For this purpose, property specs that have only required fields
1571     /// are considered inert.
1572     ///
1573     /// If this function returns true and \p inertSpecs is given, it will be
1574     /// populated with the paths to all inert prim and property specs at and
1575     /// beneath \p path. These paths will be sorted so that child paths
1576     /// appear before their parent path.
1577     bool _IsInertSubtree(const SdfPath &path,
1578                          std::vector<SdfPath>* inertSpecs = nullptr);
1579 
1580     /// Cause \p spec to be removed if it does not affect the scene. This
1581     /// removes any empty descendants before checking if \p spec itself is
1582     /// inert. Property specs are always considered non-inert, so this will
1583     /// remove them if they have only required fields (see
1584     /// PropertySpec::HasOnlyRequiredFields). This also removes inert ancestors.
1585     void _RemoveIfInert(const SdfSpec& spec);
1586 
1587     /// Performs a depth first search of the namespace hierarchy, beginning at
1588     /// \p prim, removing prims that do not affect the scene. The return value
1589     /// indicates whether the prim passed in is now inert as a result of this
1590     /// call, and can itself be removed.
1591     bool _RemoveInertDFS(SdfPrimSpecHandle prim);
1592 
1593     /// If \p prim is inert (has no affect on the scene), removes prim, then
1594     /// prunes inert parent prims back to the root.
1595     void _RemoveInertToRootmost(SdfPrimSpecHandle prim);
1596 
1597     /// Returns whether this layer is validating authoring operations.
_ValidateAuthoring()1598     bool _ValidateAuthoring() const { return _validateAuthoring; }
1599 
1600     /// Returns the path used in the muted layers set.
1601     std::string _GetMutedPath() const;
1602 
1603     // If old and new asset path is given, rename all external prim
1604     // composition dependency referring to the old path.
1605     void _UpdatePrimCompositionDependencyPaths(
1606         const SdfPrimSpecHandle &parent,
1607         const std::string &oldLayerPath,
1608         const std::string &newLayerPath);
1609 
1610     // Set the clean state to the current state.
1611     void _MarkCurrentStateAsClean() const;
1612 
1613     // Return the field definition for \p fieldName if \p fieldName is a
1614     // required field for the spec type identified by \p path.
1615     inline SdfSchema::FieldDefinition const *
1616     _GetRequiredFieldDef(const SdfPath &path,
1617                          const TfToken &fieldName,
1618                          SdfSpecType specType = SdfSpecTypeUnknown) const;
1619 
1620     // Return the field definition for \p fieldName if \p fieldName is a
1621     // required field for \p specType subject to \p schema.
1622     static inline SdfSchema::FieldDefinition const *
1623     _GetRequiredFieldDef(const SdfSchemaBase &schema,
1624                          const TfToken &fieldName,
1625                          SdfSpecType specType);
1626 
1627     // Helper to list all fields on \p data at \p path subject to \p schema.
1628     static std::vector<TfToken>
1629     _ListFields(SdfSchemaBase const &schema,
1630                 SdfAbstractData const &data, const SdfPath& path);
1631 
1632     // Helper for HasField for \p path in \p data subject to \p schema.
1633     static inline bool
1634     _HasField(const SdfSchemaBase &schema,
1635               const SdfAbstractData &data,
1636               const SdfPath& path,
1637               const TfToken& fieldName,
1638               VtValue *value);
1639 
1640     // Helper to get a field value for \p path in \p data subject to \p schema.
1641     static inline VtValue
1642     _GetField(const SdfSchemaBase &schema,
1643               const SdfAbstractData &data,
1644               const SdfPath& path,
1645               const TfToken& fieldName);
1646 
1647     // Set a value.
1648     template <class T>
1649     void _SetValue(const TfToken& key, T value);
1650 
1651     // Get a value.
1652     template <class T>
1653     T _GetValue(const TfToken& key) const;
1654 
1655     enum _ReloadResult { _ReloadFailed, _ReloadSucceeded, _ReloadSkipped };
1656     _ReloadResult _Reload(bool force);
1657 
1658     // Reads contents of asset specified by \p identifier with resolved
1659     // path \p resolvedPath into this layer.
1660     bool _Read(const std::string& identifier,
1661                const std::string& resolvedPath,
1662                bool metadataOnly);
1663 
1664     // Saves this layer if it is dirty or the layer doesn't already exist
1665     // on disk. If \p force is true, the layer will be written out
1666     // regardless of those conditions.
1667     bool _Save(bool force) const;
1668 
1669     // A helper method used by Save and Export.
1670     // This method allows Save to specify the existing file format and Export
1671     // to use the format provided by the file extension in newFileName. If no
1672     // file format can be discovered from the file name, the existing file
1673     // format associated with the layer will be used in both cases. This allows
1674     // users to export and save to any file name, regardless of extension.
1675     bool _WriteToFile(const std::string& newFileName,
1676                       const std::string& comment,
1677                       SdfFileFormatConstPtr fileFormat = TfNullPtr,
1678                       const FileFormatArguments& args = FileFormatArguments())
1679                       const;
1680 
1681     // Swap contents of _data and data. This operation does not register
1682     // inverses or emit change notification.
1683     void _SwapData(SdfAbstractDataRefPtr &data);
1684 
1685     // Set _data to match data, calling other primitive setter methods to
1686     // provide fine-grained inverses and notification.  If \p data might adhere
1687     // to a different schema than this layer's, pass a pointer to it as \p
1688     // newDataSchema.  In this case, check to see if fields from \p data are
1689     // known to this layer's schema, and if not, omit them and issue a TfError
1690     // with SdfAuthoringErrorUnrecognizedFields, but continue to set all other
1691     // known fields.
1692     void _SetData(const SdfAbstractDataPtr &newData,
1693                   const SdfSchemaBase *newDataSchema=nullptr);
1694 
1695     // Returns const handle to _data.
1696     SdfAbstractDataConstPtr _GetData() const;
1697 
1698     // Inverse primitive for setting a single field.
1699     template <class T>
1700     void _PrimSetField(const SdfPath& path,
1701                        const TfToken& fieldName,
1702                        const T& value,
1703                        const VtValue *oldValue = NULL,
1704                        bool useDelegate = true);
1705 
1706     // Inverse primitive for setting a single key in a dict-valued field.
1707     template <class T>
1708     void _PrimSetFieldDictValueByKey(const SdfPath& path,
1709                                      const TfToken& fieldName,
1710                                      const TfToken& keyPath,
1711                                      const T& value,
1712                                      const VtValue *oldValue = NULL,
1713                                      bool useDelegate = true);
1714 
1715     // Primitive for appending a child to the list of children.
1716     template <class T>
1717     void _PrimPushChild(const SdfPath& parentPath,
1718                         const TfToken& fieldName,
1719                         const T& value,
1720                         bool useDelegate = true);
1721     template <class T>
1722     void _PrimPopChild(const SdfPath& parentPath,
1723                        const TfToken& fieldName,
1724                        bool useDelegate = true);
1725 
1726     // Move all the fields at all paths at or below \a oldPath to be
1727     // at a corresponding location at or below \a newPath. This does
1728     // not update the children fields of the parents of these paths.
1729     bool _MoveSpec(const SdfPath &oldPath, const SdfPath &newPath);
1730 
1731     // Inverse primitive for moving a spec.
1732     void _PrimMoveSpec(const SdfPath &oldPath, const SdfPath &newPath,
1733                        bool useDelegate = true);
1734 
1735     // Create a new spec of type \p specType at \p path.
1736     // Returns true if spec was successfully created, false otherwise.
1737     bool _CreateSpec(const SdfPath& path, SdfSpecType specType, bool inert);
1738 
1739     // Delete all the fields at or below the specified path. This does
1740     // not update the children field of the parent of \a path.
1741     bool _DeleteSpec(const SdfPath &path);
1742 
1743     // Inverse primitive for deleting a spec.
1744     void _PrimCreateSpec(const SdfPath &path, SdfSpecType specType, bool inert,
1745                          bool useDelegate = true);
1746 
1747     // Inverse primitive for deleting a spec.
1748     void _PrimDeleteSpec(const SdfPath &path, bool inert,
1749                          bool useDelegate = true);
1750 
1751     // Inverse primitive for setting time samples.
1752     template <class T>
1753     void _PrimSetTimeSample(const SdfPath& path, double time,
1754                             const T& value,
1755                             bool useDelegate = true);
1756 
1757     // Helper method for Traverse. Visits the children of \a path using the
1758     // specified \a ChildPolicy.
1759     template <typename ChildPolicy>
1760     void _TraverseChildren(const SdfPath &path, const TraversalFunction &func);
1761 
1762 private:
1763     SdfLayerHandle _self;
1764 
1765     // File format and arguments for this layer.
1766     SdfFileFormatConstPtr _fileFormat;
1767     FileFormatArguments _fileFormatArgs;
1768 
1769     // Registry of Sdf Identities
1770     mutable Sdf_IdentityRegistry _idRegistry;
1771 
1772     // The underlying SdfData which stores all the data in the layer.
1773     SdfAbstractDataRefPtr _data;
1774 
1775     // The state delegate for this layer.
1776     SdfLayerStateDelegateBaseRefPtr _stateDelegate;
1777 
1778     // Atomic variable protecting layer initialization -- the interval between
1779     // adding a layer to the layer registry and finishing the process of
1780     // initializing its contents, at which point we can truly publish the layer
1781     // for consumption by concurrent threads. We add the layer to the registry
1782     // before initialization completes so that other threads can discover and
1783     // wait for it to finish initializing.
1784     std::atomic<bool> _initializationComplete;
1785 
1786     // This is an optional<bool> that is only set once initialization
1787     // is complete, while _initializationMutex is locked.  If the
1788     // optional<bool> is unset, initialization is still underway.
1789     boost::optional<bool> _initializationWasSuccessful;
1790 
1791     // remembers the last 'IsDirty' state.
1792     mutable bool _lastDirtyState;
1793 
1794     // Asset information for this layer.
1795     std::unique_ptr<Sdf_AssetInfo> _assetInfo;
1796 
1797     // Modification timestamp of the backing file asset when last read.
1798     mutable VtValue _assetModificationTime;
1799 
1800     // All external asset dependencies, with their modification timestamps, of
1801     // the layer when last read.
1802     mutable VtDictionary _externalAssetModificationTimes;
1803 
1804     // Mutable revision number for cache invalidation.
1805     mutable size_t _mutedLayersRevisionCache;
1806 
1807     // Cache of whether or not this layer is muted.  Only valid if
1808     // _mutedLayersRevisionCache is up-to-date with the global revision number.
1809     mutable bool _isMutedCache;
1810 
1811     // Layer permission bits.
1812     bool _permissionToEdit;
1813     bool _permissionToSave;
1814 
1815     // Whether layer edits are validated.
1816     bool _validateAuthoring;
1817 
1818     // Layer hints as of the most recent save operation.
1819     mutable SdfLayerHints _hints;
1820 
1821     // Allow access to _ValidateAuthoring() and _IsInert().
1822     friend class SdfSpec;
1823     friend class SdfPropertySpec;
1824     friend class SdfAttributeSpec;
1825 
1826     friend class Sdf_ChangeManager;
1827 
1828     // Allow access to _CreateSpec and _DeleteSpec and _MoveSpec
1829     template <class ChildPolicy> friend class Sdf_ChildrenUtils;
1830 
1831     // Give the file format access to our data.  Limit breaking encapsulation
1832     // to the base SdFileFormat class so we don't have to friend every
1833     // implementation here.
1834     friend class SdfFileFormat;
1835 
1836     // Give layer state delegates access to our data as well as to
1837     // the various _Prim functions.
1838     friend class SdfLayerStateDelegateBase;
1839 };
1840 
1841 PXR_NAMESPACE_CLOSE_SCOPE
1842 
1843 #endif // PXR_USD_SDF_LAYER_H
1844