# 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 top_set_current_if {on} { if $on top_set_current }

proc top_clear {} {
    global top_visible top_current
    
    catch {set top_current ""}
    catch {unset top_visible}
    form_kill .topologies
}

proc top_set_current {} {
    global botform_geo top_cxsep top_cysep top_visible top_current
    global last_line
    
    set d [form_init .topologies "Sub-topology map" topology done]
    if {$d != ""} {
	form_label $d.mapl "Left = select; middle = visible" {1 0}
	
	form_finish $botform_geo
	
	#####
	set top_cxsep 100
	set top_cysep 75
	
	set top_current ""
    }
    top_build_map
    
    return .topologies
}


proc top_get_current {} {
    global top_current last_line
    
    if {![info exists top_current] || ($top_current == "")} {
	command "print_topo_tree" 0
	set top_current [lindex [lindex $last_line 0] 0]
    }
    return $top_current
}

proc top_make_width {tree} {
    global top_width
    
    if {[llength $tree] == 1} {
	set top_width([lindex $tree 0]) 1
    } else {
	set w 0
	foreach n [lrange $tree 1 end] {
	    top_make_width $n
	    incr w $top_width([lindex $n 0])
	}
	set top_width([lindex $tree 0]) $w
    }
}


proc top_select { which } {
	global start_loc_0 start_loc_1 start_loc_2 start_loc_3
	global start_loc_4 start_loc_5 start_loc_6 start_loc_7
	global end_loc_0 end_loc_1 end_loc_2 end_loc_3
	global end_loc_4 end_loc_5 end_loc_6 end_loc_7
	global top_current

	set nodes [ select_node "Select the corners for the region" 8 \
			node_numbers ]
	if { $which == "from" } {
		set rtname "start_loc_"
	} else {
		set rtname "end_loc_"
	}
	set nn 0
	foreach i $nodes {
		set name $rtname$nn
		set $name "$top_current:$i"
		incr nn
	}
}

#proc top_select {n} {
#    global top_current top_visible top_selected
#    
#    if [info exists top_selected] { set top_selected $n; return }
#    
#    set top_current $n
#    if !$top_visible($n) {
#	set top_visible($n) 1
#	command "display_topology $n"
#    }
#    command "switch_blocking $n"
#    top_build_map
#    get_indices 1
#    update_display
#}

proc top_select_toponame {} {
    global top_selected

    set top_selected ""
    set w [top_set_current]
    tkwait variable top_selected
    set ret $top_selected
    unset top_selected
    form_done $w
    return $ret
}

proc top_visible {n} {
    global top_visible top_current
    
    if {$n == $top_current} {
	blt_bell
	mess "Can't blank the current topology\n" red
	return
    }
    set top_visible($n) [expr !$top_visible($n)]
    if $top_visible($n) {
	command "display_topology $n"
    } else {
	command "erase_topology $n"
    }
    top_build_map
}


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

# List view of toplogy map

proc top_clear_list {} {
    global top_visible top_current 
    
    catch {set top_current ""}
    catch {unset top_visible}
    form_kill .act_topologies
}

proc top_build_defaults {} {
    global top_current last_line
    
    command "print_topo_tree" 0
    set top_current [lindex [lindex $last_line 0] 0]
    foreach l $last_line {
	set t [lindex $l 0]
    }
}
    
proc unused__top_as_list { text } {
    global last_line top_current top_visible  top_selected
    
    set opts ""
    command "print_topo_tree" 0
    foreach l $last_line {
	set t [lindex $l 0]
	lappend opts $t
    }
    
    set sel [choose_one $text $opts $top_selected]
    if {$sel != ""} {
	set top_selected $top_current
    }
}

#returns the name of the selected topology

proc top_select_topo {text { multiple "" } } {
    global top_current last_line topo_selected
    
    set choices ""
    catch { unset topo_selected }
    command "print_topo_tree" 0
    foreach l $last_line {
	set t [lindex $l 0]
	set topo_selected($t) 0
	lappend choices $t
    }
    set topo_selected($top_current) 1
    
    if { $multiple != "" } {
	if { [ check_box_form .top_select $text $choices 10  \
		topo_selected 1 "" "" "" ] == 0 }  {
		return ""
	}
	set ret ""
	foreach l [ array names topo_selected ] {
		if { $topo_selected($l) } {
			lappend ret $l
		}
	}
	return $ret
    } else {
	return [choose_one $text $choices $top_current]
    }
}

