# 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

# blank_family_var is indexed by the family number
# and is 1 if the family is highlighted.

# add a line
proc block_change_degen_edge { }  {
	global button_instructions
	set block_num [ select_block select  \
		" whose degen edge you want to change" ] 
	set degen_edge [select_edge "Please select the new degenerate edge \
		$button_instructions" 1 "new_format"]
	command "change_degenerate_edge $block_num \
			[ lindex $degen_edge 0 ] [ lindex $degen_edge 1 ] "
	file_dirty
	update_display edge face block mesh vertex
	get_indices 0
}
proc blank_blocks {} {
    global topform_geo form_done_flag blank_family_list
    global families family_name family_dims 
    global botform_geo display_flag
    
    set display_flag(use_blanking) 1
    set d [form_init .blank_unblank "Blank/Unblank Blocks" block]
    if {$d != ""} {
	form_frame $d.fr sunken 3 {0 0}; set d $d.fr
	
	set ln 1
	form_label $d.regionl "Material:" "$ln 1"
	form_frame $d.region ridge 2 {1 2  -cols 2 -fill none}

	incr ln
	form_label $d.libfam "       Selected families:" "$ln 1"
	form_button $d.addfam "Blank" "blank_blocks_by_family 1" "$ln 2"
	form_button $d.remfam "Unblank" "blank_blocks_by_family 0" "$ln 3"

	incr ln
	form_label $d.labb "       2 corners:" "$ln 1"
	form_button $d.addb "Blank" "blank_block_mark 1 0" "$ln 2"
	form_button $d.remb "Unblank" "blank_block_mark 0 0" "$ln 3"

	incr ln
	form_label $d.labs "       Block:" "$ln 1"
	form_button $d.adds "Blank" "blank_block_mark 1 super" "$ln 2"
	form_button $d.rems "Unblank" "blank_block_mark 0 super" "$ln 3"

	incr ln
	form_label $d.labn "Block Numbers:" "$ln 1"
	form_button $d.adbn "Blank" \
	    "block_blank_numbers 1 \"to blank\"" "$ln 2"
	form_button $d.rmbn "Unblank" \
	    "block_blank_numbers 0 \"to unblank\"" "$ln 3"

	incr ln
	form_label $d.labf "       Face:" "$ln 1"
	form_button $d.addf "Blank" "blank_block_mark 1 1" "$ln 2"
	form_button $d.remf "Unblank" "blank_block_mark 0 1" "$ln 3"

	incr ln
	form_label $d.labe "       Edge:" "$ln 1"
	form_button $d.adde "Blank" "blank_block_mark 1 2" "$ln 2"
	form_button $d.reme "Unblank" "blank_block_mark 0 2" "$ln 3"

	incr ln
	form_label $d.labv     "       Vertex:" "$ln 1"
	form_button $d.addv "Blank" "blank_block_mark 1 3" "$ln 2"
	form_button $d.remv "Unblank" "blank_block_mark 0 3" "$ln 3"

	incr ln
	form_label $d.lab_ad " Index range and families " "$ln 1"
	form_button $d.add_ad "Blank" "blank_block_mark 1 all_disp" "$ln 2"
	form_button $d.rem_ad "Unblank" "blank_block_mark 0 all_disp" "$ln 3"

	incr ln
	form_label $d.lab_all " All " "$ln 1"
	form_button $d.add_all "Blank" "blank_block_mark 1 all" "$ln 2"
	form_button $d.rem_all "Unblank" "blank_block_mark 0 all" "$ln 3"

	incr ln
	form_button $d.reverse "Reverse blanking"  "blank_block_reverse" \
				"$ln 1"

	form_rowheight $d 19 2
    }
    
    set fams ""
    foreach f $families {
	if {$family_dims($f) == 3} {
	    lappend fams [list $f -text $family_name($f) \
		    -command "blank_block_mark_families blank_family_var"]
	}
    }
    if {![info exists blank_family_list] || ($blank_family_list != $fams)} {
	foreach w [winfo children .blank_unblank.main.fr.region] { destroy $w }
	set blank_family_list $fams
	check_box .blank_unblank.main.fr.region $fams 6 blank_family_var 1 \
		"blank_block_mark_families blank_family_var"
	
	# This is kind of wierd.
	if {$d != ""} {
	    form_finish $botform_geo
	} else {
	    wm withdraw .blank_unblank
	    update
	    wm geometry .blank_unblank $botform_geo
	    sun_geometry .blank_unblank $botform_geo
	    wm deiconify .blank_unblank
	}
    }
}
proc blank_block_reverse { } {
	command "blank_blocks reverse"
	update_display block edge vertex face
}
proc block_blank_numbers { blank txt } {
	command "mark_blocks unmark"
	block_mark_numbers 1 txt
	if { $blank } {
		command "blank_blocks marked"
	} else {
		command "unblank_blocks marked"
	}
	update_display block edge vertex face
}
proc blank_blocks_by_family { on } {
	global blank_family_var family_name
	mess "blank_blocks_by_family\n"
	set fams ""
	foreach i [ array names blank_family_var ] {
		if { $blank_family_var($i) } {
			append fams " $family_name($i)"
		}
	}
	if { $fams != "" } {
		command "mark_blocks unmark"
		command "mark_blocks $fams"
		if { $on } {
			command "blank_blocks marked"
		} else {
			command "unblank_blocks marked"
		}
		update_display block edge vertex face
	}
}
proc blank_block_mark_families {var {one 0}} {
     mess "$var\n"
#    block_mark_families $var $one \
#	    "m [volume_activename_string] dead_as_faces"
#    command "unblank_blocks"
#    command "blank_blocks marked"
}
proc block_innero {} {
    global topform_geo form_done_flag innero_family_list
    global innero_face_list innero_face_var
    global families family_name family_dims innero_family_var
    global innero_which innero_factor botform_geo ogrid_dont_unmark
    global ogrid_done_once innero_relative innero_dist env
    
    if [info exists ogrid_done_once] {
	set ogrid_dont_unmark [tk_dialog .unmark_blocks "Unmark blocks" \
				   "Unmark all the blocks that\
			were marked for the previous operation?" \
				   "" -1 Yes No]
    } else {
	set ogrid_dont_unmark 0
	set ogrid_done_once 1
    }
    
    # if !$ogrid_dont_unmark { block_unmark }
    # command "del marked -solid m [volume_activename_string] dead_as_faces" 0
    
    set d [form_init .innero "Inner O-grid" block]
    if {$d != ""} {
	form_frame $d.fr sunken 3 {0 0}; set d $d.fr
	
	set ln 1
	form_label $d.regionl "Material:" "$ln 1"
	form_frame $d.region ridge 2 "$ln 2  -cols 2 -fill none"

 	incr ln
 	form_label $d.facel "Face families:" "$ln 1"
 	form_frame $d.face ridge 2 "$ln 2  -cols 2 -fill none"

	incr ln
	incr ln
	form_label $d.grl "Create grid:" "$ln 1"
	form_radiobutton $d.in "In blocks" \
		innero_which in "$ln 2 -cols 2"
	incr ln
	form_radiobutton $d.around "Around blocks" \
		innero_which around "$ln 2 -cols 2"
	
	incr ln
	form_label $d.edl "   Edit region:" "$ln 1 -cols 3"
	incr ln
	form_label $d.labb "       2 corners:" "$ln 1"
	form_button $d.addb "Add" "ogrid_block_mark 1 0" "$ln 2"
	form_button $d.remb "Remove" "ogrid_block_mark 0 0" "$ln 3"

	incr ln
	form_label $d.labs "       Block:" "$ln 1"
	form_button $d.adds "Add" "ogrid_block_mark 1 super" "$ln 2"
	form_button $d.rems "Remove" "ogrid_block_mark 0 super" "$ln 3"

	incr ln
	form_label $d.labn "Block Numbers:" "$ln 1"
	form_button $d.adbn "Add" \
	    "block_mark_numbers 1 \"for O-grid\"" "$ln 2"
	form_button $d.rmbn "Remove" \
	    "block_mark_numbers 0 \"for O-grid\"" "$ln 3"

	incr ln
	form_label $d.labf "       Face:" "$ln 1"
	form_button $d.addf "Add" "ogrid_block_mark 1 4" "$ln 2"
	form_button $d.remf "Remove" "ogrid_block_mark 0 4" "$ln 3"

	incr ln
	form_label $d.labe "       Edge:" "$ln 1"
	form_button $d.adde "Add" "ogrid_block_mark 1 2" "$ln 2"
	form_button $d.reme "Remove" "ogrid_block_mark 0 2" "$ln 3"

	incr ln
	form_label $d.labv     "       Vertex:" "$ln 1"
	form_button $d.addv "Add" "ogrid_block_mark 1 3" "$ln 2"
	form_button $d.remv "Remove" "ogrid_block_mark 0 3" "$ln 3"

	incr ln
	form_label $d.lab_ad " All Displayed" "$ln 1"
	form_button $d.add_ad "Add" "ogrid_block_mark 1 all_disp" "$ln 2"
	form_button $d.rem_ad "Remove" "ogrid_block_mark 0 all_disp" "$ln 3"

	incr ln
	form_label $d.lab_all " All " "$ln 1"
	form_button $d.add_all "Add" "ogrid_block_mark 1 all" "$ln 2"
	form_button $d.rem_all "Remove" "ogrid_block_mark 0 all" "$ln 3"

	incr ln
	form_button $d.redisplay "Re-Display" "ogrid_redisplay" "$ln 1"
	form_button $d.undo "Undo" "ogrid_undo" "$ln 2"
	form_button $d.redo "Redo" "ogrid_redo" "$ln 3"

	form_rowheight $d 19 2

	incr ln
	set innero_relative 1
	form_radiobutton $d.rel "Relative distance" \
		innero_relative 1 "$ln 1 -cols 2"
	form_entry $d.fact innero_factor float_var "$ln 3" \
			{ { innero_relative 1 } }

	incr ln
	form_radiobutton $d.abs "Absolute distance" \
		innero_relative 0 "$ln 1 -cols 2"
	set innero_dist .1
	form_entry $d.dist innero_dist float_var "$ln 3" \
			{ { innero_relative 0 } }
    }
    
    set innero_factor 1.0
    set innero_which in
    
    set volfams ""
    set facefams ""
    foreach f $families {
	if {$family_dims($f) == 3} {
	    lappend volfams [list $f -text $family_name($f) \
		    -command "ogrid_block_mark_families" ]
	} else {
	    lappend facefams [ list $f -text $family_name($f) \
		-command "ogrid_block_mark_families" ]
	}
    }
    if {![info exists innero_family_list] || \
			($innero_family_list != $volfams)} {
	foreach w [winfo children .innero.main.fr.region] { destroy $w }
	set innero_family_list $volfams
	set listlen [ llength $volfams ]
	if { $listlen > 6 } {
		set listlen "6"
	}
	if { $listlen < 1 } {
		set listlen "1"
	}
	check_box .innero.main.fr.region $volfams $listlen innero_family_var 1 \
		"ogrid_block_mark_families"
	
	# This is kind of wierd.
	if {$d != ""} {
	    form_finish $botform_geo
	} else {
	    wm withdraw .innero
	    update
	    wm geometry .innero $botform_geo
	    sun_geometry .innero $botform_geo
	    wm deiconify .innero
	}
    }
    if {![info exists innero_face_list] || \
			($innero_face_list != $facefams)} {
	foreach w [winfo children .innero.main.fr.face] { destroy $w }
	set innero_face_list $facefams
	set listlen [ llength $facefams ]
	if { $listlen > 6 } {
		set listlen "6"
	}
	if { $listlen < 1 } {
		set listlen "1"
	}
	check_box .innero.main.fr.face $facefams $listlen innero_face_var 1 \
		"ogrid_block_mark_families"
	
	# This is kind of wierd.
	if {$d != ""} {
	    form_finish $botform_geo
	} else {
	    wm withdraw .innero
	    update
	    wm geometry .innero $botform_geo
	    sun_geometry .innero $botform_geo
	    wm deiconify .innero
	}
    }

    if $ogrid_dont_unmark {
	command "del marked -solid m [volume_activename_string] dead_as_faces" 0
    } else {
	ogrid_block_mark_families
    }
    set ogrid_dont_unmark 0
    tkwait variable form_done_flag(.innero)
    
    if $form_done_flag(.innero) {
	if { $innero_relative } {
		set cmd "ogrid $innero_factor"
	} else {
		if [info exists env(HEXA_TOYOTA)] {
		    set fix_dist "fix_dist"
		} else {
		    set fix_dist ""
		}
		set cmd "ogrid distance $innero_dist $fix_dist"
	}
	if {$innero_which != "in"} { append cmd " not_marked" }
# the 42 indicates a new behavior in 2d. (version 4.2 on)
# the 50 indicates a new behavior in 3d. (version 5.0 on)
	append cmd " m [volume_activename_string] -version 50"
	command $cmd
	file_dirty
	update_display edge face block mesh vertex
	get_indices 0
    }
    command "del erase" 0
}

