summaryrefslogtreecommitdiff
path: root/dxf_export/better_dxf_outlines.py
blob: 142dc8ffe523d00922c8f1fd28f43b92bb6ab754 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/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 )

e = MyEffect()
e.affect()