24#ifndef EXT_RMANPKG_25_0_PLUGIN_RENDERMAN_PLUGIN_HD_PRMAN_GPRIM_H
25#define EXT_RMANPKG_25_0_PLUGIN_RENDERMAN_PLUGIN_HD_PRMAN_GPRIM_H
31#include "hdPrman/gprimbase.h"
32#include "hdPrman/renderParam.h"
33#include "hdPrman/instancer.h"
34#include "hdPrman/material.h"
35#include "hdPrman/rixStrings.h"
36#include "hdPrman/utils.h"
40PXR_NAMESPACE_OPEN_SCOPE
44template <
typename BASE>
48 using BaseType = BASE;
60 HdPrman_RenderParam *param =
61 static_cast<HdPrman_RenderParam*
>(renderParam);
62 const SdfPath&
id = BASE::GetId();
63 riley::Riley *riley = param->AcquireRiley();
66 param->ReleaseCoordSysBindings(
id);
69 for (
const auto &instId: _instanceIds) {
70 if (instId != riley::GeometryInstanceId::InvalidId()) {
71 riley->DeleteGeometryInstance(
72 riley::GeometryPrototypeId::InvalidId(), instId);
78 if (HdPrmanInstancer* instancer = param->GetInstancer(
79 BASE::GetInstancerId())) {
80 instancer->Depopulate(renderParam,
id);
83 for (
const auto &protoId: _prototypeIds) {
84 if (protoId != riley::GeometryPrototypeId::InvalidId()) {
85 riley->DeleteGeometryPrototype(protoId);
88 _prototypeIds.clear();
93 HdDirtyBits* dirtyBits,
94 TfToken const &reprToken)
override;
97 HdDirtyBits GetInitialDirtyBitsMask()
const override = 0;
100 _PropagateDirtyBits(HdDirtyBits bits)
const override
107 _InitRepr(
TfToken const &reprToken,
108 HdDirtyBits *dirtyBits)
override
125 virtual riley::MaterialId
126 _GetFallbackMaterial(HdPrman_RenderParam *renderParam)
128 return renderParam->GetFallbackMaterialId();
132 virtual RtPrimVarList
133 _ConvertGeometry(HdPrman_RenderParam *renderParam,
137 std::vector<HdGeomSubset> *geomSubsets) = 0;
145template <
typename BASE>
149 HdDirtyBits* dirtyBits,
153 HF_MALLOC_TAG_FUNCTION();
156 HdPrman_RenderParam *param =
157 static_cast<HdPrman_RenderParam*
>(renderParam);
160 riley::Riley *riley = param->AcquireRiley();
163 BASE::_UpdateInstancer(sceneDelegate, dirtyBits);
166 SdfPath const&
id = BASE::GetId();
167 SdfPath const& instancerId = BASE::GetInstancerId();
168 const bool isHdInstance = !instancerId.
IsEmpty();
175 const int32_t primId = BASE::GetPrimId() + 1;
183 BASE::_UpdateVisibility(sceneDelegate, dirtyBits);
187 if (*dirtyBits & HdChangeTracker::DirtyMaterialId) {
188#if HD_API_VERSION < 37
189 BASE::_SetMaterialId(sceneDelegate->
GetRenderIndex().GetChangeTracker(),
195 riley::MaterialId materialId = _GetFallbackMaterial(param);
196 riley::DisplacementId dispId = riley::DisplacementId::InvalidId();
197 const SdfPath & hdMaterialId = BASE::GetMaterialId();
198 HdPrman_ResolveMaterial(sceneDelegate, hdMaterialId, riley, &materialId, &dispId);
201 riley::CoordinateSystemList coordSysList = {0,
nullptr};
202 if (HdPrman_RenderParam::RileyCoordSysIdVecRefPtr convertedCoordSys =
203 param->ConvertAndRetainCoordSysBindings(sceneDelegate,
id)) {
204 coordSysList.count = convertedCoordSys->size();
205 coordSysList.ids = convertedCoordSys->data();
211 static const int prmanProtoAttrBits =
212 HdChangeTracker::DirtyPoints |
213 HdChangeTracker::DirtyNormals |
214 HdChangeTracker::DirtyWidths |
215 HdChangeTracker::DirtyTopology;
219 static const int prmanInstAttrBits =
220 HdChangeTracker::DirtyMaterialId |
221 HdChangeTracker::DirtyTransform |
222 HdChangeTracker::DirtyVisibility |
223 HdChangeTracker::DirtyDoubleSided |
224 HdChangeTracker::DirtySubdivTags |
225 HdChangeTracker::DirtyVolumeField |
226 HdChangeTracker::DirtyCategories |
227 HdChangeTracker::DirtyPrimvar;
232 std::vector<riley::MaterialId> subsetMaterialIds;
233 std::vector<SdfPath> subsetPaths;
236 HdGeomSubsets geomSubsets;
237 RtPrimVarList primvars = _ConvertGeometry(param, sceneDelegate,
id,
238 &primType, &geomSubsets);
241 HdPrman_TransferMaterialPrimvarOpinions(sceneDelegate, hdMaterialId,
245 const size_t oldCount = _prototypeIds.size();
246 const size_t newCount = std::max((
size_t) 1, geomSubsets.size());
247 if (newCount != oldCount) {
248 for (
const auto &oldPrototypeId: _prototypeIds) {
249 if (oldPrototypeId != riley::GeometryPrototypeId::InvalidId()) {
250 riley->DeleteGeometryPrototype(oldPrototypeId);
253 _prototypeIds.resize(newCount,
254 riley::GeometryPrototypeId::InvalidId());
258 if (geomSubsets.empty()) {
262 primvars.SetString(RixStr.k_stats_prototypeIdentifier,
263 RtUString(primPath.
GetText()));
264 if (_prototypeIds[0] == riley::GeometryPrototypeId::InvalidId()) {
266 _prototypeIds[0] = riley->CreateGeometryPrototype(
268 stats::AddDataLocation(primPath.
GetText()).GetValue()),
269 primType, dispId, primvars);
270 }
else if (*dirtyBits & prmanProtoAttrBits) {
272 riley->ModifyGeometryPrototype(primType, _prototypeIds[0],
280 subsetMaterialIds.reserve(geomSubsets.size());
283 subsetPaths.reserve(geomSubsets.size());
285 for (
size_t j=0; j < geomSubsets.size(); ++j) {
286 auto& prototypeId = _prototypeIds[j];
290 std::vector<int32_t> int32Indices(subset.
indices.cbegin(),
292 primvars.SetIntegerArray(RixStr.k_shade_faceset,
294 int32Indices.size());
296 riley::MaterialId subsetMaterialId = materialId;
297 riley::DisplacementId subsetDispId = dispId;
301 HdPrman_ResolveMaterial(sceneDelegate, subset.
materialId,
302 riley, &subsetMaterialId, &subsetDispId);
303 subsetMaterialIds.push_back(subsetMaterialId);
307 subsetPaths.push_back(subsetPath);
308 primvars.SetString(RixStr.k_stats_prototypeIdentifier,
309 RtUString(subsetPath.
GetText()));
311 if (prototypeId == riley::GeometryPrototypeId::InvalidId()) {
314 riley->CreateGeometryPrototype(
316 stats::AddDataLocation(subsetPath.
GetText()).GetValue()),
317 primType, dispId, primvars);
318 }
else if (*dirtyBits & prmanProtoAttrBits) {
320 riley->ModifyGeometryPrototype(primType, prototypeId,
321 &subsetDispId, &primvars);
325 *dirtyBits &= ~prmanProtoAttrBits;
331 if (_PrototypeOnly()) {
341 bool sceneVisibility =
true;
342 RtParamList attrs = param->ConvertAttributes(sceneDelegate,
id,
true,
344 _sceneVisibility = sceneVisibility;
347 attrs.SetInteger(RixStr.k_identifier_id, primId);
353 for (
size_t i=0; i < xf.count; ++i) {
354 xf_rt[i] = HdPrman_Utils::GfMatrixToRtMatrix(xf.values[i]);
356 const riley::Transform xform = {
363 attrs.SetInteger(RixStr.k_identifier_id2, 0);
366 const size_t oldCount = _instanceIds.size();
367 const size_t newCount = _prototypeIds.size();
368 if (newCount != oldCount) {
369 for (
const auto &oldInstanceId: _instanceIds) {
370 if (oldInstanceId != riley::GeometryInstanceId::InvalidId()) {
371 riley->DeleteGeometryInstance(
372 riley::GeometryPrototypeId::InvalidId(), oldInstanceId);
377 riley::GeometryInstanceId::InvalidId());
382 TF_VERIFY(_instanceIds.size() == _prototypeIds.size());
383 for (
size_t j=0; j < _prototypeIds.size(); ++j) {
384 auto const& prototypeId = _prototypeIds[j];
385 auto& instanceId = _instanceIds[j];
386 auto instanceMaterialId = materialId;
387 RtParamList finalAttrs = attrs;
390 SdfPath* subsetPath(&primPath);
391 if (!subsetPaths.empty()) {
392 subsetPath = &subsetPaths[j];
395 finalAttrs.SetString(RixStr.k_identifier_name,
396 RtUString(subsetPath->
GetText()));
399 if (!subsetMaterialIds.empty()) {
401 instanceMaterialId = subsetMaterialIds[j];
404 if (instanceId == riley::GeometryInstanceId::InvalidId()) {
406 instanceId = riley->CreateGeometryInstance(
408 stats::AddDataLocation(subsetPath->
GetText()).GetValue()),
409 riley::GeometryPrototypeId::InvalidId(), prototypeId,
410 instanceMaterialId, coordSysList, xform, finalAttrs);
411 }
else if (*dirtyBits & prmanInstAttrBits) {
413 riley->ModifyGeometryInstance(
414 riley::GeometryPrototypeId::InvalidId(),
415 instanceId, &instanceMaterialId, &coordSysList, &xform,
419 *dirtyBits &= ~prmanInstAttrBits;
420 }
else if ((*dirtyBits & prmanInstAttrBits)
437 HdInstancer::_SyncInstancerAndParents(renderIndex, instancerId);
439 if (subsetMaterialIds.size() == 0) {
440 subsetMaterialIds.push_back(materialId);
442 if (subsetPaths.size() == 0) {
443 subsetPaths.push_back(primPath);
445 TF_VERIFY(_prototypeIds.size() == subsetMaterialIds.size() &&
446 _prototypeIds.size() == subsetPaths.size(),
447 "size mismatch (%lu, %lu, %lu)\n", _prototypeIds.size(),
448 subsetMaterialIds.size(), subsetPaths.size());
451 HdPrmanInstancer *instancer =
static_cast<HdPrmanInstancer*
>(
468PXR_NAMESPACE_CLOSE_SCOPE
Tracks changes from the HdSceneDelegate, providing invalidation cues to the render engine.
static HD_API bool IsInstancerDirty(HdDirtyBits dirtyBits, SdfPath const &id)
Returns true if the dirtyBits has a dirty instancer. id is for perflog.
HD_API bool IsVisibilityDirty(SdfPath const &id)
Returns true if the rprim identified by id has dirty visibility.
A common base class for HdPrman_Gprim types.
A mix-in template that adds shared gprim behavior to support various HdRprim types.
The Hydra render index is a flattened representation of the client scene graph, which may be composed...
HD_API HdInstancer * GetInstancer(SdfPath const &id) const
Returns the instancer of id.
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.
virtual HD_API SdfPath GetMaterialId(SdfPath const &rprimId)
Returns the material ID bound to the rprim rprimId.
virtual HD_API size_t SampleTransform(SdfPath const &id, size_t maxSampleCount, float *sampleTimes, GfMatrix4d *sampleValues)
Store up to maxSampleCount transform samples in *sampleValues.
HdRenderIndex & GetRenderIndex()
Returns the RenderIndex owned by this delegate.
virtual HD_API SdfPath GetScenePrimPath(SdfPath const &rprimId, int instanceIndex, HdInstancerContext *instancerContext=nullptr)
Returns the scene address of the prim corresponding to the given rprim/instance index.
A path value used to locate objects in layers or scenegraphs.
SDF_API const char * GetText() const
Returns the string representation of this path as a c string.
bool IsEmpty() const noexcept
Returns true if this is the empty path (SdfPath::EmptyPath()).
This is a small-vector class with local storage optimization, the local storage can be specified via ...
value_type * data()
Direct access to the underlying array.
Token for efficient comparison, assignment, and hashing of known strings.
#define TF_VERIFY(cond, format,...)
Checks a condition and reports an error if it evaluates false.
#define TF_UNUSED(x)
Stops compiler from producing unused argument or variable warnings.
Describes a subset of a piece of geometry as a set of indices.
VtIntArray indices
The list of element indices contained in the subset.
SdfPath id
The path used to identify this subset in the scene.
SdfPath materialId
The path used to identify this material bound to the subset.
An array of a value sampled over time, in struct-of-arrays layout.
#define TRACE_SCOPE(name)
Records a timestamp when constructed and a timespan event when destructed, using name as the key.