Seed painting algorithm working with optimizations.
This commit is contained in:
@@ -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")
|
||||||
|
|||||||
43
camlib.py
43
camlib.py
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user