diff --git a/src/build123d/objects_sketch.py b/src/build123d/objects_sketch.py index 7e15e48..a630e29 100644 --- a/src/build123d/objects_sketch.py +++ b/src/build123d/objects_sketch.py @@ -387,7 +387,7 @@ class SlotArc(BaseSketchObject): self.slot_height = height arc = arc if isinstance(arc, Wire) else Wire([arc]) - face = Face(arc.offset_2d(height / 2)).rotate(Axis.Z, rotation) + face = Face(arc.offset_2d(height / 2)) super().__init__(face, rotation, None, mode) @@ -426,10 +426,10 @@ class SlotCenterPoint(BaseSketchObject): half_line = point_v - center_v - if half_line.length * 2 <= height: + if half_line.length <= 0: raise ValueError( - f"Slots must have width > height. " - "Got: {height=} width={half_line.length * 2} (computed)" + "Distance between center and point must be greater than 0 " + f"Got: distance = {half_line.length} (computed)" ) face = Face( @@ -464,7 +464,7 @@ class SlotCenterToCenter(BaseSketchObject): rotation: float = 0, mode: Mode = Mode.ADD, ): - if center_separation <= 0: + if center_separation < 0: raise ValueError( f"Requires center_separation > 0. Got: {center_separation=}" ) @@ -475,14 +475,18 @@ class SlotCenterToCenter(BaseSketchObject): self.center_separation = center_separation self.slot_height = height - face = Face( - Wire( - [ - Edge.make_line(Vector(-center_separation / 2, 0, 0), Vector()), - Edge.make_line(Vector(), Vector(+center_separation / 2, 0, 0)), - ] - ).offset_2d(height / 2) - ) + if center_separation > 0: + face = Face( + Wire( + [ + Edge.make_line(Vector(-center_separation / 2, 0, 0), Vector()), + Edge.make_line(Vector(), Vector(+center_separation / 2, 0, 0)), + ] + ).offset_2d(height / 2) + ) + else: + face = cast(Face, Circle(height / 2, mode=mode).face()) + super().__init__(face, rotation, None, mode) @@ -510,7 +514,7 @@ class SlotOverall(BaseSketchObject): align: Align | tuple[Align, Align] | None = (Align.CENTER, Align.CENTER), mode: Mode = Mode.ADD, ): - if width <= height: + if width < height: raise ValueError( f"Slot requires that width > height. Got: {width=}, {height=}" ) @@ -521,7 +525,7 @@ class SlotOverall(BaseSketchObject): self.width = width self.slot_height = height - if width != height: + if width > height: face = Face( Wire( [ @@ -532,6 +536,7 @@ class SlotOverall(BaseSketchObject): ) else: face = cast(Face, Circle(width / 2, mode=mode).face()) + super().__init__(face, rotation, align, mode) diff --git a/tests/test_build_sketch.py b/tests/test_build_sketch.py index b2eeb54..bb898a0 100644 --- a/tests/test_build_sketch.py +++ b/tests/test_build_sketch.py @@ -328,25 +328,40 @@ class TestBuildSketchObjects(unittest.TestCase): self.assertEqual(s.faces()[0].normal_at(), Vector(0, 0, 1)) def test_slot_center_to_center(self): + height = 2 with BuildSketch() as test: - s = SlotCenterToCenter(4, 2) + s = SlotCenterToCenter(4, height) self.assertEqual(s.center_separation, 4) - self.assertEqual(s.slot_height, 2) + self.assertEqual(s.slot_height, height) self.assertEqual(s.rotation, 0) self.assertEqual(s.mode, Mode.ADD) - self.assertAlmostEqual(test.sketch.area, pi + 4 * 2, 5) + self.assertAlmostEqual(test.sketch.area, pi + 4 * height, 5) self.assertEqual(s.faces()[0].normal_at(), Vector(0, 0, 1)) + # Circle degenerate + s1 = SlotCenterToCenter(0, height) + self.assertTrue(len(s1.edges()) == 1) + self.assertEqual(s1.edge().geom_type, GeomType.CIRCLE) + self.assertAlmostEqual(s1.edge().radius, height / 2) + + def test_slot_overall(self): + height = 2 with BuildSketch() as test: - s = SlotOverall(6, 2) + s = SlotOverall(6, height) self.assertEqual(s.width, 6) - self.assertEqual(s.slot_height, 2) + self.assertEqual(s.slot_height, height) self.assertEqual(s.rotation, 0) self.assertEqual(s.mode, Mode.ADD) - self.assertAlmostEqual(test.sketch.area, pi + 4 * 2, 5) + self.assertAlmostEqual(test.sketch.area, pi + 4 * height, 5) self.assertEqual(s.faces()[0].normal_at(), Vector(0, 0, 1)) + # Circle degenerat + s1 = SlotOverall(2, height) + self.assertTrue(len(s1.edges()) == 1) + self.assertEqual(s1.edge().geom_type, GeomType.CIRCLE) + self.assertAlmostEqual(s1.edge().radius, height / 2) + def test_text(self): with BuildSketch() as test: t = Text("test", 2) @@ -530,9 +545,9 @@ class TestBuildSketchObjects(unittest.TestCase): @pytest.mark.parametrize( "slot,args", [ - (SlotOverall, (5, 10)), + (SlotOverall, (9, 10)), (SlotCenterToCenter, (-1, 10)), - (SlotCenterPoint, ((0, 0, 0), (2, 0, 0), 10)), + (SlotCenterPoint, ((0, 0, 0), (0, 0, 0), 10)), ], ) def test_invalid_slots(slot, args):