HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
niPrototypePropagatingSceneIndex.h
Go to the documentation of this file.
1 //
2 // Copyright 2022 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_USD_IMAGING_USD_IMAGING_NI_PROTOTYPE_PROPAGATING_SCENE_INDEX_H
8 #define PXR_USD_IMAGING_USD_IMAGING_NI_PROTOTYPE_PROPAGATING_SCENE_INDEX_H
9 
11 
14 
16 
18 
20 
21 /// \class UsdImagingNiPrototypePropagatingSceneIndex
22 ///
23 /// A scene index implementing USD native instancing. If combined
24 /// with the UsdImagingPiPrototypePropagatingSceneIndex, the native
25 /// instancing scene index has to be run after the point instancing
26 /// scene index.
27 ///
28 /// This scene index uses the UsdImagingNiInstanceAggregationSceneIndex
29 /// to find all instances, aggregate them and insert instancers for
30 /// each set of aggregated instances. This scene index then inserts
31 /// flattened and possibly further transformed (e.g. applying draw mode)
32 /// copies of the corresponding USD prototype underneath each of these
33 /// instancers. Each of these copies is actually a
34 /// UsdImagingNiPrototypePropagatingSceneIndex itself. This way, we can
35 /// handle nested native instancing. In other words, we can call the
36 /// UsdImagingNiPrototypePropagatingSceneIndex for a USD prototype and
37 /// it will find the instances within that prototype.
38 ///
39 /// The instancing scene index uses the instancedBy:prototypeRoot
40 /// of the input scene index during aggregation.
41 /// Typically, the input scene index will be a
42 /// UsdImagingPiPrototypePropagatingSceneIndex which populates
43 /// instancedBy:prototypeRoot based on which point instancer is
44 /// instancing a prim.
45 ///
46 /// This scene index is implemented by a merging scene index with the
47 /// following inputs:
48 /// - a scene index ultimately tracing back to UsdImaging_NiPrototypeSceneIndex
49 /// which prepares the prototype for which this scene index was created.
50 /// The scene indices applied after UsdImaging_NiPrototypeSceneIndex
51 /// include a flattening scene index as well as scene indices
52 /// that can be specified through a callback by a user (typically,
53 /// the draw mode scene index).
54 /// - the UsdImaging_NiInstanceAggregationSceneIndex instantiated from the
55 /// above scene index. The instance aggregation scene index will insert the
56 /// instancers for the instances within this prototype.
57 /// - More UsdImagingNiPrototypePropagatingSceneIndex's:
58 /// The _InstanceAggregationSceneIndexObserver will observe the
59 /// latter scene index to add
60 /// respective UsdImagingNiPrototypePropagatingSceneIndex's under
61 /// each instancer.
62 ///
63 /// Example 1 (also see Example 1 in niInstanceAggregationSceneIndex.h)
64 ///
65 /// USD:
66 ///
67 /// def Xform "MyPrototype"
68 /// {
69 /// def Cube "MyCube"
70 /// {
71 /// }
72 /// }
73 ///
74 /// def "Cube_1" (
75 /// instanceable = true
76 /// references = </MyPrototype>
77 /// {
78 /// }
79 ///
80 /// Inputs of the UsdImagingNiPrototypePropagatingSceneIndex(inputSceneIndex):
81 ///
82 /// * HdMergingSceneIndex
83 /// * UsdImagingDrawModeSceneIndex (through SceneIndexAppendCallback)
84 /// * HdFlatteningSceneIndex
85 /// inputArgs = UsdImagingFlattenedDataSourceProviders()
86 /// [So model:drawMode is also flattened]
87 /// * UsdImaging_NiPrototypeSceneIndex
88 /// forPrototype = false
89 /// prototypeRootOverlayDs = null
90 /// * UsdImaging_NiPrototypePruningSceneIndex
91 /// forPrototype = false
92 /// * inputSceneIndex (typically a UsdImagingPiPrototypePropagatingSceneIndex)
93 /// * UsdImaging_NiInstanceAggregationSceneIndex
94 /// forPrototype = false
95 /// instanceDataSourceNames = ['materialBindings', 'purpose', 'model']
96 /// * UsdImagingDrawModeSceneIndex
97 /// [... as above]
98 /// * UsdImagingRerootingSceneIndex
99 /// (inserted by _InstanceAggregationSceneIndexObserver::PrimsAdded
100 /// through _MergingSceneIndexEntry)
101 /// srcPrefix = /UsdNiInstancer
102 /// dstPrefix = /UsdNiPropagatedPrototypes/NoBindings/__Prototype_1/UsdNiInstancer
103 /// * UsdImagingNiPrototypePropagatingSceneIndex
104 /// prototypeName = __Prototype_1
105 /// * HdMergingSceneIndex
106 /// * UsdImagingDrawModeSceneIndex (through SceneIndexAppendCallback)
107 /// * HdFlatteningSceneIndex
108 /// inputArgs = UsdImagingFlattenedDataSourceProviders()
109 /// [So model:drawMode is also flattened]
110 /// * UsdImaging_NiPrototypeSceneIndex
111 /// forPrototype = true
112 /// * UsdImagingRerootingSceneIndex
113 /// srcPrefix = /__PrototypeRoot1
114 /// dstPrefix = /UsdNiInstancer/UsdNiPrototype
115 /// * inputSceneIndex
116 /// * UsdImaging_NiInstanceAggregationSceneIndex
117 /// forPrototype = true
118 /// * UsdImagingDrawModeSceneIndex
119 /// [... as just above]
120 ///
121 /// UsdImagingNiPrototypePropagatingSceneIndex
122 ///
123 /// /Cube_1
124 /// primType: ""
125 /// dataSource:
126 /// instance: # Useful for translating Usd proxy paths for selection.
127 /// # See corresponding example in niInstanceAggregationIndex
128 /// # for more details.
129 /// instancer: /UsdNiPropagatedPrototypes/Bindings_423...234/__Prototype_1/UsdNiInstancer
130 /// prototypeId: 0
131 /// instanceId: 0
132 /// purpose: # From flattening scene index
133 /// purpose: geometry
134 /// xform: # From flattening scene index
135 /// matrix: [ identity matrix]
136 /// primOrigin:
137 /// scenePath: HdPrimOriginSchema::OriginPath(/Cube_1)
138 /// ...
139 /// /MyPrototype # Not referenced from a different file, so appears here
140 /// # as non-prototype as well
141 /// primType: ""
142 /// /MyPrototype/MyCube
143 /// primType: cube
144 /// /UsdNiPropagatedPrototypes
145 /// primType: ""
146 /// /UsdNiPropagatedPrototypes/Bindings_423...234
147 /// primType: ""
148 /// dataSource:
149 /// purpose: # Added by instance aggregation scene index, copied from /Cube_1
150 /// purpose: geometry
151 /// # No xform, visibility (never copied by instance aggregation, written to
152 /// instancer instead)
153 /// /UsdNiPropagatedPrototypes/Bindings_423...234/__Prototype_1
154 /// primType: ""
155 /// /UsdNiPropagatedPrototypes/Bindings_423...234/__Prototype_1/UsdNiInstancer
156 /// primType: instancer
157 /// dataSource:
158 /// instancerTopology:
159 /// instanceIndices:
160 /// i0: [ 0 ]
161 /// prototypes: [ /UsdNiPropagatedPrototypes/Bindings_423...234/__Prototype_1/UsdNiInstancer/UsdNiPrototype
162 /// instanceLocations: [ /Cube_1 ] # for picking
163 /// primvars:
164 /// hydra:instanceTransforms:
165 /// primvarValue: [ identity matrix ]
166 /// interpolation: instance
167 /// /UsdNiPropagatedPrototypes/Bindings_423...234/__Prototype_1/UsdNiInstancer/UsdNiPrototype
168 /// primType: ""
169 /// dataSource:
170 /// instancedBy:
171 /// paths: [ /UsdNiPropagatedPrototypes/Bindings_423...234/__Prototype_1/UsdNiInstancer ]
172 /// prototypeRoot: /UsdNiPropagatedPrototypes/Bindings_423...234/__Prototype_1 /UsdNiInstancer/UsdNiPrototype
173 /// purpose: # Added by prototype scene index, copied from /UsdNiPropagatedPrototypes/Bindings_423...234
174 /// # Flattened scene index did not touch it.
175 /// purpose: geometry
176 /// xform: # From flattening scene index
177 /// matrix: [ identity matrix ]
178 /// resetXformStack: true
179 /// primOrigin:
180 /// scenePath: HdPrimOriginSchema::OriginPath(.)
181 /// /UsdNiPropagatedPrototypes/Bindings_423...234/__Prototype_1/UsdNiInstancer/UsdNiPrototype/MyCube
182 /// primType: cube
183 /// dataSource:
184 /// instancedBy:
185 /// paths: [ /UsdNiPropagatedPrototypes/Bindings_423...234/__Prototype_1/UsdNiInstancer ]
186 /// prototypeRoot: /UsdNiPropagatedPrototypes/Bindings_423...234/__Prototype_1 /UsdNiInstancer/UsdNiPrototype
187 /// purpose: # From flattening scene index
188 /// purpose: geometry
189 /// xform: # From flattening scene index
190 /// matrix: [ identity matrix ]
191 /// resetXformStack: true
192 /// primOrigin:
193 /// scenePath: HdPrimOriginSchema::OriginPath(MyCube)
194 ///
195 /// Example 2:
196 ///
197 /// def Xform "MyNestedPrototype" # Will become USD prototype /__Prototype_1
198 /// {
199 /// def Cube "MyCube"
200 /// {
201 /// }
202 /// }
203 ///
204 /// def Xform "MyPrototype" # Will become USD prototype /__Prototype_2
205 /// {
206 /// def "MyNestedInstance" (
207 /// instanceable = true
208 /// references = </MyNestedPrototype> )
209 /// {
210 /// }
211 /// }
212 ///
213 /// def Xform "MyInstance" (
214 /// instanceable = true
215 /// references = </MyPrototype>)
216 /// {
217 ///
218 /// }
219 ///
220 /// UsdImagingNiPrototypePropagatingSceneIndex
221 ///
222 /// ...
223 /// /MyInstance
224 /// primType: ""
225 /// dataSource:
226 /// instance:
227 /// instancer: /UsdNiPropagatedPrototypes/NoBindings/__Prototype_2/UsdNiInstancer
228 /// prototypeId: 0
229 /// instanceId: 0
230 /// ...
231 /// /UsdNiPropagatedPrototypes
232 /// primType: ""
233 /// /UsdNiPropagatedPrototypes/NoBindings
234 /// primType: ""
235 /// dataSource:
236 /// ...
237 /// /UsdNiPropagatedPrototypes/NoBindings/__Prototype_2
238 /// primType: ""
239 /// /UsdNiPropagatedPrototypes/NoBindings/__Prototype_2/UsdNiInstancer
240 /// primType: instancer
241 /// dataSource:
242 /// instanerTopology:
243 /// prototypes: [ /UsdNiPropagatedPrototypes/NoBindings/__Prototype_2/UsdNiInstancer/UsdPiPrototype ]
244 /// ...
245 /// /UsdNiPropagatedPrototypes/NoBindings/__Prototype_2/UsdNiInstancer/_Prototype_2
246 /// primType: ""
247 /// /UsdNiPropagatedPrototypes/NoBindings/__Prototype_2/UsdNiInstancer/_Prototype_2/MyNestedInstance
248 /// primType: ""
249 /// dataSource:
250 /// instancer: /UsdNiPropagatedPrototypes/NoBindings/__Prototype_2/UsdNiInstancer/UsdPiPrototype/UsdNiPropagatedPrototypes/NoBindings/__Prototype_1/UsdNiInstancer
251 /// prototypeId: 0
252 /// instanceId: 0
253 /// ...
254 /// /UsdNiPropagatedPrototypes/NoBindings/__Prototype_2/UsdNiInstancer/UsdPiPrototype/UsdNiPropagatedPrototypes
255 /// /UsdNiPropagatedPrototypes/NoBindings/__Prototype_2/UsdNiInstancer/UsdPiPrototype/UsdNiPropagatedPrototypes/NoBindings
256 /// primType: ""
257 /// dataSource:
258 /// ...
259 /// /UsdNiPropagatedPrototypes/NoBindings/__Prototype_2/UsdNiInstancer/UsdPiPrototype/UsdNiPropagatedPrototypes/NoBindings/__Prototype_1
260 /// primType: ""
261 /// /UsdNiPropagatedPrototypes/NoBindings/__Prototype_2/UsdNiInstancer/UsdPiPrototype/UsdNiPropagatedPrototypes/NoBindings/__Prototype_1/UsdNiInstancer
262 /// primType: instancer
263 /// dataSource:
264 /// instanerTopology:
265 /// prototypes: [ /UsdNiPropagatedPrototypes/NoBindings/__Prototype_2/UsdNiInstancer/UsdPiPrototype/UsdNiPropagatedPrototypes/NoBindings/__Prototype_1/UsdNiInstancer/UsdPiPrototype ]
266 /// ...
267 /// instancedBy:
268 /// paths: [ /UsdNiPropagatedPrototypes/NoBindings/__Prototype_2/UsdNiInstancer ]
269 /// prototypeRoot: /UsdNiPropagatedPrototypes/NoBindings/__Prototype_2/UsdNiInstancer/UsdPiPrototype
270 /// /UsdNiPropagatedPrototypes/NoBindings/__Prototype_2/UsdNiInstancer/UsdPiPrototype/UsdNiPropagatedPrototypes/NoBindings/__Prototype_1/UsdNiInstancer/UsdPiPrototype
271 /// primType: ""
272 /// dataSource:
273 /// instancedBy:
274 /// paths: [ /UsdNiPropagatedPrototypes/NoBindings/__Prototype_2/UsdNiInstancer/UsdPiPrototype/UsdNiPropagatedPrototypes/NoBindings/__Prototype_1/UsdNiInstancer ]
275 /// prototypeRoot: /UsdNiPropagatedPrototypes/NoBindings/__Prototype_2/UsdNiInstancer/UsdPiPrototype/UsdNiPropagatedPrototypes/NoBindings/__Prototype_1/UsdNiInstancer/UsdPiPrototype
276 /// ...
277 /// /UsdNiPropagatedPrototypes/NoBindings/__Prototype_2/UsdNiInstancer/UsdPiPrototype/UsdNiPropagatedPrototypes/NoBindings/__Prototype_1/UsdNiInstancer/UsdPiPrototype/MyCube
278 /// primType: "cube"
279 /// dataSource:
280 /// instancedBy:
281 /// paths: [ /UsdNiPropagatedPrototypes/NoBindings/__Prototype_2/UsdNiInstancer/UsdPiPrototype/UsdNiPropagatedPrototypes/NoBindings/UsdPiPrototype/UsdNiInstancer ]
282 /// prototypeRoot: /UsdNiPropagatedPrototypes/NoBindings/__Prototype_2/UsdNiInstancer/UsdPiPrototype/UsdNiPropagatedPrototypes/NoBindings/__Prototype_1/UsdNiInstancer/UsdPiPrototype
283 /// ...
284 ///
285 ///
289 {
290 public:
292  std::function<
293  HdSceneIndexBaseRefPtr(const HdSceneIndexBaseRefPtr &inputScene)>;
294 
295  // instanceDataSourceNames are the names of the data sources of a native
296  // instance prim that need to have the same values for the instances to
297  // be aggregated. A copy of these data sources is bundled into the
298  // prim data source for the binding scope.
299  //
300  // When propagating a prototype by inserting the scene index isolating
301  // that prototype into the merging scene index implementing this scene
302  // index, we also call sceneIndexAppendCallback.
303  //
304  // The use case is for the UsdImagingDrawModeSceneIndex.
305  //
307  static UsdImagingNiPrototypePropagatingSceneIndexRefPtr New(
308  HdSceneIndexBaseRefPtr const &inputSceneIndex,
309  const TfTokenVector &instanceDataSourceNames,
310  const SceneIndexAppendCallback &sceneIndexAppendCallback);
311 
314 
316  HdSceneIndexPrim GetPrim(const SdfPath &primPath) const override;
317 
319  SdfPathVector GetChildPrimPaths(const SdfPath &primPath) const override;
320 
322  std::vector<HdSceneIndexBaseRefPtr> GetInputScenes() const override;
323 
325  std::vector<HdSceneIndexBaseRefPtr> GetEncapsulatedScenes() const override;
326 
327 private:
328  class _SceneIndexCache;
329  using _SceneIndexCacheSharedPtr =
330  std::shared_ptr<_SceneIndexCache>;
331 
332  class _MergingSceneIndexOperations;
333 
336  {
337  public:
340 
341  void PrimsAdded(
342  const HdSceneIndexBase &sender,
343  const AddedPrimEntries &entries) override;
344  void PrimsDirtied(
345  const HdSceneIndexBase &sender,
346  const DirtiedPrimEntries &entries) override;
347  void PrimsRemoved(
348  const HdSceneIndexBase &sender,
349  const RemovedPrimEntries &entries) override;
350  void PrimsRenamed(
351  const HdSceneIndexBase &sender,
352  const RenamedPrimEntries &entries) override;
353 
354  private:
356  };
357 
360  {
361  public:
364 
365  void PrimsAdded(
366  const HdSceneIndexBase &sender,
367  const AddedPrimEntries &entries) override;
368  void PrimsDirtied(
369  const HdSceneIndexBase &sender,
370  const DirtiedPrimEntries &entries) override;
371  void PrimsRemoved(
372  const HdSceneIndexBase &sender,
373  const RemovedPrimEntries &entries) override;
374  void PrimsRenamed(
375  const HdSceneIndexBase &sender,
376  const RenamedPrimEntries &entries) override;
377 
378  private:
380  };
381 
382  // Use prototypeName to instantiate for "scene root".
383  static UsdImagingNiPrototypePropagatingSceneIndexRefPtr _New(
384  HdSceneIndexBaseRefPtr const &inputSceneIndex,
385  const TfToken &prototypeName,
386  HdContainerDataSourceHandle const &prototypeRootOverlayDs,
387  _SceneIndexCacheSharedPtr const &cache);
388 
390  HdSceneIndexBaseRefPtr const &inputSceneIndex,
391  const TfToken &prototypeName,
392  HdContainerDataSourceHandle const &prototypeRootOverlayDs,
393  _SceneIndexCacheSharedPtr const &cache);
394 
395  void _Populate(HdSceneIndexBaseRefPtr const &instanceAggregationSceneIndex);
396  void _PrimsAdded(
398  void _AddPrim(
399  const SdfPath &primPath,
400  _MergingSceneIndexOperations * mergingSceneIndexOperations);
401  void _PrimsRemoved(
403  void _RemovePrim(const SdfPath &primPath,
404  _MergingSceneIndexOperations * mergingSceneIndexOperations);
405 
406 private: // data
407 
408  const HdSceneIndexBaseRefPtr _inputSceneIndex;
409  const TfToken _prototypeName;
410  const HdDataSourceHashType _prototypeRootOverlayDsHash;
411  const _SceneIndexCacheSharedPtr _cache;
412 
413  HdMergingSceneIndexRefPtr _mergingSceneIndex;
414 
415  // Propagated prototypes in the _mergingSceneIndex.
416  //
417  // This map needs to be kept in sync with the HdMergingSceneIndex.
418  // There might be a way to avoid the redundant representation.
419  std::map<SdfPath, HdSceneIndexBaseRefPtr>
420  _instancersToPropagatedPrototypeSceneIndex;
421 
422  HdSceneIndexBaseRefPtr _instanceAggregationSceneIndex;
423 
425  _instanceAggregationSceneIndexObserver;
426  _MergingSceneIndexObserver _mergingSceneIndexObserver;
427 };
428 
430 
431 #endif
USDIMAGING_API ~UsdImagingNiPrototypePropagatingSceneIndex() override
#define USDIMAGING_API
Definition: api.h:23
USDIMAGING_API HdSceneIndexPrim GetPrim(const SdfPath &primPath) const override
size_t HdDataSourceHashType
#define PXR_NAMESPACE_OPEN_SCOPE
Definition: pxr.h:73
USDIMAGING_API SdfPathVector GetChildPrimPaths(const SdfPath &primPath) const override
static USDIMAGING_API UsdImagingNiPrototypePropagatingSceneIndexRefPtr New(HdSceneIndexBaseRefPtr const &inputSceneIndex, const TfTokenVector &instanceDataSourceNames, const SceneIndexAppendCallback &sceneIndexAppendCallback)
PXR_NAMESPACE_OPEN_SCOPE TF_DECLARE_REF_PTRS(HdMergingSceneIndex)
Definition: token.h:70
std::vector< class SdfPath > SdfPathVector
USDIMAGING_API std::vector< HdSceneIndexBaseRefPtr > GetEncapsulatedScenes() const override
USDIMAGING_API std::vector< HdSceneIndexBaseRefPtr > GetInputScenes() const override
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:440
Definition: path.h:280
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
std::function< HdSceneIndexBaseRefPtr(const HdSceneIndexBaseRefPtr &inputScene)> SceneIndexAppendCallback