Example #1
0
 def getGlobalRot(self, point):
     "Same as getGlobalCoords, but discards the WP position"
     vx = DraftVecUtils.scale(self.u, point.x)
     vy = DraftVecUtils.scale(self.v, point.y)
     vz = DraftVecUtils.scale(self.axis, point.z)
     pt = (vx.add(vy)).add(vz)
     return pt
Example #2
0
    def makeStraightStairsWithLanding(self,obj,edge):
        
        "builds a straight staircase with a landing in the middle"

        if obj.NumberOfSteps < 3:
            return
        import Part,DraftGeomUtils
        v = DraftGeomUtils.vec(edge)
        reslength = edge.Length - obj.Width.Value
        vLength = DraftVecUtils.scaleTo(v,float(reslength)/(obj.NumberOfSteps-2))
        vLength = Vector(vLength.x,vLength.y,0)
        vWidth = DraftVecUtils.scaleTo(vLength.cross(Vector(0,0,1)),obj.Width.Value)
        p1 = edge.Vertexes[0].Point
        if round(v.z,Draft.precision()) != 0:
            h = v.z
        else:
            h = obj.Height.Value
        hstep = h/obj.NumberOfSteps
        landing = obj.NumberOfSteps/2
        p2 = p1.add(DraftVecUtils.scale(vLength,landing-1).add(Vector(0,0,landing*hstep)))
        p3 = p2.add(DraftVecUtils.scaleTo(vLength,obj.Width.Value))
        p4 = p3.add(DraftVecUtils.scale(vLength,obj.NumberOfSteps-(landing+1)).add(Vector(0,0,(obj.NumberOfSteps-landing)*hstep)))
        self.makeStraightStairs(obj,Part.Line(p1,p2).toShape(),landing)
        self.makeStraightLanding(obj,Part.Line(p2,p3).toShape())
        self.makeStraightStairs(obj,Part.Line(p3,p4).toShape(),obj.NumberOfSteps-landing)
Example #3
0
 def align(self, basepoint, align, widthvec):
     "moves a given basepoint according to the alignment"
     if align == "Center":
         basepoint = basepoint.add(DraftVecUtils.scale(widthvec, -0.5))
     elif align == "Right":
         basepoint = basepoint.add(DraftVecUtils.scale(widthvec, -1))
     return basepoint
Example #4
0
 def getGlobalCoords(self, point):
     "returns the global coordinates of the given point, taken relatively to this working plane"
     vx = DraftVecUtils.scale(self.u, point.x)
     vy = DraftVecUtils.scale(self.v, point.y)
     vz = DraftVecUtils.scale(self.axis, point.z)
     pt = (vx.add(vy)).add(vz)
     return pt.add(self.position)
Example #5
0
    def makeStraightStairsWithLanding(self,obj,edge):
        
        "builds a straight staircase with a landing in the middle"

        if obj.NumberOfSteps < 3:
            return
        import Part,DraftGeomUtils
        v = DraftGeomUtils.vec(edge)
        reslength = edge.Length - obj.Width.Value
        vLength = DraftVecUtils.scaleTo(v,float(reslength)/(obj.NumberOfSteps-2))
        vLength = Vector(vLength.x,vLength.y,0)
        vWidth = DraftVecUtils.scaleTo(vLength.cross(Vector(0,0,1)),obj.Width.Value)
        p1 = edge.Vertexes[0].Point
        if round(v.z,Draft.precision()) != 0:
            h = v.z
        else:
            h = obj.Height.Value
        hstep = h/obj.NumberOfSteps
        landing = obj.NumberOfSteps/2
        p2 = p1.add(DraftVecUtils.scale(vLength,landing-1).add(Vector(0,0,landing*hstep)))
        p3 = p2.add(DraftVecUtils.scaleTo(vLength,obj.Width.Value))
        p4 = p3.add(DraftVecUtils.scale(vLength,obj.NumberOfSteps-(landing+1)).add(Vector(0,0,(obj.NumberOfSteps-landing)*hstep)))
        self.makeStraightStairs(obj,Part.Line(p1,p2).toShape(),landing)
        self.makeStraightLanding(obj,Part.Line(p2,p3).toShape())
        self.makeStraightStairs(obj,Part.Line(p3,p4).toShape(),obj.NumberOfSteps-landing)
Example #6
0
 def getGlobalCoords(self, point):
     "returns the global coordinates of the given point, taken relatively to this working plane"
     vx = DraftVecUtils.scale(self.u, point.x)
     vy = DraftVecUtils.scale(self.v, point.y)
     vz = DraftVecUtils.scale(self.axis, point.z)
     pt = (vx.add(vy)).add(vz)
     return pt.add(self.position)
Example #7
0
 def getGlobalRot(self, point):
     "Same as getGlobalCoords, but discards the WP position"
     vx = DraftVecUtils.scale(self.u, point.x)
     vy = DraftVecUtils.scale(self.v, point.y)
     vz = DraftVecUtils.scale(self.axis, point.z)
     pt = (vx.add(vy)).add(vz)
     return pt
Example #8
0
 def align(self,basepoint,align,widthvec):
     "moves a given basepoint according to the alignment"
     if align == "Center":
         basepoint = basepoint.add(DraftVecUtils.scale(widthvec,-0.5))
     elif align == "Right":
         basepoint = basepoint.add(DraftVecUtils.scale(widthvec,-1))
     return basepoint
Example #9
0
 def update(self, line=None, normal=None):
     import WorkingPlane, DraftGeomUtils
     if not normal:
         normal = FreeCAD.DraftWorkingPlane.axis
     if line:
         if isinstance(line, list):
             bp = line[0]
             lvec = line[1].sub(line[0])
         else:
             lvec = DraftGeomUtils.vec(line.Shape.Edges[0])
             bp = line.Shape.Edges[0].Vertexes[0].Point
     elif self.baseline:
         lvec = DraftGeomUtils.vec(self.baseline.Shape.Edges[0])
         bp = self.baseline.Shape.Edges[0].Vertexes[0].Point
     else:
         return
     right = lvec.cross(normal)
     self.cube.width.setValue(lvec.Length)
     p = WorkingPlane.getPlacementFromPoints(
         [bp, bp.add(lvec), bp.add(right)])
     self.trans.rotation.setValue(p.Rotation.Q)
     bp = bp.add(DraftVecUtils.scale(lvec, 0.5))
     bp = bp.add(
         DraftVecUtils.scaleTo(normal,
                               self.cube.depth.getValue() / 2))
     self.pos(bp)
Example #10
0
    def __init__(self, holcyl_list, name="bearwashgr", normal=VZ, pos=V0):
        doc = FreeCAD.ActiveDocument

        self.holcyl_list = holcyl_list
        self.name = name

        group_h = 0  # the accumulated height
        # in case the length is not 1
        norm_normal = DraftVecUtils.scaleTo(normal, 1)

        self.normal = norm_normal
        elem_pos = pos

        d_maxwash = 0
        d_maxbear = 0
        fco_list = []  # list of the freecad objects
        for ind, elem in enumerate(holcyl_list):
            fco = fcfun.addCylHolePos(r_out=elem.r_out,
                                      r_in=elem.r_in,
                                      h=elem.thick,
                                      name=name + str(ind + 1),
                                      normal=norm_normal,
                                      pos=elem_pos)
            fco_list.append(fco)
            # adding the height on the same direction
            elem_pos += DraftVecUtils.scale(norm_normal, elem.thick)
            #print 'index: ' + str(ind)  +' thick: ' +
            #       str(elem.thick) + ' elem_pos: ' + str(elem_pos)
            group_h += elem.thick
            if elem.part == 'washer':
                if d_maxwash < elem.d_out:
                    d_maxwash = elem.d_out
            elif elem.part == 'bearing':
                if d_maxbear < elem.d_out:
                    d_maxbear = elem.d_out

        self.height = group_h
        self.fco_list = fco_list
        self.d_maxwash = d_maxwash
        self.d_maxbear = d_maxbear
        self.r_maxwash = d_maxwash / 2.
        self.r_maxbear = d_maxbear / 2.
        self.count = len(fco_list)
        self.h_pulleybelt = self.get_pulleybelt_h

        bearwashgroup = doc.addObject("Part::Compound", name)
        bearwashgroup.Links = fco_list

        self.fco = bearwashgroup
        doc.recompute()
Example #11
0
 def getSubVolume(self,base,width,plac=None):
     "returns a subvolume from a base object"
     import Part
     max_length = 0
     f = None
     for w in base.Shape.Wires:
         if w.BoundBox.DiagonalLength > max_length:
             max_length = w.BoundBox.DiagonalLength
             f = w
     if f:
         f = Part.Face(f)
         n = f.normalAt(0,0)
         v1 = DraftVecUtils.scaleTo(n,width)
         f.translate(v1)
         v2 = DraftVecUtils.neg(v1)
         v2 = DraftVecUtils.scale(v1,-2)
         f = f.extrude(v2)
         if plac:
             f.Placement = plac
         return f
     return None
Example #12
0
 def getSubVolume(self, base, width, plac=None):
     "returns a subvolume from a base object"
     import Part
     max_length = 0
     f = None
     for w in base.Shape.Wires:
         if w.BoundBox.DiagonalLength > max_length:
             max_length = w.BoundBox.DiagonalLength
             f = w
     if f:
         f = Part.Face(f)
         n = f.normalAt(0, 0)
         v1 = DraftVecUtils.scaleTo(n, width)
         f.translate(v1)
         v2 = DraftVecUtils.neg(v1)
         v2 = DraftVecUtils.scale(v1, -2)
         f = f.extrude(v2)
         if plac:
             f.Placement = plac
         return f
     return None
 def update(self,line=None,normal=None):
     import WorkingPlane, DraftGeomUtils
     if not normal:
         normal = FreeCAD.DraftWorkingPlane.axis
     if line:
         if isinstance(line,list):
             bp = line[0]
             lvec = line[1].sub(line[0])
         else:
             lvec = DraftGeomUtils.vec(line.Shape.Edges[0])
             bp = line.Shape.Edges[0].Vertexes[0].Point
     elif self.baseline:
         lvec = DraftGeomUtils.vec(self.baseline.Shape.Edges[0])
         bp = self.baseline.Shape.Edges[0].Vertexes[0].Point
     else:
         return
     right = lvec.cross(normal)
     self.cube.width.setValue(lvec.Length)
     p = WorkingPlane.getPlacementFromPoints([bp,bp.add(lvec),bp.add(right)])
     self.trans.rotation.setValue(p.Rotation.Q)
     bp = bp.add(DraftVecUtils.scale(lvec,0.5))
     bp = bp.add(DraftVecUtils.scaleTo(normal,self.cube.depth.getValue()/2))
     self.pos(bp)
 def getSubVolume(self,base,width,plac=None):
     "returns a subvolume from a base object"
     import Part,DraftVecUtils
     
     # finding biggest wire in the base shape
     max_length = 0
     f = None
     for w in base.Shape.Wires:
         if w.BoundBox.DiagonalLength > max_length:
             max_length = w.BoundBox.DiagonalLength
             f = w
     if f:
         f = Part.Face(f)
         n = f.normalAt(0,0)
         v1 = DraftVecUtils.scaleTo(n,width*1.1) # we extrude a little more to avoid face-on-face
         f.translate(v1)
         v2 = DraftVecUtils.neg(v1)
         v2 = DraftVecUtils.scale(v1,-2)
         f = f.extrude(v2)
         if plac:
             f.Placement = plac
         return f
     return None
 def getSubVolume(self,base,width,plac=None):
     "returns a subvolume from a base object"
     import Part,DraftVecUtils
     
     # finding biggest wire in the base shape
     max_length = 0
     f = None
     for w in base.Shape.Wires:
         if w.BoundBox.DiagonalLength > max_length:
             max_length = w.BoundBox.DiagonalLength
             f = w
     if f:
         f = Part.Face(f)
         n = f.normalAt(0,0)
         v1 = DraftVecUtils.scaleTo(n,width*1.1) # we extrude a little more to avoid face-on-face
         f.translate(v1)
         v2 = DraftVecUtils.neg(v1)
         v2 = DraftVecUtils.scale(v1,-2)
         f = f.extrude(v2)
         if plac:
             f.Placement = plac
         return f
     return None
