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 
28 
29 #include "pxr/pxr.h"
30 #include "pxr/usdImaging/usdImaging/primAdapter.h"
31 
32 #include "pxr/base/tf/hashmap.h"
33 
34 #include <mutex>
35 
36 PXR_NAMESPACE_OPEN_SCOPE
37 
38 
44 {
45 public:
47 
49  virtual ~UsdImagingInstanceAdapter();
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  // ---------------------------------------------------------------------- //
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,
70  UsdTimeCode time,
71  HdDirtyBits requestedBits,
73  instancerContext = NULL) const override;
74 
75  // ---------------------------------------------------------------------- //
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  // ---------------------------------------------------------------------- //
126  // ---------------------------------------------------------------------- //
127 
128  virtual SdfPath GetPathForInstanceIndex(SdfPath const &protoCachePath,
129  int protoIndex,
130  int *instanceCountForThisLevel,
131  int *instancerIndex,
132  SdfPath *masterCachePath = NULL,
133  SdfPathVector *
134  instanceContext = NULL) override;
135 
136  virtual std::vector<VtArray<TfToken>>
137  GetInstanceCategories(UsdPrim const& prim) override;
138 
139  virtual size_t
140  SampleInstancerTransform(UsdPrim const& instancerPrim,
141  SdfPath const& instancerPath,
142  UsdTimeCode time,
143  size_t maxSampleCount,
144  float *sampleTimes,
145  GfMatrix4d *sampleValues) override;
146 
147  virtual size_t
148  SampleTransform(UsdPrim const& prim,
149  SdfPath const& cachePath,
150  UsdTimeCode time,
151  size_t maxNumSamples,
152  float *sampleTimes,
153  GfMatrix4d *sampleValues) override;
154 
155  virtual size_t
156  SamplePrimvar(UsdPrim const& usdPrim,
157  SdfPath const& cachePath,
158  TfToken const& key,
159  UsdTimeCode time,
160  size_t maxNumSamples,
161  float *sampleTimes,
162  VtValue *sampleValues) override;
163 
164  virtual PxOsdSubdivTags GetSubdivTags(UsdPrim const& usdPrim,
165  SdfPath const& cachePath,
166  UsdTimeCode time) const override;
167 
168  // ---------------------------------------------------------------------- //
170  // ---------------------------------------------------------------------- //
171 
173  SdfPath const &parentInstancerPath,
174  SdfPath const &instancerPath,
175  UsdTimeCode time) const override;
176 
177  // ---------------------------------------------------------------------- //
179  // ---------------------------------------------------------------------- //
180  virtual bool PopulateSelection(
181  HdSelection::HighlightMode const& highlightMode,
182  SdfPath const &cachePath,
183  UsdPrim const &usdPrim,
184  VtIntArray const &instanceIndices,
185  HdSelectionSharedPtr const &result) override;
186 
187  // ---------------------------------------------------------------------- //
189  // ---------------------------------------------------------------------- //
190 
191  virtual HdVolumeFieldDescriptorVector
192  GetVolumeFieldDescriptors(UsdPrim const& usdPrim, SdfPath const &id,
193  UsdTimeCode time) const override;
194 
195 protected:
196  virtual void _RemovePrim(SdfPath const& cachePath,
197  UsdImagingIndexProxy* index) override final;
198 
199 private:
200 
201  SdfPath _Populate(UsdPrim const& prim,
202  UsdImagingIndexProxy* index,
203  UsdImagingInstancerContext const* instancerContext,
204  SdfPath const& parentProxyPath);
205 
206  struct _ProtoPrim;
207  struct _ProtoGroup;
208  struct _InstancerData;
209 
210  bool _IsChildPrim(UsdPrim const& prim,
211  SdfPath const& cachePath) const;
212 
213  // Returns true if the given prim serves as an instancer.
214  bool _PrimIsInstancer(UsdPrim const& prim) const;
215 
216  // Inserts prototype prims for the given \p usdPrim into the \p index.
217  // Any inserted gprims will be inserted under a special path combining
218  // \p instancerPath and \p protoName.
219  SdfPath
220  _InsertProtoPrim(UsdPrimRange::iterator *iter,
221  const TfToken& protoName,
222  SdfPath materialId,
223  TfToken drawMode,
224  SdfPath instancerPath,
225  UsdImagingPrimAdapterSharedPtr const& primAdapter,
226  UsdImagingPrimAdapterSharedPtr const& instancerAdapter,
227  UsdImagingIndexProxy* index,
228  bool *isLeafInstancer);
229 
230  // For a usd path, collects the instancers to resync.
231  void _ResyncPath(SdfPath const& cachePath,
232  UsdImagingIndexProxy* index,
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 _GetPathForInstanceIndexFn;
310  struct _PopulateInstanceSelectionFn;
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 
346  typedef TfHashMap<SdfPath, size_t, SdfPath::Hash> _InstancerDrawCounts;
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.
360  UsdImagingPrimAdapterSharedPtr adapter;
361  };
362 
363  // Indexed by cachePath (each prim has one entry)
364  typedef TfHashMap<SdfPath, _ProtoPrim, SdfPath::Hash> _PrimMap;
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) { }
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  // Inherited primvar
382  struct PrimvarInfo {
383  TfToken name;
384  SdfValueTypeName type;
385  bool operator==(const PrimvarInfo& rhs) const;
386  bool operator<(const PrimvarInfo& rhs) const;
387  };
388  std::vector<PrimvarInfo> inheritedPrimvars;
389 
390  // Paths to Usd instance prims. Note that this is not necessarily
391  // equivalent to all the instances that will be drawn. See below.
392  std::vector<SdfPath> instancePaths;
393 
394  // Number of actual instances of this instancer that will be
395  // drawn. See comment on _RunForAllInstancesToDraw.
396  // XXX: This is mutable so that we can precache it in TrackVariability;
397  // it's inappropriate to track it in _Populate since not all instances
398  // will have been populated.
399  mutable size_t numInstancesToDraw;
400 
401  // Cached visibility. This vector contains an entry for each instance
402  // that will be drawn (i.e., visibility.size() == numInstancesToDraw).
403  enum Visibility {
404  Invisible, //< Invisible over all time
405  Visible, //< Visible over all time
406  Varying, //< Visibility varies over time
407  Unknown //< Visibility has not yet been checked
408  };
409  // XXX: This is mutable so that we can precache visibility per-instance
410  // in TrackVariability(). Can we replace this with some kind of usage
411  // of an inherited cache?
412  mutable std::vector<Visibility> visibility;
413 
414  // Map of all rprims for this instancer prim.
415  _PrimMap primMap;
416 
417  // This is a set of reference paths, where this instancer needs
418  // to deferer to another instancer. While refered to here as a child
419  // instancer, the actual relationship is more like a directed graph.
420  SdfPathSet childPointInstancers;
421 
422  // Nested native instances.
423  SdfPathVector nestedInstances;
424  };
425 
426  // Map from instancer cache path to instancer data.
427  // Note: this map is modified in multithreaded code paths and must be
428  // locked.
429  typedef std::unordered_map<SdfPath, _InstancerData, SdfPath::Hash>
430  _InstancerDataMap;
431  _InstancerDataMap _instancerData;
432 
433  // Map from instance to instancer.
434  // XXX: consider to move this forwarding map into HdRenderIndex.
435  typedef TfHashMap<SdfPath, SdfPath, SdfPath::Hash>
436  _InstanceToInstancerMap;
437  _InstanceToInstancerMap _instanceToInstancerMap;
438 
439  // Hd and UsdImaging think of instancing in terms of an 'instancer' that
440  // specifies a list of 'prototype' prims that are shared per instance.
441  //
442  // For Usd scenegraph instancing, a master prim and its descendents
443  // roughly correspond to the instancer and prototype prims. However,
444  // Hd requires a different instancer and rprims for different combinations
445  // of inherited attributes (material binding, draw mode, etc).
446  // This means we cannot use the Usd master prim as the instancer, because
447  // we can't represent this in the case where multiple Usd instances share
448  // the same master but have different bindings.
449  //
450  // Instead, we use the first instance of a master with a given set of
451  // inherited attributes as our instancer. For example, if /A and /B are
452  // both instances of /__Master_1 but /A and /B have different material
453  // bindings authored on them, both /A and /B will be instancers,
454  // with their own set of rprims and instance indices.
455  //
456  // The below is a multimap from master path to instancer path. The data
457  // for the instancer is located in the _InstancerDataMap above.
458  typedef TfHashMultiMap<SdfPath, SdfPath, SdfPath::Hash>
459  _MasterToInstancerMap;
460  _MasterToInstancerMap _masterToInstancerMap;
461 };
462 
463 
464 PXR_NAMESPACE_CLOSE_SCOPE
465 
466 #endif // PXR_USD_IMAGING_USD_IMAGING_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 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...
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.