Mesh.faces and network

I made a mixed mesh (which is a group of several square meshes) in rhino and saved it as .obj file. (see figure). I then loaded it with mesh=Mesh.from_obj. Now, mesh.face, returns only the faces of each cell, which makes scene.

So for the mesh in the figure, it mesh.face gives:
{0: [30, 8, 17, 16], 1: [3, 32, 8, 30], 2: [16, 17, 9, 12], 3: [12, 9, 0, 24], 4: [22, 34, 4, 14], 5: [29, 6, 34, 22], 6: [38, 3, 30, 36], 7: [37, 12, 24, 19], 8: [10, 37, 19, 31], 9: [6, 38, 36, 34], 10: [14, 4, 10, 25], 11: [25, 10, 31, 5], 12: [7, 18, 26, 27], 13: [35, 28, 18, 7], 14: [23, 1, 28, 35], 15: [13, 7, 27, 33], 16: [15, 35, 7, 13], 17: [20, 23, 35, 15], 18: [32, 20, 15, 17], 19: [17, 15, 13, 0], 20: [0, 13, 33, 21], 21: [19, 0, 21, 2], 22: [5, 19, 2, 11]}

I was wondering if there is a way to instead of finding the cells, we can find real faces like: [0, 9, 17, 15, 13]. So I tried:

mesh_2=Mesh()
for key, attr in mesh.vertices(True):
mesh_22.add_vertex(key, x=attr[‘x’], y=attr[‘y’], z=attr[‘z’])
mesh_2.halfedge=mesh.halfedge
network_find_faces(mesh)

This way I can get the actual faces + the boundary face, but there will be some other faces that are not correct (e.g. the ones in bold):
{0: [29, 22, 14, 25, 5, 11, 2, 21, 33, 27, 26, 18, 28, 1, 23, 20, 32, 3, 38, 6], 1: [0, 9, 17, 15, 13], 2: [9, 0, 17, 8, 32, 17, 16, 30, 8, 17], 3: [0, 13, 33, 21], 4: [17, 0, 19, 24, 0, 21, 2, 19, 0, 24, 12, 9, 0], 5: [1, 28, 35, 23], 6: [2, 11, 5, 19, 31, 10, 37, 19, 5, 31, 19], 7: [3, 32, 8, 30], 8: [38, 3, 30, 36], 9: [4, 34, 36, 30, 16, 12, 37, 10], 10: [34, 4, 14, 22], 11: [4, 10, 25, 14], 12: [5, 25, 10, 31], 13: [6, 34, 22, 29], 14: [34, 6, 38, 36], 15: [7, 27, 33, 13], 16: [27, 7, 18, 26], 17: [18, 7, 35, 28], 18: [35, 7, 13, 15], 19: [9, 12, 16, 17, 0, 19, 24, 0, 21, 2, 19, 0, 24, 12], 20: [12, 24, 19, 37], 21: [15, 17, 32, 20], 22: [35, 15, 20, 23]}

Is there a way to cure this?

are you asking for a general solution? or something that just works in this case?

Well for this case, I can remove the wrong faces, by writing a small function. But is there a general way to do this?

not really.

the mesh is in fact correct because it corresponds to the input. after all, in your input face 19 did not contain vertex 9, it just contained vertices 0, 17, 15, 13.

i also don’t think the solution posted above is correct at all. as you noticed, you will just get a bunch of weird faces…

what you could do, is to check for the faces that share at least one vertex, which edges intersect and if both faces contain the intersection point. if this is not the case, add the vertex to the face that does not contain it.

this will work in most cases i guess…

Thanks for the input.

Also is there another way to get vertices on the boundary. With the original mesh, the mesh.vertices_on_the_boundary function will stuck.

i can see that that might be the case.

in the original mesh 5, 31, 19, 24, 0, 9, 17, 8, 32 (if you move 31 and 24 slightly down and 9 and 8 slightly to the left, that fact becomes immediately clear) are also on the boundary and create loops that will confuse the algorithm.

it should not get confused by something like this so i will try to release a patch as soon as possible…

fwiw, the mesh can be made into the mesh that you want with the following snippet applied to faces
5, 19, 2, 11,
19, 0, 21, 2,
17, 15, 13, 0,
32, 20, 15, 17

fkey = mesh.halfedge[5][19]
vertices = mesh.face_vertices(fkey)
i = vertices.index(19)
vertices.insert(31, i-1)
mesh.halfedge[5][31] = fkey
mesh.halfedge[31][19] = fkey
del mesh halfedge[5][19]

which should probably also be handled by a mesh function :slight_smile:

Great. Thanks for the help. Looking forward to it.