diff --git a/CHANGELOG.md b/CHANGELOG.md
index d2adb163..b7767b06 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,10 @@ CHANGELOG for FlatCAM beta
2.05.2020
+- working on a new feature: adding interdiction area for Gcode generation. They will be added in the Geometry Object
+
+2.05.2020
+
- changed the icons for the grid snap in the status bar
- moved some of the methods from FlatCAMApp.App to flatcamGUI.FlatCAMGUI class
- fixed bug in Gerber Editor in which the units conversion wasn't calculated correct
@@ -18,6 +22,7 @@ CHANGELOG for FlatCAM beta
- modified the Panelize Tool to optimize the output from Cutout Tool such that there are no longer overlapping cuts
- some string corrections
- updated the Italian translation done by user @pcb-hobbyst
+- RELEASE 8.992
01.05.2020
diff --git a/FlatCAMApp.py b/FlatCAMApp.py
index 92d725a3..197e35ab 100644
--- a/FlatCAMApp.py
+++ b/FlatCAMApp.py
@@ -162,8 +162,8 @@ class App(QtCore.QObject):
# ###############################################################################################################
# ################################### Version and VERSION DATE ##################################################
# ###############################################################################################################
- version = 8.992
- version_date = "2020/05/01"
+ version = 8.993
+ version_date = "2020/08/01"
beta = True
engine = '3D'
diff --git a/defaults.py b/defaults.py
index 70863252..ffd84874 100644
--- a/defaults.py
+++ b/defaults.py
@@ -341,6 +341,10 @@ class FlatCAMDefaults:
"geometry_feedrate_probe": 75,
"geometry_segx": 0.0,
"geometry_segy": 0.0,
+ "geometry_area_exclusion": False,
+ "geometry_area_shape": "polygon",
+ "geometry_area_strategy": "over",
+ "geometry_area_overz": 1.0,
# Geometry Editor
"geometry_editor_sel_limit": 30,
diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py
index c1b368b4..b6d20c35 100644
--- a/flatcamGUI/FlatCAMGUI.py
+++ b/flatcamGUI/FlatCAMGUI.py
@@ -4146,6 +4146,29 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
# Jump to coords
if key == QtCore.Qt.Key_J:
self.app.on_jump_to()
+ elif self.app.call_source == 'geometry':
+ if modifiers == QtCore.Qt.ControlModifier:
+ pass
+ elif modifiers == QtCore.Qt.AltModifier:
+ pass
+ elif modifiers == QtCore.Qt.ShiftModifier:
+ pass
+ # NO MODIFIER
+ elif modifiers == QtCore.Qt.NoModifier:
+ if key == QtCore.Qt.Key_Escape or key == 'Escape':
+ sel_obj = self.app.collection.get_active()
+ assert sel_obj.kind == 'geometry', "Expected a Geometry Object, got %s" % type(sel_obj)
+
+ sel_obj.area_disconnect()
+ return
+
+ if key == QtCore.Qt.Key_G or key == 'G':
+ self.app.ui.grid_snap_btn.trigger()
+ return
+
+ # Jump to coords
+ if key == QtCore.Qt.Key_J or key == 'J':
+ self.app.on_jump_to()
def createPopupMenu(self):
menu = super().createPopupMenu()
diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py
index 4004048d..c5dacb42 100644
--- a/flatcamGUI/ObjectUI.py
+++ b/flatcamGUI/ObjectUI.py
@@ -2022,14 +2022,94 @@ class GeometryObjectUI(ObjectUI):
grid4.addWidget(pp_label, 11, 0)
grid4.addWidget(self.pp_geometry_name_cb, 11, 1)
- grid4.addWidget(QtWidgets.QLabel(''), 12, 0, 1, 2)
+ # grid4.addWidget(QtWidgets.QLabel(''), 12, 0, 1, 2)
+
+ # Exclusion Areas
+ self.exclusion_cb = FCCheckBox('%s:' % _("Exclusion areas"))
+ self.exclusion_cb.setToolTip(
+ _(
+ "Include exclusion areas.\n"
+ "In those areas the travel of the tools\n"
+ "is forbidden."
+ )
+ )
+ grid4.addWidget(self.exclusion_cb, 12, 0, 1, 2)
+
+ # ------------------------------------------------------------------------------------------------------------
+ # ------------------------- EXCLUSION AREAS ------------------------------------------------------------------
+ # ------------------------------------------------------------------------------------------------------------
+ self.exclusion_frame = QtWidgets.QFrame()
+ self.exclusion_frame.setContentsMargins(0, 0, 0, 0)
+ grid4.addWidget(self.exclusion_frame, 14, 0, 1, 2)
+
+ self.exclusion_box = QtWidgets.QVBoxLayout()
+ self.exclusion_box.setContentsMargins(0, 0, 0, 0)
+ self.exclusion_frame.setLayout(self.exclusion_box)
+
+ h_lay = QtWidgets.QHBoxLayout()
+ self.exclusion_box.addLayout(h_lay)
+
+ # Button Add Area
+ self.add_area_button = QtWidgets.QPushButton(_('Add area'))
+ self.add_area_button.setToolTip(_("Add an Exclusion Area."))
+ h_lay.addWidget(self.add_area_button)
+
+ # Button Delete Area
+ self.delete_area_button = QtWidgets.QPushButton(_('Clear areas'))
+ self.delete_area_button.setToolTip(_("Delete all exclusion areas."))
+ h_lay.addWidget(self.delete_area_button)
+
+ grid_l = QtWidgets.QGridLayout()
+ grid_l.setColumnStretch(0, 0)
+ grid_l.setColumnStretch(1, 1)
+ self.exclusion_box.addLayout(grid_l)
+
+ # Area Selection shape
+ self.area_shape_label = QtWidgets.QLabel('%s:' % _("Shape"))
+ self.area_shape_label.setToolTip(
+ _("The kind of selection shape used for area selection.")
+ )
+
+ self.area_shape_radio = RadioSet([{'label': _("Square"), 'value': 'square'},
+ {'label': _("Polygon"), 'value': 'polygon'}])
+
+ grid_l.addWidget(self.area_shape_label, 0, 0)
+ grid_l.addWidget(self.area_shape_radio, 0, 1)
+
+ # Chose Strategy
+ self.strategy_label = FCLabel('%s:' % _("Strategy"))
+ self.strategy_label.setToolTip(_("The strategy followed when encountering an exclusion area.\n"
+ "Can be:\n"
+ "- Over -> when encountering the area, the tool will go to a set height\n"
+ "- Around -> will avoid the exclusion area by going around the area"))
+ self.strategy_radio = RadioSet([{'label': _('Over'), 'value': 'over'},
+ {'label': _('Around'), 'value': 'around'}])
+
+ grid_l.addWidget(self.strategy_label, 1, 0)
+ grid_l.addWidget(self.strategy_radio, 1, 1)
+
+ # Over Z
+ self.over_z_label = FCLabel('%s:' % _("Over Z"))
+ self.over_z_label.setToolTip(_("The height Z to which the tool will rise in order to avoid\n"
+ "an interdiction area."))
+ self.over_z_entry = FCDoubleSpinner()
+ self.over_z_entry.set_range(0.000, 9999.9999)
+ self.over_z_entry.set_precision(self.decimals)
+
+ grid_l.addWidget(self.over_z_label, 2, 0)
+ grid_l.addWidget(self.over_z_entry, 2, 1)
+
+ # -------------------------- EXCLUSION AREAS END -------------------------------------------------------------
+ # ------------------------------------------------------------------------------------------------------------
+ self.ois_exclusion_geo = OptionalInputSection(self.exclusion_cb, [self.exclusion_frame])
+
warning_lbl = QtWidgets.QLabel(
_(
"Add / Select at least one tool in the tool-table.\n"
"Click the # header to select all, or Ctrl + LMB\n"
"for custom selection of tools."
))
- grid4.addWidget(warning_lbl, 13, 0, 1, 2)
+ grid4.addWidget(warning_lbl, 15, 0, 1, 2)
# Button
self.generate_cnc_button = QtWidgets.QPushButton(_('Generate CNCJob object'))
@@ -2042,9 +2122,9 @@ class GeometryObjectUI(ObjectUI):
font-weight: bold;
}
""")
- grid4.addWidget(self.generate_cnc_button, 14, 0, 1, 2)
+ grid4.addWidget(self.generate_cnc_button, 17, 0, 1, 2)
- grid4.addWidget(QtWidgets.QLabel(''), 15, 0, 1, 2)
+ grid4.addWidget(QtWidgets.QLabel(''), 19, 0, 1, 2)
# ##############
# Paint area ##
@@ -2053,7 +2133,7 @@ class GeometryObjectUI(ObjectUI):
self.tools_label.setToolTip(
_("Launch Paint Tool in Tools Tab.")
)
- grid4.addWidget(self.tools_label, 16, 0, 1, 2)
+ grid4.addWidget(self.tools_label, 20, 0, 1, 2)
# Paint Button
self.paint_tool_button = QtWidgets.QPushButton(_('Paint Tool'))
@@ -2071,7 +2151,7 @@ class GeometryObjectUI(ObjectUI):
font-weight: bold;
}
""")
- grid4.addWidget(self.paint_tool_button, 17, 0, 1, 2)
+ grid4.addWidget(self.paint_tool_button, 22, 0, 1, 2)
# NCC Tool
self.generate_ncc_button = QtWidgets.QPushButton(_('NCC Tool'))
@@ -2085,7 +2165,7 @@ class GeometryObjectUI(ObjectUI):
font-weight: bold;
}
""")
- grid4.addWidget(self.generate_ncc_button, 18, 0, 1, 2)
+ grid4.addWidget(self.generate_ncc_button, 24, 0, 1, 2)
class CNCObjectUI(ObjectUI):
diff --git a/flatcamGUI/preferences/PreferencesUIManager.py b/flatcamGUI/preferences/PreferencesUIManager.py
index a8a9eab3..14fa8762 100644
--- a/flatcamGUI/preferences/PreferencesUIManager.py
+++ b/flatcamGUI/preferences/PreferencesUIManager.py
@@ -303,6 +303,10 @@ class PreferencesUIManager:
"geometry_f_plunge": self.ui.geometry_defaults_form.geometry_adv_opt_group.fplunge_cb,
"geometry_segx": self.ui.geometry_defaults_form.geometry_adv_opt_group.segx_entry,
"geometry_segy": self.ui.geometry_defaults_form.geometry_adv_opt_group.segy_entry,
+ "geometry_area_exclusion": self.ui.geometry_defaults_form.geometry_adv_opt_group.exclusion_cb,
+ "geometry_area_shape": self.ui.geometry_defaults_form.geometry_adv_opt_group.area_shape_radio,
+ "geometry_area_strategy": self.ui.geometry_defaults_form.geometry_adv_opt_group.strategy_radio,
+ "geometry_area_overz": self.ui.geometry_defaults_form.geometry_adv_opt_group.over_z_entry,
# Geometry Editor
"geometry_editor_sel_limit": self.ui.geometry_defaults_form.geometry_editor_group.sel_limit_entry,
diff --git a/flatcamGUI/preferences/geometry/GeometryAdvOptPrefGroupUI.py b/flatcamGUI/preferences/geometry/GeometryAdvOptPrefGroupUI.py
index 53c344d3..7ade9b90 100644
--- a/flatcamGUI/preferences/geometry/GeometryAdvOptPrefGroupUI.py
+++ b/flatcamGUI/preferences/geometry/GeometryAdvOptPrefGroupUI.py
@@ -1,7 +1,7 @@
from PyQt5 import QtWidgets
from PyQt5.QtCore import QSettings
-from flatcamGUI.GUIElements import FCEntry, FloatEntry, FCDoubleSpinner, FCCheckBox, RadioSet
+from flatcamGUI.GUIElements import FCEntry, FloatEntry, FCDoubleSpinner, FCCheckBox, RadioSet, FCLabel
from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
import gettext
@@ -186,4 +186,61 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
grid1.addWidget(segy_label, 11, 0)
grid1.addWidget(self.segy_entry, 11, 1)
+ # -----------------------------
+ # --- Area Exclusion ----------
+ # -----------------------------
+ self.adv_label = QtWidgets.QLabel('%s:' % _('Area Exclusion'))
+ self.adv_label.setToolTip(
+ _("Area exclusion parameters.\n"
+ "Those parameters are available only for\n"
+ "Advanced App. Level.")
+ )
+ grid1.addWidget(self.adv_label, 12, 0, 1, 2)
+
+ # Exclusion Area CB
+ self.exclusion_cb = FCCheckBox('%s:' % _("Exclusion areas"))
+ self.exclusion_cb.setToolTip(
+ _(
+ "Include exclusion areas.\n"
+ "In those areas the travel of the tools\n"
+ "is forbidden."
+ )
+ )
+ grid1.addWidget(self.exclusion_cb, 13, 0, 1, 2)
+
+ # Area Selection shape
+ self.area_shape_label = QtWidgets.QLabel('%s:' % _("Shape"))
+ self.area_shape_label.setToolTip(
+ _("The kind of selection shape used for area selection.")
+ )
+
+ self.area_shape_radio = RadioSet([{'label': _("Square"), 'value': 'square'},
+ {'label': _("Polygon"), 'value': 'polygon'}])
+
+ grid1.addWidget(self.area_shape_label, 14, 0)
+ grid1.addWidget(self.area_shape_radio, 14, 1)
+
+ # Chose Strategy
+ self.strategy_label = FCLabel('%s:' % _("Strategy"))
+ self.strategy_label.setToolTip(_("The strategy followed when encountering an exclusion area.\n"
+ "Can be:\n"
+ "- Over -> when encountering the area, the tool will go to a set height\n"
+ "- Around -> will avoid the exclusion area by going around the area"))
+ self.strategy_radio = RadioSet([{'label': _('Over'), 'value': 'over'},
+ {'label': _('Around'), 'value': 'around'}])
+
+ grid1.addWidget(self.strategy_label, 15, 0)
+ grid1.addWidget(self.strategy_radio, 15, 1)
+
+ # Over Z
+ self.over_z_label = FCLabel('%s:' % _("Over Z"))
+ self.over_z_label.setToolTip(_("The height Z to which the tool will rise in order to avoid\n"
+ "an interdiction area."))
+ self.over_z_entry = FCDoubleSpinner()
+ self.over_z_entry.set_range(0.000, 9999.9999)
+ self.over_z_entry.set_precision(self.decimals)
+
+ grid1.addWidget(self.over_z_label, 18, 0)
+ grid1.addWidget(self.over_z_entry, 18, 1)
+
self.layout.addStretch()
diff --git a/flatcamObjects/FlatCAMGeometry.py b/flatcamObjects/FlatCAMGeometry.py
index cf70054c..f4d0554f 100644
--- a/flatcamObjects/FlatCAMGeometry.py
+++ b/flatcamObjects/FlatCAMGeometry.py
@@ -16,6 +16,7 @@ import shapely.affinity as affinity
from camlib import Geometry
from flatcamObjects.FlatCAMObj import *
+import FlatCAMTool
import ezdxf
import math
@@ -68,6 +69,10 @@ class GeometryObject(FlatCAMObj, Geometry):
"extracut_length": 0.1,
"endz": 2.0,
"endxy": '',
+ "area_exclusion": False,
+ "area_shape": "polygon",
+ "area_strategy": "over",
+ "area_overz": 1.0,
"startz": None,
"toolchange": False,
@@ -146,6 +151,18 @@ class GeometryObject(FlatCAMObj, Geometry):
self.param_fields = {}
+ # Event signals disconnect id holders
+ self.mr = None
+ self.mm = None
+ self.kp = None
+
+ # variables to be used in area exclusion
+ self.cursor_pos = (0, 0)
+ self.exclusion_areas_list = []
+ self.first_click = False
+ self.points = []
+ self.poly_drawn = False
+
# Attributes to be included in serialization
# Always append to it because it carries contents
# from predecessors.
@@ -344,7 +361,11 @@ class GeometryObject(FlatCAMObj, Geometry):
"toolchangez": self.ui.toolchangez_entry,
"endz": self.ui.endz_entry,
"endxy": self.ui.endxy_entry,
- "cnctooldia": self.ui.addtool_entry
+ "cnctooldia": self.ui.addtool_entry,
+ "area_exclusion": self.ui.exclusion_cb,
+ "area_shape":self.ui.area_shape_radio,
+ "area_strategy": self.ui.strategy_radio,
+ "area_overz": self.ui.over_z_entry,
})
self.param_fields.update({
@@ -402,6 +423,10 @@ class GeometryObject(FlatCAMObj, Geometry):
"toolchangez": None,
"endz": None,
"endxy": '',
+ "area_exclusion": None,
+ "area_shape": None,
+ "area_strategy": None,
+ "area_overz": None,
"spindlespeed": 0,
"toolchangexy": None,
"startz": None
@@ -522,6 +547,9 @@ class GeometryObject(FlatCAMObj, Geometry):
self.ui.apply_param_to_all.clicked.connect(self.on_apply_param_to_all_clicked)
self.ui.cutz_entry.returnPressed.connect(self.on_cut_z_changed)
+ self.ui.add_area_button.clicked.connect(self.on_add_area_click)
+ self.ui.delete_area_button.clicked.connect(self.on_clear_area_click)
+
def on_cut_z_changed(self):
self.old_cutz = self.ui.cutz_entry.get_value()
@@ -2545,6 +2573,219 @@ class GeometryObject(FlatCAMObj, Geometry):
self.ui.plot_cb.setChecked(True)
self.ui_connect()
+ def on_add_area_click(self):
+ self.app.inform.emit('[WARNING_NOTCL] %s' % _("Click the start point of the area."))
+ self.app.call_source = 'geometry'
+
+ if self.app.is_legacy is False:
+ self.app.plotcanvas.graph_event_disconnect('mouse_press', self.app.on_mouse_click_over_plot)
+ self.app.plotcanvas.graph_event_disconnect('mouse_move', self.app.on_mouse_move_over_plot)
+ self.app.plotcanvas.graph_event_disconnect('mouse_release', self.app.on_mouse_click_release_over_plot)
+ else:
+ self.app.plotcanvas.graph_event_disconnect(self.app.mp)
+ self.app.plotcanvas.graph_event_disconnect(self.app.mm)
+ self.app.plotcanvas.graph_event_disconnect(self.app.mr)
+
+ self.mr = self.app.plotcanvas.graph_event_connect('mouse_release', self.on_mouse_release)
+ self.mm = self.app.plotcanvas.graph_event_connect('mouse_move', self.on_mouse_move)
+ # self.kp = self.app.plotcanvas.graph_event_connect('key_press', self.on_key_press)
+
+ # To be called after clicking on the plot.
+ def on_mouse_release(self, event):
+ if self.app.is_legacy is False:
+ event_pos = event.pos
+ # event_is_dragging = event.is_dragging
+ right_button = 2
+ else:
+ event_pos = (event.xdata, event.ydata)
+ # event_is_dragging = self.app.plotcanvas.is_dragging
+ right_button = 3
+
+ event_pos = self.app.plotcanvas.translate_coords(event_pos)
+ if self.app.grid_status():
+ curr_pos = self.app.geo_editor.snap(event_pos[0], event_pos[1])
+ else:
+ curr_pos = (event_pos[0], event_pos[1])
+
+ x1, y1 = curr_pos[0], curr_pos[1]
+
+ shape_type = self.ui.area_shape_radio.get_value()
+
+ # do clear area only for left mouse clicks
+ if event.button == 1:
+ if shape_type == "square":
+ if self.first_click is False:
+ self.first_click = True
+ self.app.inform.emit('[WARNING_NOTCL] %s' % _("Click the end point of the area."))
+
+ self.cursor_pos = self.app.plotcanvas.translate_coords(event_pos)
+ if self.app.grid_status():
+ self.cursor_pos = self.app.geo_editor.snap(event_pos[0], event_pos[1])
+ else:
+ self.app.inform.emit(_("Zone added. Click to start adding next zone or right click to finish."))
+ self.app.delete_selection_shape()
+
+ x0, y0 = self.cursor_pos[0], self.cursor_pos[1]
+
+ pt1 = (x0, y0)
+ pt2 = (x1, y0)
+ pt3 = (x1, y1)
+ pt4 = (x0, y1)
+
+ new_rectangle = Polygon([pt1, pt2, pt3, pt4])
+ self.exclusion_areas_list.append(new_rectangle)
+
+ # add a temporary shape on canvas
+ FlatCAMTool.FlatCAMTool.draw_tool_selection_shape(self, old_coords=(x0, y0), coords=(x1, y1))
+
+ self.first_click = False
+ return
+ else:
+ self.points.append((x1, y1))
+
+ if len(self.points) > 1:
+ self.poly_drawn = True
+ self.app.inform.emit(_("Click on next Point or click right mouse button to complete ..."))
+
+ return ""
+ elif event.button == right_button and self.mouse_is_dragging is False:
+
+ shape_type = self.ui.area_shape_radio.get_value()
+
+ if shape_type == "square":
+ self.first_click = False
+ else:
+ # if we finish to add a polygon
+ if self.poly_drawn is True:
+ try:
+ # try to add the point where we last clicked if it is not already in the self.points
+ last_pt = (x1, y1)
+ if last_pt != self.points[-1]:
+ self.points.append(last_pt)
+ except IndexError:
+ pass
+
+ # we need to add a Polygon and a Polygon can be made only from at least 3 points
+ if len(self.points) > 2:
+ FlatCAMTool.FlatCAMTool.delete_moving_selection_shape(self)
+ pol = Polygon(self.points)
+ # do not add invalid polygons even if they are drawn by utility geometry
+ if pol.is_valid:
+ self.exclusion_areas_list.append(pol)
+ FlatCAMTool.FlatCAMTool.draw_selection_shape_polygon(self, points=self.points)
+ self.app.inform.emit(
+ _("Zone added. Click to start adding next zone or right click to finish."))
+
+ self.points = []
+ self.poly_drawn = False
+ return
+
+ FlatCAMTool.FlatCAMTool.delete_tool_selection_shape(self)
+
+ if self.app.is_legacy is False:
+ self.app.plotcanvas.graph_event_disconnect('mouse_release', self.on_mouse_release)
+ self.app.plotcanvas.graph_event_disconnect('mouse_move', self.on_mouse_move)
+ # self.app.plotcanvas.graph_event_disconnect('key_press', self.on_key_press)
+ else:
+ self.app.plotcanvas.graph_event_disconnect(self.mr)
+ self.app.plotcanvas.graph_event_disconnect(self.mm)
+ # self.app.plotcanvas.graph_event_disconnect(self.kp)
+
+ self.app.mp = self.app.plotcanvas.graph_event_connect('mouse_press',
+ self.app.on_mouse_click_over_plot)
+ self.app.mm = self.app.plotcanvas.graph_event_connect('mouse_move',
+ self.app.on_mouse_move_over_plot)
+ self.app.mr = self.app.plotcanvas.graph_event_connect('mouse_release',
+ self.app.on_mouse_click_release_over_plot)
+
+ self.app.call_source = 'app'
+
+ if len(self.exclusion_areas_list) == 0:
+ return
+
+ def area_disconnect(self):
+ if self.app.is_legacy is False:
+ self.app.plotcanvas.graph_event_disconnect('mouse_release', self.on_mouse_release)
+ self.app.plotcanvas.graph_event_disconnect('mouse_move', self.on_mouse_move)
+ else:
+ self.app.plotcanvas.graph_event_disconnect(self.mr)
+ self.app.plotcanvas.graph_event_disconnect(self.mm)
+ self.app.plotcanvas.graph_event_disconnect(self.kp)
+
+ self.app.mp = self.app.plotcanvas.graph_event_connect('mouse_press',
+ self.app.on_mouse_click_over_plot)
+ self.app.mm = self.app.plotcanvas.graph_event_connect('mouse_move',
+ self.app.on_mouse_move_over_plot)
+ self.app.mr = self.app.plotcanvas.graph_event_connect('mouse_release',
+ self.app.on_mouse_click_release_over_plot)
+ self.points = []
+ self.poly_drawn = False
+ self.exclusion_areas_list = []
+
+ FlatCAMTool.FlatCAMTool.delete_moving_selection_shape(self)
+ FlatCAMTool.FlatCAMTool.delete_tool_selection_shape(self)
+
+ self.app.call_source = "app"
+ self.app.inform.emit("[WARNING_NOTCL] %s" % _("Cancelled. Area exclusion drawing was interrupted."))
+
+ # called on mouse move
+ def on_mouse_move(self, event):
+ shape_type = self.ui.area_shape_radio.get_value()
+
+ if self.app.is_legacy is False:
+ event_pos = event.pos
+ event_is_dragging = event.is_dragging
+ # right_button = 2
+ else:
+ event_pos = (event.xdata, event.ydata)
+ event_is_dragging = self.app.plotcanvas.is_dragging
+ # right_button = 3
+
+ curr_pos = self.app.plotcanvas.translate_coords(event_pos)
+
+ # detect mouse dragging motion
+ if event_is_dragging is True:
+ self.mouse_is_dragging = True
+ else:
+ self.mouse_is_dragging = False
+
+ # update the cursor position
+ if self.app.grid_status():
+ # Update cursor
+ curr_pos = self.app.geo_editor.snap(curr_pos[0], curr_pos[1])
+
+ self.app.app_cursor.set_data(np.asarray([(curr_pos[0], curr_pos[1])]),
+ symbol='++', edge_color=self.app.cursor_color_3D,
+ edge_width=self.app.defaults["global_cursor_width"],
+ size=self.app.defaults["global_cursor_size"])
+
+ # update the positions on status bar
+ self.app.ui.position_label.setText(" X: %.4f "
+ "Y: %.4f" % (curr_pos[0], curr_pos[1]))
+ if self.cursor_pos is None:
+ self.cursor_pos = (0, 0)
+
+ self.app.dx = curr_pos[0] - float(self.cursor_pos[0])
+ self.app.dy = curr_pos[1] - float(self.cursor_pos[1])
+ self.app.ui.rel_position_label.setText("Dx: %.4f Dy: "
+ "%.4f " % (self.app.dx, self.app.dy))
+
+ # draw the utility geometry
+ if shape_type == "square":
+ if self.first_click:
+ self.app.delete_selection_shape()
+ self.app.draw_moving_selection_shape(old_coords=(self.cursor_pos[0], self.cursor_pos[1]),
+ coords=(curr_pos[0], curr_pos[1]))
+ else:
+ FlatCAMTool.FlatCAMTool.delete_moving_selection_shape(self)
+ FlatCAMTool.FlatCAMTool.draw_moving_selection_shape_poly(
+ self, points=self.points, data=(curr_pos[0], curr_pos[1]))
+
+ def on_clear_area_click(self):
+ self.exclusion_areas_list = []
+ FlatCAMTool.FlatCAMTool.delete_moving_selection_shape(self)
+ self.app.delete_selection_shape()
+
@staticmethod
def merge(geo_list, geo_final, multigeo=None):
"""
diff --git a/flatcamParsers/ParseHPGL2.py b/flatcamParsers/ParseHPGL2.py
index b612e7bb..a90a3184 100644
--- a/flatcamParsers/ParseHPGL2.py
+++ b/flatcamParsers/ParseHPGL2.py
@@ -73,6 +73,10 @@ class HPGL2:
"toolchangez": self.app.defaults["geometry_toolchangez"],
"endz": self.app.defaults["geometry_endz"],
"endxy": self.app.defaults["geometry_endxy"],
+ "area_exclusion": self.app.defaults["geometry_area_exclusion"],
+ "area_shape": self.app.defaults["geometry_area_shape"],
+ "area_strategy": self.app.defaults["geometry_area_strategy"],
+ "area_overz": self.app.defaults["geometry_area_overz"],
"spindlespeed": self.app.defaults["geometry_spindlespeed"],
"toolchangexy": self.app.defaults["geometry_toolchangexy"],
diff --git a/flatcamTools/ToolCutOut.py b/flatcamTools/ToolCutOut.py
index 31f51b31..67295b90 100644
--- a/flatcamTools/ToolCutOut.py
+++ b/flatcamTools/ToolCutOut.py
@@ -479,6 +479,10 @@ class CutOut(FlatCAMTool):
"toolchangez": float(self.app.defaults["geometry_toolchangez"]),
"startz": self.app.defaults["geometry_startz"],
"endz": float(self.app.defaults["geometry_endz"]),
+ "area_exclusion": self.app.defaults["geometry_area_exclusion"],
+ "area_shape": self.app.defaults["geometry_area_shape"],
+ "area_strategy": self.app.defaults["geometry_area_strategy"],
+ "area_overz": float(self.app.defaults["geometry_area_overz"]),
# NCC
"tools_nccoperation": self.app.defaults["tools_nccoperation"],
diff --git a/flatcamTools/ToolNCC.py b/flatcamTools/ToolNCC.py
index a5f93274..01b879b9 100644
--- a/flatcamTools/ToolNCC.py
+++ b/flatcamTools/ToolNCC.py
@@ -1039,6 +1039,11 @@ class NonCopperClear(FlatCAMTool, Gerber):
"toolchangexy": self.app.defaults["geometry_toolchangexy"],
"startz": self.app.defaults["geometry_startz"],
+ "area_exclusion": self.app.defaults["geometry_area_exclusion"],
+ "area_shape": self.app.defaults["geometry_area_shape"],
+ "area_strategy": self.app.defaults["geometry_area_strategy"],
+ "area_overz": float(self.app.defaults["geometry_area_overz"]),
+
"tools_nccoperation": self.app.defaults["tools_nccoperation"],
"tools_nccmargin": self.app.defaults["tools_nccmargin"],
"tools_nccmethod": self.app.defaults["tools_nccmethod"],
diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py
index 52623ffb..4dda2d36 100644
--- a/flatcamTools/ToolPaint.py
+++ b/flatcamTools/ToolPaint.py
@@ -1013,6 +1013,11 @@ class ToolPaint(FlatCAMTool, Gerber):
"toolchangexy": self.app.defaults["geometry_toolchangexy"],
"startz": self.app.defaults["geometry_startz"],
+ "area_exclusion": self.app.defaults["geometry_area_exclusion"],
+ "area_shape": self.app.defaults["geometry_area_shape"],
+ "area_strategy": self.app.defaults["geometry_area_strategy"],
+ "area_overz": float(self.app.defaults["geometry_area_overz"]),
+
"tooldia": self.app.defaults["tools_painttooldia"],
"tools_paintmargin": self.app.defaults["tools_paintmargin"],
"tools_paintmethod": self.app.defaults["tools_paintmethod"],
diff --git a/locale/en/LC_MESSAGES/strings.po b/locale/en/LC_MESSAGES/strings.po
index 83a3b193..c3450c9f 100644
--- a/locale/en/LC_MESSAGES/strings.po
+++ b/locale/en/LC_MESSAGES/strings.po
@@ -17916,7 +17916,7 @@ msgstr "No Geometry name in args. Provide a name and try again."
#~ msgid ""
#~ "- 'Itself' - the non copper clearing extent\n"
#~ "is based on the object that is copper cleared.\n"
-#~ " - 'Area Selection' - left mouse click to start selection of the area to "
+#~ "- 'Area Selection' - left mouse click to start selection of the area to "
#~ "be painted.\n"
#~ "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple "
#~ "areas.\n"
@@ -17925,7 +17925,7 @@ msgstr "No Geometry name in args. Provide a name and try again."
#~ msgstr ""
#~ "- 'Itself' - the non copper clearing extent\n"
#~ "is based on the object that is copper cleared.\n"
-#~ " - 'Area Selection' - left mouse click to start selection of the area to "
+#~ "- 'Area Selection' - left mouse click to start selection of the area to "
#~ "be painted.\n"
#~ "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple "
#~ "areas.\n"
diff --git a/locale/es/LC_MESSAGES/strings.po b/locale/es/LC_MESSAGES/strings.po
index 21152ba5..8597d4e5 100644
--- a/locale/es/LC_MESSAGES/strings.po
+++ b/locale/es/LC_MESSAGES/strings.po
@@ -18196,7 +18196,7 @@ msgstr ""
#~ msgid ""
#~ "- 'Itself' - the non copper clearing extent\n"
#~ "is based on the object that is copper cleared.\n"
-#~ " - 'Area Selection' - left mouse click to start selection of the area to "
+#~ "- 'Area Selection' - left mouse click to start selection of the area to "
#~ "be painted.\n"
#~ "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple "
#~ "areas.\n"
diff --git a/locale/fr/LC_MESSAGES/strings.po b/locale/fr/LC_MESSAGES/strings.po
index 82d6a131..c8beb8cd 100644
--- a/locale/fr/LC_MESSAGES/strings.po
+++ b/locale/fr/LC_MESSAGES/strings.po
@@ -11051,7 +11051,7 @@ msgid ""
"Selection of area to be processed.\n"
"- 'Itself' - the processing extent is based on the object that is "
"processed.\n"
-" - 'Area Selection' - left mouse click to start selection of the area to be "
+"- 'Area Selection' - left mouse click to start selection of the area to be "
"processed.\n"
"- 'Reference Object' - will process the area specified by another object."
msgstr ""
@@ -18201,7 +18201,7 @@ msgstr ""
#~ msgid ""
#~ "- 'Itself' - the non copper clearing extent\n"
#~ "is based on the object that is copper cleared.\n"
-#~ " - 'Area Selection' - left mouse click to start selection of the area to "
+#~ "- 'Area Selection' - left mouse click to start selection of the area to "
#~ "be painted.\n"
#~ "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple "
#~ "areas.\n"
diff --git a/locale/hu/LC_MESSAGES/strings.po b/locale/hu/LC_MESSAGES/strings.po
index 950d8d23..e8e3e651 100644
--- a/locale/hu/LC_MESSAGES/strings.po
+++ b/locale/hu/LC_MESSAGES/strings.po
@@ -10875,7 +10875,7 @@ msgid ""
"Selection of area to be processed.\n"
"- 'Itself' - the processing extent is based on the object that is "
"processed.\n"
-" - 'Area Selection' - left mouse click to start selection of the area to be "
+"- 'Area Selection' - left mouse click to start selection of the area to be "
"processed.\n"
"- 'Reference Object' - will process the area specified by another object."
msgstr ""
@@ -17881,7 +17881,7 @@ msgstr "No Geometry name in args. Provide a name and try again."
#~ msgid ""
#~ "- 'Itself' - the non copper clearing extent\n"
#~ "is based on the object that is copper cleared.\n"
-#~ " - 'Area Selection' - left mouse click to start selection of the area to "
+#~ "- 'Area Selection' - left mouse click to start selection of the area to "
#~ "be painted.\n"
#~ "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple "
#~ "areas.\n"
@@ -17890,7 +17890,7 @@ msgstr "No Geometry name in args. Provide a name and try again."
#~ msgstr ""
#~ "- 'Itself' - the non copper clearing extent\n"
#~ "is based on the object that is copper cleared.\n"
-#~ " - 'Area Selection' - left mouse click to start selection of the area to "
+#~ "- 'Area Selection' - left mouse click to start selection of the area to "
#~ "be painted.\n"
#~ "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple "
#~ "areas.\n"
diff --git a/locale/it/LC_MESSAGES/strings.po b/locale/it/LC_MESSAGES/strings.po
index 4ba96778..5df23b50 100644
--- a/locale/it/LC_MESSAGES/strings.po
+++ b/locale/it/LC_MESSAGES/strings.po
@@ -13154,7 +13154,7 @@ msgstr ""
#| msgid ""
#| "- 'Itself' - the non copper clearing extent is based on the object that "
#| "is copper cleared.\n"
-#| " - 'Area Selection' - left mouse click to start selection of the area to "
+#| "- 'Area Selection' - left mouse click to start selection of the area to "
#| "be painted.\n"
#| "- 'Reference Object' - will do non copper clearing within the area "
#| "specified by another object."
@@ -13162,7 +13162,7 @@ msgid ""
"Selection of area to be processed.\n"
"- 'Itself' - the processing extent is based on the object that is "
"processed.\n"
-" - 'Area Selection' - left mouse click to start selection of the area to be "
+"- 'Area Selection' - left mouse click to start selection of the area to be "
"processed.\n"
"- 'Reference Object' - will process the area specified by another object."
msgstr ""
@@ -19163,7 +19163,7 @@ msgstr "Nessun nome di geometria negli argomenti. Fornisci un nome e riprova."
#~ msgid ""
#~ "- 'Itself' - the non copper clearing extent\n"
#~ "is based on the object that is copper cleared.\n"
-#~ " - 'Area Selection' - left mouse click to start selection of the area to "
+#~ "- 'Area Selection' - left mouse click to start selection of the area to "
#~ "be painted.\n"
#~ "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple "
#~ "areas.\n"
diff --git a/locale/pt_BR/LC_MESSAGES/strings.po b/locale/pt_BR/LC_MESSAGES/strings.po
index 386e81b4..77a5a645 100644
--- a/locale/pt_BR/LC_MESSAGES/strings.po
+++ b/locale/pt_BR/LC_MESSAGES/strings.po
@@ -17959,7 +17959,7 @@ msgstr "Nenhum nome de geometria nos argumentos. Altere e tente novamente."
#~ msgid ""
#~ "- 'Itself' - the non copper clearing extent\n"
#~ "is based on the object that is copper cleared.\n"
-#~ " - 'Area Selection' - left mouse click to start selection of the area to "
+#~ "- 'Area Selection' - left mouse click to start selection of the area to "
#~ "be painted.\n"
#~ "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple "
#~ "areas.\n"
diff --git a/locale/ro/LC_MESSAGES/strings.po b/locale/ro/LC_MESSAGES/strings.po
index f740e587..530e8f06 100644
--- a/locale/ro/LC_MESSAGES/strings.po
+++ b/locale/ro/LC_MESSAGES/strings.po
@@ -11068,7 +11068,7 @@ msgid ""
"Selection of area to be processed.\n"
"- 'Itself' - the processing extent is based on the object that is "
"processed.\n"
-" - 'Area Selection' - left mouse click to start selection of the area to be "
+"- 'Area Selection' - left mouse click to start selection of the area to be "
"processed.\n"
"- 'Reference Object' - will process the area specified by another object."
msgstr ""
@@ -18233,7 +18233,7 @@ msgstr ""
#~ msgid ""
#~ "- 'Itself' - the non copper clearing extent\n"
#~ "is based on the object that is copper cleared.\n"
-#~ " - 'Area Selection' - left mouse click to start selection of the area to "
+#~ "- 'Area Selection' - left mouse click to start selection of the area to "
#~ "be painted.\n"
#~ "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple "
#~ "areas.\n"
diff --git a/locale_template/strings.pot b/locale_template/strings.pot
index 4e2b0c0e..584929dd 100644
--- a/locale_template/strings.pot
+++ b/locale_template/strings.pot
@@ -9707,7 +9707,7 @@ msgstr ""
msgid ""
"Selection of area to be processed.\n"
"- 'Itself' - the processing extent is based on the object that is processed.\n"
-" - 'Area Selection' - left mouse click to start selection of the area to be processed.\n"
+"- 'Area Selection' - left mouse click to start selection of the area to be processed.\n"
"- 'Reference Object' - will process the area specified by another object."
msgstr ""
diff --git a/tclCommands/TclCommandCopperClear.py b/tclCommands/TclCommandCopperClear.py
index b82efdfd..aa8e682b 100644
--- a/tclCommands/TclCommandCopperClear.py
+++ b/tclCommands/TclCommandCopperClear.py
@@ -218,6 +218,11 @@ class TclCommandCopperClear(TclCommand):
"toolchangexy": self.app.defaults["geometry_toolchangexy"],
"startz": self.app.defaults["geometry_startz"],
+ "area_exclusion": self.app.defaults["geometry_area_exclusion"],
+ "area_shape": self.app.defaults["geometry_area_shape"],
+ "area_strategy": self.app.defaults["geometry_area_strategy"],
+ "area_overz": float(self.app.defaults["geometry_area_overz"]),
+
"tooldia": self.app.defaults["tools_painttooldia"],
"tools_nccmargin": margin,
"tools_nccmethod": method_data,
diff --git a/tclCommands/TclCommandPaint.py b/tclCommands/TclCommandPaint.py
index 6b8a85ba..a7db7062 100644
--- a/tclCommands/TclCommandPaint.py
+++ b/tclCommands/TclCommandPaint.py
@@ -197,6 +197,11 @@ class TclCommandPaint(TclCommand):
"toolchangexy": self.app.defaults["geometry_toolchangexy"],
"startz": self.app.defaults["geometry_startz"],
+ "area_exclusion": self.app.defaults["geometry_area_exclusion"],
+ "area_shape": self.app.defaults["geometry_area_shape"],
+ "area_strategy": self.app.defaults["geometry_area_strategy"],
+ "area_overz": float(self.app.defaults["geometry_area_overz"]),
+
"tooldia": self.app.defaults["tools_painttooldia"],
"paintmargin": margin,
"paintmethod": method,