diff --git a/box.py b/box.py
index 1732688..722f3fd 100755
--- a/box.py
+++ b/box.py
@@ -30,8 +30,8 @@ class Box(Boxes):
self.edges["f"].settings.setValues(self.thickness, space=3, finger=3,
surroundingspaces=1)
- d2 = [Bolts(2)]
- d3 = [Bolts(3)]
+ d2 = [edges.Bolts(2)]
+ d3 = [edges.Bolts(3)]
d2 = d3 = None
diff --git a/box2.py b/box2.py
index 8b0a38a..e776a3a 100755
--- a/box2.py
+++ b/box2.py
@@ -31,8 +31,8 @@ class Box(Boxes):
self.edges["f"].settings.setValues(self.thickness, space=3, finger=3,
surroundingspaces=1)
- d2 = [Bolts(2)]
- d3 = [Bolts(3)]
+ d2 = [edges.Bolts(2)]
+ d3 = [edges.Bolts(3)]
d2 = d3 = None
diff --git a/box3.py b/box3.py
index 448b466..04dda3a 100755
--- a/box3.py
+++ b/box3.py
@@ -31,8 +31,8 @@ class Box(Boxes):
self.edges["f"].settings.setValues(self.thickness, space=3, finger=3,
surroundingspaces=1)
- d2 = [Bolts(2)]
- d3 = [Bolts(3)]
+ d2 = [edges.Bolts(2)]
+ d3 = [edges.Bolts(3)]
d2 = d3 = None
diff --git a/boxes/__init__.py b/boxes/__init__.py
index b74a683..5039b2d 100755
--- a/boxes/__init__.py
+++ b/boxes/__init__.py
@@ -20,6 +20,7 @@ import argparse
from argparse import ArgumentParser
import re
from functools import wraps
+from boxes import edges
def dist(dx, dy):
return (dx*dx+dy*dy)**0.5
@@ -34,430 +35,11 @@ def restore(func):
self.ctx.move_to(*pt)
return f
-class BoltPolicy:
- """Abstract class
- Distributes (bed) bolts on a number of segments
- (fingers of a finger joint)
- """
- def drawbolt(self, pos):
- """Add a bolt to this segment?"""
- return False
-
- def numFingers(self, numfingers):
- """returns next smaller, possible number of fingers"""
- return numFingers
-
- def _even(self, numFingers):
- return (numFingers//2) * 2
- def _odd(self, numFingers):
- if numFingers % 2:
- return numFingers
- else:
- return numFingers - 1
-
-class Bolts(BoltPolicy):
- """Distribute a fixed number of bolts evenly"""
- def __init__(self, bolts=1):
- self.bolts = bolts
- def numFingers(self, numFingers):
- if self.bolts % 2:
- self.fingers = self._even(numFingers)
- else:
- self.fingers = numFingers
- return self.fingers
-
- def drawBolt(self, pos):
- if pos > self.fingers//2:
- pos = self.fingers - pos
- if pos==0:
- return False
- if pos == self.fingers//2 and not (self.bolts % 2):
- return False
- result = (math.floor((float(pos)*(self.bolts+1)/self.fingers)-0.01) !=
- math.floor((float(pos+1)*(self.bolts+1)/self.fingers)-0.01))
- #print pos, result, ((float(pos)*(self.bolts+1)/self.fingers)-0.01), ((float(pos+1)*(self.bolts+1)/self.fingers)-0.01)
- return result
-
-#############################################################################
-### Settings
-#############################################################################
-
-class Settings:
- absolute_params = { }
- relative_params = { }
-
- def __init__(self, thickness, relative=True, **kw):
- self.values = self.absolute_params.copy()
-
- factor = 1.0
- if relative:
- factor = thickness
- for name, value in self.relative_params.items():
- self.values[name] = value * factor
- self.setValues(thickness, relative, **kw)
-
- def setValues(self, thickness, relative=True, **kw):
- factor = 1.0
- if relative:
- factor = thickness
- for name, value in kw.items():
- if name in self.absolute_params:
- self.values[name] = value
- elif name in self.relative_params:
- self.values[name] = value * factor
- else:
- raise ValueError("Unknown parameter for %s: %s" % (
- self.__class__.__name__, name))
-
- def __getattr__(self, name):
- return self.values[name]
-
-#############################################################################
-### Edges
-#############################################################################
-
-
-class Edge:
- char = 'e'
-
- def __init__(self, boxes, settings):
- self.boxes = boxes
- self.ctx = boxes.ctx
- self.settings = settings
-
- def __getattr__(self, name):
- """Hack for using unalter code form Boxes class"""
- return getattr(self.boxes, name)
-
- def __call__(self, length, **kw):
- self.ctx.move_to(0,0)
- self.ctx.line_to(length, 0)
- self.ctx.translate(*self.ctx.get_current_point())
-
- def width(self):
- return 0.0
-
- def margin(self):
- return self.boxes.spacing
-
- def spacing(self):
- return self.width() + self.margin()
-
- def startAngle(self):
- return 0.0
-
- def endAngle(self):
- return 0.0
-
-class OutSetEdge(Edge):
- char = 'E'
-
- def width(self):
- return self.boxes.thickness
-
-class CompoundEdge(Edge):
- def __init__(self, boxes, types, lengths):
- Edge.__init__(self, boxes, None)
- self.types = [self.edges.get(edge, edge) for edge in types]
- self.lengths = lengths
- self.length = sum(lengths)
-
- def width(self):
- return self.types[0].width()
-
- def margin(self):
- return max((e.margin() for e in self.types))
-
- def __call__(self, length, **kw):
- if length and abs(length - self.length) > 1E-5:
- raise ValueError("Wrong length for CompoundEdge")
- for e, l in zip(self.types, self.lengths):
- # XXX different margins???
- e(l)
-
-class Slot(Edge):
- def __init__(self, boxes, depth):
- Edge.__init__(self, boxes, None)
- self.depth = depth
-
- def __call__(self, length, **kw):
- if self.depth:
- self.boxes.corner(90)
- self.boxes.edge(self.depth)
- self.boxes.corner(-90)
- self.boxes.edge(length)
- self.boxes.corner(-90)
- self.boxes.edge(self.depth)
- self.boxes.corner(90)
- else:
- self.boxes.edge(self.length)
-
-class SlottedEdge(Edge):
-
- def __init__(self, boxes, sections, edge="e", slots=0):
- Edge.__init__(self, boxes, None)
- self.edge = self.edges.get(edge, edge)
- self.sections = sections
- self.slots = slots
-
- def width(self):
- return self.edge.width()
-
- def margin(self):
- return self.edge.margin()
-
- def __call__(self, length, **kw):
- for l in self.sections[:-1]:
- self.edge(l)
- if self.slots:
- Slot(self.boxes, self.slots)(self.thickness)
- else:
- self.edge(self.thickness)
- self.edge(self.sections[-1])
-
-class FingerJointSettings(Settings):
- absolute_params = {
- "surroundingspaces" : 2,
- }
-
- relative_params = {
- "space" : 1.0,
- "finger" : 1.0,
- "height" : 1.0,
- "width" : 1.0,
- }
-
-class FingerJointEdge(Edge):
- char = 'f'
- positive = True
-
- def __call__(self, length,
- bedBolts=None, bedBoltSettings=None, **kw):
- positive = self.positive
- space, finger = self.settings.space, self.settings.finger
-
- fingers = int((length-(self.settings.surroundingspaces-1)*space) //
- (space+finger))
-
- if bedBolts:
- fingers = bedBolts.numFingers(fingers)
- leftover = length - fingers*(space+finger) + space
-
- s, f, thickness = space, finger, self.thickness
- d, d_nut, h_nut, l, l1 = bedBoltSettings or self.boxes.bedBoltSettings
- p = 1 if positive else -1
-
- if fingers <= 0:
- fingers = 0
- leftover = length
-
- self.edge(leftover/2.0)
- for i in range(fingers):
- if i !=0:
- if not positive and bedBolts and bedBolts.drawBolt(i):
- self.hole(0.5*space,
- 0.5*self.thickness, 0.5*d)
- if positive and bedBolts and bedBolts.drawBolt(i):
- self.bedBoltHole(s, bedBoltSettings)
- else:
- self.edge(s)
- self.corner(-90*p)
- self.edge(self.settings.height)
- self.corner(90*p)
- self.edge(f)
- self.corner(90*p)
- self.edge(self.settings.height)
- self.corner(-90*p)
- self.edge(leftover/2.0)
-
- def margin(self):
- return self.boxes.spacing + self.boxes.thickness
-
-class FingerJointEdgeCounterPart(FingerJointEdge):
- char = 'F'
- positive = False
-
- def width(self):
- return self.boxes.thickness
-
- def margin(self):
- return self.boxes.spacing
-
-class FingerHoleEdge(Edge):
- char = 'h'
-
- def __call__(self, length, dist=None,
- bedBolts=None, bedBoltSettings=None, **kw):
- if dist is None:
- dist = self.fingerHoleEdgeWidth * self.thickness
- self.ctx.save()
- self.moveTo(0, dist+self.thickness/2)
- self.fingerHoles(length, bedBolts, bedBoltSettings)
- self.ctx.restore()
- # XXX continue path
- self.ctx.move_to(0, 0)
- self.ctx.line_to(length, 0)
- self.ctx.translate(*self.ctx.get_current_point())
-
- def width(self):
- return (self.fingerHoleEdgeWidth+1) * self.thickness
-
-class CrossingFingerHoleEdge(Edge):
- def __init__(self, boxes, height, **kw):
- Edge.__init__(self, boxes, None, **kw)
- self.height = height
-
- def __call__(self, length, **kw):
- self.fingerHolesAt(length/2.0, 0, self.height)
- Edge.__call__(self, length)
-
-
-class DoveTailSettings(Settings):
- absolute_params = {
- "angle" : 50,
- }
- relative_params = {
- "size" : 3,
- "depth" : 1.5,
- "radius" : 0.2,
- }
-
-class DoveTailJoint(Edge):
- char = 'd'
- positive = True
-
- def __call__(self, length, **kw):
- s = self.settings
- radius = max(s.radius, self.boxes.burn) # no smaller than burn
- positive = self.positive
- a = s.angle + 90
- alpha = 0.5*math.pi - math.pi*s.angle/180.0
-
- l1 = radius/math.tan(alpha/2.0)
- diffx = 0.5*s.depth/math.tan(alpha)
- l2 = 0.5*s.depth / math.sin(alpha)
-
- sections = int((length) // (s.size*2))
- leftover = length - sections*s.size*2
-
- p = 1 if positive else -1
-
- self.edge((s.size+leftover)/2.0+diffx-l1)
- for i in range(sections):
- self.corner(-1*p*a, radius)
- self.edge(2*(l2-l1))
- self.corner(p*a, radius)
- self.edge(2*(diffx-l1)+s.size)
- self.corner(p*a, radius)
- self.edge(2*(l2-l1))
- self.corner(-1*p*a, radius)
- if i.
+
+import math
+
+class BoltPolicy:
+ """Abstract class
+ Distributes (bed) bolts on a number of segments
+ (fingers of a finger joint)
+ """
+ def drawbolt(self, pos):
+ """Add a bolt to this segment?"""
+ return False
+
+ def numFingers(self, numfingers):
+ """returns next smaller, possible number of fingers"""
+ return numFingers
+
+ def _even(self, numFingers):
+ return (numFingers//2) * 2
+ def _odd(self, numFingers):
+ if numFingers % 2:
+ return numFingers
+ else:
+ return numFingers - 1
+
+class Bolts(BoltPolicy):
+ """Distribute a fixed number of bolts evenly"""
+ def __init__(self, bolts=1):
+ self.bolts = bolts
+ def numFingers(self, numFingers):
+ if self.bolts % 2:
+ self.fingers = self._even(numFingers)
+ else:
+ self.fingers = numFingers
+ return self.fingers
+
+ def drawBolt(self, pos):
+ if pos > self.fingers//2:
+ pos = self.fingers - pos
+ if pos==0:
+ return False
+ if pos == self.fingers//2 and not (self.bolts % 2):
+ return False
+ result = (math.floor((float(pos)*(self.bolts+1)/self.fingers)-0.01) !=
+ math.floor((float(pos+1)*(self.bolts+1)/self.fingers)-0.01))
+ #print pos, result, ((float(pos)*(self.bolts+1)/self.fingers)-0.01), ((float(pos+1)*(self.bolts+1)/self.fingers)-0.01)
+ return result
+
+#############################################################################
+### Settings
+#############################################################################
+
+class Settings:
+ absolute_params = { }
+ relative_params = { }
+
+ def __init__(self, thickness, relative=True, **kw):
+ self.values = self.absolute_params.copy()
+
+ factor = 1.0
+ if relative:
+ factor = thickness
+ for name, value in self.relative_params.items():
+ self.values[name] = value * factor
+ self.setValues(thickness, relative, **kw)
+
+ def setValues(self, thickness, relative=True, **kw):
+ factor = 1.0
+ if relative:
+ factor = thickness
+ for name, value in kw.items():
+ if name in self.absolute_params:
+ self.values[name] = value
+ elif name in self.relative_params:
+ self.values[name] = value * factor
+ else:
+ raise ValueError("Unknown parameter for %s: %s" % (
+ self.__class__.__name__, name))
+
+ def __getattr__(self, name):
+ return self.values[name]
+
+#############################################################################
+### Edges
+#############################################################################
+
+
+class Edge:
+ char = 'e'
+
+ def __init__(self, boxes, settings):
+ self.boxes = boxes
+ self.ctx = boxes.ctx
+ self.settings = settings
+
+ def __getattr__(self, name):
+ """Hack for using unalter code form Boxes class"""
+ return getattr(self.boxes, name)
+
+ def __call__(self, length, **kw):
+ self.ctx.move_to(0,0)
+ self.ctx.line_to(length, 0)
+ self.ctx.translate(*self.ctx.get_current_point())
+
+ def width(self):
+ return 0.0
+
+ def margin(self):
+ return self.boxes.spacing
+
+ def spacing(self):
+ return self.width() + self.margin()
+
+ def startAngle(self):
+ return 0.0
+
+ def endAngle(self):
+ return 0.0
+
+class OutSetEdge(Edge):
+ char = 'E'
+
+ def width(self):
+ return self.boxes.thickness
+
+class CompoundEdge(Edge):
+ def __init__(self, boxes, types, lengths):
+ Edge.__init__(self, boxes, None)
+ self.types = [self.edges.get(edge, edge) for edge in types]
+ self.lengths = lengths
+ self.length = sum(lengths)
+
+ def width(self):
+ return self.types[0].width()
+
+ def margin(self):
+ return max((e.margin() for e in self.types))
+
+ def __call__(self, length, **kw):
+ if length and abs(length - self.length) > 1E-5:
+ raise ValueError("Wrong length for CompoundEdge")
+ for e, l in zip(self.types, self.lengths):
+ # XXX different margins???
+ e(l)
+
+class Slot(Edge):
+ def __init__(self, boxes, depth):
+ Edge.__init__(self, boxes, None)
+ self.depth = depth
+
+ def __call__(self, length, **kw):
+ if self.depth:
+ self.boxes.corner(90)
+ self.boxes.edge(self.depth)
+ self.boxes.corner(-90)
+ self.boxes.edge(length)
+ self.boxes.corner(-90)
+ self.boxes.edge(self.depth)
+ self.boxes.corner(90)
+ else:
+ self.boxes.edge(self.length)
+
+class SlottedEdge(Edge):
+
+ def __init__(self, boxes, sections, edge="e", slots=0):
+ Edge.__init__(self, boxes, None)
+ self.edge = self.edges.get(edge, edge)
+ self.sections = sections
+ self.slots = slots
+
+ def width(self):
+ return self.edge.width()
+
+ def margin(self):
+ return self.edge.margin()
+
+ def __call__(self, length, **kw):
+ for l in self.sections[:-1]:
+ self.edge(l)
+ if self.slots:
+ Slot(self.boxes, self.slots)(self.thickness)
+ else:
+ self.edge(self.thickness)
+ self.edge(self.sections[-1])
+
+class FingerJointSettings(Settings):
+ absolute_params = {
+ "surroundingspaces" : 2,
+ }
+
+ relative_params = {
+ "space" : 1.0,
+ "finger" : 1.0,
+ "height" : 1.0,
+ "width" : 1.0,
+ }
+
+class FingerJointEdge(Edge):
+ char = 'f'
+ positive = True
+
+ def __call__(self, length,
+ bedBolts=None, bedBoltSettings=None, **kw):
+ positive = self.positive
+ space, finger = self.settings.space, self.settings.finger
+
+ fingers = int((length-(self.settings.surroundingspaces-1)*space) //
+ (space+finger))
+
+ if bedBolts:
+ fingers = bedBolts.numFingers(fingers)
+ leftover = length - fingers*(space+finger) + space
+
+ s, f, thickness = space, finger, self.thickness
+ d, d_nut, h_nut, l, l1 = bedBoltSettings or self.boxes.bedBoltSettings
+ p = 1 if positive else -1
+
+ if fingers <= 0:
+ fingers = 0
+ leftover = length
+
+ self.edge(leftover/2.0)
+ for i in range(fingers):
+ if i !=0:
+ if not positive and bedBolts and bedBolts.drawBolt(i):
+ self.hole(0.5*space,
+ 0.5*self.thickness, 0.5*d)
+ if positive and bedBolts and bedBolts.drawBolt(i):
+ self.bedBoltHole(s, bedBoltSettings)
+ else:
+ self.edge(s)
+ self.corner(-90*p)
+ self.edge(self.settings.height)
+ self.corner(90*p)
+ self.edge(f)
+ self.corner(90*p)
+ self.edge(self.settings.height)
+ self.corner(-90*p)
+ self.edge(leftover/2.0)
+
+ def margin(self):
+ return self.boxes.spacing + self.boxes.thickness
+
+class FingerJointEdgeCounterPart(FingerJointEdge):
+ char = 'F'
+ positive = False
+
+ def width(self):
+ return self.boxes.thickness
+
+ def margin(self):
+ return self.boxes.spacing
+
+class FingerHoleEdge(Edge):
+ char = 'h'
+
+ def __call__(self, length, dist=None,
+ bedBolts=None, bedBoltSettings=None, **kw):
+ if dist is None:
+ dist = self.fingerHoleEdgeWidth * self.thickness
+ self.ctx.save()
+ self.moveTo(0, dist+self.thickness/2)
+ self.fingerHoles(length, bedBolts, bedBoltSettings)
+ self.ctx.restore()
+ # XXX continue path
+ self.ctx.move_to(0, 0)
+ self.ctx.line_to(length, 0)
+ self.ctx.translate(*self.ctx.get_current_point())
+
+ def width(self):
+ return (self.fingerHoleEdgeWidth+1) * self.thickness
+
+class FingerHoles:
+ def __init__(self, boxes, settings):
+ self.boxes = boxes
+ self.ctx = boxes.ctx
+ self.settings = settings
+
+ def __call__(self, length, bedBolts=None, bedBoltSettings=None):
+ s, f = self.settings.space, self.settings.finger
+ fingers = int((length-(self.settings.surroundingspaces-1)*s) //
+ (s+f))
+ if bedBolts:
+ fingers = bedBolts.numFingers(fingers)
+ d, d_nut, h_nut, l, l1 = bedBoltSettings or self.boxes.bedBoltSettings
+ leftover = length - fingers*(s+f) - f
+ b = self.boxes.burn
+ if self.boxes.debug:
+ self.ctx.rectangle(0, -self.settings.width/2+b,
+ length, self.settings.width - 2*b)
+ for i in range(fingers):
+ pos = leftover/2.0+i*(s+f)
+ if bedBolts and bedBolts.drawBolt(i):
+ self.boxes.hole(pos+0.5*s, 0, d*0.5)
+ self.ctx.rectangle(pos+s+b, -self.settings.width/2+b,
+ f-2*b, self.settings.width - 2*b)
+
+ self.ctx.move_to(0, length)
+ self.ctx.translate(*self.ctx.get_current_point())
+
+class CrossingFingerHoleEdge(Edge):
+ def __init__(self, boxes, height, **kw):
+ Edge.__init__(self, boxes, None, **kw)
+ self.height = height
+
+ def __call__(self, length, **kw):
+ self.fingerHolesAt(length/2.0, 0, self.height)
+ Edge.__call__(self, length)
+
+
+class DoveTailSettings(Settings):
+ absolute_params = {
+ "angle" : 50,
+ }
+ relative_params = {
+ "size" : 3,
+ "depth" : 1.5,
+ "radius" : 0.2,
+ }
+
+class DoveTailJoint(Edge):
+ char = 'd'
+ positive = True
+
+ def __call__(self, length, **kw):
+ s = self.settings
+ radius = max(s.radius, self.boxes.burn) # no smaller than burn
+ positive = self.positive
+ a = s.angle + 90
+ alpha = 0.5*math.pi - math.pi*s.angle/180.0
+
+ l1 = radius/math.tan(alpha/2.0)
+ diffx = 0.5*s.depth/math.tan(alpha)
+ l2 = 0.5*s.depth / math.sin(alpha)
+
+ sections = int((length) // (s.size*2))
+ leftover = length - sections*s.size*2
+
+ p = 1 if positive else -1
+
+ self.edge((s.size+leftover)/2.0+diffx-l1)
+ for i in range(sections):
+ self.corner(-1*p*a, radius)
+ self.edge(2*(l2-l1))
+ self.corner(p*a, radius)
+ self.edge(2*(diffx-l1)+s.size)
+ self.corner(p*a, radius)
+ self.edge(2*(l2-l1))
+ self.corner(-1*p*a, radius)
+ if i