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
import copy
import ctypes
import itertools
import math
import os
import sys
@ -96,9 +97,12 @@ from OCP.BRepBuilderAPI import (
BRepBuilderAPI_MakeSolid,
BRepBuilderAPI_Sewing,
)
from OCP.BRepGProp import BRepGProp
from OCP.BRepMesh import BRepMesh_IncrementalMesh
from OCP.gp import gp_Pnt
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.TopExp import TopExp_Explorer
from OCP.TopoDS import TopoDS_Compound
@ -106,8 +110,8 @@ from OCP.TopLoc import TopLoc_Location
from py_lib3mf import Lib3MF
from build123d.build_enums import MeshType, Unit
from build123d.geometry import Color, TOLERANCE
from build123d.topology import Compound, Shape, Shell, Solid, downcast
from build123d.geometry import Color, TOLERANCE, Vector
from build123d.topology import Compound, Face, Shape, Shell, Solid, downcast
class Mesher:
@ -455,8 +459,11 @@ class Mesher:
# Create the triangular face using the polygon
polygon_builder = BRepBuilderAPI_MakePolygon(*ocp_vertices, Close=True)
face_builder = BRepBuilderAPI_MakeFace(polygon_builder.Wire())
# Add new Face to Shell
shell_builder.Add(face_builder.Face())
facet = 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
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())
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__":
unittest.main()