MMG2D initial mesh with required edges

I am trying to make an initial mesh from a set of input data, a bit similar to your example Mesh generation. Crucially, some of my vertices in the input data are connected (not boundary edges, but interior edges), and I’d like to preserve these edges in the final mesh. I don’t mind if additional vertices or edges are added, but I need these input edges to be remain untouched.

I figured it would be as simple as setting all edges to be MMG2D_Set_requiredEdge. Could someone be so kind as to tell me where I have gone wrong?

in pseudo-code, I’m basically doing this:

initialize mesh
fill the vertices and edges
mark all edges (and vertices?) as required
run MMG2D_mmg2dmesh

here is my test data, vertex and edge arrays used as input to the code below

double inVertices[12] = { 2, 0, 1, 1.732, -1, 1.732, -2, 0, -1, -1.732, 1, -1.732 };
int inEdges[14] = { 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 1, 1, 3 };

that is a regular hexagon (6 vertices), with 6 boundary edges and 1 more edge that connect vertex 1-3 (edge through the interior of the hexagon).

// initialize and fill mesh
MMG5_pMesh mesh = NULL;
MMG5_pSol solution = NULL;
MMG2D_Init_mesh(MMG5_ARG_start,
	MMG5_ARG_ppMesh, &mesh,
	MMG5_ARG_ppMet, &solution,
	MMG5_ARG_end);
MMG2D_Set_meshSize(mesh, inNumVertices, 0, 0, inNumEdges);

// set vertices
MMG2D_Set_vertices(mesh, inVertices, NULL);

// set edges
for (int i = 0; i < inNumEdges; i += 2) {
	MMG2D_Set_edge(mesh, inEdges[i], inEdges[i + 1], 0, i + 1);
}

// set required components
for (int i = 0; i < inNumVertices; i += 1) { MMG2D_Set_requiredVertex(mesh, i + 1); }
for (int i = 0; i < inNumEdges; i += 1) { MMG2D_Set_requiredEdge(mesh, i + 1); }

// create the initial mesh
MMG2D_mmg2dmesh(mesh, solution);

The result is a 6-equillateral triangle hexagon (7 vertices, one vertex in the exact center). but vertices 1 and 3 are not connected like I was hoping.

I noticed that using MMG2D_Set_edge in a loop is a bit less buggy than MMG2D_Set_edges. Not sure why, but I don’t mind.

some things I’ve tried:

  • setting the parameter hmax, now thousands of triangles are created, but no input edge is preserved.
  • setting the parameters noinsert, nomove, noswap. I can see these working, especially when hmax is set, but again not what I’m looking for.

Thank you!

I’ve continued to play around with this today and I learned something that might be helpful. Also I made an illustration. The black is my input data, and the red is the output from MMG.
The left example is what I described in my initial post. The right side is a new test where the MMG output succeeds in that it maintains my specified required edges in the final output.
The left example input data contains 6 vertices, the right contains 7 vertices. Both contain 7 edges.
So perhaps the question can be restated: why does MMG maintain the required edges in its output in the right example, but not in the left?

In case anyone else stumbles upon this post in the future, I found a work-around.
If you find yourself with the situation I described (above, left side in example), where an internal required edge connects between two boundary vertices:

  • subdivide the edge into two or more edges, creating new vertices to join them.
  • mark these new edges as “required” as well as these new vertices.

This seems to work in all of my tests. Here is an illustration as to what I mean. The red dot is the new vertex, and there are now two edges on either side of it.
Still not sure why this workaround works (or if it works 100% of the time). If anyone cares to explain what is going on that would be welcomed!