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