##  Col_RFStiff version 1.00

##  Copyright (c) 2006 Bruce Vaughan, BV Detailing & Design, Inc.

##  All rights reserved.

##  NOT FOR SALE. The software is provided "as is" without any warranty.

############################################################################

""" Add stiffener/continuity plates to a column and align with a beam.

    The default stiffener width based upon beam flange width: (bfb-twc)/2 + 0.0625 rounded off to the

    nearest 1/4".

    The default stiffener width based upon column "A" distance: (bfc-twc)/2 + 0.0625 rounded off to

    the nearest 1/4".

    The default stiffener thickness ("A" and "bf"): (beam tf + 0.03) rounded off to the nearest 1/8"

    The default stiffener length: mem1.depth-2 * mem1.tf - 0.0625 rounded off to the nearest 1/16".

    Thickness reference point on the stiffener material is "NS"

    If adding weld is elected, weld is added to the first stiffener only.

    The script performs an ASD code check using FF*5/3 (flange force * 1.67) and a default beam moment

    of Mr (0.66FySx/12).

    Stiffener offsets (if elected) are with respect to "Flush Top" at top stiffener and "Flush Bott"

    at bottom stiffener.

    The script does not account for the vertical dimensional offset due to beam slope and column depth.

    The user can account for it by selecting the "offset" option for stiffener alignment. The script

    does account for the gain in distance between the stiffeners due to beam slope.

  *****************************************************************************************************

    DISCLAIMER: The code check is for information only. Engineering evaluation of the calculations    *

                is required.                                                                          *

  *****************************************************************************************************

    Revision History

    R1 -    Allow for thicker top stiffener. Where the top of the column is flush with the top of the

            rigid frame beam, we usually make the top stiffener 1/4" (re: line 371) thicker and use a

            partial penetration groove weld on 3 sides.

    R2 -    Add extended shear tabs.

    R3 -    If make_top_thicker = "Yes", set condition so weld is added to first bottom stiffener,

            since top stiffener weld (BTC-P4-GF) will be added in IG.

    R4 -    Add option to set stiffener a vertical distance below top. Moved defaults to line 67.

            Edited hole pattern code to work in SDS/2 6.310 as follows:

            "Above Right">>"Above Left", "FS Face">>"NS Face", 0.0>>-45.0 group_rot, Slot direction 90.0>>0.0

            Create loops for column and beam members. Each joint gets a dialog box.

    R5 -    Update hole pattern code for SDS/2 version 6.325 (1/19/04)

            -45.0 >> 0.0 group_rot, Slot direction 0.0 >> 90.0, "Above Left" >> "Below Right"

            The combination of "Above Right" and "FS Face" also works

    Version 1.00 -  8/12/06 - Add capability to Save/Read script defaults from disk. Remove support for SDS/2 6.3xx.

                    Rework dialog boxes for tabs, group titles, image and organization.

                    Add support for partial depth extended shear tabs and stabilizer plates at bottom edge.

                    Add material usage descriptions:

                    Continuity Plate

                    Extended Shear Tab

                    Stabilizer

    ************************************************************

    ****NOTE: This version is not compatible with SDS/2 6.3.****

    ************************************************************            

 

    This script can be executed in plan, elevation, or isometric.

 

    This source is provided "as is."  All warranties are disclaimed.

    Developed in SDS/2 6.310  9/19/02 (Rev.4)  ***Will not work in 6.2xx***

 

    Developed by Bruce Vaughan, BV Detailing & Design, Inc. (BVD)  (615) 646-9239

    For comments, suggestions or questions call BVD at the number above.

 

    NOT FOR SALE

 

    Go to line "Defaults section" to set script defaults.

"""

# startup code begin

import sys

import traceback

import types

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

try:

    from os import path

    path_available = 1

except:

    path_available = 0

# startup code end

# start of defaults for stiffener plates xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# Variables section

enable_default_import_export = "Enable"                 # default to enable or disable the importing and exporting of dialog dictionary variables "Enable" "Disable"

default_file_path = "C:/ParamDef/Col_RFStiff/"          # system path for defaults file

