trimesh icon indicating copy to clipboard operation
trimesh copied to clipboard

face_adjacency() for doublesided mesh

Open clemense opened this issue 4 years ago • 2 comments

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?)

clemense avatar Apr 01 '22 21:04 clemense

A new arg at_least=2 may make sense here and be helpful for non-manifold meshes.

YuanWenqing avatar Apr 02 '22 05:04 YuanWenqing

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?

mikedh avatar Apr 05 '22 15:04 mikedh