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

- more optimizations in NCC Tool
- optimizations in Paint Tool
- maximum range for Cut Z is now zero to deal with the situation when using V-shape with tip-dia same value with cut width

Marius Stanciu 6 лет назад
Родитель
Сommit
74b3a38a71
5 измененных файлов с 194 добавлено и 75 удалено
  1. 6 0
      README.md
  2. 1 1
      flatcamGUI/ObjectUI.py
  3. 8 8
      flatcamGUI/PreferencesUI.py
  4. 10 3
      flatcamTools/ToolNonCopperClear.py
  5. 169 63
      flatcamTools/ToolPaint.py

+ 6 - 0
README.md

@@ -9,6 +9,12 @@ CAD program, and create G-Code for Isolation routing.
 
 =================================================
 
+17.12.2019
+
+- more optimizations in NCC Tool
+- optimizations in Paint Tool
+- maximum range for Cut Z is now zero to deal with the situation when using V-shape with tip-dia same value with cut width
+
 16.12.2019
 
 - in Geometry Editor added support for Jump To function such as that it works within the Editor Tools themselves. For now it works only in absolute jumps

+ 1 - 1
flatcamGUI/ObjectUI.py

@@ -348,7 +348,7 @@ class GerberObjectUI(ObjectUI):
               "below the copper surface.")
         )
         self.cutz_spinner = FCDoubleSpinner()
-        self.cutz_spinner.set_range(-9999.9999, -0.0001)
+        self.cutz_spinner.set_range(-9999.9999, 0.0000)
         self.cutz_spinner.set_precision(self.decimals)
         self.cutz_spinner.setSingleStep(0.1)
         self.cutz_spinner.setWrapping(True)

+ 8 - 8
flatcamGUI/PreferencesUI.py

@@ -1682,7 +1682,7 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI):
         )
         self.cutz_spinner = FCDoubleSpinner()
         self.cutz_spinner.set_precision(self.decimals)
-        self.cutz_spinner.set_range(-99.9999, -0.0001)
+        self.cutz_spinner.set_range(-99.9999, 0.0000)
         self.cutz_spinner.setSingleStep(0.1)
         self.cutz_spinner.setWrapping(True)
 
@@ -2352,7 +2352,7 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
         self.cutz_entry = FCDoubleSpinner()
 
         if machinist_setting == 0:
-            self.cutz_entry.set_range(-9999.9999, -0.000001)
+            self.cutz_entry.set_range(-9999.9999, 0.0000)
         else:
             self.cutz_entry.set_range(-9999.9999, 9999.9999)
 
@@ -2617,7 +2617,7 @@ class ExcellonAdvOptPrefGroupUI(OptionsGroupUI):
         )
         self.pdepth_entry = FCDoubleSpinner()
         self.pdepth_entry.set_precision(self.decimals)
-        self.pdepth_entry.set_range(-99999, -0.000001)
+        self.pdepth_entry.set_range(-99999.9999, 0.0000)
 
         grid1.addWidget(self.pdepth_label, 4, 0)
         grid1.addWidget(self.pdepth_entry, 4, 1)
@@ -3196,7 +3196,7 @@ class GeometryOptPrefGroupUI(OptionsGroupUI):
         self.cutz_entry = FCDoubleSpinner()
 
         if machinist_setting == 0:
-            self.cutz_entry.set_range(-9999.9999, -0.000001)
+            self.cutz_entry.set_range(-9999.9999, 0.0000)
         else:
             self.cutz_entry.set_range(-9999.9999, 9999.9999)
 
@@ -3486,7 +3486,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
               "to probe. Negative value, in current units.")
         )
         self.pdepth_entry = FCDoubleSpinner()
-        self.pdepth_entry.set_range(-99999, -0.000001)
+        self.pdepth_entry.set_range(-99999, 0.0000)
         self.pdepth_entry.set_precision(self.decimals)
         self.pdepth_entry.setSingleStep(0.1)
         self.pdepth_entry.setWrapping(True)
@@ -4052,7 +4052,7 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI):
         )
         self.cutz_entry = FCDoubleSpinner()
         self.cutz_entry.set_precision(self.decimals)
-        self.cutz_entry.set_range(-9999.9999, -0.000001)
+        self.cutz_entry.set_range(-9999.9999, 0.0000)
         self.cutz_entry.setSingleStep(0.1)
 
         self.cutz_entry.setToolTip(
@@ -4310,7 +4310,7 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI):
         self.cutz_entry.set_precision(self.decimals)
 
         if machinist_setting == 0:
