
# This code creates the user interface for the hexa mesher.
#
# Copyright (c) 1993 - 1995 Pacific Marketing and Consulting, Inc,
#       and ICEM Systems, GmbH.  All rights reserved.
# Author:  Wayne A. Christopher, wayne@icemcfd.com

proc reset_ogrid_ortho {} {
    global button_instructions
    set edge1 [ select_edge "Select an edge in the ogrid \
			$button_instructions" 1 new_format ]
    if { $edge1 == "" } return
    set t1 [ lindex $edge1 0 ]
    set t2 [ lindex $edge1 1 ]
    command "reset_ogrid_orthogonality $t1 $t2 \
	[range_string] [family_activename_string]" 1 1
    update_display block edge face mesh
    file_dirty
    banner ""
}
proc edge_make { what } {
    global button_instructions
    
    if ![check_enabled] return
    
    while 1 {
	set edge1 [ select_edge "Select the edge with the \
                $button_instructions" 1 new_format]

	if { $edge1 == "" }  break

	set t1 [ lindex $edge1 0 ]
	set t2 [ lindex $edge1 1 ]
	
	command "make_edge_$what $t1 $t2" 1 1

	update_display block edge face mesh
    }
    file_dirty
    banner ""
}
	
proc edge_unlink_shape { } {
    global button_instructions
    
    if ![check_enabled] return
    
    while 1 {
	set edge1 [ select_edge "Select the edge with the \
                $button_instructions" 1 new_format]

	if { $edge1 == "" }  break

	set t1 [ lindex $edge1 0 ]
	set t2 [ lindex $edge1 1 ]
	
	command "link_shape $t1 $t2" 1 1

	update_display block edge face mesh
    }
    file_dirty
    banner ""
	
}
proc edge_link_shape { } {
    global button_instructions
    
    if ![check_enabled] return
    
    while 1 {
	set edge1 [ select_edge "Select the target edges with the \
                $button_instructions" 100 new_format]

	if { $edge1 == "" }  break
	

	set edge2 [ select_edge "Select the source edge with the \
                $button_instructions" 1 new_format]
	if { $edge2 == "" } break

	set s1 [ lindex $edge2 0 ]
	set s2 [ lindex $edge2 1 ]

	
	set factor [ question_box .factor "factor for link" Factor 1.0 ]
	if { $factor == "" } break

	foreach t $edge1 {
		set t1 [ lindex $t 0 ]
		set t2 [ lindex $t 1 ]
		command "link_shape $t1 $t2 $s1 $s2 $factor" 1 1
	}

	update_display block edge face mesh
    }
    file_dirty
    banner ""
	
}
proc edge_ortho_offset { } {
    global button_instructions
    
    if ![check_enabled] return
    
    while 1 {
	set edge1 [ select_edge "Select the target edge(s) with the \
                $button_instructions" 100 new_format]

	if { $edge1 == "" }  break
	

	set edge2 [ select_edge "Select the source edge with the \
                $button_instructions" 1 new_format]
	if { $edge2 == "" } break

	set s1 [ lindex $edge2 0 ]
	set s2 [ lindex $edge2 1 ]

	
	foreach t $edge1 {
		set t1 [ lindex $t 0 ]
		set t2 [ lindex $t 1 ]
		command "set_mesh $t1 $t2 linked $s1 $s2" 1 1
		command "link_shape $t1 $t2 $s1 $s2 1.0" 1 1
	}

	update_display block edge face mesh
    }
    file_dirty
    banner ""
	
}
proc edge_split_apply {}  {
	global smooth_edge_id

	set cmd "set_edge_tangents $smooth_edge_id"
	foreach i { 1 2 } {
	    global smooth_edge_tan${i}_type smooth_edge_tan${i}
	    global smooth_edge_fac${i}

	    set type [ set smooth_edge_tan${i}_type ]
	    set fac [ set smooth_edge_fac${i} ]
	    switch $type {
	    enter {
	        set tan [ set smooth_edge_tan${i} ]
		append cmd " tan${i} $tan fac${i} $fac"
	    }
	    none { } 
	    ortho {
		append cmd " tan${i} ortho fac${i} $fac"
	    }
	    default {
		error "unhandled type $type"
	    }
	    }
	}

	command  $cmd

	update_display edge face mesh
}
proc edge_split_select_edge { } {
	global smooth_edge_id button_instructions
	set edges [select_edge \
                "Select an edge splits $button_instructions" 1 \
			"selected_direction new_format" ]
	global smooth_edge_id
	set n1 [ lindex $edges 0 ]
        set n2 [ lindex $edges 1 ]
	set smooth_edge_id "$n1 $n2"
	
}
proc edge_split { { smooth "" } } {
    global last_line
    global display_flag
    global button_instructions
    global smooth_edge_tan1 smooth_edge_tan2
    global smooth_edge_fac1 smooth_edge_fac2
    
    if ![check_enabled] return
    
    if { $smooth == "tangents" } {
	edge_split_select_edge

	set d [form_init .smooth_edge "Smooth edge" edge \
			{ { Apply edge_split_apply }  cancel } ]
	global vec_on smooth_edge_fac1 smooth_edge_fac2
	set vec_on 1
	set smooth_edge_fac1 .333
	set smooth_edge_fac2 .333

	global smooth_edge_tan1_type smooth_edge_tan2_type
	set smooth_edge_tan1_type none
	set smooth_edge_tan2_type none

        if {$d != ""} {
	    set ln 0
	    form_label $d.edgel "Edge id" "$ln 1"
            form_entry $d.edge smooth_edge_id string "$ln 2 -cols 3"
		
	    foreach i { 1 2 } {
		incr ln
		form_line $d line{$i} $ln

	    	incr ln
	    	form_label $d.end{$i} "[lindex "x Start End" $i]  tangent" \
				"$ln 1"
		set on_off_var [ list \
			[ list smooth_edge_tan${i}_type enter ortho ] ]
	    	form_label $d.fac${i}l "Factor"  "$ln 4" \
			$on_off_var
	    	form_entry $d.fac${i} smooth_edge_fac${i} float_var "$ln 5" \
			$on_off_var

		incr ln
		form_radiobutton $d.none${i} "None" \
			smooth_edge_tan${i}_type none "$ln 1"

# enter tangent
	    	incr ln
	    	form_radiobutton $d.etan${i} "Enter tangent" \
			smooth_edge_tan${i}_type enter "$ln 1"

		set on_off_var [ list [ list smooth_edge_tan${i}_type enter ] ]
		mess "$on_off_var\n"
	    	incr ln
	    	form_label $d.tan${i}l "Tangent" "$ln 1" $on_off_var

	    	form_entry $d.tan${i} smooth_edge_tan${i} coords_float \
			"$ln 2" $on_off_var

	    	select_vector_menu $d.tan${i}sv smooth_edge_tan${i} $ln 3  \
			$on_off_var



#ortho
		incr ln
		form_radiobutton $d.ortho{$i} "Ortho" \
			smooth_edge_tan${i}_type ortho "$ln 1"

	    }
	    incr ln
	    form_button $d.selnew "Select new edge" edge_split_select_edge \
		"$ln 1"

            form_finish bot
        }
	
	
    } elseif { $smooth == "vertex_smooth" } {
      while 1 {
	set mess "Please select a vertex  $button_instructions"
	set node [select_node $mess 1 node_numbers ]
	if { $node == "" } break
	command "smooth_edges_at_vertex $node [volume_activename_string]"
	update_display edge face mesh
      }
    } else {
      while 1 {
	banner "Please select the edge to split $button_instructions"
	set cmd "split_edge [range_string] [family_activename_string]"
	if $display_flag(edge_proj) {
		append cmd " proj"
	}
	if !$display_flag(edge_vol)  {
		append cmd " -no_volume"
	}
	if $display_flag(use_blanking) {
		append cmd " -not_blanked"
	}
	if { $smooth == "smooth" } {
		append cmd " -smooth"
	} elseif { $smooth == "interpolate" } {
		append cmd " -interpolate"
	}
	command $cmd 1 1
	if {$last_line == ""} break
	if { [ string match "error*" $last_line ] } break
	set cmd "replay_put split_edge $last_line"
	if { $smooth == "smooth" } {
                append cmd " -smooth"
        } elseif { $smooth == "interpolate" } {
		append cmd " -interpolate"
	}
	replay_record_command $cmd
	
	update_display block edge face mesh
      }
    }
    file_dirty
    banner ""
}

