From 675d7455d40a0939728761295a3ba4fa411fa2a1 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 27 Nov 2020 14:16:26 +0200 Subject: [PATCH] - fixed crash when launching with 2D Graphic Engine (due of recent changes) - in Geometry Editor - added new feature: Zoom on selected (by selecting a geometry element in the Geometry Table) --- CHANGELOG.md | 3 ++ appEditors/AppGeoEditor.py | 106 ++++++++++++++++++++++++++++--------- appGUI/PlotCanvasLegacy.py | 4 +- app_Main.py | 16 +++--- 4 files changed, 95 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df914a6d..5cc09ab5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,9 @@ CHANGELOG for FlatCAM beta - in Geometry Editor - fixed a crash on Geometry Editor exit - in Geometry Editor - added a new feature: ability to change the orientation (from CW to CCW and the revers) for Polygon and LinearRing geometry elements. - in Geometry Editor - added a context menu in the Geometry Table +- fixed crash when launching with 2D Graphic Engine (due of recent changes) +- in Geometry Editor - added new feature: Zoom on selected (by selecting a geometry element in the Geometry Table) + 26.11.2020 diff --git a/appEditors/AppGeoEditor.py b/appEditors/AppGeoEditor.py index 3acd6d20..f79fd997 100644 --- a/appEditors/AppGeoEditor.py +++ b/appEditors/AppGeoEditor.py @@ -20,6 +20,8 @@ from appGUI.GUIElements import OptionalInputSection, FCCheckBox, FCLabel, FCComb FCDoubleSpinner, FCButton, FCInputDoubleSpinner, FCTree, NumericalEvalTupleEntry, FCEntry, FCTextEdit from appParsers.ParseFont import * +from vispy.geometry import Rect + from shapely.geometry import LineString, LinearRing, MultiLineString, Polygon, MultiPolygon, Point from shapely.ops import unary_union, linemerge import shapely.affinity as affinity @@ -3394,38 +3396,42 @@ class AppGeoEditor(QtCore.QObject): self.geo_font.setBold(True) self.geo_parent = self.tw.invisibleRootItem() + # Zoom Selection + self.geo_zoom = FCCheckBox(_("Zoom on selection")) + grid0.addWidget(self.geo_zoom, 4, 0, 1, 3) + separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - grid0.addWidget(separator_line, 3, 0, 1, 3) + grid0.addWidget(separator_line, 6, 0, 1, 3) # Parameters Title param_title = FCLabel('%s:' % _("Parameters")) param_title.setToolTip( _("Geometry parameters.") ) - grid0.addWidget(param_title, 4, 0, 1, 3) + grid0.addWidget(param_title, 8, 0, 1, 3) # Is Valid is_valid_lbl = FCLabel('%s:' % _("Is Valid")) self.is_valid_entry = FCLabel('None') - grid0.addWidget(is_valid_lbl, 6, 0) - grid0.addWidget(self.is_valid_entry, 6, 1, 1, 2) + grid0.addWidget(is_valid_lbl, 10, 0) + grid0.addWidget(self.is_valid_entry, 10, 1, 1, 2) # Is Empty is_empty_lbl = FCLabel('%s:' % _("Is Empty")) self.is_empty_entry = FCLabel('None') - grid0.addWidget(is_empty_lbl, 8, 0) - grid0.addWidget(self.is_empty_entry, 8, 1, 1, 2) + grid0.addWidget(is_empty_lbl, 12, 0) + grid0.addWidget(self.is_empty_entry, 12, 1, 1, 2) # Is Ring is_ring_lbl = FCLabel('%s:' % _("Is Ring")) self.is_ring_entry = FCLabel('None') - grid0.addWidget(is_ring_lbl, 10, 0) - grid0.addWidget(self.is_ring_entry, 10, 1, 1, 2) + grid0.addWidget(is_ring_lbl, 14, 0) + grid0.addWidget(self.is_ring_entry, 14, 1, 1, 2) # Is CCW is_ccw_lbl = FCLabel('%s:' % _("Is CCW")) @@ -3436,16 +3442,16 @@ class AppGeoEditor(QtCore.QObject): _("Change the orientation of the geometric element.\n" "Works for LinearRing and Polygons.") ) - grid0.addWidget(is_ccw_lbl, 12, 0) - grid0.addWidget(self.is_ccw_entry, 12, 1) - grid0.addWidget(self.change_orientation_btn, 12, 2) + grid0.addWidget(is_ccw_lbl, 16, 0) + grid0.addWidget(self.is_ccw_entry, 16, 1) + grid0.addWidget(self.change_orientation_btn, 16, 2) # Is Simple is_simple_lbl = FCLabel('%s:' % _("Is Simple")) self.is_simple_entry = FCLabel('None') - grid0.addWidget(is_simple_lbl, 14, 0) - grid0.addWidget(self.is_simple_entry, 14, 1, 1, 2) + grid0.addWidget(is_simple_lbl, 18, 0) + grid0.addWidget(self.is_simple_entry, 18, 1, 1, 2) # Length len_lbl = FCLabel('%s:' % _("Length")) @@ -3453,18 +3459,21 @@ class AppGeoEditor(QtCore.QObject): _("The length of the geometry element.") ) self.geo_len_entry = FCEntry(decimals=self.decimals) - grid0.addWidget(len_lbl, 16, 0) - grid0.addWidget(self.geo_len_entry, 16, 1, 1, 2) + grid0.addWidget(len_lbl, 20, 0) + grid0.addWidget(self.geo_len_entry, 20, 1, 1, 2) # Coordinates coords_lbl = FCLabel('%s:' % _("Coordinates")) coords_lbl.setToolTip( _("The coordinates of the selected geometry element.") ) - grid0.addWidget(coords_lbl, 18, 0, 1, 3) + grid0.addWidget(coords_lbl, 22, 0, 1, 3) self.geo_coords_entry = FCTextEdit() - grid0.addWidget(self.geo_coords_entry, 20, 0, 1, 3) + self.geo_coords_entry.setPlaceholderText( + _("The coordinates of the selected geometry element.") + ) + grid0.addWidget(self.geo_coords_entry, 24, 0, 1, 3) # Vertex Points Number vertex_lbl = FCLabel('%s:' % _("Vertex Points")) @@ -3473,20 +3482,20 @@ class AppGeoEditor(QtCore.QObject): ) self.geo_vertex_entry = FCEntry(decimals=self.decimals) - grid0.addWidget(vertex_lbl, 22, 0) - grid0.addWidget(self.geo_vertex_entry, 22, 1, 1, 2) + grid0.addWidget(vertex_lbl, 26, 0) + grid0.addWidget(self.geo_vertex_entry, 26, 1, 1, 2) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - grid0.addWidget(separator_line, 23, 0, 1, 3) + grid0.addWidget(separator_line, 28, 0, 1, 3) # Simplification simplif_lbl = FCLabel('%s:' % _("Simplification")) simplif_lbl.setToolTip( _("Simplify a geometry element by reducing its vertex points number.") ) - grid0.addWidget(simplif_lbl, 24, 0, 1, 3) + grid0.addWidget(simplif_lbl, 30, 0, 1, 3) simplification_tol_lbl = FCLabel('%s:' % _("Tolerance")) simplification_tol_lbl.setToolTip( @@ -3499,8 +3508,8 @@ class AppGeoEditor(QtCore.QObject): self.geo_tol_entry.set_range(0.0000, 10000.0000) self.geo_tol_entry.set_value(10 ** -self.decimals) - grid0.addWidget(simplification_tol_lbl, 26, 0) - grid0.addWidget(self.geo_tol_entry, 26, 1, 1, 2) + grid0.addWidget(simplification_tol_lbl, 32, 0) + grid0.addWidget(self.geo_tol_entry, 32, 1, 1, 2) self.simplification_btn = FCButton(_("Simplify")) self.simplification_btn.setIcon(QtGui.QIcon(self.app.resource_location + '/simplify32.png')) @@ -3514,7 +3523,7 @@ class AppGeoEditor(QtCore.QObject): } """) - grid0.addWidget(self.simplification_btn, 27, 0, 1, 3) + grid0.addWidget(self.simplification_btn, 34, 0, 1, 3) layout.addStretch() @@ -3783,6 +3792,16 @@ class AppGeoEditor(QtCore.QObject): # Switch notebook to Properties page self.app.ui.notebook.setCurrentWidget(self.app.ui.properties_tab) + self.geo_coords_entry.setText('') + self.is_ccw_entry.set_value('None') + self.is_ring_entry.set_value('None') + self.is_simple_entry.set_value('None') + self.is_empty_entry.set_value('None') + self.is_valid_entry.set_value('None') + self.geo_vertex_entry.set_value(0.0) + self.geo_tol_entry.set_value(10 ** -self.decimals) + self.geo_zoom.set_value(False) + def build_ui(self): """ Build the appGUI in the Properties Tab for this editor @@ -3873,6 +3892,45 @@ class AppGeoEditor(QtCore.QObject): coords = 'None' vertex_nr = 0 + if self.geo_zoom.get_value(): + xmin, ymin, xmax, ymax = last_sel_geo.bounds + if xmin == xmax and ymin != ymax: + xmin = ymin + xmax = ymax + elif xmin != xmax and ymin == ymax: + ymin = xmin + ymax = xmax + + if self.app.is_legacy is False: + rect = Rect(xmin, ymin, xmax, ymax) + rect.left, rect.right = xmin, xmax + rect.bottom, rect.top = ymin, ymax + # Lock updates in other threads + self.shapes.lock_updates() + + # adjust the view camera to be slightly bigger than the bounds so the shape collection can be + # seen clearly otherwise the shape collection boundary will have no border + dx = rect.right - rect.left + dy = rect.top - rect.bottom + x_factor = dx * 0.02 + y_factor = dy * 0.02 + + rect.left -= x_factor + rect.bottom -= y_factor + rect.right += x_factor + rect.top += y_factor + + self.app.plotcanvas.view.camera.rect = rect + self.shapes.unlock_updates() + else: + width = xmax - xmin + height = ymax - ymin + xmin -= 0.05 * width + xmax += 0.05 * width + ymin -= 0.05 * height + ymax += 0.05 * height + self.app.plotcanvas.adjust_axes(xmin, ymin, xmax, ymax) + self.geo_len_entry.set_value(length, decimals=self.decimals) self.geo_coords_entry.setText(str(coords)) self.geo_vertex_entry.set_value(vertex_nr) diff --git a/appGUI/PlotCanvasLegacy.py b/appGUI/PlotCanvasLegacy.py index 994140e7..24767a74 100644 --- a/appGUI/PlotCanvasLegacy.py +++ b/appGUI/PlotCanvasLegacy.py @@ -734,7 +734,7 @@ class PlotCanvasLegacy(QtCore.QObject): """ self.clear() - def adjust_axes(self, xmin, ymin, xmax, ymax): + def adjust_axes(self, xmin=None, ymin=None, xmax=None, ymax=None): """ Adjusts all axes while maintaining the use of the whole canvas and an aspect ratio to 1:1 between x and y axes. The parameters are an original @@ -753,7 +753,7 @@ class PlotCanvasLegacy(QtCore.QObject): # FlatCAMApp.App.log.debug("PC.adjust_axes()") - if not self.app.collection.get_list(): + if not self.app.collection.get_list() and not xmin and not ymin and not xmax and not ymax: xmin = -10 ymin = -10 xmax = 100 diff --git a/app_Main.py b/app_Main.py index 112f7034..9496ae80 100644 --- a/app_Main.py +++ b/app_Main.py @@ -1084,10 +1084,9 @@ class App(QtCore.QObject): # ########################################################################################################### # determine if the Legacy Graphic Engine is to be used or the OpenGL one + self.is_legacy = True if self.defaults["global_graphic_engine"] == '3D': self.is_legacy = False - else: - self.is_legacy = True # PlotCanvas Event signals disconnect id holders self.mp = None @@ -1140,6 +1139,13 @@ class App(QtCore.QObject): from appGUI.PlotCanvasLegacy import ShapeCollectionLegacy self.tool_shapes = ShapeCollectionLegacy(obj=self, app=self, name="tool") + # Storage for Hover Shapes + if self.is_legacy is False: + self.hover_shapes = ShapeCollection(parent=self.plotcanvas.view.scene, layers=1) + else: + # will use the default Matplotlib axes + self.hover_shapes = ShapeCollectionLegacy(obj=self, app=self, name='hover') + # ########################################################################################################### # ############################################### Worker SETUP ############################################## # ########################################################################################################### @@ -7880,12 +7886,6 @@ class App(QtCore.QObject): else: self.app_cursor.enabled = False - if self.is_legacy is False: - self.hover_shapes = ShapeCollection(parent=plotcanvas.view.scene, layers=1) - else: - # will use the default Matplotlib axes - self.hover_shapes = ShapeCollectionLegacy(obj=self, app=self, name='hover') - return plotcanvas def on_zoom_fit(self):