diff --git a/src/Mod/Draft/CMakeLists.txt b/src/Mod/Draft/CMakeLists.txt index 001c777535..37561ce8cb 100644 --- a/src/Mod/Draft/CMakeLists.txt +++ b/src/Mod/Draft/CMakeLists.txt @@ -69,6 +69,7 @@ SET(Draft_make_functions draftmake/make_circle.py draftmake/make_clone.py draftmake/make_ellipse.py + draftmake/make_facebinder.py draftmake/make_line.py draftmake/make_polygon.py draftmake/make_point.py @@ -86,6 +87,7 @@ SET(Draft_objects draftobjects/circle.py draftobjects/clone.py draftobjects/ellipse.py + draftobjects/facebinder.py draftobjects/orthoarray.py draftobjects/polararray.py draftobjects/arc_3points.py @@ -106,6 +108,7 @@ SET(Draft_view_providers draftviewproviders/view_base.py draftviewproviders/view_circulararray.py draftviewproviders/view_clone.py + draftviewproviders/view_facebinder.py draftviewproviders/view_orthoarray.py draftviewproviders/view_polararray.py draftviewproviders/view_draft_annotation.py diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index 877af7442b..443f1e79c6 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -246,6 +246,13 @@ if FreeCAD.GuiUp: from draftviewproviders.view_point import ViewProviderPoint from draftviewproviders.view_point import _ViewProviderPoint +# facebinder +from draftmake.make_facebinder import make_facebinder, makeFacebinder +from draftobjects.facebinder import Facebinder, _Facebinder +if FreeCAD.GuiUp: + from draftviewproviders.view_facebinder import ViewProviderFacebinder + from draftviewproviders.view_facebinder import _ViewProviderFacebinder + # working plane proxy from draftmake.make_wpproxy import make_workingplaneproxy from draftmake.make_wpproxy import makeWorkingPlaneProxy @@ -2001,23 +2008,6 @@ def heal(objlist=None,delete=True,reparent=True): for n in dellist: FreeCAD.ActiveDocument.removeObject(n) -def makeFacebinder(selectionset,name="Facebinder"): - """makeFacebinder(selectionset,[name]): creates a Facebinder object from a selection set. - Only faces will be added.""" - if not FreeCAD.ActiveDocument: - FreeCAD.Console.PrintError("No active document. Aborting\n") - return - if not isinstance(selectionset,list): - selectionset = [selectionset] - fb = FreeCAD.ActiveDocument.addObject("Part::FeaturePython",name) - _Facebinder(fb) - if gui: - _ViewProviderFacebinder(fb.ViewObject) - faces = [] - fb.Proxy.addSubobjects(fb,selectionset) - select(fb) - return fb - def upgrade(objects,delete=False,force=None): """upgrade(objects,delete=False,force=None): Upgrades the given object(s) (can be @@ -3734,102 +3724,4 @@ class _ShapeString(_DraftObject): return ret -class _Facebinder(_DraftObject): - """The Draft Facebinder object""" - def __init__(self,obj): - _DraftObject.__init__(self,obj,"Facebinder") - obj.addProperty("App::PropertyLinkSubList","Faces","Draft",QT_TRANSLATE_NOOP("App::Property","Linked faces")) - obj.addProperty("App::PropertyBool","RemoveSplitter","Draft",QT_TRANSLATE_NOOP("App::Property","Specifies if splitter lines must be removed")) - obj.addProperty("App::PropertyDistance","Extrusion","Draft",QT_TRANSLATE_NOOP("App::Property","An optional extrusion value to be applied to all faces")) - obj.addProperty("App::PropertyBool","Sew","Draft",QT_TRANSLATE_NOOP("App::Property","This specifies if the shapes sew")) - - - def execute(self,obj): - import Part - pl = obj.Placement - if not obj.Faces: - return - faces = [] - for sel in obj.Faces: - for f in sel[1]: - if "Face" in f: - try: - fnum = int(f[4:])-1 - faces.append(sel[0].Shape.Faces[fnum]) - except(IndexError,Part.OCCError): - print("Draft: wrong face index") - return - if not faces: - return - try: - if len(faces) > 1: - sh = None - if hasattr(obj,"Extrusion"): - if obj.Extrusion.Value: - for f in faces: - f = f.extrude(f.normalAt(0,0).multiply(obj.Extrusion.Value)) - if sh: - sh = sh.fuse(f) - else: - sh = f - if not sh: - sh = faces.pop() - sh = sh.multiFuse(faces) - if hasattr(obj,"Sew"): - if obj.Sew: - sh = sh.copy() - sh.sewShape() - if hasattr(obj,"RemoveSplitter"): - if obj.RemoveSplitter: - sh = sh.removeSplitter() - else: - sh = sh.removeSplitter() - else: - sh = faces[0] - if hasattr(obj,"Extrusion"): - if obj.Extrusion.Value: - sh = sh.extrude(sh.normalAt(0,0).multiply(obj.Extrusion.Value)) - sh.transformShape(sh.Matrix, True) - except Part.OCCError: - print("Draft: error building facebinder") - return - obj.Shape = sh - obj.Placement = pl - - def addSubobjects(self,obj,facelinks): - """adds facelinks to this facebinder""" - objs = obj.Faces - for o in facelinks: - if isinstance(o,tuple) or isinstance(o,list): - if o[0].Name != obj.Name: - objs.append(tuple(o)) - else: - for el in o.SubElementNames: - if "Face" in el: - if o.Object.Name != obj.Name: - objs.append((o.Object,el)) - obj.Faces = objs - self.execute(obj) - - -class _ViewProviderFacebinder(_ViewProviderDraft): - def __init__(self,vobj): - _ViewProviderDraft.__init__(self,vobj) - - def getIcon(self): - return ":/icons/Draft_Facebinder_Provider.svg" - - def setEdit(self,vobj,mode): - import DraftGui - taskd = DraftGui.FacebinderTaskPanel() - taskd.obj = vobj.Object - taskd.update() - FreeCADGui.Control.showDialog(taskd) - return True - - def unsetEdit(self,vobj,mode): - FreeCADGui.Control.closeDialog() - return False - - ## @} diff --git a/src/Mod/Draft/draftmake/make_facebinder.py b/src/Mod/Draft/draftmake/make_facebinder.py new file mode 100644 index 0000000000..a4c5022ccd --- /dev/null +++ b/src/Mod/Draft/draftmake/make_facebinder.py @@ -0,0 +1,66 @@ +# *************************************************************************** +# * Copyright (c) 2009, 2010 Yorik van Havre * +# * Copyright (c) 2009, 2010 Ken Cline * +# * Copyright (c) 2020 FreeCAD Developers * +# * * +# * 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. * +# * * +# * This program 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 this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** +"""This module provides the code for Draft make_facebinder function. +""" +## @package make_facebinder +# \ingroup DRAFT +# \brief This module provides the code for Draft make_facebinder function. + +import FreeCAD as App + +from draftutils.gui_utils import select + +from draftobjects.facebinder import Facebinder +if App.GuiUp: + from draftviewproviders.view_facebinder import ViewProviderFacebinder + + +def make_facebinder(selectionset, name="Facebinder"): + """makeFacebinder(selectionset, [name]) + + Creates a Facebinder object from a selection set. + + Parameters + ---------- + selectionset : + Only faces will be added. + + name : string (default = "Facebinder") + Name of the created object + """ + if not App.ActiveDocument: + App.Console.PrintError("No active document. Aborting\n") + return + if not isinstance(selectionset,list): + selectionset = [selectionset] + fb = App.ActiveDocument.addObject("Part::FeaturePython",name) + Facebinder(fb) + if App.GuiUp: + ViewProviderFacebinder(fb.ViewObject) + faces = [] # unused variable? + fb.Proxy.addSubobjects(fb, selectionset) + select(fb) + return fb + + +makeFacebinder = make_facebinder \ No newline at end of file diff --git a/src/Mod/Draft/draftobjects/facebinder.py b/src/Mod/Draft/draftobjects/facebinder.py new file mode 100644 index 0000000000..57610cce86 --- /dev/null +++ b/src/Mod/Draft/draftobjects/facebinder.py @@ -0,0 +1,126 @@ +# *************************************************************************** +# * Copyright (c) 2009, 2010 Yorik van Havre * +# * Copyright (c) 2009, 2010 Ken Cline * +# * Copyright (c) 2020 FreeCAD Developers * +# * * +# * 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. * +# * * +# * This program 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 this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** +"""This module provides the object code for Draft Facebinder. +""" +## @package facebinder +# \ingroup DRAFT +# \brief This module provides the object code for Draft Facebinder. + +import FreeCAD as App + +from PySide.QtCore import QT_TRANSLATE_NOOP + +from draftobjects.base import DraftObject + + +class Facebinder(DraftObject): + """The Draft Facebinder object""" + def __init__(self,obj): + super(Facebinder, self).__init__(obj, "Facebinder") + + _tip = "Linked faces" + obj.addProperty("App::PropertyLinkSubList", "Faces", + "Draft", QT_TRANSLATE_NOOP("App::Property", _tip)) + + _tip = "Specifies if splitter lines must be removed" + obj.addProperty("App::PropertyBool","RemoveSplitter", + "Draft", QT_TRANSLATE_NOOP("App::Property", _tip)) + + _tip = "An optional extrusion value to be applied to all faces" + obj.addProperty("App::PropertyDistance","Extrusion", + "Draft" ,QT_TRANSLATE_NOOP("App::Property", _tip)) + + _tip = "This specifies if the shapes sew" + obj.addProperty("App::PropertyBool","Sew", + "Draft", QT_TRANSLATE_NOOP("App::Property", _tip)) + + + def execute(self,obj): + import Part + pl = obj.Placement + if not obj.Faces: + return + faces = [] + for sel in obj.Faces: + for f in sel[1]: + if "Face" in f: + try: + fnum = int(f[4:])-1 + faces.append(sel[0].Shape.Faces[fnum]) + except(IndexError, Part.OCCError): + print("Draft: wrong face index") + return + if not faces: + return + try: + if len(faces) > 1: + sh = None + if hasattr(obj, "Extrusion"): + if obj.Extrusion.Value: + for f in faces: + f = f.extrude(f.normalAt(0,0).multiply(obj.Extrusion.Value)) + if sh: + sh = sh.fuse(f) + else: + sh = f + if not sh: + sh = faces.pop() + sh = sh.multiFuse(faces) + if hasattr(obj, "Sew"): + if obj.Sew: + sh = sh.copy() + sh.sewShape() + if hasattr(obj, "RemoveSplitter"): + if obj.RemoveSplitter: + sh = sh.removeSplitter() + else: + sh = sh.removeSplitter() + else: + sh = faces[0] + if hasattr(obj, "Extrusion"): + if obj.Extrusion.Value: + sh = sh.extrude(sh.normalAt(0,0).multiply(obj.Extrusion.Value)) + sh.transformShape(sh.Matrix, True) + except Part.OCCError: + print("Draft: error building facebinder") + return + obj.Shape = sh + obj.Placement = pl + + def addSubobjects(self,obj,facelinks): + """adds facelinks to this facebinder""" + objs = obj.Faces + for o in facelinks: + if isinstance(o, tuple) or isinstance(o, list): + if o[0].Name != obj.Name: + objs.append(tuple(o)) + else: + for el in o.SubElementNames: + if "Face" in el: + if o.Object.Name != obj.Name: + objs.append((o.Object, el)) + obj.Faces = objs + self.execute(obj) + + +_Facebinder = Facebinder \ No newline at end of file diff --git a/src/Mod/Draft/draftviewproviders/view_facebinder.py b/src/Mod/Draft/draftviewproviders/view_facebinder.py new file mode 100644 index 0000000000..e339d060e8 --- /dev/null +++ b/src/Mod/Draft/draftviewproviders/view_facebinder.py @@ -0,0 +1,56 @@ +# *************************************************************************** +# * Copyright (c) 2009, 2010 Yorik van Havre * +# * Copyright (c) 2009, 2010 Ken Cline * +# * Copyright (c) 2020 FreeCAD Developers * +# * * +# * 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. * +# * * +# * This program 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 this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** +"""This module provides the view provider code for Draft Facebinder object. +""" +## @package view_facebinder +# \ingroup DRAFT +# \brief This module provides the view provider code for Draft Facebinder + +import FreeCAD as App +import FreeCADGui as Gui + +import DraftGui + +from draftviewproviders.view_base import ViewProviderDraft + + +class ViewProviderFacebinder(ViewProviderDraft): + def __init__(self,vobj): + super(ViewProviderFacebinder, self).__init__(vobj) + + def getIcon(self): + return ":/icons/Draft_Facebinder_Provider.svg" + + def setEdit(self,vobj,mode): + taskd = DraftGui.FacebinderTaskPanel() + taskd.obj = vobj.Object + taskd.update() + Gui.Control.showDialog(taskd) + return True + + def unsetEdit(self,vobj,mode): + Gui.Control.closeDialog() + return False + + +_ViewProviderFacebinder = ViewProviderFacebinder \ No newline at end of file