Skip to content

Commit

Permalink
Merge pull request #3586 from Autodesk/bailp/EMSUSD-996/improve-mesh-…
Browse files Browse the repository at this point in the history
…rendering

EMSUSD-996 allowing meshes with insufficient primvars data size.
  • Loading branch information
seando-adsk authored Feb 1, 2024
2 parents 3c741be + 4243fff commit a87b98f
Showing 1 changed file with 111 additions and 92 deletions.
203 changes: 111 additions & 92 deletions lib/mayaUsd/render/vp2RenderDelegate/mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,89 +82,108 @@ void _FillPrimvarData(
const VtArray<SRC_TYPE>& primvarData,
const HdInterpolation& primvarInterp)
{
const unsigned int dataSize = primvarData.size();

switch (primvarInterp) {
case HdInterpolationConstant:
case HdInterpolationConstant: {
SRC_TYPE value {};
if (dataSize > 0) {
value = primvarData[0];
} else {
TF_DEBUG(HDVP2_DEBUG_MESH)
.Msg(
"Invalid Hydra prim '%s': "
"primvar %s has %u elements, while its topology "
"references face vertex index %u.\n",
rprimId.asChar(),
primvarName.GetText(),
dataSize,
0);
}

for (size_t v = 0; v < numVertices; v++) {
SRC_TYPE* pointer = reinterpret_cast<SRC_TYPE*>(
reinterpret_cast<float*>(&vertexBuffer[v]) + channelOffset);
*pointer = primvarData[0];
*pointer = value;
}
break;
}
case HdInterpolationVarying:
case HdInterpolationVertex:
if (numVertices <= renderingToSceneFaceVtxIds.size()) {
const unsigned int dataSize = primvarData.size();
for (size_t v = 0; v < numVertices; v++) {
unsigned int index = renderingToSceneFaceVtxIds[v];
if (index < dataSize) {
SRC_TYPE* pointer = reinterpret_cast<SRC_TYPE*>(
reinterpret_cast<float*>(&vertexBuffer[v]) + channelOffset);
*pointer = primvarData[index];
} else {
TF_DEBUG(HDVP2_DEBUG_MESH)
.Msg(
"Invalid Hydra prim '%s': "
"primvar %s has %u elements, while its topology "
"references face vertex index %u.\n",
rprimId.asChar(),
primvarName.GetText(),
dataSize,
index);
}
}
} else {
TF_CODING_ERROR(
"Invalid Hydra prim '%s': "
"requires %zu vertices, while the number of elements in "
"renderingToSceneFaceVtxIds is %zu. Skipping primvar update.",
rprimId.asChar(),
numVertices,
renderingToSceneFaceVtxIds.size());

memset(vertexBuffer, 0, sizeof(DEST_TYPE) * numVertices);
// The primvar has less data than needed, we issue a warning but
// don't skip update. Truncate the buffer to the lesser length.
if (numVertices > renderingToSceneFaceVtxIds.size()) {
TF_DEBUG(HDVP2_DEBUG_MESH)
.Msg(
"Invalid Hydra prim '%s': "
"requires %zu vertices, while the number of elements in "
"renderingToSceneFaceVtxIds is %zu.",
rprimId.asChar(),
numVertices,
renderingToSceneFaceVtxIds.size());
numVertices = renderingToSceneFaceVtxIds.size();
}
break;
case HdInterpolationUniform: {
const VtIntArray& faceVertexCounts = topology.GetFaceVertexCounts();
const size_t numFaces = faceVertexCounts.size();
if (numFaces <= primvarData.size()) {
// The primvar has more data than needed, we issue a warning but
// don't skip update. Truncate the buffer to the expected length.
if (numFaces < primvarData.size()) {

for (size_t v = 0; v < numVertices; v++) {
unsigned int index = renderingToSceneFaceVtxIds[v];
if (index < dataSize) {
SRC_TYPE* pointer = reinterpret_cast<SRC_TYPE*>(
reinterpret_cast<float*>(&vertexBuffer[v]) + channelOffset);
*pointer = primvarData[index];
} else {
TF_DEBUG(HDVP2_DEBUG_MESH)
.Msg(
"Invalid Hydra prim '%s': "
"primvar %s has %zu elements, while its topology "
"references only upto element index %zu.\n",
"primvar %s has %u elements, while its topology "
"references face vertex index %u.\n",
rprimId.asChar(),
primvarName.GetText(),
primvarData.size(),
numFaces);
dataSize,
index);
}
}
break;
case HdInterpolationUniform: {
const VtIntArray& faceVertexCounts = topology.GetFaceVertexCounts();
size_t numFaces = faceVertexCounts.size();

for (size_t f = 0, v = 0; f < numFaces; f++) {
const size_t faceVertexCount = faceVertexCounts[f];
const size_t faceVertexEnd = v + faceVertexCount;
for (; v < faceVertexEnd; v++) {
SRC_TYPE* pointer = reinterpret_cast<SRC_TYPE*>(
reinterpret_cast<float*>(&vertexBuffer[v]) + channelOffset);
*pointer = primvarData[f];
}
}
} else {
// The primvar has less data than needed. Issue warning and skip
// update like what is done in HdStMesh.
// The primvar has less data than needed, we issue a warning but
// don't skip update. Truncate the buffer to the lesser length.
if (numFaces > dataSize) {
TF_DEBUG(HDVP2_DEBUG_MESH)
.Msg(
"Invalid Hydra prim '%s': "
"primvar %s has only %zu elements, while its topology expects "
"at least %zu elements. Skipping primvar update.\n",
"primvar %s has only %u elements, while its topology expects "
"at least %zu elements.\n",
rprimId.asChar(),
primvarName.GetText(),
primvarData.size(),
dataSize,
numFaces);
numFaces = dataSize;
}

// The primvar has more data than needed, we issue a warning but
// don't skip update. Truncate the buffer to the expected length.
if (numFaces < dataSize) {
TF_DEBUG(HDVP2_DEBUG_MESH)
.Msg(
"Invalid Hydra prim '%s': "
"primvar %s has %u elements, while its topology "
"references only upto element index %zu.\n",
rprimId.asChar(),
primvarName.GetText(),
dataSize,
numFaces);
}

memset(vertexBuffer, 0, sizeof(DEST_TYPE) * numVertices);
for (size_t f = 0, v = 0; f < numFaces; f++) {
const size_t faceVertexCount = faceVertexCounts[f];
const size_t faceVertexEnd = v + faceVertexCount;
for (; v < faceVertexEnd; v++) {
SRC_TYPE* pointer = reinterpret_cast<SRC_TYPE*>(
reinterpret_cast<float*>(&vertexBuffer[v]) + channelOffset);
*pointer = primvarData[f];
}
}
break;
}
Expand All @@ -174,46 +193,46 @@ void _FillPrimvarData(
// from 0, thus we can save a lookup into the table. If the assumption
// about the natural sequence is changed, we will need the lookup and
// remap indices.
if (numVertices <= primvarData.size()) {
// If the primvar has more data than needed, we issue a warning,
// but don't skip the primvar update. Truncate the buffer to the
// expected length.
if (numVertices < primvarData.size()) {
TF_DEBUG(HDVP2_DEBUG_MESH)
.Msg(
"Invalid Hydra prim '%s': "
"primvar %s has %zu elements, while its topology references "
"only upto element index %zu.\n",
rprimId.asChar(),
primvarName.GetText(),
primvarData.size(),
numVertices);
}

if (channelOffset == 0 && std::is_same<DEST_TYPE, SRC_TYPE>::value) {
const void* source = static_cast<const void*>(primvarData.cdata());
memcpy(vertexBuffer, source, sizeof(DEST_TYPE) * numVertices);
} else {
for (size_t v = 0; v < numVertices; v++) {
SRC_TYPE* pointer = reinterpret_cast<SRC_TYPE*>(
reinterpret_cast<float*>(&vertexBuffer[v]) + channelOffset);
*pointer = primvarData[v];
}
}
} else {
// It is unexpected to have less data than we index into. Issue
// a warning and skip update.
// The primvar has less data than needed, we issue a warning but
// don't skip update. Truncate the buffer to the lesser length.
if (numVertices > dataSize) {
TF_DEBUG(HDVP2_DEBUG_MESH)
.Msg(
"Invalid Hydra prim '%s': "
"primvar %s has only %u elements, while its topology expects "
"at least %zu elements.\n",
rprimId.asChar(),
primvarName.GetText(),
dataSize,
numVertices);
numVertices = dataSize;
}

// If the primvar has more data than needed, we issue a warning,
// but don't skip the primvar update. Truncate the buffer to the
// expected length.
if (numVertices < dataSize) {
TF_DEBUG(HDVP2_DEBUG_MESH)
.Msg(
"Invalid Hydra prim '%s': "
"primvar %s has only %zu elements, while its topology expects "
"at least %zu elements. Skipping primvar update.\n",
"primvar %s has %u elements, while its topology references "
"only upto element index %zu.\n",
rprimId.asChar(),
primvarName.GetText(),
primvarData.size(),
dataSize,
numVertices);
}

memset(vertexBuffer, 0, sizeof(DEST_TYPE) * numVertices);
if (channelOffset == 0 && std::is_same<DEST_TYPE, SRC_TYPE>::value) {
const void* source = static_cast<const void*>(primvarData.cdata());
memcpy(vertexBuffer, source, sizeof(DEST_TYPE) * numVertices);
} else {
for (size_t v = 0; v < numVertices; v++) {
SRC_TYPE* pointer = reinterpret_cast<SRC_TYPE*>(
reinterpret_cast<float*>(&vertexBuffer[v]) + channelOffset);
*pointer = primvarData[v];
}
}
break;
default:
Expand Down

0 comments on commit a87b98f

Please sign in to comment.