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