Example #16
0
def belt_wire_dir (center_sep, rad1, rad2,
                   fc_axis_l = VX,
                   fc_axis_s = VY,
                   ref_l = 1,
                   ref_s = 1,
                   pos=V0):

    """
    Makes a shape of a wire with 2 circles and exterior tangent lines
    check: https://en.wikipedia.org/wiki/Tangent_lines_to_circles
    It is not easy to draw it well
    rad1 and rad2 can be exchanged, rad1 doesnt have to be larger
            ....                    fc_axis_s
           :    ( \ tangent          |
      rad1 :   (    \  .. rad2       |--> fc_axis_l, on the direction of rad2
           .--(  +   +)--
               (    /:
                ( /  :
                 :   :
                 :...:
                   + center_sep
 
                  ....                fc_axis_s
                 :    ( \ tangent       |
            rad1 :   (    \  .. rad2    |
                  --(  +   +)--         |--> fc_axis_l, on the direction of rad2
                     (    /:             centered on this axis
                      ( /  :
                       :   :
                       :...:
             ref_l: 3  2 1
 
    Arguments:
    center_sep: separation of the circle centers
    rad1: Radius of the firs circle, on the opposite direction of fc_axis_l
    fc_axis_l: vector on the direction circle centers, pointing to rad2
    fc_axis_s: vector on the direction perpendicular to fc_axis_l, on the plane
               of the wire
    ref_l: reference (zero) of the fc_axis_l
            1: reference on the center 
            2: reference at one of the semicircle centers (point 2)
               the other circle center will be on the direction of fc_axis_l
            3: reference at the end of rad1 circle
               the other end will be on the direction of fc_axis_l
    pos: FreeCAD vector of the position of the reference
    returns the shape of the wire
    """

    # normalize the axis
    axis_l = DraftVecUtils.scaleTo(fc_axis_l,1)
    axis_s = DraftVecUtils.scaleTo(fc_axis_s,1)


    #        ....                fc_axis_s
    #            :    ( \ tangent       |
    #       rad1 :   (    \  .. rad2    |
    #             --3  2 1 45--         |--> fc_axis_l, on the direction of rad2
    #                (    /:             centered on this axis
    #                 ( /  :
    #                  :   :
    #                  :...:
    #                    + center_sep
       

    # ----- Distance vectors on axis_l
    # distance from 1 to 2 in axis_l
    fc_1_2_l = DraftVecUtils.scale(axis_l, -center_sep/2.)
    fc_2_3_l = DraftVecUtils.scale(axis_l, -rad1)
    fc_2_4_l = DraftVecUtils.scale(axis_l, center_sep)
    fc_4_5_l = DraftVecUtils.scale(axis_l, rad2)
    fc_2_5_l = fc_2_4_l + fc_4_5_l
    # ----- reference is point 2 on axis_l
    # vector to go from the reference point to point 2 in l
    if ref_l == 1:  # ref on circle center sep
        refto_2_l = fc_1_2_l
    elif ref_l == 2:  # ref on circle center (rad1)
        refto_2_l = V0
    elif ref_l == 3:  # ref at the left end
        refto_2_l = fc_2_3_l.negative()
    else:
        logger.error('wrong ref_l in shp_belt_wire_dir')


    # Now define the center of the rad1 circle
    # and everything will be defined from this point
    # ln: L axis Negative side
    # lp: L axis Positive side
    # sn: S axis Negative side
    # sp: S axis Positive side
    # s0: S axis at zero
    #
    #        ....      ln_sp          fc_axis_s
    #            :    ( \ tangent     |
    #       rad1 :   (    \ lp_sp     |
    #           ln_s0  2   4lp_s0     |--> fc_axis_l, on the direction of rad2
    #                (    / lp_sn        centered on this axis
    #                 ( /
    #                  lp_sp
    #
    
    # cs_rad1 is point 2 (center of circle 1)
    #cs_rad1 = pos +  refto_2_l
    # reference at point 3 (ln_s0)
    cs_rad1 = refto_2_l + fc_2_3_l.negative()
    # cs_rad2 is point 4 (center of circle 2)
    cs_rad2 = cs_rad1 + fc_2_4_l
    # ln_s0 is point 3 
    ln_s0_pos = cs_rad1 + fc_2_3_l # should be 0,0
    # lp_s0 is point 5 
    lp_s0_pos = cs_rad2 + fc_4_5_l

    dif_rad = float(abs(rad1 - rad2))
    # Since we take our reference on axis_l, they are aligned, like if they were
    # on axis X, and axis Y would be zero.
    # therefore, angle gamma is zero (se wikipedia)
    # check: https://en.wikipedia.org/wiki/Tangent_lines_to_circles
    # the angle beta of the tanget is calculate from pythagoras:
    # the length (separation between centers) and dif_rad
    beta = math.atan (dif_rad/center_sep)
    #print('beta %f', 180*beta/math.pi)
    #print('beta %f', beta*math.pi/2)
    # depending on who is larger rad1 or rad2, the negative angle will be either
    # on top or down of axis_s

    #
    #                 (          \
    #                ( /alfa   beta\ which is 90-beta
    #               (               )
    #                (             / 
    #                 (          /
    #  
   
    cos_beta = math.cos(beta) 
    sin_beta = math.sin(beta) 
    tan_axis_s_rad1add = DraftVecUtils.scale(axis_s, rad1 * cos_beta)
    tan_axis_s_rad2add = DraftVecUtils.scale(axis_s, rad2 * cos_beta)
    if rad1 > rad2: # then it will be positive on axis_l on rad1 and rad2
        tan_axis_l_rad1add = DraftVecUtils.scale(axis_l, rad1 * sin_beta)
        tan_axis_l_rad2add = DraftVecUtils.scale(axis_l, rad2 * sin_beta)
    else:
        tan_axis_l_rad1add = DraftVecUtils.scale(axis_l, - rad1 * sin_beta)
        tan_axis_l_rad2add = DraftVecUtils.scale(axis_l, - rad2 * sin_beta)

    ln_sp_pos = cs_rad1 + tan_axis_l_rad1add + tan_axis_s_rad1add 
    ln_sn_pos = cs_rad1 + tan_axis_l_rad1add + tan_axis_s_rad1add.negative() 
    lp_sp_pos = cs_rad2 + tan_axis_l_rad2add + tan_axis_s_rad2add 
    lp_sn_pos = cs_rad2 + tan_axis_l_rad2add + tan_axis_s_rad2add.negative() 
    

    #cq_plane = cq.Plane(origin=(pos.x,pos.y,pos.z), xDir=fc_axis_l,
    #                            normal=fc_axis_l.cross(fc_axis_s))
    #cq_plane = cq.Plane(origin=(lp_sp_pos.x,lp_sp_pos.y,pos.z),
    cq_plane = cq.Plane(origin=(pos.x,pos.y,pos.z),
                                xDir=axis_s.negative(),
                                normal=axis_l.cross(axis_s))

    lp_sp_pos_y = lp_sp_pos.dot(axis_l)
    lp_sp_pos_x = lp_sp_pos.dot(axis_s)

    lp_s0_pos_y = lp_s0_pos.dot(axis_l)
    lp_s0_pos_x = lp_s0_pos.dot(axis_s)

    lp_sn_pos_y = lp_sn_pos.dot(axis_l)
    lp_sn_pos_x = lp_sn_pos.dot(axis_s)

    ln_sp_pos_y = ln_sp_pos.dot(axis_l)
    ln_sp_pos_x = ln_sp_pos.dot(axis_s)

    ln_s0_pos_y = ln_s0_pos.dot(axis_l)
    ln_s0_pos_x = ln_s0_pos.dot(axis_s)

    ln_sn_pos_y = ln_sn_pos.dot(axis_l)
    ln_sn_pos_x = ln_sn_pos.dot(axis_s)

    result = cq.Workplane(cq_plane).move(lp_sp_pos_x,lp_sp_pos_y)\
               .threePointArc((lp_s0_pos_x, lp_s0_pos_y),
                              (lp_sn_pos_x, lp_sn_pos_y))\
               .lineTo(ln_sn_pos_x,ln_sn_pos_y)\
               .threePointArc((ln_s0_pos_x, ln_s0_pos_y),
                              (ln_sp_pos_x, ln_sp_pos_y))\
               .close()

    return (result)
#axis_front = VYN
axis_mov = VY
axis_front = VX
axis_up = VZ

# distance in mm that the filter is going to move
mov_distance = 60.

# width of the timming belt
belt_w = 6.

# position of the filter
# position of the filter in the middle
filter_pos_0 = V0
# position of the filter relative to it 0 position
filter_mov = DraftVecUtils.scale(axis_mov, 0)
filter_pos = filter_pos_0 + filter_mov
# the point of this position is the filter center of symmetry and its base
filter_pos_d = 9
filter_pos_w = 0
filter_pos_h = 1

# width of the belt
belt_w = 6.
# height of the belt clamp
beltclamp_h = belt_w + 2
# length of the motor shaft
motorshaft_l = 24.

# width of the aluminum profile
aluprof_w = 15.
Example #18
0
leadscrew_tot_l = 510. #(mirar)
leadscrew_motor_space_l = 30.
leadscrew_int_l = leadscrew_tot_l - leadscrew_motor_space_l
leadscrew_d = 12 # trapecial, or 16.

# perfiles del portico en altura
alu_len_port_v = 400

# perfiles que bajan del portico para empujar
alu_len_empuje_v = 244

alu_tray_name = 'alu_tray'

