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
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)
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
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)
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
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 __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()
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 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 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.
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)
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
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,
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
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)