From fa69f105fb91ce0685bc16a288e665284f431e99 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Fri, 19 Aug 2016 18:59:24 -0300 Subject: [PATCH 1/3] Draft: removed trailing spaces --- src/Mod/Draft/Draft.py | 520 ++++++++++++++++++++--------------------- 1 file changed, 260 insertions(+), 260 deletions(-) diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index 76eae015f..9286f7426 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -2,8 +2,8 @@ #*************************************************************************** #* * -#* Copyright (c) 2009, 2010 * -#* Yorik van Havre , Ken Cline * +#* Copyright (c) 2009, 2010 * +#* Yorik van Havre , Ken Cline * #* * #* This program is free software; you can redistribute it and/or modify * #* it under the terms of the GNU Lesser General Public License (LGPL) * @@ -54,7 +54,7 @@ if FreeCAD.GuiUp: else: #print("FreeCAD Gui not present. Draft module will have some features disabled.") gui = False - + arrowtypes = ["Dot","Circle","Arrow","Tick"] #--------------------------------------------------------------------------- @@ -108,19 +108,19 @@ def getParam(param,default=None): p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft") t = getParamType(param) #print("getting param ",param, " of type ",t, " default: ",str(default)) - if t == "int": + if t == "int": if default == None: default = 0 return p.GetInt(param,default) - elif t == "string": + elif t == "string": if default == None: default = "" return p.GetString(param,default) - elif t == "float": + elif t == "float": if default == None: default = 0 return p.GetFloat(param,default) - elif t == "bool": + elif t == "bool": if default == None: default = False return p.GetBool(param,default) @@ -128,7 +128,7 @@ def getParam(param,default=None): if default == None: default = 0 return p.GetUnsigned(param,default) - else: + else: return None def setParam(param,value): @@ -140,7 +140,7 @@ def setParam(param,value): elif t == "float": p.SetFloat(param,value) elif t == "bool": p.SetBool(param,value) elif t == "unsigned": p.SetUnsigned(param,value) - + def precision(): "precision(): returns the precision value from Draft user settings" return getParam("precision",6) @@ -150,10 +150,10 @@ def tolerance(): return getParam("tolerance",0.05) def epsilon(): - ''' epsilon(): returns a small number based on Draft.tolerance() for use in + ''' epsilon(): returns a small number based on Draft.tolerance() for use in floating point comparisons. Use with caution. ''' return (1.0/(10.0**tolerance())) - + def getRealName(name): "getRealName(string): strips the trailing numbers from a string name" for i in range(1,len(name)): @@ -209,7 +209,7 @@ def get3DView(): return None def isClone(obj,objtype,recursive=False): - """isClone(obj,objtype,[recursive]): returns True if the given object is + """isClone(obj,objtype,[recursive]): returns True if the given object is a clone of an object of the given type. If recursive is True, also check if the clone is a clone of clone (of clone...) of the given type.""" if getType(obj) == "Clone": @@ -222,7 +222,7 @@ def isClone(obj,objtype,recursive=False): if obj.CloneOf: return True return False - + def getGroupNames(): "returns a list of existing groups in the document" glist = [] @@ -238,7 +238,7 @@ def ungroup(obj): grp = FreeCAD.ActiveDocument.getObject(g) if grp.hasObject(obj): grp.removeObject(obj) - + def dimSymbol(symbol=None,invert=False): "returns the current dim symbol from the preferences as a pivy SoMarkerSet" if symbol == None: @@ -246,15 +246,15 @@ def dimSymbol(symbol=None,invert=False): from pivy import coin if symbol == 0: return coin.SoSphere() - elif symbol == 1: + elif symbol == 1: marker = coin.SoMarkerSet() marker.markerIndex = coin.SoMarkerSet.CIRCLE_LINE_9_9 return marker - elif symbol == 2: + elif symbol == 2: marker = coin.SoSeparator() t = coin.SoTransform() t.translation.setValue((0,-2,0)) - t.center.setValue((0,2,0)) + t.center.setValue((0,2,0)) if invert: t.rotation.setValue(coin.SbVec3f((0,0,1)),-math.pi/2) else: @@ -319,7 +319,7 @@ def getGroupContents(objectslist,walls=False,addgroups=False): elif (getType(obj) == "Window") or isClone(obj,"Window"): l.append(obj) return l - + newlist = [] if not isinstance(objectslist,list): objectslist = [objectslist] @@ -338,7 +338,7 @@ def getGroupContents(objectslist,walls=False,addgroups=False): newlist.append(obj) if walls: newlist.extend(getWindows(obj)) - + # cleaning possible duplicates cleanlist = [] for obj in newlist: @@ -375,10 +375,10 @@ def printShape(shape): else: for v in shape.Vertexes: print(" ",v.Point) - + def compareObjects(obj1,obj2): "Prints the differences between 2 objects" - + if obj1.TypeId != obj2.TypeId: print(obj1.Name + " and " + obj2.Name + " are of different types") elif getType(obj1) != getType(obj2): @@ -400,7 +400,7 @@ def compareObjects(obj1,obj2): def formatObject(target,origin=None): ''' formatObject(targetObject,[originObject]): This function applies - to the given target object the current properties + to the given target object the current properties set on the toolbar (line color and line width), or copies the properties of another object if given as origin. It also places the object in construction group if needed. @@ -417,7 +417,7 @@ def formatObject(target,origin=None): gname = getParam("constructiongroupname","Construction") grp = doc.getObject(gname) if not grp: - grp = doc.addObject("App::DocumentObjectGroup",gname) + grp = doc.addObject("App::DocumentObjectGroup",gname) grp.addObject(target) if hasattr(obrep,"Transparency"): obrep.Transparency = 80 @@ -501,7 +501,7 @@ def loadSvgPatterns(): for k in p: p[k] = [p[k],altpat+os.sep+f] FreeCAD.svgpatterns.update(p) - + def svgpatterns(): """svgpatterns(): returns a dictionnary with installed SVG patterns""" if hasattr(FreeCAD,"svgpatterns"): @@ -532,7 +532,7 @@ def loadTexture(filename,size=None): # pa.begin(p) # svgr.render(pa) # pa.end() - #else: + #else: # p = QtGui.QImage(filename) size = coin.SbVec2s(p.width(), p.height()) buffersize = p.byteCount() @@ -542,7 +542,7 @@ def loadTexture(filename,size=None): width = size[0] height = size[1] bytes = "" - + for y in range(height): #line = width*numcomponents*(height-(y)); for x in range(width): @@ -570,7 +570,7 @@ def loadTexture(filename,size=None): else: return img return None - + def getMovableChildren(objectslist,recursive=True): '''getMovableChildren(objectslist,[recursive]): extends the given list of objects with all child objects that have a "MoveWithHost" property set to True. If @@ -632,7 +632,7 @@ def makeCircle(radius, placement=None, face=True, startangle=None, endangle=None a2 = -math.degrees(DraftVecUtils.angle(v2,ref)) obj.FirstAngle = a1 obj.LastAngle = a2 - else: + else: obj.Radius = radius if (startangle != None) and (endangle != None): if startangle == -0: startangle = 0 @@ -646,7 +646,7 @@ def makeCircle(radius, placement=None, face=True, startangle=None, endangle=None select(obj) FreeCAD.ActiveDocument.recompute() return obj - + def makeRectangle(length, height, placement=None, face=True, support=None): '''makeRectangle(length,width,[placement],[face]): Creates a Rectangle object with length in X direction and height in Y direction. @@ -655,7 +655,7 @@ def makeRectangle(length, height, placement=None, face=True, support=None): if placement: typecheck([(placement,FreeCAD.Placement)], "makeRectangle") obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython","Rectangle") _Rectangle(obj) - + obj.Length = length obj.Height = height obj.Support = support @@ -667,7 +667,7 @@ def makeRectangle(length, height, placement=None, face=True, support=None): select(obj) FreeCAD.ActiveDocument.recompute() return obj - + def makeDimension(p1,p2,p3=None,p4=None): '''makeDimension(p1,p2,[p3]) or makeDimension(object,i1,i2,p3) or makeDimension(objlist,indices,p3): Creates a Dimension object with @@ -923,10 +923,10 @@ def makeText(stringslist,point=Vector(0,0,0),screen=False): obj.LabelText=stringslist obj.Position=point if FreeCAD.GuiUp: - if not screen: + if not screen: obj.ViewObject.DisplayMode="World" h = getParam("textheight",0.20) - if screen: + if screen: h = h*10 obj.ViewObject.FontSize = h obj.ViewObject.FontName = getParam("textfont","") @@ -1081,11 +1081,11 @@ def makeArray(baseobject,arg1,arg2,arg3,arg4=None,name="Array"): baseobject.ViewObject.hide() select(obj) return obj - + def makePathArray(baseobject,pathobject,count,xlate=None,align=False,pathobjsubs=[]): - '''makePathArray(docobj,path,count,xlate,align,pathobjsubs): distribute - count copies of a document baseobject along a pathobject or subobjects of a - pathobject. Optionally translates each copy by FreeCAD.Vector xlate direction + '''makePathArray(docobj,path,count,xlate,align,pathobjsubs): distribute + count copies of a document baseobject along a pathobject or subobjects of a + pathobject. Optionally translates each copy by FreeCAD.Vector xlate direction and distance to adjust for difference in shape centre vs shape reference point. Optionally aligns baseobject to tangent/normal/binormal of path.''' obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython","PathArray") @@ -1096,14 +1096,14 @@ def makePathArray(baseobject,pathobject,count,xlate=None,align=False,pathobjsubs sl = [] for sub in pathobjsubs: sl.append((obj.PathObj,sub)) - obj.PathSubs = list(sl) + obj.PathSubs = list(sl) if count > 1: obj.Count = count if xlate: obj.Xlate = xlate obj.Align = align if gui: - _ViewProviderDraftArray(obj.ViewObject) + _ViewProviderDraftArray(obj.ViewObject) baseobject.ViewObject.hide() formatObject(obj,obj.Base) select(obj) @@ -1120,11 +1120,11 @@ def makeEllipse(majradius,minradius,placement=None,face=True,support=None): obj.MajorRadius = majradius obj.MinorRadius = minradius obj.Support = support - if placement: + if placement: obj.Placement = placement if gui: _ViewProviderDraft(obj.ViewObject) - #if not face: + #if not face: # obj.ViewObject.DisplayMode = "Wireframe" formatObject(obj) select(obj) @@ -1280,10 +1280,10 @@ def array(objectslist,arg1,arg2,arg3,arg4=None): at xvector distance between iterations, and same for y direction with yvector and ynum. In case of polar array, center is a vector, totalangle is the angle to cover (in degrees) and totalnum is the number of objects, including the original. - + This function creates an array of independent objects. Use makeArray() to create a parametric array object.''' - + def rectArray(objectslist,xvector,yvector,xnum,ynum): typecheck([(xvector,Vector), (yvector,Vector), (xnum,int), (ynum,int)], "rectArray") if not isinstance(objectslist,list): objectslist = [objectslist] @@ -1308,7 +1308,7 @@ def array(objectslist,arg1,arg2,arg3,arg4=None): rectArray(objectslist,arg1,arg2,arg3,arg4) else: polarArray(objectslist,arg1,arg2,arg3) - + def rotate(objectslist,angle,center=Vector(0,0,0),axis=Vector(0,0,1),copy=False): '''rotate(objects,angle,[center,axis,copy]): Rotates the objects contained in objects (that can be a list of objects or an object) of the given angle @@ -1374,7 +1374,7 @@ def scale(objectslist,delta=Vector(1,1,1),center=Vector(0,0,0),copy=False,legacy a parametric copy is made. If copy is True, the actual objects are not moved, but copies are created instead. The objects (or their copies) are returned.''' if not isinstance(objectslist,list): objectslist = [objectslist] - if legacy: + if legacy: newobjlist = [] for obj in objectslist: if copy: @@ -1459,13 +1459,13 @@ def offset(obj,delta,copy=False,bind=False,sym=False,occ=False): offsetted. If bind is True, and provided the wire is open, the original and the offsetted wires will be bound by their endpoints, forming a face if sym is True, bind must be true too, and the offset is made on both - sides, the total width being the given delta length. If offsetting a + sides, the total width being the given delta length. If offsetting a BSpline, the delta must not be a Vector but a list of Vectors, one for each node of the spline.''' import Part, DraftGeomUtils newwire = None delete = None - + if getType(obj) in ["Sketch","Part"]: copy = True print("the offset tool is currently unable to offset a non-Draft object directly - Creating a copy") @@ -1654,7 +1654,7 @@ def draftify(objectslist,makeblock=False,delete=True): if len(newobjlist) == 1: return newobjlist[0] return newobjlist - + def getDXF(obj,direction=None): '''getDXF(object,[direction]): returns a DXF entity from the given object. If direction is given, the object is projected in 2D.''' @@ -1665,13 +1665,13 @@ def getDXF(obj,direction=None): if direction != Vector(0,0,0): plane = WorkingPlane.plane() plane.alignToPointAndAxis(Vector(0,0,0),direction) - + def getProj(vec): if not plane: return vec nx = DraftVecUtils.project(vec,plane.u) ny = DraftVecUtils.project(vec,plane.v) return Vector(nx.Length,ny.Length,0) - + if getType(obj) == "Dimension": p1 = getProj(obj.Start) p2 = getProj(obj.End) @@ -1680,7 +1680,7 @@ def getDXF(obj,direction=None): result += "10\n"+str(p3.x)+"\n20\n"+str(p3.y)+"\n30\n"+str(p3.z)+"\n" result += "13\n"+str(p1.x)+"\n23\n"+str(p1.y)+"\n33\n"+str(p1.z)+"\n" result += "14\n"+str(p2.x)+"\n24\n"+str(p2.y)+"\n34\n"+str(p2.z)+"\n" - + elif getType(obj) == "Annotation": p = getProj(obj.Position) count = 0 @@ -1695,7 +1695,7 @@ def getDXF(obj,direction=None): elif obj.isDerivedFrom("Part::Feature"): # TODO do this the Draft way, for ex. using polylines and rectangles import Drawing - if not direction: + if not direction: direction = FreeCAD.Vector(0,0,-1) if DraftVecUtils.isNull(direction): direction = FreeCAD.Vector(0,0,-1) @@ -1705,10 +1705,10 @@ def getDXF(obj,direction=None): print("Draft.getDXF: Unable to project ",obj.Label," to ",direction) else: result += d - + else: print("Draft.getDXF: Unsupported object: ",obj.Label) - + return result @@ -1868,7 +1868,7 @@ def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct for pole in bezierseg.getPoles()[1:]: v = getProj(pole) svg += str(v.x) +' '+ str(v.y) + ' ' - else: + else: print("Debug: one edge (hash ",e.hashCode(),\ ") has been discretized with parameter 0.1") for linepoint in bspline.discretize(0.1)[1:]: @@ -1900,7 +1900,7 @@ def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct svg += ';fill:' + fill + '"' svg += '/>\n' return svg - + def getEllipse(edge): cen = getProj(edge.Curve.Center) mir = edge.Curve.MinorRadius @@ -1945,7 +1945,7 @@ def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct else: print("getSVG: arrow type not implemented") return svg - + def getText(color,fontsize,fontname,angle,base,text,linespacing=0.5,align="center",flip=True): if not isinstance(text,list): text = text.split("\n") @@ -1992,16 +1992,16 @@ def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct svg += '\n' return svg - + if not obj: pass - + elif isinstance(obj,Part.Shape): fill = 'url(#'+fillstyle+')' lstyle = getLineStyle() svg += getPath(obj.Edges,pathname="") - - + + elif getType(obj) == "Dimension": if obj.ViewObject.Proxy: if hasattr(obj.ViewObject.Proxy,"p1"): @@ -2019,7 +2019,7 @@ def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct rv = FreeCAD.Rotation(r[0],r[1],r[2],r[3]).multVec(FreeCAD.Vector(1,0,0)) angle = -DraftVecUtils.angle(getProj(rv)) #angle = -DraftVecUtils.angle(p3.sub(p2)) - + # drawing lines svg = '\n' svg += '\n' n += 1 - + elif getType(obj) == "Space": "returns an SVG fragment for the text of a space" c = getrgb(obj.ViewObject.TextColor) @@ -2180,7 +2180,7 @@ def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct svg += getText(c,fontsize,n,a,getProj(p2),t2,linespacing,j,flip=True) elif obj.isDerivedFrom('Part::Feature'): - if obj.Shape.isNull(): + if obj.Shape.isNull(): return '' # setting fill if obj.Shape.Faces: @@ -2202,7 +2202,7 @@ def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct else: fill = 'none' lstyle = getLineStyle() - + if len(obj.Shape.Vertexes) > 1: wiredEdges = [] if obj.Shape.Faces: @@ -2227,7 +2227,7 @@ def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct else: svg = getPath(obj.Shape.Edges) return svg - + def getrgb(color,testbw=True): """getRGB(color,[testbw]): returns a rgb value #000000 from a freecad color if testwb = True (default), pure white will be converted into pure black""" @@ -2329,7 +2329,7 @@ def makeSketch(objectslist,autoconstraints=False,addTo=None,delete=False,name="S EndPoint = 2 MiddlePoint = 3 deletable = None - + if not isinstance(objectslist,list): objectslist = [objectslist] for obj in objectslist: @@ -2456,7 +2456,7 @@ def makePoint(X=0, Y=0, Z=0,color=None,name = "Point", point_size= 5): ''' makePoint(x,y,z ,[color(r,g,b),point_size]) or makePoint(Vector,color(r,g,b),point_size]) - creates a Point in the current document. - example usage: + example usage: p1 = makePoint() p1.ViewObject.Visibility= False # make it invisible p1.ViewObject.Visibility= True # make it visible @@ -2485,7 +2485,7 @@ def makePoint(X=0, Y=0, Z=0,color=None,name = "Point", point_size= 5): return obj def makeShapeString(String,FontFile,Size = 100,Tracking = 0): - '''ShapeString(Text,FontFile,Height,Track): Turns a text string + '''ShapeString(Text,FontFile,Height,Track): Turns a text string into a Compound Shape''' obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython","ShapeString") _ShapeString(obj) @@ -2493,7 +2493,7 @@ def makeShapeString(String,FontFile,Size = 100,Tracking = 0): obj.FontFile = FontFile obj.Size = Size obj.Tracking = Tracking - + if gui: _ViewProviderDraft(obj.ViewObject) formatObject(obj) @@ -2542,7 +2542,7 @@ def clone(obj,delta=None): cl.Placement = obj[0].Placement formatObject(cl,obj[0]) return cl - + def getCloneBase(obj,strict=False): '''getCloneBase(obj,[strict]): returns the object cloned by this object, if any, or this object if it is no clone. If strict is True, if this object is @@ -2560,7 +2560,7 @@ def getCloneBase(obj,strict=False): def mirror(objlist,p1,p2): '''mirror(objlist,p1,p2,[clone]): creates a mirrored version of the given object(s) along an axis that passes through the two vectors p1 and p2.''' - + if not objlist: FreeCAD.Console.PrintError(translate("draft","No object given\n")) return @@ -2569,10 +2569,10 @@ def mirror(objlist,p1,p2): return if not isinstance(objlist,list): objlist = [objlist] - + result = [] - - for obj in objlist: + + for obj in objlist: mir = FreeCAD.ActiveDocument.addObject("Part::Mirroring","mirror") mir.Label = "Mirror of "+obj.Label mir.Source = obj @@ -2585,11 +2585,11 @@ def mirror(objlist,p1,p2): mir.Normal = pnorm formatObject(mir,obj) result.append(mir) - + if len(result) == 1: result = result[0] return result - + def heal(objlist=None,delete=True,reparent=True): '''heal([objlist],[delete],[reparent]) - recreates Draft objects that are damaged, @@ -2597,7 +2597,7 @@ def heal(objlist=None,delete=True,reparent=True): the damaged objects are deleted (default). If ran without arguments, all the objects in the document will be healed if they are damaged. If reparent is True (default), new objects go at the very same place in the tree than their original.''' - + auto = False if not objlist: @@ -2612,7 +2612,7 @@ def heal(objlist=None,delete=True,reparent=True): dellist = [] got = False - + for obj in objlist: dtype = getType(obj) ftype = obj.TypeId @@ -2658,7 +2658,7 @@ def heal(objlist=None,delete=True,reparent=True): if dellist and delete: 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.""" @@ -2671,8 +2671,8 @@ def makeFacebinder(selectionset,name="Facebinder"): faces = [] fb.Proxy.addSubobjects(fb,selectionset) return fb - - + + 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. @@ -2680,21 +2680,21 @@ def upgrade(objects,delete=False,force=None): force a certain way of upgrading. It can be: makeCompound, closeGroupWires, makeSolid, closeWire, turnToParts, makeFusion, makeShell, makeFaces, draftify, joinFaces, makeSketchFace, makeWires - Returns a dictionnary containing two lists, a list of new objects and a list + Returns a dictionnary containing two lists, a list of new objects and a list of objects to be deleted""" import Part, DraftGeomUtils from DraftTools import msg,translate - + 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 @@ -2713,7 +2713,7 @@ def upgrade(objects,delete=False,force=None): def closeGroupWires(groupslist): """closes every open wire in the given groups""" result = False - for grp in groupslist: + for grp in groupslist: for obj in grp.Group: newobj = closeWire(obj) # add new objects to their respective groups @@ -2739,7 +2739,7 @@ def upgrade(objects,delete=False,force=None): addList.append(newobj) deleteList.append(obj) return newob - + def closeWire(obj): """closes a wire object, if possible""" if obj.Shape.Faces: @@ -2787,7 +2787,7 @@ def upgrade(objects,delete=False,force=None): 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) @@ -2810,7 +2810,7 @@ def upgrade(objects,delete=False,force=None): deleteList.extend(objectslist) return newobj return None - + def joinFaces(objectslist): """makes one big face from selected objects, if possible""" faces = [] @@ -2832,7 +2832,7 @@ def upgrade(objects,delete=False,force=None): deleteList.extend(objectslist) return newobj return None - + def makeSketchFace(obj): """Makes a Draft face out of a sketch""" newobj = makeWire(obj.Shape,closed=True) @@ -2842,7 +2842,7 @@ def upgrade(objects,delete=False,force=None): addList.append(newobj) return newobj return None - + def makeFaces(objectslist): """make a face from every closed wire in the list""" result = False @@ -2873,7 +2873,7 @@ def upgrade(objects,delete=False,force=None): w = Part.Wire(nedges) except Part.OCCError: return None - else: + else: if len(w.Edges) == len(edges): newobj = FreeCAD.ActiveDocument.addObject("Part::Feature","Wire") newobj.Shape = w @@ -2922,7 +2922,7 @@ def upgrade(objects,delete=False,force=None): #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"]: @@ -2932,49 +2932,49 @@ def upgrade(objects,delete=False,force=None): 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: msg(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: msg(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 + + # we have one shell: we try to make a solid if (len(objects) == 1) and (len(faces) > 3): result = makeSolid(objects[0]) if result: msg(translate("draft", "Found 1 solidificable object: solidifying it\n")) - - # we have exactly 2 objects: we fuse them + + # we have exactly 2 objects: we fuse them elif (len(objects) == 2) and (not curves): result = makeFusion(objects[0],objects[1]) if result: msg(translate("draft", "Found 2 objects: fusing them\n")) - - # we have many separate faces: we try to make a shell + + # 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: msg(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: msg(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: msg(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 @@ -2987,10 +2987,10 @@ def upgrade(objects,delete=False,force=None): if isinstance(e.Curve,Part.Line): result = turnToLine(objects[0]) if result: msg(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]) @@ -3005,12 +3005,12 @@ def upgrade(objects,delete=False,force=None): elif (len(openwires) == 1) and (not faces) and (not loneedges): result = closeWire(objects[0]) if result: msg(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: msg(translate("draft", "Found several open wires: joining them\n")) - + # only loneedges: we try to join them elif loneedges and (not facewires): result = makeWires(objects) @@ -3020,11 +3020,11 @@ def upgrade(objects,delete=False,force=None): elif (len(objects) > 1): result = makeCompound(objects) if result: msg(translate("draft", "Found several non-treatable objects: creating compound\n")) - + # no result has been obtained if not result: msg(translate("draft", "Unable to upgrade these objects.\n")) - + if delete: names = [] for o in deleteList: @@ -3034,28 +3034,28 @@ def upgrade(objects,delete=False,force=None): FreeCAD.ActiveDocument.removeObject(n) 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. The force attribute can be used to force a certain way of downgrading. It can be: explode, shapify, subtr, splitFaces, cut2, getWire, splitWires, splitCompounds. - Returns a dictionnary containing two lists, a list of new objects and a list + Returns a dictionnary containing two lists, a list of new objects and a list of objects to be deleted""" - + import Part, DraftGeomUtils from DraftTools import msg,translate - + if not isinstance(objects,list): objects = [objects] global deleteList, addList deleteList = [] addList = [] - + # actions definitions - + def explode(obj): """explodes a Draft block""" pl = obj.Placement @@ -3067,7 +3067,7 @@ def downgrade(objects,delete=False,force=None): deleteList(obj) return newobj return None - + def cut2(objects): """cuts first object from the last one""" newobj = cut(objects[0],objects[1]) @@ -3088,7 +3088,7 @@ def downgrade(objects,delete=False,force=None): result = True deleteList.append(o) return result - + def splitFaces(objects): """split faces contained in objects into new objects""" result = False @@ -3101,7 +3101,7 @@ def downgrade(objects,delete=False,force=None): result = True deleteList.append(o) return result - + def subtr(objects): """subtracts objects from the first one""" faces = [] @@ -3118,7 +3118,7 @@ def downgrade(objects,delete=False,force=None): addList.append(newobj) return newobj return None - + def getWire(obj): """gets the wire from a face object""" result = False @@ -3129,7 +3129,7 @@ def downgrade(objects,delete=False,force=None): result = True deleteList.append(obj) return result - + def splitWires(objects): """splits the wires contained in objects into edges""" result = False @@ -3142,9 +3142,9 @@ def downgrade(objects,delete=False,force=None): deleteList.append(o) result = True return result - + # analyzing objects - + faces = [] edges = [] onlyedges = True @@ -3186,11 +3186,11 @@ def downgrade(objects,delete=False,force=None): result = splitCompounds(objects) #print(result) if result: msg(translate("draft", "Found 1 multi-solids compound: exploding it\n")) - + # special case, we have one parametric object: we "de-parametrize" it elif (len(objects) == 1) and (objects[0].isDerivedFrom("Part::Feature")) and ("Base" in objects[0].PropertiesList): result = shapify(objects[0]) - if result: + if result: msg(translate("draft", "Found 1 parametric object: breaking its dependencies\n")) addList.append(result) #deleteList.append(objects[0]) @@ -3225,7 +3225,7 @@ def downgrade(objects,delete=False,force=None): # no result has been obtained if not result: msg(translate("draft", "No more downgrade possible\n")) - + if delete: names = [] for o in deleteList: @@ -3252,17 +3252,17 @@ class _DraftObject: def __setstate__(self,state): if state: - self.Type = state + self.Type = state def execute(self,obj): pass def onChanged(self, obj, prop): - pass + pass class _ViewProviderDraft: "The base class for Draft Viewproviders" - + def __init__(self, vobj): from DraftTools import translate vobj.Proxy = self @@ -3279,7 +3279,7 @@ class _ViewProviderDraft: def __setstate__(self, state): return None - + def attach(self,vobj): self.texture = None self.texcoords = None @@ -3353,7 +3353,7 @@ class _ViewProviderDraft: if vobj.PatternSize: s = vobj.PatternSize self.texcoords.directionS.setValue(s,0,0) - self.texcoords.directionT.setValue(0,s,0) + self.texcoords.directionT.setValue(0,s,0) return def execute(self,vobj): @@ -3370,7 +3370,7 @@ class _ViewProviderDraft: FreeCAD.activeDraftCommand.finish() FreeCADGui.Control.closeDialog() return False - + def getIcon(self): return(":/icons/Draft_Draft.svg") @@ -3386,7 +3386,7 @@ class _ViewProviderDraft: class _ViewProviderDraftAlt(_ViewProviderDraft): "a view provider that doesn't swallow its base object" - + def __init__(self,vobj): _ViewProviderDraft.__init__(self,vobj) @@ -3395,7 +3395,7 @@ class _ViewProviderDraftAlt(_ViewProviderDraft): class _ViewProviderDraftPart(_ViewProviderDraftAlt): "a view provider that displays a Part icon instead of a Draft icon" - + def __init__(self,vobj): _ViewProviderDraftAlt.__init__(self,vobj) @@ -3418,7 +3418,7 @@ class _Dimension(_DraftObject): obj.Start = FreeCAD.Vector(0,0,0) obj.End = FreeCAD.Vector(1,0,0) obj.Dimline = FreeCAD.Vector(0,1,0) - + def onChanged(self,obj,prop): if hasattr(obj,"Distance"): obj.setEditorMode('Distance',1) @@ -3426,7 +3426,7 @@ class _Dimension(_DraftObject): obj.setEditorMode('Normal',2) if hasattr(obj,"Support"): obj.setEditorMode('Support',2) - + def execute(self, obj): if obj.LinkedGeometry: if "Edge" in obj.LinkedGeometry[0][1]: @@ -3468,7 +3468,7 @@ class _ViewProviderDimension(_ViewProviderDraft): obj.addProperty("App::PropertyColor","LineColor","Draft","Line color") obj.addProperty("App::PropertyDistance","ExtLines","Draft","Length of the extension lines") obj.addProperty("App::PropertyBool","FlipArrows","Draft","Rotate the dimension arrows 180 degrees") - obj.addProperty("App::PropertyBool","ShowUnit","Draft","Show the unit suffix") + obj.addProperty("App::PropertyBool","ShowUnit","Draft","Show the unit suffix") obj.addProperty("App::PropertyVectorDistance","TextPosition","Draft","The position of the text. Leave (0,0,0) for automatic position") obj.addProperty("App::PropertyString","Override","Draft","Text override. Use $dim to insert the dimension length") obj.FontSize = getParam("textheight",0.20) @@ -3509,8 +3509,8 @@ class _ViewProviderDimension(_ViewProviderDraft): self.trans1 = coin.SoTransform() self.coord2 = coin.SoCoordinate3() self.trans2 = coin.SoTransform() - self.marks = coin.SoSeparator() - self.drawstyle = coin.SoDrawStyle() + self.marks = coin.SoSeparator() + self.drawstyle = coin.SoDrawStyle() self.line = coin.SoType.fromName("SoBrepEdgeSet").createInstance() self.coords = coin.SoCoordinate3() self.node = coin.SoGroup() @@ -3534,21 +3534,21 @@ class _ViewProviderDimension(_ViewProviderDraft): self.onChanged(vobj,"FontName") self.onChanged(vobj,"ArrowType") self.onChanged(vobj,"LineColor") - + def updateData(self, obj, prop): "called when the base object is changed" import DraftGui if prop in ["Start","End","Dimline","Direction"]: - + if obj.Start == obj.End: return - + if not hasattr(self,"node"): return - + import Part, DraftGeomUtils from pivy import coin - + # calculate the 4 points self.p1 = obj.Start self.p4 = obj.End @@ -3597,20 +3597,20 @@ class _ViewProviderDimension(_ViewProviderDraft): self.coord1.point.setValue((self.p2.x,self.p2.y,self.p2.z)) self.trans2.translation.setValue((self.p3.x,self.p3.y,self.p3.z)) self.coord2.point.setValue((self.p3.x,self.p3.y,self.p3.z)) - + # calculate the text position and orientation if hasattr(obj,"Normal"): if DraftVecUtils.isNull(obj.Normal): - if proj: + if proj: norm = (self.p3.sub(self.p2).cross(proj)).negative() - else: + else: norm = Vector(0,0,1) else: norm = obj.Normal else: if proj: - norm = (self.p3.sub(self.p2).cross(proj)).negative() - else: + norm = (self.p3.sub(self.p2).cross(proj)).negative() + else: norm = Vector(0,0,1) if not DraftVecUtils.isNull(norm): norm.normalize() @@ -3629,7 +3629,7 @@ class _ViewProviderDimension(_ViewProviderDraft): offset = DraftVecUtils.scaleTo(v1,obj.ViewObject.TextSpacing.Value) else: offset = DraftVecUtils.scaleTo(v1,0.05) - + # setting text try: m = obj.ViewObject.DisplayMode @@ -3665,7 +3665,7 @@ class _ViewProviderDimension(_ViewProviderDraft): # set the distance property if round(obj.Distance.Value,precision()) != round(l,precision()): obj.Distance = l - + # set the lines if m == "3D": # calculate the spacing of the text @@ -3691,7 +3691,7 @@ class _ViewProviderDimension(_ViewProviderDraft): def onChanged(self, vobj, prop): "called when a view property has changed" - + if (prop == "FontSize") and hasattr(vobj,"FontSize"): if hasattr(self,"font"): self.font.size = vobj.FontSize.Value @@ -3712,25 +3712,25 @@ class _ViewProviderDimension(_ViewProviderDraft): elif (prop in ["ArrowSize","ArrowType"]) and hasattr(vobj,"ArrowSize"): if hasattr(self,"node") and hasattr(self,"p2"): from pivy import coin - + if not hasattr(vobj,"ArrowType"): return - + if self.p3.x < self.p2.x: inv = False else: inv = True - + # set scale symbol = arrowtypes.index(vobj.ArrowType) s = vobj.ArrowSize.Value self.trans1.scaleFactor.setValue((s,s,s)) self.trans2.scaleFactor.setValue((s,s,s)) - + # remove existing nodes self.node.removeChild(self.marks) self.node3d.removeChild(self.marks) - + # set new nodes self.marks = coin.SoSeparator() self.marks.addChild(self.color) @@ -3746,8 +3746,8 @@ class _ViewProviderDimension(_ViewProviderDraft): s2.addChild(self.coord2) else: s2.addChild(self.trans2) - s2.addChild(dimSymbol(symbol,invert=inv)) - self.marks.addChild(s2) + s2.addChild(dimSymbol(symbol,invert=inv)) + self.marks.addChild(s2) self.node.insertChild(self.marks,2) self.node3d.insertChild(self.marks,2) vobj.Object.touch() @@ -3798,7 +3798,7 @@ class _ViewProviderDimension(_ViewProviderDraft): def __getstate__(self): return self.Object.ViewObject.DisplayMode - + def __setstate__(self,state): if state: self.defaultmode = state @@ -3820,7 +3820,7 @@ class _AngularDimension(_DraftObject): obj.LastAngle = 90 obj.Dimline = FreeCAD.Vector(0,1,0) obj.Center = FreeCAD.Vector(0,0,0) - + def onChanged(self,obj,prop): if hasattr(obj,"Angle"): obj.setEditorMode('Angle',1) @@ -3828,7 +3828,7 @@ class _AngularDimension(_DraftObject): obj.setEditorMode('Normal',2) if hasattr(obj,"Support"): obj.setEditorMode('Support',2) - + def execute(self, fp): if fp.ViewObject: fp.ViewObject.update() @@ -3887,7 +3887,7 @@ class _ViewProviderAngularDimension(_ViewProviderDraft): self.coord2 = coin.SoCoordinate3() self.trans2 = coin.SoTransform() self.marks = coin.SoSeparator() - self.drawstyle = coin.SoDrawStyle() + self.drawstyle = coin.SoDrawStyle() self.coords = coin.SoCoordinate3() self.arc = coin.SoType.fromName("SoBrepEdgeSet").createInstance() self.node = coin.SoGroup() @@ -3920,7 +3920,7 @@ class _ViewProviderAngularDimension(_ViewProviderDraft): text = None ivob = None arcsegs = 24 - + # calculate the arc data if DraftVecUtils.isNull(obj.Normal): norm = Vector(0,0,1) @@ -3932,7 +3932,7 @@ class _ViewProviderAngularDimension(_ViewProviderDraft): self.p3 = self.circle.Vertexes[-1].Point mp = DraftGeomUtils.findMidpoint(self.circle.Edges[0]) ray = mp.sub(obj.Center) - + # set text value if obj.LastAngle.Value > obj.FirstAngle.Value: a = obj.LastAngle.Value - obj.FirstAngle.Value @@ -3949,13 +3949,13 @@ class _ViewProviderAngularDimension(_ViewProviderDraft): self.string = obj.ViewObject.Override.replace("$dim",\ self.string) self.text.string = self.text3d.string = stringencodecoin(self.string) - + # check display mode try: m = obj.ViewObject.DisplayMode except: # swallow all exceptions here since it always fails on first run (Displaymode enum no set yet) m = ["2D","3D"][getParam("dimstyle",0)] - + # set the arc if m == "3D": # calculate the spacing of the text @@ -3987,7 +3987,7 @@ class _ViewProviderAngularDimension(_ViewProviderDraft): pts.append([p.x,p.y,p.z]) self.coords.point.setValues(pts) self.arc.coordIndex.setValues(0,arcsegs+1,list(range(arcsegs+1))) - + # set the arrow coords and rotation self.trans1.translation.setValue((self.p2.x,self.p2.y,self.p2.z)) self.coord1.point.setValue((self.p2.x,self.p2.y,self.p2.z)) @@ -4009,7 +4009,7 @@ class _ViewProviderAngularDimension(_ViewProviderDraft): q2 = FreeCAD.Placement(DraftVecUtils.getPlaneRotation(u2,v2,w2)).Rotation.Q self.trans1.rotation.setValue((q1[0],q1[1],q1[2],q1[3])) self.trans2.rotation.setValue((q2[0],q2[1],q2[2],q2[3])) - + # setting text pos & rot self.tbase = mp if hasattr(obj.ViewObject,"TextPosition"): @@ -4020,7 +4020,7 @@ class _ViewProviderAngularDimension(_ViewProviderDraft): v3 = norm.cross(u3) r = FreeCAD.Placement(DraftVecUtils.getPlaneRotation(u3,v3,norm)).Rotation offset = r.multVec(Vector(0,1,0)) - + if hasattr(obj.ViewObject,"TextSpacing"): offset = DraftVecUtils.scaleTo(offset,obj.ViewObject.TextSpacing.Value) else: @@ -4031,7 +4031,7 @@ class _ViewProviderAngularDimension(_ViewProviderDraft): q = r.Q self.textpos.translation.setValue([self.tbase.x,self.tbase.y,self.tbase.z]) self.textpos.rotation = coin.SbRotation(q[0],q[1],q[2],q[3]) - + # set the angle property if round(obj.Angle,precision()) != round(a,precision()): obj.Angle = a @@ -4057,20 +4057,20 @@ class _ViewProviderAngularDimension(_ViewProviderDraft): elif prop in ["ArrowSize","ArrowType"]: if hasattr(self,"node") and hasattr(self,"p2"): from pivy import coin - + if not hasattr(vobj,"ArrowType"): return - + # set scale symbol = arrowtypes.index(vobj.ArrowType) s = vobj.ArrowSize.Value self.trans1.scaleFactor.setValue((s,s,s)) self.trans2.scaleFactor.setValue((s,s,s)) - + # remove existing nodes self.node.removeChild(self.marks) self.node3d.removeChild(self.marks) - + # set new nodes self.marks = coin.SoSeparator() self.marks.addChild(self.color) @@ -4086,8 +4086,8 @@ class _ViewProviderAngularDimension(_ViewProviderDraft): s2.addChild(self.coord2) else: s2.addChild(self.trans2) - s2.addChild(dimSymbol(symbol,invert=True)) - self.marks.addChild(s2) + s2.addChild(dimSymbol(symbol,invert=True)) + self.marks.addChild(s2) self.node.insertChild(self.marks,2) self.node3d.insertChild(self.marks,2) vobj.Object.touch() @@ -4146,7 +4146,7 @@ class _ViewProviderAngularDimension(_ViewProviderDraft): class _Rectangle(_DraftObject): "The Rectangle object" - + def __init__(self, obj): _DraftObject.__init__(self,obj,"Rectangle") obj.addProperty("App::PropertyDistance","Length","Draft","Length of the rectangle") @@ -4156,7 +4156,7 @@ class _Rectangle(_DraftObject): obj.addProperty("App::PropertyBool","MakeFace","Draft","Create a face") obj.addProperty("App::PropertyInteger","Rows","Draft","Horizontal subdivisions of this rectange") obj.addProperty("App::PropertyInteger","Columns","Draft","Vertical subdivisions of this rectange") - obj.MakeFace = getParam("fillmode",True) + obj.MakeFace = getParam("fillmode",True) obj.Length=1 obj.Height=1 obj.Rows=1 @@ -4191,7 +4191,7 @@ class _Rectangle(_DraftObject): if obj.ChamferSize.Value != 0: w = DraftGeomUtils.filletWire(p,obj.ChamferSize.Value,chamfer=True) if w: - p = w + p = w if "FilletRadius" in obj.PropertiesList: if obj.FilletRadius.Value != 0: w = DraftGeomUtils.filletWire(p,obj.FilletRadius.Value) @@ -4213,7 +4213,7 @@ class _Rectangle(_DraftObject): if obj.ChamferSize.Value != 0: w = DraftGeomUtils.filletWire(shape,obj.ChamferSize.Value,chamfer=True) if w: - shape = w + shape = w if "FilletRadius" in obj.PropertiesList: if obj.FilletRadius.Value != 0: w = DraftGeomUtils.filletWire(shape,obj.FilletRadius.Value) @@ -4236,7 +4236,7 @@ class _ViewProviderRectangle(_ViewProviderDraft): class _Circle(_DraftObject): "The Circle object" - + def __init__(self, obj): _DraftObject.__init__(self,obj,"Circle") obj.addProperty("App::PropertyAngle","FirstAngle","Draft","Start angle of the arc") @@ -4259,10 +4259,10 @@ class _Circle(_DraftObject): obj.Shape = shape obj.Placement = plm obj.positionBySupport() - + class _Ellipse(_DraftObject): "The Circle object" - + def __init__(self, obj): _DraftObject.__init__(self,obj,"Ellipse") obj.addProperty("App::PropertyAngle","FirstAngle","Draft","Start angle of the arc") @@ -4299,7 +4299,7 @@ class _Ellipse(_DraftObject): class _Wire(_DraftObject): "The Wire object" - + def __init__(self, obj): _DraftObject.__init__(self,obj,"Wire") obj.addProperty("App::PropertyVectorList","Points","Draft","The vertices of the wire") @@ -4312,7 +4312,7 @@ class _Wire(_DraftObject): obj.addProperty("App::PropertyLength","FilletRadius","Draft","Radius to use to fillet the corners") obj.addProperty("App::PropertyLength","ChamferSize","Draft","Size of the chamfer to give to the corners") obj.addProperty("App::PropertyBool","MakeFace","Draft","Create a face if this object is closed") - obj.addProperty("App::PropertyInteger","Subdivisions","Draft","The number of subdivisions of each edge") + obj.addProperty("App::PropertyInteger","Subdivisions","Draft","The number of subdivisions of each edge") obj.MakeFace = getParam("fillmode",True) obj.Closed = False @@ -4406,7 +4406,7 @@ class _Wire(_DraftObject): if obj.ChamferSize.Value != 0: w = DraftGeomUtils.filletWire(shape,obj.ChamferSize.Value,chamfer=True) if w: - shape = w + shape = w if "FilletRadius" in obj.PropertiesList: if obj.FilletRadius.Value != 0: w = DraftGeomUtils.filletWire(shape,obj.FilletRadius.Value) @@ -4419,7 +4419,7 @@ class _Wire(_DraftObject): obj.Placement = plm obj.positionBySupport() self.onChanged(obj,"Placement") - + def onChanged(self, obj, prop): if prop == "Start": pts = obj.Points @@ -4459,7 +4459,7 @@ class _Wire(_DraftObject): obj.setEditorMode('End',2) if hasattr(obj,"Length"): obj.setEditorMode('Length',2) - + class _ViewProviderWire(_ViewProviderDraft): "A View Provider for the Wire object" @@ -4470,7 +4470,7 @@ class _ViewProviderWire(_ViewProviderDraft): obj.addProperty("App::PropertyEnumeration","ArrowType","Draft","Arrow type") obj.ArrowSize = getParam("arrowsize",0.1) obj.ArrowType = arrowtypes - obj.ArrowType = arrowtypes[getParam("dimsymbol",0)] + obj.ArrowType = arrowtypes[getParam("dimsymbol",0)] def attach(self, obj): from pivy import coin @@ -4485,7 +4485,7 @@ class _ViewProviderWire(_ViewProviderDraft): self.pt.addChild(self.symbol) _ViewProviderDraft.attach(self,obj) self.onChanged(obj,"EndArrow") - + def updateData(self, obj, prop): if prop == "Points": if obj.Points: @@ -4531,10 +4531,10 @@ class _ViewProviderWire(_ViewProviderDraft): if hasattr(self.Object,"Base"): return [self.Object.Base,self.Object.Tool] return [] - + class _Polygon(_DraftObject): "The Polygon object" - + def __init__(self, obj): _DraftObject.__init__(self,obj,"Polygon") obj.addProperty("App::PropertyInteger","FacesNumber","Draft","Number of faces") @@ -4567,7 +4567,7 @@ class _Polygon(_DraftObject): if obj.ChamferSize.Value != 0: w = DraftGeomUtils.filletWire(shape,obj.ChamferSize.Value,chamfer=True) if w: - shape = w + shape = w if "FilletRadius" in obj.PropertiesList: if obj.FilletRadius.Value != 0: w = DraftGeomUtils.filletWire(shape,obj.FilletRadius.Value) @@ -4640,7 +4640,7 @@ class _DrawingView(_DraftObject): result += svg result += '' obj.ViewResult = result - + def getDXF(self,obj): "returns a DXF fragment" result = "" @@ -4654,7 +4654,7 @@ class _DrawingView(_DraftObject): class _BSpline(_DraftObject): "The BSpline object" - + def __init__(self, obj): _DraftObject.__init__(self,obj,"BSpline") obj.addProperty("App::PropertyVectorList","Points","Draft", "The points of the b-spline") @@ -4699,7 +4699,7 @@ class _BSpline(_DraftObject): self.knotSeq = self.parameterization(obj.Points, obj.Parameterization, obj.Closed) plm = obj.Placement if obj.Closed and (len(obj.Points) > 2): - if obj.Points[0] == obj.Points[-1]: # should not occur, but OCC will crash + if obj.Points[0] == obj.Points[-1]: # should not occur, but OCC will crash msg(translate('draft', "_BSpline.createGeometry: Closed with same first/last Point. Geometry not updated.\n"), "error") return spline = Part.BSplineCurve() @@ -4717,7 +4717,7 @@ class _BSpline(_DraftObject): except Part.OCCError: pass obj.Shape = shape - else: + else: spline = Part.BSplineCurve() spline.interpolate(obj.Points, PeriodicFlag = False, Parameters = self.knotSeq) obj.Shape = spline.toShape() @@ -4729,7 +4729,7 @@ _ViewProviderBSpline = _ViewProviderWire class _BezCurve(_DraftObject): "The BezCurve object" - + def __init__(self, obj): _DraftObject.__init__(self,obj,"BezCurve") obj.addProperty("App::PropertyVectorList","Points","Draft", @@ -4857,7 +4857,7 @@ _ViewProviderBezCurve = _ViewProviderWire class _Block(_DraftObject): "The Block object" - + def __init__(self, obj): _DraftObject.__init__(self,obj,"Block") obj.addProperty("App::PropertyLinkList","Components","Draft","The components of this block") @@ -4977,7 +4977,7 @@ class _Shape2DView(_DraftObject): comp.Placement = opl.inverse() if comp: obj.Shape = comp - + elif obj.Base.isDerivedFrom("App::DocumentObjectGroup"): shapes = [] objs = getGroupContents(obj.Base) @@ -4990,7 +4990,7 @@ class _Shape2DView(_DraftObject): import Part comp = Part.makeCompound(shapes) obj.Shape = self.getProjected(obj,comp,obj.Projection) - + elif obj.Base.isDerivedFrom("Part::Feature"): if not DraftVecUtils.isNull(obj.Projection): if obj.ProjectionMode == "Solid": @@ -5119,7 +5119,7 @@ class _PathArray(_DraftObject): _DraftObject.__init__(self,obj,"PathArray") obj.addProperty("App::PropertyLink","Base","Draft","The base object that must be duplicated") obj.addProperty("App::PropertyLink","PathObj","Draft","The path object along which to distribute objects") - obj.addProperty("App::PropertyLinkSubList","PathSubs","Draft","Selected subobjects (edges) of PathObj") + obj.addProperty("App::PropertyLinkSubList","PathSubs","Draft","Selected subobjects (edges) of PathObj") obj.addProperty("App::PropertyInteger","Count","Draft","Number of copies") obj.addProperty("App::PropertyVectorDistance","Xlate","Draft","Optional translation vector") obj.addProperty("App::PropertyBool","Align","Draft","Orientation of Base along path") @@ -5143,10 +5143,10 @@ class _PathArray(_DraftObject): else: FreeCAD.Console.PrintLog ("_PathArray.createGeometry: path " + obj.PathObj.Name + " has no edges\n") return - obj.Shape = self.pathArray(obj.Base.Shape,w,obj.Count,obj.Xlate,obj.Align) + obj.Shape = self.pathArray(obj.Base.Shape,w,obj.Count,obj.Xlate,obj.Align) if not DraftGeomUtils.isNull(pl): obj.Placement = pl - + def getWireFromSubs(self,obj): '''Make a wire from PathObj subelements''' import Part @@ -5155,7 +5155,7 @@ class _PathArray(_DraftObject): e = sub[0].Shape.getElement(sub[1]) sl.append(e) return Part.Wire(sl) - + def getParameterFromV0(self, edge, offset): '''return parameter at distance offset from edge.Vertexes[0]''' '''sb method in Part.TopoShapeEdge???''' @@ -5168,7 +5168,7 @@ class _PathArray(_DraftObject): # this edge is right way around length = offset return(edge.getParameterByLength(length)) - + def orientShape(self,shape,edge,offset,RefPt,xlate,align,normal=None): '''Orient shape to tangent at parm offset along edge.''' # http://en.wikipedia.org/wiki/Euler_angles @@ -5186,7 +5186,7 @@ class _PathArray(_DraftObject): ns.translate(RefPt+xlate) if not align: return ns - + # get local coord system - tangent, normal, binormal, if possible t = edge.tangentAt(self.getParameterFromV0(edge,offset)) t.normalize() @@ -5196,15 +5196,15 @@ class _PathArray(_DraftObject): else: n = edge.normalAt(self.getParameterFromV0(edge,offset)) n.normalize() - b = (t.cross(n)) + b = (t.cross(n)) b.normalize() except FreeCAD.Base.FreeCADError: # no normal defined here n = nullv - b = nullv + b = nullv FreeCAD.Console.PrintLog ("Draft PathArray.orientShape - Cannot calculate Path normal.\n") lnodes = z.cross(b) if lnodes != nullv: - lnodes.normalize() # Can't normalize null vector. + lnodes.normalize() # Can't normalize null vector. # pathological cases: if n == nullv: # 1) can't determine normal, don't align. psi = 0.0 @@ -5212,11 +5212,11 @@ class _PathArray(_DraftObject): phi = 0.0 FreeCAD.Console.PrintWarning("Draft PathArray.orientShape - Path normal is Null. Cannot align.\n") elif b == z: # 2) binormal is same as z - psi = math.degrees(DraftVecUtils.angle(x,t,z)) # align shape x to tangent + psi = math.degrees(DraftVecUtils.angle(x,t,z)) # align shape x to tangent theta = 0.0 phi = 0.0 FreeCAD.Console.PrintLog ("Draft PathArray.orientShape - Aligned to tangent only (b == z).\n") - else: # regular case + else: # regular case psi = math.degrees(DraftVecUtils.angle(x,lnodes,z)) theta = math.degrees(DraftVecUtils.angle(z,b,lnodes)) phi = math.degrees(DraftVecUtils.angle(lnodes,t,b)) @@ -5227,7 +5227,7 @@ class _PathArray(_DraftObject): if phi != 0.0: ns.rotate(RefPt,b,phi) return ns - + def pathArray(self,shape,pathwire,count,xlate,align): '''Distribute shapes along a path.''' import Part @@ -5249,31 +5249,31 @@ class _PathArray(_DraftObject): ns = self.orientShape(shape,path[-1],path[-1].Length,pt,xlate,align,normal) base.append(ns) if count < 3: - return(Part.makeCompound(base)) + return(Part.makeCompound(base)) - # place the middle shapes - if closedpath: - stop = count + # place the middle shapes + if closedpath: + stop = count else: - stop = count - 1 - step = float(cdist)/stop + stop = count - 1 + step = float(cdist)/stop remain = 0 travel = step - for i in range(1,stop): + for i in range(1,stop): # which edge in path should contain this shape? iend = len(ends) - 1 # avoids problems with float math travel > ends[-1] - for j in range(0,len(ends)): - if travel <= ends[j]: + for j in range(0,len(ends)): + if travel <= ends[j]: iend = j break # place shape at proper spot on proper edge remains = ends[iend] - travel - offset = path[iend].Length - remains + offset = path[iend].Length - remains pt = path[iend].valueAt(self.getParameterFromV0(path[iend],offset)) ns = self.orientShape(shape,path[iend],offset,pt,xlate,align,normal) base.append(ns) travel += step - return(Part.makeCompound(base)) + return(Part.makeCompound(base)) class _Point(_DraftObject): "The Draft Point object" @@ -5357,7 +5357,7 @@ class _Clone(_DraftObject): obj.Placement = pl if hasattr(obj,"positionBySupport"): obj.positionBySupport() - + def getSubVolume(self,obj,placement=None): # this allows clones of arch windows to return a subvolume too if obj.Objects: @@ -5371,38 +5371,38 @@ class _Clone(_DraftObject): class _ViewProviderClone: "a view provider that displays a Clone icon instead of a Draft icon" - + def __init__(self,vobj): vobj.Proxy = self def getIcon(self): return ":/icons/Draft_Clone.svg" - + def __getstate__(self): return None def __setstate__(self, state): return None - + def getDisplayModes(self, vobj): modes=[] return modes def setDisplayMode(self, mode): return mode - + class _ViewProviderDraftArray(_ViewProviderDraft): "a view provider that displays a Array icon instead of a Draft icon" - + def __init__(self,vobj): _ViewProviderDraft.__init__(self,vobj) def getIcon(self): return ":/icons/Draft_Array.svg" - + class _ShapeString(_DraftObject): "The ShapeString object" - + def __init__(self, obj): _DraftObject.__init__(self,obj,"ShapeString") obj.addProperty("App::PropertyString","String","Draft","Text string") @@ -5410,8 +5410,8 @@ class _ShapeString(_DraftObject): obj.addProperty("App::PropertyLength","Size","Draft","Height of text") obj.addProperty("App::PropertyLength","Tracking","Draft", "Inter-character spacing") - - def execute(self, obj): + + def execute(self, obj): import Part # import OpenSCAD2Dgeom import os @@ -5420,7 +5420,7 @@ class _ShapeString(_DraftObject): plm = obj.Placement CharList = Part.makeWireString(obj.String,obj.FontFile,obj.Size,obj.Tracking) SSChars = [] - + # test a simple letter to know if we have a sticky font or not sticky = False testWire = Part.makeWireString("L",obj.FontFile,obj.Size,obj.Tracking)[0][0] @@ -5434,7 +5434,7 @@ class _ShapeString(_DraftObject): sticky = True else: sticky = True - + for char in CharList: if sticky: for CWire in char: @@ -5452,8 +5452,8 @@ class _ShapeString(_DraftObject): s = self.makeFaces(char) SSChars.append(s) shape = Part.Compound(SSChars) - obj.Shape = shape - if plm: + obj.Shape = shape + if plm: obj.Placement = plm obj.positionBySupport() @@ -5502,7 +5502,7 @@ class _ShapeString(_DraftObject): import Part if len(facelist) == 1: return(facelist[0]) - + sortedfaces = sorted(facelist,key=(lambda shape: shape.Area),reverse=True) biggest = sortedfaces[0] @@ -5518,18 +5518,18 @@ class _ShapeString(_DraftObject): # biggest completely overlaps current face ==> cut result = result.cut(face) # elif biggest.common(face).Area == 0: - elif bcfA <= eps: + elif bcfA <= eps: # island islands.append(face) else: # partial overlap - (font designer error?) - result = result.fuse(face) + result = result.fuse(face) #glyphfaces = [result] wl = result.Wires for w in wl: w.fixWire() glyphfaces = [Part.Face(wl)] - glyphfaces.extend(islands) + glyphfaces.extend(islands) ret = Part.Compound(glyphfaces) # should we fuse these instead of making compound? return ret @@ -5569,7 +5569,7 @@ class _Facebinder(_DraftObject): return obj.Shape = sh obj.Placement = pl - + def addSubobjects(self,obj,facelinks): "adds facelinks to this facebinder" objs = obj.Faces @@ -5584,12 +5584,12 @@ class _Facebinder(_DraftObject): objs.append((o.Object,el)) obj.Faces = objs self.execute(obj) - - + + class _ViewProviderFacebinder(_ViewProviderDraft): def __init__(self,vobj): _ViewProviderDraft.__init__(self,vobj) - + def setEdit(self,vobj,mode): import DraftGui taskd = DraftGui.FacebinderTaskPanel() @@ -5600,7 +5600,7 @@ class _ViewProviderFacebinder(_ViewProviderDraft): def unsetEdit(self,vobj,mode): FreeCADGui.Control.closeDialog() - return False + return False class _VisGroup: @@ -5619,7 +5619,7 @@ class _VisGroup: def execute(self,obj): pass - + class _ViewProviderVisGroup: "A View Provider for the VisGroup object" def __init__(self,vobj): @@ -5641,7 +5641,7 @@ class _ViewProviderVisGroup: def attach(self,vobj): self.Object = vobj.Object return - + def claimChildren(self): return self.Object.Group From c0a5310511c42e4ef947de2be2e3c583b0f2b219 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Fri, 19 Aug 2016 19:09:23 -0300 Subject: [PATCH 2/3] Arch: fixed typo --- src/Mod/Arch/ArchComponent.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mod/Arch/ArchComponent.py b/src/Mod/Arch/ArchComponent.py index 00fcdbcc3..310b10b2a 100644 --- a/src/Mod/Arch/ArchComponent.py +++ b/src/Mod/Arch/ArchComponent.py @@ -772,7 +772,7 @@ class ViewProviderComponent: if Draft.getType(self.Object) == "Wall": if Draft.getType(s) == "Roof": continue - if (Draft.getType(s) == "Window") or Draft.isCloneOf(s,"Window"): + if (Draft.getType(s) == "Window") or Draft.isClone(s,"Window"): if not swalW: continue c.append(s) From 0a8ed569629785648f4a41331b3da468cbe25cf5 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Fri, 19 Aug 2016 20:24:27 -0300 Subject: [PATCH 3/3] Draft: Pressing Wire when several connected lines are selected now turns them into a wire --- src/Mod/Draft/DraftTools.py | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/Mod/Draft/DraftTools.py b/src/Mod/Draft/DraftTools.py index f5741fbfb..26d4a5e14 100644 --- a/src/Mod/Draft/DraftTools.py +++ b/src/Mod/Draft/DraftTools.py @@ -569,15 +569,42 @@ class Line(Creator): class Wire(Line): "a FreeCAD command for creating a wire" + def __init__(self): Line.__init__(self,wiremode=True) + def GetResources(self): return {'Pixmap' : 'Draft_Wire', 'Accel' : "W, I", 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Wire", "DWire"), 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Wire", "Creates a multiple-point DraftWire (DWire). CTRL to snap, SHIFT to constrain")} + def Activated(self): - Line.Activated(self,name=translate("draft","DWire")) + + # allow to convert several Draft Lines to a Wire + if len(FreeCADGui.Selection.getSelection()) > 1: + edges = [] + for o in FreeCADGui.Selection.getSelection(): + if Draft.getType(o) != "Wire": + edges = [] + break + edges.extend(o.Shape.Edges) + if edges: + try: + import Part + w = Part.Wire(edges) + except: + msg(translate("draft", "Unable to create a Wire from selected objects\n"),mode="error") + else: + pts = ",".join([str(v.Point) for v in w.Vertexes]) + pts = pts.replace("Vector","FreeCAD.Vector") + rems = ["FreeCAD.ActiveDocument.removeObject(\""+o.Name+"\")" for o in FreeCADGui.Selection.getSelection()] + FreeCADGui.addModule("Draft") + todo.delayCommit([(translate("draft","Convert to Wire"), + ['Draft.makeWire(['+pts+'])']+rems)]) + return + + Line.Activated(self,name=translate("draft","DWire")) class BSpline(Line):