proc edge_unsplit { { what "single" } } {
    global button_instructions last_line all_lines

    if ![check_enabled] return
    
    switch $what {
    single {
        banner "Please select the edge vertex to remove $button_instructions"
        command "remove_edge_point [range_string] [volume_activename_string]" 1 1
        file_dirty
        banner ""
	set edges $all_lines
	foreach e $all_lines {
	    replay_record_command "replay_put remove_edge_point $e"
        }
        update_display block edge face mesh
    }
    one_edge {
	while  1 {
	    set edges [select_edge \
		"Select the edges where you are removing all \
                splits $button_instructions" 1 new_format]
	    if { $edges == "" } break
	    set n1 [ lindex $edges 0 ]
	    set n2 [ lindex $edges 1 ]
	    command "remove_edge_points $n1 $n2"
	    file_dirty
	    update_display block edge face mesh
	}
    }
    all_displayed {
	command "remove_edge_points [range_string] [volume_activename_string]"
	file_dirty
        update_display block edge face mesh
    }
    all {
	command "remove_edge_points"
	file_dirty
        update_display block edge face mesh
    }
    default {
	error "unhandled case $what in edge_unsplit"
    }
    }
}

proc edge_modify {} {
    global edge_modify_dependent edge_modify_last
    
    set edge_modify_last ""
    
    set d [form_init .edge_modify "Move vertex" edge done]
    if {$d != ""} {
	form_checkbutton $d.dep "Move dependents" edge_modify_dependent {0 0}
	form_button $d.sing "Move single" {
	    set opt ""; if $edge_modify_dependent { set opt move_dependent }
	    edge_modify_single $opt
	} {1 0}
	form_button $d.mult "Move multiple" {
	    set opt ""; if $edge_modify_dependent { set opt move_dependent }
	    edge_modify_mult $opt
	} {2 0}
	# form_button $d.mnp "Make new prescribed" \
	    "edge_modify_make_prescribed 0" {3 0}
	form_button $d.mlp "Make last prescribed" \
	    "edge_modify_make_prescribed 1" {4 0}
	form_button $d.aln "Align vertices" edge_modify_align_verts {5 0}
	
	form_finish bot
    }
}

