summaryrefslogtreecommitdiff
path: root/dxf_export
diff options
context:
space:
mode:
authorMichael Schwarz <michi.schwarz@gmail.com>2014-12-10 22:13:34 +0100
committerMichael Schwarz <michi.schwarz@gmail.com>2014-12-10 22:13:34 +0100
commit8e5a1520cd5e901f514c382ad17e77d64727896a (patch)
tree184de9647c4776669f54fabf72e6f1f4bf2253a3 /dxf_export
parent785aec3aa6e2deda9acfefa8a9114ea3e7d39f44 (diff)
downloadpogojig-8e5a1520cd5e901f514c382ad17e77d64727896a.tar.gz
pogojig-8e5a1520cd5e901f514c382ad17e77d64727896a.tar.bz2
pogojig-8e5a1520cd5e901f514c382ad17e77d64727896a.zip
Moved DXF export scripts to separate directory.
Diffstat (limited to 'dxf_export')
-rw-r--r--dxf_export/__main__.py95
-rwxr-xr-xdxf_export/better_dxf_outlines.py123
-rwxr-xr-xdxf_export/bezmisc.py274
-rwxr-xr-xdxf_export/cspsubdiv.py37
-rwxr-xr-xdxf_export/cubicsuperpath.py169
-rwxr-xr-xdxf_export/dxf_templates.py645
-rwxr-xr-xdxf_export/ffgeom.py141
-rwxr-xr-xdxf_export/inkex.py241
-rwxr-xr-xdxf_export/simplepath.py212
-rwxr-xr-xdxf_export/simplestyle.py244
-rwxr-xr-xdxf_export/simpletransform.py241
11 files changed, 0 insertions, 2422 deletions
diff --git a/dxf_export/__main__.py b/dxf_export/__main__.py
deleted file mode 100644
index ea6c7ad..0000000
--- a/dxf_export/__main__.py
+++ /dev/null
@@ -1,95 +0,0 @@
-import sys, os, xml.etree.ElementTree, subprocess, tempfile, contextlib, shutil
-import better_dxf_outlines
-
-
-@contextlib.contextmanager
-def TemporaryDirectory():
- dir = tempfile.mkdtemp()
-
- try:
- yield dir
- finally:
- shutil.rmtree(dir)
-
-
-def _export_dxf(in_path, out_path):
- dxf_export = better_dxf_outlines.MyEffect()
- dxf_export.affect(args = [in_path], output = False)
-
- with open(out_path, 'w') as file:
- file.write(dxf_export.dxf)
-
-
-def _get_inkscape_layer_count(svg_path):
- document = xml.etree.ElementTree.parse(svg_path)
- layers = document.findall(
- '{http://www.w3.org/2000/svg}g[@{http://www.inkscape.org/namespaces/inkscape}groupmode="layer"]')
-
- return len(layers)
-
-
-def _command(args):
- process = subprocess.Popen(args)
- process.wait()
-
- assert not process.returncode
-
-
-def _inkscape(svg_path, verbs):
- def iter_args():
- yield os.environ['INKSCAPE']
-
- for i in verbs:
- yield '--verb'
- yield i
-
- yield svg_path
-
- _command(list(iter_args()))
-
-
-def _unfuck_svg_document(temp_svg_path):
- """
- Unfucks an SVG document so is can be processed by the better_dxf_export plugin.
- """
-
- layers_count = _get_inkscape_layer_count(temp_svg_path)
-
- def iter_inkscape_verbs():
- yield 'LayerUnlockAll'
- yield 'LayerShowAll'
-
- # Go to the first layer
- for _ in range(layers_count):
- yield 'LayerPrev'
-
- for _ in range(layers_count):
- yield 'EditSelectAll'
- yield 'ObjectToPath'
- yield 'EditSelectAll'
- yield 'SelectionUnGroup'
- yield 'EditSelectAll'
- yield 'StrokeToPath'
- yield 'EditSelectAll'
- yield 'SelectionUnion'
- yield 'LayerNext'
-
- yield 'FileSave'
- yield 'FileClose'
- yield 'FileQuit'
-
- _inkscape(temp_svg_path, list(iter_inkscape_verbs()))
-
-
-def main(in_path, out_path):
- with TemporaryDirectory() as temp_dir:
- temp_svg_path = os.path.join(temp_dir, 'temp.svg')
-
- shutil.copyfile(in_path, temp_svg_path)
-
- _unfuck_svg_document(temp_svg_path)
-
- _export_dxf(temp_svg_path, out_path)
-
-
-main(*sys.argv[1:])
diff --git a/dxf_export/better_dxf_outlines.py b/dxf_export/better_dxf_outlines.py
deleted file mode 100755
index 19ec6c8..0000000
--- a/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/dxf_export/bezmisc.py b/dxf_export/bezmisc.py
deleted file mode 100755
index e663fa6..0000000
--- a/dxf_export/bezmisc.py
+++ /dev/null
@@ -1,274 +0,0 @@
-#!/usr/bin/env python
-'''
-Copyright (C) 2010 Nick Drobchenko, nick@cnc-club.ru
-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
-'''
-
-import math, cmath
-
-def rootWrapper(a,b,c,d):
- if a:
- # Monics formula see http://en.wikipedia.org/wiki/Cubic_function#Monic_formula_of_roots
- a,b,c = (b/a, c/a, d/a)
- m = 2.0*a**3 - 9.0*a*b + 27.0*c
- k = a**2 - 3.0*b
- n = m**2 - 4.0*k**3
- w1 = -.5 + .5*cmath.sqrt(-3.0)
- w2 = -.5 - .5*cmath.sqrt(-3.0)
- if n < 0:
- m1 = pow(complex((m+cmath.sqrt(n))/2),1./3)
- n1 = pow(complex((m-cmath.sqrt(n))/2),1./3)
- else:
- if m+math.sqrt(n) < 0:
- m1 = -pow(-(m+math.sqrt(n))/2,1./3)
- else:
- m1 = pow((m+math.sqrt(n))/2,1./3)
- if m-math.sqrt(n) < 0:
- n1 = -pow(-(m-math.sqrt(n))/2,1./3)
- else:
- n1 = pow((m-math.sqrt(n))/2,1./3)
- x1 = -1./3 * (a + m1 + n1)
- x2 = -1./3 * (a + w1*m1 + w2*n1)
- x3 = -1./3 * (a + w2*m1 + w1*n1)
- return (x1,x2,x3)
- elif b:
- det=c**2.0-4.0*b*d
- if det:
- return (-c+cmath.sqrt(det))/(2.0*b),(-c-cmath.sqrt(det))/(2.0*b)
- else:
- return -c/(2.0*b),
- elif c:
- return 1.0*(-d/c),
- return ()
-
-def bezierparameterize(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3))):
- #parametric bezier
- x0=bx0
- y0=by0
- cx=3*(bx1-x0)
- bx=3*(bx2-bx1)-cx
- ax=bx3-x0-cx-bx
- cy=3*(by1-y0)
- by=3*(by2-by1)-cy
- ay=by3-y0-cy-by
-
- return ax,ay,bx,by,cx,cy,x0,y0
- #ax,ay,bx,by,cx,cy,x0,y0=bezierparameterize(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)))
-
-def linebezierintersect(((lx1,ly1),(lx2,ly2)),((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3))):
- #parametric line
- dd=lx1
- cc=lx2-lx1
- bb=ly1
- aa=ly2-ly1
-
- if aa:
- coef1=cc/aa
- coef2=1
- else:
- coef1=1
- coef2=aa/cc
-
- ax,ay,bx,by,cx,cy,x0,y0=bezierparameterize(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)))
- #cubic intersection coefficients
- a=coef1*ay-coef2*ax
- b=coef1*by-coef2*bx
- c=coef1*cy-coef2*cx
- d=coef1*(y0-bb)-coef2*(x0-dd)
-
- roots = rootWrapper(a,b,c,d)
- retval = []
- for i in roots:
- if type(i) is complex and i.imag==0:
- i = i.real
- if type(i) is not complex and 0<=i<=1:
- retval.append(bezierpointatt(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)),i))
- return retval
-
-def bezierpointatt(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)),t):
- ax,ay,bx,by,cx,cy,x0,y0=bezierparameterize(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)))
- x=ax*(t**3)+bx*(t**2)+cx*t+x0
- y=ay*(t**3)+by*(t**2)+cy*t+y0
- return x,y
-
-def bezierslopeatt(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)),t):
- ax,ay,bx,by,cx,cy,x0,y0=bezierparameterize(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)))
- dx=3*ax*(t**2)+2*bx*t+cx
- dy=3*ay*(t**2)+2*by*t+cy
- return dx,dy
-
-def beziertatslope(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)),(dy,dx)):
- ax,ay,bx,by,cx,cy,x0,y0=bezierparameterize(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)))
- #quadratic coefficents of slope formula
- if dx:
- slope = 1.0*(dy/dx)
- a=3*ay-3*ax*slope
- b=2*by-2*bx*slope
- c=cy-cx*slope
- elif dy:
- slope = 1.0*(dx/dy)
- a=3*ax-3*ay*slope
- b=2*bx-2*by*slope
- c=cx-cy*slope
- else:
- return []
-
- roots = rootWrapper(0,a,b,c)
- retval = []
- for i in roots:
- if type(i) is complex and i.imag==0:
- i = i.real
- if type(i) is not complex and 0<=i<=1:
- retval.append(i)
- return retval
-
-def tpoint((x1,y1),(x2,y2),t):
- return x1+t*(x2-x1),y1+t*(y2-y1)
-def beziersplitatt(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)),t):
- m1=tpoint((bx0,by0),(bx1,by1),t)
- m2=tpoint((bx1,by1),(bx2,by2),t)
- m3=tpoint((bx2,by2),(bx3,by3),t)
- m4=tpoint(m1,m2,t)
- m5=tpoint(m2,m3,t)
- m=tpoint(m4,m5,t)
-
- return ((bx0,by0),m1,m4,m),(m,m5,m3,(bx3,by3))
-
-'''
-Approximating the arc length of a bezier curve
-according to <http://www.cit.gu.edu.au/~anthony/info/graphics/bezier.curves>
-
-if:
- L1 = |P0 P1| +|P1 P2| +|P2 P3|
- L0 = |P0 P3|
-then:
- L = 1/2*L0 + 1/2*L1
- ERR = L1-L0
-ERR approaches 0 as the number of subdivisions (m) increases
- 2^-4m
-
-Reference:
-Jens Gravesen <gravesen@mat.dth.dk>
-"Adaptive subdivision and the length of Bezier curves"
-mat-report no. 1992-10, Mathematical Institute, The Technical
-University of Denmark.
-'''
-def pointdistance((x1,y1),(x2,y2)):
- return math.sqrt(((x2 - x1) ** 2) + ((y2 - y1) ** 2))
-def Gravesen_addifclose(b, len, error = 0.001):
- box = 0
- for i in range(1,4):
- box += pointdistance(b[i-1], b[i])
- chord = pointdistance(b[0], b[3])
- if (box - chord) > error:
- first, second = beziersplitatt(b, 0.5)
- Gravesen_addifclose(first, len, error)
- Gravesen_addifclose(second, len, error)
- else:
- len[0] += (box / 2.0) + (chord / 2.0)
-def bezierlengthGravesen(b, error = 0.001):
- len = [0]
- Gravesen_addifclose(b, len, error)
- return len[0]
-
-# balf = Bezier Arc Length Function
-balfax,balfbx,balfcx,balfay,balfby,balfcy = 0,0,0,0,0,0
-def balf(t):
- retval = (balfax*(t**2) + balfbx*t + balfcx)**2 + (balfay*(t**2) + balfby*t + balfcy)**2
- return math.sqrt(retval)
-
-def Simpson(f, a, b, n_limit, tolerance):
- n = 2
- multiplier = (b - a)/6.0
- endsum = f(a) + f(b)
- interval = (b - a)/2.0
- asum = 0.0
- bsum = f(a + interval)
- est1 = multiplier * (endsum + (2.0 * asum) + (4.0 * bsum))
- est0 = 2.0 * est1
- #print multiplier, endsum, interval, asum, bsum, est1, est0
- while n < n_limit and abs(est1 - est0) > tolerance:
- n *= 2
- multiplier /= 2.0
- interval /= 2.0
- asum += bsum
- bsum = 0.0
- est0 = est1
- for i in xrange(1, n, 2):
- bsum += f(a + (i * interval))
- est1 = multiplier * (endsum + (2.0 * asum) + (4.0 * bsum))
- #print multiplier, endsum, interval, asum, bsum, est1, est0
- return est1
-
-def bezierlengthSimpson(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)), tolerance = 0.001):
- global balfax,balfbx,balfcx,balfay,balfby,balfcy
- ax,ay,bx,by,cx,cy,x0,y0=bezierparameterize(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)))
- balfax,balfbx,balfcx,balfay,balfby,balfcy = 3*ax,2*bx,cx,3*ay,2*by,cy
- return Simpson(balf, 0.0, 1.0, 4096, tolerance)
-
-def beziertatlength(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)), l = 0.5, tolerance = 0.001):
- global balfax,balfbx,balfcx,balfay,balfby,balfcy
- ax,ay,bx,by,cx,cy,x0,y0=bezierparameterize(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)))
- balfax,balfbx,balfcx,balfay,balfby,balfcy = 3*ax,2*bx,cx,3*ay,2*by,cy
- t = 1.0
- tdiv = t
- curlen = Simpson(balf, 0.0, t, 4096, tolerance)
- targetlen = l * curlen
- diff = curlen - targetlen
- while abs(diff) > tolerance:
- tdiv /= 2.0
- if diff < 0:
- t += tdiv
- else:
- t -= tdiv
- curlen = Simpson(balf, 0.0, t, 4096, tolerance)
- diff = curlen - targetlen
- return t
-
-#default bezier length method
-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
- curves = [((0,0),(1,5),(4,5),(5,5)),
- ((0,0),(0,0),(5,0),(10,0)),
- ((0,0),(0,0),(5,1),(10,0)),
- ((-10,0),(0,0),(10,0),(10,10)),
- ((15,10),(0,0),(10,0),(-5,10))]
- '''
- for curve in curves:
- timing.start()
- g = bezierlengthGravesen(curve,tol)
- timing.finish()
- gt = timing.micro()
-
- timing.start()
- s = bezierlengthSimpson(curve,tol)
- timing.finish()
- st = timing.micro()
-
- print g, gt
- print s, st
- '''
- for curve in curves:
- print beziertatlength(curve,0.5)
-
-
-# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99
diff --git a/dxf_export/cspsubdiv.py b/dxf_export/cspsubdiv.py
deleted file mode 100755
index c34236a..0000000
--- a/dxf_export/cspsubdiv.py
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env python
-from bezmisc import *
-from ffgeom import *
-
-def maxdist(((p0x,p0y),(p1x,p1y),(p2x,p2y),(p3x,p3y))):
- p0 = Point(p0x,p0y)
- p1 = Point(p1x,p1y)
- p2 = Point(p2x,p2y)
- p3 = Point(p3x,p3y)
-
- s1 = Segment(p0,p3)
- return max(s1.distanceToPoint(p1),s1.distanceToPoint(p2))
-
-
-def cspsubdiv(csp,flat):
- for sp in csp:
- subdiv(sp,flat)
-
-def subdiv(sp,flat,i=1):
- while i < len(sp):
- p0 = sp[i-1][1]
- p1 = sp[i-1][2]
- p2 = sp[i][0]
- p3 = sp[i][1]
-
- b = (p0,p1,p2,p3)
- m = maxdist(b)
- if m <= flat:
- i += 1
- else:
- one, two = beziersplitatt(b,0.5)
- sp[i-1][2] = one[1]
- sp[i][0] = two[2]
- p = [one[2],one[3],two[1]]
- sp[i:1] = [p]
-
-# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 fileencoding=utf-8 textwidth=99
diff --git a/dxf_export/cubicsuperpath.py b/dxf_export/cubicsuperpath.py
deleted file mode 100755
index af61acb..0000000
--- a/dxf_export/cubicsuperpath.py
+++ /dev/null
@@ -1,169 +0,0 @@
-#!/usr/bin/env python
-"""
-cubicsuperpath.py
-
-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
-
-"""
-import simplepath
-from math import *
-
-def matprod(mlist):
- prod=mlist[0]
- for m in mlist[1:]:
- a00=prod[0][0]*m[0][0]+prod[0][1]*m[1][0]
- a01=prod[0][0]*m[0][1]+prod[0][1]*m[1][1]
- a10=prod[1][0]*m[0][0]+prod[1][1]*m[1][0]
- a11=prod[1][0]*m[0][1]+prod[1][1]*m[1][1]
- prod=[[a00,a01],[a10,a11]]
- return prod
-def rotmat(teta):
- return [[cos(teta),-sin(teta)],[sin(teta),cos(teta)]]
-def applymat(mat, pt):
- x=mat[0][0]*pt[0]+mat[0][1]*pt[1]
- y=mat[1][0]*pt[0]+mat[1][1]*pt[1]
- pt[0]=x
- pt[1]=y
-def norm(pt):
- return sqrt(pt[0]*pt[0]+pt[1]*pt[1])
-
-def ArcToPath(p1,params):
- A=p1[:]
- 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]])
- mat=matprod((rotmat(teta),[[1/rx,0],[0,1/ry]],rotmat(-teta)))
- applymat(mat, A)
- applymat(mat, B)
- k=[-(B[1]-A[1]),B[0]-A[0]]
- d=k[0]*k[0]+k[1]*k[1]
- k[0]/=sqrt(d)
- k[1]/=sqrt(d)
- d=sqrt(max(0,1-d/4))
- if longflag==sweepflag:
- d*=-1
- O=[(B[0]+A[0])/2+d*k[0],(B[1]+A[1])/2+d*k[1]]
- OA=[A[0]-O[0],A[1]-O[1]]
- OB=[B[0]-O[0],B[1]-O[1]]
- start=acos(OA[0]/norm(OA))
- if OA[1]<0:
- start*=-1
- end=acos(OB[0]/norm(OB))
- if OB[1]<0:
- end*=-1
-
- if sweepflag and start>end:
- end +=2*pi
- if (not sweepflag) and start<end:
- end -=2*pi
-
- NbSectors=int(abs(start-end)*2/pi)+1
- dTeta=(end-start)/NbSectors
- #v=dTeta*2/pi*0.552
- #v=dTeta*2/pi*4*(sqrt(2)-1)/3
- v = 4*tan(dTeta/4)/3
- #if not sweepflag:
- # v*=-1
- p=[]
- for i in range(0,NbSectors+1,1):
- angle=start+i*dTeta
- v1=[O[0]+cos(angle)-(-v)*sin(angle),O[1]+sin(angle)+(-v)*cos(angle)]
- pt=[O[0]+cos(angle) ,O[1]+sin(angle) ]
- v2=[O[0]+cos(angle)- v *sin(angle),O[1]+sin(angle)+ v *cos(angle)]
- p.append([v1,pt,v2])
- p[ 0][0]=p[ 0][1][:]
- p[-1][2]=p[-1][1][:]
-
- mat=matprod((rotmat(teta),[[rx,0],[0,ry]],rotmat(-teta)))
- for pts in p:
- applymat(mat, pts[0])
- applymat(mat, pts[1])
- applymat(mat, pts[2])
- return(p)
-
-def CubicSuperPath(simplepath):
- csp = []
- subpath = -1
- subpathstart = []
- last = []
- lastctrl = []
- for s in simplepath:
- cmd, params = s
- if cmd == 'M':
- if last:
- csp[subpath].append([lastctrl[:],last[:],last[:]])
- subpath += 1
- csp.append([])
- subpathstart = params[:]
- last = params[:]
- lastctrl = params[:]
- elif cmd == 'L':
- csp[subpath].append([lastctrl[:],last[:],last[:]])
- last = params[:]
- lastctrl = params[:]
- elif cmd == 'C':
- csp[subpath].append([lastctrl[:],last[:],params[:2]])
- last = params[-2:]
- lastctrl = params[2:4]
- elif cmd == 'Q':
- q0=last[:]
- q1=params[0:2]
- q2=params[2:4]
- x0= q0[0]
- x1=1./3*q0[0]+2./3*q1[0]
- x2= 2./3*q1[0]+1./3*q2[0]
- x3= q2[0]
- y0= q0[1]
- y1=1./3*q0[1]+2./3*q1[1]
- y2= 2./3*q1[1]+1./3*q2[1]
- y3= q2[1]
- csp[subpath].append([lastctrl[:],[x0,y0],[x1,y1]])
- last = [x3,y3]
- lastctrl = [x2,y2]
- elif cmd == 'A':
- arcp=ArcToPath(last[:],params[:])
- arcp[ 0][0]=lastctrl[:]
- last=arcp[-1][1]
- lastctrl = arcp[-1][0]
- csp[subpath]+=arcp[:-1]
- elif cmd == 'Z':
- csp[subpath].append([lastctrl[:],last[:],last[:]])
- last = subpathstart[:]
- lastctrl = subpathstart[:]
- #append final superpoint
- csp[subpath].append([lastctrl[:],last[:],last[:]])
- return csp
-
-def unCubicSuperPath(csp):
- a = []
- for subpath in csp:
- if subpath:
- a.append(['M',subpath[0][1][:]])
- for i in range(1,len(subpath)):
- a.append(['C',subpath[i-1][2][:] + subpath[i][0][:] + subpath[i][1][:]])
- return a
-
-def parsePath(d):
- return CubicSuperPath(simplepath.parsePath(d))
-
-def formatPath(p):
- return simplepath.formatPath(unCubicSuperPath(p))
-
-
-# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99
diff --git a/dxf_export/dxf_templates.py b/dxf_export/dxf_templates.py
deleted file mode 100755
index fb26632..0000000
--- a/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/dxf_export/ffgeom.py b/dxf_export/ffgeom.py
deleted file mode 100755
index 1983586..0000000
--- a/dxf_export/ffgeom.py
+++ /dev/null
@@ -1,141 +0,0 @@
-#!/usr/bin/env python
-"""
- ffgeom.py
- Copyright (C) 2005 Aaron Cyril Spike, aaron@ekips.org
-
- This file is part of FretFind 2-D.
-
- FretFind 2-D 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.
-
- FretFind 2-D 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 FretFind 2-D; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-"""
-import math
-try:
- NaN = float('NaN')
-except ValueError:
- PosInf = 1e300000
- NaN = PosInf/PosInf
-
-class Point:
- precision = 5
- def __init__(self, x, y):
- self.__coordinates = {'x' : float(x), 'y' : float(y)}
- def __getitem__(self, key):
- return self.__coordinates[key]
- def __setitem__(self, key, value):
- self.__coordinates[key] = float(value)
- def __repr__(self):
- return '(%s, %s)' % (round(self['x'],self.precision),round(self['y'],self.precision))
- def copy(self):
- return Point(self['x'],self['y'])
- def translate(self, x, y):
- self['x'] += x
- self['y'] += y
- def move(self, x, y):
- self['x'] = float(x)
- self['y'] = float(y)
-
-class Segment:
- def __init__(self, e0, e1):
- self.__endpoints = [e0, e1]
- def __getitem__(self, key):
- return self.__endpoints[key]
- def __setitem__(self, key, value):
- self.__endpoints[key] = value
- def __repr__(self):
- return repr(self.__endpoints)
- def copy(self):
- return Segment(self[0],self[1])
- def translate(self, x, y):
- self[0].translate(x,y)
- self[1].translate(x,y)
- def move(self,e0,e1):
- self[0] = e0
- self[1] = e1
- def delta_x(self):
- return self[1]['x'] - self[0]['x']
- def delta_y(self):
- return self[1]['y'] - self[0]['y']
- #alias functions
- run = delta_x
- rise = delta_y
- def slope(self):
- if self.delta_x() != 0:
- return self.delta_x() / self.delta_y()
- return NaN
- def intercept(self):
- if self.delta_x() != 0:
- return self[1]['y'] - (self[0]['x'] * self.slope())
- return NaN
- def distanceToPoint(self, p):
- s2 = Segment(self[0],p)
- c1 = dot(s2,self)
- if c1 <= 0:
- return Segment(p,self[0]).length()
- c2 = dot(self,self)
- if c2 <= c1:
- return Segment(p,self[1]).length()
- return self.perpDistanceToPoint(p)
- def perpDistanceToPoint(self, p):
- len = self.length()
- if len == 0: return NaN
- return math.fabs(((self[1]['x'] - self[0]['x']) * (self[0]['y'] - p['y'])) - \
- ((self[0]['x'] - p['x']) * (self[1]['y'] - self[0]['y']))) / len
- def angle(self):
- return math.pi * (math.atan2(self.delta_y(), self.delta_x())) / 180
- def length(self):
- return math.sqrt((self.delta_x() ** 2) + (self.delta_y() ** 2))
- def pointAtLength(self, len):
- if self.length() == 0: return Point(NaN, NaN)
- ratio = len / self.length()
- x = self[0]['x'] + (ratio * self.delta_x())
- y = self[0]['y'] + (ratio * self.delta_y())
- return Point(x, y)
- def pointAtRatio(self, ratio):
- if self.length() == 0: return Point(NaN, NaN)
- x = self[0]['x'] + (ratio * self.delta_x())
- y = self[0]['y'] + (ratio * self.delta_y())
- return Point(x, y)
- def createParallel(self, p):
- return Segment(Point(p['x'] + self.delta_x(), p['y'] + self.delta_y()), p)
- def intersect(self, s):
- return intersectSegments(self, s)
-
-def intersectSegments(s1, s2):
- x1 = s1[0]['x']
- x2 = s1[1]['x']
- x3 = s2[0]['x']
- x4 = s2[1]['x']
-
- y1 = s1[0]['y']
- y2 = s1[1]['y']
- y3 = s2[0]['y']
- y4 = s2[1]['y']
-
- denom = ((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1))
- num1 = ((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3))
- num2 = ((x2 - x1) * (y1 - y3)) - ((y2 - y1) * (x1 - x3))
-
- num = num1
-
- if denom != 0:
- x = x1 + ((num / denom) * (x2 - x1))
- y = y1 + ((num / denom) * (y2 - y1))
- return Point(x, y)
- return Point(NaN, NaN)
-
-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
diff --git a/dxf_export/inkex.py b/dxf_export/inkex.py
deleted file mode 100755
index e487822..0000000
--- a/dxf_export/inkex.py
+++ /dev/null
@@ -1,241 +0,0 @@
-#!/usr/bin/env python
-"""
-inkex.py
-A helper module for creating Inkscape extensions
-
-Copyright (C) 2005,2007 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
-"""
-import sys, copy, optparse, random, re
-import gettext
-from math import *
-_ = gettext.gettext
-
-#a dictionary of all of the xmlns prefixes in a standard inkscape doc
-NSS = {
-u'sodipodi' :u'http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd',
-u'cc' :u'http://creativecommons.org/ns#',
-u'ccOLD' :u'http://web.resource.org/cc/',
-u'svg' :u'http://www.w3.org/2000/svg',
-u'dc' :u'http://purl.org/dc/elements/1.1/',
-u'rdf' :u'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
-u'inkscape' :u'http://www.inkscape.org/namespaces/inkscape',
-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()])
- else:
- retval = 0.0
- if u:
- try:
- return retval * uuconv[u.string[u.start():u.end()]]
- 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'))
-
-def debug(what):
- sys.stderr.write(str(what) + "\n")
- return what
-
-def errormsg(msg):
- """Intended for end-user-visible error messages.
-
- (Currently just writes to stderr with an appended newline, but could do
- something better in future: e.g. could add markup to distinguish error
- messages from status messages or debugging output.)
-
- Note that this should always be combined with translation:
-
- import gettext
- _ = gettext.gettext
- ...
- inkex.errormsg(_("This extension requires two selected paths."))
- """
- sys.stderr.write((unicode(msg) + "\n").encode("UTF-8"))
-
-def check_inkbool(option, opt, value):
- if str(value).capitalize() == 'True':
- return True
- elif str(value).capitalize() == 'False':
- return False
- else:
- raise optparse.OptionValueError("option %s: invalid inkbool value: %s" % (opt, value))
-
-def addNS(tag, ns=None):
- val = tag
- if ns!=None and len(ns)>0 and NSS.has_key(ns) and len(tag)>0 and tag[0]!='{':
- val = "{%s}%s" % (NSS[ns], tag)
- return val
-
-class InkOption(optparse.Option):
- TYPES = optparse.Option.TYPES + ("inkbool",)
- TYPE_CHECKER = copy.copy(optparse.Option.TYPE_CHECKER)
- TYPE_CHECKER["inkbool"] = check_inkbool
-
-class Effect:
- """A class for creating Inkscape SVG Effects"""
-
- def __init__(self, *args, **kwargs):
- self.document=None
- self.original_document=None
- self.ctx=None
- self.selected={}
- self.doc_ids={}
- self.options=None
- self.args=None
- self.OptionParser = optparse.OptionParser(usage="usage: %prog [options] SVGfile",option_class=InkOption)
- self.OptionParser.add_option("--id",
- action="append", type="string", dest="ids", default=[],
- help="id attribute of object to manipulate")
-
- def effect(self):
- pass
-
- def getoptions(self,args=sys.argv[1:]):
- """Collect command line arguments"""
- self.options, self.args = self.OptionParser.parse_args(args)
-
- def parse(self,file=None):
- """Parse document in specified file or on stdin"""
- try:
- try:
- stream = open(file,'r')
- except:
- stream = open(self.svg_file,'r')
- except:
- 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()
-
- def getposinlayer(self):
- #defaults
- self.current_layer = self.document.getroot()
- self.view_center = (0.0,0.0)
-
- layerattr = self.document.xpath('//sodipodi:namedview/@inkscape:current-layer', namespaces=NSS)
- if layerattr:
- layername = layerattr[0]
- layer = self.document.xpath('//svg:g[@id="%s"]' % layername, namespaces=NSS)
- if layer:
- self.current_layer = layer[0]
-
- 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]
- 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
-
- def getselected(self):
- """Collect selected nodes"""
- for i in self.options.ids:
- path = '//*[@id="%s"]' % i
- for node in self.document.xpath(path, namespaces=NSS):
- self.selected[i] = node
-
- def getElementById(self, id):
- path = '//*[@id="%s"]' % id
- el_list = self.document.xpath(path, namespaces=NSS)
- if el_list:
- return el_list[0]
- else:
- return None
-
- def getParentNode(self, node):
- for parent in self.document.getiterator():
- if node in parent.getchildren():
- return parent
- break
-
-
- def getdocids(self):
- docIdNodes = self.document.xpath('//@id', namespaces=NSS)
- for m in docIdNodes:
- self.doc_ids[m] = 1
-
- def getNamedView(self):
- return self.document.xpath('//sodipodi:namedview', namespaces=NSS)[0]
-
- def createGuide(self, posX, posY, angle):
- atts = {
- 'position': str(posX)+','+str(posY),
- 'orientation': str(sin(radians(angle)))+','+str(-cos(radians(angle)))
- }
- guide = etree.SubElement(
- self.getNamedView(),
- addNS('guide','sodipodi'), atts )
- return guide
-
- def output(self):
- """Serialize document into XML on stdout"""
- original = etree.tostring(self.original_document)
- result = etree.tostring(self.document)
- if original != result:
- self.document.write(sys.stdout)
-
- def affect(self, args=sys.argv[1:], output=True):
- """Affect an SVG document with a callback effect"""
- self.svg_file = args[-1]
- self.getoptions(args)
- self.parse()
- self.getposinlayer()
- self.getselected()
- self.getdocids()
- self.effect()
- if output: self.output()
-
- def uniqueId(self, old_id, make_new_id = True):
- new_id = old_id
- if make_new_id:
- while new_id in self.doc_ids:
- new_id += random.choice('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
- self.doc_ids[new_id] = 1
- return new_id
-
- def xpathSingle(self, path):
- try:
- retval = self.document.xpath(path, namespaces=NSS)[0]
- except:
- 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
diff --git a/dxf_export/simplepath.py b/dxf_export/simplepath.py
deleted file mode 100755
index f62b1b4..0000000
--- a/dxf_export/simplepath.py
+++ /dev/null
@@ -1,212 +0,0 @@
-#!/usr/bin/env python
-"""
-simplepath.py
-functions for digesting paths into a simple list structure
-
-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
-
-"""
-import re, math
-
-def lexPath(d):
- """
- returns and iterator that breaks path data
- identifies command and parameter tokens
- """
- offset = 0
- length = len(d)
- delim = re.compile(r'[ \t\r\n,]+')
- command = re.compile(r'[MLHVCSQTAZmlhvcsqtaz]')
- parameter = re.compile(r'(([-+]?[0-9]+(\.[0-9]*)?|[-+]?\.[0-9]+)([eE][-+]?[0-9]+)?)')
- while 1:
- m = delim.match(d, offset)
- if m:
- offset = m.end()
- if offset >= length:
- break
- m = command.match(d, offset)
- if m:
- yield [d[offset:m.end()], True]
- offset = m.end()
- continue
- m = parameter.match(d, offset)
- if m:
- yield [d[offset:m.end()], False]
- offset = m.end()
- continue
- #TODO: create new exception
- raise Exception, 'Invalid path data!'
-'''
-pathdefs = {commandfamily:
- [
- implicitnext,
- #params,
- [casts,cast,cast],
- [coord type,x,y,0]
- ]}
-'''
-pathdefs = {
- 'M':['L', 2, [float, float], ['x','y']],
- 'L':['L', 2, [float, float], ['x','y']],
- 'H':['H', 1, [float], ['x']],
- 'V':['V', 1, [float], ['y']],
- 'C':['C', 6, [float, float, float, float, float, float], ['x','y','x','y','x','y']],
- 'S':['S', 4, [float, float, float, float], ['x','y','x','y']],
- 'Q':['Q', 4, [float, float, float, float], ['x','y','x','y']],
- 'T':['T', 2, [float, float], ['x','y']],
- 'A':['A', 7, [float, float, float, int, int, float, float], ['r','r','a',0,'s','x','y']],
- 'Z':['L', 0, [], []]
- }
-def parsePath(d):
- """
- Parse SVG path and return an array of segments.
- Removes all shorthand notation.
- Converts coordinates to absolute.
- """
- retval = []
- lexer = lexPath(d)
-
- pen = (0.0,0.0)
- subPathStart = pen
- lastControl = pen
- lastCommand = ''
-
- while 1:
- try:
- token, isCommand = lexer.next()
- except StopIteration:
- break
- params = []
- needParam = True
- if isCommand:
- if not lastCommand and token.upper() != 'M':
- raise Exception, 'Invalid path, must begin with moveto.'
- else:
- command = token
- else:
- #command was omited
- #use last command's implicit next command
- needParam = False
- if lastCommand:
- if lastCommand.isupper():
- command = pathdefs[lastCommand][0]
- else:
- command = pathdefs[lastCommand.upper()][0].lower()
- else:
- raise Exception, 'Invalid path, no initial command.'
- numParams = pathdefs[command.upper()][1]
- while numParams > 0:
- if needParam:
- try:
- token, isCommand = lexer.next()
- if isCommand:
- raise Exception, 'Invalid number of parameters'
- except StopIteration:
- raise Exception, 'Unexpected end of path'
- cast = pathdefs[command.upper()][2][-numParams]
- param = cast(token)
- if command.islower():
- if pathdefs[command.upper()][3][-numParams]=='x':
- param += pen[0]
- elif pathdefs[command.upper()][3][-numParams]=='y':
- param += pen[1]
- params.append(param)
- needParam = True
- numParams -= 1
- #segment is now absolute so
- outputCommand = command.upper()
-
- #Flesh out shortcut notation
- if outputCommand in ('H','V'):
- if outputCommand == 'H':
- params.append(pen[1])
- if outputCommand == 'V':
- params.insert(0,pen[0])
- outputCommand = 'L'
- if outputCommand in ('S','T'):
- params.insert(0,pen[1]+(pen[1]-lastControl[1]))
- params.insert(0,pen[0]+(pen[0]-lastControl[0]))
- if outputCommand == 'S':
- outputCommand = 'C'
- if outputCommand == 'T':
- outputCommand = 'Q'
-
- #current values become "last" values
- if outputCommand == 'M':
- subPathStart = tuple(params[0:2])
- pen = subPathStart
- if outputCommand == 'Z':
- pen = subPathStart
- else:
- pen = tuple(params[-2:])
-
- if outputCommand in ('Q','C'):
- lastControl = tuple(params[-4:-2])
- else:
- lastControl = pen
- lastCommand = command
-
- retval.append([outputCommand,params])
- return retval
-
-def formatPath(a):
- """Format SVG path data from an array"""
- return "".join([cmd + " ".join([str(p) for p in params]) for cmd, params in a])
-
-def translatePath(p, x, y):
- for cmd,params in p:
- defs = pathdefs[cmd]
- for i in range(defs[1]):
- if defs[3][i] == 'x':
- params[i] += x
- elif defs[3][i] == 'y':
- params[i] += y
-
-def scalePath(p, x, y):
- for cmd,params in p:
- defs = pathdefs[cmd]
- for i in range(defs[1]):
- if defs[3][i] == 'x':
- params[i] *= x
- elif defs[3][i] == 'y':
- params[i] *= y
- elif defs[3][i] == 'r': # radius parameter
- params[i] *= x
- elif defs[3][i] == 's': # sweep-flag parameter
- if x*y < 0:
- params[i] = 1 - params[i]
- elif defs[3][i] == 'a': # x-axis-rotation angle
- if y < 0:
- params[i] = - params[i]
-
-def rotatePath(p, a, cx = 0, cy = 0):
- if a == 0:
- return p
- for cmd,params in p:
- defs = pathdefs[cmd]
- for i in range(defs[1]):
- if defs[3][i] == 'x':
- x = params[i] - cx
- y = params[i + 1] - cy
- r = math.sqrt((x**2) + (y**2))
- if r != 0:
- theta = math.atan2(y, x) + a
- params[i] = (r * math.cos(theta)) + cx
- params[i + 1] = (r * math.sin(theta)) + cy
-
-
-# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99
diff --git a/dxf_export/simplestyle.py b/dxf_export/simplestyle.py
deleted file mode 100755
index 3ec971e..0000000
--- a/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/dxf_export/simpletransform.py b/dxf_export/simpletransform.py
deleted file mode 100755
index 47cc61e..0000000
--- a/dxf_export/simpletransform.py
+++ /dev/null
@@ -1,241 +0,0 @@
-#!/usr/bin/env python
-'''
-Copyright (C) 2006 Jean-Francois Barraud, barraud@math.univ-lille1.fr
-Copyright (C) 2010 Alvin Penner, penner@vaxxine.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
-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
-
-def parseTransform(transf,mat=[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]):
- if transf=="" or transf==None:
- return(mat)
- stransf = transf.strip()
- result=re.match("(translate|scale|rotate|skewX|skewY|matrix)\s*\(([^)]*)\)\s*,?",stransf)
-#-- translate --
- if result.group(1)=="translate":
- args=result.group(2).replace(',',' ').split()
- dx=float(args[0])
- if len(args)==1:
- dy=0.0
- else:
- dy=float(args[1])
- matrix=[[1,0,dx],[0,1,dy]]
-#-- scale --
- if result.group(1)=="scale":
- args=result.group(2).replace(',',' ').split()
- sx=float(args[0])
- if len(args)==1:
- sy=sx
- else:
- sy=float(args[1])
- matrix=[[sx,0,0],[0,sy,0]]
-#-- rotate --
- if result.group(1)=="rotate":
- args=result.group(2).replace(',',' ').split()
- a=float(args[0])*math.pi/180
- if len(args)==1:
- cx,cy=(0.0,0.0)
- else:
- cx,cy=map(float,args[1:])
- matrix=[[math.cos(a),-math.sin(a),cx],[math.sin(a),math.cos(a),cy]]
- matrix=composeTransform(matrix,[[1,0,-cx],[0,1,-cy]])
-#-- skewX --
- if result.group(1)=="skewX":
- a=float(result.group(2))*math.pi/180
- matrix=[[1,math.tan(a),0],[0,1,0]]
-#-- skewY --
- if result.group(1)=="skewY":
- a=float(result.group(2))*math.pi/180
- matrix=[[1,0,0],[math.tan(a),1,0]]
-#-- matrix --
- if result.group(1)=="matrix":
- a11,a21,a12,a22,v1,v2=result.group(2).replace(',',' ').split()
- matrix=[[float(a11),float(a12),float(v1)], [float(a21),float(a22),float(v2)]]
-
- matrix=composeTransform(mat,matrix)
- if result.end() < len(stransf):
- return(parseTransform(stransf[result.end():], matrix))
- else:
- return matrix
-
-def formatTransform(mat):
- return ("matrix(%f,%f,%f,%f,%f,%f)" % (mat[0][0], mat[1][0], mat[0][1], mat[1][1], mat[0][2], mat[1][2]))
-
-def composeTransform(M1,M2):
- a11 = M1[0][0]*M2[0][0] + M1[0][1]*M2[1][0]
- a12 = M1[0][0]*M2[0][1] + M1[0][1]*M2[1][1]
- a21 = M1[1][0]*M2[0][0] + M1[1][1]*M2[1][0]
- a22 = M1[1][0]*M2[0][1] + M1[1][1]*M2[1][1]
-
- v1 = M1[0][0]*M2[0][2] + M1[0][1]*M2[1][2] + M1[0][2]
- v2 = M1[1][0]*M2[0][2] + M1[1][1]*M2[1][2] + M1[1][2]
- return [[a11,a12,v1],[a21,a22,v2]]
-
-def composeParents(node, mat):
- trans = node.get('transform')
- if trans:
- mat = composeTransform(parseTransform(trans), mat)
- if node.getparent().tag == inkex.addNS('g','svg'):
- mat = composeParents(node.getparent(), mat)
- return mat
-
-def applyTransformToNode(mat,node):
- m=parseTransform(node.get("transform"))
- newtransf=formatTransform(composeTransform(mat,m))
- node.set("transform", newtransf)
-
-def applyTransformToPoint(mat,pt):
- x = mat[0][0]*pt[0] + mat[0][1]*pt[1] + mat[0][2]
- y = mat[1][0]*pt[0] + mat[1][1]*pt[1] + mat[1][2]
- pt[0]=x
- pt[1]=y
-
-def applyTransformToPath(mat,path):
- for comp in path:
- for ctl in comp:
- for pt in ctl:
- applyTransformToPoint(mat,pt)
-
-def fuseTransform(node):
- if node.get('d')==None:
- #FIXME: how do you raise errors?
- raise AssertionError, 'can not fuse "transform" of elements that have no "d" attribute'
- t = node.get("transform")
- if t == None:
- return
- m = parseTransform(t)
- d = node.get('d')
- p = cubicsuperpath.parsePath(d)
- applyTransformToPath(m,p)
- node.set('d', cubicsuperpath.formatPath(p))
- del node.attrib["transform"]
-
-####################################################################
-##-- Some functions to compute a rough bbox of a given list of objects.
-##-- this should be shipped out in an separate file...
-
-def boxunion(b1,b2):
- if b1 is None:
- return b2
- elif b2 is None:
- return b1
- else:
- return((min(b1[0],b2[0]), max(b1[1],b2[1]), min(b1[2],b2[2]), max(b1[3],b2[3])))
-
-def roughBBox(path):
- xmin,xMax,ymin,yMax = path[0][0][0][0],path[0][0][0][0],path[0][0][0][1],path[0][0][0][1]
- for pathcomp in path:
- for ctl in pathcomp:
- for pt in ctl:
- xmin = min(xmin,pt[0])
- xMax = max(xMax,pt[0])
- ymin = min(ymin,pt[1])
- yMax = max(yMax,pt[1])
- return xmin,xMax,ymin,yMax
-
-def refinedBBox(path):
- xmin,xMax,ymin,yMax = path[0][0][1][0],path[0][0][1][0],path[0][0][1][1],path[0][0][1][1]
- for pathcomp in path:
- for i in range(1, len(pathcomp)):
- cmin, cmax = cubicExtrema(pathcomp[i-1][1][0], pathcomp[i-1][2][0], pathcomp[i][0][0], pathcomp[i][1][0])
- xmin = min(xmin, cmin)
- xMax = max(xMax, cmax)
- cmin, cmax = cubicExtrema(pathcomp[i-1][1][1], pathcomp[i-1][2][1], pathcomp[i][0][1], pathcomp[i][1][1])
- ymin = min(ymin, cmin)
- yMax = max(yMax, cmax)
- return xmin,xMax,ymin,yMax
-
-def cubicExtrema(y0, y1, y2, y3):
- cmin = min(y0, y3)
- cmax = max(y0, y3)
- d1 = y1 - y0
- d2 = y2 - y1
- d3 = y3 - y2
- if (d1 - 2*d2 + d3):
- if (d2*d2 > d1*d3):
- t = (d1 - d2 + math.sqrt(d2*d2 - d1*d3))/(d1 - 2*d2 + d3)
- if (t > 0) and (t < 1):
- y = y0*(1-t)*(1-t)*(1-t) + 3*y1*t*(1-t)*(1-t) + 3*y2*t*t*(1-t) + y3*t*t*t
- cmin = min(cmin, y)
- cmax = max(cmax, y)
- t = (d1 - d2 - math.sqrt(d2*d2 - d1*d3))/(d1 - 2*d2 + d3)
- if (t > 0) and (t < 1):
- y = y0*(1-t)*(1-t)*(1-t) + 3*y1*t*(1-t)*(1-t) + 3*y2*t*t*(1-t) + y3*t*t*t
- cmin = min(cmin, y)
- cmax = max(cmax, y)
- elif (d3 - d1):
- t = -d1/(d3 - d1)
- if (t > 0) and (t < 1):
- y = y0*(1-t)*(1-t)*(1-t) + 3*y1*t*(1-t)*(1-t) + 3*y2*t*t*(1-t) + y3*t*t*t
- cmin = min(cmin, y)
- cmax = max(cmax, y)
- return cmin, cmax
-
-def computeBBox(aList,mat=[[1,0,0],[0,1,0]]):
- bbox=None
- for node in aList:
- m = parseTransform(node.get('transform'))
- m = composeTransform(mat,m)
- #TODO: text not supported!
- d = None
- if node.get("d"):
- d = node.get('d')
- elif node.get('points'):
- d = 'M' + node.get('points')
- elif node.tag in [ inkex.addNS('rect','svg'), 'rect', inkex.addNS('image','svg'), 'image' ]:
- d = 'M' + node.get('x', '0') + ',' + node.get('y', '0') + \
- 'h' + node.get('width') + 'v' + node.get('height') + \
- 'h-' + node.get('width')
- elif node.tag in [ inkex.addNS('line','svg'), 'line' ]:
- d = 'M' + node.get('x1') + ',' + node.get('y1') + \
- ' ' + node.get('x2') + ',' + node.get('y2')
- elif node.tag in [ inkex.addNS('circle','svg'), 'circle', \
- inkex.addNS('ellipse','svg'), 'ellipse' ]:
- rx = node.get('r')
- if rx is not None:
- ry = rx
- else:
- rx = node.get('rx')
- ry = node.get('ry')
- cx = float(node.get('cx', '0'))
- cy = float(node.get('cy', '0'))
- x1 = cx - float(rx)
- x2 = cx + float(rx)
- d = 'M %f %f ' % (x1, cy) + \
- 'A' + rx + ',' + ry + ' 0 1 0 %f,%f' % (x2, cy) + \
- 'A' + rx + ',' + ry + ' 0 1 0 %f,%f' % (x1, cy)
-
- if d is not None:
- p = cubicsuperpath.parsePath(d)
- applyTransformToPath(m,p)
- bbox=boxunion(refinedBBox(p),bbox)
-
- elif node.tag == inkex.addNS('use','svg') or node.tag=='use':
- refid=node.get(inkex.addNS('href','xlink'))
- path = '//*[@id="%s"]' % refid[1:]
- refnode = node.xpath(path)
- bbox=boxunion(computeBBox(refnode,m),bbox)
-
- bbox=boxunion(computeBBox(node,m),bbox)
- return bbox
-
-
-# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 fileencoding=utf-8 textwidth=99