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 116 virtual riley::MaterialId
117 _GetFallbackMaterial(HdPrman_RenderParam *renderParam)
119 return renderParam->GetFallbackMaterialId();
123 virtual RtPrimVarList
124 _ConvertGeometry(HdPrman_RenderParam *renderParam,
128 std::vector<HdGeomSubset> *geomSubsets) = 0;
136 template <
typename BASE>
140 HdDirtyBits* dirtyBits,
144 HF_MALLOC_TAG_FUNCTION();
147 HdPrman_RenderParam *param =
148 static_cast<HdPrman_RenderParam*>(renderParam);
151 riley::Riley *riley = param->AcquireRiley();
154 BASE::_UpdateInstancer(sceneDelegate, dirtyBits);
157 SdfPath const&
id = BASE::GetId();
158 SdfPath const& instancerId = BASE::GetInstancerId();
159 const bool isHdInstance = !instancerId.
IsEmpty();
166 const int32_t primId = BASE::GetPrimId() + 1;
174 BASE::_UpdateVisibility(sceneDelegate, dirtyBits);
178 if (*dirtyBits & HdChangeTracker::DirtyMaterialId) {
179 #if HD_API_VERSION < 37 180 BASE::_SetMaterialId(sceneDelegate->
GetRenderIndex().GetChangeTracker(),
186 riley::MaterialId materialId = _GetFallbackMaterial(param);
187 riley::DisplacementId dispId = riley::DisplacementId::InvalidId();
188 const SdfPath & hdMaterialId = BASE::GetMaterialId();
189 HdPrman_ResolveMaterial(sceneDelegate, hdMaterialId, &materialId, &dispId);
192 riley::CoordinateSystemList coordSysList = {0,
nullptr};
193 if (HdPrman_RenderParam::RileyCoordSysIdVecRefPtr convertedCoordSys =
194 param->ConvertAndRetainCoordSysBindings(sceneDelegate,
id)) {
195 coordSysList.count = convertedCoordSys->size();
196 coordSysList.ids = convertedCoordSys->data();
201 const int prmanPrimvarBits =
202 HdChangeTracker::DirtyPrimvar;
203 const int prmanAttrBits =
204 HdChangeTracker::DirtyVisibility |
205 HdChangeTracker::DirtyTransform;
210 std::vector<riley::MaterialId> subsetMaterialIds;
211 std::vector<SdfPath> subsetPaths;
214 HdGeomSubsets geomSubsets;
215 RtPrimVarList primvars = _ConvertGeometry(param, sceneDelegate,
id,
216 &primType, &geomSubsets);
219 HdPrman_TransferMaterialPrimvarOpinions(sceneDelegate, hdMaterialId,
223 const size_t oldCount = _prototypeIds.size();
224 const size_t newCount = std::max((
size_t) 1, geomSubsets.size());
225 if (newCount != oldCount) {
226 for (
const auto &oldPrototypeId: _prototypeIds) {
227 if (oldPrototypeId != riley::GeometryPrototypeId::InvalidId()) {
228 riley->DeleteGeometryPrototype(oldPrototypeId);
231 _prototypeIds.resize(newCount,
232 riley::GeometryPrototypeId::InvalidId());
236 if (geomSubsets.empty()) {
240 if (_prototypeIds[0] == riley::GeometryPrototypeId::InvalidId()) {
241 _prototypeIds[0] = riley->CreateGeometryPrototype(
243 stats::AddDataLocation(primPath.
GetText()).GetValue()),
244 primType, dispId, primvars);
245 }
else if (*dirtyBits & prmanPrimvarBits) {
246 riley->ModifyGeometryPrototype(primType, _prototypeIds[0],
254 subsetMaterialIds.reserve(geomSubsets.size());
257 subsetPaths.reserve(geomSubsets.size());
259 for (
size_t j=0; j < geomSubsets.size(); ++j) {
260 auto& prototypeId = _prototypeIds[j];
264 std::vector<int32_t> int32Indices(subset.
indices.begin(),
266 primvars.SetIntegerArray(RixStr.k_shade_faceset,
268 int32Indices.size());
270 riley::MaterialId subsetMaterialId = materialId;
271 riley::DisplacementId subsetDispId = dispId;
275 HdPrman_ResolveMaterial(sceneDelegate, subset.
materialId,
276 &subsetMaterialId, &subsetDispId);
277 subsetMaterialIds.push_back(subsetMaterialId);
281 subsetPaths.push_back(subsetPath);
283 if (prototypeId == riley::GeometryPrototypeId::InvalidId()) {
285 riley->CreateGeometryPrototype(
287 stats::AddDataLocation(subsetPath.
GetText()).GetValue()),
288 primType, dispId, primvars);
289 }
else if (*dirtyBits & prmanPrimvarBits) {
290 riley->ModifyGeometryPrototype(primType, prototypeId,
301 RtParamList attrs = param->ConvertAttributes(sceneDelegate,
id);
306 for (
size_t i=0; i < xf.count; ++i) {
307 xf_rt[i] = HdPrman_GfMatrixToRtMatrix(xf.values[i]);
309 const riley::Transform xform = {
317 attrs.SetInteger(RixStr.k_identifier_id, primId);
318 attrs.SetInteger(RixStr.k_identifier_id2, 0);
320 const size_t newNumHdInstances = 1u;
321 const size_t oldCount = _instanceIds.size();
322 const size_t newCount = newNumHdInstances * _prototypeIds.size();
323 if (newCount != oldCount) {
324 for (
const auto &oldInstanceId: _instanceIds) {
325 if (oldInstanceId != riley::GeometryInstanceId::InvalidId()) {
326 riley->DeleteGeometryInstance(
327 riley::GeometryPrototypeId::InvalidId(), oldInstanceId);
332 riley::GeometryInstanceId::InvalidId());
337 TF_VERIFY(_instanceIds.size() == _prototypeIds.size());
338 for (
size_t j=0; j < _prototypeIds.size(); ++j) {
339 auto const& prototypeId = _prototypeIds[j];
340 auto& instanceId = _instanceIds[j];
341 auto instanceMaterialId = materialId;
344 SdfPath* subsetPath(&primPath);
345 if (!subsetPaths.empty()) {
346 subsetPath = &subsetPaths[j];
350 if (!subsetMaterialIds.empty()) {
352 instanceMaterialId = subsetMaterialIds[j];
355 if (instanceId == riley::GeometryInstanceId::InvalidId()) {
356 instanceId = riley->CreateGeometryInstance(
358 stats::AddDataLocation(subsetPath->
GetText()).GetValue()),
359 riley::GeometryPrototypeId::InvalidId(),
360 prototypeId, instanceMaterialId, coordSysList,
362 }
else if (*dirtyBits & prmanAttrBits) {
363 riley->ModifyGeometryInstance(
364 riley::GeometryPrototypeId::InvalidId(),
365 instanceId, &instanceMaterialId, &coordSysList,
375 HdInstancer::_SyncInstancerAndParents(renderIndex, instancerId);
377 HdPrmanInstancer *instancer = static_cast<HdPrmanInstancer*>(
379 VtIntArray instanceIndices =
384 instancer->SampleInstanceTransforms(
id, instanceIndices, &ixf);
390 const size_t newNumHdInstances =
391 (ixf.count > 0) ? ixf.values[0].size() : 0;
392 const size_t oldCount = _instanceIds.size();
393 const size_t newCount = newNumHdInstances * _prototypeIds.size();
394 if (newCount != oldCount) {
395 for (
const auto &oldInstanceId: _instanceIds) {
396 riley->DeleteGeometryInstance(
397 riley::GeometryPrototypeId::InvalidId(),
402 _instanceIds.clear();
403 _instanceIds.resize(newCount,
404 riley::GeometryInstanceId::InvalidId());
408 attrs.SetInteger(RixStr.k_identifier_id, primId);
411 std::vector<VtArray<TfToken>> instanceCategories =
415 for (
size_t i=0; i < newNumHdInstances; ++i) {
417 size_t instanceIndex = 0;
418 if (i < instanceIndices.size()) {
419 instanceIndex = instanceIndices[i];
423 RtParamList instanceAttrs = attrs;
424 instancer->GetInstancePrimvars(
id, instanceIndex, instanceAttrs);
426 instanceAttrs.SetInteger(RixStr.k_identifier_id2, i);
429 if (instanceIndex < instanceCategories.size()) {
430 param->ConvertCategoriesToAttributes(
431 id, instanceCategories[instanceIndex], instanceAttrs);
441 (xf.count == 1 && (xf.values[0] ==
GfMatrix4d(1)))) {
443 for (
size_t j=0; j < ixf.count; ++j) {
444 rt_xf[j] = HdPrman_GfMatrixToRtMatrix(ixf.values[j][i]);
448 for (
size_t j=0; j < ixf.count; ++j) {
451 HdPrman_GfMatrixToRtMatrix(xf_j * ixf.values[j][i]);
454 const riley::Transform xform =
455 { unsigned(ixf.count), rt_xf.data(), ixf.times.
data() };
459 for (
size_t j=0; j < _prototypeIds.size(); ++j) {
460 auto const& prototypeId = _prototypeIds[j];
461 auto& instanceId = _instanceIds[i*_prototypeIds.size() + j];
462 auto instanceMaterialId = materialId;
465 SdfPath* subsetPath(&primPath);
466 if (!subsetPaths.empty()) {
467 subsetPath = &subsetPaths[j];
471 if (!subsetMaterialIds.empty()) {
473 instanceMaterialId = subsetMaterialIds[j];
476 if (instanceId == riley::GeometryInstanceId::InvalidId()) {
481 instanceId = riley->CreateGeometryInstance(
483 stats::AddDataLocation(instancePath.
GetText())
485 riley::GeometryPrototypeId::InvalidId(), prototypeId,
486 instanceMaterialId, coordSysList, xform, instanceAttrs);
487 }
else if (*dirtyBits & prmanAttrBits) {
488 riley->ModifyGeometryInstance(
489 riley::GeometryPrototypeId::InvalidId(),
490 instanceId, &instanceMaterialId, &coordSysList,
491 &xform, &instanceAttrs);
499 PXR_NAMESPACE_CLOSE_SCOPE
501 #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.