##  Beam_OutriggerPL.py Version 1.04

##  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 outrigger plates to beams for support of edge material.

    Outriggers can be added normal or true vertical. End distances are measured along the beam slope.

   

    User can enter minimum start point distances from beam left and right end WPs for "Fixed Spacing",

    fixed start point distances from beam left and right end WPs and maximum spacing for "Automatic Spacing",

    or pick point locations along the member line while in plan or elevation. Point.x and Point.y input

    must be on member line. Script adjusts Point.z to correct elevation.

 

    User can add erection pin hole(s) for hanger attachments.

 

    Outriggers can be "Full Depth" or "Non Full Depth".

    

    Thickness reference point on the plate material is alwalys "Center".

    The default cope length is the beam "A" dimension + 0.53125, rounded off to the nearest 1/4".

    The default cope depth is the beam "K" dimension + 0.047 + vert_offset, rounded off to the nearest 1/8".

 

    R1 -    Fixed a bug 'division by zero' if no_spaces = 0 (line 302)

    R2 -    Add minimum cope dimensions (go to Defaults section to change minimum dimensions)

    R3 -    Update code (1/19/04)

    V7R1 -  Test in SDS/2 7.002, update code

    V7R2 -  Add support for HSS beams

    V7R3 -  Add ClearSelection() (2/16/06)

    V7R4 -  Add default save to file and import from file

    V7R5 (4/21/06)  -  Add more rows to menu item 'no_rows' in dialog box, modify colors, get bolt type and material grade from setup

    V7R6 (6/11/06)  -  Add variable to offset selected points along beam 'X' axis.

    Version 1.00 (8/12/06) -    Remove support for SDS/2 version 6.3xx.

                                Weld is added to all plates instead of to the first one added

    Version 1.01 (9/30/06) -    Add material usage description: 'Beam_OutriggerPL'

    Version 1.02 (5/7/07) -     Import MemSelection, FileDefaults, Weld

                                Read images from macro/Images

    Version 1.03 (8/27/07) -    Add option to fit outrigger plate under flange. The cuts are made with cut layout.

                                Cut depth dimension is rounded up to the next 1/16", length to the next 1/8".

                                Move start up code outside of function run_script().

                                Add ClearSelection() in finally block.

                                Fix several minor code errors.

    Version 1.04 (10/3/07) -    Add default variable in dialog box for bolt_type

   

    This script can be executed in plan, elevation (on CL beam), or isometric. If adding outriggers by picking,

    points, user must be in plan or elevation.

   

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

    Developed in SDS2 6.232, Python 1.5.1    10/22/01

    Tested in SDS2 7.002, Python 2.2.1  8/18/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 Defaults section to modify script defaults.

