diff --git a/boxes/generators/coasterholder.py b/boxes/generators/coasterholder.py new file mode 100644 index 000000000..31695bc3f --- /dev/null +++ b/boxes/generators/coasterholder.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python3 +# Copyright (C) 2013-2014 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 * +from boxes.lids import LidSettings + + +class CoasterHolder(Boxes): + """A coaste holder""" + + description = "This is a coaster holder" + + ui_group = "Box" + + def __init__(self) -> None: + Boxes.__init__(self) + self.buildArgParser(x=102, y=102, h=35) + self.argparser.add_argument( + "--opening", action="store", type=float, default=40, + help="percent of front that's open") + self.argparser.add_argument( + "--bottom_radius", action="store", type=float, default=5, + help="radius of the bottom corners") + self.argparser.add_argument( + "--short_wall_radius", action="store", type=float, default=10, + help="radius of the short wall corner") + self.argparser.add_argument( + "--flange_out", action="store", type=float, default=5, + help="size of the over flange") + + def bottomWall(self, x, y, o, flange=5.0, r=10.0, callback=None, move=None, label=""): + rl = min(r, flange) + + if self.move(x+2*flange+2*self.thickness, y+2*flange+2*self.thickness, move, before=True): + return + + # bottom desk + with self.saved_context(): + self.moveTo(rl, 0) + self.edge(x + (flange-rl)*2 + self.thickness*2) + self.corner(90, rl) + self.edge(y + (flange-rl)*2 + self.thickness*2) + self.corner(90, rl) + self.edge(x + (flange - rl) * 2 + self.thickness*2) + self.corner(90, rl) + self.edge(y + (flange - rl) * 2 + self.thickness*2) + self.corner(90, rl) + + self.moveTo(self.thickness*0.5+flange, self.thickness*0.5+flange) + d = x * (1 - o / 100) / 2 + # bottom short holes + self.fingerHolesAt(self.thickness*0.5, 0, d, 0) + self.fingerHolesAt(x - d + self.thickness*0.5, 0, d, 0) + # right holes + self.fingerHolesAt(x+self.thickness, self.thickness*0.5, y, 90) + # left holes + self.fingerHolesAt(0, y+0.5*self.thickness, y, 270) + # top short holes + self.fingerHolesAt(x+self.thickness*0.5, y+self.thickness, d, 180) + self.fingerHolesAt(d+self.thickness*0.5, y+self.thickness, d, 180) + + self.move(x+2*flange+2*self.thickness, y+2*flange+2*self.thickness, move, label=label) + + + + def shorterWall(self, x, h, o, r=2.0, callback=None, move=None, label=""): + sl = x * (1 - o / 100) / 2 + rl = min(r, max(sl, h)) + + if self.move(sl+self.thickness, h+self.thickness, move, before=True): + return + self.moveTo(self.thickness,self.thickness) + self.edges["f"](sl) + self.corner(90) + self.edges["e"](h-rl-self.burn) + self.corner(90, rl) + self.edges["e"](sl-rl-self.burn) + self.corner(90) + self.edges["f"](h) + + self.move(sl + self.thickness, h + self.thickness, move, label=label) + + def render(self): + x, y, h = self.x, self.y, self.h + r_out = self.bottom_radius + r_wall = self.short_wall_radius + flange_out = self.flange_out + o = self.opening + + self.bottomWall(x, y, o, flange_out, r_out) + self.bottomWall(x, y, o, flange_out, r_out, move="right only") + + self.rectangularWall(y, h, ["f", "F", "e", "F"], + ignore_widths=[1, 6], move="up") + self.rectangularWall(y, h, ["f", "F", "e", "F"], ignore_widths=[1, 6], move="up") + + self.shorterWall(x, h, o, r_wall, move="right") + self.shorterWall(x, h, o, r_wall, move="right mirror") + + self.shorterWall(x, h, o, r_wall, move="right") + self.shorterWall(x, h, o, r_wall, move="right mirror") diff --git a/static/samples/CoasterHolder-thumb.jpg b/static/samples/CoasterHolder-thumb.jpg new file mode 100644 index 000000000..874db1e31 Binary files /dev/null and b/static/samples/CoasterHolder-thumb.jpg differ diff --git a/static/samples/CoasterHolder.jpg b/static/samples/CoasterHolder.jpg new file mode 100755 index 000000000..01e2d05b7 Binary files /dev/null and b/static/samples/CoasterHolder.jpg differ diff --git a/static/samples/samples.sha256 b/static/samples/samples.sha256 index 1496df5bf..c9ed9647d 100644 --- a/static/samples/samples.sha256 +++ b/static/samples/samples.sha256 @@ -142,3 +142,4 @@ c8adb0661956430ccec7fc00aa4b8e3c42d02083e17a9307541bc0160251cb96 ../static/samp fda14ba0920ef7ea0579117a30b5bb4a05ab3be4da3d87a4fc03fc40b085992b ../static/samples/PirateChest.jpg 125033a02263e74d5688287936f54cd83e917276b7c35f3fd37e6cb86efc0dcc ../static/samples/Shoe.jpg 7bf29dc9e2f0b5a0bbedc8b7b6814fe4cec58e9dcebfcd1167757a2bbcc91c17 ../static/samples/Hook.jpg +37f084837ba5177dff8af8e2f695695ea9567a9e76051b33beef064953bb0a96 ../static/samples/CoasterHolder.jpg