##MtrlCutHole.py Version 1.00

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

##All rights reserved.

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

"""

/// Given 3 non-collinear points, define a plane and create a list of points about

/// point 1 to be used to make a hole with cut layout.

/// User can be in any model orientation, but must align with surface to cut.

/// Developed by Bruce Vaughan, BV Detailing & Design, Inc. (October 2006)

/// URL: www.bvdetailing.com

/// Credit Paul Bourke for 'Rotate A Point About An Arbitrary Axis (3D)' (August 2002) and

/// 'Equation of a plane' (March 1989))

///

/// Revision History:

///     Version 1.00 (01/24/07) -   Initial release

///

///

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

///     P3D.py

///     pickle.py (required for FileDefaults)

///     FileDefaults.py

///     ExceptWarn.py

///     PolarPt.py

///     printPtList

///

/// Go to 'Variables section to edit default values file path and file name

"""

def run_script():

    # startup code begin

    from macrolib.P3D import Plane3D

    from macrolib.FileDefaults import import_data, export_data

    from macrolib.ExceptWarn import formatExceptionInfo

    from macrolib.PolarPt import PolarPt3D

    from macrolib.PrintPtList import formatPtList

    import types

    import os

    from math import floor, ceil, pi, sqrt

    from param import yes_or_no, Dialog, dim_print

    from mtrl_list import MtrlLocate, HoleLocate

    from point import Point, PointLocate

    from mtrl_cut import MtrlCut

   

    # startup code end

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

    ## Variables section

    # system path for defaults file

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

    # default values file

    def_file = "PlateCutRadius_v1_00.txt"

    # no images in this version

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

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

    enable_default_import_export = "Enable"    

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

    ## Defaults Section

    no_spa = 36                             # Number of points to calculate for the hole

    mtrl_orientation = 'Web'                # ('Web', 'Top Flg', 'Bott Flg', 'RE', 'LE')

    ## End variables and defaults section

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

    ## Cut layout function

    def radius_cut(mtrl, ptList, rot):

        #try:

        # mtrl cut begin

        mcut1 = MtrlCut()

        mcut1.mtrl = [mtrl, ]

        mcut1.rotate = rot

        for pt in ptList:

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

        mcut1.cut("Layout")

        return True

        #except:

            #Warning(formatExceptionInfo())

            #return False

        # mtrl cut end

 

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

    # if enabled, import defaults used previously from disk file

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

            else:

                Warning("Invalid data - Reverting to original defaults")

    ## Main program

    while 1:

        m1 = MtrlLocate("Select material to cut")

       

        pt1 = PointLocate("Pick center point of hole")

        pt2 = PointLocate("Pick material cut start point at radius")

        pt3 = PointLocate("Pick a reference point to define the current plane")

        theta = pi

       

        if pt1 != None and pt2 != None and pt3 != None:

            a = Plane3D(pt1, pt2, pt3, theta)

            if a.N_len > 0.0:

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

                dlg1 = Dialog("Radius Material Cut Options")

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

                dlg1.line("The arc radius = %s and the arc length = %s." % (dim_print(a.Ra), dim_print(a.pp)))

                dlg1.entry("no_spa", no_spa, "Number of spaces")

                dlg1.line("At the present time only valid orientations are 'Web', 'Top Flg', and 'LE'")

                dlg1.menu('mtrl_orientation', ('Web', 'Top Flg', 'LE'), mtrl_orientation, "Material View")

               

                try:

                    dd1 = dlg1.done()

                except ResponseNotOK:

                    break

                for key, value in dd1.items():

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

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

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

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

                if print_doc == "Yes":

                    print __doc__

                    break

               

                if mtrl_orientation == 'Web':

                    cut_arg = (0,0,0)

                elif mtrl_orientation == 'Top Flg':

                    cut_arg = (90.0,0,0)

                elif mtrl_orientation == 'Bott Flg': # does not work

                    cut_arg = (-90.0,0,0)

                elif mtrl_orientation == 'RE': # does not work

                    cut_arg = (0,90.0,0)

                elif mtrl_orientation == 'LE':

                    cut_arg = (0,-90.0,0)

                else:

                    break

               

                # Export defaults to disk if enabled

                if enable_default_import_export == "Enable":

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

               

                pt_list = [pt2, ]

           

                # spacing_method == "Even Spacing":

                actual_spa = a.pp/(no_spa/2)

                dst = actual_spa

                spaces = no_spa - 1

 

                # Compile a list of points determined by the angle required between construction lines

                for i in range(spaces):

                    pt_list.append(a.PointRotate3D(pt2, dst/a.Ra))

                    dst = dst + actual_spa

                       

                pt_list.append(a.PointRotate3D(pt2, 2*pi))

 

                print formatPtList("Selected point list:", [pt1, pt2, pt3])

                print formatPtList("Cut point list:", pt_list)

               

                radius_cut(m1, pt_list, cut_arg)

 

            else:

                Warning("The 3 points selected must not be collinear.")

        if not yes_or_no("Cut more material?"):

            break

## end run_script() #########################################################

if __name__ == '__main__':

    try:

        run_script()

    finally:

        del run_script