-            self.cutz_entry.setRange(-9999.9999, -0.00001)
+            self.cutz_entry.setRange(-9999.9999, 0.0000)
         else:
             self.cutz_entry.setRange(-9999.9999, 9999.9999)
 
@@ -5119,7 +5119,7 @@ class ToolsCalculatorsPrefGroupUI(OptionsGroupUI):
 
         # ## Depth-of-cut Cut Z
         self.cut_z_entry = FCDoubleSpinner()
-        self.cut_z_entry.set_range(-9999.9999, -0.00001)
+        self.cut_z_entry.set_range(-9999.9999, 0.0000)
         self.cut_z_entry.set_precision(self.decimals)
         self.cut_z_entry.setSingleStep(0.01)
 

+ 10 - 3
flatcamTools/ToolNonCopperClear.py

@@ -258,7 +258,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
         )
         self.cutz_entry = FCDoubleSpinner()
         self.cutz_entry.set_precision(self.decimals)
-        self.cutz_entry.set_range(-99999, -0.00000000000001)
+        self.cutz_entry.set_range(-99999.9999, 0.0000)
 
         self.cutz_entry.setToolTip(
            _("Depth of cut into material. Negative value.\n"
@@ -1810,7 +1810,11 @@ class NonCopperClear(FlatCAMTool, Gerber):
                             if self.app.abort_flag:
                                 # graceful abort requested by the user
                                 raise FlatCAMApp.GracefulException
-                            if p is not None:
+
+                            # clean the polygon
+                            p = p.buffer(0)
+
+                            if p is not None and p.is_valid:
                                 poly_processed = list()
                                 try:
                                     for pol in p:
@@ -2201,7 +2205,10 @@ class NonCopperClear(FlatCAMTool, Gerber):
                                 # graceful abort requested by the user
                                 raise FlatCAMApp.GracefulException
 
-                            if p is not None:
+                            # clean the polygon
+                            p = p.buffer(0)
+
+                            if p is not None and p.is_valid:
                                 # provide the app with a way to process the GUI events when in a blocking loop
                                 QtWidgets.QApplication.processEvents()
 

+ 169 - 63
flatcamTools/ToolPaint.py

@@ -1450,8 +1450,7 @@ class ToolPaint(FlatCAMTool, Gerber):
                     geo_obj.solid_geometry += list(cpoly.get_objects())
                     return cpoly
                 else:
-                    app_obj.inform.emit('[ERROR_NOTCL] %s' %
-                                        _('Geometry could not be painted completely'))
+                    app_obj.inform.emit('[ERROR_NOTCL] %s' %  _('Geometry could not be painted completely'))
                     return None
 
             current_uid = int(1)
@@ -1769,62 +1768,162 @@ class ToolPaint(FlatCAMTool, Gerber):
 
                 pol_nr = 0
                 for geo in painted_area:
-                    try:
-                        # Polygons are the only really paintable geometries, lines in theory have no area to be painted
-                        if not isinstance(geo, Polygon):
-                            continue
-                        poly_buf = geo.buffer(-paint_margin)
 
-                        if paint_method == "seed":
-                            # Type(cp) == FlatCAMRTreeStorage | None
-                            cp = self.clear_polygon2(poly_buf,
-                                                     tooldia=tool_dia,
-                                                     steps_per_circle=self.app.defaults["geometry_circle_steps"],
-                                                     overlap=over,
-                                                     contour=cont,
-                                                     connect=conn,
-                                                     prog_plot=prog_plot)
-
-                        elif paint_method == "lines":
-                            # Type(cp) == FlatCAMRTreeStorage | None
-                            cp = self.clear_polygon3(poly_buf,
-                                                     tooldia=tool_dia,
-                                                     steps_per_circle=self.app.defaults["geometry_circle_steps"],
-                                                     overlap=over,
-                                                     contour=cont,
-                                                     connect=conn,
-                                                     prog_plot=prog_plot)
-
-                        else:
-                            # Type(cp) == FlatCAMRTreeStorage | None
-                            cp = self.clear_polygon(poly_buf,
-                                                    tooldia=tool_dia,
-                                                    steps_per_circle=self.app.defaults["geometry_circle_steps"],
-                                                    overlap=over,
-                                                    contour=cont,
-                                                    connect=conn,
-                                                    prog_plot=prog_plot)
-
-                        if cp is not None:
-                            total_geometry += list(cp.get_objects())
-                    except FlatCAMApp.GracefulException:
-                        return "fail"
-                    except Exception as e:
-                        log.debug("Could not Paint the polygons. %s" % str(e))
-                        self.app.inform.emit('[ERROR] %s\n%s' %
-                                             (_("Could not do Paint All. Try a different combination of parameters. "
-                                                "Or a different Method of paint"),
-                                              str(e)))
-                        return "fail"
-
-                    pol_nr += 1
-                    disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
-                    # log.debug("Polygons cleared: %d" % pol_nr)
+                    # provide the app with a way to process the GUI events when in a blocking loop
+                    QtWidgets.QApplication.processEvents()
+
+                    if self.app.abort_flag:
+                        # graceful abort requested by the user
+                        raise FlatCAMApp.GracefulException
+
+                    # try to clean the Polygon but it may result into a MultiPolygon
+                    geo = geo.buffer(0)
+                    poly_buf = geo.buffer(-paint_margin)
+
+                    if geo is not None and geo.is_valid:
+                        poly_processed = list()
+                        try:
+                            for pol in poly_buf:
+                                if pol is not None and isinstance(pol, Polygon):
+                                    if paint_method == 'standard':
+                                        cp = self.clear_polygon(pol,
+                                                                tooldia=tool_dia,
+                                                                steps_per_circle=self.app.defaults[
+                                                                    "geometry_circle_steps"],
+                                                                overlap=over,
+                                                                contour=cont,
+                                                                connect=conn,
+                                                                prog_plot=prog_plot)
+                                    elif paint_method == 'seed':
+                                        cp = self.clear_polygon2(pol,
+                                                                 tooldia=tool_dia,
+                                                                 steps_per_circle=self.app.defaults[
+                                                                     "geometry_circle_steps"],
+                                                                 overlap=over,
+                                                                 contour=cont,
+                                                                 connect=conn,
+                                                                 prog_plot=prog_plot)
+                                    else:
+                                        cp = self.clear_polygon3(pol,
+                                                                 tooldia=tool_dia,
+                                                                 steps_per_circle=self.app.defaults[
+                                                                     "geometry_circle_steps"],
+                                                                 overlap=over,
+                                                                 contour=cont,
+                                                                 connect=conn,
+                                                                 prog_plot=prog_plot)
+                                    if cp:
+                                        total_geometry += list(cp.get_objects())
+                                        poly_processed.append(True)
+                                    else:
+                                        poly_processed.append(False)
+                                        log.warning("Polygon in MultiPolygon can not be cleared.")
+                                else:
+                                    log.warning("Geo in Iterable can not be cleared because it is not Polygon. "
+                                                "It is: %s" % str(type(pol)))
+                        except TypeError:
+                            if isinstance(poly_buf, Polygon):
+                                if paint_method == 'standard':
+                                    cp = self.clear_polygon(poly_buf,
+                                                            tooldia=tool_dia,
+                                                            steps_per_circle=self.app.defaults[
+                                                                "geometry_circle_steps"],
+                                                            overlap=over,
+                                                            contour=cont,
+                                                            connect=conn,
+                                                            prog_plot=prog_plot)
+                                elif paint_method == 'seed':
+                                    cp = self.clear_polygon2(poly_buf,
+                                                             tooldia=tool_dia,
+                                                             steps_per_circle=self.app.defaults[
+                                                                 "geometry_circle_steps"],
+                                                             overlap=over,
+                                                             contour=cont,
+                                                             connect=conn,
+                                                             prog_plot=prog_plot)
+                                else:
+                                    cp = self.clear_polygon3(poly_buf,
+                                                             tooldia=tool_dia,
+                                                             steps_per_circle=self.app.defaults[
+                                                                 "geometry_circle_steps"],
+                                                             overlap=over,
+                                                             contour=cont,
+                                                             connect=conn,
+                                                             prog_plot=prog_plot)
+                                if cp:
+                                    total_geometry += list(cp.get_objects())
+                                    poly_processed.append(True)
+                                else:
+                                    poly_processed.append(False)
+                                    log.warning("Polygon can not be cleared.")
+                            else:
+                                log.warning("Geo can not be cleared because it is: %s" % str(type(poly_buf)))
+
+                        p_cleared = poly_processed.count(True)
+                        p_not_cleared = poly_processed.count(False)
+
+                        if p_not_cleared:
+                            app_obj.poly_not_cleared = True
+
+                        if p_cleared == 0:
+                            continue
 
-                    if old_disp_number < disp_number <= 100:
-                        app_obj.proc_container.update_view_text(' %d%%' % disp_number)
-                        old_disp_number = disp_number
-                        # log.debug("Polygons cleared: %d. Percentage done: %d%%" % (pol_nr, disp_number))
+                    # try:
+                    #     # Polygons are the only really paintable geometries, lines in theory have no area to be painted
+                    #     if not isinstance(geo, Polygon):
+                    #         continue
+                    #     poly_buf = geo.buffer(-paint_margin)
+                    #
+                    #     if paint_method == "seed":
+                    #         # Type(cp) == FlatCAMRTreeStorage | None
+                    #         cp = self.clear_polygon2(poly_buf,
+                    #                                  tooldia=tool_dia,
+                    #                                  steps_per_circle=self.app.defaults["geometry_circle_steps"],
+                    #                                  overlap=over,
+                    #                                  contour=cont,
+                    #                                  connect=conn,
+                    #                                  prog_plot=prog_plot)
+                    #
+                    #     elif paint_method == "lines":
+                    #         # Type(cp) == FlatCAMRTreeStorage | None
+                    #         cp = self.clear_polygon3(poly_buf,
+                    #                                  tooldia=tool_dia,
+                    #                                  steps_per_circle=self.app.defaults["geometry_circle_steps"],
+                    #                                  overlap=over,
+                    #                                  contour=cont,
+                    #                                  connect=conn,
+                    #                                  prog_plot=prog_plot)
+                    #
+                    #     else:
+                    #         # Type(cp) == FlatCAMRTreeStorage | None
+                    #         cp = self.clear_polygon(poly_buf,
+                    #                                 tooldia=tool_dia,
+                    #                                 steps_per_circle=self.app.defaults["geometry_circle_steps"],
+                    #                                 overlap=over,
+                    #                                 contour=cont,
+                    #                                 connect=conn,
+                    #                                 prog_plot=prog_plot)
+                    #
+                    #     if cp is not None:
+                    #         total_geometry += list(cp.get_objects())
+                    # except FlatCAMApp.GracefulException:
+                    #     return "fail"
+                    # except Exception as e:
+                    #     log.debug("Could not Paint the polygons. %s" % str(e))
+                    #     self.app.inform.emit('[ERROR] %s\n%s' %
+                    #                          (_("Could not do Paint All. Try a different combination of parameters. "
+                    #                             "Or a different Method of paint"),
+                    #                           str(e)))
+                    #     return "fail"
+
+                        pol_nr += 1
+                        disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
+                        # log.debug("Polygons cleared: %d" % pol_nr)
+
+                        if old_disp_number < disp_number <= 100:
+                            app_obj.proc_container.update_view_text(' %d%%' % disp_number)
+                            old_disp_number = disp_number
+                            # log.debug("Polygons cleared: %d. Percentage done: %d%%" % (pol_nr, disp_number))
 
                 # add the solid_geometry to the current too in self.paint_tools (tools_storage)
                 # dictionary and then reset the temporary list that stored that solid_geometry
@@ -1837,17 +1936,24 @@ class ToolPaint(FlatCAMTool, Gerber):
             if self.app.defaults["tools_paint_plotting"] == 'progressive':
                 self.temp_shapes.clear(update=True)
 
+            # # delete tools with empty geometry
+            # keys_to_delete = []
+            # # look for keys in the tools_storage dict that have 'solid_geometry' values empty
+            # for uid in tools_storage:
+            #     # if the solid_geometry (type=list) is empty
+            #     if not tools_storage[uid]['solid_geometry']:
+            #         keys_to_delete.append(uid)
+            #
+            # # actual delete of keys from the tools_storage dict
+            # for k in keys_to_delete:
+            #     tools_storage.pop(k, None)
+
             # delete tools with empty geometry
-            keys_to_delete = []
             # look for keys in the tools_storage dict that have 'solid_geometry' values empty
-            for uid in tools_storage:
+            for uid in list(tools_storage.keys()):
                 # if the solid_geometry (type=list) is empty
                 if not tools_storage[uid]['solid_geometry']:
-                    keys_to_delete.append(uid)
-
-            # actual delete of keys from the tools_storage dict
-            for k in keys_to_delete:
-                tools_storage.pop(k, None)
+                    tools_storage.pop(uid, None)
 
             geo_obj.options["cnctooldia"] = str(tool_dia)
             # this turn on the FlatCAMCNCJob plot for multiple tools