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 USDIMAGING_INSTANCE_ADAPTER_H
25 #define USDIMAGING_INSTANCE_ADAPTER_H
26 
28 
29 #include "pxr/pxr.h"
30 #include "pxr/usdImaging/usdImaging/primAdapter.h"
31 
32 #include "pxr/base/tf/hashmap.h"
33 
34 #include <boost/unordered_map.hpp>
35 #include <boost/shared_ptr.hpp>
36 #include <boost/enable_shared_from_this.hpp>
37 
38 #include <mutex>
39 
40 PXR_NAMESPACE_OPEN_SCOPE
41 
42 
48 {
49 public:
51 
53  virtual ~UsdImagingInstanceAdapter();
54 
55  virtual SdfPath Populate(UsdPrim const& prim, UsdImagingIndexProxy* index,
56  UsdImagingInstancerContext const* instancerContext = NULL) override;
57 
58  virtual bool ShouldCullChildren() const override;
59 
60  virtual bool IsInstancerAdapter() const override;
61 
62  // ---------------------------------------------------------------------- //
64  // ---------------------------------------------------------------------- //
65 
66  virtual void TrackVariability(UsdPrim const& prim,
67  SdfPath const& cachePath,
68  HdDirtyBits* timeVaryingBits,
70  instancerContext = NULL) const override;
71 
72  virtual void UpdateForTime(UsdPrim const& prim,
73  SdfPath const& cachePath,
74  UsdTimeCode time,
75  HdDirtyBits requestedBits,
77  instancerContext = NULL) const override;
78 
79  // ---------------------------------------------------------------------- //
81  // ---------------------------------------------------------------------- //
82 
83  virtual HdDirtyBits ProcessPropertyChange(UsdPrim const& prim,
84  SdfPath const& cachePath,
85  TfToken const& propertyName) override;
86 
87  virtual void ProcessPrimResync(SdfPath const& cachePath,
88  UsdImagingIndexProxy* index) override;
89 
90  virtual void ProcessPrimRemoval(SdfPath const& cachePath,
91  UsdImagingIndexProxy* index) override;
92 
93 
94  virtual void MarkDirty(UsdPrim const& prim,
95  SdfPath const& cachePath,
96  HdDirtyBits dirty,
97  UsdImagingIndexProxy* index) override;
98 
99  // As this adapter hijacks the adapter for the child prim
100  // We need to forward these messages on, in case the child
101  // adapter needs them
102  virtual void MarkRefineLevelDirty(UsdPrim const& prim,
103  SdfPath const& cachePath,
104  UsdImagingIndexProxy* index) override;
105 
106  virtual void MarkReprDirty(UsdPrim const& prim,
107  SdfPath const& cachePath,
108  UsdImagingIndexProxy* index) override;
109 
110  virtual void MarkCullStyleDirty(UsdPrim const& prim,
111  SdfPath const& cachePath,
112  UsdImagingIndexProxy* index) override;
113 
114  virtual void MarkRenderTagDirty(UsdPrim const& prim,
115  SdfPath const& cachePath,
116  UsdImagingIndexProxy* index) override;
117 
118  virtual void MarkTransformDirty(UsdPrim const& prim,
119  SdfPath const& cachePath,
120  UsdImagingIndexProxy* index) override;
121 
122  virtual void MarkVisibilityDirty(UsdPrim const& prim,
123  SdfPath const& cachePath,
124  UsdImagingIndexProxy* index) override;
125 
126 
127 
128  // ---------------------------------------------------------------------- //
130  // ---------------------------------------------------------------------- //
131 
132  virtual SdfPath GetPathForInstanceIndex(SdfPath const &protoCachePath,
133  int protoIndex,
134  int *instanceCountForThisLevel,
135  int *instancerIndex,
136  SdfPath *masterCachePath = NULL,
137  SdfPathVector *
138  instanceContext = NULL) override;
139 
140  virtual SdfPath GetInstancer(SdfPath const &cachePath) override;
141 
142  virtual std::vector<VtArray<TfToken>>
143  GetInstanceCategories(UsdPrim const& prim) override;
144 
145  virtual size_t
146  SampleInstancerTransform(UsdPrim const& instancerPrim,
147  SdfPath const& instancerPath,
148  UsdTimeCode time,
149  size_t maxSampleCount,
150  float *sampleTimes,
151  GfMatrix4d *sampleValues) override;
152 
153  virtual size_t
154  SampleTransform(UsdPrim const& prim,
155  SdfPath const& cachePath,
156  UsdTimeCode time,
157  size_t maxNumSamples,
158  float *sampleTimes,
159  GfMatrix4d *sampleValues) override;
160 
161  virtual size_t
162  SamplePrimvar(UsdPrim const& usdPrim,
163  SdfPath const& cachePath,
164  TfToken const& key,
165  UsdTimeCode time,
166  size_t maxNumSamples,
167  float *sampleTimes,
168  VtValue *sampleValues) override;
169 
170  virtual PxOsdSubdivTags GetSubdivTags(UsdPrim const& usdPrim,
171  SdfPath const& cachePath,
172  UsdTimeCode time) const override;
173 
174  // ---------------------------------------------------------------------- //
176  // ---------------------------------------------------------------------- //
177 
178  virtual VtIntArray GetInstanceIndices(SdfPath const &instancerPath,
179  SdfPath const &protoRprimPath,
180  UsdTimeCode time) override;
181 
183  SdfPath const &parentInstancerPath,
184  SdfPath const &instancerPath,
185  UsdTimeCode time) const override;
186 
187  // ---------------------------------------------------------------------- //
189  // ---------------------------------------------------------------------- //
190  virtual bool PopulateSelection(
191  HdSelection::HighlightMode const& highlightMode,
192  SdfPath const &path,
193  VtIntArray const &instanceIndices,
194  HdSelectionSharedPtr const &result) override;
195 
196  // ---------------------------------------------------------------------- //
198  // ---------------------------------------------------------------------- //
199 
200  virtual HdVolumeFieldDescriptorVector
201  GetVolumeFieldDescriptors(UsdPrim const& usdPrim, SdfPath const &id,
202  UsdTimeCode time) const override;
203 
204  // ---------------------------------------------------------------------- //
206  // ---------------------------------------------------------------------- //
207 
210  virtual SdfPathVector GetDependPaths(SdfPath const &path) const override;
211 
212 protected:
213  virtual void _RemovePrim(SdfPath const& cachePath,
214  UsdImagingIndexProxy* index) override final;
215 
216 private:
217 
218  SdfPath _Populate(UsdPrim const& prim,
219  UsdImagingIndexProxy* index,
220  UsdImagingInstancerContext const* instancerContext,
221  SdfPath const& parentProxyPath);
222 
223  struct _ProtoRprim;
224  struct _ProtoGroup;
225 
226  bool _IsChildPrim(UsdPrim const& prim,
227  SdfPath const& cachePath) const;
228 
229  UsdImagingPrimAdapterSharedPtr _GetSharedFromThis();
230 
231  // Returns true if the given prim serves as an instancer.
232  bool _PrimIsInstancer(UsdPrim const& prim) const;
233 
234  // Inserts an rprim for the given \p usdPrim into the \p index.
235  // The rprim will be created under a child path combining the
236  // \p instancerPath and \p protoName; that path will be returned.
237  SdfPath
238  _InsertProtoRprim(UsdPrimRange::iterator *iter,
239  const TfToken& protoName,
240  SdfPath materialId,
241  TfToken drawMode,
242  SdfPath instancerPath,
243  UsdImagingPrimAdapterSharedPtr const& primAdapter,
244  UsdImagingPrimAdapterSharedPtr const& instancerAdapter,
245  UsdImagingIndexProxy* index,
246  bool *isLeafInstancer);
247 
248  // For a usd path, collects the instancers to resync.
249  void _ResyncPath(SdfPath const& cachePath,
250  UsdImagingIndexProxy* index,
251  bool reload);
252  // Removes and optionally reloads all instancer data, both locally and
253  // from the render index.
254  void _ResyncInstancer(SdfPath const& instancerPath,
255  UsdImagingIndexProxy* index, bool reload);
256 
257  // Updates per-frame data in the instancer map. This is primarily used
258  // during update to send new instance indices out to Hydra.
259  struct _UpdateInstanceMapFn;
260  void _UpdateInstanceMap(UsdPrim const& instancerPrim,
261  UsdTimeCode time) const;
262 
263  // Precomputes the instancer visibility data (as visible, invis, varying
264  // per-node), and returns whether the instance map is variable.
265  // Note: this function assumes the instancer data is already locked by
266  // the caller...
267  struct _InstancerData;
268  struct _ComputeInstanceMapVariabilityFn;
269  bool _ComputeInstanceMapVariability(UsdPrim const& instancerPrim,
270  _InstancerData& instrData) const;
271 
272  // Update the dirty bits per-instancer. This is only executed once per
273  // instancer, this method uses the instancer mutex to avoid redundant work.
274  //
275  // Returns the instancer's dirty bits.
276  int _UpdateDirtyBits(UsdPrim const& instancerPrim) const;
277 
278  // Gets the associated _ProtoRprim and instancer context for the given
279  // instancer and cache path.
280  _ProtoRprim const& _GetProtoRprim(SdfPath const& instancerPath,
281  SdfPath const& cachePath,
282  UsdImagingInstancerContext* ctx) const;
283 
284  // Computes the transforms for all instances corresponding to the given
285  // instancer.
286  struct _ComputeInstanceTransformFn;
287  bool _ComputeInstanceTransforms(UsdPrim const& instancer,
288  VtMatrix4dArray* transforms,
289  UsdTimeCode time) const;
290 
291  // Gathers the authored transforms time samples given an instancer.
292  struct _GatherInstanceTransformTimeSamplesFn;
293  bool _GatherInstanceTransformsTimeSamples(UsdPrim const& instancer,
294  GfInterval interval,
295  std::vector<double>* outTimes)
296  const;
297 
298  // Returns true if any of the instances corresponding to the given
299  // instancer has a varying transform.
300  struct _IsInstanceTransformVaryingFn;
301  bool _IsInstanceTransformVarying(UsdPrim const& instancer) const;
302 
303  // Computes the value of a primvar for all instances corresponding to the
304  // given instancer. The templated version runs the templated functor,
305  // and the un-templated version does type dispatch.
306  template<typename T> struct _ComputeInheritedPrimvarFn;
307 
308  template<typename T>
309  bool _ComputeInheritedPrimvar(UsdPrim const& instancer,
310  TfToken const& primvarName,
311  VtValue *result,
312  UsdTimeCode time) const;
313 
314  bool _ComputeInheritedPrimvar(UsdPrim const& instancer,
315  TfToken const& primvarName,
316  SdfValueTypeName const& type,
317  VtValue *result,
318  UsdTimeCode time) const;
319 
320  // Returns true if any of the instances corresponding to the given
321  // instancer has varying inherited primvars.
322  struct _IsInstanceInheritedPrimvarVaryingFn;
323  bool _IsInstanceInheritedPrimvarVarying(UsdPrim const& instancer) const;
324 
325  struct _GetPathForInstanceIndexFn;
326  struct _PopulateInstanceSelectionFn;
327 
328  // Helper functions for dealing with "actual" instances to be drawn.
329  //
330  // Suppose we have:
331  // /Root
332  // Instance_A (master: /__Master_1)
333  // Instance_B (master: /__Master_1)
334  // /__Master_1
335  // AnotherInstance_A (master: /__Master_2)
336  // /__Master_2
337  //
338  // /__Master_2 has only one associated instance in the Usd scenegraph:
339  // /__Master_1/AnotherInstance_A. However, imaging actually needs to draw
340  // two instances of /__Master_2, because AnotherInstance_A is a nested
341  // instance beneath /__Master_1, and there are two instances of /__Master_1.
342  //
343  // Each instance to be drawn is addressed by the chain of instances
344  // that caused it to be drawn. In the above example, the two instances
345  // of /__Master_2 to be drawn are:
346  //
347  // [ /Root/Instance_A, /__Master_1/AnotherInstance_A ],
348  // [ /Root/Instance_B, /__Master_1/AnotherInstance_A ]
349  //
350  // This "instance context" describes the chain of opinions that
351  // ultimately affect the final drawn instance. For example, the
352  // transform of each instance to draw is the combined transforms
353  // of the prims in each context.
354  template <typename Functor>
355  void _RunForAllInstancesToDraw(UsdPrim const& instancer, Functor* fn) const;
356  template <typename Functor>
357  bool _RunForAllInstancesToDrawImpl(UsdPrim const& instancer,
358  std::vector<UsdPrim>* instanceContext,
359  size_t* instanceIdx,
360  Functor* fn) const;
361 
362  typedef TfHashMap<SdfPath, size_t, SdfPath::Hash> _InstancerDrawCounts;
363  size_t _CountAllInstancesToDraw(UsdPrim const& instancer) const;
364  size_t _CountAllInstancesToDrawImpl(UsdPrim const& instancer,
365  _InstancerDrawCounts* drawCounts) const;
366 
367  // A proto group represents a complete set of rprims for a given prototype
368  // declared on the instancer.
369  struct _ProtoGroup {
370  // The time at which the instance data should be fetched.
371  UsdTimeCode time;
372  // A vector of prototype indices that also index into the primvar data.
373  // All elements in this array can be dispatched as a single hardware
374  // draw call (though this is a detail of the renderer implementation).
375  VtIntArray indices;
376  };
377  typedef boost::shared_ptr<_ProtoGroup> _ProtoGroupPtr;
378 
379  // A proto rprim represents a single rprim under a prototype root declared
380  // on the instancer. For example, a character may be targeted by the
381  // prototypes relationship, which will have many meshes, each mesh is
382  // represented as a proto rprim.
383  struct _ProtoRprim {
384  _ProtoRprim() {}
385  // Each rprim will become a prototype "child" under the instancer. This
386  // path is the path to the gprim on the Usd Stage (the path to a single
387  // mesh, for example).
388  SdfPath path;
389  // The prim adapter for the actual prototype gprim.
390  UsdImagingPrimAdapterSharedPtr adapter;
391  // The prototype group that this rprim belongs to.
392  // Over time, as instances are animated, multiple copies of the
393  // prototype may be required to, for example, draw two different frames
394  // of animation. This ID maps the rprim its associated instance data
395  // over time.
396  _ProtoGroupPtr protoGroup;
397  };
398 
399  // Indexed by cachePath (each rprim has one entry)
400  typedef TfHashMap<SdfPath, _ProtoRprim, SdfPath::Hash> _PrimMap;
401 
402  // All data associated with a given instancer prim. PrimMap could
403  // technically be split out to avoid two lookups, however it seems cleaner
404  // to keep everything bundled up under the instancer path.
405  struct _InstancerData {
406  _InstancerData() : numInstancesToDraw(0) { }
407 
408  // The master prim path associated with this instancer.
409  SdfPath masterPath;
410 
411  // The USD material path associated with this instancer.
412  SdfPath materialUsdPath;
413 
414  // The drawmode associated with this instancer.
415  TfToken drawMode;
416 
417  // Inherited primvar
418  struct PrimvarInfo {
419  TfToken name;
420  SdfValueTypeName type;
421  bool operator==(const PrimvarInfo& rhs) const;
422  bool operator<(const PrimvarInfo& rhs) const;
423  };
424  std::vector<PrimvarInfo> inheritedPrimvars;
425 
426  // Paths to Usd instance prims. Note that this is not necessarily
427  // equivalent to all the instances that will be drawn. See below.
428  std::vector<SdfPath> instancePaths;
429 
430  // Number of actual instances of this instancer that will be
431  // drawn. See comment on _RunForAllInstancesToDraw.
432  size_t numInstancesToDraw;
433 
434  // Cached visibility. This vector contains an entry for each instance
435  // that will be drawn (i.e., visibility.size() == numInstancesToDraw).
436  enum Visibility {
437  Invisible, //< Invisible over all time
438  Visible, //< Visible over all time
439  Varying, //< Visibility varies over time
440  Unknown //< Visibility has not yet been checked
441  };
442  std::vector<Visibility> visibility;
443 
444  // Map of all rprims for this instancer prim.
445  _PrimMap primMap;
446 
447  // This is a set of reference paths, where this instancer needs
448  // to deferer to another instancer. While refered to here as a child
449  // instancer, the actual relationship is more like a directed graph.
450  SdfPathSet childPointInstancers;
451 
452  // Nested native instances.
453  SdfPathVector nestedInstances;
454 
455  // Proto group containing the instance indexes for each prototype
456  // rprim.
457  _ProtoGroupPtr protoGroup;
458 
459  // Instancer dirty bits.
460  HdDirtyBits dirtyBits;
461 
462  std::mutex mutex;
463  };
464 
465  // Map from instancer cache path to instancer data.
466  // Note: this map is modified in multithreaded code paths and must be
467  // locked.
468  typedef boost::unordered_map<SdfPath, _InstancerData, SdfPath::Hash>
469  _InstancerDataMap;
470  mutable _InstancerDataMap _instancerData;
471 
472  // Map from instance to instancer.
473  // XXX: consider to move this forwarding map into HdRenderIndex.
474  typedef TfHashMap<SdfPath, SdfPath, SdfPath::Hash>
475  _InstanceToInstancerMap;
476  _InstanceToInstancerMap _instanceToInstancerMap;
477 
478  // Hd and UsdImaging think of instancing in terms of an 'instancer' that
479  // specifies a list of 'prototype' prims that are shared per instance.
480  //
481  // For Usd scenegraph instancing, a master prim and its descendents
482  // roughly correspond to the instancer and prototype prims. However,
483  // Hd requires a different instancer and rprims for different combinations
484  // of inherited attributes (material binding, draw mode, etc).
485  // This means we cannot use the Usd master prim as the instancer, because
486  // we can't represent this in the case where multiple Usd instances share
487  // the same master but have different bindings.
488  //
489  // Instead, we use the first instance of a master with a given set of
490  // inherited attributes as our instancer. For example, if /A and /B are
491  // both instances of /__Master_1 but /A and /B have different material
492  // bindings authored on them, both /A and /B will be instancers,
493  // with their own set of rprims and instance indices.
494  //
495  // The below is a multimap from master path to instancer path. The data
496  // for the instancer is located in the _InstancerDataMap above.
497  typedef TfHashMultiMap<SdfPath, SdfPath, SdfPath::Hash>
498  _MasterToInstancerMap;
499  _MasterToInstancerMap _masterToInstancerMap;
500 };
501 
502 
503 PXR_NAMESPACE_CLOSE_SCOPE
504 
505 #endif // USDIMAGING_INSTANCE_ADAPTER_H
Tags for non-hierarchial subdiv surfaces.
Definition: subdivTags.h:41
virtual void ProcessPrimResync(SdfPath const &cachePath, UsdImagingIndexProxy *index) override
When a PrimResync event occurs, the prim may have been deleted entirely, adapter plug-ins should over...
virtual SdfPath GetInstancer(SdfPath const &cachePath) override
Returns the instancer path for given instancePath.
virtual size_t SampleInstancerTransform(UsdPrim const &instancerPrim, SdfPath const &instancerPath, UsdTimeCode time, size_t maxSampleCount, float *sampleTimes, GfMatrix4d *sampleValues) override
Sample the instancer transform for the given prim.
HighlightMode
Selection modes allow differentiation in selection highlight behavior.
Definition: selection.h:53
Represents a value type name, i.e.
Definition: valueTypeName.h:83
This proxy class exposes a subset of the private Delegate API to PrimAdapters.
Definition: indexProxy.h:47
virtual void ProcessPrimRemoval(SdfPath const &cachePath, UsdImagingIndexProxy *index) override
Removes all associated Rprims and dependencies from the render index without scheduling them for repo...
virtual SdfPath GetPathForInstanceIndex(SdfPath const &protoCachePath, int protoIndex, int *instanceCountForThisLevel, int *instancerIndex, SdfPath *masterCachePath=NULL, SdfPathVector *instanceContext=NULL) override
Returns the usd path of the original instancer prim corresponding to the given instanced protoCachePa...
virtual VtIntArray GetInstanceIndices(SdfPath const &instancerPath, SdfPath const &protoRprimPath, UsdTimeCode time) override
Returns the instance index array for protoRprimPath, instanced by instancerPath.
virtual SdfPathVector GetDependPaths(SdfPath const &path) const override
Returns the depending rprim paths which don&#39;t exist in descendants.
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:89
virtual void UpdateForTime(UsdPrim const &prim, SdfPath const &cachePath, UsdTimeCode time, HdDirtyBits requestedBits, UsdImagingInstancerContext const *instancerContext=NULL) const override
Populates the cache for the given prim, time and requestedBits.
virtual size_t SamplePrimvar(UsdPrim const &usdPrim, SdfPath const &cachePath, TfToken const &key, UsdTimeCode time, size_t maxNumSamples, float *sampleTimes, VtValue *sampleValues) override
Sample the primvar for the given prim.
Stores a 4x4 matrix of double elements.
Definition: matrix4d.h:88
Represent a time value, which may be either numeric, holding a double value, or a sentinel value UsdT...
Definition: timeCode.h:85
Base class for all PrimAdapters.
Definition: primAdapter.h:67
UsdPrim is the sole persistent scenegraph object on a UsdStage, and is the embodiment of a &quot;Prim&quot; as ...
Definition: prim.h:131
virtual PxOsdSubdivTags GetSubdivTags(UsdPrim const &usdPrim, SdfPath const &cachePath, UsdTimeCode time) const override
Get the subdiv tags for this prim.
A basic mathematical interval class.
Definition: interval.h:50
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:287
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.
virtual std::vector< VtArray< TfToken > > GetInstanceCategories(UsdPrim const &prim) override
Return an array of the categories used by each instance.
virtual SdfPath Populate(UsdPrim const &prim, UsdImagingIndexProxy *index, UsdImagingInstancerContext const *instancerContext=NULL) override
Called to populate the RenderIndex for this UsdPrim.
Delegate support for instanced prims.
virtual void TrackVariability(UsdPrim const &prim, SdfPath const &cachePath, HdDirtyBits *timeVaryingBits, UsdImagingInstancerContext const *instancerContext=NULL) const override
For the given prim, variability is detected and stored in timeVaryingBits.
VT_API bool operator==(VtDictionary const &, VtDictionary const &)
Equality comparison.
Object used by instancer prim adapters to pass along context about the instancer and instance prim to...
virtual HdDirtyBits ProcessPropertyChange(UsdPrim const &prim, SdfPath const &cachePath, TfToken const &propertyName) override
Returns a bit mask of attributes to be updated, or HdChangeTracker::AllDirty if the entire prim must ...
A forward iterator into a UsdPrimRange.
Definition: primRange.h:140
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Definition: value.h:182
virtual GfMatrix4d GetRelativeInstancerTransform(SdfPath const &parentInstancerPath, SdfPath const &instancerPath, UsdTimeCode time) const override
Returns the transform of protoInstancerPath relative to instancerPath.