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_REFERENCES_H 25 #define PXR_USD_USD_REFERENCES_H 26 27 #include "pxr/pxr.h" 28 #include "pxr/usd/usd/api.h" 29 #include "pxr/usd/usd/common.h" 30 #include "pxr/usd/usd/prim.h" 31 32 #include "pxr/usd/sdf/declareHandles.h" 33 #include "pxr/usd/sdf/path.h" 34 #include "pxr/usd/sdf/reference.h" 35 36 PXR_NAMESPACE_OPEN_SCOPE 37 38 /// \class UsdReferences 39 /// 40 /// UsdReferences provides an interface to authoring and introspecting 41 /// references in Usd. 42 /// 43 /// References are the primary operator for "encapsulated aggregation" of 44 /// scene description. \em aggregation means that references let us 45 /// build up rich scenes by composing scene description recorded in a (most 46 /// often) different layer. A scene can reference the same layer many times at 47 /// different locations in a scene's namespace. Referenced scene description 48 /// can be overridden in the referencing (or stronger) layers, allowing each 49 /// instance of the reference to be directly customized/overridden. 50 /// \em Encapsulated means that regardless of how much scene description is in 51 /// the referenced layer, only the scene description under and composed from 52 /// (via other composition arcs in the referenced layer) the targeted prim 53 /// will be composed into the aggregate scene. Multiple references to the 54 /// same layer will result in the layer being opened and retained in memory 55 /// only once, although each referencing prim will compose unique 56 /// \ref PcpPrimIndex "prim indices" for the tree rooted at the referenced prim. 57 /// 58 /// \section Usd_References Important Qualities and Effective Use of References 59 /// 60 /// \li Any prim can host zero, one or multiple references 61 /// 62 /// \li References are \ref SdfListOp "list editable"; that is, they compose 63 /// differently than ordinary properties and metadata. In any given 64 /// LayerStack, each authored reference operation at the same SdfPath 65 /// location in each layer (i.e. on the same prim) will compose into an 66 /// aggregate result by adding to, removing from, or replacing "weaker" 67 /// references. 68 /// 69 /// \li References can target the same LayerStack in which they are authored, 70 /// as long as doing so does not introduce a cycle in the composition graph. 71 /// See \ref Usd_Internal_References 72 /// 73 /// \li The \c identifier component of a reference in the provided API 74 /// can be a resolvable asset-path to some external layer, empty, in which case 75 /// the reference targets the root layer of the LayerStack containing the 76 /// referencing layer, or the identifier of an existing anonymous, in-memory-only 77 /// SdfLayer. Care should be exercised in the latter case: calling Export() on 78 /// an anonymous layer to serialize it to a file will not attempt to replace 79 /// any references to anonymous layers with references to file-backed layers. 80 /// 81 /// \li Opinions brought in by reference on an ancestor prim are weaker than 82 /// opinions brought in by references on a descendant prim. 83 /// 84 /// \subsection Usd_DefaultPrim_References Expressing references without prim paths 85 /// 86 /// References may omit the target prim path if the referenced layer has the 87 /// 'defaultPrim' metadata set. In this case, the reference targets the 88 /// 'defaultPrim' in the referenced layer. A layer's defaultPrim can be 89 /// authored and accessed on a UsdStage whose root layer is the layer in 90 /// question: see UsdStage::GetDefaultPrim() and UsdStage::SetDefaultPrim(). 91 /// One can also author defaultPrim directly on an SdfLayer - see 92 /// SdfLayer::GetDefaultPrim(), SdfLayer::SetDefaultPrim(). 93 /// 94 /// \subsection Usd_Internal_References Expressing "internal" references to the containing LayerStack 95 /// 96 /// References may omit the identifier specifying the referenced layer. This 97 /// creates an "internal" reference. During composition, the referenced layer 98 /// will be resolved to the root layer of the LayerStack containing the 99 /// layer where the reference was authored. See AddInternalReference(). 100 /// 101 /// \subsection Usd_Subroot_References Referencing sub-root prims 102 /// 103 /// References may target any prim in a layer. In the simplest and most 104 /// common case, a root prim in a layer will be referenced. However, 105 /// referencing sub-root prims can be useful in a variety of other cases; 106 /// for example, a user might organize prims into a meaningful hierarchy 107 /// in a layer for display purposes, then use sub-root references to 108 /// reference a selection from that hierarchy into a scene. 109 /// 110 /// Sub-root references have subtle behaviors with respect to opinions 111 /// and composition arcs authored on ancestors of the referenced prim. 112 /// Users should carefully consider this when deciding whether to use 113 /// sub-root references. These issues can be avoided by not authoring 114 /// any properties or metadata on ancestors of prims that are meant to 115 /// be referenced. 116 /// 117 /// Consider the following example: 118 /// 119 /// \code 120 /// * shot.usda | * asset.usda 121 /// | 122 /// #usda 1.0 | #usda 1.0 123 /// | 124 /// over "Class" | class "Class" 125 /// { | { 126 /// over "B" | } 127 /// { | 128 /// over "Model" | def "A" ( 129 /// { | inherits = </Class> 130 /// int a = 3 | ) 131 /// } | { 132 /// } | token purpose = "render" 133 /// } | 134 /// | def "B" ( 135 /// over "A" | variantSets = "type" 136 /// { | variants = { 137 /// over "B" ( | string type = "a" 138 /// # variant selection won't be used | } 139 /// variants = { | ) 140 /// string type = "b" | { 141 /// } | variantSet "type" = { 142 /// ) | "a" { 143 /// { | def "Model" 144 /// } | { 145 /// } | int a = 1 146 /// | } 147 /// def "ReferencedModel" ( | } 148 /// references = @./asset.usda@</A/B/Model> | "b" { 149 /// ) | def "Model" 150 /// { | { 151 /// } | int a = 2 152 /// | } 153 /// | } 154 /// | } 155 /// | } 156 /// | } 157 /// \endcode 158 /// 159 /// * Property and metadata opinions on the ancestors of the referenced prim 160 /// *are not* present in the composed stage and will never contribute to any 161 /// computations. In this example, the opinion for the attribute /A.purpose 162 /// in asset.usda will never be visible in the UsdStage for shot.usda. 163 /// 164 /// * Property and metadata opinions due to ancestral composition arcs 165 /// *are* present in the composed stage. In this example, the attribute 166 /// /Class/B/Model.a in shot.usda will be present in the UsdStage for 167 /// shot.usda, even though the inherit arc is authored on an ancestor 168 /// of the referenced prim. 169 /// 170 /// * A consequence of these rules is that users might not be able to 171 /// override ancestral variant selections that affect the referenced prim. 172 /// In this example, the Model prim being referenced comes from the 173 /// variant selection {type=a} on prim /A/B in asset.usda. The {type=b} 174 /// variant cannot be selected in shot.usda, even if prims with the 175 /// same hierarchy happen to exist there. There are various workarounds 176 /// for this; in this example, the {type=b} variant selection could be 177 /// authored on /Class/B/Model in shot.usda instead because of the 178 /// inherit arc that was established on prim /A. 179 /// 180 /// \subsection Usd_Failing_References Reasons why adding a reference may fail, why adding a reference may succeed but still generate errors, and what it all means 181 /// 182 /// AddReference() and SetReferences() can each fail for a number of 183 /// reasons. If one of the specified prim targets for one of the references 184 /// is not a prim, we will generate an error, fail to author any scene 185 /// description, and return \c false. If anything goes wrong in attempting 186 /// to write the reference, we also return false, and the reference will also 187 /// remain unauthored. Otherwise, if the reference was successfully 188 /// authored, we will return \c true. <b>A successful reference authoring 189 /// operation may still generate composition errors!</b> Just because the 190 /// reference you specified was syntactically correct and therefore 191 /// successfully authored, does not imply it was meaningful. If you wish to 192 /// ensure that the reference you are about to author will be meaningfully 193 /// consumable by your stage, you are strongly encouraged to <b>ensure it 194 /// will resolve to an actual file by using 195 /// UsdStage::ResolveIdentifierToEditTarget() before authoring the 196 /// reference.</b> 197 /// 198 /// When adding an internal reference, the given prim path is expected to 199 /// be in the namespace of the owning prim's stage. Sub-root prim paths 200 /// will be translated from this namespace to the namespace of the 201 /// current edit target, if necessary. If a path cannot be translated, 202 /// a coding error will be issued and no changes will be made. Non-sub-root 203 /// paths will not be translated. 204 /// 205 /// Immediately upon successful authoring of the reference (before returning 206 /// from AddReference(), RemoveReference(), ClearReferences(), or 207 /// SetReferences()), the UsdStage on which the reference was authored will 208 /// recompose the subtree rooted at the prim hosting the reference. If the 209 /// provided identifier does not resolve to a layer that is already opened or 210 /// that can be opened in the usd format, \em or if the provided primPath is 211 /// not an actual prim in that layer, the stage's recomposition will 212 /// fail, and pass on composition errors to the client. 213 /// 214 class UsdReferences { 215 friend class UsdPrim; 216 UsdReferences(const UsdPrim & prim)217 explicit UsdReferences(const UsdPrim& prim) : _prim(prim) {} 218 219 public: 220 /// Adds a reference to the reference listOp at the current EditTarget, 221 /// in the position specified by \p position. 222 /// \sa \ref Usd_Failing_References "Why adding references may fail" for 223 /// explanation of expectations on \p ref and what return values and errors 224 /// to expect, and \ref Usd_OM_ListOps for details on list editing and 225 /// composition of listOps. 226 USD_API 227 bool AddReference(const SdfReference& ref, 228 UsdListPosition position=UsdListPositionBackOfPrependList); 229 230 /// \overload 231 USD_API 232 bool AddReference(const std::string &identifier, 233 const SdfPath &primPath, 234 const SdfLayerOffset &layerOffset = SdfLayerOffset(), 235 UsdListPosition position=UsdListPositionBackOfPrependList); 236 237 /// \overload 238 /// \sa \ref Usd_DefaultPrim_References "References Without Prim Paths" 239 USD_API 240 bool AddReference(const std::string &identifier, 241 const SdfLayerOffset &layerOffset = SdfLayerOffset(), 242 UsdListPosition position=UsdListPositionBackOfPrependList); 243 244 /// Add an internal reference to the specified prim. 245 /// \sa \ref Usd_Internal_References "Internal References" 246 USD_API 247 bool AddInternalReference(const SdfPath &primPath, 248 const SdfLayerOffset &layerOffset = SdfLayerOffset(), 249 UsdListPosition position=UsdListPositionBackOfPrependList); 250 251 /// Removes the specified reference from the references listOp at the 252 /// current EditTarget. This does not necessarily eliminate the 253 /// reference completely, as it may be added or set in another layer in 254 /// the same LayerStack as the current EditTarget. 255 /// \sa \ref Usd_OM_ListOps 256 USD_API 257 bool RemoveReference(const SdfReference& ref); 258 259 /// Removes the authored reference listOp edits at the current EditTarget. 260 /// The same caveats for Remove() apply to Clear(). In fact, Clear() may 261 /// actually increase the number of composed references, if the listOp 262 /// being cleared contained the "remove" operator. 263 /// \sa \ref Usd_OM_ListOps 264 USD_API 265 bool ClearReferences(); 266 267 /// Explicitly set the references, potentially blocking weaker opinions 268 /// that add or remove items. 269 /// \sa \ref Usd_Failing_References "Why adding references may fail" for 270 /// explanation of expectations on \p ref and what return values and errors 271 /// to expect, and \ref Usd_OM_ListOps for details on list editing and 272 /// composition of listOps. 273 USD_API 274 bool SetReferences(const SdfReferenceVector& items); 275 276 /// Return the prim this object is bound to. GetPrim()277 const UsdPrim &GetPrim() const { return _prim; } 278 279 /// \overload GetPrim()280 UsdPrim GetPrim() { return _prim; } 281 282 explicit operator bool() { return bool(_prim); } 283 284 private: 285 UsdPrim _prim; 286 }; 287 288 PXR_NAMESPACE_CLOSE_SCOPE 289 290 #endif // PXR_USD_USD_REFERENCES_H 291