materialOverrideResolvingSceneIndex.h
1 //
2 // Copyright 2024 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_IMAGING_HDSI_MATERIAL_OVERRIDE_RESOLVING_SCENE_INDEX_H
8 #define PXR_IMAGING_HDSI_MATERIAL_OVERRIDE_RESOLVING_SCENE_INDEX_H
9 
11 #include "pxr/imaging/hd/filteringSceneIndex.h"
14 #include "pxr/imaging/hdsi/api.h"
15 
16 #include <optional>
17 #include <unordered_map>
18 #include <unordered_set>
19 
20 PXR_NAMESPACE_OPEN_SCOPE
21 
22 using PathSet = std::unordered_set<SdfPath, SdfPath::Hash>;
23 
24 TF_DECLARE_WEAK_AND_REF_PTRS(HdsiMaterialOverrideResolvingSceneIndex);
25 
26 /*
27 HdsiMaterialOverrideResolvingSceneIndex applies material overrides in the form
28 of edits to a material's interface or directly to parameters of its shader nodes.
29 
30 Overrides to a material's interface are only applied if their interface mappings
31 are found.
32 The overrides for a particular 'publicUIName' are specified at path like this:
33 
34 materialOverride.interfaceValues.<publicUIName>.value
35  -> overrideValueDataSource
36 
37 The 'overrideValueDataSource' is copied over a network node parameter's original
38 'valueDataSource' at paths like this:
39 
40 material.<renderContext>.nodes.<nodePath>.parameters.<inputName>.value
41  -> valueDataSource
42 
43 The scene index identifies which network node parameter to override by using
44 the material's interface mappings which are defined at paths like this:
45 
46 material.<renderContext>.interface.parameters.<publicUIName>.mappings
47  -> [(nodePath, inputName), (nodePath, inputName), ...]
48 
49 Edits of input parameters of shaders within the material are specified at a path
50 like this:
51 materialOverride.parameterValues.<shaderNodeName>.<parameterName>.value ->
52  paramEditValueDataSource
53 
54 The 'paramEditValueDataSource' is copied over a network node parameter's original
55 'valueDataSource' at paths like this:
56 
57 material.<renderContext>.nodes.<nodePath>.parameters.<inputName>.value
58  -> valueDataSource
59 
60 If the same input parameter is overridden both by an edit to the material
61 interface and by a direct parameter edit, the interface override will take
62 precedence.
63 
64 If a geometry prim contains materialOverride data sources, a copy of
65 the material bound to that location will be generated, and the overrides will
66 only be applied to the generated material.
67 Any changes to the original material will be reflected in the generated material.
68 Geometry prims that contain materialOverride data sources are only
69 processed by this Scene Index if they contain a materialBindings data source
70 with material binds for one of the following purposes: full, allPurpose.
71 A minimum set of materials will be generated to satisfy material overrides: two
72 geometry prims bound to the same material and containing the same set of
73 material overrides will share the same generated material.
74 
75 Below is a diagram of the expected attributes needed for material interface
76 and parameter edits on a scene index prim of type 'material':
77 
78 MaterialPrim
79 |
80 +------materialOverride
81 | |
82 | +----interfaceValues
83 | | |
84 | | +-publicUIName
85 | | | |
86 | | | +---value -> overrideValueDataSource
87 | | |
88 | | +-publicUIName
89 | | | |
90 | | | +---value -> overrideValueDataSource
91 | | |
92 | | +-...
93 | |
94 | +----parameterValues
95 | |
96 | +-nodePath
97 | | |
98 | | +---inputName
99 | | | |
100 | | | +---value -> paramEditValueDataSource
101 | | |
102 | | +---inputName
103 | | | |
104 | | | +---value -> paramEditValueDataSource
105 | | |
106 | | +---...
107 | |
108 | +-...
109 |
110 +------material
111  |
112  +----ri
113  |
114  +--nodes
115  | |
116  | +-nodePath
117  | | |
118  | | +-parameters
119  | | |
120  | | +-inputName
121  | | | |
122  | | | +-value -> valueDataSource
123  | | |
124  | | +-inputName
125  | | |
126  | | +-value -> valueDataSource
127  | |
128  | +-nodePath
129  | |
130  | +-parameters
131  | |
132  | +-...
133  |
134  +--interface
135  |
136  +-parameters
137  | |
138  | +-publicUIName
139  | | |
140  | | +-mappings
141  | | +-i0
142  | | | |
143  | | | +----nodePath
144  | | | |
145  | | | +----inputName
146  | | |
147  | | +-i1
148  | | | |
149  | | | +----nodePath
150  | | | |
151  | | | +----inputName
152  | | |
153  | | +-...
154  | |
155  | +-publicUIName
156  | | |
157  | | +-mappings
158  | | +-i0
159  | | | |
160  | | | +----nodePath
161  | | | |
162  | | | +----inputName
163  | | |
164  | | +-i1
165  | | | |
166  | | | +----nodePath
167  | | | |
168  | | | +----inputName
169  | | |
170  | | +-...
171  | +-...
172  |
173  +-parameterOrder = ...
174 */
175 
176 class HdsiMaterialOverrideResolvingSceneIndex final :
178 {
179  // Forward Declarations
180  struct MaterialData;
181  struct PrimData;
182 
183  // Type Definitions
184  using PrimDataMap = std::unordered_map<SdfPath, PrimData, SdfPath::Hash>;
185  using MaterialPathsMap = std::unordered_map<SdfPath, PathSet, SdfPath::Hash>;
186  using MaterialDataMap = std::unordered_map<SdfPath, MaterialData,
187  SdfPath::Hash>;
188  using HashToMaterialPathMap = std::unordered_map<uint64_t, SdfPath>;
189  using MaterialHashMap = std::unordered_map<SdfPath, HashToMaterialPathMap,
190  SdfPath::Hash>;
191 
192 public:
193  static HdsiMaterialOverrideResolvingSceneIndexRefPtr New(
194  const HdSceneIndexBaseRefPtr &inputScene)
195  {
196  return TfCreateRefPtr(
197  new HdsiMaterialOverrideResolvingSceneIndex(inputScene));
198  }
199 
200  // HdSceneIndexBase overrides
201  HDSI_API
202  HdSceneIndexPrim GetPrim(const SdfPath &primPath) const override;
203 
204  HDSI_API
205  SdfPathVector GetChildPrimPaths(const SdfPath &primPath) const override;
206 
207 protected:
208 
209  HDSI_API
210  HdsiMaterialOverrideResolvingSceneIndex(
211  const HdSceneIndexBaseRefPtr &inputScene);
212 
213  // HdSingleInputFilteringSceneIndexBase overrides
214  void _PrimsAdded(
215  const HdSceneIndexBase &sender,
216  const HdSceneIndexObserver::AddedPrimEntries &entries) override;
217 
218  void _PrimsRemoved(
219  const HdSceneIndexBase &sender,
220  const HdSceneIndexObserver::RemovedPrimEntries &entries) override;
221 
222  void _PrimsDirtied(
223  const HdSceneIndexBase &sender,
224  const HdSceneIndexObserver::DirtiedPrimEntries &entries) override;
225 
226 private:
229  HdMaterialOverrideSchema _GetMaterialOverrides(
230  const SdfPath& primPath) const;
231 
236  HdSceneIndexObserver::AddedPrimEntries _AddGeneratedMaterials(
238 
244  SdfPath _AddGeneratedMaterial(
245  const TfToken& primType,
246  const SdfPath& primPath);
247 
252  HdSceneIndexObserver::DirtiedPrimEntries _DirtyGeneratedMaterials(
254 
264  void _DirtyBaseMaterial(
265  const SdfPath& primPath,
266  const PathSet& generatedMaterials,
267  PathSet* dirtiedPaths) const;
268 
281  void _DirtyGeometry(
283  const HdSceneIndexBaseRefPtr inputScene,
284  const PrimData& primData,
285  PathSet* processedPrimsSet,
286  PathSet* addedPaths,
287  PathSet* dirtiedPaths,
288  PathSet* removedPaths);
289 
297  void _DirtyMaterialOverrideLocator(
298  const SdfPath& primPath,
299  const HdSceneIndexBaseRefPtr inputScene,
300  PathSet* addedPaths,
301  PathSet* dirtiedPaths);
302 
305  PathSet _GetGeneratedMaterials(const SdfPath& primPath) const;
306 
309  bool _IsGeneratedMaterial(const SdfPath& primPath) const;
310 
313  void _CreateGeneratedMaterialDataSource(
314  HdSceneIndexPrim& prim,
315  const SdfPath& primPath) const;
316 
318  uint64_t _GetHash(const HdMaterialOverrideSchema& materialOverrides) const;
319 
322  void _InvalidateMaps(const SdfPath& primPath);
323 
326  struct MaterialData
327  {
328  // Path to the material bound to materialOverridePrimPath
329  // before any changes are made by this scene index
330  SdfPath originalMaterialPath;
331 
332  // Set of geometry prims using this generated material
333  PathSet boundPrims;
334  };
335 
338  struct PrimData
339  {
340  // Path to the generated material bound to this geometry prim
341  SdfPath generatedMaterialPath;
342 
343  // Hash of the material overrides found on this prim
344  uint64_t materialOverrideHash;
345  };
346 
347  // Map linking a path of a material scope to a set of materials that are
348  // generated by this scene index as a result of resolving material
349  // overrides at non-material locations.
350  MaterialPathsMap _scopeToNewMaterialPaths;
351 
352  // Map linking a material to a set of materials generated from it.
353  MaterialPathsMap _oldToNewMaterialPaths;
354 
355  // Map linking geometry prims to the path of the generated material that
356  // will be bound to them and to the hash for their material overrides.
357  // The keys in this map represent geometry prims that have
358  // a material binding and a material override data source.
359  PrimDataMap _primData;
360 
361  // Map linking materials generated in the process of resolving material
362  // overrides to their data.
363  MaterialDataMap _materialData;
364 
365  // Map relating a geometry prim's bound material (before this scene index
366  // executes) and the hash of its material override data source to the path
367  // of a generated material.
368  // Used to allow multiple geometry prims that share the same starting
369  // material and material overrides to use the same generated material.
370  // For example:
371  // PlasticMaterial --> ..0123 --> __MOR_PlasticMaterial_Mesh
372  // --> ..4567 --> __MOR_PlasticMaterial_AnotherMesh
373  // WoodMaterial --> ..0123 --> __MOR_WoodMaterial_Mesh
374  // MetalMaterial --> ..4567 --> __MOR_MetalMaterial_Point
375  MaterialHashMap _materialHashMap;
376 };
377 
378 PXR_NAMESPACE_CLOSE_SCOPE
379 
380 #endif // PXR_IMAGING_HDSI_MATERIAL_OVERRIDE_RESOLVING_SCENE_INDEX_H
An abstract base class for a filtering scene index that observes a single input scene index.
virtual HdSceneIndexPrim GetPrim(const SdfPath &primPath) const =0
Returns a pair of (prim type, datasource).
Standard pointer typedefs.
#define TF_DECLARE_WEAK_AND_REF_PTRS(type)
Define standard weak, ref, and vector pointer types.
Definition: declarePtrs.h:72
Small struct representing a 'prim' in the Hydra scene index.
Definition: sceneIndex.h:35
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:80
virtual SdfPathVector GetChildPrimPaths(const SdfPath &primPath) const =0
Returns the paths of all scene index prims located immediately below primPath.
Abstract interface to scene data.
Definition: sceneIndex.h:54
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:280
The MaterialOverride schema allows overrides to be made to various parts of materials,...
A notice indicating a prim was invalidated.