diff options
author | Michael Schwarz <michi.schwarz@gmail.com> | 2014-12-25 15:16:42 +0100 |
---|---|---|
committer | Michael Schwarz <michi.schwarz@gmail.com> | 2014-12-25 15:16:42 +0100 |
commit | d08e4be25f157d59075e0b2a669e6388cb462474 (patch) | |
tree | 29b1363948f6dc83fff4c68052b6924f81d215d8 /support | |
parent | 2433482b8768533244480bf15ba759eee3f51969 (diff) | |
parent | bdf3ae0ae3d66235bbff5710ffe1b34e9d7f12d2 (diff) | |
download | pogojig-d08e4be25f157d59075e0b2a669e6388cb462474.tar.gz pogojig-d08e4be25f157d59075e0b2a669e6388cb462474.tar.bz2 pogojig-d08e4be25f157d59075e0b2a669e6388cb462474.zip |
Merge branch 'master' into no-examples
Conflicts:
.gitignore
Diffstat (limited to 'support')
-rw-r--r-- | support/dxf_export/__main__.py | 14 | ||||
-rwxr-xr-x | support/dxf_export/better_dxf_outlines.py | 123 | ||||
-rwxr-xr-x | support/dxf_export/bezmisc.py | 3 | ||||
-rwxr-xr-x | support/dxf_export/cubicsuperpath.py | 6 | ||||
-rw-r--r-- | support/dxf_export/dxf_footer.txt | 62 | ||||
-rw-r--r-- | support/dxf_export/dxf_header.txt | 580 | ||||
-rwxr-xr-x | support/dxf_export/dxf_templates.py | 645 | ||||
-rw-r--r-- | support/dxf_export/effect.py | 175 | ||||
-rwxr-xr-x | support/dxf_export/ffgeom.py | 2 | ||||
-rwxr-xr-x | support/dxf_export/inkex.py | 211 | ||||
-rwxr-xr-x | support/dxf_export/simplepath.py | 2 | ||||
-rwxr-xr-x | support/dxf_export/simplestyle.py | 244 | ||||
-rwxr-xr-x | support/dxf_export/simpletransform.py | 4 | ||||
-rw-r--r-- | support/lib/util.py | 7 | ||||
-rw-r--r-- | support/openscad/__main__.py | 21 |
15 files changed, 1029 insertions, 1070 deletions
diff --git a/support/dxf_export/__main__.py b/support/dxf_export/__main__.py index 76c2121..c770a0e 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): @@ -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/better_dxf_outlines.py b/support/dxf_export/better_dxf_outlines.py deleted file mode 100755 index 19ec6c8..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 = inkex.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/bezmisc.py b/support/dxf_export/bezmisc.py index e663fa6..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 @@ -271,4 +270,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/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..206ce9d --- /dev/null +++ b/support/dxf_export/effect.py @@ -0,0 +1,175 @@ +""" +Based on code from Aaron Spike. See http://www.bobcookdev.com/inkscape/inkscape-dxf.html +""" + +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))) + + 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_transform, element_transform): + layer = self._get_inkscape_layer(node) + path = cubicsuperpath.parsePath(node.get('d')) + + transform = simpletransform.composeTransform( + document_transform, + simpletransform.composeParents(node, element_transform)) + + simpletransform.applyTransformToPath(transform, path) + + self._add_dxf_path(layer, path) + + def effect(self): + 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_transform, element_transform) + + 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 _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: + layer = node.get(inkex.addNS('label', 'inkscape')) + + if layer is not None: + return layer + + 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/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..19e860b 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 <aaron@ekips.org> and contributors + +Contributors: + Aurélio A. Heckert <aurium(a)gmail.com> + Bulia Byak <buliabyak@users.sf.net> + Nicolas Dufour, nicoduf@yahoo.fr + Peter J. R. Moulder <pjrm@users.sourceforge.net> 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,31 @@ 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")) + +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 +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 +158,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 +203,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 +283,88 @@ class Effect: errormsg(_("No matching node for expression: %s") % path) retval = None return retval + + #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())) + 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 encoding=utf-8 textwidth=99 +# 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 deleted file mode 100755 index 3ec971e..0000000 --- a/support/dxf_export/simplestyle.py +++ /dev/null @@ -1,244 +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', - '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 encoding=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: 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..3c103e5 100644 --- a/support/openscad/__main__.py +++ b/support/openscad/__main__.py @@ -21,17 +21,32 @@ 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) -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) |