diff --git a/boxes/__init__.py b/boxes/__init__.py index 02cdc1f..332ec6b 100755 --- a/boxes/__init__.py +++ b/boxes/__init__.py @@ -247,6 +247,10 @@ class Boxes: self.addPart(edges.FingerHoleEdge(self, s)) self.addPart(edges.FingerHoles(self, s)) + ss = edges.StackableSettings(self.thickness) + self.addPart(edges.StackableEdge(self, ss, s)) + self.addPart(edges.StackableEdgeTop(self, ss, s)) + s = edges.DoveTailSettings(self.thickness) self.addPart(edges.DoveTailJoint(self, s)) self.addPart(edges.DoveTailJointCounterPart(self, s)) diff --git a/boxes/edges.py b/boxes/edges.py index 6150ee6..c7f6c7b 100644 --- a/boxes/edges.py +++ b/boxes/edges.py @@ -416,6 +416,79 @@ class CrossingFingerHoleEdge(Edge): self.fingerHolesAt(length/2.0, 0, self.height) Edge.__call__(self, length) +############################################################################# +#### Stackable Joints +############################################################################# + +class StackableSettings(Settings): + """Settings for StackableEdge classes + +Values: + +* absolute_params + + * angle : 60 : inside angle of the feet + +* relative (in multiples of thickness) + + * height : 2.0 : height of the feet + * width : 4.0 : width of the feet + * holedistance : 1.0 : distance from finger holes to bottom edge + +""" + + absolute_params = { + "angle" : 60, + } + relative_params = { + "height" : 2.0, + "width" : 4.0, + "holedistance" : 1.0, + } + +class StackableEdge(Edge): + """Edge for having stackable Boxes. The Edge creates feet on the bottom + and has matching recesses on the top corners.""" + + char = "s" + + bottom = True + + def __init__(self, boxes, settings, fingerjointsettings): + Edge.__init__(self, boxes, settings) + self.fingerjointsettings = fingerjointsettings + + def __call__(self, length, **kw): + s = self.settings + r = s.height / 2.0 / (1-math.cos(math.radians(s.angle))) + l = r * math.sin(math.radians(s.angle)) + p = 1 if self.bottom else -1 + + if self.bottom: + self.boxes.fingerHolesAt(0, s.height+self.settings.holedistance+0.5*self.boxes.thickness, + length, 0) + + self.boxes.edge(s.width) + self.boxes.corner(p*s.angle, r) + self.boxes.corner(-p*s.angle, r) + self.boxes.edge(length-2*s.width-4*l) + self.boxes.corner(-p*s.angle, r) + self.boxes.corner(p*s.angle, r) + self.boxes.edge(s.width) + + def _height(self): + return self.settings.height + self.settings.holedistance + self.settings.thickness + + def width(self): + return self._height() if self.bottom else 0 + + def margin(self): + return 0 if self.bottom else self._height() + +class StackableEdgeTop(StackableEdge): + char = "S" + bottom = False + ############################################################################# #### Dove Tail Joints ############################################################################# diff --git a/boxes/generators/box.py b/boxes/generators/box.py index 37c227f..8478a4c 100755 --- a/boxes/generators/box.py +++ b/boxes/generators/box.py @@ -29,7 +29,7 @@ class Box(Boxes): def render(self): x, y, h = self.x, self.y, self.h t = self.thickness - self.open(width=x+y+40, height=y+2*h+50) + self.open(width=max(x+y,2*x)+10*t, height=y+2*h+12*t) d2 = [edges.Bolts(2)] d3 = [edges.Bolts(3)] diff --git a/documentation/src/edges.rst b/documentation/src/edges.rst index 5ce71d3..883d2eb 100644 --- a/documentation/src/edges.rst +++ b/documentation/src/edges.rst @@ -7,6 +7,8 @@ callables. A set of instances are kept the ``.edges`` attribute of the * e : Edge * E : OutSetEdge +* s : StackableEdge +* S : StackableEdgeTop * f : FingerJointEdge * F : FingerJointEdgeCounterPart * h : FingerHoleEdge @@ -37,6 +39,18 @@ Straight Edges .. autoclass:: boxes.edges.Edge .. autoclass:: boxes.edges.OutSetEdge +Stackable Edges +--------------- + +.. autoclass:: boxes.edges.StackableEdge +.. autoclass:: boxes.edges.StackableEdgeTop + +Stackable Edge Settings +....................... + +.. autoclass:: boxes.edges.StackableSettings + :members: + Finger joints -------------