proc accept_callback {} {
	global mv_callback mv_opts
	$mv_callback $mv_opts
}

proc select_edge_direction {} {
    global fix_dir button_instructions
    global last_line

    set edge [select_edge "Select the edge for direction\
               $button_instructions" 1 new_format]
    if { $edge == "" } return

    set n1 [lindex $edge 0]
    set n2 [lindex $edge 1]

    command "get_node_location $n1"
    set loc1 $last_line
    command "get_node_location $n2"
    set loc2 $last_line

    set mag 0
    foreach i {0 1 2} {
	set dvec($i) [expr [lindex $loc1 $i] -  [lindex $loc2 $i]]
	set mag [expr $mag + ($dvec($i) * $dvec($i))]
    }
    foreach i {0 1 2} {
	set dvec($i) [format %.3g [expr $dvec($i) / sqrt($mag)]]
    }

    set fix_dir "$dvec(0) $dvec(1) $dvec(2)"
}

proc create_constraints_window { func_name opt } {
    global mv_fixx mv_fixy mv_fixz botform_geo mv_normal
    global mv_callback mv_opts
    global mv_vec fix_dir

    set mv_callback $func_name
    set mv_opts $opt
# create constraints window
    set buts [list [list Accept accept_callback ] cancel]
    set d [ form_init .mvconstraints "Vertex Constraints" block $buts ]
    if { $d != "" } {
	form_frame $d.fr sunken 3 {0 0}; set d $d.fr

	set mv_fixx 0
	set mv_fixy 0
	set mv_fixz 0
        set ln 1
	form_checkbutton $d.fixx "Fix x" mv_fixx "$ln 1"
	incr ln
	form_checkbutton $d.fixy "Fix y" mv_fixy "$ln 1"
	incr ln
	form_checkbutton $d.fixz "Fix z" mv_fixz "$ln 1"
	incr ln
	form_checkbutton $d.norm "Normal to surface" mv_normal "$ln 1"

	incr ln
	form_checkbutton $d.vec "Fix direction" mv_vec "$ln 0"
	form_entry $d.dir fix_dir string "$ln 1" mv_vec
	form_button $d.edge "Select" select_edge_direction "$ln 2" mv_vec

	form_finish $botform_geo
    }
    focus .v
}

proc edge_modify_single {{opt ""}} {
    global env

    if ![check_enabled] return

    create_constraints_window edge_modify_single_doit $opt


    edge_modify_single_doit $opt

    if ![info exists env(HEXA_TOYOTA)] {
	after 10000 "form_cancel .mvconstraints"
    }
}

proc edge_modify_single_doit { { opt "" } } {
    global display_flag all_lines edge_modify_last edge_modify_dependent
    global button_instructions mv_fixx mv_fixy mv_fixz mv_normal
    global mv_vec fix_dir

    banner "Please select and move the edge vertex \
		$button_instructions"
    
    set cmd "place_node [range_string] [family_activename_string] $opt \
			-node_numbers"
    if $display_flag(edge_vol) { append cmd " volume" }
    if $edge_modify_dependent { append cmd " move_dependent"}
    if $display_flag(use_blanking) { append cmd " -not_blanked" }
    if $mv_fixx { append cmd " -fixx" }
    if $mv_fixy { append cmd " -fixy" }
    if $mv_fixz { append cmd " -fixz" }
    if $mv_normal { append cmd " -normal" }
    if $mv_vec { 
	if {$fix_dir == ""} {
	    mess "Error: No fixed direction specified\n" red
	    banner ""
	    return
	}
	append cmd " -vec $fix_dir" 
    }
    command $cmd 1 1
    banner ""
    set places $all_lines
    
    set edge_modify_last $places
    if {$places == ""} return
    
    file_dirty
    
# update the edge, face, block scan displays
    
    update_display edge face block mesh scan vert
    foreach pl $places {
	if { [ string match "undo*" $pl ] } continue
	replay_record_command "replay_put place_node $pl"
    }
}

proc edge_modify_mult {{opt ""}} {
    global env

    if ![check_enabled] return

    create_constraints_window edge_modify_mult_doit $opt

    edge_modify_mult_doit $opt

    if ![info exists env(HEXA_TOYOTA)] {
	after 10000 "form_cancel .mvconstraints"
    }
}

proc edge_modify_mult_doit {{opt ""}} {
    global mv_fixx mv_fixy mv_fixz mv_normal mv_vec
    global display_flag all_lines edge_modify_last
    global edge_modify_dependent fix_dir
    global button_instructions
    
    if ![check_enabled] return
    
    banner "Please select the edge vertices to modify \
		$button_instructions"
    while { 1 } {
    	set cmd "place_nodes [range_string] [family_activename_string] $opt \
			-node_numbers"
    	if $display_flag(edge_vol) { append cmd " volume" }
    	if $edge_modify_dependent { append cmd " move_dependent" }
    	if $display_flag(use_blanking) { append cmd " -not_blanked" }
	if $mv_fixx { append cmd " -fixx" }
	if $mv_fixy { append cmd " -fixy" }
	if $mv_fixz { append cmd " -fixz" }
	if $mv_normal { append cmd " -normal" }
	if $mv_vec { 
	    if {$fix_dir == ""} {
		mess "Error: No fixed direction specified\n" red
		banner ""
		return
	    }
	    append cmd " -vec $fix_dir" 
	}
	command $cmd 1 1
    	set places $all_lines
    
    	set edge_modify_last $places
    	if {$places == ""} break
    	file_dirty
    
    
    	replay_record_command "replay_put place_nodes -none"
    	foreach pl $places {
		replay_record_command "replay_put place_node $pl"
    	}
    }
    update_display edge face block mesh
    banner ""
}

