- started a new way to clear the Gerber polygons based on the 'follow' lines

This commit is contained in:
Marius Stanciu 2020-02-10 12:27:49 +02:00 committed by Marius
parent e3be6ff22f
commit 82ab0d83d6
2 changed files with 141 additions and 1 deletions

View File

@ -14,6 +14,7 @@ CAD program, and create G-Code for Isolation routing.
- optimized the Paint and NCC Tools. When the Lines type of painting/clearing is used, the lines will try to arrange themselves on the direction that the lines length clearing the polygon are bigger
- solved bug that made drilling with Marlin preprocessor very slow
- applied the fix for above bug to the TclCommand Drillcncjob too
- started a new way to clear the Gerber polygons based on the 'follow' lines
8.02.2020

141
camlib.py
View File

@ -1446,7 +1446,7 @@ class Geometry(object):
return None
# decide the direction of the lines
if abs(left - right) >= abs(top -bot):
if abs(left - right) >= abs(top - bot):
# First line
try:
y = top - tooldia / 1.99999999
@ -1562,6 +1562,145 @@ class Geometry(object):
return geoms
def fill_with_lines(self, line, aperture_size, tooldia, steps_per_circle, overlap=0.15, connect=True, contour=True,
prog_plot=False):
"""
Creates geometry of lines inside a polygon for a tool to cover
the whole area.
This algorithm draws parallel lines inside the polygon.
:param line: The target line that create painted polygon.
:type line: shapely.geometry.LineString or shapely.geometry.MultiLineString
:param tooldia: Tool diameter.
:param steps_per_circle: how many linear segments to use to approximate a circle
:param overlap: Tool path overlap percentage.
:param connect: Connect lines to avoid tool lifts.
:param contour: Paint around the edges.
:param prog_plot: boolean; if to use the progressive plotting
:return:
"""
# log.debug("camlib.fill_with_lines()")
if not isinstance(line, LineString) or not isinstance(line, MultiLineString):
log.debug("camlib.Geometry.fill_with_lines() --> Not a LineString/MultiLineString but %s" % str(type(line)))
return None
# ## The toolpaths
# Index first and last points in paths
def get_pts(o):
return [o.coords[0], o.coords[-1]]
geoms = FlatCAMRTreeStorage()
geoms.get_points = get_pts
lines_trimmed = []
polygon = line.buffer(aperture_size / 1.99999999999999999, int(steps_per_circle))
try:
margin_poly = polygon.buffer(-tooldia / 1.99999999, int(steps_per_circle))
except Exception:
log.debug("camlib.Geometry.fill_with_lines() --> Could not buffer the Polygon, tool diameter too high")
return None
# First line
try:
delta = 0
while delta < aperture_size / 2:
if self.app.abort_flag:
# graceful abort requested by the user
raise FlatCAMApp.GracefulException
# provide the app with a way to process the GUI events when in a blocking loop
QtWidgets.QApplication.processEvents()
line = line.parallel_offset(distance=delta, side='left', resolution=int(steps_per_circle))
line = line.intersection(margin_poly)
lines_trimmed.append(line)
line = line.parallel_offset(distance=delta, side='right', resolution=int(steps_per_circle))
line = line.intersection(margin_poly)
lines_trimmed.append(line)
delta += tooldia * (1 - overlap)
if prog_plot:
self.plot_temp_shapes(line)
self.temp_shapes.redraw()
# Last line
delta = aperture_size / 2
line = line.parallel_offset(distance=delta, side='left', resolution=int(steps_per_circle))
line = line.intersection(margin_poly)
for ll in line:
lines_trimmed.append(ll)
if prog_plot:
self.plot_temp_shapes(line)
line = line.parallel_offset(distance=delta, side='left', resolution=int(steps_per_circle))
line = line.intersection(margin_poly)
for ll in line:
lines_trimmed.append(ll)
if prog_plot:
self.plot_temp_shapes(line)
except Exception as e:
log.debug('camlib.Geometry.fill_with_lines() Processing poly --> %s' % str(e))
return None
if prog_plot:
self.temp_shapes.redraw()
lines_trimmed = unary_union(lines_trimmed)
# Add lines to storage
try:
for line in lines_trimmed:
if isinstance(line, LineString) or isinstance(line, LinearRing):
geoms.insert(line)
else:
log.debug("camlib.Geometry.fill_with_lines(). Not a line: %s" % str(type(line)))
except TypeError:
# in case lines_trimmed are not iterable (Linestring, LinearRing)
geoms.insert(lines_trimmed)
# Add margin (contour) to storage
if contour:
try:
for poly in margin_poly:
if isinstance(poly, Polygon) and not poly.is_empty:
geoms.insert(poly.exterior)
if prog_plot:
self.plot_temp_shapes(poly.exterior)
for ints in poly.interiors:
geoms.insert(ints)
if prog_plot:
self.plot_temp_shapes(ints)
except TypeError:
if isinstance(margin_poly, Polygon) and not margin_poly.is_empty:
marg_ext = margin_poly.exterior
geoms.insert(marg_ext)
if prog_plot:
self.plot_temp_shapes(margin_poly.exterior)
for ints in margin_poly.interiors:
geoms.insert(ints)
if prog_plot:
self.plot_temp_shapes(ints)
if prog_plot:
self.temp_shapes.redraw()
# Optimization: Reduce lifts
if connect:
# log.debug("Reducing tool lifts...")
geoms_conn = Geometry.paint_connect(geoms, polygon, tooldia, steps_per_circle)
if geoms_conn:
return geoms_conn
return geoms
def scale(self, xfactor, yfactor, point=None):
"""
Scales all of the object's geometry by a given factor. Override