#!/usr/bin/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 MotorEdge(edges.BaseEdge): # def margin(self): # return 30 def __call__(self, l, **kw): self.polyline( l - 165, 45, 25 * 2 ** 0.5, -45, 60, -45, 25 * 2 ** 0.5, 45, 55) class OutsetEdge(edges.OutSetEdge): def startwidth(self): return 20 class HangerEdge(edges.BaseEdge): char = "H" def margin(self): return 40 def __call__(self, l, **kw): self.fingerHolesAt(0, -0.5 * self.thickness, l, angle=0) w = self.settings self.polyline(0, -90, 22 + w, 90, 70, 135, 2 ** 0.5 * 12, 45, 35, -45, 2 ** 0.5 * 0.5 * w, -90, 2 ** 0.5 * 0.5 * w, -45, l - 28, 45, 2 ** 0.5 * 5, 45, 5, -90) class RollerEdge(edges.BaseEdge): def margin(self): return 20 def __call__(self, l, **kw): m = 40 + 100 self.polyline((l - m) / 2.0, -45, 2 ** 0.5 * 20, 45, 100, 45, 2 ** 0.5 * 20, -45, (l - m) / 2.0) class RollerEdge2(edges.BaseEdge): def margin(self): return self.thickness def __call__(self, l, **kw): a = 30 f = 1 / math.cos(math.radians(a)) self.edges["f"](70) self.polyline(0, a, f * 25, -a, l - 190, -a, f * 25, a, 0) self.edges["f"](70) class Rotary(Boxes): """Rotary Attachment for engraving cylindrical objects in a laser cutter""" ui_group = "Unstable" def __init__(self): Boxes.__init__(self) self.addSettingsArgs(edges.FingerJointSettings) self.argparser.add_argument( "--diameter", action="store", type=float, default=72., help="outer diameter of the wheels (including O rings)") self.argparser.add_argument( "--rubberthickness", action="store", type=float, default=5., help="diameter of the strings of the O rings") self.argparser.add_argument( "--axle", action="store", type=float, default=6., help="diameter of the axles") self.argparser.add_argument( "--knifethickness", action="store", type=float, default=8., help="thickness of the knifes in mm. Use 0 for use with honey comb table.") self.argparser.add_argument( "--beamwidth", action="store", type=float, default=32., help="width of the (aluminium) profile connecting the parts") self.argparser.add_argument( "--beamheight", action="store", type=float, default=7.1, help="height of the (aluminium) profile connecting the parts") def mainPlate(self): # Motor block outer side t = self.thickness d = self.diameter a = self.axle bw, bh = self.beamwidth, self.beamheight hh = 0.5 * d + bh + 2 # hole height self.hole(1.0 * d, hh, a/2.) #self.hole(1.0 * d, hh, d/2.) self.hole(2.0 * d + 5, hh, a/2.) #self.hole(2.0 * d + 5, hh, d/2.) # Main beam self.rectangularHole(1.5*d+2.5, 0.5*bh, bw, bh) def frontPlate(self): # Motor block inner side with motor mount t = self.thickness d = self.diameter a = self.axle bw, bh = self.beamwidth, self.beamheight hh = 0.5 * d + bh + 2 # hole height self.hole(1.0 * d, hh, a/2.) #self.hole(1.0 * d, hh, d/2.) self.hole(2.0 * d + 5, hh, a/2.) #self.hole(2.0 * d + 5, hh, d/2.) # Main beam self.rectangularHole(1.5 * d+2.5, 0.5 * bh, bw, bh) # Motor mx = 2.7 * d + 20 self.rectangularHole(mx, hh, 36 + 20, 36, r=36 / 2.0) for x in (-1, 1): for y in (-1,1): self.rectangularHole(mx+x * 25, hh + y * 25, 20, 4, r=2) def link(self, x, y, a, middleHole=False, move=None): t = self.thickness overallwidth = x + y overallheight = y ra = a / 2.0 if self.move(overallwidth, overallheight, move, before=True): return self.moveTo(y / 2.0, 0) self.hole(0, y / 2., ra) self.hole(x, y / 2., ra) if middleHole: self.hole(x / 2., y / 2., ra) self.edge(10) self.edges["F"](60) self.polyline(x - 70, (180, y / 2.), x, (180, y / 2.)) self.move(overallwidth, overallheight, move) def holderBaseCB(self): bw, bh = self.beamwidth, self.beamheight self.hole(20, self.hh - 10, self.a / 2) self.rectangularHole(self.hl - 70, self.hh - 10, 110, self.a, r=self.a / 2) self.rectangularHole(self.hl / 2, 0.5 * bh, bw, bh) def holderTopCB(self): self.fingerHolesAt(0, 30 - 0.5 * self.thickness, self.hl, 0) d = self.diameter / 2.0 + 1 # XXX y = -0.5 * self.diameter + self.th + self.hh - self.beamheight - 2. self.hole(self.hl / 2 + d, y, self.axle / 2.0) self.hole(self.hl / 2 - d, y, self.axle / 2.0) self.hole(self.hl / 2 + d, y, self.diameter / 2.0) self.hole(self.hl / 2 - d, y, self.diameter / 2.0) def render(self): # adjust to the variables you want in the local scope t = self.thickness d = self.diameter a = self.a = self.axle bw, bh = self.beamwidth, self.beamheight # self.spacing = 0.1 * t # Change settings of default edges if needed. E.g.: self.edges["f"].settings.setValues(self.thickness, space=2, finger=2, surroundingspaces=1) if self.knifethickness: self.addPart(HangerEdge(self, self.knifethickness)) else: self.edges["H"] = self.edges["F"] # Holder hw = self.hw = 70. hh = self.hh = 35. + bh hl = self.hl = 240 # Base self.rectangularWall(hl, hh, edges="hfef", callback=[self.holderBaseCB, None, lambda: self.rectangularHole(hl / 2 + 50, hh - t / 2 - 1, 60, t + 2)], move="up") self.rectangularWall(hl, hh, edges="hfef", callback=[self.holderBaseCB], move="up") self.rectangularWall(hl, hw, edges="ffff", callback=[lambda: self.hole(hl / 2 - 16 - 20, 25, 5)], move="up") with self.saved_context(): self.rectangularWall(hw, hh, edges="hFeF", callback=[ lambda: self.hole(hw / 2, hh - 20, 4)],move="right") self.rectangularWall(hw, hh, edges="hFeF", move="right") # Top th = self.th = 30 # sides self.rectangularWall(hw + 20, th, edges="fFeF", move="right", callback=[lambda: self.fingerHolesAt(20 - 0.5 * t, 0, th)]) self.rectangularWall(hw + 20, th, edges="fFeF", move="right", callback=[lambda: self.fingerHolesAt(20 - 0.5 * t, 0, th)]) self.rectangularWall(hw, hh, edges="hFeF", move="up only") outset = OutsetEdge(self, None) roller2 = RollerEdge2(self, None) self.rectangularWall(hl, th, edges=[roller2, "f", "e", "f"], callback=[ lambda: self.hole(20, 15, a / 2), None, lambda: self.rectangularHole(50, th - 15, 70, a, r=a / 2)], move="up") self.rectangularWall(hl, th, edges=[roller2, "f", "e", "f"], callback=[ lambda: self.hole(20, 15, a / 2), None, lambda: self.rectangularHole(50, th - 15 - t, 70, a, r=a / 2)], move="up") self.rectangularWall(hl, th, edges=[roller2, "f", RollerEdge(self, None), "f"], callback=[ self.holderTopCB], move="up") self.rectangularWall(hl, 20 - t, edges="feee", move="up") tl = 70 self.rectangularWall(tl, hw + 20, edges="FeFF", move="right", callback=[None, lambda: self.fingerHolesAt(20 - 0.5 * t, 0, tl)]) self.rectangularWall(tl, hw + 20, edges="FeFF", move="", callback=[None, lambda: self.fingerHolesAt(20 - 0.5 * t, 0, tl)]) self.rectangularWall(tl, hw + 20, edges="FeFF", move="left up only", callback=[None, lambda: self.fingerHolesAt(20 - 0.5 * t, 0, tl)]) # Links self.link(hl - 40, 25, a, True, move="up") self.link(hl - 40, 25, a, True, move="up") self.link(hl - 40, 25, a, True, move="up") self.link(hl - 40, 25, a, True, move="up") with self.saved_context(): self.rectangularWall(hw - 2 * t - 2, 60, edges="efef", move="right") self.rectangularWall(hw - 4 * t - 4, 60, edges="efef", move="right") # Spindel auxiliaries self.parts.waivyKnob(50, callback=lambda: self.nutHole("M8"), move="right") self.parts.waivyKnob(50, callback=lambda: self.nutHole("M8"), move="right") self.rectangularWall(hw - 2 * t - 4, 60, edges="efef", move="up only") with self.saved_context(): slot = edges.SlottedEdge(self, [(30 - t) / 2, (30 - t) / 2], slots=15) self.rectangularWall(30, 30, edges=["e", "e", slot, "e"], callback=[lambda: self.hole(7, 23, self.axle / 2)], move="right") self.rectangularWall(30, 30, edges=["e", "e", slot, "e"], callback=[lambda: self.hole(7, 23, self.axle / 2)], move="right") leftover = (hw - 6 * t - 6 - 20) / 2.0 slot = edges.SlottedEdge(self, [leftover, 20, leftover], slots=15) self.rectangularWall(hw - 4 * t - 6, 30, edges=[slot, "e", "e", "e"], callback=[lambda: self.hole((hw - 4 * t - 6) / 2., 15, 4)], move="right") for i in range(3): self.rectangularWall(20, 30, callback=[lambda: self.nutHole("M8", 10, 15)], move="right") self.rectangularWall(20, 30, callback=[lambda: self.hole(10, 15, 4)], move="right") self.rectangularWall(30, 30, move="up only") self.h = h = bh + 2 + 1.0 * d # height of outer pieces # Other side if self.knifethickness: ow = 10 self.rectangularWall(3.6 * d, h, edges="hfFf", callback=[ lambda:self.rectangularHole(1.8 * d, 0.5 * bh, bw, bh)], move="up") self.rectangularWall(3.6 * d, h, edges="hfFf", callback=[ lambda:self.rectangularHole(1.8 * d, 0.5 * bh, bw, bh)], move="up") self.rectangularWall(3.6 * d, ow, edges="ffff", move="up") self.rectangularWall(3.6 * d, ow, edges="ffff", move="up") with self.saved_context(): self.rectangularWall(ow, h, edges="hFFH", move="right") self.rectangularWall(ow, h, edges="hFFH", move="right") self.rectangularWall(ow, h, edges="hFFH", move="up only") # Motor block mw = 40 self.rectangularWall(3.6 * d, h, edges=["h", "f", MotorEdge(self, None),"f"], callback=[self.mainPlate], move="up") self.rectangularWall(3.6 * d, h, edges=["h", "f", MotorEdge(self, None),"f"], callback=[self.frontPlate], move="up") self.rectangularWall(3.6 * d, mw, edges="ffff", move="up") with self.saved_context(): self.rectangularWall(mw, h, edges="hFeH", move="right") self.rectangularWall(mw, h, edges="hFeH", move="right") self.pulley(88, "GT2_2mm", r_axle=a / 2.0, move="right") self.pulley(88, "GT2_2mm", r_axle=a / 2.0, move="right") self.rectangularWall(mw, h, edges="hFeH", move="up only") self.axle = 19 for i in range(3): self.parts.disc(self.diameter - 2 * self.rubberthickness, hole=self.axle, move="right") self.parts.disc(self.diameter - 2 * self.rubberthickness, hole=self.axle, move="up right") for i in range(3): self.parts.disc(self.diameter - 2 * self.rubberthickness, hole=self.axle, move="left") self.parts.disc(self.diameter - 2 * self.rubberthickness, hole=self.axle, move="left up") for i in range(3): self.parts.disc(self.diameter - 2 * self.rubberthickness + 4, hole=self.axle, move="right") self.parts.disc(self.diameter - 2 * self.rubberthickness + 4, hole=self.axle, move="right up")