# ----------------------------------------------------------------------------
# -- Belt Clamp Tensioner
# -- comps library
# -- Python classes and functions to make belt tensioner in FreeCAD
# ----------------------------------------------------------------------------
# -- (c) Felipe Machado
# -- Area of Electronics. Rey Juan Carlos University (urjc.es)
# -- October-2016
# ----------------------------------------------------------------------------
# --- LGPL Licence
# ----------------------------------------------------------------------------
import FreeCAD
import Part
import Draft
import DraftVecUtils
import logging
import inspect
import Mesh
import MeshPart
import os
# can be taken away after debugging
# directory this file is
filepath = os.getcwd()
import sys
# to get the components
# In FreeCAD can be added: Preferences->General->Macro->Macro path
sys.path.append(filepath)
import kcomp # import material constants and other constants
import fcfun # import my functions for freecad
import kparts
import shp_clss
import fc_clss
from fcfun import V0, VX, VY, VZ, V0ROT, addBox, addCyl
from kcomp import TOL
stl_dir = "/stl/"
logger = logging.getLogger(__name__)
# Belt dimensions:
# space for the 2 belts to clamp them
# the GT2 belt is 1.38mm width. 2 together facing teeth will be about 2mm
# I make it 2.8mm
# Internal Width of the Clamp Block
CB_IW = 2.8
# Width of the exterior clamp blocks (Y axis)
CB_W = 4.0
# Length of the clamp blocks (X axis)
CB_L = 12.0
# GT2 height is 6 mm, making the heigth 8mm
C_H = 8.0
# GT2 Clamp Cylinder radius
CCYL_R = 4.0
# separation between the clamp blocks and the clamp cylinder
CS = 3.0
# separation of the nut hole from the edge
NUT_HOLE_EDGSEP = 3
# --------------------------- belt clamp and tensioner
# radius of the cylinder
#""
# TOPVIEW
# CLAMPBLOCK
# CB
# ____
# CB_W { XXXX ___
# CB_IW { ____ / \
# 0,1 or 2: CB_MW { XXXX | | CCYL: CLAMPCYL
# CB_IW { ____ \___/
# CB_W { XXXX
#
# CB_L CS
#
#
# Y A (width)
# |
# |---> X (length)
#
#
# Arguments:
# midblock: 0 or 1. It will add a none/single width middle block
# In the future I may consider a double middle block (2)
# base_h: height of the base
# Attributes:
# fco : the FreeCAD Object of the belt clamp
# fco_cont : the FreeCAD object of the belt clamp offset. To make a cut
# on the FreeCAD object where the belt tensioner will be.
class Gt2BeltClamp (object):
# space for the 2 belts to clamp them
# the GT2 belt is 1.38mm width. 2 together facing teeth will be about 2mm
# I make it 2.8mm
# Internal Width of the Clamp Block
CB_IW = 2.8
# Width of the exterior clamp blocks (Y axis)
CB_W = 4.0
# Length of the clamp blocks (X axis)
CB_L = 12.0
# GT2 height is 6 mm, making the heigth 8mm
C_H = 8.0
# GT2 Clamp Cylinder radius
CCYL_R = 4.0
# separation between the clamp blocks and the clamp cylinder
CS = 3.0
# separation of the nut hole from the edge
NUT_HOLE_EDGSEP = 3
"""
how much the rail is inside
________________________________________________
|
| __________________________
\ ____ CBASERAILIND
|
/ _____ CBASE_RAIL ___
|
|_________________________ CBASE_WALL _________ CBASE_H
|-|
CBASERAILIND_SIG (it is 45 degrees). SIG: can be + or -
if midblock > 0 this will be the indentation,
if midblock == 0 it will be outward, like this:
_________
| |
/ \
| |
\ /
|_________|
"""
CBASE_L = CB_L + CS + 2*CCYL_R
def __init__(self, base_h, midblock, name):
doc = FreeCAD.ActiveDocument
self.base_place = (0,0,0)
# Clamp base
self.CBASE_H = base_h
# divides how much is rail and how much is wall
# It has to be greater than 1. If it is 1, there is no wall.
# if it is 2. Half is wall, half is indent
self.CBASE_RAIL_DIV = 1.6 #2.0
self.CBASE_RAIL = self.CBASE_H / self.CBASE_RAIL_DIV # rail for the base
# the part that is wall, divided by 2, because one goes at the bottom
# and the other on top
# rail for the base
self.CBASE_WALL = (self.CBASE_H - self.CBASE_RAIL)/2.0
# Indentation, if midblock == 0, the Indentation is negative, which
# means it will be outward, otherwise, inward
self.CBASERAILIND = self.CBASE_RAIL/3.0
self.midblock = midblock
# Width of the interior/middle clamp blocks
self.CB_MW = midblock * self.CB_W
if midblock == 0:
self.CBASE_W = self.CB_IW + 2 * self.CB_W
self.CBASERAILIND_SIG = - self.CBASERAILIND
# Since the indentation is outwards, we have to add it
self.TotW = self.CBASE_W + 2 * self.CBASERAILIND
# external indent, so all the internal elements have to have this
# nternal offset. In Y axis
self.extind = self.CBASERAILIND
else:
self.CBASE_W = 2 * self.CB_IW + 2 * self.CB_W + self.CB_MW
self.CBASERAILIND_SIG = self.CBASERAILIND
# Since the indentation is inward, it is just the base
self.TotW = self.CBASE_W
# no external indent, so the internal elements don't have to have
# this internal offset
self.extind = 0
gt2_clamp_list = []
# we make it using points-plane and extrusions
#gt2_base =addBox (self.CBASE_L, self.CBASE_W, self.CBASE_H, "gt2_base")
gt2_cb_1 = addBox (self.CB_L, self.CB_W, self.C_H+1, name + "_cb1")
gt2_cb_1.Placement.Base = FreeCAD.Vector (self.CBASE_L-self.CB_L,
self.extind,
self.CBASE_H-1)
gt2_clamp_list.append (gt2_cb_1)
if midblock > 0:
gt2_cb_2 = addBox (self.CB_L, self.CB_MW, self.C_H+1, name + "_cb2")
gt2_cb_2.Placement.Base = FreeCAD.Vector (self.CBASE_L-self.CB_L,
self.CB_W + self.CB_IW + self.extind,
self.CBASE_H-1)
gt2_clamp_list.append (gt2_cb_2)
gt2_cb_3 = addBox (self.CB_L, self.CB_W, self.C_H + 1, name + "_cb3")
gt2_cb_3.Placement.Base = FreeCAD.Vector (self.CBASE_L-self.CB_L,
self.CBASE_W - self.CB_W + self.extind,
self.CBASE_H-1)
gt2_clamp_list.append (gt2_cb_3)
gt2_cyl = fcfun.addCyl (self.CCYL_R, self.C_H + 1, name + "_cyl")
gt2_cyl.Placement.Base = FreeCAD.Vector (self.CCYL_R,
self.CBASE_W/2 + self.extind,
self.CBASE_H-1)
gt2_clamp_list.append (gt2_cyl)
# base
# calling to the method that gets a list of the points to make
# the polygon of the base
#gt2_base_list = self.get_base_list_v()
# doing this because the carriage is already printed, so I am going
# to make the base smaller to fit. CHANGE to the upper sentence
gt2_base_list = self.get_base_list_v(offs_y = -TOL/2, offs_z = - TOL)
"""
gt2_base_plane_yz = Part.makePolygon(gt2_base_list)
gt2_base = gt2_base_plane_xy.extrude(FreeCAD.Vector(self.CBASE_L,0,0))
"""
gt2_base_plane_yz = doc.addObject("Part::Polygon",
name + "base_plane_yz")
gt2_base_plane_yz.Nodes = gt2_base_list
gt2_base_plane_yz.Close = True
gt2_base = doc.addObject("Part::Extrusion",
name + "extr_base")
gt2_base.Base = gt2_base_plane_yz
gt2_base.Dir = (self.CBASE_L,0,0)
gt2_base.Solid = True
gt2_clamp_list.append(gt2_base)
gt2_clamp_basic = doc.addObject("Part::MultiFuse", name + "clamp_base")
gt2_clamp_basic.Shapes = gt2_clamp_list
# creation of the same base, but with a little offset to be able to
# cut the piece where it will be inserted
#gt2_baseof_list = self.get_base_list_v(offs_y = TOL, offs_z = TOL/2.0)
# CHANGE TO THE UPPER SENTENCE
gt2_baseof_list = self.get_base_list_v(offs_y = TOL, offs_z = 0)
gt2_baseof_plane_yz = doc.addObject("Part::Polygon",
name + "_baseof_plane_yz")
gt2_baseof_plane_yz.Nodes = gt2_baseof_list
gt2_baseof_plane_yz.Close = True
gt2_baseof = doc.addObject("Part::Extrusion",
name + "_baseof")
gt2_baseof.Base = gt2_baseof_plane_yz
gt2_baseof.Dir = (self.CBASE_L,0,0)
gt2_baseof.Solid = True
self.fco_cont = gt2_baseof
# hole for the leadscrew bolt
# the head is longer because it can be inserted deeper into the piece
# so a shorter bolt will be needed
gt2_base_lscrew = fcfun.addBolt (kcomp.M3_SHANK_R_TOL, self.CBASE_L,
kcomp.M3_HEAD_R_TOL, 2.5*kcomp.M3_HEAD_L,
extra = 1, support = 0,
name= name + "_base_lscrew")
gt2_base_lscrew.Placement.Base = FreeCAD.Vector (self.CBASE_L,
self.CBASE_W/2.0 + self.extind,
self.CBASE_H/2.0)
gt2_base_lscrew.Placement.Rotation = FreeCAD.Rotation (VY, -90)
# ------------ hole for a nut, also M3, for the leadscrew
gt2_base_lscrew_nut = doc.addObject("Part::Prism",
name + "_base_lscrew_nut")
gt2_base_lscrew_nut.Polygon = 6
gt2_base_lscrew_nut.Circumradius = kcomp.M3_NUT_R_TOL
gt2_base_lscrew_nut.Height = kcomp.M3NUT_HOLE_H
gt2_base_lscrew_nut.Placement.Rotation = \
gt2_base_lscrew.Placement.Rotation
# + TOL so it will be a little bit higher, so more room
gt2_base_lscrew_nut.Placement.Base = FreeCAD.Vector (
#(self.CBASE_L-kcomp.M3_HEAD_L)/2.0 - kcomp.M3NUT_HOLE_H/2.0,
self.NUT_HOLE_EDGSEP,
self.CBASE_W/2.0 + self.extind,
self.CBASE_H/2.0 + TOL)
gt2_base_lscrew_nut.Placement.Rotation = FreeCAD.Rotation (VY, 90)
# ------------ hole to reach out the nut hole
# X is the length: M3NUT_HOLE_H. Y is the width. M3_2APOT_TOL
gt2_base_lscrew_nut2 = addBox (kcomp.M3NUT_HOLE_H,
kcomp.M3_2APOT_TOL,
self.CBASE_H/2.0 + TOL,
name + "_base_lscrew_nut2")
gt2_base_lscrew_nut2.Placement.Base = (
#((self.CBASE_L-kcomp.M3_HEAD_L) - kcomp.M3NUT_HOLE_H)/2.0,
self.NUT_HOLE_EDGSEP,
(self.CBASE_W - kcomp.M3_2APOT_TOL)/2.0 + self.extind,
0)
gt2_base_holes_l = [ gt2_base_lscrew,
gt2_base_lscrew_nut,
gt2_base_lscrew_nut2]
# fuse the holes
gt2_clamp_holes = doc.addObject("Part::MultiFuse", name + "_clamp_hole")
gt2_clamp_holes.Shapes = gt2_base_holes_l
# Substract the holes
gt2_clamp = doc.addObject("Part::Cut", name)
gt2_clamp.Base = gt2_clamp_basic
gt2_clamp.Tool = gt2_clamp_holes
self.fco = gt2_clamp # the FreeCad Object
def BasePlace (self, position = (0,0,0)):
self.base_place = position
self.fco.Placement.Base = FreeCAD.Vector(position)
self.fco_cont.Placement.Base = FreeCAD.Vector(position)
# --------------------------------------------------------------------
# obtains the list of vectors for the base of the clamp
# offs_y: if zero it takes normal points
# offs_z added because it didn't fit
# offs_z: if zero it takes normal points
# CBASERAILIND_SIG <0: CBASERAILIND_SIG > 0
# lv5 _________ ___________
# lv4 | | |
# lv3 / \ \
# lv2 | | |
# lv1 \ / /
# lv0 |_________| |_
#
#
#
def get_base_list_v(self, offs_y = 0, offs_z = 0):
if self.CBASERAILIND_SIG < 0:
offs_zsig = - offs_z
else:
offs_zsig = offs_z
# Points that make the shape of the base
# left side (offs is negative
gt2_base_lv00 = FreeCAD.Vector (0,
0 - offs_y,
0)
# offs_z higher when CBASERAILIND_SIG > 0
gt2_base_lv01 = FreeCAD.Vector (0,
0 - offs_y,
self.CBASE_WALL + offs_zsig)
gt2_base_lv02 = FreeCAD.Vector (
0,
self.CBASERAILIND_SIG - offs_y,
self.CBASE_WALL + self.CBASERAILIND + offs_zsig)
# offs_z negative (lower)
gt2_base_lv03 = FreeCAD.Vector (0,
self.CBASERAILIND_SIG - offs_y,
self.CBASE_WALL + 2*self.CBASERAILIND - offs_zsig)
gt2_base_lv04 = FreeCAD.Vector (0,0 - offs_y,
self.CBASE_WALL + self.CBASE_RAIL - offs_zsig)
gt2_base_lv05 = FreeCAD.Vector (0,0 - offs_y,
self.CBASE_H)
# right side (offs_y is positive
gt2_base_rv00 = FreeCAD.Vector (0,
self.CBASE_W + offs_y,
0)
gt2_base_rv01 = FreeCAD.Vector (0,
self.CBASE_W + offs_y,
self.CBASE_WALL + offs_zsig)
gt2_base_rv02 = FreeCAD.Vector (0,
self.CBASE_W - self.CBASERAILIND_SIG + offs_y,
self.CBASE_WALL + self.CBASERAILIND + offs_zsig)
gt2_base_rv03 = FreeCAD.Vector (0,
self.CBASE_W - self.CBASERAILIND_SIG + offs_y,
self.CBASE_WALL + 2*self.CBASERAILIND - offs_zsig)
gt2_base_rv04 = FreeCAD.Vector (0,
self.CBASE_W + offs_y,
self.CBASE_WALL + self.CBASE_RAIL - offs_zsig)
gt2_base_rv05 = FreeCAD.Vector (0,
self.CBASE_W + offs_y,
self.CBASE_H)
gt2_base_list = [
gt2_base_lv00,
gt2_base_lv01,
gt2_base_lv02,
gt2_base_lv03,
gt2_base_lv04,
gt2_base_lv05,
gt2_base_rv05,
gt2_base_rv04,
gt2_base_rv03,
gt2_base_rv02,
gt2_base_rv01,
gt2_base_rv00
]
# if it is negative, the indentation will be outwards, so we will
# make the Y=0 on the most outward point, except for the offs_y
# that will be negative when Y=0
if self.CBASERAILIND_SIG < 0:
addofs = FreeCAD.Vector (0, - self.CBASERAILIND_SIG,0)
gt2_base_list = [x + addofs for x in gt2_base_list]
return gt2_base_list
# end class Gt2BeltClamp:
# ----------- shp_topbeltclamp
# Creates a shape of a belt clamp. Just the rail and the cylinder
# just one way: 2 clamp blocks
# It is references at the end of the rail
#""
# TOPVIEW
# CLAMPBLOCK
# CB
# ____ ___
# CB_W { XXXX / \
# CB_IW { ____ | | CCYL: CLAMPCYL
# CB_W { XXXX \___/
#
# CB_L CS
#
def shp_topbeltclamp (railaxis = 'x', bot_norm = '-z', pos = V0, extra=1):
cyl_posx = Gt2BeltClamp.CB_L + Gt2BeltClamp.CS + Gt2BeltClamp.CCYL_R
height = Gt2BeltClamp.C_H + extra
shpcyl = fcfun.shp_cyl(r= Gt2BeltClamp.CCYL_R,
h= height,
normal = VZ,
pos = FreeCAD.Vector(cyl_posx,0,-extra) )
bl_posy0 = Gt2BeltClamp.CB_IW/2.
bl_posy1 = Gt2BeltClamp.CB_IW/2. + Gt2BeltClamp.CB_W
# block on top
blt_p0 = FreeCAD.Vector(0, bl_posy0, -extra)
blt_p1 = FreeCAD.Vector(Gt2BeltClamp.CB_L , bl_posy0, -extra)
blt_p2 = FreeCAD.Vector(Gt2BeltClamp.CB_L , bl_posy1, -extra)
blt_p3 = FreeCAD.Vector(0 , bl_posy1, -extra)
shp_wire_blt = Part.makePolygon([blt_p0,blt_p1,blt_p2,blt_p3, blt_p0])
shp_face_blt = Part.Face(shp_wire_blt)
shpblt = shp_face_blt.extrude(FreeCAD.Vector(0,0,height))
# block on bottom
blb_p0 = FreeCAD.Vector(0 , -bl_posy1, -extra)
blb_p1 = FreeCAD.Vector(Gt2BeltClamp.CB_L , -bl_posy1, -extra)
blb_p2 = FreeCAD.Vector(Gt2BeltClamp.CB_L , -bl_posy0, -extra)
blb_p3 = FreeCAD.Vector(0, -bl_posy0, -extra)
shp_wire_blb = Part.makePolygon([blb_p0,blb_p1,blb_p2,blb_p3, blb_p0])
shp_face_blb = Part.Face(shp_wire_blb)
shpblb = shp_face_blb.extrude(FreeCAD.Vector(0,0,height))
shp_clamp = shpcyl.multiFuse([shpblt, shpblb])
vec_railaxis = fcfun.getvecofname(railaxis)
vec_botnorm = fcfun.getvecofname(bot_norm)
vrot = fcfun.calc_rot(vec_railaxis, vec_botnorm)
shp_clamp.Placement.Rotation = vrot
shp_clamp.Placement.Base = pos
return shp_clamp
#Part.show (shp_clamp)
def fco_topbeltclamp (railaxis = 'x', bot_norm = '-z', pos = V0, extra=1,
name = "bclamp"):
doc = FreeCAD.ActiveDocument
shptopbeltclamp = shp_topbeltclamp (railaxis = railaxis,
bot_norm = bot_norm,
pos = pos, extra= extra)
fcotopbeltclamp = doc.addObject("Part::Feature", name)
fcotopbeltclamp.Shape = shptopbeltclamp
#doc = FreeCAD.newDocument()
#shp = shp_topbeltclamp (railaxis = 'x', bot_norm= '-z', pos=FreeCAD.Vector(2,0,4))
# ----------- shp_topbeltclamp_dir
[docs]class BeltClamp (object):
"""
Similar to shp_topbeltclamp, but with any direction, and
can have a base
Creates a shape of a belt clamp. Just the rail and the cylinder
and may have a rectangular base
just one way: 2 clamp blocks
It is referenced on the base of the clamp, but it may have 5 different
positions
Parameters
----------
fc_fro_ax : FreeCAD.Vector
FreeCAD.Vector pointing to the front, see pricture
fc_top_ax : FreeCAD.Vector
FreeCAD.Vector pointing to the top, see pricture
base_h : float
Height of the base,
* if 0 and bolt_d=0: no base
* if 0 and bolt_d!= 0: minimum base to have the bolt head and
not touching with the belt (countersunk) if bolt_csunk > 0
base_l : float
Length of the base, if base_h not 0.
* if 0 and bolt_d=0: will have the minimum length, defined by the
clamp
* if 0 and bolt_d!=0: will have the minimum length, defined by
the clamp plus the minimum separation due to the bolt holes
base_w : float
Width of the base, if base_h not 0.
bolt_d : float
Diameter of the bolts, if zero, no bolts
bolt_csunk : float
If the bolt is countersunk
* if >0: there is a whole to countersink the head of the bolt
there will be an extra height if not enough
bolt_d has to be > 0
* if 0: no whole for the height, and no extra height
* if >0, the size will determine the minimum height of the
base, below the countersink hole
ref : int
Reference of the position (see picture below)
extra : float
If extra, it will have an extra height below the zero height,
this is to be joined to some other piece
wfco : int
* if 1: With FreeCad Object: a freecad object is created
* if 0: only the shape
intol : float
Internal extra tolerance to the dimension CB_IW, substracting
to CB_W. If negative, makes CB_IW smaller.
name : str
Name of the freecad object, if created
::
fc_top_ax
:
_____ _:_ ..........
| | | : | + C_H
____|_____|_____|_:_|____.....:
| :: : :: | + base_h
fc_fro_ax...|_::_______________*___::_|....:
CLAMPBLOCK
CB * ref
clamp2end clamp2end
..+... ...+...
: : : :
: bolt2end : bolt2end
:+..+. :.+..+.
: : : : : :
:__:__:______________:__:__:...................
| : ____ ___ | :
CB_W { | : |____| / \ | :
CB_IW { | O ____ | * | O | CCYL: CLAMPCYL + base_w
CB_W { | |____| \___/ | :
|__________________________|..................:
: : : : : :
: :CB_L:.CS..:.: :
: + :
: CCYL_R :
:......... base_l .........:
__________________________
| ____ ___ |
CB_W { | |____| / \ |
CB_IW { 4 3 2____ | 1 | 5 6 CCYL: CLAMPCYL
CB_W { | |____| \___/ |
|__________________________|
: :
:CB_L:.CS.:
References:
1: cencyl: center of cylinder
2: frontclamp: front of the clamps
3: frontbolt
4: frontbase
5: backbolt
6: backbase
fc_top_ax
:
_____ _:_
| | | : |
____|_____|_____|_:_|____
|:..: : :..:|.....
fc_fro_ax...|_::_______________*___::_|....+ bolt_csunk (if not 0)
"""
# minimum base
MIN_BASE_H = 2.
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 = vec_2to1 + vec_1to5
vec_tobackbase = vec_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 color (self, color = (1,1,1)):
if self.wfco == 1:
self.fco.ViewObject.ShapeColor = color
else:
logger.debug("Clamp object with no fco")
# exports the shape into stl format
def export_stl (self, name = ""):
#filepath = os.getcwd()
if not name:
name = self.name
#stlPath = filepath + "/freecad/stl/"
stlPath = filepath + stl_dir
stlFileName = stlPath + name + ".stl"
# exportStl is not working well with FreeCAD 0.17
#self.shp.exportStl(stlFileName)
mesh_shp = MeshPart.meshFromShape(self.shp,
LinearDeflection=kparts.LIN_DEFL,
AngularDeflection=kparts.ANG_DEFL)
mesh_shp.write(stlFileName)
del mesh_shp
# Revisar el caso con agujeros de bolt
#BeltClamp (VX, VY, base_h = 0, bolt_d=3, bolt_csunk = 2)
class ShpBeltClamped (shp_clss.WireBeltClamped):
""" Creates a belt from a wire of the trajectory of the belt and its
section. The shape is not toothed, it is just a rough shape
::
axis_w
:
:
pulley1 pulley2
-----------------------------------
( ) ( )--------> axis_d
---------=== ( ) ( ) ===--------
clamp1 clamp2
1 0 2 3 45 67 8 9 10 11 pos_d
: : : :
: : : :
: :............: :
: + :
: clamp_sep :
: :
:.................................:
+
pull_sep_d
pos_w points:
axis_w
: pull2
: clamp1 clamp2
2_ 3-
( 1 ) - - pull_sep_w (positive)
( 0 ) - - - - - - - - - - - - - - - 5- - -
6 ___ ...................___.............:+ clamp_pull1_w (neg)
4- 7 < ) ( > :+ clamp_w
8 ___ ...................___.............:
axis_w
: pull2
: clamp1 clamp2
_ -
( ) - - pull_sep_w(positive)
( ) - - - - - - - - - - - - - - - - - - - -
___ ...................___.............:+ clamp_pull1_w (neg)
- x < ) ( > :+ clamp_w
___ ...................___.............:
: : : :: : : : :
: : : :cyl_r : : : :
: : :...: :...: :.......:
: : : + + : : +
: : : clamp_cyl_sep : : +
: : : : : clamp_pull2_d
: : : :...:
: : : : +
: : :..................: clamp_d
: : : +
: : : clamp_sep
: :...:
: : +
: : clamp_d
: :
:......:
+
clamp_pull1_d
Section of the belt. The belt starts at point x (see upper drawing)
axis_h
:
:
_____ : _____
| 1 __:__ |....................
clamp| | : ||clamp :
| | : || :
| | : || :+belt_width (can be confusing)
| | : || : is the width of the belt
| 0| :..||........ axis_w : but in the drawing is the
| | || : height
| | || axis_d is pointing out of the screen
| | || (to you)
| |belt || :
| |_____||....................:
| 0 12| for now, the belt will be at this pos_w 2
because, there is alread a pos_w for the wire
: :
:.....:
+
belt_thick
Parameters:
-----------
pull1_dm: float
Diameter of pulley 1
pull2_dm: float
Diameter of pulley 2
pull_sep_d : float
Separation between the 2 pulleys centers along axis_d
pull_sep_w : float
Separation between the 2 pulleys centers along axis_w
* if positive, pulley 2 is further away in the direction of axis_w
* if negative, pulley 2 is further away opposite to the direction of
axis_w
clamp_pull1_d : float
Separation between the clamp (side closer to the center) and the center
of the pulley1 along axis d
clamp_pull1_w : float
Separation between the center of the clamp and the center of the
pulley1 along axis w
clamp_pull2_d : float
Separation between the clamp (side closer to the center) and the center
of the pulley1 along axis d
clamp_pull2_w can be calculated because the clamps are aligned along
axis_d, so it will be clamp_pull1_d + pull_sep_w
clamp_d : float
Length of the clamp (same for each clamp)
clamp_w : float
Width of inner space (same for each clamp)
clamp_cyl_sep : float
Separation between clamp and the center of the cylinder (or the center)
of the larger cylinder (when is a belt shape)
cyl_r : float
Radius of the cylinder for the belt, if it is not a cylinder but a
shape of 2 cylinders: < ) , then the raidius of the larger one
belt_width : float
Width of the belt, can be consfusing becasue the width is along axis_h
belt_thick : float
Thickness of the belt, it doesnt take into account the teeth, or the
detailed shape (contour)
axis_d : FreeCAD.Vector
Coordinate System Vector along the depth
axis_w : FreeCAD.Vector
Coordinate System Vector along the width
axis_h : FreeCAD.Vector
Coordinate System Vector along the height
pos_d : int
Location of pos along the axis_d, see drawing
* 0: center of the pulley 1
* 1: end of pulley 1
* 2: end of clamp 1, closest end to pulley 1
* 3: other end of clamp 1, closest to cylinder
* 4: center of cylinder (or shape < ) 1
* 5: external radius of cylinder 1
* 6: external radius of cylinder 2
* 7: center of cylinder (or shape ( > 2
* 8: end of clamp 2, closest to cylinder
* 9: other end of clamp 2, closest end to pulley 2
* 10: center of pulley 2
* 11: end of pulley 2
pos_w : int
Location of pos along the axis_w, see drawing
* 0: center of pulley 1
* 1: center of pulley 2
* 2: end (radius) of pulley 1 along axis_w
* 3: end (radius) of pulley 2 along axis_w
* 4: other end (radius) of pulley 1 opposite to axis_w
* 5: other end (radius) of pulley 2 opposite to axis_w
* 6: clamp space, closest to the pulley
* 7: center of clamp space
* 8: clamp space, far away from the pulley
pos_h : int
Location of pos along the axis_h, see drawing
* 0: center of symmetry
* 1: top of the belt
since it is symmetric -1 will be at the bottom of the belt
pos: FreeCAD vector of the position of the reference
Attributes:
-----------
clamp_sep : float
Separation between clamps, the closest ends
"""
def __init__(self,
pull1_dm,
pull2_dm,
pull_sep_d,
pull_sep_w,
clamp_pull1_d,
clamp_pull1_w,
clamp_pull2_d,
clamp_d,
clamp_w,
clamp_cyl_sep,
cyl_r,
belt_width = 6.,
belt_thick = 1.38,
axis_d = VY,
axis_w = VX,
axis_h = VZ,
pos_d = 0,
pos_w = 0,
pos_h = 0,
pos=V0):
shp_clss.WireBeltClamped.__init__( self,
pull1_dm = pull1_dm,
pull2_dm = pull2_dm,
pull_sep_d = pull_sep_d,
pull_sep_w = pull_sep_w,
clamp_pull1_d = clamp_pull1_d,
clamp_pull1_w = clamp_pull1_w,
clamp_pull2_d = clamp_pull2_d,
clamp_d = clamp_d,
clamp_w = clamp_w,
clamp_cyl_sep = clamp_cyl_sep,
cyl_r = cyl_r,
axis_d = axis_d,
axis_w = axis_w,
pos_d = pos_d,
pos_w = pos_w,
pos = pos)
self.belt_thick = belt_thick
self.belt_width = belt_width
# vectors from the origin to the points along axis_h:
self.h0_cen = 1 # symmetric
self.axis_h = DraftVecUtils.scaleTo(axis_h,1)
self.h_o[0] = V0 # origin (center symmetric)
self.h_o[1] = self.vec_h(-self.belt_width/2.)
print(str(self.h_o[1]))
# calculates the position of the origin, and keeps it in attribute pos_o
self.set_pos_o()
# Four corners of the belt section
#
# axis_h
# :
# : ___
# 4_:_1|
# | ||
# | |.....> axis_w
# | ||
# 3___2| clamp
# |
#
belt_sec_pt1 = self.get_pos_dwh(2,6,1)
belt_sec_pt2 = self.get_pos_dwh(2,6,-1)
belt_sec_pt3 = belt_sec_pt2 + self.vec_w(-belt_thick)
belt_sec_pt4 = belt_sec_pt1 + self.vec_w(-belt_thick)
wire_belt_sec = Part.makePolygon([belt_sec_pt1, belt_sec_pt2,
belt_sec_pt3, belt_sec_pt4,
belt_sec_pt1])
shp_belt = self.belt_wire.makePipeShell([wire_belt_sec],True, False,2)
shp_belt = shp_belt.removeSplitter()
self.shp = shp_belt
# not using this yet
#def get_o_to_wb (self, pos_wb):
# """ returns the vector from origin of the belt section to pos_wb
# wb is related to the belt
# If it is symmetrical, pos_wb == 0 will be at the middle
# Then, pos_wb > 0 will be the points on the positive side of axis_w
# Then, pos_wb < 0 will be the points on the negative side of axis_w
# """
# abs_pos_wb = abs(pos_wb)
# if self.wb0_cen == 1:
# if pos_wb <= 0:
# try:
# vec = self.wb_o[abs_pos_wb]
# except KeyError:
# logger.error('pos_wb key not defined ' + str(pos_wb))
# else:
# return vec
# else:
# try:
# vec_0_to_wb = (self.wb_o[0]).sub(self.wb_o[pos_wb]) #D= B-C
# except KeyError:
# logger.error('pos_wb key not defined ' + str(pos_wb))
# else:
# vec_orig_to_wb = self.wb_o[0] + vec_0_to_wb # A = B + D
# return vec_orig_to_wb
# else: #pos_d == 0 is at the end, distances are calculated directly
# try:
# vec = self.wb_o[pos_wb]
# except KeyError:
# logger.error('pos_wb key not defined' + str(pos_wb))
# else:
# return vec
#belt = ShpBeltClamped (
# pull1_dm = 5,
# pull2_dm = 6,
# pull_sep_d = 80,
# pull_sep_w = 0,
# clamp_pull1_d = 15,
# clamp_pull1_w = 5,
# clamp_pull2_d = 15,
# clamp_d = 5,
# clamp_w = 4,
# clamp_cyl_sep = 8,
# cyl_r = 3,
# belt_width = 6.,
# belt_thick = 1.38,
# axis_d = VY,
# axis_w = VX,
# axis_h = VZ,
# pos_d = 0,
# pos_w = 0,
# pos_h = 0,
# pos=V0)
class PartBeltClamped (fc_clss.SinglePart, ShpBeltClamped):
""" Integration of a ShpBeltClamped object into a PartBeltClamped object
Same parameters as ShpBeltClamped plus
model_type
name
"""
def __init__(self,
pull1_dm,
pull2_dm,
pull_sep_d,
pull_sep_w,
clamp_pull1_d,
clamp_pull1_w,
clamp_pull2_d,
clamp_d,
clamp_w,
clamp_cyl_sep,
cyl_r,
belt_width = 6.,
belt_thick = 1.38,
axis_d = VY,
axis_w = VX,
axis_h = VZ,
pos_d = 0,
pos_w = 0,
pos_h = 0,
pos=V0,
model_type = 1, # dimensional model
name = ''):
default_name = 'gt2_belt'
self.set_name (name, default_name, change=0)
ShpBeltClamped.__init__(self,
pull1_dm = pull1_dm,
pull2_dm = pull2_dm,
pull_sep_d = pull_sep_d,
pull_sep_w = pull_sep_w,
clamp_pull1_d = clamp_pull1_d,
clamp_pull1_w = clamp_pull1_w,
clamp_pull2_d = clamp_pull2_d,
clamp_d = clamp_d,
clamp_w = clamp_w,
clamp_cyl_sep = clamp_cyl_sep,
cyl_r = cyl_r,
belt_width = belt_width,
belt_thick = belt_thick,
axis_d = axis_d,
axis_w = axis_w,
axis_h = axis_h,
pos_d = pos_d,
pos_w = pos_w,
pos_h = pos_h,
pos = pos)
# creation of the part
fc_clss.SinglePart.__init__(self)
# save the arguments as attributes:
frame = inspect.currentframe()
args, _, _, values = inspect.getargvalues(frame)
for i in args:
if not hasattr(self,i):
setattr(self, i, values[i])
#belt = PartBeltClamped (
# pull1_dm = 5,
# pull2_dm = 6,
# pull_sep_d = 80,
# pull_sep_w = 0,
# clamp_pull1_d = 15,
# clamp_pull1_w = 5,
# clamp_pull2_d = 15,
# clamp_d = 5,
# clamp_w = 4,
# clamp_cyl_sep = 8,
# cyl_r = 3,
# belt_width = 6.,
# belt_thick = 1.38,
# axis_d = VY,
# axis_w = VX,
# axis_h = VZ,
# pos_d = 0,
# pos_w = 0,
# pos_h = 1,
# pos=V0)
[docs]class DoubleBeltClamp (shp_clss.Obj3D):
"""
Similar to BeltClamp, but in two ways
Creates a shape of a double belt clamp.
positions
Parameters
----------
fc_fro_ax : FreeCAD.Vector
FreeCAD.Vector pointing to the front, see pricture
fc_top_ax : FreeCAD.Vector
FreeCAD.Vector pointing to the top, see pricture
base_h : float
Height of the base,
* if 0 and bolt_d=0: no base
* if 0 and bolt_d!= 0: minimum base to have the bolt head and
not touching with the belt (countersunk) if bolt_csunk > 0
base_l : float
Length of the base, if base_h not 0.
* if 0 and bolt_d=0: will have the minimum length, defined by the
clamp
* if 0 and bolt_d!=0: will have the minimum length, defined by
the clamp plus the minimum separation due to the bolt holes
base_w : float
Width of the base, if base_h not 0.
bolt_d : float
Diameter of the bolts, if zero, no bolts
bolt_csunk : float
If the bolt is countersunk
* if >0: there is a whole to countersink the head of the bolt
there will be an extra height if not enough
bolt_d has to be > 0
* if 0: no whole for the height, and no extra height
* if >0, the size will determine the minimum height of the
base, below the countersink hole
ref : int
Reference of the position (see picture below)
extra : float
If extra, it will have an extra height below the zero height,
this is to be joined to some other piece
wfco : int
* if 1: With FreeCad Object: a freecad object is created
* if 0: only the shape
intol : float
Internal extra tolerance to the dimension CB_IW, substracting
to CB_W. If negative, makes CB_IW smaller.
name : str
Name of the freecad object, if created
::
axis_h
:
_____ _:_ _:_ _____ ..........
| | | : | | : | | | + C_H
____|_____|_____|_:_|_________|_:_|_____|_____|____.....:
| :: : | | : :: | + base_h
axis_d...|_::_______________*__|_______|__*_______________::_|.:
clamp2end clamp2end
...+... ...+...
: : : :
: bolt2end _______ : bolt2end
:+..+.: | | :+..+.:
: : : | O | : : :
:__:__:_______________|_______|_______________:__:__:...................
| : ____ ___ ___ ____ | :
CB_W { | : |____| / \ / \ |____| | :
CB_IW { | O ____ | * | | * | ____ O | CCYL: CLAMPCYL + base_w
CB_W { | |____| \___/ \___/ |____| | :
|___________________________________________________|..................:
: : : : : | | :
: : : : : | O | :
: :CB_L:.CS..:.: |_______| :
: + :
: CCYL_R :
:...................... base_l .....................:
_______
| |
| O |
_____________________|_______|______________________
| ____ ___ ___ ____ |
CB_W { | |____| / \ / \ |____| |
CB_IW { -4 -3 -2____ |-1 | 0 | 1 | ____2 3 4
CB_W { | |____| \___/ \___/ |____| |
|___________________________________________________|
| |
| O |
|_______|
1: center
2: center of left cylinder
3: center of right cylinder
4: front of the left clamps
5: front of the right clamps
6: left bolt
7: right bolt
8: left base
9: right base
___3___
| |
| 2 |
_____________________|_______|______________________
| ____ ___ ___ ____ |
CB_W { | |____| . . / \ . 1 . / \ . . |____| |
CB_IW { | ____ | | 0 | | ____ |
CB_W { | |____| . . \___/ . -1 . \___/ . . |____| |
|___________________________________________________|
| |
| -2 |
|__-3___|
1: center
2: bolt up
3: bolt down
4: up base
5: down base
"""
def __init__(self,
axis_h = VZ,
axis_d = VX,
axis_w = VY,
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 = 'double_belt_clamp' ):
doc = FreeCAD.ActiveDocument
self.name = name
self.axis_d = axis_d
self.axis_h = axis_h
self.axis_w = axis_w
if axis_w is None or axis_w == V0:
axis_w = axis_h.cross(axis_d)
shp_clss.Obj3D.__init__(self, axis_d, axis_w, axis_h)
# save the arguments as attributes:
frame = inspect.currentframe()
args, _, _, values = inspect.getargvalues(frame)
for i in args:
if not hasattr(self,i):
setattr(self, i, values[i])
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']
# 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
clamponly_l = 2 * (CB_L + CS + 2 * CCYL_R)
clamponly_w = max((cb_in_w+2*cb_wall_w), (2*CCYL_R))
# 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 + 3 * 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 base_w == 0:
base_w = clamponly_w
logger.debug("base_w too short, Taking min width %s",
clamponly_w)
elif base_w < clamponly_w:
logger.debug("base_w too short, Taking min width %s",
clamponly_w)
base_w = clamponly_w
self.base_h = base_h
self.base_w = base_w
self.base_l = base_l
self.pos_o = pos
self.pos_d = 0
self.pos_w = 0
self.pos_h = 0
chmf_r = 1.
if extra == 0:
extra_pos = V0
else:
extra_pos = DraftVecUtils.scale(self.axis_h, -extra)
pos_extra = pos + extra_pos
base_top_add = DraftVecUtils.scale(self.axis_h, base_h + extra)
# position centered
self.d0_cen = 1
self.w0_cen = 1
self.h0_cen = 0
# position along axis_d
self.d_o[0] = V0
self.d_o[1] = self.vec_d(clamp2end/2 + CCYL_R)
self.d_o[2] = self.vec_d(clamp2end/2 + CCYL_R + CS + CB_L)
self.d_o[3] = self.vec_d(self.base_l/2 - bolt_head_r)
self.d_o[4] = self.vec_d(clamp2end/2 + CCYL_R + CS + CB_L + clamp2end)
# position along axis_w
self.w_o[0] = V0
self.w_o[1] = self.vec_w((cb_in_w + cb_wall_w)/2.)
self.w_o[2] = self.vec_w((self.base_w + clamp2end)/2)
self.w_o[3] = self.vec_w(self.base_w/2 + 2*bolt2end)
# position along axis_h
self.h_o[0] = V0
self.h_o[1] = self.vec_h(self.base_h)
# Make the base
# principal
shp_base_1 = fcfun.shp_box_dir(box_w = self.base_w,
box_d = self.base_l,
box_h = self.base_h,
fc_axis_w = self.axis_w,
fc_axis_h = self.axis_h,
fc_axis_d = self.axis_d,
cw=1, cd=1, ch=0, # 1 centrado, 0 descentrado
pos = self.pos_o)
shp_base_1 = fcfun.shp_filletchamfer_dir (shp_base_1, self.axis_h,
fillet = 1, radius = chmf_r)
# perp
shp_base_2 = fcfun.shp_box_dir(box_w = self.base_w + clamp2end + 2*bolt_head_r,
box_d = 2 * bolt_head_r,
box_h = self.base_h,
fc_axis_w = self.axis_w,
fc_axis_h = self.axis_h,
fc_axis_d = self.axis_d,
cw=1, cd=1, ch=0, # 1 centrado, 0 descentrado
pos = self.pos_o)
shp_base_2 = fcfun.shp_filletchamfer_dir (shp_base_2, self.axis_h,
fillet = 1, radius = chmf_r)
shp_base = fcfun.fuseshplist([shp_base_1, shp_base_2])
# make the clampblock
clamp_tot_h = C_H + base_h + extra
clampcyl_pos_1 = self.d_o [1] + pos_extra
#clampcyl_pos_2 = self.d_o[-1] - pos_extra
clampblock_side_add = DraftVecUtils.scale(self.axis_w,
(cb_in_w + cb_wall_w)/2.)
clampblock_1_pos = self.d_o[2]
#clampblock_2_pos = self.d_o[-2]
shp_cyl_1 = fcfun.shp_cyl(CCYL_R, clamp_tot_h, self.axis_h, self.get_pos_dwh(1,0,1))#self.pos + clampcyl_pos_1 + FreeCAD.Vector(0,0,self.base_h/2))
shp_clampblock_1_a = fcfun.shp_box_dir(box_w = cb_wall_w,
box_d = CB_L,
box_h = clamp_tot_h,
fc_axis_h = self.axis_h,
fc_axis_d = self.axis_d,
cw=1, cd=1, ch=0,
pos = self.get_pos_dwh(2,1,0))#self.pos + clampblock_1_pos + clampblock_side_add)
shp_clampblock_1_b = fcfun.shp_box_dir(box_w = cb_wall_w,
box_d = CB_L,
box_h = clamp_tot_h,
fc_axis_h = self.axis_h,
fc_axis_d = self.axis_d,
cw=1, cd=1, ch=0,
pos = self.get_pos_dwh(2,-1,0))#self.pos + clampblock_1_pos - clampblock_side_add)
shp_cyl_2 = fcfun.shp_cyl(CCYL_R, clamp_tot_h, self.axis_h, self.get_pos_dwh(-1,0,1))#self.pos + clampcyl_pos_2 - FreeCAD.Vector(0,0,self.base_h/2))
shp_clampblock_2_a = fcfun.shp_box_dir(box_w = cb_wall_w,
box_d = CB_L,
box_h = clamp_tot_h,
fc_axis_h = self.axis_h,
fc_axis_d = self.axis_d,
cw=1, cd=1, ch=0,
pos = self.get_pos_dwh(-2,1,0))#self.pos + clampblock_2_pos + clampblock_side_add)
shp_clampblock_2_b = fcfun.shp_box_dir(box_w = cb_wall_w,
box_d = CB_L,
box_h = clamp_tot_h,
fc_axis_h = self.axis_h,
fc_axis_d = self.axis_d,
cw=1, cd=1, ch=0,
pos = self.get_pos_dwh(-2,-1,0))#self.pos + clampblock_2_pos - clampblock_side_add)
shp_clamp = fcfun.fuseshplist([shp_cyl_1, shp_clampblock_1_a, shp_clampblock_1_b,
shp_cyl_2, shp_clampblock_2_a, shp_clampblock_2_b])
# Make holes
if bolt_d > 0:
# pos_bolt_1 = self.pos + self.d_o[6]
# pos_bolt_2 = self.pos + self.d_o[5]
# pos_bolt_3 = self.pos + self.w_o[1] + pos_extra + base_top_add + FreeCAD.Vector(0,0,-self.base_h)
# pos_bolt_4 = self.pos + self.w_o[2] - pos_extra - base_top_add
if bolt_csunk > 0 :
shp_bolt_1 = 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 = self.axis_h,
pos= self.get_pos_dwh(3,0,0))#pos_bolt_1)
shp_bolt_2 = 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 = self.axis_h,
pos= self.get_pos_dwh(-3,0,0))#pos_bolt_2)
shp_bolt_3 = 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 = self.axis_h,
pos= self.get_pos_dwh(0,2,0))#pos_bolt_3)
shp_bolt_4 = 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 = self.axis_h,
pos= self.get_pos_dwh(0,-2,0))#pos_bolt_4)
else: # no head, just a cylinder:
shp_bolt_1 = fcfun.shp_cylcenxtr (
r = bolt_shank_r,
h = base_h + extra,
normal = self.axis_h,
ch = 0,
xtr_top=1, xtr_bot=1,
pos = self.get_pos_dwh(3,0,0))#pos_bolt_1)
shp_bolt_2 = fcfun.shp_cylcenxtr (
r = bolt_shank_r,
h = base_h + extra,
normal = self.axis_h,
ch = 0,
xtr_top=1, xtr_bot=1,
pos = self.get_pos_dwh(-3,0,0))#pos_bolt_2)
shp_bolt_3 = fcfun.shp_cylcenxtr (
r = bolt_shank_r,
h = base_h + extra,
normal = self.axis_h,
ch = 0,
xtr_top=1, xtr_bot=1,
pos = self.get_pos_dwh(0,2,0))#pos_bolt_3)
shp_bolt_4 = fcfun.shp_cylcenxtr (
r = bolt_shank_r,
h = base_h + extra,
normal = self.axis_h,
ch = 0,
xtr_top=1, xtr_bot=1,
pos = self.get_pos_dwh(0,-2,0))#pos_bolt_4)
# fuse the bolts:
shp_bolts = fcfun.fuseshplist([shp_bolt_1,
shp_bolt_2,
shp_bolt_3,
shp_bolt_4])
shp_base = shp_base.cut(shp_bolts)
shp = fcfun.fuseshplist([shp_base, shp_clamp])
#doc.recompute()
shp = shp.removeSplitter()
self.shp = shp
self.wfco = wfco
if wfco == 1:
# a freeCAD object is created
fco_clamp = doc.addObject("Part::Feature", name )
fco_clamp.Shape = shp
self.fco = fco_clamp