def_file = "Col_RFStiff.txt"                            # defaults file name

script_name = "Col_RFStiff_v1.00.py"

image_name1 = "C:\ParamImg\Col_RFStiff1.gif"

image_name2 = "C:\ParamImg\Col_RFStiff2.gif"

# Defaults section

add_shr_tab = "No"                      # default add extended shear tabs "Yes", "No"

add_stf_tb = "Both"                     # default add stiffeners "Both", "Top", Bott", "None"

which_side = "BS"                       # default side(s) for stiffeners "BS" "NS" "FS"

which_stiff = "User"                    # default which stiffener to accept "Beam bf", "Column A", "User"

stiff_width = 4.75                      # default "user" stiffener width

stiff_thk = 0.75                        # default "user" stiffener thickness

stiff_color = "None"                    # default stiffener finish "None", "Red Oxide", "Yellow Zinc", "Gray Oxide", "Sandblasted", "Blued Steel", "Galvanized"

stiff_grade = "A36"                     # default steel grade

top_align = "Flush Top"                 # default alignment "Flush Top", "Flush Bott", Align CL", "Offset"

bot_align = "Flush Bott"                # default alignment "Flush Top", "Flush Bott", Align CL", "Offset", "Vert Dist"

top_offset = 0.0                        # default offset top stiffener

bot_offset = 0.0                        # default offset bottom stiffener

stiff_clip = 1.0                        # default stiffener corner clip

ad_stf_weld = "Yes"                     # default for adding stiffener weld       "Yes" "No"

stf_weld_type = "Fillet"                # default for weld type "Fillet" "Bevel groove" "Square butt"

stf_weld_size = 0.3125                  # default stiffener weld size

stiff_calc = "Fixed"                    # Flag to calculate weld size based on stiffener thickness or to use default "stf_weld_size" "Fixed, "Calc"

tail_text = "TYP"                       # default weld tail text

prt_code_chk = "No"                     # default to print ASD code check "Yes" "No"

top_stiff_extra = "1/8"

# end of defaults for stiffeners

# start of defaults for extended shear tabs xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

which_side_NS = "Right"                 # locate NS plate which side of column CL (right is preferred) "Right", "Left"

which_side_FS = "Left"                  # locate FS plate which side of column CL (left is preferred) "Right", "Left"

full_part_depth = "Partial Depth"       # ("Full Depth", "Partial Depth")

dist_1st = 3.0                          # distance to first hole from T/S

no_cols = 2                             # number of bolt columns (2 columns = double gage)

row_spa = 3.0                           # spacing of bolt rows

col_spa = 3.0                           # spacing of bolt columns

pl_thk = 0.5                            # thickness of plate material

vert_ed = 1.5                           # vertical edge distace from hole to edge of cope

add_bott_stab = "Yes"                   # ("Yes", "No")   

stab_width = "5 1/2"                    #

prep_list = ["Cope Top", "Cope Bott", "Clip Top", "Clip Bott"] # ["Cope Top", "Cope Bott", "Clip Top", "Clip Bott", "None"]

clip_dim = 0.75                         # shear plate clip dimension

pl_end_gap = 1.0                        # dimension from end of beam material to edge of cope

pl_color = "None"                       # shear plate finish "None", "Red Oxide", "Yellow Zinc", "Gray Oxide", "Sandblasted", "Blued Steel", "Galvanized"

pl_grade = "A36"                        # steel grade

bolt_size = 0.75                        # bolt diameter

hole_type_web = "Short Slot"            # hole type in web leg "Standard Round", "Short Slot", "Oversized Round", "Long Slot"

bolt_type_web = "A325N"                 # bolt type in web leg "A325N" "A307" "A325SC"

tab_weld_type = "Fillet"                # weld type "Fillet" "Bevel groove" "Square Butt"

tab_weld_size = 0.3125                  # weld size to column web

tabstf_weld_size = 0.25                 # weld size to stiffener

