Fix import of invalid triangles Issue #472

This commit is contained in:
gumyr 2024-01-13 11:06:09 -05:00
parent 047d9cc53f
commit 97088d6f3c
3 changed files with 22 additions and 4 deletions

View file

@ -82,6 +82,7 @@ license:
# pylint: disable=no-name-in-module, import-error # pylint: disable=no-name-in-module, import-error
import copy import copy
import ctypes import ctypes
import itertools
import math import math
import os import os
import sys import sys
@ -96,9 +97,12 @@ from OCP.BRepBuilderAPI import (
BRepBuilderAPI_MakeSolid, BRepBuilderAPI_MakeSolid,
BRepBuilderAPI_Sewing, BRepBuilderAPI_Sewing,
) )
from OCP.BRepGProp import BRepGProp
from OCP.BRepMesh import BRepMesh_IncrementalMesh from OCP.BRepMesh import BRepMesh_IncrementalMesh
from OCP.gp import gp_Pnt from OCP.gp import gp_Pnt
import OCP.TopAbs as ta import OCP.TopAbs as ta
from OCP.GProp import GProp_GProps
from OCP.ShapeFix import ShapeFix_Shape
from OCP.TopAbs import TopAbs_ShapeEnum from OCP.TopAbs import TopAbs_ShapeEnum
from OCP.TopExp import TopExp_Explorer from OCP.TopExp import TopExp_Explorer
from OCP.TopoDS import TopoDS_Compound from OCP.TopoDS import TopoDS_Compound
@ -106,8 +110,8 @@ from OCP.TopLoc import TopLoc_Location
from py_lib3mf import Lib3MF from py_lib3mf import Lib3MF
from build123d.build_enums import MeshType, Unit from build123d.build_enums import MeshType, Unit
from build123d.geometry import Color, TOLERANCE from build123d.geometry import Color, TOLERANCE, Vector
from build123d.topology import Compound, Shape, Shell, Solid, downcast from build123d.topology import Compound, Face, Shape, Shell, Solid, downcast
class Mesher: class Mesher:
@ -455,8 +459,11 @@ class Mesher:
# Create the triangular face using the polygon # Create the triangular face using the polygon
polygon_builder = BRepBuilderAPI_MakePolygon(*ocp_vertices, Close=True) polygon_builder = BRepBuilderAPI_MakePolygon(*ocp_vertices, Close=True)
face_builder = BRepBuilderAPI_MakeFace(polygon_builder.Wire()) face_builder = BRepBuilderAPI_MakeFace(polygon_builder.Wire())
# Add new Face to Shell facet = face_builder.Face()
shell_builder.Add(face_builder.Face()) facet_properties = GProp_GProps()
BRepGProp.SurfaceProperties_s(facet, facet_properties)
if facet_properties.Mass() != 0: # Area==0 is an invalid facet
shell_builder.Add(facet)
# Create the Shell(s) - if the object has voids there will be multiple # Create the Shell(s) - if the object has voids there will be multiple
shell_builder.Perform() shell_builder.Perform()

BIN
tests/cyl_w_rect_hole.stl Normal file

Binary file not shown.

View file

@ -190,5 +190,16 @@ class TestHollowImport(unittest.TestCase):
self.assertTrue(stl[0].is_valid()) self.assertTrue(stl[0].is_valid())
class TestImportDegenerateTriangles(unittest.TestCase):
def test_degenerate_import(self):
"""Some STLs may contain 'triangles' where all three points are on a line"""
importer = Mesher()
stl = importer.read("cyl_w_rect_hole.stl")[0]
self.assertEqual(type(stl), Solid)
self.assertTrue(stl.is_manifold)
self.assertTrue(stl.is_valid())
self.assertEqual(sum(f.area == 0 for f in stl.faces()), 0)
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()