From 3d2fb0127e12b463781edb183559009fec6052d6 Mon Sep 17 00:00:00 2001 From: vocx-fc Date: Sun, 2 Feb 2020 14:04:22 -0600 Subject: [PATCH] Draft: new Draft_OrthoArray command It replaces the older `Draft_Array` command, and provides a task panel to select the properties, similar to the `Draft_PolarArray` and `Draft_CircularArray` commands. It can also create `App::Links` directly from this task panel, so it also replaces the `Draft_LinkArray` introduced by the LinkMerge. --- src/Mod/Arch/InitGui.py | 1 + src/Mod/Draft/CMakeLists.txt | 4 + src/Mod/Draft/InitGui.py | 1 + src/Mod/Draft/Resources/Draft.qrc | 1 + .../Resources/ui/TaskPanel_OrthoArray.ui | 441 ++++++++++++++++++ src/Mod/Draft/draftguitools/gui_arrays.py | 2 +- src/Mod/Draft/draftguitools/gui_orthoarray.py | 142 ++++++ src/Mod/Draft/draftobjects/orthoarray.py | 60 +++ .../Draft/drafttaskpanels/task_orthoarray.py | 347 ++++++++++++++ .../draftviewproviders/view_orthoarray.py | 43 ++ 10 files changed, 1041 insertions(+), 1 deletion(-) create mode 100644 src/Mod/Draft/Resources/ui/TaskPanel_OrthoArray.ui create mode 100644 src/Mod/Draft/draftguitools/gui_orthoarray.py create mode 100644 src/Mod/Draft/draftobjects/orthoarray.py create mode 100644 src/Mod/Draft/drafttaskpanels/task_orthoarray.py create mode 100644 src/Mod/Draft/draftviewproviders/view_orthoarray.py diff --git a/src/Mod/Arch/InitGui.py b/src/Mod/Arch/InitGui.py index 07962ad989..53d154c1b9 100644 --- a/src/Mod/Arch/InitGui.py +++ b/src/Mod/Arch/InitGui.py @@ -51,6 +51,7 @@ class ArchWorkbench(FreeCADGui.Workbench): import DraftGui from draftguitools import gui_circulararray from draftguitools import gui_polararray + from draftguitools import gui_orthoarray from draftguitools import gui_arrays import Arch_rc import Arch diff --git a/src/Mod/Draft/CMakeLists.txt b/src/Mod/Draft/CMakeLists.txt index 31e6e30e64..ae6a91f934 100644 --- a/src/Mod/Draft/CMakeLists.txt +++ b/src/Mod/Draft/CMakeLists.txt @@ -60,12 +60,14 @@ SET(Draft_utilities SET(Draft_objects draftobjects/__init__.py draftobjects/circulararray.py + draftobjects/orthoarray.py draftobjects/polararray.py ) SET(Draft_view_providers draftviewproviders/__init__.py draftviewproviders/view_circulararray.py + draftviewproviders/view_orthoarray.py draftviewproviders/view_polararray.py ) @@ -73,6 +75,7 @@ SET(Draft_GUI_tools draftguitools/__init__.py draftguitools/gui_base.py draftguitools/gui_circulararray.py + draftguitools/gui_orthoarray.py draftguitools/gui_polararray.py draftguitools/gui_arrays.py ) @@ -80,6 +83,7 @@ SET(Draft_GUI_tools SET(Draft_task_panels drafttaskpanels/__init__.py drafttaskpanels/task_circulararray.py + drafttaskpanels/task_orthoarray.py drafttaskpanels/task_polararray.py ) diff --git a/src/Mod/Draft/InitGui.py b/src/Mod/Draft/InitGui.py index cace902269..d864f31af4 100644 --- a/src/Mod/Draft/InitGui.py +++ b/src/Mod/Draft/InitGui.py @@ -82,6 +82,7 @@ class DraftWorkbench(FreeCADGui.Workbench): import DraftFillet from draftguitools import gui_circulararray from draftguitools import gui_polararray + from draftguitools import gui_orthoarray from draftguitools import gui_arrays FreeCADGui.addLanguagePath(":/translations") FreeCADGui.addIconPath(":/icons") diff --git a/src/Mod/Draft/Resources/Draft.qrc b/src/Mod/Draft/Resources/Draft.qrc index 0156b55822..0eef2df32e 100644 --- a/src/Mod/Draft/Resources/Draft.qrc +++ b/src/Mod/Draft/Resources/Draft.qrc @@ -152,6 +152,7 @@ ui/preferences-oca.ui ui/preferences-svg.ui ui/TaskPanel_CircularArray.ui + ui/TaskPanel_OrthoArray.ui ui/TaskPanel_PolarArray.ui ui/TaskSelectPlane.ui ui/TaskShapeString.ui diff --git a/src/Mod/Draft/Resources/ui/TaskPanel_OrthoArray.ui b/src/Mod/Draft/Resources/ui/TaskPanel_OrthoArray.ui new file mode 100644 index 0000000000..52541fe2f9 --- /dev/null +++ b/src/Mod/Draft/Resources/ui/TaskPanel_OrthoArray.ui @@ -0,0 +1,441 @@ + + + DraftOrthoArrayTaskPanel + + + + 0 + 0 + 440 + 883 + + + + + 0 + 0 + + + + + 250 + 0 + + + + Orthogonal array + + + + + + + 0 + 0 + + + + + + + + + + Distance between the elements in the Z direction. Normally, only the Z value is necessary; the other two values can give an additional shift in their respective directions. + + + Interval Z + + + + + + + + Z + + + + + + + Y + + + + + + + X + + + + + + + + 0 + 0 + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + 0 + 0 + + + + + + + 100.000000000000000 + + + + + + + + + Reset the distances + + + Reset Z + + + + + + + + + + + + If checked, the resulting objects in the array will be fused if they touch each other + + + Fuse + + + + + + + If checked, the resulting objects in the array will be Links instead of simple copies + + + Use Links + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Number of elements in the array in the specified direction, including a copy of the original object. The number must be at least 1 in each direction. + + + Number of elements + + + + + + + + X + + + + + + + Z + + + + + + + Y + + + + + + + 1 + + + 2 + + + + + + + 1 + + + 2 + + + + + + + 1 + + + 1 + + + + + + + + + + + + (Placeholder for the icon) + + + + + + + Distance between the elements in the X direction. Normally, only the X value is necessary; the other two values can give an additional shift in their respective directions. + + + Interval X + + + + + + + + Z + + + + + + + + 0 + 0 + + + + + + + 100.000000000000000 + + + + + + + + 0 + 0 + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + X + + + + + + + Y + + + + + + + + + Reset the distances + + + Reset X + + + + + + + + + + Distance between the elements in the Y direction. Normally, only the Y value is necessary; the other two values can give an additional shift in their respective directions. + + + Interval Y + + + + + + + + X + + + + + + + Y + + + + + + + Z + + + + + + + + 0 + 0 + + + + + + + + + + + + 0 + 0 + + + + + + + 100.000000000000000 + + + + + + + + 0 + 0 + + + + + + + + + + + + + Reset the distances + + + Reset Y + + + + + + + + + + + + + + Gui::InputField + QLineEdit +
Gui/InputField.h
+
+
+ + input_X_x + input_X_y + input_X_z + button_reset_X + checkbox_fuse + checkbox_link + + + +
diff --git a/src/Mod/Draft/draftguitools/gui_arrays.py b/src/Mod/Draft/draftguitools/gui_arrays.py index c0048c2e78..49a7f096f5 100644 --- a/src/Mod/Draft/draftguitools/gui_arrays.py +++ b/src/Mod/Draft/draftguitools/gui_arrays.py @@ -35,7 +35,7 @@ class ArrayGroupCommand: def GetCommands(self): """Tuple of array commands.""" - return tuple(["Draft_Array", "Draft_LinkArray", + return tuple(["Draft_OrthoArray", "Draft_PolarArray", "Draft_CircularArray", "Draft_PathArray", "Draft_PathLinkArray", "Draft_PointArray"]) diff --git a/src/Mod/Draft/draftguitools/gui_orthoarray.py b/src/Mod/Draft/draftguitools/gui_orthoarray.py new file mode 100644 index 0000000000..b7c0551f3b --- /dev/null +++ b/src/Mod/Draft/draftguitools/gui_orthoarray.py @@ -0,0 +1,142 @@ +"""Provide the Draft OrthoArray tool.""" +## @package gui_orthoarray +# \ingroup DRAFT +# \brief Provide the Draft OrthoArray tool. + +# *************************************************************************** +# * (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 * +# * * +# *************************************************************************** + +import FreeCAD as App +import FreeCADGui as Gui +import Draft +import DraftGui +import Draft_rc +from . import gui_base +from drafttaskpanels import task_orthoarray + + +if App.GuiUp: + from PySide.QtCore import QT_TRANSLATE_NOOP + # import DraftTools + from draftutils.translate import translate + # from DraftGui import displayExternal + from pivy import coin +else: + def QT_TRANSLATE_NOOP(context, text): + return text + + def translate(context, text): + return text + + +def _tr(text): + """Translate the text with the context set.""" + return translate("Draft", text) + + +# So the resource file doesn't trigger errors from code checkers (flake8) +True if Draft_rc.__name__ else False + + +class GuiCommandOrthoArray(gui_base.GuiCommandBase): + """Gui command for the OrthoArray tool.""" + + def __init__(self): + super().__init__() + self.command_name = "OrthoArray" + # self.location = None + self.mouse_event = None + self.view = None + # self.callback_move = None + self.callback_click = None + self.ui = None + self.point = App.Vector() + + def GetResources(self): + """Set icon, menu and tooltip.""" + _msg = ("Creates copies of a selected object, " + "and places the copies in an orthogonal pattern.\n" + "The properties of the array can be further modified after " + "the new object is created, including turning it into " + "a different type of array.") + d = {'Pixmap': 'Draft_Array', + 'MenuText': QT_TRANSLATE_NOOP("Draft", "Array"), + 'ToolTip': QT_TRANSLATE_NOOP("Draft", _msg)} + return d + + def Activated(self): + """Execute this when the command is called. + + We add callbacks that connect the 3D view with + the widgets of the task panel. + """ + # self.location = coin.SoLocation2Event.getClassTypeId() + self.mouse_event = coin.SoMouseButtonEvent.getClassTypeId() + self.view = Draft.get3DView() + # self.callback_move = \ + # self.view.addEventCallbackPivy(self.location, self.move) + self.callback_click = \ + self.view.addEventCallbackPivy(self.mouse_event, self.click) + + self.ui = task_orthoarray.TaskPanelOrthoArray() + # The calling class (this one) is saved in the object + # of the interface, to be able to call a function from within it. + self.ui.source_command = self + # Gui.Control.showDialog(self.ui) + DraftGui.todo.delay(Gui.Control.showDialog, self.ui) + + def click(self, event_cb=None): + """Run callback for when the mouse pointer clicks on the 3D view. + + It should act as if the Enter key was pressed, or the OK button + was pressed in the task panel. + """ + if event_cb: + event = event_cb.getEvent() + if (event.getState() != coin.SoMouseButtonEvent.DOWN + or event.getButton() != coin.SoMouseButtonEvent.BUTTON1): + return + if self.ui and self.point: + # The accept function of the interface + # should call the completed function + # of the calling class (this one). + self.ui.accept() + + def completed(self): + """Run when the command is terminated. + + We should remove the callbacks that were added to the 3D view + and then close the task panel. + """ + # self.view.removeEventCallbackPivy(self.location, + # self.callback_move) + self.view.removeEventCallbackPivy(self.mouse_event, + self.callback_click) + if Gui.Control.activeDialog(): + Gui.Snapper.off() + Gui.Control.closeDialog() + super().finish() + + +if App.GuiUp: + Gui.addCommand('Draft_OrthoArray', GuiCommandOrthoArray()) diff --git a/src/Mod/Draft/draftobjects/orthoarray.py b/src/Mod/Draft/draftobjects/orthoarray.py new file mode 100644 index 0000000000..f8d415f614 --- /dev/null +++ b/src/Mod/Draft/draftobjects/orthoarray.py @@ -0,0 +1,60 @@ +"""Provide the object code for Draft Array.""" +## @package orthoarray +# \ingroup DRAFT +# \brief Provide the object code for Draft Array. + +# *************************************************************************** +# * (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 * +# * * +# *************************************************************************** + +import FreeCAD as App +import Draft + + +def make_ortho_array(obj, + v_x=App.Vector(10, 0, 0), + v_y=App.Vector(0, 10, 0), + v_z=App.Vector(0, 0, 10), + n_x=2, + n_y=2, + n_z=1, + use_link=False): + """Create an orthogonal array from the given object.""" + obj = Draft.makeArray(obj, + arg1=v_x, arg2=v_y, arg3=v_z, + arg4=n_x, arg5=n_y, arg6=n_z, + useLink=use_link) + return obj + + +def make_ortho_array2(obj, + v_x=App.Vector(10, 0, 0), + v_y=App.Vector(0, 10, 0), + n_x=2, + n_y=2, + use_link=False): + """Create a 2D orthogonal array from the given object.""" + obj = Draft.makeArray(obj, + arg1=v_x, arg2=v_y, + arg3=n_x, arg4=n_y, + useLink=use_link) + return obj diff --git a/src/Mod/Draft/drafttaskpanels/task_orthoarray.py b/src/Mod/Draft/drafttaskpanels/task_orthoarray.py new file mode 100644 index 0000000000..170be5e810 --- /dev/null +++ b/src/Mod/Draft/drafttaskpanels/task_orthoarray.py @@ -0,0 +1,347 @@ +"""Provide the task panel for the Draft OrthoArray tool.""" +## @package task_orthoarray +# \ingroup DRAFT +# \brief Provide the task panel for the Draft OrthoArray tool. + +# *************************************************************************** +# * (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 * +# * * +# *************************************************************************** + +import FreeCAD as App +import FreeCADGui as Gui +# import Draft +import Draft_rc +import DraftVecUtils + +import PySide.QtGui as QtGui +from PySide.QtCore import QT_TRANSLATE_NOOP +# import DraftTools +from draftutils.translate import translate +# from DraftGui import displayExternal + +_Quantity = App.Units.Quantity + + +def _Msg(text, end="\n"): + """Print message with newline.""" + App.Console.PrintMessage(text + end) + + +def _Wrn(text, end="\n"): + """Print warning with newline.""" + App.Console.PrintWarning(text + end) + + +def _tr(text): + """Translate with the context set.""" + return translate("Draft", text) + + +# So the resource file doesn't trigger errors from code checkers (flake8) +True if Draft_rc else False + + +class TaskPanelOrthoArray: + """TaskPanel for the OrthoArray command. + + The names of the widgets are defined in the `.ui` file. + In this class all those widgets are automatically created + under the name `self.form.` + + The `.ui` file may use special FreeCAD widgets such as + `Gui::InputField` (based on `QLineEdit`) and + `Gui::QuantitySpinBox` (based on `QAbstractSpinBox`). + See the Doxygen documentation of the corresponding files in `src/Gui/`, + for example, `InputField.h` and `QuantitySpinBox.h`. + """ + + def __init__(self): + ui_file = ":/ui/TaskPanel_OrthoArray.ui" + self.form = Gui.PySideUic.loadUi(ui_file) + self.name = self.form.windowTitle() + + icon_name = "Draft_Array" + svg = ":/icons/" + icon_name + pix = QtGui.QPixmap(svg) + icon = QtGui.QIcon.fromTheme(icon_name, QtGui.QIcon(svg)) + self.form.setWindowIcon(icon) + self.form.label_icon.setPixmap(pix.scaled(32, 32)) + + start_x = _Quantity(100.0, App.Units.Length) + start_y = start_x + start_z = start_x + start_zero = _Quantity(0.0, App.Units.Length) + length_unit = start_x.getUserPreferred()[2] + + self.form.input_X_x.setProperty('rawValue', start_x.Value) + self.form.input_X_x.setProperty('unit', length_unit) + self.form.input_X_y.setProperty('rawValue', start_zero.Value) + self.form.input_X_y.setProperty('unit', length_unit) + self.form.input_X_z.setProperty('rawValue', start_zero.Value) + self.form.input_X_z.setProperty('unit', length_unit) + + self.form.input_Y_x.setProperty('rawValue', start_zero.Value) + self.form.input_Y_x.setProperty('unit', length_unit) + self.form.input_Y_y.setProperty('rawValue', start_y.Value) + self.form.input_Y_y.setProperty('unit', length_unit) + self.form.input_Y_z.setProperty('rawValue', start_zero.Value) + self.form.input_Y_z.setProperty('unit', length_unit) + + self.form.input_Z_x.setProperty('rawValue', start_zero.Value) + self.form.input_Z_x.setProperty('unit', length_unit) + self.form.input_Z_y.setProperty('rawValue', start_zero.Value) + self.form.input_Z_y.setProperty('unit', length_unit) + self.form.input_Z_z.setProperty('rawValue', start_z.Value) + self.form.input_Z_z.setProperty('unit', length_unit) + + self.v_X = App.Vector(100, 0, 0) + self.v_Y = App.Vector(0, 100, 0) + self.v_Z = App.Vector(0, 0, 100) + + # Old style for Qt4, avoid! + # QtCore.QObject.connect(self.form.button_reset, + # QtCore.SIGNAL("clicked()"), + # self.reset_point) + # New style for Qt5 + self.form.button_reset_X.clicked.connect(lambda: self.reset_v("X")) + self.form.button_reset_Y.clicked.connect(lambda: self.reset_v("Y")) + self.form.button_reset_Z.clicked.connect(lambda: self.reset_v("Z")) + + self.n_X = 2 + self.n_Y = 2 + self.n_Z = 1 + + self.form.spinbox_n_X.setValue(self.n_X) + self.form.spinbox_n_Y.setValue(self.n_Y) + self.form.spinbox_n_Z.setValue(self.n_Z) + + self.valid_input = False + + # When the checkbox changes, change the fuse value + self.fuse = False + self.form.checkbox_fuse.stateChanged.connect(self.set_fuse) + + self.use_link = False + self.form.checkbox_link.stateChanged.connect(self.set_link) + + def accept(self): + """Execute when clicking the OK button.""" + selection = Gui.Selection.getSelection() + n_X = self.form.spinbox_n_X.value() + n_Y = self.form.spinbox_n_Y.value() + n_Z = self.form.spinbox_n_Z.value() + self.valid_input = self.validate_input(selection, + n_X, + n_Y, + n_Z) + if self.valid_input: + self.create_object(selection) + self.print_messages(selection) + self.finish() + + def validate_input(self, selection, n_X, n_Y, n_Z): + """Check that the input is valid.""" + if not selection: + _Wrn(_tr("At least one element must be selected")) + return False + if n_X < 1 or n_Y < 1 or n_Z < 1: + _Wrn(_tr("Number of elements must be at least 1")) + return False + # Todo: each of the elements of the selection could be tested, + # not only the first one. + obj = selection[0] + if obj.isDerivedFrom("App::FeaturePython"): + _Wrn(_tr("Selection is not suitable for array")) + _Wrn(_tr("Object:") + " {0} ({1})".format(obj.Label, obj.TypeId)) + return False + return True + + def create_object(self, selection): + """Create the actual object.""" + self.v_X, self.v_Y, self.v_Z = self.set_intervals() + self.n_X, self.n_Y, self.n_Z = self.set_numbers() + + if len(selection) == 1: + sel_obj = selection[0] + else: + # This can be changed so a compound of multiple + # selected objects is produced + sel_obj = selection[0] + + self.fuse = self.form.checkbox_fuse.isChecked() + self.use_link = self.form.checkbox_link.isChecked() + + # This creates the object immediately + # obj = Draft.makeArray(sel_obj, + # self.v_X, self.v_Y, self.v_Z, + # self.n_X, self.n_Y, self.n_Z) + # if obj: + # obj.Fuse = self.fuse + + # Instead, we build the commands to execute through the parent + # of this class, the GuiCommand. + # This is needed to schedule geometry manipulation + # that would crash Coin3D if done in the event callback. + _cmd = "obj = Draft.makeArray(" + _cmd += "FreeCAD.ActiveDocument." + sel_obj.Name + ", " + _cmd += "arg1=" + DraftVecUtils.toString(self.v_X) + ", " + _cmd += "arg2=" + DraftVecUtils.toString(self.v_Y) + ", " + _cmd += "arg3=" + DraftVecUtils.toString(self.v_Z) + ", " + _cmd += "arg4=" + str(self.n_X) + ", " + _cmd += "arg5=" + str(self.n_Y) + ", " + _cmd += "arg6=" + str(self.n_Z) + ", " + _cmd += "useLink=" + str(self.use_link) + _cmd += ")" + + _cmd_list = ["FreeCADGui.addModule('Draft')", + _cmd, + "obj.Fuse = " + str(self.fuse), + "Draft.autogroup(obj)", + "FreeCAD.ActiveDocument.recompute()"] + self.source_command.commit("Ortho array", _cmd_list) + + def set_numbers(self): + """Assign the number of elements.""" + self.n_X = self.form.spinbox_n_X.value() + self.n_Y = self.form.spinbox_n_Y.value() + self.n_Z = self.form.spinbox_n_Z.value() + return self.n_X, self.n_Y, self.n_Z + + def set_intervals(self): + """Assign the interval vectors.""" + v_X_x_str = self.form.input_X_x.text() + v_X_y_str = self.form.input_X_y.text() + v_X_z_str = self.form.input_X_z.text() + self.v_X = App.Vector(_Quantity(v_X_x_str).Value, + _Quantity(v_X_y_str).Value, + _Quantity(v_X_z_str).Value) + + v_Y_x_str = self.form.input_Y_x.text() + v_Y_y_str = self.form.input_Y_y.text() + v_Y_z_str = self.form.input_Y_z.text() + self.v_Y = App.Vector(_Quantity(v_Y_x_str).Value, + _Quantity(v_Y_y_str).Value, + _Quantity(v_Y_z_str).Value) + + v_Z_x_str = self.form.input_X_x.text() + v_Z_y_str = self.form.input_X_y.text() + v_Z_z_str = self.form.input_X_z.text() + self.v_Z = App.Vector(_Quantity(v_Z_x_str).Value, + _Quantity(v_Z_y_str).Value, + _Quantity(v_Z_z_str).Value) + return self.v_X, self.v_Y, self.v_Z + + def reset_v(self, interval): + """Reset the interval to zero distance.""" + if interval == "X": + self.form.input_X_x.setProperty('rawValue', 100) + self.form.input_X_y.setProperty('rawValue', 0) + self.form.input_X_z.setProperty('rawValue', 0) + _Msg(_tr("Interval X reset:") + + " ({0}, {1}, {2})".format(self.v_X.x, + self.v_X.y, + self.v_X.z)) + elif interval == "Y": + self.form.input_Y_x.setProperty('rawValue', 0) + self.form.input_Y_y.setProperty('rawValue', 100) + self.form.input_Y_z.setProperty('rawValue', 0) + _Msg(_tr("Interval Y reset:") + + " ({0}, {1}, {2})".format(self.v_Y.x, + self.v_Y.y, + self.v_Y.z)) + elif interval == "Z": + self.form.input_Z_x.setProperty('rawValue', 0) + self.form.input_Z_y.setProperty('rawValue', 0) + self.form.input_Z_z.setProperty('rawValue', 100) + _Msg(_tr("Interval Z reset:") + + " ({0}, {1}, {2})".format(self.v_Z.x, + self.v_Z.y, + self.v_Z.z)) + + self.n_X, self.n_Y, self.n_Z = self.set_intervals() + + def print_fuse_state(self): + """Print the state translated.""" + if self.fuse: + translated_state = QT_TRANSLATE_NOOP("Draft", "True") + else: + translated_state = QT_TRANSLATE_NOOP("Draft", "False") + _Msg(_tr("Fuse:") + " {}".format(translated_state)) + + def set_fuse(self): + """Run callback when the fuse checkbox changes.""" + self.fuse = self.form.checkbox_fuse.isChecked() + self.print_fuse_state() + + def print_link_state(self): + """Print the state translated.""" + if self.use_link: + translated_state = QT_TRANSLATE_NOOP("Draft", "True") + else: + translated_state = QT_TRANSLATE_NOOP("Draft", "False") + _Msg(_tr("Use Link object:") + " {}".format(translated_state)) + + def set_link(self): + """Run callback when the link checkbox changes.""" + self.use_link = self.form.checkbox_link.isChecked() + self.print_link_state() + + def print_messages(self, selection): + """Print messages about the operation.""" + if len(selection) == 1: + sel_obj = selection[0] + else: + # This can be changed so a compound of multiple + # selected objects is produced + sel_obj = selection[0] + _Msg("{}".format(16*"-")) + _Msg("{}".format(self.name)) + _Msg(_tr("Object:") + " {}".format(sel_obj.Label)) + _Msg(_tr("Number of X elements:") + " {}".format(self.n_X)) + _Msg(_tr("Interval X:") + + " ({0}, {1}, {2})".format(self.v_X.x, + self.v_X.y, + self.v_X.z)) + _Msg(_tr("Number of Y elements:") + " {}".format(self.n_Y)) + _Msg(_tr("Interval Y:") + + " ({0}, {1}, {2})".format(self.v_Y.x, + self.v_Y.y, + self.v_Y.z)) + _Msg(_tr("Number of Z elements:") + " {}".format(self.n_Z)) + _Msg(_tr("Interval Z:") + + " ({0}, {1}, {2})".format(self.v_Z.x, + self.v_Z.y, + self.v_Z.z)) + self.print_fuse_state() + self.print_link_state() + + def reject(self): + """Run when clicking the Cancel button.""" + _Msg(_tr("Aborted:") + " {}".format(self.name)) + self.finish() + + def finish(self): + """Run at the end after OK or Cancel.""" + # App.ActiveDocument.commitTransaction() + Gui.ActiveDocument.resetEdit() + # Runs the parent command to complete the call + self.source_command.completed() diff --git a/src/Mod/Draft/draftviewproviders/view_orthoarray.py b/src/Mod/Draft/draftviewproviders/view_orthoarray.py new file mode 100644 index 0000000000..461475a557 --- /dev/null +++ b/src/Mod/Draft/draftviewproviders/view_orthoarray.py @@ -0,0 +1,43 @@ +"""Provide the view provider code for Draft Array.""" +## @package view_orthoarray +# \ingroup DRAFT +# \brief Provide the view provider code for Draft Array. + +# *************************************************************************** +# * (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 * +# * * +# *************************************************************************** + +import Draft +import Draft_rc +ViewProviderDraftArray = Draft._ViewProviderDraftArray + +# So the resource file doesn't trigger errors from code checkers (flake8) +True if Draft_rc else False + + +class ViewProviderOrthoArray(ViewProviderDraftArray): + + def __init__(self, vobj): + super().__init__(self, vobj) + + def getIcon(self): + return ":/icons/Draft_Array"