proc ogrid_undo { } {
	global last_line
	command "undo query"
	if { $last_line == "mark blocks" || $last_line == "mark_blocks" } {
		command "undo"
		ogrid_redisplay
	}
}
proc ogrid_redo { } {
	global last_line
	command "redo query"
	if { $last_line == "mark blocks" || $last_line == "mark_blocks"} {
		command "redo"
		ogrid_redisplay
	}
}
proc ogrid_redisplay {  } {
	command "del marked -solid [volume_activename_string] [range_string] dead_as_faces"
}

proc block_mark2 {on face del_opts txt} {
	global display_flag
	switch $face {
	super {
		block_mark_super $on 0 $txt $del_opts
	}
	all_disp {
		if { $on } {
			set markval ""
		} else {
			set markval "unmark"
		}
		set cmd "mark_blocks [volume_activename_string] \
				[range_string] $markval"
		if { $display_flag(use_blanking) } {
			append cmd " -not_blanked"
		}
		command $cmd
		ogrid_redisplay
	}
	all {
		if { $on } {
			set markval ""
		} else {
			set markval "unmark"
		}
		command "mark_blocks $markval"
		ogrid_redisplay 
	}
	faces {
		global blank_face_var family_name
		command "mark_blocks unmark"
		set fams ""
		foreach i [ array names blank_family_var ] {
			if { $blank_family_var($i) } {
				if [ info exists family_name($i) ] {
					append fams " $family_name($i)"
				} else {
					mess "no family_name($i)\n"
				}
			}
		}
		if { $fams != "" } {
			command "mark_blocks -faces $fams"
		}
	}
	fams {
		global blank_family_var family_name
		command "mark_blocks unmark"
		set fams ""
		foreach i [ array names blank_family_var ] {
			if { $blank_family_var($i) } {
				if [ info exists family_name($i) ] {
					append fams " $family_name($i)"
				} else {
					mess "no family_name($i)\n"
				}
			}
		}
		if { $fams != "" } {
			command "mark_blocks $fams"
		}
	}
	default {
# 0 is two corners
# 1 is face
# 2 is edge
# 3 is vertex
		while { [ block_mark $on $face $del_opts ] } {}
	}
	}
}
proc blank_block_mark { on face } {
	command "mark_blocks unmark"
	set del_opts "m [volume_activename_string]"
	mess "blank_block_mark $on $face $del_opts\n"
	if { $on } {
		set txt "to blank"
	} else {
		set txt "to unblank"
	}
	block_mark2 1 $face $del_opts $txt
	if { $on } {
		command "blank_blocks marked"
	} else {
		command "unblank_blocks marked"
	}
	update_display block edge face vertex
}
proc ogrid_block_mark {on face} {
	set del_opts "m [volume_activename_string] dead_as_faces"
	block_mark2 $on $face $del_opts "for the O-grid"
}


proc ogrid_block_mark_families {} {
    global ogrid_dont_unmark
    if !$ogrid_dont_unmark {
	block_mark_families innero_family_var innero_face_var \
	    "m [volume_activename_string] dead_as_faces"
    }
}



proc block_outero {} {
    global outero_perp form_done_flag botform_geo
    global button_instructions
    
    set mess "Please select two vertices $button_instructions"
    set nodes [select_node $mess 2]
    if {[llength $nodes] != 2} return
    set first [lindex $nodes 0]
    set second [lindex $nodes 1]
    
    set d [form_init .outero "Outer O-grid" block]
    if {$d != ""} {
	form_frame $d.fr sunken 3 {0 0}; set d $d.fr
	
	form_checkbutton $d.iperp "I perpendicular" outero_perp(i) {1 1}
	form_checkbutton $d.jperp "J perpendicular" outero_perp(j) {2 1}
	form_checkbutton $d.kperp "K perpendicular" outero_perp(k) {3 1}
	
	form_finish $botform_geo
    }
    
    tkwait variable form_done_flag(.outero)
    
    if $form_done_flag(.outero) {
	set cmd "outer_o_grid { $first } { $second }"
	foreach i {i j k} { if $outero_perp($i) { append cmd " ${i}perp" } }
	command $cmd
	file_dirty
	update_display edge face block mesh
	get_indices 0
    }
}

proc block_split {} {
    global form_done_flag split_dir split_ind index_max split_val
    global split_projnew split_n1 split_n2 index_min index_max
    global botform_geo split_onlymarked inside_split_operation
    global button_instructions move_ogrid_nodes last_line
    global split_dist split_point split_param split_type split_curve
    global display_flag
    
    command "mark_blocks unmark" 0
    set split_onlymarked 0
   
    set split_edge [select_edge "Please select the edge to split \
		$button_instructions" 1 "new_format"]
    if {$split_edge == ""} return
    
    set split_n1 [ lindex $split_edge 0 ]
    set split_n2 [ lindex $split_edge 1 ]

    command "edge_node_dim $split_n1 $split_n2"
    set split_dir [ lindex $last_line 0 ]
    set split_ind [ lindex $last_line 1 ]

    
    set d [form_init .split "Split block" block]
    set split_type rel
    set split_val .5
    if {$d != ""} {
	set ln 0
	form_frame $d.fr sunken 3 "$ln 0"; set d $d.fr
	incr ln
	
	form_label $d.dirl "Direction" "$ln 1"
	futil_updown $d.dir split_dir 0 5 "$ln 2"
	incr ln
	
	form_label $d.indl "Index" "$ln 1"
	futil_updown $d.ind split_ind 0 0 "$ln 2"
	incr ln
	
	form_radiobutton $d.vall "Split value" split_type rel "$ln 1"
	form_entry $d.val split_val float_var "$ln 2" { { split_type rel } }
	incr ln

	form_radiobutton $d.distl "Split distance" split_type abs "$ln 1"
	form_entry $d.dist split_dist float_var "$ln 2" { { split_type abs } }
	incr ln
	
	form_radiobutton $d.pre "Prescribed point" split_type point "$ln 1"
	form_entry $d.pointl split_point string "$ln 2" {{ split_type point }} 
	incr ln

	form_radiobutton $d.cpar "Curve parameter" split_type curve "$ln 1"
	form_entry $d.curve split_curve string "$ln 2" {{ split_type curve }}
	form_entry $d.par split_param float_var "$ln 3" {{ split_type curve }}
	incr ln

	form_button $d.vals "Screen select" "block_split_screen" "$ln 1"
	incr ln 
	
	form_checkbutton $d.pnew "Project new vertices" split_projnew \
	    "$ln 1 -cols 2"
	incr ln
	
	form_checkbutton $d.onlymark "Marked blocks" split_onlymarked "$ln 1"
	incr ln

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

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

	form_label $d.labn "Block Numbers:" "$ln 1"
	form_button $d.addbn "Add" \
	    {block_mark_numbers 1 "to Split" ""} "$ln 2" split_onlymarked
	form_button $d.rembn "Remove" \
	    {block_mark_numbers 0 "to Split" ""} "$ln 3" split_onlymarked
	incr ln
	
	form_finish $botform_geo
	
	set split_val 0.5
	set split_dist 0.0
    }
    
    if [ info exists index_max($split_dir) ] {
    	futil_updown_reset_minmax split_ind $split_ind $index_max($split_dir)
    }

    set inside_split_operation 1
    
    after 1 block_split_screen doit
    tkwait variable form_done_flag(.split)
    
    if ![info exists inside_split_operation] return
    
    if $form_done_flag(.split) {
	set mrk ""
	if $split_onlymarked { 
		set mrk "marked" 
	} elseif { $display_flag(use_blanking) } {
		set mrk "marked"
		command "mark_blocks unmark"
		command "mark_blocks [volume_activename_string] -not_blanked"
	}
	switch $split_type {
		rel {
			set temp $split_val
		}
		abs {
			set temp abs:$split_dist
		}
		curve {
			set temp curve:$split_curve:$split_param
		}
		point {
			set temp $split_point
		}
		default {
			mess "unknown split type $split_type\n"
			return
		}
	}
	command "split_grid $split_n1 $split_n2 $temp \
			[range_string] m [volume_activename_string] $mrk"
	file_dirty
	
	if $split_projnew {
	    incr split_ind
	    set cmd "project_to_surface $split_dir:$split_ind,$split_ind \
		[volume_activename_string]"
	    if { $move_ogrid_nodes } {
		append cmd " move_ogrid_nodes"
	    }
	    command $cmd
	}
	
	if {$split_dir < 3} {
	    if {$split_ind <= $index_max($split_dir)} {
		incr index_max($split_dir)
	    }
	    if {$split_ind < $index_min($split_dir)} {
		incr index_min($split_dir)
	    }
	}
	update_display edge face block mesh
# update the indices incrementing changed index
	get_indices 3
	index_update_all
    }
    command "select_value erase" 0
    unset inside_split_operation
}

