## ConsArrayLinear.py Version 1.03

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

## All rights reserved.

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

"""

/// ConsArrayLinear.py Version 1.03 (renamed from PlaneConstSpacing3D.py on 11/7/07)

/// Given 3 non-collinear points in 3D space, define a plane and layout construction lines between the first two points.

/// The third point must be selected to define the current model orientation.

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

/// URL: www.bvdetailing.com

/// Credit Paul Bourke for 'Equation of a plane' (March 1989) and 'Intersection of three planes' (October 2001)

///

/// Revision History:

///     Version 1.01 (10/20/06) -   Modify while loop to add additional construction line patterns.

///                                 Incorporate import/export default files

///                                 Add option to print documentation only

///     Version 1.02 (10/30/06) -   Create function run_script() to execute

///                                 Import functions import_data and export_data

///                                 Add construction line color variable

///     Version 1.03 (02/12/07) -   Modify import of default values

///

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

///     P3D.py

///     FileDefaults.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 math import floor, ceil, pi

    import types

    import os

    from param import yes_or_no, dim_print, Dialog

    from point import Point, PointLocate

    from cons_line import ConsLine

    # 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 = "PlaneConstSpacing3D_v1_03.txt"              # defaults file

    script_name = "PlaneConstSpacing3D_v1.03.py"

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

    enable_default_import_export = "Enable"

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

    ## Defaults Section

    #("Fixed Spacing", "Auto Spacing", "Even Spacing")

    spacing_method = "Even Spacing"

    max_spa = 24.0

    start_pt_dist = 12.0

    end_pt_dist = 12.0

    fix_spa = 24.0

    min_start_dist = 12.0

    min_end_dist = 12.0

    no_spa = 8

    cons_color = "Cyan"

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

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

        pt1 = PointLocate("Pick point 1")

        pt2 = PointLocate("Pick point 2")

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

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

            a = Plane3D(pt1, pt2, pt3)

            if a.N_len > 0.0:

                pp_dist = pt1.dist(pt2)

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

                dlg1 = Dialog("Construction Line Layout Options")

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

                dlg1.group_title("General")

                dlg1.menu("spacing_method", ("Fixed Spacing", "Auto Spacing", "Even Spacing"), spacing_method, "Layout Method                                   ")

                dlg1.menu("cons_color", ["White", "Red", "Yellow", "Green", "Cyan", "Blue", "Magenta"], cons_color, "Construction line color")

                dlg1.group_title_end

                dlg1.group_title("Fixed Spacing Options")

                dlg1.entry("fix_spa", dim_print(fix_spa), "Fixed spacing dimension")

                dlg1.entry("min_start_dist", dim_print(min_start_dist), "Min dist from 1st point to first cons line")

                dlg1.entry("min_end_dist", dim_print(min_end_dist), "Min dist from 2nd point to last cons line")

                dlg1.group_title_end

                dlg1.group_title("Auto Spacing Options")

                dlg1.entry("max_spa", dim_print(max_spa), "Maximum spacing dimension")

                dlg1.entry("start_pt_dist", dim_print(start_pt_dist), "Fixed dist from 1st point to first cons line")

                dlg1.entry("end_pt_dist", dim_print(end_pt_dist), "Fixed dist from 2nd point to last cons line")

                dlg1.group_title_end

                dlg1.group_title("Even Spacing Options")

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

                dlg1.group_title_end

                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

               

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

               

                if spacing_method == "Fixed Spacing":

                    allow_out_to_out = pp_dist - min_start_dist - min_end_dist

                    no_spa = int(floor(allow_out_to_out / fix_spa))

                    dst = min_start_dist + (allow_out_to_out/2) - (no_spa*fix_spa/2.0)

                    for i in range(no_spa + 1):

                        b = (dst + (i * fix_spa))

                        pt_list.append(pt1 + Point((b * a.d0.x), (b * a.d0.y), (b * a.d0.z)))

               

                if spacing_method == "Auto Spacing":

                    no_spa = int(ceil((pp_dist - start_pt_dist - end_pt_dist) / max_spa))

                    actual_spa = (pp_dist - start_pt_dist - end_pt_dist) / no_spa

                    for i in range (no_spa + 1):

                        b = (start_pt_dist + (i * actual_spa))

                        pt_list.append(pt1 + Point((b * a.d0.x), (b * a.d0.y), (b * a.d0.z)))

               

                elif spacing_method == "Even Spacing":

                    actual_spa = pp_dist/no_spa

                    for i in range(no_spa - 1):

                        b = (actual_spa + (i * actual_spa))

                        pt_list.append(pt1 + Point((b * a.d0.x), (b * a.d0.y), (b * a.d0.z)))

                       

                pt_list.append(pt2)

                # construction line begin

                cl2 = ConsLine()

                cl2.pt1 = pt1

                cl2.pt2 = pt2

                cl2.pen = cons_color

                cl2.add()

                # construction line end

                for pt in pt_list:           

                    # construction line begin

                    cl2 = ConsLine()

                    cl2.pt1 = pt

                    cl2.pt2 = pt + a.cross_product(a.d0, a.N_uv)

                    cl2.pen = cons_color

                    cl2.add()

                    # construction line end      

            else:

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

               

        if not yes_or_no("Add more construction lines?"):

            break

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

if __name__ == '__main__':

    try:

        run_script()

    finally:

        del run_script