From 66959b268894baade0125a0c279e3de5ce72fd96 Mon Sep 17 00:00:00 2001 From: vocx-fc Date: Sun, 24 May 2020 21:28:58 -0500 Subject: [PATCH] Draft: clean up CircularArray code Avoid `Draft.py` in the `make_circular_array` function because it creates a circular dependency. Use function to find the object in `make_circular_array`. Now the make function accepts as input a `"String"` which must be the `Label` of an object in the document, so it is easier to create arrays interactively from the Python console. Clean up the GuiCommand and task panel code, and avoid printing messages to the terminal, as this is already done by the make function. --- .../Draft/draftguitools/gui_circulararray.py | 14 +++-- src/Mod/Draft/draftmake/make_circulararray.py | 61 +++++++++++++------ .../drafttaskpanels/task_circulararray.py | 20 +++--- 3 files changed, 60 insertions(+), 35 deletions(-) diff --git a/src/Mod/Draft/draftguitools/gui_circulararray.py b/src/Mod/Draft/draftguitools/gui_circulararray.py index be5e82b5d7..78ecaf2a82 100644 --- a/src/Mod/Draft/draftguitools/gui_circulararray.py +++ b/src/Mod/Draft/draftguitools/gui_circulararray.py @@ -32,11 +32,12 @@ import FreeCAD as App import FreeCADGui as Gui import Draft import Draft_rc # include resources, icons, ui files +import draftutils.todo as todo + from draftutils.messages import _msg, _log from draftutils.translate import _tr from draftguitools import gui_base from drafttaskpanels import task_circulararray -import draftutils.todo as todo # The module is used to prevent complaints from code checkers (flake8) bool(Draft_rc.__name__) @@ -58,11 +59,12 @@ class CircularArray(gui_base.GuiCommandBase): def GetResources(self): """Set icon, menu and tooltip.""" - _tip = ("Creates copies of a selected object, " - "and places the copies in a circular 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.") + _tip = ("Creates copies of the selected object, " + "and places the copies in a radial pattern\n" + "creating various circular layers.\n" + "\n" + "The array can be turned into an orthogonal " + "or a polar array by changing its type.") d = {'Pixmap': 'Draft_CircularArray', 'MenuText': QT_TRANSLATE_NOOP("Draft", "Circular array"), diff --git a/src/Mod/Draft/draftmake/make_circulararray.py b/src/Mod/Draft/draftmake/make_circulararray.py index 0a6411f4ee..51918d9b3b 100644 --- a/src/Mod/Draft/draftmake/make_circulararray.py +++ b/src/Mod/Draft/draftmake/make_circulararray.py @@ -26,39 +26,43 @@ # \brief Provides functions for creating circular arrays in a plane. import FreeCAD as App -import Draft -# import draftmake.make_array as make_array + +import draftmake.make_array as make_array import draftutils.utils as utils + from draftutils.messages import _msg, _err from draftutils.translate import _tr -def make_circular_array(obj, - r_distance=100, tan_distance=100, - number=2, symmetry=1, +def make_circular_array(base_object, + r_distance=100, tan_distance=50, + number=3, symmetry=1, axis=App.Vector(0, 0, 1), center=App.Vector(0, 0, 0), use_link=True): """Create a circular array from the given object. Parameters ---------- - obj: Part::Feature - Any type of object that has a `Part::TopoShape` - that can be duplicated. + base_object: Part::Feature or str + Any of object that has a `Part::TopoShape` that can be duplicated. + This means most 2D and 3D objects produced with any workbench. + If it is a string, it must be the `Label` of that object. + Since a label is not guaranteed to be unique in a document, + it will use the first object found with this label. r_distance: float, optional It defaults to `100`. Radial distance to the next ring of circular arrays. tan_distance: float, optional - It defaults to `100`. + It defaults to `50`. The tangential distance between two elements located in the same circular ring. The tangential distance together with the radial distance determine how many copies are created. number: int, optional - It defaults to 2. + It defaults to 3. The number of layers or rings of repeated objects. The original object stays at the center, and is counted as a layer itself. So, if you want at least one layer of circular @@ -88,7 +92,7 @@ def make_circular_array(obj, It defaults to `True`. If it is `True` the produced copies are not `Part::TopoShape` copies, but rather `App::Link` objects. - The Links repeat the shape of the original `obj` exactly, + The Links repeat the shape of the original `base_object` exactly, and therefore the resulting array is more memory efficient. Also, when `use_link` is `True`, the `Fuse` property @@ -103,12 +107,31 @@ def make_circular_array(obj, Returns ------- Part::FeaturePython - A scripted object with `Proxy.Type='Array'`. + A scripted object of type `'Array'`. Its `Shape` is a compound of the copies of the original object. + + None + If there is a problem it will return `None`. + + See Also + -------- + make_ortho_array, make_polar_array, make_path_array, make_point_array """ _name = "make_circular_array" utils.print_header(_name, _tr("Circular array")) + if isinstance(base_object, str): + base_object_str = base_object + + found, base_object = utils.find_object(base_object, + doc=App.activeDocument()) + if not found: + _msg("base_object: {}".format(base_object_str)) + _err(_tr("Wrong input: object not in document.")) + return None + + _msg("base_object: {}".format(base_object.Label)) + _msg("r_distance: {}".format(r_distance)) _msg("tan_distance: {}".format(tan_distance)) @@ -140,12 +163,12 @@ def make_circular_array(obj, _err(_tr("Wrong input: must be a vector.")) return None - _msg("use_link: {}".format(bool(use_link))) + use_link = bool(use_link) + _msg("use_link: {}".format(use_link)) - # new_obj = make_array.make_array() - new_obj = Draft.makeArray(obj, - arg1=r_distance, arg2=tan_distance, - arg3=axis, arg4=center, - arg5=number, arg6=symmetry, - use_link=use_link) + new_obj = make_array.make_array(base_object, + arg1=r_distance, arg2=tan_distance, + arg3=axis, arg4=center, + arg5=number, arg6=symmetry, + use_link=use_link) return new_obj diff --git a/src/Mod/Draft/drafttaskpanels/task_circulararray.py b/src/Mod/Draft/drafttaskpanels/task_circulararray.py index 7ec5f7c565..7c41b2cf14 100644 --- a/src/Mod/Draft/drafttaskpanels/task_circulararray.py +++ b/src/Mod/Draft/drafttaskpanels/task_circulararray.py @@ -33,9 +33,10 @@ import FreeCADGui as Gui import Draft_rc # include resources, icons, ui files import DraftVecUtils import draftutils.utils as utils + +from FreeCAD import Units as U from draftutils.messages import _msg, _wrn, _err, _log from draftutils.translate import _tr -from FreeCAD import Units as U # The module is used to prevent complaints from code checkers (flake8) bool(Draft_rc.__name__) @@ -198,7 +199,8 @@ class TaskPanelCircularArray: self.center) if self.valid_input: self.create_object() - self.print_messages() + # The internal function already displays messages + # self.print_messages() self.finish() def validate_input(self, selection, @@ -266,15 +268,13 @@ class TaskPanelCircularArray: sel_obj = self.selection[0] # This creates the object immediately - # obj = Draft.makeArray(sel_obj, - # self.r_distance, self.tan_distance, - # self.axis, self.center, - # self.number, self.symmetry, - # self.use_link) - # if obj: - # obj.Fuse = self.fuse + # obj = Draft.make_circular_array(sel_obj, + # self.r_distance, self.tan_distance, + # self.number, self.symmetry, + # self.axis, self.center, + # self.use_link) - # Instead, we build the commands to execute through the parent + # Instead, we build the commands to execute through the caller # of this class, the GuiCommand. # This is needed to schedule geometry manipulation # that would crash Coin3D if done in the event callback.