Skip to content

Commit 5749c32

Browse files
authored
repair.fix_inversion(multibody): flip each connected component if watertight (#2484)
Instead of giving up if the whole mesh is non-watertight, only skip the components that aren't watertight. I'm having success with this on my data.
2 parents 150488a + f272feb commit 5749c32

File tree

1 file changed

+17
-15
lines changed

1 file changed

+17
-15
lines changed

trimesh/repair.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,15 @@ def fix_inversion(mesh, multibody=False):
9797
multibody : bool
9898
If True will try to fix normals on every body
9999
"""
100-
if not mesh.is_watertight:
101-
# this will make things worse for non-watertight meshes
102-
return
100+
if not multibody:
101+
if not mesh.is_watertight:
102+
# this will make things worse for non-watertight meshes
103+
return
103104

104-
if multibody:
105+
elif mesh.volume < 0.0:
106+
mesh.invert()
107+
108+
else: # multibody
105109
groups = graph.connected_components(mesh.face_adjacency)
106110
# escape early for single body
107111
if len(groups) == 1:
@@ -115,14 +119,15 @@ def fix_inversion(mesh, multibody=False):
115119
cross = mesh.triangles_cross
116120
# indexes of mesh.faces, not actual faces
117121
for faces in groups:
118-
# calculate the volume of the submesh faces
119-
volume = triangles.mass_properties(
120-
tri[faces], crosses=cross[faces], skip_inertia=True
121-
)["volume"]
122-
# if that volume is negative it is either
123-
# inverted or just total garbage
124-
if volume < 0.0:
125-
flip[faces] = True
122+
if mesh.is_watertight or graph.is_watertight(faces_to_edges(mesh.faces[faces])):
123+
# calculate the volume of the submesh faces
124+
volume = triangles.mass_properties(
125+
tri[faces], crosses=cross[faces], skip_inertia=True
126+
)["volume"]
127+
# if that volume is negative it is either
128+
# inverted or just total garbage
129+
if volume < 0.0:
130+
flip[faces] = True
126131
# one or more faces needs flipping
127132
if flip.any():
128133
# flip normals of necessary faces
@@ -136,9 +141,6 @@ def fix_inversion(mesh, multibody=False):
136141
if normals is not None:
137142
mesh.face_normals = normals
138143

139-
elif mesh.volume < 0.0:
140-
mesh.invert()
141-
142144

143145
def fix_normals(mesh, multibody=False):
144146
"""

0 commit comments

Comments
 (0)