proc edge_modify_make_prescribed {} {
    global edge_modify_last tetin_save_needed last_line display_flag
    global button_instructions families

    set last 0

    set fam [select_one_family "Select a family for the new points."]
    if {$fam == ""} return

    set new_fam 0
    if {  [ lsearch $families $fam ] == -1 } {
	set new_fam 1
    }

    while 1  {
	set mess "Please select vertices $button_instructions"
	
	set nodes [select_node $mess 100 node_numbers ]
	if {$nodes == ""} break
    
    
        foreach pt $nodes {
	    set n [llength $pt]
	    command "get_node_location $pt"
	    command "define_point $last_line family $fam"
	    command "move_node $pt $last_line"
        }
        set tetin_save_needed 1
        update_display edge point
	if { $new_fam } {
		add_families
		set new_fam 0
	}
    }
}

proc edge_modify_align_verts {} {
    global align_verts
    
    set d [form_init .edge_align_verts "Align vertices" "edge sub" {accept cancel}]
    if {$d != ""} {
	array set align_verts {
	    dim 0
	    index 1
	    par_dir yz
	    par_vec "0 0 0"
	}
	
	form_label $d.diml "Dimension" {0 0}
	form_label $d.indl "Index" {1 0}
	form_label $d.parl "Parallel to" {2 0}
	
	form_entry $d.dim align_verts(dim) int {0 1}
	form_entry $d.ind align_verts(index) int {1 1}
	form_radiobutton $d.par_yz "Y-Z" align_verts(par_dir) yz {2 1}
	form_radiobutton $d.par_xz "X-Z" align_verts(par_dir) xz {3 1}
	form_radiobutton $d.par_xy "X-Y" align_verts(par_dir) xy {4 1}
	form_radiobutton $d.par_ot "Other" align_verts(par_dir) other {5 1}
	form_entry $d.par_other align_verts(par_vec) string {6 1} \
	    {{align_verts(par_dir) other}}
	
	form_finish bot
    }
    
    if ![form_wait .edge_align_verts] return
    
    set vec ""
    switch $align_verts(par_dir) {
	yz    { set vec "1 0 0" }
	xz    { set vec "0 1 0" }
	xy    { set vec "0 0 1" }
	other { set vec $align_verts(par_vec) }
    }
    command "align_vertices $align_verts(dim) $align_verts(index) $vec \
	[range_string] [volume_activename_string]"
    file_dirty
    update_display edge face block mesh
}

proc edge_set_pos {} {
    global set_xyz last_line
    
    set buts {
	{ Apply edge_set_pos_doit }
	{ "Select new" edge_set_pos_selnew }
	dismiss
    }
    set d [form_init .xyz_pos "Vertex positions" edge $buts edge_set_pos_doit]
    if {$d != ""} {
	set set_xyz(delta) 0
	set set_xyz(use_visible) 0
	
	set ln 0
	form_radiobutton $d.setp "Set position" set_xyz(delta) 0 \
	    "$ln 0 -cols 2"

	incr ln
	form_radiobutton $d.setd "Increment position" set_xyz(delta) 1 \
	    "$ln 0 -cols 2"
	
	incr ln
	form_radiobutton $d.range0 "Individual vertices" set_xyz(use_visible) 0 \
	    "$ln 0 -cols 2"

	incr ln
	form_radiobutton $d.range1 "Visible vertices" set_xyz(use_visible) 1 \
	    "$ln 0 -cols 2"
	
	incr ln
	form_label $d.nodesl "Vertices" "$ln 0" {{set_xyz(use_visible) 0}}
	form_entry $d.nodes set_xyz(nodes) int "$ln 1" {{set_xyz(use_visible) 0}}
	
	incr ln
	form_checkbutton $d.setx "Modify X" set_xyz(x) "$ln 0"
	form_entry $d.valx set_xyz(xval) float_var "$ln 1" set_xyz(x)

	incr ln
	form_checkbutton $d.sety "Modify Y" set_xyz(y) "$ln 0"
	form_entry $d.valy set_xyz(yval) float_var "$ln 1" set_xyz(y)

	incr ln
	form_checkbutton $d.setz "Modify Z" set_xyz(z) "$ln 0"
	form_entry $d.valz set_xyz(zval) float_var "$ln 1" set_xyz(z)

	incr ln
	form_checkbutton $d.norm "Normal to Surface" set_xyz(norm) "$ln 0"
	form_entry $d.valn set_xyz(normval) float_var "$ln 1" set_xyz(norm)

	incr ln
	form_label $d.setpl "Get from:" "$ln 0"
	form_button $d.setpn "Vertex" edge_set_pos_from_node "$ln 1"

	incr ln
	form_button $d.setps "Screen pos" edge_set_pos_from_screen "$ln 1"
	
	incr ln
	form_button $d.setpnt "Point" edge_set_pos_from_point "$ln 1"
	
	
	form_finish bot
    }
    focus .v
    edge_set_pos_selnew
}

