##  Beam_Stiff.py Version 1.16

##  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 normal or vertical stiffener plates to a beam.

   

    Building or wind columns can be selected for stiffener placement. If multiple columns are selected

    in the same loop, the stiffener pattern entered will be common for all columns. The selected column(s)

    need not be on the beam centerline.

   

    Stiffeners can be added by picking points along a beam (R5). The script defaults to 'Single'.

   

    Stiffeners can be added with a fixed spacing along the length of a beam (V7R4).

 

    User has the option of adding the stiffeners to all beams with the same piecemark as the selected beam.   

   

    The script defaults to 'Single' if a column is not selected.

   

    'Single' pair -     The script adds the stiffeners aligned with the column center or the selected point.

                        Default if points are selected.

 

    'Double' pairs -    The user can set the face to face dimension or center to center dimension of the stiffener pairs.

                        The dimension is rounded off to the nearest 1/16".

 

    The thickness reference point on the stiffener material is always "Center".

   

    The script calculates the dimension between the flanges of the beam, subtracts 0.046875" and

    rounds off the length to the nearest 1/16". Go to "Calculate stiffener length" to modify clearance at bottom flange.

   

    If a column is selected:

        The default stiffener width is the beam "A" dimension + 0.0625 rounded off to the nearest 1/4".

        The default stiffener thickness is column flange thickness + 0.0625 rounded off to the nearest 1/8"

        Go to "set remaining stiffener defaults" to edit these values.

   

    If adding weld is elected, weld is added to all stiffeners (Version 1.07).

   

    Edit this file to change the value of variable "max_thk". This variable will limit the calculated

    default stiffener thickness.

 

    NOTE: If multiple columns are selected, the same stiffener pattern will be added to the beam for each column

    in the column selection set.

 

    R1 -    Fixed a bug 'division by zero' line 233.

    R2 -    Stiffener locations were not being calculated correctly. Replaced "try" statement with

            "if" statement to test for 'division by zero' line 235.

    R3 -    Added option to set stiffeners to align with column below or above if "Normal" is selected.

            Changed default stiffener thickness calculation to Column tf + 0.03 rounded off to nearest 1/8".

    R4 -    Added maximum stiffener thickness variable. Set this value (see "defaults") to the maximum

            thickness of stiffener that you want installed. This overrides the input thickness if applicable.

    R5 -    Add ability to pick points for stiffeners. Select column for stiffener placement or "return" to pick points.

    R5A -   Created loop for adding stiffeners by picking points.

    R5B -   Clarified note in input screen for norm_align: ("Top", "Bott"), norm_align, "If Normal, align at top or bott flange"

    R6 -    Add loop to allow the selection of multiple columns. You will get one dialog box for each set of columns.

            Remove max_thk from dialog box. Default thickness in dialog box is maximum of max_thk or calculated/input thickness.

            User can enter a thickness greater than "max_thk"

    R6A -   Fix an error in the code line 327 - variable name was rp12 - should have been rp31

    R7 -    Allow user to override default depth of stiffener (length of plate material). The plate will start at the top flange.

            Option to add plates to all members with the same piecemark

            Reorganize dialog box

    R7A -   Changed bm_list[0] to mem1 line 332. bm_list[0] may not be the actual member selected so the script may have calculated

            the wrong stiffener locations

    V7R1 -  Test in SDS/2 7.002, Update code

            Add partial depth stiffeners

    V7R2 -  Add the following:      if VersionCompare(curr_version, '6.4' ) >= 0:

                                    ClearSelection()

   

    Version 1.03 -              Add minimum stiffener thickness check. Set minimum stiffener in Defaults section.

    Version 1.04 (3/16/06)  -   Remove support for SDS/2 version 6.3

                                Add option to space stiffeners over length of beam

                                Add import/export script defaults from/to disk file

    Version 1.05 (3/17/06)  -   Rework calculation of first stiffener location

                                Calculation in V7R4 would provide incorrect results if min_dist_left <> min_dist_right

    Version 1.06 (4/9/06) -     Move 'weld_added = "No"' inside beam_list loop

    Version 1.07 (8/22/06) -    Add variable to offset selected points along beam 'X' axis

                                Weld, if added, is applied to all stiffeners

                                Remove variable 'weld_added'

    Version 1.08 (9/30/06) -    Add material usage description 'rp1.mtrl_usage = "Beam_Stiff"'

    Version 1.09 (10/17/06) -   Incorporate Pickler and Unpickler to export and import default files

                                Revise image and default paths to "C:/SDS2_7.0/macro/examples/Defaults/" and "C:/SDS2_7.0/macro/examples/Images/"

                                Incorporate 'MemberAllocated()" into member_count function

    Version 1.10 (10/18/06) -   Move image and default subdirectories directly under "C:/SDS2_7.0/macro/"

                                Add option to print documentation only.

    Version 1.11 (10/19/06) -   Make script into a function. Delete from global namespace upon completion.

                                Variables are kept local where possible.

                                Update the documentation.

    Version 1.12 (10/23/06) -   Import modules

                                Use 'os.getcwd()' to determine the current working directory.

                                The current working directory should be the SDS/2 data root directory.

                                Create function to run script - all variables are local - delete from

                                    global namespace upon exit

                                Add option in dialog box to print documentation only

    Version 1.13 (11/19/06) -   Import mtrl_weld from module

    Version 1.14 (11/27/06) -   Eliminate imports string and types

    Version 1.15 (3/28/07)  -   Skip option to select columns for stiffener placement

                                Remember single or double stiffener option

                                Variable name correction in mtrl_weld() function call - was rp12, should have been rp22

    Version 1.16 (5/11/07) -    Use mem.trans_to_local to calculate pt_WP

                                rework for loop - 'for bm in bm_list:'

    Version 1.17 (8/6/07) -     Add ClearSelection() to work in SDS/2 7.1xx

                                    

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

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

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

   

    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.

 

    NOTE: This script will not work in versions priot to 7.016.   

 

    This script must be executed in plan or elevation if picking points ('Pick Points') for stiffener placement.

    The script can be run in plan, elevation, or isometric if selecting a column for alignment or 'Fixed Spacing' is selected.

    the user must be in plan or elevation and pick on the beam CL.

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

 

    Originally developed in SDS2 6.232 (job #560), Python 1.5.1 - 10/22/01 (R0)   

    Developed in SDS2 6.310 - 4/20/04 (R7)

    Tested in SDS2 7.002 and 6.329 (8/11/04)

    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 'Variables section' to turn off the importing and exporting of the default file

    Go to 'Variables section' to edit system paths for image and default files

    Go to 'Defaults section' to edit script defaults.

 

    Required files from folder 'macrolib' on SDS/2 system path:

        pickle.py (required for FileDefaults)

        FileDefaults.py

        MemCnt.py

        angle.py

        Weld.py

 

    Required folders:

        "system path"/macrolib

        "system path"/Defaults

        "system path"/Images       

   

"""

import os

import sys

 

from math import cos, sin, floor, atan, tan

from param import yes_or_no, ResponseNotOK, Units, ClearSelection, Dialog, dim_print, Warning, dim

Units("feet")

from shape import Shape

from point import Point, PointLocate

from member import Member, MemberLocate, MemberAllocated

from rect_plate import RectPlate

from weld_add import Weld

from job import Job

from fab import Fabricator

 

def run_script():

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

    # startup code begin

    from macrolib.FileDefaults import import_data, export_data

    from macrolib.angle import rtod, dtor

    from macrolib.Weld import mtrl_weld

    from macrolib.MemSelection import mem_select

 

    # 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_Stiff_v1_17.txt"

    # image files

    image_path = os.path.join(os.getcwd(), "macro", "Images")

    image_name = os.path.join(image_path, "Beam_Stiff.gif")

    image_name2 = os.path.join(image_path, "Beam_Stiff2.gif")

    image_name3 = os.path.join(image_path, "Beam_Stiff3.gif")

    image_name4 = os.path.join(image_path, "Beam_Stiff4.gif")

    image_name5 = os.path.join(image_path, "Beam_Stiff5.gif")

    image_name6 = os.path.join(image_path, "Beam_Stiff6.gif")

    image_name7 = os.path.join(image_path, "Beam_Stiff7.gif")

    script_name = "Beam_Stiff_v1.17.py"

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

    enable_default_import_export = "Enable"    

    ## Defaults section

    points_x_offset = 0.1875

    location_method = "Fixed Spacing"       # "Pick Points", "Fixed Spacing"

    no_pairs = "Single"                     # "Single" or "Double" stiffeners

    which_side = "BS"                       # "BS" "NS" "FS"

    pl_norm = "Vertical"                    # "Normal" "Vertical"

    # if pl_norm = "Normal", align with vertical line where crossing top or bottom flange "Top", "Bott"

    norm_align = "Top"                     

    pl_color = "Yellow Zinc"                # material finish

    steelgrade = "A36"                      # Job().steel_grades("Plate").keys()

    add_stf_weld = "Yes"                    # "Yes" "No"

    stf_weld_type = "Fillet"                # Fillet" "Bevel groove" "Square butt"

    weld_size = 0.1875

    weld_tail_text = "None"                 # only "None" is allowed

    # dimension face reference with 2 pairs of stiffeners "Stf face" "Stf CL"

    stf_ref = "Stf FACE"                   

    max_thk = 1.0                           # calculated maximum stiffener thickness

    min_thk = 0.375                         # calculated minimum stiffener thickness

    # Use calculated stiffener thickness or input thickness (input thickness overrides max_thk) "Input", "Calc"

    calc_or_input = "Input"                

    input_thk = 0.375                       # input thickness

    input_width = 2.5                       # input width

    stiff_thk = 0.375

    stiff_width = 2.5

    stf_ff_dim = 12.0

    stf_fc_dim = 11.5

   

    # Create options for stiffener depth other than full:

    #   "Full Depth",  "Top flange half depth", "Bottom flange half depth",

    #   "Top flange user depth", "Bottom flange user depth",

    #   "Top flange bottom k", "Bottom flange top k"   

    other_options = "Top flange half depth"

 

    # 'stiffener_options' is assigned based on value of 'other_options'   

    # stiffener_options = "Full Depth"      #   "Other", "Full Depth"

    custom_depth = 12.0                     #   If "Other" is selected, default user stiffener depth

    # Options for stiffeners automatically spaced

    min_dist_left = 16.0

    min_dist_right = 16.0

    stf_spa = 48.0

    ## End variables and defaults section

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

    ## Define function to add rectangular plate material

    ## Returns a rectangular plate object

    def stiff_pl(bm, pnt1, pnt2, stiff_width, stiff_thk, stiff_clip,\

                 rotpl, thk_ref, left_prep, right_prep, steelgrade):

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

        # rectangular plate begin

        rp1 = RectPlate()

        rp1.member = bm

        rp1.pt1 = pnt1

        rp1.pt2 = pnt2

        rp1.grade = steelgrade

        rp1.origin = thk_ref

        rp1.top_oper_left = left_prep

        rp1.top_length_left = stiff_clip

        rp1.top_clip_left = stiff_clip

        rp1.top_oper_right = right_prep

        rp1.top_length_right = stiff_clip

        rp1.top_clip_right = stiff_clip

        rp1.bottom_oper_left = "None"

        rp1.bottom_oper_right = "None"

        rp1.width = stiff_width

        rp1.thick = stiff_thk

        rp1.work_pt_dist = pnt1.dist(pnt2)

        rp1.setback_left = 0

        rp1.setback_right = 0

        rp1.web_cut_angle_left = 0

        rp1.web_cut_angle_right = 0

        rp1.length = pnt1.dist(pnt2)

        rp1.mtrl_type = "Plate"

        rp1.mtrl_usage = "Beam_Stiff"

        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   

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

    # 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

           

    ## Main program loop

    while True:

       

        # Select members

        bm_list = mem_select("Select W flange BEAM Member to Add Stiffener Plates", ['Beam',], ["W flange", ])

        if bm_list is None:

            break

        mem1 = bm_list[0]

 

        col_list = []

       

        mem2 = MemberLocate("Select a COLUMN member or RETURN to pick point")

        if mem2 != None and mem2.type == "Column":

            col_list.append(mem2)

            while 1:

                mem = MemberLocate("Select additional COLUMN members or RETURN")

                if not mem:

                    break

                if mem.type == "Column":

                    col_list.append(mem)

                else:

                    Warning("You picked a %s. Member not added to selection set." % (mem.type))

       

        # set remaining stiffener defaults

        if len(col_list) < 1:

            mem2 = "pick point"

            # no_pairs = "Single"

            stiff_thk = input_thk

            calc_or_input = "Input"

        else:

            stiff_thk = (min((round((mem2.tf + 0.03) * 8.0) / 8.0), max_thk))

            stiff_width = (round(((bm_list[0].bf - bm_list[0].tw) / 2 + 0.0625) * 4.0) / 4.0)  # "calculated" width

            stf_ff_dim = (round(mem2.depth / 2.0 * 16.0) / 16.0)

            stf_fc_dim = (round((mem2.depth - mem2.tf) / 2.0 * 16.0) / 16.0)

            calc_or_input = "Calc"

            if stiff_thk < min_thk:

                stiff_thk = min_thk

        stiff_clip = (round((bm_list[0].k - bm_list[0].tf + 0.0625) * 8.0) / 8.0) # default stiffener clip dimension

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

        ## DIALOG BOX 1 ---------------------------------------------------------------------------------------------------------------------#

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

        dlg1 = Dialog("Add stiffener plates to beam members")

        dlg1.menu("print_doc", ("Yes", "No"), "No", "Print documentation only")

        dlg1.tabset_begin()

        dlg1.tab("General Information")

        dlg1.column_group_begin()

        dlg1.column(0)

        if mem2 == "pick point":

            dlg1.group_title("Stiffener Location Selection Method")

            dlg1.menu("location_method", ("Pick Points", "Fixed Spacing"), location_method, "Method of locating stiffeners              ")

            dlg1.entry("points_x_offset", dim_print(points_x_offset), "'Pick Points' member 'X' offset distance")

            dlg1.group_title_end

        dlg1.group_title("Single/Double, Side, Color, Grade")

        dlg1.menu("no_pairs", ("Single", "Double"), no_pairs, "Single or Double Stiffeners               ")

        dlg1.menu("which_side", ("BS", "NS", "FS"), which_side, "Side of beam web")

        dlg1.menu("pl_color", ("None", "Red Oxide", "Yellow Zinc", "Gray Oxide", "Sandblasted", "Blued Steel", "Galvanized"), \

                  pl_color, "Select material finish" )

        dlg1.menu("steelgrade", Job().steel_grades("Plate").keys(), steelgrade, "Select stiffener material grade")

        dlg1.group_title_end

        dlg1.group_title("Stiffener Orientation")

        dlg1.menu("pl_norm", ("Normal", "Vertical"), pl_norm, "Orientation - Vertical or Normal to beam")

        dlg1.group_title_end

        dlg1.group_title("Applies to 'Normal' Stiffener Orientation")

        dlg1.menu("norm_align", ("Top", "Bott"), norm_align, "Align stiffeners at top or bott flange")

        dlg1.group_title_end

        dlg1.group_title("Stiffener dimensions")

        if calc_or_input == "Input":

            dlg1.line("Stiffener Dimensions User Input Defaults - Beam 'bf/2-tw/2' = %s" % (dim_print(mem1.bf/2 - mem1.tw/2)))

            dlg1.entry("input_thk", dim_print(input_thk), "Stiffener thickness")

            dlg1.entry("input_width", dim_print(input_width), "Stiffener width")

            dlg1.entry("stiff_clip", dim_print(stiff_clip), "Stiffener clip dimension (calculated)")

        else:

            dlg1.line("Stiffener Dimensions Calculated Defaults")

            dlg1.entry("stiff_thk", dim_print(stiff_thk), "'Calculated' stiffener thickness")   

            dlg1.entry("stiff_width", dim_print(stiff_width), "'Calculated' stiffener width")

            dlg1.entry("stiff_clip", dim_print(stiff_clip), "Stiffener clip dimension (calculated)")

        dlg1.group_title_end

        dlg1.column(0)

        dlg1.line("Size & Mark: " + mem1.section_size + " " + mem1.piecemark)

        dlg1.line("Plan length: " + dim_print(mem1.plan_length))

        dlg1.line("Member slope: " + "%0.4f"%mem1.slope)

        dlg1.line("Slope length: " + dim_print(mem1.input_length))

        dlg1.group_title("'Normal' orientation")

        dlg1.image(image_name5)

        dlg1.group_title_end

        dlg1.group_title("'Vertical' orientation")

        dlg1.image(image_name6)

        dlg1.group_title_end

        dlg1.column_group_end()

 

        if mem2 == "pick point":

            dlg1.tab("Fixed spacing options")

            dlg1.group_title("Variables for 'Fixed Spacing' option")

            dlg1.entry("min_dist_left", dim_print(min_dist_left), "Minimum distance from left end of material      ")

            dlg1.entry("min_dist_right", dim_print(min_dist_right), "Minimum distance from right end of material")

            dlg1.entry("stf_spa", dim_print(stf_spa), "Stiffener spacing")

            dlg1.group_title_end

            dlg1.group_title("Fixed Spacing, Single Stiffeners")

            dlg1.image(image_name7)

            dlg1.group_title_end

 

        dlg1.tab("Double Stiffener Options")   

        dlg1.group_title("Dimensional reference to stiffener FACE or CL from selected/calculated WP")

        dlg1.menu("stf_ref", ("Stf FACE", "Stf CL"), stf_ref, "Stiffener reference")

        dlg1.entry("stf_ff_dim", dim_print(stf_ff_dim), "Dim from WP to Stf FACE")

        dlg1.entry("stf_fc_dim", dim_print(stf_fc_dim), "Dim from WP to Stf CL")    

        dlg1.group_title_end

        dlg1.group_title("Image of double stiffeners")

        dlg1.image(image_name2)

        dlg1.group_title_end

       

        dlg1.tab("Depth Options")

        dlg1.group_title("Stiffener depth options")

        dlg1.menu("other_options", ("Full Depth", "Top flange half depth", "Bottom flange half depth", "Top flange user depth", \

                                    "Bottom flange user depth", "Top flange bottom k", "Bottom flange top k"), other_options, "Stiffener depth options")

        dlg1.group_title_end

        dlg1.group_title("User Depth - Applies if 'Top flange user depth' or 'Bottom flange user depth' option is selected")

        dlg1.entry("custom_depth", dim_print(custom_depth), "User stiffener depth")

        dlg1.group_title_end

        dlg1.group_title("Various Depth Options")

        dlg1.image(image_name3)

        dlg1.group_title_end

       

        dlg1.tab("Weld")

        dlg1.menu("add_stf_weld", ("Yes", "No"), add_stf_weld, "Add weld to stiffener?")

        dlg1.menu("stf_weld_type", ("Fillet", "Square butt", "Bevel groove"), stf_weld_type, "Weld type")

        dlg1.entry("weld_size", dim_print(weld_size), "Weld size")

        dlg1.menu("weld_tail_text", ("None", "TYP"), weld_tail_text, "Tail text")

        dlg1.group_title("Drawing Editor Image")

        dlg1.image(image_name4)

        dlg1.group_title_end

       

        dlg1.tab("Graphic Image")

        dlg1.image(image_name)

        dlg1.tabset_end()

        try:

            dd1 = dlg1.done()

        except ResponseNotOK:

            break

        for key, value in dd1.items():

            exec "%s = %s" % (key, repr(value)) in None

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

        ## END DIALOG BOX 1 ----------------------------------------#

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

        if print_doc == "Yes":

            print __doc__

            break

        if mem2 != "pick point":

            points_x_offset = 0.0

        if location_method == "Fixed Spacing":

            points_x_offset = 0.0

        if calc_or_input == "Input":

            stiff_thk = input_thk

            stiff_width = input_width

        # make sure default data is saved in dictionary dd1

        dd1['stiff_thk'] = stiff_thk

        dd1['stiff_width'] = stiff_width

        dd1['input_thk'] = input_thk

        dd1['input_width'] = input_width

        dd1['points_x_offset'] = points_x_offset

        if other_options == "Full Depth":

            stiffener_options = "Full Depth"

        else:

            stiffener_options = "Other"

        # Export defaults to disk if enabled

        if enable_default_import_export == "Enable":

            export_data(os.path.join(default_file_path, def_file), dd1)

        # Calculate WP at top of beam and center of column "pt_WP"

        pt_list = []

        if mem2 == "pick point":

            if location_method == "Pick Points":           

                while 1:

                    pt21 = PointLocate("Select stiffener locations")

                    if pt21 == None:

                        break

                    else:

                        pt_list.append(pt21)

            else:

                allow_out_to_out = mem1.length - min_dist_left - min_dist_right

                no_spa = int(floor(allow_out_to_out / stf_spa))

                # round off to the nearest 1/4"

                dist_left = round((mem1.left.setback + min_dist_left + (allow_out_to_out/2) - (no_spa*stf_spa/2.0)) * 4.0) / 4.0

                for i in range(no_spa + 1):

                    pt_list.append(mem1.left.location + mem1.translate(dist_left + (i * stf_spa), 0.0, 0.0))

        else:

            for col in col_list:

                pt_list.append(col.left_location)

        # convert points in pt_list to member coordinates for mem1 and create pt_list_loc

        pt_list_loc = []

        for pt in pt_list:

            pt = mem1.trans_to_local(pt - mem1.left_location)

            pt_list_loc.append(Point(pt.x + points_x_offset, pt.y, 0.0))

        # option to add same stiffener pattern to other beams using same dialog box options

        while True:

            # begin beam loop

            for bm in bm_list:

                pt_list = []

               

                # begin loop for selected/calculated points, calculate pt_WP at top of beam on CL

                for pt in pt_list_loc:

                    dist_b = pt.x - (pt.y * tan(dtor(bm.slope)))

 

                    pt_WP = bm.left_location + bm.translate(dist_b, 0.0, 0.0)

                    

                    if pl_norm == "Vertical":

                        sl = bm.slope

                    else:

                        sl = 0.0

                        if norm_align == "Bott":

                            pt_WP = pt_WP - bm.translate(bm.depth*tan(dtor(bm.slope)), 0.0, 0.0)

                           

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

                    # Calculate stiffener length and material work points

                    real1 = (bm.tf / cos(dtor(sl))) + (stiff_thk / 2) * abs(tan(dtor(sl)))

                    max_length_possible = matl_length = (bm.depth / cos(dtor(sl))) - (2 * real1)

                    if stiffener_options == "Other":

                        if other_options == "Top flange half depth":

                            # round off to nearest 1/4"

                            matl_length = round((bm.depth/2.0 / cos(dtor(sl)) - real1 + 0.125) * 4.0) / 4.0

                            pt31 = pt_WP + bm.translate(real1 * -sin(dtor(sl)), -real1 * cos(dtor(sl)), 0.0)

                            pt32 = pt31 + bm.translate(matl_length * sin(dtor(sl)), -matl_length * cos(dtor(sl)), 0.0)

                        elif other_options == "Bottom flange half depth":

                            # round off to nearest 1/4"

                            matl_length = round((bm.depth/2.0 / cos(dtor(sl)) - real1 + 0.125) * 4.0) / 4.0

                            real2 = real1 + max_length_possible - matl_length

                            pt31 = pt_WP + bm.translate(real2 * -sin(dtor(sl)), -real2 * cos(dtor(sl)), 0.0)

                            pt32 = pt31 + bm.translate(matl_length * sin(dtor(sl)), -matl_length * cos(dtor(sl)), 0.0)

                        elif other_options == "Top flange user depth":

                            if custom_depth > 0.0 and custom_depth < max_length_possible:

                                matl_length = custom_depth

                                pt31 = pt_WP + bm.translate(real1 * -sin(dtor(sl)), -real1 * cos(dtor(sl)), 0.0)

                                pt32 = pt31 + bm.translate(matl_length * sin(dtor(sl)), -matl_length * cos(dtor(sl)), 0.0)

                            else:

                                stiffener_options = "Full Depth"

                                matl_length = round((bm.depth / cos(dtor(sl)) - (2 * real1) - 0.046875) * 16.0) / 16.0

                                pt31 = pt_WP + bm.translate(real1 * -sin(dtor(sl)), -real1 * cos(dtor(sl)), 0.0)

                                pt32 = pt31 + bm.translate(matl_length * sin(dtor(sl)), -matl_length * cos(dtor(sl)), 0.0)

                        elif other_options ==  "Bottom flange user depth":

                            if custom_depth > 0.0 and custom_depth < max_length_possible:

                                matl_length = custom_depth

                                real2 = real1 + max_length_possible - matl_length

                                pt31 = pt_WP + bm.translate(real2 * -sin(dtor(sl)), -real2 * cos(dtor(sl)), 0.0)

                                pt32 = pt31 + bm.translate(matl_length * sin(dtor(sl)), -matl_length * cos(dtor(sl)), 0.0)

                            else:

                                stiffener_options = "Full Depth"

                                matl_length = round((bm.depth / cos(dtor(sl)) - (2 * real1) - 0.046875) * 16.0) / 16.0

                                pt31 = pt_WP + bm.translate(real1 * -sin(dtor(sl)), -real1 * cos(dtor(sl)), 0.0)

                                pt32 = pt31 + bm.translate(matl_length * sin(dtor(sl)), -matl_length * cos(dtor(sl)), 0.0)

                        elif other_options == "Top flange bottom k":

                            # round off to nearest 1/8"

                            matl_length = round((((bm.depth-bm.k) / cos(dtor(sl))) \

                                                 - real1 - ((stiff_thk / 2) * abs(tan(dtor(sl))) - 0.0625)) * 8.0) / 8.0

                            pt31 = pt_WP + bm.translate(real1 * -sin(dtor(sl)), -real1 * cos(dtor(sl)), 0.0)

                            pt32 = pt31 + bm.translate(matl_length * sin(dtor(sl)), -matl_length * cos(dtor(sl)), 0.0)

                        elif other_options == "Bottom flange top k":

                            # round off to nearest 1/8"

                            matl_length = round((((bm.depth-bm.k) / cos(dtor(sl))) \

                                                 - real1 - ((stiff_thk / 2) * abs(tan(dtor(sl))) - 0.0625)) * 8.0) / 8.0

                            real2 = real1 + max_length_possible - matl_length

                            pt31 = pt_WP + bm.translate(real2 * -sin(dtor(sl)), -real2 * cos(dtor(sl)), 0.0)

                            pt32 = pt31 + bm.translate(matl_length * sin(dtor(sl)), -matl_length * cos(dtor(sl)), 0.0)

                        else:

                            Warning("Invalid stiffener depth option")

                    elif stiffener_options == "Full Depth":

                        matl_length = round((bm.depth / cos(dtor(sl)) - (2 * real1) - 0.046875) * 16.0) / 16.0

                        pt31 = pt_WP + bm.translate(real1 * -sin(dtor(sl)), -real1 * cos(dtor(sl)), 0.0)

                        pt32 = pt31 + bm.translate(matl_length * sin(dtor(sl)), -matl_length * cos(dtor(sl)), 0.0)

                    else:

                        Warning("Invalid selection")

                    # Set stiffener clipped corners where required

                    if stiffener_options == "Full Depth":

                        left_clip = "Clip"

                        right_clip = "Clip"

                    else:

                        if other_options in ["Top flange half depth", "Top flange user depth", "Top flange bottom k"]:

                            left_clip = "Clip"

                            right_clip = "None"

                        else:

                            left_clip = "None"

                            right_clip = "Clip"

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

                    # Add the stiffeners and weld

                    if no_pairs == "Single":

                        if which_side == "NS" or which_side == "BS":

                            pt33 = pt31 + bm.translate(0.0, 0.0, bm.tw / 2)

                            pt34 = pt32 + bm.translate(0.0, 0.0, bm.tw / 2)

                            rp11 = stiff_pl(bm, pt33, pt34, stiff_width, stiff_thk, stiff_clip,\

                                            (-90.0, 0.0, -90.0), "Center", left_clip, right_clip, steelgrade)

                            if add_stf_weld == "Yes":

                                mtrl_weld([bm, ], [rp11, ], weld_size, stf_weld_type, _tail_text = weld_tail_text)

                     

                        if which_side == "FS" or which_side == "BS":

                            pt35 = pt31 + bm.translate(0.0, 0.0, -bm.tw / 2)

                            pt36 = pt32 + bm.translate(0.0, 0.0, -bm.tw / 2)

                            rp12 = stiff_pl(bm, pt35, pt36, stiff_width, stiff_thk, stiff_clip,\

                                            (90.0, 0.0, -90.0), "Center", left_clip, right_clip, steelgrade)

                            if add_stf_weld == "Yes":

                                mtrl_weld([bm, ], [rp12, ], weld_size, stf_weld_type, _tail_text = weld_tail_text)

        

                    else:

                        if stf_ref == "Stf FACE":

                            stf_fc_dim = stf_ff_dim - stiff_thk / 2

                        if which_side == "NS" or which_side == "BS":

                            pt41 = pt31 + bm.translate(-stf_fc_dim / cos(dtor(sl)), 0.0, bm.tw / 2)

                            pt42 = pt32 + bm.translate(-stf_fc_dim / cos(dtor(sl)), 0.0, bm.tw / 2)

                            rp21 = stiff_pl(bm, pt41, pt42, stiff_width, stiff_thk, stiff_clip,\

                                            (-90.0, 0.0, -90.0), "Center", left_clip, right_clip, steelgrade)

                            if add_stf_weld == "Yes":

                                mtrl_weld([bm, ], [rp21, ], weld_size, stf_weld_type, _tail_text = weld_tail_text)

                    

                            pt51 = pt31 + bm.translate(stf_fc_dim / cos(dtor(sl)), 0.0, bm.tw / 2)

                            pt52 = pt32 + bm.translate(stf_fc_dim / cos(dtor(sl)), 0.0, bm.tw / 2)

                            rp22 = stiff_pl(bm, pt51, pt52, stiff_width, stiff_thk, stiff_clip,\

                                            (-90.0, 0.0, -90.0), "Center", left_clip, right_clip, steelgrade)

                            if add_stf_weld == "Yes":

                                mtrl_weld([bm, ], [rp22, ], weld_size, stf_weld_type, _tail_text = weld_tail_text)

                               

                        if which_side == "FS" or which_side == "BS":

                            pt41 = pt31 + bm.translate(-stf_fc_dim / cos(dtor(sl)), 0.0, -bm.tw / 2)

                            pt42 = pt32 + bm.translate(-stf_fc_dim / cos(dtor(sl)), 0.0, -bm.tw / 2)

                            rp31 = stiff_pl(bm, pt41, pt42, stiff_width, stiff_thk, stiff_clip,\

                                            (90.0, 0.0, -90.0), "Center", left_clip, right_clip, steelgrade)

                            if add_stf_weld == "Yes":

                                mtrl_weld([bm, ], [rp31, ], weld_size, stf_weld_type, _tail_text = weld_tail_text)

                   

                            pt51 = pt31 + bm.translate(stf_fc_dim / cos(dtor(sl)), 0.0, -bm.tw / 2)

                            pt52 = pt32 + bm.translate(stf_fc_dim / cos(dtor(sl)), 0.0, -bm.tw / 2)

                            rp32 = stiff_pl(bm, pt51, pt52, stiff_width, stiff_thk, stiff_clip,\

                                            (90.0, 0.0, -90.0), "Center", left_clip, right_clip, steelgrade)

                            if add_stf_weld == "Yes":

                                mtrl_weld([bm, ], [rp32, ], weld_size, stf_weld_type, _tail_text = weld_tail_text)

            # Select members

            bm_list = mem_select("Select W flange BEAM Member to add same stiffener pattern or RETURN", ['Beam',], ["W flange", "W Tee"])

            if bm_list is None:

                break

            mem1 = bm_list[0]

        ClearSelection()

        if not yes_or_no("Add more full or partial depth stiffener plates to beams?"):

            break

#### END run_script() xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

if __name__ == '__main__':

    try:

        run_script()

    finally:

        ClearSelection()

        del run_script