From 30487e03f4fedfc531252246796bb11c48e635da Mon Sep 17 00:00:00 2001 From: Michael Schwarz Date: Sat, 6 Dec 2014 13:36:55 +0100 Subject: Upgraded Python files copied from the Inkscape distribution to those from version 0.91.99.13724. --- support/dxf_export/bezmisc.py | 2 +- support/dxf_export/cubicsuperpath.py | 6 +- support/dxf_export/ffgeom.py | 2 +- support/dxf_export/inkex.py | 165 ++++++++++++++++++++++++++--------- support/dxf_export/simplepath.py | 2 +- support/dxf_export/simplestyle.py | 3 +- 6 files changed, 131 insertions(+), 49 deletions(-) (limited to 'support') diff --git a/support/dxf_export/bezmisc.py b/support/dxf_export/bezmisc.py index e663fa6..0c7ad49 100755 --- a/support/dxf_export/bezmisc.py +++ b/support/dxf_export/bezmisc.py @@ -271,4 +271,4 @@ if __name__ == '__main__': print beziertatlength(curve,0.5) -# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99 +# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 fileencoding=utf-8 textwidth=99 diff --git a/support/dxf_export/cubicsuperpath.py b/support/dxf_export/cubicsuperpath.py index af61acb..925efdb 100755 --- a/support/dxf_export/cubicsuperpath.py +++ b/support/dxf_export/cubicsuperpath.py @@ -46,8 +46,8 @@ def ArcToPath(p1,params): rx,ry,teta,longflag,sweepflag,x2,y2=params[:] teta = teta*pi/180.0 B=[x2,y2] - if rx==0 or ry==0: - return([[A,A,A],[B,B,B]]) + if rx==0 or ry==0 or A==B: + return([[A[:],A[:],A[:]],[B[:],B[:],B[:]]]) mat=matprod((rotmat(teta),[[1/rx,0],[0,1/ry]],rotmat(-teta))) applymat(mat, A) applymat(mat, B) @@ -166,4 +166,4 @@ def formatPath(p): return simplepath.formatPath(unCubicSuperPath(p)) -# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99 +# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 fileencoding=utf-8 textwidth=99 diff --git a/support/dxf_export/ffgeom.py b/support/dxf_export/ffgeom.py index 1983586..ef8799b 100755 --- a/support/dxf_export/ffgeom.py +++ b/support/dxf_export/ffgeom.py @@ -138,4 +138,4 @@ def dot(s1, s2): return s1.delta_x() * s2.delta_x() + s1.delta_y() * s2.delta_y() -# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99 +# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 fileencoding=utf-8 textwidth=99 diff --git a/support/dxf_export/inkex.py b/support/dxf_export/inkex.py index e487822..0f88000 100755 --- a/support/dxf_export/inkex.py +++ b/support/dxf_export/inkex.py @@ -1,9 +1,16 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- """ inkex.py A helper module for creating Inkscape extensions -Copyright (C) 2005,2007 Aaron Spike, aaron@ekips.org +Copyright (C) 2005,2010 Aaron Spike and contributors + +Contributors: + Aurélio A. Heckert + Bulia Byak + Nicolas Dufour, nicoduf@yahoo.fr + Peter J. R. Moulder 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 @@ -19,10 +26,14 @@ 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 sys, copy, optparse, random, re +import copy import gettext +import optparse +import os +import random +import re +import sys from math import * -_ = gettext.gettext #a dictionary of all of the xmlns prefixes in a standard inkscape doc NSS = { @@ -37,34 +48,35 @@ u'xlink' :u'http://www.w3.org/1999/xlink', u'xml' :u'http://www.w3.org/XML/1998/namespace' } -#a dictionary of unit to user unit conversion factors -uuconv = {'in':90.0, 'pt':1.25, 'px':1, 'mm':3.5433070866, 'cm':35.433070866, 'm':3543.3070866, - 'km':3543307.0866, 'pc':15.0, 'yd':3240 , 'ft':1080} -def unittouu(string): - '''Returns userunits given a string representation of units in another system''' - unit = re.compile('(%s)$' % '|'.join(uuconv.keys())) - param = re.compile(r'(([-+]?[0-9]+(\.[0-9]*)?|[-+]?\.[0-9]+)([eE][-+]?[0-9]+)?)') - - p = param.match(string) - u = unit.search(string) - if p: - retval = float(p.string[p.start():p.end()]) +def localize(): + domain = 'inkscape' + if sys.platform.startswith('win'): + import locale + current_locale, encoding = locale.getdefaultlocale() + os.environ['LANG'] = current_locale + try: + localdir = os.environ['INKSCAPE_LOCALEDIR']; + trans = gettext.translation(domain, localdir, [current_locale], fallback=True) + except KeyError: + trans = gettext.translation(domain, fallback=True) + elif sys.platform.startswith('darwin'): + try: + localdir = os.environ['INKSCAPE_LOCALEDIR']; + trans = gettext.translation(domain, localdir, fallback=True) + except KeyError: + try: + localdir = os.environ['PACKAGE_LOCALE_DIR']; + trans = gettext.translation(domain, localdir, fallback=True) + except KeyError: + trans = gettext.translation(domain, fallback=True) else: - retval = 0.0 - if u: try: - return retval * uuconv[u.string[u.start():u.end()]] + localdir = os.environ['PACKAGE_LOCALE_DIR']; + trans = gettext.translation(domain, localdir, fallback=True) except KeyError: - pass - return retval - -def uutounit(val, unit): - return val/uuconv[unit] - -try: - from lxml import etree -except: - sys.exit(_('The fantastic lxml wrapper for libxml2 is required by inkex.py and therefore this extension. Please download and install the latest version from http://cheeseshop.python.org/pypi/lxml/, or install it through your package manager by a command like: sudo apt-get install python-lxml')) + trans = gettext.translation(domain, fallback=True) + #sys.stderr.write(str(localdir) + "\n") + trans.install() def debug(what): sys.stderr.write(str(what) + "\n") @@ -79,13 +91,24 @@ def errormsg(msg): Note that this should always be combined with translation: - import gettext - _ = gettext.gettext + import inkex + inkex.localize() ... inkex.errormsg(_("This extension requires two selected paths.")) """ - sys.stderr.write((unicode(msg) + "\n").encode("UTF-8")) + if isinstance(msg, unicode): + sys.stderr.write(msg.encode("UTF-8") + "\n") + else: + sys.stderr.write((unicode(msg, "utf-8", errors='replace') + "\n").encode("UTF-8")) +# third party library +try: + from lxml import etree +except Exception, e: + localize() + errormsg(_("The fantastic lxml wrapper for libxml2 is required by inkex.py and therefore this extension. Please download and install the latest version from http://cheeseshop.python.org/pypi/lxml/, or install it through your package manager by a command like: sudo apt-get install python-lxml\n\nTechnical details:\n%s" % (e,))) + sys.exit() + def check_inkbool(option, opt, value): if str(value).capitalize() == 'True': return True @@ -128,20 +151,37 @@ class Effect: """Collect command line arguments""" self.options, self.args = self.OptionParser.parse_args(args) - def parse(self,file=None): + def parse(self, filename=None): """Parse document in specified file or on stdin""" - try: + + # First try to open the file from the function argument + if filename != None: try: - stream = open(file,'r') - except: - stream = open(self.svg_file,'r') - except: + stream = open(filename, 'r') + except Exception: + errormsg(_("Unable to open specified file: %s") % filename) + sys.exit() + + # If it wasn't specified, try to open the file specified as + # an object member + elif self.svg_file != None: + try: + stream = open(self.svg_file, 'r') + except Exception: + errormsg(_("Unable to open object member file: %s") % self.svg_file) + sys.exit() + + # Finally, if the filename was not specified anywhere, use + # standard input stream + else: stream = sys.stdin + p = etree.XMLParser(huge_tree=True) self.document = etree.parse(stream, parser=p) self.original_document = copy.deepcopy(self.document) stream.close() + # defines view_center in terms of document units def getposinlayer(self): #defaults self.current_layer = self.document.getroot() @@ -156,10 +196,10 @@ class Effect: xattr = self.document.xpath('//sodipodi:namedview/@inkscape:cx', namespaces=NSS) yattr = self.document.xpath('//sodipodi:namedview/@inkscape:cy', namespaces=NSS) - doc_height = unittouu(self.document.getroot().get('height')) if xattr and yattr: - x = xattr[0] - y = yattr[0] + x = self.unittouu( xattr[0] + 'px' ) + y = self.unittouu( yattr[0] + 'px') + doc_height = self.unittouu(self.document.getroot().get('height')) if x and y: self.view_center = (float(x), doc_height - float(y)) # FIXME: y-coordinate flip, eliminate it when it's gone in Inkscape @@ -236,6 +276,47 @@ class Effect: errormsg(_("No matching node for expression: %s") % path) retval = None return retval - -# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99 + def getDocumentUnit(self): + docunit = self.document.xpath('//sodipodi:namedview/@inkscape:document-units', namespaces=NSS) + if docunit: + return docunit[0] + else: + return 'px' + + #a dictionary of unit to user unit conversion factors + __uuconv = {'in':96.0, 'pt':1.33333333333, 'px':1.0, 'mm':3.77952755913, 'cm':37.7952755913, + 'm':3779.52755913, 'km':3779527.55913, 'pc':16.0, 'yd':3456.0 , 'ft':1152.0} + def unittouu(self, string): + '''Returns userunits given a string representation of units in another system''' + unit = re.compile('(%s)$' % '|'.join(self.__uuconv.keys())) + param = re.compile(r'(([-+]?[0-9]+(\.[0-9]*)?|[-+]?\.[0-9]+)([eE][-+]?[0-9]+)?)') + + p = param.match(string) + u = unit.search(string) + if p: + retval = float(p.string[p.start():p.end()]) + else: + retval = 0.0 + if u: + try: + return retval * (self.__uuconv[u.string[u.start():u.end()]] / self.__uuconv[self.getDocumentUnit()]) + except KeyError: + pass + else: # default assume 'px' unit + return retval / self.__uuconv[self.getDocumentUnit()] + + return retval + + def uutounit(self, val, unit): + return val / (self.__uuconv[unit] / self.__uuconv[self.getDocumentUnit()]) + + def addDocumentUnit(self, value): + ''' Add document unit when no unit is specified in the string ''' + try: + float(value) + return value + self.getDocumentUnit() + except ValueError: + return value + +# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 fileencoding=utf-8 textwidth=99 diff --git a/support/dxf_export/simplepath.py b/support/dxf_export/simplepath.py index f62b1b4..94ab092 100755 --- a/support/dxf_export/simplepath.py +++ b/support/dxf_export/simplepath.py @@ -209,4 +209,4 @@ def rotatePath(p, a, cx = 0, cy = 0): params[i + 1] = (r * math.sin(theta)) + cy -# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99 +# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 fileencoding=utf-8 textwidth=99 diff --git a/support/dxf_export/simplestyle.py b/support/dxf_export/simplestyle.py index 3ec971e..806b818 100755 --- a/support/dxf_export/simplestyle.py +++ b/support/dxf_export/simplestyle.py @@ -141,6 +141,7 @@ svgcolors={ 'plum':'#dda0dd', 'powderblue':'#b0e0e6', 'purple':'#800080', + 'rebeccapurple':'#663399', 'red':'#ff0000', 'rosybrown':'#bc8f8f', 'royalblue':'#4169e1', @@ -241,4 +242,4 @@ def formatColor3f(r,g,b): return '#%02x%02x%02x' % (int(round(r*255)),int(round(g*255)),int(round(b*255))) -# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99 +# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 fileencoding=utf-8 textwidth=99 -- cgit From eb74f4e6d9a9a006d30deb9ca4673f21e01e1a7f Mon Sep 17 00:00:00 2001 From: Michael Schwarz Date: Sat, 6 Dec 2014 13:53:16 +0100 Subject: Fixed DXF plugin to work with new inkex library. --- support/dxf_export/better_dxf_outlines.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'support') diff --git a/support/dxf_export/better_dxf_outlines.py b/support/dxf_export/better_dxf_outlines.py index 19ec6c8..2757fa9 100755 --- a/support/dxf_export/better_dxf_outlines.py +++ b/support/dxf_export/better_dxf_outlines.py @@ -95,7 +95,7 @@ class MyEffect(inkex.Effect): self.dxf_add( dxf_templates.r14_header ) scale = 25.4/90.0 - h = inkex.unittouu(self.document.getroot().xpath('@height',namespaces=inkex.NSS)[0]) + h = self.unittouu(self.document.getroot().xpath('@height',namespaces=inkex.NSS)[0]) path = '//svg:path' for node in self.document.getroot().xpath(path,namespaces=inkex.NSS): -- cgit From e309a206be4d5c0cd082ef557633d477b1638850 Mon Sep 17 00:00:00 2001 From: Michael Schwarz Date: Sat, 20 Dec 2014 23:19:33 +0100 Subject: Removed some unused imports in the scripts copied from the Inkscape distribution. --- support/dxf_export/__main__.py | 6 +- support/dxf_export/better_dxf_outlines.py | 123 ------ support/dxf_export/dxf_footer.txt | 62 +++ support/dxf_export/dxf_header.txt | 580 +++++++++++++++++++++++++++ support/dxf_export/dxf_templates.py | 645 ------------------------------ support/dxf_export/effect.py | 81 ++++ 6 files changed, 726 insertions(+), 771 deletions(-) delete mode 100755 support/dxf_export/better_dxf_outlines.py create mode 100644 support/dxf_export/dxf_footer.txt create mode 100644 support/dxf_export/dxf_header.txt delete mode 100755 support/dxf_export/dxf_templates.py create mode 100644 support/dxf_export/effect.py (limited to 'support') diff --git a/support/dxf_export/__main__.py b/support/dxf_export/__main__.py index 76c2121..676935e 100644 --- a/support/dxf_export/__main__.py +++ b/support/dxf_export/__main__.py @@ -1,14 +1,14 @@ import sys, os, xml.etree.ElementTree, shutil from lib import util -from . import better_dxf_outlines +from . import effect def _export_dxf(in_path, out_path): - dxf_export = better_dxf_outlines.MyEffect() + dxf_export = effect.DXFExportEffect() dxf_export.affect(args = [in_path], output = False) with open(out_path, 'w') as file: - file.write(dxf_export.dxf) + dxf_export.write(file) def _get_inkscape_layer_count(svg_path): diff --git a/support/dxf_export/better_dxf_outlines.py b/support/dxf_export/better_dxf_outlines.py deleted file mode 100755 index 2757fa9..0000000 --- a/support/dxf_export/better_dxf_outlines.py +++ /dev/null @@ -1,123 +0,0 @@ -#!/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 -- bug fix for xpath() calls added February 2009 by Bob Cook, bob@bobcookdev.com -- max value of 10 on path flattening, August 2011 by Bob Cook, bob@bobcookdev.com - -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, 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: - if f > 10: - break - try: - cspsubdiv.cspsubdiv(p, f) - 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 DXF Output" (bob@bobcookdev.com)' ) - self.dxf_add( dxf_templates.r14_header ) - - scale = 25.4/90.0 - h = self.unittouu(self.document.getroot().xpath('@height',namespaces=inkex.NSS)[0]) - - path = '//svg:path' - for node in self.document.getroot().xpath(path,namespaces=inkex.NSS): - - layer = node.getparent().get(inkex.addNS('label','inkscape')) - if layer == None: - layer = '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: - self.dxf_path_to_lines(layer,p) - else: - self.dxf_path_to_point(layer,p) - - self.dxf_add( dxf_templates.r14_footer ) diff --git a/support/dxf_export/dxf_footer.txt b/support/dxf_export/dxf_footer.txt new file mode 100644 index 0000000..a225dd7 --- /dev/null +++ b/support/dxf_export/dxf_footer.txt @@ -0,0 +1,62 @@ +0 +ENDSEC +0 +SECTION +2 +OBJECTS +0 +DICTIONARY +5 +C +330 +0 +100 +AcDbDictionary +3 +ACAD_GROUP +350 +D +3 +ACAD_MLINESTYLE +350 +17 +0 +DICTIONARY +5 +D +330 +C +100 +AcDbDictionary +0 +DICTIONARY +5 +1A +330 +C +100 +AcDbDictionary +0 +DICTIONARY +5 +17 +330 +C +100 +AcDbDictionary +3 +STANDARD +350 +18 +0 +DICTIONARY +5 +19 +330 +C +100 +AcDbDictionary +0 +ENDSEC +0 +EOF diff --git a/support/dxf_export/dxf_header.txt b/support/dxf_export/dxf_header.txt new file mode 100644 index 0000000..341cb1b --- /dev/null +++ b/support/dxf_export/dxf_header.txt @@ -0,0 +1,580 @@ +0 +SECTION +2 +HEADER +9 +$ACADVER +1 +AC1014 +9 +$HANDSEED +5 +FFFF +0 +ENDSEC +0 +SECTION +2 +TABLES +0 +TABLE +2 +VPORT +5 +8 +330 +0 +100 +AcDbSymbolTable +70 +4 +0 +VPORT +5 +2E +330 +8 +100 +AcDbSymbolTableRecord +100 +AcDbViewportTableRecord +2 +*ACTIVE +70 +0 +10 +0.0 +20 +0.0 +11 +1.0 +21 +1.0 +12 +4.25 +22 +5.5 +13 +0.0 +23 +0.0 +14 +10.0 +24 +10.0 +15 +10.0 +25 +10.0 +16 +0.0 +26 +0.0 +36 +1.0 +17 +0.0 +27 +0.0 +37 +0.0 +40 +11 +41 +1.24 +42 +50.0 +43 +0.0 +44 +0.0 +50 +0.0 +51 +0.0 +71 +0 +72 +100 +73 +1 +74 +3 +75 +0 +76 +0 +77 +0 +78 +0 +0 +ENDTAB +0 +TABLE +2 +LTYPE +5 +5 +330 +0 +100 +AcDbSymbolTable +70 +1 +0 +LTYPE +5 +14 +330 +5 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord +2 +BYBLOCK +70 +0 +3 + +72 +65 +73 +0 +40 +0.0 +0 +LTYPE +5 +15 +330 +5 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord +2 +BYLAYER +70 +0 +3 + +72 +65 +73 +0 +40 +0.0 +0 +LTYPE +5 +16 +330 +5 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord +2 +CONTINUOUS +70 +0 +3 +Solid line +72 +65 +73 +0 +40 +0.0 +0 +ENDTAB +0 +TABLE +2 +LAYER +5 +2 +330 +0 +100 +AcDbSymbolTable +70 +1 +0 +LAYER +5 +10 +330 +2 +100 +AcDbSymbolTableRecord +100 +AcDbLayerTableRecord +2 +0 +70 +0 +62 +7 +6 +CONTINUOUS +0 +ENDTAB +0 +TABLE +2 +STYLE +5 +3 +330 +0 +100 +AcDbSymbolTable +70 +1 +0 +STYLE +5 +11 +330 +3 +100 +AcDbSymbolTableRecord +100 +AcDbTextStyleTableRecord +2 +STANDARD +70 +0 +40 +0.0 +41 +1.0 +50 +0.0 +71 +0 +42 +2.5 +3 +txt +4 + +0 +ENDTAB +0 +TABLE +2 +VIEW +5 +6 +330 +0 +100 +AcDbSymbolTable +70 +0 +0 +ENDTAB +0 +TABLE +2 +UCS +5 +7 +330 +0 +100 +AcDbSymbolTable +70 +0 +0 +ENDTAB +0 +TABLE +2 +APPID +5 +9 +330 +0 +100 +AcDbSymbolTable +70 +2 +0 +APPID +5 +12 +330 +9 +100 +AcDbSymbolTableRecord +100 +AcDbRegAppTableRecord +2 +ACAD +70 +0 +0 +ENDTAB +0 +TABLE +2 +DIMSTYLE +5 +A +330 +0 +100 +AcDbSymbolTable +70 +1 +0 +DIMSTYLE +105 +27 +330 +A +100 +AcDbSymbolTableRecord +100 +AcDbDimStyleTableRecord +2 +ISO-25 +70 +0 +3 + +4 + +5 + +6 + +7 + +40 +1.0 +41 +2.5 +42 +0.625 +43 +3.75 +44 +1.25 +45 +0.0 +46 +0.0 +47 +0.0 +48 +0.0 +140 +2.5 +141 +2.5 +142 +0.0 +143 +0.03937007874016 +144 +1.0 +145 +0.0 +146 +1.0 +147 +0.625 +71 +0 +72 +0 +73 +0 +74 +0 +75 +0 +76 +0 +77 +1 +78 +8 +170 +0 +171 +3 +172 +1 +173 +0 +174 +0 +175 +0 +176 +0 +177 +0 +178 +0 +270 +2 +271 +2 +272 +2 +273 +2 +274 +3 +340 +11 +275 +0 +280 +0 +281 +0 +282 +0 +283 +0 +284 +8 +285 +0 +286 +0 +287 +3 +288 +0 +0 +ENDTAB +0 +TABLE +2 +BLOCK_RECORD +5 +1 +330 +0 +100 +AcDbSymbolTable +70 +1 +0 +BLOCK_RECORD +5 +1F +330 +1 +100 +AcDbSymbolTableRecord +100 +AcDbBlockTableRecord +2 +*MODEL_SPACE +0 +BLOCK_RECORD +5 +1B +330 +1 +100 +AcDbSymbolTableRecord +100 +AcDbBlockTableRecord +2 +*PAPER_SPACE +0 +ENDTAB +0 +ENDSEC +0 +SECTION +2 +BLOCKS +0 +BLOCK +5 +20 +330 +1F +100 +AcDbEntity +8 +0 +100 +AcDbBlockBegin +2 +*MODEL_SPACE +70 +0 +10 +0.0 +20 +0.0 +30 +0.0 +3 +*MODEL_SPACE +1 + +0 +ENDBLK +5 +21 +330 +1F +100 +AcDbEntity +8 +0 +100 +AcDbBlockEnd +0 +BLOCK +5 +1C +330 +1B +100 +AcDbEntity +67 +1 +8 +0 +100 +AcDbBlockBegin +2 +*PAPER_SPACE +1 + +0 +ENDBLK +5 +1D +330 +1B +100 +AcDbEntity +67 +1 +8 +0 +100 +AcDbBlockEnd +0 +ENDSEC +0 +SECTION +2 +ENTITIES diff --git a/support/dxf_export/dxf_templates.py b/support/dxf_export/dxf_templates.py deleted file mode 100755 index fb26632..0000000 --- a/support/dxf_export/dxf_templates.py +++ /dev/null @@ -1,645 +0,0 @@ -r14_header = ''' 0 -SECTION - 2 -HEADER - 9 -$ACADVER - 1 -AC1014 - 9 -$HANDSEED - 5 -FFFF - 0 -ENDSEC - 0 -SECTION - 2 -TABLES - 0 -TABLE - 2 -VPORT - 5 -8 -330 -0 -100 -AcDbSymbolTable - 70 - 4 - 0 -VPORT - 5 -2E -330 -8 -100 -AcDbSymbolTableRecord -100 -AcDbViewportTableRecord - 2 -*ACTIVE - 70 - 0 - 10 -0.0 - 20 -0.0 - 11 -1.0 - 21 -1.0 - 12 -4.25 - 22 -5.5 - 13 -0.0 - 23 -0.0 - 14 -10.0 - 24 -10.0 - 15 -10.0 - 25 -10.0 - 16 -0.0 - 26 -0.0 - 36 -1.0 - 17 -0.0 - 27 -0.0 - 37 -0.0 - 40 -11 - 41 -1.24 - 42 -50.0 - 43 -0.0 - 44 -0.0 - 50 -0.0 - 51 -0.0 - 71 - 0 - 72 - 100 - 73 - 1 - 74 - 3 - 75 - 0 - 76 - 0 - 77 - 0 - 78 - 0 - 0 -ENDTAB - 0 -TABLE - 2 -LTYPE - 5 -5 -330 -0 -100 -AcDbSymbolTable - 70 - 1 - 0 -LTYPE - 5 -14 -330 -5 -100 -AcDbSymbolTableRecord -100 -AcDbLinetypeTableRecord - 2 -BYBLOCK - 70 - 0 - 3 - - 72 - 65 - 73 - 0 - 40 -0.0 - 0 -LTYPE - 5 -15 -330 -5 -100 -AcDbSymbolTableRecord -100 -AcDbLinetypeTableRecord - 2 -BYLAYER - 70 - 0 - 3 - - 72 - 65 - 73 - 0 - 40 -0.0 - 0 -LTYPE - 5 -16 -330 -5 -100 -AcDbSymbolTableRecord -100 -AcDbLinetypeTableRecord - 2 -CONTINUOUS - 70 - 0 - 3 -Solid line - 72 - 65 - 73 - 0 - 40 -0.0 - 0 -ENDTAB - 0 -TABLE - 2 -LAYER - 5 -2 -330 -0 -100 -AcDbSymbolTable - 70 -1 - 0 -LAYER - 5 -10 -330 -2 -100 -AcDbSymbolTableRecord -100 -AcDbLayerTableRecord - 2 -0 - 70 - 0 - 62 - 7 - 6 -CONTINUOUS - 0 -ENDTAB - 0 -TABLE - 2 -STYLE - 5 -3 -330 -0 -100 -AcDbSymbolTable - 70 - 1 - 0 -STYLE - 5 -11 -330 -3 -100 -AcDbSymbolTableRecord -100 -AcDbTextStyleTableRecord - 2 -STANDARD - 70 - 0 - 40 -0.0 - 41 -1.0 - 50 -0.0 - 71 - 0 - 42 -2.5 - 3 -txt - 4 - - 0 -ENDTAB - 0 -TABLE - 2 -VIEW - 5 -6 -330 -0 -100 -AcDbSymbolTable - 70 - 0 - 0 -ENDTAB - 0 -TABLE - 2 -UCS - 5 -7 -330 -0 -100 -AcDbSymbolTable - 70 - 0 - 0 -ENDTAB - 0 -TABLE - 2 -APPID - 5 -9 -330 -0 -100 -AcDbSymbolTable - 70 - 2 - 0 -APPID - 5 -12 -330 -9 -100 -AcDbSymbolTableRecord -100 -AcDbRegAppTableRecord - 2 -ACAD - 70 - 0 - 0 -ENDTAB - 0 -TABLE - 2 -DIMSTYLE - 5 -A -330 -0 -100 -AcDbSymbolTable - 70 - 1 - 0 -DIMSTYLE -105 -27 -330 -A -100 -AcDbSymbolTableRecord -100 -AcDbDimStyleTableRecord - 2 -ISO-25 - 70 - 0 - 3 - - 4 - - 5 - - 6 - - 7 - - 40 -1.0 - 41 -2.5 - 42 -0.625 - 43 -3.75 - 44 -1.25 - 45 -0.0 - 46 -0.0 - 47 -0.0 - 48 -0.0 -140 -2.5 -141 -2.5 -142 -0.0 -143 -0.03937007874016 -144 -1.0 -145 -0.0 -146 -1.0 -147 -0.625 - 71 - 0 - 72 - 0 - 73 - 0 - 74 - 0 - 75 - 0 - 76 - 0 - 77 - 1 - 78 - 8 -170 - 0 -171 - 3 -172 - 1 -173 - 0 -174 - 0 -175 - 0 -176 - 0 -177 - 0 -178 - 0 -270 - 2 -271 - 2 -272 - 2 -273 - 2 -274 - 3 -340 -11 -275 - 0 -280 - 0 -281 - 0 -282 - 0 -283 - 0 -284 - 8 -285 - 0 -286 - 0 -287 - 3 -288 - 0 - 0 -ENDTAB - 0 -TABLE - 2 -BLOCK_RECORD - 5 -1 -330 -0 -100 -AcDbSymbolTable - 70 - 1 - 0 -BLOCK_RECORD - 5 -1F -330 -1 -100 -AcDbSymbolTableRecord -100 -AcDbBlockTableRecord - 2 -*MODEL_SPACE - 0 -BLOCK_RECORD - 5 -1B -330 -1 -100 -AcDbSymbolTableRecord -100 -AcDbBlockTableRecord - 2 -*PAPER_SPACE - 0 -ENDTAB - 0 -ENDSEC - 0 -SECTION - 2 -BLOCKS - 0 -BLOCK - 5 -20 -330 -1F -100 -AcDbEntity - 8 -0 -100 -AcDbBlockBegin - 2 -*MODEL_SPACE - 70 - 0 - 10 -0.0 - 20 -0.0 - 30 -0.0 - 3 -*MODEL_SPACE - 1 - - 0 -ENDBLK - 5 -21 -330 -1F -100 -AcDbEntity - 8 -0 -100 -AcDbBlockEnd - 0 -BLOCK - 5 -1C -330 -1B -100 -AcDbEntity - 67 - 1 - 8 -0 -100 -AcDbBlockBegin - 2 -*PAPER_SPACE - 1 - - 0 -ENDBLK - 5 -1D -330 -1B -100 -AcDbEntity - 67 - 1 - 8 -0 -100 -AcDbBlockEnd - 0 -ENDSEC - 0 -SECTION - 2 -ENTITIES -''' - - -r14_footer = ''' 0 -ENDSEC - 0 -SECTION - 2 -OBJECTS - 0 -DICTIONARY - 5 -C -330 -0 -100 -AcDbDictionary - 3 -ACAD_GROUP -350 -D - 3 -ACAD_MLINESTYLE -350 -17 - 0 -DICTIONARY - 5 -D -330 -C -100 -AcDbDictionary - 0 -DICTIONARY - 5 -1A -330 -C -100 -AcDbDictionary - 0 -DICTIONARY - 5 -17 -330 -C -100 -AcDbDictionary - 3 -STANDARD -350 -18 - 0 -DICTIONARY - 5 -19 -330 -C -100 -AcDbDictionary - 0 -ENDSEC - 0 -EOF''' diff --git a/support/dxf_export/effect.py b/support/dxf_export/effect.py new file mode 100644 index 0000000..09699b0 --- /dev/null +++ b/support/dxf_export/effect.py @@ -0,0 +1,81 @@ +""" +Based on code from Aaron Spike. See http://www.bobcookdev.com/inkscape/inkscape-dxf.html +""" + +import pkgutil +from . import inkex, simpletransform, cubicsuperpath, cspsubdiv + + +class DXFExportEffect(inkex.Effect): + def __init__(self): + inkex.Effect.__init__(self) + self._dxf_instructions = [] + self._handle = 255 + self._flatness = 0.1 + + def _add_instruction(self, code, value): + self._dxf_instructions.append((code, str(value))) + + def _add_dxf_line(self, layer, csp): + self._add_instruction(0, 'LINE') + self._add_instruction(8, layer) + self._add_instruction(62, 4) + self._add_instruction(5, '{:x}'.format(self._handle)) + self._add_instruction(100, 'AcDbEntity') + self._add_instruction(100, 'AcDbLine') + self._add_instruction(10, repr(csp[0][0])) + self._add_instruction(20, repr(csp[0][1])) + self._add_instruction(30, 0.0) + self._add_instruction(11, repr(csp[1][0])) + self._add_instruction(21, repr(csp[1][1])) + self._add_instruction(31, 0.0) + + def _add_dxf_path(self, layer, path): + cspsubdiv.cspsubdiv(path, self._flatness) + + for sub in path: + for i in range(len(sub) - 1): + self._handle += 1 + s = sub[i] + e = sub[i + 1] + self._add_dxf_line(layer, [s[1], e[1]]) + + def _add_dxf_shape(self, node, document_transformation): + layer = self._get_inkscape_layer(node) + path = cubicsuperpath.parsePath(node.get('d')) + + transformation = simpletransform.composeTransform( + document_transformation, + simpletransform.composeParents(node, [[1, 0, 0], [0, 1, 0]])) + + simpletransform.applyTransformToPath(transformation, path) + + self._add_dxf_path(layer, path) + + def effect(self): + height = self.unittouu(self.document.getroot().xpath('@height', namespaces = inkex.NSS)[0]) + document_transformation = [[1, 0, 0], [0, -1, height]] + + for node in self.document.getroot().xpath('//svg:path', namespaces = inkex.NSS): + self._add_dxf_shape(node, document_transformation) + + def write(self, file): + file.write(pkgutil.get_data(__name__, 'dxf_header.txt')) + + for code, value in self._dxf_instructions: + print >> file, code + print >> file, value + + file.write(pkgutil.get_data(__name__, 'dxf_footer.txt')) + + @classmethod + def _get_inkscape_layer(cls, node): + while node is not None: + layer = node.get(inkex.addNS('label', 'inkscape')) + + if layer is not None: + return layer + + node = node.getparent() + + return '' -- cgit From c74efa59dc37b06cc1aeddd0ba736552a5b9f35e Mon Sep 17 00:00:00 2001 From: Michael Schwarz Date: Sat, 20 Dec 2014 22:22:04 +0100 Subject: Rewritten unit conversion methods of inkex.py to properly handle viewport settings. --- support/dxf_export/__main__.py | 8 ++- support/dxf_export/effect.py | 112 +++++++++++++++++++++++++++++++++++++---- support/dxf_export/inkex.py | 62 ++++++++++++++++++++--- support/lib/util.py | 7 ++- support/openscad/__main__.py | 8 ++- 5 files changed, 178 insertions(+), 19 deletions(-) (limited to 'support') diff --git a/support/dxf_export/__main__.py b/support/dxf_export/__main__.py index 676935e..c770a0e 100644 --- a/support/dxf_export/__main__.py +++ b/support/dxf_export/__main__.py @@ -76,4 +76,10 @@ def main(in_path, out_path): _export_dxf(temp_svg_path, out_path) -main(*sys.argv[1:]) +try: + main(*sys.argv[1:]) +except util.UserError as e: + print 'Error:', e + sys.exit(1) +except KeyboardInterrupt: + sys.exit(2) diff --git a/support/dxf_export/effect.py b/support/dxf_export/effect.py index 09699b0..206ce9d 100644 --- a/support/dxf_export/effect.py +++ b/support/dxf_export/effect.py @@ -2,17 +2,70 @@ Based on code from Aaron Spike. See http://www.bobcookdev.com/inkscape/inkscape-dxf.html """ -import pkgutil +import pkgutil, re from . import inkex, simpletransform, cubicsuperpath, cspsubdiv +def _get_unit_factors_map(): + # Fluctuates somewhat between Inkscape releases. + pixels_per_inch = 96. + pixels_per_mm = pixels_per_inch / 25.4 + + return { + 'px': 1.0, + 'mm': pixels_per_mm, + 'cm': pixels_per_mm * 10, + 'm' : pixels_per_mm * 1e3, + 'km': pixels_per_mm * 1e6, + 'pt': pixels_per_inch / 72, + 'pc': pixels_per_inch / 6, + 'in': pixels_per_inch, + 'ft': pixels_per_inch * 12, + 'yd': pixels_per_inch * 36 } + + class DXFExportEffect(inkex.Effect): + _unit_factors = _get_unit_factors_map() + def __init__(self): inkex.Effect.__init__(self) + self._dxf_instructions = [] self._handle = 255 self._flatness = 0.1 + def _get_user_unit(self): + """ + Return the size in pixels of the unit used for measures without an explicit unit. + """ + + document_height = self._measure_to_pixels(self._get_document_height_attr()) + view_box_attr = self.document.getroot().get('viewBox') + + if view_box_attr: + _, _, _, view_box_height = map(float, view_box_attr.split()) + else: + view_box_height = document_height + + return document_height / view_box_height + + def _get_document_unit(self): + """ + Return the size in pixels that the user is working with in Inkscape. + """ + + inkscape_unit_attrs = self.document.getroot().xpath('./sodipodi:namedview/@inkscape:document-units', namespaces = inkex.NSS) + + if inkscape_unit_attrs: + unit = inkscape_unit_attrs[0] + else: + _, unit = self._parse_measure(self._get_document_height_attr()) + + return self._get_unit_factor(unit) + + def _get_document_height_attr(self): + return self.document.getroot().xpath('@height', namespaces = inkex.NSS)[0] + def _add_instruction(self, code, value): self._dxf_instructions.append((code, str(value))) @@ -40,24 +93,31 @@ class DXFExportEffect(inkex.Effect): e = sub[i + 1] self._add_dxf_line(layer, [s[1], e[1]]) - def _add_dxf_shape(self, node, document_transformation): + def _add_dxf_shape(self, node, document_transform, element_transform): layer = self._get_inkscape_layer(node) path = cubicsuperpath.parsePath(node.get('d')) - transformation = simpletransform.composeTransform( - document_transformation, - simpletransform.composeParents(node, [[1, 0, 0], [0, 1, 0]])) + transform = simpletransform.composeTransform( + document_transform, + simpletransform.composeParents(node, element_transform)) - simpletransform.applyTransformToPath(transformation, path) + simpletransform.applyTransformToPath(transform, path) self._add_dxf_path(layer, path) def effect(self): - height = self.unittouu(self.document.getroot().xpath('@height', namespaces = inkex.NSS)[0]) - document_transformation = [[1, 0, 0], [0, -1, height]] + user_unit = self._get_user_unit() + document_unit = self._get_document_unit() + height = self._measure_to_pixels(self._get_document_height_attr()) + + document_transform = simpletransform.composeTransform( + [[1 / document_unit, 0, 0], [0, 1 / document_unit, 0]], + [[1, 0, 0], [0, -1, height]]) + + element_transform = [[user_unit, 0, 0], [0, user_unit, 0]] for node in self.document.getroot().xpath('//svg:path', namespaces = inkex.NSS): - self._add_dxf_shape(node, document_transformation) + self._add_dxf_shape(node, document_transform, element_transform) def write(self, file): file.write(pkgutil.get_data(__name__, 'dxf_header.txt')) @@ -68,6 +128,30 @@ class DXFExportEffect(inkex.Effect): file.write(pkgutil.get_data(__name__, 'dxf_footer.txt')) + @classmethod + def _parse_measure(cls, string): + value_match = re.match(r'(([-+]?[0-9]+(\.[0-9]*)?|[-+]?\.[0-9]+)([eE][-+]?[0-9]+)?)', string) + unit_match = re.search('(%s)$' % '|'.join(cls._unit_factors.keys()), string) + + value = float(string[value_match.start():value_match.end()]) + + if unit_match: + unit = string[unit_match.start():unit_match.end()] + else: + unit = None + + return value, unit + + @classmethod + def _measure_to_pixels(cls, string, default_unit_factor = None): + """ + Parse a string containing a measure and return it's value converted to pixels. If the measure has no unit, it will be assumed that the unit has the size of the specified number of pixels. + """ + + value, unit = cls._parse_measure(string) + + return value * cls._get_unit_factor(unit, default_unit_factor) + @classmethod def _get_inkscape_layer(cls, node): while node is not None: @@ -79,3 +163,13 @@ class DXFExportEffect(inkex.Effect): node = node.getparent() return '' + + @classmethod + def _get_unit_factor(cls, unit, default = None): + if unit is None: + if default is None: + default = 1 + + return default + else: + return cls._unit_factors[unit] diff --git a/support/dxf_export/inkex.py b/support/dxf_export/inkex.py index 0f88000..19e860b 100755 --- a/support/dxf_export/inkex.py +++ b/support/dxf_export/inkex.py @@ -101,6 +101,13 @@ def errormsg(msg): else: sys.stderr.write((unicode(msg, "utf-8", errors='replace') + "\n").encode("UTF-8")) +def are_near_relative(a, b, eps): + if (a-b <= a*eps) and (a-b >= -a*eps): + return True + else: + return False + + # third party library try: from lxml import etree @@ -277,16 +284,57 @@ class Effect: retval = None return retval - def getDocumentUnit(self): - docunit = self.document.xpath('//sodipodi:namedview/@inkscape:document-units', namespaces=NSS) - if docunit: - return docunit[0] - else: - return 'px' - #a dictionary of unit to user unit conversion factors __uuconv = {'in':96.0, 'pt':1.33333333333, 'px':1.0, 'mm':3.77952755913, 'cm':37.7952755913, 'm':3779.52755913, 'km':3779527.55913, 'pc':16.0, 'yd':3456.0 , 'ft':1152.0} + + # Function returns the unit used for the values in SVG. + # For lack of an attribute in SVG that explicitly defines what units are used for SVG coordinates, + # try to calculate the unit from the SVG width and SVG viewbox. + # Defaults to 'px' units. + def getDocumentUnit(self): + svgunit = 'px' #default to pixels + + svgwidth = self.document.getroot().get('width') + viewboxstr = self.document.getroot().get('viewBox') + if viewboxstr: + unitmatch = re.compile('(%s)$' % '|'.join(self.__uuconv.keys())) + param = re.compile(r'(([-+]?[0-9]+(\.[0-9]*)?|[-+]?\.[0-9]+)([eE][-+]?[0-9]+)?)') + + p = param.match(svgwidth) + u = unitmatch.search(svgwidth) + + width = 100 #default + viewboxwidth = 100 #default + svgwidthunit = 'px' #default assume 'px' unit + if p: + width = float(p.string[p.start():p.end()]) + else: + errormsg(_("SVG Width not set correctly! Assuming width = 100")) + if u: + svgwidthunit = u.string[u.start():u.end()] + + viewboxnumbers = [] + for t in viewboxstr.split(): + try: + viewboxnumbers.append(float(t)) + except ValueError: + pass + if len(viewboxnumbers) == 4: #check for correct number of numbers + viewboxwidth = viewboxnumbers[2] + + svgunitfactor = self.__uuconv[svgwidthunit] * width / viewboxwidth + + # try to find the svgunitfactor in the list of units known. If we don't find something, ... + eps = 0.01 #allow 1% error in factor + for key in self.__uuconv: + if are_near_relative(self.__uuconv[key], svgunitfactor, eps): + #found match! + svgunit = key; + + return svgunit + + def unittouu(self, string): '''Returns userunits given a string representation of units in another system''' unit = re.compile('(%s)$' % '|'.join(self.__uuconv.keys())) diff --git a/support/lib/util.py b/support/lib/util.py index bede240..8b65e58 100644 --- a/support/lib/util.py +++ b/support/lib/util.py @@ -1,6 +1,10 @@ import contextlib, subprocess, tempfile, shutil, re, os +class UserError(Exception): + pass + + @contextlib.contextmanager def TemporaryDirectory(): dir = tempfile.mkdtemp() @@ -15,7 +19,8 @@ def command(args): process = subprocess.Popen(args) process.wait() - assert not process.returncode + if process.returncode: + raise UserError('Command failed: {}'.format(' '.join(args))) def bash_escape_string(string): diff --git a/support/openscad/__main__.py b/support/openscad/__main__.py index 08b2ab6..0f319f8 100644 --- a/support/openscad/__main__.py +++ b/support/openscad/__main__.py @@ -34,4 +34,10 @@ def main(in_path, out_path, deps_path): _write_dependencies(deps_path, relpath(out_path), deps - ignored_files) -main(*sys.argv[1:]) +try: + main(*sys.argv[1:]) +except util.UserError as e: + print 'Error:', e + sys.exit(1) +except KeyboardInterrupt: + sys.exit(2) -- cgit From dde79ab4b28a7e414114a1ebd991a9fcb378e076 Mon Sep 17 00:00:00 2001 From: Michael Schwarz Date: Sat, 20 Dec 2014 23:19:33 +0100 Subject: Removed some unused imports in the scripts copied from the Inkscape distribution. --- support/dxf_export/bezmisc.py | 1 - support/dxf_export/simplestyle.py | 245 ---------------------------------- support/dxf_export/simpletransform.py | 4 +- 3 files changed, 2 insertions(+), 248 deletions(-) delete mode 100755 support/dxf_export/simplestyle.py (limited to 'support') diff --git a/support/dxf_export/bezmisc.py b/support/dxf_export/bezmisc.py index 0c7ad49..b7f5429 100755 --- a/support/dxf_export/bezmisc.py +++ b/support/dxf_export/bezmisc.py @@ -243,7 +243,6 @@ def beziertatlength(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)), l = 0.5, toleranc bezierlength = bezierlengthSimpson if __name__ == '__main__': - import timing #print linebezierintersect(((,),(,)),((,),(,),(,),(,))) #print linebezierintersect(((0,1),(0,-1)),((-1,0),(-.5,0),(.5,0),(1,0))) tol = 0.00000001 diff --git a/support/dxf_export/simplestyle.py b/support/dxf_export/simplestyle.py deleted file mode 100755 index 806b818..0000000 --- a/support/dxf_export/simplestyle.py +++ /dev/null @@ -1,245 +0,0 @@ -#!/usr/bin/env python -""" -simplestyle.py -Two simple functions for working with inline css -and some color handling on top. - -Copyright (C) 2005 Aaron Spike, aaron@ekips.org - -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 -""" - -svgcolors={ - 'aliceblue':'#f0f8ff', - 'antiquewhite':'#faebd7', - 'aqua':'#00ffff', - 'aquamarine':'#7fffd4', - 'azure':'#f0ffff', - 'beige':'#f5f5dc', - 'bisque':'#ffe4c4', - 'black':'#000000', - 'blanchedalmond':'#ffebcd', - 'blue':'#0000ff', - 'blueviolet':'#8a2be2', - 'brown':'#a52a2a', - 'burlywood':'#deb887', - 'cadetblue':'#5f9ea0', - 'chartreuse':'#7fff00', - 'chocolate':'#d2691e', - 'coral':'#ff7f50', - 'cornflowerblue':'#6495ed', - 'cornsilk':'#fff8dc', - 'crimson':'#dc143c', - 'cyan':'#00ffff', - 'darkblue':'#00008b', - 'darkcyan':'#008b8b', - 'darkgoldenrod':'#b8860b', - 'darkgray':'#a9a9a9', - 'darkgreen':'#006400', - 'darkgrey':'#a9a9a9', - 'darkkhaki':'#bdb76b', - 'darkmagenta':'#8b008b', - 'darkolivegreen':'#556b2f', - 'darkorange':'#ff8c00', - 'darkorchid':'#9932cc', - 'darkred':'#8b0000', - 'darksalmon':'#e9967a', - 'darkseagreen':'#8fbc8f', - 'darkslateblue':'#483d8b', - 'darkslategray':'#2f4f4f', - 'darkslategrey':'#2f4f4f', - 'darkturquoise':'#00ced1', - 'darkviolet':'#9400d3', - 'deeppink':'#ff1493', - 'deepskyblue':'#00bfff', - 'dimgray':'#696969', - 'dimgrey':'#696969', - 'dodgerblue':'#1e90ff', - 'firebrick':'#b22222', - 'floralwhite':'#fffaf0', - 'forestgreen':'#228b22', - 'fuchsia':'#ff00ff', - 'gainsboro':'#dcdcdc', - 'ghostwhite':'#f8f8ff', - 'gold':'#ffd700', - 'goldenrod':'#daa520', - 'gray':'#808080', - 'grey':'#808080', - 'green':'#008000', - 'greenyellow':'#adff2f', - 'honeydew':'#f0fff0', - 'hotpink':'#ff69b4', - 'indianred':'#cd5c5c', - 'indigo':'#4b0082', - 'ivory':'#fffff0', - 'khaki':'#f0e68c', - 'lavender':'#e6e6fa', - 'lavenderblush':'#fff0f5', - 'lawngreen':'#7cfc00', - 'lemonchiffon':'#fffacd', - 'lightblue':'#add8e6', - 'lightcoral':'#f08080', - 'lightcyan':'#e0ffff', - 'lightgoldenrodyellow':'#fafad2', - 'lightgray':'#d3d3d3', - 'lightgreen':'#90ee90', - 'lightgrey':'#d3d3d3', - 'lightpink':'#ffb6c1', - 'lightsalmon':'#ffa07a', - 'lightseagreen':'#20b2aa', - 'lightskyblue':'#87cefa', - 'lightslategray':'#778899', - 'lightslategrey':'#778899', - 'lightsteelblue':'#b0c4de', - 'lightyellow':'#ffffe0', - 'lime':'#00ff00', - 'limegreen':'#32cd32', - 'linen':'#faf0e6', - 'magenta':'#ff00ff', - 'maroon':'#800000', - 'mediumaquamarine':'#66cdaa', - 'mediumblue':'#0000cd', - 'mediumorchid':'#ba55d3', - 'mediumpurple':'#9370db', - 'mediumseagreen':'#3cb371', - 'mediumslateblue':'#7b68ee', - 'mediumspringgreen':'#00fa9a', - 'mediumturquoise':'#48d1cc', - 'mediumvioletred':'#c71585', - 'midnightblue':'#191970', - 'mintcream':'#f5fffa', - 'mistyrose':'#ffe4e1', - 'moccasin':'#ffe4b5', - 'navajowhite':'#ffdead', - 'navy':'#000080', - 'oldlace':'#fdf5e6', - 'olive':'#808000', - 'olivedrab':'#6b8e23', - 'orange':'#ffa500', - 'orangered':'#ff4500', - 'orchid':'#da70d6', - 'palegoldenrod':'#eee8aa', - 'palegreen':'#98fb98', - 'paleturquoise':'#afeeee', - 'palevioletred':'#db7093', - 'papayawhip':'#ffefd5', - 'peachpuff':'#ffdab9', - 'peru':'#cd853f', - 'pink':'#ffc0cb', - 'plum':'#dda0dd', - 'powderblue':'#b0e0e6', - 'purple':'#800080', - 'rebeccapurple':'#663399', - 'red':'#ff0000', - 'rosybrown':'#bc8f8f', - 'royalblue':'#4169e1', - 'saddlebrown':'#8b4513', - 'salmon':'#fa8072', - 'sandybrown':'#f4a460', - 'seagreen':'#2e8b57', - 'seashell':'#fff5ee', - 'sienna':'#a0522d', - 'silver':'#c0c0c0', - 'skyblue':'#87ceeb', - 'slateblue':'#6a5acd', - 'slategray':'#708090', - 'slategrey':'#708090', - 'snow':'#fffafa', - 'springgreen':'#00ff7f', - 'steelblue':'#4682b4', - 'tan':'#d2b48c', - 'teal':'#008080', - 'thistle':'#d8bfd8', - 'tomato':'#ff6347', - 'turquoise':'#40e0d0', - 'violet':'#ee82ee', - 'wheat':'#f5deb3', - 'white':'#ffffff', - 'whitesmoke':'#f5f5f5', - 'yellow':'#ffff00', - 'yellowgreen':'#9acd32' -} - -def parseStyle(s): - """Create a dictionary from the value of an inline style attribute""" - if s is None: - return {} - else: - return dict([[x.strip() for x in i.split(":")] for i in s.split(";") if len(i.strip())]) - -def formatStyle(a): - """Format an inline style attribute from a dictionary""" - return ";".join([att+":"+str(val) for att,val in a.iteritems()]) - -def isColor(c): - """Determine if its a color we can use. If not, leave it unchanged.""" - if c.startswith('#') and (len(c)==4 or len(c)==7): - return True - if c.lower() in svgcolors.keys(): - return True - #might be "none" or some undefined color constant or rgb() - #however, rgb() shouldnt occur at this point - return False - -def parseColor(c): - """Creates a rgb int array""" - tmp = svgcolors.get(c.lower()) - if tmp is not None: - c = tmp - elif c.startswith('#') and len(c)==4: - c='#'+c[1:2]+c[1:2]+c[2:3]+c[2:3]+c[3:]+c[3:] - elif c.startswith('rgb('): - # remove the rgb(...) stuff - tmp = c.strip()[4:-1] - numbers = [number.strip() for number in tmp.split(',')] - converted_numbers = [] - if len(numbers) == 3: - for num in numbers: - if num.endswith(r'%'): - converted_numbers.append(int(float(num[0:-1])*255/100)) - else: - converted_numbers.append(int(num)) - return tuple(converted_numbers) - else: - return (0,0,0) - try: - r=int(c[1:3],16) - g=int(c[3:5],16) - b=int(c[5:],16) - except: - # unknown color ... - # Return a default color. Maybe not the best thing to do but probably - # better than raising an exception. - return(0,0,0) - return (r,g,b) - -def formatColoria(a): - """int array to #rrggbb""" - return '#%02x%02x%02x' % (a[0],a[1],a[2]) - -def formatColorfa(a): - """float array to #rrggbb""" - return '#%02x%02x%02x' % (int(round(a[0]*255)),int(round(a[1]*255)),int(round(a[2]*255))) - -def formatColor3i(r,g,b): - """3 ints to #rrggbb""" - return '#%02x%02x%02x' % (r,g,b) - -def formatColor3f(r,g,b): - """3 floats to #rrggbb""" - return '#%02x%02x%02x' % (int(round(r*255)),int(round(g*255)),int(round(b*255))) - - -# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 fileencoding=utf-8 textwidth=99 diff --git a/support/dxf_export/simpletransform.py b/support/dxf_export/simpletransform.py index 47cc61e..55082ed 100755 --- a/support/dxf_export/simpletransform.py +++ b/support/dxf_export/simpletransform.py @@ -21,8 +21,8 @@ barraud@math.univ-lille1.fr This code defines several functions to make handling of transform attribute easier. ''' -import inkex, cubicsuperpath, bezmisc, simplestyle -import copy, math, re +import inkex, cubicsuperpath +import math, re def parseTransform(transf,mat=[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]): if transf=="" or transf==None: -- cgit From 72eca42f2d3c7fe1066c2681c6d52db4e890832b Mon Sep 17 00:00:00 2001 From: Michael Schwarz Date: Sun, 21 Dec 2014 19:10:49 +0100 Subject: Workaround for OpenSCAD sometimes writing an empty STL file when it crashes. --- support/openscad/__main__.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'support') diff --git a/support/openscad/__main__.py b/support/openscad/__main__.py index 0f319f8..3c103e5 100644 --- a/support/openscad/__main__.py +++ b/support/openscad/__main__.py @@ -21,17 +21,26 @@ def main(in_path, out_path, deps_path): temp_mk_path = os.path.join(temp_dir, 'mk') temp_files_path = os.path.join(temp_dir, 'files') - _openscad(in_path, out_path, temp_deps_path) + # OpenSCAD requires the output file name to end in .stl + temp_stl_path = os.path.join(temp_dir, 'out.stl') + + _openscad(in_path, temp_stl_path, temp_deps_path) mk_content = '%:; echo "$@" >> {}'.format(util.bash_escape_string(temp_files_path)) + # Use make to parse the dependency makefile written by OpenSCAD util.write_file(temp_mk_path, mk_content.encode()) util.command(['make', '-s', '-B', '-f', temp_mk_path, '-f', temp_deps_path]) + # All dependencies as paths relative to the project root. deps = set(map(relpath, util.read_file(temp_files_path).decode().splitlines())) - ignored_files = set(map(relpath, [temp_deps_path, temp_mk_path, in_path, out_path])) + # Relative paths to all files that should not appear in the dependency makefile. + ignored_files = set(map(relpath, [in_path, temp_deps_path, temp_mk_path, temp_stl_path])) + + # Write output files. _write_dependencies(deps_path, relpath(out_path), deps - ignored_files) + os.rename(temp_stl_path, out_path) try: -- cgit