Beispiel #1
0
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
Beispiel #2
0
def portsDir(o):
    '''
  portsDir(o)
  Returns the orientation of Ports of the pype-object o
  '''
    dirs = list()
    two_ways = ['Pipe', 'Reduct', 'Flange']
    if hasattr(o, 'PType'):
        if o.PType in two_ways:
            dirs = [
                o.Placement.Rotation.multVec(p)
                for p in [FreeCAD.Vector(0, 0, -1),
                          FreeCAD.Vector(0, 0, 1)]
            ]
        elif hasattr(o, 'Ports') and hasattr(o, 'Placement'):
            dirs = list()
            for p in o.Ports:
                if p.Length:
                    dirs.append(
                        rounded(o.Placement.Rotation.multVec(p).normalize()))
                else:
                    dirs.append(
                        rounded(
                            o.Placement.Rotation.multVec(
                                FreeCAD.Vector(0, 0, -1)).normalize()))
    return dirs
Beispiel #3
0
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
Beispiel #4
0
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
Beispiel #5
0
def portsPos(o):
    '''
  portsPos(o)
  Returns the position of Ports of the pype-object o
  '''
    if hasattr(o, 'Ports') and hasattr(o, 'Placement'):
        return [rounded(o.Placement.multVec(p)) for p in o.Ports]
Beispiel #6
0
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')
Beispiel #7
0
def intersectionCLines(thing1=None, thing2=None):
  '''
  intersectionCLines(thing1=None, thing2=None)
  Returns the intersection (vector) of the center lines of thing1 and thing2.
  Things can be any combination of intersecting beams, pipes or edges.
  If less than 2 arguments are given, thing1 and thing2 are the first 2 beams
  or pipes found in the selection set.
  '''
  if not (thing1 and thing2):
    try:
      thing1,thing2=beams()[:2]
    except:
      FreeCAD.Console.PrintError('Insufficient arguments for intersectionCLines\n')
      return None
  edges=[]
  for thing in [thing1,thing2]:
    if beams([thing]):
      edges.append(vec2edge(thing.Placement.Base,beamAx(thing)))
    elif hasattr(thing,'ShapeType') and thing.ShapeType=='Edge':
      edges.append(thing)
  intersections=dgu.findIntersection(*edges, infinite1=True, infinite2=True)
  if len(intersections):
    return rounded(intersections[0])
  else:
    FreeCAD.Console.PrintError('No intersection found\n')
    return None
Beispiel #8
0
def intersectionCLines(thing1=None, thing2=None):
    '''
  intersectionCLines(thing1=None, thing2=None)
  Returns the intersection (vector) of the center lines of thing1 and thing2.
  Things can be any combination of intersecting beams, pipes or edges.
  If less than 2 arguments are given, thing1 and thing2 are the first 2 beams
  or pipes found in the selection set.
  '''
    if not (thing1 and thing2):
        try:
            thing1, thing2 = beams()[:2]
        except:
            FreeCAD.Console.PrintError(
                'Insufficient arguments for intersectionCLines\n')
            return None
    edges = []
    for thing in [thing1, thing2]:
        if beams([thing]):
            edges.append(vec2edge(thing.Placement.Base, beamAx(thing)))
        elif hasattr(thing, 'ShapeType') and thing.ShapeType == 'Edge':
            edges.append(thing)
    intersections = dgu.findIntersection(*edges,
                                         infinite1=True,
                                         infinite2=True)
    if len(intersections):
        return rounded(intersections[0])
    else:
        FreeCAD.Console.PrintError('No intersection found\n')
        return None
Beispiel #9
0
def intersectionPlane(base=None, v=None, face=None):
    '''
  intersectionPlane(base,v,face)
  Returns the point (vector) at the intersection of a line and a plane.
    base (vector): the base point to be projected
    v (vector): the direction of the line that intersect the plane
    face (Face): the face that defines the plane to be intersect
  '''
    # only for quick testing:
    if base == v == face == None:
        face = faces()[0]
        beam = beams()[0]
        base = beam.Placement.Base
        v = beamAx(beam)
    if isOrtho(v, face):
        FreeCAD.Console.PrintError(
            'Direction of projection and Face are parallel.\n')
        return None
    else:
        # equation of plane: ax+by+cz+d=0
        a, b, c = list(face.normalAt(0, 0))
        d = -face.CenterOfMass.dot(face.normalAt(0, 0))
        #FreeCAD.Console.PrintMessage('a=%.2f b=%.2f c=%.2f d=%.2f\n' %(a,b,c,d))
        ## definition of line
        #FreeCAD.Console.PrintMessage('base=(%.2f,%.2f,%.2f)\n' %(base.x,base.y,base.z))
        #FreeCAD.Console.PrintMessage('v=(%.2f,%.2f,%.2f)\n' %(v.x,v.y,v.z))
        ##intersection
        k = -1 * (a * base.x + b * base.y + c * base.z +
                  d) / (a * v.x + b * v.y + c * v.z)
        #FreeCAD.Console.PrintMessage('k=%f\n' %float(k))
        P = base + v * k
        return rounded(P)
