Fix import stl as Shell

This commit is contained in:
gumyr 2023-07-27 10:18:20 -04:00
parent a0fcba378b
commit 80fffa78ca
2 changed files with 29 additions and 12 deletions

View file

@ -48,7 +48,6 @@ from OCP.BRepBuilderAPI import (
BRepBuilderAPI_Sewing,
)
from OCP.gp import gp_Pnt
from OCP.ShapeAnalysis import ShapeAnalysis_Shell
from build123d.topology import (
Compound,
@ -185,16 +184,24 @@ def import_stl(file_name: str, for_reference: bool = True) -> Union[Face, Solid]
shell_builder.Add(face)
shell_builder.Perform()
occ_shell = downcast(shell_builder.SewedShape())
shell_analyzer = ShapeAnalysis_Shell()
shell_analyzer.LoadShells(occ_shell)
is_manifold = shell_analyzer.HasFreeEdges()
# Check of the shell is open or closed
edge_count = {}
for face in Shell(occ_shell).faces():
for edge in face.edges():
if edge in edge_count:
edge_count[edge] += 1
else:
edge_count[edge] = 1
unique_edges = [edge for edge, count in edge_count.items() if count == 1]
# Create a solid
if is_manifold:
if unique_edges:
stl_obj = Shell(occ_shell)
else:
solid_builder = BRepBuilderAPI_MakeSolid(occ_shell)
stl_obj = Solid(solid_builder.Solid())
else:
stl_obj = Shell(occ_shell)
return stl_obj

View file

@ -1161,20 +1161,30 @@ class TestImportExport(DirectApiTestCase):
step_box = import_step("test_box.step")
def test_import_stl(self):
# import solid
original_box = Solid.make_box(1, 2, 3)
original_box.export_stl("test_box.stl")
stl_box = import_stl("test_box.stl", for_reference=False).clean()
original_box.export_stl("test.stl")
stl_box = import_stl("test.stl", for_reference=False).clean()
self.assertEqual(len(stl_box.vertices()), 8)
self.assertEqual(len(stl_box.edges()), 12)
self.assertEqual(len(stl_box.faces()), 6)
self.assertTrue(isinstance(stl_box, Solid))
self.assertAlmostEqual(stl_box.volume, 1 * 2 * 3, 5)
stl_box = import_stl("test_box.stl", for_reference=True)
# import as face
stl_box = import_stl("test.stl", for_reference=True)
self.assertVectorAlmostEquals(stl_box.position, (0, 0, 0), 5)
os.remove("test_box.stl")
# import shell
original_face = Face.make_rect(1, 2)
original_face.export_stl("test.stl")
stl_face = import_stl("test.stl", for_reference=False).clean()
self.assertTrue(isinstance(stl_face, Shell))
# missing file
os.remove("test.stl")
with self.assertRaises(ValueError):
import_stl("test_box.stl", for_reference=False)
import_stl("test.stl", for_reference=False)
class TestJoints(DirectApiTestCase):