#
# These aie_pre_ procedures do not change geometry, but
# may create images with ic_image. 
# Use "ic_image delete" to delete all.
# Purpose: preview and data settings: return values and/or in array aie_pre_set 
# 
# Contents:
# aie_pre_project_nearest_srfs
# aie_pre_project_tangent_srfs 
# aie_pre_get_crv_dir
#
proc aie_pre_project_nearest_srfs {how srfs coords restrict_dir angle im_name_root} {
global aie_pre_set
#
# how - "part" then all surfaces of the part, or assume names in srfs
# return empty line or projection of ALL "coords" to nearest "srfs"
# restrict_dir: if angle > 0 then "restrict_dir" must have vector for each
# "coords". Projection direction must have at least "angle" with "restrict_dir".
# if "im_name_root" has length, create arrow with names 0.$im... 1.$...
# between each xyz and xyz_projected 
# Usage: set of locations on curve. restrict_dir is tangency to location
# 
# Note: Validate input data in advance, outside of the proc:
# This proc may be used in the loop for numerous sets of surfaces.
# 
	set n 0
	set res ""
	if {$how == "part"} {
		set srfs [ic_geo_get_objects surface $srfs]
	}
	set aie_pre_set(max_dist) 0
	foreach xyz $coords {
		set xyz_proj [ic_geo_project_coords surface $srfs $xyz "0 0 0"]
		if {$xyz_proj == ""} return
		if {$angle > 0} {
			set crv_tan  [lindex $restrict_dir $n]
			set proj_dir [ic_vcalc dir $xyz $xyz_proj]
			set ang [ic_vcalc angle $crv_tan $proj_dir]
			set ang [expr 90.0-abs(90.0-$ang)]
			if {$ang < $angle} return
		}			
		lappend res $xyz_proj
		set d [ic_vcalc distance $xyz $xyz_proj]
		if {$d > $aie_pre_set(max_dist)} {set aie_pre_set(max_dist) $d}
		incr n
	}
# Create arrow if requested:
	if {$im_name_root != ""} {				   
		for {set i 0} {$i < $n } {incr i} {
			ic_image arrow_im ${i}.$im_name_root [lindex $coords $i] [lindex $res $i]
		}
	}
	return $res
}
proc aie_pre_project_tangent_srfs {how srfs coords srf_tan_dir im_name_root} {
global aie_pre_set
#
# return empty line or projection of ALL "coords" to "srfs" in "srf_tan_dir".
# "srf_tan_dir" must have vector for each "coords".
# if "im_name_root" has length, create arrow with names 0.$im... 1.$...
# between each xyz and xyz_projected 
# Usage: set of locations on curve. Calculate in advance srf_tan_dir for each coords.
# 
# Validate input data in advance, outside of the proc.
# This proc may be used in the loop for numerous sets of surfaces.
#
# 05/13/05: Check max nearest distance to surface aie_pre_set(max_near).
#
	set n 0
	set res ""
	if {$how == "part"} {
		set srfs [ic_geo_get_objects surface $srfs]
	}
	set aie_pre_set(max_dist) 0
	set aie_pre_set(max_near) 0
	foreach xyz $coords {
		set dir [lindex $srf_tan_dir $n]
		set mindist 1e9
		set minnear 1e9
		foreach srf $srfs {
			set xyz_p [ic_geo_project_coords surface $srf $xyz $dir]
			set xyz_pmin [ic_geo_project_coords surface $srf $xyz "0 0 0"]
			if {"" == $xyz_p} continue
			set dist [ic_vcalc distance $xyz $xyz_p]
			if {$dist < $mindist} {
				set xyz_proj $xyz_p
				set mindist $dist
			}
			set dist [ic_vcalc distance $xyz $xyz_pmin]
			if {$dist < $minnear} {
				set minnear $dist
			}
		}
		if {$mindist == 1e9} return
		if {$minnear > $aie_pre_set(max_near)} {
			set aie_pre_set(max_near) $minnear
		}
		lappend res $xyz_proj 
		set d [ic_vcalc distance $xyz $xyz_proj]
		if {$d > $aie_pre_set(max_dist)} {set aie_pre_set(max_dist) $d}
		incr n
	}
# Create arrow if requested:
	if {$im_name_root != ""} {				   
		for {set i 0} {$i < $n } {incr i} {
			ic_image arrow_im ${i}.$im_name_root [lindex $coords $i] [lindex $res $i]
		}
	}
	return $res
}
proc aie_pre_get_crv_dir {crv par_list up_coords up_tan_dirs up_from_dirs} {
# using cscale to find direction "tangential" and "out of surface" for single curve.
# assume that surface is relatively "smooth" within the cscale
# 
	upvar $up_coords coords
	upvar $up_tan_dirs crv_dirs
	upvar $up_from_dirs from_dirs
	set coords ""
	set crv_dirs ""
	set from_dirs ""

	set cscale [expr [ic_geo_crv_length $crv]/100.0]
	set srf [ic_geo_incident curve $crv]
	set crv_dirs ""
	foreach par $par_list {
			set xyz [lindex [ic_geo_get_crv_pos $par $crv] 0]
			set tan [ic_geo_get_crv_tan $par $crv]

			set uv [ic_geo_find_nearest_srf_pnt $srf $xyz]
			set nrm [lindex [eval ic_geo_get_srf_nrm $uv $srf] 0]				 
#   calculate (product) normal to curve, tangent to surface
#   this direction is good for "Normal to Curve"
			set dir [ic_vcalc nrm [ic_vcalc product $tan $nrm]]
			set vec [ic_vcalc smult $dir $cscale]
			set p1  [ic_vcalc sum $vec $xyz]
			set p2  [ic_vcalc diff $vec $xyz]
			set p1p [ic_geo_project_coords surface $srf $p1 "0 0 0"]
			set p2p [ic_geo_project_coords surface $srf $p2 "0 0 0"]
			set d1  [ic_vcalc distance $xyz $p1p]
			set d2  [ic_vcalc distance $xyz $p2p]			 
			if {$d1 < $d2} {
				set dir [ic_vcalc smult $dir -1]
			}			
			lappend coords $xyz
			lappend crv_dirs $tan			
			lappend from_dirs $dir
		}
}