mikedh / trimesh

Python library for loading and using triangular meshes.
https://trimesh.org
MIT License
2.85k stars 566 forks source link

Trimesh trimesh.intersections.slice_mesh_plane returns non-manifold mesh #2203

Open PFvanBeerendonk opened 2 months ago

PFvanBeerendonk commented 2 months ago

Reproducable issue

Given the following code

import trimesh
from trimesh.caching import tracked_array
import numpy as np

mesh = trimesh.load_mesh('path\\to\\part')
origin = tracked_array([ 0., 0., 92.36976624])
normal = tracked_array([0, 0, 1])

# inspired by https://github.com/mikedh/trimesh/issues/235
dot = np.dot(normal, (mesh.vertices - origin).T)[mesh.faces]

s = mesh.slice_plane(plane_normal=normal,
    plane_origin=origin, cap=True,
    cached_dots=dot)

# Mesh becomes non-manifold

result = s.split()

assert len(result) == 1

here: 'path\to\part' refers to tue_logo__by_pieter.zip

The mesh s is non-manifold (I exported it an checked it in blender, the cap is broken). As a consequence s.split() returns []

PFvanBeerendonk commented 2 months ago

https://github.com/PFvanBeerendonk/trimesh/tree/T2203-slice_mesh_plane-not-watertight

Testcase here

PFvanBeerendonk commented 2 months ago

I did some testing, seems that polygons.edges_to_polygons in trimesh.intersections.slice_mesh_plane ignores vertices that are on the same line.

i.e. given edges:

[
[0,0],
[1,1],
[2,2]
]

it seems to ignore [1,1]. Thus the cap misses such coordinates.

Edit: It seems that the result p of polygons.edges_to_polygons has an (unexpected to me) interior

Edit2: for dfs in graph.traversals(edges, mode="dfs"): in edges_to_polygons in trimesh.paht.polygons actually produces 2 sets (would expect 1), resulting in above noted interior