UMeshDescriptionBase::GetTriangleVertices array size crash

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]

Hi Tim,

Looking at the header MeshDescription.h, void FMeshDescription::GetTriangleVertices(const FTriangleID TriangleID, TArrayView<FVertexID> OutVertexIDs) const, the one you are calling is deprecated since 4.26. And I agree should have been removed.

That said, which version of UE are you compiling against? This report is stating 5.7.

Finally, TArray<FVertexID> TriangleVertices = StaticMeshDescription->GetTriangleVertices(TriangleID); should work since version 5.0.

I hope this helps.

Regards,

Jean-Luc

[Attachment Removed]

Hello,

Thanks for your answer ! We’ve indeed settled on using that solution, which works fine.

The deprecated function you mention is not the one we were calling !

UMeshDescriptionBase::GetTriangleVertices is not marked as deprecated, only the specified overload of FMeshDescription::GetTriangleVertices is.

This is a source of confusion for users, maybe it should also be flagged as deprecated ?

Have a great day,

Tim

[Attachment Removed]

Hello Tim,

My bad! I overlooked the class you were calling GetTriangleVertices from.

I always directly used the FMeshDescription struc :frowning:

Looking at the code of UMeshDescriptionBase::GetTriangleVertices in 5.7, I now understand the issue. Algo::Copy is misused :frowning: I’ll fix it for next version.

Regards,

Jean-Luc

[Attachment Removed]