Add HandleEdge
This commit is contained in:
parent
4966ec631f
commit
bfaabc2619
|
@ -479,7 +479,7 @@ class Boxes:
|
|||
if default is None: default = "e"
|
||||
self.argparser.add_argument(
|
||||
"--top_edge", action="store",
|
||||
type=ArgparseEdgeType("efFhcESŠikvLtG"), choices=list("efFhcESŠikvfLtG"),
|
||||
type=ArgparseEdgeType("efFhcESŠikvLtGyY"), choices=list("efFhcESŠikvfLtGyY"),
|
||||
default=default, help="edge type for top edge")
|
||||
elif arg == "outside":
|
||||
if default is None: default = True
|
||||
|
@ -600,6 +600,9 @@ class Boxes:
|
|||
# Mounting Edge
|
||||
edges.MountingSettings(self.thickness, True,
|
||||
**self.edgesettings.get("Mounting", {})).edgeObjects(self)
|
||||
# Handle Edge
|
||||
edges.HandleEdgeSettings(self.thickness, True,
|
||||
**self.edgesettings.get("HandleEdge", {})).edgeObjects(self)
|
||||
# HexHoles
|
||||
self.hexHolesSettings = HexHolesSettings(self.thickness, True,
|
||||
**self.edgesettings.get("HexHoles", {}))
|
||||
|
|
142
boxes/edges.py
142
boxes/edges.py
|
@ -23,6 +23,39 @@ import abc
|
|||
|
||||
from boxes import gears
|
||||
|
||||
def argparseSections(s):
|
||||
"""
|
||||
Parse sections parameter
|
||||
|
||||
:param s: string to parse
|
||||
|
||||
"""
|
||||
|
||||
result = []
|
||||
|
||||
s = re.split(r"\s|:", s)
|
||||
|
||||
try:
|
||||
for part in s:
|
||||
m = re.match(r"^(\d+(\.\d+)?)/(\d+)$", part)
|
||||
if m:
|
||||
n = int(m.group(3))
|
||||
result.extend([float(m.group(1)) / n] * n)
|
||||
continue
|
||||
m = re.match(r"^(\d+(\.\d+)?)\*(\d+)$", part)
|
||||
if m:
|
||||
n = int(m.group(3))
|
||||
result.extend([float(m.group(1))] * n)
|
||||
continue
|
||||
result.append(float(part))
|
||||
except ValueError:
|
||||
raise argparse.ArgumentTypeError("Don't understand sections string")
|
||||
|
||||
if not result:
|
||||
result.append(0.0)
|
||||
|
||||
return result
|
||||
|
||||
def getDescriptions():
|
||||
d = {edge.char: edge.description for edge in globals().values()
|
||||
if inspect.isclass(edge) and issubclass(edge, BaseEdge)
|
||||
|
@ -2465,3 +2498,112 @@ class RoundedTriangleFingerHolesEdge(RoundedTriangleEdge):
|
|||
def __call__(self, length, **kw):
|
||||
self.fingerHolesAt(0, 0.5*self.settings.thickness, length, 0)
|
||||
super().__call__(length, **kw)
|
||||
|
||||
|
||||
class HandleEdgeSettings(Settings):
|
||||
|
||||
"""Settings for HandleEdge
|
||||
Values:
|
||||
|
||||
* absolute_params
|
||||
|
||||
* height : 20. : height above the wall in mm
|
||||
* radius : 10. : radius of corners in mm
|
||||
* hole_width : "40:40" : width of hole(s) in percentage of maximum hole width (width of edge - (n+1) * material thickness)
|
||||
* hole_height : 75. : height of hole(s) in percentage of maximum hole height (handle height - 2 * material thickness)
|
||||
* on_sides : True, : added to side panels if checked, to front and back otherwise (only used with top_edge parameter)
|
||||
|
||||
* relative
|
||||
|
||||
* outset : 1. : extend the handle along the length of the edge (multiples of thickness)
|
||||
|
||||
"""
|
||||
|
||||
absolute_params = {
|
||||
"height" : 20.,
|
||||
"radius" : 10.,
|
||||
"hole_width" : "40:40",
|
||||
"hole_height" : 75.,
|
||||
"on_sides": True,
|
||||
}
|
||||
|
||||
relative_params = {
|
||||
"outset" : 1.,
|
||||
}
|
||||
|
||||
def edgeObjects(self, boxes, chars="yY", add=True):
|
||||
edges = [HandleEdge(boxes, self),
|
||||
HandleHoleEdge(boxes, self)]
|
||||
return self._edgeObjects(edges, boxes, chars, add)
|
||||
|
||||
# inspiration came from https://www.thingiverse.com/thing:327393
|
||||
|
||||
class HandleEdge(Edge):
|
||||
"""Extends an 'edge' by adding a rounded bumpout with optional holes"""
|
||||
description = "Handle for e.g. a drawer"
|
||||
char = "y"
|
||||
extra_height = 0.0
|
||||
|
||||
def __call__(self, length, **kw):
|
||||
length += 2 * self.settings.outset
|
||||
extra_height = self.extra_height * self.settings.thickness
|
||||
|
||||
r = self.settings.radius
|
||||
if r > length / 2:
|
||||
r = length / 2
|
||||
if r > self.settings.height:
|
||||
r = self.settings.height
|
||||
|
||||
widths = argparseSections(self.settings.hole_width)
|
||||
|
||||
if self.settings.outset:
|
||||
self.polyline(0, -180, self.settings.outset, 90)
|
||||
else:
|
||||
self.corner(-90)
|
||||
|
||||
if self.settings.hole_height and sum(widths) > 0:
|
||||
if sum(widths) < 100:
|
||||
slot_offset = ((1 - sum(widths) / 100) * (length - (len(widths) + 1) * self.thickness)) / (len(widths) * 2)
|
||||
else:
|
||||
slot_offset = 0
|
||||
|
||||
slot_height = (self.settings.height - 2 * self.thickness) * self.settings.hole_height / 100
|
||||
slot_x = self.thickness + slot_offset
|
||||
|
||||
for w in widths:
|
||||
if sum(widths) > 100:
|
||||
slotwidth = w / sum(widths) * (length - (len(widths) + 1) * self.thickness)
|
||||
else:
|
||||
slotwidth = w / 100 * (length - (len(widths) + 1) * self.thickness)
|
||||
slot_x += slotwidth / 2
|
||||
with self.saved_context():
|
||||
self.moveTo((self.settings.height / 2) + extra_height, slot_x, 0)
|
||||
self.rectangularHole(0,0,slot_height,slotwidth,slot_height/2,True,True)
|
||||
slot_x += slotwidth / 2 + slot_offset + self.thickness + slot_offset
|
||||
|
||||
self.edge(self.settings.height - r + extra_height, tabs=1)
|
||||
self.corner(90, r, tabs=1)
|
||||
self.edge(length - 2 * r, tabs=1)
|
||||
self.corner(90, r, tabs=1)
|
||||
self.edge(self.settings.height - r + extra_height, tabs=1)
|
||||
|
||||
if self.settings.outset:
|
||||
self.polyline(0, 90, self.settings.outset, -180)
|
||||
else:
|
||||
self.corner(-90)
|
||||
|
||||
def margin(self):
|
||||
return self.settings.height
|
||||
|
||||
class HandleHoleEdge(HandleEdge):
|
||||
"""Extends an 'edge' by adding a rounded bumpout with optional holes and holes for parallel finger joint"""
|
||||
description = "Handle with holes for parallel finger joint"
|
||||
char = "Y"
|
||||
extra_height = 1.0
|
||||
|
||||
def __call__(self, length, **kw):
|
||||
self.fingerHolesAt(0, -0.5*self.settings.thickness, length, 0)
|
||||
super().__call__(length, **kw)
|
||||
|
||||
def margin(self):
|
||||
return self.settings.height + self.extra_height*self.settings.thickness
|
||||
|
|
|
@ -30,6 +30,7 @@ class AllEdges(Boxes):
|
|||
self.addSettingsArgs(edges.LidSettings)
|
||||
self.addSettingsArgs(edges.ClickSettings)
|
||||
self.addSettingsArgs(edges.FlexSettings)
|
||||
self.addSettingsArgs(edges.HandleEdgeSettings)
|
||||
|
||||
self.buildArgParser(x=100)
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ class StorageShelf(_TopEdge):
|
|||
#if top_edge is t put the handle on the x walls
|
||||
if(self.top_edge=='t'):
|
||||
t1,t2,t3,t4=(t2,t1,t4,t3)
|
||||
self.closedtop = self.top_edge in "fFhŠ"
|
||||
self.closedtop = self.top_edge in "fFhŠY"
|
||||
|
||||
# x sides
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ class _TopEdge(Boxes):
|
|||
|
||||
def addTopEdgeSettings(self, fingerjoint={}, stackable={}, hinge={},
|
||||
cabinethinge={}, lid={}, click={},
|
||||
roundedtriangle={}, mounting={}):
|
||||
roundedtriangle={}, mounting={}, handle={}):
|
||||
self.addSettingsArgs(edges.FingerJointSettings, **fingerjoint)
|
||||
self.addSettingsArgs(edges.StackableSettings, **stackable)
|
||||
self.addSettingsArgs(edges.HingeSettings, **hinge)
|
||||
|
@ -101,6 +101,7 @@ class _TopEdge(Boxes):
|
|||
self.addSettingsArgs(edges.ClickSettings, **click)
|
||||
self.addSettingsArgs(edges.RoundedTriangleEdgeSettings, **roundedtriangle)
|
||||
self.addSettingsArgs(edges.MountingSettings, **mounting)
|
||||
self.addSettingsArgs(edges.HandleEdgeSettings, **handle)
|
||||
|
||||
def topEdges(self, top_edge):
|
||||
t1 = t2 = t3 = t4 = self.edges.get(top_edge, self.edges["e"])
|
||||
|
@ -128,6 +129,18 @@ class _TopEdge(Boxes):
|
|||
t4 = "G"
|
||||
else: #PARAM_BACK
|
||||
t2 = "G"
|
||||
elif t1.char == "y":
|
||||
t1 = t2 = t3 = t4 = "e"
|
||||
if self.edges["y"].settings.on_sides == True:
|
||||
t1 = t3 = "y"
|
||||
else:
|
||||
t2 = t4 = "y"
|
||||
elif t1.char == "Y":
|
||||
t1 = t2 = t3 = t4 = "h"
|
||||
if self.edges["Y"].settings.on_sides == True:
|
||||
t1 = t3 = "Y"
|
||||
else:
|
||||
t2 = t4 = "Y"
|
||||
return [t1, t2, t3, t4]
|
||||
|
||||
def drawLid(self, x, y, top_edge, bedBolts=[None, None]):
|
||||
|
@ -136,7 +149,7 @@ class _TopEdge(Boxes):
|
|||
self.rectangularWall(x, y, "CCCC", bedBolts=[d2, d3, d2, d3], move="up", label="top")
|
||||
elif top_edge == "f":
|
||||
self.rectangularWall(x, y, "FFFF", move="up", label="top")
|
||||
elif top_edge in "FhŠ":
|
||||
elif top_edge in "FhŠY":
|
||||
self.rectangularWall(x, y, "ffff", move="up", label="top")
|
||||
elif top_edge == "L":
|
||||
self.rectangularWall(x, y, "nlmE", move="up", label="lid top")
|
||||
|
|
|
@ -61,6 +61,8 @@ A set of instances are kept the ``.edges`` attribute of the
|
|||
* t : RoundedTriangleEdge
|
||||
* uUvV : CabinetHingeEdge
|
||||
* X : FlexEdge
|
||||
* y : HandleEdge
|
||||
* Y : HandleHoleEdge
|
||||
* Z : GroovedEdgeCounterPart
|
||||
* z : GroovedEdge
|
||||
|
||||
|
|
Loading…
Reference in New Issue