proc update_top_as_list {} {
    if {[winfo exists .act_topologies] && [winfo viewable .act_topologies]} {
	#top_as_list "Active topologies"
    }
}

proc switch_topology { new_top } {
	global top_current top_visible
    
	if { $top_current != "" } {
		set top_visible($top_current) 0
	}
	
	set top_current $new_top
# make visible the current topology and erase the previous one
	
	set top_visible($top_current) 1

	command "switch_blocking $top_current"
	
	get_indices 1
	update_display
}

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

proc top_select_current {} {
    global top_current
    
    if ![info exists top_current] {
	top_build_defaults
    }
    
    set ret [top_select_topo "Active Topologies" ]
    if { $ret != "" } {
	switch_topology $ret
    }
}



proc top_insert {} {
    global top_current last_line
    global button_instructions

    
    set name [top_get_current]
    if {$name == ""} {
	return
    }
    
    command "print_n_break_points $name" 0
    set breaks $last_line
    
    command "display_block_orientation $name"
    
    set nnodes 1
    set text "Orig"
    foreach i {0 1 2} {
	set p [lindex {I J K} $i]
	set n [lindex $breaks $i]
	for {set j 1} {$j <= $n} {incr j} {
	    incr nnodes
	    lappend text $p$j
	}
	mess "Number of $p nodes = $n\n"
    }
    
    mess "For a floating node, select the origin (the first node selected).\n"
    
    set ns [select_node_text "Please select the destination nodes \
		$button_instructions" \
		[expr {$nnodes + 1}] $text]
    
    if {[llength $ns] < $nnodes} {
	mess "Not enough nodes selected.\n" red
	return
    }
    
    command "display_block_orientation erase"
    set cmd "insert_blocking $name $top_current"
    append cmd " \{[lindex $ns 0]\}"
    
    set k 1
    foreach i {0 1 2} {
	set n [lindex $breaks $i]
	append cmd " \{"
	for {set j 1} {$j <= $n} {incr j} {
	    append cmd " \{[lindex $ns $k]\}"
	    incr k
	}
	append cmd " \}"
    }
    
    command $cmd
    
    update_top_as_list
    update_display
    file_dirty
}

proc top_delete {} {
    global top_visible top_current 
    
    
    if ![info exists top_current] {
	top_build_defaults
    }
    
    set ret [top_select_topo "Delete Topology" mult ]
    if { $ret != "" } {
	    foreach i $ret {
	    	command "delete_blocking $i"
	       catch {unset top_visible($i)}
	    
# if we are deleting the same topology as we had
# before, then null out saved current topology
	    
	        if {$i == $top_current} {
		    set top_current ""
		    set top_current [top_get_current]
	        }
	    }
    }
    
# restore state of currently selected topologies
    
# top_build_map

    update_top_as_list
    update_display
    file_dirty
}

proc top_extract {} {
    global top_visible top_newname form_done_flag botform_geo top_current
    
    block_unmark
    command "del marked -solid m [volume_activename_string]" 0
    
    set top_newname sub
    for {set i 2} {[info exists top_visible($top_newname)]} {incr i} {
	set top_newname sub$i
    }
    set d [form_init .textract "Extract Topology" topo "accept cancel" ]
    if {$d != ""} {
	form_frame $d.fr sunken 3 {0 0}; set d $d.fr
	
	set ln 0
	form_label $d.toponl "Topology name:" "$ln 0"
	form_entry $d.topon top_newname string "$ln 1"
	
	incr ln
	form_label $d.regl "Region:" "$ln 0"

	incr ln
	form_label $d.labc "2 corners:" "$ln 0"
	form_button $d.addb "Add" {while {[block_mark 1 0]} {}} "$ln 1"
	form_button $d.remb "Remove" {while {[block_mark 0 0]} {}} "$ln 2"

	incr ln
	form_label $d.labb "Block:" "$ln 0"
	form_button $d.adds "Add" \
	    {block_mark_super 1 0 "to Extract" ""} "$ln 1"
	form_button $d.rems "Remove" \
	    {block_mark_super 0 0 "to Extract" ""} "$ln 2"

	incr ln
	form_label $d.labn "Block Numbers:" "$ln 0"
	form_button $d.addbn "Add" \
	    {block_mark_numbers 1 "to Extract" ""} "$ln 1"
	form_button $d.rembn "Remove" \
	    {block_mark_numbers 0 "to Extract" ""} "$ln 2"

	incr ln
	form_label $d.alld "All Displayed" "$ln 0"
	form_button $d.addall "Add" \
	    { block_mark_all 1 "to Extract" ""} "$ln 1"
	form_button $d.remall "Remove" \
	    {block_mark_all 0 "to Extract" ""} "$ln 2"

	incr ln
	form_button $d.redisplay "Re-Display" "ogrid_redisplay" "$ln 0"
	form_button $d.undo "Undo" "ogrid_undo" "$ln 1"
	form_button $d.redo "Redo" "ogrid_redo" "$ln 2"
	
	form_finish $botform_geo
    }
    tkwait variable form_done_flag(.textract)
    if !$form_done_flag(.textract) return
    
    if [info exists top_visible($top_newname)] {
	tk_dialog .err "Error" "Can't use the name \"$top_newname\" because there is already\
		a subtopology with that name." "" 0 Ok
    }
    
    command "extract_blocking $top_newname"
# unmark the old blocks
    block_unmark
# switch to the new blocking
    command "switch_blocking $top_newname"
    set top_current $top_newname
    get_indices 0
    update_display 
    
# top_build_map
    update_top_as_list
    file_dirty
}

