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 _InitRepr(
TfToken const &reprToken,
103 HdDirtyBits *dirtyBits)
override 120 virtual riley::MaterialId
121 _GetFallbackMaterial(HdPrman_RenderParam *renderParam)
123 return renderParam->GetFallbackMaterialId();
127 virtual RtPrimVarList
128 _ConvertGeometry(HdPrman_RenderParam *renderParam,
132 std::vector<HdGeomSubset> *geomSubsets) = 0;
140 template <
typename BASE>
144 HdDirtyBits* dirtyBits,
148 HF_MALLOC_TAG_FUNCTION();
151 HdPrman_RenderParam *param =
152 static_cast<HdPrman_RenderParam*>(renderParam);
155 riley::Riley *riley = param->AcquireRiley();
158 BASE::_UpdateInstancer(sceneDelegate, dirtyBits);
161 SdfPath const&
id = BASE::GetId();
162 SdfPath const& instancerId = BASE::GetInstancerId();
163 const bool isHdInstance = !instancerId.
IsEmpty();
170 const int32_t primId = BASE::GetPrimId() + 1;
178 BASE::_UpdateVisibility(sceneDelegate, dirtyBits);
182 if (*dirtyBits & HdChangeTracker::DirtyMaterialId) {
183 #if HD_API_VERSION < 37 184 BASE::_SetMaterialId(sceneDelegate->
GetRenderIndex().GetChangeTracker(),
190 riley::MaterialId materialId = _GetFallbackMaterial(param);
191 riley::DisplacementId dispId = riley::DisplacementId::InvalidId();
192 const SdfPath & hdMaterialId = BASE::GetMaterialId();
193 HdPrman_ResolveMaterial(sceneDelegate, hdMaterialId, &materialId, &dispId);
196 riley::CoordinateSystemList coordSysList = {0,
nullptr};
197 if (HdPrman_RenderParam::RileyCoordSysIdVecRefPtr convertedCoordSys =
198 param->ConvertAndRetainCoordSysBindings(sceneDelegate,
id)) {
199 coordSysList.count = convertedCoordSys->size();
200 coordSysList.ids = convertedCoordSys->data();
206 static const int prmanProtoAttrBits =
207 HdChangeTracker::DirtyPoints |
208 HdChangeTracker::DirtyNormals |
209 HdChangeTracker::DirtyWidths |
210 HdChangeTracker::DirtyTopology;
214 static const int prmanInstAttrBits =
215 HdChangeTracker::DirtyMaterialId |
216 HdChangeTracker::DirtyTransform |
217 HdChangeTracker::DirtyVisibility |
218 HdChangeTracker::DirtyDoubleSided |
219 HdChangeTracker::DirtySubdivTags |
220 HdChangeTracker::DirtyVolumeField |
221 HdChangeTracker::DirtyCategories |
222 HdChangeTracker::DirtyPrimvar;
227 std::vector<riley::MaterialId> subsetMaterialIds;
228 std::vector<SdfPath> subsetPaths;
231 HdGeomSubsets geomSubsets;
232 RtPrimVarList primvars = _ConvertGeometry(param, sceneDelegate,
id,
233 &primType, &geomSubsets);
236 HdPrman_TransferMaterialPrimvarOpinions(sceneDelegate, hdMaterialId,
240 const size_t oldCount = _prototypeIds.size();
241 const size_t newCount = std::max((
size_t) 1, geomSubsets.size());
242 if (newCount != oldCount) {
243 for (
const auto &oldPrototypeId: _prototypeIds) {
244 if (oldPrototypeId != riley::GeometryPrototypeId::InvalidId()) {
245 riley->DeleteGeometryPrototype(oldPrototypeId);
248 _prototypeIds.resize(newCount,
249 riley::GeometryPrototypeId::InvalidId());
253 if (geomSubsets.empty()) {
257 primvars.SetString(RixStr.k_stats_prototypeIdentifier,
258 RtUString(primPath.
GetText()));
259 if (_prototypeIds[0] == riley::GeometryPrototypeId::InvalidId()) {
260 _prototypeIds[0] = riley->CreateGeometryPrototype(
262 stats::AddDataLocation(primPath.
GetText()).GetValue()),
263 primType, dispId, primvars);
264 }
else if (*dirtyBits & prmanProtoAttrBits) {
265 riley->ModifyGeometryPrototype(primType, _prototypeIds[0],
273 subsetMaterialIds.reserve(geomSubsets.size());
276 subsetPaths.reserve(geomSubsets.size());
278 for (
size_t j=0; j < geomSubsets.size(); ++j) {
279 auto& prototypeId = _prototypeIds[j];
283 std::vector<int32_t> int32Indices(subset.
indices.begin(),
285 primvars.SetIntegerArray(RixStr.k_shade_faceset,
287 int32Indices.size());
289 riley::MaterialId subsetMaterialId = materialId;
290 riley::DisplacementId subsetDispId = dispId;
294 HdPrman_ResolveMaterial(sceneDelegate, subset.
materialId,
295 &subsetMaterialId, &subsetDispId);
296 subsetMaterialIds.push_back(subsetMaterialId);
300 subsetPaths.push_back(subsetPath);
301 primvars.SetString(RixStr.k_stats_prototypeIdentifier,
302 RtUString(subsetPath.
GetText()));
304 if (prototypeId == riley::GeometryPrototypeId::InvalidId()) {
306 riley->CreateGeometryPrototype(
308 stats::AddDataLocation(subsetPath.
GetText()).GetValue()),
309 primType, dispId, primvars);
310 }
else if (*dirtyBits & prmanProtoAttrBits) {
311 riley->ModifyGeometryPrototype(primType, prototypeId,
312 &subsetDispId, &primvars);
316 *dirtyBits &= ~prmanProtoAttrBits;
322 if (_PrototypeOnly()) {
331 RtParamList attrs = param->ConvertAttributes(sceneDelegate,
id,
true);
336 for (
size_t i=0; i < xf.count; ++i) {
337 xf_rt[i] = HdPrman_GfMatrixToRtMatrix(xf.values[i]);
339 const riley::Transform xform = {
347 attrs.SetInteger(RixStr.k_identifier_id, primId);
348 attrs.SetInteger(RixStr.k_identifier_id2, 0);
350 const size_t newNumHdInstances = 1u;
351 const size_t oldCount = _instanceIds.size();
352 const size_t newCount = newNumHdInstances * _prototypeIds.size();
353 if (newCount != oldCount) {
354 for (
const auto &oldInstanceId: _instanceIds) {
355 if (oldInstanceId != riley::GeometryInstanceId::InvalidId()) {
356 riley->DeleteGeometryInstance(
357 riley::GeometryPrototypeId::InvalidId(), oldInstanceId);
362 riley::GeometryInstanceId::InvalidId());
367 TF_VERIFY(_instanceIds.size() == _prototypeIds.size());
368 for (
size_t j=0; j < _prototypeIds.size(); ++j) {
369 auto const& prototypeId = _prototypeIds[j];
370 auto& instanceId = _instanceIds[j];
371 auto instanceMaterialId = materialId;
374 SdfPath* subsetPath(&primPath);
375 if (!subsetPaths.empty()) {
376 subsetPath = &subsetPaths[j];
380 if (!subsetMaterialIds.empty()) {
382 instanceMaterialId = subsetMaterialIds[j];
385 if (instanceId == riley::GeometryInstanceId::InvalidId()) {
386 instanceId = riley->CreateGeometryInstance(
388 stats::AddDataLocation(subsetPath->
GetText()).GetValue()),
389 riley::GeometryPrototypeId::InvalidId(), prototypeId,
390 instanceMaterialId, coordSysList, xform, attrs);
391 }
else if (*dirtyBits & prmanInstAttrBits) {
392 riley->ModifyGeometryInstance(
393 riley::GeometryPrototypeId::InvalidId(),
394 instanceId, &instanceMaterialId, &coordSysList, &xform,
398 *dirtyBits &= ~prmanInstAttrBits;
415 HdInstancer::_SyncInstancerAndParents(renderIndex, instancerId);
417 if (subsetMaterialIds.size() == 0) {
418 subsetMaterialIds.push_back(materialId);
420 if (subsetPaths.size() == 0) {
421 subsetPaths.push_back(primPath);
423 TF_VERIFY(_prototypeIds.size() == subsetMaterialIds.size() &&
424 _prototypeIds.size() == subsetPaths.size(),
425 "size mismatch (%lu, %lu, %lu)\n", _prototypeIds.size(),
426 subsetMaterialIds.size(), subsetPaths.size());
429 HdPrmanInstancer *instancer = static_cast<HdPrmanInstancer*>(
446 PXR_NAMESPACE_CLOSE_SCOPE
448 #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.
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.
#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.
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.
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.
static HD_API bool IsInstancerDirty(HdDirtyBits dirtyBits, SdfPath const &id)
Returns true if the dirtyBits has a dirty instancer. id is for perflog.