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" 32 #include "hdPrman/gprimbase.h" 33 #include "hdPrman/renderParam.h" 34 #include "hdPrman/instancer.h" 35 #include "hdPrman/material.h" 36 #include "hdPrman/rixStrings.h" 39 #include "RixShadingUtils.h" 40 #include "RixPredefinedStrings.hpp" 42 PXR_NAMESPACE_OPEN_SCOPE
46 template <
typename BASE>
50 using BaseType = BASE;
62 HdPrman_RenderParam *param =
63 static_cast<HdPrman_RenderParam*>(renderParam);
65 riley::Riley *riley = param->AcquireRiley();
68 param->ReleaseCoordSysBindings(BASE::GetId());
71 for (
const auto &
id: _instanceIds) {
72 if (
id != riley::GeometryInstanceId::InvalidId()) {
73 riley->DeleteGeometryInstance(
74 riley::GeometryPrototypeId::InvalidId(),
id);
78 for (
const auto &
id: _prototypeIds) {
79 if (
id != riley::GeometryPrototypeId::InvalidId()) {
80 riley->DeleteGeometryPrototype(
id);
83 _prototypeIds.clear();
88 HdDirtyBits* dirtyBits,
89 TfToken const &reprToken)
override;
92 HdDirtyBits GetInitialDirtyBitsMask()
const override = 0;
95 _PropagateDirtyBits(HdDirtyBits bits)
const override 102 return bits ? (bits | GetInitialDirtyBitsMask()) : bits;
106 _InitRepr(
TfToken const &reprToken,
107 HdDirtyBits *dirtyBits)
override 124 virtual riley::MaterialId
125 _GetFallbackMaterial(HdPrman_RenderParam *renderParam)
127 return renderParam->GetFallbackMaterialId();
131 virtual RtPrimVarList
132 _ConvertGeometry(HdPrman_RenderParam *renderParam,
136 std::vector<HdGeomSubset> *geomSubsets) = 0;
144 template <
typename BASE>
148 HdDirtyBits* dirtyBits,
152 HF_MALLOC_TAG_FUNCTION();
155 HdPrman_RenderParam *param =
156 static_cast<HdPrman_RenderParam*>(renderParam);
159 riley::Riley *riley = param->AcquireRiley();
162 BASE::_UpdateInstancer(sceneDelegate, dirtyBits);
165 SdfPath const&
id = BASE::GetId();
166 SdfPath const& instancerId = BASE::GetInstancerId();
167 const bool isHdInstance = !instancerId.
IsEmpty();
174 const int32_t primId = BASE::GetPrimId() + 1;
182 BASE::_UpdateVisibility(sceneDelegate, dirtyBits);
186 if (*dirtyBits & HdChangeTracker::DirtyMaterialId) {
187 #if HD_API_VERSION < 37 188 BASE::_SetMaterialId(sceneDelegate->
GetRenderIndex().GetChangeTracker(),
194 riley::MaterialId materialId = _GetFallbackMaterial(param);
195 riley::DisplacementId dispId = riley::DisplacementId::InvalidId();
196 const SdfPath & hdMaterialId = BASE::GetMaterialId();
197 HdPrman_ResolveMaterial(sceneDelegate, hdMaterialId, &materialId, &dispId);
200 riley::CoordinateSystemList coordSysList = {0,
nullptr};
201 if (HdPrman_RenderParam::RileyCoordSysIdVecRefPtr convertedCoordSys =
202 param->ConvertAndRetainCoordSysBindings(sceneDelegate,
id)) {
203 coordSysList.count = convertedCoordSys->size();
204 coordSysList.ids = convertedCoordSys->data();
209 const int prmanPrimvarBits =
210 HdChangeTracker::DirtyPrimvar;
211 const int prmanAttrBits =
212 HdChangeTracker::DirtyVisibility |
213 HdChangeTracker::DirtyTransform;
218 std::vector<riley::MaterialId> subsetMaterialIds;
219 std::vector<SdfPath> subsetPaths;
222 HdGeomSubsets geomSubsets;
223 RtPrimVarList primvars = _ConvertGeometry(param, sceneDelegate,
id,
224 &primType, &geomSubsets);
227 HdPrman_TransferMaterialPrimvarOpinions(sceneDelegate, hdMaterialId,
231 const size_t oldCount = _prototypeIds.size();
232 const size_t newCount = std::max((
size_t) 1, geomSubsets.size());
233 if (newCount != oldCount) {
234 for (
const auto &oldPrototypeId: _prototypeIds) {
235 if (oldPrototypeId != riley::GeometryPrototypeId::InvalidId()) {
236 riley->DeleteGeometryPrototype(oldPrototypeId);
239 _prototypeIds.resize(newCount,
240 riley::GeometryPrototypeId::InvalidId());
244 if (geomSubsets.empty()) {
248 if (_prototypeIds[0] == riley::GeometryPrototypeId::InvalidId()) {
249 _prototypeIds[0] = riley->CreateGeometryPrototype(
251 stats::AddDataLocation(primPath.
GetText()).GetValue()),
252 primType, dispId, primvars);
253 }
else if (*dirtyBits & prmanPrimvarBits) {
254 riley->ModifyGeometryPrototype(primType, _prototypeIds[0],
262 subsetMaterialIds.reserve(geomSubsets.size());
265 subsetPaths.reserve(geomSubsets.size());
267 for (
size_t j=0; j < geomSubsets.size(); ++j) {
268 auto& prototypeId = _prototypeIds[j];
272 std::vector<int32_t> int32Indices(subset.
indices.begin(),
274 primvars.SetIntegerArray(RixStr.k_shade_faceset,
276 int32Indices.size());
278 riley::MaterialId subsetMaterialId = materialId;
279 riley::DisplacementId subsetDispId = dispId;
283 HdPrman_ResolveMaterial(sceneDelegate, subset.
materialId,
284 &subsetMaterialId, &subsetDispId);
285 subsetMaterialIds.push_back(subsetMaterialId);
289 subsetPaths.push_back(subsetPath);
291 if (prototypeId == riley::GeometryPrototypeId::InvalidId()) {
293 riley->CreateGeometryPrototype(
295 stats::AddDataLocation(subsetPath.
GetText()).GetValue()),
296 primType, dispId, primvars);
297 }
else if (*dirtyBits & prmanPrimvarBits) {
298 riley->ModifyGeometryPrototype(primType, prototypeId,
308 if (_PrototypeOnly()) {
317 RtParamList attrs = param->ConvertAttributes(sceneDelegate,
id,
true);
322 for (
size_t i=0; i < xf.count; ++i) {
323 xf_rt[i] = HdPrman_GfMatrixToRtMatrix(xf.values[i]);
325 const riley::Transform xform = {
333 attrs.SetInteger(RixStr.k_identifier_id, primId);
334 attrs.SetInteger(RixStr.k_identifier_id2, 0);
336 const size_t newNumHdInstances = 1u;
337 const size_t oldCount = _instanceIds.size();
338 const size_t newCount = newNumHdInstances * _prototypeIds.size();
339 if (newCount != oldCount) {
340 for (
const auto &oldInstanceId: _instanceIds) {
341 if (oldInstanceId != riley::GeometryInstanceId::InvalidId()) {
342 riley->DeleteGeometryInstance(
343 riley::GeometryPrototypeId::InvalidId(), oldInstanceId);
348 riley::GeometryInstanceId::InvalidId());
353 TF_VERIFY(_instanceIds.size() == _prototypeIds.size());
354 for (
size_t j=0; j < _prototypeIds.size(); ++j) {
355 auto const& prototypeId = _prototypeIds[j];
356 auto& instanceId = _instanceIds[j];
357 auto instanceMaterialId = materialId;
360 SdfPath* subsetPath(&primPath);
361 if (!subsetPaths.empty()) {
362 subsetPath = &subsetPaths[j];
366 if (!subsetMaterialIds.empty()) {
368 instanceMaterialId = subsetMaterialIds[j];
371 if (instanceId == riley::GeometryInstanceId::InvalidId()) {
372 instanceId = riley->CreateGeometryInstance(
374 stats::AddDataLocation(subsetPath->
GetText()).GetValue()),
375 riley::GeometryPrototypeId::InvalidId(),
376 prototypeId, instanceMaterialId, coordSysList,
378 }
else if (*dirtyBits & prmanAttrBits) {
379 riley->ModifyGeometryInstance(
380 riley::GeometryPrototypeId::InvalidId(),
381 instanceId, &instanceMaterialId, &coordSysList,
391 HdInstancer::_SyncInstancerAndParents(renderIndex, instancerId);
393 HdPrmanInstancer *instancer = static_cast<HdPrmanInstancer*>(
395 VtIntArray instanceIndices =
400 instancer->SampleInstanceTransforms(
id, instanceIndices, &ixf);
406 const size_t newNumHdInstances =
407 (ixf.count > 0) ? ixf.values[0].size() : 0;
408 const size_t oldCount = _instanceIds.size();
409 const size_t newCount = newNumHdInstances * _prototypeIds.size();
410 if (newCount != oldCount) {
411 for (
const auto &oldInstanceId: _instanceIds) {
412 riley->DeleteGeometryInstance(
413 riley::GeometryPrototypeId::InvalidId(),
418 _instanceIds.clear();
419 _instanceIds.resize(newCount,
420 riley::GeometryInstanceId::InvalidId());
424 attrs.SetInteger(RixStr.k_identifier_id, primId);
427 std::vector<VtArray<TfToken>> instanceCategories =
431 for (
size_t i=0; i < newNumHdInstances; ++i) {
433 size_t instanceIndex = 0;
434 if (i < instanceIndices.size()) {
435 instanceIndex = instanceIndices[i];
439 RtParamList instanceAttrs = attrs;
440 instancer->GetInstancePrimvars(
id, instanceIndex, instanceAttrs);
442 instanceAttrs.SetInteger(RixStr.k_identifier_id2, i);
445 if (instanceIndex < instanceCategories.size()) {
446 param->ConvertCategoriesToAttributes(
447 id, instanceCategories[instanceIndex], instanceAttrs);
457 (xf.count == 1 && (xf.values[0] ==
GfMatrix4d(1)))) {
459 for (
size_t j=0; j < ixf.count; ++j) {
460 rt_xf[j] = HdPrman_GfMatrixToRtMatrix(ixf.values[j][i]);
464 for (
size_t j=0; j < ixf.count; ++j) {
467 HdPrman_GfMatrixToRtMatrix(xf_j * ixf.values[j][i]);
470 const riley::Transform xform =
471 { unsigned(ixf.count), rt_xf.data(), ixf.times.
data() };
475 for (
size_t j=0; j < _prototypeIds.size(); ++j) {
476 auto const& prototypeId = _prototypeIds[j];
477 auto& instanceId = _instanceIds[i*_prototypeIds.size() + j];
478 auto instanceMaterialId = materialId;
481 SdfPath* subsetPath(&primPath);
482 if (!subsetPaths.empty()) {
483 subsetPath = &subsetPaths[j];
487 if (!subsetMaterialIds.empty()) {
489 instanceMaterialId = subsetMaterialIds[j];
492 if (instanceId == riley::GeometryInstanceId::InvalidId()) {
497 instanceId = riley->CreateGeometryInstance(
499 stats::AddDataLocation(instancePath.
GetText())
501 riley::GeometryPrototypeId::InvalidId(), prototypeId,
502 instanceMaterialId, coordSysList, xform, instanceAttrs);
503 }
else if (*dirtyBits & prmanAttrBits) {
504 riley->ModifyGeometryInstance(
505 riley::GeometryPrototypeId::InvalidId(),
506 instanceId, &instanceMaterialId, &coordSysList,
507 &xform, &instanceAttrs);
515 PXR_NAMESPACE_CLOSE_SCOPE
517 #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 ...
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 ...
SDF_API const char * GetText() const
Returns the string representation of this path as a c string.
#define TF_UNUSED(x)
Stops compiler from producing unused argument or variable warnings.
A common base class for HdPrman_Gprim types.
Token for efficient comparison, assignment, and hashing of known strings.
HD_API HdInstancer * GetInstancer(SdfPath const &id) const
Returns the instancer of id.
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.
TYPE Resample(float u) const
Convience method for invoking HdResampleRawTimeSamples on this HdTimeSampleArray.
A path value used to locate objects in layers or scenegraphs.
VtIntArray indices
The list of element indices contained in the subset.
HD_API bool IsVisibilityDirty(SdfPath const &id)
Returns true if the rprim identified by id has dirty visibility.
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.
SdfPath id
The path used to identify this subset in the scene.
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.
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.