# travesano interno para el final del husillo y su soporte
alu_base_traves_int_pos = DraftVecUtils.scale(VY, leadscrew_int_l-alu_w/2)
h_alu = comps.getaluprof_dir(d_alu, length=alu_len_w_int1,
                                 fc_axis_l = VX,
                                 fc_axis_w = VY,
                                 fc_axis_p = VZN,
                                 ref_l = 1, # centered
                                 ref_w = 1, # centered
                                 ref_p = 2, # at top
                                 wfco = 1,
                                 pos = alu_base_traves_int_pos + pos_0,
                                 name = 'travesano_int')

print ('travesanos ancho: ', str(alu_len_w))
# los travesanos en direccion x, cubren el ancho
for y_i in [0,1]:  # 
    alu_name = 'alu_travesano_base' + '_y' + str(y_i)
    def __init__(self, size,
                 fc_axis_h = VZ,
                 fc_axis_d = VX,
                 fc_axis_w = V0,
                 pos_h = 1,
                 pos_w = 1,
                 pos_d = 1,
                 pillow = 0, #make it the same height of a pillow block
                 pos = V0,
                 wfco = 1,
                 tol = 0.3,
                 name= "shaft_holder"):
        self.size = size
        self.wfco = wfco
        self.name = name

        self.pos = FreeCAD.Vector(0,0,0)
        self.position = pos

        self.tol = tol
        self.pos_h = pos_h
        self.pos_w = pos_w
        self.pos_d = pos_d

        doc = FreeCAD.ActiveDocument
        if pillow == 0:
            skdict = kcomp.SK.get(size)
        else:
            skdict = kcomp.PILLOW_SK.get(size)
        if skdict == None:
            logger.error("Sk size %d not supported", size)

        # normalize de axis
        axis_h = DraftVecUtils.scaleTo(fc_axis_h,1)
        axis_d = DraftVecUtils.scaleTo(fc_axis_d,1)
        if fc_axis_w == V0:
            axis_w = axis_h.cross(axis_d)
        else:
            axis_w = DraftVecUtils.scaleTo(fc_axis_w,1)

        axis_h_n = axis_h.negative()
        axis_d_n = axis_d.negative()
        axis_w_n = axis_w.negative()

        NuevaClase.Obj3D.__init__(self, axis_d, axis_w, axis_h, name = name)

        # Total height:
        sk_h = skdict['H']
        self.tot_h = sk_h
        # Total width (Y):
        sk_w = skdict['W']
        self.tot_w = sk_w
        # Total depth (x):
        sk_d = skdict['L']
        self.tot_d = sk_d
        # Base height
        sk_base_h = skdict['g']
        # center width
        sk_center_w = skdict['I']
        # Axis height:
        sk_axis_h = skdict['h']
        # self.axis_h = sk_axis_h
        # Mounting bolts separation
        sk_mbolt_sep = skdict['B']
    
        # tightening bolt with added tolerances:
        tbolt_d = skdict['tbolt']
        # Bolt's head radius
        tbolt_head_r = (self.holtol
                        * kcomp.D912_HEAD_D[skdict['tbolt']])/2.0
        # Bolt's head lenght
        tbolt_head_l = (self.holtol
                        * kcomp.D912_HEAD_L[skdict['tbolt']] )
        # Mounting bolt radius with added tolerance
        mbolt_r = self.holtol * skdict['mbolt']/2.


        self.d0_cen = 0 
        self.w0_cen = 1 # symmetric
        self.h0_cen = 0
        # vectors from the origin to the points along axis_d:
        self.d_o[0] = V0 # origin
        self.d_o[1] = self.vec_d(sk_d/2.)
        self.d_o[2] = self.vec_d(sk_d)
        
        # vectors from the origin to the points along axis_w:
        self.w_o[0] = V0
        self.w_o[1] = self.vec_w(sk_mbolt_sep/2)
        self.w_o[2] = self.vec_w(sk_w/2)

        # vectors from the origin to the points along axis_h:
        self.h_o[0] = V0
        self.h_o[1] = self.vec_h(sk_axis_h)

        # calculates the position of the origin, and keeps it in attribute pos_o
        self.set_pos_o()

        # TODO: See how to change this reference points
        if pos_h == 1:  # distance vectors on axis_h
            ref2rod_h = V0 # h_o[0]
            ref2base_h = DraftVecUtils.scale(axis_h, -sk_axis_h) # h_o[1]
        else:
            ref2rod_h = DraftVecUtils.scale(axis_h, sk_axis_h) # h_o[1]
            ref2base_h = V0 # h_o[0]
        if pos_w == 0:  # distance vectors on axis_w
            ref2cen_w = V0 # w_o[0]
            ref2bolt_w = DraftVecUtils.scale(axis_w, -sk_mbolt_sep/2.) # w_o[-1]
            ref2end_w = DraftVecUtils.scale(axis_w, -sk_w/2.) # w_o[2]
        elif pos_w == 1:
            ref2cen_w =  DraftVecUtils.scale(axis_w, sk_mbolt_sep/2.) # w_o[1]
            ref2bolt_w = V0 # w_o[0]
            ref2end_w = DraftVecUtils.scale(axis_w, -(sk_w-sk_mbolt_sep)/2.) # w_o[]
        else: # w_o == -1 at the end on the width dimension
            ref2cen_w =  DraftVecUtils.scale(axis_w, sk_w/2.) # w_o[2]
            ref2bolt_w = DraftVecUtils.scale(axis_w, (sk_w-sk_mbolt_sep)/2.) # w_o[]
        if pos_d == 1:  # distance vectors on axis_d
            ref2cen_d = V0 # d_o[0]
            ref2end_d = DraftVecUtils.scale(axis_d, -sk_d/2.) # d_o[1]
        else:
            ref2cen_d = DraftVecUtils.scale(axis_d, sk_d/2.) # d_o[1]
            ref2end_d = V0 # d_o[0]

        # TODO: Use the newe method:
        # super().get_pos_dwh(pos_d,pos_w,pos_h)
        basecen_pos = self.pos + ref2base_h + ref2cen_w + ref2cen_d
        # Making the tall box:
        shp_tall = fcfun.shp_box_dir (box_w = sk_center_w, 
                                  box_d = sk_d,
                                  box_h = sk_h,
                                  fc_axis_w = axis_w,
                                  fc_axis_h = axis_h,
                                  fc_axis_d = axis_d,
                                  cw = 1, cd= 1, ch=0, pos = basecen_pos)
        # Making the wide box:
        shp_wide = fcfun.shp_box_dir (box_w = sk_w, 
                                  box_d = sk_d,
                                  box_h = sk_base_h,
                                  fc_axis_w = axis_w,
                                  fc_axis_h = axis_h,
                                  fc_axis_d = axis_d,
                                  cw = 1, cd= 1, ch=0, pos = basecen_pos)
        shp_sk = shp_tall.fuse(shp_wide)
        doc.recompute()
        shp_sk = shp_sk.removeSplitter()

        
        holes = []

        # Shaft hole, 
        rodcen_pos = self.pos + ref2rod_h + ref2cen_w + ref2cen_d
        rod_hole = fcfun.shp_cylcenxtr(r= size/2. +self.tol,
                                         h = sk_d,
                                         normal = axis_d,
                                         ch = 1,
                                         xtr_top = 1,
                                         xtr_bot = 1,
                                         pos = rodcen_pos)
        holes.append(rod_hole)

        # the upper sepparation
        shp_topopen = fcfun.shp_box_dir_xtr (
                                  box_w = self.up_sep_dist, 
                                  box_d = sk_d,
                                  box_h = sk_h-sk_axis_h,
                                  fc_axis_w = axis_w,
                                  fc_axis_h = axis_h,
                                  fc_axis_d = axis_d,
                                  cw = 1, cd= 1, ch=0,
                                  xtr_h = 1, xtr_d = 1, xtr_nd = 1,
                                  pos = rodcen_pos)
        holes.append(shp_topopen)

        # Tightening bolt hole
        # tbolt_d is the diameter of the bolt: (M..) M4, ...
        # tbolt_head_r: is the radius of the tightening bolt's head
        # (including tolerance), which its bottom either
        #- is at the middle point between
        #  - A: the total height :sk_h
        #  - B: the top of the shaft hole: axis_h + size/2.
        #  - so the result will be (A + B)/2
        # tot_h - (axis_h + size/2.)
        #       _______..A........................
        #      |  ___  |.B.......+ rodtop2top_dist = sk_h - (axis_h + size/2.) 
        #      | /   \ |.......+ size/2.
        #      | \___/ |       :
        #    __|       |__     + axis_h
        #   |_____________|....:

        rodtop2top_dist = sk_h - (sk_axis_h + size/2.)
        tbolt_pos = (   rodcen_pos
                      + DraftVecUtils.scale(axis_w, sk_center_w/2.)
                      + DraftVecUtils.scale(axis_h, size/2.)
                      + DraftVecUtils.scale(axis_h, rodtop2top_dist/2.))
        shp_tbolt = fcfun.shp_bolt_dir(r_shank= tbolt_d/2.,
                                        l_bolt = sk_center_w,
                                        r_head = tbolt_head_r,
                                        l_head = tbolt_head_l,
                                        hex_head = 0,
                                        xtr_head = 1,
                                        xtr_shank = 1,
                                        support = 0,
                                        fc_normal = axis_w_n,
                                        fc_verx1 = axis_h,
                                        pos = tbolt_pos)
        holes.append(shp_tbolt)
 
        #Mounting bolts
        cen2mbolt_w = DraftVecUtils.scale(axis_w, sk_mbolt_sep/2.)
        for w_pos in [cen2mbolt_w.negative(), cen2mbolt_w]:
            mbolt_pos = basecen_pos + w_pos
            mbolt_hole = fcfun.shp_cylcenxtr(r= mbolt_r,
                                           h = sk_d,
                                           normal = axis_h,
                                           ch = 0,
                                           xtr_top = 1,
                                           xtr_bot = 1,
                                           pos = mbolt_pos)
            holes.append(mbolt_hole)
 

        shp_holes = fcfun.fuseshplist(holes)
        shp_sk = shp_sk.cut(shp_holes)
        self.shp = shp_sk

        if wfco == 1:
            super().create_fco()
            # Need to set first in (0,0,0) and after that set the real placement.
            # This enable to do rotations without any issue
            self.fco.Placement.Base = FreeCAD.Vector(0,0,0) 
            self.fco.Placement.Base = self.position
