From e87245aeef6bdd9e4c81b87e8cbf96fb5375a9b8 Mon Sep 17 00:00:00 2001 From: vocx-fc Date: Fri, 10 Apr 2020 18:49:14 -0500 Subject: [PATCH] Draft: move Mirror GuiCommand to gui_mirror module --- src/Mod/Draft/CMakeLists.txt | 1 + src/Mod/Draft/DraftTools.py | 127 +------------ src/Mod/Draft/draftguitools/gui_mirror.py | 214 ++++++++++++++++++++++ 3 files changed, 216 insertions(+), 126 deletions(-) create mode 100644 src/Mod/Draft/draftguitools/gui_mirror.py diff --git a/src/Mod/Draft/CMakeLists.txt b/src/Mod/Draft/CMakeLists.txt index 02509d3647..2ac6cf24db 100644 --- a/src/Mod/Draft/CMakeLists.txt +++ b/src/Mod/Draft/CMakeLists.txt @@ -125,6 +125,7 @@ SET(Modifier_tools draftguitools/gui_pointarray.py draftguitools/gui_polararray.py draftguitools/gui_clone.py + draftguitools/gui_mirror.py ) SET(Draft_GUI_tools diff --git a/src/Mod/Draft/DraftTools.py b/src/Mod/Draft/DraftTools.py index e36c8cdff9..30f52b6018 100644 --- a/src/Mod/Draft/DraftTools.py +++ b/src/Mod/Draft/DraftTools.py @@ -195,131 +195,7 @@ from draftguitools.gui_patharray import PathLinkArray from draftguitools.gui_pointarray import PointArray import draftguitools.gui_arrays from draftguitools.gui_clone import Draft_Clone - - -class Mirror(Modifier): - """The Draft_Mirror FreeCAD command definition""" - - def GetResources(self): - return {'Pixmap' : 'Draft_Mirror', - 'Accel' : "M, I", - 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Mirror", "Mirror"), - 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Mirror", "Mirrors the selected objects along a line defined by two points")} - - def Activated(self): - self.name = translate("draft","Mirror", utf8_decode=True) - Modifier.Activated(self,self.name) - self.ghost = None - if self.ui: - if not FreeCADGui.Selection.getSelection(): - self.ui.selectUi() - FreeCAD.Console.PrintMessage(translate("draft", "Select an object to mirror")+"\n") - self.call = self.view.addEventCallback("SoEvent",selectObject) - else: - self.proceed() - - def proceed(self): - if self.call: self.view.removeEventCallback("SoEvent",self.call) - self.sel = FreeCADGui.Selection.getSelection() - self.ui.pointUi(self.name) - self.ui.modUi() - self.ui.xValue.setFocus() - self.ui.xValue.selectAll() - # self.ghost = trackers.ghostTracker(self.sel) TODO: solve this (see below) - self.call = self.view.addEventCallback("SoEvent",self.action) - FreeCAD.Console.PrintMessage(translate("draft", "Pick start point of mirror line")+"\n") - self.ui.isCopy.hide() - - def finish(self,closed=False,cont=False): - if self.ghost: - self.ghost.finalize() - Modifier.finish(self) - if cont and self.ui: - if self.ui.continueMode: - FreeCADGui.Selection.clearSelection() - self.Activated() - - def mirror(self,p1,p2,copy=False): - """mirroring the real shapes""" - sel = '[' - for o in self.sel: - if len(sel) > 1: - sel += ',' - sel += 'FreeCAD.ActiveDocument.'+o.Name - sel += ']' - FreeCADGui.addModule("Draft") - self.commit(translate("draft","Mirror"), - ['Draft.mirror('+sel+','+DraftVecUtils.toString(p1)+','+DraftVecUtils.toString(p2)+')', - 'FreeCAD.ActiveDocument.recompute()']) - - def action(self,arg): - """scene event handler""" - if arg["Type"] == "SoKeyboardEvent": - if arg["Key"] == "ESCAPE": - self.finish() - elif arg["Type"] == "SoLocation2Event": #mouse movement detection - self.point,ctrlPoint,info = getPoint(self,arg) - if (len(self.node) > 0): - last = self.node[-1] - if self.ghost: - if self.point != last: - # TODO : the following doesn't work at the moment - mu = self.point.sub(last).normalize() - if FreeCAD.GuiUp: - mv = FreeCADGui.ActiveDocument.ActiveView.getViewDirection().negative() - else: - mv = FreeCAD.Vector(0,0,1) - mw = mv.cross(mu) - import WorkingPlane - tm = WorkingPlane.plane(u=mu,v=mv,w=mw,pos=last).getPlacement().toMatrix() - m = self.ghost.getMatrix() - m = m.multiply(tm.inverse()) - m.scale(FreeCAD.Vector(1,1,-1)) - m = m.multiply(tm) - m.scale(FreeCAD.Vector(-1,1,1)) - self.ghost.setMatrix(m) - if self.extendedCopy: - if not hasMod(arg,MODALT): self.finish() - redraw3DView() - elif arg["Type"] == "SoMouseButtonEvent": - if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"): - if self.point: - self.ui.redraw() - if (self.node == []): - self.node.append(self.point) - self.ui.isRelative.show() - if self.ghost: - self.ghost.on() - FreeCAD.Console.PrintMessage(translate("draft", "Pick end point of mirror line")+"\n") - if self.planetrack: - self.planetrack.set(self.point) - else: - last = self.node[0] - if self.ui.isCopy.isChecked() or hasMod(arg,MODALT): - self.mirror(last,self.point,True) - else: - self.mirror(last,self.point) - if hasMod(arg,MODALT): - self.extendedCopy = True - else: - self.finish(cont=True) - - def numericInput(self,numx,numy,numz): - """this function gets called by the toolbar when valid x, y, and z have been entered there""" - self.point = Vector(numx,numy,numz) - if not self.node: - self.node.append(self.point) - if self.ghost: - self.ghost.on() - FreeCAD.Console.PrintMessage(translate("draft", "Pick end point of mirror line")+"\n") - else: - last = self.node[-1] - if self.ui.isCopy.isChecked(): - self.mirror(last,self.point,True) - else: - self.mirror(last,self.point) - self.finish() - +from draftguitools.gui_mirror import Mirror # --------------------------------------------------------------------------- # Snap tools @@ -348,7 +224,6 @@ from draftguitools.gui_snaps import ShowSnapBar # drawing commands # modification commands -FreeCADGui.addCommand('Draft_Mirror',Mirror()) # context commands diff --git a/src/Mod/Draft/draftguitools/gui_mirror.py b/src/Mod/Draft/draftguitools/gui_mirror.py new file mode 100644 index 0000000000..6c48e72585 --- /dev/null +++ b/src/Mod/Draft/draftguitools/gui_mirror.py @@ -0,0 +1,214 @@ +# *************************************************************************** +# * (c) 2009, 2010 Yorik van Havre * +# * (c) 2009, 2010 Ken Cline * +# * (c) 2020 Eliud Cabrera Castillo * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** +"""Provides tools for creating mirrored objects with the Draft Workbench. + +The mirror tool creates a `Part::Mirroring` object, which is the same +as the one created by the Part module. + +Perhaps in the future a specific Draft `Mirror` object can be defined. +""" +## @package gui_mirror +# \ingroup DRAFT +# \brief Provides tools for creating mirrored objects with the Draft Workbench. + +from PySide.QtCore import QT_TRANSLATE_NOOP + +import FreeCAD as App +import FreeCADGui as Gui +import Draft_rc +import DraftVecUtils +import WorkingPlane +import draftguitools.gui_base_original as gui_base_original +import draftguitools.gui_tool_utils as gui_tool_utils +from draftutils.messages import _msg +from draftutils.translate import translate + +# The module is used to prevent complaints from code checkers (flake8) +True if Draft_rc.__name__ else False + + +class Mirror(gui_base_original.Modifier): + """Gui Command for the Mirror tool.""" + + def GetResources(self): + """Set icon, menu and tooltip.""" + _tip = ("Mirrors the selected objects along a line " + "defined by two points.") + + return {'Pixmap': 'Draft_Mirror', + 'Accel': "M, I", + 'MenuText': QT_TRANSLATE_NOOP("Draft_Mirror", "Mirror"), + 'ToolTip': QT_TRANSLATE_NOOP("Draft_Mirror", _tip)} + + def Activated(self): + """Execute when the command is called.""" + self.name = translate("draft", "Mirror") + super().Activated(name=self.name) + self.ghost = None + if self.ui: + if not Gui.Selection.getSelection(): + self.ui.selectUi() + _msg(translate("draft", "Select an object to mirror")) + self.call = \ + self.view.addEventCallback("SoEvent", + gui_tool_utils.selectObject) + else: + self.proceed() + + def proceed(self): + """Proceed with the command if one object was selected.""" + if self.call: + self.view.removeEventCallback("SoEvent", self.call) + + self.sel = Gui.Selection.getSelection() + self.ui.pointUi(self.name) + self.ui.modUi() + self.ui.xValue.setFocus() + self.ui.xValue.selectAll() + # self.ghost = trackers.ghostTracker(self.sel) + # TODO: solve this (see below) + self.call = self.view.addEventCallback("SoEvent", self.action) + _msg(translate("draft", "Pick start point of mirror line")) + self.ui.isCopy.hide() + + def finish(self, closed=False, cont=False): + """Terminate the operation of the tool.""" + if self.ghost: + self.ghost.finalize() + super().finish() + if cont and self.ui: + if self.ui.continueMode: + Gui.Selection.clearSelection() + self.Activated() + + def mirror(self, p1, p2, copy=False): + """Mirror the real shapes.""" + sel = '[' + for o in self.sel: + if len(sel) > 1: + sel += ', ' + sel += 'FreeCAD.ActiveDocument.' + o.Name + sel += ']' + Gui.addModule("Draft") + _cmd = 'Draft.mirror' + _cmd += '(' + _cmd += sel + ', ' + _cmd += DraftVecUtils.toString(p1) + ', ' + _cmd += DraftVecUtils.toString(p2) + _cmd += ')' + _cmd_list = ['m = ' + _cmd, + 'FreeCAD.ActiveDocument.recompute()'] + self.commit(translate("draft", "Mirror"), + _cmd_list) + + def action(self, arg): + """Handle the 3D scene events. + + This is installed as an EventCallback in the Inventor view. + + Parameters + ---------- + arg: dict + Dictionary with strings that indicates the type of event received + from the 3D view. + """ + if arg["Type"] == "SoKeyboardEvent": + if arg["Key"] == "ESCAPE": + self.finish() + elif arg["Type"] == "SoLocation2Event": # mouse movement detection + (self.point, + ctrlPoint, info) = gui_tool_utils.getPoint(self, arg) + if len(self.node) > 0: + last = self.node[-1] + if self.ghost: + if self.point != last: + # TODO: the following doesn't work at the moment + mu = self.point.sub(last).normalize() + # This part used to test for the GUI to obtain + # the camera view but this is unnecessary + # as this command is always launched in the GUI. + _view = Gui.ActiveDocument.ActiveView + mv = _view.getViewDirection().negative() + mw = mv.cross(mu) + _plane = WorkingPlane.plane(u=mu, v=mv, w=mw, + pos=last) + tm = _plane.getPlacement().toMatrix() + m = self.ghost.getMatrix() + m = m.multiply(tm.inverse()) + m.scale(App.Vector(1, 1, -1)) + m = m.multiply(tm) + m.scale(App.Vector(-1, 1, 1)) + self.ghost.setMatrix(m) + if self.extendedCopy: + if not gui_tool_utils.hasMod(arg, gui_tool_utils.MODALT): + self.finish() + gui_tool_utils.redraw3DView() + elif arg["Type"] == "SoMouseButtonEvent": + if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"): + if self.point: + self.ui.redraw() + if (self.node == []): + self.node.append(self.point) + self.ui.isRelative.show() + if self.ghost: + self.ghost.on() + _msg(translate("draft", + "Pick end point of mirror line")) + if self.planetrack: + self.planetrack.set(self.point) + else: + last = self.node[0] + if (self.ui.isCopy.isChecked() + or gui_tool_utils.hasMod(arg, gui_tool_utils.MODALT)): + self.mirror(last, self.point, True) + else: + self.mirror(last, self.point) + if gui_tool_utils.hasMod(arg, gui_tool_utils.MODALT): + self.extendedCopy = True + else: + self.finish(cont=True) + + def numericInput(self, numx, numy, numz): + """Validate the entry fields in the user interface. + + This function is called by the toolbar or taskpanel interface + when valid x, y, and z have been entered in the input fields. + """ + self.point = App.Vector(numx, numy, numz) + if not self.node: + self.node.append(self.point) + if self.ghost: + self.ghost.on() + _msg(translate("draft", "Pick end point of mirror line")) + else: + last = self.node[-1] + if self.ui.isCopy.isChecked(): + self.mirror(last, self.point, True) + else: + self.mirror(last, self.point) + self.finish() + + +Gui.addCommand('Draft_Mirror', Mirror())