- Geometry Editor: made the tool to be able to continuously move until the tool is exited either by ESC key or by right mouse button click
- Geometry Editor Move Tool: if no shape is selected when triggering this tool, now it is possible to make the selection inside the tool - Gerber editor Move Tool: fixed a bug that repeated the plotting function unnecessarily - Gerber editor Move Tool: if no shape is selected the tool will exit
This commit is contained in:
parent
0a150fba79
commit
28fce82432
|
@ -15,6 +15,10 @@ CAD program, and create G-Code for Isolation routing.
|
||||||
- added move action for solid_geometry stored in the gerber_obj.apertures
|
- added move action for solid_geometry stored in the gerber_obj.apertures
|
||||||
- fixed camlib.Gerber skew, rotate, offset, mirror functions to work for geometry stored in the Gerber apertures
|
- fixed camlib.Gerber skew, rotate, offset, mirror functions to work for geometry stored in the Gerber apertures
|
||||||
- fixed Gerber Editor follow_geometry reconstruction
|
- fixed Gerber Editor follow_geometry reconstruction
|
||||||
|
- Geometry Editor: made the tool to be able to continuously move until the tool is exited either by ESC key or by right mouse button click
|
||||||
|
- Geometry Editor Move Tool: if no shape is selected when triggering this tool, now it is possible to make the selection inside the tool
|
||||||
|
- Gerber editor Move Tool: fixed a bug that repeated the plotting function unnecessarily
|
||||||
|
- Gerber editor Move Tool: if no shape is selected the tool will exit
|
||||||
|
|
||||||
7.05.2019
|
7.05.2019
|
||||||
|
|
||||||
|
|
|
@ -7269,13 +7269,13 @@ class CNCjob(Geometry):
|
||||||
|
|
||||||
self.create_geometry()
|
self.create_geometry()
|
||||||
|
|
||||||
|
|
||||||
def get_bounds(geometry_list):
|
def get_bounds(geometry_list):
|
||||||
xmin = Inf
|
xmin = Inf
|
||||||
ymin = Inf
|
ymin = Inf
|
||||||
xmax = -Inf
|
xmax = -Inf
|
||||||
ymax = -Inf
|
ymax = -Inf
|
||||||
|
|
||||||
#print "Getting bounds of:", str(geometry_set)
|
|
||||||
for gs in geometry_list:
|
for gs in geometry_list:
|
||||||
try:
|
try:
|
||||||
gxmin, gymin, gxmax, gymax = gs.bounds()
|
gxmin, gymin, gxmax, gymax = gs.bounds()
|
||||||
|
|
|
@ -18,6 +18,7 @@ from FlatCAMTool import FlatCAMTool
|
||||||
from flatcamGUI.ObjectUI import LengthEntry, RadioSet
|
from flatcamGUI.ObjectUI import LengthEntry, RadioSet
|
||||||
|
|
||||||
from shapely.geometry import LineString, LinearRing, MultiLineString
|
from shapely.geometry import LineString, LinearRing, MultiLineString
|
||||||
|
# from shapely.geometry import mapping
|
||||||
from shapely.ops import cascaded_union, unary_union
|
from shapely.ops import cascaded_union, unary_union
|
||||||
import shapely.affinity as affinity
|
import shapely.affinity as affinity
|
||||||
|
|
||||||
|
@ -29,6 +30,7 @@ from flatcamGUI.GUIElements import OptionalInputSection, FCCheckBox, FCEntry, FC
|
||||||
FCTable, FCDoubleSpinner, FCButton, EvalEntry2, FCInputDialog
|
FCTable, FCDoubleSpinner, FCButton, EvalEntry2, FCInputDialog
|
||||||
from flatcamParsers.ParseFont import *
|
from flatcamParsers.ParseFont import *
|
||||||
|
|
||||||
|
# from vispy.io import read_png
|
||||||
import gettext
|
import gettext
|
||||||
import FlatCAMTranslation as fcTranslate
|
import FlatCAMTranslation as fcTranslate
|
||||||
|
|
||||||
|
@ -1861,7 +1863,6 @@ class DrawTool(object):
|
||||||
def __init__(self, draw_app):
|
def __init__(self, draw_app):
|
||||||
self.draw_app = draw_app
|
self.draw_app = draw_app
|
||||||
self.complete = False
|
self.complete = False
|
||||||
self.start_msg = "Click on 1st point..."
|
|
||||||
self.points = []
|
self.points = []
|
||||||
self.geometry = None # DrawToolShape or None
|
self.geometry = None # DrawToolShape or None
|
||||||
|
|
||||||
|
@ -1939,7 +1940,6 @@ class FCCircle(FCShapeTool):
|
||||||
self.cursor = QtGui.QCursor(QtGui.QPixmap('share/aero_circle_geo.png'))
|
self.cursor = QtGui.QCursor(QtGui.QPixmap('share/aero_circle_geo.png'))
|
||||||
QtGui.QGuiApplication.setOverrideCursor(self.cursor)
|
QtGui.QGuiApplication.setOverrideCursor(self.cursor)
|
||||||
|
|
||||||
self.start_msg = _("Click on Center point ...")
|
|
||||||
self.draw_app.app.inform.emit(_("Click on Center point ..."))
|
self.draw_app.app.inform.emit(_("Click on Center point ..."))
|
||||||
self.steps_per_circ = self.draw_app.app.defaults["geometry_circle_steps"]
|
self.steps_per_circ = self.draw_app.app.defaults["geometry_circle_steps"]
|
||||||
|
|
||||||
|
@ -1991,7 +1991,6 @@ class FCArc(FCShapeTool):
|
||||||
self.cursor = QtGui.QCursor(QtGui.QPixmap('share/aero_arc.png'))
|
self.cursor = QtGui.QCursor(QtGui.QPixmap('share/aero_arc.png'))
|
||||||
QtGui.QGuiApplication.setOverrideCursor(self.cursor)
|
QtGui.QGuiApplication.setOverrideCursor(self.cursor)
|
||||||
|
|
||||||
self.start_msg = _("Click on Center point ...")
|
|
||||||
self.draw_app.app.inform.emit(_("Click on Center point ..."))
|
self.draw_app.app.inform.emit(_("Click on Center point ..."))
|
||||||
|
|
||||||
# Direction of rotation between point 1 and 2.
|
# Direction of rotation between point 1 and 2.
|
||||||
|
@ -2210,12 +2209,13 @@ class FCRectangle(FCShapeTool):
|
||||||
self.cursor = QtGui.QCursor(QtGui.QPixmap('share/aero.png'))
|
self.cursor = QtGui.QCursor(QtGui.QPixmap('share/aero.png'))
|
||||||
QtGui.QGuiApplication.setOverrideCursor(self.cursor)
|
QtGui.QGuiApplication.setOverrideCursor(self.cursor)
|
||||||
|
|
||||||
self.start_msg = _("Click on 1st corner ...")
|
self.draw_app.app.inform.emit( _("Click on 1st corner ..."))
|
||||||
|
|
||||||
def click(self, point):
|
def click(self, point):
|
||||||
self.points.append(point)
|
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 ..."))
|
||||||
return "Click on opposite corner to complete ..."
|
return "Click on opposite corner to complete ..."
|
||||||
|
|
||||||
if len(self.points) == 2:
|
if len(self.points) == 2:
|
||||||
|
@ -2262,14 +2262,14 @@ class FCPolygon(FCShapeTool):
|
||||||
self.cursor = QtGui.QCursor(QtGui.QPixmap('share/aero.png'))
|
self.cursor = QtGui.QCursor(QtGui.QPixmap('share/aero.png'))
|
||||||
QtGui.QGuiApplication.setOverrideCursor(self.cursor)
|
QtGui.QGuiApplication.setOverrideCursor(self.cursor)
|
||||||
|
|
||||||
self.start_msg = _("Click on 1st point ...")
|
self.draw_app.app.inform.emit(_("Click on 1st corner ..."))
|
||||||
|
|
||||||
def click(self, point):
|
def click(self, point):
|
||||||
self.draw_app.in_action = True
|
self.draw_app.in_action = True
|
||||||
self.points.append(point)
|
self.points.append(point)
|
||||||
|
|
||||||
if len(self.points) > 0:
|
if len(self.points) > 0:
|
||||||
self.draw_app.app.inform.emit(_("Click on next Point or click Right mouse button to complete ..."))
|
self.draw_app.app.inform.emit(_("Click on next Point or click right mouse button to complete ..."))
|
||||||
return "Click on next point or hit ENTER to complete ..."
|
return "Click on next point or hit ENTER to complete ..."
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
|
@ -2445,21 +2445,33 @@ class FCMove(FCShapeTool):
|
||||||
FCShapeTool.__init__(self, draw_app)
|
FCShapeTool.__init__(self, draw_app)
|
||||||
self.name = 'move'
|
self.name = 'move'
|
||||||
|
|
||||||
# self.shape_buffer = self.draw_app.shape_buffer
|
try:
|
||||||
if not self.draw_app.selected:
|
QtGui.QGuiApplication.restoreOverrideCursor()
|
||||||
self.draw_app.app.inform.emit(_("[WARNING_NOTCL] Move cancelled. No shape selected."))
|
except:
|
||||||
return
|
pass
|
||||||
|
|
||||||
|
self.storage = self.draw_app.storage
|
||||||
|
|
||||||
self.origin = None
|
self.origin = None
|
||||||
self.destination = None
|
self.destination = None
|
||||||
self.start_msg = _("Click on reference point.")
|
|
||||||
|
if len(self.draw_app.get_selected()) == 0:
|
||||||
|
self.draw_app.app.inform.emit(_("[WARNING_NOTCL] MOVE: No shape selected. Select a shape to move ..."))
|
||||||
|
else:
|
||||||
|
self.draw_app.app.inform.emit(_(" MOVE: Click on reference point ..."))
|
||||||
|
|
||||||
def set_origin(self, origin):
|
def set_origin(self, origin):
|
||||||
self.draw_app.app.inform.emit(_("Click on destination point."))
|
self.draw_app.app.inform.emit(_(" Click on destination point ..."))
|
||||||
self.origin = origin
|
self.origin = origin
|
||||||
|
|
||||||
def click(self, point):
|
def click(self, point):
|
||||||
if len(self.draw_app.get_selected()) == 0:
|
if len(self.draw_app.get_selected()) == 0:
|
||||||
return "Nothing to move."
|
# self.complete = True
|
||||||
|
# self.draw_app.app.inform.emit(_("[WARNING_NOTCL] Move cancelled. No shape selected."))
|
||||||
|
self.select_shapes(point)
|
||||||
|
self.draw_app.replot()
|
||||||
|
self.draw_app.app.inform.emit(_(" MOVE: Click on reference point ..."))
|
||||||
|
return
|
||||||
|
|
||||||
if self.origin is None:
|
if self.origin is None:
|
||||||
self.set_origin(point)
|
self.set_origin(point)
|
||||||
|
@ -2517,6 +2529,58 @@ class FCMove(FCShapeTool):
|
||||||
# return DrawToolUtilityShape([affinity.translate(geom.geo, xoff=dx, yoff=dy)
|
# return DrawToolUtilityShape([affinity.translate(geom.geo, xoff=dx, yoff=dy)
|
||||||
# for geom in self.draw_app.get_selected()])
|
# for geom in self.draw_app.get_selected()])
|
||||||
|
|
||||||
|
def select_shapes(self, pos):
|
||||||
|
# list where we store the overlapped shapes under our mouse left click position
|
||||||
|
over_shape_list = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
_, closest_shape = self.storage.nearest(pos)
|
||||||
|
except StopIteration:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
over_shape_list.append(closest_shape)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# if there is no shape under our click then deselect all shapes
|
||||||
|
# it will not work for 3rd method of click selection
|
||||||
|
if not over_shape_list:
|
||||||
|
self.draw_app.selected = []
|
||||||
|
self.draw_app.draw_shape_idx = -1
|
||||||
|
else:
|
||||||
|
# if there are shapes under our click then advance through the list of them, one at the time in a
|
||||||
|
# circular way
|
||||||
|
self.draw_app.draw_shape_idx = (FlatCAMGeoEditor.draw_shape_idx + 1) % len(over_shape_list)
|
||||||
|
try:
|
||||||
|
obj_to_add = over_shape_list[int(FlatCAMGeoEditor.draw_shape_idx)]
|
||||||
|
except IndexError:
|
||||||
|
return
|
||||||
|
|
||||||
|
key_modifier = QtWidgets.QApplication.keyboardModifiers()
|
||||||
|
if self.draw_app.app.defaults["global_mselect_key"] == 'Control':
|
||||||
|
# if CONTROL key is pressed then we add to the selected list the current shape but if it's
|
||||||
|
# already in the selected list, we removed it. Therefore first click selects, second deselects.
|
||||||
|
if key_modifier == Qt.ControlModifier:
|
||||||
|
if obj_to_add in self.draw_app.selected:
|
||||||
|
self.draw_app.selected.remove(obj_to_add)
|
||||||
|
else:
|
||||||
|
self.draw_app.selected.append(obj_to_add)
|
||||||
|
else:
|
||||||
|
self.draw_app.selected = []
|
||||||
|
self.draw_app.selected.append(obj_to_add)
|
||||||
|
else:
|
||||||
|
if key_modifier == Qt.ShiftModifier:
|
||||||
|
if obj_to_add in self.draw_app.selected:
|
||||||
|
self.draw_app.selected.remove(obj_to_add)
|
||||||
|
else:
|
||||||
|
self.draw_app.selected.append(obj_to_add)
|
||||||
|
else:
|
||||||
|
self.draw_app.selected = []
|
||||||
|
self.draw_app.selected.append(obj_to_add)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
log.error("[ERROR] Something went bad. %s" % str(e))
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
class FCCopy(FCMove):
|
class FCCopy(FCMove):
|
||||||
def __init__(self, draw_app):
|
def __init__(self, draw_app):
|
||||||
|
@ -2550,7 +2614,7 @@ class FCText(FCShapeTool):
|
||||||
self.draw_app = draw_app
|
self.draw_app = draw_app
|
||||||
self.app = draw_app.app
|
self.app = draw_app.app
|
||||||
|
|
||||||
self.start_msg = _("Click on the Destination point...")
|
self.draw_app.app.inform.emit(_("Click on 1st corner ..."))
|
||||||
self.origin = (0, 0)
|
self.origin = (0, 0)
|
||||||
|
|
||||||
self.text_gui = TextInputTool(self.app)
|
self.text_gui = TextInputTool(self.app)
|
||||||
|
@ -2602,7 +2666,7 @@ class FCBuffer(FCShapeTool):
|
||||||
self.draw_app = draw_app
|
self.draw_app = draw_app
|
||||||
self.app = draw_app.app
|
self.app = draw_app.app
|
||||||
|
|
||||||
self.start_msg = _("Create buffer geometry ...")
|
self.draw_app.app.inform.emit(_("Create buffer geometry ..."))
|
||||||
self.origin = (0, 0)
|
self.origin = (0, 0)
|
||||||
self.buff_tool = BufferSelectionTool(self.app, self.draw_app)
|
self.buff_tool = BufferSelectionTool(self.app, self.draw_app)
|
||||||
self.buff_tool.run()
|
self.buff_tool.run()
|
||||||
|
@ -2720,7 +2784,7 @@ class FCPaint(FCShapeTool):
|
||||||
self.draw_app = draw_app
|
self.draw_app = draw_app
|
||||||
self.app = draw_app.app
|
self.app = draw_app.app
|
||||||
|
|
||||||
self.start_msg = _("Create Paint geometry ...")
|
self.draw_app.app.inform.emit(_("Create Paint geometry ..."))
|
||||||
self.origin = (0, 0)
|
self.origin = (0, 0)
|
||||||
self.draw_app.paint_tool.run()
|
self.draw_app.paint_tool.run()
|
||||||
|
|
||||||
|
@ -2734,7 +2798,7 @@ class FCTransform(FCShapeTool):
|
||||||
self.draw_app = draw_app
|
self.draw_app = draw_app
|
||||||
self.app = draw_app.app
|
self.app = draw_app.app
|
||||||
|
|
||||||
self.start_msg = _("Shape transformations ...")
|
self.draw_app.app.infrom.emit(_("Shape transformations ..."))
|
||||||
self.origin = (0, 0)
|
self.origin = (0, 0)
|
||||||
self.draw_app.transform_tool.run()
|
self.draw_app.transform_tool.run()
|
||||||
|
|
||||||
|
@ -3159,6 +3223,9 @@ class FlatCAMGeoEditor(QtCore.QObject):
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if shape is None:
|
||||||
|
return
|
||||||
|
|
||||||
# List of DrawToolShape?
|
# List of DrawToolShape?
|
||||||
if isinstance(shape, list):
|
if isinstance(shape, list):
|
||||||
for subshape in shape:
|
for subshape in shape:
|
||||||
|
@ -3280,8 +3347,6 @@ class FlatCAMGeoEditor(QtCore.QObject):
|
||||||
self.tools[t]["button"].setChecked(False)
|
self.tools[t]["button"].setChecked(False)
|
||||||
|
|
||||||
self.active_tool = self.tools[tool]["constructor"](self)
|
self.active_tool = self.tools[tool]["constructor"](self)
|
||||||
if not isinstance(self.active_tool, FCSelect):
|
|
||||||
self.app.inform.emit(self.active_tool.start_msg)
|
|
||||||
else:
|
else:
|
||||||
self.app.log.debug("%s is NOT checked." % tool)
|
self.app.log.debug("%s is NOT checked." % tool)
|
||||||
for t in self.tools:
|
for t in self.tools:
|
||||||
|
@ -3341,6 +3406,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
|
||||||
|
|
||||||
# Selection with left mouse button
|
# Selection with left mouse button
|
||||||
if self.active_tool is not None and event.button is 1:
|
if self.active_tool is not None and event.button is 1:
|
||||||
|
|
||||||
# Dispatch event to active_tool
|
# Dispatch event to active_tool
|
||||||
msg = self.active_tool.click(self.snap(self.pos[0], self.pos[1]))
|
msg = self.active_tool.click(self.snap(self.pos[0], self.pos[1]))
|
||||||
|
|
||||||
|
@ -3348,28 +3414,11 @@ class FlatCAMGeoEditor(QtCore.QObject):
|
||||||
if isinstance(self.active_tool, FCShapeTool) and self.active_tool.complete:
|
if isinstance(self.active_tool, FCShapeTool) and self.active_tool.complete:
|
||||||
self.on_shape_complete()
|
self.on_shape_complete()
|
||||||
|
|
||||||
# MS: always return to the Select Tool if modifier key is not pressed
|
|
||||||
# else return to the current tool
|
|
||||||
key_modifier = QtWidgets.QApplication.keyboardModifiers()
|
|
||||||
if self.app.defaults["global_mselect_key"] == 'Control':
|
|
||||||
modifier_to_use = Qt.ControlModifier
|
|
||||||
else:
|
|
||||||
modifier_to_use = Qt.ShiftModifier
|
|
||||||
|
|
||||||
if isinstance(self.active_tool, FCText):
|
if isinstance(self.active_tool, FCText):
|
||||||
self.select_tool("select")
|
self.select_tool("select")
|
||||||
else:
|
else:
|
||||||
self.select_tool(self.active_tool.name)
|
self.select_tool(self.active_tool.name)
|
||||||
|
|
||||||
|
|
||||||
# if modifier key is pressed then we add to the selected list the current shape but if
|
|
||||||
# it's already in the selected list, we removed it. Therefore first click selects, second deselects.
|
|
||||||
# if key_modifier == modifier_to_use:
|
|
||||||
# self.select_tool(self.active_tool.name)
|
|
||||||
# else:
|
|
||||||
# self.select_tool("select")
|
|
||||||
# return
|
|
||||||
|
|
||||||
if isinstance(self.active_tool, FCSelect):
|
if isinstance(self.active_tool, FCSelect):
|
||||||
# self.app.log.debug("Replotting after click.")
|
# self.app.log.debug("Replotting after click.")
|
||||||
self.replot()
|
self.replot()
|
||||||
|
@ -3616,13 +3665,13 @@ class FlatCAMGeoEditor(QtCore.QObject):
|
||||||
self.selected.remove(shape) # TODO: Check performance
|
self.selected.remove(shape) # TODO: Check performance
|
||||||
|
|
||||||
def on_move(self):
|
def on_move(self):
|
||||||
|
# if not self.selected:
|
||||||
|
# self.app.inform.emit(_("[WARNING_NOTCL] Move cancelled. No shape selected."))
|
||||||
|
# return
|
||||||
self.app.ui.geo_move_btn.setChecked(True)
|
self.app.ui.geo_move_btn.setChecked(True)
|
||||||
self.on_tool_select('move')
|
self.on_tool_select('move')
|
||||||
|
|
||||||
def on_move_click(self):
|
def on_move_click(self):
|
||||||
if not self.selected:
|
|
||||||
self.app.inform.emit(_("[WARNING_NOTCL] Move cancelled. No shape selected."))
|
|
||||||
return
|
|
||||||
self.on_move()
|
self.on_move()
|
||||||
self.active_tool.set_origin(self.snap(self.x, self.y))
|
self.active_tool.set_origin(self.snap(self.x, self.y))
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ from PyQt5 import QtGui, QtCore, QtWidgets
|
||||||
from PyQt5.QtCore import Qt, QSettings
|
from PyQt5.QtCore import Qt, QSettings
|
||||||
|
|
||||||
from shapely.geometry import LineString, LinearRing, MultiLineString
|
from shapely.geometry import LineString, LinearRing, MultiLineString
|
||||||
|
# from shapely.geometry import mapping
|
||||||
from shapely.ops import cascaded_union, unary_union
|
from shapely.ops import cascaded_union, unary_union
|
||||||
import shapely.affinity as affinity
|
import shapely.affinity as affinity
|
||||||
|
|
||||||
|
@ -19,6 +20,9 @@ from FlatCAMTool import FlatCAMTool
|
||||||
|
|
||||||
from numpy.linalg import norm as numpy_norm
|
from numpy.linalg import norm as numpy_norm
|
||||||
|
|
||||||
|
# from vispy.io import read_png
|
||||||
|
# import pngcanvas
|
||||||
|
|
||||||
import gettext
|
import gettext
|
||||||
import FlatCAMTranslation as fcTranslate
|
import FlatCAMTranslation as fcTranslate
|
||||||
|
|
||||||
|
@ -1449,11 +1453,18 @@ class FCApertureMove(FCShapeTool):
|
||||||
self.destination = None
|
self.destination = None
|
||||||
self.selected_apertures = []
|
self.selected_apertures = []
|
||||||
|
|
||||||
|
if len(self.draw_app.get_selected()) == 0:
|
||||||
|
self.draw_app.app.inform.emit(_("[WARNING_NOTCL] Nothing selected to move ..."))
|
||||||
|
self.complete = True
|
||||||
|
self.draw_app.select_tool("select")
|
||||||
|
return
|
||||||
|
|
||||||
if self.draw_app.launched_from_shortcuts is True:
|
if self.draw_app.launched_from_shortcuts is True:
|
||||||
self.draw_app.launched_from_shortcuts = False
|
self.draw_app.launched_from_shortcuts = False
|
||||||
self.draw_app.app.inform.emit(_("Click on target location ..."))
|
self.draw_app.app.inform.emit(_("Click on target location ..."))
|
||||||
else:
|
else:
|
||||||
self.draw_app.app.inform.emit(_("Click on reference location ..."))
|
self.draw_app.app.inform.emit(_("Click on reference location ..."))
|
||||||
|
|
||||||
self.current_storage = None
|
self.current_storage = None
|
||||||
self.geometry = []
|
self.geometry = []
|
||||||
|
|
||||||
|
@ -1485,6 +1496,37 @@ class FCApertureMove(FCShapeTool):
|
||||||
self.draw_app.select_tool("select")
|
self.draw_app.select_tool("select")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# def create_png(self):
|
||||||
|
# """
|
||||||
|
# Create a PNG file out of a list of Shapely polygons
|
||||||
|
# :return:
|
||||||
|
# """
|
||||||
|
# if len(self.draw_app.get_selected()) == 0:
|
||||||
|
# return None
|
||||||
|
#
|
||||||
|
# geo_list = [geoms.geo for geoms in self.draw_app.get_selected()]
|
||||||
|
# xmin, ymin, xmax, ymax = get_shapely_list_bounds(geo_list)
|
||||||
|
#
|
||||||
|
# iwidth = (xmax - xmin)
|
||||||
|
# iwidth = int(round(iwidth))
|
||||||
|
# iheight = (ymax - ymin)
|
||||||
|
# iheight = int(round(iheight))
|
||||||
|
# c = pngcanvas.PNGCanvas(iwidth, iheight)
|
||||||
|
#
|
||||||
|
# pixels = []
|
||||||
|
# for geom in self.draw_app.get_selected():
|
||||||
|
# m = mapping(geom.geo.exterior)
|
||||||
|
# pixels += [[coord[0], coord[1]] for coord in m['coordinates']]
|
||||||
|
# for g in geom.geo.interiors:
|
||||||
|
# m = mapping(g)
|
||||||
|
# pixels += [[coord[0], coord[1]] for coord in m['coordinates']]
|
||||||
|
# c.polyline(pixels)
|
||||||
|
# pixels = []
|
||||||
|
#
|
||||||
|
# f = open("%s.png" % 'D:\\shapely_image', "wb")
|
||||||
|
# f.write(c.dump())
|
||||||
|
# f.close()
|
||||||
|
|
||||||
def make(self):
|
def make(self):
|
||||||
# Create new geometry
|
# Create new geometry
|
||||||
dx = self.destination[0] - self.origin[0]
|
dx = self.destination[0] - self.origin[0]
|
||||||
|
@ -1499,13 +1541,14 @@ class FCApertureMove(FCShapeTool):
|
||||||
self.geometry.append(DrawToolShape(affinity.translate(select_shape.geo, xoff=dx, yoff=dy)))
|
self.geometry.append(DrawToolShape(affinity.translate(select_shape.geo, xoff=dx, yoff=dy)))
|
||||||
self.current_storage.remove(select_shape)
|
self.current_storage.remove(select_shape)
|
||||||
sel_shapes_to_be_deleted.append(select_shape)
|
sel_shapes_to_be_deleted.append(select_shape)
|
||||||
self.draw_app.on_grb_shape_complete(self.current_storage)
|
self.draw_app.on_grb_shape_complete(self.current_storage, noplot=True)
|
||||||
self.geometry = []
|
self.geometry = []
|
||||||
|
|
||||||
for shp in sel_shapes_to_be_deleted:
|
for shp in sel_shapes_to_be_deleted:
|
||||||
self.draw_app.selected.remove(shp)
|
self.draw_app.selected.remove(shp)
|
||||||
sel_shapes_to_be_deleted = []
|
sel_shapes_to_be_deleted = []
|
||||||
|
|
||||||
|
self.draw_app.plot_all()
|
||||||
self.draw_app.build_ui()
|
self.draw_app.build_ui()
|
||||||
self.draw_app.app.inform.emit(_("[success] Done. Apertures Move completed."))
|
self.draw_app.app.inform.emit(_("[success] Done. Apertures Move completed."))
|
||||||
|
|
||||||
|
@ -1531,8 +1574,9 @@ class FCApertureMove(FCShapeTool):
|
||||||
|
|
||||||
dx = data[0] - self.origin[0]
|
dx = data[0] - self.origin[0]
|
||||||
dy = data[1] - self.origin[1]
|
dy = data[1] - self.origin[1]
|
||||||
for geom in self.draw_app.get_selected():
|
# for geom in self.draw_app.get_selected():
|
||||||
geo_list.append(affinity.translate(geom.geo, xoff=dx, yoff=dy))
|
# geo_list.append(affinity.translate(geom.geo, xoff=dx, yoff=dy))
|
||||||
|
geo_list = [affinity.translate(geom.geo, xoff=dx, yoff=dy) for geom in self.draw_app.get_selected()]
|
||||||
return DrawToolUtilityShape(geo_list)
|
return DrawToolUtilityShape(geo_list)
|
||||||
|
|
||||||
|
|
||||||
|
@ -3188,7 +3232,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
|
||||||
self.options[key] = self.sender().isChecked()
|
self.options[key] = self.sender().isChecked()
|
||||||
return self.options[key]
|
return self.options[key]
|
||||||
|
|
||||||
def on_grb_shape_complete(self, storage=None, specific_shape=None):
|
def on_grb_shape_complete(self, storage=None, specific_shape=None, noplot=False):
|
||||||
self.app.log.debug("on_shape_complete()")
|
self.app.log.debug("on_shape_complete()")
|
||||||
|
|
||||||
if specific_shape:
|
if specific_shape:
|
||||||
|
@ -3209,8 +3253,9 @@ class FlatCAMGrbEditor(QtCore.QObject):
|
||||||
self.delete_utility_geometry()
|
self.delete_utility_geometry()
|
||||||
self.tool_shape.clear(update=True)
|
self.tool_shape.clear(update=True)
|
||||||
|
|
||||||
# Replot and reset tool.
|
if noplot is False:
|
||||||
self.plot_all()
|
# Replot and reset tool.
|
||||||
|
self.plot_all()
|
||||||
|
|
||||||
def add_gerber_shape(self, shape, storage):
|
def add_gerber_shape(self, shape, storage):
|
||||||
"""
|
"""
|
||||||
|
@ -4860,3 +4905,22 @@ class TransformEditorTool(FlatCAMTool):
|
||||||
else:
|
else:
|
||||||
self.app.inform.emit(
|
self.app.inform.emit(
|
||||||
_("[WARNING_NOTCL] Geometry shape skew Y cancelled..."))
|
_("[WARNING_NOTCL] Geometry shape skew Y cancelled..."))
|
||||||
|
|
||||||
|
|
||||||
|
def get_shapely_list_bounds(geometry_list):
|
||||||
|
xmin = Inf
|
||||||
|
ymin = Inf
|
||||||
|
xmax = -Inf
|
||||||
|
ymax = -Inf
|
||||||
|
|
||||||
|
for gs in geometry_list:
|
||||||
|
try:
|
||||||
|
gxmin, gymin, gxmax, gymax = gs.bounds
|
||||||
|
xmin = min([xmin, gxmin])
|
||||||
|
ymin = min([ymin, gymin])
|
||||||
|
xmax = max([xmax, gxmax])
|
||||||
|
ymax = max([ymax, gymax])
|
||||||
|
except:
|
||||||
|
log.warning("DEVELOPMENT: Tried to get bounds of empty geometry.")
|
||||||
|
|
||||||
|
return [xmin, ymin, xmax, ymax]
|
Loading…
Reference in New Issue