From dbe0105f9b998996e6de77b299750811f71acd85 Mon Sep 17 00:00:00 2001 From: Juan Pablo Caram Date: Wed, 21 Sep 2016 13:01:51 -0400 Subject: [PATCH] Fixes SVG parser to produce polygons. Fixes #212. --- FlatCAMObj.py | 2 +- camlib.py | 27 ++++++++++++++++++--------- svgparse.py | 14 +++++++++----- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 76f018ca..b4098b38 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -1276,11 +1276,11 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): :param inside_pt: [x, y] :param tooldia: Diameter of the painting tool :param overlap: Overlap of the tool between passes. + :param outname: Name of the resulting Geometry Object. :return: None """ # Which polygon. - #poly = find_polygon(self.solid_geometry, inside_pt) poly = self.find_polygon(inside_pt) # No polygon? diff --git a/camlib.py b/camlib.py index e65ef0fc..86186c30 100644 --- a/camlib.py +++ b/camlib.py @@ -223,10 +223,16 @@ class Geometry(object): def find_polygon(self, point, geoset=None): """ Find an object that object.contains(Point(point)) in - poly, which can can be iterable, contain iterable of, or + geoset, which can can be iterable, contain iterables of, or be itself an implementer of .contains(). - :param poly: See description + Note: + * Shapely Polygons will work as expected here. Linearrings + will only yield true if the point is in the perimeter. + + :param point: See description + :param geoset: Set to search. If none, the defaults to + self.solid_geometry. :return: Polygon containing point or None. """ @@ -416,6 +422,8 @@ class Geometry(object): :param filename: Path to the SVG file. :type filename: str + :param flip: Flip the vertically. + :type flip: bool :return: None """ @@ -424,8 +432,6 @@ class Geometry(object): svg_root = svg_tree.getroot() # Change origin to bottom left - # 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) @@ -437,12 +443,15 @@ class Geometry(object): self.solid_geometry = [] if type(self.solid_geometry) is list: - self.solid_geometry.append(cascaded_union(geos)) + # self.solid_geometry.append(cascaded_union(geos)) + if type(geos) is list: + self.solid_geometry += geos + else: + self.solid_geometry.append(geos) else: # It's shapely geometry - self.solid_geometry = cascaded_union([self.solid_geometry, - cascaded_union(geos)]) - - return + # self.solid_geometry = cascaded_union([self.solid_geometry, + # cascaded_union(geos)]) + self.solid_geometry = [self.solid_geometry, geos] def size(self): """ diff --git a/svgparse.py b/svgparse.py index 544f0ba6..c24f64dd 100644 --- a/svgparse.py +++ b/svgparse.py @@ -23,7 +23,7 @@ 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, Point +from shapely.geometry import LinearRing, LineString, Point, Polygon from shapely.affinity import translate, rotate, scale, skew, affine_transform import numpy as np import logging @@ -109,7 +109,8 @@ def path2shapely(path, res=1.0): continue if path.closed: - return LinearRing(points) + return Polygon(points).buffer(0) + # return LinearRing(points) else: return LineString(points) @@ -178,7 +179,8 @@ def svgrect2shapely(rect, n_points=32): [(x, y + h - ry), (x, y + ry)] + \ lower_left - return LinearRing(pts) + return Polygon(pts).buffer(0) + # return LinearRing(pts) def svgcircle2shapely(circle): @@ -223,7 +225,8 @@ def svgellipse2shapely(ellipse, n_points=64): y = cy + ry * np.sin(2 * np.pi * t) pts = [(x[i], y[i]) for i in range(n_points)] - return LinearRing(pts) + return Polygon(pts).buffer(0) + # return LinearRing(pts) def svgline2shapely(line): @@ -256,7 +259,8 @@ def svgpolygon2shapely(polygon): ptliststr = polygon.get('points') points = parse_svg_point_list(ptliststr) - return LinearRing(points) + return Polygon(points).buffer(0) + # return LinearRing(points) def getsvggeo(node):