# set defaults for extended shear tab end  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# Define functions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# Function definitions

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 stiff_width, stiff_thk, top_offset, bot_offset, stiff_clip, stf_weld_size, top_stiff_extra

    stiff_width = dim_print(dim(stiff_width))

    stiff_thk = dim_print(dim(stiff_thk))

    top_offset = dim_print(dim(top_offset))

    bot_offset = dim_print(dim(bot_offset))

    stiff_clip = dim_print(dim(stiff_clip))

    stf_weld_size = dim_print(dim(stf_weld_size))

    top_stiff_extra = dim_print(dim(top_stiff_extra))

 

def form_script_variables2():

    global dist_1st, row_spa, col_spa, pl_thk, vert_ed, stab_width, clip_dim, pl_end_gap, bolt_size, tab_weld_size, tabstf_weld_size

    dist_1st = dim_print(dim(dist_1st))

    row_spa = dim_print(dim(row_spa))

    col_spa = dim_print(dim(col_spa))

    pl_thk = dim_print(dim(pl_thk))

    vert_ed = dim_print(dim(vert_ed))

    stab_width = dim_print(dim(stab_width))

    clip_dim = dim_print(dim(clip_dim))

    pl_end_gap = dim_print(dim(pl_end_gap))

    bolt_size = dim_print(dim(bolt_size))

    tab_weld_size = dim_print(dim(tab_weld_size))

    tabstf_weld_size = dim_print(dim(tabstf_weld_size))   

 

########################################################################################################################################################

## Function definitions for saving default values to disk

## See Python file "Script_Defaults.py" for usage documentation

########################################################################################################################################################

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

##################################################################################################################################################   

# convert radians to degrees

def rtod ( r ):

    return (r * 180.0 / pi)

# convert degrees to radians

def dtor ( d ):

    return (d * pi / 180.0)

# returns Fy of member based upon member grade (mem.grade)

# if member grade is not listed, the function will return 65.0

def ret_Fy (mem):

    if mem.grade == "A992":

        Fy = 50.0

    elif mem.grade == "A36":

        Fy = 36.0

    elif mem.grade == "A572-50":

        Fy = 50.0

    elif mem.grade == "A500B":

        Fy = 46.0

    else:

        Fy = 65.0

        print "Material grade not listed - returning 65 ksi"

    return Fy   

# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# define function to return the WP at the column CL

def ret_WP(mem11, mem12):

    global which_end

    dist1 = Point(mem11.left_location.x, mem11.left_location.y, 0.000000).dist(Point(mem12.left_location.x, mem12.left_location.y, 0.000000))

    dist2 = Point(mem11.left_location.x, mem11.left_location.y, 0.000000).dist(Point(mem12.right_location.x, mem12.right_location.y, 0.000000))

    if dist1 < dist2:

        pt1 = Point(mem11.left_location.x, mem11.left_location.y, mem12.left_location.z)

       

        which_end = "left end"

    else:

        pt1 = Point(mem11.left_location.x, mem11.left_location.y, mem12.right_location.z)

        which_end = "right end"

    return (pt1, which_end)

# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# add rectangular plate material

# returns a rectangular plate object

def stiff_pl(mem, pnt1, pnt2, pl_thk, rotpl):

    rot_arg = (rotpl[0], rotpl[1], (rotpl[2] - 0.0))

    # rectangular plate begin

    rp11 = RectPlate()

    rp11.member = mem

    rp11.pt1 = pnt1

    rp11.pt2 = pnt2

    rp11.grade = stiff_grade

    rp11.origin = "NS"

    rp11.top_oper_left = "Clip"

    rp11.top_length_left = stiff_clip

    rp11.top_clip_left = stiff_clip

    rp11.top_oper_right = "Clip"

    rp11.top_length_right = stiff_clip

    rp11.top_clip_right = stiff_clip

    rp11.bottom_oper_left = "None"

    rp11.bottom_oper_right = "None"

    rp11.width = stiff_width

    rp11.thick = pl_thk

    rp11.work_pt_dist = rp11.pt1.dist( rp11.pt2 )

    rp11.setback_left = 0

    rp11.setback_right = 0

    rp11.web_cut_angle_left = 0

    rp11.web_cut_angle_right = 0

    rp11.length = stiff_length

    rp11.mtrl_type = "Plate"

    rp11.mtrl_usage = "Continuity Plate"

    rp11.finish = stiff_color

    rp11.ref_pt_offset = (0.000000, 0.000000, 0.000000)

    rp11.add()

    rp11.rotate(rp11.member, rot_arg)

    # rectangular plate end

    return rp11

