Polygons and triangles correspondence after triangulating a mesh in Blender

One of the methods for mesh analytics is exploring its triangulated geometry. For example, such exploration is used when searching for polygons that overlaps in the mesh itself or in its UV. In order to return the result obtained after analyzing the triangulated mesh back to the original mesh, we need to know the exact correspondence between the original polygon and the triangles created from it.

The bmesh.ops.triangulate() operator itself, which is the easiest way to triangulate a mesh, provides a certain tool for finding such a correspondence, but it could be slightly improved.

For example, let’s create a bmesh from the currently active mesh and match the indices for its vertices, edges and polygons. Also make a copy of it, we will use it later.

Now we can triangulate the bmesh.

All the triangulation is done immediately with the bmesh geometry. For further actions, we also need the result returned by the triangulation function.

The bmesh.ops.triangulate() function returns a dictionary, which consists of four dictionaries: “edges”, “faces”, “face_map” and “face_map_double”.

The “face_map” dictionary will be the most useful to us. This dictionary has the following format: {triangle: source polygon, triangle: source polygon, …}.

This dictionary allows us to perform triangle-polygon correspondence from the side of the resulting triangulated mesh, but it is much more useful to be able to obtain a set of obtained triangles based on the source polygon.

We can get a list of tuples ((triangle, polygon), (triangle, polygon), …) using the items() function.

But this format also does not allow us to quickly obtain the required data.

We can invert the “face_map” dictionary.

And now we already get something similar to what we need – through the items() function we can get a list of tuples like: ((original polygon, [triangle, triangle]), …).

However, there is one more problem here – if the original mesh initially contained triangular polygons, they, were not triangulated and did not get into the final list. We can check this simply by comparing the lengths of the resulting list, the list of all polygons of the original mesh, and the list of triangular polygons of the original mesh.

As we can see, the total number of polygons – 500 can be made up of the number of polygons in the inverted face_map – 468, and the number of triangles in the original polygon – 32.

Let’s convert the inverted face_map to a dictionary, in which the keys will be the indices of the original polygons, and the elements will be the list of triangles created from this polygon.

And make the same dictionary for the missing triangles from the original mesh. We used the bmesh copy, we created earlier, for this.

Merge both dictionaries into one.

As a result, we got a complete dictionary with keys – indices of the original polygons, and elements – triangles after triangulation.

Now to quickly get the triangles that were created from a polygon with an index of, for example, 322, we simply need to access this final dictionary by the index:

If we need to save the triangulation, we can write the result from the bmesh back to the original mesh and remove bmesh we need no longer.

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comment
Newest
Oldest Most Voted
Inline Feedbacks
View all comments