HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
instanceAdapter.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_USD_IMAGING_USD_IMAGING_INSTANCE_ADAPTER_H
25 #define PXR_USD_IMAGING_USD_IMAGING_INSTANCE_ADAPTER_H
26 
27 /// \file usdImaging/instanceAdapter.h
28 
29 #include "pxr/pxr.h"
31 
32 #include "pxr/base/tf/hashmap.h"
33 
34 #include <mutex>
35 
37 
38 
39 /// \class UsdImagingInstanceAdapter
40 ///
41 /// Delegate support for instanced prims.
42 ///
44 {
45 public:
47 
50 
51  virtual SdfPath Populate(UsdPrim const& prim, UsdImagingIndexProxy* index,
52  UsdImagingInstancerContext const* instancerContext = NULL) override;
53 
54  virtual bool ShouldCullChildren() const override;
55 
56  virtual bool IsInstancerAdapter() const override;
57 
58  // ---------------------------------------------------------------------- //
59  /// \name Parallel Setup and Resolve
60  // ---------------------------------------------------------------------- //
61 
62  virtual void TrackVariability(UsdPrim const& prim,
63  SdfPath const& cachePath,
64  HdDirtyBits* timeVaryingBits,
66  instancerContext = NULL) const override;
67 
68  virtual void UpdateForTime(UsdPrim const& prim,
69  SdfPath const& cachePath,
71  HdDirtyBits requestedBits,
73  instancerContext = NULL) const override;
74 
75  // ---------------------------------------------------------------------- //
76  /// \name Change Processing
77  // ---------------------------------------------------------------------- //
78 
79  virtual HdDirtyBits ProcessPropertyChange(UsdPrim const& prim,
80  SdfPath const& cachePath,
81  TfToken const& propertyName) override;
82 
83  virtual void ProcessPrimResync(SdfPath const& cachePath,
84  UsdImagingIndexProxy* index) override;
85 
86  virtual void ProcessPrimRemoval(SdfPath const& cachePath,
87  UsdImagingIndexProxy* index) override;
88 
89 
90  virtual void MarkDirty(UsdPrim const& prim,
91  SdfPath const& cachePath,
92  HdDirtyBits dirty,
93  UsdImagingIndexProxy* index) override;
94 
95  // As this adapter hijacks the adapter for the child prim
96  // We need to forward these messages on, in case the child
97  // adapter needs them
98  virtual void MarkRefineLevelDirty(UsdPrim const& prim,
99  SdfPath const& cachePath,
100  UsdImagingIndexProxy* index) override;
101 
102  virtual void MarkReprDirty(UsdPrim const& prim,
103  SdfPath const& cachePath,
104  UsdImagingIndexProxy* index) override;
105 
106  virtual void MarkCullStyleDirty(UsdPrim const& prim,
107  SdfPath const& cachePath,
108  UsdImagingIndexProxy* index) override;
109 
110  virtual void MarkRenderTagDirty(UsdPrim const& prim,
111  SdfPath const& cachePath,
112  UsdImagingIndexProxy* index) override;
113 
114  virtual void MarkTransformDirty(UsdPrim const& prim,
115  SdfPath const& cachePath,
116  UsdImagingIndexProxy* index) override;
117 
118  virtual void MarkVisibilityDirty(UsdPrim const& prim,
119  SdfPath const& cachePath,
120  UsdImagingIndexProxy* index) override;
121 
122 
123 
124  // ---------------------------------------------------------------------- //
125  /// \name Instancing
126  // ---------------------------------------------------------------------- //
127 
128  virtual std::vector<VtArray<TfToken>>
129  GetInstanceCategories(UsdPrim const& prim) override;
130 
131  virtual size_t
132  SampleInstancerTransform(UsdPrim const& instancerPrim,
133  SdfPath const& instancerPath,
135  size_t maxSampleCount,
136  float *sampleTimes,
137  GfMatrix4d *sampleValues) override;
138 
139  virtual size_t
140  SampleTransform(UsdPrim const& prim,
141  SdfPath const& cachePath,
142  UsdTimeCode time,
143  size_t maxNumSamples,
144  float *sampleTimes,
145  GfMatrix4d *sampleValues) override;
146 
147  virtual size_t
148  SamplePrimvar(UsdPrim const& usdPrim,
149  SdfPath const& cachePath,
150  TfToken const& key,
152  size_t maxNumSamples,
153  float *sampleTimes,
154  VtValue *sampleValues) override;
155 
156  virtual PxOsdSubdivTags GetSubdivTags(UsdPrim const& usdPrim,
157  SdfPath const& cachePath,
158  UsdTimeCode time) const override;
159 
160  // ---------------------------------------------------------------------- //
161  /// \name Nested instancing support
162  // ---------------------------------------------------------------------- //
163 
165  SdfPath const &parentInstancerPath,
166  SdfPath const &instancerPath,
167  UsdTimeCode time) const override;
168 
169  // ---------------------------------------------------------------------- //
170  /// \name Picking & selection
171  // ---------------------------------------------------------------------- //
172 
173  virtual SdfPath GetScenePrimPath(
174  SdfPath const& cachePath,
175  int instanceIndex,
176  HdInstancerContext *instancerContext) const override;
177 
178  virtual bool PopulateSelection(
179  HdSelection::HighlightMode const& highlightMode,
180  SdfPath const &cachePath,
181  UsdPrim const &usdPrim,
182  int const hydraInstanceIndex,
183  VtIntArray const &parentInstanceIndices,
184  HdSelectionSharedPtr const &result) const override;
185 
186  // ---------------------------------------------------------------------- //
187  /// \name Volume field information
188  // ---------------------------------------------------------------------- //
189 
191  GetVolumeFieldDescriptors(UsdPrim const& usdPrim, SdfPath const &id,
192  UsdTimeCode time) const override;
193 
194 protected:
195  virtual void _RemovePrim(SdfPath const& cachePath,
196  UsdImagingIndexProxy* index) override final;
197 
198 private:
199 
200  SdfPath _Populate(UsdPrim const& prim,
202  UsdImagingInstancerContext const* instancerContext,
203  SdfPath const& parentProxyPath);
204 
205  struct _ProtoPrim;
206  struct _ProtoGroup;
207  struct _InstancerData;
208 
209  bool _IsChildPrim(UsdPrim const& prim,
210  SdfPath const& cachePath) const;
211 
212  // Returns true if the given prim serves as an instancer.
213  bool _PrimIsInstancer(UsdPrim const& prim) const;
214 
215  // Inserts prototype prims for the given \p usdPrim into the \p index.
216  // Any inserted gprims will be inserted under a special path combining
217  // \p instancerPath and \p protoName.
218  SdfPath
219  _InsertProtoPrim(UsdPrimRange::iterator *iter,
220  const TfToken& protoName,
221  SdfPath materialId,
222  TfToken drawMode,
223  TfToken inheritablePurpose,
224  SdfPath instancerPath,
225  UsdImagingPrimAdapterSharedPtr const& primAdapter,
226  UsdImagingPrimAdapterSharedPtr const& instancerAdapter,
228  bool *isLeafInstancer);
229 
230  // For a usd path, collects the instancers to resync.
231  void _ResyncPath(SdfPath const& cachePath,
233  bool reload);
234  // Removes and optionally reloads all instancer data, both locally and
235  // from the render index.
236  void _ResyncInstancer(SdfPath const& instancerPath,
237  UsdImagingIndexProxy* index, bool reload);
238 
239  // Computes per-frame data in the instancer map. This is primarily used
240  // during update to send new instance indices out to Hydra.
241  struct _ComputeInstanceMapFn;
242  VtIntArray _ComputeInstanceMap(UsdPrim const& instancerPrim,
243  _InstancerData const& instrData,
244  UsdTimeCode time) const;
245 
246  // Precomputes the instancer visibility data (as visible, invis, varying
247  // per-node), and returns whether the instance map is variable.
248  // Note: this function assumes the instancer data is already locked by
249  // the caller...
250  struct _ComputeInstanceMapVariabilityFn;
251  bool _ComputeInstanceMapVariability(UsdPrim const& instancerPrim,
252  _InstancerData const& instrData) const;
253 
254  // Gets the associated _ProtoPrim and instancer context for the given
255  // instancer and cache path.
256  _ProtoPrim const& _GetProtoPrim(SdfPath const& instancerPath,
257  SdfPath const& cachePath,
258  UsdImagingInstancerContext* ctx) const;
259 
260  // Computes the transforms for all instances corresponding to the given
261  // instancer.
262  struct _ComputeInstanceTransformFn;
263  bool _ComputeInstanceTransforms(UsdPrim const& instancer,
264  VtMatrix4dArray* transforms,
265  UsdTimeCode time) const;
266 
267  // Gathers the authored transforms time samples given an instancer.
268  struct _GatherInstanceTransformTimeSamplesFn;
269  bool _GatherInstanceTransformsTimeSamples(UsdPrim const& instancer,
270  GfInterval interval,
271  std::vector<double>* outTimes)
272  const;
273 
274  // Gathers the specified primvar time samples given an instancer.
275  struct _GatherInstancePrimvarTimeSamplesFn;
276  bool _GatherInstancePrimvarTimeSamples(UsdPrim const& instancer,
277  TfToken const& key,
278  GfInterval interval,
279  std::vector<double>* outTimes)
280  const;
281 
282  // Returns true if any of the instances corresponding to the given
283  // instancer has a varying transform.
284  struct _IsInstanceTransformVaryingFn;
285  bool _IsInstanceTransformVarying(UsdPrim const& instancer) const;
286 
287  // Computes the value of a primvar for all instances corresponding to the
288  // given instancer. The templated version runs the templated functor,
289  // and the un-templated version does type dispatch.
290  template<typename T> struct _ComputeInheritedPrimvarFn;
291 
292  template<typename T>
293  bool _ComputeInheritedPrimvar(UsdPrim const& instancer,
294  TfToken const& primvarName,
295  VtValue *result,
296  UsdTimeCode time) const;
297 
298  bool _ComputeInheritedPrimvar(UsdPrim const& instancer,
299  TfToken const& primvarName,
300  SdfValueTypeName const& type,
301  VtValue *result,
302  UsdTimeCode time) const;
303 
304  // Returns true if any of the instances corresponding to the given
305  // instancer has varying inherited primvars.
306  struct _IsInstanceInheritedPrimvarVaryingFn;
307  bool _IsInstanceInheritedPrimvarVarying(UsdPrim const& instancer) const;
308 
309  struct _PopulateInstanceSelectionFn;
310  struct _GetScenePrimPathFn;
311 
312  // Helper functions for dealing with "actual" instances to be drawn.
313  //
314  // Suppose we have:
315  // /Root
316  // Instance_A (master: /__Master_1)
317  // Instance_B (master: /__Master_1)
318  // /__Master_1
319  // AnotherInstance_A (master: /__Master_2)
320  // /__Master_2
321  //
322  // /__Master_2 has only one associated instance in the Usd scenegraph:
323  // /__Master_1/AnotherInstance_A. However, imaging actually needs to draw
324  // two instances of /__Master_2, because AnotherInstance_A is a nested
325  // instance beneath /__Master_1, and there are two instances of /__Master_1.
326  //
327  // Each instance to be drawn is addressed by the chain of instances
328  // that caused it to be drawn. In the above example, the two instances
329  // of /__Master_2 to be drawn are:
330  //
331  // [ /Root/Instance_A, /__Master_1/AnotherInstance_A ],
332  // [ /Root/Instance_B, /__Master_1/AnotherInstance_A ]
333  //
334  // This "instance context" describes the chain of opinions that
335  // ultimately affect the final drawn instance. For example, the
336  // transform of each instance to draw is the combined transforms
337  // of the prims in each context.
338  template <typename Functor>
339  void _RunForAllInstancesToDraw(UsdPrim const& instancer, Functor* fn) const;
340  template <typename Functor>
341  bool _RunForAllInstancesToDrawImpl(UsdPrim const& instancer,
342  std::vector<UsdPrim>* instanceContext,
343  size_t* instanceIdx,
344  Functor* fn) const;
345 
347  size_t _CountAllInstancesToDraw(UsdPrim const& instancer) const;
348  size_t _CountAllInstancesToDrawImpl(UsdPrim const& instancer,
349  _InstancerDrawCounts* drawCounts) const;
350 
351  // A proto prim represents a single adapter under a prototype root declared
352  // on the instancer.
353  struct _ProtoPrim {
354  _ProtoPrim() {}
355  // Each prim will become a prototype "child" under the instancer. This
356  // path is the path to the prim on the Usd Stage (the path to a single
357  // mesh, for example).
358  SdfPath path;
359  // The prim adapter for the actual prototype prim.
361  };
362 
363  // Indexed by cachePath (each prim has one entry)
365 
366  // All data associated with a given instancer prim. PrimMap could
367  // technically be split out to avoid two lookups, however it seems cleaner
368  // to keep everything bundled up under the instancer path.
369  struct _InstancerData {
370  _InstancerData() : numInstancesToDraw(0), refreshVariability(false) { }
371 
372  // The master prim path associated with this instancer.
373  SdfPath masterPath;
374 
375  // The USD material path associated with this instancer.
376  SdfPath materialUsdPath;
377 
378  // The drawmode associated with this instancer.
379  TfToken drawMode;
380 
381  // The purpose value associated with this instance that can be inherited
382  // by proto prims that need to inherit ancestor purpose.
383  TfToken inheritablePurpose;
384 
385  // Inherited primvar
386  struct PrimvarInfo {
389  bool operator==(const PrimvarInfo& rhs) const;
390  bool operator<(const PrimvarInfo& rhs) const;
391  };
392  std::vector<PrimvarInfo> inheritedPrimvars;
393 
394  // Paths to Usd instance prims. Note that this is not necessarily
395  // equivalent to all the instances that will be drawn. See below.
396  std::vector<SdfPath> instancePaths;
397 
398  // Number of actual instances of this instancer that will be
399  // drawn. See comment on _RunForAllInstancesToDraw.
400  // XXX: This is mutable so that we can precache it in TrackVariability;
401  // it's inappropriate to track it in _Populate since not all instances
402  // will have been populated.
403  mutable size_t numInstancesToDraw;
404 
405  // Cached visibility. This vector contains an entry for each instance
406  // that will be drawn (i.e., visibility.size() == numInstancesToDraw).
407  enum Visibility {
408  Invisible, //< Invisible over all time
409  Visible, //< Visible over all time
410  Varying, //< Visibility varies over time
411  Unknown //< Visibility has not yet been checked
412  };
413  // XXX: This is mutable so that we can precache visibility per-instance
414  // in TrackVariability(). Can we replace this with some kind of usage
415  // of an inherited cache?
416  mutable std::vector<Visibility> visibility;
417 
418  // Map of all rprims for this instancer prim.
419  _PrimMap primMap;
420 
421  // This is a set of reference paths, where this instancer needs
422  // to deferer to another instancer. While refered to here as a child
423  // instancer, the actual relationship is more like a directed graph.
424  SdfPathSet childPointInstancers;
425 
426  // Nested (child) native instances.
427  SdfPathVector nestedInstances;
428 
429  // Parent native instances.
430  SdfPathVector parentInstances;
431 
432  // Flag indicating we've queued up the delegate to call TrackVariability
433  // on this instancer. We record this so we don't do it multiple times.
434  mutable bool refreshVariability;
435  };
436 
437  // Map from instancer cache path to instancer data.
438  // Note: this map is modified in multithreaded code paths and must be
439  // locked.
440  typedef std::unordered_map<SdfPath, _InstancerData, SdfPath::Hash>
441  _InstancerDataMap;
442  _InstancerDataMap _instancerData;
443 
444  // Map from instance to instancer.
445  // XXX: consider to move this forwarding map into HdRenderIndex.
447  _InstanceToInstancerMap;
448  _InstanceToInstancerMap _instanceToInstancerMap;
449 
450  // Hd and UsdImaging think of instancing in terms of an 'instancer' that
451  // specifies a list of 'prototype' prims that are shared per instance.
452  //
453  // For Usd scenegraph instancing, a master prim and its descendents
454  // roughly correspond to the instancer and prototype prims. However,
455  // Hd requires a different instancer and rprims for different combinations
456  // of inherited attributes (material binding, draw mode, etc).
457  // This means we cannot use the Usd master prim as the instancer, because
458  // we can't represent this in the case where multiple Usd instances share
459  // the same master but have different bindings.
460  //
461  // Instead, we use the first instance of a master with a given set of
462  // inherited attributes as our instancer. For example, if /A and /B are
463  // both instances of /__Master_1 but /A and /B have different material
464  // bindings authored on them, both /A and /B will be instancers,
465  // with their own set of rprims and instance indices.
466  //
467  // The below is a multimap from master path to instancer path. The data
468  // for the instancer is located in the _InstancerDataMap above.
470  _MasterToInstancerMap;
471  _MasterToInstancerMap _masterToInstancerMap;
472 };
473 
474 
476 
477 #endif // PXR_USD_IMAGING_USD_IMAGING_INSTANCE_ADAPTER_H
virtual void ProcessPrimRemoval(SdfPath const &cachePath, UsdImagingIndexProxy *index) override
GT_API const UT_StringHolder time
GLuint index
Definition: glew.h:1814
uint32_t HdDirtyBits
Definition: types.h:127
virtual void MarkVisibilityDirty(UsdPrim const &prim, SdfPath const &cachePath, UsdImagingIndexProxy *index) override
virtual void ProcessPrimResync(SdfPath const &cachePath, UsdImagingIndexProxy *index) override
virtual void MarkRenderTagDirty(UsdPrim const &prim, SdfPath const &cachePath, UsdImagingIndexProxy *index) override
VaryingRef< T > Varying(T *x)
Definition: varyingref.h:227
virtual std::vector< VtArray< TfToken > > GetInstanceCategories(UsdPrim const &prim) override
Return an array of the categories used by each instance.
virtual void UpdateForTime(UsdPrim const &prim, SdfPath const &cachePath, UsdTimeCode time, HdDirtyBits requestedBits, UsdImagingInstancerContext const *instancerContext=NULL) const override
virtual HdDirtyBits ProcessPropertyChange(UsdPrim const &prim, SdfPath const &cachePath, TfToken const &propertyName) override
std::vector< std::pair< SdfPath, int > > HdInstancerContext
Instancer context: a pair of instancer paths and instance indices.
Definition: sceneDelegate.h:61
virtual bool IsInstancerAdapter() const override
virtual PxOsdSubdivTags GetSubdivTags(UsdPrim const &usdPrim, SdfPath const &cachePath, UsdTimeCode time) const override
Get the subdiv tags for this prim.
Definition: token.h:87
UsdImagingPrimAdapter BaseAdapter
virtual void MarkTransformDirty(UsdPrim const &prim, SdfPath const &cachePath, UsdImagingIndexProxy *index) override
Definition: prim.h:132
virtual void MarkReprDirty(UsdPrim const &prim, SdfPath const &cachePath, UsdImagingIndexProxy *index) override
HighlightMode
Selection modes allow differentiation in selection highlight behavior.
Definition: selection.h:55
Definition: path.h:288
GLuint GLuint GLsizei GLenum type
Definition: glew.h:1253
std::vector< HdVolumeFieldDescriptor > HdVolumeFieldDescriptorVector
virtual void TrackVariability(UsdPrim const &prim, SdfPath const &cachePath, HdDirtyBits *timeVaryingBits, UsdImagingInstancerContext const *instancerContext=NULL) const override
std::vector< class SdfPath > SdfPathVector
A vector of SdfPaths.
Definition: path.h:209
virtual void MarkDirty(UsdPrim const &prim, SdfPath const &cachePath, HdDirtyBits dirty, UsdImagingIndexProxy *index) override
std::set< class SdfPath > SdfPathSet
A set of SdfPaths.
Definition: path.h:207
GLsizei const GLchar *const * path
Definition: glew.h:6461
virtual void MarkRefineLevelDirty(UsdPrim const &prim, SdfPath const &cachePath, UsdImagingIndexProxy *index) override
bool operator==(const PrimvarInfo &rhs) const
virtual size_t SamplePrimvar(UsdPrim const &usdPrim, SdfPath const &cachePath, TfToken const &key, UsdTimeCode time, size_t maxNumSamples, float *sampleTimes, VtValue *sampleValues) override
virtual bool PopulateSelection(HdSelection::HighlightMode const &highlightMode, SdfPath const &cachePath, UsdPrim const &usdPrim, int const hydraInstanceIndex, VtIntArray const &parentInstanceIndices, HdSelectionSharedPtr const &result) const override
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1346
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
std::shared_ptr< UsdImagingPrimAdapter > UsdImagingPrimAdapterSharedPtr
virtual bool ShouldCullChildren() const override
virtual HdVolumeFieldDescriptorVector GetVolumeFieldDescriptors(UsdPrim const &usdPrim, SdfPath const &id, UsdTimeCode time) const override
virtual void _RemovePrim(SdfPath const &cachePath, UsdImagingIndexProxy *index) overridefinal
Returns true if the adapter can be populated into the target index.
virtual ~UsdImagingInstanceAdapter()
virtual SdfPath GetScenePrimPath(SdfPath const &cachePath, int instanceIndex, HdInstancerContext *instancerContext) const override
virtual GfMatrix4d GetRelativeInstancerTransform(SdfPath const &parentInstancerPath, SdfPath const &instancerPath, UsdTimeCode time) const override
GLuint64EXT * result
Definition: glew.h:14007
virtual size_t SampleTransform(UsdPrim const &prim, SdfPath const &cachePath, UsdTimeCode time, size_t maxNumSamples, float *sampleTimes, GfMatrix4d *sampleValues) override
Samples the transform for the given prim.
bool operator<(const PrimvarInfo &rhs) const
virtual size_t SampleInstancerTransform(UsdPrim const &instancerPrim, SdfPath const &instancerPath, UsdTimeCode time, size_t maxSampleCount, float *sampleTimes, GfMatrix4d *sampleValues) override
virtual SdfPath Populate(UsdPrim const &prim, UsdImagingIndexProxy *index, UsdImagingInstancerContext const *instancerContext=NULL) override
std::shared_ptr< class HdSelection > HdSelectionSharedPtr
Definition: selection.h:40
Definition: value.h:174
virtual void MarkCullStyleDirty(UsdPrim const &prim, SdfPath const &cachePath, UsdImagingIndexProxy *index) override