proc edge_set_pos_from_point {} {
    global set_xyz last_line
    global button_instructions
    
    set points [select_point "Please select the point $button_instructions" ]
    if {$points == ""} return
    
    command "point_location [lindex $points 0] _tempx _tempy _tempz"
    if { $set_xyz(delta) } {
# get second point
        set points [select_point "Please select the point $button_instructions" ]
        if {$points == ""} return
    	command "point_location [lindex $points 0] _temp2x _temp2y _temp2z"
        foreach i {0 1 2} {
	    set delta delta[lindex { x y z } $i ]
	    set x1 \$_temp[lindex { x y z } $i]
	    set x2 \$_temp2[lindex { x y z } $i]
	    command "evaluate $delta \"%.9g\" \"$x2 - $x1\" "
	    set set_xyz([lindex {x y z} $i]val) \$$delta
	}
    } else {
        foreach i {0 1 2} {
	    set set_xyz([lindex {x y z} $i]val) "\$_temp[lindex { x y z } $i]"
	}
    }
}

proc edge_set_pos_from_node {} {
    global set_xyz last_line
    global button_instructions
    
    set nodes [select_node "Please select the node $button_instructions" \
		2 "node_numbers edge_nodes" ]
    if {$nodes == ""} return
    
    set n1 [lindex $nodes 0]
    if { $n1 == "" } return
    command "get_node_location $n1 _tempx _tempy _tempz"
    if { $set_xyz(delta) } {
	set n2 [lindex $nodes 1]
	if { $n2 == "" } return;
    	command "get_node_location $n2 _temp2x _temp2y _temp2z"
        foreach i {0 1 2} {
	    set delta delta[lindex { x y z } $i ]
	    set x1 \$_temp[lindex { x y z } $i]
	    set x2 \$_temp2[lindex { x y z } $i]
	    command "eval $delta \"%.9g\" \"$x2 - $x1\" "
	    set set_xyz([lindex {x y z} $i]val) \$$delta
	}
    } else {
        foreach i {0 1 2} {
	    set set_xyz([lindex {x y z} $i]val) "\$_temp[lindex { x y z } $i]"
	}
    }
}

proc edge_set_pos_from_screen {} {
    global set_xyz last_line
    
    banner "Select a position on the screen with the left button."
    command graphics_loc
    set pos $last_line
    banner ""
    
    if {$pos == ""} return
    
    if { $set_xyz(delta) } {
	command graphics_loc
	set pos2 $last_line
	foreach i { 0 1 2 } {
	    set delta [ expr { [ lindex $pos2 $i ] - [ lindex $pos $i ] } ]
	    set set_xyz([lindex {x y z} $i]val) $delta
	}
    } else {
	    foreach i {0 1 2} {
		set set_xyz([lindex {x y z} $i]val) [lindex $pos $i]
	    }
    }
}

proc user_error {mess} {
    tk_dialog .lpopup_message Message $mess "" -1 Ok
}

proc edge_set_pos_doit {} {
    global set_xyz
    
    set pos ""
    foreach i {x y z norm} {
	if $set_xyz($i) {
	    if $set_xyz(delta) { append pos d }
	    set v [string trim $set_xyz(${i}val)]
	    if {$v == ""} { error "The value for $i was left blank." }
	    append pos "$i $v "
	}
    }
    if {$pos == ""} {
	user_error "None of X Y or Z selected."
	return
    }
    
    if $set_xyz(use_visible) {
	command "set_node_location $pos [range_string] [volume_activename_string]"
# $set_xyz(dim):$set_xyz(min),$set_xyz(max)
    } else {
	set cmd "set_node_location $pos node_numbers"
	set nn 0
	foreach n $set_xyz(nodes) {
	    append cmd " \{ $n \}"
	    incr nn
	}
	if { $nn == 0 } {
		user_error "no vertices selected"
		return
	}
	command $cmd
    }
    file_dirty
    update_display edge face block mesh
}

proc edge_set_pos_selnew {} {
    global last_line set_xyz
    global button_instructions
    
    set nodes [select_node "Please select the nodes to set \
		$button_instructions" \
		100 "node_numbers edge_nodes"]
    set set_xyz(nodes) $nodes
    if {$nodes == ""} return
    
    switch [llength $nodes] {
	1 {
	    command "get_node_location $nodes"
	    foreach i {0 1 2} {
		set set_xyz([lindex {x y z} $i]val) [lindex $last_line $i]
	    }
	    set set_xyz(use_visible) 0
	}
	0 {
	    set set_xyz(use_visible) 1
	}
    }
}

proc comp_screen {} {
	global display_flag last_line
	global button_instructions

	if ![check_enabled] return
	if !$display_flag(curve) {
		set display_flag(curve) 1; update_display curve
	}
	banner "Please select the curves you want to group \
			$button_instructions"
	while 1 {
		if ![command "select_curve" 1 1] { set last_line "" }
		if {$last_line == ""} break
		command "composite_curve $last_line"
		file_dirty
		update_display curve
	}
	banner ""
}
proc comp_region {} {
	global display_flag last_line button_instructions
	if ![check_enabled] return
        if !$display_flag(curve) {
                set display_flag(curve) 1; update_display curve
        }
	banner "Please select by region the curves you want to group \
			$button_instructions"
        while 1 {
		if ![command "select_curve region_in" 1 1] {set last_line "" }
                if {$last_line == ""} break
                command "composite_curve $last_line"
                file_dirty
                update_display curve
        }
	banner ""
}

