diff --git a/boxes/generators/slatwallpinrow.py b/boxes/generators/slatwallpinrow.py new file mode 100644 index 0000000..c4bdf44 --- /dev/null +++ b/boxes/generators/slatwallpinrow.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python3 +# Copyright (C) 2013-2019 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 PinEdge(edges.BaseEdge): + def __call__(self, length, **kw): + w2 = self.settings.pinwidth/2 + l = self.settings.pinlength + s = self.settings.pinspacing + inc = self.settings.pinspacing_increment + t = self.settings.thickness + + pin = [0, -90, l+t-w2, (180, w2), l+t-w2, -90] + + self.edge(s/2-w2) + s += inc/2 + for i in range(self.pins-1): + self.polyline(*pin, s-2*w2) + s+=inc + self.polyline(*pin, s/2-w2-inc/4) + + def margin(self): + return self.settings.thickness+self.settings.pinlength + +class SlatwallPinRow(Boxes): + """Outset and angled plate to mount stuff to""" + + ui_group = "Unstable" + ui_group = "SlatWall" + + def __init__(self): + Boxes.__init__(self) + + self.addSettingsArgs(edges.FingerJointSettings, surroundingspaces=0.0) + self.addSettingsArgs(edges.SlatWallSettings) + + self.argparser.add_argument( + "--pins", action="store", type=int, default=8, + help="number of pins") + self.argparser.add_argument( + "--pinlength", action="store", type=float, default=35, + help="length of pins (in mm)") + self.argparser.add_argument( + "--pinwidth", action="store", type=float, default=10, + help="width of pins (in mm)") + self.argparser.add_argument( + "--pinspacing", action="store", type=float, default=35, + help="space from middle to middle of pins (in mm)") + self.argparser.add_argument( + "--pinspacing_increment", action="store", type=float, default=0.0, + help="increase spacing from left to right (in mm)") + self.argparser.add_argument( + "--angle", action="store", type=float, default=20.0, + help="angle of the pins pointing up (in degrees)") + + self.argparser.add_argument( + "--hooks", action="store", type=int, default=3, + help="number of hooks into the slatwall") + self.argparser.add_argument( + "--h", action="store", type=float, default=50.0, + help="height of the front plate (in mm) - needs to be at least 7 time the thickness") + + def frontCB(self): + s = self.pinspacing + inc = self.pinspacing_increment + t = self.thickness + + pos = s/2 + s += 0.5*inc + for i in range(self.pins): + self.rectangularHole(pos, 2*t, self.pinwidth, t) + pos += s + s+=inc + + for i in range(1, self.hooks-1): + self.fingerHolesAt(i*self.x/(self.hooks-1), self.h/2, self.h/2) + + + def backCB(self): + t = self.thickness + self.fingerHolesAt(0, 2.5*t, self.x, 0) + if self.angle < 0.001: + return + for i in range(1, self.hooks-1): + self.fingerHolesAt(i*self.x/(self.hooks-1), 3*t, self.h/2-3*t) + + def sideWall(self, move=None): + a = self.angle + ar = math.radians(a) + h = self.h + t = self.thickness + + sh = math.sin(ar)*6*t + math.cos(ar)*h + + tw = self.edges["a"].margin() + math.sin(ar)*h + math.cos(ar)*6*t + th = sh + 6 + if self.move(tw, th, move, True): + return + + self.moveTo(self.edges["a"].margin()) + + self.polyline(math.sin(ar)*h, a, 4*t) + self.fingerHolesAt(-3.5*t, 0, h/2, 90) + self.edgeCorner("e", "h") + self.edges["h"](h) + self.polyline(0, 90-a, math.cos(ar)*6*t, 90) + self.edges["a"](sh) + self.corner(90) + + self.move(tw, th, move) + + + def supportWall(self, move=None): + a = self.angle + ar = math.radians(a) + h = self.h + t = self.thickness + + sh = math.sin(ar)*6*t + math.cos(ar)*h + + tw = self.edges["a"].margin() + max( + math.sin(ar)*h/2 + math.cos(ar)*5*t, + math.sin(ar)*h) + th = sh + 6 + if self.move(tw, th, move, True): + return + + self.moveTo(self.edges["a"].margin()) + + if a > 0.001: + self.polyline(math.sin(ar)*h, a+90, 3*t) + self.edges["f"](h/2-3*t) + self.polyline(0, -90) + self.polyline(4*t, 90) + self.edges["f"](h/2) + self.polyline(math.sin(ar)*2*t, 90-a, + math.cos(ar)*4*t - math.sin(ar)**2*2*t, 90) + if a > 0.001: + self.edges["a"](sh) + else: + self.edges["a"](h/2) + self.corner(90) + + self.move(tw, th, move) + + + def render(self): + # Add slat wall edges + s = edges.SlatWallSettings(self.thickness, True, + **self.edgesettings.get("SlatWall", {})) + s.edgeObjects(self) + self.slatWallHolesAt = edges.SlatWallHoles(self, s) + + p = PinEdge(self, self) + n = self.pins + t = self.thickness + + if self.h < 7*t: + self.h = 7*t + + self.x = x = n*self.pinspacing + (n)*(n-1)/2 *self.pinspacing_increment + + + self.rectangularWall(x, 3*t, [p, "f", "f", "f"], move="up") + self.rectangularWall(x, self.h, "efef", callback=[self.frontCB], + move="up") + self.rectangularWall(x, self.h/2, "efef", callback=[self.backCB], + move="up") + self.sideWall(move="right") + for i in range(self.hooks-2): + self.supportWall(move="right") + self.sideWall(move="right")