7#ifndef EXT_RMANPKG_PLUGIN_RENDERMAN_PLUGIN_HD_PRMAN_INSTANCER_H
8#define EXT_RMANPKG_PLUGIN_RENDERMAN_PLUGIN_HD_PRMAN_INSTANCER_H
10#include "hdPrman/renderParam.h"
11#include "hdPrman/rixStrings.h"
13#include "pxr/imaging/hd/instancer.h"
14#include "pxr/imaging/hd/sceneDelegate.h"
15#include "pxr/imaging/hd/timeSampleArray.h"
16#include "pxr/imaging/hd/types.h"
18#include "pxr/usd/sdf/path.h"
21#include "pxr/base/tf/hashmap.h"
24#include "pxr/base/vt/value.h"
30#include <RiTypesHelper.h>
32#include <tbb/concurrent_unordered_map.h>
33#include <tbb/spin_rw_mutex.h>
41#include <unordered_map>
42#include <unordered_set>
46#define HDPRMAN_INSTANCER_MAX_TIME_SAMPLES 1
48PXR_NAMESPACE_OPEN_SCOPE
62 HdDirtyBits *dirtyBits)
override;
66 HdDirtyBits GetInitialDirtyBitsMask()
const override;
117 HdDirtyBits* dirtyBits,
118 const SdfPath& hydraPrototypeId,
119 const std::vector<riley::GeometryPrototypeId>& rileyPrototypeIds,
120 const riley::CoordinateSystemList& coordSysList,
121 const RtParamList& prototypeParams,
124 const std::vector<riley::MaterialId>& rileyMaterialIds,
125 const SdfPathVector& prototypePaths,
126 const riley::LightShaderId& lightShaderId = riley::LightShaderId::InvalidId());
144 const SdfPath& prototypePrimPath,
145 const std::vector<riley::GeometryPrototypeId>& excludedPrototypeIds = {});
158 struct _RtParamListHashFunctor
160 size_t operator()(
const RtParamList& params)
const noexcept
163 RtParamList copy = params;
164 return std::hash<uint32_t>()(copy.Hash());
168 struct _RtParamListEqualToFunctor
170 bool operator()(
const RtParamList& lhs,
const RtParamList& rhs)
const noexcept
172 return _RtParamListHashFunctor()(lhs) == _RtParamListHashFunctor()(rhs);
186 std::unordered_set<TfToken, TfToken::HashFunctor> categories;
194 _FlattenData() =
default;
195 _FlattenData(
const VtTokenArray& cats)
196 : categories(cats.begin(), cats.end()) { }
197 _FlattenData(
const VtTokenArray& cats,
bool vis)
198 : categories(cats.begin(), cats.end())
203 _FlattenData(
const _FlattenData& other)
204 : categories(other.categories.cbegin(), other.categories.cend())
206 params.Update(other.params);
211 void Inherit(
const _FlattenData& rhs)
213 categories.insert(rhs.categories.cbegin(), rhs.categories.cend());
214 params.Inherit(rhs.params);
219 void Update(
const _FlattenData& rhs)
221 categories.insert(rhs.categories.cbegin(), rhs.categories.cend());
222 params.Update(rhs.params);
228 void UpdateVisAndFilterParamList(RtParamList& other) {
230 for (
const RtUString& param : _GetVisibilityParams()) {
232 if (other.GetInteger(param, val)) {
234 params.Remove(param);
236 params.SetInteger(param, val);
249 RtUString groupingMembership;
250 if (other.GetString(RixStr.k_grouping_membership, groupingMembership)) {
251 params.SetString(RixStr.k_grouping_membership, groupingMembership);
257 for (
const RtUString& param : _GetLightLinkParams()) {
263 void SetVisibility(
bool visible) {
265 for (
const RtUString& param : _GetVisibilityParams()) {
266 params.Remove(param);
269 for (
const RtUString& param : _GetVisibilityParams()) {
270 params.SetInteger(param, 0);
276 bool operator==(
const _FlattenData& rhs)
const noexcept
278 return categories == rhs.categories &&
279 _RtParamListEqualToFunctor()(params, rhs.params);
283 size_t operator()(
const _FlattenData& fd)
const noexcept
288 for (
const TfToken& tok : fd.categories) {
291 return hash ^ _RtParamListHashFunctor()(fd.params);
296 static std::vector<RtUString> _GetLightLinkParams()
300 static const std::vector<RtUString> LightLinkParams = {
301 RixStr.k_lightfilter_subset,
302 RixStr.k_lighting_subset,
303 RixStr.k_grouping_membership,
304 RixStr.k_lighting_excludesubset
306 return LightLinkParams;
309 static std::vector<RtUString> _GetVisibilityParams()
313 static const std::vector<RtUString> VisParams = {
314 RixStr.k_visibility_camera,
315 RixStr.k_visibility_indirect,
316 RixStr.k_visibility_transmission
325 _FlattenData flattenData;
327 _GfMatrixSA transform;
329 _InstanceData() =
default;
330 _InstanceData(
const RtParamList& p,
const _GfMatrixSA& xform)
348 typename Hash = std::hash<Key>,
349 typename KeyEqual = std::equal_to<Key>>
355 bool has(
const Key& key)
const
357 tbb::spin_rw_mutex::scoped_lock lock(_mutex,
false);
358 if (_map.size() == 0) {
return false; }
359 return _map.find(key) != _map.end();
365 T& get(
const Key& key)
367 static_assert(std::is_default_constructible<T>::value,
368 "T must be default constructible");
370 tbb::spin_rw_mutex::scoped_lock lock(_mutex,
false);
371 auto it = _map.find(key);
372 if (it == _map.end()) {
374 std::piecewise_construct,
375 std::forward_as_tuple(key),
376 std::tuple<>{}).first;
383 bool set(
const Key& key, T& val)
385 static_assert(std::is_copy_assignable<T>::value,
386 "T must be copy-assignable");
388 tbb::spin_rw_mutex::scoped_lock lock(_mutex,
false);
389 if (_map.size() > 0) {
390 auto it = _map.find(key);
391 if (it != _map.end()) {
396 _map.insert({key, val});
401 void iterate(std::function<
void(
const Key&, T&)> fn)
404 tbb::spin_rw_mutex::scoped_lock lock(_mutex,
true);
405 for (std::pair<const Key, T>& p : _map) {
406 fn(p.first, p.second);
411 void citerate(std::function<
void(
const Key&,
const T&)> fn)
const
413 tbb::spin_rw_mutex::scoped_lock lock(_mutex,
false);
414 for (
const auto& p : _map) {
415 fn(p.first, p.second);
422 tbb::spin_rw_mutex::scoped_lock lock(_mutex,
false);
427 void erase(
const Key& key)
430 tbb::spin_rw_mutex::scoped_lock lock(_mutex,
true);
431 _map.unsafe_erase(key);
438 tbb::spin_rw_mutex::scoped_lock lock(_mutex,
true);
442 tbb::concurrent_unordered_map<Key, T, Hash, KeyEqual> _map;
443 mutable tbb::spin_rw_mutex _mutex;
446 using _LockingFlattenGroupMap = _LockingMap<
448 riley::GeometryPrototypeId,
449 _FlattenData::HashFunctor>;
451 struct _RileyInstanceId
453 riley::GeometryPrototypeId groupId;
454 riley::GeometryInstanceId geoInstanceId;
455 riley::LightInstanceId lightInstanceId;
458 using _InstanceIdVec = std::vector<_RileyInstanceId>;
462 size_t operator()(
const riley::GeometryPrototypeId&
id)
const noexcept
464 return std::hash<uint32_t>()(
id.AsUInt32());
468 using _ProtoInstMap = std::unordered_map<
469 riley::GeometryPrototypeId,
473 using _LockingProtoGroupCounterMap = _LockingMap<
474 riley::GeometryPrototypeId,
478 struct _ProtoMapEntry
484 using _LockingProtoMap = _LockingMap<SdfPath, _ProtoMapEntry, SdfPath::Hash>;
491 void _SyncPrimvars(
const HdDirtyBits* dirtyBits);
494 void _SyncTransforms(
const HdDirtyBits* dirtyBits, HdPrman_RenderParam *);
497 void _SyncCategories(
const HdDirtyBits* dirtyBits);
500 void _SyncVisibility(
const HdDirtyBits* dirtyBits);
504 void _ComposeInstances(
506 const std::vector<_InstanceData>& subInstances,
507 std::vector<_InstanceData>& instances);
512 void _ComposeInstanceFlattenData(
514 RtParamList& instanceParams,
516 const _FlattenData& fromBelow = _FlattenData());
523 void _ComposePrototypeData(
525 const RtParamList& globalProtoParams,
527 const std::vector<riley::GeometryPrototypeId>& protoIds,
528 const SdfPathVector& subProtoPaths,
529 const std::vector<_FlattenData>& subProtoFlats,
530 std::vector<RtParamList>& protoParams,
531 std::vector<_FlattenData>& protoFlats,
532 std::vector<TfToken>& protoRenderTags);
538 bool _RemoveDeadInstances(
540 const SdfPath& prototypePrimPath,
541 const std::vector<riley::GeometryPrototypeId>& protoIds);
545 void _SetPrototypesDirty();
553 void _PopulateInstances(
555 HdDirtyBits* dirtyBits,
556 const SdfPath& hydraPrototypeId,
557 const SdfPath& prototypePrimPath,
558 const std::vector<riley::GeometryPrototypeId>& rileyPrototypeIds,
559 const riley::CoordinateSystemList& coordSysList,
560 const RtParamList& prototypeParams,
563 const std::vector<riley::MaterialId>& rileyMaterialIds,
564 const SdfPathVector& prototypePaths,
565 const riley::LightShaderId& lightShaderId,
566 const std::vector<_InstanceData>& subInstances,
567 const std::vector<_FlattenData>& prototypeFlats);
574 void _PopulateInstancesFromChild(
576 HdDirtyBits* dirtyBits,
577 const SdfPath& hydraPrototypeId,
578 const SdfPath& prototypePrimPath,
579 const std::vector<riley::GeometryPrototypeId>& rileyPrototypeIds,
580 const riley::CoordinateSystemList& coordSysList,
581 const RtParamList& prototypeParams,
584 const std::vector<riley::MaterialId>& rileyMaterialIds,
585 const SdfPathVector& prototypePaths,
586 const riley::LightShaderId& lightShaderId,
587 const std::vector<_InstanceData>& subInstances,
588 const std::vector<_FlattenData>& prototypeFlats);
591 HdPrmanInstancer* _GetParentInstancer();
596 void _ResizeProtoMap(
598 const SdfPath& prototypePrimPath,
599 const std::vector<riley::GeometryPrototypeId>& rileyPrototypeIds,
604 bool _CleanDisusedGroupIds(HdPrman_RenderParam* param);
609 bool _AcquireGroupId(
610 HdPrman_RenderParam* param,
611 const _FlattenData& flattenGroup,
612 riley::GeometryPrototypeId& groupId);
616 void _GetInstanceParams(
617 size_t instanceIndex,
618 RtParamList& params);
621 void _GetPrototypeParams(
628 void _GetInstanceTransform(
629 size_t instanceIndex,
631 const _GfMatrixSA& left = _GfMatrixSA());
648 riley::CoordinateSystemList _coordSysList = { 0,
nullptr };
652 std::vector<VtTokenArray> _instanceCategories;
655 _FlattenData _instancerFlat;
658 TfHashMap<TfToken, _PrimvarValue, TfToken::HashFunctor> _primvarMap;
667 _LockingFlattenGroupMap _groupMap;
671 _LockingProtoGroupCounterMap _groupCounters;
676 tbb::spin_rw_mutex _groupIdAcquisitionLock;
687 _LockingProtoMap _protoMap;
693 _LockingMap<SdfPath, tbb::spin_rw_mutex, SdfPath::Hash> _childPopulateLocks;
696PXR_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...