HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
materialBindingAPI.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 USDSHADE_GENERATED_MATERIALBINDINGAPI_H
25 #define USDSHADE_GENERATED_MATERIALBINDINGAPI_H
26 
27 /// \file usdShade/materialBindingAPI.h
28 
29 #include "pxr/pxr.h"
30 #include "pxr/usd/usdShade/api.h"
32 #include "pxr/usd/usd/prim.h"
33 #include "pxr/usd/usd/stage.h"
35 
37 #include "pxr/usd/usdGeom/subset.h"
39 #include <tbb/concurrent_unordered_map.h>
40 
41 #include "pxr/base/vt/value.h"
42 
43 #include "pxr/base/gf/vec3d.h"
44 #include "pxr/base/gf/vec3f.h"
45 #include "pxr/base/gf/matrix4d.h"
46 
47 #include "pxr/base/tf/token.h"
48 #include "pxr/base/tf/type.h"
49 
51 
52 class SdfAssetPath;
53 
54 // -------------------------------------------------------------------------- //
55 // MATERIALBINDINGAPI //
56 // -------------------------------------------------------------------------- //
57 
58 /// \class UsdShadeMaterialBindingAPI
59 ///
60 /// UsdShadeMaterialBindingAPI is an API schema that provides an
61 /// interface for binding materials to prims or collections of prims
62 /// (represented by UsdCollectionAPI objects).
63 ///
64 /// In the USD shading model, each renderable gprim computes a single
65 /// <b>resolved Material</b> that will be used to shade the gprim (exceptions,
66 /// of course, for gprims that possess UsdGeomSubsets, as each subset can be
67 /// shaded by a different Material). A gprim <b>and each of its ancestor
68 /// prims</b> can possess, through the MaterialBindingAPI, both a
69 /// <b>direct</b> binding to a Material, and any number of
70 /// <b>collection-based</b> bindings to Materials; each binding can be generic
71 /// or declared for a particular <b>purpose</b>, and given a specific <b>binding
72 /// strength</b>. It is the process of "material resolution" (see
73 /// \ref UsdShadeMaterialBindingAPI_MaterialResolution) that examines all of
74 /// these bindings, and selects the one Material that best matches the
75 /// client's needs.
76 ///
77 /// The intent of <b>purpose</b> is that each gprim should be able to resolve a
78 /// Material for any given purpose, which implies it can have differently bound
79 /// materials for different purposes. There are two <i>special</i> values of
80 /// <b>purpose</b> defined in UsdShade, although the API fully supports
81 /// specifying arbitrary values for it, for the sake of extensibility:
82 /// <ul><li><b>UsdShadeTokens->full</b>: to be used when the purpose of the
83 /// render is entirely to visualize the truest representation of a scene,
84 /// considering all lighting and material information, at highest fidelity.</li>
85 /// <li><b>UsdShadeTokens->preview</b>: to be used when the render is in
86 /// service of a goal other than a high fidelity "full" render (such as scene
87 /// manipulation, modeling, or realtime playback). Latency and speed are
88 /// generally of greater concern for preview renders, therefore preview
89 /// materials are generally designed to be "lighterweight" compared to full
90 /// materials.</li></ul>
91 /// A binding can also have no specific purpose at all, in which
92 /// case, it is considered to be the fallback or all-purpose binding (denoted
93 /// by the empty-valued token <b>UsdShadeTokens->allPurpose</b>).
94 ///
95 /// The <b>purpose</b> of a material binding is encoded in the name of the
96 /// binding relationship.
97 /// <ul><li>
98 /// In the case of a direct binding, the <i>allPurpose</i> binding is
99 /// represented by the relationship named <b>"material:binding"</b>.
100 /// Special-purpose direct bindings are represented by relationships named
101 /// <b>"material:binding:<i>purpose</i></b>. A direct binding relationship
102 /// must have a single target path that points to a <b>UsdShadeMaterial</b>.</li>
103 /// <li>
104 /// In the case of a collection-based binding, the <i>allPurpose</i> binding is
105 /// represented by a relationship named
106 /// "material:binding:collection:<i>bindingName</i>", where
107 /// <b>bindingName</b> establishes an identity for the binding that is unique
108 /// on the prim. Attempting to establish two collection bindings of the same
109 /// name on the same prim will result in the first binding simply being
110 /// overridden. A special-purpose collection-based binding is represented by a
111 /// relationship named "material:binding:collection:<i>purpose:bindingName</i>".
112 /// A collection-based binding relationship must have exacly two targets, one of
113 /// which should be a collection-path (see
114 /// ef UsdCollectionAPI::GetCollectionPath()) and the other should point to a
115 /// <b>UsdShadeMaterial</b>. In the future, we may allow a single collection
116 /// binding to target multiple collections, if we can establish a reasonable
117 /// round-tripping pattern for applications that only allow a single collection
118 /// to be associated with each Material.
119 /// </li>
120 /// </ul>
121 ///
122 /// <b>Note:</b> Both <b>bindingName</b> and <b>purpose</b> must be
123 /// non-namespaced tokens. This allows us to know the role of a binding
124 /// relationship simply from the number of tokens in it.
125 /// <ul><li><b>Two tokens</b>: the fallback, "all purpose", direct binding,
126 /// <i>material:binding</i></li>
127 /// <li><b>Three tokens</b>: a purpose-restricted, direct, fallback binding,
128 /// e.g. material:binding:preview</li>
129 /// <li><b>Four tokens</b>: an all-purpose, collection-based binding, e.g.
130 /// material:binding:collection:metalBits</li>
131 /// <li><b>Five tokens</b>: a purpose-restricted, collection-based binding,
132 /// e.g. material:binding:collection:full:metalBits</li>
133 /// </ul>
134 ///
135 /// A <b>binding-strength</b> value is used to specify whether a binding
136 /// authored on a prim should be weaker or stronger than bindings that appear
137 /// lower in namespace. We encode the binding strength with as token-valued
138 /// metadata <b>'bindMaterialAs'</b> for future flexibility, even though for
139 /// now, there are only two possible values:
140 /// <i>UsdShadeTokens->weakerThanDescendants</i> and
141 /// <i>UsdShadeTokens->strongerThanDescendants</i>. When binding-strength is
142 /// not authored (i.e. empty) on a binding-relationship, the default behavior
143 /// matches UsdShadeTokens->weakerThanDescendants.
144 ///
145 /// \note If a material binding relationship is a built-in property defined as
146 /// part of a typed prim's schema, a fallback value should not be provided for
147 /// it. This is because the "material resolution" algorithm only conisders
148 /// <i>authored</i> properties.
149 ///
150 ///
152 {
153 public:
154  /// Compile time constant representing what kind of schema this class is.
155  ///
156  /// \sa UsdSchemaKind
158 
159  /// Construct a UsdShadeMaterialBindingAPI on UsdPrim \p prim .
160  /// Equivalent to UsdShadeMaterialBindingAPI::Get(prim.GetStage(), prim.GetPath())
161  /// for a \em valid \p prim, but will not immediately throw an error for
162  /// an invalid \p prim
164  : UsdAPISchemaBase(prim)
165  {
166  }
167 
168  /// Construct a UsdShadeMaterialBindingAPI on the prim held by \p schemaObj .
169  /// Should be preferred over UsdShadeMaterialBindingAPI(schemaObj.GetPrim()),
170  /// as it preserves SchemaBase state.
171  explicit UsdShadeMaterialBindingAPI(const UsdSchemaBase& schemaObj)
172  : UsdAPISchemaBase(schemaObj)
173  {
174  }
175 
176  /// Destructor.
178  virtual ~UsdShadeMaterialBindingAPI();
179 
180  /// Return a vector of names of all pre-declared attributes for this schema
181  /// class and all its ancestor classes. Does not include attributes that
182  /// may be authored by custom/extended methods of the schemas involved.
184  static const TfTokenVector &
185  GetSchemaAttributeNames(bool includeInherited=true);
186 
187  /// Return a UsdShadeMaterialBindingAPI holding the prim adhering to this
188  /// schema at \p path on \p stage. If no prim exists at \p path on
189  /// \p stage, or if the prim at that path does not adhere to this schema,
190  /// return an invalid schema object. This is shorthand for the following:
191  ///
192  /// \code
193  /// UsdShadeMaterialBindingAPI(stage->GetPrimAtPath(path));
194  /// \endcode
195  ///
198  Get(const UsdStagePtr &stage, const SdfPath &path);
199 
200 
201  /// Returns true if this <b>single-apply</b> API schema can be applied to
202  /// the given \p prim. If this schema can not be a applied to the prim,
203  /// this returns false and, if provided, populates \p whyNot with the
204  /// reason it can not be applied.
205  ///
206  /// Note that if CanApply returns false, that does not necessarily imply
207  /// that calling Apply will fail. Callers are expected to call CanApply
208  /// before calling Apply if they want to ensure that it is valid to
209  /// apply a schema.
210  ///
211  /// \sa UsdPrim::GetAppliedSchemas()
212  /// \sa UsdPrim::HasAPI()
213  /// \sa UsdPrim::CanApplyAPI()
214  /// \sa UsdPrim::ApplyAPI()
215  /// \sa UsdPrim::RemoveAPI()
216  ///
218  static bool
219  CanApply(const UsdPrim &prim, std::string *whyNot=nullptr);
220 
221  /// Applies this <b>single-apply</b> API schema to the given \p prim.
222  /// This information is stored by adding "MaterialBindingAPI" to the
223  /// token-valued, listOp metadata \em apiSchemas on the prim.
224  ///
225  /// \return A valid UsdShadeMaterialBindingAPI object is returned upon success.
226  /// An invalid (or empty) UsdShadeMaterialBindingAPI object is returned upon
227  /// failure. See \ref UsdPrim::ApplyAPI() for conditions
228  /// resulting in failure.
229  ///
230  /// \sa UsdPrim::GetAppliedSchemas()
231  /// \sa UsdPrim::HasAPI()
232  /// \sa UsdPrim::CanApplyAPI()
233  /// \sa UsdPrim::ApplyAPI()
234  /// \sa UsdPrim::RemoveAPI()
235  ///
238  Apply(const UsdPrim &prim);
239 
240 protected:
241  /// Returns the kind of schema this class belongs to.
242  ///
243  /// \sa UsdSchemaKind
245  UsdSchemaKind _GetSchemaKind() const override;
246 
247 private:
248  // needs to invoke _GetStaticTfType.
249  friend class UsdSchemaRegistry;
251  static const TfType &_GetStaticTfType();
252 
253  static bool _IsTypedSchema();
254 
255  // override SchemaBase virtuals.
257  const TfType &_GetTfType() const override;
258 
259 public:
260  // ===================================================================== //
261  // Feel free to add custom code below this line, it will be preserved by
262  // the code generator.
263  //
264  // Just remember to:
265  // - Close the class declaration with };
266  // - Close the namespace with PXR_NAMESPACE_CLOSE_SCOPE
267  // - Close the include guard with #endif
268  // ===================================================================== //
269  // --(BEGIN CUSTOM CODE)--
270 
271  /// \anchor UsdShadeMaterialBindingAPI_SchemaProperties
272  /// \name Schema property and associated data retrieval API
273  ///
274  /// This section contains API for fetching the two kinds of binding
275  /// relationships and for computing the corresponding bindings.
276  ///
277  /// @{
278 
279  /// Returns the direct material-binding relationship on this prim for the
280  /// given material purpose.
281  ///
282  /// The material purpose of the relationship that's returned will match
283  /// the specified \p materialPurpose.
286  const TfToken &materialPurpose=UsdShadeTokens->allPurpose) const;
287 
288  /// Returns the collection-based material-binding relationship with the
289  /// given \p bindingName and \p materialPurpose on this prim.
290  ///
291  /// For info on \p bindingName, see UsdShadeMaterialBindingAPI::Bind().
292  /// The material purpose of the relationship that's returned will match
293  /// the specified \p materialPurpose.
296  const TfToken &bindingName,
297  const TfToken &materialPurpose=UsdShadeTokens->allPurpose) const;
298 
299  /// Returns the list of collection-based material binding relationships
300  /// on this prim for the given material purpose, \p materialPurpose.
301  ///
302  /// The returned list of binding relationships will be in native property
303  /// order. See UsdPrim::GetPropertyOrder(), UsdPrim::SetPropertyOrder().
304  /// Bindings that appear earlier in the property order are considered to be
305  /// stronger than the ones that come later. See rule #6 in
306  /// \ref UsdShadeMaterialBindingAPI_MaterialResolution.
308  std::vector<UsdRelationship> GetCollectionBindingRels(
309  const TfToken &materialPurpose=UsdShadeTokens->allPurpose) const;
310 
311  /// \class DirectBinding
312  /// This class represents a direct material binding.
314  public:
315  /// Default constructor initializes a DirectBinding object with
316  /// invalid material and bindingRel data members.
318  {}
319 
321  explicit DirectBinding(const UsdRelationship &bindingRel);
322 
323  /// Gets the material object that this direct binding binds to.
326 
327  /// Returns the path to the material that is bound to by this
328  /// direct binding.
329  const SdfPath &GetMaterialPath() const {
330  return _materialPath;
331  }
332 
333  /// Returns the binding-relationship that represents this direct
334  /// binding.
336  return _bindingRel;
337  }
338 
339  /// Returns the purpose of the direct binding.
340  const TfToken &GetMaterialPurpose() const {
341  return _materialPurpose;
342  }
343 
344  /// Returns true if there is a material bound.
345  ///
346  /// Note, GetMaterialPath() could be empty, which would indicate that no
347  /// material should be bound (and nothing should be inherited).
348  bool IsBound() const {
349  return _isBound;
350  }
351 
352  private:
353  // The path to the material that is bound to.
354  SdfPath _materialPath;
355 
356  // The binding relationship.
357  UsdRelationship _bindingRel;
358 
359  // The purpose of the material binding.
360  TfToken _materialPurpose;
361 
362  // Store if there was a binding here. This allows us to distinguish if
363  // a direct binding is purposefully empty.
364  bool _isBound;
365  };
366 
367  /// \class CollectionBinding
368  /// This struct is used to represent a collection-based material binding,
369  /// which contains two objects - a collection and a bound material.
371  public:
372  /// Default constructor initializes a CollectionBinding object with
373  /// invalid collection, material and bindingRel data members.
375  {}
376 
377  /// Constructs a CollectionBinding object from the given collection-
378  /// binding relationship. This inspects the targets of the relationship
379  /// and determines the bound collection and the target material that
380  /// the collection is bound to.
382  explicit CollectionBinding(const UsdRelationship &collBindingRel);
383 
384  /// Constructs and returns the material object that this
385  /// collection-based binding binds to.
388 
389  /// Constructs and returns the CollectionAPI object for the collection
390  /// that is bound by this collection-binding.
393 
394  /// Checks if the \p bindingRel identifies a collection
396  static bool IsCollectionBindingRel(const UsdRelationship &bindingRel);
397 
398  /// Returns true if the CollectionBinding points to a non-empty material
399  /// path and collection.
400  bool IsValid() const {
401  return CollectionBinding::IsCollectionBindingRel(_bindingRel)
402  && !GetMaterialPath().IsEmpty();
403  }
404  /// Returns the path to the collection that is bound by this binding.
405  const SdfPath &GetCollectionPath() const {
406  return _collectionPath;
407  }
408 
409  /// Returns the path to the material that is bound to by this binding.
410  const SdfPath &GetMaterialPath() const {
411  return _materialPath;
412  }
413 
414  /// Returns the binding-relationship that represents this collection-
415  /// based binding.
417  return _bindingRel;
418  }
419 
420  private:
421  // The collection being bound.
422  SdfPath _collectionPath;
423 
424  // The material that is bound to.
425  SdfPath _materialPath;
426 
427  // The relationship that binds the collection to the material.
428  UsdRelationship _bindingRel;
429  };
430 
431  using CollectionBindingVector = std::vector<CollectionBinding>;
432 
433  /// Computes and returns the direct binding for the given material purpose
434  /// on this prim.
435  ///
436  /// The returned binding always has the specified \p materialPurpose
437  /// (i.e. the all-purpose binding is not returned if a special purpose
438  /// binding is requested).
439  ///
440  /// If the direct binding is to a prim that is not a Material, this does not
441  /// generate an error, but the returned Material will be invalid (i.e.
442  /// evaluate to false).
445  const TfToken &materialPurpose=UsdShadeTokens->allPurpose) const;
446 
447  /// Returns all the collection-based bindings on this prim for the given
448  /// material purpose.
449  ///
450  /// The returned CollectionBinding objects always have the specified
451  /// \p materialPurpose (i.e. the all-purpose binding is not returned if a
452  /// special purpose binding is requested).
453  ///
454  /// If one or more collection based bindings are to prims that are not
455  /// Materials, this does not generate an error, but the corresponding
456  /// Material(s) will be invalid (i.e. evaluate to false).
457  ///
458  /// The python version of this API returns a tuple containing the
459  /// vector of CollectionBinding objects and the corresponding vector
460  /// of binding relationships.
461  ///
462  /// The returned list of collection-bindings will be in native property
463  /// order of the associated binding relationships. See
464  /// UsdPrim::GetPropertyOrder(), UsdPrim::SetPropertyOrder().
465  /// Binding relationships that come earlier in the list are considered to
466  /// be stronger than the ones that come later. See rule #6 in
467  /// \ref UsdShadeMaterialBindingAPI_MaterialResolution.
470  const TfToken &materialPurpose=UsdShadeTokens->allPurpose) const;
471 
472  /// Resolves the 'bindMaterialAs' token-valued metadata on the given binding
473  /// relationship and returns it.
474  /// If the resolved value is empty, this returns the fallback value
475  /// UsdShadeTokens->weakerThanDescendants.
476  ///
477  /// \sa UsdShadeMaterialBindingAPI::SetMaterialBindingStrength()
480  const UsdRelationship &bindingRel);
481 
482  /// Sets the 'bindMaterialAs' token-valued metadata on the given binding
483  /// relationship.
484  ///
485  /// If \p bindingStrength is <i>UsdShadeTokens->fallbackStrength</i>, the
486  /// value UsdShadeTokens->weakerThanDescendants is authored sparsely, i.e.
487  /// only when there is a different existing bindingStrength value.
488  /// To stamp out the bindingStrength value explicitly, clients can pass in
489  /// UsdShadeTokens->weakerThanDescendants or
490  /// UsdShadeTokens->strongerThanDescendants directly.
491 
492  /// Returns true on success, false otherwise.
493  ///
494  /// \sa UsdShadeMaterialBindingAPI::GetMaterialBindingStrength()
496  static bool SetMaterialBindingStrength(
497  const UsdRelationship &bindingRel,
498  const TfToken &bindingStrength);
499 
500  /// @}
501 
502  /// \anchor UsdShadeMaterialBindingAPI_Binding
503  /// \name Binding authoring and clearing API
504  ///
505  /// This section provides API for authoring and clearing both direct and
506  /// collection-based material bindings on a prim.
507  ///
508  /// @{
509 
510  /// Authors a direct binding to the given \p material on this prim.
511  ///
512  /// If \p bindingStrength is UsdShadeTokens->fallbackStrength, the value
513  /// UsdShadeTokens->weakerThanDescendants is authored sparsely.
514  /// To stamp out the bindingStrength value explicitly, clients can pass in
515  /// UsdShadeTokens->weakerThanDescendants or
516  /// UsdShadeTokens->strongerThanDescendants directly.
517  ///
518  /// If \p materialPurpose is specified and isn't equal to
519  /// UsdShadeTokens->allPurpose, the binding only applies to the specified
520  /// material purpose.
521  ///
522  /// Note that UsdShadeMaterialBindingAPI is a SingleAppliedAPI schema which
523  /// when applied updates the prim definition accordingly. This information
524  /// on the prim definition is helpful in multiple queries and more
525  /// performant. Hence its recommended to call
526  /// UsdShadeMaterialBindingAPI::Apply() when Binding a material.
527  ///
528  /// Returns true on success, false otherwise.
530  bool Bind(
531  const UsdShadeMaterial &material,
532  const TfToken &bindingStrength=UsdShadeTokens->fallbackStrength,
533  const TfToken &materialPurpose=UsdShadeTokens->allPurpose) const;
534 
535  /// Authors a collection-based binding, which binds the given \p material
536  /// to the given \p collection on this prim.
537  ///
538  /// \p bindingName establishes an identity for the binding that is unique
539  /// on the prim. Attempting to establish two collection bindings of the same
540  /// name on the same prim will result in the first binding simply being
541  /// overridden. If \p bindingName is empty, it is set to the base-name of
542  /// the collection being bound (which is the collection-name with any
543  /// namespaces stripped out). If there are multiple collections with the
544  /// same base-name being bound at the same prim, clients should pass in a
545  /// unique binding name per binding, in order to preserve all bindings.
546  /// The binding name used in constructing the collection-binding
547  /// relationship name shoud not contain namespaces. Hence, a coding error
548  /// is issued and no binding is authored if the provided value of
549  /// \p bindingName is non-empty and contains namespaces.
550  ///
551  /// If \p bindingStrength is <i>UsdShadeTokens->fallbackStrength</i>, the
552  /// value UsdShadeTokens->weakerThanDescendants is authored sparsely, i.e.
553  /// only when there is an existing binding with a different bindingStrength.
554  /// To stamp out the bindingStrength value explicitly, clients can pass in
555  /// UsdShadeTokens->weakerThanDescendants or
556  /// UsdShadeTokens->strongerThanDescendants directly.
557  ///
558  /// If \p materialPurpose is specified and isn't equal to
559  /// UsdShadeTokens->allPurpose, the binding only applies to the specified
560  /// material purpose.
561  ///
562  /// Note that UsdShadeMaterialBindingAPI is a SingleAppliedAPI schema which
563  /// when applied updates the prim definition accordingly. This information
564  /// on the prim definition is helpful in multiple queries and more
565  /// performant. Hence its recommended to call
566  /// UsdShadeMaterialBindingAPI::Apply() when Binding a material.
567  ///
568  /// Returns true on success, false otherwise.
570  bool Bind(
571  const UsdCollectionAPI &collection,
572  const UsdShadeMaterial &material,
573  const TfToken &bindingName=TfToken(),
574  const TfToken &bindingStrength=UsdShadeTokens->fallbackStrength,
575  const TfToken &materialPurpose=UsdShadeTokens->allPurpose) const;
576 
577  /// Unbinds the direct binding for the given material purpose
578  /// (\p materialPurpose) on this prim. It accomplishes this by blocking
579  /// the targets of the binding relationship in the current edit target.
580  ///
581  /// This does not remove the UsdShadeMaterialBindingAPI schema application.
583  bool UnbindDirectBinding(
584  const TfToken &materialPurpose=UsdShadeTokens->allPurpose) const;
585 
586  /// Unbinds the collection-based binding with the given \p bindingName, for
587  /// the given \p materialPurpose on this prim. It accomplishes this by
588  /// blocking the targets of the associated binding relationship in the
589  /// current edit target.
590  ///
591  /// If a binding was created without specifying a \p bindingName, then
592  /// the correct \p bindingName to use for unbinding is the instance name
593  /// of the targetted collection.
594  ///
595  /// This does not remove the UsdShadeMaterialBindingAPI schema application.
598  const TfToken &bindingName,
599  const TfToken &materialPurpose=UsdShadeTokens->allPurpose) const;
600 
601  /// Unbinds all direct and collection-based bindings on this prim.
603  bool UnbindAllBindings() const;
604 
605  /// Removes the specified \p prim from the collection targeted by the
606  /// binding relationship corresponding to given \p bindingName and
607  /// \p materialPurpose.
608  ///
609  /// If the collection-binding relationship doesn't exist or if the
610  /// targeted collection does not include the \p prim, then this does
611  /// nothing and returns true.
612  ///
613  /// If the targeted collection includes \p prim, then this modifies the
614  /// collection by removing the prim from it (by invoking
615  /// UsdCollectionAPI::RemovePrim()). This method can be used in conjunction
616  /// with the Unbind*() methods (if desired) to guarantee that a prim
617  /// has no resolved material binding.
620  const UsdPrim &prim,
621  const TfToken &bindingName,
622  const TfToken &materialPurpose) const;
623 
624  /// Adds the specified \p prim to the collection targeted by the
625  /// binding relationship corresponding to given \p bindingName and
626  /// \p materialPurpose.
627  ///
628  /// If the collection-binding relationship doesn't exist or if the
629  /// targeted collection already includes the \p prim, then this does
630  /// nothing and returns true.
631  ///
632  /// If the targeted collection does not include \p prim (or excludes it
633  /// explicitly), then this modifies the collection by adding the prim to it
634  /// (by invoking UsdCollectionAPI::AddPrim()).
637  const UsdPrim &prim,
638  const TfToken &bindingName,
639  const TfToken &materialPurpose) const;
640 
641  /// @}
642 
643  /// \anchor UsdShadeMaterialBindingAPI_MaterialResolution
644  /// \name Bound Material Resolution
645  ///
646  /// Material resolution is the process of determining the final bound
647  /// material for a given gprim (or UsdGeomSubset), for a given value of
648  /// material purpose. It involves examining all the bindings on the prim
649  /// and its ancestors, until a matching binding is found. The following
650  /// set of rules are applied in the process:
651  /// <ul>
652  /// <li>[1] Material bindings are inherited down the namespace chain.
653  /// Bindings lower in namespace (closer to leaf gprims) are stronger than
654  /// bindings on ancestors, unless they have their binding-strength set to
655  /// <i>UsdShadeTokens->strongerThanDescendants</i>.</li>
656  /// <li>[2] A collection binding only applies to members of the collection
657  /// that are at or beneath the prim owning the binding relationship.</li>
658  /// <li>[3] The purpose of the resolved material binding must either match
659  /// the requested special (i.e. restricted) purpose or be an all-purpose
660  /// binding. The restricted purpose binding, if available is preferred over
661  /// an all-purpose binding.
662  /// <li>[4] At any given prim, the collection-based bindings are considered
663  /// to be stronger than the direct bindings. This reflects our belief that
664  /// the combination would appear primarily to define a "fallback" material
665  /// to be used by any child prims that are not targeted by a more specific
666  /// assignment</li>
667  /// <li>[5] Collection-based binding relationships are applied in native
668  /// property order, with the earlier ordered binding relationships being
669  /// stronger.</li>
670  /// <li>[6] The "namespace specificity" with which a prim is included in a
671  /// collection is irrelevant to the binding strength of the collection. For
672  /// example, if a prim contains the ordered collection bindings
673  /// material:binding:collection:metalBits and
674  /// material:binding:collection:plasticBits, each of which targets a
675  /// collection of the same name, then if metalBits includes </Chair/Back>,
676  /// while plasticBits includes </Chair/Back/Brace/Rivet>, the binding for
677  /// </Chair/Back/Brace/Rivet> will be metalBits, because the metalBits
678  /// collection is bound more strongly than the plasticBits, and includes
679  /// an ancestor of </Chair/Back/Brace/Rivet>.
680  /// </li>
681  /// </ul>
682  ///
683  /// \note If a material binding relationship is a built-in property defined
684  /// as part of a typed prim schema, a fallback value should not be provided
685  /// for it. This is because the "material resolution" algorithm only
686  /// conisders <i>authored</i> properties.
687  ///
688  /// @{
689 
690  /// An unordered list of collection paths mapped to the associated
691  /// collection's MembershipQuery object. This is used to cache the
692  /// MembershipQuery objects for collections that are encountered during
693  /// binding resolution for a tree of prims.
694  using CollectionQueryCache =
695  tbb::concurrent_unordered_map<SdfPath,
696  std::unique_ptr<UsdCollectionAPI::MembershipQuery>, SdfPath::Hash>;
697 
698  /// Alias for a unique_ptr to a DirectBinding object.
699  using DirectBindingPtr = std::unique_ptr<DirectBinding>;
700 
701  struct BindingsAtPrim {
702  /// Inspects all the material:binding* properties on the \p prim and
703  /// computes direct and collection-based bindings for the given
704  /// value of \p materialPurpose.
705  ///
706  /// To provide backward compatibility with old assets not having
707  /// MaterialBindingAPI applied, \p supportLegacyBindings is used to
708  /// determine whether we perform the full computation even if
709  /// MaterialBindingAPI is not applied to \p prim.
710  ///
712  BindingsAtPrim(const UsdPrim &prim, const TfToken &materialPurpose,
713  bool supportLegacyBindings);
714 
715  /// If the prim has a restricted purpose direct binding, then it is
716  /// stored here. If there is no restricted purpose binding on the prim,
717  /// then the all-purpose direct binding is stored.
719 
720  /// The ordered list of restricted-purpose collection bindings on the
721  /// prim.
723 
724  /// The ordered list of all-purpose collection bindings on the prim.
726  };
727 
728  /// BindingsAtPrim needs to invoke private _GetCollectionBindings().
729  friend struct BindingsAtPrim;
730 
731  /// An unordered list of prim-paths mapped to the corresponding set of
732  /// bindings at the associated prim. This is used when computing resolved
733  /// bindings to avoid redundant computations for the shared ancestor
734  /// prims and to re-use the computed results for leaf prims.
735  using BindingsCache = tbb::concurrent_unordered_map<SdfPath,
736  std::unique_ptr<BindingsAtPrim>, SdfPath::Hash>;
737 
738  /// Returns a vector of the possible values for the 'material purpose'.
741 
742  /// returns the path of the resolved target identified by \p bindingRel.
745  const UsdRelationship &bindingRel);
746 
747  /// Computes the resolved bound material for this prim, for the given
748  /// material purpose.
749  ///
750  /// This overload of ComputeBoundMaterial makes use of the BindingsCache
751  /// (\p bindingsCache) and CollectionQueryCache (\p collectionQueryCache)
752  /// that are passed in, to avoid redundant binding computations and
753  /// computations of MembershipQuery objects for collections.
754  /// It would be beneficial to make use of these when resolving bindings for
755  /// a tree of prims. These caches are populated lazily as more and more
756  /// bindings are resolved.
757  ///
758  /// When the goal is to compute the bound material for a range (or list) of
759  /// prims, it is recommended to use this version of ComputeBoundMaterial().
760  /// Here's how you could compute the bindings of a range of prims
761  /// efficiently in C++:
762  ///
763  /// \code
764  /// std::vector<std::pair<UsdPrim, UsdShadeMaterial> primBindings;
765  /// UsdShadeMaterialBindingAPI::BindingsCache bindingsCache;
766  /// UsdShadeMaterialBindingAPI::CollectionQueryCache collQueryCache;
767  ///
768  /// for (auto prim : UsdPrimRange(rootPrim)) {
769  /// UsdShadeMaterial boundMaterial =
770  /// UsdShadeMaterialBindingAPI(prim).ComputeBoundMaterial(
771  /// &bindingsCache, &collQueryCache);
772  /// if (boundMaterial) {
773  /// primBindings.emplace_back({prim, boundMaterial});
774  /// }
775  /// }
776  /// \endcode
777  ///
778  /// If \p bindingRel is not null, then it is set to the "winning" binding
779  /// relationship.
780  ///
781  /// Note the resolved bound material is considered valid if the target path
782  /// of the binding relationship is a valid non-empty prim path. This makes
783  /// sure winning binding relationship and the bound material remain consistent
784  /// consistent irrespective of the presence/absence of prim at material
785  /// path. For ascenario where ComputeBoundMaterial returns a invalid
786  /// UsdShadeMaterial with a valid winning bindingRel, clients can use the
787  /// static method
788  /// UsdShadeMaterialBindingAPI::GetResolvedTargetPathFromBindingRel to get
789  /// the path of the resolved target identified by the winning bindingRel.
790  ///
791  /// In order for backward compatibility with old assets not having
792  /// MaterialBindingAPI applied, \p supportLegacyBindings defaults to true.
793  /// Though its recommended for clients to update the assets to have
794  /// MaterialBindingAPI applied for optimized computation of bound material.
795  ///
796  /// Note: In a future release the default for \p supportLegacyBindings will
797  /// be updated to "false".
798  ///
799  /// See \ref UsdShadeMaterialBindingAPI_MaterialResolution "Bound Material Resolution"
800  /// for details on the material resolution process.
801  ///
802  /// The python version of this method returns a tuple containing the
803  /// bound material and the "winning" binding relationship.
806  BindingsCache *bindingsCache,
807  CollectionQueryCache *collectionQueryCache,
808  const TfToken &materialPurpose=UsdShadeTokens->allPurpose,
809  UsdRelationship *bindingRel=nullptr,
810  bool supportLegacyBindings=true) const;
811 
812  /// \overload
813  /// Computes the resolved bound material for this prim, for the given
814  /// material purpose.
815  ///
816  /// This overload does not utilize cached MembershipQuery object. However,
817  /// it only computes the MembershipQuery of every collection that bound
818  /// in the ancestor chain at most once.
819  ///
820  /// If \p bindingRel is not null, then it is set to the winning binding
821  /// relationship.
822  ///
823  /// In order for backward compatibility with old assets not having
824  /// MaterialBindingAPI applied, \p supportLegacyBindings defaults to true.
825  /// Though its recommended for clients to update the assets to have
826  /// MaterialBindingAPI applied for optimized computation of bound material.
827  ///
828  /// Note: In a future release the default for \p supportLegacyBindings will
829  /// be updated to "false".
830  ///
831  /// See \ref UsdShadeMaterialBindingAPI_MaterialResolution "Bound Material Resolution"
832  /// for details on the material resolution process.
833  ///
834  /// The python version of this method returns a tuple containing the
835  /// bound material and the "winning" binding relationship.
838  const TfToken &materialPurpose=UsdShadeTokens->allPurpose,
839  UsdRelationship *bindingRel=nullptr,
840  bool supportLegacyBindings=true) const;
841 
842  /// Static API for efficiently and concurrently computing the resolved
843  /// material bindings for a vector of UsdPrims, \p prims for the
844  /// given \p materialPurpose.
845  ///
846  /// The size of the returned vector always matches the size of the input
847  /// vector, \p prims. If a prim is not bound to any material, an invalid
848  /// or empty UsdShadeMaterial is returned at the index corresponding to it.
849  ///
850  /// If the pointer \p bindingRels points to a valid vector, then it is
851  /// populated with the set of all "winning" binding relationships.
852  ///
853  /// In order for backward compatibility with old assets not having
854  /// MaterialBindingAPI applied, \p supportLegacyBindings defaults to true.
855  /// Though its recommended for clients to update the assets to have
856  /// MaterialBindingAPI applied for optimized computation of bound material.
857  ///
858  /// Note: In a future release the default for \p supportLegacyBindings will
859  /// be updated to "false".
860  ///
861  /// The python version of this method returns a tuple containing two lists -
862  /// the bound materials and the corresponding "winning" binding
863  /// relationships.
865  static std::vector<UsdShadeMaterial> ComputeBoundMaterials(
866  const std::vector<UsdPrim> &prims,
867  const TfToken &materialPurpose=UsdShadeTokens->allPurpose,
868  std::vector<UsdRelationship> *bindingRels=nullptr,
869  bool supportLegacyBindings=true);
870 
871  /// @}
872 
873  // --------------------------------------------------------------------- //
874  /// \anchor UsdShadeMaterialBindingAPI_Subsets
875  /// \name Binding materials to subsets
876  ///
877  /// API to create, access and query the presence of GeomSubsets that are
878  /// created for the purpose of binding materials.
879  ///
880  /// \note GeomSubsets can only be created on valid UsdGeomImageable prims.
881  /// Hence, this API only works when the prim held by the MaterialBindingAPI
882  /// schema object is an imageable prim.
883  ///
884  /// \note Material bindings authored on GeomSubsets are honored by renderers
885  /// only if their familyName is <b>UsdShadeTokens->materialBind</b>. This
886  /// allows robust interchange of subset bindings between multiple DCC apps.
887  ///
888  /// \note The family type of the <i>materialBind</i> family of subsets
889  /// defaults to UsdGeomTokens->nonOverlapping. It can be set to
890  /// UsdGeomTokens->partition, using the API
891  /// SetMaterialBindFaceSubsetsFamilyType(). It should never be set to
892  /// UsdGeomTokens->unrestricted, since it is invalid for a piece of
893  /// geometry to be bound to multiple materials.
894  ///
895  /// Here's some sample code that shows how to create "face" subsets and
896  /// and bind materials to them.
897  /// \code
898  /// // Get the imageable prim under which subsets must be created and
899  /// // bound.
900  /// UsdGeomImageable mesh = UsdGeomImageable::Get(stage,
901  /// SdfPath("/path/to/meshPrim");
902  ///
903  /// // Get the materials to bind to.
904  /// UsdShadeMaterial plastic = UsdShadeMaterial::Get(stage,
905  /// SdfPath("/path/to/PlasticMaterial");
906  /// UsdShadeMaterial metal = UsdShadeMaterial::Get(stage,
907  /// SdfPath("/path/to/MetalMaterial");
908  ///
909  /// VtIntArray plasticFaces, metalFaces;
910  /// //.. populate faceIndices here.
911  /// //..
912  ///
913  /// UsdGeomMaterialBindingAPI meshBindingAPI(mesh.GetPrim());
914  /// UsdGeomSubset plasticSubset = meshBindingAPI.CreateMaterialBindSubset(
915  /// "plasticSubset", plasticFaces);
916  /// UsdGeomSubset metalSubset = meshBindingAPI.CreateMaterialBindSubset(
917  /// "metalSubset", metalFaces);
918  ///
919  /// // Bind materials to the created geom-subsets.
920  /// UsdShadeMaterialBindingAPI(pasticSubset.GetPrim()).Bind(plastic)
921  /// UsdShadeMaterialBindingAPI(metalSubset.GetPrim()).Bind(metal)
922  ///
923  /// \endcode
924  /// @{
925 
926  /// Creates a GeomSubset named \p subsetName with element type,
927  /// \p elementType and familyName <b>materialBind<b> below this prim.
928  ///
929  /// If a GeomSubset named \p subsetName already exists, then its
930  /// "familyName" is updated to be UsdShadeTokens->materialBind and its
931  /// indices (at <i>default</i> timeCode) are updated with the provided
932  /// \p indices value before returning.
933  ///
934  /// This method forces the familyType of the "materialBind" family of
935  /// subsets to UsdGeomTokens->nonOverlapping if it's unset or explicitly set
936  /// to UsdGeomTokens->unrestricted.
937  ///
938  /// The default value \p elementType is UsdGeomTokens->face, as we expect
939  /// materials to be bound most often to subsets of faces on meshes.
942  const TfToken &subsetName,
943  const VtIntArray &indices,
944  const TfToken &elementType=UsdGeomTokens->face);
945 
946  /// Returns all the existing GeomSubsets with
947  /// familyName=UsdShadeTokens->materialBind below this prim.
949  std::vector<UsdGeomSubset> GetMaterialBindSubsets();
950 
951  /// Author the <i>familyType</i> of the "materialBind" family of GeomSubsets
952  /// on this prim.
953  ///
954  /// The default \p familyType is <i>UsdGeomTokens->nonOverlapping<i>. It
955  /// can be set to <i>UsdGeomTokens->partition</i> to indicate that the
956  /// entire imageable prim is included in the union of all the "materialBind"
957  /// subsets. The family type should never be set to
958  /// UsdGeomTokens->unrestricted, since it is invalid for a single piece
959  /// of geometry (in this case, a subset) to be bound to more than one
960  /// material. Hence, a coding error is issued if \p familyType is
961  /// UsdGeomTokens->unrestricted.
962  ///
963  /// \sa UsdGeomSubset::SetFamilyType
965  bool SetMaterialBindSubsetsFamilyType(const TfToken &familyType);
966 
967  /// Returns the familyType of the family of "materialBind" GeomSubsets on
968  /// this prim.
969  ///
970  /// By default, materialBind subsets have familyType="nonOverlapping", but
971  /// they can also be tagged as a "partition", using
972  /// SetMaterialBindFaceSubsetsFamilyType().
973  ///
974  /// \sa UsdGeomSubset::GetFamilyNameAttr
977 
978  /// Test whether a given \p name contains the "material:binding:" prefix
979  ///
981  static bool CanContainPropertyName(const TfToken &name);
982 
983  /// @}
984 
985 private:
986 
987  UsdRelationship _CreateDirectBindingRel(
988  const TfToken &materialPurpose) const;
989 
990  UsdRelationship _CreateCollectionBindingRel(
991  const TfToken &bindingName,
992  const TfToken &materialPurpose) const;
993 
994  // Helper method for getting collection bindings when the set of all
995  // collection binding relationship names for the required purpose is
996  // known.
997  CollectionBindingVector _GetCollectionBindings(
998  const TfTokenVector &collBindingPropertyNames) const;
999 };
1000 
1002 
1003 #endif
USDSHADE_API UsdSchemaKind _GetSchemaKind() const override
#define USDSHADE_API
Definition: api.h:40
static USDSHADE_API UsdShadeMaterialBindingAPI Get(const UsdStagePtr &stage, const SdfPath &path)
static USDSHADE_API bool SetMaterialBindingStrength(const UsdRelationship &bindingRel, const TfToken &bindingStrength)
const SdfPath & GetMaterialPath() const
Returns the path to the material that is bound to by this binding.
GLsizei GLenum const void * indices
Definition: glcorearb.h:406
USDSHADE_API std::vector< UsdGeomSubset > GetMaterialBindSubsets()
USDSHADE_API TfStaticData< UsdShadeTokensType > UsdShadeTokens
const TfToken & GetMaterialPurpose() const
Returns the purpose of the direct binding.
Single Apply API schema.
CollectionBindingVector allPurposeCollBindings
The ordered list of all-purpose collection bindings on the prim.
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
USDSHADE_API UsdShadeMaterial GetMaterial() const
Gets the material object that this direct binding binds to.
static USDSHADE_API const SdfPath GetResolvedTargetPathFromBindingRel(const UsdRelationship &bindingRel)
returns the path of the resolved target identified by bindingRel.
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
USDSHADE_API bool SetMaterialBindSubsetsFamilyType(const TfToken &familyType)
static USDSHADE_API bool CanContainPropertyName(const TfToken &name)
USDSHADE_API bool UnbindAllBindings() const
Unbinds all direct and collection-based bindings on this prim.
bool IsEmpty() const noexcept
Returns true if this is the empty path (SdfPath::EmptyPath()).
Definition: path.h:424
static USDSHADE_API bool CanApply(const UsdPrim &prim, std::string *whyNot=nullptr)
USDSHADE_API DirectBinding GetDirectBinding(const TfToken &materialPurpose=UsdShadeTokens->allPurpose) const
const SdfPath & GetCollectionPath() const
Returns the path to the collection that is bound by this binding.
static USDSHADE_API TfTokenVector GetMaterialPurposes()
Returns a vector of the possible values for the 'material purpose'.
USDSHADE_API bool Bind(const UsdShadeMaterial &material, const TfToken &bindingStrength=UsdShadeTokens->fallbackStrength, const TfToken &materialPurpose=UsdShadeTokens->allPurpose) const
USDSHADE_API UsdRelationship GetDirectBindingRel(const TfToken &materialPurpose=UsdShadeTokens->allPurpose) const
static USDSHADE_API std::vector< UsdShadeMaterial > ComputeBoundMaterials(const std::vector< UsdPrim > &prims, const TfToken &materialPurpose=UsdShadeTokens->allPurpose, std::vector< UsdRelationship > *bindingRels=nullptr, bool supportLegacyBindings=true)
Definition: token.h:87
tbb::concurrent_unordered_map< SdfPath, std::unique_ptr< UsdCollectionAPI::MembershipQuery >, SdfPath::Hash > CollectionQueryCache
static const UsdSchemaKind schemaKind
USDSHADE_API bool AddPrimToBindingCollection(const UsdPrim &prim, const TfToken &bindingName, const TfToken &materialPurpose) const
USDSHADE_API bool UnbindDirectBinding(const TfToken &materialPurpose=UsdShadeTokens->allPurpose) const
USDSHADE_API UsdGeomSubset CreateMaterialBindSubset(const TfToken &subsetName, const VtIntArray &indices, const TfToken &elementType=UsdGeomTokens->face)
static USDSHADE_API UsdShadeMaterialBindingAPI Apply(const UsdPrim &prim)
Definition: prim.h:135
USDSHADE_API bool UnbindCollectionBinding(const TfToken &bindingName, const TfToken &materialPurpose=UsdShadeTokens->allPurpose) const
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:442
GLuint const GLchar * name
Definition: glcorearb.h:786
Definition: path.h:291
USDSHADE_API UsdShadeMaterial ComputeBoundMaterial(BindingsCache *bindingsCache, CollectionQueryCache *collectionQueryCache, const TfToken &materialPurpose=UsdShadeTokens->allPurpose, UsdRelationship *bindingRel=nullptr, bool supportLegacyBindings=true) const
USDSHADE_API UsdCollectionAPI GetCollection() const
USDSHADE_API UsdShadeMaterial GetMaterial() const
static USDSHADE_API bool IsCollectionBindingRel(const UsdRelationship &bindingRel)
Checks if the bindingRel identifies a collection.
UsdShadeMaterialBindingAPI(const UsdPrim &prim=UsdPrim())
UsdSchemaKind
Definition: common.h:127
USDSHADE_API bool RemovePrimFromBindingCollection(const UsdPrim &prim, const TfToken &bindingName, const TfToken &materialPurpose) const
const UsdRelationship & GetBindingRel() const
USDSHADE_API BindingsAtPrim(const UsdPrim &prim, const TfToken &materialPurpose, bool supportLegacyBindings)
USDSHADE_API UsdRelationship GetCollectionBindingRel(const TfToken &bindingName, const TfToken &materialPurpose=UsdShadeTokens->allPurpose) const
USDGEOM_API TfStaticData< UsdGeomTokensType > UsdGeomTokens
std::unique_ptr< DirectBinding > DirectBindingPtr
Alias for a unique_ptr to a DirectBinding object.
static USDSHADE_API TfToken GetMaterialBindingStrength(const UsdRelationship &bindingRel)
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1441
UsdShadeMaterialBindingAPI(const UsdSchemaBase &schemaObj)
CollectionBindingVector restrictedPurposeCollBindings
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
static USDSHADE_API const TfTokenVector & GetSchemaAttributeNames(bool includeInherited=true)
Definition: type.h:64
tbb::concurrent_unordered_map< SdfPath, std::unique_ptr< BindingsAtPrim >, SdfPath::Hash > BindingsCache
USDSHADE_API TfToken GetMaterialBindSubsetsFamilyType()
USDSHADE_API CollectionBindingVector GetCollectionBindings(const TfToken &materialPurpose=UsdShadeTokens->allPurpose) const
virtual USDSHADE_API ~UsdShadeMaterialBindingAPI()
Destructor.
USDSHADE_API std::vector< UsdRelationship > GetCollectionBindingRels(const TfToken &materialPurpose=UsdShadeTokens->allPurpose) const
const UsdRelationship & GetBindingRel() const
std::vector< CollectionBinding > CollectionBindingVector