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