def filter_stage_fun(move_l, Filter_Length, Filter_Width, nut_hole,
                     tens_stroke_Var, base_w, wall_thick_Var, size_motor,
                     h_motor, thik_motor, pos):
    #move_l => mov_distance
    #nut_hole => bolttens_mtr
    #tens_stroke_Var => tens_stroke
    #base_w => aluprof_w
    #wall_thick_Var => wall_thick

    # distance in mm that the filter is going to move
    mov_distance = move_l  #60.

    # width of the timming belt
    belt_w = 6.

    # position of the filter
    # position of the filter in the middle
    filter_pos_0 = pos
    # position of the filter relative to it 0 position
    filter_mov = DraftVecUtils.scale(axis_mov, 0)
    filter_pos = filter_pos_0 + filter_mov
    # the point of this position is the filter center of symmetry and its base
    filter_pos_d = 9
    filter_pos_w = 0
    filter_pos_h = 1

    # width of the belt
    belt_w = 6.
    # height of the belt clamp
    beltclamp_h = belt_w + 2
    # length of the motor shaft
    motorshaft_l = 24.

    # width of the aluminum profile
    aluprof_w = base_w  #Base del tension holder  #20.
    # dictionary with the dimensions of the aluminum profile
    aluprof_dict = kcomp.ALU_PROF[aluprof_w]

    belt_dict = kcomp.GT[2]

    # ------ linear guide for the filter holder
    linguide_dict = kcomp.SEB15A
    linguide_blk_dict = linguide_dict['block']
    linguide_rail_dict = linguide_dict['rail']
    bolt_linguide_mtr = linguide_blk_dict['boltd']

    filter_holder = filter_holder_clss.PartFilterHolder(
        filter_l=Filter_Length,
        filter_w=Filter_Width,
        filter_t=2.5,
        base_h=6.,
        hold_d=10.,  #12
        filt_supp_in=2.,
        filt_rim=3.,
        filt_cen_d=30,
        fillet_r=1.,
        boltcol1_dist=20 / 2.,
        boltcol2_dist=12.5,
        boltcol3_dist=25,
        boltrow1_h=0,
        boltrow1_2_dist=12.5,
        boltrow1_3_dist=20.,
        boltrow1_4_dist=25.,
        bolt_cen_mtr=4,
        bolt_linguide_mtr=bolt_linguide_mtr,
        beltclamp_t=3.,
        beltclamp_l=12.,
        beltclamp_h=beltclamp_h,
        clamp_post_dist=4.,
        sm_beltpost_r=1.,
        tol=kcomp.TOL,
        axis_d=axis_front,
        axis_w=axis_mov,
        axis_h=axis_up,
        pos_d=filter_pos_d,
        pos_w=filter_pos_w,
        pos_h=filter_pos_h,
        pos=filter_pos,
        name='filter_holder')

    filter_holder.set_color(fcfun.YELLOW_05)

    # ------ linear guide for the filter holder
    # block:
    partLinGuideBlock = comps.PartLinGuideBlock(block_dict=linguide_blk_dict,
                                                rail_dict=linguide_rail_dict,
                                                axis_d=axis_mov,
                                                axis_w=axis_up,
                                                axis_h=axis_front,
                                                pos_d=0,
                                                pos_w=-2,
                                                pos_h=3,
                                                pos=filter_holder.get_pos_dwh(
                                                    0, 0, 3))

    # 4 bolts to attach the filter holder to the linear guide
    # the bolt head has to be touching the hole for the bolt: pos_d = 5
    bolt_head_pos = filter_holder.get_o_to_d(5)
    for w_i in [-2, 2]:
        for d_i in [-1, 1]:
            # positions of the bolts at the linear guide
            filter_bolt_pos_i = (partLinGuideBlock.get_pos_dwh(d_i, w_i, 3) +
                                 bolt_head_pos)
            fc_clss.Din912Bolt(
                metric=bolt_linguide_mtr,
                shank_l=(bolt_head_pos.Length + partLinGuideBlock.bolt_l),
                shank_l_adjust=-1,  # shorter to shank_l
                axis_h=axis_front.negative(),
                pos_h=3,
                pos=filter_bolt_pos_i,
                name='filter_bolt_w' + str(w_i) + '_d' + str(d_i))

    # rail
    # the rail will be in the direcion of:
    #   axis_up: defined by partLinGuideBlock
    #   axis_front: defined by partLinGuideBlock
    #   axis_mov: NOT defined by partLinGuideBlock, because it moves along
    #             this axis
    #             Defined by filter_pos_0

    pos_fromblock = partLinGuideBlock.get_pos_dwh(0, 0, 4)
    #dif_pos = pos_fromblock - filter_mov
    #min_axis_mov = DraftVecUtils.project(dif_pos, axis_mov)

    rail_xtr_d = 10.

    pos_rail = (pos_fromblock - filter_mov +
                DraftVecUtils.scale(axis_mov, rail_xtr_d / 2.))

    partLinGuideRail = comps.PartLinGuideRail(
        rail_d=(filter_holder.tot_w + mov_distance + rail_xtr_d),
        rail_dict=linguide_rail_dict,
        boltend_sep=0,
        axis_d=axis_mov,
        axis_w=axis_up,
        axis_h=axis_front,
        # center along axis_d and axis_d, base along axis_h
        pos_d=2,
        pos_w=0,
        pos_h=0,
        pos=pos_rail)

    # get the position of the belt of the filter, at center of symmetry
    belt_pos_mov = filter_holder.get_pos_dwh(2, 0, 7)
    # get the position of the belt of the filter if not moved
    belt_pos = filter_holder.get_pos_dwh(2, 0, 7) - filter_mov

    tensioner_pos = (belt_pos + DraftVecUtils.scale(
        axis_mov, mov_distance / 2. + filter_holder.tot_w / 2. +
        tens_stroke_Var) + DraftVecUtils.scale(axis_up, belt_w / 2.))

    # position of the set: motor pulley holder
    nemaholder_w_motor_pos = (belt_pos + DraftVecUtils.scale(
        axis_mov, -mov_distance / 2. - filter_holder.tot_w / 2. - aluprof_w) +
                              DraftVecUtils.scale(axis_up, belt_w / 2.))

    print(str(belt_pos))
    print(str(tensioner_pos))

    # at the end of the idler tensioner, when it is all the way in
    tensioner_pos_d = 6
    #tensioner_pos_d = 2
    tensioner_pos_w = -1  # at the pulley radius
    tensioner_pos_h = 3  # middle point of the pulley

    # calculating the distance from the base of the tensioner to the middle of the
    # pulley, distance along axis_up (two planes)
    # these to sentences are equivalent
    # no need to be this complicated if using axis_z

    #tensioner_belt_h = ((DraftVecUtils.project(
    #                         tensioner_pos-pos_rail, axis_up)).Length
    #                       - aluprof_w / 2.)

    tensioner_belt_h = (
        pos_rail.distanceToPlane(tensioner_pos, axis_up.negative()) -
        aluprof_w / 2.)

    # metric of the bolt to attach the tensioner
    boltaluprof_mtr = 4

    tensioner = tensioner_clss.TensionerSet(
        aluprof_w=base_w,  #20.,
        belt_pos_h=tensioner_belt_h,
        hold_bas_h=0,
        hold_hole_2sides=1,
        boltidler_mtr=3,
        bolttens_mtr=nut_hole,  #métrica del tensor
        boltaluprof_mtr=boltaluprof_mtr,
        tens_stroke=tens_stroke_Var,
        wall_thick=wall_thick_Var,
        in_fillet=2.,
        pulley_stroke_dist=0,
        nut_holder_thick=nut_hole,
        opt_tens_chmf=0,
        min_width=0,
        tol=kcomp.TOL,
        axis_d=axis_mov.negative(),
        axis_w=axis_front.negative(),
        axis_h=axis_up,
        pos_d=tensioner_pos_d,
        pos_w=tensioner_pos_w,
        pos_h=tensioner_pos_h,
        pos=tensioner_pos,
        name='tensioner_set')

    # get_idler_tensioner gets the set, including the pulley. Either of these 2
    # would be correct
    #tensioner.get_idler_tensioner().get_idler_tensioner().set_color(fcfun.ORANGE)
    tensioner.get_idler_tensioner().set_color(fcfun.ORANGE,
                                              2)  #2: the tensioner
    tensioner.set_color(fcfun.LSKYBLUE, 2)  #2: the holder

    # position of the aluminum profile that supports the tensioner
    # point at the base, at the end along axis w, centered along axis_d (bolts)
    aluprof_tens_pos = tensioner.get_pos_dwh(2, -4, 0)

    #distance from this end of the aluprofile to the linear guide rail

    aluprof_tens_l = (aluprof_tens_pos.distanceToPlane(pos_rail, axis_front) +
                      aluprof_w)

    print('aluprof: ' + str(aluprof_tens_l))

    # length of the aluminum profile that supports the tensioner
    #aluprof_tens_l = tensioner.get_tensioner_holder().hold_bas_w

    aluprof_tens = comps.PartAluProf(
        depth=aluprof_tens_l,
        aluprof_dict=aluprof_dict,
        xtr_d=0,
        #xtr_nd = aluprof_tens_l/2., # extra length
        xtr_nd=0,
        axis_d=axis_front.negative(),
        axis_w=axis_mov,
        axis_h=axis_up,
        pos_d=1,  #end not counting xtr_nd
        pos_w=0,  # centered
        pos_h=3,
        pos=aluprof_tens_pos)

    # Bolts for the belt tensioner
    max_tens_bolt_l = (
        aluprof_tens.get_h_ab(3, 1).Length  # space for bolt in profile
        + tensioner.get_tensioner_holder().hold_bas_h)  # base thickness
    print('shank_l ' + str(max_tens_bolt_l))
    for w_i in [-3, 3]:  # position of bolts
        tens_bolt_i_pos = tensioner.get_pos_dwh(2, w_i, 1)
        tens_bolt_i = partset.Din912BoltWashSet(
            metric=boltaluprof_mtr,
            shank_l=max_tens_bolt_l,
            # smaller considering the washer
            shank_l_adjust=-2,
            axis_h=axis_up.negative(),
            pos_h=3,
            pos_d=0,
            pos_w=0,
            pos=tens_bolt_i_pos)

    # set with:
    # + motor holder
    # + motor
    # + pulley

    motor_holder_pos = (
        belt_pos + DraftVecUtils.scale(axis_mov, -mov_distance) +
        DraftVecUtils.scale(axis_up, -(motorshaft_l - beltclamp_h)))

    #nema_size = 11
    nema_size = size_motor

    nemaholder_w_motor = partset.NemaMotorPulleyHolderSet(
        nema_size=nema_size,
        motor_base_l=32.,
        motor_shaft_l=motorshaft_l,
        motor_circle_r=11.,
        motor_circle_h=2.,
        motor_chmf_r=1.,
        pulley_pitch=2.,
        pulley_n_teeth=20,
        pulley_toothed_h=7.5,
        pulley_top_flange_h=1.,
        pulley_bot_flange_h=0,
        pulley_tot_h=16.,
        pulley_flange_d=15.,
        pulley_base_d=15.,
        #pulley_tol = 0,
        pulley_pos_h=5.,
        hold_wall_thick=thik_motor,  #4.,
        hold_motorside_thick=3.,
        hold_reinf_thick=3.,
        hold_rail_min_h=3.,
        hold_rail_max_h=h_motor,  #20.,
        hold_motor_xtr_space=2.,
        hold_bolt_wall_d=4.,
        # hold_chmf_r = 1.,
        axis_h=axis_up,
        axis_d=axis_mov.negative(),
        axis_w=axis_front,
        pos_h=11,  # middle point of the pulley toothed part
        pos_d=0,  #0: at the wall where this holder is attached
        pos_w=5,  #5: inner radius of the pulley (to the back
        pos=nemaholder_w_motor_pos)

    nemaholder_w_motor.set_color(fcfun.GREEN_05, 2)  #2: the holder

    # aluminum profile for the motor holder

    aluprof_distance = (aluprof_tens_pos.distanceToPlane(
        nemaholder_w_motor_pos, axis_mov))

    aluprof_motor_pos = (aluprof_tens_pos -
                         DraftVecUtils.scale(axis_mov, aluprof_distance))

    aluprof_motor = comps.PartAluProf(
        depth=aluprof_tens_l,
        aluprof_dict=aluprof_dict,
        xtr_d=0,
        #xtr_nd = aluprof_tens_l/2., # extra length
        xtr_nd=0,
        axis_d=axis_front.negative(),
        axis_w=axis_mov,
        axis_h=axis_up,
        pos_d=1,  #end not counting xtr_nd
        pos_w=-3,  #not centered, touching the holder
        pos_h=3,
        pos=aluprof_motor_pos)

    # get the top-right-corner:
    aluprof_linguide_pos = aluprof_motor.get_pos_dwh(5, 3, 3)

    aluprof_linguide = comps.PartAluProf(
        depth=aluprof_distance - 3 * aluprof_w / 2.,
        aluprof_dict=aluprof_dict,
        xtr_d=0,
        xtr_nd=0,
        axis_d=axis_mov,
        axis_w=axis_front,
        axis_h=axis_up,
        pos_d=0,  #end not counting xtr_nd
        pos_w=-3,
        pos_h=3,
        pos=aluprof_linguide_pos)

    nema_motor_pull = nemaholder_w_motor.get_nema_motor_pulley()
    motor_pull = nema_motor_pull.get_gt_pulley()
    # external diameter of the motor pulley
    motor_pull_dm = 2 * (motor_pull.tooth_in_r + belt_dict['BELT_H'])

    tens_idler_set = tensioner.get_idler_tensioner()
    tens_pull = tens_idler_set.get_bear_wash_set()

    tens_pull_dm = 2 * (tens_pull.bear_r_out + belt_dict['BELT_H'])

    # d=5: center of pulley, inside
    # h=3: center of pulley on the height
    tens_pull_pos = tensioner.get_pos_dwh(5, 0, 3)
    # d=3: center of pulley
    # h=11: center of pulley on the height
    motor_pull_pos = nemaholder_w_motor.get_pos_dwh(3, 0, 11)

    pull_sep = tens_pull_pos - motor_pull_pos
    pull_sep_mov = pull_sep.dot(axis_mov)
    pull_sep_front = pull_sep.dot(axis_front.negative())

    # position of the internal side of the clamp block, closer to the motor
    # and closer to the linear guide
    filthold_clamp_pos_n = filter_holder.get_pos_dwh(1, -7, 8)
    filthold_clamp_pos = filter_holder.get_pos_dwh(1, 7, 8)

    # distances to the belt
    motorpull_clamp_sep = filthold_clamp_pos_n - motor_pull_pos
    motorpull_clamp_sep_mov = motorpull_clamp_sep.dot(axis_mov)
    motorpull_clamp_sep_front = motorpull_clamp_sep.dot(axis_front)
    idlpull_clamp_sep_mov = (pull_sep_mov - motorpull_clamp_sep_mov -
                             filter_holder.tot_w)

    belt = beltcl.PartBeltClamped(
        pull1_dm=motor_pull_dm,
        pull2_dm=tens_pull_dm,
        pull_sep_d=pull_sep_mov,
        pull_sep_w=pull_sep_front,
        clamp_pull1_d=motorpull_clamp_sep_mov,
        clamp_pull1_w=motorpull_clamp_sep_front,
        clamp_pull2_d=idlpull_clamp_sep_mov,
        clamp_d=filter_holder.beltclamp_l,
        clamp_w=filter_holder.beltclamp_t,
        clamp_cyl_sep=filter_holder.clamp_lrbeltpostcen_dist,
        cyl_r=filter_holder.lr_beltpost_r + belt_dict['BELT_H'],
        belt_width=belt_w,
        belt_thick=belt_dict['BELT_H'],
        axis_d=axis_mov,
        axis_w=axis_front.negative(),
        axis_h=axis_up,
        pos_d=0,
        pos_w=0,
        pos_h=0,
        pos=motor_pull_pos)

    belt.set_color(fcfun.GRAY_08)
