Mesh.QuadRemesh Method Issue

Hello all,

I am facing a weird issue in my code. My code generates a simple triangular mesh, which is quite rough. Thus, I want to run some smoothing on this mesh.

But I am having problems with the Mesh.QuadRemesh Method. It doesn’t work in my triangular Mesh - returns null.
You will say that the problem is in the underlying mesh, but I don’t think so because, for the triangular Mesh:
1- The Mesh.IsValid returns true.
2- I can add successfully the Mesh into the document.
3- If I run the _QuadRemesh command in the user interface, the QuadRemesh is successful with the following options:
image

The C# code that fails is the following:

// JUST EXAMPLE OF HOW MESH IS BUILT
Mesh triangMesh = new Mesh();
triangMesh.Vertices.AddVertices(LIST);
foreach (int[] fIndices in faceIndices)
{
	// Triangular face
	if (fIndices.Length == 3)
	{
		MeshFace face = new MeshFace(fIndices[0], fIndices[1], fIndices[2]);
		triangMesh.Faces.AddFace(face);
	}
	else if (fIndices.Length == 4)
	{
		MeshFace face = new MeshFace(fIndices[0], fIndices[1], fIndices[2], fIndices[3]);
		triangMesh.Faces.AddFace(face);
	}
	else if (fIndices.Length > 4)
	{
		// Must break the polygon
		throw new Exception($"Unexpected large polygon");
	}
}

triangMesh.FillHoles();
triangMesh.Weld(RhinoMath.ToRadians(10));

// Quad Remesh - FAILS
Mesh quadMesh = triangMesh.QuadRemesh(new QuadRemeshParameters()
{
	AdaptiveQuadCount = true,
	AdaptiveSize = 0.5, // I TRIED WITH 50 as well - doesn't work
	DetectHardEdges = true,
	TargetQuadCount = 500,
});
Mesh finalMesh = triangMesh;
if (quadMesh == null || quadMesh.Faces.Count == 0) throw new Exception($"Could not generate quad mesh - continuing with triangular mesh.");
else finalMesh = quadMesh; // QuadMesh is NEVER valid.

// Adds to the Document
Guid idAdded = Doc.Objects.AddMesh(finalMesh);

Please note that the triangMesh is added without issue to the document - and that I can without any run the _QuadMesh command onto the added triangMesh.

One thing I though was that:
1- Perhaps the QuadRemesh method can only work on Mesh that have been added to a document?
2- Perhaps the QuadRemesh method must work on the UI thread (WHY would that be the case?)?

Any light would greatly help.

Rafael

Oh yeah. It seems that the QuadRemesh method only works on meshes that have been added to the document - or that have gotten some validation. The code below works, but only if the mesh is added to the document. I am using the Dispatcher because I have found out that adding/removing objects to the document must be done in the UI thread to avoid weird exceptions.

But I am still looking for a way to avoid having to add a bogus element to the document…

this.Dispatcher.Invoke(() =>
{
	Guid bogusAdd = StructuralLidarPluginData.Doc.Objects.AddMesh(hullMesh);
	MeshObject bogusObject = Doc.Objects.FindId(bogusAdd) as MeshObject;
	Mesh toQuad = bogusObject.MeshGeometry;

	var quadMesh = toQuad.QuadRemesh(new QuadRemeshParameters()
	{
		AdaptiveQuadCount = true,
		AdaptiveSize = 50,
		DetectHardEdges = true,
		TargetQuadCount = 500,
	});
	if (quadMesh == null || quadMesh.Faces.Count == 0)
	{
		BusyOverlay.AppendToLongReport($"Could not generate quad mesh - continuing with triangular mesh.");
	}
	else hullMesh = quadMesh;

	Doc.Objects.Delete(bogusAdd, true);
});

I did separate the Dispatcher calls to only include the adding and removal of the bogus element and it does work. This concludes that the QuadRemesh works only on meshes that have been added to the document, without the need to be called from the UI thread.

My guess is that the mesh you’re creating doesn’t have any normals and when you add it to the document, Rhino is computing them.