Explorar el Código

SVG: Accept but ignore units in length.

Juan Pablo Caram hace 10 años
padre
commit
67ef16e776
Se han modificado 3 ficheros con 32 adiciones y 12 borrados
  1. 4 4
      FlatCAMGUI.py
  2. 8 5
      camlib.py
  3. 20 3
      svgparse.py

+ 4 - 4
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)

+ 8 - 5
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
 

+ 20 - 3
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)