def filter_holder_fun(Filter_Length, Filter_Width, Set_Select):

    # Other option. Set a value to change all the values (1*Size)

    mov_distance = 60.
    filter_mov = DraftVecUtils.scale(axis_mov, 0)
    linguide_dict = kcomp.SEB15A
    linguide_blk_dict = linguide_dict['block']
    linguide_rail_dict = linguide_dict['rail']
    bolt_linguide_mtr = linguide_blk_dict['boltd']

    filter_holder = filter_holder_clss.PartFilterHolder(
        filter_l=Filter_Length,
        filter_w=Filter_Width,
        filter_t=2.5,
        base_h=6.,
        hold_d=12.,
        filt_supp_in=2.,
        filt_rim=3.,
        filt_cen_d=30,
        fillet_r=1.,
        boltcol1_dist=20 / 2.,
        boltcol2_dist=12.5,
        boltcol3_dist=25,
        boltrow1_h=0,
        boltrow1_2_dist=12.5,
        boltrow1_3_dist=20.,
        boltrow1_4_dist=25.,
        bolt_cen_mtr=4,
        bolt_linguide_mtr=bolt_linguide_mtr,
        beltclamp_t=3.,
        beltclamp_l=12.,
        beltclamp_h=5.,  #beltclamp_h,
        clamp_post_dist=4.,
        sm_beltpost_r=1.,
        tol=kcomp.TOL,
        axis_d=axis_front,
        axis_w=axis_mov,
        axis_h=axis_up,
        pos_d=0,  #filter_pos_d,
        pos_w=0,  #filter_pos_w,
        pos_h=0,  #filter_pos_h,
        pos=V0,  #filter_pos,
        name='filter_holder')
    filter_holder.set_color(fcfun.YELLOW_05)

    if Set_Select == 1:
        # ------ linear guide for the filter holder
        # block:
        partLinGuideBlock = comps.PartLinGuideBlock(
            block_dict=linguide_blk_dict,
            rail_dict=linguide_rail_dict,
            axis_d=axis_mov,
            axis_w=axis_up,
            axis_h=axis_front,
            pos_d=0,
            pos_w=-2,
            pos_h=3,
            pos=filter_holder.get_pos_dwh(0, 0, 3))
        # 4 bolts to attach the filter holder to the linear guide
        bolt_head_pos = filter_holder.get_o_to_d(5)
        for w_i in [-2, 2]:
            for d_i in [-1, 1]:
                # positions of the bolts at the linear guide
                filter_bolt_pos_i = (
                    partLinGuideBlock.get_pos_dwh(d_i, w_i, 3) + bolt_head_pos)
                fc_clss.Din912Bolt(
                    metric=bolt_linguide_mtr,
                    shank_l=(bolt_head_pos.Length + partLinGuideBlock.bolt_l),
                    shank_l_adjust=-1,  # shorter to shank_l
                    axis_h=axis_front.negative(),
                    pos_h=3,
                    pos=filter_bolt_pos_i,
                    name='filter_bolt_w' + str(w_i) + '_d' + str(d_i))

        pos_fromblock = partLinGuideBlock.get_pos_dwh(0, 0, 4)

        rail_xtr_d = 10.

        pos_rail = (pos_fromblock - filter_mov +
                    DraftVecUtils.scale(axis_mov, rail_xtr_d / 2.))

        partLinGuideRail = comps.PartLinGuideRail(
            rail_d=(filter_holder.tot_w + mov_distance + rail_xtr_d),
            rail_dict=linguide_rail_dict,
            boltend_sep=0,
            axis_d=axis_mov,
            axis_w=axis_up,
            axis_h=axis_front,
            # center along axis_d and axis_d, base along axis_h
            pos_d=2,
            pos_w=0,
            pos_h=0,
            pos=pos_rail)
