Просмотр исходного кода

Seed painting algorithm working with optimizations.

jpcaram 11 лет назад
Родитель
Сommit
c2c7a83855
2 измененных файлов с 36 добавлено и 17 удалено
  1. 7 3
      FlatCAMObj.py
  2. 29 14
      camlib.py

+ 7 - 3
FlatCAMObj.py

@@ -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"
-        self.app.new_object("geometry", name, gen_paintarea)
+        def job_thread(app_obj):
+            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")

+ 29 - 14
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):
-                    log.debug("Jump to path #%d is inside. Joining." % path_count)
+                if walk_cut.within(boundary) and walk_path.length < max_walk:
+                    #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