trimesh icon indicating copy to clipboard operation
trimesh copied to clipboard

face_adjacency_edges_tree invalid for meshes with a boundary/border

Open DanielGrestH3D opened this issue 11 months ago • 1 comments

We love the trimesh library and are using it a lot in our daily work. Great work !

I have encountered an issue with face_adjacency_edges_tree and edges_faces. It seems that the data is not valid for meshes, that are not watertight. A comment about this in the function description would have saved us hours of debugging. Fixing it would be even better though :)

Code to reproduce:

mesh = trimesh.creation.icosphere(subdivisions=2, radius=1.0)

plane_normal = [0, 0, 1]

plane_origin = [0, 0, 0]

mesh = mesh.slice_plane(plane_origin, plane_normal)

edge = mesh.edges_sorted[0]

adj_index = mesh.face_adjacency_edges_tree.query([edge])[1]

adjacent_faces = mesh.face_adjacency[adj_index]

adjacent_faces

Out[10]: array([[111, 146]])

adjacent_face_definitions = mesh.faces[adjacent_faces]

adjacent_face_definitions

Out[12]: 
TrackedArray([[[50, 64,  6],
               [ 6, 64, 46]]], dtype=int64)

edge
Out[13]: array([ 0, 67], dtype=int64)

trimesh version: 4.5.3

DanielGrestH3D avatar Dec 17 '24 13:12 DanielGrestH3D

Hey, I think what may be happening is edge doesn't exist in face_adjacency_edges because presumably it's on a boundary so it's giving a wrong index:

 sliced.face_adjacency_edges_tree.query(edge)
Out[21]: (6.708203932499369, 126)

Since we're sort of using the cKDTree off-script for this backwards index lookup if the distance isn't zero it will be totally wrong, you may want to add a check:

distance_check, adj_index = mesh.face_adjacency_edges_tree.query([edge])
assert (distance_check < 1e-12).all()

mikedh avatar Dec 17 '24 17:12 mikedh