Example #22
0
    def makeStraightStairsWithLanding(self,obj,edge):

        "builds a straight staircase with/without a landing in the middle"

        if obj.NumberOfSteps < 3:
            return
        import Part,DraftGeomUtils
        v = DraftGeomUtils.vec(edge)

        landing = 0
        if obj.TreadDepthEnforce == 0:
            if obj.Landings == "At center":
                if obj.LandingDepth:
                    reslength = edge.Length - obj.LandingDepth.Value
                else:
                    reslength = edge.Length - obj.Width.Value

                vLength = DraftVecUtils.scaleTo(v,float(reslength)/(obj.NumberOfSteps-2))
            else:
                reslength = edge.Length
                vLength = DraftVecUtils.scaleTo(v,float(reslength)/(obj.NumberOfSteps-1))

        else:

            if obj.Landings == "At center":
                reslength = obj.TreadDepthEnforce * (obj.NumberOfSteps-2) # TODO any use ?
            else:
                reslength = obj.TreadDepthEnforce * (obj.NumberOfSteps-1) # TODO any use ?
            vLength = DraftVecUtils.scaleTo(v,float(obj.TreadDepthEnforce))
        vLength = Vector(vLength.x,vLength.y,0)

        vWidth = DraftVecUtils.scaleTo(vLength.cross(Vector(0,0,1)),obj.Width.Value)
        p1 = edge.Vertexes[0].Point

        if obj.RiserHeightEnforce == 0:
            if round(v.z,Draft.precision()) != 0:
                h = v.z
            else:
                h = obj.Height.Value
            hstep = h/obj.NumberOfSteps

        else:
            h = obj.RiserHeightEnforce.Value * (obj.NumberOfSteps) 
            hstep = obj.RiserHeightEnforce.Value

        if obj.Landings == "At center":
            landing = int(obj.NumberOfSteps/2)
        else:
            landing = obj.NumberOfSteps

        if obj.LastSegment:
            lastSegmentAbsTop = obj.LastSegment.AbsTop
            p1 = Vector(p1.x, p1.y,lastSegmentAbsTop.z)			# use Last Segment top's z-coordinate 

        obj.AbsTop = p1.add(Vector(0,0,h))
        p2 = p1.add(DraftVecUtils.scale(vLength,landing-1).add(Vector(0,0,landing*hstep)))

        if obj.Landings == "At center":
            if obj.LandingDepth:
                p3 = p2.add(DraftVecUtils.scaleTo(vLength,obj.LandingDepth.Value))
            else:
                p3 = p2.add(DraftVecUtils.scaleTo(vLength,obj.Width.Value))
   
            if obj.Flight in ["HalfTurnLeft HalfTurnLeft", "HalfTurnRight"]:
                if (obj.Align == "Left" and obj.Flight == "HalfTurnLeft") or (obj.Align == "Right" and obj.Flight == "HalfTurnRight"):
                    p3r = p2
                elif (obj.Align == "Left" and obj.Flight == "HalfTurnRight"):
                    p3r = self.align(p2,"Right",-2*vWidth) # -ve / opposite direction of "Right" - no "Left" in _Stairs.Align()
                elif (obj.Align == "Right" and obj.Flight == "HalfTurnLeft"):
                    p3r = self.align(p2,"Right",2*vWidth)
                elif (obj.Align == "Center" and obj.Flight == "HalfTurnLeft"):
                    p3r = self.align(p2,"Right",vWidth)
                elif (obj.Align == "Center" and obj.Flight == "HalfTurnRight"):
                    p3r = self.align(p2,"Right",-vWidth) # -ve / opposite direction of "Right" - no "Left" in _Stairs.Align()
                else:
                    print("Should have a bug here, if see this")
                p4r = p3r.add(DraftVecUtils.scale(-vLength,obj.NumberOfSteps-(landing+1)).add(Vector(0,0,(obj.NumberOfSteps-landing)*hstep)))
            else:
                p4 = p3.add(DraftVecUtils.scale(vLength,obj.NumberOfSteps-(landing+1)).add(Vector(0,0,(obj.NumberOfSteps-landing)*hstep)))
            self.makeStraightLanding(obj,Part.LineSegment(p2,p3).toShape(), None, True)

            if obj.Flight in ["HalfTurnLeft", "HalfTurnRight"]:
                self.makeStraightStairs(obj,Part.LineSegment(p3r,p4r).toShape(),obj.NumberOfSteps-landing)
            else:
                self.makeStraightStairs(obj,Part.LineSegment(p3,p4).toShape(),obj.NumberOfSteps-landing)

        self.makeStraightStairs(obj,Part.LineSegment(p1,p2).toShape(),landing)
        print (p1, p2)
        if obj.Landings == "At center" and obj.Flight not in ["HalfTurnLeft", "HalfTurnRight"]:
            print (p3, p4)
        elif obj.Landings == "At center" and obj.Flight in ["HalfTurnLeft", "HalfTurnRight"]:
            print (p3r, p4r)
    def __init__(self,
                 d_endstop,
                 rail_l = 15,
                 base_h = 5.,
                 h = 0,
                 holder_out = 2.,
                 #csunk = 1,
                 mbolt_d = 3.,
                 endstop_nut_dist = 0,
                 min_d = 0,
                 axis_d = VX,
                 axis_w = V0,
                 axis_h = VZ,
                 pos_d = 1,
                 pos_w = 1,
                 pos_h = 1,
                 pos = V0,
                 wfco = 1,
                 name = 'simple_enstop_holder'):

        self.pos = FreeCAD.Vector(0,0,0)
        self.position = pos

        self.wfco = wfco
        self.name = name
        self.base_h = base_h,

        # normalize the axis
        axis_h = DraftVecUtils.scaleTo(axis_h,1)
        axis_d = DraftVecUtils.scaleTo(axis_d,1)
        if axis_w == V0:
            axis_w = axis_h.cross(axis_d)
        else:
            axis_w = DraftVecUtils.scaleTo(axis_w,1)
        axis_h_n = axis_h.negative()
        axis_d_n = axis_d.negative()
        axis_w_n = axis_w.negative()    

        self.axis_h = axis_h
        self.axis_d = axis_d
        self.axis_w = axis_w

        self.d0_cen = 0
        self.w0_cen = 1 # centered
        self.h0_cen = 0

        self.pos_d = pos_d
        self.pos_w = pos_w
        self.pos_h = pos_h

        self.pos = pos

        Obj3D.__init__(self, axis_d, axis_w, axis_h, name)

        # best axis to print, to be pointing up:
        self.axis_print = axis_h

        self.d_endstop = d_endstop

        #                              :holder_out
        #      __:________:____________: :..................
        #     |   _________      |     |                   :
        #     |  (_________) ----| 0   |                   + tot_w
        #     |   _________  ----|     |-----> axis_d      :
        #     |  (_________) ----| 0   |                   :
        #     |__________________|_____|...................:
        #     :  :         : :   : :     :
        #     :  :..rail_l.: :   : :     :
        #     :  :         : :   :.:     :
        #     :bolthead_d  : :   : +estp_bolt_dist
        #                  : :   :       :
        #          bolthead_r:   :.......:
        #                    :      +estp_d
        #                    :           :
        #                    :.estp_tot_d:
        #     :...................._..:  :
        #         tot_d

        #      The width depend which side is larger
        #
        #                     ...... ______________________ ....
        #        mbolt_head_r ......|   ________     |     |    :
        #        mbolt_head_d ......|  (________) ---| 0   |    :
        #mbolt_head_d or more ......|   ________  ---|     |    + estp_w or more
        #        mbolt_head_d ......|  (________) ---| 0   |    :
        #        mbolt_head_r ......|________________|_____|....:


        #   it can have a second hole:
        #                             :  :estop_topbolt_dist
        #                                : holder_out
        #      __:________:______________: :..................
        #     |   _________      |       |                   :
        #     |  (_________) ----| 0  0  |                   + tot_w
        #     |   _________  ----|       |-----> axis_d      :
        #     |  (_________) ----| 0  0  |                   :
        #     |__________________|_______|...................:
        #     :  :     

        # mounting bolt data
        d_mbolt = kcomp.D912[int(mbolt_d)]  #dictionary of the mounting bolt
        #print(str(d_mbolt))
        mbolt_r_tol = d_mbolt['shank_r_tol']
        mbolt_head_r = d_mbolt['head_r']
        mbolt_head_r_tol = d_mbolt['head_r_tol']
        mbolt_head_l = d_mbolt['head_l']
        print (str(mbolt_head_l))
        # endstop data. change h->d, d->h, l->w
        estp_tot_d = d_endstop['HT']
        estp_d = d_endstop['H']
        estp_bolt_dist = d_endstop['BOLT_H']
        estp_bolt_sep = d_endstop['BOLT_SEP']
        estp_bolt_d = d_endstop['BOLT_D']  #diameter, not depth
        estp_w = d_endstop['L']

        # if there is a second bolt 
        if 'BOLT_TOP_H' in d_endstop:
           estop_2ndbolt_topdist = d_endstop['BOLT_TOP_H']
        else:
           estop_2ndbolt_topdist = 0

        # length of the pins:
        estp_pin_d  = estp_tot_d - estp_d
        if min_d == 0:
            tot_d = 3*mbolt_head_r + rail_l + estp_tot_d - holder_out
            # nut axis: (nut axis of the hexagon vertex
            hex_verx = axis_d
        else:
            # Taking the minimum lenght, very tight
            tot_d = (3*mbolt_head_r + rail_l + estp_d - holder_out
                     + estp_pin_d/2.)
            hex_verx = axis_w # less space

        # Total width is the largest value from:
        # - the width(length) of the endstop
        # - the rail width: 2 bolt head diameters, and 2 more: 1 diameter 
        #   between, and a radius to the end
        tot_w = max(estp_w, 8 * mbolt_head_r)
 
        if h== 0:
            tot_h = base_h + mbolt_head_l
        else:
            tot_h = base_h + mbolt_head_l
            if tot_h > h:
                logger.debug('h is smaller that it should, taking: ')
                logger.debug(str(tot_h))
            else:
                tot_h = h

        self.tot_h = tot_h
        self.tot_w = tot_w
        self.tot_d = tot_d

        if endstop_nut_dist == 0:
            endstop_nut_l =  kcomp.NUT_D934_L[estp_bolt_d]+TOL
        else:
            if endstop_nut_dist > tot_h -  kcomp.NUT_D934_L[estp_bolt_d]+TOL:
                logger.debug('endstop_nut_dist: ' + str(endstop_nut_dist)
                             + ' larger than total height - (nut length+tol): '
                             + str(tot_h) + ' - '
                             + str( kcomp.NUT_D934_L[estp_bolt_d] + TOL))
                endstop_nut_l =  kcomp.NUT_D934_L[estp_bolt_d]+TOL
            else:
                endstop_nut_l = tot_h - endstop_nut_dist
            
        # ------------ DISTANCES ON AXIS_D
        # ref_d points:          fc_axis_h
                               
        #  1___2______3_______4__.5.............     ref_h = 2
        #  | :..........:    : : |:.....       + h
        #  |__:________:_____:_:_|:.....base_h.:     ref_h = 1

        # the end it is not on the holder because of -holder_out
        # distance from 1 to 2 in axis_d
        
        # vectors from the origin to the points along axis_d:
        self.d_o[0] = V0
        self.d_o[1] = self.vec_d(2* mbolt_head_r)
        self.d_o[2] = self.vec_d(2* mbolt_head_r + rail_l)
        self.d_o[3] = self.vec_d((tot_d + holder_out) - (estp_d - estp_bolt_dist))
        self.d_o[4] = self.vec_d(tot_d + holder_out)
        if estop_2ndbolt_topdist > 0 :
            self.d_o[5] = self.vec_d(tot_d + holder_out - estop_2ndbolt_topdist)
        else:
            self.d_o[5] = self.d_o[3]

        # vectors from the origin to the points along axis_w:
        self.w_o[0] = V0
        self.w_o[1] = self.vec_w(estp_bolt_sep/2.)
        self.w_o[2] = self.vec_w(tot_w/2. - 2* mbolt_head_r)
        self.w_o[3] = self.vec_w(tot_w/2.)

        # vectors from the origin to the points along axis_h:
        self.h_o[0] = V0
        self.h_o[1] = self.vec_h(tot_h)

        # calculates the position of the origin, and keeps it in attribute pos_o
        self.set_pos_o()

        # TODO: clear this parts when points d_o, w_o, h_o
        dis_1_2_d = 2* mbolt_head_r # d_o[1]
        dis_1_3_d = dis_1_2_d + rail_l # d_o[2]
        #dis_2_3_d = rail_l
        dis_1_5_d = tot_d + holder_out # d_o[4]
        dis_1_4_d = dis_1_5_d - (estp_d - estp_bolt_dist) # d_o[3]
        # distances to the new point, that is the second bolt hole, if exists
        if estop_2ndbolt_topdist > 0 :
            dis_1_6_d = dis_1_5_d - estop_2ndbolt_topdist
        else:
            # same as 4: (to avoid errors) it will be the same hole
            dis_1_6_d = dis_1_4_d

        fc_1_2_d = self.d_o[1]
        fc_1_3_d = self.d_o[2]
        fc_1_4_d = self.d_o[3]
        fc_1_5_d = self.d_o[4]
        fc_1_6_d = self.d_o[5]
        # vector from the reference point to point 1 on axis_d
        if pos_d == 0: 
            refto_1_d = V0
        elif pos_d == 1:
            refto_1_d = fc_1_2_d.negative()
        elif pos_d == 2:
            refto_1_d = fc_1_3_d.negative()
        elif pos_d == 3:
            refto_1_d = fc_1_4_d.negative()
        elif pos_d == 4:
            refto_1_d = fc_1_5_d.negative()
        elif pos_d == 5:
            refto_1_d = fc_1_6_d.negative()
        else:
            logger.error('wrong reference point')

        # ------------ DISTANCES ON AXIS_W
        # ref_w points
        #                      fc_axis_w
        #  _____________________ :
        # |   ________     |    |:
        # |  (________) ---| 0  |:
        # 1   ________  ---|    |:-----> fc_axis_d.
        # 3  (________) ---| 2  |:
        # 4________________|____|:

        # distance from 1 to 2 on axis_w
        dis_1_2_w = estp_bolt_sep/2.
        dis_1_4_w = tot_w/2.
        dis_1_3_w = dis_1_4_w - 2* mbolt_head_r

        fc_1_2_w = self.w_o[1]
        fc_1_3_w = self.w_o[2]
        fc_1_4_w = self.w_o[3]
        # vector from the reference point to point 1 on axis_w
        if pos_w == 0: 
            refto_1_w = V0
        elif pos_w == 1:
            refto_1_w = fc_1_2_w.negative()
        elif pos_w == 2:
            refto_1_w = fc_1_3_w.negative()
        elif pos_w == 3:
            refto_1_w = fc_1_4_w.negative()
        else:
            logger.error('wrong reference point')

        # ------------ DISTANCES ON AXIS_H
        fc_1_2_h = DraftVecUtils.scale(axis_h, tot_h)
        fc_2_1_h = fc_1_2_h.negative()
        if pos_h == 0: 
            refto_2_h = self.h_o[1]
        elif pos_h == 1:
            refto_2_h = V0
        else:
            logger.error('wrong reference point')


        # Situation of the point on d=1, s=1, h=2
        #       ____________
        #      /
        #     * d1_w1_h2
        #    /____________
        #    |
        #
        # this is an absolute position
        # super().get_pos_dwh(pos_d,pos_w,pos_h)
        d1_w1_h2_pos = self.pos + refto_1_d + refto_1_w + refto_2_h
        d1_w1_h1_pos = d1_w1_h2_pos + fc_2_1_h


        # draw the box from this point d1 s1 h2
        shp_box = fcfun.shp_box_dir(box_w = tot_w,
                                    box_d = tot_d,
                                    box_h = tot_h,
                                    fc_axis_h = axis_h_n,
                                    fc_axis_d = axis_d,
                                    cw = 1, cd = 0, ch = 0,
                                    pos = d1_w1_h2_pos)

        shp_box = fcfun.shp_filletchamfer_dir(shp_box, fc_axis = axis_h,
                                              fillet=1,
                                              radius = 2)

        holes = []
        # holes for the endstop bolts, point: d4 w2 h1
        for fc_1_2_wi in [fc_1_2_w, fc_1_2_w.negative()]:
            pos_estpbolt = d1_w1_h1_pos + fc_1_4_d + fc_1_2_wi
            # hole with the nut hole
            shp_estpbolt = fcfun.shp_bolt_dir (
                             r_shank= (estp_bolt_d+TOL)/2.,
                             l_bolt = tot_h,
                           # 1 TOL didnt fit
                           r_head = (kcomp.NUT_D934_D[estp_bolt_d]+2*TOL)/2.,
                             l_head = endstop_nut_l,
                             hex_head = 1,
                             xtr_head = 1, xtr_shank = 1,
                             fc_normal = axis_h,
                             fc_verx1 = hex_verx,
                             pos = pos_estpbolt)
            holes.append(shp_estpbolt)
            # it can have a second hole
            if estop_2ndbolt_topdist >0:
                pos_estp_top_bolt =  d1_w1_h1_pos + fc_1_6_d + fc_1_2_wi
                # hole with the nut hole
                shp_estpbolt = fcfun.shp_bolt_dir (
                             r_shank= (estp_bolt_d+TOL)/2.,
                             l_bolt = tot_h,
                           # 1 TOL didnt fit
                           r_head = (kcomp.NUT_D934_D[estp_bolt_d]+2*TOL)/2.,
                             l_head = endstop_nut_l,
                             hex_head = 1,
                             xtr_head = 1, xtr_shank = 1,
                             fc_normal = axis_h,
                             fc_verx1 = hex_verx,
                             pos = pos_estp_top_bolt)
                holes.append(shp_estpbolt)



        # holes for the rails, point d2 w3 h2
        for fc_1_3_wi in [fc_1_3_w, fc_1_3_w.negative()]:
            #hole for the rails, use the function stadium
            rail_pos = d1_w1_h2_pos + fc_1_2_d + fc_1_3_wi
            shp_rail_sunk = fcfun.shp_stadium_dir (
                                  length = rail_l,
                                  radius = mbolt_head_r_tol,
                                  height = mbolt_head_l,
                                  fc_axis_l = axis_d,
                                  fc_axis_h = axis_h_n,
                                  ref_l = 2, #at the center of semicircle
                                  ref_s = 1, # symmetrical on the short side
                                  ref_h = 2,
                                  xtr_h = 0,
                                  xtr_nh = 1,
                                  pos = rail_pos)
            shp_rail = fcfun.shp_stadium_dir (
                                  length = rail_l,
                                  radius = mbolt_r_tol,
                                  height = tot_h,
                                  fc_axis_l = axis_d,
                                  fc_axis_h = axis_h_n,
                                  ref_l = 2,
                                  ref_s = 1,
                                  ref_h = 2,
                                  xtr_h = 1,
                                  xtr_nh = 0,
                                  pos = rail_pos)

                                  
                                  
            holes.append(shp_rail)
            holes.append(shp_rail_sunk)

        shp_holes = fcfun.fuseshplist(holes)
        shp_holder = shp_box.cut(shp_holes)
           
        self.shp = shp_holder

        if wfco == 1:
            super().create_fco()
            # Need to set first in (0,0,0) and after that set the real placement.
            # This enable to do rotations without any issue
            self.fco.Placement.Base = FreeCAD.Vector(0,0,0) 
            self.fco.Placement.Base = self.position
