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