Skip to content

Instantly share code, notes, and snippets.

@adammhaile
Created May 12, 2015 12:32
Show Gist options
  • Save adammhaile/552166a01e4af218d9b2 to your computer and use it in GitHub Desktop.
Save adammhaile/552166a01e4af218d9b2 to your computer and use it in GitHub Desktop.
#! /usr/bin/env python
'''
Generates Inkscape SVG file containing box components needed to
laser cut a tabbed construction box taking kerf and clearance into account
Copyright (C) 2011 elliot white elliot@twot.eu
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/>.
'''
__version__ = "0.8" ### please report bugs, suggestions etc to bugs@twot.eu ###
from ink_helper import *
from math import pi, sin, cos
_ = gettext.gettext
def x_slit(center, orient, angle):
'''
make one x_slit starting
orient -- vector from center edge of baffle, slit only goes half of orient length
angle (radians) is angle of the slit (just try it and see?)
'''
orient = Vec2(orient)
w = orient.norm()
out = orient / w
up = Vec2([out[1], -out[0]])
center = Vec2(center)
path = Path([center + out * w/2. + up * sin(angle) * w/2])
path.append(center - out * w/2. - up * sin(angle) * w/2)
path.append(center - out * w/2. + up * sin(angle) * w/2)
path.append(center + out * w/2. - up * sin(angle) * w/2)
path.append(center + out * w/2. + up * sin(angle) * w/2)
return path
def u_slit(center, orient, angle):
'''
make one a single of u_slits
'''
orient = Vec2(orient)
w = orient.norm()
out = orient / w
up = Vec2([out[1], -out[0]])
center = Vec2(center)
path1 = Path([center + out * w + up * sin(angle) * w])
path1.append(center + out * w / 2. + up * sin(angle) * w/2)
path1.append(center + out * w / 2. - up * sin(angle) * w/2)
path1.append(center + out * w - up * sin(angle) * w)
return path1
def baffle(start, width, dy, angle, n):
'''
Make N slits at a dy spaceing starting at start.
angle is the slit angle
'''
orient = Vec2(width, 0)
start = Vec2(start)
up = Vec2(0, 1.)
x_slits = []
u_slits = []
center = start + orient + up * dy/2
for i in range(n):
x_slits.append(x_slit(center + i * dy * up, orient, angle))
x_fold = []
u_fold = []
dash = Path([start + orient])
ddy = dy / 10.
dash.append_from_last(up * ddy)
n_dash = int(n * dy / ddy)
for s in range(0, n_dash, 3):
x_fold.append(dash.translate(up * s * ddy))
u_fold.append(dash.translate(up * s * ddy + orient * 2.1))
x_outline = Path()
x_outline.append(start)
x_outline.append_from_last(2 * orient)
x_outline.append_from_last((n + 0) * up * dy)
x_outline.append_from_last(-2 * orient)
x_outline.append_from_last(-(n + 0) * up * dy)
u_outline = Path()
u_outline.append(start + orient * 2.1)
u_outline.append_from_last(2 * orient)
for i in range(n):
u_outline.extend(u_slit(center + i * dy * up + orient * 2.1, orient, angle))
u_outline.append(start + 4.1 * orient + n * up * dy)
u_outline.append_from_last(-2 * orient)
for i in range(n - 1, -1, -1):
u_outline.extend(u_slit(center + i * dy * up + orient * 2.1, -orient, angle))
u_outline.append(start + orient * 2.1)
## make a list of parts.
out = [x_slits, x_fold, [x_outline], u_fold, [u_outline]]
out = [''.join([p.drawXY() for p in path]) for path in out]
return out
class TSlotBoxMaker(inkex.Effect):
def __init__(self):
# Call the base class constructor.
inkex.Effect.__init__(self)
# Define options
self.OptionParser.add_option('--unit',action='store',type='string',
dest='unit',default='mm',help='Measure Units')
self.OptionParser.add_option('--height',action='store',type='float',
dest='height',default=100,help='Height of baffle')
self.OptionParser.add_option('--angle',action='store',type='float',
dest='angle',default=100,help='Angle of baffle')
self.OptionParser.add_option('--dy',action='store',type='float',
dest='dy',default=100,help='distance between baffles')
self.OptionParser.add_option('--N',action='store',type='float',
dest='N',default=100,help='number of slits')
def effect(self):
# Get access to main SVG document element and get its dimensions.
svg = self.document.getroot()
# Get the attibutes:
widthDoc = self.unittouu(svg.get('width'))
heightDoc = self.unittouu(svg.get('height'))
# Create a new layer.
layer = inkex.etree.SubElement(svg, 'g')
layer.set(inkex.addNS('label', 'inkscape'), 'newlayer')
layer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')
parent=self.current_layer
# Get script's option values.
unit=self.options.unit
H = self.unittouu( str(self.options.height) + unit )
angle = float(self.options.angle) * pi / 180
N = int(self.options.N)
dy = self.unittouu(str(self.options.dy) + unit )
width = H / cos(angle)
[drawS(obj, parent) for obj in baffle([0, 0], width, dy, angle, N)]
# Create effect instance and apply it.
effect = TSlotBoxMaker()
effect.affect()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment