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_USD_STAGE_H
25 #define PXR_USD_USD_STAGE_H
26 
27 /// \file usd/stage.h
28 
29 #include "pxr/pxr.h"
30 #include "pxr/usd/usd/api.h"
31 #include "pxr/usd/usd/common.h"
32 #include "pxr/usd/usd/editTarget.h"
33 #include "pxr/usd/usd/interpolation.h"
34 #include "pxr/usd/usd/schemaRegistry.h"
35 #include "pxr/usd/usd/stageLoadRules.h"
36 #include "pxr/usd/usd/stagePopulationMask.h"
37 #include "pxr/usd/usd/primFlags.h"
38 
39 #include "pxr/base/tf/declarePtrs.h"
40 #include "pxr/base/tf/hashmap.h"
41 #include "pxr/base/tf/weakBase.h"
42 
43 #include "pxr/usd/ar/ar.h"
44 #include "pxr/usd/ar/notice.h"
45 #include "pxr/usd/sdf/declareHandles.h"
46 #include "pxr/usd/sdf/notice.h"
47 #include "pxr/usd/sdf/path.h"
48 #include "pxr/usd/sdf/types.h"
49 #include "pxr/usd/pcp/cache.h"
50 #include "pxr/base/vt/value.h"
51 #include "pxr/base/work/dispatcher.h"
52 
53 #include <boost/optional.hpp>
54 
55 #include <tbb/concurrent_vector.h>
56 #include <tbb/concurrent_unordered_set.h>
57 #include <tbb/spin_rw_mutex.h>
58 
59 #include <functional>
60 #include <string>
61 #include <memory>
62 #include <unordered_map>
63 #include <utility>
64 
65 PXR_NAMESPACE_OPEN_SCOPE
66 
67 
68 class ArResolverContext;
69 class GfInterval;
70 class SdfAbstractDataValue;
71 class Usd_ClipCache;
72 class Usd_InstanceCache;
73 class Usd_InstanceChanges;
74 class Usd_InterpolatorBase;
75 class UsdResolveInfo;
76 class Usd_Resolver;
77 class UsdPrim;
78 class UsdPrimRange;
79 
80 SDF_DECLARE_HANDLES(SdfLayer);
81 
82 /// \class UsdStage
83 ///
84 /// The outermost container for scene description, which owns and presents
85 /// composed prims as a scenegraph, following the composition recipe
86 /// recursively described in its associated "root layer".
87 ///
88 /// USD derives its persistent-storage scalability by combining and reusing
89 /// simple compositions into richer aggregates using referencing and layering
90 /// with sparse overrides.  Ultimately, every composition (i.e. "scene") is
91 /// identifiable by its root layer, i.e. the <tt>.usd</tt> file, and a scene
92 /// is instantiated in an application on a UsdStage that presents a composed
93 /// view of the scene's root layer.  Each simple composition referenced into
94 /// a larger composition could be presented on its own UsdStage, at the same
95 /// (or not) time that it is participating in the larger composition on its
96 /// own UsdStage; all of the underlying layers will be shared by the two
97 /// stages, while each maintains its own scenegraph of composed prims.
98 ///
99 /// A UsdStage has sole ownership over the UsdPrim 's with which it is populated,
100 /// and retains \em shared ownership (with other stages and direct clients of
101 /// SdfLayer's, via the Sdf_LayerRegistry that underlies all SdfLayer creation
102 /// methods) of layers.  It provides roughly five categories of API that
103 /// address different aspects of scene management:
104 ///
105 /// - \ref Usd_lifetimeManagement "Stage lifetime management" methods for
106 /// constructing and initially populating a UsdStage from an existing layer
107 /// file, or one that will be created as a result, in memory or on the
108 /// filesystem.
109 /// - \ref Usd_workingSetManagement "Load/unload working set management" methods
110 /// that allow you to specify which \ref Usd_Payloads "payloads" should be
111 /// included and excluded from the stage's composition.
112 /// - \ref Usd_variantManagement "Variant management" methods to manage
113 /// policy for which variant to use when composing prims that provide
114 /// a named variant set, but do not specify a selection.
115 /// - \ref Usd_primManagement "Prim access, creation, and mutation" methods
116 /// that allow you to find, create, or remove a prim identified by a path on
117 /// the stage.  This group also provides methods for efficiently traversing the
118 /// prims on the stage.
119 /// - \ref Usd_layerManagement "Layers and EditTargets" methods provide access
120 /// to the layers in the stage's <em>root LayerStack</em> (i.e. the root layer
121 /// and all of its recursive sublayers), and the ability to set a UsdEditTarget
122 /// into which all subsequent mutations to objects associated with the stage
123 /// (e.g. prims, properties, etc) will go.
124 /// - \ref Usd_stageSerialization "Serialization" methods for "flattening" a
125 /// composition (to varying degrees), and exporting a completely flattened
126 /// view of the stage to a string or file.  These methods can be very useful
127 /// for targeted asset optimization and debugging, though care should be
128 /// exercized with large scenes, as flattening defeats some of the benefits of
129 /// referenced scene description, and may produce very large results,
130 /// especially in file formats that do not support data de-duplication, like
131 /// the usda ASCII format!
132 ///
133 /// \section Usd_SessionLayer Stage Session Layers
134 ///
135 /// Each UsdStage can possess an optional "session layer".  The purpose of
136 /// a session layer is to hold ephemeral edits that modify a UsdStage's contents
137 /// or behavior in a way that is useful to the client, but should not be
138 /// considered as permanent mutations to be recorded upon export.  A very
139 /// common use of session layers is to make variant selections, to pick a
140 /// specific LOD or shading variation, for example.  The session layer is
141 /// also frequently used to perform interactive vising/invsning of geometry
142 /// and assets in the scene.   A session layer, if present, contributes to a
143 /// UsdStage's identity, for purposes of stage-caching, etc.
144 ///
145 class UsdStage : public TfRefBase, public TfWeakBase {
146 public:
147 
148     // --------------------------------------------------------------------- //
149     /// \anchor Usd_lifetimeManagement
150     /// \name Lifetime Management
151     /// @{
152     // --------------------------------------------------------------------- //
153 
154     /// \enum InitialLoadSet
155     ///
156     /// Specifies the initial set of prims to load when opening a UsdStage.
157     ///
158     enum InitialLoadSet
159     {
160         LoadAll, ///< Load all loadable prims
161         LoadNone ///< Load no loadable prims
162     };
163 
164     /// Create a new stage with root layer \p identifier, destroying
165     /// potentially existing files with that identifier; it is considered an
166     /// error if an existing, open layer is present with this identifier.
167     ///
168     /// \sa SdfLayer::CreateNew()
169     ///
170     /// Invoking an overload that does not take a \p sessionLayer argument will
171     /// create a stage with an anonymous in-memory session layer.  To create a
172     /// stage without a session layer, pass TfNullPtr (or None in python) as the
173     /// \p sessionLayer argument.
174     //
175     /// The initial set of prims to load on the stage can be specified
176     /// using the \p load parameter. \sa UsdStage::InitialLoadSet.
177     ///
178     /// If \p pathResolverContext is provided it will be bound when creating the
179     /// root layer at \p identifier and whenever asset path resolution is done
180     /// for this stage, regardless of what other context may be bound at that
181     /// time. Otherwise Usd will create the root layer with no context bound,
182     /// then create a context for all future asset path resolution for the stage
183     /// by calling ArResolver::CreateDefaultContextForAsset with the root
184     /// layer's repository path if the layer has one, otherwise its resolved
185     /// path.
186     USD_API
187     static UsdStageRefPtr
188     CreateNew(const std::string& identifier,
189               InitialLoadSet load = LoadAll);
190     /// \overload
191     USD_API
192     static UsdStageRefPtr
193     CreateNew(const std::string& identifier,
194               const SdfLayerHandle& sessionLayer,
195               InitialLoadSet load = LoadAll);
196     /// \overload
197     USD_API
198     static UsdStageRefPtr
199     CreateNew(const std::string& identifier,
200               const SdfLayerHandle& sessionLayer,
201               const ArResolverContext& pathResolverContext,
202               InitialLoadSet load = LoadAll);
203     /// \overload
204     USD_API
205     static UsdStageRefPtr
206     CreateNew(const std::string& identifier,
207               const ArResolverContext& pathResolverContext,
208               InitialLoadSet load = LoadAll);
209 
210     /// Creates a new stage only in memory, analogous to creating an
211     /// anonymous SdfLayer.
212     ///
213     /// If \p pathResolverContext is provided it will be bound when creating the
214     /// root layer at \p identifier and whenever asset path resolution is done
215     /// for this stage, regardless of what other context may be bound at that
216     /// time. Otherwise Usd will create the root layer with no context bound,
217     /// then create a context for all future asset path resolution for the stage
218     /// by calling ArResolver::CreateDefaultContext.
219     ///
220     /// The initial set of prims to load on the stage can be specified
221     /// using the \p load parameter. \sa UsdStage::InitialLoadSet.
222     ///
223     /// Invoking an overload that does not take a \p sessionLayer argument will
224     /// create a stage with an anonymous in-memory session layer.  To create a
225     /// stage without a session layer, pass TfNullPtr (or None in python) as the
226     /// \p sessionLayer argument.
227     USD_API
228     static UsdStageRefPtr
229     CreateInMemory(InitialLoadSet load = LoadAll);
230     /// \overload
231     USD_API
232     static UsdStageRefPtr
233     CreateInMemory(const std::string& identifier,
234                    InitialLoadSet load = LoadAll);
235     /// \overload
236     USD_API
237     static UsdStageRefPtr
238     CreateInMemory(const std::string& identifier,
239                    const ArResolverContext& pathResolverContext,
240                    InitialLoadSet load = LoadAll);
241     /// \overload
242     USD_API
243     static UsdStageRefPtr
244     CreateInMemory(const std::string& identifier,
245                    const SdfLayerHandle &sessionLayer,
246                    InitialLoadSet load = LoadAll);
247     /// \overload
248     USD_API
249     static UsdStageRefPtr
250     CreateInMemory(const std::string& identifier,
251                    const SdfLayerHandle &sessionLayer,
252                    const ArResolverContext& pathResolverContext,
253                    InitialLoadSet load = LoadAll);
254 
255     /// Attempt to find a matching existing stage in a cache if
256     /// UsdStageCacheContext objects exist on the stack. Failing that, create a
257     /// new stage and recursively compose prims defined within and referenced by
258     /// the layer at \p filePath, which must already exist.
259     ///
260     /// The initial set of prims to load on the stage can be specified
261     /// using the \p load parameter. \sa UsdStage::InitialLoadSet.
262     ///
263     /// If \p pathResolverContext is provided it will be bound when opening the
264     /// root layer at \p filePath and whenever asset path resolution is done for
265     /// this stage, regardless of what other context may be bound at that
266     /// time. Otherwise Usd will open the root layer with no context bound, then
267     /// create a context for all future asset path resolution for the stage by
268     /// calling ArResolver::CreateDefaultContextForAsset with the layer's
269     /// repository path if the layer has one, otherwise its resolved path.
270     USD_API
271     static UsdStageRefPtr
272     Open(const std::string& filePath, InitialLoadSet load = LoadAll);
273     /// \overload
274     USD_API
275     static UsdStageRefPtr
276     Open(const std::string& filePath,
277          const ArResolverContext& pathResolverContext,
278          InitialLoadSet load = LoadAll);
279 
280     /// Create a new stage and recursively compose prims defined within and
281     /// referenced by the layer at \p filePath which must already exist, subject
282     /// to \p mask.
283     ///
284     /// These OpenMasked() methods do not automatically consult or populate
285     /// UsdStageCache s.
286     ///
287     /// The initial set of prims to load on the stage can be specified
288     /// using the \p load parameter. \sa UsdStage::InitialLoadSet.
289     ///
290     /// If \p pathResolverContext is provided it will be bound when opening the
291     /// root layer at \p filePath and whenever asset path resolution is done for
292     /// this stage, regardless of what other context may be bound at that
293     /// time. Otherwise Usd will open the root layer with no context bound, then
294     /// create a context for all future asset path resolution for the stage by
295     /// calling ArResolver::CreateDefaultContextForAsset with the layer's
296     /// repository path if the layer has one, otherwise its resolved path.
297     USD_API
298     static UsdStageRefPtr
299     OpenMasked(const std::string &filePath,
300                UsdStagePopulationMask const &mask,
301                InitialLoadSet load = LoadAll);
302     /// \overload
303     USD_API
304     static UsdStageRefPtr
305     OpenMasked(const std::string &filePath,
306                const ArResolverContext &pathResolverContext,
307                UsdStagePopulationMask const &mask,
308                InitialLoadSet load = LoadAll);
309 
310     /// Open a stage rooted at \p rootLayer.
311     ///
312     /// Attempt to find a stage that matches the passed arguments in a
313     /// UsdStageCache if UsdStageCacheContext objects exist on the calling
314     /// stack.  If a matching stage is found, return that stage.  Otherwise,
315     /// create a new stage rooted at \p rootLayer.
316     ///
317     /// Invoking an overload that does not take a \p sessionLayer argument will
318     /// create a stage with an anonymous in-memory session layer.  To create a
319     /// stage without a session layer, pass TfNullPtr (or None in python) as the
320     /// \p sessionLayer argument.
321     ///
322     /// The initial set of prims to load on the stage can be specified
323     /// using the \p load parameter. \sa UsdStage::InitialLoadSet.
324     ///
325     /// If \p pathResolverContext is provided it will be bound when whenever
326     /// asset path resolution is done for this stage, regardless of what other
327     /// context may be bound at that time. Otherwise Usd will create a context
328     /// for all future asset path resolution for the stage by calling
329     /// ArResolver::CreateDefaultContextForAsset with the layer's repository
330     /// path if the layer has one, otherwise its resolved path.
331     ///
332     /// When searching for a matching stage in bound UsdStageCache s, only the
333     /// provided arguments matter for cache lookup.  For example, if only a root
334     /// layer (or a root layer file path) is provided, the first stage found in
335     /// any cache that has that root layer is returned.  So, for example if you
336     /// require that the stage have no session layer, you must explicitly
337     /// specify TfNullPtr (or None in python) for the sessionLayer argument.
338     USD_API
339     static UsdStageRefPtr
340     Open(const SdfLayerHandle& rootLayer,
341          InitialLoadSet load=LoadAll);
342     /// \overload
343     USD_API
344     static UsdStageRefPtr
345     Open(const SdfLayerHandle& rootLayer,
346          const SdfLayerHandle& sessionLayer,
347          InitialLoadSet load=LoadAll);
348     /// \overload
349     USD_API
350     static UsdStageRefPtr
351     Open(const SdfLayerHandle& rootLayer,
352          const ArResolverContext& pathResolverContext,
353          InitialLoadSet load=LoadAll);
354     /// \overload
355     USD_API
356     static UsdStageRefPtr
357     Open(const SdfLayerHandle& rootLayer,
358          const SdfLayerHandle& sessionLayer,
359          const ArResolverContext& pathResolverContext,
360          InitialLoadSet load=LoadAll);
361 
362     /// Open a stage rooted at \p rootLayer and with limited population subject
363     /// to \p mask.
364     ///
365     /// These OpenMasked() methods do not automatically consult or populate
366     /// UsdStageCache s.
367     ///
368     /// Invoking an overload that does not take a \p sessionLayer argument will
369     /// create a stage with an anonymous in-memory session layer.  To create a
370     /// stage without a session layer, pass TfNullPtr (or None in python) as the
371     /// \p sessionLayer argument.
372     ///
373     /// The initial set of prims to load on the stage can be specified
374     /// using the \p load parameter. \sa UsdStage::InitialLoadSet.
375     ///
376     /// If \p pathResolverContext is provided it will be bound when whenever
377     /// asset path resolution is done for this stage, regardless of what other
378     /// context may be bound at that time. Otherwise Usd will create a context
379     /// for all future asset path resolution for the stage by calling
380     /// ArResolver::CreateDefaultContextForAsset with the layer's repository
381     /// path if the layer has one, otherwise its resolved path.
382     USD_API
383     static UsdStageRefPtr
384     OpenMasked(const SdfLayerHandle& rootLayer,
385                const UsdStagePopulationMask &mask,
386                InitialLoadSet load=LoadAll);
387     /// \overload
388     USD_API
389     static UsdStageRefPtr
390     OpenMasked(const SdfLayerHandle& rootLayer,
391                const SdfLayerHandle& sessionLayer,
392                const UsdStagePopulationMask &mask,
393                InitialLoadSet load=LoadAll);
394     /// \overload
395     USD_API
396     static UsdStageRefPtr
397     OpenMasked(const SdfLayerHandle& rootLayer,
398                const ArResolverContext& pathResolverContext,
399                const UsdStagePopulationMask &mask,
400                InitialLoadSet load=LoadAll);
401     /// \overload
402     USD_API
403     static UsdStageRefPtr
404     OpenMasked(const SdfLayerHandle& rootLayer,
405                const SdfLayerHandle& sessionLayer,
406                const ArResolverContext& pathResolverContext,
407                const UsdStagePopulationMask &mask,
408                InitialLoadSet load=LoadAll);
409 
410     USD_API
411     virtual ~UsdStage();
412 
413     /// Calls SdfLayer::Reload on all layers contributing to this stage,
414     /// except session layers and sublayers of session layers.
415     ///
416     /// This includes non-session sublayers, references and payloads.
417     /// Note that reloading anonymous layers clears their content, so
418     /// invoking Reload() on a stage constructed via CreateInMemory()
419     /// will clear its root layer.
420     ///
421     /// \note This method is considered a mutation, which has potentially
422     /// global effect!  Unlike the various Load() methods whose actions
423     /// affect only **this stage**, Reload() may cause layers to change their
424     /// contents, and because layers are global resources shared by
425     /// potentially many Stages, calling Reload() on one stage may result in
426     /// a mutation to any number of stages.  In general, unless you are
427     /// highly confident your stage is the only consumer of its layers, you
428     /// should only call Reload() when you are assured no other threads may
429     /// be reading from any Stages.
430     USD_API
431     void Reload();
432 
433     /// Indicates whether the specified file is supported by UsdStage.
434     ///
435     /// This function is a cheap way to determine whether a
436     /// file might be open-able with UsdStage::Open. It is
437     /// purely based on the given \p filePath and does not
438     /// open the file or perform analysis on the contents.
439     /// As such, UsdStage::Open may still fail even if this
440     /// function returns true.
441     USD_API
442     static bool
443     IsSupportedFile(const std::string& filePath);
444 
445     /// @}
446 
447     // --------------------------------------------------------------------- //
448     /// \anchor Usd_layerSerialization
449     /// \name Layer Serialization
450     ///
451     /// Functions for saving changes to layers that contribute opinions to
452     /// this stage.  Layers may also be saved by calling SdfLayer::Save or
453     /// exported to a new file by calling SdfLayer::Export.
454     ///
455     /// @{
456 
457     /// Calls SdfLayer::Save on all dirty layers contributing to this stage
458     /// except session layers and sublayers of session layers.
459     ///
460     /// This function will emit a warning and skip each dirty anonymous
461     /// layer it encounters, since anonymous layers cannot be saved with
462     /// SdfLayer::Save. These layers must be manually exported by calling
463     /// SdfLayer::Export.
464     USD_API
465     void Save();
466 
467     /// Calls SdfLayer::Save on all dirty session layers and sublayers of
468     /// session layers contributing to this stage.
469     ///
470     /// This function will emit a warning and skip each dirty anonymous
471     /// layer it encounters, since anonymous layers cannot be saved with
472     /// SdfLayer::Save. These layers must be manually exported by calling
473     /// SdfLayer::Export.
474     USD_API
475     void SaveSessionLayers();
476 
477     /// @}
478 
479     // --------------------------------------------------------------------- //
480     /// \anchor Usd_variantManagement
481     /// \name Variant Management
482     ///
483     /// These methods provide control over the policy to use when composing
484     /// prims that specify a variant set but do not specify a selection.
485     ///
486     /// The first is to declare a list of preferences in plugInfo.json
487     /// metadata on a plugin using this structure:
488     ///
489     /// \code{.json}
490     ///     "UsdVariantFallbacks": {    # top level key
491     ///         "shadingComplexity": [  # example variant set
492     ///             "full",             # example fallback #1
493     ///             "light"             # example fallback #2
494     ///         ]
495     ///     },
496     /// \endcode
497     ///
498     /// This example ensures that we will get the "full" shadingComplexity
499     /// for any prim with a shadingComplexity VariantSet that doesn't
500     /// otherwise specify a selection, \em and has a "full" variant; if its
501     /// shadingComplexity does not have a "full" variant, but \em does have
502     /// a "light" variant, then the selection will be "light".  In other
503     /// words, the entries in the "shadingComplexity" list in the plugInfo.json
504     /// represent a priority-ordered list of fallback selections.
505     ///
506     /// The plugin metadata is discovered and applied before the first
507     /// UsdStage is constructed in a given process.  It can be defined
508     /// in any plugin.  However, if multiple plugins express contrary
509     /// lists for the same named variant set, the result is undefined.
510     ///
511     /// The plugin metadata approach is useful for ensuring that sensible
512     /// default behavior applies across a pipeline without requiring
513     /// every script and binary to explicitly configure every VariantSet
514     /// that subscribes to fallback in the pipeline.
515     /// There may be times when you want to override this behavior in a
516     /// particular script -- for example, a pipeline script that knows
517     /// it wants to entirely ignore shading in order to minimize
518     /// processing time -- which motivates the second approach.
519     ///
520     /// SetGlobalVariantFallbacks() provides a way to override, for
521     /// the entire process, which fallbacks to use in subsequently
522     /// constructed UsdStage instances.
523     ///
524     /// @{
525 
526     /// Get the global variant fallback preferences used in new UsdStages.
527     USD_API
528     static PcpVariantFallbackMap GetGlobalVariantFallbacks();
529 
530     /// Set the global variant fallback preferences used in new
531     /// UsdStages. This overrides any fallbacks configured in plugin
532     /// metadata, and only affects stages created after this call.
533     ///
534     /// \note This does not affect existing UsdStages.
535     USD_API
536     static void
537     SetGlobalVariantFallbacks(const PcpVariantFallbackMap &fallbacks);
538 
539     /// @}
540 
541     // --------------------------------------------------------------------- //
542     /// \anchor Usd_workingSetManagement
543     /// \name Working Set Management
544     ///
545     /// The following rules apply to all Load/Unload methods:
546     ///
547     ///     - Loading an already loaded prim is legal, though may result in
548     ///       some recomposition cost. Similarly, unloading an unloaded prim
549     ///       is legal.
550     ///     - Specifying a path that does not target a prim is legal as long it
551     ///       has an ancestor present in the scene graph (other than the
552     ///       absolute root). If the given path has no such ancestor, it is an
553     ///       error.
554     ///     - Specifying a path to an inactive prim is an error.
555     ///     - Specifying a path to a prototype prim or a prim within a
556     ///       prototype is an error.
557     ///
558     /// If an instance prim (or a path identifying a prim descendant to an
559     /// instance) is encountered during a Load/Unload operation, these functions
560     /// may cause instancing to change on the stage in order to ensure that no
561     /// other instances are affected.  The load/unload rules that affect a given
562     /// prim hierarchy are considered when determining which prims can be
563     /// instanced together.  Instance sharing occurs when different instances
564     /// have equivalent load rules.
565     ///
566     /// The GetLoadRules() and SetLoadRules() provide direct low-level access to
567     /// the UsdStageLoadRules that govern payload inclusion on a stage.
568     ///
569     /// @{
570     // --------------------------------------------------------------------- //
571 
572     /// Modify this stage's load rules to load the prim at \p path, its
573     /// ancestors, and all of its descendants if \p policy is
574     /// UsdLoadWithDescendants.  If \p policy is UsdLoadWithoutDescendants, then
575     /// payloads on descendant prims are not loaded.
576     ///
577     /// See \ref Usd_workingSetManagement "Working Set Management" for more
578     /// information.
579     USD_API
580     UsdPrim Load(const SdfPath& path=SdfPath::AbsoluteRootPath(),
581                  UsdLoadPolicy policy=UsdLoadWithDescendants);
582 
583     /// Modify this stage's load rules to unload the prim and its descendants
584     /// specified by \p path.
585     ///
586     /// See \ref Usd_workingSetManagement "Working Set Management" for more
587     /// information.
588     USD_API
589     void Unload(const SdfPath& path=SdfPath::AbsoluteRootPath());
590 
591     /// Unload and load the given path sets.  The effect is as if the unload set
592     /// were processed first followed by the load set.
593     ///
594     /// This is equivalent to calling UsdStage::Unload for each item in the
595     /// unloadSet followed by UsdStage::Load for each item in the loadSet,
596     /// however this method is more efficient as all operations are committed in
597     /// a single batch.  The \p policy argument is described in the
598     /// documentation for Load().
599     ///
600     /// See \ref Usd_workingSetManagement "Working Set Management" for more
601     /// information.
602     USD_API
603     void LoadAndUnload(const SdfPathSet &loadSet, const SdfPathSet &unloadSet,
604                        UsdLoadPolicy policy=UsdLoadWithDescendants);
605 
606     /// Returns a set of all loaded paths.
607     ///
608     /// The paths returned are both those that have been explicitly loaded and
609     /// those that were loaded as a result of dependencies, ancestors or
610     /// descendants of explicitly loaded paths.
611     ///
612     /// This method does not return paths to inactive prims.
613     ///
614     /// See \ref Usd_workingSetManagement "Working Set Management" for more
615     /// information.
616     USD_API
617     SdfPathSet GetLoadSet();
618 
619     /// Returns an SdfPathSet of all paths that can be loaded.
620     ///
621     /// Note that this method does not return paths to inactive prims as they
622     /// cannot be loaded.
623     ///
624     /// The set returned includes loaded and unloaded paths. To determine the
625     /// set of unloaded paths, one can diff this set with the current load set,
626     /// for example:
627     /// \code
628     /// SdfPathSet loaded = stage->GetLoadSet(),
629     ///            all = stage->FindLoadable(),
630     ///            result;
631     /// std::set_difference(loaded.begin(), loaded.end(),
632     ///                     all.begin(), all.end(),
633     ///                     std::inserter(result, result.end()));
634     /// \endcode
635     ///
636     /// See \ref Usd_workingSetManagement "Working Set Management" for more
637     /// information.
638     USD_API
639     SdfPathSet FindLoadable(
640         const SdfPath& rootPath = SdfPath::AbsoluteRootPath());
641 
642     /// Return the stage's current UsdStageLoadRules governing payload
643     /// inclusion.
644     ///
645     /// See \ref Usd_workingSetManagement "Working Set Management" for more
646     /// information.
GetLoadRules()647     UsdStageLoadRules const &GetLoadRules() const {
648         return _loadRules;
649     }
650 
651     /// Set the UsdStageLoadRules to govern payload inclusion on this stage.
652     /// This rebuilds the stage's entire prim hierarchy to follow \p rules.
653     ///
654     /// Note that subsequent calls to Load(), Unload(), LoadAndUnload() will
655     /// modify this stages load rules as described in the documentation for
656     /// those member functions.
657     ///
658     /// See \ref Usd_workingSetManagement "Working Set Management" for more
659     /// information.
660     USD_API
661     void SetLoadRules(UsdStageLoadRules const &rules);
662 
663     /// Return this stage's population mask.
GetPopulationMask()664     UsdStagePopulationMask GetPopulationMask() const {
665         return _populationMask;
666     }
667 
668     /// Set this stage's population mask and recompose the stage.
669     USD_API
670     void SetPopulationMask(UsdStagePopulationMask const &mask);
671 
672     /// Expand this stage's population mask to include the targets of all
673     /// relationships that pass \p relPred and connections to all attributes
674     /// that pass \p attrPred recursively.  If \p relPred is null, include all
675     /// relationship targets; if \p attrPred is null, include all connections.
676     ///
677     /// This function can be used, for example, to expand a population mask for
678     /// a given prim to include bound materials, if those bound materials are
679     /// expressed as relationships or attribute connections.
680     ///
681     /// See also UsdPrim::FindAllRelationshipTargetPaths() and
682     /// UsdPrim::FindAllAttributeConnectionPaths().
683     USD_API
684     void ExpandPopulationMask(
685         std::function<bool (UsdRelationship const &)> const &relPred = nullptr,
686         std::function<bool (UsdAttribute const &)> const &attrPred = nullptr);
687 
688     /// @}
689 
690     // --------------------------------------------------------------------- //
691     /// \anchor Usd_primManagement
692     /// \name Prim Access, Creation and Mutation
693     /// All of the methods in this group that accept a prim path as argument
694     /// require paths in the namespace of the stage's root layer, \em regardless
695     /// of what the currently active UsdEditTarget is set to.  In other words,
696     /// a UsdStage always presents a composed view of its scene, and all
697     /// prim operations are specified in the composed namespace.
698     /// @{
699     // --------------------------------------------------------------------- //
700 
701     /// Return the stage's "pseudo-root" prim, whose name is defined by Usd.
702     ///
703     /// The stage's named root prims are namespace children of this prim,
704     /// which exists to make the namespace hierarchy a tree instead of a
705     /// forest.  This simplifies algorithms that want to traverse all prims.
706     ///
707     /// A UsdStage always has a pseudo-root prim, unless there was an error
708     /// opening or creating the stage, in which case this method returns
709     /// an invalid UsdPrim.
710     USD_API
711     UsdPrim GetPseudoRoot() const;
712 
713     /// Return the root UsdPrim on this stage whose name is the root layer's
714     /// defaultPrim metadata's value.  Return an invalid prim if there is no
715     /// such prim or if the root layer's defaultPrim metadata is unset or is not
716     /// a valid prim name.  Note that this function only examines this stage's
717     /// rootLayer.  It does not consider sublayers of the rootLayer.  See also
718     /// SdfLayer::GetDefaultPrim().
719     USD_API
720     UsdPrim GetDefaultPrim() const;
721 
722     /// Set the default prim layer metadata in this stage's root layer.  This is
723     /// shorthand for:
724     /// \code
725     /// stage->GetRootLayer()->SetDefaultPrim(prim.GetName());
726     /// \endcode
727     /// Note that this function always authors to the stage's root layer.  To
728     /// author to a different layer, use the SdfLayer::SetDefaultPrim() API.
729     USD_API
730     void SetDefaultPrim(const UsdPrim &prim);
731 
732     /// Clear the default prim layer metadata in this stage's root layer.  This
733     /// is shorthand for:
734     /// \code
735     /// stage->GetRootLayer()->ClearDefaultPrim();
736     /// \endcode
737     /// Note that this function always authors to the stage's root layer.  To
738     /// author to a different layer, use the SdfLayer::SetDefaultPrim() API.
739     USD_API
740     void ClearDefaultPrim();
741 
742     /// Return true if this stage's root layer has an authored opinion for the
743     /// default prim layer metadata.  This is shorthand for:
744     /// \code
745     /// stage->GetRootLayer()->HasDefaultPrim();
746     /// \endcode
747     /// Note that this function only consults the stage's root layer.  To
748     /// consult a different layer, use the SdfLayer::HasDefaultPrim() API.
749     USD_API
750     bool HasDefaultPrim() const;
751 
752     /// Return the UsdPrim at \p path, or an invalid UsdPrim if none exists.
753     ///
754     /// If \p path indicates a prim beneath an instance, returns an instance
755     /// proxy prim if a prim exists at the corresponding path in that instance's
756     /// prototype.
757     ///
758     /// Unlike OverridePrim() and DefinePrim(), this method will never author
759     /// scene description, and therefore is safe to use as a "reader" in the Usd
760     /// multi-threading model.
761     USD_API
762     UsdPrim GetPrimAtPath(const SdfPath &path) const;
763 
764     /// Return the UsdObject at \p path, or an invalid UsdObject if none exists.
765     ///
766     /// If \p path indicates a prim beneath an instance, returns an instance
767     /// proxy prim if a prim exists at the corresponding path in that instance's
768     /// prototype. If \p path indicates a property beneath a child of an
769     /// instance, returns a property whose parent prim is an instance proxy
770     /// prim.
771     ///
772     /// Example:
773     ///
774     /// \code
775     ///if (UsdObject obj = stage->GetObjectAtPath(path)) {
776     ///    if (UsdPrim prim = obj.As<UsdPrim>()) {
777     ///        // Do things with prim
778     ///    }
779     ///    else if (UsdProperty prop = obj.As<UsdProperty>()) {
780     ///        // Do things with property. We can also cast to
781     ///        // UsdRelationship or UsdAttribute using this same pattern.
782     ///    }
783     ///}
784     ///else {
785     ///    // No object at specified path
786     ///}
787     /// \endcode
788     USD_API
789     UsdObject GetObjectAtPath(const SdfPath &path) const;
790 
791     /// Return the UsdProperty at \p path, or an invalid UsdProperty
792     /// if none exists.
793     ///
794     /// This is equivalent to
795     /// \code{.cpp}
796     /// stage.GetObjectAtPath(path).As<UsdProperty>();
797     /// \endcode
798     /// \sa GetObjectAtPath(const SdfPath&) const
799     USD_API
800     UsdProperty GetPropertyAtPath(const SdfPath &path) const;
801 
802     /// Return the UsdAttribute at \p path, or an invalid UsdAttribute
803     /// if none exists.
804     ///
805     /// This is equivalent to
806     /// \code{.cpp}
807     /// stage.GetObjectAtPath(path).As<UsdAttribute>();
808     /// \endcode
809     /// \sa GetObjectAtPath(const SdfPath&) const
810     USD_API
811     UsdAttribute GetAttributeAtPath(const SdfPath &path) const;
812 
813     /// Return the UsdAttribute at \p path, or an invalid UsdAttribute
814     /// if none exists.
815     ///
816     /// This is equivalent to
817     /// \code{.cpp}
818     /// stage.GetObjectAtPath(path).As<UsdRelationship>();
819     /// \endcode
820     /// \sa GetObjectAtPath(const SdfPath&) const
821     USD_API
822     UsdRelationship GetRelationshipAtPath(const SdfPath &path) const;
823 private:
824     // Return the primData object at \p path.
825     Usd_PrimDataConstPtr _GetPrimDataAtPath(const SdfPath &path) const;
826     Usd_PrimDataPtr _GetPrimDataAtPath(const SdfPath &path);
827 
828     // Return the primData object at \p path.  If \p path indicates a prim
829     // beneath an instance, return the primData object for the corresponding
830     // prim in the instance's prototype.
831     Usd_PrimDataConstPtr
832     _GetPrimDataAtPathOrInPrototype(const SdfPath &path) const;
833 
834     /// See documentation on UsdPrim::GetInstances()
835     std::vector<UsdPrim>
836     _GetInstancesForPrototype(const UsdPrim& prototype) const;
837 
838 public:
839 
840     /// Traverse the active, loaded, defined, non-abstract prims on this stage
841     /// depth-first.
842     ///
843     /// Traverse() returns a UsdPrimRange , which allows low-latency
844     /// traversal, with the ability to prune subtrees from traversal.  It
845     /// is python iterable, so in its simplest form, one can do:
846     ///
847     /// \code{.py}
848     /// for prim in stage.Traverse():
849     ///     print prim.GetPath()
850     /// \endcode
851     ///
852     /// If either a pre-and-post-order traversal or a traversal rooted at a
853     /// particular prim is desired, construct a UsdPrimRange directly.
854     ///
855     /// This is equivalent to UsdPrimRange::Stage() .
856     USD_API
857     UsdPrimRange Traverse();
858 
859     /// \overload
860     /// Traverse the prims on this stage subject to \p predicate.
861     ///
862     /// This is equivalent to UsdPrimRange::Stage() .
863     USD_API
864     UsdPrimRange Traverse(const Usd_PrimFlagsPredicate &predicate);
865 
866     /// Traverse all the prims on this stage depth-first.
867     ///
868     /// \sa Traverse()
869     /// \sa UsdPrimRange::Stage()
870     USD_API
871     UsdPrimRange TraverseAll();
872 
873     /// Attempt to ensure a \a UsdPrim at \p path exists on this stage.
874     ///
875     /// If a prim already exists at \p path, return it.  Otherwise author
876     /// \a SdfPrimSpecs with \a specifier == \a SdfSpecifierOver and empty
877     /// \a typeName at the current EditTarget to create this prim and any
878     /// nonexistent ancestors, then return it.
879     ///
880     /// The given \a path must be an absolute prim path that does not contain
881     /// any variant selections.
882     ///
883     /// If it is impossible to author any of the necessary PrimSpecs, (for
884     /// example, in case \a path cannot map to the current UsdEditTarget's
885     /// namespace) issue an error and return an invalid \a UsdPrim.
886     ///
887     /// If an ancestor of \p path identifies an \a inactive prim, author scene
888     /// description as described above but return an invalid prim, since the
889     /// resulting prim is descendant to an inactive prim.
890     ///
891     USD_API
892     UsdPrim OverridePrim(const SdfPath &path);
893 
894     /// Attempt to ensure a \a UsdPrim at \p path is defined (according to
895     /// UsdPrim::IsDefined()) on this stage.
896     ///
897     /// If a prim at \p path is already defined on this stage and \p typeName is
898     /// empty or equal to the existing prim's typeName, return that prim.
899     /// Otherwise author an \a SdfPrimSpec with \a specifier ==
900     /// \a SdfSpecifierDef and \p typeName for the prim at \p path at the
901     /// current EditTarget.  Author \a SdfPrimSpec s with \p specifier ==
902     /// \a SdfSpecifierDef and empty typeName at the current EditTarget for any
903     /// nonexistent, or existing but not \a Defined ancestors.
904     ///
905     /// The given \a path must be an absolute prim path that does not contain
906     /// any variant selections.
907     ///
908     /// If it is impossible to author any of the necessary PrimSpecs (for
909     /// example, in case \a path cannot map to the current UsdEditTarget's
910     /// namespace or one of the ancestors of \p path is inactive on the
911     /// UsdStage), issue an error and return an invalid \a UsdPrim.
912     ///
913     /// Note that this method may return a defined prim whose typeName does not
914     /// match the supplied \p typeName, in case a stronger typeName opinion
915     /// overrides the opinion at the current EditTarget.
916     ///
917     USD_API
918     UsdPrim DefinePrim(const SdfPath &path,
919                        const TfToken &typeName=TfToken());
920 
921     /// Author an \a SdfPrimSpec with \a specifier == \a SdfSpecifierClass for
922     /// the class at root prim path \p path at the current EditTarget.  The
923     /// current EditTarget must have UsdEditTarget::IsLocalLayer() == true.
924     ///
925     /// The given \a path must be an absolute, root prim path that does not
926     /// contain any variant selections.
927     ///
928     /// If a defined (UsdPrim::IsDefined()) non-class prim already exists at
929     /// \p path, issue an error and return an invalid UsdPrim.
930     ///
931     /// If it is impossible to author the necessary PrimSpec, issue an error
932     /// and return an invalid \a UsdPrim.
933     USD_API
934     UsdPrim CreateClassPrim(const SdfPath &rootPrimPath);
935 
936     /// Remove all scene description for the given \p path and its subtree
937     /// <em>in the current UsdEditTarget</em>.
938     ///
939     /// This method does not do what you might initially think!  Calling this
940     /// function will not necessarily cause the UsdPrim at \p path on this
941     /// stage to disappear.  Completely eradicating a prim from a composition
942     /// can be an involved process, involving edits to many contributing layers,
943     /// some of which (in many circumstances) will not be editable by a client.
944     /// This method is a surgical instrument that \em can be used iteratively
945     /// to effect complete removal of a prim and its subtree from namespace,
946     /// assuming the proper permissions are acquired, but more commonly it
947     /// is used to perform layer-level operations; e.g.: ensuring that a given
948     /// layer (as expressed by a UsdEditTarget) provides no opinions for a
949     /// prim and its subtree.
950     ///
951     /// Generally, if your eye is attracted to this method, you probably want
952     /// to instead use UsdPrim::SetActive(false) , which will provide the
953     /// \ref Usd_ActiveInactive "composed effect" of removing the prim and
954     /// its subtree from the composition, without actually removing any
955     /// scene description, which as a bonus, means that the effect is
956     /// reversible at a later time!
957     USD_API
958     bool RemovePrim(const SdfPath& path);
959 
960     /// @}
961 
962     // --------------------------------------------------------------------- //
963     /// \anchor Usd_layerManagement
964     /// \name Layers and EditTargets
965     /// @{
966     // --------------------------------------------------------------------- //
967 
968     /// Return this stage's root session layer.
969     USD_API
970     SdfLayerHandle GetSessionLayer() const;
971 
972     /// Return this stage's root layer.
973     USD_API
974     SdfLayerHandle GetRootLayer() const;
975 
976     /// Return the path resolver context for all path resolution during
977     /// composition of this stage. Useful for external clients that want to
978     /// resolve paths with the same context as this stage, or create new
979     /// stages with the same context.
980     USD_API
981     ArResolverContext GetPathResolverContext() const;
982 
983     /// Resolve the given identifier using this stage's
984     /// ArResolverContext and the layer of its GetEditTarget()
985     /// as an anchor for relative references (e.g. \@./siblingFile.usd\@).
986     ///
987     /// \return a non-empty string containing either the same
988     /// identifier that was passed in (if the identifier refers to an
989     /// already-opened layer or an "anonymous", in-memory layer), or a resolved
990     /// layer filepath.  If the identifier was not resolvable, return the
991     /// empty string.
992     USD_API
993     std::string
994     ResolveIdentifierToEditTarget(std::string const &identifier) const;
995 
996     /// Return this stage's local layers in strong-to-weak order.  If
997     /// \a includeSessionLayers is true, return the linearized strong-to-weak
998     /// sublayers rooted at the stage's session layer followed by the linearized
999     /// strong-to-weak sublayers rooted at this stage's root layer.  If
1000     /// \a includeSessionLayers is false, omit the sublayers rooted at this
1001     /// stage's session layer.
1002     USD_API
1003     SdfLayerHandleVector GetLayerStack(bool includeSessionLayers=true) const;
1004 
1005     /// Return a vector of all of the layers \em currently consumed by this
1006     /// stage, as determined by the composition arcs that were traversed to
1007     /// compose and populate the stage.
1008     ///
1009     /// The list of consumed layers will change with the stage's load-set and
1010     /// variant selections, so the return value should be considered only
1011     /// a snapshot.  The return value will include the stage's session layer,
1012     /// if it has one. If \a includeClipLayers is true, we will also include
1013     /// all of the layers that this stage has had to open so far to perform
1014     /// value resolution of attributes affected by
1015     /// \ref Usd_Page_ValueClips "Value Clips"
1016     USD_API
1017     SdfLayerHandleVector GetUsedLayers(bool includeClipLayers=true) const;
1018 
1019     /// Return true if \a layer is one of the layers in this stage's local,
1020     /// root layerStack.
1021     USD_API
1022     bool HasLocalLayer(const SdfLayerHandle &layer) const;
1023 
1024     /// Return the stage's EditTarget.
1025     USD_API
1026     const UsdEditTarget &GetEditTarget() const;
1027 
1028     /// Return a UsdEditTarget for editing the layer at index \a i in the
1029     /// layer stack.  This edit target will incorporate any layer time
1030     /// offset that applies to the sublayer.
1031     USD_API
1032     UsdEditTarget GetEditTargetForLocalLayer(size_t i);
1033 
1034     /// Return a UsdEditTarget for editing the given local \a layer.
1035     /// If the given layer appears more than once in the layer stack,
1036     /// the time offset to the first occurrence will be used.
1037     USD_API
1038     UsdEditTarget GetEditTargetForLocalLayer(const SdfLayerHandle &layer);
1039 
1040     /// Set the stage's EditTarget.  If \a editTarget.IsLocalLayer(), check to
1041     /// see if it's a layer in this stage's local LayerStack.  If not, issue an
1042     /// error and do nothing.  If \a editTarget is invalid, issue an error
1043     /// and do nothing.  If \a editTarget differs from the stage's current
1044     /// EditTarget, set the EditTarget and send
1045     /// UsdNotice::StageChangedEditTarget.  Otherwise do nothing.
1046     USD_API
1047     void SetEditTarget(const UsdEditTarget &editTarget);
1048 
1049     /// Mute the layer identified by \p layerIdentifier.  Muted layers are
1050     /// ignored by the stage; they do not participate in value resolution
1051     /// or composition and do not appear in any LayerStack.  If the root
1052     /// layer of a reference or payload LayerStack is muted, the behavior
1053     /// is as if the muted layer did not exist, which means a composition
1054     /// error will be generated.
1055     ///
1056 #if AR_VERSION == 1
1057     /// A canonical identifier for each layer in \p layersToMute will be
1058     /// computed using ArResolver::ComputeRepositoryPath.  Any layer
1059     /// encountered during composition with the same repository path will
1060     /// be considered muted and ignored.  Relative paths will be assumed to
1061     /// be relative to the cache's root layer.  Search paths are immediately
1062     /// resolved and the result is used for computing the canonical path.
1063 #else
1064     /// A canonical identifier for each layer in \p layersToMute will be
1065     /// computed using ArResolver::CreateIdentifier using the stage's root
1066     /// layer as the anchoring asset. Any layer encountered during composition
1067     /// with the same identifier will be considered muted and ignored.
1068 #endif
1069     ///
1070     /// Note that muting a layer will cause this stage to release all
1071     /// references to that layer.  If no other client is holding on to
1072     /// references to that layer, it will be unloaded.  In this case, if
1073     /// there are unsaved edits to the muted layer, those edits are lost.
1074     /// Since anonymous layers are not serialized, muting an anonymous
1075     /// layer will cause that layer and its contents to be lost in this
1076     /// case.
1077     ///
1078     /// Muting a layer that has not been used by this stage is not an error.
1079     /// If that layer is encountered later, muting will take effect and that
1080     /// layer will be ignored.
1081     ///
1082     /// The root layer of this stage may not be muted; attempting to do so
1083     /// will generate a coding error.
1084     USD_API
1085     void MuteLayer(const std::string &layerIdentifier);
1086 
1087     /// Unmute the layer identified by \p layerIdentifier if it had
1088     /// previously been muted.
1089     USD_API
1090     void UnmuteLayer(const std::string &layerIdentifier);
1091 
1092     /// Mute and unmute the layers identified in \p muteLayers and
1093     /// \p unmuteLayers.
1094     ///
1095     /// This is equivalent to calling UsdStage::UnmuteLayer for each layer
1096     /// in \p unmuteLayers followed by UsdStage::MuteLayer for each layer
1097     /// in \p muteLayers, however this method is more efficient as all
1098     /// operations are committed in a single batch.
1099     USD_API
1100     void MuteAndUnmuteLayers(const std::vector<std::string> &muteLayers,
1101                              const std::vector<std::string> &unmuteLayers);
1102 
1103     /// Returns a vector of all layers that have been muted on this stage.
1104     USD_API
1105     const std::vector<std::string>& GetMutedLayers() const;
1106 
1107     /// Returns true if the layer specified by \p layerIdentifier is
1108     /// muted in this cache, false otherwise.  See documentation on
1109     /// MuteLayer for details on how \p layerIdentifier is compared to the
1110     /// layers that have been muted.
1111     USD_API
1112     bool IsLayerMuted(const std::string& layerIdentifier) const;
1113 
1114     /// @}
1115 
1116     // --------------------------------------------------------------------- //
1117     /// \anchor Usd_stageSerialization
1118     /// \name Flatten & Export Utilities
1119     /// @{
1120     // --------------------------------------------------------------------- //
1121     // Future Work:
1122     //    * Flatten sub-trees or individual prims
1123     //    * Allow flattening of local LayerStack
1124     //    * Move Flatten into a free-function to ensure it doesn't rely on
1125     //      Stage internals.
1126 
1127     /// Writes out the composite scene as a single flattened layer into
1128     /// \a filename.
1129     ///
1130     /// If addSourceFileComment is true, a comment in the output layer
1131     /// will mention the input layer it was generated from.
1132     ///
1133     /// See UsdStage::Flatten for details of the flattening transformation.
1134     USD_API
1135     bool Export(const std::string &filename,
1136                 bool addSourceFileComment=true,
1137                 const SdfLayer::FileFormatArguments &args =
1138                     SdfLayer::FileFormatArguments()) const;
1139 
1140     /// Writes the composite scene as a flattened Usd text
1141     /// representation into the given \a string.
1142     ///
1143     /// If addSourceFileComment is true, a comment in the output layer
1144     /// will mention the input layer it was generated from.
1145     ///
1146     /// See UsdStage::Flatten for details of the flattening transformation.
1147     USD_API
1148     bool ExportToString(std::string *result,
1149                         bool addSourceFileComment=true) const;
1150 
1151     /// Returns a single, anonymous, merged layer for this composite
1152     /// scene.
1153     ///
1154     /// Specifically, this function removes **most** composition metadata and
1155     /// authors the resolved values for each object directly into the flattened
1156     /// layer.
1157     ///
1158     /// All VariantSets are removed and only the currently selected variants
1159     /// will be present in the resulting layer.
1160     ///
1161     /// Class prims will still exist, however all inherits arcs will have
1162     /// been removed and the inherited data will be copied onto each child
1163     /// object. Composition arcs authored on the class itself will be flattened
1164     /// into the class.
1165     ///
1166     /// Flatten preserves
1167     /// \ref Usd_Page_ScenegraphInstancing "scenegraph instancing" by creating
1168     /// independent roots for each prototype currently composed on this stage,
1169     /// and adding a single internal reference arc on each instance prim to its
1170     /// corresponding prototype.
1171     ///
1172     /// Time samples across sublayer offsets will will have the time offset and
1173     /// scale applied to each time index.
1174     ///
1175     /// Finally, any deactivated prims will be pruned from the result.
1176     ///
1177     USD_API
1178     SdfLayerRefPtr Flatten(bool addSourceFileComment=true) const;
1179     /// @}
1180 
1181 public:
1182     // --------------------------------------------------------------------- //
1183     /// \anchor Usd_stageMetadata
1184     /// \name Stage Metadata
1185     /// Stage metadata applies to the entire contents of the stage, and is
1186     /// recorded only in the stage's root or primary session-layer.  Most of
1187     /// the other, specific metadata methods on UsdStage are defined in terms
1188     /// of these generic methods.
1189     /// @{
1190     // --------------------------------------------------------------------- //
1191 
1192     /// Return in \p value an authored or fallback value (if one was defined
1193     /// for the given metadatum) for Stage metadatum \p key.  Order of
1194     /// resolution is session layer, followed by root layer, else fallback to
1195     /// the SdfSchema.
1196     ///
1197     /// \return true if we successfully retrieved a value of the requested type;
1198     /// false if \p key is not allowed as layer metadata or no value was found.
1199     /// Generates a coding error if we retrieved a stored value of a type other
1200     /// than the requested type
1201     ///
1202     /// \sa \ref Usd_OM_Metadata
1203     template <class T>
1204     bool GetMetadata(const TfToken &key, T *value) const;
1205     /// \overload
1206     USD_API
1207     bool GetMetadata(const TfToken &key, VtValue *value) const;
1208 
1209     /// Returns true if the \a key has a meaningful value, that is, if
1210     /// GetMetadata() will provide a value, either because it was authored
1211     /// or because the Stage metadata was defined with a meaningful fallback
1212     /// value.
1213     ///
1214     /// Returns false if \p key is not allowed as layer metadata.
1215     USD_API
1216     bool HasMetadata(const TfToken &key) const;
1217 
1218     /// Returns \c true if the \a key has an authored value, \c false if no
1219     /// value was authored or the only value available is the SdfSchema's
1220     /// metadata fallback.
1221     ///
1222     /// \note If a value for a metadatum \em not legal to author on layers
1223     /// is present in the root or session layer (which could happen through
1224     /// hand-editing or use of certain low-level API's), this method will
1225     /// still return \c false.
1226     USD_API
1227     bool HasAuthoredMetadata(const TfToken &key) const;
1228 
1229     /// Set the value of Stage metadatum \p key to \p value, if the stage's
1230     /// current UsdEditTarget is the root or session layer.
1231     ///
1232     /// If the current EditTarget is any other layer, raise a coding error.
1233     /// \return true if authoring was successful, false otherwise.
1234     /// Generates a coding error if \p key is not allowed as layer metadata.
1235     ///
1236     /// \sa \ref Usd_OM_Metadata
1237     template<typename T>
1238     bool SetMetadata(const TfToken &key, const T &value) const;
1239     /// \overload
1240     USD_API
1241     bool SetMetadata(const TfToken &key, const VtValue &value) const;
1242 
1243     /// Clear the value of stage metadatum \p key, if the stage's
1244     /// current UsdEditTarget is the root or session layer.
1245     ///
1246     /// If the current EditTarget is any other layer, raise a coding error.
1247     /// \return true if authoring was successful, false otherwise.
1248     /// Generates a coding error if \p key is not allowed as layer metadata.
1249     ///
1250     /// \sa \ref Usd_OM_Metadata
1251     USD_API
1252     bool ClearMetadata(const TfToken &key) const;
1253 
1254     /// Resolve the requested dictionary sub-element \p keyPath of
1255     /// dictionary-valued metadatum named \p key, returning the resolved
1256     /// value.
1257     ///
1258     /// If you know you need just a small number of elements from a dictionary,
1259     /// accessing them element-wise using this method can be much less
1260     /// expensive than fetching the entire dictionary with GetMetadata(key).
1261     ///
1262     /// \return true if we successfully retrieved a value of the requested type;
1263     /// false if \p key is not allowed as layer metadata or no value was found.
1264     /// Generates a coding error if we retrieved a stored value of a type other
1265     /// than the requested type
1266     ///
1267     /// The \p keyPath is a ':'-separated path addressing an element
1268     /// in subdictionaries.  If \p keyPath is empty, returns an empty VtValue.
1269     template<typename T>
1270     bool GetMetadataByDictKey(const TfToken& key, const TfToken &keyPath,
1271                               T* value) const;
1272     /// overload
1273     USD_API
1274     bool GetMetadataByDictKey(
1275         const TfToken& key, const TfToken &keyPath, VtValue *value) const;
1276 
1277     /// Return true if there exists any authored or fallback opinion for
1278     /// \p key and \p keyPath.
1279     ///
1280     /// The \p keyPath is a ':'-separated path identifying a value in
1281     /// subdictionaries stored in the metadata field at \p key.  If
1282     /// \p keyPath is empty, returns \c false.
1283     ///
1284     /// Returns false if \p key is not allowed as layer metadata.
1285     ///
1286     /// \sa \ref Usd_Dictionary_Type
1287     USD_API
1288     bool HasMetadataDictKey(
1289         const TfToken& key, const TfToken &keyPath) const;
1290 
1291     /// Return true if there exists any authored opinion (excluding
1292     /// fallbacks) for \p key and \p keyPath.
1293     ///
1294     /// The \p keyPath is a ':'-separated path identifying a value in
1295     /// subdictionaries stored in the metadata field at \p key.  If
1296     /// \p keyPath is empty, returns \c false.
1297     ///
1298     /// \sa \ref Usd_Dictionary_Type
1299     USD_API
1300     bool HasAuthoredMetadataDictKey(
1301         const TfToken& key, const TfToken &keyPath) const;
1302 
1303     /// Author \p value to the field identified by \p key and \p keyPath
1304     /// at the current EditTarget.
1305     ///
1306     /// The \p keyPath is a ':'-separated path identifying a value in
1307     /// subdictionaries stored in the metadata field at \p key.  If
1308     /// \p keyPath is empty, no action is taken.
1309     ///
1310     /// \return true if the value is authored successfully, false otherwise.
1311     /// Generates a coding error if \p key is not allowed as layer metadata.
1312     ///
1313     /// \sa \ref Usd_Dictionary_Type
1314     template<typename T>
1315     bool SetMetadataByDictKey(const TfToken& key, const TfToken &keyPath,
1316                               const T& value) const;
1317     /// \overload
1318     USD_API
1319     bool SetMetadataByDictKey(
1320         const TfToken& key, const TfToken &keyPath, const VtValue& value) const;
1321 
1322     /// Clear any authored value identified by \p key and \p keyPath
1323     /// at the current EditTarget.
1324     ///
1325     /// The \p keyPath is a ':'-separated path identifying a path in
1326     /// subdictionaries stored in the metadata field at \p key.  If
1327     /// \p keyPath is empty, no action is taken.
1328     ///
1329     /// \return true if the value is cleared successfully, false otherwise.
1330     /// Generates a coding error if \p key is not allowed as layer metadata.
1331     ///
1332     /// \sa \ref Usd_Dictionary_Type
1333     USD_API
1334     bool ClearMetadataByDictKey(
1335         const TfToken& key, const TfToken& keyPath) const;
1336 
1337     /// Writes the fallback prim types defined in the schema registry to the
1338     /// stage as dictionary valued fallback prim type metadata. If the stage
1339     /// already has fallback prim type metadata, the fallback types from the
1340     /// schema registry will be added to the existing metadata, only for types
1341     /// that are already present in the dictionary, i.e. this won't overwrite
1342     /// existing fallback entries.
1343     ///
1344     /// The current edit target determines whether the metadata is written to
1345     /// the root layer or the session layer. If the edit target specifies
1346     /// another layer besides these, this will produce an error.
1347     ///
1348     /// This function can be used at any point before calling Save or Export on
1349     /// a stage to record the fallback types for the current schemas. This
1350     /// allows another version of Usd to open this stage and treat prim types it
1351     /// doesn't recognize as a type it does recognize defined for it in this
1352     /// metadata.
1353     ///
1354     /// \sa \ref Usd_OM_FallbackPrimTypes UsdSchemaRegistry::GetFallbackPrimTypes
1355     USD_API
1356     void WriteFallbackPrimTypes();
1357 
1358     /// @}
1359 
1360     // --------------------------------------------------------------------- //
1361     /// \anchor Usd_timeCodeAPI
1362     /// \name TimeCode API
1363     /// Methods for managing the Stage's active timeSample range, time units,
1364     /// and intended rate of playback.  See \ref Usd_OM_UsdTimeCode for more
1365     /// on time and TimeCodes in USD.
1366     /// @{
1367     // --------------------------------------------------------------------- //
1368     /// Returns the stage's start timeCode. If the stage has an associated
1369     /// session layer with a start timeCode opinion, this value is returned.
1370     /// Otherwise, the start timeCode opinion from the root layer is returned.
1371     USD_API
1372     double GetStartTimeCode() const;
1373 
1374     /// Sets the stage's start timeCode.
1375     ///
1376     /// The start timeCode is set in the current EditTarget, if it is the root
1377     /// layer of the stage or the session layer associated with the stage. If
1378     /// the current EditTarget is neither, a warning is issued and the start
1379     /// timeCode is not set.
1380     USD_API
1381     void SetStartTimeCode(double);
1382 
1383     /// Returns the stage's end timeCode. If the stage has an associated
1384     /// session layer with an end timeCode opinion, this value is returned.
1385     /// Otherwise, the end timeCode opinion from the root layer is returned.
1386     USD_API
1387     double GetEndTimeCode() const;
1388 
1389     /// Sets the stage's end timeCode.
1390     ///
1391     /// The end timeCode is set in the current EditTarget, if it is the root
1392     /// layer of the stage or the session layer associated with the stage. If
1393     /// the current EditTarget is neither, a warning is issued and the end
1394     /// timeCode is not set.
1395     USD_API
1396     void SetEndTimeCode(double);
1397 
1398     /// Returns true if the stage has both start and end timeCodes
1399     /// authored in the session layer or the root layer of the stage.
1400     USD_API
1401     bool HasAuthoredTimeCodeRange() const;
1402 
1403     /// Returns the stage's timeCodesPerSecond value.
1404     ///
1405     /// The timeCodesPerSecond value scales the time ordinate for the samples
1406     /// contained in the stage to seconds. If timeCodesPerSecond is 24, then a
1407     /// sample at time ordinate 24 should be viewed exactly one second after the
1408     /// sample at time ordinate 0.
1409     ///
1410     /// Like SdfLayer::GetTimeCodesPerSecond, this accessor uses a dynamic
1411     /// fallback to framesPerSecond.  The order of precedence is:
1412     ///
1413     /// \li timeCodesPerSecond from session layer
1414     /// \li timeCodesPerSecond from root layer
1415     /// \li framesPerSecond from session layer
1416     /// \li framesPerSecond from root layer
1417     /// \li fallback value of 24
1418     USD_API
1419     double GetTimeCodesPerSecond() const;
1420 
1421     /// Sets the stage's timeCodesPerSecond value.
1422     ///
1423     /// The timeCodesPerSecond value is set in the current EditTarget, if it
1424     /// is the root layer of the stage or the session layer associated with the
1425     /// stage. If the current EditTarget is neither, a warning is issued and no
1426     /// value is set.
1427     ///
1428     /// \sa GetTimeCodesPerSecond()
1429     USD_API
1430     void SetTimeCodesPerSecond(double timeCodesPerSecond) const;
1431 
1432     /// Returns the stage's framesPerSecond value.
1433     ///
1434     /// This makes an advisory statement about how the contained data can be
1435     /// most usefully consumed and presented.  It's primarily an indication of
1436     /// the expected playback rate for the data, but a timeline editing tool
1437     /// might also want to use this to decide how to scale and label its
1438     /// timeline.
1439     ///
1440     /// The default value of framesPerSecond is 24.
1441     USD_API
1442     double GetFramesPerSecond() const;
1443 
1444     /// Sets the stage's framesPerSecond value.
1445     ///
1446     /// The framesPerSecond value is set in the current EditTarget, if it
1447     /// is the root layer of the stage or the session layer associated with the
1448     /// stage. If the current EditTarget is neither, a warning is issued and no
1449     /// value is set.
1450     ///
1451     /// \sa GetFramesPerSecond()
1452     USD_API
1453     void SetFramesPerSecond(double framesPerSecond) const;
1454 
1455     /// @}
1456 
1457     // --------------------------------------------------------------------- //
1458     /// \anchor Usd_ColorConfigurationAPI
1459     /// \name Color Configuration API
1460     ///
1461     /// Methods for authoring and querying the color configuration to
1462     /// be used to interpret the per-attribute color-spaces. An external
1463     /// system (like OpenColorIO) is typically used for interpreting the
1464     /// configuration.
1465     ///
1466     /// Site-wide fallback values for the colorConfiguration and
1467     /// colorManagementSystem metadata can be set in the plugInfo.json file of
1468     /// a plugin using this structure:
1469     ///
1470     /// \code{.json}
1471     ///         "UsdColorConfigFallbacks": {
1472     ///             "colorConfiguration" = "https://github.com/imageworks/OpenColorIO-Configs/blob/master/aces_1.0.1/config.ocio",
1473     ///             "colorManagementSystem" : "OpenColorIO"
1474     ///         }
1475     /// \endcode
1476     ///
1477     /// The color space in which a given color or texture attribute is authored
1478     /// is set as token-valued metadata 'colorSpace' on the attribute. For
1479     /// color or texture attributes that don't have an authored 'colorSpace'
1480     /// value, the fallback color-space is gleaned from the color configuration
1481     /// oracle. This is usually the config's <b>scene_linear</b> role
1482     /// color-space.
1483     ///
1484     /// Here's the pseudo-code for determining an attribute's color-space.
1485     ///
1486     /// \code{.cpp}
1487     /// UsdStageRefPtr stage = UsdStage::Open(filePath);
1488     /// UsdPrim prim = stage->GetPrimAtPath("/path/to/prim")
1489     /// UsdAttribute attr = prim.GetAttribute("someColorAttr");
1490     /// TfToken colorSpace = attr.GetColorSpace();
1491     /// if (colorSpace.IsEmpty()) {
1492     ///     // If colorSpace is empty, get the default from the stage's
1493     ///     // colorConfiguration, using external API (not provided by USD).
1494     ///     colorSpace = ExternalAPI::GetDefaultColorSpace(
1495     ///                         stage->GetColorConfiguration());
1496     /// }
1497     /// \endcode
1498     ///
1499     /// \sa \ref Usd_AttributeColorSpaceAPI "UsdAttribute ColorSpace API"
1500     ///
1501     ///
1502     /// @{
1503     // --------------------------------------------------------------------- //
1504 
1505     /// Sets the default color configuration to be used to interpret the
1506     /// per-attribute color-spaces in the composed USD stage. This is specified
1507     /// as asset path which can be resolved to the color spec file.
1508     ///
1509     /// \ref Usd_ColorConfigurationAPI "Color Configuration API"
1510     USD_API
1511     void SetColorConfiguration(const SdfAssetPath &colorConfig) const;
1512 
1513     /// Returns the default color configuration used to interpret the per-
1514     /// attribute color-spaces in the composed USD stage.
1515     ///
1516     /// \ref Usd_ColorConfigurationAPI "Color Configuration API"
1517     USD_API
1518     SdfAssetPath GetColorConfiguration() const;
1519 
1520     /// Sets the name of the color management system used to interpret the
1521     /// color configuration file pointed at by the colorConfiguration metadata.
1522     ///
1523     /// \ref Usd_ColorConfigurationAPI "Color Configuration API"
1524     USD_API
1525     void SetColorManagementSystem(const TfToken &cms) const;
1526 
1527     /// Sets the name of the color management system to be used for loading
1528     /// and interpreting the color configuration file.
1529     ///
1530     /// \ref Usd_ColorConfigurationAPI "Color Configuration API"
1531     USD_API
1532     TfToken GetColorManagementSystem() const;
1533 
1534     /// Returns the global fallback values of 'colorConfiguration' and
1535     /// 'colorManagementSystem'. These are set in the plugInfo.json file
1536     /// of a plugin, but can be overridden by calling the static method
1537     /// SetColorConfigFallbacks().
1538     ///
1539     /// The python wrapping of this method returns a tuple containing
1540     /// (colorConfiguration, colorManagementSystem).
1541     ///
1542     ///
1543     /// \sa SetColorConfigFallbacks,
1544     /// \ref Usd_ColorConfigurationAPI "Color Configuration API"
1545     USD_API
1546     static void GetColorConfigFallbacks(SdfAssetPath *colorConfiguration,
1547                                         TfToken *colorManagementSystem);
1548 
1549     /// Sets the global fallback values of color configuration metadata which
1550     /// includes the 'colorConfiguration' asset path and the name of the
1551     /// color management system. This overrides any fallback values authored
1552     /// in plugInfo files.
1553     ///
1554     /// If the specified value of \p colorConfiguration or
1555     /// \p colorManagementSystem is empty, then the corresponding fallback
1556     /// value isn't set. In other words, for this call to have an effect,
1557     /// at least one value must be non-empty. Additionally, these can't be
1558     /// reset to empty values.
1559     ///
1560     /// \sa GetColorConfigFallbacks()
1561     /// \ref Usd_ColorConfigurationAPI "Color Configuration API"
1562     USD_API
1563     static void
1564     SetColorConfigFallbacks(const SdfAssetPath &colorConfiguration,
1565                             const TfToken &colorManagementSystem);
1566 
1567     /// @}
1568 
1569     // --------------------------------------------------------------------- //
1570     /// \anchor Usd_interpolation
1571     /// \name Attribute Value Interpolation
1572     /// Controls the interpolation behavior when retrieving attribute
1573     /// values.  The default behavior is linear interpolation.
1574     /// See \ref Usd_AttributeInterpolation for more details.
1575     /// @{
1576     // --------------------------------------------------------------------- //
1577 
1578     /// Sets the interpolation type used during value resolution
1579     /// for all attributes on this stage.  Changing this will cause a
1580     /// UsdNotice::StageContentsChanged notice to be sent, as values at
1581     /// times where no samples are authored may have changed.
1582     USD_API
1583     void SetInterpolationType(UsdInterpolationType interpolationType);
1584 
1585     /// Returns the interpolation type used during value resolution
1586     /// for all attributes on this stage.
1587     USD_API
1588     UsdInterpolationType GetInterpolationType() const;
1589 
1590     /// @}
1591 
1592     // --------------------------------------------------------------------- //
1593     /// \anchor Usd_instancing
1594     /// \name Instancing
1595     /// See \ref Usd_Page_ScenegraphInstancing for more details.
1596     /// @{
1597     // --------------------------------------------------------------------- //
1598 
1599     /// Returns all native instancing prototype prims.
1600     USD_API
1601     std::vector<UsdPrim> GetPrototypes() const;
1602 
1603     /// @}
1604 
1605 private:
1606     struct _IncludePayloadsPredicate;
1607 
1608     // --------------------------------------------------------------------- //
1609     // Stage Construction & Initialization
1610     // --------------------------------------------------------------------- //
1611 
1612     UsdStage(const SdfLayerRefPtr& rootLayer,
1613              const SdfLayerRefPtr& sessionLayer,
1614              const ArResolverContext& pathResolverContext,
1615              const UsdStagePopulationMask& mask,
1616              InitialLoadSet load);
1617 
1618     // Helper for Open() overloads -- searches and publishes to bound caches.
1619     template <class... Args>
1620     static UsdStageRefPtr _OpenImpl(InitialLoadSet load, Args const &... args);
1621 
1622     // Releases resources used by this stage.
1623     void _Close();
1624 
1625     // Common ref ptr initialization, called by public, static constructors.
1626     //
1627     // This method will either return a valid refptr (if the stage is correctly
1628     // initialized) or it will return a null ref pointer, deleting the
1629     // raw stage pointer in the process.
1630     static UsdStageRefPtr
1631     _InstantiateStage(const SdfLayerRefPtr &rootLayer,
1632                       const SdfLayerRefPtr &sessionLayer,
1633                       const ArResolverContext &pathResolverContext,
1634                       const UsdStagePopulationMask &mask,
1635                       InitialLoadSet load);
1636 
1637     // --------------------------------------------------------------------- //
1638     // Spec Existence & Definition Helpers
1639     // --------------------------------------------------------------------- //
1640 
1641     SdfPropertySpecHandleVector
1642     _GetPropertyStack(const UsdProperty &prop, UsdTimeCode time) const;
1643 
1644     SdfPropertySpecHandle
1645     _GetSchemaPropertySpec(const UsdPrim &prim, const TfToken &propName) const;
1646 
1647     SdfPropertySpecHandle
1648     _GetSchemaPropertySpec(const UsdProperty &prop) const;
1649 
1650     template <class PropType>
1651     SdfHandle<PropType>
1652     _GetSchemaPropertySpec(const UsdProperty &prop) const;
1653 
1654     SdfAttributeSpecHandle
1655     _GetSchemaAttributeSpec(const UsdAttribute &attr) const;
1656 
1657     SdfRelationshipSpecHandle
1658     _GetSchemaRelationshipSpec(const UsdRelationship &rel) const;
1659 
1660     SdfPrimSpecHandle
1661     _CreatePrimSpecForEditing(const UsdPrim& prim);
1662 
1663     template <class PropType>
1664     SdfHandle<PropType>
1665     _CreatePropertySpecForEditing(const UsdProperty &prop);
1666 
1667     SdfPropertySpecHandle
1668     _CreatePropertySpecForEditing(const UsdProperty &prop);
1669 
1670     SdfAttributeSpecHandle
1671     _CreateAttributeSpecForEditing(const UsdAttribute &attr);
1672 
1673     SdfRelationshipSpecHandle
1674     _CreateRelationshipSpecForEditing(const UsdRelationship &rel);
1675 
1676     // Check if the given path is valid to use with the prim creation API,
1677     // like DefinePrim. If it is valid, returns (true, GetPrimAtPath(path)).
1678     // Otherwise, returns (false, UsdPrim()).
1679     std::pair<bool, UsdPrim>
1680     _IsValidPathForCreatingPrim(const SdfPath &path) const;
1681 
1682     // Validates that editing a specified prim is allowed. If editing is not
1683     // allowed, issues a coding error like "Cannot <operation> ..." and
1684     // returns false. Otherwise, returns true.
1685     bool _ValidateEditPrim(const UsdPrim &prim, const char* operation) const;
1686     bool _ValidateEditPrimAtPath(const SdfPath &primPath,
1687                                  const char* operation) const;
1688 
1689     UsdPrim _DefinePrim(const SdfPath &path, const TfToken &typeName);
1690 
1691     bool _RemoveProperty(const SdfPath& path);
1692 
1693     UsdProperty _FlattenProperty(const UsdProperty &srcProp,
1694                                  const UsdPrim &dstParent,
1695                                  const TfToken &dstName);
1696 
1697     // --------------------------------------------------------------------- //
1698     // Value & Metadata Authoring
1699     // --------------------------------------------------------------------- //
1700 
1701     // Trait that allows us to call the correct versions of _SetValue and
1702     // _SetMetadata for types whose values need to be mapped when written to
1703     // different edit targets.
1704     template <class T>
1705     struct _IsEditTargetMappable {
1706         static const bool value =
1707             std::is_same<T, SdfTimeCode>::value ||
1708             std::is_same<T, VtArray<SdfTimeCode>>::value ||
1709             std::is_same<T, SdfTimeSampleMap>::value ||
1710             std::is_same<T, VtDictionary>::value;
1711     };
1712 
1713     // Set value for types that don't need to be mapped for edit targets.
1714     template <class T>
1715     typename std::enable_if<!_IsEditTargetMappable<T>::value, bool>::type
1716     _SetValue(
1717         UsdTimeCode time, const UsdAttribute &attr, const T &newValue);
1718 
1719     // Set value for types that do need to be mapped for edit targets.
1720     template <class T>
1721     typename std::enable_if<_IsEditTargetMappable<T>::value, bool>::type
1722     _SetValue(
1723         UsdTimeCode time, const UsdAttribute &attr, const T &newValue);
1724 
1725     // Set value for dynamically typed VtValue. Will map the value across edit
1726     // targets if the held value type supports it.
1727     bool _SetValue(
1728         UsdTimeCode time, const UsdAttribute &attr, const VtValue &newValue);
1729 
1730     template <class T>
1731     bool _SetEditTargetMappedValue(
1732         UsdTimeCode time, const UsdAttribute &attr, const T &newValue);
1733 
1734     template <class T>
1735     bool _SetValueImpl(
1736         UsdTimeCode time, const UsdAttribute &attr, const T& value);
1737 
1738     bool _ClearValue(UsdTimeCode time, const UsdAttribute &attr);
1739 
1740     // Set metadata for types that don't need to be mapped across edit targets.
1741     template <class T>
1742     typename std::enable_if<!_IsEditTargetMappable<T>::value, bool>::type
1743     _SetMetadata(const UsdObject &object, const TfToken& key,
1744                  const TfToken &keyPath, const T& value);
1745 
1746     // Set metadata for types that do need to be mapped for edit targets.
1747     template <class T>
1748     typename std::enable_if<_IsEditTargetMappable<T>::value, bool>::type
1749     _SetMetadata(const UsdObject &object, const TfToken& key,
1750                  const TfToken &keyPath, const T& value);
1751 
1752     // Set metadata for dynamically typed VtValue. Will map the value across
1753     // edit targets if the held value type supports it.
1754     USD_API
1755     bool _SetMetadata(const UsdObject &object,
1756                       const TfToken& key,
1757                       const TfToken &keyPath,
1758                       const VtValue& value);
1759 
1760     template <class T>
1761     bool _SetEditTargetMappedMetadata(
1762         const UsdObject &obj, const TfToken& fieldName,
1763         const TfToken &keyPath, const T &newValue);
1764 
1765     template <class T>
1766     bool _SetMetadataImpl(
1767         const UsdObject &obj, const TfToken& fieldName,
1768         const TfToken &keyPath, const T &value);
1769 
1770     bool _ClearMetadata(const UsdObject &obj, const TfToken& fieldName,
1771                         const TfToken &keyPath=TfToken());
1772 
1773     // --------------------------------------------------------------------- //
1774     // Misc Internal Helpers
1775     // --------------------------------------------------------------------- //
1776 
1777     // Pcp helpers.
_GetPcpCache()1778     PcpCache const *_GetPcpCache() const { return _cache.get(); }
_GetPcpCache()1779     PcpCache *_GetPcpCache() { return _cache.get(); }
1780 
1781     // Returns the PrimIndex, using the read-only PcpCache API. We expect prims
1782     // to be composed during initial stage composition, so this method should
1783     // not be used in that context.
1784     const PcpPrimIndex* _GetPcpPrimIndex(const SdfPath& primPath) const;
1785 
1786     // Helper to report pcp errors.
1787     void _ReportPcpErrors(const PcpErrorVector &errors,
1788                           const std::string &context) const;
1789     void _ReportErrors(const PcpErrorVector &errors,
1790                        const std::vector<std::string>& otherErrors,
1791                        const std::string &context) const;
1792 
1793     // --------------------------------------------------------------------- //
1794     // Scenegraph Composition & Change Processing
1795     // --------------------------------------------------------------------- //
1796 
1797     // Compose the prim indexes in the subtrees rooted at the paths in
1798     // \p primIndexPaths.  If \p instanceChanges is given, returns
1799     // changes to prototypes and instances due to the discovery of new instances
1800     // during composition.
1801     void _ComposePrimIndexesInParallel(
1802         const std::vector<SdfPath>& primIndexPaths,
1803         const std::string& context,
1804         Usd_InstanceChanges* instanceChanges = nullptr);
1805 
1806     // Recompose the subtree rooted at \p prim: compose its type, flags, and
1807     // list of children, then invoke _ComposeSubtree on all its children.
1808     void _ComposeSubtree(
1809         Usd_PrimDataPtr prim, Usd_PrimDataConstPtr parent,
1810         UsdStagePopulationMask const *mask,
1811         const SdfPath &primIndexPath = SdfPath());
1812     void _ComposeSubtreeImpl(
1813         Usd_PrimDataPtr prim, Usd_PrimDataConstPtr parent,
1814         UsdStagePopulationMask const *mask,
1815         const SdfPath &primIndexPath = SdfPath());
1816     void _ComposeSubtreeInParallel(Usd_PrimDataPtr prim);
1817     void _ComposeSubtreesInParallel(
1818         const std::vector<Usd_PrimDataPtr> &prims,
1819         const std::vector<SdfPath> *primIndexPaths = nullptr);
1820 
1821     // Compose subtree rooted at \p prim under \p parent.  This function
1822     // ensures that the appropriate prim index is specified for \p prim if
1823     // \p parent is in a prototype.
1824     void _ComposeChildSubtree(Usd_PrimDataPtr prim,
1825                               Usd_PrimDataConstPtr parent,
1826                               UsdStagePopulationMask const *mask);
1827 
1828     // Compose \p prim's list of children and make any modifications necessary
1829     // to its _children member and the stage's _primMap, including possibly
1830     // instantiating new prims, or destroying existing subtrees of prims.  The
1831     // any newly created prims *do not* have their prim index, type, flags, or
1832     // children composed.
1833     //
1834     // Compose only \p prim's direct children if recurse=false.  Otherwise
1835     // recompose every descendent of \p prim.  Callers that pass recurse=false
1836     // should invoke _ComposeSubtree on any newly created prims to ensure caches
1837     // are correctly populated.
1838     void _ComposeChildren(Usd_PrimDataPtr prim,
1839                           UsdStagePopulationMask const *mask, bool recurse);
1840 
1841     // Instantiate a prim instance.  There must not already be an instance
1842     // at \p primPath.
1843     Usd_PrimDataPtr _InstantiatePrim(const SdfPath &primPath);
1844 
1845     // Instantiate a prototype prim and sets its parent to pseudoroot.
1846     // There must not already be a prototype at \p primPath.
1847     Usd_PrimDataPtr _InstantiatePrototypePrim(const SdfPath &primPath);
1848 
1849     // For \p prim and all of its descendants, remove from _primMap and empty
1850     // their _children vectors.
1851     void _DestroyPrim(Usd_PrimDataPtr prim);
1852 
1853     // Destroy the prim subtrees rooted at each path in \p paths. \p paths may
1854     // not contain any path that is a descendent of another path in \p paths.
1855     void _DestroyPrimsInParallel(const std::vector<SdfPath>& paths);
1856 
1857     // Invoke _DestroyPrim() on all of \p prim's direct children.
1858     void _DestroyDescendents(Usd_PrimDataPtr prim);
1859 
1860     // Returns true if the object at the given path is a descendant of
1861     // an instance prim, i.e. a prim beneath an instance prim, or a property
1862     // of a prim beneath an instance prim.
1863     bool _IsObjectDescendantOfInstance(const SdfPath& path) const;
1864 
1865     // If the given prim is an instance, returns the corresponding
1866     // prototype prim.  Otherwise, returns an invalid prim.
1867     Usd_PrimDataConstPtr _GetPrototypeForInstance(Usd_PrimDataConstPtr p) const;
1868 
1869     // Returns the path of the Usd prim using the prim index at the given path.
1870     SdfPath _GetPrimPathUsingPrimIndexAtPath(const SdfPath& primIndexPath) const;
1871 
1872     // Update stage contents in response to changes in scene description.
1873     void _HandleLayersDidChange(const SdfNotice::LayersDidChangeSentPerLayer &);
1874 
1875     // Update stage contents in response to changes to the asset resolver.
1876     void _HandleResolverDidChange(const ArNotice::ResolverChanged &);
1877 
1878     // Process stage change information stored in _pendingChanges.
1879     // _pendingChanges will be set to nullptr by the end of the function.
1880     void _ProcessPendingChanges();
1881 
1882     // Remove scene description for the prim at \p fullPath in the current edit
1883     // target.
1884     bool _RemovePrim(const SdfPath& fullPath);
1885 
1886     SdfPrimSpecHandle _GetPrimSpec(const SdfPath& fullPath);
1887 
1888     // Find and return the defining spec type for the property spec at the given
1889     // path, or SdfSpecTypeUnknown if none exists.  The defining spec type is
1890     // either the builtin definition's spec type, if the indicated property is
1891     // builtin, otherwise it's the strongest authored spec's type if one exists,
1892     // otherwise it's SdfSpecTypeUnknown.
1893     SdfSpecType _GetDefiningSpecType(Usd_PrimDataConstPtr primData,
1894                                      const TfToken &propName) const;
1895 
1896     // Helper to apply Pcp changes and recompose the scenegraph accordingly,
1897     // given an optional initial set of paths to recompose.
1898     void _Recompose(const PcpChanges &changes);
1899     template <class T>
1900     void _Recompose(const PcpChanges &changes, T *pathsToRecompose);
1901     template <class T>
1902     void _RecomposePrims(T *pathsToRecompose);
1903 
1904     // Helper for _Recompose to find the subtrees that need to be
1905     // fully recomposed and to recompose the name children of the
1906     // parents of these subtrees. Note that [start, finish) must be a
1907     // sorted range of paths with no descendent paths.
1908     template <class Iter>
1909     void _ComputeSubtreesToRecompose(Iter start, Iter finish,
1910                                      std::vector<Usd_PrimDataPtr>* recompose);
1911 
1912     // return true if the path is valid for load/unload operations.
1913     // This method will emit errors when invalid paths are encountered.
1914     bool _IsValidForLoad(const SdfPath& path) const;
1915     bool _IsValidForUnload(const SdfPath& path) const;
1916 
1917     // Discover all payloads in a given subtree, adding the path of each
1918     // discovered prim index to the \p primIndexPaths set. If specified,
1919     // the corresponding UsdPrim path will be added to the \p usdPrimPaths
1920     // set. The root path will be considered for inclusion in the result set.
1921     //
1922     // Note that some payloads may not be discoverable in until an ancestral
1923     // payload has been included. UsdStage::LoadAndUnload takes this into
1924     // account.
1925     void _DiscoverPayloads(const SdfPath& rootPath,
1926                            UsdLoadPolicy policy,
1927                            SdfPathSet* primIndexPaths,
1928                            bool unloadedOnly = false,
1929                            SdfPathSet* usdPrimPaths = nullptr) const;
1930 
1931     // ===================================================================== //
1932     //                          VALUE RESOLUTION                             //
1933     // ===================================================================== //
1934     // --------------------------------------------------------------------- //
1935     // Specialized Value Resolution
1936     // --------------------------------------------------------------------- //
1937 
1938     // Helpers for resolving values for metadata fields requiring
1939     // special behaviors.
1940     static SdfSpecifier _GetSpecifier(Usd_PrimDataConstPtr primData);
1941     static TfToken _GetKind(Usd_PrimDataConstPtr primData);
1942     static bool _IsActive(Usd_PrimDataConstPtr primData);
1943 
1944     // Custom is true if it is true anywhere in the stack.
1945     bool _IsCustom(const UsdProperty &prop) const;
1946 
1947     // Variability is determined by the weakest opinion in the stack.
1948     SdfVariability _GetVariability(const UsdProperty &prop) const;
1949 
1950     // Helper functions for resolving asset paths during value resolution.
1951     void _MakeResolvedAssetPaths(UsdTimeCode time, const UsdAttribute &attr,
1952                                  SdfAssetPath *assetPaths,
1953                                  size_t numAssetPaths,
1954                                  bool anchorAssetPathsOnly = false) const;
1955 
1956     void _MakeResolvedAssetPathsValue(UsdTimeCode time, const UsdAttribute &attr,
1957                                       VtValue *value,
1958                                       bool anchorAssetPathsOnly = false) const;
1959 
1960     void _MakeResolvedTimeCodes(UsdTimeCode time, const UsdAttribute &attr,
1961                                 SdfTimeCode *timeCodes,
1962                                 size_t numTimeCodes) const;
1963 
1964     void _MakeResolvedAttributeValue(UsdTimeCode time, const UsdAttribute &attr,
1965                                      VtValue *value) const;
1966 
1967     // --------------------------------------------------------------------- //
1968     // Metadata Resolution
1969     // --------------------------------------------------------------------- //
1970 
1971 public:
1972     // Trait that allows us to call the correct version of _GetMetadata for
1973     // types that require type specific value resolution as opposed to just
1974     // strongest opinion. These types also use type specific resolution
1975     // in _GetValue.
1976     template <class T>
1977     struct _HasTypeSpecificResolution {
1978         static const bool value =
1979             std::is_same<T, SdfAssetPath>::value ||
1980             std::is_same<T, VtArray<SdfAssetPath>>::value ||
1981             std::is_same<T, SdfTimeCode>::value ||
1982             std::is_same<T, VtArray<SdfTimeCode>>::value ||
1983             std::is_same<T, SdfTimeSampleMap>::value ||
1984             std::is_same<T, VtDictionary>::value;
1985     };
1986 
1987 private:
1988     // Get metadata for types that do not have type specific value resolution.
1989     template <class T>
1990     typename std::enable_if<!_HasTypeSpecificResolution<T>::value, bool>::type
1991     _GetMetadata(const UsdObject &obj,
1992                  const TfToken& fieldName,
1993                  const TfToken &keyPath,
1994                  bool useFallbacks,
1995                  T* result) const;
1996 
1997     // Get metadata for types that do have type specific value resolution.
1998     template <class T>
1999     typename std::enable_if<_HasTypeSpecificResolution<T>::value, bool>::type
2000     _GetMetadata(const UsdObject &obj,
2001                  const TfToken& fieldName,
2002                  const TfToken &keyPath,
2003                  bool useFallbacks,
2004                  T* result) const;
2005 
2006     // Get metadata as a dynamically typed VtValue. Will perform type specific
2007     // value resolution if the returned held type requires it.
2008     bool _GetMetadata(const UsdObject &obj,
2009                       const TfToken& fieldName,
2010                       const TfToken &keyPath,
2011                       bool useFallbacks,
2012                       VtValue* result) const;
2013 
2014     // Gets a metadata value using only strongest value resolution. It is
2015     // assumed that result is holding a value that does not require type
2016     // specific value resolution.
2017     USD_API
2018     bool _GetStrongestResolvedMetadata(const UsdObject &obj,
2019                                        const TfToken& fieldName,
2020                                        const TfToken &keyPath,
2021                                        bool useFallbacks,
2022                                        SdfAbstractDataValue* result) const;
2023 
2024     // Gets a metadata value with the type specific value resolution for the
2025     // type applied. This is only implemented for types that
2026     // _HasTypeSpecificResolution.
2027     template <class T>
2028     USD_API
2029     bool _GetTypeSpecificResolvedMetadata(const UsdObject &obj,
2030                                           const TfToken& fieldName,
2031                                           const TfToken &keyPath,
2032                                           bool useFallbacks,
2033                                           T* result) const;
2034 
2035     template <class Composer>
2036     void _GetAttrTypeImpl(const UsdAttribute &attr,
2037                           const TfToken &fieldName,
2038                           bool useFallbacks,
2039                           Composer *composer) const;
2040 
2041     template <class Composer>
2042     void _GetAttrVariabilityImpl(const UsdAttribute &attr,
2043                                  bool useFallbacks,
2044                                  Composer *composer) const;
2045 
2046     template <class Composer>
2047     void _GetPropCustomImpl(const UsdProperty &prop,
2048                             bool useFallbacks,
2049                             Composer *composer) const;
2050 
2051     template <class Composer>
2052     bool _GetSpecialPropMetadataImpl(const UsdObject &obj,
2053                                      const TfToken &fieldName,
2054                                      const TfToken &keyPath,
2055                                      bool useFallbacks,
2056                                      Composer *composer) const;
2057     template <class Composer>
2058     bool _GetMetadataImpl(const UsdObject &obj,
2059                           const TfToken& fieldName,
2060                           const TfToken& keyPath,
2061                           bool includeFallbacks,
2062                           Composer *composer) const;
2063 
2064     template <class Composer>
2065     bool _GetGeneralMetadataImpl(const UsdObject &obj,
2066                                  const TfToken& fieldName,
2067                                  const TfToken& keyPath,
2068                                  bool includeFallbacks,
2069                                  Composer *composer) const;
2070 
2071     // NOTE: The "authoredOnly" flag is not yet in use, but when we have
2072     // support for prim-based metadata fallbacks, they should be ignored when
2073     // this flag is set to true.
2074     bool _HasMetadata(const UsdObject &obj, const TfToken& fieldName,
2075                       const TfToken &keyPath, bool useFallbacks) const;
2076 
2077     TfTokenVector
2078     _ListMetadataFields(const UsdObject &obj, bool useFallbacks) const;
2079 
2080     void _GetAllMetadata(const UsdObject &obj,
2081                          bool useFallbacks,
2082                          UsdMetadataValueMap* result,
2083                          bool anchorAssetPathsOnly = false) const;
2084 
2085     // --------------------------------------------------------------------- //
2086     // Default & TimeSample Resolution
2087     // --------------------------------------------------------------------- //
2088 
2089     void _GetResolveInfo(const UsdAttribute &attr,
2090                          UsdResolveInfo *resolveInfo,
2091                          const UsdTimeCode *time = nullptr) const;
2092 
2093     template <class T> struct _ExtraResolveInfo;
2094 
2095     template <class T>
2096     void _GetResolveInfo(const UsdAttribute &attr,
2097                          UsdResolveInfo *resolveInfo,
2098                          const UsdTimeCode *time = nullptr,
2099                          _ExtraResolveInfo<T> *extraInfo = nullptr) const;
2100 
2101     template <class T> struct _ResolveInfoResolver;
2102     struct _PropertyStackResolver;
2103 
2104     template <class Resolver>
2105     void _GetResolvedValueImpl(const UsdProperty &prop,
2106                                Resolver *resolver,
2107                                const UsdTimeCode *time = nullptr) const;
2108 
2109     bool _GetValue(UsdTimeCode time, const UsdAttribute &attr,
2110                    VtValue* result) const;
2111 
2112     template <class T>
2113     bool _GetValue(UsdTimeCode time, const UsdAttribute &attr,
2114                    T* result) const;
2115 
2116     template <class T>
2117     bool _GetValueImpl(UsdTimeCode time, const UsdAttribute &attr,
2118                        Usd_InterpolatorBase* interpolator,
2119                        T* value) const;
2120 
2121     SdfLayerRefPtr
2122     _GetLayerWithStrongestValue(
2123         UsdTimeCode time, const UsdAttribute &attr) const;
2124 
2125 
2126 
2127     USD_API
2128     bool _GetValueFromResolveInfo(const UsdResolveInfo &info,
2129                                   UsdTimeCode time, const UsdAttribute &attr,
2130                                   VtValue* result) const;
2131 
2132     template <class T>
2133     USD_API
2134     bool _GetValueFromResolveInfo(const UsdResolveInfo &info,
2135                                   UsdTimeCode time, const UsdAttribute &attr,
2136                                   T* result) const;
2137 
2138     template <class T>
2139     bool _GetValueFromResolveInfoImpl(const UsdResolveInfo &info,
2140                                       UsdTimeCode time, const UsdAttribute &attr,
2141                                       Usd_InterpolatorBase* interpolator,
2142                                       T* value) const;
2143 
2144     // --------------------------------------------------------------------- //
2145     // Specialized Time Sample I/O
2146     // --------------------------------------------------------------------- //
2147 
2148     /// Gets the set of time samples authored for a given attribute
2149     /// within the \p interval. The interval may have any combination
2150     /// of open/infinite and closed/finite endpoints; it may not have
2151     /// open/finite endpoints, however, this restriction may be lifted
2152     /// in the future.
2153     /// Returns false on an error.
2154     bool _GetTimeSamplesInInterval(const UsdAttribute &attr,
2155                                    const GfInterval& interval,
2156                                    std::vector<double>* times) const;
2157 
2158     bool _GetTimeSamplesInIntervalFromResolveInfo(
2159                                    const UsdResolveInfo &info,
2160                                    const UsdAttribute &attr,
2161                                    const GfInterval& interval,
2162                                    std::vector<double>* times) const;
2163 
2164     size_t _GetNumTimeSamples(const UsdAttribute &attr) const;
2165 
2166     size_t _GetNumTimeSamplesFromResolveInfo(const UsdResolveInfo &info,
2167                                            const UsdAttribute &attr) const;
2168 
2169     /// Gets the bracketing times around a desiredTime. Only false on error
2170     /// or if no value exists (default or timeSamples). See
2171     /// UsdAttribute::GetBracketingTimeSamples for details.
2172     bool _GetBracketingTimeSamples(const UsdAttribute &attr,
2173                                    double desiredTime,
2174                                    bool authoredOnly,
2175                                    double* lower,
2176                                    double* upper,
2177                                    bool* hasSamples) const;
2178 
2179     bool _GetBracketingTimeSamplesFromResolveInfo(const UsdResolveInfo &info,
2180                                                   const UsdAttribute &attr,
2181                                                   double desiredTime,
2182                                                   bool authoredOnly,
2183                                                   double* lower,
2184                                                   double* upper,
2185                                                   bool* hasSamples) const;
2186 
2187     bool _ValueMightBeTimeVarying(const UsdAttribute &attr) const;
2188 
2189     bool _ValueMightBeTimeVaryingFromResolveInfo(const UsdResolveInfo &info,
2190                                                  const UsdAttribute &attr) const;
2191 
2192     void _RegisterPerLayerNotices();
2193     void _RegisterResolverChangeNotice();
2194 
2195 private:
2196 
2197     // The 'pseudo root' prim.
2198     Usd_PrimDataPtr _pseudoRoot;
2199 
2200     // The stage's root layer.
2201     SdfLayerRefPtr _rootLayer;
2202 
2203     // Every UsdStage has an implicit, in-memory session layer.
2204     // This is to allow for runtime overrides such as variant selections.
2205     SdfLayerRefPtr _sessionLayer;
2206 
2207     // The stage's EditTarget.
2208     UsdEditTarget _editTarget;
2209 
2210     std::unique_ptr<PcpCache> _cache;
2211     std::unique_ptr<Usd_ClipCache> _clipCache;
2212     std::unique_ptr<Usd_InstanceCache> _instanceCache;
2213 
2214     TfHashMap<TfToken, TfToken, TfHash> _invalidPrimTypeToFallbackMap;
2215 
2216     size_t _usedLayersRevision;
2217 
2218     // A map from Path to Prim, for fast random access.
2219     typedef TfHashMap<
2220         SdfPath, Usd_PrimDataIPtr, SdfPath::Hash> PathToNodeMap;
2221     PathToNodeMap _primMap;
2222     mutable boost::optional<tbb::spin_rw_mutex> _primMapMutex;
2223 
2224     // The interpolation type used for all attributes on the stage.
2225     UsdInterpolationType _interpolationType;
2226 
2227     typedef std::vector<
2228         std::pair<SdfLayerHandle, TfNotice::Key> > _LayerAndNoticeKeyVec;
2229     _LayerAndNoticeKeyVec _layersAndNoticeKeys;
2230     size_t _lastChangeSerialNumber;
2231 
2232     TfNotice::Key _resolverChangeKey;
2233 
2234     // Data for pending change processing.
2235     class _PendingChanges;
2236     _PendingChanges* _pendingChanges;
2237 
2238     boost::optional<WorkDispatcher> _dispatcher;
2239 
2240     // To provide useful aggregation of malloc stats, we bill everything
2241     // for this stage - from all access points - to this tag.
2242     char const *_mallocTagID;
2243 
2244     // The state used when instantiating the stage.
2245     const InitialLoadSet _initialLoadSet;
2246 
2247     // The population mask that applies to this stage.
2248     UsdStagePopulationMask _populationMask;
2249 
2250     // The load rules that apply to this stage.
2251     UsdStageLoadRules _loadRules;
2252 
2253     bool _isClosingStage;
2254     bool _isWritingFallbackPrimTypes;
2255 
2256     friend class UsdAPISchemaBase;
2257     friend class UsdAttribute;
2258     friend class UsdAttributeQuery;
2259     friend class UsdEditTarget;
2260     friend class UsdInherits;
2261     friend class UsdObject;
2262     friend class UsdPrim;
2263     friend class UsdProperty;
2264     friend class UsdRelationship;
2265     friend class UsdSpecializes;
2266     friend class UsdVariantSet;
2267     friend class UsdVariantSets;
2268     friend class Usd_FlattenAccess;
2269     friend class Usd_PcpCacheAccess;
2270     friend class Usd_PrimData;
2271     friend class Usd_StageOpenRequest;
2272     template <class T> friend struct Usd_AttrGetValueHelper;
2273     friend struct Usd_AttrGetUntypedValueHelper;
2274     template <class RefsOrPayloadsEditorType, class RefsOrPayloadsProxyType>
2275         friend struct Usd_ListEditImpl;
2276 };
2277 
2278 // UsdObject's typed metadata query relies on this specialization being
2279 // externally visible and exporting the primary template does not
2280 // automatically export this specialization.
2281 template <>
2282 USD_API
2283 bool
2284 UsdStage::_GetTypeSpecificResolvedMetadata(const UsdObject &obj,
2285                                            const TfToken& fieldName,
2286                                            const TfToken &keyPath,
2287                                            bool useFallbacks,
2288                                            SdfTimeSampleMap* result) const;
2289 
2290 template<typename T>
2291 bool
GetMetadata(const TfToken & key,T * value)2292 UsdStage::GetMetadata(const TfToken& key, T* value) const
2293 {
2294     VtValue result;
2295     if (!GetMetadata(key, &result)){
2296         return false;
2297     }
2298 
2299     if (result.IsHolding<T>()){
2300         *value = result.UncheckedGet<T>();
2301         return true;
2302     } else {
2303         TF_CODING_ERROR("Requested type %s for stage metadatum %s does not"
2304                         " match retrieved type %s",
2305                         ArchGetDemangled<T>().c_str(),
2306                         key.GetText(),
2307                         result.GetTypeName().c_str());
2308         return false;
2309     }
2310 }
2311 
2312 template<typename T>
2313 bool
SetMetadata(const TfToken & key,const T & value)2314 UsdStage::SetMetadata(const TfToken& key, const T& value) const
2315 {
2316     VtValue in(value);
2317     return SetMetadata(key, in);
2318 }
2319 
2320 template<typename T>
2321 bool
GetMetadataByDictKey(const TfToken & key,const TfToken & keyPath,T * value)2322 UsdStage::GetMetadataByDictKey(const TfToken& key, const TfToken &keyPath,
2323                                T* value) const
2324 {
2325     VtValue result;
2326     if (!GetMetadataByDictKey(key, keyPath, &result)){
2327         return false;
2328     }
2329 
2330     if (result.IsHolding<T>()){
2331         *value = result.UncheckedGet<T>();
2332         return true;
2333     } else {
2334         TF_CODING_ERROR("Requested type %s for stage metadatum %s[%s] does not"
2335                         " match retrieved type %s",
2336                         ArchGetDemangled<T>().c_str(),
2337                         key.GetText(),
2338                         keyPath.GetText(),
2339                         result.GetTypeName().c_str());
2340         return false;
2341     }
2342 }
2343 
2344 template<typename T>
2345 bool
SetMetadataByDictKey(const TfToken & key,const TfToken & keyPath,const T & value)2346 UsdStage::SetMetadataByDictKey(const TfToken& key, const TfToken &keyPath,
2347                                const T& value) const
2348 {
2349     VtValue in(value);
2350     return SetMetadataByDictKey(key, keyPath, in);
2351 }
2352 
2353 // Get metadata for types that do not have type specific value resolution.
2354 template <class T>
2355 typename std::enable_if<
2356     !UsdStage::_HasTypeSpecificResolution<T>::value, bool>::type
_GetMetadata(const UsdObject & obj,const TfToken & fieldName,const TfToken & keyPath,bool useFallbacks,T * result)2357 UsdStage::_GetMetadata(const UsdObject &obj,
2358                        const TfToken& fieldName,
2359                        const TfToken &keyPath,
2360                        bool useFallbacks,
2361                        T* result) const
2362 {
2363     // Since these types don't have type specific value resolution, we can just
2364     // get the strongest metadata value and be done.
2365     SdfAbstractDataTypedValue<T> out(result);
2366     return _GetStrongestResolvedMetadata(
2367         obj, fieldName, keyPath, useFallbacks, &out);
2368 }
2369 
2370 // Get metadata for types that do have type specific value resolution.
2371 template <class T>
2372 typename std::enable_if<
2373     UsdStage::_HasTypeSpecificResolution<T>::value, bool>::type
_GetMetadata(const UsdObject & obj,const TfToken & fieldName,const TfToken & keyPath,bool useFallbacks,T * result)2374 UsdStage::_GetMetadata(const UsdObject &obj,
2375                        const TfToken& fieldName,
2376                        const TfToken &keyPath,
2377                        bool useFallbacks,
2378                        T* result) const
2379 {
2380     // Call the templated type specifice resolved metadata implementation that
2381     // will only be implemented for types that support it.
2382     return _GetTypeSpecificResolvedMetadata(
2383         obj, fieldName, keyPath, useFallbacks, result);
2384 }
2385 
2386 
2387 // Set metadata for types that don't need to be mapped across edit targets.
2388 template <class T>
2389 typename std::enable_if<!UsdStage::_IsEditTargetMappable<T>::value, bool>::type
_SetMetadata(const UsdObject & object,const TfToken & key,const TfToken & keyPath,const T & value)2390 UsdStage::_SetMetadata(const UsdObject &object, const TfToken& key,
2391                        const TfToken &keyPath, const T& value)
2392 {
2393     // Since we know that we don't need to map the value for edit targets,
2394     // we can just type erase the value and set the metadata as is.
2395     SdfAbstractDataConstTypedValue<T> in(&value);
2396     return _SetMetadataImpl<SdfAbstractDataConstValue>(
2397         object, key, keyPath, in);
2398 }
2399 
2400 // Set metadata for types that do need to be mapped for edit targets.
2401 template <class T>
2402 typename std::enable_if<UsdStage::_IsEditTargetMappable<T>::value, bool>::type
_SetMetadata(const UsdObject & object,const TfToken & key,const TfToken & keyPath,const T & value)2403 UsdStage::_SetMetadata(const UsdObject &object, const TfToken& key,
2404                        const TfToken &keyPath, const T& value)
2405 {
2406     return _SetEditTargetMappedMetadata(object, key, keyPath, value);
2407 }
2408 
2409 
2410 PXR_NAMESPACE_CLOSE_SCOPE
2411 
2412 #endif //PXR_USD_USD_STAGE_H
2413 
2414