24#ifndef EXT_RMANPKG_25_0_PLUGIN_RENDERMAN_PLUGIN_HD_PRMAN_INSTANCER_H
25#define EXT_RMANPKG_25_0_PLUGIN_RENDERMAN_PLUGIN_HD_PRMAN_INSTANCER_H
29#include "hdPrman/renderParam.h"
30#include "hdPrman/rixStrings.h"
32#include "pxr/imaging/hd/instancer.h"
33#include "pxr/imaging/hd/sceneDelegate.h"
34#include "pxr/imaging/hd/timeSampleArray.h"
35#include "pxr/base/tf/hashmap.h"
38#include "pxr/base/vt/value.h"
40#include "tbb/concurrent_unordered_map.h"
41#include "tbb/spin_rw_mutex.h"
43PXR_NAMESPACE_OPEN_SCOPE
57 HdDirtyBits *dirtyBits)
override;
61 HdDirtyBits GetInitialDirtyBitsMask()
const override;
112 HdDirtyBits* dirtyBits,
113 const SdfPath& hydraPrototypeId,
114 const std::vector<riley::GeometryPrototypeId>& rileyPrototypeIds,
115 const riley::CoordinateSystemList& coordSysList,
116 const RtParamList protoParams,
118 const std::vector<riley::MaterialId>& rileyMaterialIds,
119 const SdfPathVector& prototypePaths,
120 const riley::LightShaderId& lightShaderId = riley::LightShaderId::InvalidId());
138 const SdfPath& prototypePrimPath,
139 const std::vector<riley::GeometryPrototypeId>& excludedPrototypeIds = {});
150 struct _RtParamListHashFunctor
152 size_t operator()(
const RtParamList& params)
const noexcept
155 RtParamList copy = params;
156 return std::hash<uint32_t>()(copy.Hash());
160 struct _RtParamListEqualToFunctor
162 bool operator()(
const RtParamList& lhs,
const RtParamList& rhs)
const noexcept
164 return _RtParamListHashFunctor()(lhs) == _RtParamListHashFunctor()(rhs);
178 std::unordered_set<TfToken, TfToken::HashFunctor> categories;
187 _FlattenData(
const VtTokenArray& cats)
188 : categories(cats.begin(), cats.end()) { }
189 _FlattenData(
const VtTokenArray& cats,
bool vis)
190 : categories(cats.begin(), cats.end())
195 _FlattenData(
const _FlattenData& other)
196 : categories(other.categories.cbegin(), other.categories.cend())
198 params.Update(other.params);
203 void Inherit(
const _FlattenData& rhs)
205 categories.insert(rhs.categories.cbegin(), rhs.categories.cend());
206 params.Inherit(rhs.params);
211 void Update(
const _FlattenData& rhs)
213 categories.insert(rhs.categories.cbegin(), rhs.categories.cend());
214 params.Update(rhs.params);
220 void UpdateVisAndFilterParamList(RtParamList& other) {
222 for (
const RtUString& param : _GetVisibilityParams()) {
224 if (other.GetInteger(param, val)) {
226 params.Remove(param);
228 params.SetInteger(param, val);
241 RtUString groupingMembership;
242 if (other.GetString(RixStr.k_grouping_membership, groupingMembership)) {
243 params.SetString(RixStr.k_grouping_membership, groupingMembership);
249 for (
const RtUString& param : _GetLightLinkParams()) {
255 void SetVisibility(
bool visible) {
257 for (
const RtUString& param : _GetVisibilityParams()) {
258 params.Remove(param);
261 for (
const RtUString& param : _GetVisibilityParams()) {
262 params.SetInteger(param, 0);
268 bool operator==(
const _FlattenData& rhs)
const noexcept
270 return categories == rhs.categories &&
271 _RtParamListEqualToFunctor()(params, rhs.params);
275 size_t operator()(
const _FlattenData& fd)
const noexcept
280 for (
const TfToken& tok : fd.categories) {
283 return hash ^ _RtParamListHashFunctor()(fd.params);
288 static std::vector<RtUString> _GetLightLinkParams()
292 static const std::vector<RtUString> LightLinkParams = {
293 RixStr.k_lightfilter_subset,
294 RixStr.k_lighting_subset,
295 RixStr.k_grouping_membership,
296 RixStr.k_lighting_excludesubset
298 return LightLinkParams;
301 static std::vector<RtUString> _GetVisibilityParams()
305 static const std::vector<RtUString> VisParams = {
306 RixStr.k_visibility_camera,
307 RixStr.k_visibility_indirect,
308 RixStr.k_visibility_transmission
317 _FlattenData flattenData;
319 _GfMatrixSA transform;
323 const VtTokenArray& cats,
325 const RtParamList& p,
344 typename Hash = std::hash<Key>,
345 typename KeyEqual = std::equal_to<Key>>
351 bool has(
const Key& key)
const
353 tbb::spin_rw_mutex::scoped_lock lock(_mutex,
false);
354 if (_map.size() == 0) {
return false; }
355 return _map.find(key) != _map.end();
361 T& get(
const Key& key)
363 static_assert(std::is_default_constructible<T>::value,
364 "T must be default constructible");
366 tbb::spin_rw_mutex::scoped_lock lock(_mutex,
false);
367 auto it = _map.find(key);
368 if (it == _map.end()) {
370 std::piecewise_construct,
371 std::forward_as_tuple(key),
372 std::tuple<>{}).first;
379 bool set(
const Key& key, T& val)
381 static_assert(std::is_copy_assignable<T>::value,
382 "T must be copy-assignable");
384 tbb::spin_rw_mutex::scoped_lock lock(_mutex,
false);
385 if (_map.size() > 0) {
386 auto it = _map.find(key);
387 if (it != _map.end()) {
392 _map.insert({key, val});
397 void iterate(std::function<
void(
const Key&, T&)> fn)
400 tbb::spin_rw_mutex::scoped_lock lock(_mutex,
true);
401 for (std::pair<const Key, T>& p : _map) {
402 fn(p.first, p.second);
407 void citerate(std::function<
void(
const Key&,
const T&)> fn)
const
409 tbb::spin_rw_mutex::scoped_lock lock(_mutex,
false);
410 for (
const std::pair<const Key, const T>& p : _map) {
411 fn(p.first, p.second);
418 tbb::spin_rw_mutex::scoped_lock lock(_mutex,
false);
423 void erase(
const Key& key)
426 tbb::spin_rw_mutex::scoped_lock lock(_mutex,
true);
427 _map.unsafe_erase(key);
434 tbb::spin_rw_mutex::scoped_lock lock(_mutex,
true);
438 tbb::concurrent_unordered_map<Key, T, Hash, KeyEqual> _map;
439 mutable tbb::spin_rw_mutex _mutex;
442 using _LockingFlattenGroupMap = _LockingMap<
444 riley::GeometryPrototypeId,
445 _FlattenData::HashFunctor>;
447 struct _RileyInstanceId
449 riley::GeometryPrototypeId groupId;
450 riley::GeometryInstanceId geoInstanceId;
451 riley::LightInstanceId lightInstanceId;
454 using _InstanceIdVec = std::vector<_RileyInstanceId>;
458 size_t operator()(
const riley::GeometryPrototypeId&
id)
const noexcept
460 return std::hash<uint32_t>()(
id.AsUInt32());
464 using _ProtoInstMap = std::unordered_map<
465 riley::GeometryPrototypeId,
469 using _LockingProtoGroupCounterMap = _LockingMap<
470 riley::GeometryPrototypeId,
474 struct _ProtoMapEntry
480 using _LockingProtoMap = _LockingMap<SdfPath, _ProtoMapEntry, SdfPath::Hash>;
487 void _SyncPrimvars(HdDirtyBits* dirtyBits);
490 void _SyncTransforms(HdDirtyBits* dirtyBits);
493 void _SyncCategories(HdDirtyBits* dirtyBits);
496 void _SyncVisibility(HdDirtyBits* dirtyBits);
500 void _ComposeInstances(
502 const std::vector<_InstanceData>& subInstances,
503 std::vector<_InstanceData>& instances);
508 void _ComposeInstanceFlattenData(
509 const size_t instanceId,
510 RtParamList& instanceParams,
512 const _FlattenData& fromBelow = _FlattenData());
519 void _ComposePrototypeData(
521 const RtParamList& globalProtoParams,
523 const std::vector<riley::GeometryPrototypeId>& protoIds,
524 const SdfPathVector& subProtoPaths,
525 const std::vector<_FlattenData>& subProtoFlats,
526 std::vector<RtParamList>& protoParams,
527 std::vector<_FlattenData>& protoFlats);
533 bool _RemoveDeadInstances(
535 const SdfPath& prototypePrimPath,
536 const std::vector<riley::GeometryPrototypeId>& protoIds);
540 void _SetPrototypesDirty();
548 void _PopulateInstances(
550 HdDirtyBits* dirtyBits,
551 const SdfPath& hydraPrototypeId,
552 const SdfPath& prototypePrimPath,
553 const std::vector<riley::GeometryPrototypeId>& rileyPrototypeIds,
554 const riley::CoordinateSystemList& coordSysList,
555 const RtParamList protoParams,
557 const std::vector<riley::MaterialId>& rileyMaterialIds,
558 const SdfPathVector& prototypePaths,
559 const riley::LightShaderId& lightShaderId,
560 const std::vector<_InstanceData>& subInstances,
561 const std::vector<_FlattenData>& prototypeFlats);
568 void _PopulateInstancesFromChild(
570 HdDirtyBits* dirtyBits,
571 const SdfPath& hydraPrototypeId,
572 const SdfPath& prototypePrimPath,
573 const std::vector<riley::GeometryPrototypeId>& rileyPrototypeIds,
574 const riley::CoordinateSystemList& coordSysList,
575 const RtParamList protoParams,
577 const std::vector<riley::MaterialId>& rileyMaterialIds,
578 const SdfPathVector& prototypePaths,
579 const riley::LightShaderId& lightShaderId,
580 const std::vector<_InstanceData>& subInstances,
581 const std::vector<_FlattenData>& prototypeFlats);
584 HdPrmanInstancer* _GetParentInstancer();
589 void _ResizeProtoMap(
591 const SdfPath& prototypePrimPath,
592 const std::vector<riley::GeometryPrototypeId>& rileyPrototypeIds,
593 const size_t newSize);
597 bool _CleanDisusedGroupIds(HdPrman_RenderParam* param);
602 bool _AcquireGroupId(
603 HdPrman_RenderParam* param,
604 const _FlattenData& flattenGroup,
605 riley::GeometryPrototypeId& groupId);
609 void _GetInstanceParams(
610 const size_t instanceIndex,
611 RtParamList& params);
614 void _GetPrototypeParams(
621 void _GetInstanceTransform(
622 const size_t instanceIndex,
624 const _GfMatrixSA& left = _GfMatrixSA());
641 riley::CoordinateSystemList _coordSysList = { 0,
nullptr };
645 std::vector<VtTokenArray> _instanceCategories;
648 _FlattenData _instancerFlat;
651 TfHashMap<TfToken, _PrimvarValue, TfToken::HashFunctor> _primvarMap;
660 _LockingFlattenGroupMap _groupMap;
664 _LockingProtoGroupCounterMap _groupCounters;
669 tbb::spin_rw_mutex _groupIdAcquisitionLock;
680 _LockingProtoMap _protoMap;
686 _LockingMap<SdfPath, tbb::spin_rw_mutex, SdfPath::Hash> _childPopulateLocks;
689PXR_NAMESPACE_CLOSE_SCOPE
Defines all the types "TYPED" for which Vt creates a VtTYPEDArray typedef.
This class exists to facilitate point cloud style instancing.
The HdRenderParam is an opaque (to core Hydra) handle, to an object that is obtained from the render ...
Adapter class providing data exchange with the client scene graph.
A path value used to locate objects in layers or scenegraphs.
Token for efficient comparison, assignment, and hashing of known strings.
size_t Hash() const
Return a size_t hash for this token.
Provides a container which may hold any type, and provides introspection and iteration over array typ...
An array of a value sampled over time, in struct-of-arrays layout.
TfToken class for efficient string referencing and hashing, plus conversions to and from stl string c...