def placeTheElbow(c, v1=None, v2=None, P=None): ''' placeTheElbow(c,v1,v2,P=None) Puts the curve C between vectors v1 and v2. If point P is given, translates it in there. NOTE: v1 and v2 oriented in the same direction along the path! ''' if not (v1 and v2): v1, v2 = [e.tangentAt(0) for e in frameCmd.edges()] try: P = frameCmd.intersectionCLines(*frameCmd.edges()) except: pass if hasattr(c, 'PType') and hasattr(c, 'BendAngle') and v1 and v2: v1.normalize() v2.normalize() ortho = rounded(frameCmd.ortho(v1, v2)) bisect = rounded(v2 - v1) ang = degrees(v1.getAngle(v2)) c.BendAngle = ang rot1 = FreeCAD.Rotation( rounded(frameCmd.beamAx(c, FreeCAD.Vector(0, 0, 1))), ortho) c.Placement.Rotation = rot1.multiply(c.Placement.Rotation) rot2 = FreeCAD.Rotation( rounded(frameCmd.beamAx(c, FreeCAD.Vector(1, 1, 0))), bisect) c.Placement.Rotation = rot2.multiply(c.Placement.Rotation) if not P: P = c.Placement.Base c.Placement.Base = P
def placeoTherElbow(c, v1=None, v2=None, P=None): ''' Like placeTheElbow() but with more math. ''' if not (v1 and v2): v1, v2 = [e.tangentAt(0) for e in frameCmd.edges()] try: P = frameCmd.intersectionCLines(*frameCmd.edges()) except: pass if hasattr(c, 'PType') and hasattr(c, 'BendAngle') and v1 and v2: v1.normalize() v2.normalize() ortho = rounded(frameCmd.ortho(v1, v2)) bisect = rounded(v2 - v1) cBisect = rounded(c.Ports[1] + c.Ports[0]) # math cZ = c.Ports[0].cross(c.Ports[1]) # more math ang = degrees(v1.getAngle(v2)) c.BendAngle = ang rot1 = FreeCAD.Rotation(rounded(frameCmd.beamAx(c, cZ)), ortho) c.Placement.Rotation = rot1.multiply(c.Placement.Rotation) rot2 = FreeCAD.Rotation(rounded(frameCmd.beamAx(c, cBisect)), bisect) c.Placement.Rotation = rot2.multiply(c.Placement.Rotation) if not P: P = c.Placement.Base c.Placement.Base = P
def flattenTheTube(obj=None, v1=None, v2=None, X=None): ''' flattenTheTube(obj=None,v1=None,v2=None, X=None) Put obj in the same plane defined by vectors v1 and v2 and move it to X. obj: the object to be rotated v1, v2: the vectors of the plane X: the Placement.Base If no parameter is defined: v1, v2 are the axis of the first two beams in the selections set, X is their intersection and obj is the first other object in the selection set. ''' if None in [obj, v1, v2]: try: sel = FreeCADGui.Selection.getSelection() t1, t2 = frameCmd.beams()[:2] v1 = frameCmd.beamAx(t1) v2 = frameCmd.beamAx(t2) sel.remove(t1) sel.remove(t2) obj = sel[0] X = frameCmd.intersectionCLines(t1, t2) except: FreeCAD.Console.PrintError('Not enough arguments\n') return obj.Placement.Rotation = FreeCAD.Rotation( frameCmd.beamAx(obj), v1.cross(v2)).multiply(obj.Placement.Rotation) obj.Placement.Base = X
def insert(self): selex=FreeCADGui.Selection.getSelectionEx() if len(selex)==0: d=self.pipeDictList[self.sizeList.currentRow()] propList=[d['PSize'],self.PRating,float(pq(d['C'])),float(pq(d['H'])),float(pq(d['d']))] FreeCAD.activeDocument().openTransaction('Insert clamp in (0,0,0)') ub=pipeCmd.makeUbolt(propList) if self.combo.currentText()!='<none>': pipeCmd.moveToPyLi(ub,self.combo.currentText()) FreeCAD.activeDocument().commitTransaction() FreeCAD.activeDocument().recompute() else: FreeCAD.activeDocument().openTransaction('Insert clamp on tube') for objex in selex: if hasattr(objex.Object,'PType') and objex.Object.PType=='Pipe': d=[typ for typ in self.pipeDictList if typ['PSize']==objex.Object.PSize] if len(d)>0: d=d[0] else: d=self.pipeDictList[self.sizeList.currentRow()] propList=[d['PSize'],self.PRating,float(pq(d['C'])),float(pq(d['H'])),float(pq(d['d']))] H=float(objex.Object.Height) gap=H-float(pq(d['C'])) steps=[gap*self.cb1.isChecked(),H/2*self.cb2.isChecked(),(H-gap)*self.cb3.isChecked()] for s in steps: if s: ub=pipeCmd.makeUbolt(propList,pos=objex.Object.Placement.Base, Z=frameCmd.beamAx(objex.Object)) ub.Placement.move(frameCmd.beamAx(objex.Object).multiply(s)) if self.refNorm: pipeCmd.rotateTheTubeAx(obj=ub,angle=degrees(self.refNorm.getAngle((frameCmd.beamAx(ub,FreeCAD.Vector(0,1,0)))))) if self.combo.currentText()!='<none>': pipeCmd.moveToPyLi(ub,self.combo.currentText()) FreeCAD.activeDocument().commitTransaction() FreeCAD.activeDocument().recompute()
def update(self, fp, edges=None): import pipeCmd, frameCmd 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 = pipeCmd.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 pipeCmd.moveToPyLi(p, fp.Label) pipes.append(p) n = len(pipes) - 1 if n and not frameCmd.isParallel(frameCmd.beamAx(pipes[n]), frameCmd.beamAx(pipes[n - 1])): #---Create the curve--- propList = [fp.PSize, fp.OD, fp.thk, 90, fp.BendRadius] c = pipeCmd.makeElbowBetweenThings(edges[n], edges[n - 1], propList) portA, portB = [c.Placement.multVec(port) for port in c.Ports] #---Trim the tube--- p1, p2 = pipes[-2:] frameCmd.extendTheBeam(p1, portA) frameCmd.extendTheBeam(p2, portB) pipeCmd.moveToPyLi(c, fp.Label)
def update(self,fp,edges=None): import pipeCmd, frameCmd 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=pipeCmd.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 pipeCmd.moveToPyLi(p,fp.Label) pipes.append(p) n=len(pipes)-1 if n and not frameCmd.isParallel(frameCmd.beamAx(pipes[n]),frameCmd.beamAx(pipes[n-1])): #---Create the curve--- propList=[fp.PSize,fp.OD,fp.thk,90,fp.BendRadius] c=pipeCmd.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:] frameCmd.extendTheBeam(p1,portA) frameCmd.extendTheBeam(p2,portB) pipeCmd.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 = frameCmd.edges()[:2] P = frameCmd.intersectionCLines(thing1, thing2) directions = list() try: for thing in [thing1, thing2]: if frameCmd.beams([thing]): directions.append( rounded( (frameCmd.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 = frameCmd.bisect(directions[0], directions[1]) elbBisect = rounded(frameCmd.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 frameCmd.beams([t])]: vectA = tube.Shape.Solids[0].CenterOfMass - portA vectB = tube.Shape.Solids[0].CenterOfMass - portB if frameCmd.isParallel(vectA, frameCmd.beamAx(tube)): frameCmd.extendTheBeam(tube, portA) else: frameCmd.extendTheBeam(tube, portB) return elb
def update(self, fp, edges=None): import pipeCmd, frameCmd 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 = pipeCmd.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 pipeCmd.moveToPyLi(p, fp.Label) pipes.append(p) n = len(pipes) - 1 if n and not frameCmd.isParallel(frameCmd.beamAx(pipes[n]), frameCmd.beamAx(pipes[n - 1])): #---Create the curve: method 1--- #P=rounded(frameCmd.intersectionCLines(pipes[n-1],pipes[n])) #alternative -> P=pipes[n].Placement.Base #dir1=rounded((frameCmd.beamAx(pipes[n-1]).multiply(pipes[n-1].Height/2)+pipes[n-1].Placement.Base)-P).normalize() #dir2=rounded((frameCmd.beamAx(pipes[n]).multiply(pipes[n].Height/2)+pipes[n].Placement.Base)-P).normalize() #ang=180.0-degrees(dir1.getAngle(dir2)) #propList=[fp.PSize,fp.OD,fp.thk,ang,fp.BendRadius] #c=pipeCmd.makeElbow(propList,P,dir1.negative().cross(dir2.negative())) #elbBisect=rounded(frameCmd.beamAx(c,FreeCAD.Vector(1,1,0))).normalize() # if not rounded, it fails with linux when sketch is vertical!(?) #rot=FreeCAD.Rotation(elbBisect,frameCmd.bisect(dir1,dir2)) #c.Placement.Rotation=rot.multiply(c.Placement.Rotation) #---Create the curve: method 2--- propList = [fp.PSize, fp.OD, fp.thk, 90, fp.BendRadius] c = pipeCmd.makeElbowBetweenThings( edges[n], edges[n - 1], propList) #before was ...(p1,p2,propList) portA = c.Placement.multVec(c.Ports[0]) portB = c.Placement.multVec(c.Ports[1]) #---Trim the tube: method 1--- #for tube in pipes[-2:]: # vectA=c.Placement.Rotation.multVec(c.Ports[0]) # if frameCmd.isParallel(vectA,frameCmd.beamAx(tube)): # frameCmd.extendTheBeam(tube,portA) # else: # frameCmd.extendTheBeam(tube,portB) #---Trim the tube: method 2--- p1, p2 = pipes[-2:] frameCmd.extendTheBeam(p1, portA) frameCmd.extendTheBeam(p2, portB) pipeCmd.moveToPyLi(c, fp.Label)
def breakTheTubes(point, pipes=[], gap=0): ''' breakTheTube(point,pipes=[],gap=0) Breaks the "pipes" at "point" leaving a "gap". ''' pipes2nd = list() if not pipes: pipes = [p for p in frameCmd.beams() if isPipe(p)] if pipes: for pipe in pipes: if point < float( pipe.Height) and gap < (float(pipe.Height) - point): propList = [ pipe.PSize, float(pipe.OD), float(pipe.thk), float(pipe.Height) - point - gap ] pipe.Height = point Z = frameCmd.beamAx(pipe) pos = pipe.Placement.Base + Z * (float(pipe.Height) + gap) pipe2nd = makePipe(propList, pos, Z) pipes2nd.append(pipe2nd) #FreeCAD.activeDocument().recompute() return pipes2nd
def laydownTheTube(pipe=None, refFace=None, support=None): ''' laydownTheTube(pipe=None, refFace=None, support=None) Makes one pipe touch one face if the center-line is parallel to it. If support is not None, support is moved towards pipe. ''' if not (pipe and refFace): # without argument take from selection set refFace = [ f for f in frameCmd.faces() if type(f.Surface) == Part.Plane ][0] pipe = [p for p in frameCmd.beams() if hasattr(p, 'OD')][0] try: if type(refFace.Surface) == Part.Plane and frameCmd.isOrtho( refFace, frameCmd.beamAx(pipe)) and hasattr(pipe, 'OD'): dist = rounded( refFace.normalAt(0, 0).multiply( refFace.normalAt(0, 0).dot(pipe.Placement.Base - refFace.CenterOfMass) - float(pipe.OD) / 2)) if support: support.Placement.move(dist) else: pipe.Placement.move(dist.multiply(-1)) else: FreeCAD.Console.PrintError( 'Face is not flat or not parallel to axis of pipe\n') except: FreeCAD.Console.PrintError('Wrong selection\n')
def accept(self): if self.labTail: self.labTail.removeLabel() self.labTail=None self.L=frameCmd.getDistance() if self.form.edit1.text(): length=float(self.form.edit1.text()) FreeCAD.activeDocument().openTransaction('Stretch beam') for beam in frameCmd.beams(): delta=float(beam.Height)-length frameCmd.stretchTheBeam(beam,length) if self.form.tail.isChecked(): disp=frameCmd.beamAx(beam).multiply(delta) beam.Placement.move(disp) elif self.form.both.isChecked(): disp=frameCmd.beamAx(beam).multiply(delta/2.0) beam.Placement.move(disp) FreeCAD.activeDocument().recompute() FreeCAD.activeDocument().commitTransaction()
def accept(self): # stretch if self.labTail: self.labTail.removeLabel() self.labTail = None self.L = frameCmd.getDistance() if self.form.edit1.text(): length = float(self.form.edit1.text()) FreeCAD.activeDocument().openTransaction('Stretch beam') for beam in frameCmd.beams(): delta = float(beam.Height) - length frameCmd.stretchTheBeam(beam, length) if self.form.tail.isChecked(): disp = frameCmd.beamAx(beam).multiply(delta) beam.Placement.move(disp) elif self.form.both.isChecked(): disp = frameCmd.beamAx(beam).multiply(delta / 2.0) beam.Placement.move(disp) FreeCAD.activeDocument().recompute() FreeCAD.activeDocument().commitTransaction()
def rotateTheTubeAx(obj=None, vShapeRef=None, angle=45): ''' rotateTheTubeAx(obj=None,vShapeRef=None,angle=45) Rotates obj around the vShapeRef axis of its Shape by an angle. obj: if not defined, the first in the selection set vShapeRef: if not defined, the Z axis of the Shape angle: default=45 deg ''' if obj == None: obj = FreeCADGui.Selection.getSelection()[0] if vShapeRef == None: vShapeRef = FreeCAD.Vector(0, 0, 1) rot = FreeCAD.Rotation(frameCmd.beamAx(obj, vShapeRef), angle) obj.Placement.Rotation = rot.multiply(obj.Placement.Rotation)
def execute(self,obj): X=FreeCAD.Vector(1,0,0) Z=FreeCAD.Vector(0,0,1) if hasattr(obj,'Base') and obj.Base and hasattr(obj,'Beams'): n=obj.Base.Placement.Rotation.multVec(Z) for i in range(len(obj.Beams)): if obj.Beams[i]: edge=obj.Base.Shape.Edges[i] beam=FreeCAD.ActiveDocument.getObject(obj.Beams[i]) beam.Height=float(obj.Base.Shape.Edges[i].Length)+beam.tailOffset+beam.headOffset offset=FreeCAD.Vector(0,0,beam.tailOffset).negative() spin=FreeCAD.Rotation() beam.AttachmentOffset = FreeCAD.Placement(offset, spin) angle=degrees(frameCmd.beamAx(beam,X).getAngle(n)) beam.AttachmentOffset.Rotation=FreeCAD.Rotation(Z,angle+beam.spin)
def execute(self, obj): X = FreeCAD.Vector(1, 0, 0) Z = FreeCAD.Vector(0, 0, 1) if hasattr(obj, 'Base') and obj.Base and hasattr(obj, 'Beams'): n = obj.Base.Placement.Rotation.multVec(Z) for i in range(len(obj.Beams)): if obj.Beams[i]: edge = obj.Base.Shape.Edges[i] beam = FreeCAD.ActiveDocument.getObject(obj.Beams[i]) beam.Height = float(obj.Base.Shape.Edges[i].Length ) + beam.tailOffset + beam.headOffset offset = FreeCAD.Vector(0, 0, beam.tailOffset).negative() spin = FreeCAD.Rotation() beam.AttachmentOffset = FreeCAD.Placement(offset, spin) angle = degrees(frameCmd.beamAx(beam, X).getAngle(n)) beam.AttachmentOffset.Rotation = FreeCAD.Rotation( Z, angle + beam.spin)
def reverseTheTube(objEx): ''' reverseTheTube(objEx) Reverse the orientation of objEx spinning it 180 degrees around the x-axis of its shape. If an edge is selected, it's used as pivot. ''' disp=None selectedEdges=[e for e in objEx.SubObjects if e.ShapeType=='Edge'] if selectedEdges: for edge in frameCmd.edges([objEx]): if edge.curvatureAt(0): disp=edge.centerOfCurvatureAt(0)-objEx.Object.Placement.Base break elif frameCmd.beams([objEx.Object]): ax=frameCmd.beamAx(objEx.Object) disp=ax*((edge.CenterOfMass-objEx.Object.Placement.Base).dot(ax)) rotateTheTubeAx(objEx.Object,FreeCAD.Vector(1,0,0),180) if disp: objEx.Object.Placement.move(disp*2)
def onPushButton1(self): from math import pi, degrees import frameCmd try: obj=self.Selection.getSelection()[0] self.labName.setText(obj.Label) self.labBaseVal.setText(str("P = %.1f,%.1f,%.1f"%tuple(obj.Placement.Base))) self.labRotAng.setText(str("%.2f " %(degrees(obj.Placement.Rotation.Angle)))) ax=obj.Placement.Rotation.Axis self.labRotAx.setText(str("v = (%(x).2f,%(y).2f,%(z).2f)" %{'x':ax.x,'y':ax.y,'z':ax.z})) shapes=[y for x in self.Selection.getSelectionEx() for y in x.SubObjects if hasattr(y,'ShapeType')] if len(shapes)==1: sub=shapes[0] if sub.ShapeType=='Edge': if sub.curvatureAt(0)==0: self.labSubObj.setText(sub.ShapeType+':\tL = %.1f mm' %sub.Length) else: x,y,z=sub.centerOfCurvatureAt(0) d=2/sub.curvatureAt(0) self.labSubObj.setText(sub.ShapeType+':\tD = %.1f mm\n\tC = %.1f,%.1f,%.1f' %(d,x,y,z)) elif sub.ShapeType=='Face': self.labSubObj.setText(sub.ShapeType+':\tA = %.1f mm2' %sub.Area) elif sub.ShapeType=='Vertex': self.labSubObj.setText(sub.ShapeType+': pos = (%(x).1f,%(y).1f,%(z).1f)' %{'x':sub.X,'y':sub.Y,'z':sub.Z}) elif len(shapes)>1: self.labSubObj.setText(shapes[0].ShapeType+' to '+shapes[1].ShapeType+': distance = %.1f mm' %(shapes[0].distToShape(shapes[1])[0])) else: self.labSubObj.setText(' ') if len(frameCmd.beams())==1: b=frameCmd.beams()[0] self.labBeam.setText(b.Label+":\tL=%.2f"%(b.Height)) self.labProfile.setText("Profile: "+b.Profile) elif len(frameCmd.beams())>1: b1,b2=frameCmd.beams()[:2] self.labBeam.setText(b1.Label+"^"+b2.Label+": %.2f"%(degrees(frameCmd.beamAx(b1).getAngle(frameCmd.beamAx(b2))))) self.labProfile.setText("") else: self.labBeam.setText("") self.labProfile.setText("") except: pass
def onPushButton1(self): from math import pi, degrees import frameCmd try: obj = self.Selection.getSelection()[0] self.labName.setText(obj.Label) self.labBaseVal.setText( str("P = %.1f,%.1f,%.1f" % tuple(obj.Placement.Base))) self.labRotAng.setText( str("%.2f " % (degrees(obj.Placement.Rotation.Angle)))) ax = obj.Placement.Rotation.Axis self.labRotAx.setText( str("v = (%(x).2f,%(y).2f,%(z).2f)" % { 'x': ax.x, 'y': ax.y, 'z': ax.z })) shapes = [ y for x in self.Selection.getSelectionEx() for y in x.SubObjects if hasattr(y, 'ShapeType') ] if len(shapes) == 1: sub = shapes[0] if sub.ShapeType == 'Edge': if sub.curvatureAt(0) == 0: self.labSubObj.setText(sub.ShapeType + ': L = %.1f mm' % sub.Length) else: self.labSubObj.setText(sub.ShapeType + ': D = %.1f mm' % (2 / sub.curvatureAt(0))) elif sub.ShapeType == 'Face': self.labSubObj.setText(sub.ShapeType + ': A = %.1f mm2' % sub.Area) elif sub.ShapeType == 'Vertex': self.labSubObj.setText( sub.ShapeType + ': pos = (%(x).1f,%(y).1f,%(z).1f)' % { 'x': sub.X, 'y': sub.Y, 'z': sub.Z }) elif len(shapes) > 1: self.labSubObj.setText(shapes[0].ShapeType + ' to ' + shapes[1].ShapeType + ': distance = %.1f mm' % (shapes[0].distToShape(shapes[1])[0])) else: self.labSubObj.setText(' ') if len(frameCmd.beams()) == 1: b = frameCmd.beams()[0] self.labBeam.setText(b.Label + ": L=%.2f" % (b.Height)) self.labProfile.setText("Profile: " + b.Profile) elif len(frameCmd.beams()) > 1: b1, b2 = frameCmd.beams()[:2] self.labBeam.setText(b1.Label + "^" + b2.Label + ": %.2f" % ( degrees(frameCmd.beamAx(b1).getAngle(frameCmd.beamAx(b2)))) ) self.labProfile.setText("") else: self.labBeam.setText("") self.labProfile.setText("") except: pass
def insert(self): r=self.pipeDictList[self.sizeList.currentRow()] pos=Z=H=None selex=FreeCADGui.Selection.getSelectionEx() pipes=[p.Object for p in selex if hasattr(p.Object,'PType') and p.Object.PType=='Pipe'] if len(pipes)>1 and frameCmd.isParallel(frameCmd.beamAx(pipes[0]),frameCmd.beamAx(pipes[1])): # if at least 2 pipes are selected... if pipes[0].OD>=pipes[1].OD: p1,p2=pipes[:2] else: p2,p1=pipes[:2] DN=p1.PSize OD1=float(p1.OD) OD2=float(p2.OD) thk1=float(p1.thk) thk2=float(p2.thk) H=float(pq(self.findDN(DN)['H'])) Z=p2.Shape.Solids[0].CenterOfMass-p1.Shape.Solids[0].CenterOfMass Z.normalize() pos=p1.Shape.Solids[0].CenterOfMass+Z*float(p1.Height/2) elif len(pipes)>0: # if 1 pipe is selected... DN=pipes[0].PSize OD1=float(pipes[0].OD) OD2=float(pq(self.OD2list.currentItem().text())) thk1=float(pipes[0].thk) thk2=float(pq(r['thk2'].split('>')[self.OD2list.currentRow()])) H=float(pq(self.findDN(DN)['H'])) curves=[e for e in frameCmd.edges() if e.curvatureAt(0)>0] if len(curves): #...and 1 curve is selected... pos=curves[0].centerOfCurvatureAt(0) else: #...or no curve is selected... pos=pipes[0].Placement.Base Z= pos-pipes[0].Shape.Solids[0].CenterOfMass else: # if no pipe is selected... DN=r['PSize'] OD1=float(pq(r['OD'])) OD2=float(pq(self.OD2list.currentItem().text())) thk1=float(pq(r['thk'])) try: thk2=float(pq(r['thk2'].split('>')[self.OD2list.currentRow()])) except: thk2=thk1 H=pq(r['H']) if frameCmd.edges(): #...but 1 curve is selected... edge=frameCmd.edges()[0] if edge.curvatureAt(0)>0: pos=edge.centerOfCurvatureAt(0) Z=edge.tangentAt(0).cross(edge.normalAt(0)) else: pos=edge.valueAt(0) Z=edge.tangentAt(0) elif selex and selex[0].SubObjects[0].ShapeType=="Vertex": #...or 1 vertex.. pos=selex[0].SubObjects[0].Point if not H: # calculate length if it's not defined H=float(3*(OD1-OD2)) propList=[DN,OD1,OD2,thk1,thk2,H] FreeCAD.activeDocument().openTransaction('Insert reduction') if self.cb1.isChecked(): self.lastReduct=pipeCmd.makeReduct(propList,pos,Z,False) else: self.lastReduct=pipeCmd.makeReduct(propList,pos,Z) FreeCAD.activeDocument().commitTransaction() FreeCAD.activeDocument().recompute() if self.combo.currentText()!='<none>': pipeCmd.moveToPyLi(self.lastReduct,self.combo.currentText())