def update(self,fp,edges=None): from DraftVecUtils import rounded from math import degrees if not edges and hasattr(fp.Base,'Shape'): edges=fp.Base.Shape.Edges if not edges: FreeCAD.Console.PrintError('Base has not valid edges\n') return pipes=list() for e in edges: #---Create the tube--- p=pCmd.makePipe([fp.PSize,fp.OD,fp.thk,e.Length],pos=e.valueAt(0),Z=e.tangentAt(0)) p.PRating=fp.PRating p.PSize=fp.PSize pCmd.moveToPyLi(p,fp.Label) pipes.append(p) n=len(pipes)-1 if n and not fCmd.isParallel(fCmd.beamAx(pipes[n]),fCmd.beamAx(pipes[n-1])): #---Create the curve--- propList=[fp.PSize,fp.OD,fp.thk,90,fp.BendRadius] c=pCmd.makeElbowBetweenThings(edges[n],edges[n-1],propList) if c: portA,portB=[c.Placement.multVec(port) for port in c.Ports] #---Trim the tube--- p1,p2=pipes[-2:] fCmd.extendTheBeam(p1,portA) fCmd.extendTheBeam(p2,portB) pCmd.moveToPyLi(c,fp.Label)
def makeElbowBetweenThings(thing1=None, thing2=None, propList=None): ''' makeElbowBetweenThings(thing1, thing2, propList=None): Place one elbow at the intersection of thing1 and thing2. Things can be any combination of intersecting beams, pipes or edges. If nothing is passed as argument, the function attempts to take the first two edges selected in the view. propList is one optional list with 5 elements: DN (string): nominal diameter OD (float): outside diameter thk (float): shell thickness BA (float): bend angle - that will be recalculated! - BR (float): bend radius Default is "DN50 (SCH-STD)" Remember: property PRating must be defined afterwards ''' if not (thing1 and thing2): thing1,thing2=fCmd.edges()[:2] P=fCmd.intersectionCLines(thing1,thing2) directions=list() try: for thing in [thing1,thing2]: if fCmd.beams([thing]): directions.append(rounded((fCmd.beamAx(thing).multiply(thing.Height/2)+thing.Placement.Base)-P)) elif hasattr(thing,'ShapeType') and thing.ShapeType=='Edge': directions.append(rounded(thing.CenterOfMass-P)) except: return None ang=180-degrees(directions[0].getAngle(directions[1])) if ang==0 or ang==180: return None if not propList: propList=["DN50",60.3,3.91,ang,45.24] else: propList[3]=ang elb=makeElbow(propList,P,directions[0].negative().cross(directions[1].negative())) # mate the elbow ends with the pipes or edges b=fCmd.bisect(directions[0],directions[1]) elbBisect=rounded(fCmd.beamAx(elb,FreeCAD.Vector(1,1,0))) #if not rounded, fail in plane xz rot=FreeCAD.Rotation(elbBisect,b) elb.Placement.Rotation=rot.multiply(elb.Placement.Rotation) # trim the adjacent tubes #FreeCAD.activeDocument().recompute() # may delete this row? portA=elb.Placement.multVec(elb.Ports[0]) portB=elb.Placement.multVec(elb.Ports[1]) for tube in [t for t in [thing1,thing2] if fCmd.beams([t])]: vectA=tube.Shape.Solids[0].CenterOfMass-portA vectB=tube.Shape.Solids[0].CenterOfMass-portB if fCmd.isParallel(vectA,fCmd.beamAx(tube)): fCmd.extendTheBeam(tube,portA) else: fCmd.extendTheBeam(tube,portB) return elb
def doPipes(propList=['DN50',60.3,3,1000], pypeline=None): ''' propList = [ DN (string): nominal diameter OD (float): outside diameter thk (float): shell thickness H (float): length of pipe ] pypeline = string ''' FreeCAD.activeDocument().openTransaction('Insert pipe') plist=list() if len(fCmd.edges())==0: #..no edges selected vs=[v for sx in FreeCADGui.Selection.getSelectionEx() for so in sx.SubObjects for v in so.Vertexes] if len(vs)==0: # ...no vertexes selected plist.append(makePipe(propList)) else: # ... one or more vertexes for v in vs: plist.append(makePipe(propList,v.Point)) else: selex=FreeCADGui.Selection.getSelectionEx() for objex in selex: o=objex.Object if fCmd.faces(): # Face selected... for face in fCmd.faces(): x=(face.ParameterRange[0]+face.ParameterRange[1])/2 y=(face.ParameterRange[2]+face.ParameterRange[3])/2 plist.append(makePipe(propList,face.valueAt(x,y),face.normalAt(x,y))) FreeCAD.activeDocument().commitTransaction() FreeCAD.activeDocument().recompute() else: for edge in fCmd.edges([objex]): # ...one or more edges... if edge.curvatureAt(0)==0: # ...straight edges pL=propList pL[3]=edge.Length plist.append(makePipe(pL,edge.valueAt(0),edge.tangentAt(0))) else: # ...curved edges pos=edge.centerOfCurvatureAt(0) Z=edge.tangentAt(0).cross(edge.normalAt(0)) if isElbow(o): p0,p1=[o.Placement.Rotation.multVec(p) for p in o.Ports] if not fCmd.isParallel(Z,p0): Z=p1 plist.append(makePipe(propList,pos,Z)) if pypeline: for p in plist: moveToPyLi(p,pypeline) FreeCAD.activeDocument().commitTransaction() FreeCAD.activeDocument().recompute() return plist
def setWP(): #TARGET [working]: deal with App::Parts 'function to change working plane' import FreeCAD, FreeCADGui, fCmd normal = point = None curves = [] straight = [] Z = FreeCAD.Vector(0, 0, 1) for edge in fCmd.edges(): if edge.curvatureAt(0) != 0: curves.append(edge) else: straight.append(edge) # define normal: 1st from face->2nd from curve->3rd from straight edges if fCmd.faces(): normal = fCmd.faces()[0].normalAt(0, 0) elif curves: normal = curves[0].tangentAt(0).cross(curves[0].normalAt(0)) elif len(straight) > 1: if straight and not fCmd.isParallel(straight[0].tangentAt(0), straight[1].tangentAt(0)): normal = straight[0].tangentAt(0).cross(straight[1].tangentAt(0)) elif FreeCADGui.Selection.getSelection(): normal = FreeCAD.DraftWorkingPlane.getRotation().multVec(Z) else: normal = Z # define point: 1st from vertex->2nd from centerOfCurvature->3rd from intersection->4th from center of edge points = [ v.Point for sx in FreeCADGui.Selection.getSelectionEx() for v in sx.SubObjects if v.ShapeType == 'Vertex' ] if not points: points = [edge.centerOfCurvatureAt(0) for edge in curves] if not points and len(straight) > 1: inters = fCmd.intersectionCLines(straight[0], straight[1]) if inters: points.append(inters) if not points and len(straight): points.append(straight[0].CenterOfMass) if points: point = points[0] else: point = FreeCAD.Vector() # move the draft WP FreeCAD.DraftWorkingPlane.alignToPointAndAxis(point, normal) FreeCADGui.Snapper.setGrid()
def doElbow(propList=['DN50',60.3,3,90,45.225], pypeline=None): ''' propList = [ DN (string): nominal diameter OD (float): outside diameter thk (float): shell thickness BA (float): bend angle BR (float): bend radius ] pypeline = string ''' elist=[] FreeCAD.activeDocument().openTransaction('Insert elbow') selex=FreeCADGui.Selection.getSelectionEx() if len(selex)==0: # no selection -> insert one elbow at origin elist.append(makeElbow(propList)) elif len(selex)==1 and len(selex[0].SubObjects)==1: #one selection -> ... if selex[0].SubObjects[0].ShapeType=="Vertex": # ...on vertex elist.append(makeElbow(propList,selex[0].SubObjects[0].Point)) elif selex[0].SubObjects[0].ShapeType=="Edge" and selex[0].SubObjects[0].curvatureAt(0)!=0: # ...on center of curved edge P=selex[0].SubObjects[0].centerOfCurvatureAt(0) N=selex[0].SubObjects[0].normalAt(0).cross(selex[0].SubObjects[0].tangentAt(0)).normalize() elb=makeElbow(propList,P) if isPipe(selex[0].Object): #..on the edge of a pipe ax=selex[0].Object.Shape.Solids[0].CenterOfMass-P rot=FreeCAD.Rotation(elb.Ports[0],ax) elb.Placement.Rotation=rot.multiply(elb.Placement.Rotation) Port0=getElbowPort(elb) elb.Placement.move(P-Port0) elif isElbow(selex[0].Object): #..on the edge of an elbow p0,p1=[selex[0].Object.Placement.Rotation.multVec(p) for p in selex[0].Object.Ports] if fCmd.isParallel(p0,N): elb.Placement.Rotation=FreeCAD.Rotation(elb.Ports[0],p0*-1) else: elb.Placement.Rotation=FreeCAD.Rotation(elb.Ports[0],p1*-1) delta=getElbowPort(elb) elb.Placement.move(P-delta) else: #..on any other curved edge print('hello') rot=FreeCAD.Rotation(elb.Ports[0],N) elb.Placement.Rotation=rot.multiply(elb.Placement.Rotation) # elb.Placement.move(elb.Placement.Rotation.multVec(elb.Ports[0])*-1) v=portsDir(elb)[0].negative()*elb.Ports[0].Length elb.Placement.move(v) elist.append(elb) FreeCAD.activeDocument().recompute() else: # multiple selection -> insert one elbow at intersection of two edges or beams or pipes ## things=[] for objEx in selex: if len(fCmd.beams([objEx.Object]))==1: # if the object is a beam or pipe, append it to the "things".. things.append(objEx.Object) else: # ..else append its edges for edge in fCmd.edges([objEx]): things.append(edge) if len(things)>=2: break try: #create the feature elb=elist.append(makeElbowBetweenThings(*things[:2],propList=propList)) except: FreeCAD.Console.PrintError('Creation of elbow is failed\n') if pypeline: for e in elist: moveToPyLi(e,pypeline) FreeCAD.activeDocument().commitTransaction() FreeCAD.activeDocument().recompute() return elist