In our 5.7 project we are building a editor-only tool to analyze imported static meshes. We need to access topology data such as vertex positions.
We are getting the UStaticMeshDescription from the UStaticMesh instance. Using the method UMeshDescriptionBase::GetTriangleVertices gives us incorrect vertex IDs.
This method fills an array, passed in parameter. We make sure to pass in an empty array. We are expecting it to contain 3 valid vertex IDs. Unfortunately, we noticed that it always has 6 elements, the first 3 being inconsistent garbage values :
[Image Removed]
Here is a debugger view of the result of the execution of the method. The last 3 FVertexID are valid, but the first 3 ones are unexpected.
Digging into the engine code, the bug is clear :
- UMeshDescriptionBase::GetTriangleVertices first calls .SetNumInitialized(3) on the output array (probably as some sort of optimization because the number of elements is expected to be 3). This is where the garbage (uninitialized values) come from.
- Then it calls Algo::Copy to copy the vertex IDs of the triangle to this output array. But Algo::Copy performs an Add operation, appending 3 elements seuqnetially at the end of the array, so after the first 3 uninitialized values.
The array always ends up with 6 values, the first 3 of them being incorrect, which can lead to a check failing in other methods needing a FVertexID.
This happens with any mesh.
A simple, reliable fix, would be to remove the line OutVertexIDs.SetNumUninitialized(3) from UMeshDescriptionBase::GetTriangleVertices.
Here is our calling editor code :
constexpr int32 LOD_0{0};
const UStaticMeshDescription *const StaticMeshDescription{StaticMeshAsset->GetStaticMeshDescription(LOD_0)};
for (const FTriangleID TriangleID : StaticMeshDescription->Triangles().GetElementIDs())
{
const FPolygonGroupID PolygonGroupID{ StaticMeshDescription->GetTrianglePolygonGroup(TriangleID) };
TArray<FVertexID> TriangleVertices{};
StaticMeshDescription->GetTriangleVertices(TriangleID, OUT TriangleVertices);
check(TriangleVertices.Num() == 3); // <- THIS FAILS
// Do some processing on vertices using the FVertexID array
}
[Attachment Removed]