Back to SDS/2 Parametric Scripts
## Beam_MomentClip.py Version 1.02
## Copyright (c) 2006 Bruce Vaughan, BV
Detailing & Design, Inc.
## All rights reserved.
## NOT FOR
############################################################################
"""
Add end moment clips to a WF, Tube or
Channel beam.
This script can be executed in plan,
elevation, or isometric.
The script reads the beam end minus
dimension to set the clip angle locations.
If beam has plain end, set the minus
dimension to the face of supporting member.
Reprocess the members to match holes and
add bolts.
Originally developed in
Tested in
Developed by Bruce Vaughan, BV Detailing
& Design, Inc. (BVD)
For comments, suggestions or questions call
BVD at the number above.
NOT FOR
R1 -
Updated code (
R2 -
Reworked dialog box (
V7R1 -
Tested in
Version 1.00 (
Updated code
Version 1.01 (
Version 1.02 (
Go to Defaults section to modify script
defaults.
"""
def
run_script():
# startup code begin
from math import cos, floor, pi, tan
from param import yes_or_no, ResponseNotOK,
Units, ClearSelection, Dialog, dim_print, Warning, dim
from macrolib.FileDefaults import
import_data, export_data #
macrolib.pickle required
from macrolib.MemCnt import member_count
from macrolib.Weld import mtrl_weld
from macrolib.ColumnFraming import
ColumnSupport, ColumnCondition
from macrolib.MemSelection import
mem_select
import os
import sys
Units("feet")
from shape import Shape
from point import Point, PointLocate
from member import Member, MemberLocate,
MemberAllocated
from rolled_section import RolledSection
from
weld_add import Weld
from job import Job
from fab import Fabricator
from hole_add import Hole
from bolt_add import Bolt
# startup code end
#################################################################
## Variables section
############################################
# system path for defaults file
default_file_path =
os.path.join(os.getcwd(), "macro", "Defaults")
# defaults file
def_file = "Beam_MomentClip.txt"
# Dialog box image path and file name
image_path = os.path.join(os.getcwd(),
"macro", "Images")
image_name1 = os.path.join(image_path,
"Beam_MomentClip.gif")
image_name2 = os.path.join(image_path,
"Beam_MomentClip1.gif")
image_name3 = os.path.join(image_path,
"Beam_MomentClip2.gif")
# image_name7 = os.path.join(image_path,
"PurlinRafterBanner1.gif")
# default to enable or disable the
importing and exporting of dialog dictionary variables "Enable"
"Disable"
enable_default_import_export =
"Enable"
finishList = ["None", "Red
Oxide", "Yellow Zinc", "Gray Oxide",
"Sandblasted", "Blued Steel", "Galvanized"]
holeTypeList = ["Standard Round",
"Short Slot", "Oversized Round", "Long Slot"]
holeTypeList1 = ["Standard
Round", "Oversized Round"]
wsList = ['3/16', '1/4', '5/16',
'3/8']
## Defaults section
#############################################
# extend clip beyond member minus dimension
extend_clip = 1.0
# end to add moment clip "Left"
"Right" "Both"
which_end = "Right"
# top or bottom of beam "Top",
"Bott", "Both"
t_or_b = "Both"
# clip angle size
clip_size = "L4x4x1/2"
# long leg vertical or horizontal where
applicable
llv_llh = "LLV"
#
Job().steel_grades("Angle").keys()
steelgrade = "A36"
# finishList
clip_finish = "Yellow Zinc"
# add weld "Yes" "No"
add_clip_weld = "Yes"
# weld type "Fillet"
clip_weld_type = "Fillet"
# weld size - wsList
weld_size = 0.25
col_leg_ga = 4.0 # default hole
centers(0" for 1 bolt)
clip_gage = 2.5 # default gage of clip
angle OSL
dbl_gage_spa = 3.0 # default double gage
spacing - 0" for single gage only
edge_dist = 1.5 # default edge
distance
bolt_size = 0.75 # bolt diameter
# holeTypeList - leg against column
hole_type_col = "Standard Round"
# bolt type against column
Job().bolt_sched()
bolt_type_col = "A325N"
#
slot rotation if applicable "VT.", "HZ."
slot_rot = "VT."
# Beam flange holes
# add flange holes in beam
add_flg_hls = "No"
# gage of clip angle FLG leg
clip_gage1 = 2.5
# double gage spacing in FLG leg- 0"
for single gage only
dbl_gage_spa1 = 0.0
# bolt diameter
bolt_size1 = 0.75
# hole type in leg against beam -
holeTypeList
hole_type_flg = "Standard Round"
# bolt type in leg against beam Job().bolt_sched()
bolt_type_flg = "A325N"
# slot rotation if applicable
"VT.", "HZ."
slot_rot1 = "VT."
###################################################################
## Function definition section
# Function to add angle material
def add_clip(mem, pt1, pt2, size, grade,
finish, orient, rot_args):
# rolled section begin
rl6 = RolledSection()
rl6.member = mem
rl6.pt1 = pt1
rl6.pt2 = pt2
rl6.section_size = size
rl6.grade = grade
rl6.centered = 'No'
rl6.llv = orient
rl6.toe_io = "In"
rl6.work_pt_dist = pt1.dist(pt2)
rl6.setback_left = 0
rl6.setback_right = 0
rl6.end_cut_left = "Standard
Cut"
rl6.end_cut_right = "Standard
Cut"
rl6.length = pt1.dist(pt2)
rl6.mtrl_type = 'Angle'
rl6.finish = finish
rl6.ref_pt_offset = (0.000000,
0.000000, 0.000000)
rl6.add()
rl6.rotate(rl6.member, rot_args)
# rolled section end
return rl6
# Function to add holes in clip angle
def moment_clip_hole (mat, pt1, ht,
hl_face, x_off, y_off, dgs, hole_rot, bt, db, gr):
if dgs >= 2.6667*db:
no_row = 2
else:
no_row = 1
try:
# hole group add begin
hole26 = Hole()
hole26.mtrl = [mat, ]
hole26.pt1 = pt1 # +
mat.translate(0.0, 0.0, y_off)
hole26.hole_type = ht
hole26.face = hl_face
hole26.valid_cnc = "Yes"
hole26.x_ref_offset = x_off
hole26.y_ref_offset = y_off
hole26.x_spa = 0.0
hole26.y_spa = dgs
hole26.group_rot = gr
hole26.locate = "Above"
hole26.columns = 1
hole26.rows = no_row
hole26.bolt_type = bt
hole26.bolt_dia = db
hole26.slot_rot = hole_rot
hole26.length =
hole26.calc_slot_length()
hole26.hole_dia = hole26.calc_hole_size()
hole26.show_window =
"Yes"
hole26.create()
# hole group add end
except: pass
# define function to return web gage of
column to use as default
def ret_web_ga(mem):
if mem.nom_depth < 9.0:
return 3.0
elif mem.nom_depth < 11.0:
return 4.0
else:
return 6.0
# End function definitions
#####################################################################
## import defaults data if enabled
if enable_default_import_export ==
"Enable":
dd0 =
import_data(os.path.join(default_file_path, def_file))
if dd0:
for key, value in dd0.items():
exec "%s = %s" %
(key, repr(value)) in None
#####################################################################
## Main program loop
################################################
while True:
bm_list = mem_select("Select
if bm_list is None:
break
mem1 = bm_list[0]
#############################################################
# Check framing conditions at ends of
beam, calculate default gage in column face
a = ColumnSupport(mem1, 2.0)
if a.left_member <>
"None":
b = ColumnCondition(a.left_member,
mem1, 2.0)
left_end_face = b.frmg_face()
left_col_mark =
a.left_member.piecemark
left_col_size = a.left_member.size
if left_end_face == "Face
B" or left_end_face == "Face D":
col_leg_ga_left =
ret_web_ga(a.left_member)
else:
col_leg_ga_left = a.left_member.gage
else:
col_leg_ga_left = col_leg_ga
left_end_face = "None"
left_col_mark = "None"
left_col_size = "None"
if a.right_member <>
"None":
c = ColumnCondition(a.right_member,
mem1, 2.0)
right_end_face = c.frmg_face()
right_col_mark =
a.right_member.piecemark
right_col_size =
a.right_member.size
if right_end_face == "Face
B" or right_end_face == "Face D":
col_leg_ga_right =
ret_web_ga(a.right_member)
else:
col_leg_ga_right =
a.right_member.gage
else:
col_leg_ga_right = col_leg_ga
right_end_face = "None"
right_col_mark = "None"
right_col_size = "None"
# gage of beam flange for beam flange
leg
flg_ga = mem1.gage
# Dialog refresh loop
while True:
# Check for valid clip angle
material and determine leg data
try:
clip_shape = Shape(clip_size)
sh1 = Shape(clip_size)
if llv_llh == "LLV":
leg_to_column =
sh1.LL_depth
leg_to_beam = sh1.SL_depth
else:
leg_to_column =
sh1.SL_depth
leg_to_beam = sh1.LL_depth
except:
# If clip_size is invalid, set
to known valid material
# Default gages in the dialog
box are calculated from the shape attributes
clip_size =
"L4x4x1/2"
Warning("The default clip
angle material size is invalid")
#############################################################
## DIALOG
#############################################################
dlg1 = Dialog( "Add end moment
clips to a beam" )
dlg1.menu("print_doc",
("Yes", "No"), "No", "Print documentation
only
")
dlg1.tabset_begin()
dlg1.tab("General
Information")
dlg1.group_title("Supporting
Columns")
dlg1.line("Column member at
left end of beam: %s - %s - %s" %
(left_col_size, left_col_mark,
left_end_face))
dlg1.line("Column member at
right end of beam: %s - %s - %s" % (right_col_size, right_col_mark, right_end_face))
dlg1.group_title_end
dlg1.group_title("Locations
Required")
dlg1.menu("which_end",
("Left", "Right", "Both"), which_end,
"Select Which End of Beam" )
dlg1.menu("t_or_b",
("Top", "Bott", "Both"), t_or_b, "Select
Top, Bottom or Both" )
dlg1.entry("extend_clip",
extend_clip, 'Project clip beyond minus dimension')
dlg1.group_title_end
dlg1.group_title("Clip Angle
Data")
dlg1.entry("clip_size",
clip_size, "Enter material size")
dlg1.menu("llv_llh",("LLV", "LLH"),
llv_llh, "Long leg vert or horizontal?")
dlg1.menu("steelgrade",Job().steel_grades("Angle").keys(),
steelgrade, "Select material grade" )
dlg1.menu("clip_finish",
finishList, clip_finish, "Select material color" )
dlg1.entry("edge_dist",
dim_print(edge_dist), "Enter minimum edge distance at holes")
dlg1.group_title_end
dlg1.group_title("Refresh
Dialog Box")
dlg1.menu("refresh_dialog", ("Refresh",
"Continue"), "Continue", "Refresh dialog box or
continue")
# dlg1.image(image_name7)
dlg1.group_title_end
dlg1.tab("Holes/Bolts in Beam
Leg")
dlg1.group_title("Hole
information in CLIP
dlg1.line("If weld is
selected, bolts/holes in beam flange leg will be disabled")
dlg1.label(dim_print(leg_to_beam),
"Angle leg width against
if add_clip_weld == 'Yes':
add_flg_hls = 'No'
dlg1.menu( "add_flg_hls",
("Yes", "No"), add_flg_hls, "Bolt clip to beam
flange")
dlg1.entry( "flg_ga",
dim_print(flg_ga), "Enter
dlg1.entry( "clip_gage1",
dim_print(clip_gage1), "Enter gage of CLIP
dlg1.entry( "bolt_size1",
dim_print(bolt_size1), "Enter bolt size in CLIP
dlg1.entry(
"dbl_gage_spa1", dim_print(dbl_gage_spa1), "DBL GAGE SPACING (0
for single ga.)")
dlg1.menu( "bolt_type_flg",
Job().bolt_sched(), bolt_type_flg, "Bolt type in CLIP
dlg1.menu(
"hole_type_flg", holeTypeList, hole_type_flg, "Hole type in CLIP
dlg1.menu( "slot_rot1",
("VT.", "HZ."), slot_rot1, "Slot rotation in CLIP
dlg1.group_title_end
dlg1.tab("Holes/Bolts in
Column Leg")
dlg1.group_title("Supporting
Columns")
dlg1.line("Column member at
left end of beam: %s - %s - %s" %
(left_col_size, left_col_mark,
left_end_face))
dlg1.line("Column member at
right end of beam: %s - %s - %s" % (right_col_size, right_col_mark, right_end_face))
dlg1.group_title_end
dlg1.group_title("Hole
information in CLIP
dlg1.label(dim_print(leg_to_column), "Angle leg width against
COLUMN")
dlg1.entry(
"col_leg_ga_left", dim_print(col_leg_ga_left), "Enter COLUMN
GAGE LEFT END")
dlg1.entry(
"col_leg_ga_right", dim_print(col_leg_ga_right), "Enter COLUMN
GAGE RIGHT END")
dlg1.entry( "bolt_size",
dim_print(bolt_size), "Enter bolt size in OSL")
dlg1.entry( "clip_gage", dim_print(clip_gage),
"Enter gage of OSL")
dlg1.entry(
"dbl_gage_spa", dim_print(dbl_gage_spa), "Dbl gage spa. (0 for
single ga.)")
dlg1.menu(
"bolt_type_col", Job().bolt_sched(), bolt_type_col, "Bolt type
in OSL")
dlg1.menu(
"hole_type_col", holeTypeList, hole_type_col, "Hole type in
OSL")
dlg1.menu( "slot_rot",
("VT.", "HZ."), slot_rot, "Slot rotation in OSL")
dlg1.group_title_end
dlg1.tab("Weld")
dlg1.line("If weld is selected,
bolts/holes in beam flange leg will be disabled")
dlg1.menu("add_clip_weld", ("Yes", "No"),
add_clip_weld, "Add weld moment clip to beam" )
dlg1.menu("clip_weld_type", ("Fillet", ),
clip_weld_type, "Select weld type" )
dlg1.menu("weld_size",
wsList, weld_size, "Enter weld size")
dlg1.tab("Illustration")
dlg1.image(image_name1)
dlg1.tab("Images")
dlg1.column_group_begin()
dlg1.column(0)
dlg1.image(image_name2)
dlg1.column(0)
dlg1.image(image_name3)
dlg1.column_group_end()
dlg1.tabset_end()
try:
dd = dlg1.done()
except ResponseNotOK:
break
# Update the local namespace
for key, value in dd.items():
exec "%s = %s" %
(key, repr(value)) in None
###############################################################
## END DIALOG
###############################################################
if refresh_dialog ==
"Continue":
break
if print_doc == "Yes":
print __doc__
break
try:
clip_shape = Shape(clip_size)
except:
# If clip_size is invalid, set to
known valid material and break out of the loop to return to member selection.
# Default gages in the dialog box
are calculated from the shape attributes
clip_size = "L6x4x3/8"
Warning("The clip angle
material size entered is invalid - resetting to 'L6x4x3/8'")
break
if add_clip_weld == 'Yes':
add_flg_hls = "No"
dd['add_flg_hls'] = "No"
# Export defaults to disk if enabled
if enable_default_import_export ==
"Enable":
export_data(os.path.join(default_file_path, def_file), dd)
#############################################################
# Set slot rotations
if slot_rot == "VT.":
rot1 = 90.0
else:
rot1 = 0.0
if slot_rot1 == "VT.":
rot2 = 90.0
else:
rot2 = 0.0
# Set leg orientation
if llv_llh == "LLV":
leg_orient = "VT."
else:
leg_orient = "HZ."
# Set hole faces
if leg_orient == "VT.":
face = "Web FS"
face1 = "Top Face"
else:
face = "Top Face"
face1 = "Web FS"
## Begin beam loop
for bm_mem in bm_list:
# Calculate material work points,
add clips, welds, and holes as required
if which_end == "Right"
or which_end == "Both":
# Calculate length of clip
angle
if add_flg_hls ==
"Yes":
matl_length = max ((flg_ga
+ edge_dist * 2.0), (col_leg_ga_right + edge_dist * 2.0))
else:
matl_length =
(col_leg_ga_right + edge_dist * 2.0)
pt10 = bm_mem.right_location
# Calculate clip WP at member
right minus dimension
pt11 = pt10 +
bm_mem.translate(-bm_mem.right.minus_dim + extend_clip, 0.0, 0.0)
pt12 = pt11 +
bm_mem.translate(0.0, 0.0, -matl_length/2.0)
pt13 = pt12 +
bm_mem.translate(0.0, 0.0, matl_length)
pt14 = pt11 +
bm_mem.translate(0.0, -(round(bm_mem.depth*16.0)/16.0), 0.0)
pt15 = pt14 +
bm_mem.translate(0.0, 0.0, -matl_length/2.0)
pt16 = pt15 +
bm_mem.translate(0.0, 0.0, matl_length)
if t_or_b == "Top" or
t_or_b == "Both":
rl1 = add_clip( bm_mem, pt12, pt13,
clip_size, steelgrade, clip_finish, leg_orient, (-90.0, 90.0, 0.0))
moment_clip_hole(rl1, pt11,
hole_type_col, face, col_leg_ga_right/2, clip_gage,\
dbl_gage_spa, rot1,
bolt_type_col, bolt_size, 180.0)
if add_flg_hls ==
"Yes":
moment_clip_hole (rl1,
pt11, hole_type_flg, face1, flg_ga/2, clip_gage1,\
dbl_gage_spa1, rot2, bolt_type_flg, bolt_size1, 0.0)
if add_clip_weld == 'Yes':
mtrl_weld([bm_mem.main_mtrl(), ], [rl1, ], weld_size, clip_weld_type)
if t_or_b == "Bott"
or t_or_b == "Both":
rl2 = add_clip(bm_mem,
pt16, pt15, clip_size, steelgrade, clip_finish, leg_orient, (90.0, -90.0, 0.0))
moment_clip_hole(rl2, pt14,
hole_type_col, face, col_leg_ga_right/2, clip_gage,\
dbl_gage_spa, rot1, bolt_type_col, bolt_size, 180.0)
if add_flg_hls ==
"Yes":
moment_clip_hole (rl2,
pt14, hole_type_flg, face1, flg_ga/2, clip_gage1,\
dbl_gage_spa1, rot2, bolt_type_flg, bolt_size1, 0.0)
if add_clip_weld == 'Yes':
mtrl_weld([bm_mem.main_mtrl(), ], [rl2, ], weld_size, clip_weld_type)
if which_end == "Left" or
which_end == "Both":
# Calculate length of clip
angle
if add_flg_hls ==
"Yes":
matl_length = max ((flg_ga
+ edge_dist * 2.0), (col_leg_ga_left + edge_dist * 2.0))
else:
matl_length =
(col_leg_ga_left + edge_dist * 2.0)
pt10 = bm_mem.left_location
# Calculate clip WP at member
left minus dimension
pt11 = pt10 +
bm_mem.translate(bm_mem.left.minus_dim - extend_clip, 0.0, 0.0)
pt12 = pt11 +
bm_mem.translate(0.0, 0.0, matl_length/2.0)
pt13 = pt12 +
bm_mem.translate(0.0, 0.0, -matl_length)
pt14 = pt11 +
bm_mem.translate(0.0, -(round(bm_mem.depth*16.0)/16.0), 0.0)
pt15 = pt14 +
bm_mem.translate(0.0, 0.0, matl_length/2.0)
pt16 = pt15 +
bm_mem.translate(0.0, 0.0, -matl_length)
if t_or_b == "Top" or
t_or_b == "Both":
rl3 = add_clip( bm_mem,
pt12, pt13, clip_size, steelgrade, clip_finish, leg_orient, (-90.0, -90.0,
0.0))
moment_clip_hole (rl3,
pt11, hole_type_col, face, col_leg_ga_left/2, clip_gage,\
dbl_gage_spa, rot1, bolt_type_col, bolt_size, 180.0)
if add_flg_hls ==
"Yes":
moment_clip_hole (rl3,
pt11, hole_type_flg, face1, flg_ga/2, clip_gage1,\
dbl_gage_spa1, rot2, bolt_type_flg, bolt_size1, 0.0)
if add_clip_weld == 'Yes':
mtrl_weld([bm_mem.main_mtrl(),
], [rl3, ], weld_size, clip_weld_type)
if t_or_b == "Bott"
or t_or_b == "Both":
rl4 = add_clip( bm_mem,
pt16, pt15, clip_size, steelgrade, clip_finish, leg_orient, (90.0, 90.0, 0.0))
moment_clip_hole (rl4,
pt14, hole_type_col, face, col_leg_ga_left/2, clip_gage,\
dbl_gage_spa, rot1, bolt_type_col, bolt_size, 180.0)
if add_flg_hls ==
"Yes":
moment_clip_hole (rl4,
pt14, hole_type_flg, face1, flg_ga/2, clip_gage1,\
dbl_gage_spa1, rot2, bolt_type_flg, bolt_size1, 0.0)
if add_clip_weld == 'Yes':
mtrl_weld([bm_mem.main_mtrl(), ], [rl4, ], weld_size, clip_weld_type)
if not yes_or_no("Add moment clips
to another beam?"):
break
## End
script #######################################################
if
__name__ == '__main__':
try:
run_script()
finally:
del run_script