proc comp_tangent { } {
    global display_flag
    
    if ![check_enabled] return
    
    if !$display_flag(curve) {
	set display_flag(curve) 1; update_display curve
    }
    
    command "composite_curve tangential_curves"

    file_dirty
    update_display curve
}

proc comp_families { { which "" } } {
    global display_flag
    
    if ![check_enabled] return
    
    if !$display_flag(curve) {
	set display_flag(curve) 1; update_display curve
    }
    
    if { $which == "" } {
	set fam [comp_form "Group curve" ]
	if {$fam == ""} return
    
    	command "composite_curve family $fam"
    } else {
	command "composite_curve by_family"
    }
    file_dirty
    update_display curve
}

proc edge_uncomp {} {
    global display_flag last_line
    global button_instructions

    
    if ![check_enabled] return
    
    if !$display_flag(curve) {
	set display_flag(curve) 1; update_display curve
    }

    set fam "Screen select"
    
    if {$fam == "Screen select"} {
	banner "Please select the grouped curves you want to ungroup\
		$button_instructions"
	while 1 {
	    if ![command "select_curve" 1 1] {set last_line ""}
	    if {$last_line == ""} break
	    
	    command "delete_composite $last_line"
	    file_dirty
	    update_display curve
	}
	banner ""
    } else {
	command "delete_composite family $fam"
	file_dirty
	update_display curve
    }
}

proc comp_form {title} {
    global topform_geo comp_form_var form_done_flag families family_dims
    global family_name
    
    if ![check_enabled] return
    
    
    set buts {
	{Accept {form_accept_hack .comp_form}}
	{Cancel {form_done .comp_form; set form_done_flag(.comp_form) 0}}
    }
    
    form_kill .comp_form
    set d [form_init .comp_form $title block $buts]
    form_frame $d.fr sunken 3 {1 0}
    
    set fams ""
#    set fams [list [list {Screen select} -text {Screen select}] \
#		   [list {Screen region} -text {Screen region}]]
    
    set appfam [surface_name_string]
    foreach f $appfam {
	lappend fams $f
    }
    foreach f $fams {
	if ![info exists comp_form_var($f)] {
	    set comp_form_var($f) 0
	}
    }
    
    check_box $d.fr $fams 6 comp_form_var 1
    form_finish +400+400
    
    tkwait variable form_done_flag(.comp_form)
    if !$form_done_flag(.comp_form) { return "" }
    set ret ""
    foreach f $fams {
	if $comp_form_var($f) { lappend ret $f }
    }
    return $ret
}

proc edge_crpoint {} {
    global last_line tetin_save_needed button_instructions
    
    set fam [select_one_family "Select a family for\nthe new points."]
    if {$fam == ""} return
    
    banner "Select the new prescribed points $button_instructions"
    while 1 {
	command graphics_loc
	set pt $last_line
	if {$pt == ""} {
	    banner ""
	    set tetin_save_needed 1
	    return
	}
	command "define_point $pt family $fam"
	set ptname $last_line
	
	set node [select_node "Please select the vertex to associate \
		$button_instructions"]
	if {$node != ""} {
	    command "move_node $node $ptname"
	}
    }
}

proc edge_create_iso {} {
    global all_lines tetin_save_needed button_instructions
    global last_line
    
    set surf [select_surface "Select the surface $button_instructions" ]
    if {$surf == ""} return
    
    set surf [ lindex $surf 0 ]

    command "get_surface_family $surf"
    set fam $last_line
    set ncreated 0
    while 1 {
	banner "Pick two points on the surface $button_instructions"
	command "select_surf_uv $surf"
	banner ""
	if {[llength $all_lines] < 2} break
	set u1 [lindex [lindex $all_lines 0] 0]
	set v1 [lindex [lindex $all_lines 0] 1]
	set u2 [lindex [lindex $all_lines 1] 0]
	set v2 [lindex [lindex $all_lines 1] 1]
	set du [expr abs($u1 - $u2)]
	set dv [expr abs($v1 - $v2)]
	if {$du < $dv} { set uv u; set val $u1 } else { set uv v; set val $v1 }
	command "isocurve $surf $uv $val family $fam"
	update_display curve
	incr ncreated
    }
    set tetin_save_needed 1
}

proc vertex_to_edge { } {
    global last_line button_instructions
    while 1 {
	set nns [select_node "Please select the vertices to collapse\
			$button_instructions" 1 node_numbers]
	if { $nns == "" } break
	set edge [select_edge "Select the edge \
               $button_instructions" 1 new_format]
	if { $edge == "" } break
	command "vertex_to_edge $nns  [lindex $edge 0] [lindex $edge 1]"
	file_dirty
	update_display edge face block
    }
}
proc edge_collapse { how } {
    global last_line button_instructions
    global env
    
    if ![check_enabled] return
    
    if [info exists env(HEXA_TOYOTA)] {
	set reb -rebuild_orphan
    } else {
	set reb ""
    }
    while 1 {
	    set nns [select_node "Please select the two vertices to collapse\
			$button_instructions" 2 node_numbers]
	    if {[llength $nns] != 2} return
	    if { $how == "join" } {
		command "collapse_edge $nns join $reb -version 101"
	    } else {
		command "collapse_edge $nns $reb -version 101"
	    }
	    file_dirty
	    update_display edge face block
    }
}

