## IMAGE

##MtrlCutRadius.py Version 1.03

##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 and between points 2 and 3 to be used to make a radiused material cut.

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

///     Version 1.01 (02/12/07) -   Modify import default values code

///     Version 1.02 (07/09/07) -   Reword cut 'Above/Below' to 'Outside/Inside'

///     Version 1.03 (07/26/07) -   Modify cut layout point locations beyond material

///

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

///     P3D.py

///     pickle.py (required for FileDefaults)

///     FileDefaults.py

///     ExceptWarn.py

///     PolarPt.py

///     PrintPtList.py

///

/// 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_02.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

    spacing_method = "Even Spacing"         #("Even Spacing", )

    no_spa = 8

    cut_side = 'Outside'                      # ('Outside', 'Inside')

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

    # cons_color = "Cyan"

    ## End variables and defaults section

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

    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

 

    def mag(p):

            return sqrt(p.x**2 + p.y**2 + p.z**2)       

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

    # 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

    ## Main program

    while 1:

        m1 = MtrlLocate("Select material to cut")

        pick_180 = yes_or_no("Radius Material Cut - Available options", \

                             "180 degree arc",\

                             "Less than 180 degree arc"

                             )

        pt1 = PointLocate("Pick center point of radius cut")

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

        if pick_180 == "180 degree arc":

            pt3 = PointLocate("Pick radius cut end point")

            pt4 = PointLocate("Pick a reference point to define the current plane AND RADIUS SIDE")

            theta = pi

        else:

            pt3 = PointLocate("Pick radius cut end point")

            pt4 = pt3

            theta = 0.0

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

            a = Plane3D(pt1, pt2, pt4, 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.menu("spacing_method", ("Even Spacing", ), spacing_method, "Layout Method                ")

                dlg1.menu("cut_side", ("Outside", "Inside"), cut_side, "Remove material side")

                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)

                pt2_beyond = PolarPt3D(pt3, pt2, a.Ra/2)

                pt3_beyond = PolarPt3D(pt2, pt3, a.Ra/2)

                # pt_list = [pt2_beyond, pt2, ]

                pt_list = [pt2, ] # 1.03

           

                # spacing_method == "Even Spacing":

                actual_spa = a.pp/no_spa

                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, a.Q))

                # pt_list.append(pt3_beyond)

 

                p0 = pt2_beyond-pt3_beyond

                p0_uv = Point(p0.x/mag(p0), p0.y/mag(p0), p0.z/mag(p0))

                if cut_side == 'Inside':

                    p03 = pt3_beyond + a.cross_product(p0_uv, a.N_uv)

                    p02 = pt2_beyond + a.cross_product(p0_uv, a.N_uv)

                else:

                    p03 = pt3_beyond - a.cross_product(p0_uv, a.N_uv)

                    p02 = pt2_beyond - a.cross_product(p0_uv, a.N_uv)

               

                pt_list.append(PolarPt3D(pt3_beyond, p03, a.Ra+12.0))

                pt_list.append(PolarPt3D(pt2_beyond, p02, a.Ra+12.0))

                # pt_list.append(pt2_beyond)

                pt_list.append(pt2) # 1.03

 

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

                # 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

 

 

 

 

# Sample point list output

“””

Selected point list:

X attribute         Y attribute         Z attribute        

============================================================

30-0                21-3                478-10             

30-0                23-10 3/4           476-11             

30-0                23-6 11/16          480-10 5/16        

30-0                23-6 11/16          480-10 5/16        

 

Cut point list:

X attribute         Y attribute         Z attribute        

============================================================

30-0                23-11 13/16         475-11 1/16        

30-0                23-10 3/4           476-11             

30-0                24-0                477-0 13/16        

30-0                24-1 1/8            477-2 3/4          

30-0                24-2 3/16           477-4 11/16         

30-0                24-3 1/16           477-6 11/16        

30-0                24-3 7/8            477-8 11/16        

30-0                24-4 9/16           477-10 13/16       

30-0                24-5 1/8            478-0 15/16        

30-0                24-5 5/8            478-3 1/16         

30-0                24-5 15/16          478-5 1/4          

30-0                24-6 1/8            478-7 7/16         

30-0                24-6 3/16           478-9 5/8          

30-0                24-6 3/16           478-11 13/16       

30-0                24-6                479-2              

30-0                24-5 3/4            479-4 3/16         

30-0                24-5 5/16           479-6 3/8          

30-0                24-4 13/16          479-8 1/2          

30-0                24-4 1/8            479-10 5/8         

30-0                24-3 3/8            480-0 11/16        

30-0                24-2 1/2            480-2 11/16        

30-0                24-1 1/2            480-4 5/8          

30-0                24-0 3/8            480-6 9/16         

30-0                23-11 3/16          480-8 3/8          

30-0                23-9 7/8            480-10 1/8         

30-0                23-8 1/2            480-11 7/8         

30-0                23-5 11/16          481-10 1/4         

30-0                19-1 11/16          481-5 3/4          

30-0                19-7 13/16          475-6 9/16         

30-0                23-11 13/16         475-11 1/16    

“””