Back to SDS/2 Parametric Scripts
## Beam_NailerHoles.py Version 1.07
## Copyright (c) 2006
## All rights
reserved.
## NOT FOR
########################################################################
"""
Add nailer holes
to WF beam flanges and web.
Flange gage is obtained from the material
file.
This script can be executed in plan,
elevation, or isometric.
R3 -
Add options for Top Flange, Bottom Flange, or Both Flages
- staggered or non-staggered
If non-staggered - NS, FS, or BS
R4 -
Add options for hole type and bolt type
Version 1.02 (
Version 1.03 (
Remove support
for
Add holes in
web
Add support for
short beams
Version 1.04 (
Pass hole add function if cols_ns and cols_fs = 0
Version 1.05 (
Version 1.06 (
Version 1.07 (
************************************************************
****NOTE: This version is not compatible
with
************************************************************
NOTE:
This script will read and write the
defaults to a disk file if so enabled in the "Defaults section". The
first time the script is executed the
defaults file will
be created. Subsequent script executions will import the defaults used in the
previous execution. Set the variable
"enable_default_import_export"
to "Disable" to disable this feature.
Developed in
Developed by
Mark Karpinsky,
New Jersey Iron, Inc.
For comments, suggestions or questions call
BVD at the number above or email bvaughan@bvdetailing.com
Go to Defaults section to modify defaults.
"""
# startup code begin
import sys
import traceback
from param import *
from math import *
Units("feet")
saved_sds2_version
= '7.002'
saved_python_version = (2, 1, 1, 'final', 0)
try:
from shape import
Shape
from point import
Point, PointLocate
from member import
Member, MemberLocate
from mtrl_list import MtrlLocate, HoleLocate
from cons_line import ConsLine
from cons_circle import ConsCircle
from rnd_plate import RndPlate
from rect_plate import RectPlate
from bnt_plate import BntPlate
from rolled_section import RolledSection
from weld_add import Weld
from flat_bar import FlatBar
from hole_add import Hole
from bolt_add import Bolt
from roll_plate import RollPl
from sqr_bar import SqrBar
from rnd_bar import RndBar
from shr_stud import ShrStud
from grate import
Grate
from grate_trd import GrateTrd
from deck import
Deck
from mtrl_fit import MtrlFit
from version import
CurrentVersion, VersionCompare
curr_version = CurrentVersion()
except ImportError:
curr_version =
'None'
def VersionCompare( v1, v2 ):
return -1
if
VersionCompare( curr_version,
'6.311' ) >= 0:
from job import
Job
from fab import Fabricator
if
VersionCompare( curr_version,
'6.312' ) >= 0:
from plate_layout import PlateLayout
if
VersionCompare( curr_version,
'6.314' ) >= 0:
from plate_layout import BntPlateLayout
if
VersionCompare( curr_version,
'6.4' ) >= 0:
from mtrl_cut import MtrlCut
import os
# startup code end
#######################################################################
##
Variables section
# system path for defaults file
default_file_path = os.path.join(os.getcwd(), "macro",
"Defaults")
# defaults file name
def_file = "Beam_NailerHoles.txt"
#
Path to image files and file names
image_path = os.path.join(os.getcwd(), "macro",
"Images")
image_name = os.path.join(image_path, "C:/ParamImg/Beam_NailerHoles.gif")
image_name1
= os.path.join(image_path,
"C:/ParamImg/Beam_NailerHoles1.gif")
image_name2
= os.path.join(image_path,
"C:/ParamImg/Beam_NailerHoles2.gif")
script_name = "Beam_NailerHoles_v1.07.py"
# default to enable or disable the importing and exporting of
dialog dictionary variables "Enable" "Disable"
enable_default_import_export = "Enable"
##
Defaults section
min_dist_left = "6" # default minimum distance
from left end of material
min_dist_right = "6" # default minimum distance from
right end of material
bolt_size = "1/2" # default bolt size
hole_type = "Standard Round" # "Standard Round",
"Oversized Round", "Plug Weld Hole"
type_bolt = "A325N" # type of bolt Job().bolt_sched()
nailer_spacing = "32" # default nailer
hole spacing
beam_face_list = ["Top Flange"] # "Top Flange", "Bottom
Flange", "Both Flanges", "Web"
stagger_yes_or_no = "Staggered" # "Staggered", "Not
Staggered"
which_side = "BS" # "NS",
"FS", "BS"
#
Defaults for web holes
dist_first = "3"
vert_spa = "6"
#######################################################################
##
Function definition section
def
form_script_variables():
# All variables are defined as strings in
defaults section. Defaults are saved to disk as dlg.done() defines them.
# Default variables must be reformatted for
imported data or for the second loop if not importing data.
# Only floating
point numbers need be reformatted. Integers should be formatted in the dialog
box.
global min_dist_left, min_dist_right, bolt_size, nailer_spacing, dist_first, vert_spa
min_dist_left = dim_print(dim(min_dist_left))
min_dist_right = dim_print(dim(min_dist_right))
bolt_size = dim_print(dim(bolt_size))
nailer_spacing = dim_print(dim(nailer_spacing))
dist_first = dim_print(dim(dist_first))
vert_spa = dim_print(dim(vert_spa))
##########################################################
##
Function definitions for saving default values to disk
##########################################################
def
import_data(file):
try:
ff =
open(file)
except:
# print
"There was an error opening the default data file. Please check your
directory path and that file exists."
return 0
else:
dd
= {}
key_values_list
= ff.readlines()[3:]
ff.close()
for ii in key_values_list:
key_name,
key_value = ii.split("=", 1)
dd[key_name.strip()]
= key_value.strip()
return dd
##########################################################################
def
export_data(file_name, dd_list, script_name): # pass
script name for default file
try:
f = open(file_name, "w")
f.write("Defaults file for script " + script_name
+ "\nVariable Name = Value Name\n\n")
for jj in dd_list:
for key_name in jj.keys():
key_value
= jj[key_name]
f.write("%s =
%s\n" % (key_name, key_value))
f.close()
except:
dd_list = 0
print "There was an error exporting the default data to
disk. Please check your directory path. "
return dd_list
########################################################################
#
begin definition of hole pattern add function
def
nailer_hole (mem, hl_ref_pt, x_off, y_off, c_c, ht, bd, bt, patt_type,
no_cols, no_rows, which_flg, v_spa):
try:
hole26 = Hole()
hole26.mtrl = [mem, ]
hole26.pt1 = hl_ref_pt
hole26.hole_type = ht
hole26.face = which_flg
hole26.valid_cnc = "Yes"
hole26.x_ref_offset = x_off
hole26.y_ref_offset = y_off
hole26.x_spa = c_c
hole26.y_spa = v_spa
hole26.group_rot = 0.0
hole26.locate = patt_type
hole26.columns = no_cols
hole26.rows = no_rows
hole26.bolt_type = bt
hole26.bolt_dia = bd
hole26.slot_rot = 0.0
hole26.length = hole26.calc_slot_length()
hole26.hole_dia = hole26.calc_hole_size()
hole26.show_window = "Yes"
hole26.create()
# hole group
add end
except:
yes_or_no("Error ading holes.\n" + formatExceptionInfo(),
"OK")
# end function definition
#
define function to return list of members with the same piecemark
def
member_count(mem):
mem_index = 1
no_mem = 0
mem_list = []
while no_mem < 100:
try:
mem2 = Member(mem_index)
except:
mem_index
= mem_index + 1
no_mem = no_mem + 1
else:
if
mem2.piecemark == mem.piecemark:
mem_list.append(mem2)
no_mem =
0
mem_index
= mem_index + 1
return mem_list
# end function definition
#######################################################################
# a
exception handler function to format the exception info into a string for dialog
display - credit
def
formatExceptionInfo(maxTBlevel=5):
cla,
exc, trbk = sys.exc_info()
excName
= cla.__name__
try:
excArgs = exc.__dict__["args"]
except KeyError:
excArgs = "<none>"
excTb
= traceback.format_tb(trbk,
maxTBlevel)
#- build the
return string ready to be displayed
_str =
"Error: " + excName + "\nDesc: "
for i in range(len(excArgs)):
_str = _str + excArgs[i]
+ "\n"
#for ii in range(len(excTb)):
_str = _str + excTb.pop() # + "\n"
return _str
#######################################################################
##
End function definitions
# if enabled, import defaults used previously from disk file
if
enable_default_import_export == "Enable":
try:
globals().update(import_data(os.path.join(default_file_path, def_file)))
except:
Warning("There
was a problem importing data - reverting to original defaults")
if beam_face_list == None:
beam_face_list
= "['Top Flange']"
try:
beam_face_list
= eval(beam_face_list)
except:
beam_face_list
= ['Top Flange']
##
Main program loop
while 1:
ClearSelection()
z = 1
bm_list = []
while z:
mem1 = MemberLocate("Select WF
or Std
if mem1 ==
None:
break
else:
if
mem1.type == "Beam":
if
mem1.mtrl_type in ["W flange", "S Shape",
"Channel"]:
z = 0
else:
Warning(mem1.mtrl_type
+ " beam material is not supported.")
else:
Warning("You
picked a " + mem1.type + ". You must pick a Beam.")
if mem1 == None:
break
else:
bm_list.append(mem1)
chk_mem_list =
member_count(bm_list[0])
if len(chk_mem_list) > 1:
if yes_or_no("Add nailer holes
to all members with the same piecemark (" + str(len(chk_mem_list)) + "
members with mark " + bm_list[0].piecemark +
")?") == 1:
bm_list =
chk_mem_list
form_script_variables()
flg_gage = bm_list[0].gage
## DIALOG
dlg1 = Dialog(
"Add Nailer Holes to WF Beams" )
dlg1.tabset_begin()
dlg1.tab("General
Information")
dlg1.column_group_begin()
dlg1.column(0)
dlg1.checkbutton("beam_face_list",
["Top Flange", "Bottom Flange", "Both Flanges",
"Web"], beam_face_list, "Select
Flange(s) or Web")
dlg1.group_title("Nailer hole pattern options")
dlg1.menu("stagger_yes_or_no", ("Staggered", "Not
Staggered"), stagger_yes_or_no, "Staggered
or Not Staggered")
dlg1.entry("nailer_spacing", nailer_spacing,
"Nailer Hole Spacing")
dlg1.entry("min_dist_left", min_dist_left,
"Minimum Distance Left End")
dlg1.entry("min_dist_right", min_dist_right,
"Minimum Distance Right End")
dlg1.group_title_end
dlg1.column(0)
dlg1.group_title("Bolt/Hole
Information")
dlg1.entry("flg_gage", dim_print(flg_gage), "Flange gage")
dlg1.entry("bolt_size", bolt_size,
"Bolt Size")
dlg1.menu("hole_type", ("Standard Round",
"Oversized Round", "Plug Weld Hole"), hole_type,
"Hole type")
dlg1.menu("type_bolt", Job().bolt_sched(),
type_bolt, "Bolt type")
dlg1.group_title_end
dlg1.group_title("Not
Staggered Option for Flanges")
dlg1.menu("which_side", ("NS", "FS",
"BS"), which_side, "Which Side")
dlg1.group_title_end
dlg1.group_title("Web
Hole Options")
dlg1.entry("dist_first", dist_first,
"Distance to first row")
dlg1.entry("vert_spa", vert_spa,
"Row spacing")
dlg1.column_group_end()
dlg1.image(image_name1)
dlg1.column_group_end()
dlg1.tab("Graphic
Image")
dlg1.image(image_name)
dlg1.line("Illustration
of the basic variables for adding nailer holes in the
flanges and web of beam members")
dlg1.tab("Short
Beam Image")
dlg1.group_title("Pairs
of holes each end will be added to short beams")
dlg1.image(image_name2)
dlg1.group_title_end
dlg1.tabset_end()
try:
dd1 = dlg1.done()
except ResponseNotOK:
break
globals().update(dd1)
try:
beam_face_list
= dd1['beam_face_list']
except KeyError:
beam_face_list
= []
## END DIALOG
# save defaults to
disk for the next time
if enable_default_import_export == "Enable":
export_data(os.path.join(default_file_path, def_file),
[dd1, ], script_name)
matl_length = bm_list[0].input_length - bm_list[0].left.setback - bm_list[0].right.setback
allow_out_to_out
= matl_length - min_dist_left
- min_dist_right
no_spa = int(floor(allow_out_to_out / nailer_spacing))
dist_left = min_dist_left + (allow_out_to_out/2) - (no_spa*nailer_spacing/2.0)
if allow_out_to_out <= nailer_spacing:
short_beam =
"Yes"
if allow_out_to_out <= nailer_spacing:
dimen_out_to_out
= allow_out_to_out
else:
dimen_out_to_out
= nailer_spacing
dist_left = min_dist_left
else:
short_beam =
"No"
dimen_out_to_out
= no_spa*nailer_spacing
if stagger_yes_or_no == "Staggered":
if no_spa/2 ==
float(no_spa)/2:
cols_ns =
int(float(no_spa)/2-1)
cols_fs =
int(float(no_spa)/2)
else:
cols_ns =
int(float(no_spa)/2)
cols_fs =
int(float(no_spa)/2)
for bi in
range(len(bm_list)):
ref_WP = bm_list[bi].left_location + bm_list[bi].translate(bm_list[bi].left.setback, 0.0,
0.0)
if
"Top Flange" in beam_face_list or
"Both Flanges" in beam_face_list:
nailer_hole(bm_list[bi],
ref_WP, dist_left,
flg_gage/2, dimen_out_to_out, hole_type,\
bolt_size,
type_bolt, "Center Right", 2, 1, 1, 0.0)
if short_beam == "No":
if
cols_ns > 0:
nailer_hole(bm_list[bi],
ref_WP, dist_left+nailer_spacing*2,
flg_gage/2, nailer_spacing*2, hole_type,\
bolt_size, type_bolt, "Below
Right", cols_ns, 1, 1, 0.0)
if
cols_fs > 0:
nailer_hole(bm_list[bi],
ref_WP, dist_left + nailer_spacing, flg_gage/2, nailer_spacing*2,
hole_type,\
bolt_size, type_bolt, "Above
Right", cols_fs, 1, 1, 0.0)
if
"Bottom Flange" in beam_face_list or
"Both Flanges" in beam_face_list:
nailer_hole(bm_list[bi],
ref_WP, dist_left,
flg_gage/2, dimen_out_to_out, hole_type,\
bolt_size,
type_bolt, "Center Right", 2, 1, 3, 0.0)
if short_beam == "No":
if
cols_ns > 0:
nailer_hole(bm_list[bi],
ref_WP, dist_left+nailer_spacing*2,
flg_gage/2, nailer_spacing*2, hole_type,\
bolt_size, type_bolt, "Below
Right", cols_ns, 1, 3, 0.0)
if
cols_fs > 0:
nailer_hole(bm_list[bi],
ref_WP, dist_left + nailer_spacing, flg_gage/2, nailer_spacing*2,
hole_type,\
bolt_size, type_bolt, "Above
Right", cols_fs, 1, 3, 0.0)
if
"Web" in beam_face_list:
nailer_hole(bm_list[bi],
ref_WP, dist_left, dist_first, dimen_out_to_out, hole_type,\
bolt_size,
type_bolt, "Below Right", 2, 2, 2, vert_spa)
if short_beam == "No":
if
cols_ns > 0:
nailer_hole(bm_list[bi],
ref_WP, dist_left+nailer_spacing*2,
dist_first, nailer_spacing*2,
hole_type,\
bolt_size, type_bolt, "Below
Right", cols_ns, 1, 2, 0.0)
if
cols_fs > 0:
nailer_hole(bm_list[bi],
ref_WP, dist_left+nailer_spacing,
dist_first+vert_spa, nailer_spacing*2,
hole_type,\
bolt_size, type_bolt, "Below
Right", cols_fs, 1, 2, 0.0)
else:
for bi in
range(len(bm_list)):
ref_WP = bm_list[bi].left_location + bm_list[bi].translate(bm_list[bi].left.setback, 0.0,
0.0)
if which_side == "NS":
hl_patt_ref
= "Below Right"
elif which_side ==
"FS":
hl_patt_ref
= "Above Right"
else:
hl_patt_ref
= "Center Right"
if short_beam == "No":
if
"Top Flange" in beam_face_list or
"Both Flanges" in beam_face_list:
nailer_hole(bm_list[bi],
ref_WP, dist_left,
flg_gage/2, nailer_spacing, hole_type,\
bolt_size, type_bolt, hl_patt_ref, no_spa + 1, 1, 1,
0.0)
if
"Bottom Flange" in beam_face_list or
"Both Flanges" in beam_face_list:
nailer_hole(bm_list[bi],
ref_WP, dist_left,
-flg_gage/2, nailer_spacing, hole_type,\
bolt_size, type_bolt, hl_patt_ref, no_spa + 1, 1, 3,
0.0)
if
"Web" in beam_face_list:
nailer_hole(bm_list[bi],
ref_WP, dist_left, dist_first, nailer_spacing, hole_type,\
bolt_size, type_bolt, hl_patt_ref, no_spa + 1, 2, 2, vert_spa)
else:
if
"Top Flange" in beam_face_list or
"Both Flanges" in beam_face_list:
nailer_hole(bm_list[bi],
ref_WP, dist_left,
flg_gage/2, allow_out_to_out, hole_type,\
bolt_size,
type_bolt, hl_patt_ref, 2,
1, 1, 0.0)
if
"Bottom Flange" in beam_face_list or
"Both Flanges" in beam_face_list:
nailer_hole(bm_list[bi],
ref_WP, dist_left,
-flg_gage/2, allow_out_to_out, hole_type,\
bolt_size, type_bolt, "Below
Right", 2, 1, 3, 0.0)
if
"Web" in beam_face_list:
nailer_hole(bm_list[bi],
ref_WP, dist_left, dist_first, allow_out_to_out, hole_type,\
bolt_size, type_bolt, "Below
Right", 2, 2, 2, vert_spa)
Add_nailer = yes_or_no("Add
nailer holes to another WF beam")
if Add_nailer == 0:
break
# xxxxxxxxxxxxxxxxxxxxxxxxxxxx end
script xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx