7#ifndef EXT_RMANPKG_25_0_PLUGIN_RENDERMAN_PLUGIN_HD_PRMAN_INSTANCER_H
8#define EXT_RMANPKG_25_0_PLUGIN_RENDERMAN_PLUGIN_HD_PRMAN_INSTANCER_H
12#include "hdPrman/renderParam.h"
13#include "hdPrman/rixStrings.h"
15#include "pxr/imaging/hd/instancer.h"
16#include "pxr/imaging/hd/sceneDelegate.h"
17#include "pxr/imaging/hd/timeSampleArray.h"
18#include "pxr/base/tf/hashmap.h"
21#include "pxr/base/vt/value.h"
23#include "tbb/concurrent_unordered_map.h"
24#include "tbb/spin_rw_mutex.h"
26PXR_NAMESPACE_OPEN_SCOPE
40 HdDirtyBits *dirtyBits)
override;
44 HdDirtyBits GetInitialDirtyBitsMask()
const override;
95 HdDirtyBits* dirtyBits,
96 const SdfPath& hydraPrototypeId,
97 const std::vector<riley::GeometryPrototypeId>& rileyPrototypeIds,
98 const riley::CoordinateSystemList& coordSysList,
99 const RtParamList protoParams,
101 const std::vector<riley::MaterialId>& rileyMaterialIds,
102 const SdfPathVector& prototypePaths,
103 const riley::LightShaderId& lightShaderId = riley::LightShaderId::InvalidId());
121 const SdfPath& prototypePrimPath,
122 const std::vector<riley::GeometryPrototypeId>& excludedPrototypeIds = {});
133 struct _RtParamListHashFunctor
135 size_t operator()(
const RtParamList& params)
const noexcept
138 RtParamList copy = params;
139 return std::hash<uint32_t>()(copy.Hash());
143 struct _RtParamListEqualToFunctor
145 bool operator()(
const RtParamList& lhs,
const RtParamList& rhs)
const noexcept
147 return _RtParamListHashFunctor()(lhs) == _RtParamListHashFunctor()(rhs);
161 std::unordered_set<TfToken, TfToken::HashFunctor> categories;
170 _FlattenData(
const VtTokenArray& cats)
171 : categories(cats.begin(), cats.end()) { }
172 _FlattenData(
const VtTokenArray& cats,
bool vis)
173 : categories(cats.begin(), cats.end())
178 _FlattenData(
const _FlattenData& other)
179 : categories(other.categories.cbegin(), other.categories.cend())
181 params.Update(other.params);
186 void Inherit(
const _FlattenData& rhs)
188 categories.insert(rhs.categories.cbegin(), rhs.categories.cend());
189 params.Inherit(rhs.params);
194 void Update(
const _FlattenData& rhs)
196 categories.insert(rhs.categories.cbegin(), rhs.categories.cend());
197 params.Update(rhs.params);
203 void UpdateVisAndFilterParamList(RtParamList& other) {
205 for (
const RtUString& param : _GetVisibilityParams()) {
207 if (other.GetInteger(param, val)) {
209 params.Remove(param);
211 params.SetInteger(param, val);
224 RtUString groupingMembership;
225 if (other.GetString(RixStr.k_grouping_membership, groupingMembership)) {
226 params.SetString(RixStr.k_grouping_membership, groupingMembership);
232 for (
const RtUString& param : _GetLightLinkParams()) {
238 void SetVisibility(
bool visible) {
240 for (
const RtUString& param : _GetVisibilityParams()) {
241 params.Remove(param);
244 for (
const RtUString& param : _GetVisibilityParams()) {
245 params.SetInteger(param, 0);
251 bool operator==(
const _FlattenData& rhs)
const noexcept
253 return categories == rhs.categories &&
254 _RtParamListEqualToFunctor()(params, rhs.params);
258 size_t operator()(
const _FlattenData& fd)
const noexcept
263 for (
const TfToken& tok : fd.categories) {
266 return hash ^ _RtParamListHashFunctor()(fd.params);
271 static std::vector<RtUString> _GetLightLinkParams()
275 static const std::vector<RtUString> LightLinkParams = {
276 RixStr.k_lightfilter_subset,
277 RixStr.k_lighting_subset,
278 RixStr.k_grouping_membership,
279 RixStr.k_lighting_excludesubset
281 return LightLinkParams;
284 static std::vector<RtUString> _GetVisibilityParams()
288 static const std::vector<RtUString> VisParams = {
289 RixStr.k_visibility_camera,
290 RixStr.k_visibility_indirect,
291 RixStr.k_visibility_transmission
300 _FlattenData flattenData;
302 _GfMatrixSA transform;
306 const VtTokenArray& cats,
308 const RtParamList& p,
327 typename Hash = std::hash<Key>,
328 typename KeyEqual = std::equal_to<Key>>
334 bool has(
const Key& key)
const
336 tbb::spin_rw_mutex::scoped_lock lock(_mutex,
false);
337 if (_map.size() == 0) {
return false; }
338 return _map.find(key) != _map.end();
344 T& get(
const Key& key)
346 static_assert(std::is_default_constructible<T>::value,
347 "T must be default constructible");
349 tbb::spin_rw_mutex::scoped_lock lock(_mutex,
false);
350 auto it = _map.find(key);
351 if (it == _map.end()) {
353 std::piecewise_construct,
354 std::forward_as_tuple(key),
355 std::tuple<>{}).first;
362 bool set(
const Key& key, T& val)
364 static_assert(std::is_copy_assignable<T>::value,
365 "T must be copy-assignable");
367 tbb::spin_rw_mutex::scoped_lock lock(_mutex,
false);
368 if (_map.size() > 0) {
369 auto it = _map.find(key);
370 if (it != _map.end()) {
375 _map.insert({key, val});
380 void iterate(std::function<
void(
const Key&, T&)> fn)
383 tbb::spin_rw_mutex::scoped_lock lock(_mutex,
true);
384 for (std::pair<const Key, T>& p : _map) {
385 fn(p.first, p.second);
390 void citerate(std::function<
void(
const Key&,
const T&)> fn)
const
392 tbb::spin_rw_mutex::scoped_lock lock(_mutex,
false);
393 for (
const std::pair<const Key, const T>& p : _map) {
394 fn(p.first, p.second);
401 tbb::spin_rw_mutex::scoped_lock lock(_mutex,
false);
406 void erase(
const Key& key)
409 tbb::spin_rw_mutex::scoped_lock lock(_mutex,
true);
410 _map.unsafe_erase(key);
417 tbb::spin_rw_mutex::scoped_lock lock(_mutex,
true);
421 tbb::concurrent_unordered_map<Key, T, Hash, KeyEqual> _map;
422 mutable tbb::spin_rw_mutex _mutex;
425 using _LockingFlattenGroupMap = _LockingMap<
427 riley::GeometryPrototypeId,
428 _FlattenData::HashFunctor>;
430 struct _RileyInstanceId
432 riley::GeometryPrototypeId groupId;
433 riley::GeometryInstanceId geoInstanceId;
434 riley::LightInstanceId lightInstanceId;
437 using _InstanceIdVec = std::vector<_RileyInstanceId>;
441 size_t operator()(
const riley::GeometryPrototypeId&
id)
const noexcept
443 return std::hash<uint32_t>()(
id.AsUInt32());
447 using _ProtoInstMap = std::unordered_map<
448 riley::GeometryPrototypeId,
452 using _LockingProtoGroupCounterMap = _LockingMap<
453 riley::GeometryPrototypeId,
457 struct _ProtoMapEntry
463 using _LockingProtoMap = _LockingMap<SdfPath, _ProtoMapEntry, SdfPath::Hash>;
470 void _SyncPrimvars(HdDirtyBits* dirtyBits);
473 void _SyncTransforms(HdDirtyBits* dirtyBits);
476 void _SyncCategories(HdDirtyBits* dirtyBits);
479 void _SyncVisibility(HdDirtyBits* dirtyBits);
483 void _ComposeInstances(
485 const std::vector<_InstanceData>& subInstances,
486 std::vector<_InstanceData>& instances);
491 void _ComposeInstanceFlattenData(
492 const size_t instanceId,
493 RtParamList& instanceParams,
495 const _FlattenData& fromBelow = _FlattenData());
502 void _ComposePrototypeData(
504 const RtParamList& globalProtoParams,
506 const std::vector<riley::GeometryPrototypeId>& protoIds,
507 const SdfPathVector& subProtoPaths,
508 const std::vector<_FlattenData>& subProtoFlats,
509 std::vector<RtParamList>& protoParams,
510 std::vector<_FlattenData>& protoFlats,
511 std::vector<TfToken>& protoRenderTags);
517 bool _RemoveDeadInstances(
519 const SdfPath& prototypePrimPath,
520 const std::vector<riley::GeometryPrototypeId>& protoIds);
524 void _SetPrototypesDirty();
532 void _PopulateInstances(
534 HdDirtyBits* dirtyBits,
535 const SdfPath& hydraPrototypeId,
536 const SdfPath& prototypePrimPath,
537 const std::vector<riley::GeometryPrototypeId>& rileyPrototypeIds,
538 const riley::CoordinateSystemList& coordSysList,
539 const RtParamList protoParams,
541 const std::vector<riley::MaterialId>& rileyMaterialIds,
542 const SdfPathVector& prototypePaths,
543 const riley::LightShaderId& lightShaderId,
544 const std::vector<_InstanceData>& subInstances,
545 const std::vector<_FlattenData>& prototypeFlats);
552 void _PopulateInstancesFromChild(
554 HdDirtyBits* dirtyBits,
555 const SdfPath& hydraPrototypeId,
556 const SdfPath& prototypePrimPath,
557 const std::vector<riley::GeometryPrototypeId>& rileyPrototypeIds,
558 const riley::CoordinateSystemList& coordSysList,
559 const RtParamList protoParams,
561 const std::vector<riley::MaterialId>& rileyMaterialIds,
562 const SdfPathVector& prototypePaths,
563 const riley::LightShaderId& lightShaderId,
564 const std::vector<_InstanceData>& subInstances,
565 const std::vector<_FlattenData>& prototypeFlats);
568 HdPrmanInstancer* _GetParentInstancer();
573 void _ResizeProtoMap(
575 const SdfPath& prototypePrimPath,
576 const std::vector<riley::GeometryPrototypeId>& rileyPrototypeIds,
577 const size_t newSize);
581 bool _CleanDisusedGroupIds(HdPrman_RenderParam* param);
586 bool _AcquireGroupId(
587 HdPrman_RenderParam* param,
588 const _FlattenData& flattenGroup,
589 riley::GeometryPrototypeId& groupId);
593 void _GetInstanceParams(
594 const size_t instanceIndex,
595 RtParamList& params);
598 void _GetPrototypeParams(
605 void _GetInstanceTransform(
606 const size_t instanceIndex,
608 const _GfMatrixSA& left = _GfMatrixSA());
625 riley::CoordinateSystemList _coordSysList = { 0,
nullptr };
629 std::vector<VtTokenArray> _instanceCategories;
632 _FlattenData _instancerFlat;
635 TfHashMap<TfToken, _PrimvarValue, TfToken::HashFunctor> _primvarMap;
644 _LockingFlattenGroupMap _groupMap;
648 _LockingProtoGroupCounterMap _groupCounters;
653 tbb::spin_rw_mutex _groupIdAcquisitionLock;
664 _LockingProtoMap _protoMap;
670 _LockingMap<SdfPath, tbb::spin_rw_mutex, SdfPath::Hash> _childPopulateLocks;
673PXR_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...