Example #24
0
import shp_clss # import my TopoShapes classes 
import fc_clss # import my freecad classes 
import comps   # import my CAD components
import partset 

from fcfun import V0, VX, VY, VZ, V0ROT
from fcfun import VXN, VYN, VZN

logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)




axis_punta = VZ
axis_punta_n = DraftVecUtils.scale(axis_punta,-1)
axis_brida = VX
axis_lateral = VY
axis_lateral_n = DraftVecUtils.scale(axis_lateral,-1)
brida_r_out = 20.
brida_r_bolt2cen = 31.5/2.
brida_d_bolt = 5+0.5
brida_h = 6.

union_l = []
cut_l = []

# brida
shp_brida = fcfun.shp_cylhole_bolthole (r_out = brida_r_out , r_in = 0,
                     h=brida_h,
                     n_bolt = 4, d_bolt = brida_d_bolt,
Example #25
0
    def __init__(self,
                 fc_fro_ax,
                 fc_top_ax,
                 base_h = 2,
                 base_l = 0,
                 base_w = 0,
                 bolt_d = 3,
                 bolt_csunk = 0,
                 ref = 1,
                 pos = V0,
                 extra=1,
                 wfco = 1,
                 intol = 0,
                 name = 'belt_clamp' ):

        doc = FreeCAD.ActiveDocument
        self.name = name

        # if more tolerance is needed in the center
        cb_in_w = CB_IW + intol
        self.cb_in_w = cb_in_w
        cb_wall_w = CB_W - intol/2
        self.cb_wall_w = cb_wall_w

        # normalize and get the other base vector
        nfro_ax = DraftVecUtils.scaleTo(fc_fro_ax,1)
        nfro_ax_n = nfro_ax.negative()
        ntop_ax = DraftVecUtils.scaleTo(fc_top_ax,1)
        ntop_ax_n = ntop_ax.negative()
        nsid_ax = nfro_ax.cross(ntop_ax)

        clamponly_l = CB_L + CS + 2 * CCYL_R
        clamponly_w = max((cb_in_w+2*cb_wall_w), (2*CCYL_R))

        bolt2end = 0 # they will change in case they are used
        clamp2end = 0
        if base_h == 0 and bolt_d == 0:
            # No base
            base = 0
            base_l = 0
        else:
            base = 1
            if bolt_d > 0 :
                d_bolt = kcomp.D912[bolt_d]
                bolt_shank_r = d_bolt['shank_r_tol']
                bolt_head_r = d_bolt['head_r_tol']
                bolt_head_l = d_bolt['head_l']
                # there are bolt holes, calculate the extra length needed
                # from the end to the clamp / cylinder
                bolt2end = fcfun.get_bolt_end_sep(bolt_d,hasnut=0)
                # bolt space on one side
                clamp2end = 2 * bolt2end
                base_min_len = clamponly_l + 2 * clamp2end
                if base_l < base_min_len:
                    logger.debug("base_l too short, taking min len %s",
                                  base_min_len)
                    base_l = base_min_len
                else:
                    clamp2end = (base_l - clamponly_l) /2.
                    bolt2end = clamp2end / 2.
                if bolt_csunk > 0:
                    # there are countersunk holes for the bolts
                    if base_h == 0:
                        # minimum height:
                        base_h = bolt_csunk + bolt_head_l
                    else:
                        # check if there is enough base height
                        if base_h < bolt_csunk + bolt_head_l:
                            base_h = bolt_csunk + bolt_head_l
                            logger.debug("base_h too short,taking height %s",
                                  base_h)
                else:
                    if base_h < self.MIN_BASE_H:
                        base_h = self.MIN_BASE_H
                        logger.debug("taking base height %s",
                                  base_h)
            else: # No bolt
                bolt2end = 0
                if base_l < clamponly_l:
                    if base_l > 0:
                        logger.debug("base_l too short, Taking min len %s",
                                      clamponly_l) 
                    base_l = clamponly_l
                    clamp2end = 0
                else: #base larger than clamp
                    clamp2end = (base_l - clamponly_l) /2.
            if base_w == 0:
                base_w = clamponly_w
            elif base_w < clamponly_w:
                logger.debug("base_w too short, Taking min width %s",
                              clamponly_w)
                base_w = clamponly_w

        ###
        cencyl2froclamp = CB_L+CS+CCYL_R
        #vectors to references:
        # from the center of the cylinder to the front clamp
        vec_1to2 = DraftVecUtils.scale(nfro_ax,cencyl2froclamp)
        vec_2to1 = vec_1to2.negative()
        # from the front clamp to the front bolt
        vec_2to3 = DraftVecUtils.scale(nfro_ax, bolt2end)
        vec_3to2 = vec_2to3.negative()
        # Since not always there is a bolt, from the clamp
        vec_2to4 = DraftVecUtils.scale(nfro_ax, clamp2end)
        vec_4to2 = vec_2to4.negative()
        # from the center of the cylinder to the back bolt
        vec_5to1 = DraftVecUtils.scale(nfro_ax,CCYL_R) + vec_2to3
        vec_1to5 = vec_5to1.negative()
        # from the back bolt to the back end
        vec_6to1 = DraftVecUtils.scale(nfro_ax,CCYL_R) + vec_2to4
        vec_1to6 = vec_6to1.negative()

        # default values
        vec_tocencyl = V0
        vec_tofrontclamp = V0
        vec_tofrontbolt = V0
        vec_tofrontbase = V0
        vec_tobackbolt = V0
        vec_tobackbase = V0
        if ref==1: #ref on the center of the cylinder
            vec_tocencyl = V0
            vec_tofrontclamp = vec_1to2 
            vec_tofrontbolt = vec_1to2 + vec_2to3
            vec_tofrontbase = vec_1to2 + vec_2to4
            vec_tobackbolt = vec_1to5
            vec_tobackbase = vec_1to6
        elif ref==2: #ref on the front of the clamps
            vec_tocencyl = vec_2to1
            vec_tofrontclamp = V0
            vec_tofrontbolt = vec_2to3
            vec_tofrontbase = vec_2to4
            vec_tobackbolt = ve_2to1 + vec_1to5
            vec_tobackbase = ve_2to1 + vec_1to6
        elif ref == 3:
            if clamp2end == 0 or bolt2end == 0:
                logger.error('reference on the bolts, there are no bolts')
            else:
                vec_tocencyl = vec_3to2 + vec_2to1
                vec_tofrontclamp = vec_3to2
                vec_tofrontbolt = V0
                vec_tofrontbase = vec_2to3 #same as 3 to 4
                vec_tobackbolt = vec_3to2 + vec_2to1 + vec_1to5
                vec_tobackbase = vec_3to2 + vec_2to1 + vec_1to6
        elif ref == 4:
            if clamp2end == 0:
                logger.debug('reference at the end, same as the clamps')
            vec_tocencyl = vec_4to2 + vec_2to1
            vec_tofrontclamp = vec_4to2
            vec_tofrontbolt = vec_3to2 # same as 4 to 3
            vec_tofrontbase = V0
            vec_tobackbolt = vec_4to2 + vec_2to1 + vec_1to5
            vec_tobackbase = vec_4to2 + vec_2to1 + vec_1to6
        elif ref == 5:
            if clamp2end == 0 or bolt2end == 0:
                logger.error('reference on the bolts, there are no bolts')
            else:
                vec_tocencyl = vec_5to1
                vec_tofrontclamp = vec_5to1 + vec_1to2
                vec_tofrontbolt = vec_5to1 + vec_1to2 + vec_2to3
                vec_tofrontbase = vec_5to1 + vec_1to2 + vec_2to4
                vec_tobackbolt = V0
                vec_tobackbase = vec_3to2 #5to6: same as 3to2
        elif ref == 6:
            if clamp2end == 0:
                logger.debug('reference at the end, same as the clamps')
            vec_tocencyl = vec_6to1
            vec_tofrontclamp = vec_6to1 + vec_1to2
            vec_tofrontbolt = vec_6to1 + vec_1to2 + vec_2to3
            vec_tofrontbase = vec_6to1 + vec_1to2 + vec_2to4
            vec_tobackbolt = vec_2to3 # same as 6 to 5
            vec_tobackbase = V0
        else:
            logger.error('reference out of range')
          


        if extra == 0:
            extra_pos = V0
        else:
            extra_pos = DraftVecUtils.scale(ntop_ax, -extra)
        pos_extra = pos + extra_pos
        base_top_add = DraftVecUtils.scale(ntop_ax, base_h + extra)
        
        
        # total height of the clamp, including the base
        clamp_tot_h = C_H + base_h + extra
        # position of the clamp cylinder:
        clampcyl_pos = pos_extra + vec_tocencyl
        shp_cyl = fcfun.shp_cyl(CCYL_R, clamp_tot_h, ntop_ax, clampcyl_pos)
        # position of the clamp blocks, without going to the side axis
        clampblock_pos = pos_extra + vec_tofrontclamp
        clampblock_side_add = DraftVecUtils.scale(nsid_ax, 
                                                  (cb_in_w + cb_wall_w)/2.)
        clampblock_1_pos = clampblock_pos + clampblock_side_add
        clampblock_2_pos = clampblock_pos - clampblock_side_add
        shp_clampblock_1 = fcfun.shp_box_dir(box_w = cb_wall_w,
                                             box_d = CB_L,
                                             box_h = clamp_tot_h,
                                             fc_axis_h = ntop_ax,
                                             fc_axis_d = nfro_ax_n,
                                             cw=1, cd=0, ch=0,
                                             pos = clampblock_1_pos)
        shp_clampblock_2 = fcfun.shp_box_dir(box_w = cb_wall_w,
                                             box_d = CB_L,
                                             box_h = clamp_tot_h,
                                             fc_axis_h = ntop_ax,
                                             fc_axis_d = nfro_ax_n,
                                             cw=1, cd=0, ch=0,
                                             pos = clampblock_2_pos)

        shp_clamp = shp_cyl.multiFuse([shp_clampblock_1, shp_clampblock_2])


        #position of the base, we will take it on the point 4 and make it not 
        # centered
        if base == 1:
            base_pos = pos_extra + vec_tofrontbase 
            shp_base = fcfun.shp_box_dir(box_w = base_w,
                                         box_d = base_l,
                                         box_h = base_h + extra,
                                         fc_axis_h = ntop_ax,
                                         fc_axis_d = nfro_ax_n,
                                         cw=1, cd=0, ch=0,
                                         pos = base_pos)
            if base_l > clamponly_l: # chamfer
                shp_base = fcfun.shp_filletchamfer_dir (shp_base,
                                              fc_axis=ntop_ax,
                                              fillet=1, radius= 2)

            # shape of the bolt holes, if there are
            if bolt_d > 0:
                pos_bolt_front = pos_extra + vec_tofrontbolt + base_top_add
                pos_bolt_back = pos_extra + vec_tobackbolt + base_top_add
                if bolt_csunk > 0 :
                    shp_bolt_front = fcfun.shp_bolt_dir(
                                              r_shank = bolt_shank_r,
                                              l_bolt = base_h + extra,
                                              r_head = bolt_head_r,
                                              l_head = bolt_head_l,
                                              support=0,
                                              fc_normal = ntop_ax_n,
                                              pos=pos_bolt_front)
                    shp_bolt_back = fcfun.shp_bolt_dir(
                                              r_shank = bolt_shank_r,
                                              l_bolt = base_h + extra,
                                              r_head = bolt_head_r,
                                              l_head = bolt_head_l,
                                              support=0,
                                              fc_normal = ntop_ax_n,
                                              pos=pos_bolt_back)
                else: # no head, just a cylinder:
                    shp_bolt_front = fcfun.shp_cylcenxtr (
                                              r = bolt_shank_r,
                                              h = base_h + extra,
                                              normal = ntop_ax_n,
                                              ch = 0,
                                              xtr_top=1, xtr_bot=1,
                                              pos = pos_bolt_front)
                    shp_bolt_back = fcfun.shp_cylcenxtr (
                                              r = bolt_shank_r,
                                              h = base_h + extra,
                                              normal = ntop_ax_n,
                                              ch = 0,
                                              xtr_top=1, xtr_bot=1,
                                              pos = pos_bolt_back)


                # fuse the bolts:
                shp_bolts = shp_bolt_front.fuse(shp_bolt_back)
                shp_base = shp_base.cut(shp_bolts)
            shp_clamp = shp_base.fuse(shp_clamp)

              
 

        doc.recompute()
        shp_clamp = shp_clamp.removeSplitter()
        self.shp = shp_clamp

        self.wfco = wfco
        if wfco == 1:
            # a freeCAD object is created
            fco_clamp = doc.addObject("Part::Feature", name )
            fco_clamp.Shape = shp_clamp
            self.fco = fco_clamp
Example #26
0
    def makeStraightStairsWithLanding(self, obj, edge):

        "builds a straight staircase with a landing in the middle"

        if obj.NumberOfSteps < 3:
            return
        import Part, DraftGeomUtils
        v = DraftGeomUtils.vec(edge)
        if obj.LandingDepth:
            reslength = edge.Length - obj.LandingDepth.Value
        else:
            reslength = edge.Length - obj.Width.Value
        vLength = DraftVecUtils.scaleTo(
            v,
            float(reslength) / (obj.NumberOfSteps - 2))
        vLength = Vector(vLength.x, vLength.y, 0)
        vWidth = DraftVecUtils.scaleTo(vLength.cross(Vector(0, 0, 1)),
                                       obj.Width.Value)
        p1 = edge.Vertexes[0].Point
        if round(v.z, Draft.precision()) != 0:
            h = v.z
        else:
            h = obj.Height.Value
        hstep = h / obj.NumberOfSteps
        landing = int(obj.NumberOfSteps / 2)

        if obj.LastSegment:
            print("obj.LastSegment is: ")
            print(obj.LastSegment.Name)
            lastSegmentAbsTop = obj.LastSegment.AbsTop
            print("lastSegmentAbsTop is: ")
            print(lastSegmentAbsTop)
            p1 = Vector(
                p1.x, p1.y,
                lastSegmentAbsTop.z)  # use Last Segment top's z-coordinate
            print(p1)
        obj.AbsTop = p1.add(Vector(0, 0, h))

        p2 = p1.add(
            DraftVecUtils.scale(vLength,
                                landing - 1).add(Vector(0, 0,
                                                        landing * hstep)))
        if obj.LandingDepth:
            p3 = p2.add(DraftVecUtils.scaleTo(vLength, obj.LandingDepth.Value))
        else:
            p3 = p2.add(DraftVecUtils.scaleTo(vLength, obj.Width.Value))
        if obj.Flight == "HalfTurnLeft":
            p3r = p2
            p4r = p2.add(
                DraftVecUtils.scale(
                    -vLength, obj.NumberOfSteps - (landing + 1)).add(
                        Vector(0, 0, (obj.NumberOfSteps - landing) * hstep)))
        else:
            p4 = p3.add(
                DraftVecUtils.scale(
                    vLength, obj.NumberOfSteps - (landing + 1)).add(
                        Vector(0, 0, (obj.NumberOfSteps - landing) * hstep)))
        self.makeStraightStairs(obj,
                                Part.LineSegment(p1, p2).toShape(), landing)

        self.makeStraightLanding(obj,
                                 Part.LineSegment(p2, p3).toShape(), None,
                                 True)

        if obj.Flight == "HalfTurnLeft":
            self.makeStraightStairs(obj,
                                    Part.LineSegment(p3r, p4r).toShape(),
                                    obj.NumberOfSteps - landing)
        else:
            self.makeStraightStairs(obj,
                                    Part.LineSegment(p3, p4).toShape(),
                                    obj.NumberOfSteps - landing)