Seed painting algorithm working with optimizations.

This commit is contained in:
jpcaram
2015-01-29 17:02:06 -05:00
parent 6733ebbfa8
commit c2c7a83855
2 changed files with 36 additions and 17 deletions

View File

@@ -990,12 +990,16 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
cp = self.clear_polygon(poly.buffer(-self.options["paintmargin"]), tooldia, overlap=overlap) cp = self.clear_polygon(poly.buffer(-self.options["paintmargin"]), tooldia, overlap=overlap)
if self.options["paintmethod"] == "seed": if self.options["paintmethod"] == "seed":
cp = self.clear_polygon2(poly.buffer(-self.options["paintmargin"]), tooldia, overlap=overlap) cp = self.clear_polygon2(poly.buffer(-self.options["paintmargin"]), tooldia, overlap=overlap)
geo_obj.solid_geometry = cp geo_obj.solid_geometry = list(cp.get_objects())
geo_obj.options["cnctooldia"] = tooldia geo_obj.options["cnctooldia"] = tooldia
self.app.inform.emit("Done.") self.app.inform.emit("Done.")
name = self.options["name"] + "_paint" def job_thread(app_obj):
self.app.new_object("geometry", name, gen_paintarea) name = self.options["name"] + "_paint"
app_obj.new_object("geometry", name, gen_paintarea)
self.app.inform.emit("Polygon Paint started ...")
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
def on_generatecnc_button_click(self, *args): def on_generatecnc_button_click(self, *args):
self.app.report_usage("geometry_on_generatecnc_button") self.app.report_usage("geometry_on_generatecnc_button")

View File

@@ -384,7 +384,13 @@ class Geometry(object):
break break
else: else:
#geoms.append(path) #geoms.append(path)
geoms.insert(path) #geoms.insert(path)
# path can be a collection of paths.
try:
for p in path:
geoms.insert(p)
except TypeError:
geoms.insert(path)
radius += tooldia * (1 - overlap) radius += tooldia * (1 - overlap)
@@ -399,13 +405,14 @@ class Geometry(object):
geoms.insert(g) geoms.insert(g)
# Optimization connect touching paths # Optimization connect touching paths
log.debug("Connecting paths...")
geoms = Geometry.path_connect(geoms)
# Optimization: Reduce lifts # Optimization: Reduce lifts
log.debug("Reducing tool lifts...") log.debug("Reducing tool lifts...")
p = Geometry.paint_connect(g.flat_geometry, polygon, tooldia) geoms = Geometry.paint_connect(geoms, polygon, tooldia)
return p return geoms
def scale(self, factor): def scale(self, factor):
""" """
@@ -429,7 +436,7 @@ class Geometry(object):
return return
@staticmethod @staticmethod
def paint_connect(storage, boundary, tooldia): def paint_connect(storage, boundary, tooldia, max_walk=None):
""" """
Connects paths that results in a connection segment that is Connects paths that results in a connection segment that is
within the paint area. This avoids unnecessary tool lifting. within the paint area. This avoids unnecessary tool lifting.
@@ -437,6 +444,10 @@ class Geometry(object):
:return: :return:
""" """
# If max_walk is not specified, the maximum allowed is
# 10 times the tool diameter
max_walk = max_walk or 10 * tooldia
# Assuming geolist is a flat list of flat elements # Assuming geolist is a flat list of flat elements
## Index first and last points in paths ## Index first and last points in paths
@@ -466,7 +477,7 @@ class Geometry(object):
try: try:
while True: while True:
path_count += 1 path_count += 1
log.debug("Path %d" % path_count) #log.debug("Path %d" % path_count)
pt, candidate = storage.nearest(current_pt) pt, candidate = storage.nearest(current_pt)
storage.remove(candidate) storage.remove(candidate)
@@ -479,10 +490,11 @@ class Geometry(object):
# Straight line from current_pt to pt. # Straight line from current_pt to pt.
# Is the toolpath inside the geometry? # Is the toolpath inside the geometry?
jump = LineString([current_pt, pt]).buffer(tooldia / 2) walk_path = LineString([current_pt, pt])
walk_cut = walk_path.buffer(tooldia / 2)
if jump.within(boundary): if walk_cut.within(boundary) and walk_path.length < max_walk:
log.debug("Jump to path #%d is inside. Joining." % path_count) #log.debug("Walk to path #%d is inside. Joining." % path_count)
# Completely inside. Append... # Completely inside. Append...
geo.coords = list(geo.coords) + list(candidate.coords) geo.coords = list(geo.coords) + list(candidate.coords)
@@ -495,7 +507,7 @@ class Geometry(object):
else: else:
# Have to lift tool. End path. # Have to lift tool. End path.
log.debug("Path #%d not within boundary. Next." % path_count) #log.debug("Path #%d not within boundary. Next." % path_count)
#optimized_paths.append(geo) #optimized_paths.append(geo)
optimized_paths.insert(geo) optimized_paths.insert(geo)
geo = candidate geo = candidate
@@ -518,6 +530,8 @@ class Geometry(object):
:return: None :return: None
""" """
log.debug("path_connect()")
## Index first and last points in paths ## Index first and last points in paths
def get_pts(o): def get_pts(o):
return [o.coords[0], o.coords[-1]] return [o.coords[0], o.coords[-1]]
@@ -540,10 +554,10 @@ class Geometry(object):
while True: while True:
path_count += 1 path_count += 1
print "geo is", geo #print "geo is", geo
_, left = storage.nearest(geo.coords[0]) _, left = storage.nearest(geo.coords[0])
print "left is", left #print "left is", left
# If left touches geo, remove left from original # If left touches geo, remove left from original
# storage and append to geo. # storage and append to geo.
@@ -569,7 +583,7 @@ class Geometry(object):
continue continue
_, right = storage.nearest(geo.coords[-1]) _, right = storage.nearest(geo.coords[-1])
print "right is", right #print "right is", right
# If right touches geo, remove left from original # If right touches geo, remove left from original
# storage and append to geo. # storage and append to geo.
@@ -611,7 +625,8 @@ class Geometry(object):
except StopIteration: # Nothing found in storage. except StopIteration: # Nothing found in storage.
optimized_geometry.insert(geo) optimized_geometry.insert(geo)
print path_count #print path_count
log.debug("path_count = %d" % path_count)
return optimized_geometry return optimized_geometry