proc block_split_screen { { doit "" } } {
	global last_line split_n1 split_n2 split_val
	global button_instructions split_dist split_type
	global display_flag

	if { $split_type == "point" } {
		block_split_prescr
	} elseif { $split_type == "curve" } {
		block_split_cpar
	} else {
		banner $button_instructions
		set cmd "select_value $split_n1 $split_n2 \
			[volume_activename_string] [range_string]"
		if $display_flag(use_blanking) { 
			append cmd " -not_blanked" 
		}
		command $cmd 1 1
		set val [lindex $last_line 0]
		banner ""
		if {($val > 0.0) && ($val < 1.0)} {
			set split_val $val
			if { $doit == "doit" } {
				form_accept_hack .split
			}
		}
		command "mesh_params $split_n1 $split_n2"
		if { [ lindex $last_line 5 ]  != "" } {
		    set split_dist [ lindex $last_line 5 ]
		    set split_dist [ expr $split_dist * $split_val ]
		}
		command "select_value erase" 0
	}
}

proc block_split_cpar {} {
    global split_curve split_param
    global button_instructions

    set p [ select_curve_parameter $button_instructions ]
    if { $p == "" } return
    set curve_par [ split $p : ]
    set split_curve [ lindex $curve_par 0 ]
    set split_param [ lindex $curve_par 1 ]
}
proc block_split_prescr {} {
    global split_point
    global button_instructions
    
    set p [select_point $button_instructions ]
    if {$p == ""} return
    
    set split_point $p
}

proc block_decimate {} {
	global use_output_blocks
	if ![tk_dialog .pnew "Decimate" "Extend all splits?" "" 1 "Yes" "No"] {
		command mark_blocks
		set cmd "decimate_blocks "
		if $use_output_blocks { append cmd " output_blocks" }
		command $cmd
		update_display edge face block mesh
    	}
}
proc block_extsplit {} {
    global form_done_flag split_dir split_ind index_max split_val split_projnew
    global split_vert split_edge index_min index_max botform_geo last_line
    global use_output_blocks
    global button_instructions move_ogrid_nodes
    global display_flag
    
    set split_edge [select_edge "Please select the split edge to extend \
		$button_instructions" 1 new_format ]
    if {$split_edge == ""} return
    
    foreach i {0 1 2} {
	set split_[lindex {vert dir ind} $i] [lindex $split_edge $i]
    }

    set cmd "index_from_edge \{ $split_vert \} $split_dir"
    if $use_output_blocks { append cmd " output_blocks" }
    command $cmd
    
    if {[llength $last_line] != 2} {
	mess "Bad edge selected.\n" red
	return
    }
    set split_dim [ lindex $last_line 0 ]
    set split_ind [ lindex $last_line 1 ]
#    puts "split_ind $split_ind"
    set cmd \
	"extend_split $split_dim $split_ind [range_string] m [volume_activename_string]"
    
    if $use_output_blocks { append cmd " output_blocks" }
    if $display_flag(use_blanking) { append cmd " -not_blanked" }
    command $cmd
    file_dirty
    
    if ![tk_dialog .pnew "Project" "Project new vertices?" "" 1 "Yes" "No"] {
	set cmd "project_to_surface $split_dim:$split_ind,$split_ind \
		[volume_activename_string]"
	if { $move_ogrid_nodes } {
		append cmd " move_ogrid_nodes"
	}
	command $cmd
    }
    
    update_display edge face block mesh
    get_indices 0
    index_update_all
}

proc block_uncollapse {} {
    global form_done_flag button_instructions
    
    
    while 1 {
    	set nodes [select_node \
		"Please select a node to uncollapse $button_instructions" 1 \
		node_numbers ]
    	if {[llength $nodes] != 1} return
    	set first [lindex $nodes 0]
    	command "uncollapse_edge $first"
    	file_dirty
    	update_display edge face block mesh
    }
	
}
proc block_delete_station {} {
    global form_done_flag button_instructions last_line
    
    set nodes [select_node \
	"Please select two vertices $button_instructions" 2 node_numbers ]

    if {[llength $nodes] != 2} return
    set first [lindex $nodes 0]
    set second [lindex $nodes 1]
    if { 0 } {
    	
	set dir [del_dim $first $second]
	if {$dir == ""} return
	set ind1 [node_index $first $dir]
	set ind2 [node_index $second $dir]
	if {($ind1 == "") || ($ind2 == "")} return
    } else {
	command "edge_node_dim $first $second"
	set dir [ lindex $last_line 0 ]
	set ind1 [ lindex $last_line 1 ]
	set ind2 $ind1
	incr ind2
	if { [ lindex $last_line 2 ] } {
		set temp $ind1
		set ind1 $ind2
		set ind2 $temp
	}
    }
    
    set mess "Confirm delete station:\n       direction = $dir\
	    \n	index 1 = $ind1\n	index 2 = $ind2"
    if ![tk_dialog .delete "Delete station" $mess "" 0 Confirm Cancel] {
    	# command "dls $dir $ind1 $ind2"
	command "dls -nodes $first $second"
	file_dirty
	update_display edge face block mesh
	get_indices 0
    }
}

proc del_dim {ijk1 ijk2} {
    for {set i 0} {$i < 3} {incr i} {
	if {[lindex $ijk1 $i] != [lindex $ijk2 $i]} {
	    return $i
	}
    }
    # now look at the remainder of the coordinates
    set l1 [llength $ijk1]
    set l2 [llength $ijk2]
    set mn [expr {($l1 < $l2) ? $l1 : $l2}]
    
    for {set i 3} {$i < $mn} {incr i} {
	set hp [lindex $ijk1 $i]
	if {[scan [lindex $ijk1 $i] "%d:%d" d1 i1] != 2} {
	    mess "internal error 1\n" red
	    return ""
	}
	if {[scan [lindex $ijk2 $i] "%d:%d" d2 i2] != 2} {
	    mess "internal error 2\n" red
	    return ""
	}
	if {$d1 < $d2} {
	    return $d1
	}
	if {$d2 < $d1} {
	    return $d2
	}
	if {$i1 != $i2} {
	    return $d1
	}
    }
    if {$l1 < $l2} {
	incr l2 -1
	if {$l1 != $l2} {
	    mess "internal error 3\n" red
	    return ""
	}
	if {[scan [lindex $ijk2 $l2] "%d:%d" d2 i2] != 2} {
	    mess "internal error 4\n" red
	    return ""
	}
	return $d2
    }
    if {$l2 < $l1} {
	incr l1 -1
	if {$l1 != $l2} {
	    mess "internal error 5\n" red
	    return ""
	}
	if {[scan [lindex $ijk1 $l1] "%d:%d" d1 i1] != 2} {
	    mess "internal error 6\n" red
	    return ""
	}
	return $d1
    }
    mess "identical nodes\n" red
    return ""
}

proc node_index {ijk dim} {
    if {$dim < 3} {
	return [lindex $ijk $dim]
    }
    set len [llength $ijk]
    for {set i 3} {$i < $len} {incr i} {
	set hp [lindex $ijk $i]
	if {[scan [lindex $ijk $i] "%d:%d" d ind] != 2} {
	    mess "internal error 7\n" red
	    return ""
	}
	if {$d == $dim} {
	    return $ind
	}
    }
    return 0
}

proc block_rescale {} {
    global form_done_flag rescale_dir rescale_ind index_max 
    global rescale_val rescale_abs
    global index_min index_max botform_geo
    global button_instructions
    
    set rescale_edge [select_edge "Please select the edge to rescale \
		$button_instructions" 1]
    if {$rescale_edge == ""} return
    
    foreach i {0 1 2} {
	set rescale_[lindex {vert dir ind} $i] [lindex $rescale_edge $i]
    }
    
    set d [form_init .rescale "Rescale ogrid" block]
    if { [ info exists rescale_abs ] == 0 } {
	set rescale_abs 0
    }
    if {$d != ""} {
	form_frame $d.fr sunken 3 {0 0}; set d $d.fr
	
#	form_label $d.dirl "Direction" {1 1}
#	futil_updown $d.dir rescale_dir 0 5 {1 2}
#	
#	form_label $d.indl "Index" {2 1}
#	futil_updown $d.ind rescale_ind 0 0 {2 2}
	
	form_label $d.vall "Rescale value" {3 1}
	form_entry $d.val rescale_val float_var {3 2}
	
	form_radiobutton $d.rel "Relative distance" rescale_abs 0 {4 1 -cols 2}
	form_radiobutton $d.abs "Absolute distance" rescale_abs 1 {5 1 -cols 2}
	
	form_finish $botform_geo
	
	set rescale_val 1.0
	set rescale_abs 0
    }
    
    if [info exists index_max($rescale_dir)] {
	futil_updown_reset_minmax rescale_ind $rescale_ind \
		$index_max($rescale_dir)
    }
    
    tkwait variable form_done_flag(.rescale)

    if $form_done_flag(.rescale) {
	set cmd "rescale_ogrid $rescale_dir $rescale_ind $rescale_val \
		[range_string] m [volume_activename_string]"
	if $rescale_abs { append cmd " abs" }
	command $cmd
	file_dirty
	
	update_display edge face block mesh
    }
}

proc block_collapse {} {
    global form_done_flag coll_dir botform_geo
    global button_instructions
    
    block_unmark
    set coll_edge [select_edge "Please select the edge to collapse \
		$button_instructions" 1 outer]
    if {$coll_edge == ""} return

    set coll_dir [lindex $coll_edge 1]
    
    set d [form_init .coll "Collapse block" block]
    if {$d != ""} {
	form_frame $d.fr sunken 3 {0 0}; set d $d.fr
	
	form_label $d.dirl "Direction" {1 1}
	futil_updown $d.dir coll_dir 0 5 {1 2}
	
	form_label $d.labc "       2 corners:" {2 1}
	form_label $d.labb "       Block:" {3 1}
	form_label $d.labn "Block Numbers:" {4 1}
	form_button $d.add "Add" \
	    {while {[block_mark 1 0]} {}} {2 2}
	form_button $d.rem "Remove" \
	    {while {[block_mark 0 0]} {}} {2 3}
	form_button $d.adds "Add" \
	    {block_mark_super 1 0 "to Collapse" ""} {3 2}
	form_button $d.rems "Remove" \
	    {block_mark_super 0 0 "to Collapse" ""} {3 3}
	form_button $d.addbn "Add" \
	    {block_mark_numbers 1 "to Collapse" ""} {4 2}
	form_button $d.rembn "Remove" \
	    {block_mark_numbers 0 "to Collapse" ""} {4 3}
	
	form_finish $botform_geo
    }
    
    futil_updown_reset_minmax coll_dir $coll_dir 5
    
    tkwait variable form_done_flag(.coll)
    
    if $form_done_flag(.coll) {
	command "collapse_blocks $coll_dir version 410"
	file_dirty
    }
    update_display edge face block mesh
}

proc surface_mesh_select_surfs { } {
	global surface_mesh
	global button_instructions

	set surface_mesh(surfs) [select_surface "Please select surfaces \
		$button_instructions" ]
}