Beispiel #10
0
def intersectionPlane(base=None,v=None,face=None):
  '''
  intersectionPlane(base,v,face)
  Returns the point (vector) at the intersection of a line and a plane.
    base (vector): the base point to be projected
    v (vector): the direction of the line that intersect the plane
    face (Face): the face that defines the plane to be intersect
  '''   
  # only for quick testing:
  if base==v==face==None:
    face = faces()[0]
    beam=beams()[0]
    base=beam.Placement.Base
    v=beamAx(beam)
  if isOrtho(v,face):
    FreeCAD.Console.PrintError('Direction of projection and Face are parallel.\n')
    return None
  else:
    # equation of plane: ax+by+cz+d=0
    a,b,c=list(face.normalAt(0,0))
    d=-face.CenterOfMass.dot(face.normalAt(0,0))
    #FreeCAD.Console.PrintMessage('a=%.2f b=%.2f c=%.2f d=%.2f\n' %(a,b,c,d))
    ## definition of line
    #FreeCAD.Console.PrintMessage('base=(%.2f,%.2f,%.2f)\n' %(base.x,base.y,base.z))
    #FreeCAD.Console.PrintMessage('v=(%.2f,%.2f,%.2f)\n' %(v.x,v.y,v.z))
    ##intersection
    k=-1*(a*base.x+b*base.y+c*base.z+d)/(a*v.x+b*v.y+c*v.z)
    #FreeCAD.Console.PrintMessage('k=%f\n' %float(k))
    P=base+v*k
    return rounded(P)
Beispiel #11
0
 def getReference(self):
   selex=FreeCADGui.Selection.getSelectionEx()
   for sx in selex:
     if sx.SubObjects:
       planes=[f for f in frameCmd.faces([sx]) if type(f.Surface)==Part.Plane]
       if len(planes)>0:
         self.refNorm=rounded(planes[0].normalAt(0,0))
         self.lab1.setText("ref. Face on "+sx.Object.Label)
Beispiel #12
0
def rotjoinTheBeam(beam=None, e1=None, e2=None):
    if not (beam and e1 and e2):
        beam = beams()[1]
        e1, e2 = edges()
    rot = FreeCAD.Rotation(e2.tangentAt(0), e1.tangentAt(0))
    dist = dgu.findDistance(beam.Placement.Base, e1)
    delta = beam.Placement.Base - e2.CenterOfMass
    beam.Placement.Rotation = rot.multiply(beam.Placement.Rotation)
    beam.Placement.move(rounded(dist + rot.multVec(delta)))
Beispiel #13
0
def rotjoinTheBeam(beam=None,e1=None,e2=None):
  if not (beam and e1 and e2):
    beam=beams()[1]
    e1,e2=edges()
  rot=FreeCAD.Rotation(e2.tangentAt(0),e1.tangentAt(0))
  dist=dgu.findDistance(beam.Placement.Base,e1)
  delta=beam.Placement.Base-e2.CenterOfMass
  beam.Placement.Rotation=rot.multiply(beam.Placement.Rotation)
  beam.Placement.move(rounded(dist+rot.multVec(delta)))
