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):