## Col_BntPLConn.py Version 1.00
## Copyright (c) 2007 Bruce Vaughan, BV
Detailing & Design, Inc.
## All rights reserved.
## NOT FOR
############################################################################
"""
Add a one-sided
bent plate to a WF or Tube column as a connection for a selection set of skewed
WF beams -
The bent plate is
welded to the column, and the beam field bolts to the bent plate.
The bent plate
orientation can be conventional, hooked, wrapped, or hooked and wrapped.
The hooked bent
plate orientation is not applicable to tube columns. The bent plate will be
attached
to the flange of
a wide flange column. The bent plate can be attached to the short side
(flange), the
long side (web),
or both sides (for a knife connection) of a tube column.
The the work
point of the beam should coincide with the column CL. The script will work if
the WP
location offsets,
but the user will have to manually move the bent plate into the proper
location.
The calculates
and sets the proper beam minus dimension.
The script adds a
hole pattern to the beam web and matches for bolting.
This script can
be executed in plan, elevation, or isometric, and was tested in
This script was
originally developed in
does not work in
This script can
be executed in plan, elevation, or isometric.
Version History:
1.00 (
NOTE:
The beam end
distance from the bolt column is hard coded 2*bolt_diameter.
#############################################################
#### NOTE: This
version is not compatible with
#############################################################
Developed by
Bruce Vaughan, BV Detailing & Design, Inc. (BVD)
For comments,
suggestions or questions call BV at the number above, email bvdet@comcast.net,
or post to
Go to defaults
section to set script defaults.
"""
# startup code
begin
import os
import sys
from
macrolib.FileDefaults import import_data, export_data
from macrolib.L3D
import LineLineIntersect3D, ret_WP
from
macrolib.angle import rtod, dtor, angle_between_members
from
macrolib.ExceptWarn import formatExceptionInfo
from
macrolib.bp_data import BPdata
from
macrolib.MemSelection import mem_select, memAreaSelect
from
macrolib.Weld import mtrl_weld
from
macrolib.bolt_match import bolt_match, hole_bolt_match
from
macrolib.round_length import round_length_near
from param import
*
from math import
*
Units("feet")
from shape import
Shape
from point import
Point, PointLocate
from member
import Member, MemberLocate
from mtrl_list
import MtrlLocate, HoleLocate, MtrlByGuid
from rect_plate
import RectPlate
from bnt_plate
import BntPlate
from
rolled_section import RolledSection
from hole_add
import Hole
from bolt_add
import Bolt
from job import
Job, ProcessJob, ProcessOneMem
from fab import
Fabricator
epsilon =
0.000001
# startup code
end
def run_script():
#####################################################################
## Variables section
# system path for defaults file
default_file_path = os.path.join(os.getcwd(),
"macro", "Defaults")
# defaults file name
def_file = "Col_BntPLConn.txt"
# Path to image files and file names
image_path = os.path.join(os.getcwd(),
"macro", "Images")
image_name = os.path.join(image_path,
"Col_BntPLConn.gif")
image_name1 = os.path.join(image_path,
"Col_BntPLConn1.gif")
image_name2 = os.path.join(image_path,
"Col_BntPLConn2.gif")
image_name3 = os.path.join(image_path,
"Col_BntPLConn3.gif")
image_name4 = os.path.join(image_path,
"Col_BntPLConn4.gif")
# enable or disable the importing and
exporting of dialog dictionary
# variables "Enable"
"Disable"
enable_default_import_export =
"Enable"
holetypeList = ["Standard Round",
"Short Slot", "Oversized Round", "Long Slot"]
finishList = ["None", "Red
Oxide", "Yellow Zinc", "Gray Oxide",
"Sandblasted", "Blued Steel", "Galvanized"]
conntypeList = ["Conventional",
"Hooked", "Wrapped", "HookWrap"]
bolttypeList = Job().bolt_sched()
weldtypeList = ["Fillet", ]
weldsizeList = ['3/16', '1/4', '5/16',
'3/8', '7/16', '1/2']
sideList = ["Short Side",
"Long Side", "Both Sides"]
boltOptionsList = ["Match Holes",
"Match Holes/Bolts", "Process", "Do Nothing"]
#####################################################################
## Defaults section
# cut a section at the bent plate
"Yes", "No"
cut_sect = "Yes"
# option for matching holes and adding
bolts to beam material
boltOptions = "Process"
# bent plate orientation - conntypeList
conn_type = "Conventional"
# distance to first hole from T/S
dist_1st = 3.0
# number of bolt columns (2 columns =
double gage)
no_cols = 1
# spacing of bolt rows
row_spa = 3.0
# spacing of bolt columns
col_spa = 3.0
# gage on bent plate material from outside
bend corner
bp_ga = 2.5
# thickness of bent plate material
bp_thk = 0.375
# edge distance at end of bp material
end_ed = 1.5
# horizontal edge distance
hor_ed = 1.5
# width of bent plate leg attached to
column
osl_width = 4.0
# bent plate material finish
mtrl_finish = "Gray Oxide"
# bent plate material grade
Job().steel_grades("Plate").keys()
mtrl_grade = "A36"
# bolt diameter
bolt_size = 0.75
# hole type in web leg - holetypeList
hole_type_web = "Short Slot"
# bolt type in web leg - bolttypeList
bolt_type_web = "A325N"
# Welding
add_weld = "Yes"
# weld type
weld_type = "Fillet"
# weld size - weldsizeList
weld_size = 0.25
# weld all around "No"
"Yes"
weld_around = "No"
# if column is HSS, add bent plate to
flange or web
# "Short Side", "Long
Side", "Both Sides"
bp_location = "Short Side"
###########################################################
## Function definition section ######
#####################################
# function to add bent plate material
def add_bent_pl (mem, p1, mtrl_length,
grade, thk, bend, bolt_leg, col_leg, finish, rot):
# bent plate begin
bp1 = BntPlate()
bp1.member = mem
bp1.pt1 = p1
bp1.pt2 = p1 +
mem.translate(mtrl_length, 0.0, 0.0)
bp1.grade = grade
bp1.centered = "No"
bp1.thick = thk
bp1.bend_angle = bend
bp1.bend_radius = thk
bp1.leg = bolt_leg
bp1.osl = col_leg
bp1.work_pt_dist =
bp1.pt1.dist(bp1.pt2)
bp1.setback_left = 0
bp1.setback_right = 0
bp1.length = bp1.work_pt_dist -
bp1.setback_left - bp1.setback_right
bp1.mtrl_type = "Bent plate"
bp1.mtrl_usage = "one-sided
bp1.finish = finish
bp1.ref_pt_offset = (0.000000,
0.000000, 0.000000)
bp1.add()
bp1.rotate(bp1.member, rot)
# bent plate end
return bp1
###########################################################
# function to add a hole pattern to the
bent plate material
def add_bp_holes (m, patt_WP, ht, xs, ys,
cols, rows, bt, bd):
# hole group add begin
hole4 = Hole()
hole4.mtrl = [m, ]
hole4.pt1 = hole4.mtrl.location +
hole4.mtrl.translate(patt_WP[0], -patt_WP[1], 0.000000)
hole4.hole_type = ht
hole4.face = "Web FS"
hole4.valid_cnc = "Yes"
hole4.x_ref_offset = 0
hole4.y_ref_offset = 0
hole4.x_spa = xs
hole4.y_spa = -ys
hole4.group_rot = 0
hole4.locate = "Below Right"
hole4.columns = cols
hole4.rows = rows
hole4.bolt_type = bt
hole4.bolt_dia = bd
hole4.slot_rot = 90.0
hole4.length = hole4.calc_slot_length()
hole4.hole_dia = hole4.calc_hole_size()
hole4.show_window = "Yes"
hole4.create()
# hole group add end
return hole4
# function to add a hole pattern to the
beam material
def add_bm_holes (bm, pt, ht, ys, xs, rows,
cols, bt, bd, we):
if we == "left end":
loc = "Below Right"
else:
loc = "Below Left"
# hole group add begin
hole4 = Hole()
hole4.mtrl = [bm, ]
hole4.pt1 = bm.left.location
hole4.hole_type = ht
hole4.face = "
hole4.valid_cnc = "Yes"
hole4.x_ref_offset = pt.x
hole4.y_ref_offset = pt.y
hole4.x_spa = xs
hole4.y_spa = ys
hole4.group_rot = 0
hole4.locate =loc
hole4.columns = cols
hole4.rows = rows
hole4.bolt_type = bt
hole4.bolt_dia = bd
hole4.slot_rot = 0.0
hole4.length = hole4.calc_slot_length()
hole4.hole_dia = hole4.calc_hole_size()
hole4.show_window = "Yes"
hole4.create()
# hole group add end
return hole4
###########################################################
# define function to return default number
of bolt rows
# (bolt columns with respect to bent plate
material)
def row_list(mem):
try:
return Job().min_shear(mem.nom_depth).num_rows
except:
return 3
###########################################################
####### End function definitions section
##################
###########################################################
# if enabled, import defaults used
previously from disk file
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
##
while True:
try:
ClearSelection()
# Section for member selection
colList = mem_select("Select a
WF or TUBE COLUMN member", ['Column', ], \
['W flange',
'Tube'], single=True, all_mks=False)
if not colList:
break
mem1 = colList[0]
bmList = memAreaSelect("Select
WF
["Beam"], ['W flange',])
if not bmList:
Warning("You did not pick
any beams of the right material type. Exiting script.")
break
## Begin beam loop
####################################
for bi, bm in enumerate(bmList):
no_rows = row_list(bm)
if isinstance(weld_size, str):
weld_size = dim(weld_size)
#############################################################
## DIALOG
#############################################################
dlg1 = Dialog( "Beam to
column one-sided bent plate connection" )
dlg1.menu("print_doc", ("Yes", "No"),
"No", "Print documentation only")
dlg1.line("Column (%s, %s)
Plan rotation: %0.4f" % (mem1.piecemark, mem1.section_size,
mem1.rotation))
dlg1.line("Beam (%s, %s)
Plan rotation: %0.4f" % (bm.piecemark, bm.section_size, bm.plan_rotation))
dlg1.tabset_begin()
dlg1.tab("General")
dlg1.group_title("General
options (**not available in this version of
dlg1.menu("conn_type", conntypeList, conn_type,
"Connection orientation
")
dlg1.menu("boltOptions", boltOptionsList, boltOptions,
"Hole match options")
dlg1.menu("cut_sect",
['Yes', 'No'], cut_sect, "Cut a column section**")
dlg1.menu("mtrl_grade",
Job().steel_grades("Plate").keys(), mtrl_grade, "Material
grade")
dlg1.menu("mtrl_finish", finishList, mtrl_finish,
"Material finish")
if mem1.mtrl_type ==
"Tube":
dlg1.menu("bp_location", sideList, bp_location, "Apply
bent plate to which side?")
dlg1.group_title("Connection options")
dlg1.entry("dist_1st", dim_print(dist_1st), "Distance to
first bolt row")
dlg1.entry("no_rows",
no_rows, "Number of bolt rows")
dlg1.entry("no_cols",
no_cols, "Number of bolt cols")
dlg1.entry("row_spa",
dim_print(row_spa), "Bolt row spacing")
dlg1.entry("col_spa",
dim_print(col_spa), "Bolt column spacing")
dlg1.entry("bp_ga",
dim_print(bp_ga), "Gage to 1st bolt column")
dlg1.group_title("Bent plate
dimensions" )
dlg1.entry("osl_width", dim_print(osl_width), "Leg width
against column")
dlg1.entry("bp_thk",
dim_print(bp_thk), "Thickness of bent plate")
dlg1.entry("end_ed",
dim_print(end_ed), "
dlg1.entry("hor_ed",
dim_print(hor_ed), "
dlg1.tab("Bolts/Holes")
dlg1.group_title("Bolt
options")
dlg1.entry("bolt_size", dim_print(bolt_size), "Enter bolt
diameter")
dlg1.menu("bolt_type_web", bolttypeList, bolt_type_web,
"Bolt type in bent plate")
dlg1.menu("hole_type_web", holetypeList, hole_type_web,
"Hole type in bent plate")
dlg1.group_title("Wrapped bent plate
connection")
dlg1.image(image_name3)
dlg1.tab("Weld" )
dlg1.group_title("General
Information")
dlg1.menu("add_weld",
("Yes", "No"), add_weld, "Add bent plate to column
weld" )
dlg1.menu("weld_type", weldtypeList, weld_type, "Weld
type")
dlg1.menu("weld_size", weldsizeList, dim_print(weld_size),
"Weld size")
dlg1.menu("weld_around", ("Yes", "No"),
weld_around, "Weld all around")
dlg1.group_title("Knifed
bent plate connection")
dlg1.image(image_name4)
dlg1.tab("Graphic")
dlg1.image(image_name)
dlg1.tab("Image")
dlg1.line("Hooked bent
plate connection")
dlg1.image(image_name1)
dlg1.line("Conventional
bent plate connection")
dlg1.image(image_name2)
dlg1.tabset_end()
try:
dd1 = dlg1.done()
except ResponseNotOK:
break
# Update the local namespace
for key, value in dd1.items():
exec "%s = %s" %
(key, repr(value)) in None
###############################################################
## END DIALOG
###############################################################
if enable_default_import_export
== "Enable":
export_data(os.path.join(default_file_path, def_file), dd1)
if print_doc == "Yes":
print __doc__
break
# sets option to flange if
column is not a tube
if mem1.mtrl_type == "W
flange":
bp_location = "Short
Side"
# Check for invalid orientation
if mem1.mtrl_type ==
"Tube":
if bp_location ==
"Both Sides" and conn_type != "Conventional":
conn_type =
"Conventional"
Warning("Column
has tube material - a conventionally oriented bent plate will be substituted
for the specified orientation.")
elif conn_type ==
"Hooked":
conn_type = "Conventional"
Warning("Column
has tube material - a conventionally oriented bent plate will be substituted
for a hooked one.")
elif conn_type ==
"HookWrap":
conn_type =
"Wrapped"
Warning("Column has tube
material - a wrapped oriented bent plate will be substituted for a
hooked/wrapped one.")
# determine connection WP and
which end of member
ref_pt, which_end = ret_WP(mem1,
bm)
if bp_location == "Both
Sides":
loc_list = ["Short
Side", "Long Side"]
e_clr = 0.125
else:
loc_list = [bp_location, ]
e_clr = 0.0
beam_updated = False
bpList = []
for si in loc_list:
# determine angular
relationship and case number
hss_flg_web = si
a = BPdata(mem1, bm,
hss_flg_web, which_end, conn_type, bp_ga, bp_thk, e_clr)
rel_rotation = a.relRot
rotList = a.rot
case_no = a.caseno
bend_angle = a.bendAng
x_off, y_off, z_dist =
a.xyz_offsets()
# determine bent plate gage
to use if knife connection
if bp_location ==
"Both Sides":
zoffSS = BPdata(mem1,
bm, "Short Side", which_end, conn_type, bp_ga, bp_thk,
e_clr).xyz_offsets()[2]
zoffLS = BPdata(mem1,
bm, "Long Side", which_end, conn_type, bp_ga, bp_thk,
e_clr).xyz_offsets()[2]
if zoffSS < zoffLS
and hss_flg_web == "Short Side":
bp_ga1 = bp_ga +
zoffLS - zoffSS
z_dist = z_dist +
zoffLS - zoffSS
elif zoffLS < zoffSS
and hss_flg_web == "Long Side":
bp_ga1 = bp_ga + zoffSS - zoffLS
z_dist = z_dist +
zoffSS - zoffLS
else:
bp_ga1 = bp_ga
else:
bp_ga1 = bp_ga
# Calculate dimensions and
work points
matl_length = (end_ed *
2.0) + ((no_rows - 1) * row_spa)
webleg_width =
round_length_near(bp_ga1 + (no_cols - 1) * col_spa + hor_ed, '1/16')
bp_WP = ref_pt +
mem1.translate(0.0, -x_off, -y_off)
ptWP1 = bp_WP -
mem1.translate(dist_1st - end_ed, 0.0, 0.0)
ptWP2 = ptWP1 -
mem1.translate(matl_length, 0.0, 0.0)
if not beam_updated:
# set the beam end to
plain end, change setback, process
if which_end == 'left
end':
bm.left.auto_minus_dim = "No"
bm.left.minus_dim =
round_length_near(z_dist-(bolt_size*2), '1/16')
bm.left.auto_setback = "No"
bm.left.setback =
bm.left.minus_dim
bm.left.input_conn_type = 'Plain end'
else:
bm.right.auto_minus_dim = "No"
bm.right.minus_dim
= round_length_near(z_dist-(bolt_size*2), '1/16')
bm.right.auto_setback = "No"
bm.right.setback = bm.right.minus_dim
bm.right.input_conn_type = 'Plain end'
bm.update()
try:
ProcessOneMem(bm.number)
except:
Warning("Member process failed")
beam_updated = True
bm = Member(bm.number)
# add plate material,
holes, and weld
if case_no == "Case
2" or case_no == "Case 4":
if hss_flg_web ==
"Short Side":
bp11 = add_bent_pl
(mem1, ptWP1, matl_length, mtrl_grade, bp_thk, -bend_angle, \
webleg_width,
osl_width, mtrl_finish, rotList)
else:
bp11 = add_bent_pl
(mem1, ptWP2, matl_length, mtrl_grade, bp_thk, -bend_angle, \
webleg_width, osl_width, mtrl_finish,
rotList)
else:
if hss_flg_web ==
"Short Side":
bp11 = add_bent_pl
(mem1, ptWP2, matl_length, mtrl_grade, bp_thk, -bend_angle, \
webleg_width,
osl_width, mtrl_finish, rotList)
else:
bp11 = add_bent_pl
(mem1, ptWP1, matl_length, mtrl_grade, bp_thk, -bend_angle, \
webleg_width, osl_width, mtrl_finish,
rotList)
hlpatt = add_bp_holes(bp11,
(end_ed, bp_ga1), hole_type_web, row_spa, col_spa, no_rows, \
no_cols, bolt_type_web, bolt_size)
if add_weld ==
"Yes":
mtrl_weld([mem1, ],
[bp11, ], weld_size, weld_type, around=weld_around)
bpList.append(bp11)
# add hole pattern to the beam
# "Match Holes",
"Match Holes/Bolts", "Process", "Do Nothing"
if boltOptions == "Match
Holes":
hole_match(bm, hlpatt)
elif boltOptions == "Match
Holes/Bolts":
hole_bolt_match(bm, hlpatt,
bpList)
elif boltOptions ==
"Process":
try:
ProcessOneMem(bm.number)
except:
Warning("Process
member failed")
'''
ptLoc =
bm.trans_to_local(hlpatt.pt1 - bm.left_location)
add_bm_holes(bm, pt,
"Standard Round", row_spa, col_spa, no_rows, no_cols, bolt_type_web,
bolt_size, which_end)
bolt_match(bp11, bm)
'''
if bi < len(bmList)-1:
if not yes_or_no("Dist
from WP to first bolt column = %s (%0.4f)\rProceed?" % (dim_print(z_dist),
z_dist)):
break
# end beam loop
if not yes_or_no("Dist from WP
to first bolt column = %s (%0.4f)\nContinue?" % (dim_print(z_dist),
z_dist)):
break
except:
Warning(formatExceptionInfo())
break
## END
run_script() #######################################
if __name__ ==
'__main__':
try:
run_script()
finally:
ClearSelection()