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 targetted 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 targetting prim on
69 /// the targetted 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 targetted 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 targetted 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 masters is not allowed, since master
99 /// prims do not have a stable identity across runs. Consumers must author
100 /// 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 masters
107 /// to resolve targets in the context of each of that master'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 targetting 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 targetted 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 master prims or any other objects in masters will
146  /// 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 master prims or any other objects in masters will
159  /// 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  /// Clears all target edits from the current EditTarget, and makes
165  /// the opinion explicit, which means we are effectively resetting the
166  /// composed value of the targets list to empty.
167  USD_API
168  bool BlockTargets() const;
169 
170  /// Make the authoring layer's opinion of the targets list explicit,
171  /// and set exactly to \p targets.
172  ///
173  /// Passing paths to master prims or any other objects in masters will
174  /// cause an error to be issued. It is not valid to author targets to
175  /// these objects.
176  ///
177  /// If any target in \p targets is invalid, no targets will be authored
178  /// and this function will return false.
179  USD_API
180  bool SetTargets(const SdfPathVector& targets) const;
181 
182  /// Remove all opinions about the target list from the current edit
183  /// target.
184  ///
185  /// Only remove the spec if \p removeSpec is true (leave the spec to
186  /// preserve meta-data we may have intentionally authored on the
187  /// relationship)
188  USD_API
189  bool ClearTargets(bool removeSpec) const;
190 
191  /// Compose this relationship's targets and fill \p targets with the result.
192  /// All preexisting elements in \p targets are lost.
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  /// When composition errors occur, continue to collect successfully
207  /// composed targets, but return false to indicate to the caller that
208  /// errors occurred.
209  ///
210  /// When a forwarded target cannot be determined, e.g. due to a composition
211  /// error, no value is returned for that target; the alternative would be to
212  /// return the relationship path at which the forwarded targets could not be
213  /// composed, however this would require all callers of
214  /// GetForwardedTargets() to account for unexpected relationship paths
215  /// being returned with the expected target results. For example, a
216  /// particular caller may expect only prim paths in the target vector, but
217  /// when composition errors occur, relationships would be included,
218  /// potentially triggering additional down stream errors.
219  ///
220  /// See \ref usd_relationship_forwarding for details on the semantics.
221  ///
222  /// The result is not cached, so will be recomputed on every query.
223  USD_API
224  bool GetForwardedTargets(SdfPathVector* targets) const;
225 
226  /// Returns true if any target path opinions have been authored.
227  /// Note that this may include opinions that clear targets and may not
228  /// indicate that target paths will exist for this relationship.
229  USD_API
230  bool HasAuthoredTargets() const;
231 
232  /// @}
233 
234 private:
235  friend class UsdObject;
236  friend class UsdPrim;
237  friend class Usd_PrimData;
238  template <class A0, class A1>
239  friend struct UsdPrim_TargetFinder;
240 
242  const SdfPath &proxyPrimPath,
243  const TfToken& relName)
244  : UsdProperty(UsdTypeRelationship, prim, proxyPrimPath, relName) {}
245 
246  UsdRelationship(UsdObjType objType,
247  const Usd_PrimDataHandle &prim,
248  const SdfPath &proxyPrimPath,
249  const TfToken &propName)
250  : UsdProperty(objType, prim, proxyPrimPath, propName) {}
251 
252  SdfRelationshipSpecHandle _CreateSpec(bool fallbackCustom=true) const;
253  bool _Create(bool fallbackCustom) const;
254 
255  bool _GetForwardedTargets(SdfPathVector* targets,
256  bool includeForwardingRels) const;
257 
258  bool _GetForwardedTargets(SdfPathSet* visited,
259  SdfPathSet* uniqueTargets,
260  SdfPathVector* targets,
261  bool includeForwardingRels) const;
262 
263  SdfPath _GetTargetForAuthoring(const SdfPath &targetPath,
264  std::string* whyNot = 0) const;
265 };
266 
267 
269 
270 #endif //PXR_USD_USD_RELATIONSHIP_H
UsdObjType
Definition: object.h:49
#define USD_API
Definition: api.h:40
UsdListPosition
Definition: common.h:88
USD_API bool GetTargets(SdfPathVector *targets) const
GLenum target
Definition: glew.h:2865
friend struct UsdPrim_TargetFinder
Definition: relationship.h:239
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
USD_API bool BlockTargets() const
std::vector< UsdRelationship > UsdRelationshipVector
A std::vector of UsdRelationships.
Definition: relationship.h:41
Definition: prim.h:132
Definition: path.h:288
std::vector< class SdfPath > SdfPathVector
A vector of SdfPaths.
Definition: path.h:209
std::set< class SdfPath > SdfPathSet
A set of SdfPaths.
Definition: path.h:207
GLsizei const GLchar *const * string
Definition: glew.h:1844
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:1346
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
USD_API bool SetTargets(const SdfPathVector &targets) const
UsdRelationship()
Construct an invalid relationship.
Definition: relationship.h:131