From 67ef16e77673291c1d44275b6c084c0033ee39f7 Mon Sep 17 00:00:00 2001 From: Juan Pablo Caram Date: Sun, 20 Dec 2015 20:51:33 -0500 Subject: [PATCH] SVG: Accept but ignore units in length. --- FlatCAMGUI.py | 8 ++++---- camlib.py | 13 ++++++++----- svgparse.py | 23 ++++++++++++++++++++--- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/FlatCAMGUI.py b/FlatCAMGUI.py index a0ffe96f..bf9988df 100644 --- a/FlatCAMGUI.py +++ b/FlatCAMGUI.py @@ -40,14 +40,14 @@ class FlatCAMGUI(QtGui.QMainWindow): self.menufileopengcode = QtGui.QAction(QtGui.QIcon('share/folder16.png'), 'Open G-&Code ...', self) self.menufile.addAction(self.menufileopengcode) - # Import SVG ... - self.menufileimportsvg = QtGui.QAction(QtGui.QIcon('share/folder16.png'), 'Import &SVG ...', self) - self.menufile.addAction(self.menufileimportsvg) - # Open Project ... self.menufileopenproject = QtGui.QAction(QtGui.QIcon('share/folder16.png'), 'Open &Project ...', self) self.menufile.addAction(self.menufileopenproject) + # Import SVG ... + self.menufileimportsvg = QtGui.QAction(QtGui.QIcon('share/folder16.png'), 'Import &SVG ...', self) + self.menufile.addAction(self.menufileimportsvg) + # Save Project self.menufilesaveproject = QtGui.QAction(QtGui.QIcon('share/floppy16.png'), '&Save Project', self) self.menufile.addAction(self.menufilesaveproject) diff --git a/camlib.py b/camlib.py index 576aac04..83721f33 100644 --- a/camlib.py +++ b/camlib.py @@ -353,7 +353,7 @@ class Geometry(object): return False - def import_svg(self, filename): + def import_svg(self, filename, flip=True): """ Imports shapes from an SVG file into the object's geometry. @@ -367,20 +367,23 @@ class Geometry(object): svg_root = svg_tree.getroot() # Change origin to bottom left - h = float(svg_root.get('height')) + # h = float(svg_root.get('height')) # w = float(svg_root.get('width')) + h = svgparselength(svg_root.get('height'))[0] # TODO: No units support yet geos = getsvggeo(svg_root) - geo_flip = [translate(scale(g, 1.0, -1.0, origin=(0, 0)), yoff=h) for g in geos] + + if flip: + geos = [translate(scale(g, 1.0, -1.0, origin=(0, 0)), yoff=h) for g in geos] # Add to object if self.solid_geometry is None: self.solid_geometry = [] if type(self.solid_geometry) is list: - self.solid_geometry.append(cascaded_union(geo_flip)) + self.solid_geometry.append(cascaded_union(geos)) else: # It's shapely geometry self.solid_geometry = cascaded_union([self.solid_geometry, - cascaded_union(geo_flip)]) + cascaded_union(geos)]) return diff --git a/svgparse.py b/svgparse.py index 7643a6df..b980b311 100644 --- a/svgparse.py +++ b/svgparse.py @@ -23,6 +23,20 @@ from shapely.geometry import LinearRing, LineString, Point from shapely.affinity import translate, rotate, scale, skew, affine_transform +def svgparselength(lengthstr): + + integer_re_str = r'[+-]?[0-9]+' + number_re_str = r'(?:' + integer_re_str + r'(?:[Ee]' + integer_re_str + r')?' + r')|' + \ + r'(?: [+-]?[0-9]*\.[0-9]+(?:[Ee]' + integer_re_str + ')?)' + length_re_str = r'(' + number_re_str + r')(em|ex|px|in|cm|mm|pt|pc|%)?' + + match = re.search(length_re_str, lengthstr) + if match: + return float(match.group(1)), match.group(2) + + raise Exception('Cannot parse SVG length: %s' % lengthstr) + + def path2shapely(path, res=1.0): """ Converts an svg.path.Path into a Shapely @@ -106,9 +120,12 @@ def svgcircle2shapely(circle): :type circle: xml.etree.ElementTree.Element :return: shapely.geometry.polygon.LinearRing """ - cx = float(circle.get('cx')) - cy = float(circle.get('cy')) - r = float(circle.get('r')) + # cx = float(circle.get('cx')) + # cy = float(circle.get('cy')) + # r = float(circle.get('r')) + cx = svgparselength(circle.get('cx'))[0] # TODO: No units support yet + cy = svgparselength(circle.get('cy'))[1] # TODO: No units support yet + r = svgparselength(circle.get('r'))[0] # TODO: No units support yet # TODO: No resolution specified. return Point(cx, cy).buffer(r)