Merged in vbenso/flatcam/issue282 (pull request #139)
Issue282 - Paint tool behavior isn't the expected for imported svg polygons with holes Approved-by: Marius Stanciu <marius.adrian@gmail.com>
This commit is contained in:
@@ -621,7 +621,7 @@ class Geometry(object):
|
|||||||
|
|
||||||
# flatten the self.solid_geometry list for import_svg() to import SVG as Gerber
|
# flatten the self.solid_geometry list for import_svg() to import SVG as Gerber
|
||||||
self.solid_geometry = list(self.flatten_list(self.solid_geometry))
|
self.solid_geometry = list(self.flatten_list(self.solid_geometry))
|
||||||
self.solid_geometry = cascaded_union(self.solid_geometry)
|
#self.solid_geometry = cascaded_union(self.solid_geometry)
|
||||||
|
|
||||||
geos_text = getsvgtext(svg_root, object_type, units=units)
|
geos_text = getsvgtext(svg_root, object_type, units=units)
|
||||||
if geos_text is not None:
|
if geos_text is not None:
|
||||||
|
|||||||
@@ -56,9 +56,9 @@ def svgparselength(lengthstr):
|
|||||||
def path2shapely(path, object_type, res=1.0):
|
def path2shapely(path, object_type, res=1.0):
|
||||||
"""
|
"""
|
||||||
Converts an svg.path.Path into a Shapely
|
Converts an svg.path.Path into a Shapely
|
||||||
LinearRing or LinearString.
|
Polygon or LinearString.
|
||||||
|
|
||||||
:rtype : LinearRing
|
:rtype : Polygon
|
||||||
:rtype : LineString
|
:rtype : LineString
|
||||||
:param path: svg.path.Path instance
|
:param path: svg.path.Path instance
|
||||||
:param res: Resolution (minimum step along path)
|
:param res: Resolution (minimum step along path)
|
||||||
@@ -68,6 +68,7 @@ def path2shapely(path, object_type, res=1.0):
|
|||||||
points = []
|
points = []
|
||||||
geometry = []
|
geometry = []
|
||||||
geo_element = None
|
geo_element = None
|
||||||
|
rings = []
|
||||||
|
|
||||||
for component in path:
|
for component in path:
|
||||||
|
|
||||||
@@ -109,35 +110,30 @@ def path2shapely(path, object_type, res=1.0):
|
|||||||
|
|
||||||
# Move
|
# Move
|
||||||
if isinstance(component, Move):
|
if isinstance(component, Move):
|
||||||
if object_type == 'geometry':
|
|
||||||
geo_element = LineString(points)
|
|
||||||
elif object_type == 'gerber':
|
|
||||||
# Didn't worked out using Polygon because if there is a large outline it will envelope everything
|
|
||||||
# and create issues with intersections. I will let the parameter obj_type present though
|
|
||||||
# geo_element = Polygon(points)
|
|
||||||
geo_element = LineString(points)
|
|
||||||
else:
|
|
||||||
log.error("[ERROR]: Not a valid target object.")
|
|
||||||
if not points:
|
if not points:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
geometry.append(geo_element)
|
rings.append(points)
|
||||||
points = []
|
points = []
|
||||||
continue
|
continue
|
||||||
log.warning("I don't know what this is: %s" % str(component))
|
log.warning("I don't know what this is: %s" % str(component))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# if there are still points in points then add them as a LineString
|
# if there are still points in points then add them to the last ring
|
||||||
if points:
|
|
||||||
geo_element = LineString(points)
|
if points:
|
||||||
geometry.append(geo_element)
|
rings.append(points)
|
||||||
points = []
|
if len(rings) > 0:
|
||||||
|
if len(rings) == 1:
|
||||||
|
# Polygons are closed and require more than 2 points
|
||||||
|
if Point(rings[0][0]).almost_equals(Point(rings[0][-1])) and len(rings[0]) > 2:
|
||||||
|
geo_element = Polygon(rings[0])
|
||||||
|
else:
|
||||||
|
geo_element = LineString(rings[0])
|
||||||
|
else:
|
||||||
|
geo_element = Polygon(rings[0], rings[1:])
|
||||||
|
geometry.append(geo_element)
|
||||||
|
|
||||||
# if path.closed:
|
|
||||||
# return Polygon(points).buffer(0)
|
|
||||||
# # return LinearRing(points)
|
|
||||||
# else:
|
|
||||||
# return LineString(points)
|
|
||||||
return geometry
|
return geometry
|
||||||
|
|
||||||
def svgrect2shapely(rect, n_points=32):
|
def svgrect2shapely(rect, n_points=32):
|
||||||
@@ -362,7 +358,7 @@ def getsvggeo(node, object_type):
|
|||||||
if tr[0] == 'translate':
|
if tr[0] == 'translate':
|
||||||
geo = [translate(geoi, tr[1], tr[2]) for geoi in geo]
|
geo = [translate(geoi, tr[1], tr[2]) for geoi in geo]
|
||||||
elif tr[0] == 'scale':
|
elif tr[0] == 'scale':
|
||||||
geo = [scale(geoi, tr[0], tr[1], origin=(0, 0))
|
geo = [scale(geoi, tr[1], tr[2], origin=(0, 0))
|
||||||
for geoi in geo]
|
for geoi in geo]
|
||||||
elif tr[0] == 'rotate':
|
elif tr[0] == 'rotate':
|
||||||
geo = [rotate(geoi, tr[1], origin=(tr[2], tr[3]))
|
geo = [rotate(geoi, tr[1], origin=(tr[2], tr[3]))
|
||||||
@@ -459,7 +455,7 @@ def getsvgtext(node, object_type, units='MM'):
|
|||||||
if tr[0] == 'translate':
|
if tr[0] == 'translate':
|
||||||
geo = [translate(geoi, tr[1], tr[2]) for geoi in geo]
|
geo = [translate(geoi, tr[1], tr[2]) for geoi in geo]
|
||||||
elif tr[0] == 'scale':
|
elif tr[0] == 'scale':
|
||||||
geo = [scale(geoi, tr[0], tr[1], origin=(0, 0))
|
geo = [scale(geoi, tr[1], tr[2], origin=(0, 0))
|
||||||
for geoi in geo]
|
for geoi in geo]
|
||||||
elif tr[0] == 'rotate':
|
elif tr[0] == 'rotate':
|
||||||
geo = [rotate(geoi, tr[1], origin=(tr[2], tr[3]))
|
geo = [rotate(geoi, tr[1], origin=(tr[2], tr[3]))
|
||||||
@@ -592,7 +588,7 @@ def parse_svg_transform(trstr):
|
|||||||
trlist.append([
|
trlist.append([
|
||||||
'translate',
|
'translate',
|
||||||
float(match.group(1)),
|
float(match.group(1)),
|
||||||
float(match.group(2)) if match.group else 0.0
|
float(match.group(2)) if (match.group(2) is not None) else 0.0
|
||||||
])
|
])
|
||||||
trstr = trstr[len(match.group(0)):].strip(' ')
|
trstr = trstr[len(match.group(0)):].strip(' ')
|
||||||
continue
|
continue
|
||||||
@@ -600,9 +596,9 @@ def parse_svg_transform(trstr):
|
|||||||
match = re.search(r'^' + scale_re_str, trstr)
|
match = re.search(r'^' + scale_re_str, trstr)
|
||||||
if match:
|
if match:
|
||||||
trlist.append([
|
trlist.append([
|
||||||
'translate',
|
'scale',
|
||||||
float(match.group(1)),
|
float(match.group(1)),
|
||||||
float(match.group(2)) if not None else float(match.group(1))
|
float(match.group(2)) if (match.group(2) is not None) else float(match.group(1))
|
||||||
])
|
])
|
||||||
trstr = trstr[len(match.group(0)):].strip(' ')
|
trstr = trstr[len(match.group(0)):].strip(' ')
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -1068,8 +1068,9 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||||||
|
|
||||||
for geo in recurse(obj.solid_geometry):
|
for geo in recurse(obj.solid_geometry):
|
||||||
try:
|
try:
|
||||||
|
#Polygons are the only really paintable geometries, lines in theory have no area to be painted
|
||||||
if not isinstance(geo, Polygon):
|
if not isinstance(geo, Polygon):
|
||||||
geo = Polygon(geo)
|
continue
|
||||||
poly_buf = geo.buffer(-paint_margin)
|
poly_buf = geo.buffer(-paint_margin)
|
||||||
|
|
||||||
if paint_method == "seed":
|
if paint_method == "seed":
|
||||||
|
|||||||
Reference in New Issue
Block a user