DynamicMesh::SetVertexColor has no effect

Hi people :slight_smile:

im trying to update the vertex colors of a DynamicMesh but even if SetVertex works well, trying to use SetVertexColor in the same loop does absolutely nothing.

This is basically the code im using:

FDynamicMesh3 tempMesh = MeshComp->GetDynamicMesh()->GetMeshRef();


if (!tempMesh.HasVertexColors())
{
	tempMesh.EnableVertexColors(FVector3f(0.0f, 0.0f, 0.0f));
	tempMesh.EnableAttributes();
	tempMesh.Attributes()->EnablePrimaryColors();
}


for (int32 i : tempMesh.VertexIndicesItr())
{
	tempMesh.SetVertex(i, vertPos + ...);

	tempMesh.SetVertexColor(i, FVector3f(1.0f, 0.0f, 0.0f));
}


MeshComp->SetMesh(MoveTemp(tempMesh));
MeshComp->NotifyMeshUpdated();
MeshComp->UpdateCollision();

I also used a Material with vertex colors as the base color for debugging.
Trying to ask ChatGPT only gave me hallucinated pseudo-code and i didn’t find any other solution online.

Thx for your help in advance!

You need to use primatyColor instead of VertexColor, so you should write something like this:

FDynamicMesh3 tempMesh = MeshComp->GetDynamicMesh()->GetMeshRef();

if (!tempMesh.HasAttributes())
{
	tempMesh.EnableAttributes();
}
if (!tempMesh.Attributes()->HasPrimaryColors())
{
	tempMesh.Attributes()->EnablePrimaryColors();
}

FDynamicMeshColorOverlay* Colors = tempMesh.Attributes()->PrimaryColors();
Colors->ClearElements();
		
TArray<int32> ElemIDs;
ElemIDs.SetNum(tempMesh.MaxVertexID());
		
for (int32 i : tempMesh.VertexIndicesItr())
{
	tempMesh.SetVertex(i, vertPos + ...);
			
	ElemIDs[i] = Colors->AppendElement(FVector4f(1.0f, 0.0f, 0.0f, 0.0f));
}
for (int32 TriangleID : tempMesh.TriangleIndicesItr())
{
	FIndex3i Triangle = tempMesh.GetTriangle(TriangleID);
	Colors->SetTriangle(TriangleID, FIndex3i(ElemIDs[Triangle.A], ElemIDs[Triangle.B], ElemIDs[Triangle.C]) );
}

MeshComp->SetMesh(MoveTemp(tempMesh));
MeshComp->NotifyMeshUpdated();
MeshComp->UpdateCollision();

Also note: It is better to use a special function to get FDynamicMesh3. Using GetMeshRef is not recommended, use EditMesh instead, as shown below:

MeshComp->GetDynamicMesh()->EditMesh([&](FDynamicMesh3& EditMesh)
{
	if (!EditMesh.HasAttributes())
	{
		EditMesh.EnableAttributes();
	}
	if (!EditMesh.Attributes()->HasPrimaryColors())
	{
		EditMesh.Attributes()->EnablePrimaryColors();
	}

	FDynamicMeshColorOverlay* Colors = EditMesh.Attributes()->PrimaryColors();
	Colors->ClearElements();
	TArray<int32> ElemIDs;
	ElemIDs.SetNum(EditMesh.MaxVertexID());
		
	for (int32 i : EditMesh.VertexIndicesItr())
	{
		tempMesh.SetVertex(i, vertPos + ...);
			
		ElemIDs[i] = Colors->AppendElement(FVector4f(1.0f, 0.0f, 0.0f, 0.0f));
	}
	for (int32 TriangleID : EditMesh.TriangleIndicesItr())
	{
		FIndex3i Triangle = EditMesh.GetTriangle(TriangleID);
		Colors->SetTriangle(TriangleID, FIndex3i(ElemIDs[Triangle.A], ElemIDs[Triangle.B], ElemIDs[Triangle.C]) );
	}
}, EDynamicMeshChangeType::GeneralEdit);

Both codes should give the same result.