- in Geometry Editor, in the Simplification Tool made sure that the selected shape is highlighted
- in Geometry Editor, in Rectangle Tool added a modification mode where a selected shape (using the SHIFT + click combo) while the tool is active, can be modified
This commit is contained in:
@@ -7,6 +7,11 @@ CHANGELOG for FlatCAM Evo beta
|
|||||||
|
|
||||||
=================================================
|
=================================================
|
||||||
|
|
||||||
|
16.04.2022
|
||||||
|
|
||||||
|
- in Geometry Editor, in the Simplification Tool made sure that the selected shape is highlighted
|
||||||
|
- in Geometry Editor, in Rectangle Tool added a modification mode where a selected shape (using the SHIFT + click combo) while the tool is active, can be modified
|
||||||
|
|
||||||
15.04.2022
|
15.04.2022
|
||||||
|
|
||||||
- in Geometry Editor moved the simplification feature in its own Editor Tool (plugin)
|
- in Geometry Editor moved the simplification feature in its own Editor Tool (plugin)
|
||||||
|
|||||||
@@ -776,6 +776,7 @@ class FCRectangle(FCShapeTool):
|
|||||||
self.draw_app = draw_app
|
self.draw_app = draw_app
|
||||||
self.app = self.draw_app.app
|
self.app = self.draw_app.app
|
||||||
self.plugin_name = _("Rectangle")
|
self.plugin_name = _("Rectangle")
|
||||||
|
self.storage = self.draw_app.storage
|
||||||
|
|
||||||
try:
|
try:
|
||||||
QtGui.QGuiApplication.restoreOverrideCursor()
|
QtGui.QGuiApplication.restoreOverrideCursor()
|
||||||
@@ -798,12 +799,37 @@ class FCRectangle(FCShapeTool):
|
|||||||
pass
|
pass
|
||||||
self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x))
|
self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x))
|
||||||
|
|
||||||
self.points.append(point)
|
modifiers = QtWidgets.QApplication.keyboardModifiers()
|
||||||
|
if modifiers == QtCore.Qt.KeyboardModifier.ShiftModifier:
|
||||||
|
# deselect all shapes
|
||||||
|
self.draw_app.selected = []
|
||||||
|
for ____ in self.storage.get_objects():
|
||||||
|
try:
|
||||||
|
__, closest_shape = self.storage.nearest(point)
|
||||||
|
# select closes shape
|
||||||
|
self.draw_app.selected.append(closest_shape)
|
||||||
|
except StopIteration:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
if self.draw_app.selected:
|
||||||
|
self.draw_app.plot_all()
|
||||||
|
self.rect_tool.mode = 'change'
|
||||||
|
sel_shape_geo = self.draw_app.selected[-1].geo
|
||||||
|
geo_bounds = sel_shape_geo.bounds
|
||||||
|
# assuming that the default setting for anchor is center
|
||||||
|
origin_x_sel_geo = geo_bounds[0] + ((geo_bounds[2] - geo_bounds[0]) / 2)
|
||||||
|
self.rect_tool.ui.x_entry.set_value(origin_x_sel_geo)
|
||||||
|
origin_y_sel_geo = geo_bounds[1] + ((geo_bounds[3] - geo_bounds[1]) / 2)
|
||||||
|
self.rect_tool.ui.y_entry.set_value(origin_y_sel_geo)
|
||||||
|
self.draw_app.app.inform.emit(
|
||||||
|
_("Click on 1st corner to add a new rectangle or Apply to change the selection."))
|
||||||
|
return
|
||||||
|
|
||||||
|
self.rect_tool.mode = 'add'
|
||||||
|
self.points.append(point)
|
||||||
if len(self.points) == 1:
|
if len(self.points) == 1:
|
||||||
self.draw_app.app.inform.emit(_("Click on opposite corner to complete ..."))
|
self.draw_app.app.inform.emit(_("Click on opposite corner to complete ..."))
|
||||||
return "Click on opposite corner to complete ..."
|
return "Click on opposite corner to complete ..."
|
||||||
|
|
||||||
if len(self.points) == 2:
|
if len(self.points) == 2:
|
||||||
self.make()
|
self.make()
|
||||||
return "Done."
|
return "Done."
|
||||||
@@ -1994,6 +2020,7 @@ class FCSimplification(FCShapeTool):
|
|||||||
self.draw_app.selected.append(closest_shape)
|
self.draw_app.selected.append(closest_shape)
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
return ""
|
return ""
|
||||||
|
self.draw_app.plot_all()
|
||||||
|
|
||||||
last_sel_geo = self.draw_app.selected[-1].geo
|
last_sel_geo = self.draw_app.selected[-1].geo
|
||||||
self.simp_tool.calculate_coords_vertex(last_sel_geo)
|
self.simp_tool.calculate_coords_vertex(last_sel_geo)
|
||||||
@@ -3262,6 +3289,7 @@ class AppGeoEditor(QtCore.QObject):
|
|||||||
:type build_ui: bool
|
:type build_ui: bool
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
ret = []
|
||||||
|
|
||||||
if shape is None:
|
if shape is None:
|
||||||
return
|
return
|
||||||
@@ -3275,13 +3303,16 @@ class AppGeoEditor(QtCore.QObject):
|
|||||||
try:
|
try:
|
||||||
w_geo = shape.geoms if isinstance(shape, (MultiPolygon, MultiLineString)) else shape
|
w_geo = shape.geoms if isinstance(shape, (MultiPolygon, MultiLineString)) else shape
|
||||||
for subshape in w_geo:
|
for subshape in w_geo:
|
||||||
self.add_shape(subshape)
|
ret_shape = self.add_shape(subshape)
|
||||||
|
ret.append(ret_shape)
|
||||||
return
|
return
|
||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if not isinstance(shape, DrawToolShape):
|
if not isinstance(shape, DrawToolShape):
|
||||||
shape = DrawToolShape(shape)
|
shape = DrawToolShape(shape)
|
||||||
|
ret.append(shape)
|
||||||
|
|
||||||
# assert isinstance(shape, DrawToolShape), "Expected a DrawToolShape, got %s" % type(shape)
|
# assert isinstance(shape, DrawToolShape), "Expected a DrawToolShape, got %s" % type(shape)
|
||||||
assert shape.geo is not None, "Shape object has empty geometry (None)"
|
assert shape.geo is not None, "Shape object has empty geometry (None)"
|
||||||
assert (isinstance(shape.geo, list) and len(shape.geo) > 0) or not isinstance(shape.geo, list), \
|
assert (isinstance(shape.geo, list) and len(shape.geo) > 0) or not isinstance(shape.geo, list), \
|
||||||
@@ -3299,6 +3330,8 @@ class AppGeoEditor(QtCore.QObject):
|
|||||||
if build_ui is True:
|
if build_ui is True:
|
||||||
self.build_ui_sig.emit() # Build UI
|
self.build_ui_sig.emit() # Build UI
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
def delete_utility_geometry(self):
|
def delete_utility_geometry(self):
|
||||||
"""
|
"""
|
||||||
Will delete the shapes in the utility shapes storage.
|
Will delete the shapes in the utility shapes storage.
|
||||||
@@ -3420,6 +3453,7 @@ class AppGeoEditor(QtCore.QObject):
|
|||||||
modifiers = QtWidgets.QApplication.keyboardModifiers()
|
modifiers = QtWidgets.QApplication.keyboardModifiers()
|
||||||
# If the SHIFT key is pressed when LMB is clicked then the coordinates are copied to clipboard
|
# If the SHIFT key is pressed when LMB is clicked then the coordinates are copied to clipboard
|
||||||
if modifiers == QtCore.Qt.KeyboardModifier.ShiftModifier:
|
if modifiers == QtCore.Qt.KeyboardModifier.ShiftModifier:
|
||||||
|
if self.active_tool is not None and self.active_tool.name != 'rectangle':
|
||||||
self.app.clipboard.setText(
|
self.app.clipboard.setText(
|
||||||
self.app.options["global_point_clipboard_format"] %
|
self.app.options["global_point_clipboard_format"] %
|
||||||
(self.decimals, self.pos[0], self.decimals, self.pos[1])
|
(self.decimals, self.pos[0], self.decimals, self.pos[1])
|
||||||
@@ -3736,15 +3770,15 @@ class AppGeoEditor(QtCore.QObject):
|
|||||||
|
|
||||||
def on_delete_btn(self):
|
def on_delete_btn(self):
|
||||||
self.delete_selected()
|
self.delete_selected()
|
||||||
self.plot_all()
|
# self.plot_all()
|
||||||
|
|
||||||
def delete_selected(self):
|
def delete_selected(self):
|
||||||
tempref = [s for s in self.selected]
|
tempref = [s for s in self.selected]
|
||||||
for shape in tempref:
|
for shape in tempref:
|
||||||
self.delete_shape(shape)
|
self.delete_shape(shape)
|
||||||
self.plot_all()
|
|
||||||
self.selected = []
|
self.selected = []
|
||||||
self.build_ui()
|
self.build_ui()
|
||||||
|
self.plot_all()
|
||||||
|
|
||||||
def delete_shape(self, shape):
|
def delete_shape(self, shape):
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class RectangleEditorTool(AppTool):
|
|||||||
|
|
||||||
self.draw_app = draw_app
|
self.draw_app = draw_app
|
||||||
self.decimals = app.decimals
|
self.decimals = app.decimals
|
||||||
|
self._mode = 'add'
|
||||||
|
|
||||||
self.ui = RectangleEditorUI(layout=self.layout, rect_class=self)
|
self.ui = RectangleEditorUI(layout=self.layout, rect_class=self)
|
||||||
self.ui.pluginName = plugin_name
|
self.ui.pluginName = plugin_name
|
||||||
@@ -25,7 +26,7 @@ class RectangleEditorTool(AppTool):
|
|||||||
|
|
||||||
def connect_signals_at_init(self):
|
def connect_signals_at_init(self):
|
||||||
# Signals
|
# Signals
|
||||||
self.ui.add_button.clicked.connect(self.on_add)
|
self.ui.add_button.clicked.connect(self.on_execute)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self.app.defaults.report_usage("Geo Editor RectangleTool()")
|
self.app.defaults.report_usage("Geo Editor RectangleTool()")
|
||||||
@@ -78,8 +79,17 @@ class RectangleEditorTool(AppTool):
|
|||||||
self.draw_app.select_tool("select")
|
self.draw_app.select_tool("select")
|
||||||
self.app.ui.notebook.callback_on_close = lambda: None
|
self.app.ui.notebook.callback_on_close = lambda: None
|
||||||
|
|
||||||
|
def on_execute(self):
|
||||||
|
if self.mode == 'add':
|
||||||
|
self.app.log.info("RectangleEditorTool.on_add() -> adding a Rectangle shape")
|
||||||
|
self.on_add()
|
||||||
|
else:
|
||||||
|
self.app.log.info("RectangleEditorTool.on_add() -> modifying a Rectangle shape")
|
||||||
|
self.draw_app.delete_selected()
|
||||||
|
self.on_add()
|
||||||
|
self.draw_app.app.inform.emit(_("Click on 1st corner ..."))
|
||||||
|
|
||||||
def on_add(self):
|
def on_add(self):
|
||||||
self.app.log.info("RecrangleEditorTool.on_add() -> adding a Rectangle shape")
|
|
||||||
origin = self.ui.anchor_radio.get_value()
|
origin = self.ui.anchor_radio.get_value()
|
||||||
origin_x = self.ui.x_entry.get_value()
|
origin_x = self.ui.x_entry.get_value()
|
||||||
origin_y = self.ui.y_entry.get_value()
|
origin_y = self.ui.y_entry.get_value()
|
||||||
@@ -130,12 +140,30 @@ class RectangleEditorTool(AppTool):
|
|||||||
else: # 's' - square
|
else: # 's' - square
|
||||||
geo = box(minx, miny, maxx, maxy).exterior
|
geo = box(minx, miny, maxx, maxy).exterior
|
||||||
|
|
||||||
self.draw_app.add_shape(geo)
|
added_shapes = self.draw_app.add_shape(geo)
|
||||||
|
for added_shape in added_shapes:
|
||||||
|
added_shape.data['type'] = _("Rectangle")
|
||||||
self.draw_app.plot_all()
|
self.draw_app.plot_all()
|
||||||
|
|
||||||
def on_clear(self):
|
def on_clear(self):
|
||||||
self.set_tool_ui()
|
self.set_tool_ui()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mode(self):
|
||||||
|
return self._mode
|
||||||
|
|
||||||
|
@mode.setter
|
||||||
|
def mode(self, val):
|
||||||
|
self._mode = val
|
||||||
|
if self._mode == 'add':
|
||||||
|
# remove selections when adding a new rectangle
|
||||||
|
self.draw_app.selected = []
|
||||||
|
self.ui.add_button.set_value(_("Add"))
|
||||||
|
self.ui.add_button.setIcon(QtGui.QIcon(self.app.resource_location + '/plus16.png'))
|
||||||
|
else:
|
||||||
|
self.ui.add_button.set_value(_("Apply"))
|
||||||
|
self.ui.add_button.setIcon(QtGui.QIcon(self.app.resource_location + '/apply32.png'))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def length(self):
|
def length(self):
|
||||||
return self.ui.length_entry.get_value()
|
return self.ui.length_entry.get_value()
|
||||||
@@ -266,10 +294,18 @@ class RectangleEditorUI:
|
|||||||
|
|
||||||
# Buttons
|
# Buttons
|
||||||
self.add_button = FCButton(_("Add"))
|
self.add_button = FCButton(_("Add"))
|
||||||
|
self.add_button.setIcon(QtGui.QIcon(self.app.resource_location + '/plus16.png'))
|
||||||
grid0.addWidget(self.add_button, 18, 0, 1, 2)
|
grid0.addWidget(self.add_button, 18, 0, 1, 2)
|
||||||
|
|
||||||
self.layout.addStretch(1)
|
self.layout.addStretch(1)
|
||||||
|
|
||||||
|
# Note
|
||||||
|
self.note_lbl = FCLabel('<b>%s</b>' % _("Note"))
|
||||||
|
self.layout.addWidget(self.note_lbl)
|
||||||
|
self.note_description_lbl = FCLabel('%s' % _("Shift + click to select a shape for modification."))
|
||||||
|
self.layout.addWidget(self.note_description_lbl)
|
||||||
|
|
||||||
|
# Signals
|
||||||
self.corner_radio.activated_custom.connect(self.on_corner_changed)
|
self.corner_radio.activated_custom.connect(self.on_corner_changed)
|
||||||
|
|
||||||
def on_corner_changed(self, val):
|
def on_corner_changed(self, val):
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ class SimplificationTool(AppTool):
|
|||||||
selected_shapes_geos.append(obj_shape.geo.simplify(tolerance=tol))
|
selected_shapes_geos.append(obj_shape.geo.simplify(tolerance=tol))
|
||||||
|
|
||||||
if not selected_shapes:
|
if not selected_shapes:
|
||||||
self.app.inform.emit('[WARNING_NOTCL] %s' % _("Failed."))
|
self.app.inform.emit('%s' % _("Failed."))
|
||||||
return
|
return
|
||||||
|
|
||||||
for shape in selected_shapes:
|
for shape in selected_shapes:
|
||||||
@@ -115,6 +115,8 @@ class SimplificationTool(AppTool):
|
|||||||
last_sel_geo = selected_shapes_geos[-1]
|
last_sel_geo = selected_shapes_geos[-1]
|
||||||
self.calculate_coords_vertex(last_sel_geo)
|
self.calculate_coords_vertex(last_sel_geo)
|
||||||
|
|
||||||
|
self.app.inform.emit('%s' % _("Done."))
|
||||||
|
|
||||||
self.draw_app.plot_all()
|
self.draw_app.plot_all()
|
||||||
self.draw_app.interdict_selection = False
|
self.draw_app.interdict_selection = False
|
||||||
self.draw_app.build_ui_sig.emit()
|
self.draw_app.build_ui_sig.emit()
|
||||||
|
|||||||
Reference in New Issue
Block a user