##  Embed_BrgPlate.py 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 a rectangular plate miscellaneous member with studs or holes as an

    embedded bearing plates for beams and joists. The embed member line will

    be centered on the beam length at a user selected distance from the beam

    member work point (left end or right end) at a user entered plan rotation.

    Select a member and enter information into dialog box. User must enter

    the proper embedded plate plan rotation. Studs will be applied to the

    underside of the rectangular plate object.

 

    If 'Both Ends' is selected, the plan rotation entered will apply to

    the left end and the bearing plate at the right end will be rotated

    180 degrees.

 

    The stud or hole pattern will be centered on the rectangular plate.

 

    Plan rotation of 0.0: -------- <--member line

                          | o  o |

                          |      |

                          | o  o |

                          --------

   

    Generally, nailer holes are not required for beam bearing plates.

   

    You must be in plan to execute this script for the intended purpose.

 

    Sequence, member description and user views cannot be manipulated

    through parametrics at this time.

 

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

    For comments, suggestions or questions call BV at the number above, email

    bvaughan@bvdetailing or post to SDS/2 forum.

 

    Version 1.00 (3/17/07) - Initial release

   

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

    ****NOTE: This version is not compatible with SDS/2 versions prior to 7.023.****

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

 

"""

def run_script():

    # startup code begin

    import os

    from math import cos, pi, tan, atan2, atan, sin

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

    from macrolib.FileDefaults import import_data, export_data

    # macrolib.pickle required

    from macrolib.angle import rtod, dtor, calc_plan_rotation

    from macrolib.stud_info import stud_dim

    from macrolib.PolarPt import polar_pt_plan

    from macrolib.MemSelection import mem_select

    # macrolib.MemCnt required

 

    Units("feet")

    from shape import Shape

    from point import Point, PointLocate

    from member import Member, MemberLocate

    from mtrl_list import MtrlLocate, HoleLocate

    from rolled_section import RolledSection

    from hole_add import Hole

    from shr_stud import ShrStud

    from job import Job

    from fab import Fabricator

    # startup code end

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

    ## Variables section

    # defaults file path

    default_file_path = os.path.join(os.getcwd(), "macro", "Defaults")

    # defaults file

    def_file = "Embed_BrgPlate.txt"

    script_name = "Embed_BrgPlate_v1.00.py"

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

    enable_default_import_export = "Enable"

 

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

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

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

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

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

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

 

    stud_diaList = ("1/4", "3/8", "1/2", "5/8", "3/4", "7/8", "1")

    finishList = ("None", "Red Oxide", "Yellow Zinc", "Gray Oxide", "Sandblasted", "Blued Steel", "Galvanized")

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

    boltTypeList = Job().bolt_sched()

 

    ## Defaults section

    # "Left End", "Right End", "Both Ends"

    which_end = "Left End"

    # "Holes", "Studs"

    holesORstuds = 'Holes'

    # "User" "System" Create user piece mark or system piece mark

    embed_mark_system_user = "User"            

    user_piece_mark = "MB_01"

    # Member sequence - must be a string

    plate_seq = "12"

    # stud diameter ("1/4", "3/8", "1/2", "5/8", "3/4", "7/8", "1")

    stud_diam = 0.75

    stud_length = 6.1875

    # finishList

    stud_color = "Yellow Zinc"

 

    # Plate dimensions

    plate_length = 12.0

    plate_width = 7.0

    plate_thk = 0.75

 

    # Member line distance from beam WP

    embed_dist = 1.0

 

    # stud/hole spacing along miscellaneous member x-axis

    x_spa = 6.0

    # stud/hole spacing along miscellaneous member y-axis

    y_spa = 4.0

    # stud/hole columns

    no_cols = 2

    # stud/hole rows

    no_rows = 2   

 

    # embed rotation

    embed_plan_rotation = 0.0

 

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

    plate_grade = Job().steel_grades("Plate").keys()[0]

 

    bolt_size = 0.75

    bolt_type = "A325"

    hole_type = "Standard Round"

    # long slot length where applicable - enter 0" and SDS/2 will calculate length

    ls_len = 1.5

   

    # end script defaults

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

    # Function definitions

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

    def apply_stud(mem, pt11, pt12, _stud_diam, _head_thk, _head_diam, _stud_color, rot_args=(0.0, 0.0, 0.0)):

        # shear stud begin

        m1 = ShrStud()

        m1.member = mem

        m1.pt1 = pt11

        m1.pt2 = pt12

        m1.stud_dia = _stud_diam

        m1.head_thick = _head_thk

        m1.head_dia = _head_diam

        m1.length = m1.pt1.dist(m1.pt2)

        m1.mtrl_type = "Shear stud"

        m1.mtrl_usage = "Embed_Plate_Stud"

        m1.finish = _stud_color

        m1.ref_pt_offset = (0.000000, 0.000000, 0.000000)

        m1.add()

        # m1.rotate(m1.member, rot_args)

        # shear stud end

       

    # define function to add the miscellaneous member, rectangular plate

    def add_misc_rect_plate(pnt1, pnt2, mk, pd, pt, rot, grade, seq):

        # member begin

        memadd5 = Member('Misc Rectangular Plate')

        memadd5.left.location = pnt1

        memadd5.right.location = pnt2

        memadd5.piecemark = mk

        memadd5.grade = grade

        memadd5.origin = "NS"

        memadd5.top_oper_left = "None"

        memadd5.top_oper_right = "None"

        memadd5.bottom_oper_left = "None"

        memadd5.bottom_oper_right = "None"

        memadd5.width = pd

        memadd5.thick = pt

        memadd5.work_pt_dist = memadd5.left.location.dist(memadd5.right.location)

        memadd5.setback_left = 0

        memadd5.setback_right = 0

        memadd5.length = memadd5.work_pt_dist - memadd5.setback_left - memadd5.setback_right

        memadd5.mtrl_type = "Plate"

        memadd5.mtrl_usage = "Embed_Plate"

        memadd5.finish = "Galvanized"

        memadd5.ref_pt_offset = (0, 0, 0)

        memadd5.description = "Embedded Plate"

        # memadd5.sequence = str(seq)

        memadd5.add()

        memadd5.rotate(rot)

        # member end

        return memadd5

 

    # function to add holes to the embedded plate

    def pl_holes (mem, ref_pt, x_dist, y_dist, x_spa, y_spa, no_cols, no_rows, pattern_orientation, bs, bt, ht, hs, slrot=90.0):

        if ht == "Long Slot":

            if hs:

                str1 = "hs"

            else:       

                str1 = "hole26.calc_slot_length()"

        else:

            slrot = 0.0

            str1 = "hole26.calc_slot_length()"

        # hole group add begin

        hole26 = Hole()

        hole26.mtrl = [mem, ]

        hole26.pt1 = ref_pt

        hole26.hole_type = ht

        hole26.face = "NS Face"

        hole26.valid_cnc = "Yes"

        hole26.x_ref_offset = x_dist

        hole26.y_ref_offset = y_dist

        hole26.x_spa = x_spa

        hole26.y_spa = y_spa

        hole26.group_rot = 0.0

        hole26.locate = pattern_orientation

        hole26.columns = no_cols

        hole26.rows = no_rows

        hole26.bolt_type = bt

        hole26.bolt_dia = bs

        hole26.slot_rot = slrot

        hole26.length = eval(str1)

        hole26.hole_dia = hole26.calc_hole_size()

        hole26.show_window = "No"

        hole26.create()

        # hole group add end

        return hole26

    # end function definitions

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

    ## Import default values 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:

        misc_list = mem_select("Select BEAM member or ENTER to exit", ['Beam', 'Joist'], ["All",])

        if misc_list is None:

            break

        mem1 = misc_list[0]

 

        # determine stud dimensions based upon stud diameter               

        head_thk, head_diam, burn_off = stud_dim(dim(stud_diam))

 

        try:

            plate_seq = int(plate_seq)

        except:

            pass

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

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

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

        dlg1 = Dialog( "Create an embedded plate member" )

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

       

        dlg1.tabset_begin()

        dlg1.tab("Embed general information")

        dlg1.line("Rotation = 0 - Member Line/Material Axis left to right")

        dlg1.line("Rotation - 180 - Member Line left to right, Material Axis right to left")

        dlg1.group_title("Holes or Studs")

        dlg1.menu('holesORstuds', ("Holes", "Studs", "None"), holesORstuds, 'Add holes or studs')

        dlg1.group_title_end

       

        dlg1.group_title("Embedded plate location and plan rotation")

        dlg1.menu("which_end", ("Left End", "Right End", "Both Ends"), which_end, "Place embed at which end of beam member      ")

        dlg1.entry("embed_plan_rotation", embed_plan_rotation, "Embed plan rotation")

        dlg1.entry("embed_dist", dim_print(embed_dist), "Distance from beam WP to embed member line")

        dlg1.group_title_end

       

        dlg1.group_title("Embedded plate piece mark and material grade")

        dlg1.menu("embed_mark_system_user", ("User", "System"), embed_mark_system_user, "User or System Piece Mark")

        dlg1.entry("user_piece_mark", user_piece_mark, "User Piece Mark")

        dlg1.menu("plate_grade", Job().steel_grades("Plate").keys(), plate_grade, "Plate Material Grade")

        dlg1.entry("plate_seq", plate_seq, "Embed Member Sequence")

        dlg1.group_title_end

       

        dlg1.group_title("Embedded plate dimensions")

        dlg1.entry("plate_length", dim_print(plate_length), "Plate length")

        dlg1.entry("plate_width", dim_print(plate_width), "Plate width")

        dlg1.entry("plate_thk", dim_print(plate_thk), "Plate thickness")

        dlg1.group_title_end

       

        dlg1.tab("Studs")

        dlg1.group_title("Stud attributes")

        dlg1.label(dim_print(head_diam) + " diam. x " + dim_print(head_thk), "Stud head dimensions for default stud diameter: ")

        dlg1.label(dim_print(burn_off), "Burn off for default diameter: ")

        dlg1.menu("stud_diam", stud_diaList, stud_diam, "Stud diameter")

        dlg1.entry("stud_length", dim_print(stud_length), "Stud length")

        dlg1.menu("stud_color", finishList, stud_color, "Finish of stud material")

        dlg1.group_title_end

       

        dlg1.group_title("Stud Pattern")

        dlg1.entry("no_cols", int(no_cols), "Number of stud columns")

        dlg1.entry("no_rows", int(no_rows), "Number of stud rows")

        dlg1.entry("x_spa", dim_print(x_spa), "Stud column spacing")

        dlg1.entry("y_spa", dim_print(y_spa), "Stud row spacing")

        dlg1.group_title_end

        dlg1.group_title("Image of embed plate with studs supporting a joist")

        dlg1.image(image_name6)

        dlg1.group_title_end

       

        dlg1.tab("Holes")       

        dlg1.group_title("Hole Information")

        dlg1.entry("no_cols", int(no_cols), "Number of hole columns")

        dlg1.entry("no_rows", int(no_rows), "Number of hole rows")

        dlg1.entry("x_spa", dim_print(x_spa), "Hole column spacing")

        dlg1.entry("y_spa", dim_print(y_spa), "Hole row spacing")

        dlg1.entry("bolt_size", dim_print(bolt_size), "Bolt diameter")

        dlg1.menu("bolt_type", Job().bolt_sched(), bolt_type, "Bolt type")             

        dlg1.menu("hole_type", holeTypeList, hole_type, "Hole type")

        dlg1.group_title_end

        dlg1.group_title("Long slot length is calculated if 0")

        dlg1.entry("ls_len", dim_print(ls_len), "Long slot length")

        dlg1.group_title_end

       

        dlg1.group_title("Image of embed plate with holes")

        dlg1.image(image_name4)

        dlg1.group_title_end

       

        dlg1.tab("Graphic Images")

        dlg1.column_group_begin()

        dlg1.column(5)

        dlg1.image(image_name1)

        dlg1.column(5)

        dlg1.image(image_name2)

        dlg1.column_group_end()

        dlg1.group_title("Add stiffeners with Beam_Stiff.py")

        dlg1.image(image_name5)

        dlg1.group_title_end

        dlg1.tabset_end()

       

        try:

            dd1 = dlg1.done()

        except ResponseNotOK:

            break

 

        # Update the local namespace

        for key, value in dd1.items():

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

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

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

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

        if print_doc == "Yes":

            print __doc__

            break

       

        # Export defaults to disk if enabled

        if enable_default_import_export == "Enable":

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

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

           

        # Adjust plan rotation angle

        while embed_plan_rotation < -180.0:

            embed_plan_rotation = embed_plan_rotation + 360.0

        while embed_plan_rotation > 180.0:

            embed_plan_rotation = embed_plan_rotation - 360.0

           

        # Set material rotations

        if embed_plan_rotation <= 90.0 and embed_plan_rotation > -90.0:

            plate_rot = 0.0

        else:

            plate_rot = 180.0

       

        # Set stud dimensions

        head_thk, head_diam, burn_off = stud_dim(dim(stud_diam))

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

        for bm in misc_list:

            if embed_mark_system_user == "System":

                _mark_ = ""

            else:

                _mark_ = user_piece_mark

            if which_end in ["Left End", "Both Ends"]:

                pt1 = bm.left.location + bm.translate(embed_dist, 0.0, 0.0)

                ptWP1 = polar_pt_plan(pt1, -plate_length/2, embed_plan_rotation)

                ptWP2 = polar_pt_plan(pt1, plate_length/2, embed_plan_rotation)

               

            elif which_end == "Right End":

                pt1 = bm.right.location + bm.translate(-embed_dist, 0.0, 0.0)

                ptWP1 = polar_pt_plan(pt1, -plate_length/2, embed_plan_rotation)

                ptWP2 = polar_pt_plan(pt1, plate_length/2, embed_plan_rotation)

               

            if bm.type == "Joist":

                ptWP1.z +=  -bm.brg_depth

                ptWP2.z +=  -bm.brg_depth

            else:

                ptWP1.z +=  -bm.depth

                ptWP2.z +=  -bm.depth

           

            # Add member

            memLst = [add_misc_rect_plate(ptWP1, ptWP2, _mark_, plate_width, plate_thk, \

                                            (0.0, 0.0, plate_rot), plate_grade, plate_seq), ]

           

            if which_end == "Both Ends":

                if embed_plan_rotation <= 90.0 and embed_plan_rotation > -90.0:

                    plate_rot1 = 180.0

                else:

                    plate_rot1 = 0.0

                pt1 = bm.right_location + bm.translate(-embed_dist, 0.0, 0.0)

                ptWP1 = polar_pt_plan(pt1, -plate_length/2, embed_plan_rotation-180.0)

                ptWP2 = polar_pt_plan(pt1, plate_length/2, embed_plan_rotation-180.0)

               

                if bm.type == "Joist":

                    ptWP1.z +=  -bm.brg_depth

                    ptWP2.z +=  -bm.brg_depth

                else:

                    ptWP1.z +=  -bm.depth

                    ptWP2.z +=  -bm.depth

                # Add member

                memLst.append(add_misc_rect_plate(ptWP1, ptWP2, _mark_, plate_width, plate_thk, \

                                                 (0.0, 0.0, plate_rot1), plate_grade, plate_seq))

 

            if holesORstuds == "Studs":

 

                for mem in memLst:

                    first_dist_horiz = ((plate_length - x_spa * (no_cols - 1)) / 2)

                    first_dist_vert = ((plate_width - y_spa * (no_rows - 1)) / 2)

                    point1 = mem.left_location + mem.main_mtrl().translate (first_dist_horiz, -first_dist_vert, -plate_thk)

                    x_dist = 0.0

                    for i in range(no_cols):

                        y_dist = 0.0

                        x_dist = i*x_spa

                        for j in range(no_rows):

                            y_dist = j*y_spa

                            ptWP = point1 + mem.main_mtrl().translate (x_dist, -y_dist, 0.0)

                            apply_stud(mem, ptWP, Point(ptWP.x, ptWP.y, ptWP.z - stud_length), dim(stud_diam), head_thk, head_diam, stud_color)

                           

            elif holesORstuds == "Holes":

                for mem in memLst:

                    first_dist_horiz = ((plate_length - x_spa * (no_cols - 1)) / 2)

                    first_dist_vert = ((plate_width - y_spa * (no_rows - 1)) / 2)

                    point1 = mem.left_location + mem.main_mtrl().translate (first_dist_horiz, -first_dist_vert, 0.0)

                    pl_holes (mem, point1, 0.0, 0.0, x_spa, y_spa, no_cols, no_rows, 'Below Right', bolt_size, bolt_type, hole_type, ls_len)

               

            else:

                # Add nothing

                pass

 

## End run_script()

if __name__ == '__main__':

    try:

        run_script()

    finally:

        del run_script