Beispiel #14
0
def intersectionLines(p1=None,
                      v1=None,
                      p2=None,
                      v2=None):  # OBSOLETE: replaced with intersectionCLines
    '''
  intersectionLines(p1,v1,p2,v2)
  If exist, returns the intersection (vector) between two lines 
    p1,v1: the reference point and direction of first line
    p2,v2: the reference point and direction of second line
  '''

    if None in [p1, p2, v1, v2]:
        eds = edges()[:2]
        p1, p2 = [e.valueAt(0) for e in eds]
        v1, v2 = [e.tangentAt(0) for e in eds]
    if not isParallel(v1, v2):
        dist = p1 - p2
        import numpy
        #M=numpy.matrix([list(v1),list(v2),list(dist)]) # does not work: it seems for lack of accuracy of FreeCAD.Base.Vector operations!
        rowM1 = [round(x, 2) for x in v1]
        rowM2 = [round(x, 2) for x in v2]
        rowM3 = [round(x, 2) for x in dist]
        M = numpy.matrix([rowM1, rowM2, rowM3])
        if numpy.linalg.det(M) == 0:
            #3 equations, 2 unknowns => 1 eq. must be dependent
            a11, a21, a31 = list(v1)
            a12, a22, a32 = list(v2 * -1)
            M1 = numpy.matrix([[a11, a12], [a21, a22]])
            M2 = numpy.matrix([[a21, a22], [a31, a32]])
            M3 = numpy.matrix([[a31, a32], [a11, a12]])
            pl1 = list(p1)
            pl2 = list(p2)
            if numpy.linalg.det(M1) != 0:
                k = numpy.linalg.inv(M1) * numpy.matrix([[pl2[0] - pl1[0]],
                                                         [pl2[1] - pl1[1]]])
            elif numpy.linalg.det(M2) != 0:
                k = numpy.linalg.inv(M2) * numpy.matrix([[pl2[1] - pl1[1]],
                                                         [pl2[2] - pl1[2]]])
            else:
                k = numpy.linalg.inv(M3) * numpy.matrix([[pl2[2] - pl1[2]],
                                                         [pl2[0] - pl1[0]]])
            P = p1 + v1 * float(k[0])  # ..=p2+v2*float(k[1])
            #FreeCAD.Console.PrintWarning("k1 = "+str(float(k[0]))+"\nk2 = "+str(float(k[1]))+"\n")
            return rounded(P)
        else:  #se i vettori non sono complanari <=>  intersezione nulla
            FreeCAD.Console.PrintError('Lines are not in the same plane.\n')
            return None
    else:  #se i vettori sono paralleli <=>  intersezione nulla
        FreeCAD.Console.PrintError('Lines are parallel.\n')
        return None
Beispiel #15
0
def intersectionLines(p1=None,v1=None,p2=None,v2=None): # OBSOLETE: replaced with intersectionCLines
  '''
  intersectionLines(p1,v1,p2,v2)
  If exist, returns the intersection (vector) between two lines 
    p1,v1: the reference point and direction of first line
    p2,v2: the reference point and direction of second line
  '''
  
  if None in [p1,p2,v1,v2]:
    eds=edges()[:2]
    p1,p2=[e.valueAt(0) for e in eds]
    v1,v2=[e.tangentAt(0) for e in eds]
  if not isParallel(v1,v2):  
    dist=p1-p2
    import numpy
    #M=numpy.matrix([list(v1),list(v2),list(dist)]) # does not work: it seems for lack of accuracy of FreeCAD.Base.Vector operations!
    rowM1=[round(x,2) for x in v1]
    rowM2=[round(x,2) for x in v2]
    rowM3=[round(x,2) for x in dist]
    M=numpy.matrix([rowM1,rowM2,rowM3])
    if numpy.linalg.det(M)==0: 
      #3 equations, 2 unknowns => 1 eq. must be dependent
      a11,a21,a31=list(v1)
      a12,a22,a32=list(v2*-1)
      M1=numpy.matrix([[a11,a12],[a21,a22]])
      M2=numpy.matrix([[a21,a22],[a31,a32]])
      M3=numpy.matrix([[a31,a32],[a11,a12]])
      pl1=list(p1)
      pl2=list(p2)
      if numpy.linalg.det(M1)!=0:
        k=numpy.linalg.inv(M1)*numpy.matrix([[pl2[0]-pl1[0]],[pl2[1]-pl1[1]]])
      elif numpy.linalg.det(M2)!=0:
        k=numpy.linalg.inv(M2)*numpy.matrix([[pl2[1]-pl1[1]],[pl2[2]-pl1[2]]])
      else:
        k=numpy.linalg.inv(M3)*numpy.matrix([[pl2[2]-pl1[2]],[pl2[0]-pl1[0]]])
      P=p1+v1*float(k[0]) # ..=p2+v2*float(k[1])
      #FreeCAD.Console.PrintWarning("k1 = "+str(float(k[0]))+"\nk2 = "+str(float(k[1]))+"\n")
      return rounded(P)
    else:     #se i vettori non sono complanari <=>  intersezione nulla
      FreeCAD.Console.PrintError('Lines are not in the same plane.\n')
      return None
  else:  #se i vettori sono paralleli <=>  intersezione nulla
    FreeCAD.Console.PrintError('Lines are parallel.\n')
    return None