- added ability to see the verbose log when importing SVG's (if set in preferences)
- added some more logs to the SVG import
This commit is contained in:
@@ -7,6 +7,11 @@ CHANGELOG for FlatCAM beta
|
|||||||
|
|
||||||
=================================================
|
=================================================
|
||||||
|
|
||||||
|
21.01.2021
|
||||||
|
|
||||||
|
- added ability to see the verbose log when importing SVG's (if set in preferences)
|
||||||
|
- added some more logs to the SVG import
|
||||||
|
|
||||||
19.01.2021
|
19.01.2021
|
||||||
|
|
||||||
- fixed the Gerber export to convert all the aperture macros to regions and therefore export also the data from aperture macros
|
- fixed the Gerber export to convert all the aperture macros to regions and therefore export also the data from aperture macros
|
||||||
|
|||||||
@@ -73,15 +73,17 @@ class Gerber(Geometry):
|
|||||||
|
|
||||||
def __init__(self, steps_per_circle=None):
|
def __init__(self, steps_per_circle=None):
|
||||||
"""
|
"""
|
||||||
The constructor takes no parameters. Use ``gerber.parse_files()``
|
Use ``gerber.parse_files()`` or ``gerber.parse_lines()`` to populate the object from Gerber source.
|
||||||
or ``gerber.parse_lines()`` to populate the object from Gerber source.
|
|
||||||
|
|
||||||
:return: Gerber object
|
:return: Gerber object
|
||||||
:rtype: Gerber
|
:rtype: Gerber
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# How to approximate a circle with lines.
|
# How to approximate a circle with lines.
|
||||||
self.steps_per_circle = int(self.app.defaults["gerber_circle_steps"])
|
if steps_per_circle is None:
|
||||||
|
self.steps_per_circle = int(self.app.defaults["gerber_circle_steps"])
|
||||||
|
else:
|
||||||
|
self.steps_per_circle = steps_per_circle
|
||||||
self.decimals = self.app.decimals
|
self.decimals = self.app.decimals
|
||||||
|
|
||||||
# Initialize parent
|
# Initialize parent
|
||||||
@@ -1905,9 +1907,13 @@ class Gerber(Geometry):
|
|||||||
units = self.app.defaults['units'] if units is None else units
|
units = self.app.defaults['units'] if units is None else units
|
||||||
res = self.app.defaults['gerber_circle_steps']
|
res = self.app.defaults['gerber_circle_steps']
|
||||||
factor = svgparse_viewbox(svg_root)
|
factor = svgparse_viewbox(svg_root)
|
||||||
geos = getsvggeo(svg_root, 'gerber', units=units, res=res, factor=factor)
|
geos = getsvggeo(svg_root, 'gerber', units=units, res=res, factor=factor, app=self.app)
|
||||||
|
|
||||||
|
self.app.log.debug("appParsers.ParseGerber.Gerber.import_svg(). Finished parsing the SVG geometry.")
|
||||||
|
|
||||||
if flip:
|
if flip:
|
||||||
geos = [translate(scale(g, 1.0, -1.0, origin=(0, 0)), yoff=h) for g in geos]
|
geos = [translate(scale(g, 1.0, -1.0, origin=(0, 0)), yoff=h) for g in geos]
|
||||||
|
self.app.log.debug("appParsers.ParseGerber.Gerber.import_svg(). SVG geometry was flipped.")
|
||||||
|
|
||||||
# Add to object
|
# Add to object
|
||||||
if self.solid_geometry is None:
|
if self.solid_geometry is None:
|
||||||
|
|||||||
@@ -393,7 +393,7 @@ def svgpolygon2shapely(polygon, n_points=64, factor=1.0):
|
|||||||
# return LinearRing(points)
|
# return LinearRing(points)
|
||||||
|
|
||||||
|
|
||||||
def getsvggeo(node, object_type, root=None, units='MM', res=64, factor=1.0):
|
def getsvggeo(node, object_type, root=None, units='MM', res=64, factor=1.0, app=None):
|
||||||
"""
|
"""
|
||||||
Extracts and flattens all geometry from an SVG node
|
Extracts and flattens all geometry from an SVG node
|
||||||
into a list of Shapely geometry.
|
into a list of Shapely geometry.
|
||||||
@@ -405,19 +405,26 @@ def getsvggeo(node, object_type, root=None, units='MM', res=64, factor=1.0):
|
|||||||
:param res: resolution to be used for circles buffering
|
:param res: resolution to be used for circles buffering
|
||||||
:param factor: correction factor due of virtual units
|
:param factor: correction factor due of virtual units
|
||||||
:type factor: float
|
:type factor: float
|
||||||
|
:param app: Application reference
|
||||||
|
|
||||||
:return: List of Shapely geometry
|
:return: List of Shapely geometry
|
||||||
:rtype: list
|
:rtype: list
|
||||||
"""
|
"""
|
||||||
if root is None:
|
if root is None:
|
||||||
root = node
|
root = node
|
||||||
|
|
||||||
|
if app is not None:
|
||||||
|
log = app.log
|
||||||
|
else:
|
||||||
|
log = logging.getLogger('base2')
|
||||||
|
|
||||||
kind = re.search('(?:\{.*\})?(.*)$', node.tag).group(1)
|
kind = re.search('(?:\{.*\})?(.*)$', node.tag).group(1)
|
||||||
geo = []
|
geo = []
|
||||||
|
|
||||||
# Recurse
|
# Recurse
|
||||||
if len(node) > 0:
|
if len(node) > 0:
|
||||||
for child in node:
|
for child in node:
|
||||||
subgeo = getsvggeo(child, object_type, root=root, units=units, res=res, factor=factor)
|
subgeo = getsvggeo(child, object_type, root=root, units=units, res=res, factor=factor, app=app)
|
||||||
if subgeo is not None:
|
if subgeo is not None:
|
||||||
geo += subgeo
|
geo += subgeo
|
||||||
# Parse
|
# Parse
|
||||||
@@ -465,7 +472,10 @@ def getsvggeo(node, object_type, root=None, units='MM', res=64, factor=1.0):
|
|||||||
href = node.attrib['href'] if 'href' in node.attrib else node.attrib['{http://www.w3.org/1999/xlink}href']
|
href = node.attrib['href'] if 'href' in node.attrib else node.attrib['{http://www.w3.org/1999/xlink}href']
|
||||||
ref = root.find(".//*[@id='%s']" % href.replace('#', ''))
|
ref = root.find(".//*[@id='%s']" % href.replace('#', ''))
|
||||||
if ref is not None:
|
if ref is not None:
|
||||||
geo = getsvggeo(ref, object_type, root=root, units=units, res=res, factor=factor)
|
geo = getsvggeo(ref, object_type, root=root, units=units, res=res, factor=factor, app=app)
|
||||||
|
|
||||||
|
elif kind in ['defs', 'namedview', 'format', 'type', 'title']:
|
||||||
|
log.warning('SVG Element not supported: %s. Skipping to next.' % kind)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
log.warning("Unknown kind: " + kind)
|
log.warning("Unknown kind: " + kind)
|
||||||
@@ -568,11 +578,12 @@ def getsvgtext(node, object_type, app, units='MM'):
|
|||||||
geo = [(scale(g, 1.0, -1.0)) for g in geo]
|
geo = [(scale(g, 1.0, -1.0)) for g in geo]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.error(str(e))
|
log.error(str(e))
|
||||||
|
geo = None
|
||||||
else:
|
else:
|
||||||
geo = None
|
geo = None
|
||||||
|
|
||||||
# ignore transformation for unknown kind
|
# ignore transformation for unknown kind
|
||||||
if geo is not None:
|
if geo and geo is not None:
|
||||||
# Transformations
|
# Transformations
|
||||||
if 'transform' in node.attrib:
|
if 'transform' in node.attrib:
|
||||||
trstr = node.get('transform')
|
trstr = node.get('transform')
|
||||||
@@ -597,6 +608,9 @@ def getsvgtext(node, object_type, app, units='MM'):
|
|||||||
else:
|
else:
|
||||||
raise Exception('Unknown transformation: %s', tr)
|
raise Exception('Unknown transformation: %s', tr)
|
||||||
|
|
||||||
|
if not geo:
|
||||||
|
geo = None
|
||||||
|
|
||||||
return geo
|
return geo
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -486,6 +486,8 @@ class QRCode(AppTool):
|
|||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
self.app.log.debug("QRCode.import_svg()")
|
||||||
|
|
||||||
# Parse into list of shapely objects
|
# Parse into list of shapely objects
|
||||||
svg_tree = ET.parse(filename)
|
svg_tree = ET.parse(filename)
|
||||||
svg_root = svg_tree.getroot()
|
svg_root = svg_tree.getroot()
|
||||||
@@ -497,16 +499,21 @@ class QRCode(AppTool):
|
|||||||
units = self.app.defaults['units'] if units is None else units
|
units = self.app.defaults['units'] if units is None else units
|
||||||
res = self.app.defaults['geometry_circle_steps']
|
res = self.app.defaults['geometry_circle_steps']
|
||||||
factor = svgparse_viewbox(svg_root)
|
factor = svgparse_viewbox(svg_root)
|
||||||
geos = getsvggeo(svg_root, object_type, units=units, res=res, factor=factor)
|
geos = getsvggeo(svg_root, object_type, units=units, res=res, factor=factor, app=self.app)
|
||||||
|
|
||||||
|
self.app.log.debug("QRCode.import_svg(). Finished parsing the SVG geometry.")
|
||||||
|
|
||||||
if flip:
|
if flip:
|
||||||
geos = [translate(scale(g, 1.0, -1.0, origin=(0, 0)), yoff=h) for g in geos]
|
geos = [translate(scale(g, 1.0, -1.0, origin=(0, 0)), yoff=h) for g in geos]
|
||||||
|
self.app.log.debug("QRCode.import_svg(). SVG geometry was flipped.")
|
||||||
|
|
||||||
# flatten the svg geometry for the case when the QRCode SVG is added into a Gerber object
|
# flatten the svg geometry for the case when the QRCode SVG is added into a Gerber object
|
||||||
solid_geometry = list(self.flatten_list(geos))
|
solid_geometry = list(self.flatten_list(geos))
|
||||||
|
|
||||||
geos_text = getsvgtext(svg_root, object_type, app=self.app, units=units)
|
geos_text = getsvgtext(svg_root, object_type, app=self.app, units=units)
|
||||||
if geos_text is not None:
|
if geos_text is not None:
|
||||||
|
self.app.log.debug("QRCode.import_svg(). Processing SVG text.")
|
||||||
|
|
||||||
geos_text_f = []
|
geos_text_f = []
|
||||||
if flip:
|
if flip:
|
||||||
# Change origin to bottom left
|
# Change origin to bottom left
|
||||||
|
|||||||
18
camlib.py
18
camlib.py
@@ -1151,7 +1151,7 @@ class Geometry(object):
|
|||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
log.debug("camlib.Geometry.import_svg()")
|
self.app.log.debug("camlib.Geometry.import_svg()")
|
||||||
|
|
||||||
# Parse into list of shapely objects
|
# Parse into list of shapely objects
|
||||||
svg_tree = ET.parse(filename)
|
svg_tree = ET.parse(filename)
|
||||||
@@ -1166,9 +1166,13 @@ class Geometry(object):
|
|||||||
res = self.app.defaults['geometry_circle_steps']
|
res = self.app.defaults['geometry_circle_steps']
|
||||||
factor = svgparse_viewbox(svg_root)
|
factor = svgparse_viewbox(svg_root)
|
||||||
|
|
||||||
geos = getsvggeo(svg_root, object_type, units=units, res=res, factor=factor)
|
geos = getsvggeo(svg_root, object_type, units=units, res=res, factor=factor, app=self.app)
|
||||||
|
|
||||||
|
self.app.log.debug("camlib.Geometry.import_svg(). Finished parsing the SVG geometry.")
|
||||||
|
|
||||||
if flip:
|
if flip:
|
||||||
geos = [translate(scale(g, 1.0, -1.0, origin=(0, 0)), yoff=h) for g in geos]
|
geos = [translate(scale(g, 1.0, -1.0, origin=(0, 0)), yoff=h) for g in geos]
|
||||||
|
self.app.log.debug("camlib.Geometry.import_svg(). SVG geometry was flipped.")
|
||||||
|
|
||||||
# trying to optimize the resulting geometry by merging contiguous lines
|
# trying to optimize the resulting geometry by merging contiguous lines
|
||||||
geos = list(self.flatten_list(geos))
|
geos = list(self.flatten_list(geos))
|
||||||
@@ -1180,7 +1184,13 @@ class Geometry(object):
|
|||||||
else:
|
else:
|
||||||
geos_lines.append(g)
|
geos_lines.append(g)
|
||||||
|
|
||||||
merged_lines = linemerge(geos_lines)
|
try:
|
||||||
|
merged_lines = linemerge(geos_lines)
|
||||||
|
except Exception:
|
||||||
|
merged_lines = geos_lines
|
||||||
|
self.app.log.error(
|
||||||
|
'camlib.Geometry.import_svg(). Could not merge the lines, working with the original SVG geometry.')
|
||||||
|
|
||||||
geos = geos_polys
|
geos = geos_polys
|
||||||
try:
|
try:
|
||||||
for ml in merged_lines:
|
for ml in merged_lines:
|
||||||
@@ -1204,7 +1214,9 @@ class Geometry(object):
|
|||||||
self.solid_geometry = list(self.flatten_list(self.solid_geometry))
|
self.solid_geometry = list(self.flatten_list(self.solid_geometry))
|
||||||
|
|
||||||
geos_text = getsvgtext(svg_root, object_type, app=self.app, units=units)
|
geos_text = getsvgtext(svg_root, object_type, app=self.app, units=units)
|
||||||
|
|
||||||
if geos_text is not None:
|
if geos_text is not None:
|
||||||
|
self.app.log.debug("camlib.Geometry.import_svg(). Processing SVG text.")
|
||||||
geos_text_f = []
|
geos_text_f = []
|
||||||
if flip:
|
if flip:
|
||||||
# Change origin to bottom left
|
# Change origin to bottom left
|
||||||
|
|||||||
Reference in New Issue
Block a user