##  Col_BPL_Nonsym.py Version 1.18

##  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 nonsymmetrical base plate to the bottom of a column shaft or cap plate

    to the top of a column shaft.

    Input the column with the desired minus dimension (bottom of base plate)

    and the material setback (top of base plate) with desired web and flange cuts.

    The plate x slope = web cut and y slope = flange cut. The script ignores the

    flange cut bevel if the web cut bevel > abs(0.0). The distance the user enters to

    locate each hole pattern is measured from the column center at the top of

    the base plate or bottom of cap plate (enter positive x and y to locate in the

    desired quadrant). The user must account for the resulting offset to the bottom

    of the base plate or top of cap plate where required if the base plate slopes.

 

    The user can select a plate rotation. Plate rotation is disabled when the end of

    the column is bevel cut.

 

    The default plate thickness is (material setback - minus dimension) * cos(pl_slope).

 

    The user can input up to 4 hole patterns - ul, ur, ll, lr (ex. - ul = upper left

    quadrant of base plate when looking down at the column bottom end view).

    Example: To add a 6 hole pattern (:::), select any quadrant, enter positive x and y

    distances to the corner hole in the selected quadrant, enter 3 columns and 2 rows,

    and enter positive column and row spacings (check the 'None' button for plain plate).

 

    All hole patterns use the same bolt diameter, hole size, etc. The reference point

    for the hole patterns is the column center at the top of base plate or bottom of

    the cap plate.

 

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

 

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

    Developed in SDS2 6.313, Python 2.2.1 2/28/03

    Tested in SDS/2 7.022 3/14/06   **NOT COMPATIBLE WITH SDS/2 6.3**

 

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

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

 

    REVISION HIOSTORY:

    R1-6_2  Update code (2/28/02) Note that positive column and row spacings now

            will take the hole pattern toward the column. Entering negative spacings

            will take the hole pattern away from the column.

    R1-6_3  Modified hole pattern for rectangular plate to work in SDS/2 6.3xx as follows:

            Line 172 was "hole26.group_rot = 0.0"

            Change line 172 to "hole26.group_rot = -90.0"

    R2      Changed hole pattern rotation to work in SDS/2 version 6.323 and later -

                Change line 177 to "hole26.group_rot = 180.0"

    R3      Changed rectangular plate reference point (line 147) to:

                rp1.ref_pt_offset = (pl_left, -pl_up, 0.0) # global variables pl_left, pl_up

    V7R1    Test in SDS/2 7.002, update code

            Add cap plates

            Add ability to import and export default data

    V7R2    Rework import/export functions

    V7R2a   Fixed problem with importing file defaults in 6.3 (9/11/04)

    V7R2b   Fixed a problem with using the variable name "str" which is a built in function

    V7R3    Add ClearSelection() (3/13/05)

    V7R4    Corrected hole type "Oversized" to "Oversized round" (6/10/05)

    V7R5    Add column information to dialog box

    V7R6    Incorporate dd.file for selection of default file names

    V7R7    Add system path for defaults files

    V7R8    Add option to automatically save/import defaults to/from disk file

    V7R9    Add tabs and columns in dialog box

    R10     Add option to rotate base plate on square/standard cut ends (3/15/06)

   

    Version 1.11 (4/9/06) -     Correct variable name at import_data function call.

    Version 1.12 (5/25/06) -    Added code to ensure variable 'patt_list' was defined when importing

                                a custom default file.

    Version 1.13 (7/10/06) -    Incorporate dd1.file_save into dialog box.

                                Note this version will not work in versions prior to 7.026.

    Version 1.14 (9/14/06) -    Sort on dialog box variable names when writing defaults to disk.

    Version 1.15 (10/28/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.16 (11/7/06) -    Corrected variable name 'def_file' to 'import_file' where importing

                                user default values file.

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

    Version 1.18 (12/17/06) -   Eliminate check for import of a list of dictionaries.

                                'import_data' now returns one dictionary or None.

                                Make corrections and enhancements to user import defaults

                                import mem_select

   

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

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

    ****      This version will not work in versions prior to 7.026 ******

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

 

    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

        ExceptWarn.py

        P3D.py

 

    Required folders:

        "system path"/macrolib

        "system path"/Defaults

        "system path"/Images

 

"""

def run_script():

    # startup code begin

    from math import cos, sin, atan2, ceil

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

    import macrolib.pickle

    from macrolib.FileDefaults import import_data, export_data, job_Defaults_path1, data_Defaults_path, check_Defaults_dir

    from macrolib.FileDefaults import import_user_data, export_user_data

    from macrolib.MemCnt import member_count

    from macrolib.angle import rtod, dtor

    from macrolib.ExceptWarn import formatExceptionInfo

    from macrolib.P3D import Plane3D

    from macrolib.MemSelection import mem_select

   

    import os

    import sys

    Units("feet")

    from job import Job

    from shape import Shape

    from point import Point, PointLocate

    from member import Member, MemberLocate

    from cons_line import ConsLine

    from rect_plate import RectPlate

    from bnt_plate import BntPlate

    from rolled_section import RolledSection

    from weld_add import Weld

    from hole_add import Hole

    from mtrl_cut import MtrlCut

    # startup code end

    try:

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

        drv_letter, drv_path = os.path.splitdrive(os.getcwd())

        ## Variables section

        # system path for default values files

        # auto save path

        default_file_path = data_Defaults_path()

        # user save path

        job_default_file_path = os.path.join(job_Defaults_path1(), "Col_BPL_Nonsym")

        # default values file

        def_file = "Col_BPL_Nonsym_v1_18.txt"

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

        # ("Enable", "Disable") to/from 'def_file'

        enable_default_import_export = "Enable"

        # Set this option to 'Yes' in the dialog box to save defaults to a custom default file

        default_file_for_saving = "BPXXX.txt"

        script_name = 'Col_BPL_Nonsym'

 

        """

            The saving and importing of default files requires that a subdirectory 'Defaults' exists.

            The 'Defaults' directory for automatic import/export is returned by 'data_Defaults_path()' ('SDS/2 root data/macro/Defaults)

            The 'Defaults' directory for user import/export is returned by 'job_Defaults_path1()'('job directory'/macro/Defaults')

        """

        # check if automatic defaults directory exists

        if enable_default_import_export == "Enable":

            if not check_Defaults_dir(default_file_path):

                Warning("Edit the parametric and change variable \n'enable_default_import_export' value to 'Disable'")

        # check if user defaults directory exists

        if not check_Defaults_dir(job_default_file_path):

            job_default_file_path = default_file_path

       

        # Dialog box image path and file name

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

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

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

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

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

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

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

        pl_rotation = 45.0      # plate rotation about column CL (degrees)

        pl_left = 12.0           # distance to left plate edge

        pl_right = 18.0          # distance to right plate edge

        pl_up = 12.0             # distance to upper plate edge

        pl_down = 18.0           # distance to lower plate edge

 

        # UPPER LEFT

        ul_x = 10.0              # upper left pattern x dimension

        ul_y = 10.0              # upper left pattern y dimension

        ul_cols = 2             # upper left pattern number of columns (x direction)

        ul_rows = 2             # upper left pattern number of rows (y direction)

        ul_spx = 8.0            # column spacing

        ul_spy = 8.0           # row spacing

 

        # LOWER LEFT

        ll_x = 0.0              # lower left pattern x dimension

        ll_y = 6.5              # lower left pattern y dimension

        ll_cols = 1             # lower left pattern number of columns (x direction)

        ll_rows = 2             # lower left pattern number of rows (y direction)

        ll_spx = 3.0            # column spacing

        ll_spy = 3.0            # row spacing

 

        # UPPER RIGHT

        ur_x = 5.0              # upper right pattern x dimension

        ur_y = 5.0              # upper right pattern y dimension

        ur_cols = 2             # upper right pattern number of columns (x direction)

        ur_rows = 1             # upper right pattern number of rows (y direction)

        ur_spx = 7.5            # column spacing

        ur_spy = 7.5            # row spacing

 

        # LOWER RIGHT

        lr_x = 5.0           # lower right pattern x dimension

        lr_y = 5.0           # lower right pattern y dimension

        lr_cols = 1             # lower right pattern number of columns (x direction)

        lr_rows = 1             # lower right pattern number of rows (y direction)

        lr_spx = 12.0           # column spacing

        lr_spy = 12.0           # row spacing

 

        # default material finish "None", "Red Oxide", "Yellow Zinc", "Gray Oxide", "Sandblasted", "Blued Steel", "Galvanized"   

        pl_color = "Yellow Zinc"        

        steelgrade = "A36"              # plate material grade

        bolt_size = 0.75                # bolt diameter

        # hole diameter (enter 0.0 for SDS/2 to calculate hole diameter from hole type and bolt diameter)

        hole_dia = 0.0

       

        # default hole type ["Standard Round", "Short Slot", "Oversized round", "Long Slot", "Cope Hole",

        # "Erection Pin Hole", "Anchor Bolt Hole", "Plug Weld Hole"]

        hole_type = "Oversized round"

       

        bolt_type = "Auto"          # bolt type "Auto" "A325N" "A325SC" "A307"

        ad_pl_weld = "Yes"          # add base plate weld       "Yes" "No"

        pl_weld_type = "Fillet"     # weld type "Fillet" "Bevel groove"

        weld_size = 0.1875          # weld size

        weld_around = "Yes"         # weld all around "No" "Yes"

        patt_list = ["UL", "LR"]    # pattern quadrant "UL" "LL" "UR" "LR" "None"

       

        # Add a cap or base plate

        cap_or_base = "Base Plate"  # "Cap Plate", "Base Plate"

        # End defaults section

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

        ## FUNCTION DEFINITIONS -------------------------------------------------##

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

        # Add a rectangular plate object

        # Ref_pt is the center of the column

        # Returns the rectangular plate object

        def plate_add(col, ref_pt, pnt1, pnt2, pl_width, pl_thk, pl_length, pl_grade, pl_color, rot1, pl_slope, pl_origin):

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

            # rectangular plate begin

            rp1 = RectPlate()

            rp1.member = col

            rp1.pt1 = pnt1

            rp1.pt2 = pnt2

            rp1.grade = pl_grade

            rp1.origin = pl_origin

            rp1.top_oper_left = "None"

            rp1.top_oper_right = "None"

            rp1.bottom_oper_left = "None"

            rp1.bottom_oper_right = "None"

            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.finish = pl_color

            rp1.ref_pt_offset = (pl_left, -pl_up, 0.0) # global variables pl_left, pl_up

            rp1.add()

            rp1.rotate(rp1.member, rot_arg)

            # rectangular plate end

            return rp1

 

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

        # Add a hole pattern

        def bp_hole (rect_pl, hl_ref_pt, hl_face, x_off, y_off, bd, hs, ht, bt, quadrant, no_x, no_y, spa_x, spa_y):

            if quadrant == "UL":

                hl_patt = "Below Right"

            elif quadrant == "LL":

                hl_patt = "Above Right"

            elif quadrant == "UR":

                hl_patt = "Below Left"

            elif quadrant == "LR":

                hl_patt = "Above Left"

            else:

                print "Something is wrong with pattern"

       

            if hs > 0.0:

                str1 = "hs"

            else:       

                str1 = "hole26.calc_hole_size()"

               

            try:

                # hole group add begin

                hole26 = Hole()

                hole26.mtrl = [rect_pl, ]

                hole26.pt1 = hl_ref_pt

                hole26.hole_type = ht

                hole26.face = hl_face

                hole26.valid_cnc = "Yes"

                hole26.x_ref_offset = x_off

                hole26.y_ref_offset = y_off

                hole26.x_spa = spa_x

                hole26.y_spa = spa_y

                hole26.group_rot = 0.0

                hole26.locate = hl_patt

                hole26.columns = int(no_x)

                hole26.rows = int(no_y)

                hole26.bolt_type = bt

                hole26.bolt_dia = bd

                hole26.slot_rot = 0.0

                hole26.length = hole26.calc_slot_length()

                hole26.hole_dia = eval(str1)

                hole26.show_window = "Yes"

                hole26.create()

                # hole group add end

            except:

                Warning("The %s hole pattern you entered could not be added.\n%s" % (quadrant, formatExceptionInfo()))

                

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

        # Add base plate weld

        def base_pl_weld(col, rl5, weld_size, weld_type, around):

            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 = [col, ]

                weld9.min_size = dim(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 = around

                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:

                Warning("The weld could not be added.\n" + (formatExceptionInfo()))

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

        ## End function definitions ###############################################

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

        ## 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 1:

            ddOut = {}

            ClearSelection()

            ## DIALOG BOX FOR IMPORT DEFAULT VALUES FILE AND CAP OR BASE PLATE

            dlg11 = Dialog("Initial Options")

            dlg11.group_title("Import User Default Values File")

            dlg11.menu('import_yes_or_no', ('Yes', 'No'), 'No', 'Import file?               ')

            dlg11.file('import_file', os.path.join(job_default_file_path, "*.txt"), "Enter file name or browse")

            dlg11.group_title("Base or Cap Plate")

            dlg11.menu('cap_or_base', ("Cap Plate", "Base Plate"), cap_or_base, "Cap Plate or Base Plate?")

            try:

                dd11 = dlg11.done()

            except ResponseNotOK:

                break

 

            if dd11['import_yes_or_no'] == 'Yes':

                dd0 = import_user_data(dd11['import_file'])

                if dd0:

                    dd11.update(dd0)

                                   

            # Update the local namespace

            for key, value in dd11.items():

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

           

            ddOut.update(dd11)

           

            if cap_or_base == "Cap Plate":

                Add_bpl = "Cap Plate"

            else:

                Add_bpl = "Base Plate"

 

            if patt_list == 'None':

                patt_list = ['None', ]

            # Select column member

            col_list = mem_select("Select a COLUMN member to receive cap or base plate.", ['Column',], ["All", ])

            if col_list is None:

                break

            mem1 = col_list[0]

                   

            # Calculate additional values, set plate slope

            if Add_bpl == "Base Plate":

                pl_slope_flg = round(mem1.left.flange_cut_angle * 10000) / 10000

                pl_slope_web = round(mem1.left.web_cut_angle * 10000) / 10000

                pl_thk = abs(mem1.left.setback - mem1.left.minus_dim) * cos(dtor(pl_slope_web))

                if abs(pl_slope_flg) > 0.0 and pl_slope_web == 0.0:

                    pl_thk = abs(mem1.left.setback - mem1.left.minus_dim) * cos(dtor(pl_slope_flg))

                bpl_origin = "NS"                   # plate material reference point

            else:

                pl_slope_flg = round(mem1.right.flange_cut_angle * 10000) / 10000

                pl_slope_web = round(mem1.right.web_cut_angle * 10000) / 10000

                pl_thk = abs(mem1.right.setback - mem1.right.minus_dim) * cos(dtor(pl_slope_web))

                if abs(pl_slope_flg) > 0.0 and pl_slope_web == 0.0:

                    pl_thk = abs(mem1.right.setback - mem1.right.minus_dim) * cos(dtor(pl_slope_flg))

                bpl_origin = "FS"                   # plate material reference point

               

            # Do not allow plate thicknesses less than 1/4

            if pl_thk < 0.25:

                pl_thk = 0.25

               

            if round(pl_slope_flg, 3) == 0.0 and round(pl_slope_web, 3) == 0.0:

                enable_pl_rotation = "Yes"

            else:

                enable_pl_rotation = "No"

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

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

            dlg1 = Dialog( "Add a nonsymmetrical cap or base plate to a column" )

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

            dlg1.menu("default_save", ("Yes", "No"), "No", "Save dialog box values to user's disk file         ")

            dlg1.tabset_begin()       

            dlg1.tab("General Information")

            dlg1.column_group_begin()

            dlg1.column(0)

            dlg1.line(Add_bpl + " - Selected Column Information")

            dlg1.line("%s (%s) at location %s, %s, %s" % (col_list[0].size, col_list[0].piecemark, \

                                                          dim_print(col_list[0].left.location.x), \

                                                          dim_print(col_list[0].left.location.y), \

                                                          dim_print(col_list[0].left.location.z)))

            dlg1.line("Column Rotation = " + "%*.*f" % (5,4,col_list[0].plan_rotation))

            dlg1.checkbutton("patt_list", ["UL", "LL", "UR", "LR", "None"], patt_list, "Available Hole Patterns" )

                     

            dlg1.group_title(Add_bpl + " Dimensions, Mtrl Grade and Color")

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

            dlg1.entry("pl_left", dim_print(pl_left), "Plate dimension left")

            dlg1.entry("pl_right", dim_print(pl_right), "Plate dimension right")

            dlg1.entry("pl_up", dim_print(pl_up), "Plate dimension up")

            dlg1.entry("pl_down", dim_print(pl_down), "Plate dimension down")

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

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

                      pl_color, "Select plate finish" )

            dlg1.group_title_end

                     

            if enable_pl_rotation == "Yes":

                dlg1.group_title(Add_bpl + " Rotation")

                dlg1.entry("pl_rotation", pl_rotation, "Plate rotation about column CL in degrees")

            elif round(pl_slope_flg, 3) <> 0.0:

                dlg1.group_title(Add_bpl + " Rotation")

                dlg1.line("Column flange cut = %*.*f. %s rotation is disabled." %(5,4,pl_slope_flg, Add_bpl))

                pl_rotation = 0.0

            elif round(pl_slope_web, 3) <> 0.0:

                dlg1.group_title(Add_bpl + " Rotation")

                dlg1.line("Column web cut = " + "%*.*f. %s rotation is disabled." %(5,4,pl_slope_web, Add_bpl))

                pl_rotation = 0.0

            else:

                dlg1.line("There was a problem. Base plate rotation is disabled.")

                pl_rotation = 0.0

               

            dlg1.column(24)

            if Add_bpl == "Base Plate":

                dlg1.image(image_name2)

            else:

                dlg1.image(image_name1)

            dlg1.column_group_end()

           

            dlg1.tab("Weld and Hole Options")

            dlg1.group_title("Welding")

            dlg1.column_group_begin()

            dlg1.column(0)

            dlg1.menu("ad_pl_weld", ("Yes", "No"), ad_pl_weld, "Add weld" )

            dlg1.menu("pl_weld_type", ("Fillet", "Square butt", "Bevel groove"), pl_weld_type, "Select weld type")

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

            dlg1.menu("weld_around", ("Yes", "No"), weld_around, "Weld all around")

            dlg1.column(0)

            dlg1.image(image_name4)

            dlg1.column_group_end()

            dlg1.group_title_end

           

            dlg1.group_title("Bolt/Holes")

            dlg1.column_group_begin()

            dlg1.column(0)

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

            dlg1.entry("hole_dia", dim_print(hole_dia), "Hole diameter (enter 0 to calculate)")

            dlg1.menu("hole_type", ("Standard Round", "Short Slot", "Oversized round", "Long Slot", "Cope Hole", "Erection Pin Hole",\

                                    "Anchor Bolt Hole", "Plug Weld Hole"), hole_type, "Hole type")

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

            dlg1.column(0)

            dlg1.image(image_name5)

            dlg1.column_group_end()

            dlg1.group_title_end

           

            dlg1.tab("Graphic")

            dlg1.image(image_name)

            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

               

            if not patt_list:

                patt_list = ["None", ]

                dd1["patt_list"] = ["None", ]

            else:

                if "None" in patt_list:

                    patt_list = ["None", ]

                    dd1["patt_list"] = ["None", ]

                   

            if pl_rotation == 0.0:

                dd1["pl_rotation"] = 0.0

            if print_doc == "Yes":

                print __doc__

                break

            ddOut.update(dd1)

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

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

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

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

            if "None" not in patt_list:

                dlg2 = Dialog( "Hole pattern dimensions" )

                dlg2.tabset_begin()

                if "UL" in patt_list:

                    dlg2.tab("Upper Left")

                    dlg2.line("X and Y dims. locate corner hole. Enter positive column and row spacings for pattern to spread toward column.")

                    dlg2.line("Plate Size: " + dim_print((pl_left + pl_right)) + " x " + dim_print((pl_up + pl_down)))

                    dlg2.line("Plate UL location: " + dim_print(pl_left) + ", " + dim_print(pl_up))

                    dlg2.entry("ul_x", dim_print(ul_x), "Corner Hole X dimension   ")

                    dlg2.entry("ul_y", dim_print(ul_y), "Corner Hole Y dimension   ")

                    dlg2.entry("ul_cols", ul_cols, "Number of columns (X dir)")

                    dlg2.entry("ul_rows", ul_rows, "Number of rows (Y dir)")

                    dlg2.entry("ul_spx", dim_print(ul_spx), "Column spacing")

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

                if "LL" in patt_list:

                    dlg2.tab("Lower Left")

                    dlg2.line("X and Y dims. locate corner hole. Enter positive column and row spacings for pattern to spread toward column.")

                    dlg2.line("Plate Size: " + dim_print((pl_left + pl_right)) + " x " + dim_print((pl_up + pl_down)))

                    dlg2.line("Plate LL location: " + dim_print(pl_left) + ", " + dim_print(pl_down))

                    dlg2.entry("ll_x", dim_print(ll_x), "Corner Hole X dimension   ")

                    dlg2.entry("ll_y", dim_print(ll_y), "Corner Hole Y dimension   ")

                    dlg2.entry("ll_cols", ll_cols, "Number of columns (X dir)")

                    dlg2.entry("ll_rows", ll_rows, "Number of rows (Y dir)")

                    dlg2.entry("ll_spx", dim_print(ll_spx), "Column spacing")

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

                if "UR" in patt_list:

                    dlg2.tab("Upper Right")

                    dlg2.line("X and Y dims. locate corner hole. Enter positive column and row spacings for pattern to spread toward column.")

                    dlg2.line("Plate Size: " + dim_print((pl_left + pl_right)) + " x " + dim_print((pl_up + pl_down)))

                    dlg2.line("Plate UR location: " + dim_print(pl_right) + ", " + dim_print(pl_up))

                    dlg2.entry("ur_x", dim_print(ur_x), "Corner Hole X dimension   ")

                    dlg2.entry("ur_y", dim_print(ur_y), "Corner Hole Y dimension   ")

                    dlg2.entry("ur_cols", ur_cols, "Number of columns (X dir)") 

                    dlg2.entry("ur_rows", ur_rows, "Number of rows (Y dir)")

                    dlg2.entry("ur_spx", dim_print(ur_spx), "Column spacing")

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

                if "LR" in patt_list:

                    dlg2.tab("Lower Right")

                    dlg2.line("X and Y dims. locate corner hole. Enter positive column and row spacings for pattern to spread toward column.")

                    dlg2.line("Plate Size: " + dim_print((pl_left + pl_right)) + " x " + dim_print((pl_up + pl_down)))

                    dlg2.line("Plate LR location: " + dim_print(pl_right) + ", " + dim_print(pl_down))

                    dlg2.entry("lr_x", dim_print(lr_x), "Corner Hole X dimension   ")

                    dlg2.entry("lr_y", dim_print(lr_y), "Corner Hole Y dimension   ")

                    dlg2.entry("lr_cols", lr_cols, "Number of columns (X dir)")      

                    dlg2.entry("lr_rows", lr_rows, "Number of rows (Y dir)")

                    dlg2.entry("lr_spx", dim_print(lr_spx), "Column spacing")       

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

                dlg2.tab("Graphic Image")

                dlg2.image(image_name)

                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

                   

                ddOut.update(dd2)

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

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

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

               

            # User save default values to disk

            if default_save == "Yes":

                dlg3 = Dialog("Save Current Dialog Values To Disk")

                dlg3.file_save('export_file', os.path.join(job_default_file_path, "BP.txt"), "Enter file name or browse")

                try:

                    dd3 = dlg3.done()

                except ResponseNotOK:

                    break

                ddOut.update(dd3)

               

                for key in ddOut:

                    print '%s = %s' % (key, ddOut[key])

                export_user_data(dd3['export_file'], ddOut, script_name)

               

            # Auto export default values to disk if enabled

            if enable_default_import_export == "Enable":

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

                   

            ### ADD THE CAP OR BASE PLATE AND HOLE PATTERNS ###########################

            i = 0

            while i < len(col_list):

                # Calculate plate work point locations and rotation required

                if Add_bpl == "Base Plate":

                   

                    if enable_pl_rotation == "Yes":

                        pt11 = col_list[i].left.location

                        # calculate point at CL column and top of base plate

                        pt23 = pt11 + col_list[i].translate(col_list[i].left.minus_dim + pl_thk, 0.0, 0.0)

                        # define plane of top of base plate

                        a = Plane3D(pt23, pt23 + col_list[i].translate(0.0, 0.0, 10.0), \

                                    pt23 + col_list[i].translate(0.0, 10.0, 0.0))

                        # calculate material WP of plate given pl_left, pl_up, pl_rotation (in radians)

                        pt21 = a.PointRotate3D((pt23 + col_list[i].translate(0.0, pl_left, -pl_up)), -dtor(pl_rotation))

                        # calculate opposite material WP of plate along column length

                        pt22 = pt21 + col_list[i].translate(pl_left + pl_right, 0.0, 0.0)

                        rot_pl = (-90.0, -pl_rotation, -90.0)

                    else:   

                        reqd_left_setback = col_list[i].left.minus_dim + (pl_thk / cos(dtor(pl_slope_web)))

                        pt11 = col_list[i].left.location

                        pt21 = pt11 + col_list[i].translate(reqd_left_setback - pl_left * sin(dtor(pl_slope_web)), \

                                                            pl_left * cos(dtor(pl_slope_web)), -pl_up)

                        pt22 = pt21 + col_list[i].translate((pl_left + pl_right) * sin(dtor(pl_slope_web)), \

                                                            (pl_left + pl_right) * cos(dtor(pl_slope_web)), 0.0)

                        pt23 = pt11 + col_list[i].translate(reqd_left_setback, 0.0, 0.0)

                        rot_pl = (-90.0, 0.0, -90.0 + pl_slope_web)

                        if abs(pl_slope_flg) > 0.0 and pl_slope_web == 0.0:

                            reqd_left_setback = col_list[i].left.minus_dim + (pl_thk / cos(dtor(pl_slope_flg)))

                            pt21 = pt11 + col_list[i].translate(reqd_left_setback - pl_up * sin(dtor(pl_slope_flg)), \

                                                                pl_left, -pl_up * cos(dtor(pl_slope_flg)))

                            pt22 = pt21 + col_list[i].translate(0.0, pl_left + pl_right, 0.0)

                            rot_pl = (-90.0 - pl_slope_flg, 0.0, -90.0)

                           

                elif Add_bpl == "Cap Plate":

                   

                    if enable_pl_rotation == "Yes":

                        pt11 = col_list[i].right.location

                        # calculate point at CL column and bottom of cap plate

                        pt23 = pt11 + col_list[i].translate(-col_list[i].left.minus_dim - pl_thk, 0.0, 0.0)

                        # define plane of bottom of cap plate

                        a = Plane3D(pt23, pt23 + col_list[i].translate(0.0, 0.0, 10.0), \

                                    pt23 + col_list[i].translate(0.0, 10.0, 0.0))

                        # calculate material WP of plate given pl_left, pl_up, pl_rotation (in radians)

                        pt21 = a.PointRotate3D((pt23 + col_list[i].translate(0.0, pl_left, -pl_up)), -dtor(pl_rotation))

                        pt22 = pt21 + col_list[i].translate(pl_left + pl_right, 0.0, 0.0)

                        rot_pl = (-90.0, -pl_rotation, -90.0)

                       

                    else:               

                        reqd_right_setback = col_list[i].right.minus_dim + (pl_thk / cos(dtor(pl_slope_web)))

                        pt11 = col_list[i].right.location

                        pt21 = pt11 + col_list[i].translate(-reqd_right_setback - pl_left * sin(dtor(pl_slope_web)), \

                                                            pl_left * cos(dtor(pl_slope_web)), -pl_up)

                        pt22 = pt21 + col_list[i].translate((pl_left + pl_right) * sin(dtor(pl_slope_web)), \

                                                            (pl_left + pl_right) * cos(dtor(pl_slope_web)), 0.0)

                        pt23 = pt11 + col_list[i].translate(-reqd_right_setback, 0.0, 0.0)

                        rot_pl = (-90.0, 0.0, -90.0 + pl_slope_web)

                       

                        if abs(pl_slope_flg) > 0.0 and pl_slope_web == 0.0:

                            reqd_right_setback = col_list[i].right.minus_dim + (pl_thk / cos(dtor(pl_slope_flg)))

                            pt21 = pt11 + col_list[i].translate(-reqd_right_setback - pl_up * sin(dtor(pl_slope_flg)), \

                                                                pl_left, -pl_up * cos(dtor(pl_slope_flg)))

                            pt22 = pt21 + col_list[i].translate(0.0, pl_left + pl_right, 0.0)

                            rot_pl = (-90.0 - pl_slope_flg, 0.0, -90.0)

                           

                else:

                    print "Invalid option"

                    break

               

                # Add base plate

                rp1 = plate_add(col_list[i], pt23, pt21, pt22, (pl_up + pl_down), pl_thk, \

                                (pl_left + pl_right), steelgrade, pl_color, rot_pl, 0.0, bpl_origin)

               

                # Add hole pattern(s)

                if "UL" in patt_list:

                    bp_hole (rp1, pt23, "NS Face", -ul_x, -ul_y, bolt_size, hole_dia, hole_type, \

                             bolt_type, "UL", ul_cols, ul_rows, ul_spx, ul_spy)

                if "LL" in patt_list:

                    bp_hole (rp1, pt23, "NS Face", -ll_x, -ll_y, bolt_size, hole_dia, hole_type, \

                             bolt_type, "LL", ll_cols, ll_rows, ll_spx, ll_spy)

                if "UR" in patt_list:

                    bp_hole (rp1, pt23, "NS Face", -ur_x, -ur_y, bolt_size, hole_dia, hole_type, \

                             bolt_type, "UR", ur_cols, ur_rows, ur_spx, ur_spy)

                if "LR" in patt_list:

                    bp_hole (rp1, pt23, "NS Face", -lr_x, -lr_y, bolt_size, hole_dia, hole_type, \

                             bolt_type, "LR", lr_cols, lr_rows, lr_spx, lr_spy)

                if ad_pl_weld == "Yes":

                    base_pl_weld(col_list[i], rp1, weld_size, pl_weld_type, weld_around)

               

                if i == 0:

                    # If user is satisfied with the first base plate added, script proceeds to

                    # add to the remaining members in the selection set. If the user is not

                    # satisfied, the base plate is erased and the loop starts over.

                    base_plate_OK= yes_or_no("Is the plate added correct? Yes to accept, No to erase.", "Yes", "No")

                    if base_plate_OK == "No":

                        rp1.erase()

                        break

                i = i+1

    except:

        Warning(formatExceptionInfo())

## END run_script() ###########################################################

if __name__ == '__main__':

    try:

        run_script()

    finally:

        del run_script