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.menufileopenexcellon.triggered.connect(self.on_fileopenexcellon)
|
||||||
self.ui.menufileopengcode.triggered.connect(self.on_fileopengcode)
|
self.ui.menufileopengcode.triggered.connect(self.on_fileopengcode)
|
||||||
self.ui.menufileopenproject.triggered.connect(self.on_file_openproject)
|
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.menufilesaveproject.triggered.connect(self.on_file_saveproject)
|
||||||
self.ui.menufilesaveprojectas.triggered.connect(self.on_file_saveprojectas)
|
self.ui.menufilesaveprojectas.triggered.connect(self.on_file_saveprojectas)
|
||||||
self.ui.menufilesaveprojectcopy.triggered.connect(lambda: self.on_file_saveprojectas(make_copy=True))
|
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()
|
# thread safe. The new_project()
|
||||||
self.open_project(filename)
|
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):
|
def on_file_saveproject(self):
|
||||||
"""
|
"""
|
||||||
Callback for menu item File->Save Project. Saves the project to
|
Callback for menu item File->Save Project. Saves the project to
|
||||||
|
|
|
@ -28,7 +28,7 @@ class FlatCAMGUI(QtGui.QMainWindow):
|
||||||
# Recent
|
# Recent
|
||||||
self.recent = self.menufile.addMenu(QtGui.QIcon('share/folder16.png'), "Open 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.menufileopengerber = QtGui.QAction(QtGui.QIcon('share/folder16.png'), 'Open &Gerber ...', self)
|
||||||
self.menufile.addAction(self.menufileopengerber)
|
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.menufileopengcode = QtGui.QAction(QtGui.QIcon('share/folder16.png'), 'Open G-&Code ...', self)
|
||||||
self.menufile.addAction(self.menufileopengcode)
|
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 ...
|
# Open Project ...
|
||||||
self.menufileopenproject = QtGui.QAction(QtGui.QIcon('share/folder16.png'), 'Open &Project ...', self)
|
self.menufileopenproject = QtGui.QAction(QtGui.QIcon('share/folder16.png'), 'Open &Project ...', self)
|
||||||
self.menufile.addAction(self.menufileopenproject)
|
self.menufile.addAction(self.menufileopenproject)
|
||||||
|
|
|
@ -358,6 +358,7 @@ class Geometry(object):
|
||||||
Imports shapes from an SVG file into the object's geometry.
|
Imports shapes from an SVG file into the object's geometry.
|
||||||
|
|
||||||
:param filename: Path to the SVG file.
|
:param filename: Path to the SVG file.
|
||||||
|
:type filename: str
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
49
svgparse.py
49
svgparse.py
|
@ -2,15 +2,24 @@
|
||||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||||
# http://flatcam.org #
|
# http://flatcam.org #
|
||||||
# Author: Juan Pablo Caram (c) #
|
# Author: Juan Pablo Caram (c) #
|
||||||
# Date: 12/18/2015 #
|
# Date: 12/18/2015 #
|
||||||
# MIT Licence #
|
# 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 xml.etree.ElementTree as ET
|
||||||
import re
|
import re
|
||||||
import itertools
|
import itertools
|
||||||
from svg.path import Path, Line, Arc, CubicBezier, QuadraticBezier, parse_path
|
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
|
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 \
|
if isinstance(component, Arc) or \
|
||||||
isinstance(component, CubicBezier) or \
|
isinstance(component, CubicBezier) or \
|
||||||
isinstance(component, QuadraticBezier):
|
isinstance(component, QuadraticBezier):
|
||||||
|
|
||||||
|
# How many points to use in the dicrete representation.
|
||||||
length = component.length(res / 10.0)
|
length = component.length(res / 10.0)
|
||||||
steps = int(length / res + 0.5)
|
steps = int(length / res + 0.5)
|
||||||
frac = 1.0 / steps
|
frac = 1.0 / steps
|
||||||
print length, steps, frac
|
|
||||||
|
# print length, steps, frac
|
||||||
for i in range(steps):
|
for i in range(steps):
|
||||||
point = component.point(i * frac)
|
point = component.point(i * frac)
|
||||||
x, y = point.real, point.imag
|
x, y = point.real, point.imag
|
||||||
|
@ -66,6 +78,16 @@ def path2shapely(path, res=1.0):
|
||||||
|
|
||||||
|
|
||||||
def svgrect2shapely(rect):
|
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'))
|
w = float(rect.get('width'))
|
||||||
h = float(rect.get('height'))
|
h = float(rect.get('height'))
|
||||||
x = float(rect.get('x'))
|
x = float(rect.get('x'))
|
||||||
|
@ -76,6 +98,22 @@ def svgrect2shapely(rect):
|
||||||
return LinearRing(pts)
|
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):
|
def getsvggeo(node):
|
||||||
"""
|
"""
|
||||||
Extracts and flattens all geometry from an SVG node
|
Extracts and flattens all geometry from an SVG node
|
||||||
|
@ -106,6 +144,11 @@ def getsvggeo(node):
|
||||||
R = svgrect2shapely(node)
|
R = svgrect2shapely(node)
|
||||||
geo = [R]
|
geo = [R]
|
||||||
|
|
||||||
|
elif kind == 'circle':
|
||||||
|
print "***CIRCLE***"
|
||||||
|
C = svgcircle2shapely(node)
|
||||||
|
geo = [C]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print "Unknown kind:", kind
|
print "Unknown kind:", kind
|
||||||
geo = None
|
geo = None
|
||||||
|
|
Loading…
Reference in New Issue