Skip to content

Instantly share code, notes, and snippets.

@drayde
Created June 15, 2015 09:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save drayde/ee9151b0ad985ca348cd to your computer and use it in GitHub Desktop.
Save drayde/ee9151b0ad985ca348cd to your computer and use it in GitHub Desktop.
b2_dxf_outlines.py from "Better better DXF output" fixed to run with Inkscape 0.91
#!/usr/bin/env python
'''
Copyright (C) 2005,2007 Aaron Spike, aaron@ekips.org
- template dxf_outlines.dxf added Feb 2008 by Alvin Penner, penner@vaxxine.com
- layers, transformation, flattening added April 2008 by Bob Cook, bob@bobcookdev.com
- improved layering support added Feb 2009 by T. R. Gipson, drmn4ea at google mail
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 2 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
'''
import inkex, simplepath, simpletransform, cubicsuperpath, cspsubdiv, dxf_templates_b2, re
class MyEffect(inkex.Effect):
def __init__(self):
inkex.Effect.__init__(self)
self.dxf = ''
self.handle = 255
self.flatness = 0.1
def output(self):
print self.dxf
def dxf_add(self, str):
self.dxf += str
def dxf_insert_code(self, code, value):
self.dxf += code + "\n" + value + "\n"
def dxf_line(self,layer,csp):
self.dxf_insert_code( '0', 'LINE' )
self.dxf_insert_code( '8', layer )
self.dxf_insert_code( '62', '4' )
self.dxf_insert_code( '5', '%x' % self.handle )
self.dxf_insert_code( '100', 'AcDbEntity' )
self.dxf_insert_code( '100', 'AcDbLine' )
self.dxf_insert_code( '10', '%f' % csp[0][0] )
self.dxf_insert_code( '20', '%f' % csp[0][1] )
self.dxf_insert_code( '30', '0.0' )
self.dxf_insert_code( '11', '%f' % csp[1][0] )
self.dxf_insert_code( '21', '%f' % csp[1][1] )
self.dxf_insert_code( '31', '0.0' )
def dxf_point(self,layer,x,y):
self.dxf_insert_code( '0', 'POINT' )
self.dxf_insert_code( '8', layer )
self.dxf_insert_code( '62', '4' )
self.dxf_insert_code( '5', '%x' % self.handle )
self.dxf_insert_code( '100', 'AcDbEntity' )
self.dxf_insert_code( '100', 'AcDbPoint' )
self.dxf_insert_code( '10', '%f' % x )
self.dxf_insert_code( '20', '%f' % y )
self.dxf_insert_code( '30', '0.0' )
def dxf_path_to_lines(self,layer,p):
f = self.flatness
is_flat = 0
while is_flat < 1:
try:
cspsubdiv.cspsubdiv(p, self.flatness)
is_flat = 1
except:
f += 0.1
for sub in p:
for i in range(len(sub)-1):
self.handle += 1
s = sub[i]
e = sub[i+1]
self.dxf_line(layer,[s[1],e[1]])
def dxf_path_to_point(self,layer,p):
bbox = simpletransform.roughBBox(p)
x = (bbox[0] + bbox[1]) / 2
y = (bbox[2] + bbox[3]) / 2
self.dxf_point(layer,x,y)
def effect(self):
self.dxf_insert_code( '999', 'Inkscape export via "Better Better DXF Output" (http://tim.cexx.org/?p=590)' )
self.dxf_add( dxf_templates_b2.r14_header )
scale = 25.4/90.0
h = self.unittouu(self.document.getroot().xpath('@height',namespaces=inkex.NSS)[0])
path = '//svg:path'
# run thru entire document gathering a list of layers to generate a proper DXF LAYER table. There is probably a better way to do this.
layers=[];
for node in self.document.getroot().xpath(path, namespaces=inkex.NSS):
layer = node.getparent().get(inkex.addNS('label','inkscape'))
if layer == None:
layer = 'Default'
if not layer in layers:
layers.append(layer)
self.dxf_insert_code('0', 'TABLE')
self.dxf_insert_code('2', 'LAYER')
self.dxf_insert_code('5', '2')
self.dxf_insert_code('330', '0')
self.dxf_insert_code('100', 'AcDbSymbolTable')
# group code 70 tells a reader how many table records to expect (e.g. pre-allocate memory for).
# It must be greater or equal to the actual number of records
self.dxf_insert_code('70',str(len(layers)))
for layer in layers:
self.dxf_insert_code('0', 'LAYER')
self.dxf_insert_code('5', '10')
self.dxf_insert_code('330', '2')
self.dxf_insert_code('100', 'AcDbSymbolTableRecord')
self.dxf_insert_code('100', 'AcDbLayerTableRecord')
self.dxf_insert_code('2', layer)
self.dxf_insert_code('70', '0')
self.dxf_insert_code('62', '7')
self.dxf_insert_code('6', 'CONTINUOUS')
self.dxf_insert_code('0','ENDTAB')
self.dxf_insert_code('0','ENDSEC')
self.dxf_add( dxf_templates_b2.r14_blocks )
# Generate actual geometry...
for node in self.document.getroot().xpath(path,namespaces=inkex.NSS):
layer = node.getparent().get(inkex.addNS('label','inkscape'))
if layer == None:
layer = 'Default' # Layer 1
d = node.get('d')
p = cubicsuperpath.parsePath(d)
t = node.get('transform')
if t != None:
m = simpletransform.parseTransform(t)
simpletransform.applyTransformToPath(m,p)
m = [[scale,0,0],[0,-scale,h*scale]]
simpletransform.applyTransformToPath(m,p)
if re.search('drill$',layer,re.I) == None:
#if layer == 'Brackets Drill':
self.dxf_path_to_lines(layer,p)
else:
self.dxf_path_to_point(layer,p)
self.dxf_add( dxf_templates_b2.r14_footer )
e = MyEffect()
e.affect()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment