proc aie_cr_geom_plane { {method "" } {pntnumber "" } {dez ""} {normal ""} } {
	global va_set tdv_default

	#Available methods:threepoints and pointandplane
	#Pntnumber is used to specify the particular number of the three point plane
	#Dez is used to specify the calling DEZ
	#Normal is used for the entry value of the normal for the plane
	#---this is done this way so that the plane can be modified mid-pick
	
	if {$method == ""} {mess "Specify method" ; return	}
	if {$method == "threepoints" && $pntnumber == ""} {mess "Specify point number" ; return	}
	#if { ($pntnumber != 1)  ||  ($pntnumber != 2) || ($pntnumber != 3) } {mess "Invalid point number" ; return}
	
	
	set rad 1	
	set rr [$tdv_default bbox interesting]
    if {$rr != ""} {
	set va_set(bmin) [lindex $rr 0]
	set va_set(bmax) [lindex $rr 1]
    }
	   
    set va_set(dez) $dez
    set va_set(normal_var_name) $normal
    
     
	if [info exists va_set(img)] {
		catch {$va_set(img) delete}
	}
    	set va_set(img) [pgeom_cut -interesting 0 -color #575]
    	$va_set(img) set_default 2
	$va_set(img) configure -display_type 0x3

	$va_set(img) set_material 0.5
	
	#Based off of method, set the values to do.
	switch $method	{
		pointandplane {
    	  set va_set(do_when_create_xyz_start) {
    	  	{$tdv_default add_image $va_set(img)}
			{set vec [$va_set(dez) get $va_set(normal_var_name)]}
			{set vec [ic_coords_dir_into_global $vec]}			
			{set x_dir    [ic_vcalc vec_norm $vec]}
			{set x_dir    [ic_vcalc smult [ic_vcalc nrm $x_dir] $rad]}
			{set p1 [ic_vcalc sum $x_dir $va_set(xyz_xyz)]}
			{set y_dir    [ic_vcalc product $vec $x_dir]}
			{set y_dir    [ic_vcalc smult [ic_vcalc nrm $y_dir] $rad]}
			{set p2 [ic_vcalc sum $y_dir $va_set(xyz_xyz)]}
			{set p3 [ic_vcalc diff $x_dir $va_set(xyz_xyz)]}
			{set p4 [ic_vcalc diff $y_dir $va_set(xyz_xyz)]}
	    	{set va_set(center) [aie_get_3pnt_center $p1 $p2 $p3]}
			{set va_set(normal) [get_plane_normal $p1 $p2 $p3]	}   
	    	{eval $va_set(img) set_corner $p1 $p2 $p3}
			{eval "$va_set(img) set_ptnorm $va_set(center) $va_set(normal)"}
			{$va_set(img) configure -mbmin $va_set(bmin) -mbmax $va_set(bmax)}

	      }	

          set va_set(do_when_create_xyz_continue) {
			{set x_dir    [ic_vcalc vec_norm $vec]}
			{set x_dir    [ic_vcalc smult [ic_vcalc nrm $x_dir] $rad]}
			{set p1 [ic_vcalc sum $x_dir $va_set(xyz_xyz)]}
			{set y_dir    [ic_vcalc product $vec $x_dir]}
			{set y_dir    [ic_vcalc smult [ic_vcalc nrm $y_dir] $rad]}
			{set p2 [ic_vcalc sum $y_dir $va_set(xyz_xyz)]}
			{set p3 [ic_vcalc diff $x_dir $va_set(xyz_xyz)]}
			{set p4 [ic_vcalc diff $y_dir $va_set(xyz_xyz)]}
	    	{set va_set(center) [aie_get_3pnt_center $p1 $p2 $p3]}
			{set va_set(normal) [get_plane_normal $p1 $p2 $p3]	}   
	    	{eval $va_set(img) set_corner $p1 $p2 $p3}
			{eval "$va_set(img) set_ptnorm $va_set(center) $va_set(normal)"}
			{$va_set(img) configure -mbmin $va_set(bmin) -mbmax $va_set(bmax)}

	      }
	      set va_set(do_when_create_xyz_end) "" 
		}
		threepoints {
			switch $pntnumber {
				1 {
    				set va_set(do_when_create_xyz_start) {
    				  	{$tdv_default add_image $va_set(img)}
	    				{set va_set(center) [aie_get_3pnt_center $va_set(xyz_xyz) $va_set(pln_pnt2) $va_set(pln_pnt3)]}
						{set va_set(normal) [get_plane_normal $va_set(xyz_xyz) $va_set(pln_pnt2) $va_set(pln_pnt3)]	}   
	    				{eval $va_set(img) set_corner $va_set(xyz_xyz) $va_set(pln_pnt2) $va_set(pln_pnt3)}
						{eval "$va_set(img) set_ptnorm $va_set(center) $va_set(normal)"}
						{$va_set(img) configure -mbmin $va_set(bmin) -mbmax $va_set(bmax)}

					}	

    				set va_set(do_when_create_xyz_continue) {
	    				{set va_set(center) [aie_get_3pnt_center $va_set(xyz_xyz) $va_set(pln_pnt2) $va_set(pln_pnt3)]}
						{set va_set(normal) [get_plane_normal $va_set(xyz_xyz) $va_set(pln_pnt2) $va_set(pln_pnt3) ]}   
	    				{eval $va_set(img) set_corner $va_set(xyz_xyz) $va_set(pln_pnt2) $va_set(pln_pnt3)}
						{eval "$va_set(img) set_ptnorm $va_set(center) $va_set(normal)"}
						{$va_set(img) configure -mbmin $va_set(bmin) -mbmax $va_set(bmax)}

					}
					set va_set(do_when_create_xyz_end) {
	    				{eval $va_set(img) set_corner $va_set(xyz_xyz) $va_set(pln_pnt2) $va_set(pln_pnt3) }
						{eval "$va_set(img) set_ptnorm $va_set(center) $va_set(normal)"}
						{$va_set(img) configure -mbmin $va_set(bmin) -mbmax $va_set(bmax)}
			
					}	
				}
				2 {
    				set va_set(do_when_create_xyz_start) {
    				  	  	{$tdv_default add_image $va_set(img)}
	    				{set va_set(center) [aie_get_3pnt_center $va_set(pln_pnt1) $va_set(xyz_xyz) $va_set(pln_pnt3)]}
						{set va_set(normal) [get_plane_normal $va_set(pln_pnt1) $va_set(xyz_xyz) $va_set(pln_pnt3)]	}   
	    				{eval $va_set(img) set_corner $va_set(pln_pnt1) $va_set(xyz_xyz) $va_set(pln_pnt3)}
						{eval "$va_set(img) set_ptnorm $va_set(center) $va_set(normal)"}
						{$va_set(img) configure -mbmin $va_set(bmin) -mbmax $va_set(bmax)}

					}	

    				set va_set(do_when_create_xyz_continue) {
	    				{set va_set(center) [aie_get_3pnt_center $va_set(pln_pnt1) $va_set(xyz_xyz) $va_set(pln_pnt3)]}
						{set va_set(normal) [get_plane_normal $va_set(pln_pnt1) $va_set(xyz_xyz) $va_set(pln_pnt3) ]	}   
	    				{eval $va_set(img) set_corner $va_set(pln_pnt1) $va_set(xyz_xyz) $va_set(pln_pnt3)}
						{eval "$va_set(img) set_ptnorm $va_set(center) $va_set(normal)"}
						{$va_set(img) configure -mbmin $va_set(bmin) -mbmax $va_set(bmax)}

					}
					set va_set(do_when_create_xyz_end) {
	    				{eval $va_set(img) set_corner $va_set(pln_pnt1) $va_set(xyz_xyz) $va_set(pln_pnt3) }
						{eval "$va_set(img) set_ptnorm $va_set(center) $va_set(normal)"}
						{$va_set(img) configure -mbmin $va_set(bmin) -mbmax $va_set(bmax)}
			
					}
				}
				3 {
					set va_set(do_when_create_xyz_start) {
					  	  	{$tdv_default add_image $va_set(img)}
	    				{set va_set(center) [aie_get_3pnt_center $va_set(pln_pnt1) $va_set(pln_pnt2) $va_set(xyz_xyz)]}
						{set va_set(normal) [get_plane_normal $va_set(pln_pnt1) $va_set(pln_pnt2) $va_set(xyz_xyz)]	}   
	    				{eval $va_set(img) set_corner $va_set(pln_pnt1) $va_set(pln_pnt2) $va_set(xyz_xyz)}
						{eval "$va_set(img) set_ptnorm $va_set(center) $va_set(normal)"}
						{$va_set(img) configure -mbmin $va_set(bmin) -mbmax $va_set(bmax)}

					}	
    				set va_set(do_when_create_xyz_continue) {
	    				{set va_set(center) [aie_get_3pnt_center $va_set(pln_pnt1) $va_set(pln_pnt2) $va_set(xyz_xyz)]}
						{set va_set(normal) [get_plane_normal $va_set(pln_pnt1) $va_set(pln_pnt2) $va_set(xyz_xyz)]	}   
	    				{eval $va_set(img) set_corner $va_set(pln_pnt1) $va_set(pln_pnt2) $va_set(xyz_xyz)}
						{eval "$va_set(img) set_ptnorm $va_set(center) $va_set(normal)"}
						{$va_set(img) configure -mbmin $va_set(bmin) -mbmax $va_set(bmax)}

					}
					set va_set(do_when_create_xyz_end) {
	    				{eval $va_set(img) set_corner $va_set(pln_pnt1) $va_set(pln_pnt2) $va_set(xyz_xyz)}
						{eval "$va_set(img) set_ptnorm $va_set(center) $va_set(normal)"}
						{$va_set(img) configure -mbmin $va_set(bmin) -mbmax $va_set(bmax)}
			
					}
				}
			}
		}
	}
}


#------------
proc aie_update_bridge_curve { args } {
global va_set

ic_undo_suspend 

if { [ic_geo_check_objects_exist curve $va_set(brcrv)] == $va_set(brcrv) && $va_set(brcrv) != "" }  {
	ic_delete_geometry curve names $va_set(brcrv) 0

	if {$va_set(c1mag) < 0.000001} { set va_set(c1mag) 0.000001 } \
	elseif {$va_set(c1mag) > 0.999999} { set va_set(c1mag) 0.999999 }

	if {$va_set(c2mag) < 0.000001} { set va_set(c2mag) 0.000001 } \
	elseif {$va_set(c2mag) > 0.999999} { set va_set(c2mag) 0.999999 }
	
	ic_geo_cre_bridge_crv $va_set(prtname) $va_set(brcrv) $va_set(crv1) $va_set(crv2) $va_set(end1) $va_set(end2) $va_set(c1mag) $va_set(c2mag)
	
}

ic_undo_resume
	
}

#------------
proc aie_curve_from_location {point} {
global tdv_default

set screenlocation [$tdv_default world2screen [lindex $point 0] [lindex $point 1] [lindex $point 2] ]
set x [expr int([lindex $screenlocation 0])]
set y [expr int([lindex $screenlocation 1])]

set bsp_curve [$tdv_default pick $x $y geom_curve "" 0]
set curve_name [object_name_of_image [lindex $bsp_curve 0]]
return $curve_name

}

#------------
proc aie_trim_crv_to_crv {curve1 curve2 point {remove 1}} {
global tdv_default

if {$curve1 == $curve2} {
	mess "\nPlease select two curves\n" red
	return
}

set screenlocation [$tdv_default world2screen [lindex $point 0]  [lindex $point 1] [lindex $point 2] ]
set x [expr int([lindex $screenlocation 0])]
set y [expr int([lindex $screenlocation 1])]


ic_undo_group_begin
set intersecpoint [ic_geo_create_points_curveinter "$curve1 $curve2" 0.1 POINTS ]
if {$intersecpoint == ""} {mess "\nNo intersection Found\n" ; return}

set newcurves [catch {ic_geo_split_curve $curve2 $intersecpoint} res]
if {$newcurves > 0} {
	ic_delete_geometry point names $intersecpoint 0
	mess "\nTrim Failed\n" red
	return
}

set curve [$tdv_default pick $x $y geom_curve "" 0]

if {$remove == "1"} {
	set removecurve [object_name_of_image [lindex $curve 0] ]
	if {$removecurve != $curve1} {
		ic_delete_geometry curve names $removecurve 0
	}
}

ic_delete_geometry point names $intersecpoint 0
ic_undo_group_end		

}		

proc aie_wait_for_click {{ent entity} {scrn 0} {f9_key 0}} {
    global tdv_waiting_for_click explicit_location_value va_set tdv_default
    global select_action options tdv_mouse_bindings tdv_current_viewer select_in_dynamics
    
    select_set_bindings 4 0 0 0 ""
    select_unset_bindings 0
    set select_in_dynamics 0
    
if 0 {
    bind $tdv_default <F9> "set tdv_waiting_for_click($tdv_default) F9"
    bind .v.console.text <F9> "set tdv_waiting_for_click($tdv_default) F9"
    bind .v <F9> "set tdv_waiting_for_click($tdv_default) F9"
}
    tdv_push_key_command F9 "select_toggle_dynamics 0"
    set tdv_waiting_for_click($tdv_default) 1
    tkwait variable tdv_waiting_for_click
    if ![info exists tdv_waiting_for_click($tdv_default)] {
		busy reset
		return
    }
    set cc $tdv_waiting_for_click($tdv_default)
    unset tdv_waiting_for_click($tdv_default)
    bind $tdv_default <F9> ""
    bind .v <F9> ""
    bind .v.console.text <F9> ""
    
    switch -- [lindex $cc 0] {
        e  { return [lrange $cc 1 end] }
        1  {
            if $scrn { return $cc }
            set pt [$tdv_default pick [lindex $cc 1] [lindex $cc 2] geom_$ent "" 0]
            return $pt
        }
        2  { return 2 }
        3  { return 3 }
        F9 {
            if !$f9_key {
               bind $tdv_default <F9> "set tdv_waiting_for_click($tdv_default) F9"
               bind .v.console.text <F9> "set tdv_waiting_for_click($tdv_default) F9"
               bind .v <F9> "set tdv_waiting_for_click($tdv_default) F9"
               tdv_cur $tdv_default dynamics
               set pb [banner "Dynamics mode - hit F9 to return to selection mode."]
               tkwait variable tdv_waiting_for_click
               tdv_cur $tdv_default pick
               banner $pb
               return [aie_wait_for_click $ent $scrn $f9_key]
            } else {
               return f9_key
            }
        }
        default { 
            return ""
        }
    }
}

proc aie_cut_stl_by_curve {{surf1 ""} {curve1 ""} {proj "0"} {regroup "1"} {merge "0"} {pts ""} {fam ""}} {
# surf1 - surface to trim
# curve1 - curve(s) to trim surface by
# proj - 0=project input curves, 1=do not project curves (curves are already projected) 
# regroup - 1=run regroup procedure if trim fails
# merge - 0=regroup surface prior to trim
# pts - provide points list to regroup by

global va_set
global tdv_default

  set va_set(prg_crv) ""
  set seg_surf ""
  set va_set(surf) $surf1
  set va_set(curves) $curve1
  
  if {$va_set(surf) == ""} {
    set va_set(surf) [geo_select surface 1]
    if {$va_set(surf) == ""} {
      return
      }
    }    
 
  if {$va_set(curves) == ""} {
    set va_set(curves) [geo_select curve 0]
    if {$va_set(curves) == ""} {
      return
      }
    }

  if {$proj == "0"} {
    foreach crv $va_set(curves) {
      set new_name [ic_geo_new_name curve MPTEMP_[pid]]
      ic_geo_project_curve_to_surface $crv $va_set(surf) $new_name MPTEMP_[pid]     
      if {[ic_geo_lookup curve names $new_name] != ""} {
      lappend va_set(prg_crv) $new_name
      }
      }
    } else {
      set va_set(prg_crv) $va_set(curves)
      }

  set scheck(before) [ic_geo_lookup surface all]
  set scheck(num_before) [llength $scheck(before)]
  set scheck(nam_before) ""
  foreach ent $scheck(before) {
    lappend scheck(nam_before) [lindex $ent 1]
    }
  
  if {$merge == 1} {
     set seg_surf $va_set(surf)
     } else {
       if {[ic_geo_get_object_type surface $va_set(surf)] == "mesh"} {
          set seg_surf [aie_set_tri_fam $va_set(surf) $va_set(prg_crv) 1 some 2 0 1 $pts]
          } else {
            set seg_surf $va_set(surf)
            }
       }
  
  set new_surf [ic_geo_create_surface_segment $seg_surf curve angle 20 mintri 1 \
      plane_p {0 0 0} plane_n {0 0 1} keep_old 0 curves $va_set(prg_crv)] 

  update_fam_window
 

  set check [ic_geo_check_objects_exist surface $seg_surf]
  if {$check != ""} {
     update_geom_visible surface p
     ic_mess "Trim surface failed \n" red
     aie_geo_merge_objects surface $va_set(surf) $seg_surf
#Somethink weird: conflict with next command     ic_delete_geometry surface names $seg_surf
     ic_geo_finish_edit surface $va_set(surf)   
     if $regroup {
     set new_surf [aie_set_tri_fam $va_set(surf) $va_set(prg_crv) 0 all 10 1 0 $pts]}
       
   } else {
     ic_mess "Trim surface done \n" blue  
   }
   if {$new_surf == ""} {
     busy reset
     return 
     } else {
     set flag "Keep"
     set result "cancel"
     set i 0
     if {[llength $new_surf] > 1} {
       set frtsurf [lindex $new_surf 0]
       set sndsurf [lindex $new_surf 1]
       set new_surf [lreplace $new_surf 0 0 $sndsurf]
       set new_surf [lreplace $new_surf 1 1 $frtsurf]
       set i 0
     }
     set new_surf_def $new_surf
     
     while {$flag == "Keep"} {
       set va_set(flag) $flag        
       ic_highlight color green width 5 names [lindex $new_surf $i]
       if [winfo exists .va_seg_done] {destroy .va_seg_done}
       set title "Segmentation"
       set form_name .va_seg_done
       set moving Keep
       if [winfo exists .va_seg_done] {form_kill .va_seg_done}
       busy reset
       if {[llength $new_surf] == 1}  {
         set flag [form_init $form_name $title "" \
              [list [list Move "set va_set(flag) Trash; form_done .va_seg_done"] \
              [list Done "set va_set(flag) Done; form_done .va_seg_done"] \
              [list Cancel "set va_set(flag) Cancel; form_done .va_seg_done"] ] ]       
       } else {  
         set flag [form_init $form_name $title "" \
             [list [list Move "set va_set(flag) Trash; form_done .va_seg_done"] \
             [list Keep "set va_set(flag) Keep; form_done .va_seg_done"] \
             [list Regroup "set va_set(flag) Regroup; form_done .va_seg_done"] nl \
             [list Done "set va_set(flag) Done; form_done .va_seg_done"] \
             [list Cancel "set va_set(flag) Cancel; form_done .va_seg_done"] ] ]         
       }
       form_label $flag.lab "Modify highlighted surface?\n [expr $i+1] of [llength $new_surf]" "0 0" 
       form_finish +100+200 1 1
       
       form_wait $form_name
       set flag $va_set(flag) 

       if {$flag == "Keep"} {
           ic_highlight
           incr i
           if { $i >= [llength $new_surf]} {
              set i 0
              } 
           }
       if {$flag == "Trash"} {
           if { [ic_geo_new_family MPJUNK] } {
	        ic_set_family_color_for_name MPJUNK grey
	        fam_stuff_changed
              } 
           if {$fam == ""} {
	           set cutfam MPJUNK
           } else {
	           set cutfam $fam
       	   }
           set mpcut [lindex $new_surf $i]
           set new_surf [lreplace $new_surf $i $i]
           set nsurf [llength $new_surf]
	   ic_geo_set_family surface $cutfam names $mpcut
	   ic_highlight
	   if { $i >= $nsurf} {
	       set i 0
	       }    
	   if {[llength $new_surf] == 0} {
             set flag "Done"
             } else {set flag "Keep"}	       
          }
       
       if {$flag == "Regroup"} {
           aie_geo_merge_objects surface $va_set(surf) $new_surf_def
           ic_delete_geometry surface names $new_surf_def 0
           set new_surf [aie_set_tri_fam $va_set(surf) $va_set(curves) 0 all 3 0]
           set flag "Keep"
                 
          }
       
       if {$flag == "Done" && $merge == 0} {
           aie_geo_merge_objects surface $va_set(surf) $new_surf
           ic_delete_geometry surface names $new_surf 0
          }
       
       if {$flag == "Cancel"&& $merge == 0} {
           aie_geo_merge_objects surface $va_set(surf) $new_surf_def
           ic_delete_geometry surface names $new_surf_def 0
          }
          
       set va_set(flag) $flag
       
       }   
     }
     
     if {[ic_geo_check_objects_exist surface $va_set(surf)] == $va_set(surf)} {
       catch "ic_geo_finish_edit surface $va_set(surf)"  }
     
     if {[ic_geo_check_objects_exist surface $new_surf] == $new_surf} {
       catch "ic_geo_finish_edit surface $new_surf"  }
  
  ic_highlight   
  busy reset
  if { $tdv_default != ".v.view" } {aie_create_initial_assemblies}

}				

#------------
proc aie_select_screen_points {{cut ""} {bind 0}} {
 global va_set tdv_library tdv_default
   set points ""
   set ims ""
   set va_set(sp_line) 1
   if {$bind == 1} {
      tdv_set_key_command l {set va_set(sp_line) 0
                               aie_cr_poly_spline }
      tdv_set_key_command p {set va_set(sp_line) 1
                               aie_cr_poly_spline }
      tdv_set_key_command s {set va_set(sp_line) 2
                               aie_cr_poly_spline }
      tdv_set_key_command b {set va_set(sp_line) 3
                               aie_cr_poly_spline }
      ic_mess "Selection hot keys: \n" blue
      ic_mess " \"l\" for linear, \"b\" for b_spline,\n\
      \"p\" for polygon & \"s\" for close b_spline.\n" brown
      }
   if {$bind == 2} {
         tdv_set_key_command l {}
         tdv_set_key_command p {set va_set(sp_line) 1
                                  aie_cr_poly_spline }
         tdv_set_key_command s {set va_set(sp_line) 2
                                  aie_cr_poly_spline }
         tdv_set_key_command b {}
         ic_mess "Selection hot keys: \n" blue
         ic_mess " \"p\" for polygon & \"s\" for close b_spline.\n" brown
      }
   set mess points
   banner "Select $mess on the screen with the left button; middle = done; right = cancel." 
   if [info exists tdv_library] {
        set ocur [set_cursor $tdv_default [list @$tdv_library/pick.cur orange]]
   }
   set is_tdv [llength [info commands tdv_point_im]]
   while 1 {
          set bot [aie_wait_for_click "" 1 1]
          if {$bot == ""} break
          if {$bot == "f9_key"} continue
          if {$bot == 2} {
               break
             } else {
               if { $bot != 3 } {
                     set real_cor [vam_screen2plane [lindex $bot 1] [lindex $bot 2]]
                     if {$real_cor != [lindex $points end] } {lappend points $real_cor}
                     set im [tdv_point_im -color white -size 4 -point $real_cor ]
                     $tdv_default add_image $im
                     lappend ims $im
                     update
              } else {
               if { $points == "" } {
                  break
                  } else {
                    if {[llength $points] == 1 } {
                       set va_set(surf_name) ""
                       }
                    set del_pnt [lindex $points end]
                    set del     [lindex $ims    end]
                    set points [lreplace $points end end]
                    set ims    [lreplace $ims    end end]
                    $del delete
                  }
               }
          }

            set va_set(points) $points
       if { $cut == "" || $cut == 0 } {
          aie_cr_poly_spline 
          }
    }
    
    foreach im $ims {catch "$im delete" }
    select_unset_bindings 0
    banner ""
    if [info exists tdv_library] {
        set_cursor $tdv_default $ocur
    }
    return  $points
}

#------------
proc aie_seg_surf_by_screen {{fam ""}} {
global va_set tdv_default
  # 04/09/07. VG -- Fixed bug with plane geometry; improved readability 
   set surfs [ic_geo_objects surface only_if_faceted only_if_visible]
   if {$surfs == ""} {
      ic_mess "No visible faceted surfaces\n" red
      return
   }
    # Create bbox of visible faceted surfaces:
   set ents ""
   foreach s $surfs {
    lappend ents "surface $s"
   } 
   foreach "bbmin bbmax" [ic_geo_bbox_of_entities $ents] ""
   # bbox diagonal and center:
   set bbox_scale [ic_vcalc len [ic_vcalc diff $bbmin $bbmax]]
   set bbox_center [ic_vcalc sum_smult $bbmin $bbmax 0.5]
   
   # Screen normal:
   set nm_dir [lindex [$tdv_default screen2world 100 100] 1]
   set nm_dir [ic_vcalc nrm $nm_dir]
   
   # Create temporary LCS at bbox center with Z -> screen normal
   set axis0 [ic_vcalc vec_norm $nm_dir]
   set axis1 [ic_vcalc product $axis0 $nm_dir]
   ic_csystem_create tmpLCS cartesian $bbox_center $axis0 $axis1 $nm_dir
   ic_csystem_set_current tmpLCS
   
   # Calculate offset vectors in LCS; bbox_scale is always positive:
   set pp1 [ic_coords_into_global "0 0 $bbox_scale"]
   set pp2 [ic_coords_into_global "0 0 -$bbox_scale"]
   set shift1 [ic_vcalc diff $bbox_center $pp1]
   set shift2 [ic_vcalc diff $bbox_center $pp2]     

   # Next command creates global xyz in LCS plane using vam_screen2plane
   set check [aie_select_screen_points "" 2]
   
   # Delete temporary LCS
   ic_csystem_set_current global
   ic_csystem_delete tmpLCS
  
   # No selection: not an error
  if {![info exists va_set(points)] || ![info exists va_set(py_name)]} return   
   set crv1 $va_set(py_name)
   
   # Select at least 3 points:
   if {[llength $check] < 3} {
    # Delete temporary curve, which was created during selection:
       ic_delete_geometry curve names $crv1 0   
   set va_set(py_name) ""
       ic_mess " Minimum of 3 points required\n" red
         return
     }
   
   set crv2 [ic_geo_duplicate curve $crv1 ""]
   ic_move_geometry curve names $crv1 translate $shift1
   ic_move_geometry curve names $crv2 translate $shift2
 
   set newname [ic_geo_new_name surface MPTEMP_[pid]]
   set intersurf [ic_geo_create_surface_from_curves MPTEMP_[pid] $newname 0.001 "$crv1 $crv2"]
   set intercrv ""
 
   foreach surf $surfs {
       set crvinter [ic_geo_intersect_surfaces MPCRV "$intersurf $surf"]
       if {$crvinter != ""} {
         lappend intercrv $crvinter
         lappend intersrf $surf
         }
     }
   ic_delete_geometry surface names $intersurf 0 
   ic_delete_geometry curve names "$crv1 $crv2" 0  
   if {$intercrv == ""} {
      busy reset
      return
      }

   set surfs [ic_geo_objects surface only_if_faceted only_if_visible]
   set sppts ""
   for {set i 0} {$i < [llength $intersrf]} {incr i} {
     set srf [lindex $intersrf $i]
     set crv [lindex $intercrv $i]
     set exists [ic_geo_check_objects_exist surface $surf ]
     if {$exists != ""} {   
       if {$va_set(sp_line) > 1} {       
         set cr [ic_facetize_geometry curve $intercrv]
         update
         
         set nodes [ic_geo_extract_points $cr 0]
         ic_delete_geometry curve names $cr 0
         foreach p $nodes {
             lappend sppts [ic_geo_get_point_location $p]
             }
         ic_delete_geometry point names $nodes 0
         aie_cut_stl_by_curve $srf $crv 1 1 0 $sppts $fam
         } else {
         aie_cut_stl_by_curve $srf $crv 1 1 0 $va_set(points) $fam
         }
       }
     }
   ic_delete_geometry curve names "$crv1 $crv2" 0
   foreach crv $intercrv {
      if {$crv == [ic_geo_check_objects_exist curve $crv]} {
         ic_delete_geometry curve names $crv 0
         }
      }
    busy reset
}
#======================================



proc va_cr_circle_3p {fam name p1 p2 p3 {s_ang 0} {e_ang 360}} {
ic_virtual define point pc {pc1 pc2 pc3 radius 0 angle 0 offset 0}
ic_virtual define point pc1 $p1
ic_virtual define point pc2 $p2
ic_virtual define point pc3 $p3
ic_virtual define point pc {pc1 pc2 pc3 radius 0 angle 0 offset 0}
set control [ic_virtual check point pc 1]
if $control {return 0}
set pc_cor [lindex [ic_virtual] 0]
set radius [ic_vcalc distance $pc_cor $p1]
set r2 [ic_vcalc distance $pc_cor $p3]
if {$radius == 0 || $r2 == 0} return
set v1 [ic_vcalc dir $pc_cor $p1]
set v2 [ic_vcalc dir $pc_cor $p3]
set normal [ic_vcalc product $v1 $v2]
if {$name == ""} {set name [ic_geo_new_name curve $fam/]}
set cir_nm [ic_geo_cre_crv_arc_ctr_rad $fam $name $pc_cor $v1 $normal $radius $s_ang $e_ang]
return $cir_nm
}

#------------

proc aie_cr_poly_spline {{fam ""}} {
    global va_set str_option fam_visible
    
    if ![info exists va_set(usepts)] { set va_set(usepts) "" }
    if ![info exists va_set(usepts_1st)] { set va_set(usepts_1st) "" }
    if ![info exists va_set(usepts_end)] { set va_set(usepts_end) "" }   
    set bs_pnt ""
    if {![info exists va_set(points)] && $va_set(usepts_1st) == "" } return
    if {$va_set(points) == "" && $va_set(usepts_1st) == ""} return

    if {$va_set(usepts) == 1} {
        if {$va_set(usepts_1st) != ""} {
            set loc [ic_geo_get_point_location $va_set(usepts_1st)]
            set bs_pnt [list $loc]
       }     
    }
    set bs_pnt [eval list $bs_pnt $va_set(points)]
    
    if {$va_set(usepts) == 1} {
        if {$va_set(usepts_end) != ""} {
            set loc [ list [ic_geo_get_point_location $va_set(usepts_end)] ]
            set bs_pnt [eval list $bs_pnt $loc]
        }     
    }
    
    set how $va_set(sp_line)
    if [info exists va_set(py_name)] {
       set py_name [ic_geo_check_objects_exist curve $va_set(py_name)]
       if {$py_name == $va_set(py_name)} {
          ic_delete_geometry curve names $py_name 0
       }
       unset va_set(py_name)
    }
    if { [llength $bs_pnt] < 2 } return
    if { [llength $bs_pnt] == 2 } { set how 0 }
    if {$fam == ""} { set fam "MPTEMP_[pid]" }
    set fam_visible($fam) 1
    ic_visible geometry curve 1
    if { $how == 1 || $how == 2 } {
        lappend bs_pnt [lindex $bs_pnt 0] 
    }
    if { $how < 2 } {
        if ![ic_geo_check_family $fam] { ic_geo_new_family $fam }
        set cur_con ""
        for {set i 1 } { $i < [llength $bs_pnt] } {incr i} {
            set j [expr $i-1]
            set p1 [lindex $bs_pnt $j]
            set p2 [lindex $bs_pnt $i]
            lappend cur_con [ic_geo_cre_line $fam ${fam}_ $p1 $p2]
        }
        set new_name [ic_geo_new_name curve temp]
        if {[llength $cur_con] > 1} {
            set va_set(py_name) [ic_geo_cre_crv_concat $fam $new_name 0.1 $cur_con]
            ic_delete_geometry curve names $cur_con 0
        } else {
            set va_set(py_name) $cur_con
        }
#       set va_set(py_name) [ic_geo_create_unstruct_curve_from_points {} $fam $bs_pnt]
    } else {
        set p1 [lindex $bs_pnt 0]
        set p2 [lindex $bs_pnt 1]
        set p3 [lindex $bs_pnt 2]
        set circle  0
        if {[llength $bs_pnt] == 4 && $how == 2} {
            set circle 1
        }
        if { [llength $bs_pnt] == 3 || $circle } {
            if { $how == 3} {
                set va_set(py_name) [ic_geo_cre_arc_from_pnts $fam ${fam}_ $p1 $p2 $p3] 
            } else {
                set va_set(py_name) [va_cr_circle_3p $fam ${fam}_ $p1 $p2 $p3]
            } 
        } else {
            if ![info exists va_set(bsp_tol)] { set va_set(bsp_tol) 0 }
            if {$va_set(bsp_tol) == ""} { set va_set(bsp_tol) 0 }
            if {$how == 2} {
                ic_virtual define point p0 [lindex $bs_pnt 0]
                ic_virtual define point p1 [lindex $bs_pnt 1]
                ic_virtual define point p2 [lindex $bs_pnt 2]
                set chck_pnt [ic_virtual define point pp "p0 p1 p2 0.01" 1]
                if !$chck_pnt {
                    set chck_cor [lindex [ic_virtual check point pp] 0]
                    set plc [expr [llength $bs_pnt]-1]
                    set bs_pnt [linsert $bs_pnt $plc $chck_cor]
                }
            }
            set va_set(py_name) [ic_geo_cre_bsp_crv_n_pnts $fam ${fam}_ $bs_pnt $va_set(bsp_tol)]
        }
    }
    ic_highlight names $va_set(py_name) width 3
}	

#------------
proc aie_vector_length {v} {
    return [ic_vcalc len $v]
}

#------------ This was from Yuriy's mesh pro stuff.
proc aie_vector_nrm {v} {
    return [ic_vcalc nrm $v]
}

#------------ This was from Yuriy's mesh pro stuff.
proc aie_vector_mult {v k} {
    return [ic_vcalc smult $v $k]
}

#This is copied from Mesh Prototyper stuff.......................................................
#=================================================
proc aie_transp_matrix {M} {
  set n1 [llength $M]
  set n2 [llength [lindex $M 0]]
  set M1 ""
  for {set i 0} {$i < $n2} {incr i} {
    set row ""
    for {set j 0} {$j < $n1} {incr j} {
      lappend row [lindex [lindex $M $j] $i]
    }
    lappend M1 "$row"
  }
  return $M1
}

#This is copied from Mesh Prototyper stuff.......................................................
#=================================================
proc aie_mult_matrixes {M1 M2} {
  set n1 [llength $M1]
  set n2 [llength [lindex $M1 0]]
  for {set i 1} {$i < $n1} {incr i} {
    if {[llength [lindex $M1 0]] != $n2} {
      mess "Matrix is not rectangular \n" red
      val_pmatrix $M1
      va_err "Math error"
      return
    }
  }
  set n3 [llength $M2]
  if {$n3 != $n2} {
    mess "Columns number in matrix " red
    val_pmatrix $M1
    mess "and rows number in matrix " red
    val_pmatrix $M2
    mess "are not equal \n" red
    va_err "Math error"
    return
  }
  set n4 [llength [lindex $M2 0]]
  for {set i 1} {$i < $n3} {incr i} {
    if {[llength [lindex $M2 0]] != $n4} {
      mess "Matrix is not rectangular \n" red
      val_pmatrix $M2
      va_err "Math error"
      return
    }
  }
  set M3 ""
  for {set i 0} {$i < $n1} {incr i} {
    set row ""
    for {set j 0} {$j < $n4} {incr j} {
      set c 0
      for {set k 0} {$k < $n2} {incr k} {
        set a [lindex [lindex $M1 $i] $k]
        set b [lindex [lindex $M2 $k] $j]
        set c [expr $c+$a*$b]
      }
      lappend row $c
    }
    lappend M3 "$row"
  }
  return $M3
}

proc aie_set_tri_fam {{surf1 ""} {curves ""} {sel "0"} {m "all"} {pix "3"} {window "1"} {max "0"} {pts ""}} {

# surf1  == the surface to trim
# sel    == 0 for surface is set in surf1, 1 to request user to select surface
# curves == name of curves if curves = "" then user will be asked for curves
# window == 1--> will display window, 0--> will not display will, it will just do it
# pix    == is the number of pixels to grow the window by
# max    == max --> 1 == using bounding box to regroup
# pts    == instead of providing a curve to extract points from just give it all the points
# m      == m must be set to all or some


  global tdv_default  va_set options
   update_geom_visible surface p

    if {$window == 1} {
      set result [tk_messageBox -parent $tdv_default -title "Regrouping" \
                -type yesno -message "Surface segmentation has failed.\nTry to regroup?"]
      if {$result == "no"} {
        return
      } else {
        ic_mess "Regrouping surface...\n" blue
      }
    }
    if {$surf1 == "" && $sel == 1} {
           set surf1 [geo_select surface 1]
        }   
  if {$pts == "" } {      
    if {$curves == ""} {
       set curves [geo_select curve]
    }
    update
    foreach cr $curves {
      set type [ic_geo_get_object_type curve $cr]
      if {$type == "default"} {
         ic_mess "Only select all faceted or all parametric curves\n" red
         continue}
      if {$type == "param"} {
         set cr [ic_facetize_geometry curve $cr]
      }
      update
      set pnt [ic_geo_extract_points $cr 0]
      foreach p $pnt {
        lappend pts [ic_geo_get_point_location $p]
      }
      ic_delete_geometry point names $pnt 0
     }
    } 
    set what "surface"
    set item "triangle"
    if {$surf1 == ""} {
       set surf1 $va_set(surf_name)
       }
    if {$surf1 == ""} {
       ic_mess "va_set(surf_name) \n" red
       return
       }
    ic_visible geometry surface 1
    set fam  [ic_geo_get_family surface $surf1]
    if {[llength $pts] < 3} {ic_mess "pts\n" red; return}
    set to_new 1; set x_c 0 ; set y_c 0 ; set x_max "" ; set y_max "" ; set x_min "" ; set y_min ""
    foreach pt $pts {
        set scr [$tdv_default world2screen [lindex $pt 0] [lindex $pt 1] [lindex $pt 2]]
        set x_s [lindex $scr 0]
        set y_s [lindex $scr 1]
        set x_c [expr round($x_s)+$x_c]
        set y_c [expr round($y_s)+$y_c]
        if { $max == 1 } {
          if {$x_max == "" } {
             set x_max $x_s
             }
          if {$x_min == "" } {
              set x_min $x_s
             }
          if {$y_max == "" } {
	     set y_max $y_s
             }
          if {$y_min == ""} {
	     set y_min $y_s
             }
             
          if {$x_max < $x_s } {
             set x_max $x_s
             }
          if {$y_max < $y_s } {
	     set y_max $y_s
             }
          if {$x_min > $x_s } {
	     set x_min $x_s
	     }
	  if {$y_min > $y_s } {
	      set y_min $y_s
             }
          }   
        lappend x_l [expr round($x_s)]
        lappend y_l [expr round($y_s)]
    }
    set x_cnt [expr ($x_c*1.0)/[llength $x_l]]
    set y_cnt [expr ($y_c*1.0)/[llength $y_l]]
    for {set n 0} {$n < [llength $x_l]} {incr n} {
       set x_p [lindex $x_l $n]
       set y_p [lindex $y_l $n]
       if {$x_cnt > $x_p} {
          set x_p [expr $x_p-$pix]
          } else {
            if {$x_cnt < $x_p} {
               set x_p [expr $x_p+$pix]
               }
            }
       if {$y_cnt > $y_p} {
          set y_p [expr $y_p-$pix]
          } else {
            if {$y_cnt < $y_p} {
               set y_p [expr $y_p+$pix]
               }
            }
       
       lappend poly [list $x_p $y_p]
    }
    
 if {$max == 1} {
    set x_min [expr round($x_min)-5]
    set x_max [expr round($x_max)+5]
    set y_min [expr round($y_min)-5]
    set y_max [expr round($y_max)+5]    
    set poly [list "$x_min $y_min" "$x_min $y_max" "$x_max $y_max" "$x_max $y_min"]
 }

    
    ic_geo_set_config_param surface $surf1 draw_first_high_diff 0
    ic_geo_set_tag clear    ""    geo_select_segment 0
    ic_geo_set_tag surface $surf1 geo_select_segment 1
    set pts [$tdv_default pick_polygon geo_select_segment $poly subseg_$m]

    set nf  [ic_geo_new_family $fam]
    set nn  [ic_geo_new_name surface $fam]
    set surf2 [ic_geo_create_empty_unstruct_${what} $nn $fam]

    if  $nf   update_fam_window
    ic_undo_group_begin
    foreach point $pts {
      set va_set(pp) $point
      set surf_n [object_name_of_image [lindex $point 0]]
      if {$surf_n != $surf1} continue
      set pnt_c  [lindex $point 1]
      set flag [ic_geo_move_segments $what $surf1 $surf2 $item $pnt_c]

      }  
    
    ic_geo_finish_edit $what $surf1
    ic_geo_finish_edit $what $surf2
    geo_show_edit $what $surf1 0
    geo_show_edit $what $surf2 0
    ic_undo_group_end

    ic_geo_delete_if_empty $what $surf1
    ic_geo_delete_if_empty $what $surf2
    if [info exist type ] {
      if {$type == "param"} {
        ic_delete_geometry curve names $cr 0
        }
      }
   # foreach i $va_set(im) {$i delete}
   return $surf2
}


proc aie_geo_merge_objects {type srf1 srfs} {
# if srf1 does not exist - merge all "surfaces" and set name $srf1
	set all_srfs ""
  foreach srf "$srf1 $srfs" {
     if {[ic_geo_check_objects_exist $type $srf] == ""} continue
     lappend all_srfs $srf
  }
  set first_srf [lindex $all_srfs 0]
  ic_geo_merge_objects $type $first_srf [lrange $all_srfs 1 end]
	if {$first_srf != $srf1} {
		ic_geo_set_name $type $first_srf $srf1 
	}	
}

proc aie_cut_stl {{fam ""} } {
   global va_set str_option geom_visible
   
   set va_set(usepts_1st) ""
   set va_set(usepts_end) ""

   set va_set(bsp_tol) 1
   if [info exists va_set(py_name)] {unset va_set(py_name)}
   set bs_pnt [aie_select_points]
   if {$bs_pnt == ""} return
   set bs_pnt_m $bs_pnt
   if ![info exists va_set(surf_name)] return
   set number_surf [llength $va_set(surf_name)]
   set number_pnt [llength $bs_pnt]
   if {$number_pnt < 1} {
      ic_delete_geometry  all families MPTEMP_[pid] 0
      return
   }
   if {$number_pnt < 2} {
      ic_mess "Pick more than one point \n" red
      ic_delete_geometry  all families MPTEMP_[pid] 0       
      return
   }
   foreach surf $va_set(surf_name) {
      set new_name [ic_geo_new_name curve MPTEMP_[pid]]
      ic_geo_project_curve_to_surface $va_set(py_name) $surf $new_name MPTEMP_[pid]
      #set new_surf [ic_geo_create_surface_segment $surf curve angle 20 mintri 1 \
      #plane_p {0 0 0} plane_n {0 0 1} keep_old 0 curves $new_name] 
      #update_fam_window
      lappend cur_nam $new_name
      }
  
   aie_cut_stl_by_curve $va_set(surf_name) $cur_nam 1 1 1 "" $fam
  
  
   ic_delete_geometry  all families MPTEMP_[pid] 0
   set va_set(points) ""
   busy reset
}

proc aie_select_points {{cut ""} {mess ""} {fam ""} {max 0} {bind "all"} } {
    global va_set tdv_waiting_for_click tdv_library geom_visible
    global tdv_default tdv_waiting_for_motion

   set points ""
   set ims "" ; set imst ""
   if ![info exists va_set(mode)] {set va_set(mode) ""}
   if {$va_set(mode) == ""} {set va_set(mode) "lite pixels" }
   set va_set(surf_name) ""
   set check_curve $geom_visible(curve)
   if !$check_curve {set geom_visible(curve) 1}
   if ![info exists va_set(sp_line)] {set va_set(sp_line) 1}
   if {$bind == "limit"} {
     if {$va_set(sp_line) == 1 || $va_set(sp_line) == 2} {set va_set(sp_line) 0}
     }
   #tdv_set_key_command n {mp_selection_mode}
   #ic_mess "Select by $va_set(mode)\n"
   if {$cut == ""} {
       if {$bind == "all"} {
         tdv_set_key_command l {set va_set(sp_line) 0 aie_cr_poly_spline }
         tdv_set_key_command p {set va_set(sp_line) 1 aie_cr_poly_spline }
         tdv_set_key_command s {set va_set(sp_line) 2 aie_cr_poly_spline }
         tdv_set_key_command b {set va_set(sp_line) 3 aie_cr_poly_spline }
         ic_mess "Selection hot keys: \n" blue
         ic_mess " \"l\" for linear, \"b\" for b_spline,\n\
               \"p\" for polygon & \"s\" for close b_spline.\n" brown
         }
         
       if {$bind == "limit"} {
         tdv_set_key_command l {set va_set(sp_line) 0 aie_cr_poly_spline }
         tdv_set_key_command b {set va_set(sp_line) 3 aie_cr_poly_spline }
         ic_mess "Selection hot keys: \n" blue
         ic_mess " \"l\" for linear, \"b\" for b_spline,\n" brown
         }         
         
   }
   if {$mess == "" } {set mess points}
   #banner "Select $mess on the screen with the left button; middle = done; right = cancel.\
   #        Hit <F9> Dynamics mode. Hit <n> node/lite pixel mode"
   banner "Select $mess on the surface with the left button; middle = done; right = cancel.\
           Hit <F9> Dynamics mode."
   if [info exists tdv_library] {
        set ocur [set_cursor $tdv_default [list @$tdv_library/pick.cur orange]]
   }
   set is_tdv [llength [info commands tdv_point_im]]
   while 1 {
          set bot [aie_wait_for_click]
          if {$bot == ""} break
          if {$bot == "f9_key"} continue
          update
          if {$bot == 2} {
               break
             } else {
               if { $bot != 3 } {
                  if $max {
                     if {[llength $points] == $max} break
                     }
                set bsp      [lindex $bot 0]
                set bsp_typ  [object_geotype_of_image $bsp]
                if {$bsp_typ == "surface"} {
                  set bsp_name [object_name_of_image $bsp]
                  set pos [lsearch $va_set(surf_name) $bsp_name]
                  if { [ic_geo_get_object_type surface $bsp_name] != "mesh"} { 
	                  mess "Wrong surface type selected, must be faceted."
	                  break	                  
                  }
                  if {$va_set(surf_name) == ""} {
                      set pos 1
                      lappend va_set(surf_name) $bsp_name
                      }
                  if { $pos != -1 } {
                     set real_cor [lindex $bot end]
                     if {$real_cor != [lindex $points end] } { lappend points $real_cor}
                     set im [tdv_point_im -color white -size 4 -point $real_cor ]
                     $tdv_default add_image $im
                     lappend ims $im
                     update
                     } else {ic_mess "Wrong selection\n" green }
              }
           } else { if { $points == "" } {
                  break
                  } else {
                    if {[llength $points] == 1 } {
                       set va_set(surf_name) ""
                       }
                    set del_pnt [lindex $points end]
                    set del     [lindex $ims    end]
                    set points [lreplace $points end end]
                    set ims    [lreplace $ims    end end]
                    $del delete
                    }
                  }
          }
       set va_set(points) $points
       if { $cut == "" || $cut == 0 } {
          aie_cr_poly_spline $fam
          }
    }
    foreach im $ims { $im delete }
    select_unset_bindings 0
    banner ""
    if !$check_curve {set geom_visible(curve) 0}
    if [info exists tdv_library] {
        set_cursor $tdv_default $ocur
    }
    return  $points
}






