24 #ifndef EXT_RMANPKG_24_0_PLUGIN_RENDERMAN_PLUGIN_HD_PRMAN_GPRIM_H
25 #define EXT_RMANPKG_24_0_PLUGIN_RENDERMAN_PLUGIN_HD_PRMAN_GPRIM_H
28 #include "pxr/imaging/hd/enums.h"
33 #include "hdPrman/context.h"
34 #include "hdPrman/instancer.h"
35 #include "hdPrman/material.h"
36 #include "hdPrman/renderParam.h"
37 #include "hdPrman/renderPass.h"
38 #include "hdPrman/rixStrings.h"
41 #include "RixShadingUtils.h"
42 #include "RixPredefinedStrings.hpp"
44 PXR_NAMESPACE_OPEN_SCOPE
48 template <
typename BASE>
51 typedef BASE BaseType;
63 HdPrman_Context *context =
64 static_cast<HdPrman_RenderParam*
>(renderParam)->AcquireContext();
66 riley::Riley *riley = context->riley;
69 context->ReleaseCoordSysBindings(BASE::GetId());
72 for (
const auto &
id: _instanceIds) {
73 if (
id != riley::GeometryInstanceId::InvalidId()) {
74 riley->DeleteGeometryInstance(
75 riley::GeometryPrototypeId::InvalidId(),
id);
79 for (
const auto &
id: _prototypeIds) {
80 if (
id != riley::GeometryPrototypeId::InvalidId()) {
81 riley->DeleteGeometryPrototype(
id);
84 _prototypeIds.clear();
89 HdDirtyBits* dirtyBits,
90 TfToken const &reprToken)
override;
93 HdDirtyBits GetInitialDirtyBitsMask()
const override = 0;
96 _PropagateDirtyBits(HdDirtyBits bits)
const override
103 return bits ? (bits | GetInitialDirtyBitsMask()) : bits;
107 _InitRepr(
TfToken const &reprToken,
108 HdDirtyBits *dirtyBits)
override
117 virtual riley::MaterialId
118 _GetFallbackMaterial(HdPrman_Context *context)
120 return context->fallbackMaterial;
124 virtual RtPrimVarList
125 _ConvertGeometry(HdPrman_Context *context,
129 std::vector<HdGeomSubset> *geomSubsets) = 0;
136 std::vector<riley::GeometryPrototypeId> _prototypeIds;
137 std::vector<riley::GeometryInstanceId> _instanceIds;
140 template <
typename BASE>
144 HdDirtyBits* dirtyBits,
148 HF_MALLOC_TAG_FUNCTION();
151 HdPrman_Context *context =
152 static_cast<HdPrman_RenderParam*
>(renderParam)->AcquireContext();
155 BASE::_UpdateInstancer(sceneDelegate, dirtyBits);
158 SdfPath const&
id = BASE::GetId();
159 SdfPath const& instancerId = BASE::GetInstancerId();
160 const bool isHdInstance = !instancerId.
IsEmpty();
165 const int32_t primId = BASE::GetPrimId() + 1;
172 riley::Riley *riley = context->riley;
175 if (*dirtyBits & HdChangeTracker::DirtyMaterialId) {
176 #if HD_API_VERSION < 37
177 BASE::_SetMaterialId(sceneDelegate->
GetRenderIndex().GetChangeTracker(),
183 riley::MaterialId materialId = _GetFallbackMaterial(context);
184 riley::DisplacementId dispId = riley::DisplacementId::InvalidId();
185 const SdfPath & hdMaterialId = BASE::GetMaterialId();
186 HdPrman_ResolveMaterial(sceneDelegate, hdMaterialId, &materialId, &dispId);
189 riley::CoordinateSystemList coordSysList = {0,
nullptr};
190 if (HdPrman_Context::RileyCoordSysIdVecRefPtr convertedCoordSys =
191 context->ConvertAndRetainCoordSysBindings(sceneDelegate,
id)) {
192 coordSysList.count = convertedCoordSys->size();
193 coordSysList.ids = &(*convertedCoordSys)[0];
198 const int prmanPrimvarBits =
199 HdChangeTracker::DirtyPrimvar;
200 const int prmanAttrBits =
201 HdChangeTracker::DirtyVisibility |
202 HdChangeTracker::DirtyTransform;
207 std::vector<riley::MaterialId> subsetMaterialIds;
210 HdGeomSubsets geomSubsets;
211 RtPrimVarList primvars = _ConvertGeometry(context, sceneDelegate,
id,
212 &primType, &geomSubsets);
215 const size_t oldCount = _prototypeIds.size();
216 const size_t newCount = std::max((
size_t) 1, geomSubsets.size());
217 if (newCount != oldCount) {
218 for (
const auto &oldPrototypeId: _prototypeIds) {
219 if (oldPrototypeId != riley::GeometryPrototypeId::InvalidId()) {
220 riley->DeleteGeometryPrototype(oldPrototypeId);
223 _prototypeIds.resize(newCount,
224 riley::GeometryPrototypeId::InvalidId());
228 if (geomSubsets.empty()) {
232 if (_prototypeIds[0] == riley::GeometryPrototypeId::InvalidId()) {
234 riley->CreateGeometryPrototype(riley::UserId::DefaultId(),
237 }
else if (*dirtyBits & prmanPrimvarBits) {
238 riley->ModifyGeometryPrototype(primType, _prototypeIds[0],
246 subsetMaterialIds.reserve(geomSubsets.size());
247 for (
size_t j=0; j < geomSubsets.size(); ++j) {
248 auto& prototypeId = _prototypeIds[j];
251 std::vector<int32_t> int32Indices(subset.
indices.begin(),
253 primvars.SetIntegerArray(RixStr.k_shade_faceset,
255 int32Indices.size());
257 riley::MaterialId subsetMaterialId = materialId;
258 riley::DisplacementId subsetDispId = dispId;
262 HdPrman_ResolveMaterial(sceneDelegate, subset.
materialId,
263 &subsetMaterialId, &subsetDispId);
264 subsetMaterialIds.push_back(subsetMaterialId);
265 if (prototypeId == riley::GeometryPrototypeId::InvalidId()) {
267 riley->CreateGeometryPrototype(
268 riley::UserId::DefaultId(),
269 primType, dispId, primvars);
270 }
else if (*dirtyBits & prmanPrimvarBits) {
271 riley->ModifyGeometryPrototype(primType, prototypeId,
282 RtParamList attrs = context->ConvertAttributes(sceneDelegate,
id);
287 for (
size_t i=0; i < xf.count; ++i) {
288 xf_rt[i] = HdPrman_GfMatrixToRtMatrix(xf.values[i]);
290 const riley::Transform xform = {
298 attrs.SetInteger(RixStr.k_identifier_id, primId);
299 attrs.SetInteger(RixStr.k_identifier_id2, 0);
301 const size_t newNumHdInstances = 1u;
302 const size_t oldCount = _instanceIds.size();
303 const size_t newCount = newNumHdInstances * _prototypeIds.size();
304 if (newCount != oldCount) {
305 for (
const auto &oldInstanceId: _instanceIds) {
306 if (oldInstanceId != riley::GeometryInstanceId::InvalidId()) {
307 riley->DeleteGeometryInstance(
308 riley::GeometryPrototypeId::InvalidId(), oldInstanceId);
313 riley::GeometryInstanceId::InvalidId());
317 TF_VERIFY(_instanceIds.size() == _prototypeIds.size());
318 for (
size_t j=0; j < _prototypeIds.size(); ++j) {
319 auto const& prototypeId = _prototypeIds[j];
320 auto& instanceId = _instanceIds[j];
321 auto instanceMaterialId = materialId;
323 if (!subsetMaterialIds.empty()) {
325 instanceMaterialId = subsetMaterialIds[j];
327 if (instanceId == riley::GeometryInstanceId::InvalidId()) {
328 instanceId = riley->CreateGeometryInstance(
329 riley::UserId::DefaultId(),
330 riley::GeometryPrototypeId::InvalidId(),
331 prototypeId, instanceMaterialId, coordSysList,
333 }
else if (*dirtyBits & prmanAttrBits) {
334 riley->ModifyGeometryInstance(
335 riley::GeometryPrototypeId::InvalidId(),
336 instanceId, &instanceMaterialId, &coordSysList,
346 HdInstancer::_SyncInstancerAndParents(renderIndex, instancerId);
348 HdPrmanInstancer *instancer =
static_cast<HdPrmanInstancer*
>(
350 VtIntArray instanceIndices =
355 instancer->SampleInstanceTransforms(
id, instanceIndices, &ixf);
361 const size_t newNumHdInstances =
362 (ixf.count > 0) ? ixf.values[0].size() : 0;
363 const size_t oldCount = _instanceIds.size();
364 const size_t newCount = newNumHdInstances * _prototypeIds.size();
365 if (newCount != oldCount) {
366 for (
const auto &oldInstanceId: _instanceIds) {
367 riley->DeleteGeometryInstance(
368 riley::GeometryPrototypeId::InvalidId(),
371 _instanceIds.resize(newCount,
372 riley::GeometryInstanceId::InvalidId());
376 attrs.SetInteger(RixStr.k_identifier_id, primId);
379 std::vector<VtArray<TfToken>> instanceCategories =
383 for (
size_t i=0; i < newNumHdInstances; ++i) {
385 size_t instanceIndex = 0;
386 if (i < instanceIndices.size()) {
387 instanceIndex = instanceIndices[i];
391 RtParamList instanceAttrs = attrs;
392 instancer->GetInstancePrimvars(
id, instanceIndex, instanceAttrs);
394 instanceAttrs.SetInteger(RixStr.k_identifier_id2, i);
397 if (instanceIndex < instanceCategories.size()) {
398 context->ConvertCategoriesToAttributes(
399 id, instanceCategories[instanceIndex], instanceAttrs);
409 (xf.count == 1 && (xf.values[0] ==
GfMatrix4d(1)))) {
411 for (
size_t j=0; j < ixf.count; ++j) {
412 rt_xf[j] = HdPrman_GfMatrixToRtMatrix(ixf.values[j][i]);
416 for (
size_t j=0; j < ixf.count; ++j) {
419 HdPrman_GfMatrixToRtMatrix(xf_j * ixf.values[j][i]);
422 const riley::Transform xform =
423 { unsigned(ixf.count), rt_xf.data(), ixf.times.
data() };
427 for (
size_t j=0; j < _prototypeIds.size(); ++j) {
428 auto const& prototypeId = _prototypeIds[j];
429 auto& instanceId = _instanceIds[i*_prototypeIds.size() + j];
430 auto instanceMaterialId = materialId;
432 if (!subsetMaterialIds.empty()) {
434 instanceMaterialId = subsetMaterialIds[j];
436 if (instanceId == riley::GeometryInstanceId::InvalidId()) {
437 instanceId = riley->CreateGeometryInstance(
438 riley::UserId::DefaultId(),
439 riley::GeometryPrototypeId::InvalidId(),
440 prototypeId, instanceMaterialId, coordSysList,
441 xform, instanceAttrs);
442 }
else if (*dirtyBits & prmanAttrBits) {
443 riley->ModifyGeometryInstance(
444 riley::GeometryPrototypeId::InvalidId(),
445 instanceId, &instanceMaterialId, &coordSysList,
446 &xform, &instanceAttrs);
454 PXR_NAMESPACE_CLOSE_SCOPE
456 #endif // EXT_RMANPKG_24_0_PLUGIN_RENDERMAN_PLUGIN_HD_PRMAN_GPRIM_H
The Hydra render index is a flattened representation of the client scene graph, which may be composed...
Tracks changes from the HdSceneDelegate, providing invalidation cues to the render engine...
This is a small-vector class with local storage optimization, the local storage can be specified via ...
HD_API HdInstancer * GetInstancer(SdfPath const &id) const
Returns the instancer of id.
value_type * data()
Direct access to the underlying array.
virtual HD_API SdfPath GetMaterialId(SdfPath const &rprimId)
Returns the material ID bound to the rprim rprimId.
virtual HD_API std::vector< VtArray< TfToken > > GetInstanceCategories(SdfPath const &instancerId)
Returns the categories for all instances in the instancer.
The HdRenderParam is an opaque (to core Hydra) handle, to an object that is obtained from the render ...
TYPE Resample(float u) const
Convience method for invoking HdResampleRawTimeSamples on this HdTimeSampleArray. ...
#define TF_UNUSED(x)
Stops compiler from producing unused argument or variable warnings.
Token for efficient comparison, assignment, and hashing of known strings.
virtual HD_API size_t SampleTransform(SdfPath const &id, size_t maxSampleCount, float *sampleTimes, GfMatrix4d *sampleValues)
Store up to maxSampleCount transform samples in *sampleValues.
Stores a 4x4 matrix of double elements.
#define TF_VERIFY(cond, format,...)
Checks a condition and reports an error if it evaluates false.
Adapter class providing data exchange with the client scene graph.
A mix-in template that adds shared gprim behavior to support various HdRprim types.
A path value used to locate objects in layers or scenegraphs.
VtIntArray indices
The list of element indices contained in the subset.
SdfPath materialId
The path used to identify this material bound to the subset.
virtual HD_API VtIntArray GetInstanceIndices(SdfPath const &instancerId, SdfPath const &prototypeId)
Gets the extracted indices array of the prototype id used in the instancer.
bool IsEmpty() const noexcept
Returns true if this is the empty path (SdfPath::EmptyPath()).
HdRenderIndex & GetRenderIndex()
Returns the RenderIndex owned by this delegate.
Describes a subset of a piece of geometry as a set of indices.