Merge pull request #1003 from jwagenet/slot-fixes
Some checks failed
benchmarks / benchmarks (macos-13, 3.12) (push) Has been cancelled
benchmarks / benchmarks (macos-14, 3.12) (push) Has been cancelled
benchmarks / benchmarks (ubuntu-latest, 3.12) (push) Has been cancelled
benchmarks / benchmarks (windows-latest, 3.12) (push) Has been cancelled
Upload coverage reports to Codecov / run (push) Has been cancelled
pylint / lint (3.10) (push) Has been cancelled
Run type checker / typecheck (3.10) (push) Has been cancelled
Run type checker / typecheck (3.13) (push) Has been cancelled
Wheel building and publishing / Build wheel on ubuntu-latest (push) Has been cancelled
tests / tests (macos-13, 3.10) (push) Has been cancelled
tests / tests (macos-13, 3.13) (push) Has been cancelled
tests / tests (macos-14, 3.10) (push) Has been cancelled
tests / tests (macos-14, 3.13) (push) Has been cancelled
tests / tests (ubuntu-latest, 3.10) (push) Has been cancelled
tests / tests (ubuntu-latest, 3.13) (push) Has been cancelled
tests / tests (windows-latest, 3.10) (push) Has been cancelled
tests / tests (windows-latest, 3.13) (push) Has been cancelled
Wheel building and publishing / upload_pypi (push) Has been cancelled

Bugfixes: Slot objects
This commit is contained in:
Roger Maitland 2025-06-04 19:30:35 -04:00 committed by GitHub
commit 1102dfab34
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 43 additions and 23 deletions

View file

@ -387,7 +387,7 @@ class SlotArc(BaseSketchObject):
self.slot_height = height self.slot_height = height
arc = arc if isinstance(arc, Wire) else Wire([arc]) 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) super().__init__(face, rotation, None, mode)
@ -426,10 +426,10 @@ class SlotCenterPoint(BaseSketchObject):
half_line = point_v - center_v half_line = point_v - center_v
if half_line.length * 2 <= height: if half_line.length <= 0:
raise ValueError( raise ValueError(
f"Slots must have width > height. " "Distance between center and point must be greater than 0 "
"Got: {height=} width={half_line.length * 2} (computed)" f"Got: distance = {half_line.length} (computed)"
) )
face = Face( face = Face(
@ -464,7 +464,7 @@ class SlotCenterToCenter(BaseSketchObject):
rotation: float = 0, rotation: float = 0,
mode: Mode = Mode.ADD, mode: Mode = Mode.ADD,
): ):
if center_separation <= 0: if center_separation < 0:
raise ValueError( raise ValueError(
f"Requires center_separation > 0. Got: {center_separation=}" f"Requires center_separation > 0. Got: {center_separation=}"
) )
@ -475,14 +475,18 @@ class SlotCenterToCenter(BaseSketchObject):
self.center_separation = center_separation self.center_separation = center_separation
self.slot_height = height self.slot_height = height
face = Face( if center_separation > 0:
Wire( face = Face(
[ Wire(
Edge.make_line(Vector(-center_separation / 2, 0, 0), Vector()), [
Edge.make_line(Vector(), Vector(+center_separation / 2, 0, 0)), Edge.make_line(Vector(-center_separation / 2, 0, 0), Vector()),
] Edge.make_line(Vector(), Vector(+center_separation / 2, 0, 0)),
).offset_2d(height / 2) ]
) ).offset_2d(height / 2)
)
else:
face = cast(Face, Circle(height / 2, mode=mode).face())
super().__init__(face, rotation, None, mode) super().__init__(face, rotation, None, mode)
@ -510,7 +514,7 @@ class SlotOverall(BaseSketchObject):
align: Align | tuple[Align, Align] | None = (Align.CENTER, Align.CENTER), align: Align | tuple[Align, Align] | None = (Align.CENTER, Align.CENTER),
mode: Mode = Mode.ADD, mode: Mode = Mode.ADD,
): ):
if width <= height: if width < height:
raise ValueError( raise ValueError(
f"Slot requires that width > height. Got: {width=}, {height=}" f"Slot requires that width > height. Got: {width=}, {height=}"
) )
@ -521,7 +525,7 @@ class SlotOverall(BaseSketchObject):
self.width = width self.width = width
self.slot_height = height self.slot_height = height
if width != height: if width > height:
face = Face( face = Face(
Wire( Wire(
[ [
@ -532,6 +536,7 @@ class SlotOverall(BaseSketchObject):
) )
else: else:
face = cast(Face, Circle(width / 2, mode=mode).face()) face = cast(Face, Circle(width / 2, mode=mode).face())
super().__init__(face, rotation, align, mode) super().__init__(face, rotation, align, mode)

View file

@ -328,25 +328,40 @@ class TestBuildSketchObjects(unittest.TestCase):
self.assertEqual(s.faces()[0].normal_at(), Vector(0, 0, 1)) self.assertEqual(s.faces()[0].normal_at(), Vector(0, 0, 1))
def test_slot_center_to_center(self): def test_slot_center_to_center(self):
height = 2
with BuildSketch() as test: with BuildSketch() as test:
s = SlotCenterToCenter(4, 2) s = SlotCenterToCenter(4, height)
self.assertEqual(s.center_separation, 4) 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.rotation, 0)
self.assertEqual(s.mode, Mode.ADD) 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)) 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): def test_slot_overall(self):
height = 2
with BuildSketch() as test: with BuildSketch() as test:
s = SlotOverall(6, 2) s = SlotOverall(6, height)
self.assertEqual(s.width, 6) 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.rotation, 0)
self.assertEqual(s.mode, Mode.ADD) 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)) 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): def test_text(self):
with BuildSketch() as test: with BuildSketch() as test:
t = Text("test", 2) t = Text("test", 2)
@ -530,9 +545,9 @@ class TestBuildSketchObjects(unittest.TestCase):
@pytest.mark.parametrize( @pytest.mark.parametrize(
"slot,args", "slot,args",
[ [
(SlotOverall, (5, 10)), (SlotOverall, (9, 10)),
(SlotCenterToCenter, (-1, 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): def test_invalid_slots(slot, args):