diff --git a/README.md b/README.md index d7b555f9..19f46ccc 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,13 @@ 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 +- modified QValidator in FCDoubleSpinner() GUI element to allow entering the minus sign when the range maximum is set as 0.0; also for positive numbers allowed entering the symbol plus + 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 @@ -22,6 +29,7 @@ CAD program, and create G-Code for Isolation routing. - fixed the CNCJob geometry created with HPGL preprocessor - fixed GCode generated with HPGL preprocessor to output only integer coordinates - fixed the HPGL2 import parsing for absolute linear movements +- fixed the line endings for setup_ubuntu.sh 15.12.2019 diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index 21068200..96fa793d 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -21,8 +21,16 @@ import re import logging import html +import gettext +import FlatCAMTranslation as fcTranslate +import builtins + log = logging.getLogger('base') +fcTranslate.apply_language('strings') +if '_' not in builtins.__dict__: + _ = gettext.gettext + EDIT_SIZE_HINT = 70 @@ -624,7 +632,7 @@ class FCDoubleSpinner(QtWidgets.QDoubleSpinBox): # by default don't allow the minus sign to be entered as the default for QDoubleSpinBox is the positive range # between 0.00 and 99.00 (2 decimals) self.lineEdit().setValidator( - QtGui.QRegExpValidator(QtCore.QRegExp("[0-9]*[.,]?[0-9]{%d}" % self.decimals()), self)) + QtGui.QRegExpValidator(QtCore.QRegExp("\+?[0-9]*[.,]?[0-9]{%d}" % self.decimals()), self)) if suffix: self.setSuffix(' %s' % str(suffix)) @@ -710,15 +718,15 @@ class FCDoubleSpinner(QtWidgets.QDoubleSpinBox): self.setDecimals(val) # make sure that the user can't type more decimals than the set precision - if self.minimum() < 0 or self.maximum() < 0: + if self.minimum() < 0 or self.maximum() <= 0: self.lineEdit().setValidator( QtGui.QRegExpValidator(QtCore.QRegExp("-?[0-9]*[.,]?[0-9]{%d}" % self.decimals()), self)) else: self.lineEdit().setValidator( - QtGui.QRegExpValidator(QtCore.QRegExp("[0-9]*[.,]?[0-9]{%d}" % self.decimals()), self)) + QtGui.QRegExpValidator(QtCore.QRegExp("\+?[0-9]*[.,]?[0-9]{%d}" % self.decimals()), self)) def set_range(self, min_val, max_val): - if min_val < 0 or max_val < 0: + if min_val < 0 or max_val <= 0: self.lineEdit().setValidator( QtGui.QRegExpValidator(QtCore.QRegExp("-?[0-9]*[.,]?[0-9]{%d}" % self.decimals()), self)) diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index c5df313d..f5d432b3 100644 --- a/flatcamGUI/ObjectUI.py +++ b/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) @@ -381,7 +381,7 @@ class GerberObjectUI(ObjectUI): ) passlabel.setMinimumWidth(90) self.iso_width_entry = FCSpinner() - self.iso_width_entry.setRange(1, 999) + self.iso_width_entry.set_range(1, 999) grid1.addWidget(passlabel, 5, 0) grid1.addWidget(self.iso_width_entry, 5, 1, 1, 2) @@ -394,7 +394,7 @@ class GerberObjectUI(ObjectUI): self.iso_overlap_entry = FCDoubleSpinner(suffix='%') self.iso_overlap_entry.set_precision(self.decimals) self.iso_overlap_entry.setWrapping(True) - self.iso_overlap_entry.setRange(0.0000, 99.9999) + self.iso_overlap_entry.set_range(0.0000, 99.9999) self.iso_overlap_entry.setSingleStep(0.1) grid1.addWidget(overlabel, 6, 0) grid1.addWidget(self.iso_overlap_entry, 6, 1, 1, 2) @@ -827,9 +827,9 @@ class ExcellonObjectUI(ObjectUI): self.cutz_entry.set_precision(self.decimals) if machinist_setting == 0: - self.cutz_entry.setRange(-9999.9999, -0.000001) + self.cutz_entry.set_range(-9999.9999, 0.0000) else: - self.cutz_entry.setRange(-9999.9999, 9999.9999) + self.cutz_entry.set_range(-9999.9999, 9999.9999) self.cutz_entry.setSingleStep(0.1) @@ -846,9 +846,9 @@ class ExcellonObjectUI(ObjectUI): self.travelz_entry.set_precision(self.decimals) if machinist_setting == 0: - self.travelz_entry.setRange(0.00001, 9999.9999) + self.travelz_entry.set_range(0.00001, 9999.9999) else: - self.travelz_entry.setRange(-9999.9999, 9999.9999) + self.travelz_entry.set_range(-9999.9999, 9999.9999) self.travelz_entry.setSingleStep(0.1) @@ -873,9 +873,9 @@ class ExcellonObjectUI(ObjectUI): self.toolchangez_entry.set_precision(self.decimals) if machinist_setting == 0: - self.toolchangez_entry.setRange(0.0, 9999.9999) + self.toolchangez_entry.set_range(0.0, 9999.9999) else: - self.toolchangez_entry.setRange(-9999.9999, 9999.9999) + self.toolchangez_entry.set_range(-9999.9999, 9999.9999) self.toolchangez_entry.setSingleStep(0.1) @@ -903,9 +903,9 @@ class ExcellonObjectUI(ObjectUI): self.eendz_entry.set_precision(self.decimals) if machinist_setting == 0: - self.eendz_entry.setRange(0.0, 9999.9999) + self.eendz_entry.set_range(0.0, 9999.9999) else: - self.eendz_entry.setRange(-9999.9999, 9999.9999) + self.eendz_entry.set_range(-9999.9999, 9999.9999) self.eendz_entry.setSingleStep(0.1) @@ -922,7 +922,7 @@ class ExcellonObjectUI(ObjectUI): grid1.addWidget(frlabel, 6, 0) self.feedrate_entry = FCDoubleSpinner() self.feedrate_entry.set_precision(self.decimals) - self.feedrate_entry.setRange(0.0, 9999.9999) + self.feedrate_entry.set_range(0.0, 9999.9999) self.feedrate_entry.setSingleStep(0.1) grid1.addWidget(self.feedrate_entry, 6, 1) @@ -939,7 +939,7 @@ class ExcellonObjectUI(ObjectUI): grid1.addWidget(self.feedrate_rapid_label, 7, 0) self.feedrate_rapid_entry = FCDoubleSpinner() self.feedrate_rapid_entry.set_precision(self.decimals) - self.feedrate_rapid_entry.setRange(0.0, 9999.9999) + self.feedrate_rapid_entry.set_range(0.0, 9999.9999) self.feedrate_rapid_entry.setSingleStep(0.1) grid1.addWidget(self.feedrate_rapid_entry, 7, 1) @@ -967,7 +967,7 @@ class ExcellonObjectUI(ObjectUI): ) self.dwelltime_entry = FCDoubleSpinner() self.dwelltime_entry.set_precision(self.decimals) - self.dwelltime_entry.setRange(0.0, 9999.9999) + self.dwelltime_entry.set_range(0.0, 9999.9999) self.dwelltime_entry.setSingleStep(0.1) self.dwelltime_entry.setToolTip( @@ -998,7 +998,7 @@ class ExcellonObjectUI(ObjectUI): grid1.addWidget(self.pdepth_label, 11, 0) self.pdepth_entry = FCDoubleSpinner() self.pdepth_entry.set_precision(self.decimals) - self.pdepth_entry.setRange(-9999.9999, 9999.9999) + self.pdepth_entry.set_range(-9999.9999, 9999.9999) self.pdepth_entry.setSingleStep(0.1) grid1.addWidget(self.pdepth_entry, 11, 1) @@ -1013,7 +1013,7 @@ class ExcellonObjectUI(ObjectUI): self.feedrate_probe_entry = FCDoubleSpinner() self.feedrate_probe_entry.set_precision(self.decimals) - self.feedrate_probe_entry.setRange(0.0, 9999.9999) + self.feedrate_probe_entry.set_range(0.0, 9999.9999) self.feedrate_probe_entry.setSingleStep(0.1) grid1.addWidget(self.feedrate_probe_label, 12, 0) @@ -1077,7 +1077,7 @@ class ExcellonObjectUI(ObjectUI): ) self.tooldia_entry = FCDoubleSpinner() self.tooldia_entry.set_precision(self.decimals) - self.tooldia_entry.setRange(0.0, 9999.9999) + self.tooldia_entry.set_range(0.0, 9999.9999) self.tooldia_entry.setSingleStep(0.1) self.generate_milling_button = QtWidgets.QPushButton(_('Mill Drills Geo')) @@ -1104,7 +1104,7 @@ class ExcellonObjectUI(ObjectUI): self.slot_tooldia_entry = FCDoubleSpinner() self.slot_tooldia_entry.set_precision(self.decimals) - self.slot_tooldia_entry.setRange(0.0, 9999.9999) + self.slot_tooldia_entry.set_range(0.0, 9999.9999) self.slot_tooldia_entry.setSingleStep(0.1) self.generate_milling_slots_button = QtWidgets.QPushButton(_('Mill Slots Geo')) @@ -1286,7 +1286,7 @@ class GeometryObjectUI(ObjectUI): ) self.tool_offset_entry = FCDoubleSpinner() self.tool_offset_entry.set_precision(self.decimals) - self.tool_offset_entry.setRange(-9999.9999, 9999.9999) + self.tool_offset_entry.set_range(-9999.9999, 9999.9999) self.tool_offset_entry.setSingleStep(0.1) self.grid1.addWidget(self.tool_offset_lbl, 0, 0) @@ -1298,7 +1298,7 @@ class GeometryObjectUI(ObjectUI): ) self.addtool_entry = FCDoubleSpinner() self.addtool_entry.set_precision(self.decimals) - self.addtool_entry.setRange(0.00001, 9999.9999) + self.addtool_entry.set_range(0.00001, 9999.9999) self.addtool_entry.setSingleStep(0.1) self.addtool_btn = QtWidgets.QPushButton(_('Add')) @@ -1379,7 +1379,7 @@ class GeometryObjectUI(ObjectUI): ) self.tipdia_entry = FCDoubleSpinner() self.tipdia_entry.set_precision(self.decimals) - self.tipdia_entry.setRange(0.00001, 9999.9999) + self.tipdia_entry.set_range(0.00001, 9999.9999) self.tipdia_entry.setSingleStep(0.1) self.grid3.addWidget(self.tipdialabel, 1, 0) @@ -1395,7 +1395,7 @@ class GeometryObjectUI(ObjectUI): ) self.tipangle_entry = FCDoubleSpinner() self.tipangle_entry.set_precision(self.decimals) - self.tipangle_entry.setRange(0.0, 180.0) + self.tipangle_entry.set_range(0.0, 180.0) self.tipangle_entry.setSingleStep(1) self.grid3.addWidget(self.tipanglelabel, 2, 0) @@ -1413,9 +1413,9 @@ class GeometryObjectUI(ObjectUI): self.cutz_entry.set_precision(self.decimals) if machinist_setting == 0: - self.cutz_entry.setRange(-9999.9999, -0.00001) + self.cutz_entry.set_range(-9999.9999, 0.0000) else: - self.cutz_entry.setRange(-9999.9999, 9999.9999) + self.cutz_entry.set_range(-9999.9999, 9999.9999) self.cutz_entry.setSingleStep(0.1) @@ -1435,7 +1435,7 @@ class GeometryObjectUI(ObjectUI): self.maxdepth_entry = FCDoubleSpinner() self.maxdepth_entry.set_precision(self.decimals) - self.maxdepth_entry.setRange(0, 9999.9999) + self.maxdepth_entry.set_range(0, 9999.9999) self.maxdepth_entry.setSingleStep(0.1) self.maxdepth_entry.setToolTip( @@ -1458,9 +1458,9 @@ class GeometryObjectUI(ObjectUI): self.travelz_entry.set_precision(self.decimals) if machinist_setting == 0: - self.travelz_entry.setRange(0.00001, 9999.9999) + self.travelz_entry.set_range(0.00001, 9999.9999) else: - self.travelz_entry.setRange(-9999.9999, 9999.9999) + self.travelz_entry.set_range(-9999.9999, 9999.9999) self.travelz_entry.setSingleStep(0.1) @@ -1486,9 +1486,9 @@ class GeometryObjectUI(ObjectUI): self.toolchangez_entry.set_precision(self.decimals) if machinist_setting == 0: - self.toolchangez_entry.setRange(0, 9999.9999) + self.toolchangez_entry.set_range(0, 9999.9999) else: - self.toolchangez_entry.setRange(-9999.9999, 9999.9999) + self.toolchangez_entry.set_range(-9999.9999, 9999.9999) self.toolchangez_entry.setSingleStep(0.1) @@ -1518,9 +1518,9 @@ class GeometryObjectUI(ObjectUI): self.gendz_entry.set_precision(self.decimals) if machinist_setting == 0: - self.gendz_entry.setRange(0, 9999.9999) + self.gendz_entry.set_range(0, 9999.9999) else: - self.gendz_entry.setRange(-9999.9999, 9999.9999) + self.gendz_entry.set_range(-9999.9999, 9999.9999) self.gendz_entry.setSingleStep(0.1) @@ -1535,7 +1535,7 @@ class GeometryObjectUI(ObjectUI): ) self.cncfeedrate_entry = FCDoubleSpinner() self.cncfeedrate_entry.set_precision(self.decimals) - self.cncfeedrate_entry.setRange(0, 9999.9999) + self.cncfeedrate_entry.set_range(0, 9999.9999) self.cncfeedrate_entry.setSingleStep(0.1) self.grid3.addWidget(frlabel, 10, 0) @@ -1550,7 +1550,7 @@ class GeometryObjectUI(ObjectUI): ) self.cncplunge_entry = FCDoubleSpinner() self.cncplunge_entry.set_precision(self.decimals) - self.cncplunge_entry.setRange(0, 9999.9999) + self.cncplunge_entry.set_range(0, 9999.9999) self.cncplunge_entry.setSingleStep(0.1) self.grid3.addWidget(frzlabel, 11, 0) @@ -1567,7 +1567,7 @@ class GeometryObjectUI(ObjectUI): ) self.cncfeedrate_rapid_entry = FCDoubleSpinner() self.cncfeedrate_rapid_entry.set_precision(self.decimals) - self.cncfeedrate_rapid_entry.setRange(0, 9999.9999) + self.cncfeedrate_rapid_entry.set_range(0, 9999.9999) self.cncfeedrate_rapid_entry.setSingleStep(0.1) self.grid3.addWidget(self.fr_rapidlabel, 12, 0) @@ -1627,7 +1627,7 @@ class GeometryObjectUI(ObjectUI): ) self.dwelltime_entry = FCDoubleSpinner() self.dwelltime_entry.set_precision(self.decimals) - self.dwelltime_entry.setRange(0, 9999.9999) + self.dwelltime_entry.set_range(0, 9999.9999) self.dwelltime_entry.setSingleStep(0.1) self.dwelltime_entry.setToolTip( @@ -1658,7 +1658,7 @@ class GeometryObjectUI(ObjectUI): ) self.pdepth_entry = FCDoubleSpinner() self.pdepth_entry.set_precision(self.decimals) - self.pdepth_entry.setRange(-9999.9999, 9999.9999) + self.pdepth_entry.set_range(-9999.9999, 9999.9999) self.pdepth_entry.setSingleStep(0.1) self.grid3.addWidget(self.pdepth_label, 17, 0) @@ -1674,7 +1674,7 @@ class GeometryObjectUI(ObjectUI): ) self.feedrate_probe_entry = FCDoubleSpinner() self.feedrate_probe_entry.set_precision(self.decimals) - self.feedrate_probe_entry.setRange(0.0, 9999.9999) + self.feedrate_probe_entry.set_range(0.0, 9999.9999) self.feedrate_probe_entry.setSingleStep(0.1) self.grid3.addWidget(self.feedrate_probe_label, 18, 0) diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index 4e1c1c28..cb033589 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/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) diff --git a/flatcamTools/ToolNonCopperClear.py b/flatcamTools/ToolNonCopperClear.py index 07c99879..a5f874b4 100644 --- a/flatcamTools/ToolNonCopperClear.py +++ b/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() diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 1d04def1..20756dbe 100644 --- a/flatcamTools/ToolPaint.py +++ b/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): + + # 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 - 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) + # 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" - 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) + pol_nr += 1 + disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100])) + # log.debug("Polygons cleared: %d" % pol_nr) - 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)) + 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