proc top_rename {} {
    global top_current
    
    set name [top_get_current]
    if {$name == ""} return
    
    set nname $name
    set nname [question_box .tname Name "Specify a new name for topology\
	    \"$name\"." $nname]
    if {$nname == ""} return
    
    command "rename_blocking $name $nname"
    # top_build_map
    set top_current $nname
    update_top_as_list
    file_dirty
}

proc top_copy {} {
    global top_visible top_current move_translate
    global button_instructions move_useijk move_usemat
    
    set name [top_get_current]
    if {$name == ""} return
    
    for {set i 0} {[info exists top_visible(topo$i)]} {incr i} {}
    set nname topo$i
    set nname [question_box .tname Name "Specify a name for the\
	    new topology." $nname]
    if {$nname == ""} return
    
    if ![info exists move_translate] {
	set move_translate "5 5 5"
    }
    
    set cmd "copy_blocking $name $nname"
# need to add questions for this  in the above form
#    if { $move_useijk } {
#	append cmd " [range_string] "
#    }
#    if { $move_usemat } {
#	append cmd "m [volume_activename_string] "
#    }
    command $cmd
    
    # top_build_map
    update_top_as_list
    file_dirty
}

proc top_transform {} {
    global top_transform_name
    
    set top_transform_name [top_get_current]
    if {$top_transform_name == ""} return
    
    top_transform_form .top_transform
}

proc top_load {} {
    global top_visible top_current
    
    set filename [select_blocking_file 0]
    if {$filename == ""} return
    
    for {set i 0} {[info exists top_visible(topo$i)]} {incr i} {}
    set nname topo$i
    set nname [question_box .tname Name "Specify a name for the\
	    new topology." $nname]
    if {$nname == ""} return
    
    command "restore_blocking $filename $nname"
    
# switch to that topology
    command "switch_blocking $nname"
    set top_current $nname
    update_top_as_list
    get_indices 1
    update_display
    file_dirty
}

proc top_save {} {
    file_save 1
}

# ------------------
proc select_vector_menu { d var ln cl on_off_var } {
	set m $d.m
	form_menubutton_regular $d "Select" $m "$ln $cl" $on_off_var
	menu $m
	$m add command -label "Graphic location" -command \
			"top_select_vector $var graphic"
	$m add command -label "Prescribed points" -command \
			"top_select_vector $var pre_points"
}

proc form_line { d name ln } {
 	frame $d.$name -borderwidth 1 -background black -relief raised
 	blt_table $d $d.$name $ln,1 -columnspan 5 \
 	    -anchor center -pady 5 -fill x
}