proc merge_vertices {} {
    global last_line button_instructions merge_verts
 
    set buts [list [list Apply merge_vertices_doit] dismiss]
    set d [form_init .merge_vertices "Merge Vertices" "" $buts]
    if {$d != ""} {
	set ln 0
	form_label $d.methodl "Merge vertices Method:" "$ln 0"
	form_radiobutton $d.all "All" merge_verts(type) all "$ln 1"
	incr ln
	form_radiobutton $d.select "Selected"  merge_verts(type) selected "$ln 1"

	set act {{merge_verts(type) selected}}

	incr ln
	form_label $d.nl "Nodes" "$ln 0" $act
	form_entry $d.ne  merge_verts(nodes) string "$ln 1" $act
        form_button $d.n "Select" merge_vertices_select "$ln 2" $act

	incr ln
	form_label $d.tl "tolerance" "$ln 0"
	form_entry $d.te merge_verts(tol) float "$ln 1"
	form_finish bot
    }    
}

proc merge_vertices_select {} {
    global merge_verts button_instructions

    set merge_verts(nodes) [select_node "Please select vertices to merge\
			$button_instructions" 100 node_numbers]    
}

proc merge_vertices_doit {} {
    global merge_verts

    if {$merge_verts(type) == "all"} {
	command "merge_vertices $merge_verts(tol) all"
    } else {
	command "merge_vertices $merge_verts(tol) [llength $merge_verts(nodes)] $merge_verts(nodes)"
    }

    # Recreate VORFN
    command "mark_blocks unmark"
    command "mark_blocks VORFN"
    command "delete_blocks marked"

    get_indices 1
    index_update_all
    update_display edge face block
}

proc edge_set_length {} {
    global edge_set

    set d [form_init .edge_legth "Set Edge Length" "" \
	       { { Accept edge_set_length_apply }  cancel } ]
    if {$d != ""} {
	set edge_set(length,method) "nofix"
	set ln 0
	form_label $d.method "Method:" "$ln 0"
	form_radiobutton $d.nofix "Move both ends" edge_set(length,method) "nofix" "$ln 1"	

	incr ln
	form_radiobutton $d.fix "Fix one end" edge_set(length,method) "fixnode" "$ln 1"

	form_finish bot
    }
}

proc edge_set_length_apply {} {
    global last_line
    global button_instructions
    global edge_set

    if {$edge_set(length,method) == "fixnode"} {
	set nedges 1
    } else {
	set nedges 1000
    }

    while 1 {
	set edges [select_edge "Select the edges with the \
		$button_instructions" $nedges new_format]
	if {$edges == ""} return
	
	set node -1
	if {$edge_set(length,method) == "fixnode"} {
	    set edges [list $edges]
	    set mess "Please select a vertex to fix $button_instructions"
	    set node [select_node $mess 1 node_numbers ]
	    if { $node == "" } return
	}

	set e [lindex $edges 0]
	command "mesh_params [lindex $e 0] [lindex $e 1]"
	set len [lindex $last_line 5]
	
	set len [question_box .edge_length "Edge length" \
		     "Enter the new edge length." $len]
	if {$len == ""} return
	
	foreach e $edges {
	    if {$edge_set(length,method) == "fixnode"} {
		command "set_edge_length [lindex $e 0] [lindex $e 1] $len fix $node"
	    } else {
		command "set_edge_length [lindex $e 0] [lindex $e 1] $len"
	    }
	}
	update_display
    }
}
proc split_edges { which  { how "" } } {
	global button_instructions

	if { $which == "select" } {
	    while { 1 } {
		set edge1 [ select_edge "Select the edge with the \
                $button_instructions" 1 new_format]

		if { $edge1 == "" }  break

		set t1 [ lindex $edge1 0 ]
		set t2 [ lindex $edge1 1 ]

		command "auto_split_edge $t1 $t2" 1 1

		update_display edge
	    }
	} elseif { $which == "all_displayed" } {
	    set mess "Automatically split all displayed edges ?"
            set ret [tk_dialog .tivc "Confirm" $mess "" 0 Apply Cancel]
            if {$ret} {
                return
            }
	    if { $how == "" } {
		command "auto_split_edge -all [range_string] [volume_activename_string]"
	    } elseif { $how == "smooth" } {
		command "smooth_edges_at_vertex [range_string] [volume_activename_string]"
	    }
	    update_display edge
	} elseif { $which == "all" } {
	    set mess "Automatically split all edges ?"
            set ret [tk_dialog .tivc "Confirm" $mess "" 0 Apply Cancel]
            if {$ret} {
                return
            }
	    if { $how == "" } {
	    	command "auto_split_edge -all"
	    } elseif { $how == "smooth" } {
		command "smooth_edges_at_vertex"
	    }
		
	    update_display edge
	} else {
		error "unhandled arguement $which to split_edges"
	}
}

