While this post is very old, I’ll post an answer here as I had a gander at this as well and came across this thread during my journey. Do note that this answer is for UE 5.3, older versions may not work the same.
First of all, you need to grab the vertices and indices that make up the mesh - this assumes you’ve got a valid reference to a UStaticMesh
, but you can also get the UStaticMesh
from a UStaticMeshComponent
.
You can then fetch the data like this;
// Preferrably this is event-driven, and not done at runtime
// Reset the arrays if you change/update the mesh
Vertices.Reset(); // TArray<FVector>
Indices.Reset(); // TArray<int32>
// Get the mesh description, here you can specify a specific LOD
UStaticMeshDescription* MeshDescription = MyStaticMesh->GetStaticMeshDescription(0);
const FVertexArray& VertexArray = MeshDescription->Vertices();
const FTriangleArray& TriangleArray = MeshDescription->Triangles();
// Store all the vertex positions (local space)
for (FVertexID VertexID : VertexArray.GetElementIDs())
{
FVector VertexLocation = MeshDescription->GetVertexPosition(VertexID);
Vertices.Add(VertexLocation);
}
// Iterate through all the triangles to get the indices
for (FTriangleID TriangleID : TriangleArray.GetElementIDs())
{
// Get the triangle vertex instances, these are the indices - weird naming
// there should always be 3 vertices per triangle
TArray<FVertexInstanceID> VertexInstanceIds;
MeshDescription->GetTriangleVertexInstances(TriangleID, VertexInstanceIds);
for (const FVertexInstanceID VertexInstanceID : VertexInstanceIds)
{
FVertexID VertexID = MeshDescription->GetVertexInstanceVertex(VertexInstanceID);
Indices.Add(static_cast<int32>(VertexID));
}
}
In order to draw the actual mesh, you need to include "SceneManagement.h"
, this contains a lot of various drawing methods. Specifically you want to use this;
void DrawDebugMesh(const UWorld* InWorld, TArray<FVector> const& Verts, TArray<int32> const& Indices, FColor const& Color, bool bPersistent=false, float LifeTime=-1.f, uint8 DepthPriority = 0);
Do note that this requires a UWorld
pointer and not a FPrimitiveDrawingInterface
. If you’re working with component visualizers like me - this is easy enough to get from the DrawVisualization
method.
Furthermore, do note that you must specify a LifeTime
value that is greater than 0.0f
. I believe they expect you to use a DeltaTime, but component visualizers do not provide this as far as I’m aware.
For example, this is how I draw mine;
UWorld* World = MyComponent->GetWorld();
TArray<FVector> ComponentSpaceVertices;
for (auto Vertex : MyComponent->Vertices)
{
ComponentSpaceVertices.Add(MyComponent.GetLocation() + Vertex);
}
DrawDebugMesh(World, ComponentSpaceVertices, MyComponent->Indices, FColor::Green, false, 0.16f, SDPG_Foreground);
This is all pseudocode and not exactly how I work with mine, but it should be enough to convey the idea of how it works.
Also do note, that this drawn mesh is not wireframed as I thought it would be. Which honestly is quite weird, or at least that there is no option to draw the mesh exclusively with lines.
That said, you now have the ability to get the data you need from the mesh description in order to draw lines if you want a wireframed mesh. You can also get edges similarly to how you get triangles.