Source code for boxes.generators.kamishibai

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

from boxes import *
from boxes.lids import _TopEdge
from boxes.edges import HingeSettings
pass

[docs] class Kamishibai(_TopEdge): """Kamishibai butai (japanese image theatre)""" ui_group = "Misc" description = """ This is a kamishibai butai (japanese image theatre), with several options for covering the different holes when put away. Magenta cuts should be performed before the blue cuts. The recommended wood thickness is 5 mm at least, particularly if you go for big sizes (which works fine with A4 or A3). If you use 3 mm, you should not use the screwing option (disabled by default), so you can assemble your box with glue or force the pieces together (using a bigger burn parameter). Please note that using the screwing option often means adding feet (which can be 3D printed for example). It makes the box easier to mount and unmount for repairing purposes, and the feet protect the wood from whatever surface the box is put on. Screws are not compatible with a small frame thickness (i.e. with sheets with a small margin). For assembling the box, please follow the following steps: 1. Assemble the front side and back side pieces to the front and back of the front and back panels respectively 2. Assemble the top handle pieces together and insert two of the plates into the two holes (centered); then insert the assembled handles into the dansle ceiling and add the two other plates 3. Insert the front and back panels into the bottom panel 4. Attach the handle between the top of the front and back panels, then add the top panel but do not fasten it yet, just keep it loose on top 5. Assemble the locks together to the doors if enabled: 5.1 lock with key : lock front - lock external - plate cut from the door (also add the door now) - lock internal 5.2 lock simple : lock grip - lock external - plate cut from the door (also add the door now) - lock internal 5.3 small extra locks for top and bottom : lock grip - plate cut from the door (also add the door now) - lock internal - lock spacer - lock locker 6. Add the hinges to the doors if needed (for two-panes front doors) 7. fasten the top 8. Attach two side panel inner plates to a side panel with the two pegs (use glue if necessary) and repeat a second time 9. If you use a lock with key, add the last short peg to the back plate (you may want to sand it a bit on the other half so that the key can be attached easily enough, but it should not fal off either) 10. You should now be able to close and open all the doors Usage recommendations: 1. Add your paper sheets from one side or the other (normally you leave either left or right closed, depending on which is more comfortable for you) 2. Thick paper is easier to handle ; if you print on a home printer, use the thickest you printer can print (probably around 200 grams per square meter) ; if you want extra quality, go to a printing shop and ask them for 300 grams per square meter printing 3. You can also buy virgin drawing paper to write your own stories 4. If you decided to go for the lock with key, you can ask one of the participants to unlock the box, it really helps in immersing into toe story 5. If you need a kamishibai for showing images during a guided tour, you may choose to use the one-panel front, and use transparent acrylic for the back and front panels to keep you sheets protected from light rain ; you may need to cut the box from a rain-resistant material (outside-compatible plywood or acrylic) """ def __init__(self) -> None: Boxes.__init__(self) self.addSettingsArgs(edges.FingerJointSettings, surroundingspaces=1.5) self.addSettingsArgs(edges.SlideOnLidSettings, hole_width=15.0, spring="none", second_pin=True, play=0.1) # ~ self.addSettingsArgs(edges.HingeSettings, outset=True, pinwidth=0.4, style="flush", axle=2.5, hingestrength=2) self.addSettingsArgs(edges.HingeSettings, outset=True, pinwidth=0.4, style="flush", axle=2.5, hingestrength=1) self.argparser.add_argument( "--SheetWidth", action="store", type=float, default=297.0, help="width of the sheets in mm") self.argparser.add_argument( "--SheetHeight", action="store", type=float, default=210.0, help="height of the sheets in mm") self.argparser.add_argument( "--SheetsStackDepth", action="store", type=float, default=30.0, help="Depth of the sheets stack in mm") self.argparser.add_argument( "--FrameThickness", action="store", type=float, default=20.0, help="Frame thickness in mm") self.argparser.add_argument( "--FrameCornerRadius", action="store", type=float, default=5.0, help="Radius of the frame corners in mm") self.argparser.add_argument( "--Margin", action="store", type=float, default=2.0, help="Margin for sheets and moving parts in mm") self.argparser.add_argument( "--HandleThickness", action="store", type=int, default=2, help="Thickness of the top handle in multiples of thickness (Set to 0 for no handle)") self.argparser.add_argument( "--HandleWidth", action="store", type=float, default=120.0, help="Width of the top handle in mm (Set to 0 for no handle) ; the SheetStackDepth should be at least 4 x thickness more") self.argparser.add_argument( "--HandleMargin", action="store", type=float, default=0.0, help="Margin for the top handle in mm (Set to 0 for no margin)") self.argparser.add_argument( "--BackExtraDepth", action="store", type=int, default=4, help="Back extra depth (for adding buttons for example), in multiples of thickness ; set to 0 to let the system calculate the smallest one") self.argparser.add_argument( "--PegsWidthMargin", action="store", type=float, default=0.5, help="Margin for the pegs width in mm ; set to a lower value if the pieces are forced together, a higher value if the pieces slide easily into each other (using screws or glue to assemble)") front_group = self.argparser.add_argument_group("Kamishibai front cover") front_group.add_argument( "--FrontCoverStyle", action="store", type=str, default="two-part lid with hinge eyes (both ends)", choices=["slide-on lid", "two-part lid with hinge eyes (both ends)", "three-part lid, hinges not provided"], help="style of the front cover") front_group.add_argument( "--FrontExtraDepth", action="store", type=int, default=4, help="Front extra depth (for attaching hinges for example), in multiples of thickness ; set to 0 to ignore or let the system calculate the smallest one") front_group.add_argument( "--FrontLockStyle", action="store", type=str, default="with key", choices=["none", "simple", "with key"], help="style of the front lock") front_group.add_argument( "--FrontExtraTopAndBottomLocks", action="store", type=boolarg, default=True, help="Add front extra locks at the top and bottom") hinges_3panes_group = self.argparser.add_argument_group("Kamishibai 3 pane cover hinge holes") hinges_3panes_group.add_argument( "--HingeHolesDiameter", action="store", type=float, default=2.5, help="Hinge hole diameter in mm (set to 0 for no holes)") hinges_3panes_group.add_argument( "--HingeHolesCoverEdgeDistance", action="store", type=float, default=5.5, help="distance of the cover holes from the edge to the holes centers in mm") hinges_3panes_group.add_argument( "--HingeHolesBoxEdgeDistance", action="store", type=float, default=7.0, help="distance of the box holes from the edge to the holes centers in mm") hinges_3panes_group.add_argument( "--HingeHolesCoverSeparation", action="store", type=argparseSections, default="24.0:12.0", help="separation of the cover holes from one another's center in mm (section parameter type) ; the first item is the distance from the border") hinges_3panes_group.add_argument( "--HingeHolesBoxSeparation", action="store", type=argparseSections, default="15.0:30.0", help="separation of the box holes from one another's center in mm (section parameter type) ; the first item is the distance from the border") ScrewsLocking_group = self.argparser.add_argument_group("Screws parameters for attaching the pieces together") ScrewsLocking_group.add_argument( "--LockScrewDiameter", action="store", type=float, default=0.0, help="Diameter of the screw holes in mm (set to 0 for no screws)") ScrewsLocking_group.add_argument( "--TopLockScrewLength", action="store", type=float, default=16.0, help="Length of the top locking screws in mm") ScrewsLocking_group.add_argument( "--BottomLockScrewLength", action="store", type=float, default=13.0, help="Length of the bottom locking screws in mm") ScrewsLocking_group.add_argument( "--DoorFeetScrewLength", action="store", type=float, default=16.0, help="Length of the door feet screws in mm (set to 0 for no screws)") ScrewsLocking_group.add_argument( "--LockNutThickness", action="store", type=float, default=2.4, help="Thickness of the locking nuts in mm") ScrewsLocking_group.add_argument( "--LockNutWidth", action="store", type=float, default=5.5, help="Width of the locking nuts in mm") ScrewsLocking_group.add_argument( "--LockScrewDistanceFromBorder", action="store", type=float, default=11, help="Distance of the screw axis from the side border (in multiples of thickness)") ScrewsLocking_group.add_argument( "--LockScrewExtraFeetScewDiameter", action="store", type=float, default=3.0, help="Diameter of the screw holes for extra feet at the corners, in mm (set to 0 for no screws)") ScrewsLocking_group.add_argument( "--LockScrewExtraFeetDistanceFromBorder", action="store", type=float, default=7.0, help="Distance from the border for the axis of the extra feet at the corners, in mm (set to 0 for no screws)") def screwAttachement (self, LockScrewLength): self.polyline(0, 90, self.thickness, 90, self.LockNutWidth/2 - self.LockScrewDiameter/2, -90, self.LockNutThickness, -90, self.LockNutWidth/2 - self.LockScrewDiameter/2, 90, LockScrewLength - self.LockNutThickness - self.thickness, -90, self.LockScrewDiameter, -90, LockScrewLength - self.LockNutThickness - self.thickness, 90, self.LockNutWidth/2 - self.LockScrewDiameter/2, -90, self.LockNutThickness, -90, self.LockNutWidth/2 - self.LockScrewDiameter/2, 90, self.thickness, 90) def boxFrontBackCallback (self, wi, hi, isFront): # window hole self.rectangularHole(self.thickness*2 + self.FrameThickness, self.FrameThickness, wi - self.FrameThickness*2, hi - self.Margin - self.FrameThickness*2 - self.thickness * (2 if self.HandleThickness > 0 else 0), self.FrameCornerRadius, False, False) # finger holes for handle ceiling if self.HandleThickness > 0 : self.fingerHolesAt(self.thickness*2 , hi - self.thickness * 1.5, self.thickness*4,0) self.fingerHolesAt(wi - self.thickness*2 , hi - self.thickness * 1.5, self.thickness*4,0) self.fingerHolesAt(wi/2 - self.HandleWidth/2 - self.thickness*0, hi - self.thickness * 1.5, self.thickness*4,0) self.fingerHolesAt(wi/2 + self.HandleWidth/2 - self.thickness*0, hi - self.thickness * 1.5, self.thickness*4,0) # finger holes for extra depth if (isFront and self.FrontExtraDepth > 0) or not isFront : self.fingerHolesAt(self.thickness*1.5, self.thickness*0, hi) self.fingerHolesAt(self.thickness*2.5 + wi, self.thickness*0, hi) else : # hinge holes for 3 pane panel if ((self.HingeHolesDiameter > 0) and (isFront and self.FrontCoverStyle == "three-part lid, higes not provided") or (not isFront and self.BackCoverStyle == "three-part lid, higes not provided")) : posx = self.thickness for x in self.HingeHolesBoxSeparation: posx += x self.hole(posx, hi + self.thickness - self.HingeHolesBoxEdgeDistance, self.HingeHolesDiameter/2) self.hole(wi + self.thickness*4 - posx, hi + self.thickness - self.HingeHolesBoxEdgeDistance, self.HingeHolesDiameter/2) posy=-self.thickness for y in self.HingeHolesBoxSeparation: posy += y self.hole(self.HingeHolesBoxEdgeDistance + self.thickness, posy, self.HingeHolesDiameter/2) self.hole(self.HingeHolesBoxEdgeDistance + self.thickness, (hi - self.Margin) * 3/4 - posy, self.HingeHolesDiameter/2) self.hole(wi + self.thickness*3 - self.HingeHolesBoxEdgeDistance, posy, self.HingeHolesDiameter/2) self.hole(wi + self.thickness*3 - self.HingeHolesBoxEdgeDistance, (hi - self.Margin) * 3/4 - posy, self.HingeHolesDiameter/2) def boxFrontBack (self, wi, hi, isFront, move=None, label=""): if self.LockScrewDiameter > 0 : #self.rectangularWall(wi + self.thickness*4, hi, "fNfM", callback=[ # lambda:self.boxFrontBackCallback(wi, hi, isFront) # ],move=move, label=label) if self.move(wi + self.thickness*6, hi + self.thickness*3, move, True): return self.boxFrontBackCallback(wi, hi, isFront) self.moveTo(-self.thickness*2, 0) #bottom self.edge(self.thickness*2) self.edges["f"](self.thickness*(self.LockScrewDistanceFromBorder - 3) - self.LockScrewDiameter) self.edge(self.LockScrewDiameter/2) self.screwAttachement(self.BottomLockScrewLength - self.thickness) self.edge(self.LockScrewDiameter/2) self.edges["f"](wi/2 - self.thickness*(self.LockScrewDistanceFromBorder - 5) - self.LockScrewDiameter*2) self.edge(self.LockScrewDiameter/2) self.screwAttachement(self.BottomLockScrewLength - self.thickness) self.edge(self.LockScrewDiameter/2) self.edges["f"](wi/2 - self.thickness*(self.LockScrewDistanceFromBorder - 5) - self.LockScrewDiameter*2) self.edge(self.LockScrewDiameter/2) self.screwAttachement(self.BottomLockScrewLength - self.thickness) self.edge(self.LockScrewDiameter/2) self.edges["f"](self.thickness*(self.LockScrewDistanceFromBorder - 3) - self.LockScrewDiameter) self.polyline(self.thickness*2, 90) #right self.edges["N"](hi) self.corner(90) #top self.edges["f"](self.thickness*(self.LockScrewDistanceFromBorder - 3 - edges.SlideOnLidSettings.relative_params["play"]) - self.LockScrewDiameter) self.edge(self.LockScrewDiameter/2) self.screwAttachement(self.TopLockScrewLength - self.thickness) self.edge(self.LockScrewDiameter/2) self.edges["f"](wi/2 - self.thickness*(self.LockScrewDistanceFromBorder - 5) - self.LockScrewDiameter*2) self.edge(self.LockScrewDiameter/2) self.screwAttachement(self.TopLockScrewLength - self.thickness) self.edge(self.LockScrewDiameter/2) self.edges["f"](wi/2 - self.thickness*(self.LockScrewDistanceFromBorder - 5) - self.LockScrewDiameter*2) self.edge(self.LockScrewDiameter/2) self.screwAttachement(self.TopLockScrewLength - self.thickness) self.edge(self.LockScrewDiameter/2) self.edges["f"](self.thickness*(self.LockScrewDistanceFromBorder - 3 - edges.SlideOnLidSettings.relative_params["play"]) - self.LockScrewDiameter) self.corner(90) #left self.edges["M"](hi) self.corner(90) # move plate self.move(wi + self.thickness*6, hi + self.thickness*3, move, label=label) else : self.rectangularWall(wi + self.thickness*4, hi, "fNfM", callback=[ lambda:self.boxFrontBackCallback(wi, hi, isFront) ],move=move, label=label) def boxTopBottom (self, wi, di, isTop, move=None, label=""): if self.move(wi + self.thickness*8, di + self.thickness * (self.FrontExtraDepth + self.BackExtraDepth + 6) + (self.thickness*3 if self.FrontCoverStyle == "two-part lid with hinge eyes (both ends)" else 0), move, True): return if self.LockScrewDiameter > 0 : # screw holes self.hole(self.thickness * (self.LockScrewDistanceFromBorder - 1), self.thickness * (self.BackExtraDepth + 2.5), self.LockScrewDiameter/2) self.hole(wi/2 + self.thickness * 4, self.thickness * (self.BackExtraDepth + 2.5), self.LockScrewDiameter/2) self.hole(wi - self.thickness * (self.LockScrewDistanceFromBorder - 9), self.thickness * (self.BackExtraDepth + 2.5), self.LockScrewDiameter/2) self.hole(self.thickness * (self.LockScrewDistanceFromBorder - 1), di + self.thickness * (self.BackExtraDepth + 3.5), self.LockScrewDiameter/2) self.hole(wi/2 + self.thickness * 4, di + self.thickness * (self.BackExtraDepth + 3.5), self.LockScrewDiameter/2) self.hole(wi - self.thickness * (self.LockScrewDistanceFromBorder - 9), di + self.thickness * (self.BackExtraDepth + 3.5), self.LockScrewDiameter/2) if self.LockScrewExtraFeetScewDiameter > 0 and self.LockScrewExtraFeetDistanceFromBorder > 0 and not isTop : self.hole(self.LockScrewExtraFeetDistanceFromBorder, self.LockScrewExtraFeetDistanceFromBorder, self.LockScrewExtraFeetScewDiameter/2) self.hole(wi + self.thickness * 8 - self.LockScrewExtraFeetDistanceFromBorder, self.LockScrewExtraFeetDistanceFromBorder, self.LockScrewExtraFeetScewDiameter/2) if self.FrontCoverStyle == "two-part lid with hinge eyes (both ends)": self.hole(self.thickness * 6, di + self.thickness * (self.BackExtraDepth + self.FrontExtraDepth + 4) - self.LockScrewExtraFeetDistanceFromBorder, self.LockScrewExtraFeetScewDiameter/2) self.hole(wi + self.thickness * 2, di + self.thickness * (self.BackExtraDepth + self.FrontExtraDepth + 4) - self.LockScrewExtraFeetDistanceFromBorder, self.LockScrewExtraFeetScewDiameter/2) elif self.FrontCoverStyle == "three-part lid, higes not provided": self.hole(self.LockScrewExtraFeetDistanceFromBorder, di + self.thickness * (self.BackExtraDepth + self.FrontExtraDepth + 4) - self.LockScrewExtraFeetDistanceFromBorder, self.LockScrewExtraFeetScewDiameter/2) self.hole(wi + self.thickness * 8 - self.LockScrewExtraFeetDistanceFromBorder, di + self.thickness * (self.BackExtraDepth + self.FrontExtraDepth + 4) - self.LockScrewExtraFeetDistanceFromBorder, self.LockScrewExtraFeetScewDiameter/2) else: self.hole(self.LockScrewExtraFeetDistanceFromBorder, di + self.thickness * (self.BackExtraDepth + self.FrontExtraDepth + 6) - self.LockScrewExtraFeetDistanceFromBorder, self.LockScrewExtraFeetScewDiameter/2) self.hole(wi + self.thickness * 8 - self.LockScrewExtraFeetDistanceFromBorder, di + self.thickness * (self.BackExtraDepth + self.FrontExtraDepth + 6) - self.LockScrewExtraFeetDistanceFromBorder, self.LockScrewExtraFeetScewDiameter/2) #finger holes for top and bottom door locks if self.FrontExtraTopAndBottomLocks and (self.FrontCoverStyle == "two-part lid with hinge eyes (both ends)" or (self.FrontCoverStyle == "three-part lid, higes not provided" and not isTop)): self.fingerHolesAt(wi/2 - self.thickness * 4, di + self.thickness * (self.BackExtraDepth + self.FrontExtraDepth + 2.5), self.thickness*16, 0) # finger holes for front and back if necessary #TODO update all this section... #self.fingerHolesAt(self.thickness*2, self.thickness * (self.BackExtraDepth + 2.5), wi + self.thickness*4,0) self.fingerHolesAt(self.thickness*2, self.thickness * (self.BackExtraDepth + 2.5), self.thickness*(self.LockScrewDistanceFromBorder - 3) - self.LockScrewDiameter,0) self.fingerHolesAt(self.thickness*(self.LockScrewDistanceFromBorder - 1) + self.LockScrewDiameter, self.thickness * (self.BackExtraDepth + 2.5), wi/2 - self.thickness*(self.LockScrewDistanceFromBorder - 5) - self.LockScrewDiameter*2,0) self.fingerHolesAt(wi/2 + self.thickness*4 + self.LockScrewDiameter, self.thickness * (self.BackExtraDepth + 2.5), wi/2 - self.thickness*(self.LockScrewDistanceFromBorder - 5) - self.LockScrewDiameter*2,0) self.fingerHolesAt(wi - self.thickness*(self.LockScrewDistanceFromBorder - 9) + self.LockScrewDiameter, self.thickness * (self.BackExtraDepth + 2.5), self.thickness*(self.LockScrewDistanceFromBorder - 3) - self.LockScrewDiameter,0) if self.FrontExtraDepth > 0 : #self.fingerHolesAt(self.thickness*2, di + self.thickness * (self.BackExtraDepth + 3.5), wi + self.thickness*4,0) self.fingerHolesAt(self.thickness*2, di + self.thickness * (self.BackExtraDepth + 3.5), self.thickness*(self.LockScrewDistanceFromBorder - 3) - self.LockScrewDiameter,0) self.fingerHolesAt(self.thickness*(self.LockScrewDistanceFromBorder - 1) + self.LockScrewDiameter, di + self.thickness * (self.BackExtraDepth + 3.5), wi/2 - self.thickness*(self.LockScrewDistanceFromBorder - 5) - self.LockScrewDiameter*2,0) self.fingerHolesAt(wi/2 + self.thickness*4 + self.LockScrewDiameter, di + self.thickness * (self.BackExtraDepth + 3.5), wi/2 - self.thickness*(self.LockScrewDistanceFromBorder - 5) - self.LockScrewDiameter*2,0) self.fingerHolesAt(wi - self.thickness*(self.LockScrewDistanceFromBorder - 9) + self.LockScrewDiameter, di + self.thickness * (self.BackExtraDepth + 3.5), self.thickness*(self.LockScrewDistanceFromBorder - 3) - self.LockScrewDiameter,0) else : # finger holes for front and back if necessary self.fingerHolesAt(self.thickness*2, self.thickness * (self.BackExtraDepth + 2.5), wi + self.thickness*4,0) if self.FrontExtraDepth > 0 : self.fingerHolesAt(self.thickness*2, di + self.thickness * (self.BackExtraDepth + 3.5), wi + self.thickness*4,0) # finger holes for sides # back if isTop : if self.BackExtraDepth > 2 : self.fingerHolesAt(self.thickness*3.5, self.thickness*2, self.thickness * (self.BackExtraDepth - 0), angle=90) self.fingerHolesAt(wi + self.thickness*4.5, self.thickness*2, self.thickness * (self.BackExtraDepth - 0), angle=90) else : self.fingerHolesAt(self.thickness*3.5, self.thickness*2, self.thickness * self.BackExtraDepth, angle=90) self.fingerHolesAt(wi + self.thickness*4.5, self.thickness*2, self.thickness * self.BackExtraDepth, angle=90) # front if self.FrontCoverStyle == "two-part lid with hinge eyes (both ends)" : self.fingerHolesAt(self.thickness*3.5, di + self.thickness*(self.BackExtraDepth + 4), self.thickness * (self.FrontExtraDepth - 2), angle=90) self.fingerHolesAt(wi + self.thickness*4.5, di + self.thickness*(self.BackExtraDepth + 4), self.thickness * (self.FrontExtraDepth - 2), angle=90) elif self.FrontExtraDepth > 0 and (self.FrontCoverStyle == "three-part lid, higes not provided" or self.FrontCoverStyle == "none") : self.fingerHolesAt(self.thickness*3.5, di + self.thickness*(self.BackExtraDepth + self.FrontExtraDepth + 0), self.FrontExtraDepth * self.thickness, angle=90) self.fingerHolesAt(wi + self.thickness*4.5, di + self.thickness*(self.BackExtraDepth + self.BackExtraDepth + 0), self.FrontExtraDepth * self.thickness, angle=90) elif self.FrontExtraDepth > 2 and self.FrontCoverStyle == "slide-on lid" : self.fingerHolesAt(self.thickness*3.5, di + self.thickness*(self.BackExtraDepth + 4), self.thickness * (self.FrontExtraDepth), angle=90) self.fingerHolesAt(wi + self.thickness*4.5, di + self.thickness*(self.BackExtraDepth + 4), self.thickness * (self.FrontExtraDepth), angle=90) elif self.FrontExtraDepth > 0 and not isTop and self.FrontCoverStyle == "slide-on lid" : self.fingerHolesAt(self.thickness*3.5, di + self.thickness*(self.BackExtraDepth + 4), self.thickness * (self.FrontExtraDepth), angle=90) self.fingerHolesAt(wi + self.thickness*4.5, di + self.thickness*(self.BackExtraDepth + 4), self.thickness * (self.FrontExtraDepth), angle=90) elif self.FrontExtraDepth > 0 and not isTop and not self.FrontCoverStyle == "slide-on lid" : self.fingerHolesAt(self.thickness*3.5, di + (self.BackExtraDepth + 4.5) * self.thickness, self.thickness * (self.FrontExtraDepth - 1), angle=90) self.fingerHolesAt(wi + self.thickness*4.5, di + (self.BackExtraDepth + 4.5) * self.thickness, self.thickness * (self.FrontExtraDepth - 1), angle=90) # hole for handle if (isTop and self.HandleThickness > 0 and self.HandleWidth > 0) : self.rectangularHole(self.thickness*4 + wi/2 - self.HandleWidth/2 - self.HandleMargin/2, self.thickness * (self.BackExtraDepth + 3 - self.HandleThickness/2) + di/2 - self.HandleMargin/2, self.HandleWidth + self.HandleMargin, self.thickness*self.HandleThickness + self.HandleMargin, 0, False, False) # hinge holes for 3 pane panel if (isTop and (self.HingeHolesDiameter > 0) and (self.FrontCoverStyle == "three-part lid, higes not provided") and (self.HandleThickness > 0)) : posx=self.thickness*3 for x in self.HingeHolesBoxSeparation: posx += x self.hole(posx, di + self.thickness*(self.FrontExtraDepth + self.BackExtraDepth + 4) - self.HingeHolesBoxEdgeDistance, self.HingeHolesDiameter/2) self.hole(wi + self.thickness*8 - posx, di + self.thickness*(self.FrontExtraDepth + self.BackExtraDepth + 4) - self.HingeHolesBoxEdgeDistance, self.HingeHolesDiameter/2) # plate # back side self.moveTo(self.thickness*2, 0) if isTop : self.polyline(self.thickness - self.Margin/2, 90, self.thickness * 2, -90, wi + self.thickness*2 + self.Margin, -90, self.thickness * 2, 90, self.thickness - self.Margin/2, [90, self.thickness*2]) else : self.edge(self.thickness * 2) self.edges["L"](wi) self.polyline(self.thickness * 2, [90, self.thickness*2]) # right side if isTop : self.polyline(self.thickness * self.BackExtraDepth - self.Margin/2, 90, self.thickness*2, -90, di + self.thickness*2 + self.Margin, 0) if self.FrontExtraDepth > 0 : self.polyline(0, -90, self.thickness*2, 90) self.edge(self.thickness * self.FrontExtraDepth - self.Margin/2) else : self.edge(self.thickness * (self.BackExtraDepth + 1)) self.edges["L"](di) if self.FrontCoverStyle == "slide-on lid" : self.edge(self.thickness * (1 + self.FrontExtraDepth)) else : self.edge(self.thickness * (1 + self.FrontExtraDepth)) if self.FrontCoverStyle == "slide-on lid" : self.corner(90, radius = self.thickness*2) else : self.corner(90) # front side if self.FrontExtraDepth > 0 : if self.FrontCoverStyle == "two-part lid with hinge eyes (both ends)" : self.edges["k"].settings.style = "flush_inset" self.edges["k"](wi + self.thickness*8) self.corner(90) elif self.FrontCoverStyle == "slide-on lid" : if isTop : self.polyline(self.thickness - self.Margin/2, 90, self.thickness * 2, -90, wi + self.thickness*2 + self.Margin, -90, self.thickness * 2, 90, self.thickness - self.Margin/2, [90, self.thickness*2]) else : self.edge(self.thickness * 2) self.edges["L"](wi) self.polyline(self.thickness * 2, [90, self.thickness*2]) else : self.polyline(wi + self.thickness*8, 90) else : if not isTop : self.edge(self.thickness*2) self.edges["F"](wi + self.thickness*4) if not isTop : self.edge(self.thickness*2) self.corner(90) # left side if isTop : if self.FrontExtraDepth > 0 : if self.FrontCoverStyle == "slide-on lid" : self.polyline(self.thickness * (self.FrontExtraDepth - 0) - self.Margin/2, 90) else : self.polyline(self.thickness * self.FrontExtraDepth - self.Margin/2, 90) self.polyline(self.thickness*2, -90) self.polyline(di + self.thickness*2 + self.Margin, -90, self.thickness*2, 90, self.thickness * self.BackExtraDepth - self.Margin/2, 0) else : if self.FrontCoverStyle == "slide-on lid" : self.edge(self.thickness * (1 + self.FrontExtraDepth)) else : self.edge(self.thickness * (1 + self.FrontExtraDepth)) self.edges["L"](di) self.edge(self.thickness * (self.BackExtraDepth + 1)) self.corner(90, radius=self.thickness*2) # move plate self.move(wi + self.thickness*8, di + self.thickness * (self.FrontExtraDepth + self.BackExtraDepth + 6) + (self.thickness*3 if self.FrontCoverStyle == "two-part lid with hinge eyes (both ends)" else 0), move, label=label) def boxFrontSideCallback (self, hi) : # hinge holes for 3 pane panel if ((self.HingeHolesDiameter > 0) and (self.FrontCoverStyle == "three-part lid, higes not provided")) : posy=0 for y in self.HingeHolesBoxSeparation: posy += y self.hole(posy - self.thickness, self.HingeHolesBoxEdgeDistance, self.HingeHolesDiameter/2) self.hole(hi * 3/4 + self.Margin/2 - posy, self.HingeHolesBoxEdgeDistance, self.HingeHolesDiameter/2) def boxOpenSide (self, hi, move=None): #back if self.BackExtraDepth > 2 : self.rectangularWall(hi, self.thickness*self.BackExtraDepth, "Nfff", move=move, label="back side") else : self.rectangularWall(hi, self.thickness*self.BackExtraDepth, "Neff", move=move, label="back side") # front if self.FrontExtraDepth > 0 : if self.FrontCoverStyle == "slide-on lid" : if self.FrontExtraDepth > 0 : self.rectangularWall(hi, self.thickness*(self.FrontExtraDepth), "Nfff", move=move, label="front side") else : self.rectangularWall(hi, self.thickness*(self.FrontExtraDepth), "Neff", move=move, label="front side") elif self.FrontCoverStyle == "two-part lid with hinge eyes (both ends)" : self.rectangularWall(hi, self.thickness*(self.FrontExtraDepth - 2), "efff", move=move, label="front side") elif self.FrontCoverStyle == "three-part lid, higes not provided" : self.rectangularWall(hi, self.FrontExtraDepth * self.thickness, "efff", callback=[lambda:self.boxFrontSideCallback(hi)], move=move, label="front side") else : self.rectangularWall(hi, self.thickness*self.FrontExtraDepth, "efff", move=move, label="front side") def topHandle (self, wi, di, move=None, label=""): # handle plates for i in range(self.HandleThickness): if self.move(wi, 30 + self.thickness*(self.HandleThickness * 2 + 2), move, True): return # holes for holders self.rectangularHole(wi/2 - self.HandleWidth/2 + self.thickness, self.thickness, self.thickness*3, self.thickness,0, False, False) self.rectangularHole(wi/2 + self.HandleWidth/2 - self.thickness*4, self.thickness, self.thickness*3, self.thickness,0, False, False) #hole for screw if self.LockScrewDiameter > 0 : self.hole(wi/2, self.thickness*1.5, self.LockScrewDiameter/2) #hole for handle self.rectangularHole((wi - self.HandleWidth)/2 + self.thickness * self.HandleThickness, self.thickness*2 + self.thickness * self.HandleThickness, self.HandleWidth - self.thickness * self.HandleThickness * 2, 30, 15, False, False) # main plate # bottom self.polyline(self.thickness*5, 90, self.thickness, -90, wi/2 - self.HandleWidth/2 - self.thickness*5, -90, self.thickness, 90, self.thickness*5, 90, self.thickness, -90) if (self.LockScrewDiameter > 0) : self.polyline(self.HandleWidth/2 - self.thickness*5 - self.LockNutWidth, -90, self.thickness, 90, self.LockNutWidth*2, 90, self.thickness, -90) self.edge(self.HandleWidth/2 - self.thickness*5 - self.LockNutWidth) else : self.edge(self.HandleWidth - self.thickness*10) self.polyline(0, -90, self.thickness, 90, self.thickness*5, 90, self.thickness, -90, wi/2 - self.HandleWidth/2 - self.thickness*5, -90, self.thickness, 90, self.thickness*5, 90) # right self.polyline(self.thickness*2, 90) # plate holder self.polyline(self.thickness, 90, self.thickness, -90, self.thickness*3, -90, self.thickness, 90, wi/2 - self.HandleWidth/2 - self.thickness * (self.HandleThickness+2), -90) # handle self.polyline(30 - 15 + self.thickness*(self.HandleThickness * 2), [90,15], self.HandleWidth - 30, [90,15], 30 - 15 + self.thickness*(self.HandleThickness * 2), -90, wi/2 - self.HandleWidth/2 - self.thickness * (self.HandleThickness+2), 90) #plate holder self.polyline(self.thickness, -90, self.thickness*3, -90, self.thickness, 90, self.thickness, 90) # left self.polyline(self.thickness*2, 90) # move plate self.move(wi, 30 + self.thickness*(self.HandleThickness * 2 + 2), move, label=label) # plate holders self.rectangularWall(di, self.thickness*3, move=move) self.rectangularWall(di, self.thickness*3, move=move) self.rectangularWall(di, self.thickness*3, move=move) self.rectangularWall(di, self.thickness*3, move=move) #ceiling if self.move(wi+ self.thickness, di+ self.thickness*4, move, True): return self.moveTo(0, self.thickness*2) self.rectangularHole(wi/2 - self.HandleWidth/2, di/2 - self.thickness*self.HandleThickness/2, self.thickness*5, self.thickness*self.HandleThickness, 0, False, False) self.rectangularHole(wi/2 + self.HandleWidth/2 - self.thickness*5, di/2 - self.thickness*self.HandleThickness/2, self.thickness*5, self.thickness*self.HandleThickness, 0, False, False) if (self.LockScrewDiameter > 0) : self.rectangularHole(wi/2 - self.LockNutWidth, self.thickness, self.LockNutWidth*2, di - self.thickness*2, 0, False, False) #bottom self.edges["f"](self.thickness*4) self.edge(wi/2 - self.HandleWidth/2 - self.thickness*6) self.edges["f"](self.thickness*4) self.edge(self.HandleWidth - self.thickness*4) self.edges["f"](self.thickness*4) self.edge(wi/2 - self.HandleWidth/2 - self.thickness*6) self.edges["f"](self.thickness*4) self.corner(90) #right self.polyline(di/2 - self.HandleThickness* self.thickness/2, 90, self.thickness*5, -90, self.thickness * self.HandleThickness, -90, self.thickness*5, 90, di/2 - self.HandleThickness* self.thickness/2, 90) #top self.edges["f"](self.thickness*4) self.edge(wi/2 - self.HandleWidth/2 - self.thickness*6) self.edges["f"](self.thickness*4) self.edge(self.HandleWidth - self.thickness*4) self.edges["f"](self.thickness*4) self.edge(wi/2 - self.HandleWidth/2 - self.thickness*6) self.edges["f"](self.thickness*4) self.corner(90) #left self.polyline(di/2 - self.HandleThickness* self.thickness/2, 90, self.thickness*5, -90, self.thickness * self.HandleThickness, -90, self.thickness*5, 90, di/2 - self.HandleThickness* self.thickness/2, 90) # move plate self.move(wi+ self.thickness, di+ self.thickness*4, move, label="handle ceiling") def coverPanel1Lid (self, wi, hi, hasSubLayer = False, move=None, label=""): # sides if hasSubLayer : self.rectangularWall(wi, hi, "lmen", callback = [lambda:self.rectangularHole(wi/2, self.thickness*3.5, self.thickness, self.thickness), lambda:self.rectangularHole(hi - self.thickness*5.5, wi/2, self.thickness, self.thickness)],move=move, label=label) self.rectangularWall(wi - self.Margin, hi - self.thickness*6, "eeee", callback = [lambda:self.rectangularHole(wi/2 - self.Margin/2, self.thickness*1.5, self.thickness, self.thickness), lambda:self.rectangularHole(hi - self.thickness*7.5, wi/2 - self.Margin/2, self.thickness, self.thickness)],move=move, label="side panel inner") self.rectangularWall(wi - self.Margin, hi - self.thickness*6, "eeee", callback = [lambda:self.rectangularHole(wi/2 - self.Margin/2, self.thickness*1.5, self.thickness, self.thickness), lambda:self.rectangularHole(hi - self.thickness*7.5, wi/2 - self.Margin/2, self.thickness, self.thickness)],move=move, label="side panel inner") self.rectangularWall (self.thickness + self.PegsWidthMargin, self.thickness * 3, "eeee", move=move, label="") self.rectangularWall (self.thickness + self.PegsWidthMargin, self.thickness * 3, "eeee", move=move, label="") # back or front (with key holder if necessary) else : if (self.FrontCoverStyle == "two-part lid with hinge eyes (both ends)" or self.FrontCoverStyle == "three-part lid, higes not provided") and self.FrontLockStyle == "with key" : self.rectangularWall(wi, hi, "lmen", callback=[lambda:self.hole(wi/2, hi - self.thickness*4, d=self.thickness*4), lambda:self.rectangularHole(self.thickness*2, self.thickness*2, self.thickness, self.thickness)],move=move, label=label) self.rectangularWall (self.thickness*2, self.thickness + self.PegsWidthMargin, "eeee", move=move) else : self.rectangularWall(wi, hi, "lmen", callback=[lambda:self.hole(wi/2, hi - self.thickness*4, d=self.thickness*4)],move=move, label=label) def coverPanel2SideCallback(self, wi, hi, lockStyle): if "with key" in lockStyle : self.hole((wi - self.Margin)/2 - self.thickness*1.5, hi/2, self.thickness*3.5) self.rectangularHole((wi - self.Margin)/2 - self.thickness*1.5, hi/2, self.thickness + self.Margin, self.thickness + self.Margin, 0, color=Color.MAGENTA) self.rectangularHole((wi - self.Margin)/2 - self.thickness*3.5, hi/2, self.thickness, self.thickness, 0, color=Color.MAGENTA) self.rectangularHole((wi - self.Margin)/2 + self.thickness*0.5, hi/2, self.thickness, self.thickness, 0, color=Color.MAGENTA) elif "simple" in lockStyle : self.hole((wi - self.Margin)/2, hi/2, self.thickness*2) self.rectangularHole((wi - self.Margin)/2, hi/2, self.thickness, self.thickness, 0, color=Color.MAGENTA) if "top" in lockStyle : self.hole((wi - self.Margin)/2 - self.thickness, hi - self.thickness*4, self.thickness*2) self.rectangularHole((wi - self.Margin)/2 - self.thickness, hi - self.thickness*4, self.thickness, self.thickness, 0, color=Color.MAGENTA) if "bottom" in lockStyle : self.hole((wi - self.Margin)/2 - self.thickness, self.thickness*4, self.thickness*2) self.rectangularHole((wi - self.Margin)/2 - self.thickness, self.thickness*4, self.thickness, self.thickness, 0, color=Color.MAGENTA) def coverPanel2Side(self, wi, hi, lockStyle, move=None, label=""): if self.DoorFeetScrewLength > 0 and self.LockScrewDiameter > 0 : if self.move((wi + self.thickness*6 - self.Margin)/2, hi + self.thickness*2, move, True): return self.coverPanel2SideCallback(wi, hi, lockStyle) # plate self.edges["I"](wi/2 + self.thickness * 1.5 - self.LockScrewDiameter/2 - self.Margin/2) self.screwAttachement(self.DoorFeetScrewLength) self.polyline(self.thickness * 1.5 - self.LockScrewDiameter/2, 90, hi + self.thickness*2, 90, self.thickness * 1.5, 0) self.edges["J"](wi/2 + self.thickness * 1.5 - self.Margin/2) self.polyline(0, 90, hi, 90) # move plate self.move((wi + self.thickness*6 - self.Margin)/2, hi + self.thickness*2, move, label=label) else : self.rectangularWall((wi + self.thickness*6 - self.Margin)/2, hi, "IeJe", callback=[lambda:self.coverPanel2SideCallback(wi, hi, lockStyle)], move=move, label=label) def coverPanel3Side (self, wi, hi, lockStyle, move=None, label=""): if self.move(wi/2 + self.thickness*2, hi *3/4 + self.thickness*2, move, True): return # hinge holes for 3 pane panel if (self.HingeHolesDiameter > 0) : posy=0 for y in self.HingeHolesCoverSeparation: posy += y self.hole(self.HingeHolesCoverEdgeDistance, posy, self.HingeHolesDiameter/2) self.hole(self.HingeHolesCoverEdgeDistance, hi * 3/4 + self.Margin/2 + self.thickness - posy, self.HingeHolesDiameter/2) # small extra lock t the bottom if "bottom" in lockStyle : self.hole((wi - self.Margin)/2 - self.thickness*3, self.thickness*4, self.thickness*2) self.rectangularHole((wi - self.Margin)/2 - self.thickness*3, self.thickness*4, self.thickness, self.thickness, 0, color=Color.MAGENTA) # plate if self.DoorFeetScrewLength > 0 and self.LockScrewDiameter > 0 : self.edge((wi - self.thickness - self.LockScrewDiameter - self.Margin)/2) self.screwAttachement(self.DoorFeetScrewLength) self.edge(self.thickness*1.5 - self.LockScrewDiameter/2) else : self.edge((wi + self.thickness*2 - self.Margin)/2) self.polyline(0, 90, (hi + self.thickness*2 - self.Margin)/2, 90, (wi + self.thickness*2 - self.Margin)/4, -math.atan(2*(hi + self.thickness*2-self.Margin)/(wi + self.thickness*2-self.Margin))*180/math.pi, math.sqrt(pow((hi + self.thickness*2 - self.Margin)/4, 2) + pow((wi + self.thickness*2 - self.Margin)/8, 2)), math.atan(2*(hi + self.thickness*2-self.Margin)/(wi + self.thickness*2-self.Margin))*180/math.pi, (wi + self.thickness*2 - self.Margin)/8, 90, (hi + self.thickness*2 - self.Margin)*3/4, 90) # move plate self.move(wi/2 + self.thickness*2, hi *3/4 + self.thickness*2, move, label=label) def coverPanel3Top (self, wi, hi, lockStyle, move=None, label=""): if self.move(wi + self.thickness*2, hi/2 + self.thickness*2, move, True): return # lock hole if lockStyle == "with key" : self.hole((wi + self.thickness*2)/2, hi/2 - self.thickness*4, self.thickness*3.5) self.rectangularHole((wi + self.thickness*2)/2, hi/2 - self.thickness*4, self.thickness + self.Margin, self.thickness + self.Margin, 0, color=Color.MAGENTA) self.rectangularHole((wi + self.thickness*2)/2 - self.thickness*2, hi/2 - self.thickness*4, self.thickness, self.thickness, 0, color=Color.MAGENTA) self.rectangularHole((wi + self.thickness*2)/2 + self.thickness*2, hi/2 - self.thickness*4, self.thickness, self.thickness, 0, color=Color.MAGENTA) elif lockStyle == "simple" : self.hole((wi + self.thickness*2)/2, hi/2 - self.thickness*2.5, self.thickness*2) self.rectangularHole((wi + self.thickness*2)/2, hi/2 - self.thickness*2.5, self.thickness, self.thickness, 0, color=Color.MAGENTA) # hinge holes for 3 pane panel if (self.HingeHolesDiameter > 0) : posx=0 for x in self.HingeHolesCoverSeparation: posx += x self.hole(posx, self.HingeHolesCoverEdgeDistance, self.HingeHolesDiameter/2) self.hole(wi + self.thickness*2 - posx, self.HingeHolesCoverEdgeDistance, self.HingeHolesDiameter/2) # plate self.polyline(wi + self.thickness*2, 90, (hi + self.thickness*2 - self.Margin)/4, 90, (wi + self.thickness*2)/8 + self.Margin/2, -math.atan(2*(hi + self.thickness*2-self.Margin)/(wi + self.thickness*2))*180/math.pi, math.sqrt(pow((hi + self.thickness*2 - self.Margin)/4, 2) + pow((wi + self.thickness*2)/8, 2)), math.atan(2*(hi + self.thickness*2-self.Margin)/(wi + self.thickness*2))*180/math.pi, (wi + self.thickness*2)/2 - + self.Margin, math.atan(2*(hi + self.thickness*2-self.Margin)/(wi + self.thickness*2))*180/math.pi, math.sqrt(pow((hi + self.thickness*2 - self.Margin)/4, 2) + pow((wi + self.thickness*2)/8, 2)), -math.atan(2*(hi + self.thickness*2-self.Margin)/(wi + self.thickness*2))*180/math.pi, (wi + self.thickness*2)/8 + self.Margin/2, 90, (hi + self.thickness*2 - self.Margin)/4, 90) # move plate self.move(wi + self.thickness*2, hi/2 + self.thickness*2, move, label=label) def lockSimple (self, move=None): # external locking wheel if self.move(self.thickness*10, self.thickness*10, move, True): return self.parts.disc(self.thickness*10, callback=lambda:self.rectangularHole(0, 0, self.thickness, self.thickness)) self.move(self.thickness*10, self.thickness*10, move, label="lock external") # grip wheel if self.move(self.thickness*6, self.thickness*6, move, True): return self.parts.wavyKnob(self.thickness*5, callback=lambda:self.rectangularHole(0, 0, self.thickness, self.thickness)) self.move(self.thickness*6, self.thickness*6, move, label="lock grip") # pivot wheel #not needed, it is cut from the part directly # internal locking wheel if self.move(self.thickness*11, self.thickness*11, move, True): return self.parts.disc(self.thickness*10, dwidth=0.8, callback=lambda:self.rectangularHole(0, 0, self.thickness, self.thickness)) self.move(self.thickness*11, self.thickness*11, move, label="lock internal") # discs attachment self.rectangularWall(self.thickness*4, self.thickness + self.PegsWidthMargin, "eeee", move=move) def lockExtra (self, move=None): # grip wheel if self.move(self.thickness*7, self.thickness*7, move, True): return self.parts.wavyKnob(self.thickness*5, callback=lambda:self.rectangularHole(0, 0, self.thickness, self.thickness)) self.move(self.thickness*6, self.thickness*6, move, label="lock grip") # internal plate wheel if self.move(self.thickness*6 - self.Margin, self.thickness*6 - self.Margin, move, True): return self.parts.disc(self.thickness*6 - self.Margin, callback=lambda:self.rectangularHole(0, 0, self.thickness, self.thickness)) self.move(self.thickness*6 - self.Margin, self.thickness*6, move, label="lock internal") # internal spacing wheel if self.move(self.thickness*6 - self.Margin, self.thickness*6 - self.Margin, move, True): return self.parts.disc(self.thickness*6 - self.Margin, callback=lambda:self.rectangularHole(0, 0, self.thickness, self.thickness)) self.move(self.thickness*6 - self.Margin, self.thickness*6 - self.Margin, move, label="lock spacer") # internal locking wheel if self.move(self.thickness*8 - self.Margin, self.thickness*8 - self.Margin, move, True): return self.parts.disc(self.thickness*8 - self.Margin, dwidth=0.8, callback=lambda:self.rectangularHole(0, 0, self.thickness, self.thickness)) self.move(self.thickness*8 - self.Margin, self.thickness*8 - self.Margin, move, label="lock locker") # discs attachment self.rectangularWall(self.thickness*5, self.thickness + self.PegsWidthMargin, "eeee", move=move) def keyHoles(self, centerHoleLength, isRotated=False): # center key hole if centerHoleLength == 2 : self.rectangularHole(-(self.thickness)/2, 0, self.thickness*2 + self.Margin, self.thickness+ self.Margin) elif centerHoleLength == 3 : self.rectangularHole(0, 0, self.thickness*3+ self.Margin, self.thickness + self.Margin) elif centerHoleLength == 1 : self.rectangularHole(0, 0, self.thickness+ self.Margin, self.thickness + self.Margin) # side holes if isRotated : self.rectangularHole(self.thickness*2, 0, self.thickness, self.thickness) self.rectangularHole(-self.thickness*2, 0, self.thickness, self.thickness) else : self.rectangularHole(0, self.thickness*2, self.thickness, self.thickness) self.rectangularHole(0, -self.thickness*2, self.thickness, self.thickness) def lockWithKey (self, isInnerLockRorated = False, move=None): # external locking wheel if self.move(self.thickness*15, self.thickness*15, move, True): return self.parts.disc(self.thickness*15, callback=lambda:self.keyHoles(2)) self.move(self.thickness*15, self.thickness*15, move, label="lock external") # front wheel if self.move(self.thickness*8, self.thickness*8, move, True): return self.parts.wavyKnob(self.thickness*7, callback=lambda:self.keyHoles(3)) self.move(self.thickness*8, self.thickness*8, move, label="lock front") # pivot wheel #not needed, it is cut from the part directly # internal locking wheel if self.move(self.thickness*15, self.thickness*15, move, True): return self.parts.disc(self.thickness*15, dwidth=12/15, callback=lambda:self.keyHoles(0, isInnerLockRorated)) self.move(self.thickness*15, self.thickness*15, move, label="lock internal") # discs attachment self.rectangularWall(self.thickness*4, self.thickness + self.PegsWidthMargin, "eeee", move=move) self.rectangularWall(self.thickness*4, self.thickness + self.PegsWidthMargin, "eeee", move=move) # key if self.move(self.thickness*10, self.thickness*4, move, True): return self.rectangularHole(self.thickness, self.thickness, self.thickness, self.thickness, 0, False, False) self.polyline(self.thickness*3, 90, self.thickness, -90, self.thickness*3, -90, self.thickness, 90, self.thickness*2, 90, self.thickness, -90, self.thickness, 90, self.thickness, 90, self.thickness*2, -90, self.thickness, 90, self.thickness, 90, self.thickness, -90, self.thickness*3, -90, self.thickness, 90, self.thickness*3, 90, self.thickness*3, 90) self.move(self.thickness*10, self.thickness*4, move, label="key") def render(self): hi = self.SheetHeight + self.Margin * 2 + ((self.thickness*2) if self.HandleThickness > 0 else 0) wi = self.SheetWidth + self.Margin di = self.SheetsStackDepth + self.Margin if self.FrontCoverStyle == "two-part lid with hinge eyes (both ends)" and self.FrontExtraDepth < 2 * HingeSettings.relative_params["hingestrength"] + HingeSettings.relative_params["axle"]/2 : self.FrontExtraDepth = 2 * HingeSettings.relative_params["hingestrength"] + HingeSettings.relative_params["axle"]/2 if self.FrontCoverStyle == "slide-on lid" and self.FrontExtraDepth < 3 : self.FrontExtraDepth = 3 if self.BackExtraDepth < 1 : self.BackExtraDepth = 1 self.ctx.save() # front self.boxFrontBack (wi, hi, True, move="up", label="front") # back self.boxFrontBack (wi, hi, False, move="mirror up", label="back") # top self.boxTopBottom (wi, di, True, move="up", label="top") # bottom self.boxTopBottom (wi, di, False, move="up", label="bottom") # open sides self.boxOpenSide(hi, move="up") self.boxOpenSide(hi, move="mirror up") # side covers self.coverPanel1Lid (di, hi, True, move="rotated up", label="side panel") self.coverPanel1Lid (di, hi, True, move="rotated up", label="side panel") # top handle if self.HandleThickness > 0 and self.HandleWidth > 0 : self.topHandle (wi, di, move="up", label="top handle") # front panel cover # two-part lid hinge eyes (both ends) if self.FrontCoverStyle=="two-part lid with hinge eyes (both ends)": # front panel sides self.coverPanel2Side(wi, hi, "top bottom" if self.FrontExtraTopAndBottomLocks else "none", move="mirror up", label="front panel right") self.coverPanel2Side(wi, hi, self.FrontLockStyle, move="up", label="front panel left") # lock if self.FrontLockStyle=="simple": self.lockSimple (move="up") elif self.FrontLockStyle=="with key": self.lockWithKey (True, move="up") #extra locks if self.FrontExtraTopAndBottomLocks: self.lockExtra(move="up") self.lockExtra(move="up") self.rectangularWall(self.thickness*16, self.thickness, "feee", move="up") self.rectangularWall(self.thickness*16, self.thickness, "feee", move="up") # three-part lid, higes not provided elif self.FrontCoverStyle=="three-part lid, higes not provided": # front panel sides self.coverPanel3Side(wi, hi, "bottom" if self.FrontExtraTopAndBottomLocks else "none", move="mirror up", label="front panel right") self.coverPanel3Side(wi, hi, "bottom" if self.FrontExtraTopAndBottomLocks else "none", move="up", label="front panel left") # front panel top self.coverPanel3Top(wi, hi, self.FrontLockStyle, move="up", label="front panel top") # lock if self.FrontLockStyle=="simple": self.lockSimple (move="up") elif self.FrontLockStyle=="with key": self.lockWithKey (False, move="up") #extra locks if self.FrontExtraTopAndBottomLocks: self.lockExtra(move="up") self.lockExtra(move="up") self.rectangularWall(self.thickness*16, self.thickness, "feee", move="up") self.rectangularWall(self.thickness*16, self.thickness, "feee", move="up") # slide-on lid elif self.FrontCoverStyle=="slide-on lid": self.coverPanel1Lid (wi, hi, False, move="up", label="front panel") # back panel cover self.coverPanel1Lid (wi, hi, False, move="up", label="back panel")