face_adjacency() for doublesided mesh
Hi, If I have the following mesh (a doublesided square):
data = '# https://github.com/mikedh/trimesh\nv 0.00000000 0.00000000 0.00000000 0.00000000 0.49803922 0.49803922\nv 0.00000000 119.24000000 0.00000000 0.00000000 0.00000000 1.00000000\nv 118.11000000 0.00000000 0.00000000 0.00000000 1.00000000 0.00000000\nv 118.11000000 119.24000000 0.00000000 0.00000000 0.49803922 0.49803922\nvn 0.00000000 0.00000000 0.00000000\nvn 0.00000000 0.00000000 0.00000000\nvn 0.00000000 0.00000000 0.00000000\nvn 0.00000000 0.00000000 0.00000000\nf 1//1 4//4 3//3\nf 4//4 1//1 2//2\nf 3//3 4//4 1//1\nf 2//2 1//1 4//4'
mesh = trimesh.load(io.StringIO(data), file_type='obj')
I get the following face adjacency:
In [123]: mesh.face_adjacency
Out[123]:
array([[1, 3],
[0, 2],
[1, 3],
[0, 2]])
which misses the obvious adjacenies between the faces on both sides of the square and leads to weird facets. The reason is the grouping of edges in grouping.py:
# this will return the indices for duplicate edges
# every edge appears twice in a well constructed mesh
# so for every row in edge_idx:
# edges[edge_idx[*][0]] == edges[edge_idx[*][1]]
# in this call to group rows we discard edges which
# don't occur twice
edge_groups = grouping.group_rows(edges, require_count=2)
My question: Is there any way to relax the require_count=2 assumption or would this lead to bigger problems? (i.e. should I just accept that this is not a proper mesh and make it watertight by other means?)
A new arg at_least=2 may make sense here and be helpful for non-manifold meshes.
Yeah agreed for non-watertight meshes this is janky. My main concern is keeping face_adjacency a (n, 2) int numpy array and not adding too much of a performance penalty for the watertight case. We could probably do a multiple-pass thing, where if there are any "leftover" edges with count > 2 it then stacks it into the results?