New generator: PirateChest

A chest with integrated hinge and angled lid
This commit is contained in:
J-Waal 2023-04-08 23:39:41 +02:00 committed by Florian Festi
parent 7ce8e4b6ee
commit 84ef9d84ee
4 changed files with 135 additions and 0 deletions

View File

@ -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 <http://www.gnu.org/licenses/>.
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

View File

@ -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