proc top_transform_form {w} {
    global start_locs end_locs
    global top_transform_name top_copy_name move_do_how
    global move_do_translate move_do_rotate move_do_scale
    global move_do_mirror move_translate move_rotate
    global move_rotaxis move_mirror move_scale move_about move_about_point
    global move_about_lpoint move_about_lvec
    global move_do_transfinite start_locs end_locs
    global start_loc_0 start_loc_1 start_loc_2 start_loc_3
    global start_loc_4 start_loc_5 start_loc_6 start_loc_7
    global end_loc_0 end_loc_1 end_loc_2 end_loc_3
    global end_loc_4 end_loc_5 end_loc_6 end_loc_7
    global move_useijk move_usemat move_rot_about_axis top_copy_repeat
    
    if ![info exists move_do_translate] {
	set move_do_how move
	set move_do_translate 1
	set move_do_transfinite 0
	set move_do_rotate 0
	set move_do_scale 0
	set move_do_mirror 0
	set move_translate "0 0 0"
	set move_rotate 0
	set move_rotaxis 0
	set move_rot_about_axis "1 0 0"
	set move_mirror 0
	set move_scale 1
	set move_about point
	set move_about_point "0 0 0"
	set move_about_lpoint "0 0 0"
	set move_about_lvec "0 1 0"
	set move_useijk 0
	set move_usemat 0
	set top_copy_name ""
	set start_locs ""
	set end_locs ""
	for { set i 0 } { $i < 8 } { incr i } {
		set start_loc_$i ""
		set end_loc_$i ""
	}
    }
    set top_copy_repeat 1
    
    set buts {{Apply top_transform_doit} done}
    set d [form_init $w "Translate topology" "topology sub" $buts]
    if {$d != ""} {
	form_frame $d.fr sunken 2 {0 0}; set d $d.fr
	
# topology name
	set ln 0
	form_label $d.namel "Topology" "$ln 1 -cols 2"
	form_entry $d.name top_transform_name string {0 3 -cols -}

	incr ln
	form_label $d.howl "Operation" "$ln 1 -cols 2"

	form_radiobutton $d.howt Transform move_do_how move "$ln 3 -cols -"
	
	incr ln
	form_radiobutton $d.howc "Copy/Transform" move_do_how copy "$ln 3 -cols -"
	incr ln
	form_radiobutton $d.howm "Copy/Transform/Merge" move_do_how \
			copy_merge "$ln 3 -cols -"


#	form_radiobutton $d.howt "2D -> 3D" move_do_how 2d3d {3 3 -cols -}
#	form_radiobutton $d.hows "3D -> Surface Mesh" move_do_how surf \
#							{ 4 3 -cols -}
	
	incr ln
	form_label $d.namecl "Copy Name" "$ln 2" {{move_do_how copy}}
	form_entry $d.namec top_copy_name string "$ln 3 -cols -" \
				{{move_do_how copy}}
	
	incr ln
	form_label $d.repeatcl "Number Copies" "$ln 2" \
				{{move_do_how copy copy_merge}}
	form_entry $d.repeatc top_copy_repeat int "$ln 3 -cols -" \
				{{move_do_how copy copy_merge}}
	
	incr ln
	form_line $d line1 $ln


# Translate
	incr ln
	form_checkbutton \
	    $d.translate Translate move_do_translate "$ln 1 -cols 2"
	form_entry $d.transamount move_translate coords "$ln 3 -cols 2" \
		move_do_translate
	
	select_vector_menu $d.seltrans move_translate $ln 5 move_do_translate
# Rotate
    
	incr ln
	form_checkbutton $d.rotate "Rotate" move_do_rotate \
		"$ln 1 -cols -"
	form_entry $d.rotamount move_rotate string "$ln 3 -cols -" \
		move_do_rotate

# Radio buttons for Rotate

	incr ln
	form_frame $d.rotfr flat 0 "$ln 3 -cols -"
	form_radiobutton $d.rotfr.x X move_rotaxis 0 {0 0} \
	    { move_do_rotate}
	form_radiobutton $d.rotfr.y Y move_rotaxis 1 {0 1} \
	    {move_do_rotate}
	form_radiobutton $d.rotfr.z Z move_rotaxis 2 {0 2} \
	    { move_do_rotate}
	form_radiobutton $d.rotfr.a Dir move_rotaxis -1 {0 3} \
	    { move_do_rotate}

# About dir

	incr ln
	form_label $d.rotra "About dir" "$ln 2"  \
	    { move_do_rotate {move_rotaxis -1}}
	form_entry $d.rabax move_rot_about_axis coords "$ln 3 -cols -" \
	    { move_do_rotate {move_rotaxis -1}}


# these aren't needed anymore
#	form_label $d.rotpl "2D-3D pt" {25 2}  \
#	    {{move_do_how 2d3d} move_do_rotate}
#
#	form_label $d.rotvl "2D-3D dir" {26 2}  \
#	    {{move_do_how 2d3d} move_do_rotate}
	
# Scale
	incr ln
	form_checkbutton $d.scale Scale move_do_scale "$ln 1 -cols 2"  
	form_entry $d.scaleamount move_scale coords_float "$ln 3 -cols -" \
	    { move_do_scale}

# Mirror
	incr ln
	form_checkbutton $d.mirror Mirror move_do_mirror "$ln 1 -cols 2" 
	form_radiobutton $d.mirror_normal \
		"Normal"  move_mirror 3 "$ln 3" \
	    { move_do_mirror}
	form_radiobutton $d.mirrorx YZ move_mirror 0 "$ln 4" \
	    {  move_do_mirror}
	form_radiobutton $d.mirrory XZ move_mirror 1 "$ln 5" \
	    { move_do_mirror}
	form_radiobutton $d.mirrorz XY move_mirror 2 "$ln 6" \
	    { move_do_mirror}
# Mirror axis
	incr ln
	form_label $d.mirror_axisl "Mirror normal" "$ln 1 -cols -" \
			{ move_do_mirror { move_mirror 3 } }
	form_entry $d.mirror_axis move_mirror_axis coords_float \
		"$ln 3 -cols 2" { move_do_mirror { move_mirror 3 } }
	select_vector_menu $d.selmiror move_mirror_axis $ln 5 \
				{ move_do_mirror { move_mirror 3 } } 

# Transform about	
	incr ln
	form_label $d.about "Transform about:" "$ln 1 -cols -" 

# Origin
	incr ln
	form_radiobutton $d.origin Origin move_about origin \
			"$ln 2 -cols -" 

# Centroid
	incr ln
	form_radiobutton $d.centr Centroid move_about centroid \
			"$ln 2 -cols -" 

# Point
	incr ln
	form_radiobutton $d.point Point move_about point "$ln 2 -cols -"
	form_entry $d.centpoint move_about_point coords "$ln 3 -cols 2" \
		{{move_about point} }

	set m $d.cps.m
	form_menubutton_regular $d.cps "Select" $m "$ln 5" \
		{{move_about point }}
	menu $m
	$m add command -label "Graphic location" -command \
			"top_select_point graphic"
	$m add command -label "Prescribed point" -command \
			"top_select_point pre_point"

#	form_button $d.cps "Select" "top_select_point" "$ln 5" \
#		{{move_about point} }
	
	form_colwidth $d 1 2 m
	

	
#	form_entry $d.linepoint move_about_lpoint coords {25 3 -cols -} \
#	    {{move_do_how 2d3d} move_do_rotate}
#	form_entry $d.linedir move_about_lvec coords {26 3 -cols -} \
#	    {{move_do_how 2d3d} move_do_rotate}

	
# Transfinite	
	
	incr ln
	form_checkbutton $d.transfinite Transfinite move_do_transfinite \
			"$ln 1 -cols 2" 

	form_label $d.from_locsl "from" "$ln 3" move_do_transfinite
	form_label $d.to_locsl "to" "$ln 4" move_do_transfinite

	incr ln
	form_button $d.transf_select_from "Select" "top_select from" "$ln 3" \
		{ move_do_transfinite {move_do_how move copy} }

	form_button $d.transf_select_to "Select" "top_select to" "$ln 4" \
		{ move_do_transfinite {move_do_how move copy} }

	
	for { set i 0 } { $i < 8 } { incr i } {
		incr ln
		form_label $d.node_$i "Corner $i" "$ln 2" \
			{ move_do_transfinite {move_do_how move copy} }
		
		form_entry $d.from_$i start_loc_$i int "$ln 3" \
			{ move_do_transfinite {move_do_how move copy} }

		form_entry $d.to_$i end_loc_$i int "$ln 4" \
			{ move_do_transfinite {move_do_how move copy} }
	}
	

	incr ln
	form_checkbutton $d.useijk "Only visible index range" move_useijk \
	    "$ln 1 -cols -"

	incr ln
	form_checkbutton $d.usemat "Only visible materials" move_usemat \
	    "$ln 1 -cols -"
	
	form_finish -0-0
    }
}


