Skip to content

Commit

Permalink
Fix left handed indexed meshes with normals (#2233)
Browse files Browse the repository at this point in the history
* Fix problem with left handed indexed meshes with normals rendered with husk

* store the mesh handedness to avoid calling GetTopology
  • Loading branch information
cpichard authored Feb 11, 2025
1 parent e4c49e9 commit fd41c44
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- [usd#2219](https://github.com/Autodesk/arnold-usd/issues/2219) - Fix race condition in hydra with node names
- [usd#2225](https://github.com/Autodesk/arnold-usd/issues/2225) - Fix crash in point instancers with missing prototypes
- [usd#2224](https://github.com/Autodesk/arnold-usd/issues/2224) - Fix warning "HdArnoldDriverMain is already installed"
- [usd#2232](https://github.com/Autodesk/arnold-usd/issues/2232) - Fix incorrect husk render of left handed indexed meshes with normals.

## Pending Feature release

Expand Down
20 changes: 8 additions & 12 deletions libs/render_delegate/mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,6 @@ void HdArnoldMesh::Sync(
HdArnoldRenderParamInterrupt param(renderParam);
const auto& id = GetId();
HdArnoldSampledPrimvarType _pointsSample;
VtValue vertexCountsVtValue; ///< Vertex nsides
const auto dirtyPrimvars = HdArnoldGetComputedPrimvars(sceneDelegate, id, *dirtyBits, _primvars, nullptr, &_pointsSample) ||
(*dirtyBits & HdChangeTracker::DirtyPrimvar);

Expand Down Expand Up @@ -235,15 +234,12 @@ void HdArnoldMesh::Sync(
}
}

bool isLeftHanded = false;

// We have to flip the orientation if it's left handed.
const auto dirtyTopology = HdChangeTracker::IsTopologyDirty(*dirtyBits, id);
if (dirtyTopology) {
param.Interrupt();
const auto topology = GetMeshTopology(sceneDelegate);
// We have to flip the orientation if it's left handed.
isLeftHanded = topology.GetOrientation() == PxOsdOpenSubdivTokens->leftHanded;

_isLeftHanded = topology.GetOrientation() == PxOsdOpenSubdivTokens->leftHanded;
param.Interrupt();
// Keep a reference on the vertex buffers as long as this object is live
// We try to keep the buffer consts as otherwise usd will duplicate them (COW)
const VtIntArray &vertexCounts = topology.GetFaceVertexCounts();
Expand All @@ -255,14 +251,14 @@ void HdArnoldMesh::Sync(
const bool hasNegativeValues = std::any_of(vertexCounts.cbegin(), vertexCounts.cend(), [](int i) {return i < 0;});
_vertexCountSum = 0;
// If the buffer is left handed or has negative values, we must allocate a new one to make it work with arnold
if (isLeftHanded || hasNegativeValues) {
if (_isLeftHanded || hasNegativeValues) {
VtIntArray vertexCountsTmp = topology.GetFaceVertexCounts();
VtIntArray vertexIndicesTmp = topology.GetFaceVertexIndices();
assert(vertexCountsTmp.size() == (size_t)numFaces);
if (Ai_unlikely(hasNegativeValues)) {
std::transform(vertexCountsTmp.cbegin(), vertexCountsTmp.cend(), vertexCountsTmp.begin(), [] (const int i){return i < 0 ? 0 : i;});
}
if (isLeftHanded) {
if (_isLeftHanded) {
for (int i = 0; i < numFaces; ++i) {
const int vertexCount = vertexCountsTmp[i];
for (int vertexIdx = 0; vertexIdx < vertexCount; vertexIdx += 1) {
Expand All @@ -274,14 +270,14 @@ void HdArnoldMesh::Sync(
_vertexCountSum = std::accumulate(vertexCounts.cbegin(), vertexCounts.cend(), 0);
}
// Keep the buffers alive
vertexCountsVtValue = VtValue(vertexCountsTmp);
_vertexCountsVtValue = VtValue(vertexCountsTmp);
AiNodeSetArray(GetArnoldNode(), str::nsides, _arrayHandler.CreateAtArrayFromVtArray(vertexCountsTmp, AI_TYPE_UINT));
AiNodeSetArray(GetArnoldNode(), str::vidxs, _arrayHandler.CreateAtArrayFromVtArray(vertexIndicesTmp, AI_TYPE_UINT));

} else {
_vertexCountSum = std::accumulate(vertexCounts.cbegin(), vertexCounts.cend(), 0);
// Keep the buffers alive
vertexCountsVtValue = VtValue(vertexCounts);
_vertexCountsVtValue = VtValue(vertexCounts);
AiNodeSetArray(GetArnoldNode(), str::nsides, _arrayHandler.CreateAtArrayFromVtArray(vertexCounts, AI_TYPE_UINT));
AiNodeSetArray(GetArnoldNode(), str::vidxs, _arrayHandler.CreateAtArrayFromVtArray(vertexIndices, AI_TYPE_UINT));
}
Expand Down Expand Up @@ -380,7 +376,7 @@ void HdArnoldMesh::Sync(
param.Interrupt();
const auto isVolume = _IsVolume();
AtNode *meshLight = _GetMeshLight(sceneDelegate, id);
const VtIntArray *leftHandedVertexCounts = isLeftHanded ? & vertexCountsVtValue.UncheckedGet<VtIntArray>() : nullptr;
const VtIntArray *leftHandedVertexCounts = _isLeftHanded ? & _vertexCountsVtValue.UncheckedGet<VtIntArray>() : nullptr;
for (auto& primvar : _primvars) {
auto& desc = primvar.second;
// If the positions have changed, then all non-constant primvars must be updated
Expand Down
2 changes: 2 additions & 0 deletions libs/render_delegate/mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ class HdArnoldMesh : public HdArnoldRprim<HdMesh> {

HdArnoldPrimvarMap _primvars; ///< Precomputed list of primvars.
HdArnoldSubsets _subsets; ///< Material ids from subsets.
VtValue _vertexCountsVtValue; ///< Vertex nsides. We need to keep it alive for left handed geometries.
bool _isLeftHanded = false; ///< Whether the geometry is left handed or not.
size_t _vertexCountSum = 0; ///< Sum of the vertex counts array.
size_t _numberOfPositionKeys = 1; ///< Number of vertex position keys for the mesh.
AtNode *_geometryLight = nullptr; ///< Eventual mesh light for this polymesh
Expand Down

0 comments on commit fd41c44

Please sign in to comment.