From 08448d198eef734e5d0c8930c871e023338a3bc6 Mon Sep 17 00:00:00 2001 From: carlopav Date: Sun, 26 Apr 2020 15:01:02 +0200 Subject: [PATCH] Draft: split upgrade from Draft.py . --- src/Mod/Draft/CMakeLists.txt | 1 + src/Mod/Draft/Draft.py | 409 +-------------------- src/Mod/Draft/draftfunctions/upgrade.py | 465 ++++++++++++++++++++++++ 3 files changed, 468 insertions(+), 407 deletions(-) create mode 100644 src/Mod/Draft/draftfunctions/upgrade.py diff --git a/src/Mod/Draft/CMakeLists.txt b/src/Mod/Draft/CMakeLists.txt index e78a974f14..8d87253aa5 100644 --- a/src/Mod/Draft/CMakeLists.txt +++ b/src/Mod/Draft/CMakeLists.txt @@ -70,6 +70,7 @@ SET(Draft_functions draftfunctions/rotate.py draftfunctions/scale.py draftfunctions/split.py + draftfunctions/upgrade.py ) SET(Draft_make_functions diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index 47798675d1..f778118fa9 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -204,6 +204,8 @@ from draftfunctions.offset import offset from draftfunctions.mirror import mirror +from draftfunctions.upgrade import upgrade + #--------------------------------------------------------------------------- # Draft objects #--------------------------------------------------------------------------- @@ -798,413 +800,6 @@ def makeDrawingView(obj,page,lwmod=None,tmod=None,otherProjection=None): - -def upgrade(objects,delete=False,force=None): - """upgrade(objects,delete=False,force=None): Upgrades the given object(s) (can be - an object or a list of objects). If delete is True, old objects are deleted. - The force attribute can be used to - force a certain way of upgrading. It can be: makeCompound, closeGroupWires, - makeSolid, closeWire, turnToParts, makeFusion, makeShell, makeFaces, draftify, - joinFaces, makeSketchFace, makeWires - Returns a dictionary containing two lists, a list of new objects and a list - of objects to be deleted""" - - import Part, DraftGeomUtils - - if not isinstance(objects,list): - objects = [objects] - - global deleteList, newList - deleteList = [] - addList = [] - - # definitions of actions to perform - - def turnToLine(obj): - """turns an edge into a Draft line""" - p1 = obj.Shape.Vertexes[0].Point - p2 = obj.Shape.Vertexes[-1].Point - newobj = makeLine(p1,p2) - addList.append(newobj) - deleteList.append(obj) - return newobj - - def makeCompound(objectslist): - """returns a compound object made from the given objects""" - newobj = makeBlock(objectslist) - addList.append(newobj) - return newobj - - def closeGroupWires(groupslist): - """closes every open wire in the given groups""" - result = False - for grp in groupslist: - for obj in grp.Group: - newobj = closeWire(obj) - # add new objects to their respective groups - if newobj: - result = True - grp.addObject(newobj) - return result - - def makeSolid(obj): - """turns an object into a solid, if possible""" - if obj.Shape.Solids: - return None - sol = None - try: - sol = Part.makeSolid(obj.Shape) - except Part.OCCError: - return None - else: - if sol: - if sol.isClosed(): - newobj = FreeCAD.ActiveDocument.addObject("Part::Feature","Solid") - newobj.Shape = sol - addList.append(newobj) - deleteList.append(obj) - return newobj - - def closeWire(obj): - """closes a wire object, if possible""" - if obj.Shape.Faces: - return None - if len(obj.Shape.Wires) != 1: - return None - if len(obj.Shape.Edges) == 1: - return None - if getType(obj) == "Wire": - obj.Closed = True - return True - else: - w = obj.Shape.Wires[0] - if not w.isClosed(): - edges = w.Edges - p0 = w.Vertexes[0].Point - p1 = w.Vertexes[-1].Point - if p0 == p1: - # sometimes an open wire can have its start and end points identical (OCC bug) - # in that case, although it is not closed, face works... - f = Part.Face(w) - newobj = FreeCAD.ActiveDocument.addObject("Part::Feature","Face") - newobj.Shape = f - else: - edges.append(Part.LineSegment(p1,p0).toShape()) - w = Part.Wire(Part.__sortEdges__(edges)) - newobj = FreeCAD.ActiveDocument.addObject("Part::Feature","Wire") - newobj.Shape = w - addList.append(newobj) - deleteList.append(obj) - return newobj - else: - return None - - def turnToParts(meshes): - """turn given meshes to parts""" - result = False - import Arch - for mesh in meshes: - sh = Arch.getShapeFromMesh(mesh.Mesh) - if sh: - newobj = FreeCAD.ActiveDocument.addObject("Part::Feature","Shell") - newobj.Shape = sh - addList.append(newobj) - deleteList.append(mesh) - result = True - return result - - def makeFusion(obj1,obj2): - """makes a Draft or Part fusion between 2 given objects""" - newobj = fuse(obj1,obj2) - if newobj: - addList.append(newobj) - return newobj - return None - - def makeShell(objectslist): - """makes a shell with the given objects""" - params = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft") - preserveFaceColor = params.GetBool("preserveFaceColor") # True - preserveFaceNames = params.GetBool("preserveFaceNames") # True - faces = [] - facecolors = [[], []] if (preserveFaceColor) else None - for obj in objectslist: - faces.extend(obj.Shape.Faces) - if (preserveFaceColor): - """ at this point, obj.Shape.Faces are not in same order as the - original faces we might have gotten as a result of downgrade, nor do they - have the same hashCode(); but they still keep reference to their original - colors - capture that in facecolors. - Also, cannot w/ .ShapeColor here, need a whole array matching the colors - of the array of faces per object, only DiffuseColor has that """ - facecolors[0].extend(obj.ViewObject.DiffuseColor) - facecolors[1] = faces - sh = Part.makeShell(faces) - if sh: - if sh.Faces: - newobj = FreeCAD.ActiveDocument.addObject("Part::Feature","Shell") - newobj.Shape = sh - if (preserveFaceNames): - import re - firstName = objectslist[0].Label - nameNoTrailNumbers = re.sub("\d+$", "", firstName) - newobj.Label = "{} {}".format(newobj.Label, nameNoTrailNumbers) - if (preserveFaceColor): - """ At this point, sh.Faces are completely new, with different hashCodes - and different ordering from obj.Shape.Faces; since we cannot compare - via hashCode(), we have to iterate and use a different criteria to find - the original matching color """ - colarray = [] - for ind, face in enumerate(newobj.Shape.Faces): - for fcind, fcface in enumerate(facecolors[1]): - if ((face.Area == fcface.Area) and (face.CenterOfMass == fcface.CenterOfMass)): - colarray.append(facecolors[0][fcind]) - break - newobj.ViewObject.DiffuseColor = colarray; - addList.append(newobj) - deleteList.extend(objectslist) - return newobj - return None - - def joinFaces(objectslist): - """makes one big face from selected objects, if possible""" - faces = [] - for obj in objectslist: - faces.extend(obj.Shape.Faces) - u = faces.pop(0) - for f in faces: - u = u.fuse(f) - if DraftGeomUtils.isCoplanar(faces): - u = DraftGeomUtils.concatenate(u) - if not DraftGeomUtils.hasCurves(u): - # several coplanar and non-curved faces: they can become a Draft wire - newobj = makeWire(u.Wires[0],closed=True,face=True) - else: - # if not possible, we do a non-parametric union - newobj = FreeCAD.ActiveDocument.addObject("Part::Feature","Union") - newobj.Shape = u - addList.append(newobj) - deleteList.extend(objectslist) - return newobj - return None - - def makeSketchFace(obj): - """Makes a Draft face out of a sketch""" - newobj = makeWire(obj.Shape,closed=True) - if newobj: - newobj.Base = obj - obj.ViewObject.Visibility = False - addList.append(newobj) - return newobj - return None - - def makeFaces(objectslist): - """make a face from every closed wire in the list""" - result = False - for o in objectslist: - for w in o.Shape.Wires: - try: - f = Part.Face(w) - except Part.OCCError: - pass - else: - newobj = FreeCAD.ActiveDocument.addObject("Part::Feature","Face") - newobj.Shape = f - addList.append(newobj) - result = True - if not o in deleteList: - deleteList.append(o) - return result - - def makeWires(objectslist): - """joins edges in the given objects list into wires""" - edges = [] - for o in objectslist: - for e in o.Shape.Edges: - edges.append(e) - try: - nedges = Part.__sortEdges__(edges[:]) - # for e in nedges: print("debug: ",e.Curve,e.Vertexes[0].Point,e.Vertexes[-1].Point) - w = Part.Wire(nedges) - except Part.OCCError: - return None - else: - if len(w.Edges) == len(edges): - newobj = FreeCAD.ActiveDocument.addObject("Part::Feature","Wire") - newobj.Shape = w - addList.append(newobj) - deleteList.extend(objectslist) - return True - return None - - # analyzing what we have in our selection - - edges = [] - wires = [] - openwires = [] - faces = [] - groups = [] - parts = [] - curves = [] - facewires = [] - loneedges = [] - meshes = [] - for ob in objects: - if ob.TypeId == "App::DocumentObjectGroup": - groups.append(ob) - elif hasattr(ob,'Shape'): - parts.append(ob) - faces.extend(ob.Shape.Faces) - wires.extend(ob.Shape.Wires) - edges.extend(ob.Shape.Edges) - for f in ob.Shape.Faces: - facewires.extend(f.Wires) - wirededges = [] - for w in ob.Shape.Wires: - if len(w.Edges) > 1: - for e in w.Edges: - wirededges.append(e.hashCode()) - if not w.isClosed(): - openwires.append(w) - for e in ob.Shape.Edges: - if DraftGeomUtils.geomType(e) != "Line": - curves.append(e) - if not e.hashCode() in wirededges: - loneedges.append(e) - elif ob.isDerivedFrom("Mesh::Feature"): - meshes.append(ob) - objects = parts - - #print("objects:",objects," edges:",edges," wires:",wires," openwires:",openwires," faces:",faces) - #print("groups:",groups," curves:",curves," facewires:",facewires, "loneedges:", loneedges) - - if force: - if force in ["makeCompound","closeGroupWires","makeSolid","closeWire","turnToParts","makeFusion", - "makeShell","makeFaces","draftify","joinFaces","makeSketchFace","makeWires","turnToLine"]: - result = eval(force)(objects) - else: - FreeCAD.Console.PrintMessage(translate("Draft","Upgrade: Unknown force method:")+" "+force) - result = None - - else: - - # applying transformations automatically - - result = None - - # if we have a group: turn each closed wire inside into a face - if groups: - result = closeGroupWires(groups) - if result: - FreeCAD.Console.PrintMessage(translate("draft", "Found groups: closing each open object inside")+"\n") - - # if we have meshes, we try to turn them into shapes - elif meshes: - result = turnToParts(meshes) - if result: - FreeCAD.Console.PrintMessage(translate("draft", "Found mesh(es): turning into Part shapes")+"\n") - - # we have only faces here, no lone edges - elif faces and (len(wires) + len(openwires) == len(facewires)): - - # we have one shell: we try to make a solid - if (len(objects) == 1) and (len(faces) > 3): - result = makeSolid(objects[0]) - if result: - FreeCAD.Console.PrintMessage(translate("draft", "Found 1 solidifiable object: solidifying it")+"\n") - - # we have exactly 2 objects: we fuse them - elif (len(objects) == 2) and (not curves): - result = makeFusion(objects[0],objects[1]) - if result: - FreeCAD.Console.PrintMessage(translate("draft", "Found 2 objects: fusing them")+"\n") - - # we have many separate faces: we try to make a shell - elif (len(objects) > 2) and (len(faces) > 1) and (not loneedges): - result = makeShell(objects) - if result: - FreeCAD.Console.PrintMessage(translate("draft", "Found several objects: creating a shell")+"\n") - - # we have faces: we try to join them if they are coplanar - elif len(faces) > 1: - result = joinFaces(objects) - if result: - FreeCAD.Console.PrintMessage(translate("draft", "Found several coplanar objects or faces: creating one face")+"\n") - - # only one object: if not parametric, we "draftify" it - elif len(objects) == 1 and (not objects[0].isDerivedFrom("Part::Part2DObjectPython")): - result = draftify(objects[0]) - if result: - FreeCAD.Console.PrintMessage(translate("draft", "Found 1 non-parametric objects: draftifying it")+"\n") - - # we have only one object that contains one edge - elif (not faces) and (len(objects) == 1) and (len(edges) == 1): - # we have a closed sketch: Extract a face - if objects[0].isDerivedFrom("Sketcher::SketchObject") and (len(edges[0].Vertexes) == 1): - result = makeSketchFace(objects[0]) - if result: - FreeCAD.Console.PrintMessage(translate("draft", "Found 1 closed sketch object: creating a face from it")+"\n") - else: - # turn to Draft line - e = objects[0].Shape.Edges[0] - if isinstance(e.Curve,(Part.LineSegment,Part.Line)): - result = turnToLine(objects[0]) - if result: - FreeCAD.Console.PrintMessage(translate("draft", "Found 1 linear object: converting to line")+"\n") - - # we have only closed wires, no faces - elif wires and (not faces) and (not openwires): - - # we have a sketch: Extract a face - if (len(objects) == 1) and objects[0].isDerivedFrom("Sketcher::SketchObject"): - result = makeSketchFace(objects[0]) - if result: - FreeCAD.Console.PrintMessage(translate("draft", "Found 1 closed sketch object: creating a face from it")+"\n") - - # only closed wires - else: - result = makeFaces(objects) - if result: - FreeCAD.Console.PrintMessage(translate("draft", "Found closed wires: creating faces")+"\n") - - # special case, we have only one open wire. We close it, unless it has only 1 edge!" - elif (len(openwires) == 1) and (not faces) and (not loneedges): - result = closeWire(objects[0]) - if result: - FreeCAD.Console.PrintMessage(translate("draft", "Found 1 open wire: closing it")+"\n") - - # only open wires and edges: we try to join their edges - elif openwires and (not wires) and (not faces): - result = makeWires(objects) - if result: - FreeCAD.Console.PrintMessage(translate("draft", "Found several open wires: joining them")+"\n") - - # only loneedges: we try to join them - elif loneedges and (not facewires): - result = makeWires(objects) - if result: - FreeCAD.Console.PrintMessage(translate("draft", "Found several edges: wiring them")+"\n") - - # all other cases, if more than 1 object, make a compound - elif (len(objects) > 1): - result = makeCompound(objects) - if result: - FreeCAD.Console.PrintMessage(translate("draft", "Found several non-treatable objects: creating compound")+"\n") - - # no result has been obtained - if not result: - FreeCAD.Console.PrintMessage(translate("draft", "Unable to upgrade these objects.")+"\n") - - if delete: - names = [] - for o in deleteList: - names.append(o.Name) - deleteList = [] - for n in names: - FreeCAD.ActiveDocument.removeObject(n) - select(addList) - return [addList,deleteList] - def downgrade(objects,delete=False,force=None): """downgrade(objects,delete=False,force=None): Downgrades the given object(s) (can be an object or a list of objects). If delete is True, old objects are deleted. diff --git a/src/Mod/Draft/draftfunctions/upgrade.py b/src/Mod/Draft/draftfunctions/upgrade.py new file mode 100644 index 0000000000..c6ed7bfb42 --- /dev/null +++ b/src/Mod/Draft/draftfunctions/upgrade.py @@ -0,0 +1,465 @@ +# *************************************************************************** +# * 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 upgrade function. +""" +## @package upgrade +# \ingroup DRAFT +# \brief This module provides the code for upgrade offset function. + +import FreeCAD as App + +import draftutils.gui_utils as gui_utils +import draftutils.utils as utils + +from draftutils.translate import _tr + +from draftmake.make_copy import make_copy + +from draftmake.make_line import makeLine +from draftmake.make_wire import makeWire +from draftmake.make_block import makeBlock + +from draftfunctions.draftify import draftify +from draftfunctions.fuse import fuse + + +def upgrade(objects, delete=False, force=None): + """upgrade(objects,delete=False,force=None) + + Upgrade the given object(s). + + Parameters + ---------- + objects : + + delete : bool + If delete is True, old objects are deleted. + + force : string + The force attribute can be used to force a certain way of upgrading. + Accepted values: makeCompound, closeGroupWires, makeSolid, closeWire, + turnToParts, makeFusion, makeShell, makeFaces, draftify, joinFaces, + makeSketchFace, makeWires. + + Return + ---------- + Returns a dictionary containing two lists, a list of new objects and a list + of objects to be deleted + """ + + import Part + import DraftGeomUtils + + if not isinstance(objects,list): + objects = [objects] + + global deleteList, newList + deleteList = [] + addList = [] + + # definitions of actions to perform + + def turnToLine(obj): + """turns an edge into a Draft line""" + p1 = obj.Shape.Vertexes[0].Point + p2 = obj.Shape.Vertexes[-1].Point + newobj = makeLine(p1,p2) + addList.append(newobj) + deleteList.append(obj) + return newobj + + def makeCompound(objectslist): + """returns a compound object made from the given objects""" + newobj = makeBlock(objectslist) + addList.append(newobj) + return newobj + + def closeGroupWires(groupslist): + """closes every open wire in the given groups""" + result = False + for grp in groupslist: + for obj in grp.Group: + newobj = closeWire(obj) + # add new objects to their respective groups + if newobj: + result = True + grp.addObject(newobj) + return result + + def makeSolid(obj): + """turns an object into a solid, if possible""" + if obj.Shape.Solids: + return None + sol = None + try: + sol = Part.makeSolid(obj.Shape) + except Part.OCCError: + return None + else: + if sol: + if sol.isClosed(): + newobj = App.ActiveDocument.addObject("Part::Feature","Solid") + newobj.Shape = sol + addList.append(newobj) + deleteList.append(obj) + return newobj + + def closeWire(obj): + """closes a wire object, if possible""" + if obj.Shape.Faces: + return None + if len(obj.Shape.Wires) != 1: + return None + if len(obj.Shape.Edges) == 1: + return None + if utils.get_type(obj) == "Wire": + obj.Closed = True + return True + else: + w = obj.Shape.Wires[0] + if not w.isClosed(): + edges = w.Edges + p0 = w.Vertexes[0].Point + p1 = w.Vertexes[-1].Point + if p0 == p1: + # sometimes an open wire can have its start and end points identical (OCC bug) + # in that case, although it is not closed, face works... + f = Part.Face(w) + newobj = App.ActiveDocument.addObject("Part::Feature","Face") + newobj.Shape = f + else: + edges.append(Part.LineSegment(p1,p0).toShape()) + w = Part.Wire(Part.__sortEdges__(edges)) + newobj = App.ActiveDocument.addObject("Part::Feature","Wire") + newobj.Shape = w + addList.append(newobj) + deleteList.append(obj) + return newobj + else: + return None + + def turnToParts(meshes): + """turn given meshes to parts""" + result = False + import Arch + for mesh in meshes: + sh = Arch.getShapeFromMesh(mesh.Mesh) + if sh: + newobj = App.ActiveDocument.addObject("Part::Feature","Shell") + newobj.Shape = sh + addList.append(newobj) + deleteList.append(mesh) + result = True + return result + + def makeFusion(obj1,obj2): + """makes a Draft or Part fusion between 2 given objects""" + newobj = fuse(obj1,obj2) + if newobj: + addList.append(newobj) + return newobj + return None + + def makeShell(objectslist): + """makes a shell with the given objects""" + params = App.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft") + preserveFaceColor = params.GetBool("preserveFaceColor") # True + preserveFaceNames = params.GetBool("preserveFaceNames") # True + faces = [] + facecolors = [[], []] if (preserveFaceColor) else None + for obj in objectslist: + faces.extend(obj.Shape.Faces) + if (preserveFaceColor): + """ at this point, obj.Shape.Faces are not in same order as the + original faces we might have gotten as a result of downgrade, nor do they + have the same hashCode(); but they still keep reference to their original + colors - capture that in facecolors. + Also, cannot w/ .ShapeColor here, need a whole array matching the colors + of the array of faces per object, only DiffuseColor has that """ + facecolors[0].extend(obj.ViewObject.DiffuseColor) + facecolors[1] = faces + sh = Part.makeShell(faces) + if sh: + if sh.Faces: + newobj = App.ActiveDocument.addObject("Part::Feature","Shell") + newobj.Shape = sh + if (preserveFaceNames): + import re + firstName = objectslist[0].Label + nameNoTrailNumbers = re.sub("\d+$", "", firstName) + newobj.Label = "{} {}".format(newobj.Label, nameNoTrailNumbers) + if (preserveFaceColor): + """ At this point, sh.Faces are completely new, with different hashCodes + and different ordering from obj.Shape.Faces; since we cannot compare + via hashCode(), we have to iterate and use a different criteria to find + the original matching color """ + colarray = [] + for ind, face in enumerate(newobj.Shape.Faces): + for fcind, fcface in enumerate(facecolors[1]): + if ((face.Area == fcface.Area) and (face.CenterOfMass == fcface.CenterOfMass)): + colarray.append(facecolors[0][fcind]) + break + newobj.ViewObject.DiffuseColor = colarray; + addList.append(newobj) + deleteList.extend(objectslist) + return newobj + return None + + def joinFaces(objectslist): + """makes one big face from selected objects, if possible""" + faces = [] + for obj in objectslist: + faces.extend(obj.Shape.Faces) + u = faces.pop(0) + for f in faces: + u = u.fuse(f) + if DraftGeomUtils.isCoplanar(faces): + u = DraftGeomUtils.concatenate(u) + if not DraftGeomUtils.hasCurves(u): + # several coplanar and non-curved faces: they can become a Draft wire + newobj = makeWire(u.Wires[0],closed=True,face=True) + else: + # if not possible, we do a non-parametric union + newobj = App.ActiveDocument.addObject("Part::Feature","Union") + newobj.Shape = u + addList.append(newobj) + deleteList.extend(objectslist) + return newobj + return None + + def makeSketchFace(obj): + """Makes a Draft face out of a sketch""" + newobj = makeWire(obj.Shape,closed=True) + if newobj: + newobj.Base = obj + obj.ViewObject.Visibility = False + addList.append(newobj) + return newobj + return None + + def makeFaces(objectslist): + """make a face from every closed wire in the list""" + result = False + for o in objectslist: + for w in o.Shape.Wires: + try: + f = Part.Face(w) + except Part.OCCError: + pass + else: + newobj = App.ActiveDocument.addObject("Part::Feature","Face") + newobj.Shape = f + addList.append(newobj) + result = True + if not o in deleteList: + deleteList.append(o) + return result + + def makeWires(objectslist): + """joins edges in the given objects list into wires""" + edges = [] + for o in objectslist: + for e in o.Shape.Edges: + edges.append(e) + try: + nedges = Part.__sortEdges__(edges[:]) + # for e in nedges: print("debug: ",e.Curve,e.Vertexes[0].Point,e.Vertexes[-1].Point) + w = Part.Wire(nedges) + except Part.OCCError: + return None + else: + if len(w.Edges) == len(edges): + newobj = App.ActiveDocument.addObject("Part::Feature","Wire") + newobj.Shape = w + addList.append(newobj) + deleteList.extend(objectslist) + return True + return None + + # analyzing what we have in our selection + + edges = [] + wires = [] + openwires = [] + faces = [] + groups = [] + parts = [] + curves = [] + facewires = [] + loneedges = [] + meshes = [] + for ob in objects: + if ob.TypeId == "App::DocumentObjectGroup": + groups.append(ob) + elif hasattr(ob,'Shape'): + parts.append(ob) + faces.extend(ob.Shape.Faces) + wires.extend(ob.Shape.Wires) + edges.extend(ob.Shape.Edges) + for f in ob.Shape.Faces: + facewires.extend(f.Wires) + wirededges = [] + for w in ob.Shape.Wires: + if len(w.Edges) > 1: + for e in w.Edges: + wirededges.append(e.hashCode()) + if not w.isClosed(): + openwires.append(w) + for e in ob.Shape.Edges: + if DraftGeomUtils.geomType(e) != "Line": + curves.append(e) + if not e.hashCode() in wirededges: + loneedges.append(e) + elif ob.isDerivedFrom("Mesh::Feature"): + meshes.append(ob) + objects = parts + + #print("objects:",objects," edges:",edges," wires:",wires," openwires:",openwires," faces:",faces) + #print("groups:",groups," curves:",curves," facewires:",facewires, "loneedges:", loneedges) + + if force: + if force in ["makeCompound","closeGroupWires","makeSolid","closeWire","turnToParts","makeFusion", + "makeShell","makeFaces","draftify","joinFaces","makeSketchFace","makeWires","turnToLine"]: + result = eval(force)(objects) + else: + App.Console.PrintMessage(_tr("Upgrade: Unknown force method:")+" "+force) + result = None + + else: + + # applying transformations automatically + + result = None + + # if we have a group: turn each closed wire inside into a face + if groups: + result = closeGroupWires(groups) + if result: + App.Console.PrintMessage(_tr("Found groups: closing each open object inside")+"\n") + + # if we have meshes, we try to turn them into shapes + elif meshes: + result = turnToParts(meshes) + if result: + App.Console.PrintMessage(_tr("Found mesh(es): turning into Part shapes")+"\n") + + # we have only faces here, no lone edges + elif faces and (len(wires) + len(openwires) == len(facewires)): + + # we have one shell: we try to make a solid + if (len(objects) == 1) and (len(faces) > 3): + result = makeSolid(objects[0]) + if result: + App.Console.PrintMessage(_tr("Found 1 solidifiable object: solidifying it")+"\n") + + # we have exactly 2 objects: we fuse them + elif (len(objects) == 2) and (not curves): + result = makeFusion(objects[0],objects[1]) + if result: + App.Console.PrintMessage(_tr("Found 2 objects: fusing them")+"\n") + + # we have many separate faces: we try to make a shell + elif (len(objects) > 2) and (len(faces) > 1) and (not loneedges): + result = makeShell(objects) + if result: + App.Console.PrintMessage(_tr("Found several objects: creating a shell")+"\n") + + # we have faces: we try to join them if they are coplanar + elif len(faces) > 1: + result = joinFaces(objects) + if result: + App.Console.PrintMessage(_tr("Found several coplanar objects or faces: creating one face")+"\n") + + # only one object: if not parametric, we "draftify" it + elif len(objects) == 1 and (not objects[0].isDerivedFrom("Part::Part2DObjectPython")): + result = draftify(objects[0]) + if result: + App.Console.PrintMessage(_tr("Found 1 non-parametric objects: draftifying it")+"\n") + + # we have only one object that contains one edge + elif (not faces) and (len(objects) == 1) and (len(edges) == 1): + # we have a closed sketch: Extract a face + if objects[0].isDerivedFrom("Sketcher::SketchObject") and (len(edges[0].Vertexes) == 1): + result = makeSketchFace(objects[0]) + if result: + App.Console.PrintMessage(_tr("Found 1 closed sketch object: creating a face from it")+"\n") + else: + # turn to Draft line + e = objects[0].Shape.Edges[0] + if isinstance(e.Curve,(Part.LineSegment,Part.Line)): + result = turnToLine(objects[0]) + if result: + App.Console.PrintMessage(_tr("Found 1 linear object: converting to line")+"\n") + + # we have only closed wires, no faces + elif wires and (not faces) and (not openwires): + + # we have a sketch: Extract a face + if (len(objects) == 1) and objects[0].isDerivedFrom("Sketcher::SketchObject"): + result = makeSketchFace(objects[0]) + if result: + App.Console.PrintMessage(_tr("Found 1 closed sketch object: creating a face from it")+"\n") + + # only closed wires + else: + result = makeFaces(objects) + if result: + App.Console.PrintMessage(_tr("Found closed wires: creating faces")+"\n") + + # special case, we have only one open wire. We close it, unless it has only 1 edge!" + elif (len(openwires) == 1) and (not faces) and (not loneedges): + result = closeWire(objects[0]) + if result: + App.Console.PrintMessage(_tr("Found 1 open wire: closing it")+"\n") + + # only open wires and edges: we try to join their edges + elif openwires and (not wires) and (not faces): + result = makeWires(objects) + if result: + App.Console.PrintMessage(_tr("Found several open wires: joining them")+"\n") + + # only loneedges: we try to join them + elif loneedges and (not facewires): + result = makeWires(objects) + if result: + App.Console.PrintMessage(_tr("Found several edges: wiring them")+"\n") + + # all other cases, if more than 1 object, make a compound + elif (len(objects) > 1): + result = makeCompound(objects) + if result: + App.Console.PrintMessage(_tr("Found several non-treatable objects: creating compound")+"\n") + + # no result has been obtained + if not result: + App.Console.PrintMessage(_tr("Unable to upgrade these objects.")+"\n") + + if delete: + names = [] + for o in deleteList: + names.append(o.Name) + deleteList = [] + for n in names: + App.ActiveDocument.removeObject(n) + gui_utils.select(addList) + return [addList,deleteList]