Add edges for hinges
This commit is contained in:
parent
a1c6652552
commit
60d465c83a
|
@ -256,7 +256,7 @@ class Boxes:
|
||||||
elif arg == "top_edge":
|
elif arg == "top_edge":
|
||||||
self.argparser.add_argument(
|
self.argparser.add_argument(
|
||||||
"--top_edge", action="store",
|
"--top_edge", action="store",
|
||||||
type=ArgparseEdgeType("ecES"), choices=list("ecES"),
|
type=ArgparseEdgeType("ecESi"), choices=list("ecESi"),
|
||||||
default="e", help="edge type for top edge")
|
default="e", help="edge type for top edge")
|
||||||
else:
|
else:
|
||||||
raise ValueError("No default for argument", arg)
|
raise ValueError("No default for argument", arg)
|
||||||
|
@ -324,6 +324,11 @@ class Boxes:
|
||||||
s = edges.ClickSettings(self.thickness)
|
s = edges.ClickSettings(self.thickness)
|
||||||
self.addPart(edges.ClickConnector(self, s))
|
self.addPart(edges.ClickConnector(self, s))
|
||||||
self.addPart(edges.ClickEdge(self, s))
|
self.addPart(edges.ClickEdge(self, s))
|
||||||
|
# Hinges
|
||||||
|
s = edges.HingeSettings(self.thickness)
|
||||||
|
for i in range(1, 4):
|
||||||
|
self.addPart(edges.Hinge(self, s, i))
|
||||||
|
self.addPart(edges.HingePin(self, s, i))
|
||||||
# Nuts
|
# Nuts
|
||||||
self.addPart(NutHole(self, None))
|
self.addPart(NutHole(self, None))
|
||||||
|
|
||||||
|
|
212
boxes/edges.py
212
boxes/edges.py
|
@ -550,6 +550,218 @@ class StackableEdgeTop(StackableEdge):
|
||||||
description = "Stackable (top)"
|
description = "Stackable (top)"
|
||||||
bottom = False
|
bottom = False
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
#### Hinges
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
class HingeSettings(Settings):
|
||||||
|
|
||||||
|
"""Settings for Hinge and HingePin classes
|
||||||
|
Values:
|
||||||
|
|
||||||
|
* absolute_params
|
||||||
|
|
||||||
|
* style : B : currently "A" or "B"
|
||||||
|
* outset : False : have lid overlap at the sides (similar to OutSetEdge)
|
||||||
|
* pinwidth : 1.0 : set to lower value to get disks surrounding the pins
|
||||||
|
|
||||||
|
* relative (in multiples of thickness)
|
||||||
|
|
||||||
|
* hingestrength : 1 : thickness of the arc holding the pin in place
|
||||||
|
* axle : 2 : diameter of the pin hole
|
||||||
|
|
||||||
|
"""
|
||||||
|
absolute_params = {
|
||||||
|
"style" : "B",
|
||||||
|
"outset" : False,
|
||||||
|
"pinwidth" : 0.5,
|
||||||
|
}
|
||||||
|
|
||||||
|
relative_params = {
|
||||||
|
"hingestrength" : 1,#1.5-0.5*2**0.5,
|
||||||
|
"axle" : 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
class Hinge(BaseEdge):
|
||||||
|
|
||||||
|
char = 'i'
|
||||||
|
description = "Straight edge with hinge eye"
|
||||||
|
|
||||||
|
def __init__(self, boxes, settings=None, layout=1):
|
||||||
|
super(Hinge, self).__init__(boxes,settings)
|
||||||
|
self.layout = layout
|
||||||
|
self.char = "eijk"[layout]
|
||||||
|
self.description = self.description + ('', ' (start)', ' (end)', ' (both ends)')[layout]
|
||||||
|
|
||||||
|
def margin(self):
|
||||||
|
return 3 * self.thickness
|
||||||
|
|
||||||
|
def A(self, _reversed=False):
|
||||||
|
t = self.thickness
|
||||||
|
r = t*0.5*2**0.5
|
||||||
|
hinge = (
|
||||||
|
0,
|
||||||
|
45, 0,
|
||||||
|
(-360, r), 0,
|
||||||
|
135,
|
||||||
|
t,
|
||||||
|
90,
|
||||||
|
0.5*t,
|
||||||
|
(180, 1.5*t), 0,
|
||||||
|
(-90, 0.5*t), 0
|
||||||
|
)
|
||||||
|
if _reversed:
|
||||||
|
hinge = reversed(hinge)
|
||||||
|
self.polyline(*hinge)
|
||||||
|
|
||||||
|
def Alen(self):
|
||||||
|
return 2.5 * self.thickness
|
||||||
|
|
||||||
|
def B(self, _reversed=False):
|
||||||
|
t = self.thickness
|
||||||
|
|
||||||
|
hinge = (
|
||||||
|
0, -90,
|
||||||
|
0.5*t,
|
||||||
|
(180, 0.5*self.settings.axle+self.settings.hingestrength), 0,
|
||||||
|
(-90, 0.5*t), 0
|
||||||
|
)
|
||||||
|
pos = 0.5*self.settings.axle+self.settings.hingestrength
|
||||||
|
if _reversed:
|
||||||
|
hinge = reversed(hinge)
|
||||||
|
self.hole(0.5*t+pos, -0.5*t, 0.5*self.settings.axle)
|
||||||
|
else:
|
||||||
|
self.hole(pos, -0.5*t, 0.5*self.settings.axle)
|
||||||
|
self.polyline(*hinge)
|
||||||
|
|
||||||
|
def Blen(self):
|
||||||
|
return self.settings.axle + 2*self.settings.hingestrength + 0.5*self.thickness
|
||||||
|
|
||||||
|
def __call__(self, l, **kw):
|
||||||
|
hlen = getattr(self, self.settings.style+'len')()
|
||||||
|
if self.layout & 1:
|
||||||
|
getattr(self, self.settings.style)()
|
||||||
|
self.edge(l - (self.layout & 1)*hlen - bool(self.layout & 2)*hlen)
|
||||||
|
if self.layout & 2:
|
||||||
|
getattr(self, self.settings.style)(True)
|
||||||
|
|
||||||
|
class HingePin(BaseEdge):
|
||||||
|
char = 'I'
|
||||||
|
description = "Edge with hinge pin"
|
||||||
|
|
||||||
|
def __init__(self, boxes, settings=None, layout=1):
|
||||||
|
super(HingePin, self).__init__(boxes,settings)
|
||||||
|
self.layout = layout
|
||||||
|
self.char = "EIJK"[layout]
|
||||||
|
self.description = self.description + ('', ' (start)', ' (end)', ' (both ends)')[layout]
|
||||||
|
|
||||||
|
def startwidth(self):
|
||||||
|
if self.layout & 1:
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
return self.settings.outset * self.boxes.thickness
|
||||||
|
|
||||||
|
def endwidth(self):
|
||||||
|
if self.layout & 2:
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
return self.settings.outset * self.boxes.thickness
|
||||||
|
|
||||||
|
def margin(self):
|
||||||
|
return self.thickness + self.boxes.spacing
|
||||||
|
|
||||||
|
def A(self, _reversed=False):
|
||||||
|
t = self.thickness
|
||||||
|
pin = (0, -90,
|
||||||
|
t, 90,
|
||||||
|
t,
|
||||||
|
90,
|
||||||
|
t,
|
||||||
|
-90)
|
||||||
|
|
||||||
|
if self.settings.outset:
|
||||||
|
pin += (
|
||||||
|
1.5*t,
|
||||||
|
-90,
|
||||||
|
t,
|
||||||
|
90,
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
pin += (0.0,)
|
||||||
|
if _reversed:
|
||||||
|
pin = reversed(pin)
|
||||||
|
self.polyline(*pin)
|
||||||
|
|
||||||
|
def Alen(self):
|
||||||
|
if self.settings.outset:
|
||||||
|
return 2.5* self.thickness
|
||||||
|
else:
|
||||||
|
return self.thickness
|
||||||
|
|
||||||
|
def B(self, _reversed=False):
|
||||||
|
t = self.thickness
|
||||||
|
pinl = (self.settings.axle**2-t**2)**0.5 * self.settings.pinwidth
|
||||||
|
d = (self.settings.axle - pinl) / 2.0
|
||||||
|
pin = (self.settings.hingestrength+d, -90,
|
||||||
|
t, 90,
|
||||||
|
pinl,
|
||||||
|
90,
|
||||||
|
t,
|
||||||
|
-90, d)
|
||||||
|
|
||||||
|
if self.settings.outset:
|
||||||
|
pin += (
|
||||||
|
0,
|
||||||
|
self.settings.hingestrength+0.5*t,
|
||||||
|
-90,
|
||||||
|
t,
|
||||||
|
90,
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
if _reversed:
|
||||||
|
pin = reversed(pin)
|
||||||
|
self.polyline(*pin)
|
||||||
|
|
||||||
|
def parts(self, numhinges, move=''):
|
||||||
|
"""Draw additional parts needed"""
|
||||||
|
if self.settings.pinwidth == 1.0:
|
||||||
|
return
|
||||||
|
pinl = (self.settings.axle**2-self.thickness**2)**0.5 * self.settings.pinwidth
|
||||||
|
|
||||||
|
height = self.settings.axle + 2 * self.boxes.spacing
|
||||||
|
width = numhinges * (self.settings.axle + self.boxes.spacing) + self.boxes.spacing
|
||||||
|
a = (self.settings.axle - 0.05*self.thickness)
|
||||||
|
|
||||||
|
if self.boxes.move(width, height, move, before=True):
|
||||||
|
return
|
||||||
|
self.ctx.save()
|
||||||
|
|
||||||
|
self.boxes.moveTo(-0.5 * a)
|
||||||
|
for i in range(numhinges):
|
||||||
|
self.boxes.moveTo(self.boxes.spacing + a)
|
||||||
|
self.boxes.rectangularHole(0, a/2.0, pinl, self.thickness)
|
||||||
|
self.boxes.corner(360, a/2.0)
|
||||||
|
|
||||||
|
self.ctx.restore()
|
||||||
|
self.boxes.move(width, height, move)
|
||||||
|
|
||||||
|
def Blen(self):
|
||||||
|
l = self.settings.hingestrength+self.settings.axle
|
||||||
|
if self.settings.outset:
|
||||||
|
l += self.settings.hingestrength + 0.5 * self.thickness
|
||||||
|
return l
|
||||||
|
|
||||||
|
def __call__(self, l, **kw):
|
||||||
|
plen = getattr(self, self.settings.style+'len')()
|
||||||
|
|
||||||
|
if self.layout & 1:
|
||||||
|
getattr(self, self.settings.style)()
|
||||||
|
self.edge(l - (self.layout & 1)*plen - bool(self.layout & 2)*plen)
|
||||||
|
if self.layout & 2:
|
||||||
|
getattr(self, self.settings.style)(True)
|
||||||
|
|
||||||
|
|
||||||
#############################################################################
|
#############################################################################
|
||||||
#### Click Joints
|
#### Click Joints
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
|
@ -14,6 +14,8 @@ callables. A set of instances are kept the ``.edges`` attribute of the
|
||||||
* h : FingerHoleEdge
|
* h : FingerHoleEdge
|
||||||
* d : DoveTailJoint
|
* d : DoveTailJoint
|
||||||
* D : DoveTailJointCounterPart
|
* D : DoveTailJointCounterPart
|
||||||
|
* ijk : Hinge (start, end, both sides)
|
||||||
|
* IJK : HingePin (start, end, both sides)
|
||||||
|
|
||||||
Edges of the same type share a settings instance to make sure both
|
Edges of the same type share a settings instance to make sure both
|
||||||
sides match (when the same length is given).
|
sides match (when the same length is given).
|
||||||
|
@ -120,3 +122,20 @@ CompoundEdge
|
||||||
------------
|
------------
|
||||||
.. autoclass:: boxes.edges.CompoundEdge
|
.. autoclass:: boxes.edges.CompoundEdge
|
||||||
|
|
||||||
|
Hinges
|
||||||
|
------
|
||||||
|
|
||||||
|
Hinge Settings
|
||||||
|
..............
|
||||||
|
|
||||||
|
.. autoclass:: boxes.edges.HingeSettings
|
||||||
|
|
||||||
|
Hinge
|
||||||
|
.....
|
||||||
|
|
||||||
|
.. autoclass:: boxes.edges.Hinge
|
||||||
|
|
||||||
|
HingePin
|
||||||
|
........
|
||||||
|
|
||||||
|
.. autoclass:: boxes.edges.HingePin
|
||||||
|
|
Loading…
Reference in New Issue