Added SVG importing support to the GUI menu. See issue #179.
This commit is contained in:
parent
fdf809774f
commit
d3ed12e5de
|
@ -430,6 +430,7 @@ class App(QtCore.QObject):
|
|||
self.ui.menufileopenexcellon.triggered.connect(self.on_fileopenexcellon)
|
||||
self.ui.menufileopengcode.triggered.connect(self.on_fileopengcode)
|
||||
self.ui.menufileopenproject.triggered.connect(self.on_file_openproject)
|
||||
self.ui.menufileimportsvg.triggered.connect(self.on_file_importsvg)
|
||||
self.ui.menufilesaveproject.triggered.connect(self.on_file_saveproject)
|
||||
self.ui.menufilesaveprojectas.triggered.connect(self.on_file_saveprojectas)
|
||||
self.ui.menufilesaveprojectcopy.triggered.connect(lambda: self.on_file_saveprojectas(make_copy=True))
|
||||
|
@ -1543,6 +1544,29 @@ class App(QtCore.QObject):
|
|||
# thread safe. The new_project()
|
||||
self.open_project(filename)
|
||||
|
||||
def on_file_importsvg(self):
|
||||
"""
|
||||
Callback for menu item File->Import SVG.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
self.report_usage("on_file_importsvg")
|
||||
App.log.debug("on_file_importsvg()")
|
||||
|
||||
try:
|
||||
filename = QtGui.QFileDialog.getOpenFileName(caption="Import SVG",
|
||||
directory=self.get_last_folder())
|
||||
except TypeError:
|
||||
filename = QtGui.QFileDialog.getOpenFileName(caption="Import SVG")
|
||||
|
||||
filename = str(filename)
|
||||
|
||||
if str(filename) == "":
|
||||
self.inform.emit("Open cancelled.")
|
||||
else:
|
||||
self.worker_task.emit({'fcn': self.import_svg,
|
||||
'params': [filename]})
|
||||
|
||||
def on_file_saveproject(self):
|
||||
"""
|
||||
Callback for menu item File->Save Project. Saves the project to
|
||||
|
|
|
@ -28,7 +28,7 @@ class FlatCAMGUI(QtGui.QMainWindow):
|
|||
# Recent
|
||||
self.recent = self.menufile.addMenu(QtGui.QIcon('share/folder16.png'), "Open recent ...")
|
||||
|
||||
# Open gerber
|
||||
# Open gerber ...
|
||||
self.menufileopengerber = QtGui.QAction(QtGui.QIcon('share/folder16.png'), 'Open &Gerber ...', self)
|
||||
self.menufile.addAction(self.menufileopengerber)
|
||||
|
||||
|
@ -40,6 +40,10 @@ 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)
|
||||
|
|
|
@ -358,6 +358,7 @@ class Geometry(object):
|
|||
Imports shapes from an SVG file into the object's geometry.
|
||||
|
||||
:param filename: Path to the SVG file.
|
||||
:type filename: str
|
||||
:return: None
|
||||
"""
|
||||
|
||||
|
|
49
svgparse.py
49
svgparse.py
|
@ -2,15 +2,24 @@
|
|||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# Author: Juan Pablo Caram (c) #
|
||||
# Date: 12/18/2015 #
|
||||
# Date: 12/18/2015 #
|
||||
# MIT Licence #
|
||||
# #
|
||||
# SVG Features supported: #
|
||||
# * Groups #
|
||||
# * Rectangles #
|
||||
# * Circles #
|
||||
# * Paths #
|
||||
# * All transformations #
|
||||
# #
|
||||
# Reference: www.w3.org/TR/SVG/Overview.html #
|
||||
############################################################
|
||||
|
||||
import xml.etree.ElementTree as ET
|
||||
import re
|
||||
import itertools
|
||||
from svg.path import Path, Line, Arc, CubicBezier, QuadraticBezier, parse_path
|
||||
from shapely.geometry import LinearRing, LineString
|
||||
from shapely.geometry import LinearRing, LineString, Point
|
||||
from shapely.affinity import translate, rotate, scale, skew, affine_transform
|
||||
|
||||
|
||||
|
@ -43,10 +52,13 @@ def path2shapely(path, res=1.0):
|
|||
if isinstance(component, Arc) or \
|
||||
isinstance(component, CubicBezier) or \
|
||||
isinstance(component, QuadraticBezier):
|
||||
|
||||
# How many points to use in the dicrete representation.
|
||||
length = component.length(res / 10.0)
|
||||
steps = int(length / res + 0.5)
|
||||
frac = 1.0 / steps
|
||||
print length, steps, frac
|
||||
|
||||
# print length, steps, frac
|
||||
for i in range(steps):
|
||||
point = component.point(i * frac)
|
||||
x, y = point.real, point.imag
|
||||
|
@ -66,6 +78,16 @@ def path2shapely(path, res=1.0):
|
|||
|
||||
|
||||
def svgrect2shapely(rect):
|
||||
"""
|
||||
Converts an SVG rect into Shapely geometry.
|
||||
|
||||
:param rect: Rect Element
|
||||
:type rect: xml.etree.ElementTree.Element
|
||||
:return: shapely.geometry.polygon.LinearRing
|
||||
|
||||
:param rect:
|
||||
:return:
|
||||
"""
|
||||
w = float(rect.get('width'))
|
||||
h = float(rect.get('height'))
|
||||
x = float(rect.get('x'))
|
||||
|
@ -76,6 +98,22 @@ def svgrect2shapely(rect):
|
|||
return LinearRing(pts)
|
||||
|
||||
|
||||
def svgcircle2shapely(circle):
|
||||
"""
|
||||
Converts an SVG circle into Shapely geometry.
|
||||
|
||||
:param circle: Circle Element
|
||||
: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'))
|
||||
|
||||
# TODO: No resolution specified.
|
||||
return Point(cx, cy).buffer(r)
|
||||
|
||||
|
||||
def getsvggeo(node):
|
||||
"""
|
||||
Extracts and flattens all geometry from an SVG node
|
||||
|
@ -106,6 +144,11 @@ def getsvggeo(node):
|
|||
R = svgrect2shapely(node)
|
||||
geo = [R]
|
||||
|
||||
elif kind == 'circle':
|
||||
print "***CIRCLE***"
|
||||
C = svgcircle2shapely(node)
|
||||
geo = [C]
|
||||
|
||||
else:
|
||||
print "Unknown kind:", kind
|
||||
geo = None
|
||||
|
|
Loading…
Reference in New Issue