"""

# startup code begin

import os

from macrolib.FileDefaults import import_data, export_data

from macrolib.MemSelection import mem_select

from macrolib.Weld import mtrl_weld

from macrolib.angle import rtod, dtor

from macrolib.round_length import round_length_next, round_length_near

 

from param import yes_or_no, ResponseNotOK, Units, ClearSelection

from param import Dialog, dim_print, Warning, dim

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

Units("feet")

from point import Point, PointLocate

from member import Member, MemberLocate

from mtrl_list import MtrlLocate, HoleLocate

from rect_plate import RectPlate

from hole_add import Hole

from bolt_add import Bolt

from mtrl_fit import MtrlFit

from mtrl_cut import MtrlCut

from job import Job

from fab import Fabricator

# 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

    def_file = "Beam_OutriggerPL.txt"

    script_name = "Beam_OutriggerPL_v1.04.py"

 

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

    enable_default_import_export = "Enable"

 

    # Dialog box image path and file name

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

 

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

    image_name1 = os.path.join(image_path, "Beam_OutriggerPL1.gif")

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

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

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

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

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

 

    finishList = ["None", "Red Oxide", "Yellow Zinc", "Gray Oxide", "Sandblasted", "Blued Steel", "Galvanized"]

    gradeList = Job().steel_grades("Plate").keys()

    boltList = Job().bolt_sched()

    holeList = ["Standard Round", "Short Slot", "Oversized Round", "Long Slot"]

 

    # minimum cope dimensions

    min_cope_length = "3 1/2"

    min_cope_depth = "1 1/4"

    ## Defaults section ###########################################################

    # outrigger plate depth option ("Full Depth", "Non Full Depth")

    depth_option = "Full Depth"

    # Calculate plate locations based on minimum or fixed end distances, pick points

    # ("Auto Spacing", "Fixed Spacing", "Pick Points")

    auto_or_points = "Auto Spacing"

    points_x_offset = 0.0

    # maximum outrigger spacing ("Auto Spacing"), or fixed spacing ("Fixed Spacing")                          

    max_spacing = 48.0

    # side(s) for outriggers "BS" "NS" "FS"                          

    which_side = "FS"

    # normal to beam or vertical "Normal" "Vertical"                          

    pl_norm = "Normal"

    # plate thickness                    

    outrig_thk = 0.375

    # plate width (vertical dimension)

    outrig_depth = 8.0

    # length of outrigger plate (horizontal dim.)                       

    matl_length = 7.5

    # default length of clip at lower right corner (enter 0 for no clip)                          

    outrig_clip_length = 4.0

    # depth of clip, outside vertical edge distance above clip for "Full "Depth"                    

    outrig_clip_depth = 0.0

    # minimum distance from beam left WP to first plate                          

    start_pt_dist = 14.0

    # minimum distance from right WP to last plate                      

    end_pt_dist = 14.0

                              

    # no_spaces = "1"  NO. SPACES NOW CALCULATED

    # vertical offset of plate (- is down, + is up)

    vert_offset = 0.0

    # material finish

    pl_color = "Sandblasted"

    # steel grade Job().steel_grades("Plate").keys()                          

    steelgrade = "A36"

    # default for add weld  "Yes" "No"

    # add weld       "Yes" "No"

    stf_weld = "Yes"

    # for weld type "Fillet"

    stf_weld_type = "Fillet"

    # seat weld size ("3/16", "1/4", "5/16")

    weld_size = "3/16"

 

    # Defaults for erection pin hole(s) - Allow 1 or 2 rows of bolts, 1 bolt column

    # add hole(s) for erection bolt "Yes" "No"

    ad_hole = "No"

    # horizontal distance from CL of beam to hole

    x_ga = 9.0

    # vertical distance from top of plate to hole

    y_ga = 3.0

    # number of rows

    no_rows = 2

    # row spacing                          

    row_spa = 3.0

    # bolt size                          

    bolt_size = 0.75

    # bolt type Job().bolt_sched()                       

    bolt_type = "A307"

    # hole type "Standard Round" "Short Slot" "Oversized Round" "Long Slot"

    hole_type = "Long Slot"

    # slot length

    slot_length = 1.25

    # slot direction

    slot_dir = 0.0

 

    cut_option = "Cope"   

 

    ## End Defaults section

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

    ## Function definition section

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

    # Function to add the outrigger plate

    # reference points are the end points of the plate

    # returns a rectangular plate object

    def outrig_pl(bm, pnt1, pnt2, pl_depth, pl_thk, cope, clipll, cliplr, pl_length, pl_grade, pl_color, rotpl, bm_slope, thk_ref):

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

        if cope:

            leftt_op = "Cope"

            leftt_len, leftt_dep = cope

        else:

            leftt_op = "None"

            leftt_len = 0.0

            leftt_dep = 0.0

        if cliplr:

            rightb_op = "Clip"

            right_len, right_dep = cliplr

        else:

            rightb_op = "None"

            right_len = 0.0

            right_dep = 0.0

        if clipll:

            leftb_op = "Clip"

            leftb_len = clipll

        else:

            leftb_op = "None"

            leftb_len = 0.0

            leftb_dep = 0.0       

        # rectangular plate begin

        rp1 = RectPlate()

        rp1.member = bm

        rp1.pt1 = pnt1

        rp1.pt2 = pnt2

        rp1.grade = pl_grade

        rp1.origin = thk_ref

        rp1.top_oper_left = leftt_op

        rp1.top_length_left = leftt_len

        rp1.top_cope_left = leftt_dep

        rp1.top_oper_right = "None"

        rp1.bottom_oper_left = leftb_op

        rp1.bottom_length_left = leftb_len

        rp1.bottom_clip_left = leftb_len

        rp1.bottom_oper_right = rightb_op

        rp1.bottom_length_right = right_len

        rp1.bottom_clip_right = right_dep

        rp1.width = pl_depth

        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 = "Beam_OutriggerPL"

        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

 

    # Define function to add hole pattern

    def erect_pin_hole(rp1, pnt1, x_dist, y_dist, _no_rows, _no_cols, _row_spa, _col_spa, _bolt_size, _bolt_type, _hole_type, _slot_dir, _slot_length):

        if _slot_length:

            str = "_slot_length"

        else:       

            str = "hole26.calc_slot_length()"

        try:

            # hole group add begin

            hole26 = Hole()

            hole26.mtrl = [rp1, ]

            hole26.pt1 = pnt1 #hole26.mtrl.location

            hole26.hole_type = _hole_type

            hole26.face = "NS Face"

            hole26.valid_cnc = "Yes"

            hole26.x_ref_offset = x_dist

            hole26.y_ref_offset = y_dist

            hole26.x_spa = _col_spa

            hole26.y_spa = _row_spa

            hole26.group_rot = 0.0

            hole26.locate = "Below Right"

            hole26.columns = _no_cols

            hole26.rows = _no_rows

            hole26.bolt_type = _bolt_type

            hole26.bolt_dia = _bolt_size

            hole26.slot_rot = _slot_dir

            hole26.length = eval(str)

            hole26.hole_dia = hole26.calc_hole_size()

            hole26.show_window = "Yes"

            hole26.create()

        except:

            pass

            # hole group add end

 

    # Function to return a point along the member line given member object and user selected point.

    # User selected point must be correct x and y values on member line, or calculated point will not be correct.

    def ret_pt_WP (mem, pnt2):

        pnt1 = mem.left_location

        dist_h = Point(pnt1.x, pnt1.y, 0.0).dist(Point(pnt2.x, pnt2.y, 0.0))

        ang_1 = mem.plan_rotation

        if (pnt2.x - pnt1.x) == 0.0:

            ang_2 = 90.0

        else:

            ang_2 = rtod(atan((pnt2.y - pnt1.y) / (pnt2.x - pnt1.x)))

        ang_net = ang_1 - ang_2

        dist_b = abs((dist_h * cos(dtor(ang_net))) / cos(dtor(mem.slope)))   

        return pnt1 + mem.translate(dist_b, 0.0, 0.0)

    # end function definition

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

    def cut_points(ptWP, mtrl, cut_depth, cut_length, clip_dim, vert_offset):

        '''ptWP is a point at the CL of the beam'''

        ptList = [ptWP,]

        ptList.append(ptWP + mtrl.translate(0.0, -cut_depth-clip_dim, 0.0))

        ptList.append(mtrl.pt1 + mtrl.translate(0.0, -cut_depth-clip_dim-vert_offset, 0.0))

        ptList.append(mtrl.pt1 + mtrl.translate(clip_dim, -cut_depth-vert_offset, 0.0))

        ptList.append(mtrl.pt1 + mtrl.translate(cut_length, -cut_depth-vert_offset, 0.0))

        ptList.append(mtrl.pt1 + mtrl.translate(cut_length, (cut_depth+vert_offset)*10, 0.0))

        ptList.append(ptWP + mtrl.translate(0.0, (cut_depth+vert_offset)*10, 0.0))

        ptList.append(ptWP)

        return ptList

       

    def plate_cut(mtrl, ptList):

        #try:

        # mtrl cut begin

        mcut1 = MtrlCut()

        mcut1.mtrl = [mtrl, ]

        mcut1.rotate = (0,0,0)

        for pt in ptList:

            mcut1.pts.append((pt, 0.0))

        mcut1.cut("Layout")

        return True

        #except:

            #Warning(formatExceptionInfo())

            #return False

        # mtrl cut end

 

    ## End function definitions section

 

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

    ## Import defaults data if enabled

    if enable_default_import_export == "Enable":

        dd0 = import_data(os.path.join(default_file_path, def_file))

        if dd0:

            for key, value in dd0.items():

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

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

    ## MAIN PROGRAM LOOP

    while True:

        ClearSelection()

        # Select beam member

        bm_list = mem_select("Select a WF or HSS BEAM member", ['Beam',], ["W flange", "Tube"])

        if bm_list is None:

            break

        mem1 = bm_list[0]

       

        # calculate default outrigger cope and z_offset for placement of outrigger plates later

        if mem1.mtrl_type == "W flange":

            z_offset = mem1.tw / 2

            outrig_cope_length = max((round(((mem1.bf - mem1.tw) / 2 + 0.53125) * 4.0) / 4.0), dim(min_cope_length))

            outrig_cope_depth = max((round((mem1.k + 0.046875 + dim(vert_offset)) * 8.0) / 8.0), dim(min_cope_depth))

            if dim(outrig_cope_depth) < 0.0:

                outrig_cope_depth = 0.0

        else:

            z_offset = mem1.short_depth / 2         # assume long_depth is always vertical

            outrig_cope_length = 0.0

            outrig_cope_depth = 0.0

            

        ddDict = {}

       

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

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

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

 

        dlg1 = Dialog("Add outrigger plates to a beam")

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

        dlg1.tabset_begin()

        dlg1.tab("General Information")

        dlg1.image(image_name)

        dlg1.line("Beam plan length = %s  Beam slope length = %s" % (dim_print(mem1.plan_length), dim_print(mem1.input_length)))

        dlg1.group_title("OUTRIGGER PLATE DEPTH OPTIONS")

        dlg1.menu("depth_option", ("Full Depth", "Non Full Depth"), depth_option, "Full Depth or Non Full Depth                         ")

        dlg1.group_title_end

        dlg1.group_title("GENERAL PLATE OPTIONS")

        dlg1.menu("auto_or_points", ("Auto Spacing", "Fixed Spacing", "Pick Points"), auto_or_points,\

                  "Place outriggers automatically or by picking points?")

        dlg1.menu("which_side", ("BS", "NS", "FS"), which_side, "Which side(s) of beam web?")

        dlg1.menu("pl_norm", ("Normal", "Vertical"), pl_norm, "Plate orientation")

        dlg1.menu("pl_color", finishList, pl_color, "Select material color" )

        dlg1.menu("steelgrade",gradeList, steelgrade, "Select material grade")

        dlg1.menu("stf_weld", ("Yes", "No"), stf_weld, "Add weld to outrigger plate")

        dlg1.menu("ad_hole", ("Yes", "No"), ad_hole, "Add erection pin hole(s) to outrigger plate")

        if mem1.mtrl_type == "W flange":

            dlg1.menu("cut_option", ("Cope", "Cut to Fit"), cut_option, "Cope or cut to fit beam flange")

        dlg1.group_title

        dlg1.tab("Depth Images")

        dlg1.column_group_begin()

        dlg1.column(0)

        dlg1.group_title("Non Full Depth")

        dlg1.image(image_name2)

        dlg1.group_title_end

        dlg1.column(0)

        dlg1.group_title("Full Depth")

        dlg1.image(image_name3)

        dlg1.group_title_end

        dlg1.column_group_end()

       

        dlg1.tab("Cut Images")

        dlg1.column_group_begin()

        dlg1.column(0)

        dlg1.group_title("Cut to Fit Non Full Depth")

        dlg1.image(image_name5)

        dlg1.column(0)

        dlg1.group_title("Cut to Fit Full Depth")

        dlg1.image(image_name6)

        dlg1.group_title_end

        dlg1.column_group_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 BOX 1 ------------------------------------------#

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

       

        if print_doc == "Yes":

            print __doc__

            break

 

        ddDict.update(dd1)

       

        if pl_norm == "Vertical":

            sl = mem1.slope

        else:

            sl = 0.0

           

        # Calculate plate depth if "Full Depth" is selected

        if depth_option == "Full Depth":

            # print mem1.tf, sl, cos(dtor(sl)), outrig_thk

            if mem1.mtrl_type == "W flange":

                real1 = (mem1.tf / cos(dtor(sl))) + (dim(outrig_thk) / 2) * abs(tan(dtor(sl)))

                # outrig_clip_length = round((dim(matl_length) + mem1.tw/2 - mem1.bf/2 + 0.06) * 8.0) / 8.0

            else:

                real1 = (dim(outrig_thk) / 2) * abs(tan(dtor(sl)))

                # outrig_clip_length = matl_length

            outrig_depth = round(((mem1.depth / cos(dtor(sl))) - real1 - 0.03) * 16.0) / 16.0    # round off to the nearest 16th

       

        confirm_stf_weld = stf_weld

        confirm_ad_hole = ad_hole

 

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

        ## DIALOG BOX 2 --------------------------------------------#

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

       

        dlg2 = Dialog("Additional outrigger options")

        dlg2.tabset_begin()

        dlg2.tab("Options")

        dlg2.label(auto_or_points, "Outrigger plate location option selected:")

       

        dlg2.image(image_name)

       

        if auto_or_points == "Fixed Spacing":

            dlg2.group_title("Fixed Spacing")

            dlg2.entry("max_spacing", dim_print(max_spacing), "Fixed spacing of outriggers                                     ")

            dlg2.entry("start_pt_dist", dim_print(start_pt_dist), "Minimum distance from left WP to first plate")

            dlg2.entry("end_pt_dist", dim_print(end_pt_dist), "Minimum distance from right WP to last plate")

            dlg2.group_title_end

        elif auto_or_points == "Auto Spacing":

            dlg2.group_title("Auto Spacing")

            dlg2.entry("max_spacing", dim_print(max_spacing), "Maximum spacing of outriggers                                   ")

            dlg2.entry("start_pt_dist", dim_print(start_pt_dist), "Fixed distance from left WP to first plate")

            dlg2.entry("end_pt_dist", dim_print(end_pt_dist), "Fixed distance from right WP to last plate")

            dlg2.group_title_end

        elif auto_or_points == "Pick Points":

            dlg2.group_title("Outrigger Offset")

            dlg2.entry("points_x_offset", dim_print(points_x_offset), "Member 'X' offset distance from selected points to PL CL")

            dlg2.group_title_end

           

        dlg2.group_title("Plate material dimensions")

        dlg2.entry("outrig_thk", dim_print(outrig_thk), "Plate thickness")

        dlg2.entry("matl_length", dim_print(matl_length), "Outrigger plate material length (horizontal dimension)")

        if depth_option == "Full Depth":

            dlg2.label(dim_print(outrig_depth), "Calculated outrigger plate depth:")

        else:

            dlg2.entry("outrig_depth", dim_print(outrig_depth), "Outrigger plate depth")

        dlg2.entry("vert_offset", dim_print(vert_offset), "Outrigger vertical offset (- down, + up)")

        dlg2.group_title_end

       

        dlg2.group_title("Plate material end preparations")

        if mem1.mtrl_type == "W flange":

            if cut_option == "Cope":

                dlg2.entry("outrig_cope_length", dim_print(outrig_cope_length), "Cope length at beam flange")

                dlg2.entry("outrig_cope_depth", dim_print(outrig_cope_depth), "Cope depth at beam flange")

            else:

                dlg2.line("The option to 'Cope to Fit' was selected")

        else:

            dlg2.label("%s, %s" % (dim_print(outrig_cope_length), dim_print(outrig_cope_depth)), "Outrigger plate Cope Length x Cope Depth:")

        if depth_option == "Full Depth" and mem1.mtrl_type == "W flange":

            # dlg2.label(dim_print(outrig_clip_length), "Calculated clip length lower right: ")

            dlg2.entry("outrig_clip_depth", dim_print(outrig_clip_depth), "Outside edge vertical depth above clip (0 for no clip)" )

        else:

            dlg2.entry("outrig_clip_length", dim_print(outrig_clip_length), "Clip length lower right")

            dlg2.entry("outrig_clip_depth", dim_print(outrig_clip_depth), "Clip depth lower right" )

        dlg2.group_title_end

       

        if confirm_stf_weld == "Yes":

            dlg2.tab("Weld")

            dlg2.group_title("Welding options")

            dlg2.menu( "confirm_stf_weld", ("Yes", "No"), confirm_stf_weld, "Add weld to outrigger plate" )

            dlg2.menu( "stf_weld_type", ("Fillet", "Square butt", "Bevel groove"), stf_weld_type, "Select weld type" )

            dlg2.menu( "weld_size", ('3/16', '1/4', '5/16'), weld_size, "Enter weld size")

 

            dlg2.group_title_end

            dlg2.group_title("Welded Full Depth Outrigger")

            dlg2.image(image_name3)

            dlg2.group_title_end

        if confirm_ad_hole == "Yes":

            dlg2.tab("Erection bolt hole options")

            dlg2.menu( "confirm_ad_hole", ("Yes", "No"), confirm_ad_hole, "Add erection pin hole(s) to outrigger plate          ")

            dlg2.group_title("Hole Pattern Information")       

            dlg2.entry( "x_ga", dim_print(x_ga), "Horizontal distance from beam CL to hole(s)")

            dlg2.entry( "y_ga", dim_print(y_ga), "Vertical distance from top of plate to 1st hole")

            dlg2.menu("no_rows", (1, 2, 3, 4, 5), int(no_rows), "Number of rows required")

            dlg2.entry("row_spa", dim_print(row_spa), "Row spacing")

            dlg2.group_title_end

            dlg2.group_title("Bolt/Hole Information")

            dlg2.entry( "bolt_size", dim_print(bolt_size), "Bolt size")

            dlg2.menu( "bolt_type", boltList, bolt_type, "Bolt type in plate")

            dlg2.menu( "hole_type", holeList, hole_type, "Hole type in plate")

            dlg2.entry( "slot_dir", slot_dir, "Enter slot direction")

            dlg2.entry( "slot_length", dim_print(slot_length), "Enter long slot length or 0 to calculate")

            dlg2.group_title_end

            dlg2.group_title("Outrigger Plate Used As Hung Lintel Bracket")

            dlg2.image(image_name4)

            dlg2.group_title_end

            dlg2.tabset_end()

           

        try:

            dd2 = dlg2.done()

        except ResponseNotOK:

            break

       

        # Update the local namespace

        for key, value in dd2.items():

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

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

        ## END DIALOG BOX 2 ------------------------------------------#

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

       

        ddDict.update(dd2)

            

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

        # Export defaults to disk if enabled

        if enable_default_import_export == "Enable":

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

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

 

        # Calculate outrigger plate clip dimension at W flange beam bottom flange and outrigger clip length

        if depth_option == "Full Depth":

            if mem1.mtrl_type == "W flange":

                outrig_depth = vert_offset + outrig_depth

                # full depth outrigger clip dimension at bottom flg

                full_depth_clip = (round((mem1.k - mem1.tf + 0.0625) * 8.0) / 8.0)

                outrig_clip_length = round((dim(matl_length) + mem1.tw/2 - mem1.bf/2 + 0.06) * 8.0) / 8.0

            else:

                full_depth_clip = 0

        else:

            full_depth_clip = 0

            # Check for invalid outrigger depth - change material depth if encroachment exceeds 1/8"            

            outrig_depth = min(outrig_depth, (mem1.depth - mem1.k + 0.125)) # allow 1/8" encroachment

       

        # Recalculate outrig_cope_depth - a new vert_offset may have been entered

        # Set up to create material cut point list if option 'Cut to Fit' is selected

        if mem1.mtrl_type == "W flange":

            if cut_option == "Cope":

                outrig_cope_depth = max((round((mem1.k + 0.046875 + dim(vert_offset)) * 8.0) / 8.0), dim(min_cope_depth))

                if outrig_cope_depth < 0.0:

                    outrig_cope_depth = 0.0

            else:

                # round_length_next(length, increment="1/16")

                cut_depth = round_length_next(mem1.tf)

                cut_length = round_length_next((mem1.bf/2.0)-(mem1.tw/2.0), '1/8')

                clip_dim = round_length_near(mem1.k-cut_depth+0.125, "1/4")               

               

        # Do a little maintenance

        if outrig_cope_length == 0.0 or outrig_cope_depth == 0.0 or cut_option == "Cut to Fit":

            cope = 0

        else:

            cope = (outrig_cope_length, outrig_cope_depth)

       

        if outrig_clip_length == 0.0 or outrig_clip_depth == 0.0:

            clip = 0

        else:

            if depth_option == "Full Depth" and mem1.mtrl_type == "W flange" and outrig_clip_depth > 0.0:

                actual_clip = outrig_depth - outrig_clip_depth

            else:

                # depth_option == "Non Full Depth" or material is "Tube"

                actual_clip = outrig_clip_depth

            clip = (outrig_clip_length, actual_clip)

       

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

        pt_list_loc = []

        if auto_or_points == "Pick Points":

            while 1:

                pt21 = PointLocate("Select outrigger plate locations")

                if pt21 == None:

                    break

                else:

                    # ret_pt_PT returns point with "z" value corrected to member line

                    # pt_list_loc is in local coordinates to selected member - mem1

                    # mem1 is not necessarily the first member in the set of members if add to all was selected

                    pt_list_loc.append(mem1.trans_to_local(ret_pt_WP(mem1, pt21) - mem1.left_location))

            # Adjust 'X' location of selected points to required location of outrigger plate centerline

            for i in pt_list_loc:

                i.x = i.x + points_x_offset

        elif auto_or_points == "Fixed Spacing":

            allow_out_to_out = mem1.left_location.dist(mem1.right_location) - start_pt_dist - end_pt_dist

            no_spa = int(floor(allow_out_to_out / max_spacing))

            dist_left = start_pt_dist + (allow_out_to_out/2) - (no_spa*max_spacing/2.0)

            for i in range(no_spa + 1):

                x_dimen = dist_left + (i * max_spacing)

                pt_list_loc.append(Point(x_dimen, 0.0, 0.0))

        else:

            no_spa = ceil((mem1.left_location.dist(mem1.right_location) - start_pt_dist - end_pt_dist) / max_spacing)

            actual_spacing = (mem1.left_location.dist(mem1.right_location) - start_pt_dist - end_pt_dist) / no_spa

            for i in range(int(no_spa) + 1):

                x_dimen = start_pt_dist + (i * actual_spacing)

                pt_list_loc.append(Point(x_dimen, 0.0, 0.0))

       

        ## Begin beam loop #############################

        for bm_mem in bm_list:

            for loc_point in pt_list_loc:

                pt_WP = bm_mem.left_location + bm_mem.translate(loc_point.x + sin(dtor(sl)) * vert_offset, cos(dtor(sl)) * vert_offset, 0.0)

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

                    pt21 = pt_WP + bm_mem.translate(0.0, 0.0, z_offset)

                    pt22 = pt21 + bm_mem.translate(0.0, 0.0, matl_length)

                    rp11 = outrig_pl(bm_mem, pt21, pt22, outrig_depth, outrig_thk, cope, full_depth_clip, clip, matl_length, steelgrade,\

                                     pl_color, (0.0, 90.0, 0.0), sl, "Center")

                    if confirm_ad_hole == "Yes":

                        erect_pin_hole(rp11, pt21, x_ga - z_offset, y_ga, no_rows, 1, row_spa, 3.0, bolt_size, bolt_type,\

                                       hole_type, slot_dir, slot_length)

                    if confirm_stf_weld == "Yes":

                        mtrl_weld([bm_mem, ], [rp11, ], weld_size, stf_weld_type)

                    if cut_option == "Cut to Fit":

                        plate_cut(rp11, cut_points(pt_WP, rp11, cut_depth, cut_length, clip_dim, vert_offset))

                       

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

                    pt31 = pt_WP + bm_mem.translate(0.0, 0.0, -z_offset)

                    pt32 = pt31 + bm_mem.translate(0.0, 0.0, -matl_length)

                    rp12 = outrig_pl(bm_mem, pt31, pt32, outrig_depth, outrig_thk, cope, full_depth_clip, clip, matl_length, steelgrade,\

                                     pl_color, (0.0, -90.0, 0.0), sl, "Center")

                    if confirm_ad_hole == "Yes":

                        erect_pin_hole(rp12, pt31, x_ga - z_offset, y_ga, no_rows, 1, row_spa, 3.0, bolt_size, bolt_type,\

                                       hole_type, slot_dir, slot_length)

                    if confirm_stf_weld == "Yes":

                        mtrl_weld([bm_mem,], [rp12,], weld_size, stf_weld_type)

                    if cut_option == "Cut to Fit":

                        plate_cut(rp12, cut_points(pt_WP, rp12, cut_depth, cut_length, clip_dim, vert_offset))

                       

        if not yes_or_no("Add outrigger plates to additional HSS or WF beams?"):

            break

 

## End run_script()

if __name__ == '__main__':

    try:

        run_script()

    finally:

        ClearSelection()

        del run_script