# add weld xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

def stiff_weld(weld_to_list, rl5, weld_size, weld_type, tt):

    if weld_type == "Fillet":

        allow_fillet = "Yes"

        allow_bevel = "No"

        allow_square = "Yes"

    elif weld_type == "Bevel groove":

        allow_fillet = "No"

        allow_bevel = "Yes"

        allow_square = "No"

    else:

        allow_fillet = "Yes"

        allow_bevel = "No"

        allow_square = "Yes"

    try:

        # weld add begin

        weld9 = Weld()

        weld9.mtrl = [rl5, ]

        weld9.weld_to = weld_to_list

        weld9.min_size = weld_size

        weld9.max_size = 1

        weld9.min_length = 1

        weld9.max_gap = 0.25

        weld9.stagger_length = 3

        weld9.stagger_spacing = 12

        weld9.holdback_length = 0

        weld9.root_face = 0

        weld9.root_opening = 0

        weld9.b_groove_angle = 45

        weld9.v_groove_angle = 60

        weld9.all_around = "No"

        weld9.stagger = "No"

        weld9.inside = "No"

        weld9.auto_size = 0

        weld9.full_penetration = "No"

        weld9.fillet_back = "No"

        weld9.holdback_end = 0

        weld9.prequalified = "No"

        weld9.backing_bar = 0

        weld9.spacer = 0

        weld9.contour = "None"

        weld9.allow_fillet = allow_fillet

        weld9.allow_square = allow_square

        weld9.allow_bevel = allow_bevel

        weld9.allow_v = "No"

        weld9.allow_j = "No"

        weld9.allow_u = "No"

        weld9.allow_flare_bevel = "No"

        weld9.allow_flare_v = "No"

        weld9.allow_plug = "No"

        weld9.allow_backing = "No"

        weld9.tail_text = ""

        weld9.show_window = "No"

        weld9.create()

        # weld add end

    except:

        pass

# add the shear tab xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

def plate_add(mem, pnt1, pnt2, rot1):

    rot_arg = (rot1[0], rot1[1], (rot1[2]))

    if cope_top:

        leftb_op = "Cope"

        cope_l_len = cope_top[0]

        cope_l_dep = cope_top[1]

    else:

        leftb_op = "None"

        cope_l_len = 0.0

        cope_l_dep = 0.0

    if cope_bott:

        rightb_op = "Cope"

        cope_r_len = cope_bott[0]

        cope_r_dep = cope_bott[1]

    else:

        rightb_op = "None"

        cope_r_len = 0.0

        cope_r_dep = 0.0

    if clip_top:

        leftt_op = "Clip"

        left_len = clip_top[0]

        left_dep = clip_top[1]

    else:

        leftt_op = "None"

        left_len = 0.0

        left_dep = 0.0

    if clip_bott:

        rightt_op = "Clip"

        right_len = clip_bott[0]

        right_dep = clip_bott[1]

    else:

        rightt_op = "None"

        right_len = 0.0

        right_dep = 0.0       

    # rectangular plate begin

    rp1 = RectPlate()

    rp1.member = mem

    rp1.pt1 = pnt1

    rp1.pt2 = pnt2

    rp1.grade = pl_grade

    rp1.origin = "FS"

    rp1.top_oper_left = leftt_op

    rp1.top_length_left = left_len

    rp1.top_clip_left = left_dep

    rp1.top_oper_right = rightt_op

    rp1.top_length_right = right_len

    rp1.top_clip_right = right_dep

    rp1.bottom_oper_left = leftb_op

    rp1.bottom_length_left = cope_l_len

    rp1.bottom_cope_left = cope_l_dep 

    rp1.bottom_oper_right = rightb_op

    rp1.bottom_length_right = cope_r_len

    rp1.bottom_cope_right = cope_r_dep

    rp1.width = pl_width

    rp1.thick = pl_thk

    rp1.work_pt_dist = rp1.pt1.dist( rp1.pt2 )

    rp1.setback_left = 0

    rp1.setback_right = 0

    rp1.web_cut_angle_left = 0

    rp1.web_cut_angle_right = 0

    rp1.length = pl_length

    rp1.mtrl_type = "Plate"

    rp1.mtrl_usage = "Extended Shear Tab"

    rp1.finish = pl_color

    rp1.ref_pt_offset = (0.000000, 0.000000, 0.000000)

    rp1.add()

    rp1.rotate(rp1.member, rot_arg)

    # rectangular plate end

    return rp1

# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# add holes to shear tab

# slots are rotated perpendicular to length of material

def pl_holes (rp1):

    try:

        # hole group add begin

        hole26 = Hole()

        hole26.mtrl = [rp1, ]

        hole26.pt1 = hole26.mtrl.location

        hole26.hole_type = hole_type_web

        hole26.face = "NS Face"

        hole26.valid_cnc = "Yes"

        hole26.x_ref_offset = hole_dim_x

        hole26.y_ref_offset = hole_dim_y

        hole26.x_spa = row_spa

        hole26.y_spa = col_spa

        hole26.group_rot = 0.0

        hole26.locate = "Below Right"

        hole26.columns = no_rows

        hole26.rows = no_cols

        hole26.bolt_type = bolt_type_web

        hole26.bolt_dia = bolt_size

        hole26.slot_rot = 90.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:

        pass

 

####################################################################   

def stabilizer_pl(bm, pnt1, pnt2, rotpl):

    # rectangular plate begin

    rp12 = RectPlate()

    rp12.member = bm

    rp12.pt1 = pnt1

    rp12.pt2 = pnt2

    rp12.grade = pl_grade

    rp12.origin = "NS"

    rp12.top_oper_left = "None"

    rp12.top_length_left = 0.0

    rp12.top_clip_left = 0.0

    rp12.top_oper_right = "None"

    rp12.top_length_right = 0.0

    rp12.top_clip_right = 0.0

    rp12.bottom_oper_left = "None"

    rp12.bottom_oper_right = "None"

    rp12.width = stab_width

    rp12.thick = pl_thk

    rp12.work_pt_dist = rp12.pt1.dist(rp12.pt2)

    rp12.setback_left = 0

    rp12.setback_right = 0

    rp12.web_cut_angle_left = 0

    rp12.web_cut_angle_right = 0

    rp12.length = stiff_length

    rp12.mtrl_type = "Plate"

    rp12.mtrl_usage = "Stabilizer"

    rp12.finish = pl_color

    rp12.ref_pt_offset = (0.000000, 0.000000, 0.000000)

    rp12.add()

    rp12.rotate(rp12.member, rotpl)

    # rectangular plate end

    return rp12

###########################################################################

# Default number of bolt rows (bolt columns with respect to plate material)

def row_list(matl):

    if matl[0:2] == "W8":

        return 2

    elif matl[0:3] == "W10":

        return 2

    elif matl[0:3] == "W12":

        return 3

    elif matl[0:3] == "W14":

        return 3

    elif matl[0:3] == "W16":

        return 4

    elif matl[0:3] == "W18":

        return 5

    elif matl[0:3] == "W21":

        return 5

    elif matl[0:3] == "W24":

        return 6

    elif matl[0:3] == "W27":

        return 7

    else:

        return 8

# Minimum length (depth) of partial depth extended shear tab

def tab_length(matl):

    if matl[0:2] == "W8":

        return 6.0

    elif matl[0:3] == "W10":

        return 6.75

    elif matl[0:3] == "W12":

        return 9.75

    elif matl[0:3] == "W14":

        return 11.75

    elif matl[0:3] == "W16":

        return 13.75

    elif matl[0:3] == "W18":

        return 15.75

    elif matl[0:3] == "W21":

        return 18.625

    elif matl[0:3] == "W24":

        return 18.625

    elif matl[0:3] == "W27":

        return 18.625

    else:

        return 21.0

# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

##################################################################################################################################################

# a exc