From e9549288e86cead696d44e80d3773eadcc75a4f5 Mon Sep 17 00:00:00 2001 From: Florian Festi Date: Sat, 23 Mar 2024 14:49:46 +0100 Subject: [PATCH] Replace circleSquareHole by parts and callbacks Use partsMatrix to allign the lock pieces more nicely --- boxes/generators/coinbanksafe.py | 112 ++++++++++--------------------- 1 file changed, 37 insertions(+), 75 deletions(-) diff --git a/boxes/generators/coinbanksafe.py b/boxes/generators/coinbanksafe.py index e9f5ba3b..05f0a441 100644 --- a/boxes/generators/coinbanksafe.py +++ b/boxes/generators/coinbanksafe.py @@ -15,6 +15,7 @@ from boxes import * + class CoinBankSafe(Boxes): """A piggy-bank designed to look like a safe.""" @@ -26,7 +27,7 @@ class CoinBankSafe(Boxes): ![Open](static/samples/CoinBankSafe-2.jpg) ''' - + ui_group = "Misc" def __init__(self) -> None: @@ -45,44 +46,14 @@ def __init__(self) -> None: self.argparser.add_argument( "--handleclearance", action="store", type=float, default=1.5, help="Clearance of handle in multiples of thickness") - - def circleSquareHole(self, x, y, radius, variant=False): - t = self.thickness - with self.saved_context(): - self.moveTo(x, y) - self.rectangularHole(0, 0, t, t) - if variant == "D": - self.moveTo(0,0,45) - self.rectangularHole(0, 0, t, t) - with self.saved_context(): - if not variant: - self.circle(x, y, radius) - elif variant == "D": - # can't use dhole because it's a part, not a hole - # self.dHole(x, y, radius, rel_w=0.80) - rel_w = 0.8 - w = 2.0 * radius * rel_w - w -= radius - a = math.degrees(math.acos(w / radius)) - self.moveTo(x, y, -a) - self.moveTo(radius, 0, -90) - self.corner(-360+2*a, radius) - self.corner(-a) - self.edge(2*radius*math.sin(math.radians(a))) - elif variant == "W": - # need to deal with the annoying margin applied to all Parts - self.moveTo(-t/2, -t/2) # resolve weird margin thing of parts - self.parts.waivyKnob(radius*2) def drawNumbers(self, radius, cover): fontsize = 0.9 * (radius - cover) - with self.saved_context(): - self.moveTo(radius, radius) - for num in range(8): - angle = num*45 - x = (cover + fontsize *0.4) * math.sin(math.radians(angle)) - y = (cover + fontsize *0.4) * math.cos(math.radians(angle)) - self.text(str(num+1), align="center middle", fontsize=fontsize, angle=-angle, color=[1,0,0], + for num in range(8): + angle = num*45 + x = (cover + fontsize *0.4) * math.sin(math.radians(angle)) + y = (cover + fontsize *0.4) * math.cos(math.radians(angle)) + self.text(str(num+1), align="center middle", fontsize=fontsize, angle=-angle, color=[1,0,0], y=y, x=x) def lockPin(self, layers, move=None): @@ -149,15 +120,13 @@ def render(self): move="mirror right") # locking bar - with self.saved_context(): - self.moveTo(0, 4*t) - self.rectangularWall(1.33*t, h, "eeef", move="right") - self.rectangularWall(1.33*t, h, "eeef", move="right only") + self.moveTo(0, self.edges['s'].spacing() + t) + self.rectangularWall(1.33*t, h, "eeef", move="right") # door door_clearance = .1 * t # amount to shave off of the door width so it can open before_hinge = 1.25 * t - door_clearance after_hinge = y - 2.25 * t - door_clearance - self.moveTo(1, 1+t*4) + self.moveTo(self.spacing/2, -t) self.polyline( after_hinge, -90, t, 90, t, 90, t, -90, before_hinge, 90, h, 90, @@ -171,56 +140,49 @@ def render(self): min_height = 6*big_radius + 4 raise ValueError(f"With thickness {t}, h must be at least {min_height} to fit the dials.") - self.circleSquareHole(3*t - door_clearance, h/2, 1.25 * t) - self.circleSquareHole(3*t - door_clearance, h/2 - (2*big_radius + dial_spacing), 1.25 * t) - self.circleSquareHole(3*t - door_clearance, h/2 + (2*big_radius + dial_spacing), 1.25 * t) + for pos_y in (h/2, + h/2 - (2*big_radius + dial_spacing), + h/2 + (2*big_radius + dial_spacing)): + self.hole(3*t - door_clearance, pos_y, 1.25 * t) + self.rectangularHole(3*t - door_clearance, pos_y, t, t) self.rectangularHole(y/2 - door_clearance, h/2, t, handle_length / 2) - + self.rectangularWall(x, h, "seff", move="up only") # top self.rectangularWall( y, x, "efff", callback=[ lambda: self.rectangularHole(y/2, x/2, slot_length, slot_width), - lambda: self.circleSquareHole(1.75*t, 1.75*t, 1.15*t)], + lambda: (self.hole(1.75*t, 1.75*t, 1.15*t), + self.rectangularHole(1.75*t, 1.75*t, t, t))], label="top", move="right") # bottom self.rectangularWall( y, x, "efff", callback=[ - lambda: self.circleSquareHole(1.75*t, 1.75*t, 1.15*t)], + lambda: (self.hole(1.75*t, 1.75*t, 1.15*t), + self.rectangularHole(1.75*t, 1.75*t, t, t))], label="bottom", move="right") + def holeCB(): + self.rectangularHole(0, 0, t, t) + self.moveTo(0, 0, 45) + self.rectangularHole(0, 0, t, t) + # locks with self.saved_context(): - self.circleSquareHole(big_radius, big_radius, big_radius) - self.drawNumbers(big_radius, small_radius) - self.moveTo(2 * big_radius + spacing, 0) - self.circleSquareHole(big_radius, big_radius, big_radius) - self.drawNumbers(big_radius, small_radius) - self.moveTo(2 * big_radius + spacing, 0) - self.circleSquareHole(big_radius, big_radius, big_radius) - self.drawNumbers(big_radius, small_radius) - self.moveTo(2 * big_radius + spacing, 0) - self.circleSquareHole(big_radius, big_radius, big_radius, "D") - self.moveTo(2 * 0.8 * big_radius + spacing, 0) - self.circleSquareHole(big_radius, big_radius, big_radius, "D") - self.moveTo(2 * 0.8 * big_radius + spacing, 0) - self.circleSquareHole(big_radius, big_radius, big_radius, "D") - self.moveTo(2 * 0.8 * big_radius + spacing, 0) - - self.circleSquareHole(small_radius, small_radius, small_radius) - self.moveTo(2 * small_radius + spacing, 0) - self.circleSquareHole(small_radius, small_radius, small_radius) - self.moveTo(2 * small_radius + spacing, 0) - self.circleSquareHole(small_radius, small_radius, small_radius) - self.moveTo(2 * small_radius + spacing, 0) - self.circleSquareHole(small_radius, small_radius, small_radius, "W") - self.moveTo(2 * small_radius + spacing, 0) - self.circleSquareHole(small_radius, small_radius, small_radius, "W") - self.moveTo(2 * small_radius + spacing, 0) - self.circleSquareHole(small_radius, small_radius, small_radius, "W") - self.moveTo(0, 2 * big_radius + spacing) + self.partsMatrix(3, 1, "right", self.parts.disc, 2*big_radius, + callback=lambda: (self.drawNumbers(big_radius, small_radius), self.rectangularHole(0, 0, t, t))) + self.partsMatrix(3, 1, "right", self.parts.disc, 2*big_radius, + dwidth=0.8,callback=holeCB) + self.partsMatrix( + 3, 1, "right", self.parts.disc, 2*small_radius, + callback=lambda:self.rectangularHole(0, 0, t, t)) + self.partsMatrix( + 3, 1, "right", self.parts.waivyKnob, 2*small_radius, + callback=lambda:self.rectangularHole(0, 0, t, t)) + + self.partsMatrix(3, 1, "up only", self.parts.disc, 2*big_radius) # lock pins with self.saved_context():