proc top_select_vector { var how } {
    global $var last_line button_instructions
    if { $how == "graphic" } {
 
	    banner "Please select the from point $button_instructions"
	    command graphics_loc
	    set from_point $last_line

	    banner "Please select the to point $button_instructions"
	    command graphics_loc
	    set to_point $last_line
	    banner ""

	    set $var ""
	    for { set i 0 } { $i < 3 } { incr i } {
		set x1 [ lindex $to_point $i ]
		set x2 [ lindex $from_point $i ]
		set del [ expr { $x1 - $x2 } ]
		append $var " $del"
	    }
    } elseif { $how == "pre_points" } {
	set p1 [ select_point "Please select the from point" ]
	if { $p1 == "" } return
	set p2 [ select_point "Please select the to point" ]
	if { $p2 == "" } return
	set $var "$p1 $p2"
    } else {
	puts "invalid arguement $how to top_select_trans"
    }
}
proc top_select_point { how } {
    global move_about_point last_line button_instructions
    if { $how == "graphic" } {
	    banner \
	"Please select the transform about point $button_instructions"
	    command graphics_loc
	    banner ""
	    set move_about_point $last_line
    } elseif { $how == "pre_point" } {
	set p1 [ select_point "Please select the about point" ]
	if { $p1 == "" } return
	set move_about_point $p1
    } else {
	puts "invalid arguement $how to top_select_trans"
    }
}