proc move_face {} {
    global move_face button_instructions

    set buts [list [list Apply "move_face_doit"]  [list Dismiss move_face_done]]
    set d [form_init .move_face "Move face vertices" "" $buts]
    if {$d != ""} {
	set ln 0
	form_label $d.efsl "Face to move" "$ln 0"
	form_entry $d.efsn move_face(face) string "$ln 1"
	form_button $d.efsb "Select" \
	    "select_extrude_face move_face(face) \"Please select the corner vertices of the face to move, \
                          $button_instructions\"" "$ln 2"

	incr ln
	form_label $d.methodl "Method:" "$ln 0"
	form_radiobutton $d.p "2 points" move_face(type) points "$ln 1"
	incr ln
	form_radiobutton $d.v "Vector" move_face(type) vector "$ln 1"

	set act {{move_face(type) points}}
	set act1 {{move_face(type) vector}}
	
	incr ln
	form_label $d.p1l "Start point" "$ln 0" $act
	form_entry $d.p1e move_face(point1) string "$ln 1" $act
        form_button $d.p1 "Select" \
	    "primitive_select_point move_face(point1) \"select the base point\"" "$ln 2" $act

	incr ln
	form_label $d.p2l "End point" "$ln 0" $act
	form_entry $d.p2e move_face(point2) string "$ln 1" $act
        form_button $d.p2 "Select" \
	    "primitive_select_point move_face(point2) \"select the end point\"" "$ln 2" $act

	incr ln
	form_label $d.vl "Offset Vector" "$ln 0" $act1
	form_entry $d.ve move_face(vector) string "$ln 1" $act1

	form_finish bot
    }
}

proc move_face_doit {} {
    global move_face
    
    set n_facestart [llength $move_face(face)]
    if {$n_facestart != 2} {
	mess "Error: No face selected for extrusion\n" red
	return
    }
    
    set cmd "move_face $move_face(face) $move_face(type)"

    switch $move_face(type) {
	points {
	    append cmd " $move_face(point1) $move_face(point2)"
	}
	vector {
	    append cmd " $move_face(vector)"
	}
	default {
	    mess "Error: No such move type: $move_face(type)\n" red
	    return
	}
    }

    command $cmd
    get_indices 1    
    update_display edge face block mesh vertex
}

proc move_face_done {} {
    form_done .move_face
    command "display_loc erase"
}

proc rotate_multiple {} {
    global rotate_multiple button_instructions

    set buts [list [list Apply "rotate_multiple_doit"]  [list Dismiss rotate_multiple_done]]
    set d [form_init .rotate_multiple "Rotate multiple vertices" "" $buts]
    if {$d != ""} {
	set ln 0
	form_label $d.rvsl "Vertices" "$ln 0"
	form_entry $d.rvsn rotate_multiple(verts) string "$ln 1"
	form_button $d.efsb "Select" select_rot_verts "$ln 2"
	
	incr ln
	form_label $d.rcl "Center of rotation" "$ln 0"
	form_entry $d.rce  rotate_multiple(center) string "$ln 1"
        form_button $d.rcs "Select" \
	    "primitive_select_point rotate_multiple(center) \"select center point\"" "$ln 2"

	incr ln
	form_label $d.ral "Angle" "$ln 0"
	form_entry $d.rae rotate_multiple(angle) float "$ln 1"

	incr ln
	form_label $d.rvl "Axis of rotation" "$ln 0"
	form_entry $d.rve  rotate_multiple(axis) string "$ln 1"
        form_button $d.rvs "Select" select_rot_axis  "$ln 2"
	
	form_finish bot
    }
}

proc rotate_multiple_doit {} {
    global rotate_multiple

    if {$rotate_multiple(verts) == ""} {
	mess "ERROR: No vertex selected\n" red
	return
    }

    if {$rotate_multiple(angle) == ""} {
	mess "ERROR: No angle specified\n" red
	return
    }

    if {$rotate_multiple(center) == ""} {
	mess "ERROR: No center point selected\n" red
	return
    }
    
    if {$rotate_multiple(axis) ==  ""} {
	mess "ERROR: No axis specified for rotation\n" red
	return
    }
			    
    command "rotate_nodes $rotate_multiple(angle) \
            $rotate_multiple(center) $rotate_multiple(axis) $rotate_multiple(verts)"
    update_display edge face block mesh vertex
}

proc select_rot_verts {} {
    global rotate_multiple
    global button_instructions

    set rotate_multiple(verts) [select_node "Please select vertices $button_instructions" 0 node_numbers]
}

proc select_rot_axis {} {
    global rotate_multiple
    global button_instructions

    primitive_select_point rotate_multiple(axis1) "select start point of axis"
    if {$rotate_multiple(axis1) != ""} {
	primitive_select_point rotate_multiple(axis2) "select end point of axis"
    }

    set rotate_multiple(axis) ""    
    if {$rotate_multiple(axis1) != "" && $rotate_multiple(axis2) != ""} {	
	foreach i {0 1 2} {
	    lappend rotate_multiple(axis) [expr [lindex $rotate_multiple(axis2) $i] \
					       - [lindex $rotate_multiple(axis1) $i]]
	}
    }
}

proc rotate_multiple_done {} {
    global rotate_multiple

    form_done .rotate_multiple
    command "display_loc erase"
}
