HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
relationship.h
Go to the documentation of this file.
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_RELATIONSHIP_H
25 #define PXR_USD_USD_RELATIONSHIP_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/property.h"
31 
32 #include "pxr/usd/sdf/path.h"
33 #include "pxr/base/vt/value.h"
34 
35 #include <string>
36 #include <vector>
37 
39 
40 
42 
43 /// A std::vector of UsdRelationships.
44 typedef std::vector<UsdRelationship> UsdRelationshipVector;
45 
46 /// \class UsdRelationship
47 ///
48 /// A UsdRelationship creates dependencies between scenegraph objects by
49 /// allowing a prim to \em target other prims, attributes, or relationships.
50 ///
51 /// \section usd_relationship_chars Relationship Characteristics
52 ///
53 /// A UsdRelationship is a pointer to other objects, which are named by their
54 /// scenegraph paths. When authoring relationships, the \em target parameters
55 /// should be scenegraph paths in the composed namespace of the UsdStage into
56 /// which you are authoring. If your edits are targeted to a different
57 /// layer, across various composition arcs (because you specified a non-default
58 /// \ref UsdEditTarget), the target's path will be automatically translated
59 /// into the proper namespace.
60 ///
61 /// A single UsdRelationship can target multiple other objects, which can be
62 /// of UsdPrim, UsdAttribute, or UsdRelationship type. UsdRelationship
63 /// participates in "list editing", which means that stronger layers in a
64 /// composed scene can add, remove, or reorder targets authored on the
65 /// relationship in weaker layers \em without stomping the weaker opinions,
66 /// although stomping behavior is still possible, via SetTargets().
67 ///
68 /// An authored relationship creates a dependency of the targeting prim on
69 /// the targeted prim(s). We consider these dependencies to be "load
70 /// dependencies", which means that when we load the targeting prim's
71 /// "load group", we will also load the targeted prims' load groups, to ensure
72 /// that all the data required to render the model containing the targeting
73 /// prim is composed and available.
74 ///
75 /// Like UsdAttribute, UsdRelationship objects are meant to be ephemeral,
76 /// live on the stack, and be cheap to refetch from their owning UsdPrim.
77 ///
78 /// Unlike UsdAttribute s, which can either be uniform over all time
79 /// or vary in value over time, UsdRelationship is <b>always uniform</b>.
80 ///
81 /// \section usd_relationship_restrictions Relationship Restrictions
82 ///
83 /// When authoring relationship targets in a stage's local LayerStack,
84 /// all target paths are legal (Note we may restrict this prior to launch
85 /// to only allowing targeting of already-extant scenegraph objects). However,
86 /// a relationship target that is legal in a local LayerStack may become
87 /// unreachable when the stage's root layer is \em referenced into an
88 /// aggregate, and will cause an error when attempting to load/compose
89 /// the aggregate.
90 ///
91 /// This can happen because references encapsulate just the tree whose root
92 /// is targeted in the reference - no other scene description in the
93 /// referenced layer will be composed into the aggregate. So if some
94 /// descendant prim of the referenced root targets a relationship to another
95 /// tree in the same layer, that relationship would dangle, and the client
96 /// will error in GetTargets() or GetForwardedTargets().
97 ///
98 /// Authoring targets to objects within prototypes is not allowed, since
99 /// prototype prims do not have a stable identity across runs. Consumers must
100 /// author targets to the object within an instance instead.
101 ///
102 /// Relationships authored in a descendent prim of a referenced prim may not
103 /// target the referenced prim itself or any of its immediate child properties
104 /// if the referencing prim is instanceable. Allowing this would break the
105 /// ability for this relationship to be instanced and shared by multiple
106 /// instances -- it would force consumers of relationships within prototypes
107 /// to resolve targets in the context of each of that prototype's instances.
108 ///
109 /// \section usd_relationship_forwarding Relationship Forwarding
110 ///
111 /// Because a relationship can target another relationship, we can and do
112 /// provide the ability to resolve chained or \em forwarded relationships.
113 /// This can be useful in several situations, including:
114 ///
115 /// \li Combining relationships with VariantSets to create demultiplexers.
116 /// A prim can host a relationship that serves as a "binding post" for
117 /// other prims to target. The prim also hosts a "bindingVariant"
118 /// UsdVariantSet whose variants each modulate the target of the
119 /// binding-post relationship. We can now change the \em forwarded target
120 /// of all prims targeting the binding-post by simply switching the
121 /// bindingVariant VariantSet. We will work through this example in
122 /// the USD reference manual.
123 /// \li Defining a relationship as part of a model's interface (so that it can
124 /// be targeted in model hierarchy with no models loaded), which, inside
125 /// the model's payload, forwards to prims useful to a client, the set of
126 /// which may vary depending on the model's configured VariantSets.
127 ///
128 class UsdRelationship : public UsdProperty {
129 public:
130  /// Construct an invalid relationship.
132 
133  /// \name Editing Relationships at Current EditTarget
134  /// @{
135 
136  // XXX Should the mutation API be changed to take UsdObject
137  // pointers so that we can enforce (as does Mf) that you can only
138  // target extant scenegraph objects? (Note the API would still need to
139  // validate those objects since it is easy to create a UsdAttribute
140  // or UsdRelationship object not backed by scene description).
141 
142  /// Adds \p target to the list of targets, in the position specified
143  /// by \p position.
144  ///
145  /// Passing paths to prototype prims or any other objects in prototypes
146  /// will cause an error to be issued. It is not valid to author targets to
147  /// these objects.
148  ///
149  /// What data this actually authors depends on what data is currently
150  /// authored in the authoring layer, with respect to list-editing
151  /// semantics, which we will document soon
152  USD_API
153  bool AddTarget(const SdfPath& target,
155 
156  /// Removes \p target from the list of targets.
157  ///
158  /// Passing paths to prototype prims or any other objects in prototypes
159  /// will cause an error to be issued. It is not valid to author targets to
160  /// these objects.
161  USD_API
162  bool RemoveTarget(const SdfPath& target) const;
163 
164  /// Make the authoring layer's opinion of the targets list explicit,
165  /// and set exactly to \p targets.
166  ///
167  /// Passing paths to prototype prims or any other objects in prototypes
168  /// will cause an error to be issued. It is not valid to author targets to
169  /// these objects.
170  ///
171  /// If any target in \p targets is invalid, no targets will be authored
172  /// and this function will return false.
173  USD_API
174  bool SetTargets(const SdfPathVector& targets) const;
175 
176  /// Remove all opinions about the target list from the current edit
177  /// target.
178  ///
179  /// Only remove the spec if \p removeSpec is true (leave the spec to
180  /// preserve meta-data we may have intentionally authored on the
181  /// relationship)
182  USD_API
183  bool ClearTargets(bool removeSpec) const;
184 
185  /// Compose this relationship's targets and fill \p targets with the result.
186  /// All preexisting elements in \p targets are lost.
187  ///
188  /// Returns true if any target path opinions have been authored and no
189  /// composition errors were encountered, returns false otherwise.
190  /// Note that authored opinions may include opinions that clear the targets
191  /// and a return value of true does not necessarily indicate that \p targets
192  /// will contain any target paths.
193  ///
194  /// See \ref Usd_ScenegraphInstancing_TargetsAndConnections for details on
195  /// behavior when targets point to objects beneath instance prims.
196  ///
197  /// The result is not cached, so will be recomputed on every query.
198  USD_API
199  bool GetTargets(SdfPathVector* targets) const;
200 
201  /// Compose this relationship's \em ultimate targets, taking into account
202  /// "relationship forwarding", and fill \p targets with the result. All
203  /// preexisting elements in \p targets are lost. This method never inserts
204  /// relationship paths in \p targets.
205  ///
206  /// Returns true if any of the visited relationships that are not
207  /// "purely forwarding" has an authored opinion for its target paths and
208  /// no composition errors were encountered while computing any targets.
209  /// Purely forwarding, in this context, means the relationship has at least
210  /// one target but all of its targets are paths to other relationships.
211  /// Note that authored opinions may include opinions that clear the targets
212  /// and a return value of true does not necessarily indicate that \p targets
213  /// will not be empty.
214  ///
215  /// Returns false otherwise. When composition errors occur, this function
216  /// continues to collect successfully composed targets, but returns false
217  /// to indicate to the caller that errors occurred.
218  ///
219  /// When a forwarded target cannot be determined, e.g. due to a composition
220  /// error, no value is returned for that target; the alternative would be to
221  /// return the relationship path at which the forwarded targets could not be
222  /// composed, however this would require all callers of
223  /// GetForwardedTargets() to account for unexpected relationship paths
224  /// being returned with the expected target results. For example, a
225  /// particular caller may expect only prim paths in the target vector, but
226  /// when composition errors occur, relationships would be included,
227  /// potentially triggering additional down stream errors.
228  ///
229  /// See \ref usd_relationship_forwarding for details on the semantics.
230  ///
231  /// The result is not cached, so will be recomputed on every query.
232  USD_API
233  bool GetForwardedTargets(SdfPathVector* targets) const;
234 
235  /// Returns true if any target path opinions have been authored.
236  /// Note that this may include opinions that clear targets and may not
237  /// indicate that target paths will exist for this relationship.
238  USD_API
239  bool HasAuthoredTargets() const;
240 
241  /// @}
242 
243 private:
244  friend class UsdObject;
245  friend class UsdPrim;
246  friend class Usd_PrimData;
247  template <class A0, class A1>
248  friend struct UsdPrim_TargetFinder;
249 
251  const SdfPath &proxyPrimPath,
252  const TfToken& relName)
253  : UsdProperty(UsdTypeRelationship, prim, proxyPrimPath, relName) {}
254 
255  UsdRelationship(UsdObjType objType,
256  const Usd_PrimDataHandle &prim,
257  const SdfPath &proxyPrimPath,
258  const TfToken &propName)
259  : UsdProperty(objType, prim, proxyPrimPath, propName) {}
260 
261  SdfRelationshipSpecHandle _CreateSpec(bool fallbackCustom=true) const;
262  bool _Create(bool fallbackCustom) const;
263 
264  bool _GetForwardedTargets(SdfPathVector* targets,
265  bool includeForwardingRels) const;
266 
267  bool _GetForwardedTargetsImpl(SdfPathSet* visited,
268  SdfPathSet* uniqueTargets,
269  SdfPathVector* targets,
270  bool *foundAnyErrors,
271  bool includeForwardingRels) const;
272 
273  SdfPath _GetTargetForAuthoring(const SdfPath &targetPath,
274  std::string* whyNot = 0) const;
275 };
276 
277 
279 
280 #endif //PXR_USD_USD_RELATIONSHIP_H
UsdObjType
Definition: object.h:51
#define USD_API
Definition: api.h:40
USD_API bool GetTargets(SdfPathVector *targets) const
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
friend struct UsdPrim_TargetFinder
Definition: relationship.h:248
USD_API bool RemoveTarget(const SdfPath &target) const
USD_API bool AddTarget(const SdfPath &target, UsdListPosition position=UsdListPositionBackOfPrependList) const
USD_API bool HasAuthoredTargets() const
Definition: token.h:87
std::vector< UsdRelationship > UsdRelationshipVector
A std::vector of UsdRelationships.
Definition: relationship.h:41
Definition: prim.h:133
GLenum target
Definition: glcorearb.h:1667
Definition: path.h:290
std::vector< class SdfPath > SdfPathVector
A vector of SdfPaths.
Definition: path.h:211
std::set< class SdfPath > SdfPathSet
A set of SdfPaths.
Definition: path.h:209
USD_API bool ClearTargets(bool removeSpec) const
USD_API bool GetForwardedTargets(SdfPathVector *targets) const
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1432
SIM_API const UT_StringHolder position
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
UsdListPosition
Definition: common.h:88
USD_API bool SetTargets(const SdfPathVector &targets) const
UsdRelationship()
Construct an invalid relationship.
Definition: relationship.h:131