proc top_transform_doit {} {
    global start_loc_0 start_loc_1 start_loc_2 start_loc_3
    global start_loc_4 start_loc_5 start_loc_6 start_loc_7
    global end_loc_0 end_loc_1 end_loc_2 end_loc_3
    global end_loc_4 end_loc_5 end_loc_6 end_loc_7
    global start_locs end_locs move_do_transfinite
    global top_transform_name move_do_translate move_do_rotate move_do_scale
    global move_do_mirror move_translate move_rotate
    global move_rotaxis move_mirror move_scale move_about move_about_point
    global move_about_lpoint move_about_lvec
    global last_line
    global move_useijk move_usemat move_do_how move_rot_about_axis
    global top_copy_name top_copy_repeat move_mirror_axis
    
    set mpoint ""
    set norm ""
    switch $move_about {
	point    { set mpoint $move_about_point }
	origin   { set mpoint "0 0 0" }
	centroid {
	    command "display_bounding_box" 0
	    set bb $last_line
	    set cx [expr {([lindex $bb 0] + [lindex $bb 3]) / 2}]
	    set cy [expr {([lindex $bb 1] + [lindex $bb 4]) / 2}]
	    set cz [expr {([lindex $bb 2] + [lindex $bb 5]) / 2}]
	    set mpoint "$cx $cy $cz"
	}
    }
    
    set not_done 1
    set cmd ""
    switch $move_do_how {
	copy_merge - 
	copy {
	    if {$top_transform_name == ""} {
		    mess "You must first select a topology to copy.\n" red
		    return
	    }
	    
	    if { $move_do_how == "copy_merge" } {
		set top_copy_name "__temp__"
	    } else {
		if {$top_copy_name == ""} {
		    mess "You must enter the copy name of the topology.\n" red
		    return
		}
	    }	    
	    
	    set last_transform_name $top_transform_name
	    set last_copy_name $top_copy_name
	    
	    command "undo_major_start duplicate_transform"
	    for {set i 0} {$i < $top_copy_repeat} {incr i} {
		if { $move_do_how == "copy" || $i == 0 } {
		    set cmd "copy_blocking $last_transform_name $last_copy_name"
		    if { $move_useijk } {
			append cmd " [range_string] "
		    }
		    if { $move_usemat } {
			append cmd " m [volume_activename_string] "
		    }
		    command $cmd
		}

		set cmd "transform_blocking $last_copy_name "
		if $move_do_translate {
		    append cmd "translate $move_translate "
		}
		if $move_do_rotate {
		    if {$move_rotaxis == -1} {
			set norm $move_rot_about_axis
		    } else {
			set norm \
			    [lindex {{1 0 0} {0 1 0} {0 0 1}} $move_rotaxis]
		    }
		    append cmd "rotate $mpoint $norm $move_rotate "
		}
		if $move_do_scale {
		    set sc $move_scale
		    if {[llength $sc] == 1} { set sc "$sc $sc $sc" }
		    append cmd "scale $mpoint $sc "
		}
		if $move_do_mirror {
		    if { $move_mirror == 3 } {
			set norm $move_mirror_axis
		    } else {
		    	set norm [lindex {{1 0 0} {0 1 0} {0 0 1} } \
				$move_mirror]
		    }
		    append cmd "mirror $mpoint $norm "
		}
# only apply the ijk range the first time
#		if { $move_useijk } { append cmd " [range_string] " }

		if $move_usemat { append cmd "m [volume_activename_string] " }
		
		command $cmd
# now merge it in
		if { $move_do_how == "copy_merge" } {
			set cmd "merge_blocking $top_transform_name \
				$last_copy_name"
			if { $move_usemat } {
				append cmd " [volume_activename_string]"
			}
			append cmd " -remove_unused_grid_lines"
			append cmd " -separate_classes -version 110"
			command $cmd
			set last_transform_name $last_copy_name
		} else {
# create next copy transform targets
			set last_transform_name $last_copy_name
			set last_copy_name "${top_copy_name}__[expr $i+1]"
		}
	    }
	    set not_done 0
	    if { $move_do_how == "copy_merge" } {
		command "delete_blocking __temp__"
		get_indices 1
	    }
	    command "undo_major_end duplicate_transform"
	    set copy_name ""
	}
	move {
	    if {$top_transform_name == ""} {
		mess "You must first select a topology to transform.\n" red
		return
	    }
	    
	    set cmd "transform_blocking $top_transform_name "
	    if $move_do_transfinite {
		append cmd "transfinite "
		for { set i 0 } { $i < 8 } { incr i } {
			set name start_loc_$i
			append cmd "[set $name ] "
		}
		for { set i 0 } { $i < 8 } { incr i } {
			set name end_loc_$i
			append cmd "[ set $name ] "
		}
	    }
	    if $move_do_translate {
		append cmd "translate $move_translate "
	    }
	    if $move_do_rotate {
		if {$move_rotaxis == -1} {
		    set norm $move_rot_about_axis
		} else {
		    set norm [lindex {{1 0 0} {0 1 0} {0 0 1}} $move_rotaxis]
		}
		append cmd "rotate $mpoint $norm $move_rotate "
	    }
	    if $move_do_scale {
		set sc $move_scale
		if {[llength $sc] == 1} { set sc "$sc $sc $sc" }
		append cmd "scale $mpoint $sc "
	    }
	    if $move_do_mirror {
		if { $move_mirror == 3 } {
			set norm $move_mirror_axis
		} else {
			set norm [lindex {{1 0 0} {0 1 0} {0 0 1} } \
				$move_mirror ]
		}
		append cmd "mirror $mpoint $norm "
	    }
	    if $move_useijk { append cmd " [range_string] " }
	    if $move_usemat { append cmd "m [volume_activename_string] " }
	}
	2d3d {
	    if {$move_do_translate + $move_do_rotate != 1} {
		tk_dialog .err "Error" \
		"You must select one of Translate or Rotate but not both." \
		"" 0 Ok
	    }
	    set cmd "extrude_blocks "
	    if $move_do_translate {
		append cmd "translate $move_translate "
	    } elseif $move_do_rotate {
		append cmd "rotate $move_about_lpoint $move_about_lvec \
			$move_rotate "
	    }
	}
	surf {
	     set mess "Convert volume blocking to a surface blocking ?"
	     set ret [tk_dialog .tivc "Confirm" $mess "" 0 Apply Cancel]
	     if {$ret == 0} {
		set cmd "threed_to_twod [family_activename_string]"
	     }
	}
	default {
		puts "illegal value for move_do_how $move_do_how"
	}
    }
    if {$not_done} {
	command $cmd
    }
    if { $move_do_how == "2d3d" } {
    	get_indices 1
	set_scan_plane_state
    }
    update_display
    
    file_dirty
}
proc ext_select_point {} {
    global extrude_base last_line
    command graphics_loc
    set extrude_base $last_line
}