proc block_initmesh {how { sub_opt "-mixed" } } {
    global index_max_limit domain_dir mesh_dir
    global env mesh_dir tetin_file is_win
    
    
    if { $how == "auto" } {
# auto blocking

# select an unstructured file
	set unstr [ file_select_unstruct tetra ]

	if { $unstr == "" } {
		return
	}
	if [ info exists env(AUTOBLOCK_BIN) ] {
		set auto_block $env(AUTOBLOCK_BIN)
	} else {
		set auto_block $env(ICEM_ACN)/icemcfd/auto_block
	}
	set command "$auto_block \
		$domain_dir/$unstr \
		$mesh_dir/$tetin_file \
		$mesh_dir/__temp_blocking__ "
	
	mess "$command\n"
	set logfile autoblocker.log
	set cmdfile autoblocker.cmd
	cmd_rm -f $logfile
	if $is_win {
	    eval exec $command >& $logfile &
	} else {
	    set fp [open $cmdfile w]
	    puts $fp "\#!/bin/csh -f"
	    puts $fp $command
	    close $fp
	    exec chmod 0755 $cmdfile
	    exec $cmdfile >& $logfile &
	}
       
# Now wait for the log file.
	for {set i 0} {$i < 60} {incr i} {
	    if [file exists $logfile] break
	    after 1000
	}
	if {$i == 60} {
	    mess "Error: autoblocker didn't start -- can't find log file\n" red
	    return
	}
	mess "Autoblocker is running: logfile = [file tail $logfile].\n"
       
	if [file exists $logfile] {
	    if ![show_logfile $logfile .autoblock_monitor Autoblocker "autoblocker finished" ] {
		mess "Autoblocker exited abnormally\n"
		return
	    }
	}

	command "restore_blocking __temp_blocking__"
	command "update_association root"

	get_indices 1
	update_display

# leave the file around
#	exec rm $mesh_dir/__temp_blocking__

    } else {
# 2D, 3D and surface initialization
	if { $how == "surface" } {
		global surface_mesh
		set surface_mesh(sub_opt) $sub_opt
		set buts { 
			{ Apply surface_mesh_doit }
			{ Dismiss { form_done .surface_mesh } }
		}
		set d [form_init .surface_mesh "Initialize Surface Mesh" \
			"" $buts]
		if { ! [ info exists surface_mesh(min_edge) ] } {
			set surface_mesh(min_edge) 0.0	
		}
		if { ! [ info exists surface_mesh(matname) ] } {
			set surface_mesh(matname) ""
		}
		if { $surface_mesh(matname) == "" } {
			set vas [volume_activename_string]
			if { [llength $vas ] == 1 } {
				set surface_mesh(matname) $vas
			} elseif { [ lsearch $vas LIVE ] >= 0 } {
				set surface_mesh(matname) LIVE
			}
		}
    		if {$d != ""} {
			set ln 0
			form_label $d.faml "Material" "$ln 0"
			futil_listentry $d.region surface_mesh(matname) \
			    "list [volume_name_string]" "$ln 1" "" "" 1


			incr ln
			form_label $d.min_edgel "Min edge length" "$ln 0"
			
			form_entry $d.min_edge surface_mesh(min_edge) \
				float "$ln 1"

# selected surfaces
			incr ln
			form_button $d.select_surfs "Which surfaces"  \
				"surface_mesh_select_surfs" "$ln 0"
			form_entry $d.surfs surface_mesh(surfs) \
				string "$ln 1"
				
			form_finish bot
# respect non
			incr ln
			form_checkbutton $d.respect \
				"Respect non-dormant" surface_mesh(respect) \
				"$ln 0"
# oring size
			incr ln
                        form_label $d.quad_ringl "Quad ring size" "$ln 0"

                        form_entry $d.quad_ring surface_mesh(quad_ring_size) \
                                float "$ln 1"
# can delete holes
			incr ln
			form_checkbutton $d.dholes \
				"Delete small holes" surface_mesh(dholes) \
				"$ln 0"
			
# merge across families
			incr ln
			form_checkbutton $d.dmfam \
				"Merge across families" surface_mesh(dmfam) \
				"$ln 0"
# merge across dormant curves
			incr ln
			form_checkbutton $d.dmcrvs \
			"Merge across dormant curves" surface_mesh(dmcrvs) \
				"$ln 0"
		}
		return
	} else {
		set mess "Warning: the \"Initialize mesh\" operation\
		will discard the current blocking and replace\ 
		it with a single block covering\
		the whole model."

		if [tk_dialog .initmesh Initialize $mess "" 0 \
			Initialize Cancel] {
		    return
		}
		command "initialize_mesh $how new_numbering"
	}
	get_indices 1
	reset_families
	if { $how != "surface" } {
		if {$index_max_limit(2) == 1} {
		    block_set_material {1 1 0} {2 2 1} 
		} else {
		    block_set_material {1 1 1} {2 2 2} 
		}
	}
    }
    update_display
    command "orient +z"
    set_scan_plane_state
}

proc surface_mesh_doit { } {
	global surface_mesh
	set cmd "surface_blocking $surface_mesh(matname) \
		$surface_mesh(sub_opt) -min_edge $surface_mesh(min_edge)"

	if { $surface_mesh(surfs) != "" } {
		append cmd " -surfaces $surface_mesh(surfs)"
	}
	if { $surface_mesh(respect)  || $surface_mesh(dmcrvs) } {
		append cmd " -respect_non_dormant"
	}
	if { $surface_mesh(dholes) } {
		append cmd " -delete_small_holes" 
	}
	if { $surface_mesh(quad_ring_size) != "" } {
		append cmd " -quad_ring_size $surface_mesh(quad_ring_size)"
	}
	if { $surface_mesh(dmfam) } {
		append cmd " -merge_across_families"
	}
	if { $surface_mesh(dmcrvs) } {
		append cmd " -merge_dormant"
	}
	command $cmd
	get_indices 1
	reset_families
	update_display
	# command "orient +z"
	set_scan_plane_state
	form_done .surface_mesh
}

proc block_primitive {type} {
    global tool_dir block_primitive

    
    set buts [list [list Apply "block_primitive_doit $type"] [list Dismiss "block_primitive_done $type"]]
    set d [form_init .block_prim${type} "$type Block Primitive" "" $buts]
    if {$d != ""} {
	form_frame $d.f flat 0 "0 0"
	form_label $d.f.tpipe "" "0 0"
	set im [image create photo -format GIF -file $tool_dir/block-${type}pipe.gif]
	$d.f.tpipe configure -image $im

	form_frame $d.f2 flat 0 "1 0"; set d $d.f2
	set ln 0
	form_label $d.regionl "Material" "$ln 0"
	futil_listentry $d.region block_primitive(matname) \
	    "list [volume_name_string]" "$ln 1" "" "" 1

	incr ln
	form_label $d.c1l "Curve-A" "$ln 0"
	form_entry $d.c1e block_primitive(curve1) string "$ln 1"
	form_button $d.c1 "Select" "primitive_select_curve block_primitive(curve1) \"select curve A\"" "$ln 2"

	incr ln
	form_label $d.p1l "Point-A" "$ln 0"
	form_entry $d.p1e block_primitive(point1) string "$ln 1"
	form_button $d.p1 "Select" "primitive_select_point block_primitive(point1) \"select point A\"" "$ln 2"

	incr ln
	form_label $d.d1l "Block-A size (d1)" "$ln 0"
	form_entry $d.d1e block_primitive(d1) float "$ln 1"

	incr ln
	form_label $d.c2l "Curve-B" "$ln 0"
	form_entry $d.c2e block_primitive(curve2) string "$ln 1"
	form_button $d.c2 "Select" "primitive_select_curve block_primitive(curve2) \"select curve B\"" "$ln 2"

	incr ln
	form_label $d.p2l "Point-B" "$ln 0"
	form_entry $d.p2e block_primitive(point2) string "$ln 1"
	form_button $d.p2 "Select" "primitive_select_point block_primitive(point2) \"select point B\"" "$ln 2"

	incr ln
	form_label $d.d2l "Block-B size (d2)" "$ln 0"
	form_entry $d.d2e block_primitive(d2) float "$ln 1"

	if {$type == "Y"} {
	    incr ln
	    form_label $d.c3l "Curve-C" "$ln 0"
	    form_entry $d.c3e block_primitive(curve3) string "$ln 1"
	    form_button $d.c3 "Select" "primitive_select_curve block_primitive(curve3) \"select curve C\"" "$ln 2"
	    
	    incr ln
	    form_label $d.p3l "Point-C" "$ln 0"
	    form_entry $d.p3e block_primitive(point3) string "$ln 1"
	    form_button $d.p3 "Select" "primitive_select_point block_primitive(point3) \"select point C\"" "$ln 2"
	    
	    incr ln
	    form_label $d.d3l "Block-C size (d3)" "$ln 0"
	    form_entry $d.d3e block_primitive(d3) float "$ln 1"
	}
	form_finish bot
    }
}

proc primitive_select_curve {var msg} {
    upvar \#0 $var lvar
    focus .v
    set lvar [select_curve $msg ]
}

proc primitive_select_point {var msg} {
    global last_line
    upvar \#0 $var lvar
    
    banner $msg
    focus .v
    command graphics_loc
    set lvar $last_line
    command "display_loc loc $lvar"
    banner ""
}

