diff --git a/boxes/generators/piratechest.py b/boxes/generators/piratechest.py new file mode 100644 index 0000000..8f3363c --- /dev/null +++ b/boxes/generators/piratechest.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python3 +# Copyright (C) 2013-2016 Florian Festi +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from boxes import * + +class PirateChest(Boxes): + """Box with polygon lid with chest hinges.""" + + description = """Do not assemble sides before attaching the lid! + Hinge of the lid has to be placed first because it is impossible + to get it in position without removing the side wall. The lid can + be a bit tricky to assemble. Keep track of how the parts fit together. + Part with label "lid back" is placed in the hinges""" + + ui_group = "Box" + + def __init__(self) -> None: + Boxes.__init__(self) + self.addSettingsArgs(edges.FingerJointSettings, finger=1.0,space=1.0) + self.addSettingsArgs(edges.HingeSettings) + + self.buildArgParser("x", "y", "h", "outside") + self.argparser.add_argument( + "--n", action="store", type=int, default=5, + help="number of sides on the lid. n ≥ 3") + + + def render(self): + # adjust to the variables you want in the local scope + x, y, h = self.x, self.y, self.h + if self.outside: + x = self.adjustSize(x) + y = self.adjustSize(y) + h = self.adjustSize(h, "f", False) + t = self.thickness + n = self.n + + if (n < 3): + raise ValueError("number of sides on the lid must be greater or equal to 3 (got %i)" % n) + + hy = self.edges["O"].startwidth() + h -= hy + if (h < 0): + raise ValueError("box to low to allow for hinge (%i)" % h) + + # create edge for non 90 degree joints in the lid + fingerJointSettings = copy.deepcopy(self.edges["f"].settings) + fingerJointSettings.setValues(self.thickness, angle=180./(n-1)) + fingerJointSettings.edgeObjects(self, chars="gGH") + + # render all parts + self.ctx.save() + + self.rectangularWall(x, y, "FFFF", move="up", label="Bottom") + frontlid, toplids, backlid = self.topside(y, n = n, move="only", bottem='P') + + self.rectangularWall(x, backlid, "qFgF", move="up", label="lid back") + for _ in range(n-2): + self.rectangularWall(x, toplids, "GFgF", move="up", label="lid top") + self.rectangularWall(x, frontlid, "GFeF", move="up", label="lid front") + + self.ctx.restore() + self.rectangularWall(x, y, "FFFF", move="right only") + + with self.saved_context(): + self.rectangularWall(x, h, "fFQF", ignore_widths=[2, 5], move="right", label="front") + self.rectangularWall(y, h, "ffof", ignore_widths=[5], move="right", label="right") + self.rectangularWall(0, h, "eeep", move="right only") + self.rectangularWall(x, h, "fFoF", move="up only") + self.rectangularWall(x, 0, "Peee", move="up only") + + e1 = edges.CompoundEdge(self, "Fe", (h, hy)) + e2 = edges.CompoundEdge(self, "eF", (hy, h)) + e_back = ("f", e1, "e", e2) + + with self.saved_context(): + self.rectangularWall(x, h+hy, e_back, move="right", label="back") # extend back to correct height + self.rectangularWall(0, h, "ePee", move="right only") + self.rectangularWall(y, h, "ffOf", ignore_widths=[2], move="right", label="left") + self.rectangularWall(x, h, "fFOF", move="up only") + self.rectangularWall(x, 0, "peee", move="up only") + + self.topside(y, n = n, move="right", bottem='p', label="lid left") + self.topside(y, n = n, move="right", bottem='P', label="lid right") + + + def topside(self, y, n, bottem, move=None, label=""): + radius, hp, side = self.regularPolygon((n - 1) * 2, h=y/2.0) + + tx = y + 2 * self.edges.get('f').spacing() + lidheight = hp if n % 2 else radius + ty = lidheight + self.edges.get('f').spacing() + self.edges.get(bottem).spacing() + + if self.move(tx, ty, move, before=True): + return side/2 + self.edges.get(bottem).spacing(), side, side/2 + + self.moveTo(self.edges.get('f').margin(), self.edges.get(bottem).margin()) + + self.edges.get(bottem)(y) + + self.corner(90) + if bottem == 'p': + self.edges.get('f')(side/2 + self.edges.get(bottem).spacing()) + else: + self.edges.get('f')(side/2) + + self.corner(180 / (n - 1)) + for _ in range(n-2): + self.edges.get('f')(side) + self.corner(180 / (n - 1)) + + if bottem == 'P': + self.edges.get('f')(side/2 + self.edges.get(bottem).spacing()) + else: + self.edges.get('f')(side/2) + + self.corner(90) + + self.move(tx, ty, move, label=label) + + return side/2 + self.edges.get(bottem).spacing(), side, side/2 diff --git a/static/samples/PirateChest-thumb.jpg b/static/samples/PirateChest-thumb.jpg new file mode 100644 index 0000000..40248cb Binary files /dev/null and b/static/samples/PirateChest-thumb.jpg differ diff --git a/static/samples/PirateChest.jpg b/static/samples/PirateChest.jpg new file mode 100644 index 0000000..fb0879b Binary files /dev/null and b/static/samples/PirateChest.jpg differ diff --git a/static/samples/samples.sha256 b/static/samples/samples.sha256 index 8a9dc7e..87484d7 100644 --- a/static/samples/samples.sha256 +++ b/static/samples/samples.sha256 @@ -139,3 +139,4 @@ e9ee43e336401d3a0cb8e141c3a0b87a84e90f99eed30bdd420dcaead92940e1 ../static/samp 3070eb2ed89461497d4dcc67021a0619338ab6d4d4d89d3cd1f83160da3c7920 ../static/samples/FanHole.jpg c8adb0661956430ccec7fc00aa4b8e3c42d02083e17a9307541bc0160251cb96 ../static/samples/HolePattern.jpg 7c399c1cd235c3c044f676a31aa5215109e815055f2f69aef5d0cb1a24dfae41 ../static/samples/Desksign.jpg +fda14ba0920ef7ea0579117a30b5bb4a05ab3be4da3d87a4fc03fc40b085992b ../static/samples/PirateChest.jpg