proc top_fill { } {
	set fam [select_material "Please select a volume family for\
        	the new volume blocks."]
	if { $fam == "" } return

	command "twod_to_threed $fam"
	get_indices 1
	update_display edge face block mesh
	set_scan_plane_state
	file_dirty
}
proc top_extrude { how} {
	global extrude_distance extrude_base extrude_axis extrude_angle
	global extrude_rotaxis collapse_axis extrude_ncopies extrude_npoints
	global extrude_points extrude_curves extrude_periodic

	if { $how == "translate" } {
		set mess "Enter extrusion distance"

		if ![info exists extrude_distance] { set extrude_distance 1 }
		set dist \
	[question_box .extrude_blocks Distance $mess $extrude_distance]
		if {$dist == ""} return
		set extrude_distance $dist
		command "extrude_blocks translate 0 0 $dist"
		get_indices 1
		update_display edge face block mesh
		set_scan_plane_state
		file_dirty
	} elseif { $how == "rotate" } {
	    set buts {{Apply top_extrude_doit} done}
    	    set d [form_init .extrude_rotate "Extrude rotate" "xxx" $buts]
	    if {$d != ""} {
		form_frame $d.fr sunken 3 {0 0}; set d $d.fr

		set ln 1
		form_label $d.base "base:" "$ln 0"
		set extrude_base "0 0 0"
		form_entry $d.base_val extrude_base string "$ln 1"
		form_button $d.cps "Select" "ext_select_point" "$ln 2" 

		incr ln
		form_label $d.axis "axis:" "$ln 0"
		set extrude_axis "1 0 0"
		set extrude_rotaxis 0
		form_entry $d.axis_val extrude_axis string "$ln 1" \
			{ { extrude_rotaxis -1 } }

		form_radiobutton $d.d Dir extrude_rotaxis -1 "$ln 2"
		form_radiobutton $d.x X extrude_rotaxis 0 "$ln 3 "
		form_radiobutton $d.y Y extrude_rotaxis 1 "$ln 4 "
		form_radiobutton $d.z Z extrude_rotaxis 2 "$ln 5 "
		
		incr ln
		form_label $d.angle "angle:" "$ln 0"
		set extrude_angle "90"
		form_entry $d.angle_val extrude_angle string "$ln 1"

		incr ln
		set collapse_axis 1
		form_checkbutton $d.collapse "Collapse axis nodes" \
			collapse_axis "$ln 0"

		incr ln
		set extrude_ncopies 1
		form_label $d.n_subl "Number of copies" "$ln 0"
		form_entry $d.n_sub extrude_ncopies string "$ln 1"

		incr ln
		set extrude_npoints 3
		form_label $d.n_ptsl "Num points per copy" "$ln 0"
		form_entry $d.n_pts extrude_npoints string "$ln 1"

		incr ln
		form_label $d.extr "Extrude:" "$ln 0"
		set extrude_points 1
		form_checkbutton $d.points "points" \
			extrude_points "$ln 1"
		set extrude_curves 1
		form_checkbutton $d.curves "curves" \
			extrude_curves "$ln 2"

		incr ln
		set extrude_periodic 0
		form_checkbutton $d.periodic "Set periodic nodes" \
			extrude_periodic "$ln 0"

		form_finish -0-0
	    }
	} else {
		puts "Illegal arguement to top_extrude"
	}
}
proc top_extrude_doit {} {
	global extrude_base extrude_axis extrude_angle extrude_rotaxis
	global collapse_axis extrude_ncopies extrude_points extrude_curves
	global tetin_save_needed extrude_npoints extrude_periodic

	if { $extrude_rotaxis == "-1" } {
		set axis $extrude_axis
	} elseif { $extrude_rotaxis == "0" } {
		set axis "1 0 0"
	} elseif { $extrude_rotaxis == "1" } {
		set axis "0 1 0"
	} elseif { $extrude_rotaxis == "2" } {
		set axis "0 0 1"
	}
	set cmd "extrude_blocks rotate $extrude_base $axis $extrude_angle"
	if { $collapse_axis } {
		append cmd " collapse_axis"
	}
	if { $extrude_periodic } {
		append cmd " set_periodic"
	}
	if { $extrude_ncopies > 0 } { 
		append cmd " -ncopies $extrude_ncopies"
	}
	if { $extrude_npoints > 1 } { 
		append cmd " -npoints $extrude_npoints"
	}
	if { $extrude_points } {
		append cmd " -extrude_points"
		set tetin_save_needed 1
	}
	if { $extrude_curves } {
		append cmd " -extrude_curves"
		set tetin_save_needed 1
	}
	command $cmd

	get_indices 1
	set_scan_plane_state
	update_display edge face block mesh
	file_dirty
}
proc top_surface {} {
	set mess "Convert volume blocking to a surface blocking ?"
	set ret [tk_dialog .tivc "Confirm" $mess "" 0 Apply Cancel]
	if {$ret == 0} {
		set cmd "threed_to_twod [family_activename_string]"
		command $cmd
		get_indices 1
		update_display
		file_dirty
		set_scan_plane_state
	}
	
}
proc top_invert {} {
    set name [top_get_current];
    if {$name == ""} return
    
    set mess "Invert blocks in topology \"$name\"?"
    set ret [tk_dialog .tivc "Confirm" $mess "" 0 Apply Cancel]
    if {$ret == 0} {
	command "invert_blocking $name"
    }
}

proc top_merge {} {
    global top_current
    
    set t1 [top_get_current]
    if {$t1 == ""} return
    
    set ret [ top_select_topo "Merge \"$t1\" with topology" ]
    if {$ret == ""} return

# get tolerance
    set tol [question_box .mtol "Relative Tolerance" \
		"Specify a relative tolerance for merging the topologies." \
		".1" ]
    if {$tol == ""} return

    command "merge_blocking $t1 $ret [family_activename_string] \
			-remove_unused_grid_lines -eps $tol \
			-separate_classes -version 110"
    get_indices 1
    index_reset
    index_update_all
    update_display
    
    update_top_as_list
    file_dirty
}