proc block_primitive_doit {type} {
    global block_primitive
    
    if {$block_primitive(matname) == ""} {
	mess "Error: No material specified for block primitive\n" red
	return
    }
    if {$block_primitive(curve1) == ""} {
	mess "Error: No base curve selected\n" red
	return
    }
    if {$block_primitive(curve2) == ""} {
	mess "Error: No branch curve selected\n" red
	return
    }

    set cmd "create_block_primitive $type $block_primitive(matname) \
	     $block_primitive(curve1) $block_primitive(curve2)"
    if {$type == "Y"} {
	if {$block_primitive(curve3) == ""} {
	    mess "Error: No branch curve2 selected\n" red
	    return
	}
	append cmd " $block_primitive(curve3)"
    }

    if {$block_primitive(point1) == "" || $block_primitive(point2) == ""} {
	mess "Error: Face points not selected\n" red
	return
    }
    
    append cmd " $block_primitive(point1) $block_primitive(point2)"
    if {$type == "Y"} {
	if {$block_primitive(point3) == ""} {
	    mess "Error: Face point3 not selected\n" red
	    return
	}
	append cmd " $block_primitive(point3)"
    }

    if {$block_primitive(d1) == "" || $block_primitive(d2) == ""} {
	 mess "Error: Block sizes not specified\n" red
	return
    }

    append cmd " $block_primitive(d1) $block_primitive(d2)"
    if {$type == "Y"} {
	if {$block_primitive(d3) == ""} {
	    mess "Error: Block size3 not specified\n" red
	    return
	}
	append cmd " $block_primitive(d3)"
    }

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

proc block_primitive_done {type} {
    form_done .block_prim${type}
    command "display_loc erase"
}

proc block_primitive_base {} {
    global tool_dir block_primitive
    
    set buts [list [list Apply "block_primitive_base_doit"] [list Dismiss block_primitive_base_done]]
    set d [form_init .block_primbase "Base Block Primitive" "" $buts]
    if {$d != ""} {	
	set block_primitive(type) BF
	set block_primitive(base_dir) points

	form_frame $d.f flat 0 "0 0"
	form_label $d.f.base "" "0 0"
	set im [image create photo -format GIF -file $tool_dir/base-block.gif]
	$d.f.base configure -image $im

	form_frame $d.f2 flat 0 "1 0"; set d $d.f2
	set ln 0
	#form_label $d.methodl "Base Block Method:" "$ln 0"
	#form_radiobutton $d.center "Centered" block_primitive(type) BC "$ln 1"
	#incr ln
	#form_radiobutton $d.base "Extrude Face" block_primitive(type) BF "$ln 1"

	#set act {{block_primitive(type) BC}}
	#set act1 {{block_primitive(type) BF}}
	
	#incr ln
	form_label $d.regionl "Material" "$ln 0"
	futil_listentry $d.region block_primitive(matname) \
	    "list [volume_name_string]" "$ln 1" "" "" 1

	set act1 1
	incr ln
	form_label $d.c1l "Center line" "$ln 0"
	form_entry $d.c1e block_primitive(curve1) string "$ln 1"
	form_button $d.c1 "Select" \
	    "primitive_select_curve block_primitive(curve1) \"select main pipe center line\"" "$ln 2"
	
	#incr ln
	#form_label $d.p1l "Block Center Point" "$ln 0" $act
	#form_entry $d.p1e block_primitive(point1) string "$ln 1" $act
	#form_button $d.p1 "Select" \
	    "primitive_select_point block_primitive(point1) \"select block center point\"" "$ln 2" $act

	incr ln
	form_label $d.p2l "Start Face Center (A)" "$ln 0" $act1
	form_entry $d.p2e block_primitive(point1) string "$ln 1" $act1
	form_button $d.p2 "Select" \
	    "primitive_select_point block_primitive(point1) \"select start face center point\"" "$ln 2" $act1

	incr ln
	form_label $d.p3l "End Face Center (B)" "$ln 0" $act1
	form_entry $d.p3e block_primitive(point2) string "$ln 1" $act1
	form_button $d.p3 "Select" \
	    "primitive_select_point block_primitive(point2) \"select end face center point\"" "$ln 2" $act1

	incr ln
	form_label $d.d1l "Block size (d1)" "$ln 0"
	form_entry $d.d1e block_primitive(d1) float "$ln 1"

	#incr ln
	#form_label $d.dirl "Side face direction:" "$ln 0"
	#form_radiobutton $d.p "2 points" block_primitive(base_dir) points "$ln 1"
	#incr ln
	#form_radiobutton $d.c "Sub-curve tangent" block_primitive(base_dir) curve "$ln 1"

	#set act {{block_primitive(base_dir) points}}
	#set act1 {{block_primitive(base_dir) curve}}
	
	incr ln
	form_label $d.dirl "Side face direction:" "$ln 0"

	set act 1
	incr ln
	form_label $d.dir1l "    Start point (C)" "$ln 0" $act
	form_entry $d.dir1e block_primitive(dir1) string "$ln 1" $act
	form_button $d.dir1 "Select" \
	    "primitive_select_point block_primitive(dir1) \"select the base point\"" "$ln 2" $act

	incr ln
	form_label $d.dir2l "    End point (D)" "$ln 0" $act
	form_entry $d.dir2e  block_primitive(dir2) string "$ln 1" $act
	form_button $d.dir2 "Select" \
	    "primitive_select_point block_primitive(dir2) \"select the end point\"" "$ln 2" $act
	
	#incr ln
	#form_label $d.c2l "Sub-pipe center line" "$ln 0" $act1
	#form_entry $d.c2e block_primitive(curve2) string "$ln 1" $act1
	#form_button $d.c2 "Select" \
	    "primitive_select_curve block_primitive(curve2) \"select sub-pipe center line\"" "$ln 2" $act1

	form_finish bot
    }
}

proc block_primitive_base_done {} {
    form_done .block_primbase
    command "display_loc erase"
}

proc block_primitive_base_doit {} {
    global block_primitive

    set cmd "create_block_primitive $block_primitive(type) $block_primitive(matname)"
    if {$block_primitive(base_dir) == "curve"} {
	append cmd " $block_primitive(curve1) $block_primitive(curve2)"
    } else {
	append cmd " $block_primitive(curve1) $block_primitive(curve1)"
    }

    set p1 $block_primitive(point1)
    set p2 $block_primitive(point2)
    if {$block_primitive(type) == "BC"} {
	set p2 $p1
    }
    append cmd " $p1 $p2"
    append cmd " $block_primitive(d1) 0"
    if {$block_primitive(base_dir) == "points"} {
	set vec ""
	foreach i {0 1 2} {
	    lappend vec [expr [lindex $block_primitive(dir2) $i] - [lindex $block_primitive(dir1) $i]]
	}
	append cmd " $vec"
    }
    command $cmd
    get_indices 1    
    update_display edge face block mesh vertex
}

proc block_merge {how} {
    global families family_name family_dims botform_geo use_output_blocks
    global merge_block_numbers display_flag
    global button_instructions
    
    set cmd ""
    switch $how {
	ijk {
	    set nodes [select_node \
		"Please select two vertices $button_instructions" 3 ]
	    if {[llength $nodes] < 2} return
	    set first [lindex $nodes 0]
	    set second [lindex $nodes 1]
	    set cmd "merge_blocks \{ $first \} \{ $second \} -version 51"
	}
	sel {
	    command "mark_blocks unmark" 0
	    if ![block_mark_super 1 0 "to Merge" ""] return
	    set cmd "merge_blocks -version 51"
	}
	two {
	    set nb [get_hexa_nsuperblocks]
	    for {set i 1} {$i <= $nb} {incr i} {
		set merge_block_numbers($i) 0
	    }
	    set r [form_block_numbers \
		       merge_block_numbers 0 "to Merge"]
	    
	    # If cancelled, stop here
	    
	    if !$r return;
	    
	    set mm ""
	    for {set i 1} {$i <= $nb} {incr i} {
		if $merge_block_numbers($i) { lappend mm $i }
	    }
	    set cmd "merge_blocks $mm -version 51"
	}
	auto {
	    #set mat [select_material "Select a material to merge."]
	    #if {$mat == ""} return
	    set cmd "auto_merge [volume_activename_string]"
	}
    }
    if $use_output_blocks { append cmd " output_blocks" }
    
    command $cmd

    file_dirty
    
    update_display edge face block mesh vert
    get_indices 0
}

proc block_delete {how} {
    global families family_name family_dims botform_geo use_output_blocks
    global merge_block_numbers display_flag
    global button_instructions
    
    set cmd ""
    switch $how {
	ijk {
	    set nodes [select_node \
		"Please select two vertices $button_instructions" 3 ]
	    if {[llength $nodes] < 2} return
	    set first [lindex $nodes 0]
	    set second [lindex $nodes 1]
	    set cmd "delete_blocks \{ $first \} \{ $second \}"
	}
	sel {
	    command "mark_blocks unmark" 0
	    if ![block_mark_super 1 0 "to Merge" ""] return
	    set cmd "delete_blocks marked"
	}
	two {
	    set nb [get_hexa_nsuperblocks]
	    for {set i 1} {$i <= $nb} {incr i} {
		set merge_block_numbers($i) 0
	    }
	    set r [form_block_numbers \
		       merge_block_numbers 0 "to Delete"]
	    
# If cancelled, stop here
	    
	    if !$r return;
	    
	    set mm ""
	    for {set i 1} {$i <= $nb} {incr i} {
		if $merge_block_numbers($i) { lappend mm $i }
	    }
	    set cmd "delete_blocks numbers $mm"
	}
	blanked {
	    set mess "Permanently delete blanked blocks?"
	    set ret [tk_dialog .tivc "Confirm" $mess "" 0 Apply Cancel]
	    if {$ret} {
		return
	    }
	    set cmd "delete_blocks blanked [volume_activename_string]"
	}
    }
    if $use_output_blocks { append cmd " output_blocks" }
    if $display_flag(use_blanking) { append cmd " -not_blanked" }
    
    command $cmd
    command "remove_unused_grid_lines"
    
    update_display edge face block mesh vertex
    get_indices 0
}

proc block_transfer {how} {
    global families family_name family_dims botform_geo use_output_blocks
    global merge_block_numbers display_flag
    global button_instructions transfer_block_numbers
    
    command "mark_blocks unmark" 0
	
    switch $how {
	ijk {
	    set nodes [select_node "Please select two vertices \
		$button_instructions" 3 ]
	    if {[llength $nodes] < 2} return
	    set first [lindex $nodes 0]
	    set second [lindex $nodes 1]
	    command "mark_blocks \{ $first \} \{ $second \}"
	}
	sel {
	    if { ![block_mark_super 1 0 "to Transfer" ""] }  return
	}
	nums {
	    set nb [get_hexa_nsuperblocks]
	    for {set i 1} {$i <= $nb} {incr i} {
		set transfer_block_numbers($i) 0
	    }
	    set r [form_block_numbers \
		       transfer_block_numbers 0 "to Transfer"]
	    
# If cancelled, stop here
	    
	    if !$r return;

	    
	    set mm ""
	    for {set i 1} {$i <= $nb} {incr i} {
		if $transfer_block_numbers($i) { lappend mm $i }
	    }
	    if { $mm == "" } {
		return
	    }
	    command "mark_blocks superblock $mm"
	}
    }
    command "transfer_blocks" 0
    
    
    update_display edge face block mesh
    get_indices 0
}

proc block_material {how} {
    global last_line
    global button_instructions display_flag
    
    switch $how {
	query {
	    set blocks [ select_block select "select the block to query" ]
	    command "get_block_family $blocks"
	}
	all_disp {
	    command "mark_blocks unmark" 0
		
	    command "mark_blocks [volume_activename_string] [range_string]"

	    if { $display_flag(use_blanking) } {
		command "mark_blocks unmark blanked"
	    }
		
	    block_set_material
	}
	ijk {
	    set nodes [select_node "Please select two vertices \
		$button_instructions" 3]
	    if {[llength $nodes] < 2} return
	    set first [lindex $nodes 0]
	    set second [lindex $nodes 1]
	    
	    command "mark_blocks unmark" 0
	    command "mark_blocks \{ $first \} \{ $second \}" 0
	    if {$last_line != ""} { mess "$last_line\n" red; return }
	    
	    command "del marked -solid" 0
	    block_set_material $first $second
	}
	
	select {
	    command "mark_blocks unmark" 0
	    if ![block_mark_super 1 0 "for the new material" ""] return
	    block_set_material 
	}
	
	numbers {
	    command "mark_blocks unmark" 0
	    set r [ block_mark_numbers 1 "for the new material" ]
	    if { $r == 0 } {
		return;
	    }
	    block_set_material
	}
    }
    command "mark_blocks unmark" 0
    update_display edge face block mesh
}

proc block_set_material { { first  "" } { second "" } } {
    set f [select_material "Please select an existing volume family to\
	add the selected blocks to."]
    if {$f == ""} return
    
    if { $first == "" || $second == "" } {
	command "cei $f"
    } else {
	command "cei $f \{ $first \} \{ $second \}"
    }
    file_dirty
}

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

proc block_periodic {} {
    set d [form_init .nodes_periodic "Periodic nodes" done]
    if {$d != ""} {
	form_button $d.per "Make nodes periodic" \
	    "block_make_periodic periodic" {0 0}
	form_button $d.nper "Make nodes not periodic" \
	    "block_make_periodic not_periodic" {1 0}
	form_finish bot
    }
}

proc block_make_periodic {what} {
    global button_instructions
    while 1 {
	set nn [select_node "Please select two vertices \
		$button_instructions" 2 node_numbers ]
	if {[llength $nn] != 2} return
	
	command "make_nodes_$what \{ [lindex $nn 0] \} \{ [lindex $nn 1] \}"
	update_display edge vert
    }
}

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

proc block_extrude_blocks {} {
    global extrude_distance
    
    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
}

proc block_surface_mesh {} {
	set mess "Convert blocking to a surface blocking ?"
	set ret [tk_dialog .tivc "Confirm" $mess "" 0 Apply Cancel]
	if {$ret == 0} {
		command "threed_to_twod [family_activename_string]"
	}
	update_display edge face block mesh
}

# n_faces == 0 means unlimited
proc select_face { n_faces { node_nums 0 } } {
	global last_line
	set cmd "select_super_face \
			[range_string] [family_activename_string]"
	if { $node_nums } {
		append cmd " node_numbers"
	}
	command "$cmd"
	set faces $last_line
	if { $n_faces != 0 && [ llength $last_line ] != $n_faces } {
		return ""
	}
	return $last_line
}
proc block_create_swept {} {

	set faces [ select_face 0 ]

	set len [ llength $faces ]
	if { $len < 1 || $len > 2 } return
	set cmd "create_swept_block $faces"
	command "$cmd"
	get_indices 1

	update_display edge face block mesh vertex

	file_dirty
}
proc add_interior_loop { } {
	global last_line

	set face [select_block select "Select the face to split" ]
	if { $face == "" } {
		return
	}
	set nodes ""
	while 1 {
                banner "Please select the node locations"
                command graphics_loc
                banner ""
                if { $last_line == "" } break
                lappend nodes $last_line
        }
	command "imprint_face $face $nodes"
	get_indices 1

        update_display edge face block mesh vertex

        file_dirty
}
proc split_unstruct_volume { } {
	set mess "Please select the edges on which to split the block"
	set edges [ select_edge $mess 1000 new_format ]

	set cmd "split_unstruct_volume"
	foreach i $edges {
		mess "i = $i\n"
		append cmd " { [ lindex $i 0 ] [ lindex $i 1 ] }"
	}
	mess "cmd = $cmd\n"

	command $cmd

	get_indices 1

	update_display edge face block mesh vertex

	file_dirty
	
}
proc block_create { { type "hexa" } }  {
	global last_line all_lines
	global button_instructions

	command mesh_dimension
	set nnodes ""
	if { $type == "hexa" } {
	    if { $last_line == "2" } {
		set nnodes 4
	    } else {
		set nnodes 8
	    }
	} elseif { $type == "yblock" || $type == "degen" } {
	    if { $last_line == "2" } { 
		set nnodes 3
	    } else {
		set nnodes 6
	    }
	} elseif { $type == "unstruct" } {
	    set nnodes unlimited
	} elseif { $type == "split_unstruct" } {
		set nnodes 2
	} else {
		mess "invalid type \"$type\" in create block\n"
		return
	}
	
	set nodes [select_node  "Please select the $nnodes corner vertices \
		$button_instructions" $nnodes node_numbers]
# now select the remainder as locations	
	if { $nnodes != "unlimited" } {
	    for { set i [llength $nodes] } {  $i < $nnodes } { incr i } {
		banner "Please select remainder of the locations"
		command graphics_loc
		banner ""
		if { $last_line == "" } return
		lappend nodes $last_line
	    }
	}

	if { $type != "split_unstruct" } {
	    set fam [select_material \
		"Please select an existing volume family to\
			add the selected blocks to."]

	    if {$fam == ""} return
	}

	if { $type == "hexa" } { 
		command "create_block $fam $nodes [volume_activename_string]"
	} elseif { $type == "yblock" } {
		command "create_yblock $fam $nodes [volume_activename_string]"
	} elseif { $type == "degen" } {
		command "create_degen_block $fam $nodes \
				[volume_activename_string]"
	} elseif { $type == "unstruct" } {
		command "create_unstruct_block $fam $nodes \
				[ volume_activename_string ]"
	} elseif { $type == "split_unstruct" } {
	    command "split_unstruct_block $nodes"
	    set first_line [ lindex $all_lines 0 ]
	    if { [ string match "*two splits*" $first_line ] && \
			[ string match "error*" $last_line ] } {
		set nodes2 [select_node  \
		"Please select two more corner vertices \
			$button_instructions" $nnodes node_numbers]
	        command "split_unstruct_block $nodes $nodes2"
	    }
	} else {
		mess "invalid type \"$type\" in create block\n"
		return
	}

	get_indices 1

	update_display edge face block mesh vertex

	file_dirty
}
# ------------------------

proc block_split_face { how } {
    global last_line button_instructions display_flag
    
    
    if { $how == "corners" } {
    	set nodes [select_node "Select the corners of the face to split\
		$button_instructions" 2]
    	if {[llength $nodes] != 2} return
    	set first [lindex $nodes 0]
    	set second [lindex $nodes 1]
	set face "\{ $first \} \{ $second \}"
    } elseif { $how == "select" } {
	set mess "Please select the icon for the face to associated \
			 $button_instructions"
	set cmd "select_super_face node_numbers \
			[range_string] [family_activename_string]"
	command "$cmd"
	set nums $last_line
	set face "numbers $nums"
	if !$display_flag(face) {
		command "display_super_faces erase"
	}
	if { $nums == "" } {
		return
	}
    }
# select the split location on the edge
    set edge [select_edge "Please select the edge to split \
		$button_instructions"]
    if {$edge == ""} return
    
    set pos [lindex $edge 0]
    set dim [lindex $edge 1]
    
# select the value on the edge
    banner $button_instructions
    set cmd \
	"select_value \{$pos\} $dim [volume_activename_string] [range_string]"
    
    command $cmd 1 1
    set val [lindex $last_line 0]

    banner ""
    
    command "select_value erase" 0
    
    if {$val == ""} return
    
    command "split_face $face \{ $pos \} $dim $val\
  [volume_activename_string] "
    
    update_display edge face block mesh
    get_indices 0
    index_update_all
}

proc block_merge_face {} {
    global button_instructions

    set nodes [select_node "Select the corners of the faces to merge\
	$button_instructions" 2]

    if {[llength $nodes] != 2} return
    set first [lindex $nodes 0]
    set second [lindex $nodes 1]
    
    command "merge_face \{ $first \} \{ $second \}"
    
    update_display edge face block mesh
    get_indices 0
    index_update_all
}

proc block_extrude_faces {} {
    global extrude_matname extrude_dist extrude_curve extrude_nsub
    global button_instructions extrude_type extrude_endpt
    global extrude_facenodes extrude_twist extrude_copy_proj
    
    select_extrude_faces    
    if { ! [ info exists extrude_nsub ] || \
	     $extrude_nsub == "" } {
	set extrude_nsub 1
    }

    set buts [list [list Apply "block_extrude_faces_doit"]  [list Dismiss block_extrude_faces_done]]
    set d [form_init .extrude_faces "Extrude faces" "" $buts]
    if {$d != ""} {
	form_frame $d.fr sunken 3 {0 0}; set d $d.fr
	
	set ln 0
	form_label $d.efl "Faces" "$ln 0"
	form_entry $d.efn extrude_facenodes string "$ln 1"
	form_button $d.efb "Select" select_extrude_faces "$ln 2"
	
	incr ln
	form_label $d.regionl "Material" "$ln 0"
	futil_listentry $d.region extrude_matname \
	    "list inherited [volume_name_string]" "$ln 1" "" "" 1
	
	set extrude_type original
	incr ln
	form_label $d.typel "Extrusion Method:" "$ln 0"
	incr ln
	form_radiobutton $d.type0 "Normal to face" extrude_type original "$ln 1"
	incr ln
	form_radiobutton $d.type1 "Axial along curve" extrude_type axial "$ln 1"
	incr ln
	form_radiobutton $d.type2 "Normal along curve" extrude_type normal "$ln 1"

	set act {{extrude_type original}}
	set act1 {{extrude_type axial normal}}

	incr ln
	form_label $d.distl "Distance" "$ln 0" $act
	form_entry $d.dist extrude_dist string "$ln 1" $act
	
	incr ln
	form_label $d.curvel "Along curve" "$ln 0" $act1
	form_entry $d.curve extrude_curve string "$ln 1" $act1
	form_button $d.curves "Select"  select_extrude_curve "$ln 2" $act1

	incr ln
	form_label $d.eptl "End point" "$ln 0" $act1
	form_entry $d.epte extrude_endpt string "$ln 1" $act1
	form_button $d.eptb "Select" select_extrude_endpt "$ln 2" $act1

	set extrude_twist 0.0
	incr ln
	form_label $d.twistl "Twist angle (deg)" "$ln 0" $act1
	form_entry $d.twiste extrude_twist string "$ln 1" $act1
	
	incr ln
	form_label $d.nsubl "N Blocks" "$ln 0" $act1
	futil_updown $d.nsub extrude_nsub 1 1000 "$ln 1" $act1
	
	incr ln
	form_checkbutton $d.copyp "Copy projection" extrude_copy_proj \
	    "$ln 0 -cols 2"

	form_finish bot
    }
}

proc block_extrude_faces_doit {} {
    global extrude_matname extrude_dist extrude_curve extrude_nsub
    global extrude_type extrude_endpt extrude_facenodes extrude_twist
    global extrude_copy_proj

    set n_faces [llength $extrude_facenodes]
    if !$n_faces {
	mess "Error: No face selected for extrusion\n" red
	return
    }

    if {$extrude_matname == ""} {
	set extrude_matname inherited
    }
    
#define family if it doesn't exist
    if { $extrude_matname != "inherited" } {
	set fam_num [family_name_to_number $extrude_matname]
	if { $fam_num == "" } {
	    define_family $extrude_matname
	}
    }
    
    set cmd "extrude_faces $n_faces"
    foreach nodes $extrude_facenodes {
	set first [lindex $nodes 0]
	set second [lindex $nodes 1]
	lappend cmd " $nodes"
    }

    switch $extrude_type {
	original {
	    if {$extrude_dist == "" } {
		mess "Error: No distance specified for extrusion\n" red
		return
	    }
	    append cmd " $extrude_matname $extrude_dist"
	    append cmd " -nsub 1"
	}
	axial - normal {
	    if {$extrude_curve == ""} {
		mess "Error: No curve selected for extrusion\n" red
		return
	    }
	    if {$extrude_endpt == ""} {
		mess "Error: No End point specified for extrusion\n" red
		return
	    }

	    append cmd " $extrude_matname 1.0"
	    append cmd " -end $extrude_endpt"
	    append cmd " -curve $extrude_curve"
	    append cmd " -twist $extrude_twist"
	    append cmd " -nsub $extrude_nsub"
	    if { $extrude_copy_proj } {
		append cmd " -copy_proj"
	    }
	}
	default {
		mess " error: unhandled extrude_type $extrude_type\n" red
		return
	}
    }

    append cmd " -type $extrude_type"
    append cmd " [family_activename_string]"
    append cmd " -version 50"
    command "$cmd"
    
    update_display edge face block mesh
    get_indices 1
    index_update_all
}

proc block_extrude_faces_done {} {
    command "display_loc erase"
    form_done .extrude_faces
}

proc select_extrude_faces {} { 
    global button_instructions
    global extrude_facenodes

    set extrude_facenodes ""

    command "del erase" 0
    update_display block
    command "mark_blocks unmark"
    set extrude_facenodes [select_face 0 1 ]

    if {[llength $extrude_facenodes] == 0} return

    command "mark_blocks corners $extrude_facenodes face_neighbors"
# unmark the live side
    command "mark_blocks unmark [family_activename_string]"
    command "del -solid marked m  \
		[volume_activename_string] dead_as_faces -just_faces"
}

proc select_extrude_face {var msg} { 
    upvar \#0 $var lvar
    
    command "mark_blocks unmark"
    set nodes [select_node $msg 2 node_numbers ]
    set lvar $nodes

    set first [lindex $nodes 0]
    set second [lindex $nodes 1]
    command "mark_blocks numbers $first $second face_neighbors"
    # unmark the live side
    command "mark_blocks unmark [family_activename_string]"
    command "del -solid marked m  \
		[volume_activename_string] dead_as_faces -just_faces"
}

proc select_extrude_edge {var msg {disp_vars ""}} { 
    upvar \#0 $var lvar
    
    set nodes [select_node $msg 2 node_numbers ]   
    set lvar $nodes
    display_selected_nodes $disp_vars    
}

proc display_selected_nodes {disp_vars} {
    set nodes ""
    foreach var $disp_vars {
	upvar \#0 $var lvar
	set nodes [concat $nodes $lvar]
    }
    if {$nodes != ""} {
	command "display_nodes  [range_string] [family_activename_string] number [join $nodes] numbers"
    }
}

proc select_extrude_curve {} { 
    global extrude_curve extrude_dist
    set extrude_curve [ select_curve "select the curve for extrusion" ]
    set extrude_dist ""
}
proc select_extrude_endpt {} {
    global extrude_endpt last_line
    command graphics_loc
    set extrude_endpt $last_line
    command "display_loc loc $extrude_endpt"
}

proc block_extrude_twist {} {
    global extrude_matname extrude_curve extrude_nsub
    global button_instructions extrude_type extrude_endpt
    global extrude_face extrude_edge extrude_twist
    global display_flag

    if { ! [ info exists extrude_nsub ] || \
	     $extrude_nsub == "" } {
	set extrude_nsub 1
    }
    
    set disp_vars [list {extrude_edge(start) extrude_edge(end)}]
    set buts [list [list Apply "block_extrude_twist_doit"]  [list Dismiss block_extrude_twist_done]]
    set d [form_init .extrude_twist "Extrude face twist" "" $buts]
    if {$d != ""} {
	form_frame $d.fr sunken 3 {0 0}; set d $d.fr
	
	set ln 0
	form_label $d.efsl "Start face" "$ln 0"
	form_entry $d.efsn extrude_face(start) string "$ln 1"
	form_button $d.efsb "Select" \
	    "select_extrude_face extrude_face(start) \"Please select extrusion start face, $button_instructions\"" "$ln 2"
	
	incr ln
	form_label $d.efesl "Start Edge Vertices" "$ln 0"
	form_entry $d.efesn extrude_edge(start) string "$ln 1"
	form_button $d.efesb "Select" \
	    "select_extrude_edge extrude_edge(start) \"Please select start edge vertices, $button_instructions\" $disp_vars" "$ln 2"

	incr ln
	form_label $d.efel "End face" "$ln 0"
	form_entry $d.efen extrude_face(end) string "$ln 1"
	form_button $d.efeb "Select" \
	    "select_extrude_face extrude_face(end) \"Please select extrusion start face, $button_instructions\"" "$ln 2"
	
	incr ln
	form_label $d.efensl "End Edge Vertices" "$ln 0"
	form_entry $d.efensn extrude_edge(end) string "$ln 1"
	form_button $d.efensb "Select" \
	    "select_extrude_edge extrude_edge(end) \"Please select End edge vertices, $button_instructions\" $disp_vars" "$ln 2"

	incr ln
	form_label $d.regionl "Material" "$ln 0"
	futil_listentry $d.region extrude_matname \
	    "list [volume_name_string]" "$ln 1" "" "" 1
	
	incr ln
	form_label $d.curvel "Along curve" "$ln 0"
	form_entry $d.curve extrude_curve string "$ln 1"
	form_button $d.curves "Select"  select_extrude_curve "$ln 2"

	incr ln
	form_label $d.nsubl "N Blocks" "$ln 0"
	futil_updown $d.nsub extrude_nsub 1 1000 "$ln 1"
	
	incr ln
	form_button $d.disp "Display Selected Vertices" "display_selected_nodes  $disp_vars" "$ln 1"
	form_finish bot
    }
}

proc block_extrude_twist_doit {} {
    global extrude_matname extrude_dist extrude_curve extrude_nsub
    global extrude_type extrude_face extrude_edge extrude_twist

    set n_facestart [llength $extrude_face(start)]
    if {$n_facestart != 2} {
	mess "Error: No Start face selected for extrusion\n" red
	return
    }

    set n_faceend [llength $extrude_face(start)]
    if {$n_faceend != 2} {
	mess "Error: No End face selected for extrusion\n" red
	return
    }

    if {$extrude_matname == ""} {
	mess "Error: No material specified for extruded blocks\n" red
	return
    }
    
#define family if it doesn't exist
    set fam_num [family_name_to_number $extrude_matname]
    if { $fam_num == "" } {
	define_family $extrude_matname
    }
    
    set cmd "extrude_faces 4"
    append cmd " \{ $extrude_face(start) \}"
    append cmd " \{ $extrude_face(end) \}"
    append cmd " \{ $extrude_edge(start) \}"
    append cmd " \{ $extrude_edge(end) \}"

    set extrude_type 3
    if {$extrude_curve == ""} {
	mess "Error: No curve selected for extrusion\n" red
	return
    }
    
    append cmd " $extrude_matname 1.0"
    append cmd " -curve $extrude_curve"
    append cmd " -nsub $extrude_nsub"

    append cmd " -type $extrude_type"
    append cmd " [family_activename_string]"
    append cmd " -version 50"
    command "$cmd"
    
    update_display edge face block mesh
    get_indices 1
    index_update_all

    set disp_vars [list {extrude_edge(start) extrude_edge(end)}]
}

proc block_extrude_twist_done {} {
    global display_flag

    set display_flag(vert) 0
    command "del erase" 0
    update_display block vert
    form_done .extrude_twist
}

proc block_extrude_face {} {
    global extrude_matname extrude_dist extrude_curve
    global button_instructions extrude_nsub extrude_type extrude_endpt
    
    set nodes [select_node "Select the corners of the face to extrude\
	$button_instructions" 2 node_numbers ]
    if {[llength $nodes] != 2} return
    set first [lindex $nodes 0]
    set second [lindex $nodes 1]
    
    set d [form_init .extrude_face "Extrude face" block]
    set extrude_nsub 0
    if {$d != ""} {
	form_frame $d.fr sunken 3 {0 0}; set d $d.fr
	
	set ln 0
	form_label $d.regionl "Material" "$ln 0"
	futil_listentry $d.region extrude_matname \
	    "list [volume_name_string]" "$ln 1" "" "" 1

	set extrude_type original
	incr ln
	form_label $d.typel "Extrusion Type:" "$ln 0"
	incr ln
	form_radiobutton $d.type0 "Interpolate"	extrude_type original "$ln 1"
	incr ln
	form_radiobutton $d.type1 "Axial" extrude_type axial "$ln 1"
	incr ln
	form_radiobutton $d.type2 "Normal" extrude_type normal "$ln 1"

	set act {{extrude_type original}}
	set act1 {{extrude_type axial normal}}

	incr ln
	form_label $d.distl "Distance" "$ln 0" $act
	form_entry $d.dist extrude_dist "" "$ln 1" $act
	
	incr ln
	form_label $d.eptl "End point" "$ln 0" $act1
	form_entry $d.epte extrude_endpt string "$ln 1" $act1
	form_button $d.eptb "Select" select_extrude_endpt "$ln 2" $act1

	incr ln
	form_label $d.curvel "Along curve" "$ln 0"
	form_entry $d.curve extrude_curve string "$ln 1"
	form_button $d.curves "Select"  select_extrude_curve "$ln 2"
	
	incr ln
	form_label $d.nsubl "N Blocks" "$ln 0"
	futil_updown $d.nsub extrude_nsub 0 1000 "$ln 1"
	
	form_finish bot
    }
    if ![form_wait .extrude_face] return
    
#define family if it doesn't exist
    set fam_num [family_name_to_number $extrude_matname]
    if { $fam_num == "" } {
	define_family $extrude_matname
    }
    

    if { $extrude_dist == "" } { 
	set extrude_dist 1.0
    }
    if { $extrude_curve != "" } {
	set cmd  "extrude_faces 1 { $first $second } $extrude_matname \
		$extrude_dist -curve $extrude_curve -nsub $extrude_nsub \
		-type $extrude_type"
	if {$extrude_endpt != ""} {
	    append cmd " -end $extrude_endpt"
	}
	append cmd " [family_activename_string]"
	append cmd " -version 50"
	command "$cmd"
    } else {

    	command "extrude_face \{ $first \} \{ $second \} $extrude_matname\
  	$extrude_dist [family_activename_string]"
    }
    
    update_display edge face block mesh
    get_indices 3
    index_update_all
    command "display_loc erase"
}

proc block_wing_grid {} {
    global button_instructions

    set nodes [select_node "Select the corners of the wing, \
	trailing edge first, $button_instructions" 2]
    if {[llength $nodes] != 2} return
    set first [lindex $nodes 0]
    set second [lindex $nodes 1]
    
    set dir1 [lindex [select_edge "Select the edge from the root to the tip."] 1]
    if {$dir1 == ""} return
    set dir2 [lindex [select_edge "Select the edge from the leading to the training edge."] 1]
    if {$dir2 == ""} return
    
    command "wing_grid \{ $first \} \{ $second \} $dir1 $dir2 version 410"
    
    update_display edge face block mesh
    get_indices 0
    index_update_all
}

proc select_block { how mess } {
    global use_output_blocks display_flag last_line block_ijk_number

    set blocks ""
    switch $how {
	nums {
# select from list of numbers
		set nb [get_hexa_nsuperblocks]
		for {set i 1} {$i <= $nb} {incr i} {
			set block_ijk_number($i) 0
		}
	    
		set r [form_block_numbers \
			block_ijk_number 0 "to Modify"]
	    
		for {set i 1} {$i <= $nb} {incr i} {
		    if $block_ijk_number($i) {
			return $i
		    }
		}
		return ""
	}
	select {
# screen select
		banner $mess
		set cmd "select_blocks 1 [range_string] m \
				[volume_activename_string]"
		if $use_output_blocks { append cmd " output_blocks" }
		if $display_flag(block_ijk) { append cmd " orientation" }
		if $display_flag(block_super) { append cmd " super" }
		if $display_flag(block_solid) { append cmd " -solid" }
		command $cmd
		set blocks $last_line
		banner ""
	}
	default {
		puts "illegal value $how for how"
	}
    }
    return $blocks
}
proc block_ijk {how what} {
	global use_output_blocks display_flag last_line block_ijk_number
	global button_instructions
    
	set ob ""; if $use_output_blocks { set ob output_blocks }

	if { $how == "select" || $how == "nums" } {
		set bd $display_flag(block)
		set bijk $display_flag(block_ijk)
		set bs $display_flag(block_super)

		set display_flag(block_ijk) 1
		set display_flag(block_super) 1
		set display_flag(block) 1

		update_display block
	} 
		
	
	if { $what == "align" } {
		set mess "select the block with which to align the others"
	} else {
		set mess "select the block to modify"
	}

	while 1 {

		if { $how == "select" || $how == "nums" } {
			set block_num [ select_block $how $mess ]
			if { $block_num == "" } break
		} elseif { $how == "ijk" } {
			set nodes [select_node "Please select two vertices \
						$button_instructions" 3 ]
	    		if {[llength $nodes] < 2} break;
	    		set first [lindex $nodes 0]
	    		set second [lindex $nodes 1]
			command "mark_blocks unmark"
	    		command "mark_blocks \{ $first \} \{ $second \}"
			set block_num "marked"
		} elseif { $how == "all" } {
			command "mark_blocks"
			set block_num "marked"
		} elseif { $how == "inverted" } {
			command "mark_blocks unmark"
			command "mark_blocks inverted"
			set block_num "marked"
		} elseif { $how == "all_displayed" } {
			command "mark_blocks unmark"
			command "mark_blocks [range_string] [volume_activename_string]"
			set block_num "marked"
		} else {
			puts "illegal value $how for how in block_ijk"
			break
		}


	
		if { $what == "align" } {
			command "align_superblocks $block_num"
		} elseif { $what == "invert" } {
			command "invert_super_block $block_num $ob"
		} elseif { $what == "rotate" } {
			command "rotate_super_block $block_num $ob"
		} else {
			puts "illegal value for $what for what in block_ijk"
			break
		}
		if { $what == "align" } {
			break
		}
		update_display block
		if { $how == "all" || $how == "all_displayed" \
					 || $how == "inverted" } {
			break
		}
	}
    

	if { $how == "select" || $how == "nums" } {
		set display_flag(block) $bd
		set display_flag(block_super) $bs
		set display_flag(block_ijk) $bijk
		update_display block
	}
}
proc block_convert { to_what how } {
	global last_line button_instructions
	command mesh_dimension
	set mesh_dim $last_line
	if { $to_what == "swept" } {
		if { $mesh_dim == 2 } {
			mess \
                        "you cannot have swept blocks in a 2D mesh"
			return
		}
		while 1  {
		    set blocks ""
		    while 1 {
			set mess "select the block to modify"
			set block_num [ select_block $how $mess]
			if { $block_num == "" } break
			set edge_dir [ select_edge \
					"Please select an edge \
		in the swep direction $button_instructions" 1 "new_format"]
			if { $edge_dir == "" } break
			lappend blocks "$block_num \
                        [ lindex $edge_dir 0 ] [ lindex $edge_dir 1 ]"
		    }
		    if { $blocks == "" } break
		    command "convert_to_swept $blocks"
		}
	} else {
	  while 1 {
	    if { $to_what == "struct_face" } {
		set mess "select the face to modify"
		set faces [ select_face 1 ]
		if { $faces == "" } break

		command "convert_to_struct $faces"
	    } else {
		set mess "select the block to modify"
		set block_num [ select_block $how $mess]
		if { $block_num == "" } break
		if { $to_what == "unstruct" } {
#  mapped to unstruct
			if { $mesh_dim == 2 } {
				command "convert_to_swept $block_num"
			} else {
				command "convert_to_unstruct $block_num"
			}
		} elseif { $to_what == "struct" } {
# unstruct to struct
			command "convert_to_struct $block_num"
		} elseif { $to_what == "swept" } {
# struct to o swept
			if { $mesh_dim == 2 } {
				mess \
			"you cannot have swept blocks in a 2D mesh"
			} else {
				set edge_dir [ select_edge \
					"Please select an edge \
		in the swep direction $button_instructions" 1 "new_format"]
				if { $edge_dir == "" } return
				command "convert_to_swept $block_num \
				[ lindex $edge_dir 0 ] [ lindex $edge_dir 1 ]"
			}
		} elseif { $to_what == "yblock" } {
# degen to yblock
			command "convert_degen_to_yblock $block_num"
		} else {
			mess "can't convert to $to_what\n" red
			return
		}
	    }

	    update_display block edge
	  }
	}
}
proc block_set_origin {how} {
	global use_output_blocks display_flag last_line block_ijk_number

	set ob ""; if $use_output_blocks { set ob output_blocks }

	set bd $display_flag(block)
	set bijk $display_flag(block_ijk)
	set bs $display_flag(block_super)

	set display_flag(block_ijk) 1
	set display_flag(block_super) 1
	set display_flag(block) 1

	update_display block

	while 1 {
		set mess "select the block to modify"
		set block_num [ select_block $how $mess]
    
	
		if { $block_num == "" } break
		set mess "Select the new block origin for block $block_num"
		set nn [select_node $mess 1 node_numbers]
		if {$nn != ""} {
			command "change_origin $block_num $nn $ob"
			if { $how == "nums" } {
				update_display block
			}
		}
	}
	if { $bd == 0 || $bs == 0 || $bijk == 0 } {
# set everything back
		set display_flag(block) $bd
		set display_flag(block_super) $bs
		set display_flag(block_ijk) $bijk
		update_display block
	}
}

proc get_hexa_nsuperblocks  {} {
    global last_line use_output_blocks
    
    if { $use_output_blocks } {
	    command "max_superblock_number output_blocks"
    } else {
	    command max_superblock_number
    }
    set ndom $last_line
    if !$ndom {
	mess "Error: can't renumber blocks -- no superblocks found\n" red
	return 0
    }
    return $ndom;
}

# This proc assumes you have initialized $var to some value.  Otherwise
# tcl7.4 doesn't quite work correctly -- need to be able to do
#
# set entry_name "${var}($i)"
# set $entry_name foo
#
# which can occur in tcl7.5 and above (tcl7.6?)
# instead, we use explicit comparison of the variable to the currently
# 2 variables that are modified by this routine

proc form_block_numbers {var update message} {
    global block_number_entry block_var_name $var display_flag
    global last_line block_nums
    
    set block_number_entry ""
    set block_var_name $var
    
    set blksuper $display_flag(block_super)
    set blkdisplay $display_flag(block)

    if {!$blksuper || !$blkdisplay} {
	set display_flag(block) 1
	set display_flag(block_super) 1
	update_display edge face block mesh
    }

# Save the current state of var in case we hit cancel
    
    set firstApp 1
    foreach i [array names $var] {
	set entry_name "${var}($i)"
	set save_var($i) [set ${var}($i)]
    }
    
    set opts ""
    set firstApp 1
    set maxblocks 200
    command "list_block_numbers [volume_activename_string]"
    set block_nums [ lsort -integer  $last_line ]
    if { [ llength $block_nums ] <= $maxblocks } {
# only put the list on the form if the number of blocks <= $maxblocks
      foreach i $block_nums {
	if { [ info exists save_var($i) ] && $save_var($i) } {
	    if $firstApp {
		set firstApp 0
	    } else {
		append block_number_entry " "
	    }
	    append block_number_entry $i
	}
	lappend opts [list $i -text $i -command var_block_numbers_active]
      }
    }
    
    form_kill .block_numbers
    set d [form_init .block_numbers "Selection" "" "done cancel" "form_accept_hack .block_numbers"]
    if {$d != ""} {
	set message "Select Blocks $message"
	form_message $d.mess $message {0 0}
	$d.mess configure -width 300
	form_frame $d.check flat 0 {2 0 -cols -}
    
	form_entry $d.ent block_number_entry string {0 1}

	if { [ llength $block_nums ] <= $maxblocks } {
		form_label $d.entl "Block Numbers" {1 0}
		check_box $d.check $opts 10 $var 1 var_block_numbers_active
		bind $d.ent <Return> block_number_entry_active
	} else {
		form_message $d.entl \
		"Info: too many blocks for check list" \
		{ 1 0 -cols 2 }
	}
    
	form_finish +300+300
    }
    
# wait until selection is finished
    
    set r [form_wait .block_numbers]

# make sure to process what is on the screen
    block_number_entry_active
    
    if !$r {
	
# restore the saved state of var
	
	unset $var
	foreach i [array names save_var] {
	    set ${var}($i) $save_var($i)
	}
    }
    
    # if display needs update, do it here
	  
    if {!$blksuper || !$blkdisplay} {
	set display_flag(block) $blkdisplay
	set display_flag(block_super) $blksuper
	update_display edge face block mesh
    }
	    
    return $r
}

proc block_number_entry_active {} {
    global block_var_name block_number_entry
    global block_nums
    global $block_var_name merge_block_numbers
    
    foreach idx [ array names $block_var_name ] { 
	if [set ${block_var_name}($idx)] {
		set ${block_var_name}($idx) 0
	}
    }
    
    foreach idx $block_number_entry {
# flag the merge_block_entry as on
	    set ${block_var_name}($idx) 1
    }
}

proc var_block_numbers_active {} {
    global block_var_name block_number_entry block_nblocks
    global $block_var_name block_nums
    
    set block_number_entry ""
    foreach i $block_nums {
	if [set ${block_var_name}($i)] {
	    append block_number_entry "$i "
	}
    }
}
