# author/changes - jari.spaete@ansys.com
# misc functions

proc aie_view {type} {
    global tdv_current_viewer histogram_args plot_window tdv_key_command
    global select_in_dynamics
    
    switch $type {
	    fitWindow {tdv_scale_to_fit $tdv_current_viewer}
	    boxZoom   {
	        # work-a-round to make sure the bindings are okay
	        if {[info exists tdv_key_command(F9)] && ($tdv_key_command(F9) != "off")} {
                if {[info exist select_in_dynamics] && $select_in_dynamics} {
                   tdv_zoomin $tdv_current_viewer
                } else {
                   select_toggle_dynamics 1
                   tdv_zoomin $tdv_current_viewer
                   select_toggle_dynamics 1
                }
	        } else {
		        tdv_zoomin $tdv_current_viewer
	        }
	    }
        fitBox    {tdv_zoomout $tdv_current_viewer}
	    rotate    {
	        tdv_rotate_axis $tdv_current_viewer 0 1 0 1.57075
            # pi/2 about the Y axis
	        tdv_trans_update $tdv_current_viewer
	    }
	    top       {tdv_along_axis $tdv_current_viewer -y}
	    bottom    {tdv_along_axis $tdv_current_viewer +y}
	    right     {tdv_along_axis $tdv_current_viewer -x}
	    left      {tdv_along_axis $tdv_current_viewer +x}
	    front     {tdv_along_axis $tdv_current_viewer -z}
	    back      {tdv_along_axis $tdv_current_viewer +z}
	    iso       {tdv_isoview $tdv_current_viewer}
	    edit      {
	        if [info exists histogram_args] {unset histogram_args}
	        savedview_edit $tdv_current_viewer $plot_window
	    }
    }
}

proc aie_toggle_display_origin {} {
	global options tdv_current_viewer
	tdv_toggle_origin $tdv_current_viewer $options(display_origin)
}

proc aie_toggle_tdv_axes {} {
    global vid_options tdv_wb_axes tdv_default tdv_axes_var tdv_axes
    set w $tdv_default
    switch [ic_gui_set vid_options(tdv_axes)] {
	    0 {
	        if [info exists tdv_wb_axes($w)] {
	            set im $tdv_wb_axes($w)
	            $im delete
	            unset tdv_wb_axes($w)
            }
            if [info exists tdv_axes_var($w)] {unset tdv_axes_var($w)}
            if [info exists tdv_axes($w)] {unset tdv_axes($w)}
            tdv_wb_axes_toggle $w
	    }
	    1 {
	        tdv_wb_axes_toggle $w
	        set tdv_axes_var($w) 1
	        set tdv_axes($w) $tdv_wb_axes($w)
	    }
    }
}

proc aie_updateGeoVis {{type all} {update 1} {force 0}} {
    global geom_visible aie_geoTypeVis fam_visible batch_mode
    
    if $batch_mode return
    if ![ic_geo_is_loaded] return
    set ta [tdv_active 0]
    if {$type == "all"} {
        set types "point curve surface body density"
    } else {
        set types $type
    }
    set fams [ic_geo_list_families 0 1]
    foreach type $types {
        if [info exists aie_geoTypeVis($type)] {
            if $update {
                set geom_visible($type) [expr $aie_geoTypeVis($type) ? 1 : 0]
                foreach fam $fams {
                    if {$fam == "VORFN"} continue
		            if {([info exists fam_visible($fam)]) && ($geom_visible($type))} {
                        set vis $fam_visible($fam)
		            } else {
			            if {$type == "density"} {
			                if {$fam == "ORFN" && [info exist geom_visible($type)]} {
			                    set vis $geom_visible($type)
			                } else {
			                    if {[ic_geo_get_part $type $fam] == "" && [info exist geom_visible($type)]} {
			                        set vis $geom_visible($type)
			                    } else {
			                        set vis 0
			                    }
			                }
			            } elseif [info exist geom_visible($type)] {
			                set vis $geom_visible($type)
			            } else {
			                set vis 0
			            }
		            }
		            # Next command updates families visibility
		            ic_geo_update_visibility $type $fam $vis
		        }
	        }
	    }
	    # Next command update types visibility
	    update_geom_visible $type p 0
	    if {$type == "surface"} {
	        aie_changeSurfStyle
	    }
    }
    ::AIEnv::GUIManagement::Tree::UpdateGeoVisibility
    tdv_active $ta
}

proc aie_initGeoVis {{home ""} {turn_off ""}} {
    global fam_visible aie_geoTypeVis tdv_default
    global aie_ShowCurveAttachment aie_SurfStyle batch_mode
    
    if $batch_mode return
    set ta [tdv_active 0]
    set aie_SurfStyle(transparent) 0

    # Turn off Display for all ents other than curve, unless there are only surfaces,
    # then turn on surfaces
    foreach ent {point surface density} {
	    set aie_geoTypeVis($ent) 0
    }
    set aie_geoTypeVis(body) 2
    set aie_geoTypeVis(curve) 2

    foreach attach { show0 show1 show2 show3 } {
	    set aie_ShowCurveAttachment($attach) 1
	    ::AIEnv::GUIManagement::Tree::ShowCurveAttachment $attach
    }
    aie_updateGeoVis curve 1 1

    if ![info exists aie_SurfStyle(wire)] {
        set aie_SurfStyle(wire) 1
        set aie_SurfStyle(simpval) simple
        aie_changeSurfStyle simpval
        aie_changeSurfStyle wire
    }
   
    # Turn on points/surfaces if there are no curves
    if {[ic_geo_get_objects curve] == ""} {
	    set aie_geoTypeVis(point) 2 ;# 2 means fully on
	    aie_updateGeoVis point 1 1
	    set tmp_arr(point) 1
	    if {[ic_geo_get_objects point] == ""} {
	        set nsurfs [llength [ic_geo_get_objects surface]]
	        if {$nsurfs > 0 && $nsurfs < 1000 && $turn_off != "surface"} {
		        set aie_geoTypeVis(surface) 2
		        aie_changeSurfStyle wire
		        aie_updateGeoVis surface 1 1
		        set tmp_arr(surface) 1
	        } elseif $nsurfs {
		        if {$turn_off == "surface"} {
		            mess "Please turn on the surfaces in the Entities Tree to display the surfaces.\
                          You may want to do this only for selective parts.\n" red
		        } else {
		            mess "Warning: number of surfaces > 1000; Not displaying them by default.\n\
                          Please turn on the surfaces in the Entities Tree to display the surfaces.\n\
                          You may want to do this only for selective parts.\n" red
                }
	        }
	    }
    }

    set types ""
    if ![info exists tmp_arr(point)] { lappend types point }
    if ![info exists tmp_arr(surface)] { lappend types surface }
    lappend types body density
    aie_updateGeoVis $types
    tdv_active $ta
    if {$home != ""} {
        tdv_home $tdv_default
    }
}

proc aie_updateBlockVis {{reset 0}} {
    global batch_mode

    if $batch_mode return
    if ![ic_hex_blocking_loaded] return
    get_indices $reset
    index_update_all $reset
    hex_update_display
    # update ogrid marked blocks
    if {$::AIEnv::GUIManagement::ActiveDEZ == "splitBlkDEZ"} {
        if {(![catch {splitBlkDEZ get splitBlkVal} val]) && $val == 1} {
            set del_opts "marked m [volume_activename_string] -solid dead_as_faces"
            hex_command "display_elements $del_opts"
        }
    }
}

proc aie_update_visible {{turn_off_cut 1}} {
    global fam_visible

    # Keep clean fam_visible array - Fix
    foreach f [array names fam_visible] {
	    if {$f == "VORFN"} continue
	    if {(![ic_geo_check_family $f]) && (![ic_uns_check_family $f])} {
	        unset fam_visible($f)
	    }
    }
    set types ""
    foreach "type type2" "Point point Curve curve Surf surface Body body Density density" {
        if [::AIEnv::GUIManagement::Tree::NodeVisibility geom${type}Node] {
            lappend types $type2
        }
    }
    aie_updateGeoVis $types
    aie_updateMeshVis
    if $turn_off_cut { aie_cutplane_clear 0 }
    aie_updateBlockVis
}

proc aie_disp_toggle_solid {} {
    global aie_SurfStyle aie_meshStyle

    if $aie_SurfStyle(solid) {
	    set aie_SurfStyle(wire) 1
	    aie_changeSurfStyle wire
    } else {
	    set aie_SurfStyle(solid) 1
	    aie_changeSurfStyle solid
    }
    if $aie_meshStyle(Solid) {
	    set aie_meshStyle(Wire) 1
	    aie_changeMeshDisplay style Wire
    } else {
	    set aie_meshStyle(Solid) 1
	    aie_changeMeshDisplay style Solid
    }
}

proc aie_changeSurfStyle {{style ""}} {
    global aie_SurfStyle str_option

    switch $style {
        simpval {
	        set str_option(surface,dtype) $aie_SurfStyle(simpval)
	    }
	    wire - flat_wire - solid - flat {
	        if $aie_SurfStyle($style) {
	            set str_option(surface,stype) $style
	            set str_option(surface,grey_scale) 0
	            foreach n {wire - solid - flat - flat_wire - grey_scale} {
	                if {$n != $style} {set aie_SurfStyle($n) 0}
	            }
	        }
	    }
	    grey_scale {
	        set str_option(surface,grey_scale) $aie_SurfStyle(grey_scale)
	        if $aie_SurfStyle($style) {
	            set str_option(surface,stype) solid
	            foreach n {wire - solid - flat - flat_wire} {
	                set aie_SurfStyle($n) 0
	            }
	        }
	    }
    }

    switch $style {
	    wire {
	        if {!$aie_SurfStyle(wire) && !($aie_SurfStyle(solid) && \
                $aie_SurfStyle(flat_wire) && $aie_SurfStyle(grey_scale))} {
		        set aie_SurfStyle(wire) 1
	        }
	    }
	    solid - flat {
            if {!$aie_SurfStyle($style) && !($aie_SurfStyle(wire) && \
                $aie_SurfStyle(flat_wire) && $aie_SurfStyle(grey_scale))} {
                set aie_SurfStyle($style) 1
            }
	    }
	    flat_wire {
	        if {!$aie_SurfStyle(flat_wire) && !($aie_SurfStyle(solid) && \
	            $aie_SurfStyle(wire) && $aie_SurfStyle(grey_scale))} {
		        set aie_SurfStyle(flat_wire) 1
	        }
	    }
	    grey_scale {
	        if {!$aie_SurfStyle(grey_scale) && !($aie_SurfStyle(solid) && \
                !$aie_SurfStyle(wire) && !$aie_SurfStyle(flat_wire))} {
		        set aie_SurfStyle(flat_wire) 1
	        }
	    }
    }
    set str_option(surface,transparent) $aie_SurfStyle(transparent)

    # maybe there is some geometry selected
    set selected [ic_get_geo_selected]
    if {$selected != ""} {
        ic_reset_geo_selected
    }
    update_geom_visible surface p
    if {$selected != ""} {
        ic_set_geo_selected $selected 1
    }
    if [info exists str_option(surface,dtype)] {
        set aie_SurfStyle(simpval) $str_option(surface,dtype)
    } else {
        set aie_SurfStyle(simpval) $aie_SurfStyle(simpval)
    }
}

proc aie_change_body_style {} {
    global aie_bodyStyle str_option
    
    if $aie_bodyStyle(detailed) {
        set str_option(body,dtype) detailed
    } else {
        set str_option(body,dtype) simple
    }
    update_geom_visible body p
}

proc aie_change_grey_scale {} {
    global aie_SurfStyle str_option

    set str_option(surface,grey_scale) $aie_SurfStyle(grey_scale)
    update_geom_visible surface p
}

proc unused__aie_show_params {what type} {
    global str_option aie_surfaceParams
    global aie_curveParams

    if [set aie_${what}Params($type)] {
	foreach name {tetra hexa} {
	    set aie_${what}Params($name) 0
	}
	set aie_${what}Params($type) 1
    }

    if [set aie_${what}Params(tetra)] {
	set str_option($what,sizes) tetra
    } elseif [set aie_${what}Params(hexa)] {
	set str_option($what,sizes) hexa
    } else {
	set str_option($what,sizes) none
    }
	update_geom_visible $what p
}

proc domain_newest_file {} {
    global file_name
    set nf ""; set nt 0
    foreach f [glob -nocomplain $file_name(domains_dir)/*.uns $file_name(domains_dir)/*.\[0-9\]*] {
	set t [file mtime $f]
	if {$t > $nt} {
	    set nt $t
	    set nf [file tail $f]
	}
    }
    return [list $nf $nt]
}

proc aie_listElementTypes {{type all}} {
    if {$type == "all"} {
	    set types {node line shell volume}
    } else {
	    set types $type
    }
    set etypes ""
    foreach et [ic_uns_list_types] {
	    switch $type {
	        node {
		        if {[regexp NODE+ $et]} {
		            lappend etypes $et
		        }
	        }
	        line {
		        if {([regexp LINE_+ $et]) || \
			        ([regexp BAR_+ $et])} {
		            lappend etypes $et
		        }
	        }
	        shell {
		        if {([regexp TRI_+ $et]) || \
			        ([regexp QUAD_+ $et])} {
		            lappend etypes $et
		        }
	        }
	        volume {
		        if {([regexp TETRA_+ $et]) || \
			        ([regexp HEXA_+ $et]) || \
			        ([regexp PYRA_+ $et]) || \
			        ([regexp PENTA_+ $et])} {
		            lappend etypes $et
		        }
	        }
	        default {
		        if [regexp [string toupper $type]_+ $et] {
		            lappend etypes $et
		        }
	        }
	    }
    }
    return $etypes
}

proc aie_element_type {uns_type} {
    if {[regexp NODE+ $uns_type]} {
	    return node
    }
    if {([regexp LINE_+ $uns_type]) || \
	    ([regexp BAR_+ $uns_type])} {
	    return line
    }
    if {([regexp TRI_+ $uns_type]) || \
	    ([regexp QUAD_+ $uns_type])} {
	    return shell
    }
    if {([regexp TETRA_+ $uns_type]) || \
	    ([regexp HEXA_+ $uns_type]) || \
	    ([regexp PYRA_+ $uns_type]) || \
	    ([regexp PENTA_+ $uns_type])} {
	    return volume
    }

    return NONE
}

proc aie_updateMeshCouplingsVis {} {
    global aie_meshNodes

    set nodes "meshTriNode meshQuadNode meshTetraNode meshHexaNode meshPyraNode meshPentaNode"
    set types "TRI QUAD TETRA HEXA PYRA PENTA"
    set i 0; set visible ""; set not_visible ""
    foreach type $types {
        set vis [::AIEnv::GUIManagement::Tree::NodeVisibility [lindex $nodes $i]]
        if {[lsearch -regexp [ic_uns_list_types] ${type}_+] >= 0} {
            if $vis {
                lappend visible $type
            } else {
                lappend not_visible $type
            }
        }
        incr i
    }
    if ![info exists aie_meshNodes(Displayed)] {
        set aie_meshNodes(Displayed) $visible
    }
    set ret 0
    foreach n $aie_meshNodes(Displayed) {
        if {([lsearch $not_visible $n] <= 0) || ([lsearch $visible $n] <= 0)} {
            set ret 1
        }
    }
    foreach n $visible {
        if {[lsearch $aie_meshNodes(Displayed) $n] < 0} {
            append aie_meshNodes(Displayed) " $n"
        }
    }
    return $ret
}

proc aie_updateMeshVis {{type all} {update 1}} {
    global aie_meshTypeVis fam_visible last_fvals last_tvals
    global batch_mode aie_shellDiagnosticDisplay 
    
    if $batch_mode return
    set ta [tdv_active 0]
    if [ic_uns_is_loaded] {
        if {$type == "all"} {
            set types {node line tri quad hexa tetra penta pyra}
        } else {
            set types $type
        }
        if $update {
            set fvals ""
            foreach f [array names fam_visible] {
                if $fam_visible($f) {
                    lappend fvals $f
                    # if there are subsets make sure we get the bits that belong with them also
                    if [string match SS* $f] {
                        foreach f2 [array names fam_visible] {
                            if {!$fam_visible($f2) && [string match *:$f:* :$f2:]} {
                                lappend fvals $f2
                            }
                        }
                    }
                }
            }
            if {[info exists aie_shellDiagnosticDisplay(show_only_subsets)] && $aie_shellDiagnosticDisplay(show_only_subsets) != ""} {
                ic_uns_update_family_type visible $fvals $aie_shellDiagnosticDisplay(set) update 0
            } else {	    
                set tvals ""
                foreach type $types {
                    if {[info exists aie_meshTypeVis($type)]} {
                        foreach tt [aie_listElementTypes $type] {
                            if $aie_meshTypeVis($type) {
                                if ![aie_warn_too_many_volume_elements $tt $fvals] {
                                    lappend tvals $tt
                                } else {
                                    set aie_meshTypeVis($type) 0
                                    lappend tvals !$tt
                                }
                            } else {
                                lappend tvals !$tt
                            }
                        }
                    }	           
                }
		        if {[ic_uns_subset_get_current] != "Selected"} { ic_uns_subset_set_current Selected }
		        if {(![info exists last_fvals] || $last_fvals != $fvals) || (![info exists last_tvals] || $last_tvals != $tvals)} {
		            ic_uns_update_family_type visible $fvals $tvals update 0
		        }
		        set last_fvals $fvals
		        set last_tvals $tvals
		    }
        }
        ::AIEnv::GUIManagement::Tree::UpdateUnsMeshVisibility $types
        aie_changeMeshDisplay
        #aie_update_icons mesh
        if {![info exists aie_shellDiagnosticDisplay(running)] && $update} {
            shellDiagnosticsDEZ aie_updateShellDiagnostics
        }
    } elseif [ic_str_is_loaded] {
        global aie_sharedStrDisplay
        update_str_visible
        ::AIEnv::GUIManagement::Tree::UpdateStrMeshVisibility
        if $aie_sharedStrDisplay(shared) {
            aie_changeStrSharedDisplay shared
	    } elseif $aie_sharedStrDisplay(unshared) {
	        aie_changeStrSharedDisplay unshared
	    }
    }
    tdv_active $ta
}

proc aie_changeMeshDisplay {{option ""} {value ""} {force 0}} {
    global aie_meshStyle aie_meshDisplay aie_meshNodes aie_meshShrink
    global disp_options options batch_mode tdv_current_viewer histo_crit
    global quality_metric_created histo_crit mesh_subset_shading

    if $batch_mode return
    set shading_types {Wire Solid Solid/wire "Hidden line" "By dimension" color_by_quality}
    switch $option {
        cutplane {
            global cut_info
            if {$value == ""} {set value $cut_info(active)}
            if {$value} { cutPlaneDEZ show }
            set cut_info(active) $value
            update idletasks
            if {[info command cutPlaneDEZ] != ""} {
               set wn [cutPlaneDEZ path cutPlaneOn]
               if [winfo exist $wn] { CheckFrame::actframe $wn }
            }
            aie_cutplane_set active
        }
        style {
	        if {$value != "color_by_quality"} {
	            set disp_options(backup) $value
	            set aie_meshDisplay(normals_colored) 0
	        } else {
	            if [info exists disp_options(backup)] {
	                if {$disp_options(uns_color_by_quality) && !$force} {
	                    set value $disp_options(backup)
	                }
	            }
	        }
	        foreach val $shading_types {
                if {$val != $value} {
                    set aie_meshStyle($val) 0
                }
	        }
	        set aie_meshStyle($value) 1 
	        if {$value == "color_by_quality"} {
		        set disp_options(uns_color_by_quality) 1
		        set disp_options(uns_disp) "Solid/wire"
		        if {[ic_uns_is_loaded] && (![info exists quality_metric_created])} {
		            # since user seems to want info...create some
		            if ![info exists histo_crit] {
		                ic_uns_metric visible "Quality"
		                set histo_crit "Quality"
		            } else {
		                ic_uns_metric visible $histo_crit
		            }
		            aie_create_colorband
		            set quality_metric_created $histo_crit
		        } else {
		            if [ic_uns_is_loaded] {
		                aie_create_colorband
		            }
		        }
	        } else {
                set disp_options(uns_disp) $value
                set disp_options(uns_color_by_quality) 0
                if ![winfo exists $tdv_current_viewer.colorband] {
                    aie_delete_colorband 1
                } else {
                    global plot_window
                    if {![info exists plot_window] || ![winfo exists $plot_window.graph]} {
                        aie_delete_colorband 0
                    }
                }
	        }
	    }
	    shrink {
            foreach val {100 90 50} {
                if {$val != $value} {
                    set aie_meshShrink($val) 0
                }
            }
            set disp_options(uns_shrink) $value
        }
        nodes {
            if {$value == ""} {
                set value $disp_options(uns_node_type)
                if {$value == "Ext"} { set value Nums }
            }
            if {$value == "Nums"} {
                if $options(external_num) {
                    mess "Displaying external node numbers\n" blue
	            } else {
	                mess "Displaying internal node numbers\n" blue
	            }
	        }
	        foreach val {None Dots Nums Coords Indices Indices_Triad Couplings} {
		        if {$val != $value} {
		            set aie_meshNodes($val) 0
		        }
	        }
	        set aie_meshNodes($value) 1
	        if {$value == "Nums" && $options(external_num)} {
		        set value Ext
	        }
	        if {$value == "Indices_Triad" || $value == "Indices"} {
		        if {$value == "Indices_Triad"} {
		            set disp_options(uns_node_type) "Indices"
		            set disp_options(uns_displ_orient) "Triad"
		        } else {
		            set disp_options(uns_node_type) $value
		            set disp_options(uns_displ_orient) "Number"
		        }
	        } else {
		        set disp_options(uns_node_type) $value
	        }
	    }
	    bcfield {
	        set disp_options(uns_bcfield) $aie_meshDisplay(bcfield)
	        if $aie_meshDisplay(bcfield) {
		        set ch [choose_one "Select the distributed value to view" [ic_uns_bcfield_list] $disp_options(uns_bcfield_name)]
		        if {$ch != ""} {
                    set disp_options(uns_bcfield_name) $ch
                }
            }
        }
	    default {
	        foreach t {shrink_npos only_edges single_surfaces midside_nodes
		        multiple_surfaces normals normals_colored icons enums thickness
		        directions orientation wide_lines couplings bcfield no_inner
		        vol_bounds surf_bounds periodicity locked_elements dualmesh} {
		        if ![info exists aie_meshDisplay($t)] {
		            set aie_meshDisplay($t) 0
		        }
		        set disp_options(uns_$t) $aie_meshDisplay($t)
	        }
	        if $aie_meshDisplay(enums) {
		        set disp_options(uns_enums) [expr 1 + $options(external_num)]
	        } else {
		        set disp_options(uns_enums) 0
	        }
            if {[info exists aie_meshDisplay(couplings)] && $aie_meshDisplay(couplings) && [ic_uns_num_couplings]} {
                if {$aie_meshNodes(None) && [aie_updateMeshCouplingsVis]} {
                    set aie_meshNodes(None) 0
                    set aie_meshNodes(Couplings) 1
                    update_uns_map_node_opts ""
                }
            }
	        # color_by_quality enables "Solid/wire" and returns to norm when switched off
	        if $aie_meshDisplay(normals_colored) {
		        set aie_meshDisplay(normals) 1
		        set disp_options(uns_normals) 1
		        if {$aie_meshStyle(Solid) != 1 && $aie_meshStyle(Solid/wire) != 1} {
		            foreach val $shading_types { set aie_meshStyle($val) 0 }
		            set aie_meshStyle(Solid) 1
		            set disp_options(uns_disp) Solid
		        }
	        }
	        set disp_options(uns_bcfield_name) ""
	    }
    }
    if [ic_uns_is_loaded] {
        update_uns_disp
        aie_updateShellDiagnostics
        if {[info exists mesh_subset_shading] && $mesh_subset_shading != "Inherited"} {
            aie_subset_mesh_shading
        }
    }
}

proc aie_warn_too_many_volume_elements {type parts} {
    global options batch_mode draw_too_many_last_count

    if $batch_mode { return 0 }
    if {[aie_element_type $type] != "volume"} { return 0 }
    set total [ic_count_elements $type]
    if {![string is integer -strict $options(uns_warn_user_if_display)] || (!$options(uns_warn_user_if_display) || \
        $total <= $options(uns_warn_user_if_display))} { return 0 }    
    if {[info exists draw_too_many_last_count] && ($total <= $draw_too_many_last_count)} { return 0 }

    set too_many 0
    set sub [ic_uns_subset_create]
    ic_uns_subset_add_families_and_types $sub $parts $type
    set total [ic_uns_subset_count_elements $sub $type]
    ic_uns_subset_delete $sub
    if {[info exists draw_too_many_last_count] && ($total <= $draw_too_many_last_count)} { return 0 }
    set ta [tdv_active 0]
    if {$total > $options(uns_warn_user_if_display)} {
	    if ![tk_dialog .toomany_elements "Too many elements" "You have just turned on $total elements.\n\
	        Do you really want to draw that many on the screen?" "" -1 "Don't display" "Display"] {
	        set too_many 1
	        mess "Turned off the $type elements\n" red
	    } else {
            set draw_too_many_last_count $total
        }
        if [winfo exists .toomany_elements] { destroy .toomany_elements }
    }
    tdv_active $ta
    return $too_many
}

proc aie_histo_warn_too_many_elements {} {
    global batch_mode histo_too_many_last_count

    if $batch_mode { return 0 }
    set total [ic_count_elements]
    if ![info exists histo_too_many_last_count] { set histo_too_many_last_count 10000000 }
    if {$total <= $histo_too_many_last_count} { return 0 }
    
    set too_many 0
    set ta [tdv_active 0]
    if {$total > $histo_too_many_last_count} {
	    if ![tk_dialog .toomany_elements "Many elements" "Histogram contains $total elements.\nDo you want to create the histogram?" "" -1 "Don't create" "Create"] {
	        set too_many 1
	    } else {
            set histo_too_many_last_count $total
        }
        if [winfo exists .toomany_elements] { destroy .toomany_elements }
    }
    tdv_active $ta
    return $too_many
}

proc aie_set_color_by_quality_contrast {} {
    global tdv_lighting_backup tdv_lighting aie_meshStyle
    
    if {[info exists aie_meshStyle(incr_contrast)] && $aie_meshStyle(incr_contrast) && $aie_meshStyle(color_by_quality)} {
        if [info exists tdv_lighting(specular)] {
            if ![info exists tdv_lighting_backup(specular)] {
                set tdv_lighting_backup(specular) $tdv_lighting(specular)
            }
            set tdv_lighting(specular) 0.75
            aie_set_lighting specular ""
        }
    } else {
        if [info exists tdv_lighting_backup(specular)] {
            set tdv_lighting(specular) $tdv_lighting_backup(specular)
            aie_set_lighting specular ""
        }
    }
}

proc aie_getBatchMeshDisplay {all_updates} {
    global aie_meshDisplay
    if ![ic_uns_is_loaded] return

    set known_params {
    -shrink_npos shrink_npos
	-only_edges only_edges
	-single_surfaces single_surfaces
	-draw_midside_nodes midside_nodes
	-draw_directions directions
	-multiple_surfaces multiple_surfaces
	-draw_normals normals
	-draw_normals_colored normals_colored
	-draw_icons icons
	-draw_enums enums
	-draw_thickness thickness
	-draw_orientation orientation
	-draw_vol_bounds vol_bounds
	-draw_surf_bounds surf_bounds
	-shade shade
	-color_by_quality color_by_quality
	-draw_bcfield bcfield_name
    -show_dualmesh dualmesh
    }
    foreach {cname tname} $known_params {
        if ![catch {ic_uns_subset_configure_get visible $cname} param_val] {
            if {$param_val != ""} { set aie_meshDisplay($tname) $param_val }
        }
    }
    if ![catch {ic_uns_subset_configure_get visible -width} param_val] {
        set aie_meshDisplay(wide_lines) [expr $param_val > 1]
    }

    if $all_updates {
        aie_initialize_tree_props_and_icons
        aie_load_lcs
        aie_clear_dez
    }
    aie_changeMeshDisplay
    aie_changeMeshDisplay color_by_quality 1
}

proc aie_changeStrSharedDisplay {what} {
    global aie_sharedStrDisplay
    
	if {$what == "shared"} {
	    if $aie_sharedStrDisplay(shared) {
            disp_set_visible subface s
            set aie_sharedStrDisplay(unshared) 0
        } else {
            update_str_visible
        }
    } elseif {$what == "unshared"} {
        if $aie_sharedStrDisplay(unshared) {
            disp_set_visible subface u
            set aie_sharedStrDisplay(shared) 0
        } else {
            update_str_visible
        }
    }
} 

proc aie_getBatchGeomDisplay {} {
    foreach name [ic_geo_subset_list] {
        ::AIEnv::GUIManagement::Tree::AddGroup geom_subset $name 0
        ::AIEnv::GUIManagement::Tree::ToggleGroupVisibility geom_subset $name same
    }
    aie_updateGeoVis
}

proc aie_viewInfo {type} {
    global options units_message

    switch $type {
        geometry {
	        if [ic_geo_is_loaded] {
	            mess "\n--- Geometry Info ---\n"
                set units [ic_geo_get_units 1]
                if {$units != ""} {
                    mess "Units are $units\n"
                    set units_message "Units: $units "
                } else {
                    set units_message ""
                }
		        foreach {type name} {surface surfaces curve curves point "prescribed points" body bodies density densities} {
		            set n [llength [ic_geo_get_objects $type]]
		            if $n { mess "$n $name\n" }
		        }
		        set solids [ic_geo_count_solids_without_material]
		        if $solids {
		            mess "$solids solids\n"
		        }
		        set parts [aie_list_parts 0]
		        set np [llength $parts]
		        if $np {
		            mess "$np parts\n"
		            mess "Element parts :\n"
		            set i 0
		            foreach p [lsort $parts] {
		                set npart [ic_geo_count_in_family all $p]
		                if {$npart == 0} {
		                    if [ic_geo_family_is_empty_except_dormant $p] {
		                        mess "        $p : [llength [ic_geo_get_objects all $p 1]] (all dormant)\n"
		                    }
		                }
		                if {$npart > 0} {
		                    set components [ic_geo_list_families_in_part $p]
		                    if {[llength $components] > 1} {
                                mess "        $p : $npart (contains [expr [llength $components] - 1] hidden component part(s))\n"
		                    } else {
		                        mess "        $p : $npart\n"
		                    }
		                } else {
		                    set components [ic_geo_list_families_in_part $p]
		                    set len [llength $components]
		                    set npart 0
		                    foreach cp $components {
		                        if {$cp == "$p"} { incr len -1 }
		                        set part [ic_geo_count_in_family all $cp]
                                if {$part == 0} continue
		                        incr npart [expr $part + $npart]
		                    }
		                    if $npart {
		                        mess "        $p : $npart (contains $len hidden component part(s))\n"
		                    }
		                }
		                incr i
		                if {[expr $i % 50] == 0} update
		            }
		        }
	        } else {
		        mess "No Geometry Database\n" red
	        }
	    }
	    curve_length {
	        if ![ic_geo_is_loaded] {
	            mess "No Geometry Database\n" red
	            return
	        }
	        set c [geo_select curve]
	        set tot 0
	        foreach curve $c {
	            set len [ic_geo_crv_length $curve]
		        foreach "cent xdir norm rad sa ea" [aie_get_arc_data $curve] ""
		        # Print Radius if ea - sa > 5 degree; 5 digits enough for info
		        if [info exists rad] {
		            set rad [va_round $rad 5]
		            if {[expr $sa+5] < $ea} {
		                mess "Curve $curve Length=$len Radius=$rad Center=$cent\n"
		            } else {
		                mess "Curve $curve length is $len\n"
		            }
                    unset rad
		        } else {
		            mess "Curve $curve length is $len\n"
		        }
		        set tot [expr $tot + $len]
            }
            if {[llength $c] > 1} { mess "Total length of curves is $tot\n" }
	    }
	    curve_direction {
	        if ![ic_geo_is_loaded] {
	            mess "No Geometry Database\n" red
	            return
	        }
	        aie_show_curve_direction
	    }
	    surface_area {
	        if [ic_geo_is_loaded] {
		        set c [geo_select surface]
		        set tot 0
		        foreach surface $c {
		            set len [ic_geo_srf_area $surface]
		            mess "surface $surface is $len \n"
		            set tot [expr $tot + $len]
		        }
		        if {[llength $c] > 1} {mess "Total area of surfaces is $tot\n"}
	        } else {
		        mess "No Geometry Database\n" red
	        }
	    }
	    mesh {
	        if [ic_uns_is_loaded] {
		        set ret [ic_uns_print_info summary "" $options(detail_info)]
		        if {$ret != ""} {
		            for {set i 0} {$i < 2} {incr i} {
			            set nms [lindex $ret $i]
			            if {$nms != ""} {
			                ::AIEnv::GUIManagement::Tree::AddGroup mesh_subset $nms 1
			            }
		            }
		        }
	        } elseif {[ic_str_is_loaded]} {
	            mess "\n--- Mesh Info ---\n"
                ic_str_summary
            } else {
		        mess "No Mesh Database\n" red
	        }
	    }
	    area_volume {
	        if [ic_uns_is_loaded] {
	            ic_uns_subset_types_metric Volume/Area/Length 2 2d
                ic_uns_subset_types_metric Volume 2
            } else {
		        mess "No Mesh Database\n" red
	        }      
	    }
        element - node {
	        if [ic_uns_is_loaded] {
		        set from_names __all_visible__
		        set sel_map [select_unstruct $type 0 $from_names 1]
		        if {$sel_map != ""} {
		            ic_uns_print_info $type $sel_map
		            if {[ic_uns_thickness_exists_mesh]} {
			            if {$type == "element"} {
			                set vallist [ic_uns_get_thickness $sel_map]
			            } elseif {$type == "node"} {
			                set vallist [ic_uns_get_thickness_node $sel_map]
			            }
			            foreach val $vallist {
			                set th [format "Thickness at $type %6d :" [lindex $val 0]]
			                foreach t [lrange $val 1 end] {
				                append th " [format %e $t]"
			                }
			                mess $th\n
			            }
		            }
		            # quality info
		            if {$type == "element"} {
		                mess "********** Mesh Quality **********\n" blue
		                foreach qual $options(quality_info) {
			                ic_uns_metric $sel_map $qual
		                }
		            }
		        }
		        ic_uns_subset_delete $sel_map
	        } else {
		        mess "No Mesh Database\n" red
	        }
	    }
	    node {
	        if [ic_uns_is_loaded] {
		        unstruct_print_info node
	        } else {
	    	    mess "No Mesh Database\n" red
	        }
	    }
    }
    aie_reset_geo_selected
}

proc aie_show_curve_direction {} {
    global select_action tdv_default tdv_mouse_bindings
    foreach s {select done cancel} {
        set b_$s [lindex {"" left middle right} $tdv_mouse_bindings($s)]
    }
    banner "Select curve with the $b_select button; $b_done = done, \
            $b_cancel = unselect."
    set select_action done
	va_create_xyz curve 100 0 direction
    banner ""
}

proc aie_test_histogram {} {
    global smooth

    set title "AIEnv Test Histogram"
    set xvals "0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16"
    set yvals "10 20 30 20 10 17 35 0  12 18 35 16 14 24 19 43"
    set ylimit 40
    set labels [list "First label" "Second label"]
    set nylines 4
    set nlabel 3
    set replot_com ""
    set highlight_com ""
    set replot_args ""
    set extra_buts ""

    # aie_make_histogram $title $xvals $yvals $ylimit $labels
    set smooth(criterion) Quality
    aie_smooth_update_histogram
}

proc aie_clear_plot_window {} {
    global plot_window
    
    set w $plot_window
    if ![winfo exists $w] return
    set ch [winfo children $w]
    if {$ch == ""} return
    pack propagate $w 0
    $w configure -width [winfo width $w] -height [winfo height $w]
    foreach ww $ch {
        destroy $ww
    }
}

proc aie_make_histogram {title xvals yvals {ylimit 0} {labels ""} {args ""}} {
    global plot_window histo_width histo_height
    global histogram_args histo_bad_elements options disp_options
    global histo_solid histo_show histo_color_by_quality colorBand

    if {$ylimit < 0} {
        msg ERROR "Error: y-height must be > 0, resetting to default"
        set ylimit 0
    }

    set histo_width [winfo width $plot_window]
    set histo_height [expr [winfo height $plot_window] - 25]

    if {$ylimit == 0} {
	set ylimit [expr 4 * [lindex $yvals 0]]
	if {$ylimit < 20} {
	    set ylimit 20
	}
    }
    set histogram_args [list $title $xvals $yvals $ylimit $labels]
    foreach arg $args {
        lappend histogram_args $arg
    }

    set histo_show 1
    if [info exists options(histo_show_default)] {
        set histo_show $options(histo_show_default)
    }
    set histo_solid 1
    if [info exists options(histo_solid_default)] {
        set histo_solid $options(histo_solid_default)
    }
    set histo_color_by_quality 1
    if [info exists options(histo_color_by_quality_default)] {
        set histo_color_by_quality $options(histo_color_by_quality_default)
    }
 
    if [aie_disable_colorband] { catch { unset colorBand } }
    if ![info exists histo_bad_elements] { set histo_bad_elements "bad" }
    if $disp_options(uns_color_by_quality) {
        if [ic_uns_is_loaded] {
            aie_updateMeshVis
        }
    }
    
    eval make_histogram $plot_window $histogram_args
    bind $plot_window <Configure> aie_redraw_histogram
}

proc aie_redraw_histogram {} {
    global histogram_args plot_window
    global histo_status histo_status_prev
    global histo_ids smooth colorBand

    if [aie_disable_colorband] {
       catch { unset colorBand }
    }

    if ![info exists histogram_args] return
    set args $histogram_args
    array set tstatus [array get histo_status_prev]
    if [info exists colorBand(actual_min)] {
        set restore_color_band 0
    } else {
        set restore_color_band 1
    }
    aie_delete_histogram $restore_color_band
    eval aie_make_histogram $args
    if [info exists colorBand(actual_min)] {
        aie_create_colorband $colorBand(actual_min) $colorBand(actual_max) $colorBand(xvals) $colorBand(color_by_quality)
    }	
	foreach n [array names histo_status] {
	    if [info exists colorBand($n)] {
	        set fillcolor $colorBand($n) 
	    } else {
	        set fillcolor pink
	    }
	    if [info exists tstatus($n)] {
            set id $histo_ids($n)
            if $tstatus($n) {
                if {$fillcolor != "pink"} {
                    $plot_window.graph itemconfigure $id -fill $fillcolor -outline red
                } else {
                    $plot_window.graph itemconfigure $id -fill $fillcolor
                }
                set histo_status($n) 1
            } else {
                if {$fillcolor != "pink"} {
                    $plot_window.graph itemconfigure $id -fill black -outline $fillcolor
                } else {
                    $plot_window.graph itemconfigure $id -fill green
                }
                set histo_status($n) 0
            }
	    }
    }
}

proc aie_delete_histogram {{delete 0}} {
    global histogram_args plot_window histo_status 
    global histo_minv histo_maxv histo_status_prev
    global hexa_histogram_exist disp_options colorBand
    
    if [info exists histogram_args] {
        unset histogram_args
    }
    if {([info exists hexa_histogram_exist]) && ([ic_hex_blocking_loaded])} {
        aie_hex_clear_histogram 0
    }
    catch { unset histo_status_prev }
    array set histo_status_prev [array get histo_status]
    aie_histo_delete_bad_elements
    aie_clear_plot_window
    ic_uns_diag_reset_degen_min_max
    status_message ""
    if !$disp_options(uns_color_by_quality) {
        aie_delete_colorband $delete 
        if $delete {
            set histo_minv ""
            set histo_maxv "" 
        }
    }
    if {[aie_active_dez] == "qualityMetricsDEZ"} {
        ::AIEnv::GUIManagement::ToggleGrey smoothRefreshQHisto 1
    }
    if {[aie_active_dez] == "smoothDEZ"} {
        ::AIEnv::GUIManagement::ToggleGrey smoothRefreshHisto 1
    }
}

# Diagnostic update histogram is combined with smooth
# FIXME - diag map and global names
proc aie_smooth_update_histogram {{title "Element quality"} {nbars ""} \
			       {min ""} {max ""} {ylim ""} {args ""}} {
    global smooth histo_width histo_height smooth_allmap
    global histo_minv histo_maxv histo_minv_limit histo_maxv_limit
    global histo_solid histo_color_by_quality histo_nbars histo_ylim
    global histo_color_by_quality prev_qual_criterion colorBand
    global histo_replot_changed histo_crit histo_colorband 

    if ![info exists prev_qual_criterion] {  set prev_qual_criterion \"$title\" }
    if {$smooth(criterion) == "Qualitygls"} { set smooth(criterion) Quality }
    
    set smooth(use_post) 0
    set smooth(sel_what) all
    set smooth(prism_warp_weight) 0.5
    set smooth(criterion) \"$title\"
    set histo_crit $title
    set what $smooth(histogram)

    if [ic_uns_subset_exists smooth_show_map] {
        ic_uns_subset_delete smooth_show_map
    }
    
    aie_delete_histogram

    if {$smooth(criterion) != $prev_qual_criterion} {
        set histo_minv ""
        set histo_maxv ""
    }
    set prev_qual_criterion $smooth(criterion)
    
    if {$nbars == ""} {
        if [info exists histo_nbars] {
            set nbars $histo_nbars
        } else {
	        set nbars 20
	        set histo_nbars $nbars
        }
    }

    if {$ylim == ""} {
        if [info exists histo_ylim] {
            set ylim $histo_ylim
        } else {
            set ylim 0
            set histo_ylim $ylim
        }
    }

    if {($nbars < 1) || ($nbars > 500)} {
        mess "Num. bars not in valid range {1,500}; resetting the histogram values to defaults\n" red
        set histo_nbars 20; set nbars 20
    }

    set xvals ""
    set yvals ""
    set ymax 0
    busy 1
    
    set cmd "ic_uns_metric smooth_do_map $smooth(criterion)"
    if {$what == "smooth"} {
        append cmd " prism_warp_weight $smooth(prism_warp_weight)"	
    }
    if {[info exists smooth(eval)]} {
        append cmd " eval_at_node_method $smooth(eval)"
    }
    set ret [eval $cmd]

    set smooth(actual_min) [lindex $ret 3]
    set smooth(actual_max) [lindex $ret 4] 

    # fix for first-time trace smoothMethod error
    if {$smooth(actual_max) == 0} {
        busy reset
        return
    }
    
    if {[expr abs($smooth(actual_min))] < 1.0e-08} {
        set smooth(actual_min) 0
    }
    set histo_minv_limit $smooth(actual_min)
    set histo_maxv_limit $smooth(actual_max)

    if {$histo_minv_limit == $histo_maxv_limit} {
        set histo_minv_limit 0
    }

    set inc_less_min 0; set inc_more_max 0
    if {$min == ""} {
        if {[info exists histo_minv] && ($histo_minv != "")} {
            set min $histo_minv
        } else {
            if {[info exists histo_minv] && ($histo_minv == "")} {
                set min 0.0
            } else {
                set min $smooth(actual_min)
            }
        }
        set inc_less_min 1
    } else {
        if {[info exists histo_replot_changed] && \
            [info exists histo_minv] && ($histo_minv != "")} {
            set min $histo_minv
        } else {
            if {[info exists histo_minv] && ($histo_minv == "")} {
                set min 0.0
            } else {
                set min $smooth(actual_min)
            }
        }
    }

    if {$max == ""} {
        if {[info exists histo_maxv] && ($histo_maxv != "")} {
            set max $histo_maxv
        } else {
            if {[info exists histo_maxv] && ($histo_maxv == "")} {
                set max [aie_get_max_possible_colorband]
                if {$max == "1.0e38"} {
                    set max $smooth(actual_max)
                }
            } else {
                set max $smooth(actual_max)
            }
        }
        set inc_more_max 1
    } else {
        if {[info exists histo_replot_changed] && [info exists histo_maxv] && ($histo_maxv != "")} {
            set max $histo_maxv
        } else {
            if {[info exists histo_maxv] && ($histo_maxv == "")} {
                set max [aie_get_max_possible_colorband]
                if {$max == "1.0e38"} {
                    set max $smooth(actual_max)
                }
            } else {
                set max $smooth(actual_max)
            }
        }
    }

    set smooth(criterion_ok) 1

    if {$min > $max} {
        mess "Max value can not be less than min value; resetting the histogram values to defaults\n" red
        set histo_minv 0.0; set histo_maxv 1.0
        set min $histo_minv; set max $histo_maxv
    }
    if {$min == $max} {
        if {$max < 0 } {
            set max 0
        } elseif {$max > 0} {
            set min 0
        } else {
            set max 1
        }
    }
    
    set colorBand(actual_min) $min
    set colorBand(actual_max) $max
    set histo [ic_uns_histogram smooth_do_map $min $max $nbars]
    mess "Histogram of $title values\n" blue
    set ymax 0
    set ntotal [ic_uns_subset_count_elements smooth_do_map]
    set scale [expr $max - $min]
    for {set i 0} {$i < $nbars} {incr i} {
        set n [lindex $histo [expr $i + 1]]
        if {($i == 0) && $inc_less_min} { incr n [lindex $histo 0] }
        if {($i == $nbars - 1) && $inc_more_max} { incr n [lindex $histo [expr $nbars + 1]] }
        set low [expr {$min + $scale * $i / ($nbars + 0.0)}]
        set hi [expr {$min + $scale * ($i + 1.0) / ($nbars + 0.0)}]
        lappend yvals $n
        if {$n > $ymax} { set ymax $n }
        lappend xvals $low
    }
    lappend xvals $hi
    for {set i [expr $nbars - 1]} {$i >= 0} {incr i -1} {
        set n [lindex $histo [expr $i + 1]]
        if {($i == 0) && $inc_less_min} { incr n [lindex $histo 0] }
        if {($i == $nbars - 1) && $inc_more_max} { incr n [lindex $histo [expr $nbars + 1]] }
        set low [expr {$min + $scale * $i / ($nbars + 0.0)}]
        set hi [expr {$min + $scale * ($i + 1.0) / ($nbars + 0.0)}]
        set percent [format %.3f [expr $n * 100.0 / $ntotal]]
        mess "$low -> $hi : $n ($percent%)\n" blue
    }

    # swap min-max for some
    if {$smooth(criterion) == "\"Max warp\"" || $smooth(criterion) == "\"Max warpgls\"" || $smooth(criterion) == "\"TGrid Skew\""} {
        set nmax [expr [llength $xvals] - 1]
        for {set i $nmax} {$i >= 0} {incr i -1} {
            lappend rev_xvals [lindex $xvals $i]
        }
        set xvals $rev_xvals
        set nmax [expr [llength $yvals] - 1]
        for {set i $nmax} {$i >= 0} {incr i -1} {
            lappend rev_yvals [lindex $yvals $i]
        }	
        set yvals $rev_yvals
    }
    set colorBand(xvals) $xvals
    set colorBand(color_by_quality) 1
    if [info exist histo_color_by_quality] {
        set colorBand(color_by_quality) $histo_color_by_quality
    }
    if [aie_disable_colorband] {
       catch { unset colorBand }
    } else {
        aie_create_colorband $colorBand(actual_min) $colorBand(actual_max) $colorBand(xvals) $colorBand(color_by_quality)
    }
    set labels [list "Min $smooth(actual_min)" "Max $smooth(actual_max)"]
    set extra_buts [list [list subset "Subset" aie_smooth_subset_histogram] [list done "Done" aie_smooth_clear_histogram]]
    ::AIEnv::GUIManagement::ConfigureConsoleZone 2
    aie_make_histogram $title $xvals $yvals $ylim $labels aie_smooth_update_histogram smooth_show_elements {} $extra_buts 2 12 9 1 0 0 0 0 -1
    # finally, update the colors of the elements if possible
    # aie_diag_color_by_quality_update
    busy 0
}

proc aie_diag_color_by_quality_update {} {
    global disp_options

    if ![info exists disp_options] { return }
    if {[info exists disp_options(uns_color_by_quality)] && $disp_options(uns_color_by_quality)} {
        ic_uns_diagnostics_update
        update_uns_visible
    }
}

proc aie_smooth_clear_histogram {} {
    global histo_minv histo_maxv histo_ylim histo_nbars

    ic_uns_subset_delete smooth_show_map
    aie_delete_histogram
    ::AIEnv::GUIManagement::ConfigureConsoleZone 0
}

proc smooth_show_elements {w intervals args solid show color_by_quality {crit ""} {min ""} {max ""}} {
    global smooth 

    set conf ""
    if ![ic_uns_subset_exists smooth_show_map] {
        ic_uns_subset_create smooth_show_map 1 "" 0
        lappend conf -dont_change_color_or_shade 1
    }
    if !$show {
        lappend conf -visible 0
    } else {
        lappend conf -visible 1 -color_by_quality $color_by_quality
	    if $solid {
	        lappend conf -shade flat_wire
	    } else {
	        lappend conf -shade wire
	    }
    }

    eval ic_uns_subset_configure smooth_show_map $conf
    # There is a bug in uns_diag which will fix in next release.
    # Quick fix for now
    set myint ""
    set eps 1.0e-08
    foreach intv $intervals {
	    foreach {l h} $intv {
	        if {$h >= $l} {
		        lappend myint [list [expr $l - $eps]  [expr $h + $eps]]
	        } else {
		        lappend myint [list [expr $h - $eps]  [expr $l + $eps]]
	        }
	    }
    }
    if {$crit != ""} {
        if {$min != ""} {
            if {$min < 0} { set min 0.0 }
            ic_uns_diag_set_degen_min $crit $min
        }
        if {$max != ""} {
            ic_uns_diag_set_degen_max $crit [expr $max + $min]
        }
    } else {
        ic_uns_diag_reset_degen_min_max
    }
    set tot [ic_uns_set_with_diagnostic smooth_show_map smooth_do_map $myint]
    if $tot {
        aie_histo_show_bad_elements $show $solid $color_by_quality
    } else {
        aie_histo_delete_bad_elements
    }
    mess "$tot elements\n"
}

proc aie_smooth_subset_histogram {} {
    global smooth
    
    if ![ic_uns_subset_exists smooth_show_map] {
        msg ERROR "No elements selected in the histogram"
        return
    }
    set uns DIAGNOSTIC/$smooth(criterion)
    ic_uns_subset_create $uns
    ic_uns_subset_add_from $uns smooth_show_map
    aie_subset_put_in_tree mesh "DIAGNOSTIC/$smooth(criterion)"
    update_uns_visible
}

proc aie_histo_show_bad_elements {{show 1} {solid 1} {color_by_quality 1}} {
    global fam_visible aie_badElements histo_bad_elements plot_window
    global histo_show histo_color_by_quality histo_solid

    if ![ic_uns_is_loaded] return 
    aie_histo_delete_bad_elements  
       
    if ![ic_uns_subset_exists smooth_show_map] return
    if {![info exists histo_bad_elements] || $histo_bad_elements == ""} return
    if {![info exists plot_window] || ![winfo exists $plot_window.graph]} return
    
    if {![info exists histo_show] || $histo_show != "1"} return    
    if [info exists histo_solid] { set solid $histo_solid }
    if [info exists histo_color_by_quality] { set color_by_quality $histo_color_by_quality }

    set num 0
    switch $histo_bad_elements {
        bad { return }
        bad_1_layer { set num 1 }
        bad_2_layer { set num 2 }
    }
    set active ""
    set check ""
    if {[aie_active_dez] == "smoothDEZ"} {
        switch [smoothDEZ get smoothMethod] {
            0 { set check all }
            1 { set check active }
            2 { set check visible_subsets }
            3 { set check visible }
        }
    } else {
        if ![qualityMetricsDEZ isbuilt] {
            mess "Warning: Quality is not defined for any elements\n" red
            set histo_bad_elements "bad"
            return
        } else {
            set check [qualityMetricsDEZ get checkElems]
        }
    }
    if {$check == "visible" || $check == "active"} {
        foreach p [array names fam_visible] {
            if {$p == "ORFN"} continue
            if $fam_visible($p) { lappend active $p }
        }     
        if {$check == "visible"} {
	        foreach vismap [ic_uns_subset_list_visible] {
		        if {$vismap != "Selected"} {
		            foreach p [ic_uns_subset_list_families $vismap] {
		                if {[lsearch $active $p] < 0} {
		                    lappend active $p
		                }
		            }
		        }
	        }
        }    
    } elseif {$check == "visible_subsets"} {
	     foreach vismap [ic_uns_subset_list_visible] {
		    if {$vismap != "Selected"} {
		        foreach p [ic_uns_subset_list_families $vismap] {
		            if {[lsearch $active $p] < 0} {
		                lappend active $p
		            }
		        }
		    }
	    }
    } else {
        foreach p [ic_uns_list_families] {
            if {$p == "ORFN"} continue
            lappend active $p
        }
    }
    set types ""
    if {[aie_active_dez] == "smoothDEZ"} {
        foreach row [ic_uns_list_types] {
            if {[regexp NODE $row] || [regexp LINE $row] || [regexp BAR $row]} continue
            if {[regexp TETRA_+ $row] || [regexp HEXA_+ $row] || [regexp PYRA_+ $row] || [regexp PENTA_+ $row]} continue
	        if [smoothMeshMS query $row Smooth] {
	            lappend types $row
	        }
	    }
    } else {
        foreach row [ic_uns_list_types] {
            if {$row == "NODE" || [regexp TETRA_+ $row] || [regexp HEXA_+ $row] || [regexp PYRA_+ $row] || [regexp PENTA_+ $row]} continue
            if [diagMeshMS query $row Yes] {
                lappend types $row
            }
        }
    }
    if {$active == "" || $types == ""} return
    set conf ""
    set aie_badElements(badmap) [ic_uns_subset_create "" 0 smooth_show_map]
    ic_uns_subset_add_layer $aie_badElements(badmap) $num $active $types
    ic_uns_subset_subtract_from $aie_badElements(badmap) smooth_show_map
    lappend conf -visible $show -dont_change_color_or_shade 1
    if $solid {
        lappend conf -shade flat_wire -color_by_quality $color_by_quality
    } else {
        lappend conf -shade wire -color_by_quality $color_by_quality
    }
    eval ic_uns_subset_configure $aie_badElements(badmap) $conf
}

proc aie_histo_delete_bad_elements {} {    
    global aie_badElements
    if ![info exists aie_badElements(badmap)] return
    if ![ic_uns_subset_exists $aie_badElements(badmap)] return
    ic_uns_subset_delete $aie_badElements(badmap)
    unset aie_badElements(badmap)
}

proc aie_delete_colorband {{reset 0}} {
     global tdv_current_viewer colorBand
     if [winfo exists $tdv_current_viewer.colorband] {
         top_destroy $tdv_current_viewer.colorband
         if {$reset && [info exists colorBand]} {
             unset colorBand
         }
     }
}

proc aie_get_max_possible_colorband {} {
    global smooth
    
    set flt_max_colorband {
        "Max length" "Max side" "Surface dev" "Max Ratio" \
        "Min side" "Min side (Quad Optimized)" "Prism thickness" "Quadratic dev" \
        "Surface area" Volume "Volume change" "Volume/Area/Length" \
        "Element stretch" "X size" "Y size" "Z size" \
        "Mesh expansion factor" "Max sector volume" "Min sector volume" \
        "Opp. Face Area Ratio" "Opp. Face Parallelism" "Hex. Face Distortion" \
        "Aspect Ratio (Fluent)"
    }
    set d90_max_colorband {
        "Min ortho" "Max ortho" "Max orthogls" 
    }
    set d180_max_colorband {
        "Max angle" "Min angle" "Max dihedral angle" "Max warp" "Max warpgls"
    }
    set d32_max_colorband {
        "Ford"
    }    
    set max 1.0
    if [info exists smooth(criterion)] {
        set criterion $smooth(criterion)
        regsub -all {"} $criterion "" criterion
        foreach {t m} "flt_max_colorband 1.0e38 d90_max_colorband 90 d180_max_colorband 180 d32_max_colorband 32" {
            if {$max != 1.0} break
            foreach c [set $t] {
                if [string match -nocase $c $criterion] {
                    set max $m
                    break
                }
            }
        }
    }
    return $max
}

proc aie_disable_colorband {} {
    global smooth 
    
    if [ic_hex_blocking_loaded] {
        if [ic_uns_is_loaded] {
            return 0
        }
        return 1
    }
    if {[ic_str_is_loaded] && ![ic_uns_is_loaded]} { return 1 }
    if [ic_uns_is_loaded] { return 0 }
    return 1

    array set disable_colorband {
        "Custom quality" 0 Distortion 0 "Element stretch" 0 Ford 0 \
        "Max Ratio" 0 "Max angle" 0 "Max length" 0 "Max dihedral angle" 0 \
        "Max ortho" 0 "Max orthogls" 0 "Max side" 0 "Max warp" 0 \
        "Max warpgl" 0 "Mid node" 0 "Mid node Angle" 0 "Min angle" 0 \
        "Min ortho" 0 "Min side" 0 "Min side (Quad Optimized)" 0 "Opp.Face Area Ratio" 0 \
        "Opp.Face Parallelism" 0 Orientation 0 "Prism thickness" 0 \
        "Quadratic dev" 0 "Surface area" 0 "Surface dev" 0 Taper 0 \
        "Tetra Special" 0 Volume 0 "Volume change" 0 "Volume/Area/Length" 0 \
        "X size" 0 "Y size" 0 "Z size" 0
    }
    
    set disable 0
    if [info exists smooth(criterion)] {
        set criterion $smooth(criterion)
        regsub -all {"} $criterion "" criterion
        foreach c [array names disable_colorband] {
            if [string match -nocase $c $criterion] {
                set disable 1
                break
            }
        }
    }
    return $disable
}
 
proc aie_create_colorband {{min 0.0} {max 1.0} {xvals ""} {color_by_quality 1}} {  
     global colorBand tdv_current_viewer histo_status disp_options 
     global histo_colorband histo_minv histo_maxv histo_crit smallnonboldfont

     if [aie_disable_colorband] return
     if {([ic_hex_blocking_loaded] && ![ic_uns_is_loaded]) || !$color_by_quality} {
         aie_delete_colorband 1
         return
     }

     set reverse 0
     if [info exists colorBand(xvals)] {
         if [info exists histo_crit] {
            if {$histo_crit == "Max warp" || $histo_crit == "Max warpgls" || $histo_crit == "TGrid Skew"} {
                set reverse 1
            }
         }
         aie_set_bar_colors $reverse
     }

     if !$disp_options(uns_color_by_quality) {
         if !$color_by_quality {
             aie_delete_colorband
             return
         }
         set bar_is_on 0
         foreach n [lsort -dictionary [array names histo_status]] {
             if $histo_status($n) {
                 set bar_is_on 1
                 break
             }
         }
         if !$bar_is_on {
             aie_delete_colorband
             return
         } else {
             if [winfo exists $tdv_current_viewer.colorband] return
         }
     } else {
         aie_delete_colorband
     }
     if !$disp_options(uns_color_by_quality) {
         set bar_is_on 0
         foreach n [lsort -dictionary [array names histo_status]] {
             if $histo_status($n) {
                 set bar_is_on 1
                 break
             }
         }
         if !$bar_is_on {
             aie_delete_colorband
             return
         }
     }
     set canvas [canvas $tdv_current_viewer.colorband -bd 0 -bg black -highlightthickness 0]
     pack $canvas -fill both -expand 1
     
     if {$xvals != ""} {
         set colorBand(xvals) $xvals
     } elseif [info exists colorBand(xvals)] {
         set xvals $colorBand(xvals)
     }      
     if [info exists colorBand(actual_min)] {
         set min $colorBand(actual_min)
     } else {
         set colorBand(actual_min) $min
     }
     if [info exists colorBand(actual_max)] {
         set max $colorBand(actual_max)
     } else {
         set colorBand(actual_max) $max
     }
     set colorBand(color_by_quality) $color_by_quality

     if ![info exists histo_crit] {
         set histo_crit Quality
     }

     set min 0.0
     set max $colorBand(actual_max)
     set min [format "%.2g" $min]
     set max [format "%.2g" $max]
     variable ::AIEnv::GUIManagement::GUIDisplayData
     if ![info exists smallnonboldfont] {
        set normalfont $::AIEnv::GUIManagement::GUIDisplayData("DefaultFont")
     } else {
        set normalfont $smallnonboldfont
     }
     if [catch {font configure $normalfont -size} res] {
        set normalfont -*-helvetica-bold-r-normal--10*
     }     
     set fsize 10
    
     set x 0; set xpos 70; set y 30
     set xtxt 35
     
     if {$reverse && 0} {
        set usign ""
     } else {
        set usign "<"
     }

     $canvas create rectangle 0 0 $xpos $y -fill black
     $canvas create text $xtxt 15 -text "$histo_crit" -fill white -font $normalfont -width $xpos
     if {$reverse && 0} {
        set color \#[format "%.2X%.2X%.2X" 0 255 255]
     } else {
        set color \#[format "%.2X%.2X%.2X" 255 0 0]
     }
     for {set i 0} {$i < 20} {incr i} {
         $canvas create line $x $y $xpos $y -width 1 -fill $color
         incr y
     }
     if {$reverse && 0} {
        $canvas create text $xtxt [expr $y - $fsize] -text "> $max" -font $normalfont
     } else {
        $canvas create text $xtxt [expr $y - $fsize] -text "< $min" -font $normalfont
     }
     set rangeStart $y
     for {set i 165} {$i <= 255} {incr i} {
         if ![info exists colorBand(y,$y)] {
             set colorBand(y,$y) \#[format "%.2X%.2X%.2X" 255 $i 0]
         }
         if ![info exists colorBand(ytext,min)] {
             $canvas create line $x $y $xpos $y -width 1 -fill $colorBand(y,$y)
         } else {
             if {$colorBand(ytext,min) <= $y} {
                 $canvas create line $x $y $xpos $y -width 1 -fill $colorBand(y,$y)
             }
         }
         incr y
     }
     for {set i 255} {$i >= 0} {incr i -3} {
         if ![info exists colorBand(y,$y)] {
             set colorBand(y,$y) \#[format "%.2X%.2X%.2X" $i 255 0]
         }
         if ![info exists colorBand(ytext,min)] {
             $canvas create line $x $y $xpos $y -width 1 -fill $colorBand(y,$y)
         } else {
             if {$colorBand(ytext,min) <= $y} {
                 $canvas create line $x $y $xpos $y -width 1 -fill $colorBand(y,$y)
             }
         }
         incr y
     }
     for {set i 0} {$i <= 255} {incr i 3} {
         if ![info exists colorBand(y,$y)] {
             set colorBand(y,$y) \#[format "%.2X%.2X%.2X" 0 [expr 255 - $i] $i]
         }
         if ![info exists colorBand(ytext,min)] {
             $canvas create line $x $y $xpos $y -width 1 -fill $colorBand(y,$y)
         } else {
             if {$colorBand(ytext,min) <= $y} {
                 $canvas create line $x $y $xpos $y -width 1 -fill $colorBand(y,$y)
             }
         }
         incr y
     }
     set rangeEnd [expr $y - 1]
     if {$reverse && 0} {
        set color \#[format "%.2X%.2X%.2X" 255 0 0]
     } else {
        set color \#[format "%.2X%.2X%.2X" 0 255 255]
     }
     for {set i 0} {$i < 20} {incr i} {
         $canvas create line $x $y $xpos $y -width 1 -fill $color
         incr y
     }
     set ypos [expr $y - 1]
     if {$reverse && 0}  {
        $canvas create text $xtxt [expr $ypos - $fsize] -text "< $min" -font $normalfont
     } else {
        $canvas create text $xtxt [expr $ypos - $fsize] -text "> $max" -font $normalfont 
     }
     if {$min == 0 && $max == 1} {
         if {$reverse && 0} {
            set vals "0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1" 
         } else {
            set vals "0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9" 
         }
     } else {
         set range [expr $max - $min]
         set value [expr $range / 10.0]
         set val [expr $value + $min]
         set vals ""
         for {set i 0} {$i < 9} {incr i} {
            append vals "$val "
            set val [expr $val + $value]
         }
         if {$reverse && 0} {
            set lenvals [llength $vals]
            set i 1
            set tmpvals ""
            foreach v $vals {
                append tmpvals "[lindex $vals [expr $lenvals - $i]] "
                incr i
            }     
            set vals $tmpvals
         }
     } 
     set add [expr int(($ypos - $fsize) / 11.0)]
     set diff 6
     set n 0
     if {$reverse && 0} {
        set usecol1 black
        set usecol2 white
        set usenew 3
     } else {
        set usecol1 white
        set usecol2 black
        set usenew 8
     }
     for {set i [expr $rangeStart + $fsize + $diff]} {$i < $rangeEnd} {incr i $add} {
         set val [format "%.3g" [lindex $vals $n]]
         incr n
         if {$n >= $usenew} {
             $canvas create text $xtxt $i -text "$usign $val" -fill $usecol1 -font $normalfont
         } else {
             if ![info exists colorBand(ytext,min)] {
                 $canvas create text $xtxt $i -text "$usign $val" -font $normalfont -fill $usecol2
             } else {
                 if {$colorBand(ytext,min) <= $i} {
                      $canvas create text $xtxt $i -text "$usign $val" -font $normalfont -fill $usecol2
                 }
             }
         }
     }
     set colorBand(ytext,min) 0
     set colorBand(ytext,max) $ypos
     $canvas configure -width $xpos -height $ypos
     place $tdv_current_viewer.colorband -relx 0.0 -rely 0.0
}

proc aie_set_bar_colors {{reverse 0}} {  
     global colorBand histo_colorband histo_minv histo_maxv
     
     set last [expr [llength $colorBand(xvals)] - 1]
     set y 50
     set greenStart $y
     for {set i 165} {$i <= 255} {incr i} {
         set color \#[format "%.2X%.2X%.2X" 255 $i 0]
         set colorBand(y,$y) $color
         incr y
     }
     set greenEnd [expr $y - 1]
     set redStart $y
     for {set i 255} {$i >= 0} {incr i -3} {
         set color \#[format "%.2X%.2X%.2X" $i 255 0]
         set colorBand(y,$y) $color
         incr y
     }
     set redEnd [expr $y - 1]
     set blueStart $y
     for {set i 0} {$i <= 255} {incr i 3} {
         set color \#[format "%.2X%.2X%.2X" 0 [expr 255 - $i] $i]
         set colorBand(y,$y) $color
         incr y
     }
     set blueEnd [expr $y - 1]  
     set ypos $y
     if {[info exists histo_colorband] && $histo_colorband && 0} {
         if {$histo_minv != ""} {
             set possible_min $histo_minv
         } else {
             set possible_min $colorBand(actual_min)
         }
         if {$histo_maxv != ""} {
             set possible_max $histo_maxv
         } else {
             set possible_max $colorBand(actual_max)
         }
     } else {
         set possible_min 0.0
         set possible_max $colorBand(actual_max)
         
     }
     if {$possible_max == 0} {
        set possible_max 0.0000001
     }
     set step [expr ($ypos - 50.0) / ($last)]
     for {set i 0} {$i < $last} {incr i} {
         catch { unset colorBand($i) }
         set first [lindex $colorBand(xvals) $i]
         set next [lindex $colorBand(xvals) [expr $i + 1]]
         if {$next == ""} { set next $possible_max }
         set xval [expr $first + (($next - $first) / 1.0)]
         if {$possible_max  == 1.0} {
             if {$xval < 0} {
                 set colorBand($i) #FF0000
                 continue
             } elseif {$xval == 0 && !$reverse} {
                 if {$first < 0 && $next == 0} {
                    set colorBand($i) #FF0000
                 } else {
                    set colorBand($i) #FFA500
                 }
                 continue
             } elseif {$xval == 1 && !$reverse} {
                 set colorBand($i) #0000FF
                 continue
             } elseif {$xval > 1} {
                 if {$first > 1} {
                     set colorBand($i) #00FFFF
                     continue
                 } else {
                     set val [expr 0.99 * ($blueEnd)]
                 }
             } else {
                 if !$reverse {
                    set val [expr $xval * ($ypos)]
                 } else {
                    set val [expr (49.0 + $step) + ($i * $step)]
                 }
             }
         } else {
            if !$reverse {
                set val [expr ($xval * ($ypos)) / $possible_max]
            } else {
                set val [expr (49.0 + $step) + ($i * $step)]
            }
         }
         foreach col [lsort -dictionary [array names colorBand y,*]] {
             set v [lindex [split $col ,] 1]
             if {$v >= $val} {
                set colorBand($i) $colorBand($col)
                break
             }
         }
         if ![info exists colorBand($i)] {
             if [info exists last_color] {
                 set colorBand($i) $last_color
             } else {
                 set colorBand($i) $colorBand($col)
             }
         } else {
             set last_color $colorBand($i)
         }
     }
}

# get a list of material points which are not bodies
# these are typically created by tetra and/or unstruct_flood_fill autovol

proc aie_get_materials {} {
    catch { unset body_exist }
    set materials ""
    foreach bdy [ic_geo_get_objects body] {
        set mpt [ic_geo_get_body_matlpnt $bdy]
        if {$mpt != ""} {
            set body_exist($mpt) 1
        }
    }
    set materials ""
    foreach mpt [ic_geo_get_objects material] {
        if ![info exists body_exist($mpt)] {
            lappend materials $mpt
        }
    }
    return $materials
}

proc aie_build_volumes {} {
    set matlpnts [aie_get_materials]
    if {$matlpnts == ""} return
    ic_undo_suspend
    set added 0
    set removed 0
    foreach mpt $matlpnts {
        if [string match "ORFN/-*" $mpt] {
            ic_delete_material $mpt
            incr removed
        } else {
            set fam [ic_geo_get_family material $mpt]
	        ic_geo_create_volume $mpt "" $fam
            incr added
        }
    }
    ic_geo_set_modified 1
    if $added {
        mess "Created $added bodies from material points\n" blue
    }
    if $removed {
        mess "Removed $removed old auto material points\n" blue
    }
    ic_geo_reset_bodies
    ic_undo_resume
}

# turn on display of created material points

proc aie_show_materials {} {
    set materials [aie_get_materials]
    if {$materials != ""} {
        ic_undo_suspend
        ic_create_material $materials
        ic_geo_update_visibility material *skip* 1
        ic_undo_resume
    }
}

# remove created material points from display and projlib
# we don't want these written to the tetin file

proc aie_delete_materials {} {
    set materials [aie_get_materials]
    if {$materials != ""} {
        ic_undo_suspend
        ic_geo_update_visibility material *skip* 0
        ic_delete_material $materials
        aie_delete_empty_parts
        ic_undo_resume
    }
}

proc aie_start_visual3p {v3opts} {
    global env black_and_white use_xwindows file_name AppName
    set opts ""
    if { $v3opts != ""} {set opts $v3opts}

    if ![info exists env(ICEM_V3_17)] {
       global tcl_platform host_vendor

          # for visual3p executable -------------

       # if ![info exists env(VISUAL3P_ROOT)] {
       #    set env(VISUAL3P_ROOT) $env(ICEM_ACN)
       # }

       set env(VISUAL3P_ROOT) $env(ICEM_ACN)

       set v3p_app [file join $env(VISUAL3P_ROOT) bin visual3p]
       if {$tcl_platform(platform) == "windows"} {
          append v3p_app \.exe
       }
       if ![file executable $v3p_app] {
          error "Can't find Visual3p executable $v3p_app"
       }

          # for PVM stuff ----------------

       if ![info exists  env(PVM_ROOT)] {
          set env(PVM_ROOT) [file join $env(ICEM_ACN) pvm3]
       }
       if {$tcl_platform(platform) == "windows"} {
          set env(V3P_ARCH) win40
          set env(PVM_ARCH) WIN32
          set env(PVM_TMP) c:\\tmp
          set env(PVM_DPATH) [file join $env(PVM_ROOT) lib $env(PVM_ARCH) pvmd3.exe]
       } else {
          switch -- $tcl_platform(os) {
             IRIX - IRIX64 {
                set rr [exec file $v3p_app]
                if {[lsearch $rr "64-bit"] < 0} {
                   if {[lsearch $rr "mips-4"] < 0} {
                      set env(V3P_ARCH) sgi6
                   } else {
                      set env(V3P_ARCH) mips4
                   }
                   set env(PVM_ARCH) SGI6
                } else {
                   set env(V3P_ARCH) mips64
                   set env(PVM_ARCH) SGI64
                }
             }
             HP-UX {
                set rr [exec file $v3p_app]
                if {[lsearch $rr "ELF-64"] < 0} {
                   set env(V3P_ARCH) hp10
                   set env(PVM_ARCH) HPPA
                } else {
                   set env(V3P_ARCH) hp11
                   set env(PVM_ARCH) HPPA64
                }
             }
             SunOs {
                set rr [exec file $v3p_app]
                if {[lsearch $rr "ELF-64"] < 0} {
                   set env(V3P_ARCH) sol7
                   set env(PVM_ARCH) SUN4SOL2
                } else {
                   set env(V3P_ARCH) sol64
                   set env(PVM_ARCH) SUN64
                }
             }
             default {
                set env(V3P_ARCH) $host_vendor
                set env(PVM_ARCH) \
                      [exec [file join $env(PVM_ROOT) lib pvmgetarch]]
             }
          }
          set env(PVM_DPATH) \
             [file join $env(PVM_ROOT) lib $env(PVM_ARCH) pvmd3]
       }
       if ![file executable $env(PVM_DPATH)] {
          error "Can't find PVM daemon $env(PVM_DPATH)"
       }

          # set pV3_* used in pV3 libs ------------

       if {$tcl_platform(platform) == "windows"} {
          if {![info exists env(pV3_Group)] && [info exists env(LOGNAME)]} {
             set env(pV3_Group) "pV3_$env(LOGNAME)"
          }
       }
       set env(pV3_TO) 62208000

          # to skip setup hosts etc.  --------------

       if ![info exists env(V3PUSEDEFAULTHOSTS)] {
           set env(V3PUSEDEFAULTHOSTS) 1
       }
       if ![info exists env(VISUAL3P_START)] {
           set env(VISUAL3P_START) 1
       }
       if ![info exists env(V3P_1_SVAR_SUBNAME)] {
          set env(V3P_1_SVAR_SUBNAME) Translation_Total
       }
       if ![info exists env(V3P_1_VEC_SUBNAME)] {
          set env(V3P_1_VEC_SUBNAME) Translation
       }

       if [info exists env(ICEM_AI_ENVIRONMENT)] {
          set env(VISUAL3_LOGOTEXT) $AppName
          set env(VISUAL3_TOOLNAME) "Visualizer"
       }

          # to specify v3pclient dir  --------------

       # if ![info exists env(V3PCLIENT_DIR)] {
       #    set env(V3PCLIENT_DIR) $env(ICEM_ACN)
       # }

       set env(V3PCLIENT_DIR) $env(ICEM_ACN)

          # for readers ----------------

       set platform [set tcl_platform(platform)]
       if [string compare $platform "windows"] {
          if [info exists env(LD_LIBRARY_PATH)] {
             if {[string first $env(LD_LIBRARY_PATH) "result-interfaces"] == -1 } {
                set env(LD_LIBRARY_PATH) \
                        $env(LD_LIBRARY_PATH):$env(ICEM_ACN)/icemcfd/result-interfaces
             }
          } else {
             set env(LD_LIBRARY_PATH) $env(ICEM_ACN)/icemcfd/result-interfaces
          }
 
          if [info exists env(LD_LIBRARYN32_PATH)] {
             if { [string first $env(LD_LIBRARYN32_PATH) "result-interfaces"] == -1 } {
                set env(LD_LIBRARYN32_PATH) \
                    $env(LD_LIBRARYN32_PATH):$env(ICEM_ACN)/icemcfd/result-interfaces
             }
          } else {
             set env(LD_LIBRARYN32_PATH) $env(ICEM_ACN)/icemcfd/result-interfaces
          }
 
          if [info exists env(LD_LIBRARY64_PATH)] {
             if { [string first $env(LD_LIBRARY64_PATH) "result-interfaces"] == -1 } {
                set env(LD_LIBRARY64_PATH) \
                  $env(LD_LIBRARY64_PATH):$env(ICEM_ACN)/icemcfd/result-interfaces
             }
          } else {
             set env(LD_LIBRARY64_PATH) $env(ICEM_ACN)/icemcfd/result-interfaces
          }
       }

          # for window manager's options ------------

       if [info exist env(ICEM_ONE_WINDOW)] {
          set env(ICEM_ONE_WINDOW_used) $env(ICEM_ONE_WINDOW)
       } else {
          set env(ICEM_ONE_WINDOW) 1
       }
       if [info exist env(ICEM_GRAY_BACKGROUND)] {
          set env(ICEM_GRAY_BACKGROUND_used) $env(ICEM_GRAY_BACKGROUND)
       } else {
          set env(ICEM_GRAY_BACKGROUND) 1 
       }

          # to set gsys -----------------

       if $black_and_white { set bw -bw } else { set bw "" }
       switch $use_xwindows {
	    0 { set x "" }
	    1 { set x -x }
	    2 { set x -ogl }
       }

          # to set starting directories --------------

       set olddir [pwd]
       set newdir [file join [pwd] $file_name(project_dir)]

       if ![info exists env(V3PCLIENT_START_DIR)] {
	   mess "Visual3p working directory is $newdir\n"
           set env(V3PCLIENT_START_DIR) $newdir
       } else {
	   mess "Visual3p working directory is $env(V3PCLIENT_START_DIR)\n"
       }

       if [catch {ic_chdir $newdir} res] {
	    mess "Can't change directory: $res\n"
       } 

        regsub -all \\\\ $v3p_app / v3p_app

         	# to start visual3p  ---------------
       catch {
           set logfile ""
           if {[info exist env(VISUAL3P_DEVELOPE)] && \
                     ($env(VISUAL3P_DEVELOPE) == 1)} {
              set logfile [cmd_tempfile visual3p .out]

              eval ic_exec "\"$v3p_app\" $x $bw $opts" >& $logfile
           } else {
              eval ic_exec "\"$v3p_app\" $x $bw $opts" &
           }
	 # run_application_command "$v3p_app $x $bw $opts" $logfile 0
       	}


         # to restore window manager options after visual3p exits ------

       if [info exist env(ICEM_GRAY_BACKGROUND_used)] {
           set env(ICEM_GRAY_BACKGROUND) $env(ICEM_GRAY_BACKGROUND_used)
           catch {unset env(ICEM_GRAY_BACKGROUND_used)}
       } else {
           catch {unset env(ICEM_GRAY_BACKGROUND)}
       }
       if [info exist env(ICEM_ONE_WINDOW_used)] {
           set env(ICEM_ONE_WINDOW) $env(ICEM_ONE_WINDOW_used)
           catch {unset env(ICEM_ONE_WINDOW_used)}
       } else {
           catch {unset env(ICEM_ONE_WINDOW)}
       } 
       ic_chdir $olddir
    
    } else {
	if ![info exists env(VISUAL3_DIR)] { set env(VISUAL3_DIR) $env(ICEM_ACN) }
	
	if $black_and_white { set bw -bw } else { set bw "" }
        switch $use_xwindows {
	    0 { set x "" }
	    1 { set x -x }
	    2 { set x -ogl }
	}
	set olddir [pwd]
	set newdir [file_select "New directory" \
			$olddir "Directory to start visual3 in?" 1 1]
	if {$newdir == ""} return
	
	if [catch {ic_chdir $newdir} res] {
	    mess "Can't change directory: $res\n"
	} else {
	    mess "New working directory is $newdir\n"
	}
	catch {
	    set app [get_program bin visual3]
	    run_application_command "$app $x $bw $opts"
	}
	ic_chdir $olddir
    }
}

# Overrides the proc in med_gui/file_med.tcl
proc med_file_select {what new {def ""} {mess ""} {multiple 0}} {
    global file_name tcl_platform beta_mode

    if ![file isdirectory $file_name(project_dir)] {
        set_project_dir .
    }
    set file_name(mesh_dir) $file_name(project_dir)
    set file_name(domains_dir) $file_name(project_dir)
    set file_name(parts_dir) $file_name(project_dir)/parts
    set init_dir $file_name(project_dir)

    switch $what {
        acis {
	        set ftypes [list [list "Acis Files" .sat .sab] [list "All Files" *]]
	    }
	    ddn {
	        set ftypes [list [list  "DDN Files" {.ipa .ipr}] [list "All Files" *]]
    	    set init_dir $file_name(parts_dir)
	        if ![file exists $init_dir] { cmd_mkdir $init_dir }
	    }
	    esf {
	        set ftypes [list [list  "ESF Files"  {.esf .xyz}] [list "All Files" *]]
	    }
	    gems {
	        set ftypes [list [list  "GEMS Files" .sur] [list "All Files" *]]
	    }
        step {
	        set ftypes [list [list  "STEP/IGES Files" {.stp .step .igs .iges}] [list "All Files" *]]
	        set what "STEP/IGES"
	    }
	    tetin {
	        set ftypes [list [list  "Tetin Files" .tin] [list "All Files" *]]
	    }
	    idi {
	        set ftypes [list [list  "I-DEAS IDI Files" {.idi .idi.gz}] [list "All Files" *]]
	    }
	    iges {
	        set ftypes [list [list  "Iges Files" {.igs .iges .IGS .IGES}] [list "All Files" *]]
        }
        catia {
	        set ftypes [list [list  "Catia Files" .model] [list "All Files" *]]
	    }
	    cat5 {
	        set ftypes [list [list  "Catia5 Files" .CATPart] [list "All Files" *]]
	    }
	    proe {
	        set ftypes [list [list  "ProE Files" {.prt .prt* .asm*}] [list "All Files" *]]
	    }
	    ug {
	        set ftypes [list [list  "UG Files" .prt] [list "All Files" *]]
	    }
	    patran {
	        set ftypes [list [list  "Patran Files" {.pat .wpatran}] [list "All Files" *]]
	    }
	    ps {
	        set ftypes [list [list  "Parasolid Files" {.x_t .xmt_txt .xmt_bin .x_b}] [list "All Files" *]]
	    }
	    stl {
	        set ftypes [list [list  "STL Files" .stl] [list "All Files" *]]
	    }
	    ansys {
	        set ftypes [list [list  "Ansys Files" {.cdb .rst .rfl .rmg .rth}] [list "All Files" *]]
	    }
	    lsdyna {
	        set ftypes [list [list  "LS-Dyna Files" .k] [list "All Files" *]]
	    }
	    cfx5 {
	        set ftypes [list [list  "CFX5 Files" {.def .res}] [list "All Files" *]]
	    }
	    bgplus {
	        set ftypes [list [list  "BG+ Files" .bg+] [list "All Files" *]]
	    }
	    3dm {
	        set ftypes [list [list  "Rhino Files" .3dm] [list "All Files" *]]
	    }
	    "Import Model" {
            set ftypes {
                {{ANSYS} {.agdb .anf .dsdb .mechdat .mechdb .meshdat .meshdb .mshdat .mshdb .scdoc .wbpj .pmdb}}
                {{ACIS} {.sat .sab}}
                {{BladeGen} {.bgd}}
                {{Catia V4} {.model .dlv .session}}
                {{Catia V5} {.CATPart .CATProduct}}
                {{Catia V6} {.3dxml}}
                {{Creo Elements/Direct Modeling} {.pkg .bdl .ses .sda .sdp .sdac .sdpc}}
                {{Creo Parametric} {.prt .asm .prt* .asm*}}
                {{DesignModeler} {.agdb}}
                {{GAMBIT} {.dbs}}
                {{IGES} {.iges .igs}}
                {{Inventor} {.ipt .iam}}
                {{JT} {.jt}}
                {{Parasolid} {.x_t .x_txt .xmt_b .xmt_bin .x_b}}
                {{Rhino} {.3dm}}
                {{SketchUp} {.skp}}
                {{Solid Edge} {.asm .par .psm .pwd}}
                {{SolidWorks} {.sldasm .sldprt}}
                {{SpaceClaim} {.scdoc}}
                {{STEP} {.stp .step}}
                {{STL} {.stl}}
                {{Unigraphics NX} {.prt}}
                {{All Geometry Files} {.sat .sab .anf .bgd .agdb .model .catPart .catProduct .3dm .3dxml .dbs .iges .igs .jt .opt .iam \
                    .pkg .bdl .ses .sda .sdp .sdac .sdpc .x_t xmt_txt x_b xmt_bin .x_b .prt* .asm* .par .psm .pwd \
                    .sdpc .skp .sldasm .sldprt .scdoc .stl .stp .step .anf .dsdb .mechdat .mechdb .meshdat .meshdb .mshdat .mshdb .wbpj .pmdb}}
                {{All Files} *}
            }
	    }
	    starcd {
	        set ftypes [list [list  "STAR-CD Files"  {.inp .cel .vert .vrt}] [list "All Files" *]]
	    }
	    default {
	        set ftypes [list [list "All Files" *]]
	    }
    }

    if $new {
	    return [tk_getSaveFile -initialdir $init_dir -filetypes $ftypes \
		    -initialfile [file tail $def] -title "Select $what file"]
    } else {
	    return [tk_getOpenFile -initialdir $init_dir -filetypes $ftypes -multiple $multiple \
		    -initialfile [file tail $def] -title "Select $what [expr {$multiple ? [format %s files] : [format %s file]}]"]
    }
}

# This is for compatibility with med GUI
proc file_selection {args} {
    set get_dir 0
    set default ""
    set message "Select File"
    set new_ok 0
    set multiple 0
    set open_button OK
    set filetypes ""
    
    foreach {n v} $args {
	switch -regexp (${n}) {
	    {-get_dir} - {-default} - {-message} - {-new_ok} \
                       - {-multiple} - {-filetypes} {
		set [lindex [split $n -] 1] $v
	    }
	}
    }

    set default_dir $default
    if ![file isdirectory $default_dir] {
       set default_dir [file dirname $default]
    }

    if $get_dir {
        return [tk_chooseDirectory -initialdir $default_dir]
    } else {
        set cmd_line ""
        if $new_ok {
            lappend cmd_line tk_getSaveFile
        } else {
            lappend cmd_line tk_getOpenFile
        }
        lappend cmd_line -initialdir $default_dir -title $message
        
        if [file isfile $default] {
           lappend cmd_line -initialfile [file tail $default]
        }
        if {$filetypes != ""} {
           lappend cmd_line -filetypes $filetypes
        }
        if $multiple {
           lappend cmd_line -multiple $multiple
        } 

        return [eval $cmd_line]
    }
}

proc aie_product_info {} {
    global env AppName Version tcl_platform is_win

   set plat ""
   if {$tcl_platform(platform) == "windows"} {
     if {[string first "win64" $env(ICEM_ACN) 0] > 0} {
       set plat "Windows 64-bit"
     } else {
       set plat "Windows 32-bit"
     }
   }
   if {$tcl_platform(platform) == "unix"} {
     switch -- $tcl_platform(os) {
      IRIX - IRIX64 {
        set rr  [exec file $env(ICEM_ACN)/bin/med]
        if {[lsearch $rr "64-bit"] < 0} {
          set plat "SGI 32-bit"
        } else {
          set plat "SGI 64-bit"
        }
      }
      HP-UX {
        set plat "HP 64-bit"
      }
      SunOS {
        set rr  [exec file $env(ICEM_ACN)/bin/med]
        if {[lsearch $rr "64-bit"] < 0} {
          set plat "Solaris 32-bit"
        } else {
          set plat "Solaris 64-bit"
        }
      }
      AIX {
        set plat "AIX 64-bit" 
      }
      OSF1 {
        set plat "ALPHA"
      }
      Linux {
        set rr  [exec uname -a]
        if {[lsearch $rr "ia64"] >= 0} {
          set plat "Linux 64-bit"
        } elseif {[lsearch $rr "x86_64"] >= 0} {
          set plat "Linux 64-bit"
        } else {
          set plat "Linux 32-bit"
        }
      }
    }
   }

    if {[file exists $env(ICEM_ACN)/icemcfd/version] && 0} {
        set fp [open $env(ICEM_ACN)/icemcfd/version r]
        set ver "[lindex [gets $fp] end]"
        set msg "ANSYS\u00AE $AppName\u2122 $ver\n$plat"
        close $fp
    } else {
        set msg "ANSYS\u00AE $AppName\u2122 $Version\n$plat"
    }
    if [file exists $env(ICEM_ACN)/release_date] {
	set fp [open $env(ICEM_ACN)/release_date r]
        set release_date [gets $fp]
        close $fp
        set month [lindex $release_date 0]
        set date [lrange $release_date 1 end]
        if [string match Jan* $month] { set release_date "January $date" }
        if [string match Feb* $month] { set release_date "Febuary $date" }
        if [string match Mar* $month] { set release_date "March $date" }
        if [string match Apr* $month] { set release_date "April $date" }
        if [string match May* $month] { set release_date "May $date" }
        if [string match Jun* $month] { set release_date "June $date" }
        if [string match Jul* $month] { set release_date "July $date" }
        if [string match Aug* $month] { set release_date "August $date" }
        if [string match Sep* $month] { set release_date "September $date" }
        if [string match Oct* $month] { set release_date "October $date" }
        if [string match Nov* $month] { set release_date "November $date" }
        if [string match Dec* $month] { set release_date "December $date" }
    } else {
        set release_date Unknown
    }
    set help_about "$env(ICEM_ACN)/../../commonfiles/globalsettings/install_help_about.txt"
    set help_about_txt ""
    if [file exists $help_about] {
	    set fp [open $help_about r]
	    while {[gets $fp line] >= 0} {
            append help_about_txt "$line\n"
        }
        close $fp
    }
    set msg2 "Build date: $release_date\nVersion: $Version"
    if {$help_about_txt != ""} {
        set msg2 "$msg2\n$help_about_txt"
    }
    set msg3 "Copyright 2017 SAS IP, Inc.\nAll rights reserved. Unauthorized use, distribution or duplication\nis prohibited. This product is subject to U.S. laws governing\nexport and re-export. For full Legal Notice, see documentation."

    if [winfo exists .about] { top_destroy .about }
    set buttons { {"OK" "top_destroy .about"} }
    set d [form_init .about "About ANSYS $AppName" "" $buttons]
    if {$d == ""} return

    if $is_win {
        if [file exists $env(ICEM_ACN)/lib/ai_env/icons/empty.ico] {
            wm iconbitmap .about $env(ICEM_ACN)/lib/ai_env/icons/empty.ico
        }
    }
    
    form_frame $d.1 flat 3 "0 0"
    variable GUIDisplayData
    set bigfont $::AIEnv::GUIManagement::GUIDisplayData("AboutBigFont")
    form_label $d.1.2 "$msg" "0 1 -pady 10" 
    $d.1.2 configure -font $bigfont -justify left
    form_frame $d.2 flat 1 "1 0"
    form_label $d.2.1 "$msg2" "0 0"
    $d.2.1 configure -justify left
    form_label $d.2.2 "$msg3" "1 0"
    $d.2.2 configure -justify left
    form_finish +400+200
}

proc aie_customer_number {} {
    global is_win env

    set num "  * * *  Customer number = [get_ansysLI_customer_number]  * * * "
    tk_messageBox -title "Customer Number" -message $num
}

proc onmpegDEZLoad {} {
   global mpeg_param hardcopy

   if {![info exist mpeg_param(inputfiles)] || \
            ($mpeg_param(inputfiles) == "")} {
      set mpeg_param(inputdir) [file dirname $hardcopy(outfile)] 
   }
}

proc onmpegDEZOK {} {
   global hardcopy mpeg_param

   mess "Start encoding mpeg file .....\n"
   set outfile $hardcopy(mpegfile)

  #if [file isdirectory plots] {
  #   set outfile [file join plots $outfile]
  #}

   hardcopy_create_mpeg $outfile
   set mpeg_param(inputfiles) ""
}

proc ongifaDEZOK {} {
   hardcopy_gifa_fm_update create 
}

proc onhardcopyDEZLoad {} {
    global AppName Version job_title job_name file_name hardcopy

    if {$outfile == ""} {
	set job_title $file_name(project_dir)
	set job_name $file_name(project_dir)
	set outfile screen
	set format 6
	set ps_type PS
	set ps_color color
	set ps_frame 1
	set ps_title $job_title
	set ps_label "$AppName $Version; [cmd_whoami]@[cmd_uname_n]"
	set scale 1
	set jpeg_quality 75
    }
}

proc onhardcopyDEZOK {} {
    global hardcopy has_fromppm tdv_current_viewer is_win

    set hardcopy(startcmd_current) ""
    set hardcopy(endcmd_current) ""
    set hardcopy(sub_current) $tdv_current_viewer
    set hardcopy(top_current) .[lindex [split $tdv_current_viewer \.] 1]
    set has_fromppm [expr {[glob -nocomplain $bindir/fromppm*] != ""}]

    set hardcopy(ps_direct) 0
    switch $format {
        0 { set hardcopy(format) ps; set hardcopy(ps_direct) 1}
        1 { set hardcopy(format) ps}
        2 { set hardcopy(format) ppm }
        3 { set hardcopy(format) x }
        4 { set hardcopy(format) tiff }
        5 { set hardcopy(format) gif }
        6 { set hardcopy(format) jpeg }
        7 { set hardcopy(format) vrml }
    }

    if {$ps_type == "PS"} {
        set hardcopy(ps_type) ""
    } else {
        set hardcopy(ps_type) "_eps"
    }

    if $is_win {
        if {[info exists send_to_printer] && $send_to_printer && $hardcopy(format) == "ps"} {
            set hardcopy(format) win
        }
    }

    foreach var { outfile generate_new invert landscape scale jpeg_quality \
	    ps_frame ps_color ps_title ps_label send_to_printer } {
        set hardcopy($var) [set $var]
    }
    hardcopy_create
    hardcopyDEZ setdirty
}

proc aie_change_workdir {} {
    global file_name replay_dir cart3d_started

    if [aie_check_application_running] return
    if [catch {pwd} olddir] {
        mess "Can't change directory: $olddir\n"
        return
    }
    set newdir [tk_chooseDirectory -title "New working directory" -initialdir $olddir]
    if {$newdir == ""} return

    if [catch {ic_chdir $newdir} res] {
	    mess "Can't change directory: $res\n"
	    return
    } else {
	    mess "New working directory is $newdir\n"
    }

    # Update all the file names
    foreach f [array names file_name] {
	    if [string match *_dir $f] {
	        set file_name($f) $newdir
	    }
    }
    set replay_dir $newdir
}

proc onsetSelectDEZLoad {} {
    global auto_pick_mode option_subtype options
    global mesh_min_moving_element_aspect
    global disp_options

    set option_subtype edit
    set pick_mode $auto_pick_mode
    set moving_element_aspect $mesh_min_moving_element_aspect
    set uns_cut_delay_count $disp_options(uns_cut_delay_count)
    foreach var {edit_wait flood_select_angle} {
        set $var [set options($var)]
    }
    set options(select_mode) all
}

proc onsetSelectDEZOK {} {
    global auto_pick_mode options disp_options
    global mesh_min_moving_element_aspect

    set auto_pick_mode $pick_mode
    set disp_options(uns_cut_delay_count) $uns_cut_delay_count
    set mesh_min_moving_element_aspect $moving_element_aspect
    foreach var {edit_wait flood_select_angle} {
        set options($var) [set $var]
    }
    set options(select_mode) all
    aie_set_options
}

proc onsetDisplayDEZLoad {} {
    global prev_use_xwindows env use_xwindows option_subtype options
    global med_float_precision tdv_quadratic_accuracy med_index_base
    global tdv_home_shrink tdv_rubbox_overlay tdv_default
    global tdv_current_viewer tdv_origin_var tdv_enable_smooth_move
    global icon_size1 icon_size2 beta_mode options tdv_auto_simplify_geom  
    global disable_overlay tdv_skip_visible_check env tdv_geom_simp
    
    set rubbox_overlay $tdv_rubbox_overlay
    set option_subtype display
    
    if {![info exists use_xwindows]} {set use_xwindows 0}
    if [info exists env(AI_ENV_IN_WIN)] {
	    set use_xwindows 0
    } else {	
	    #set use_xwindows $setDispGraphicsEGVal
	    set setDispGraphicsEGVal $use_xwindows
    }
    set prev_use_xwindows $use_xwindows

    variable use_displist
    set use_displist [expr ($::tdv_control_display_lists & 0x0f) ? 1 : 0]

    if {[info exists env(ICEM_NO_OVERLAY)]} {set disable_overlay $env(ICEM_NO_OVERLAY)}
    if ![info exist disable_overlay] {set disable_overlay 0}
    variable disable_on_overlay
    set disable_on_overlay $disable_overlay
    variable display_view_filter
    set display_view_filter $tdv_skip_visible_check

    set icon_size "Normal"
    if {$icon_size1 == "24" && $icon_size2 == "35"} {set icon_size "Normal"}
    if {$icon_size1 == "35" && $icon_size2 == "35"} {set icon_size "Large"}
    if {$icon_size1 == "35" && $icon_size2 == "48"} {set icon_size "Huge"}
    foreach var {xhidden_full use_dlremote external_num display_origin uns_warn_user_if_display} {
	    if [info exist options($var)] {
	        set $var [set options($var)]
	    }
    }

    variable fit_percent
    if ![info exist tdv_home_shrink] {set ::tdv_home_shrink 0.95}
    set fit_percent [expr round(100 * $::tdv_home_shrink)] 

    set med_float $med_float_precision
    set tdv_quadratic $tdv_quadratic_accuracy
    set med_index $med_index_base
    set tree_disp_line 0
    set tree_disp_node 0
    set tree_disp_tri 1
    set tree_disp_quad 1
    set tree_disp_hexa 0
    set tree_disp_tetra 0
    set tree_disp_penta 0
    set tree_disp_pyra 0
    if {[info exists options(tree_disp_line)]} {
        if {$options(tree_disp_line) == 0} {set tree_disp_line 0}
        if {$options(tree_disp_line) == 2} {set tree_disp_line 1}
    }
    if {[info exists options(tree_disp_node)]} {
        if {$options(tree_disp_node) == 0} {set tree_disp_node 0}
        if {$options(tree_disp_node) == 2} {set tree_disp_node 1}
    }
    if {[info exists options(tree_disp_tri)]} {
        if {$options(tree_disp_tri) == 0} {set tree_disp_tri 0}
        if {$options(tree_disp_tri) == 2} {set tree_disp_tri 1}
    }
    if {[info exists options(tree_disp_quad)]} {
        if { $options(tree_disp_quad) == 0} {set tree_disp_quad 0}
        if { $options(tree_disp_quad) == 2} {set tree_disp_quad 1}
    }
    if {[info exists options(tree_disp_hexa)]} {
        if {$options(tree_disp_hexa) == 0} {set tree_disp_hexa 0}
        if {$options(tree_disp_hexa) == 2} {set tree_disp_hexa 1}
    }
    if {[info exists options(tree_disp_tetra)]} {
        if {$options(tree_disp_tetra) == 0} {set tree_disp_tetra 0}
        if {$options(tree_disp_tetra) == 2} {set tree_disp_tetra 1}
    }
    if {[info exists options(tree_disp_penta)]} {
        if {$options(tree_disp_penta) == 0} {set tree_disp_penta 0}
        if {$options(tree_disp_penta) == 2} {set tree_disp_penta 1}
    }
    if {[info exists options(tree_disp_pyra)]} {
        if {$options(tree_disp_pyra) == 0} {set tree_disp_pyra 0}
        if {$options(tree_disp_pyra) == 2} {set tree_disp_pyra 1}
    }
    
    set auto_simplify_geom $tdv_auto_simplify_geom  
    if {[info exists tdv_geom_simp] && $tdv_geom_simp != ""} {
        set geom_simp $tdv_geom_simp
    } else {
        set geom_simp [ic_geo_set_simplification_level -1]
        set ::tdv_geom_simp $geom_simp
    }
    before_set_options
    if {[$tdv_default get -gsys] == "X11" && $setDispGraphicsEGVal == 0} {
        set setDispGraphicsEGVal 1
    }
    variable enable_smooth_move
    set enable_smooth_move 0
    if [info exists tdv_enable_smooth_move] {
        set enable_smooth_move $tdv_enable_smooth_move
    }
}

proc onsetDisplayDEZAfterLoad {} {
    if {[trace vinfo auto_simplify_geom] != ""} {
        trace vdelete auto_simplify_geom w aie_trace_auto_simplify_geom
    }
    trace variable auto_simplify_geom w aie_trace_auto_simplify_geom
    aie_trace_auto_simplify_geom "" "" ""
}

proc onsetDisplayDEZUnLoad {} {

    if {[trace vinfo auto_simplify_geom] != ""} {
        trace vdelete auto_simplify_geom w aie_trace_auto_simplify_geom
    }
}

proc aie_trace_auto_simplify_geom {name element op} {
    if [setDisplayDEZ get auto_simplify_geom] {
        ::AIEnv::GUIManagement::ToggleGrey setSimpLevel 0
    } else {
        ::AIEnv::GUIManagement::ToggleGrey setSimpLevel 1
    }
}

proc onsetDisplayDEZOK {} {
    global auto_pick_mode options use_xwindows prev_use_xwindows
    global med_float_precision tdv_quadratic_accuracy med_index_base
    global tdv_home_shrink tdv_rubbox_overlay tdv_default
    global icon_size1 icon_size2 beta_mode options tdv_geom_simp
    global disable_overlay tdv_skip_visible_check env tdv_auto_simplify_geom
    global tdv_use_opengl_lighting tdv_enable_smooth_move tdv_current_viewer

    variable use_displist
    if {$use_displist} {
       if {$::tdv_use_opengl_feedback} {
          set ::tdv_control_display_lists 0x0fff
       } else {
          set ::tdv_control_display_lists 1
       }
       set ::tdv_use_opengl_lighting 1
    } else {
       set ::tdv_control_display_lists 0
       set ::tdv_use_opengl_lighting 0
    }
    
    foreach var {xhidden_full use_dlremote external_num icon_size uns_warn_user_if_display} {
	    set options($var) [set $var]
    }

    variable fit_percent
    if ![string is double -strict $fit_percent] {
       set fit_percent [expr round(100 * $::tdv_home_shrink)]
    } else {
       if {$fit_percent < 5} {set fit_percent 5}
       set ::tdv_home_shrink [expr $fit_percent/100.0]
    }

    set med_float_precision $med_float
    set tdv_quadratic_accuracy $tdv_quadratic
    set med_index_base $med_index
    set tdv_rubbox_overlay $rubbox_overlay

    variable disable_on_overlay
    set disable_overlay $disable_on_overlay
    if {$disable_overlay} {
       set env(ICEM_NO_OVERLAY) 1
    } else {
       if {[info exists env(ICEM_NO_OVERLAY)]} {unset env(ICEM_NO_OVERLAY)}
    }
    variable display_view_filter
    set tdv_skip_visible_check $display_view_filter

    if [info exists env(AI_ENV_IN_WIN)] {
        set use_xwindows 0
    } else {
        set use_xwindows $setDispGraphicsEGVal
    }
       
    if {$prev_use_xwindows != $use_xwindows} {
        mess "Note that changing the graphics type between OpenGL and X11\
                will affect subprograms started from ICEM CFD, and\
                also the next invocation of ICEM CFD,\
                but not the current invocation.\n" red
	    set prev_use_xwindows $use_xwindows
    }
    if {$icon_size == "Normal"} {
         set icon_size1 "24"
         set icon_size2 "35"
    }
    if {$icon_size == "Large"} {
         set icon_size1 "35"
         set icon_size2 "35"
    }
    if {$icon_size == "Huge"} {
         set icon_size1 "35"
         set icon_size2 "48"
    }
    
    if $tree_disp_line {set options(tree_disp_line) 2} else {set options(tree_disp_line) 0}
    if $tree_disp_node {set options(tree_disp_node) 2} else {set options(tree_disp_node) 0}
    if $tree_disp_tri {set options(tree_disp_tri) 2} else {set options(tree_disp_tri) 0}
    if $tree_disp_quad {set options(tree_disp_quad) 2} else {set options(tree_disp_quad) 0}
    if $tree_disp_hexa {set options(tree_disp_hexa) 2} else {set options(tree_disp_hexa) 0}
    if $tree_disp_tetra {set options(tree_disp_tetra) 2} else {set options(tree_disp_tetra) 0}
    if $tree_disp_penta {set options(tree_disp_penta) 2} else {set options(tree_disp_penta) 0}
    if $tree_disp_pyra {set options(tree_disp_pyra) 2} else {set options(tree_disp_pyra) 0}

    aie_changeMeshDisplay nodes
    aie_changeMeshDisplay enums
    
    set tdv_auto_simplify_geom $auto_simplify_geom
    if {$auto_simplify_geom == 1 && $geom_simp != ""} {
        ic_geo_set_simplification_level $geom_simp
        $tdv_default redraw
        set ::tdv_geom_simp $geom_simp
    }
    variable enable_smooth_move
    set tdv_enable_smooth_move $enable_smooth_move
    if $enable_smooth_move {
        bind $tdv_current_viewer <Double-Button-1> "tdv_smooth_move_double_click $tdv_current_viewer %x %y"
    } else {
        bind $tdv_current_viewer <Double-Button-1> ""
    }
    aie_set_options
}

proc onsetGeneralDEZLoad {} {
    global option_subtype options is_win env

    set option_subtype general

    # fix up possible problems
    array set optnames {
        ds,a82 ANSI-82
        ds,din DIN
        ds,d DIN
        pf,a Ascii
        pf,b Binary
        pf,a Ascii
        pf,b Binary
        pf,a ASCII
        pf,b BINARY
        um,e English
        um,m Metric
    }
    foreach o [array names options] {
        if [info exists optnames($o,$options($o))] {
            set options($o) $optnames($o,$options($o))
        }
    }
    if ![info exists env(EDITOR)] {
        if $is_win {
            set env(EDITOR) notepad
        } else {
            set env(EDITOR) vi
        }
    }
    if {$options(editor) == ""} {
        set options(editor) $env(EDITOR)
    }

    set editor $options(editor)
    set n_processors $options(n_processors)
    if {$options(temporary_directory) != ""} {
        set temporary_directory $options(temporary_directory)
    } else {
        set temporary_directory [ic_temp_dir]

    }
    set med_save_emergency_mesh $options(med_save_emergency_mesh)
    set med_save_emergency_tetin $options(med_save_emergency_tetin)
    set med_save_emergency_blocking $options(med_save_emergency_blocking)
    set auto_fix_uncovered_faces $options(auto_fix_uncovered_faces)
    set clean_up_tmp_files $options(clean_up_tmp_files)
    set record_journal $options(record_journal)
    set win_java_help $options(win_java_help)
    set keep_existing_file_names $options(keep_existing_file_names)
    set clear_undo $options(clear_undo)
    set auto_save_views $options(auto_save_views)
    set enable_idle $options(enable_idle)
    set replay_internal_editor $options(replay_internal_editor)
}

proc onsetGeneralDEZAfterLoad {} {
    if {[trace vinfo n_processors] != ""} {
        trace vdelete n_processors w aie_trace_n_processors
    }
    trace variable n_processors w aie_trace_n_processors
    if {$n_processors < [ic_get_n_processors]} {
        mess "Note: maximum number of processors is [ic_get_n_processors]\n"
    }
}

proc aie_trace_n_processors {{name ""} {element ""} {op ""}} {
    if {[setGeneralDEZ get n_processors] == "0"} {
        setGeneralDEZ set n_processors [ic_get_n_processors]
    }
}

proc onsetGeneralDEZOK {} {
    global options is_win env replay_main_box replay_editbox

    if {$n_processors == "0" || $n_processors == ""} { set n_processors [ic_get_n_processors] }
    if {$n_processors <= "0" || $n_processors == ""} { set n_processors 1 }
    if {$temporary_directory != ""} {
        set tmp [ic_temp_dir $temporary_directory]
        if {$tmp == ""} {
            mess "Resetting temporary directory to default\n"
            set temporary_directory [ic_temp_dir]
        } else {
            set temporary_directory [list $tmp]
        }
    }

    foreach var {editor n_processors temporary_directory med_save_emergency_mesh \
		med_save_emergency_tetin med_save_emergency_blocking \
		record_journal win_java_help clean_up_tmp_files auto_fix_uncovered_faces \
        keep_existing_file_names clear_undo auto_save_views enable_idle replay_internal_editor}  {
	    set options($var) [set $var]
    }
    if {[info exists replay_main_box] && [winfo exists [winfo parent $replay_main_box]]} {
        catch { replay_done; form_kill [winfo parent $replay_main_box]; unset replay_main_box; unset replay_editbox }
    }
    set env(EDITOR) $options(editor)
    aie_set_options
}

proc onsetGeneralDEZUnLoad {} {
    if {[trace vinfo n_processors] != ""} {
        trace vdelete n_processors w aie_trace_n_processors
    }
}

proc onsetMemoryDEZLoad {} {
    global option_subtype options gsys_display_list_max_size undo_max_memory undo_save_whole_mesh

    set option_subtype memory
    set max_list_size $gsys_display_list_max_size
    set max_binary_tetin $options(max_binary_tetin)
    set max_cad_map_size $options(max_cad_map_size)
    set max_mesh_map_size $options(max_mesh_map_size)
    set max_undo_memory $undo_max_memory
    set undo_whole_mesh $undo_save_whole_mesh
    set undo_logging $options(undo_logging)
}

proc onsetMemoryDEZOK {} {
    global option_subtype options undo_max_memory

    foreach var {max_binary_tetin max_cad_map_size max_mesh_map_size undo_logging} {
        set options($var) [set $var]
    }
    set undo_max_memory $max_undo_memory
    set undo_save_whole_mesh $undo_whole_mesh
    ic_undo_logging $options(undo_logging)
    ic_undo_enable_largeop $undo_save_whole_mesh

    set gsys_display_list_max_size $max_list_size
    aie_set_options
}

proc onsetRemoteDEZLoad {} {
    global option_subtype options

    foreach var {remote_host remote_user remote_path remote_acn remote_sh} {
        set $var [set options($var)]
    }
    set option_subtype remote
}

proc onsetRemoteDEZOK {} {
    global option_subtype options

    foreach var {remote_host remote_user remote_path remote_acn remote_sh} {
	set options($var) [set $var]
    }
    aie_set_options
}

proc onsetSpeedDEZLoad {} {
    global option_subtype options
    global geom_fast_dynamics med_fast_dynamics tdv_dynamics_speed_thresh

    set geom_fast_dyna $geom_fast_dynamics
    set med_fast_dyna $med_fast_dynamics
    set tdv_dynamics_speed $tdv_dynamics_speed_thresh
#    set geom_simp [ic_geo_set_simplification_level -1]
    set option_subtype speed
}

proc onsetSpeedDEZOK {} {
    global option_subtype options
    global geom_fast_dynamics med_fast_dynamics tdv_dynamics_speed_thresh
    global tdv_default

    set geom_fast_dynamics $geom_fast_dyna
    set med_fast_dynamics $med_fast_dyna
    set tdv_dynamics_speed_thresh $tdv_dynamics_speed
#    ic_geo_set_simplification_level $geom_simp
    $tdv_default redraw
    aie_set_options
}

proc onsetPrismMeshOptsDEZLoad {} {
    global prism_values
    foreach i { init_dir_from_prev min_prism_quality ortho_weight fillet max_prism_angle \
	max_aspect_ratio prism_height_limit ratio_multiplier \
	prism_extra_name prism_extra_value
    } {set $i $prism_values($i)}
}

proc onsetPrismMeshOptsDEZOK {} {
    global prism_values
    foreach i {init_dir_from_prev min_prism_quality ortho_weight fillet max_prism_angle \
	    max_aspect_ratio prism_height_limit ratio_multiplier prism_extra_name prism_extra_value} {
        set prism_values($i) [set $i]
    }
}

proc onsetQualityInfoDEZLoad {} {
    global options
    
    foreach qname [ic_uns_get_metric_names] {
        qualityInfoCMS unselect "$qname" "Criteria 1"
        qualityInfoCMS unselect "$qname" "Criteria 2"
    }

    foreach qname $options(quality_info) {
        qualityInfoCMS select "$qname" "Criteria 1"
        qualityInfoCMS select "$qname" "Criteria 2"
    }
    foreach {var val} {histo_show_default 1 histo_solid_default 1 \
                       histo_color_by_quality_default 1 evaluate_diagnostic 0} {
	    if [info exists options($var)] {
	        set $var [set options($var)]
	    } else {
	        set $var $val
	    }
    }
}

proc onsetQualityInfoDEZOK {} {
    global options
    
    set options(quality_info) ""

    foreach qname [ic_uns_get_metric_names] {
	    set on [qualityInfoCMS query "$qname" "Criteria 1"]
	    if {$on == -1} {
	        set on [qualityInfoCMS query "$qname" "Criteria 2" ]
	    }
	    if {$on == 1} {
	        lappend options(quality_info) "$qname"
	    }
    }
    set options(histo_show_default) $histo_show_default
    set options(histo_solid_default) $histo_solid_default
    set options(histo_color_by_quality_default) $histo_color_by_quality_default
    set options(evaluate_diagnostic) $evaluate_diagnostic
    aie_set_options
}

proc onsetDetailInfoDEZLoad {} {
    global options

    if [info exists options(detail_info)] {
	    set calc_mesh_edge_sides $options(detail_info)
    } else {
	    set calc_mesh_edge_sides 0
    }
}

proc onsetDetailInfoDEZOK {} {
    global options

    set options(detail_info) $calc_mesh_edge_sides
    aie_set_options
}

proc aie_mouse_bindings {} {
    setMouseBindingDEZ load
}

proc aie_set_options {} {
    global options use_xwindows
    global undo_max_memory undo_save_whole_mesh gsys_display_list_max_size
    global med_float_precision tdv_quadratic_accuracy med_index_base
    global geom_fast_dynamics med_fast_dynamics tdv_dynamics_speed_thresh
    global mesh_min_moving_element_aspect disp_options
    global auto_pick_mode product_mode beta_mode
    global tdv_mouse_bindings thickness_defined tdv_background_color tdv_lighting
    global tdv_control_display_lists tdv_use_opengl_feedback tdv_use_opengl_lighting
    global tdv_home_shrink tdv_show_ansys_logo gui_style_mode
    global tdv_use_dual_lighting tdv_auto_simplify_geom tdv_opengl_renormalizing
    global solver_setup_global tdv_rubbox_overlay map_tetin_sizes import_model_options
    global prompt_for_bld_topo prompt_for_bld_topo_opts named_sels_as_parts
    global icon_size1 icon_size2 allow_plane_selection allow_preview_name vid_options
    global disable_overlay tdv_skip_visible_check display_mesh_selection
    global hex_option tdv_geom_simp tdv_start_spaceball tdv_enable_smooth_move
    global geom_off_mode mesh_off_mode meshedit_off_mode hexa_off_mode preprocessing_off_mode output_off_mode
    
    # save only the defaults for the workbench reader
    aie_wb_set_import_defaults

    set file [home_directory]/.aienv_options
    set fp [open $file w]
    puts $fp "array set options \{ [array get options] \}"
    puts $fp "set use_xwindows $use_xwindows"
    puts $fp "set icon_size1 $icon_size1"
    puts $fp "set icon_size2 $icon_size2"
    puts $fp "set undo_max_memory $undo_max_memory"
    puts $fp "set undo_save_whole_mesh $undo_save_whole_mesh"
    puts $fp "set geom_fast_dynamics $geom_fast_dynamics"
    puts $fp "set med_fast_dynamics $med_fast_dynamics"
    puts $fp "set tdv_rubbox_overlay $tdv_rubbox_overlay"
    puts $fp "set tdv_dynamics_speed_thresh $tdv_dynamics_speed_thresh"
    if [info exist tdv_home_shrink] {
       puts $fp "set tdv_home_shrink $tdv_home_shrink"
    }
    puts $fp "set med_float_precision $med_float_precision"
    puts $fp "set tdv_quadratic_accuracy $tdv_quadratic_accuracy"
    puts $fp "set med_index_base $med_index_base"
    puts $fp "set disp_options(uns_cut_delay_count) $disp_options(uns_cut_delay_count)"
    puts $fp "set mesh_min_moving_element_aspect $mesh_min_moving_element_aspect"
    puts $fp "set auto_pick_mode $auto_pick_mode"
    if {[info exists product_mode] && $product_mode != ""} {
        puts $fp "set product_mode $product_mode"
    }
    puts $fp "set geom_off_mode $geom_off_mode"
    puts $fp "set mesh_off_mode $mesh_off_mode"
    puts $fp "set meshedit_off_mode $meshedit_off_mode"
    puts $fp "set hexa_off_mode $hexa_off_mode"
    puts $fp "set preprocessing_off_mode $preprocessing_off_mode"
    puts $fp "set output_off_mode $output_off_mode"
    puts $fp "set gui_style_mode $gui_style_mode"
    puts $fp "set beta_mode $beta_mode"
    if $beta_mode {
       puts $fp "set env(AI_ENV_BETA) 1"
    } else {
       puts $fp "if {\[info exists env(AI_ENV_BETA)\]} {unset env(AI_ENV_BETA)}"
    }
    puts $fp "set solver_setup_global $solver_setup_global"
    puts $fp "array set tdv_mouse_bindings \{ [array get tdv_mouse_bindings] \}"
    if [info exists tdv_background_color] {
	    puts $fp "set tdv_background_color \{$tdv_background_color\}"
    }
    puts $fp "set tdv_show_ansys_logo $tdv_show_ansys_logo"
    puts $fp "set tdv_start_spaceball $tdv_start_spaceball"
    foreach n {ambient diffuse specular shininess dir} {
       if [info exist tdv_lighting($n)] {
           puts $fp [list set tdv_lighting($n) $tdv_lighting($n)]
       }
    }
    puts $fp "set tdv_control_display_lists $tdv_control_display_lists"
    puts $fp "set tdv_use_opengl_feedback $tdv_use_opengl_feedback"
    puts $fp "set tdv_use_opengl_lighting $tdv_use_opengl_lighting"
    puts $fp "set tdv_auto_simplify_geom $tdv_auto_simplify_geom"
    if {[info exists tdv_geom_simp] && $tdv_geom_simp != ""} {
        puts $fp "set tdv_geom_simp $tdv_geom_simp"
    }
    if {[info exists tdv_enable_smooth_move] && $tdv_enable_smooth_move != ""} {
        puts $fp "set tdv_enable_smooth_move $tdv_enable_smooth_move"
    }
    puts $fp "set tdv_use_dual_lighting $tdv_use_dual_lighting"
    puts $fp "set tdv_skip_visible_check $tdv_skip_visible_check"
    if $disable_overlay {
       puts $fp "set env(ICEM_NO_OVERLAY) 1"
    } else {
       puts $fp "if {\[info exists env(ICEM_NO_OVERLAY)\]} {unset env(ICEM_NO_OVERLAY)}"
    }
    puts $fp "set prompt_for_bld_topo $prompt_for_bld_topo"
    puts $fp "set prompt_for_bld_topo_opts $prompt_for_bld_topo_opts"
    puts $fp "set named_sels_as_parts $named_sels_as_parts"
    puts $fp "set allow_plane_selection $allow_plane_selection"
    if [info exist display_mesh_selection] {
        puts $fp "set display_mesh_selection $display_mesh_selection"
    }
    if [info exist allow_preview_name] {
       puts $fp "set allow_preview_name $allow_preview_name"
    }
    puts $fp "array set vid_options \{ [array get vid_options] \}"
    puts $fp "array set hex_option \{ [array get hex_option] \}"
    puts $fp "array set map_tetin_sizes  \{ [array get map_tetin_sizes] \}"
    puts $fp "array set import_model_options  \{ [array get import_model_options] \}"
    
    close $fp
    aie_wb_reset_import_defaults
    mess "Saved options to \"$file\"\n" blue
}

proc aie_get_tree_display_options {type} {
    global aie_meshTypeVis options
    if [info exists options(tree_disp_$type)]  {
       return $options(tree_disp_$type)
    } else {
       return $aie_meshTypeVis($type)
    }
}

proc aie_reset_project_defaults {} {
    switch -- [tk_dialog .reset_def Settings "Reset Project settings to Defaults?" "" -1 Yes No Cancel] {
        -1 { if [winfo exists .reset_def] { top_destroy .reset_def; return } }
	    0 { project_settings_reset_defaults }
	    1 - 2 { return }
    }
    mess "Project settings reset to Defaults\n" blue
}

proc aie_restore_project_defaults {} {
    global use_xwindows program_path
    set optf [home_directory]/.aienv_options
    if ![file exists $optf] return
    set use_xwindows_set $use_xwindows
    if [catch {uplevel \#0 [list source $optf]} res] {
        mess "$res\n" red
    }
    if $use_xwindows_set {
        set use_xwindows $use_xwindows_set
    }
    ic_gui_set vid_options(replace) 0
    mess "Project settings restored from $optf\n" blue
}

proc aie_save_hexa_controls {file} {
    global index_min index_max saved_index_controls
    if ![ic_hex_blocking_loaded] { return 0 }
    if ![array exists saved_index_controls] { return 0 }
    set fp [open $file w]
    puts $fp "array set saved_index_controls [list [array get saved_index_controls]]"
    close $fp
    return 1
}

proc aie_undo {{redo 0}} {
    global index_form aie_SurfStyle batch_mode aie_CurveColorByCount
    global undo_is_running fam_visible aie_ShowDormant
    global fam_visible_color plot_window histo_crit
    global tdv_waiting_for_click tdv_default
    global hexa_select select_action

    if [info exists undo_is_running] return
    set undo_is_running 1

    set prev_ijkmax ""
    set blocking_is_loaded 0
    if [ic_hex_blocking_loaded] {
        # clear if in selection mode
        if [info exists hexa_select] {
	        set select_action done
	        catch { unset hexa_select }
        }
        if [info exists tdv_waiting_for_click($tdv_default)] {
	        set tdv_waiting_for_click($tdv_default) {2 0 0}
        }
        set prev_ijkmax [ic_hex_ijk_max]
        aie_hex_update_index_form 1
        set blocking_is_loaded 1
    }
    set non_empty_before [aie_get_non_empty_parts]
    
    set invisible ""
    if [ic_geo_is_loaded] {
        if !$redo {
            set invisible [ic_geo_get_temporary_invisible entity]
        }
    }
    
    set histo_is_running 0
    if {[ic_uns_is_loaded] && [info exists histo_crit]} {
        if {[info exists plot_window] && [winfo exists $plot_window.graph]} {
            set histo_is_running 1
        }
    }
    
    tdv_active 0
    
    if $redo {
        if {[ic_redo] == "1"} {
            unset undo_is_running
            aie_after_undo
            tdv_active 1
            return
        }
    } else {
        if {[ic_undo] == "1"} {
            unset undo_is_running
            aie_after_undo
            tdv_active 1
            return
        }
    }
    
    set non_empty_after [aie_get_non_empty_parts]
    foreach p $non_empty_before {
        if {[lsearch $non_empty_after $p] < 0} {
            ::AIEnv::GUIManagement::Tree::DeleteGroup part $p 1
            # part is deleted in the tree, but fam_visible(part_name) still exists
            if [info exists fam_visible($p)] {
                if {$p == "VORFN" || $p == "ORFN"} continue
                unset fam_visible($p)
            }
        }
    }
    foreach p $non_empty_after {
        if {[lsearch $non_empty_before $p] < 0} {
            if [info exists fam_visible_color($p)] {
                if {$p == "VORFN" || $p == "ORFN"} continue
                aie_color_part $p $fam_visible_color($p)
                unset fam_visible_color($p)
            }
        }
    }

    aie_update_parts_vis 0
    aie_create_parts_in_tree_if_needed
    aie_update_parts_in_tree_if_needed
    set types ""
    foreach "type type2" "Point point Curve curve Surf surface Body body Density density" {
        if [::AIEnv::GUIManagement::Tree::NodeVisibility geom${type}Node] {
            lappend types $type2
        }
    }

    if {[ic_geo_is_loaded] && $invisible != ""} {
        foreach entity $invisible {
            ic_geo_temporary_visible [lindex $entity 0] [lindex $entity 1] 0
        }
    }
    
    aie_updateGeoVis $types
    aie_updateMeshVis

    tdv_active 1

    set cur_ijkmax ""
    if [ic_hex_blocking_loaded] {
        set cur_ijkmax [ic_hex_ijk_max]
        if {"$cur_ijkmax" != "$prev_ijkmax"} {
            set update_index 3
        } else {
            set update_index 0
        }
        aie_hex_update_index_form 0 $update_index
        if $update_index { index_reset }
        if {![info exists index_form] || ![winfo exists $index_form]} {
            hex_update_display
        }
    } else {
        if $blocking_is_loaded {
            aie_after_close_blocking
        }
    }
    aie_after_undo
    if {[ic_uns_is_loaded] && $histo_is_running} {
        aie_smooth_update_histogram $histo_crit
    }
    unset undo_is_running
}

proc aie_after_undo {} {
    global index_form aie_SurfStyle batch_mode aie_CurveColorByCount
    global undo_is_running fam_visible aie_ShowDormant
    global fam_visible_color

    if [ic_geo_is_loaded] {
        # Needed after redo/undo to update the display of surfaces
        if [::AIEnv::GUIManagement::Tree::NodeVisibility geomSurfNode] {
            foreach style {wire flat_wire solid flat} {
                if {[info exists aie_SurfStyle($style)] && $aie_SurfStyle($style)} {
                    ic_geo_configure_one_attribute surface shade $style
                    break
                }
            }
        }
        # Needed after redo/undo to update the display of curves for color by count
        if [::AIEnv::GUIManagement::Tree::NodeVisibility geomCurveNode] {
            if {[info exists aie_CurveColorByCount] && $aie_CurveColorByCount} {
                ic_geo_configure_one_attribute curve color_by_count 1
            }
        }
        # Needed after redo/undo to update the display of dormant points/curves
        foreach "type type2" {point Point curve Curve} {
            if ![::AIEnv::GUIManagement::Tree::NodeVisibility geom${type2}Node] continue
            if {[info exists aie_ShowDormant($type)] && $aie_ShowDormant($type)} {
                ::AIEnv::GUIManagement::Tree::ShowDormant $type
            }
        }
    }
}

proc aie_get_non_empty_parts {} {
    set non_empty ""
    foreach t "geo uns hex" {
        foreach p [ic_${t}_non_empty_families] {
            if ![info exists tmp($p)] {
                lappend non_empty $p
                set tmp($p) 1
            }
        }
    }
    return "$non_empty"
}

proc aie_undo_clear {} {
    ic_undo_clear
    ic_undo_start
}

proc aie_clear_dez {} {
    if { $::AIEnv::GUIManagement::ActiveDEZ != "NULL" } {
        $::AIEnv::GUIManagement::ActiveDEZ unload
    }
}

proc aie_reset_geo_selected {} {
    global va_set

    # remove any highligted points
    foreach name [array names va_set] {
	if [regexp im_+ $name] {
	    $va_set($name) delete; unset va_set($name)
	}
    }
    ic_reset_geo_selected
}

proc aie_print_file {file} {
    global aie_print is_win

    if ![info exists aie_print(cmd)] {
	if $is_win {
	    set aie_print(cmd) print
	} else {
	    set aie_print(cmd) lp
	}
    }

    if ![file exists $file] {
	mess "Couln't find file: $file for Printing\n" red
	return
    } else {
	set aie_print(file) $file
    }

    set buts [list [list OK "aie_print_file_doit"]  cancel]
    set d [form_init .print_file "Print file" "" $buts]
    if {$d != ""} {
	form_label $d.pl "Print Command" {0 1}
	form_entry $d.pe aie_print(cmd) string {0 2}
	form_finish  middle 1 1
    }
}

proc aie_print_file_doit {} {
    global aie_print

    if [catch {eval ic_exec "$aie_print(cmd) $aie_print(file)"} res] {
	mess "$res\n" red
    } else {
	mess "Sending to printer...\n" blue
    }

    form_done  .print_file
}

proc aie_set_title {string} {
    global AppName Version batch_mode use_workbench

    if $batch_mode return

    set string "$AppName $Version : $string"
    top_title . $string

    if { [info exist use_workbench] && $use_workbench } {
        if [catch { AIEWBSendToWBScript "AIESetTabName" } err ] {
            mess "err = $err\n"
        }
    }
}

proc aie_measure_distance {} {
    while {[med_check_distance] != ""} {
    }
}

proc aie_measure_angle {} {
    while {[med_check_angle] != ""} {
    }
}

proc aie_location {} { med_check_location }


# Sometimes 'c' gets set as a hot key - this is to avoid an error
proc do_center {args} {}


proc aie_thickness {what {from_solid 0} {parts ""} } {
    global thickness_defined
    set d2_fam_list [ic_uns_list_families 2]
    if { $d2_fam_list == "" } return
    switch $what {
	create { 
           set surfs ""
	   if {$from_solid != 0} {
             foreach p $parts {
                 eval lappend surfs [ic_geo_get_objects surface $p]
	     }
	   }
	   ic_uns_thickness create all 0 1 $from_solid $surfs
	   set thickness_defined 1
	}
	clear { 
	   ic_uns_thickness clear 
	   set thickness_defined 0
	}
    }
    # Grab the parameters from the element properties
    aie_update_shell_thicknesses
}

proc aie_update_shell_thicknesses {{part_names ""} {m_thick ""}} {
    if {$part_names == ""} {
        foreach pp [ic_boco_list_with_bctype ISHE *:*] {
            lappend part_names [lindex $pp 0]
        }
    }
    
    foreach part $part_names {
        if {$m_thick == ""} {
            set val ""
            foreach {n v} [aie_parse_bcs_element_prop_2d [ic_boco_get $part ISHE]] {
                if {$n == "m_thick"} { set val $v; break }
            }
            if {$val == ""} continue
        } else {
            set val $m_thick
        }
        if !$val continue
        set fams [ic_geo_list_families_in_part $part]
        set ss [ic_uns_subset_create_family_type $fams 2d 0 0]
        if {$ss != ""} {
            # This sets the thickness with priority 0 so that it doesn't overwrite
            # distributed values
            ic_uns_thickness set_part $ss $val
            ic_uns_subset_delete $ss
        }
    }
}

proc aie_update_icons {{type all}} {
    global toolBarInfo mesh_icons strmesh_icons geom_icons bc_icons block_icons output_icons
    global bc_mesh_icons non_nastran_icons lsdyna_icons
    global solver_setup solver_setup_global

    if {$solver_setup != "-1"} {
       set solve_format $solver_setup
    } else {
       set solve_format $solver_setup_global
    }

    if {[info command aie_update_v3gui_states] != ""} {
       aie_update_v3gui_states
    }

    if {$type == "mesh" || $type == "all"} {
	    if [ic_uns_is_loaded] {
	        if {[ic_uns_non_empty_families] != ""} {
	            set state normal
	        } else {
	            set state disable
	        }
	    } else {
	        set state disable
	    }

	    foreach but $mesh_icons {
	        catch { # it might not be there in 4cfx or whatever
		        $toolBarInfo(widget,$but) configure -state $state
	        }
	    }		
	
	    if [ic_str_is_loaded] {
	        set state normal
	        foreach but $strmesh_icons {
		        catch {
		            $toolBarInfo(widget,$but) configure -state $state
		        }
	        }
	        # Turn off create elem but
	        set but createElem2But
	        $toolBarInfo(widget,$but) configure -state disable
	    }
    }

    # Move here is better than in aie_afterStuffLoaded to update Distributed Properties
    if {$type == "mesh" || $type == "all"} {
	    if {[ic_uns_is_loaded] && [ic_uns_non_empty_families] != ""} {
	        catch {
	            # FIXME : need to have some kind of app_afterStuffLoaded
	            aie_update_shell_thicknesses
	            aie_update_bar_orientations
	            aie_update_bar_end_release
	            aie_update_pcomp_pid
	        }
        }
    }

    if {$type == "geom" || $type == "all"} {
	    # projlib is created always for some reason
	    if [ic_geo_is_loaded] {
	        set state normal
	    } else {
	        set state disable
	    }

	    foreach but $geom_icons {
	        catch { # it might not be there in 4cfx or whatever
                $toolBarInfo(widget,$but) configure -state $state
	        }
	    }
    }
    
    if {$type == "block" || $type == "all"} {
	    if [ic_hex_blocking_loaded] {
	        set state normal
	    } else {
	        set state disable
	    }

	    foreach but $block_icons {
	        catch { # it might not be there in 4cfx or whatever
		        $toolBarInfo(widget,$but) configure -state $state
	        }
	    }
    }
    
    if {[ic_geo_is_loaded] || [ic_uns_is_loaded]} {
	    set state normal
    } else {
	    set state disabled
    }
    foreach but [concat $bc_icons meshTetBut] {
        set state_new $state
	    if {[lsearch $non_nastran_icons $but] >= 0} {
	        if {$state == "normal"  && ($solve_format != "0")} {
	            set state_new normal
	        } else {
	            set state_new disabled
	        }
	    }
	    if {[lsearch $lsdyna_icons $but] >= 0} {
	        if {$state == "normal"  && ($solve_format == "2" || $solve_format == "4")} {
	            set state_new normal
	        } else {
	            set state_new disabled
	        }
	    }
	    catch {
	        $toolBarInfo(widget,$but) configure -state $state_new
	    }
    }

    # These are controlled by both geometry and mesh
    if {[ic_geo_is_loaded] && [ic_uns_is_loaded]} {
	    set state normal
    } else {
	    set state disabled
    }
    foreach but {meshPrismBut} {
	    catch {
	        $toolBarInfo(widget,$but) configure -state $state
	    }
    }

    # These are controlled by geometry or mesh (structured and unstructered)
    if {[ic_geo_is_loaded] || [ic_uns_is_loaded] || [ic_str_is_loaded]} {
	    set state normal
    } else {
	    set state disabled
    }
    foreach but $output_icons {
	    catch {
	        $toolBarInfo(widget,$but) configure -state $state
	    }
    }

    if {[ic_uns_is_loaded]} {
	    set state normal
    } else {
	    set state disabled
    }
    foreach but $bc_mesh_icons  {
        set state_new $state
	    if {[lsearch $non_nastran_icons $but] >= 0} {
	        if {$state == "normal"  && ($solve_format != "0")} {
	            set state_new normal
	        } else {
	            set state_new disabled
	        }
	    }
	    if {[lsearch $lsdyna_icons $but] >= 0} {
	        if {$state == "normal"  && ($solve_format == "2" || $solve_format == "4")} {
	            set state_new normal
	        } else {
	            set state_new disabled
	        }
	    }
	    catch {
	        $toolBarInfo(widget,$but) configure -state $state_new
	    }
    }
    
    aie_update_tabs
}

proc aie_update_tabs {} {
    global toolBarInfo bc_icons have_mesher_license
    global bc_mesh_icons non_nastran_icons lsdyna_icons
    global solver_setup solver_setup_global beta_mode

    if {$solver_setup != "-1"} {
       set solve_format $solver_setup
    } else {
       set solve_format $solver_setup_global
    }

    set tab $::AIEnv::GUIManagement::CurrentVisibleTab

    switch $tab {
	    StructMeshBar {
	        # this check is NOT done by launch script
	        if 1 {
		        set but createBlock
		        set state normal
		        if {![ic_geo_is_loaded] && ![ic_hex_blocking_loaded]} {
		            set state disable
		            if [aie_hex_sketching_mode] {
		                set state normal
		            }
		        }
		        catch { $toolBarInfo(widget,$but) configure -state $state }
	        }
	    }
	    elemSetupBar - constraintBar - loadBar - solveOptsBar {
	    if {[ic_geo_is_loaded] || [ic_uns_is_loaded]} {
	       set state normal
	    } else {
	       set state disable
	    }
	    foreach but $bc_icons {
                 set state_new $state
                 if {[lsearch $non_nastran_icons $but] >= 0} {
                   if {$state == "normal"  && ($solve_format != "0")} {
	              set state_new normal
                    } else {
                       set state_new disabled
                    }
                 }
                 if {[lsearch $lsdyna_icons $but] >= 0} {
                   if {$state == "normal"  && ($solve_format == "2" || $solve_format == "4")} {
	                    set state_new normal
                    } else {
                       set state_new disabled
                    }
                 }
	        catch { $toolBarInfo(widget,$but) configure -state $state_new }
	    }
	    if {[ic_uns_is_loaded]} {
	       set state normal
	    } else {
	       set state disabled
	    }
	    foreach but $bc_mesh_icons {
                 set state_new $state
                 if {[lsearch $lsdyna_icons $but] >= 0} {
                   if {$state == "normal"  && ($solve_format == "2" || $solve_format == "4")} {
	                    set state_new normal
                    } else {
                        set state_new disabled
                    }
                }
	            catch {$toolBarInfo(widget,$but) configure -state $state_new}
	    }
	}
	cart3DBar {
	     #aie_cart3d_update
	     }
         OutputBar {
             if {[info exists env(AI_ENV_CFD)] && ![info exists env(AI_ENV_CFX)]} {
	            aie_outputtab_update
             }
         }
    }
}

proc aie_sync_tabs_viewer {tab} {
    global tdv_default tdv_current_viewer

 #  set tab $::AIEnv::GUIManagement::CurrentVisibleTab
    if {![info exist tdv_current_viewer] || ![info exist tdv_default] || \
        ![winfo exist $tdv_current_viewer] || ![winfo exist $tdv_default]} {
       return ""
    }
    if {$tab != "postBar"} {
       if {$tdv_current_viewer != $tdv_default} {
          workspace_add $tdv_default
          set tdv_current_viewer $tdv_default
       }
    } else {
       if {$tdv_current_viewer == $tdv_default} {
          global dset_info
          foreach {n w} [array get dset_info *,gwin] {
             if [winfo exist $w] {
                workspace_add $w
                set tdv_current_viewer $w
                return
             }
          }
       }
    }
}

proc aie_sync_tabs_viewer {tab} {
    global tdv_default tdv_current_viewer

 #  set tab $::AIEnv::GUIManagement::CurrentVisibleTab
    if {![info exist tdv_current_viewer] || ![info exist tdv_default] || \
        ![winfo exist $tdv_current_viewer] || ![winfo exist $tdv_default]} {
       return ""
    }
    if {$tab != "postBar"} {
       if {$tdv_current_viewer != $tdv_default} {
          workspace_add $tdv_default
          set tdv_current_viewer $tdv_default
       }
    } else {
       if {$tdv_current_viewer == $tdv_default} {
          global dset_info
          foreach {n w} [array get dset_info *,gwin] {
             if [winfo exist $w] {
                workspace_add $w
                set tdv_current_viewer $w
                return
             }
          }
       }
    }
}

proc aie_renumber_everything {} {
    global renumber_stuff
    set w [form_init .renumber_stuff "Renumber nodes and elements"]
    if {$w != ""} {
	array set renumber_stuff {
	    nodes 1 elems 1 nodes_num 1 elems_num 1
	}
	form_checkbutton $w.nodes "Renumber nodes starting at:" \
	    renumber_stuff(nodes) {0 0}
	form_checkbutton $w.elems "Renumber elements starting at:" \
	    renumber_stuff(elems) {1 0}
	form_entry $w.nodesn renumber_stuff(nodes_num) int {0 1} renumber_stuff(nodes)
	form_entry $w.elemsn renumber_stuff(elems_num) int {1 1} renumber_stuff(elems)
	form_finish +200+200
    }
    if [form_wait .renumber_stuff] {
	if $renumber_stuff(nodes) {
	    ic_uns_renumber_nodes all $renumber_stuff(nodes_num)
	}
	if $renumber_stuff(elems) {
	    ic_uns_renumber_elements all $renumber_stuff(elems_num)
	}
    }
}


proc ai_shade_all {{type full} {flat 0}} {
    global aie_SurfStyle aie_blockMeshStyle display_flag
    global scan_solid
    switch $type {
	
	    full-wire {
		tdv_active 0
		aie_changeMeshDisplay style Solid/wire
		set aie_SurfStyle(solid) 1
		set aie_SurfStyle(flat_wire) 1
		aie_changeSurfStyle flat_wire
		set aie_SurfStyle(simpval) detailed
		aie_changeSurfStyle simpval	
		set aie_blockMeshStyle(2) 1	
		aie_change_meshstyle 2
		set display_flag(block_solid) 1
		hex_update_display block			
		set scan_solid 1
		scan_update all
		tdv_active 1
	    }	    	    
	    full {    
		tdv_active 0
		
		global tdv_current_viewer tdv_default
		if {[info exist tdv_default] && \
			[winfo exist $tdv_default]} {
		    $tdv_default configure -draw_trias_flat $flat
		}
		
		aie_changeMeshDisplay style Solid/wire
		if {$flat} {
			set aie_SurfStyle(flat) 1
			aie_changeSurfStyle flat
		    } else {
			set aie_SurfStyle(solid) 1
			aie_changeSurfStyle solid
		    }
		    set aie_SurfStyle(simpval) detailed
		    aie_changeSurfStyle simpval	
		    set aie_blockMeshStyle(2) 1	
		    aie_change_meshstyle 2 			
		    set display_flag(block_solid) 1
		    hex_update_display block			
		    set scan_solid 1
		    scan_update all
		    tdv_active 1
		}
		default {
		    tdv_active 0
		    aie_changeMeshDisplay style Solid/wire
		    set aie_SurfStyle(solid) 1
		    aie_changeSurfStyle solid
		    set aie_SurfStyle(simpval) simple
		    aie_changeSurfStyle simpval
		    set aie_blockMeshStyle(2) 1	
		    aie_change_meshstyle 2			
		    set display_flag(block_solid) 1
		    hex_update_display block			
		    set scan_solid 1
		    scan_update all
		    tdv_active 1
		}
	}			
	
    	
}

proc ai_wire_all {{type full}} {
    global aie_SurfStyle aie_blockMeshStyle display_flag
    global scan_solid

    switch $type {
	
		full {  
		    tdv_active 0    
		    aie_changeMeshDisplay style Wire
		    set aie_SurfStyle(wire) 1
		    aie_changeSurfStyle wire
		    set aie_SurfStyle(simpval) detailed
		    aie_changeSurfStyle simpval
		    set aie_blockMeshStyle(1) 1
		    aie_change_meshstyle 1			
		    set display_flag(block_solid) 0
		    set scan_solid 0
		    hex_update_display block			
		    scan_update all
		    tdv_active 1
		}
		default {
		    tdv_active 0
		    aie_changeMeshDisplay style Wire
		    set aie_SurfStyle(wire) 1
		    aie_changeSurfStyle wire
		    set aie_SurfStyle(simpval) simple
		    aie_changeSurfStyle simpval
		    set aie_blockMeshStyle(1) 1
		    aie_change_meshstyle 1			
		    set display_flag(block_solid) 0
		    set scan_solid 0
		    hex_update_display block			
		    scan_update all
		    tdv_active 1
		}			
	}
		
		
}

proc onmeshReportDEZLoad {} {
    global file_name AppName
    
    set project_dir $file_name(project_dir)
    if {"." == $project_dir} {
	    set project_dir [pwd]
    }

    set project_name [file root [file tail $file_name(settings)]]
    if {("" == $project_name) || ("." == $project_name)} {
        if {[ic_uns_is_loaded] != 0} {
            set project_name [file root [lindex [file split $file_name(domain)] end]]
       } else {
            mess "Mesh file is not loaded\n" red
            return
       }   
    }
       
    set report_file "mesh_report_[string tolower [string map {" " "_"} [clock format [clock seconds]]]].html"
    if {$project_name == ""} {set project_name "mesh_report"}
    set report_file "$project_name.html"
    set meshQualReportName [file join $project_dir $report_file]
    
    set meshQualReportFormat "HTML"
    
    set meshQualReportScope "All" ;# the subset name for now -- fixme!!
    
    set meshReportTitle "$project_name mesh report"
    set meshReportAuth  [cmd_whoami]
    
    set meshReportWriteSumm 1
    set meshReportWriteQual 1
    set meshReportQualAllTypes 0
    set meshReportWriteDiag 1
    set meshReportMeshTypes all
}

proc onmeshReportDEZAfterLoad {} {
    global diagTypesReport
    
    set diagTypesReport ""
    if ![ic_uns_is_loaded] {
        meshReportDEZ unload
        return
    }
    if [meshReportDEZ get meshReportWriteQual] {
        ::AIEnv::GUIManagement::ToggleGrey checkMeshReportWriteQualAll 0
    } else {
        ::AIEnv::GUIManagement::ToggleGrey checkMeshReportWriteQualAll 1
    }
    if {[trace vinfo meshReportMeshTypes] != ""} {
        trace vdelete meshReportMeshTypes w aie_trace_meshReportMeshTypes
    }
    trace variable meshReportMeshTypes w aie_trace_meshReportMeshTypes
    aie_trace_meshReportMeshTypes "" "" ""
}

proc aie_trace_meshReportMeshTypes {{name ""} {element ""} {op ""}} {
    global diagTypesReport
    
    if {[meshReportDEZ get meshReportMeshTypes] == "all"} {
        checkMeshReportMS clear
    } else {
        set etypes [ic_uns_list_types]
        set types ""
        foreach et $etypes {
            if [regexp NODE $et] continue
            lappend types $et
        }
        checkMeshReportMS clear
        checkMeshReportMS set -key "rowLabel" $types
        checkMeshReportMS set -key "columnLabel" [list "Yes" "No"]
        checkMeshReportMS set -key "title" "Mesh types to check"
        checkMeshReportMS set -key "rowExclusive" 1
        checkMeshReportMS build
        set ::diagTypesReport [join $types]
        foreach row $types {
	        if {([regexp LINE $row]) || ([regexp BAR $row])} {
		        checkMeshReportMS select $row No
	        } else {
		        checkMeshReportMS select $row Yes
	        }
        }
    }
}

proc onmeshReportDEZApply {} {
    global file_name AppName Version
    global help_program diagTypesReport
      
     if {"" == $meshQualReportName} {
	    # nb: these three lines exist verbatim in onmeshReportDEZLoad --jka
	    set project_dir $file_name(project_dir)
	    set report_file "mesh_report_[string tolower [string map {" " "_"} [clock format [clock seconds]]]].[string tolower $meshQualReportFormat]"
	    set meshQualReportName [file join $project_dir $report_file]
    }     
    if [file exists $meshQualReportName] {
	    set opt [tk_dialog .meshreportOverwrite "Already Exists" "Warning: File $meshQualReportName already exists!" "" -1 "Don't overwrite" "Overwrite"]
	    switch -- $opt {
	        -1 { if [winfo exists .meshreportOverwrite] { top_destroy .meshreportOverwrite; return } }
	        0 {
	            mess "Choose new name for mesh quality report.\n" red
	            return
	        }
	    }
    }    
    set mesher "$AppName $Version"       
    set args "All [list $meshQualReportName] -format $meshQualReportFormat -mesher \"$mesher\""

    if {0 < $meshReportTitle} {
	    append args " -title \"$meshReportTitle\""
    }
    if {0 < $meshReportAuth} {
	    append args " -user \"$meshReportAuth\""
    } else { append args " __NONE__" }
    
    if {0 < $meshReportWriteQual} {
        if {$meshReportMeshTypes != "all"} {
            set types ""
            set fams ""
            foreach row $::diagTypesReport {
	            if [checkMeshReportMS query $row Yes] {
	                lappend types $row
	            }
            }
            foreach f [ic_uns_list_families] { lappend fams $f }
            ic_uns_subset_delete do_select_map_report
            set map [ic_uns_subset_create do_select_map_report 0]
            ic_uns_subset_configure $map -list_type 1
            ic_uns_update_family_type $map $fams $types update 1  
            set tmap [ic_uns_subset_create] 
            ic_uns_subset_copy_verts $tmap all
            ic_uns_subset_add_from $map $tmap
            ic_uns_subset_delete $tmap
            append args " -write_quality Selected -map $map"           
        } else {
	        append args " -write_quality All"
	    }
    } else {
        append args " -write_quality __NONE__"
    }
    
    if {0 < $meshReportQualAllTypes} {
	    append args " -write_quality_all All"
    } else {
        append args " -write_quality_all __NONE__"
    }
    
    if {0 < $meshReportWriteSumm} {
	    append args " -write_summary All"
    } else { append args " -write_summary __NONE__" }
    
    if {0 < $meshReportWriteDiag} {
	    append args " -write_diagnostics All"
    } else { append args " -write_diagnostics __NONE__" }
    
    if [catch { eval ic_reports_write_mesh_report $args } res] {
	    mess "Error: $res\n" red
    }
    if {("" != $meshQualReportName) && [file exists $meshQualReportName]} {
	    if ![info exists help_program] {help_setup}
	    help_url $meshQualReportName
    }
    if {0 < $meshReportWriteQual && $meshReportMeshTypes != "all"} {
        ic_uns_subset_delete do_select_map_report
    }
}

proc onmeshReportDEZUnLoad {} {
    if {[trace vinfo meshReportMeshTypes] != ""} {
        trace vdelete meshReportMeshTypes w aie_trace_meshReportMeshTypes
    }
}

proc onsetProductDEZLoad {} {
    global product_mode beta_mode gui_style_mode env
    global geom_off_mode mesh_off_mode meshedit_off_mode hexa_off_mode preprocessing_off_mode output_off_mode
    
    if [info exists env(AI_NO_GEOM)] {
        set geom_off_mode $env(AI_NO_GEOM)
    }
    if [info exists env(AI_NO_MESH)] {
        set mesh_off_mode $env(AI_NO_MESH)
    }
    if [info exists env(AI_NO_MESHEDIT)] {
        set meshedit_off_mode $env(AI_NO_MESHEDIT)
    }
    if [info exists env(AI_NO_BLOCKING)] {
        set hexa_off_mode $env(AI_NO_BLOCKING)
    }
    if [info exists env(AI_NO_PREPROCESSING)] {
        set preprocessing_off_mode $env(AI_NO_PREPROCESSING)
    }
    if [info exists env(AI_NO_OUTPUT)] {
        set output_off_mode $env(AI_NO_OUTPUT)
    }
    if [info exists env(AI_ENV_BETA)] {
        set beta_mode $env(AI_ENV_BETA)
    }

    set geom_on_mode [expr !$geom_off_mode]
    set mesh_on_mode [expr !$mesh_off_mode]
    set meshedit_on_mode [expr !$meshedit_off_mode]
    set hexa_on_mode [expr !$hexa_off_mode]
    set preprocessing_on_mode [expr !$preprocessing_off_mode]
    set output_on_mode [expr !$output_off_mode]
    
    set gui_style_on_mode $gui_style_mode
    set beta_on_mode $beta_mode
}

proc onsetProductDEZOK {} {
    global product_mode beta_mode gui_style_mode env
    global tdv_background_color tdv_show_ansys_logo is_win
    global geom_off_mode mesh_off_mode meshedit_off_mode hexa_off_mode preprocessing_off_mode output_off_mode
    
    set geom_off_mode [expr !$geom_on_mode]
    set mesh_off_mode [expr !$mesh_on_mode]
    set meshedit_off_mode [expr !$meshedit_on_mode]
    set hexa_off_mode [expr !$hexa_on_mode]
    set preprocessing_off_mode [expr !$preprocessing_on_mode]
    set output_off_mode [expr !$output_on_mode]

    set style_changed 0
    if {$gui_style_mode != $gui_style_on_mode} {
        set style_changed 1
    } 
    set gui_style_mode $gui_style_on_mode

    set beta_mode $beta_on_mode
    if $beta_mode {
       set env(AI_ENV_BETA) 1
    } else {
       if {[info exists env(AI_ENV_BETA)]} {
            unset env(AI_ENV_BETA)
        }
    }

    if $style_changed {
        if {$gui_style_mode == "wb"} {
            set tdv_background_color {1 #6688dd #ffffff}
            set tdv_show_ansys_logo 1
            if !$is_win {
                global tdv_current_viewer
                set_cursor $tdv_current_viewer arrow
            }
            ::AIEnv::GUIManagement::ConfigureConsoleZone 0
        } else {
            set tdv_background_color {0 #000000 #000000}
            set tdv_show_ansys_logo 0
            ::AIEnv::GUIManagement::ConfigureConsoleZone 1
        }
        setBackgroundStyleDEZ build
        setBackgroundStyleDEZ apply
    }

    aie_set_options

    set fn [::AIEnv::GUIManagement::FindValidCache]
    if [file exists $fn] {
       mess "Removing GUI caches $fn\n" blue
       if [catch {file delete $fn} fn_err] {
          mess "$fn_err\n" red
       }
    }
}

proc aie_edit_array {arr {action ""}} {
# Note: this is a generic version of aie_vid_show; 
# still have some unnecessary "extras"
# Function returns 1 on "Apply" i.e. on settings new values, otherwice 0
# Assuming global array "arr" 
#
	set w .aie_edit_array
	global $arr aie_edit_array_def
	if ![array exists $arr] {
		ic_mess "Not found array $arr\n" red
		if [winfo exists $w] {destroy $w}
		return 0
	}
	set list [lsort -dictionary [array names $arr]]

	if [winfo exists $w] {
		if {$action == "apply"} {
			foreach name $list {
				if ![info exists aie_edit_array_def($name)] continue
				set ${arr}($name) $aie_edit_array_def($name)
			}
			destroy $w
# keep global aie_edit_array_def as a "flag" that arr was modified
			return 1
		}
		if {$action == "cancel"} {
			destroy $w
			unset aie_edit_array_def
			return 0
		}			
		destroy $w		
	} 
		toplevel $w
		wm title $w "Edit: $arr"
	set w ${w}.top
	set thefont "Helvetica 8 bold"
	if [info exists aie_edit_array_def] {unset aie_edit_array_def}

	set nnames [llength $list]
	set max_name 0
	set max_def 0
	foreach name $list {
		set aie_edit_array_def($name) [set ${arr}($name)]
		set nn [string length $name]
		if {$nn > $max_name} {set max_name $nn}
		set nn [string length $aie_edit_array_def($name)]
		if {$nn > $max_def} {set max_def $nn}
	}
	set mfont [font measure $thefont "a"]
	incr max_name 2
	incr max_def 5
	if {$max_name < 10} {set max_name 10}
	if {$max_def < 10} {set max_def 10}
	set name_pix [expr $max_name*$mfont]
	set def_pix [expr $max_def*$mfont+$name_pix]
	set res_pix [expr $def_pix+20]
		set w_main [PanedWindow $w -side top -weights available -width 6]
		pack $w_main -side top -fill both -expand 1
		$w_main add -weight 1
		set w_data [$w_main getframe 0]
		set w_ww [PanedWindow $w_data.ww -side left -weights available -width 6]
		$w_ww add -weight 5
		$w_ww add -weight 2
		set w_list [$w_ww getframe 0]	
		set w_bot  [$w_ww getframe 1]
		grid rowconfigure $w_bot 0 -weight 0	
		grid columnconfigure $w_bot 0 -weight 0	
		grid $w_ww -row 1 -column 1 -sticky nsew
		grid rowconfigure $w_data 1 -weight 1
		grid columnconfigure $w_data 1 -weight 1
		grid rowconfigure $w_list 1 -weight 1
		grid columnconfigure $w_list 1 -weight 1 

		set w_scrl $w_list.scrl


		set w_can  [canvas $w_list.can -width $res_pix -height 200 \
	  -scrollregion {0 0 200  200} -yscrollcommand "$w_scrl set"]
		scrollbar $w_scrl -command "$w_can yview" 
		pack $w_scrl -side right -fill y
		pack $w_can -side left -expand 1 -fill y
#==========================	
# simple bottom window with Apply and Cancel
		button $w_bot.1 -text Apply -command "aie_edit_array $arr apply"
		button $w_bot.2 -text Cancel -command "aie_edit_array $arr cancel"
		grid $w_bot.1  $w_bot.2 -sticky we
#================
	set h [expr $nnames*20+10]
	$w_can configure -scrollregion "0 0 200 $h" -width $res_pix
	set n 10
	foreach name $list {
		set wname $name
		while 1 {
			set idot [string first . $wname]
			if {$idot < 0} break
			set wname [string replace $wname $idot $idot _]
		}
		label $w_can.n$wname -width $max_name -text $name -bd 1 \
		 -relief ridge -font $thefont -anchor w 
		entry $w_can.d$wname -width $max_def  -textvar aie_edit_array_def($name) -bd 1\
		 -relief ridge -font $thefont
		$w_can create window 0 $n -window $w_can.n$wname -tag all -anchor w
		$w_can create window $name_pix $n -window $w_can.d$wname -tag all -anchor w	 
		incr n 20
	}
	update
	global tdv_current_viewer
	set x [winfo rootx $tdv_current_viewer]
	set y [winfo rooty $tdv_current_viewer]
	set whxy [split [wm geometry .aie_edit_array] x+]
	wm geometry .aie_edit_array ${res_pix}x[lindex $whxy 1]+${x}+$y
	wm transient .aie_edit_array $tdv_current_viewer
	$w_can yview moveto 1
# requested feature: return 1 on "Apply":
	tkwait window .aie_edit_array
	if [array exists aie_edit_array_def] {
		unset aie_edit_array_def
		return 1
	}
	return 0
}
#==============================================
proc aie_click_button {{mess ""}} {
global select_action
# returns button number 1-3 or 0 on select_action "cancel", e.g. on hot key "x"
# if !mess, keep banner "as is", so may be used "inside
# may be make ic_ proc?
	if [llength $mess] {banner $mess}
    set select_action done
	set but [vam_wait_for_click]
	if [llength $mess] {banner ""}
	return [lindex $but 0]		
}

#========================================================

#========================================================
proc onsetBackgroundStyleDEZLoad {} {
   global tdv_bgcolor tdv_bgcolor2 tdv_background_color
   global tdv_background_style tdv_show_ansys_logo env
   variable BackgroundOpts
   
   set BackgroundOpts [list Solid "Top-Bottom Gradient" "Left-Right Gradient" "Diagonal Gradient"]
   variable background_style
   if {![info exist tdv_background_color] || ([llength $tdv_background_color] < 3)} {
      global tdv_current_viewer tdv_default
      set w $tdv_current_viewer
      set tdv_background_color [list [$w cget -use_grad_bg] [$w cget -background] [$w cget -bmbgcolor]]
   }

   set n [lindex $tdv_background_color 0]

   switch -- $n {
     0 - 1 {set background_style [lindex $BackgroundOpts $n]}
     2 {set background_style [lindex $BackgroundOpts 3]}
     4 {set background_style [lindex $BackgroundOpts 2]}
   }

   set tdv_bgcolor [lindex $tdv_background_color 1]
   set tdv_bgcolor2 [lindex $tdv_background_color 2]
   if ![setProductDEZ isbuilt] { setProductDEZ build }
   if {[setProductDEZ get gui_style_on_mode] != "wb"} {
       set tdv_show_ansys_logo 0
       ::AIEnv::GUIManagement::ToggleGrey setShowAnsysLogo 1
   } else {
       ::AIEnv::GUIManagement::ToggleGrey setShowAnsysLogo 0
   }
   if [info exist env(ICEM_ACADEMIC)] {
      set tdv_show_ansys_logo 1
      ::AIEnv::GUIManagement::ToggleGrey setShowAnsysLogo 1
   } else {
      ::AIEnv::GUIManagement::ToggleGrey setShowAnsysLogo 0
   }
}

proc onsetBackgroundStyleDEZApply {} {
    variable BackgroundOpts
    variable background_style
    global tdv_current_viewer tdv_bgcolor tdv_bgcolor2
    global tdv_background_style tdv_default aie_guiOpt tool_dir2 common_tool_dir

    set k [lsearch $BackgroundOpts $background_style]
    switch -- $k {
        0 - 1 {set ::tdv_background_style $k}
        2 {set ::tdv_background_style 4}
        3 {set ::tdv_background_style 2}
     }
    tdv_background $tdv_current_viewer $tdv_bgcolor $tdv_bgcolor2
    $tdv_current_viewer redraw
    if !$tdv_show_ansys_logo {
        tdv_logo_delete $tdv_current_viewer
    } else {
        if [tdv_logo_background $tdv_current_viewer] {
            if ![info exist env(ICEM_ACADEMIC)] {
                set aie_guiOpt(logoImage) [file join $common_tool_dir ANSYS_large_black.ppm]
            } else {
                set aie_guiOpt(logoImage) [file join $common_tool_dir ANSYS_academic_large_black.ppm]
            }
        } else {
            if ![info exist env(ICEM_ACADEMIC)] {
                set aie_guiOpt(logoImage) [file join $common_tool_dir ANSYS_large_white.ppm]
            } else {
                set aie_guiOpt(logoImage) [file join $common_tool_dir ANSYS_academic_large_white.ppm]
            }
        }
        tdv_logo $tdv_current_viewer $aie_guiOpt(logoImage) $aie_guiOpt(logoPos)
    }
    if {$tdv_current_viewer == $tdv_default} {
        ic_uns_families_changed
        if [ic_hex_blocking_loaded] {
           hex_update_display
        }
    }
    aie_set_options
}

proc onsetLightingDEZLoad {} {
   global tdv_current_viewer tdv_lighting

   if {![info exist tdv_current_viewer] || \
       ![winfo exist $tdv_current_viewer]} {return ""}

   foreach n {ambient diffuse specular shininess dir} {
      set tdv_lighting($n) [$tdv_current_viewer get -light_$n]
   }
}

proc onsetLightingDEZApply {} {
   global tdv_current_viewer tdv_workspace

   foreach w [winfo children $tdv_workspace] {
      if {([winfo class $w] == "Tdv_Viewer") && \
           [winfo exist $w] && [info exist tdv_pos($w)]} {
         aie_set_lighting all $w
      }
   }

   aie_set_options
}

proc aie_set_lighting {what {w ""} args} {
    global tdv_current_viewer tdv_pos
    global tdv_lighting

    if {$w == ""} {
        if ![info exist tdv_current_viewer] {return ""}
        set w $tdv_current_viewer
    }
    if {$what == "all"} {
        set what [list ambient diffuse specular shininess dir]
    }
    set did ""
    foreach n $what {
        if {[tdv_set_lighting $n $w] != ""} {lappend did $n}
    }
    if {$did != ""} { $w redraw }
}

proc aie_reset_default_lighting {} {
    global tdv_lighting

    foreach "n v" {ambient 0.2 diffuse 0.8 specular 0.2 shininess 5 dir "0.3 -0.3 1"} {
        set tdv_lighting($n) $v
    }
    set ::tdv_use_dual_lighting 0
    setLightingDEZ apply
}

proc onsetMouseBindingDEZLoad {} {
    global tdv_binding tdv_mouse_bindings tdv_current_viewer cut_info tdv_start_spaceball

    if ![info exist tdv_binding(windows)] {
      lappend tdv_binding(windows) $tdv_current_viewer
    }

    variable MouseBindingOpts
    set MouseBindingOpts [list Rotate Pan Zoom "Box Zoom" None]
    variable MouseBindingOptsVal
    set MouseBindingOptsVal [list rot trans scale zoomin ""]

    #variable MouseWheelOpts
    #set MouseWheelOpts [list Zoom None]

    set w $tdv_current_viewer
    foreach {ent d} {<ButtonPress-1> rot <ButtonPress-2> trans \
        <ButtonPress-3> scale <Shift-ButtonPress-1> "" \
        <Shift-ButtonPress-2> scale <Shift-ButtonPress-3> zoomin \
        <Control-ButtonPress-1> rot \
        <Control-ButtonPress-2> trans <Control-ButtonPress-3> zoomin} {
        set dd $d
        if [info exist tdv_binding($w,$ent)] {
            set dd $tdv_binding($w,$ent)
        } elseif [info exist tdv_mouse_bindings($ent)] {
            set dd $tdv_mouse_bindings($ent)
        }
        set k [lsearch $MouseBindingOptsVal $dd]
        if {$k >= 0} {
            set tdv_binding($ent) [lindex $MouseBindingOpts $k]
        } else {
            set tdv_binding($ent) None
        }
    }

    variable MouseScaleDirOpts
    set MouseScaleDirOpts [list Down Up]
    set j 1
    if {[info exist tdv_mouse_bindings(scale_dir)] && \
        [string is integer -strict $tdv_mouse_bindings(scale_dir)]} {
        set j [expr ($tdv_mouse_bindings(scale_dir) + 1)/2]
    }
    set tdv_binding(scale_dir) [lindex $MouseScaleDirOpts $j]
    if ![info exists cut_info(mouse_wheel)] {
       set cut_info(mouse_wheel) 1
    }
    set start_spaceball 0
    if [info exists tdv_start_spaceball] {
        set start_spaceball $tdv_start_spaceball
   }
}

proc onsetMouseBindingDEZApply {} {
    global tdv_binding tdv_mouse_bindings tdv_current_viewer tdv_start_spaceball

    if {[lsearch $tdv_binding(windows) $tdv_current_viewer] < 0} {
        lappend tdv_binding(windows) $tdv_current_viewer
    }

    foreach w $tdv_binding(windows) {
        foreach {ent b} {<ButtonPress-1> 1 <ButtonPress-2> 2 \
            <ButtonPress-3> 3 <Shift-ButtonPress-1> 1 \
            <Shift-ButtonPress-2> 2 <Shift-ButtonPress-3> 3 \
            <Control-ButtonPress-1> 1 \
            <Control-ButtonPress-2> 2 <Control-ButtonPress-3> 3 } {
            variable MouseBindingOpts
            set k [lsearch $MouseBindingOpts $tdv_binding($ent)]
            variable MouseBindingOptsVal
            set d [lindex $MouseBindingOptsVal $k]

            if [info exist tdv_binding($w,$ent)] {
                if {$tdv_binding($w,$ent) != $d} {
                    tdv_set_mouse_press_binding $w $ent $b $d
                }
            } else {
                tdv_set_mouse_press_binding $w $ent $b $d
            }
            set tdv_mouse_bindings($ent) $d
        }
   }

   variable MouseScaleDirOpts
   set j [lsearch $MouseScaleDirOpts $tdv_binding(scale_dir)]
   set tdv_mouse_bindings(scale_dir) [expr $j * 2 - 1]

   set tdv_start_spaceball $start_spaceball

   aie_set_options
}

proc aie_gsview_menu {mm aieTree theNode nodename} {
   $mm add command -label "Apply" -command \
             "aie_gsview_cmd $aieTree $theNode apply"
   $mm add command -label "Rename" -command \
             "aie_gsview_cmd $aieTree $theNode rename"
   $mm add command -label "Remove" -command \
             "aie_gsview_cmd $aieTree $theNode remove"
}

proc aie_gsview_cmd {tree node what args} {
   set topNode $node
   while {[set p [$tree parent $topNode]] != "root"} {set topNode $p}
   set win [lindex [$tree itemcget $topNode -data] 1]

   switch -- $what {
      add {
         global aie_gsview
         if ![info exist aie_gsview(count)] {set aie_gsview(count) 0}
         incr aie_gsview(count)
         set vnode gsView$aie_gsview(count)

         set title [lindex $args 0]
         if {$title == ""} {
            set title "View $aie_gsview(count)"
         }

         set rr [list gsView $win]
         foreach s {pos rot scale center} {
            lappend rr -$s [$win cget -$s]
         }

         $tree insert end $node $vnode -text $title -data $rr
         set res [$tree edit $vnode $title]
         if {$res != ""} {
            $tree itemconfigure $vnode  -text $res
         }
         return $vnode
      }
      remove {
         $tree delete $node 
      }
      rename {
         set res [$tree edit $node [$tree itemcget $node -text]]
         if {$res != ""} {
            $tree itemconfigure $node  -text $res
         } 
      }
      apply {
         set n 0
         set rr [lrange [$tree itemcget $node -data] 2 end]
         foreach {opt val} $rr {
            switch -- $opt {
               -pos - -rot - -scale - -center {
                  set [string range $opt 1 end] $val
                  incr n
               }
            }
         }
         if {$n == 4} {
            global tdv_pos tdv_rot tdv_scale tdv_center
            foreach s {pos rot scale center} {
               set tdv_${s}($win) [set $s]
            }
            tdv_trans_update $win 1
         }
      }
   } 
}


proc test_aie_gsview_model {} {
   set top_tree [set ::AIEnv::GUIManagement::Tree::aieTree]
   aie_gsview_cmd $top_tree modelNode add
}

#==============================
proc aie_geo_move_from_orfn_non_material {} {
	global fam_visible
#
# ORFN family:
# - for material/body
#
# This proc does not change/update tree, display

	if ![info exists fam_visible(ORFN)] return
	foreach type {point curve surface} {
		set list [ic_geo_get_objects $type ORFN 1]
		if [llength $list] {
			set fam [string toupper ${type}s]
			ic_geo_set_family $type $fam names $list 0
		}
	}
}

proc aie_delete_any_space {text {case ""}} {
# delete any " " from text. Trivial, included only for scrpts readability
set res ""
set res [eval append res $text]
switch $case {
	toupper {set res [string toupper $res]}
	tolower {set res [string tolower $res]}
}
return $res 
}
#======================
proc aie_get_arc_data {crv {method arc_ctr_rad}} {
# assuming that curve is arc, get radius, center, etc data
# for 3 arc creation ic_curve method:
# [ic_geo_cre_crv_]arc_ctr_rad:cent xdir norm rad sa ea
# [ic_geo_cre_]va_arc:ps pend plane_direction_from_center central_angle
# [ic_geo_cre_arc_from_pnts] arc: ps pmid pend
# arc and va_arc will not work for circle, need different start-end pts
#
# With these data set initial values for arc create variables!
# 		
	set p1 [lindex [ic_geo_get_crv_pos 0.0 $crv] 0]
	set pc [lindex [ic_geo_get_crv_pos 0.5 $crv] 0]
	set pm $pc
	set p2 [lindex [ic_geo_get_crv_pos 1.0 $crv] 0]
	set pe $p2
#===
	if {$method == "arc"} {
		return [list $p1 $pm $p2]
	}
#===
# check for circle, with ~ the same end points:
	set d12 [ic_vcalc distance $p1 $p2]
	set d1c [ic_vcalc distance $p1 $pc]
	if {$d12 < $d1c} {
		set p2 $pc
		set pc [lindex [ic_geo_get_crv_pos 0.25 $crv] 0]
	}			 
	set hord_mid [ic_vcalc sum_smult $p1 $p2 0.5]
	set h [ic_vcalc distance $hord_mid $pc]
	if {$h < 0.001} return
	set a [ic_vcalc distance $p1 $p2]
	set r [expr ($a*$a+4*$h*$h)/8.0/$h]
	set dir [ic_vcalc dir $pc $hord_mid]
	set to_center [ic_vcalc smult $dir $r]
	set c [ic_vcalc sum $pc $to_center]
#===
	if {$method == "va_arc"} {
		global va_set
		set dir [ic_vcalc dir $c $pm]
		set angle [ic_vcalc angle $c $p1 $pe]
		if {$angle == 0} {set angle 360}
		return [list $p1 $pe $dir $angle]
	}	
#===
	set x [ic_vcalc dir $c $p1]
	set n [ic_vcalc product $dir $x]
	# start angle is 0
	set ea [ic_vcalc angle $c $p1 $pe]
	if {$ea == 0 && $r > 0} {set ea 360}	
	return [list $c $x $n $r 0 $ea]
}
proc aie_get_srf_data {srf vec {add_uv 0}} {
# vec may be vector expression
# return xyz[nearest to location] Udir nrm U V

	set coor [ic_vset -vec - $vec]
	if {$coor == ""} {
		ic_mess "Error: [ic_vset]\n" red
		return
	}
	if {[ic_geo_get_object_type surface $srf] == "mesh"} {
	    if [catch {ic_geo_find_nearest_srf_pnt $srf $coor 1} srf_pnt] {
		ic_mess "Error in aie_get_srf_data:  srf_pnt\n" red
		return TCL_ERROR
	    }	
	    set xyz [lindex $srf_pnt 1]
	    set nrm [lindex $srf_pnt 2]
    	    set udir [ic_vcalc vec_norm $nrm]
	    if $add_uv { return [list $xyz $udir $nrm 0 0]}
	    return [list $xyz $udir $nrm]
	} else {
	    if [catch {ic_geo_find_nearest_srf_pnt $srf $coor} uv] {
		ic_mess "Error in aie_get_srf_data\n" red
		return TCL_ERROR
	    } 
	    foreach "u v" $uv ""
	    set xyz [lindex [ic_geo_get_srf_pos $u $v $srf] 0]
	    if {$u > 0.99} {
		    set xyz1 [lindex [ic_geo_get_srf_pos 0.98 $v $srf] 0]
		    set udir [ic_vcalc dir $xyz1 $xyz]
	    } else {
		    set u1 [expr $u+0.01]
		    set xyz1 [lindex [ic_geo_get_srf_pos $u1 $v $srf] 0]
		    set udir [ic_vcalc dir $xyz $xyz1]
	    }
	    set nrm [lindex [ic_geo_get_srf_nrm $u $v $srf] 0]
	    if !$add_uv {return [list $xyz $udir $nrm]} 
	}
	return [list $xyz $udir $nrm $u $v]
}
#--------------
proc aie_run_frontal {} {
	global tdv_default
	set nscr [lindex [$tdv_default screen2world 100 100] 1]
	set nscr [ic_vcalc nrm $nscr]
	set keep_crvs [ic_geo_get_objects curve ORFN 1]
	ic_run_frontal dir $nscr tol 0.001
	set now_crvs [ic_geo_get_objects curve ORFN 1]
	foreach crv $now_crvs {
		if {[lsearch $keep_crvs $crv] >= 0} continue
		ic_delete_geometry curve names $crv 0
	}
}

# retuturns 1 for valid
proc aie_valid_name {name {no_colon 0}} {
    set nname [ic_geo_valid_name $name $no_colon]
    if {$nname == "" || $nname != [string toupper $name]} {
	msg ERROR "Could not set new name: $name\n"
	return 0
    }
    return 1;
}

proc aie_get_valid_name {name} {
   set newname [ic_geo_valid_name $name 1]
   if {$newname != $name} {
      mess "Name \"$name\" is not valid - changed to \"$newname\"\n" red
   }
   return $newname
}

proc aie_reset_picker {dez picker args} {
	set cmd ::AIEnv::GUIManagement::ResetPicker
	if {$dez == ""} {set dez [TreeStack peek]}
	eval $cmd $dez $picker $args
} 

proc aie_show_name {item on} {
	set cmd ::AIEnv::GUIManagement::ShowName
	set dez [TreeStack peek]
	eval $cmd $dez $item $on
} 

proc aie_set_crvs_connected {crvs} {
# This function split list of "crvs" on connected groups and return
# list of lists of curves (groups).  "single" may be used as argument "crvs"
# Uses topo info (incident/boundary)
	if {$crvs == "single"} {
		set crvs ""
		foreach crv [ic_geo_get_objects curve] {
			set srfs [ic_geo_incident curve $crv]
			if {[llength $srfs] != 1} continue
			lappend crvs $crv
		}
	}
	foreach crv $crvs {
		set tmp_crv($crv) 0
		foreach p [ic_geo_boundary curve $crv] {
			lappend tmp_pnt($p) $crv
		}
	}
	set n_group 0
	set result ""
	foreach crv $crvs {
		if ![info exists tmp_crv($crv)] continue
		if [array exists tmp_group] {
			lappend result [array names tmp_group]
			unset tmp_group
		}

		set tmp_group($crv) 1
		while 1 {
			set added 0			
			foreach c [array names tmp_group] {
				set bcrvs [ic_geo_boundary curve $c 0 1]
				if {[llength $bcrvs] != 2} {
				    ic_mess "Topology points not found. Build topology and try again\n" red
				    return ""
				}
				foreach {p1 p2} $bcrvs ""
				if {![info exists tmp_pnt($p1)] || ![info exists tmp_pnt($p2)]} continue
				foreach cc "$tmp_pnt($p1) $tmp_pnt($p2)" {
					if [info exists tmp_crv($cc)] {
						set tmp_group($cc) 1
						unset tmp_crv($cc) 
						set added 1
					}
				}
			}
			if !$added break
		} 
	} 
	if [array exists tmp_group] {
		lappend result [array names tmp_group]
	}
	return $result		
}

proc aie_select_nodes {{n 0}} {
	if ![ic_uns_is_loaded] { return "" }
	set sel [select_unstruct node $n]
	if {$sel == ""} { return "" }
	set list [ic_uns_subset_list_elements $sel]
	if {$list == ""} { return "" }
	set res ""
	foreach elem $list {
		lappend res [lindex $elem end]
	}
	return $res
}

proc aie_select_vertex {{n 0}} {
	if ![ic_hex_is_loaded] { return "" }
	set sel [select_hexa vertex $n "Select $n vertex"]
	if {$sel == ""} { return "" }
	set res ""
	foreach elem $sel {
		lappend res [lindex [ic_hex_vertex_number $elem] 0]
	}
	return $res
}

proc aie_apply_other_dez {dez args} {
# To avoid duplication just apply other dez. set args {name val}...{}
	set m ::AIEnv::GUIManagement::
	set from [set ${m}ActiveDEZ]
	${m}DEZ::_load $dez "" 
#	$from unload
# may be not created yet; var may be not defined
# but if defined, must restore old value.
#	catch "$dez create"
#	catch "$dez	load"
#	catch "$dez	setdirty"
	set d ::AIEnv::DEZ::${dez}::
	foreach {name v} $args {
		set n ${d}$name
		if ![info exists $n] {set $n $v}
		set was$name [set $n]
		set $n $v
	}
	$dez apply
	foreach {name v} $args {
		set ${d}$name [set was$name]
	}
	${m}DEZ::_load $from "" 
} 

proc aie_remove_header_lines_tetinfile {} {
    global file_name
    
    mess "Select tetin file to shrink\n" blue
    set file [tk_getOpenFile -initialdir $file_name(project_dir) \
		-filetypes {{{Geometry Files} {.tin}} {{All Files} *}} \
		-multiple 0 -title "Shrink tetin file: Load"]
    if {$file == ""} return 
    set newfile [cmd_tempfile [file rootname $file] .tin]
    if [file exists $newfile] return
    mess "Save shrinked tetin file as " blue
    set usefile [tk_getSaveFile -initialdir $file_name(project_dir) \
	    -initialfile [file tail $newfile] -title "Shrink tetin file: Save as" \
	    -filetypes {{{Geometry Files} {.tin} } {{All Files} *}}]   
    if {$usefile == ""} return
    mess "$usefile\n"
    ic_geo_shrink_tetinfile $file $usefile
}

proc aie_setup_domain_form_list {} {
    global str_type_visible str_number_visible plot_window domain_form
     
    if {([info exists plot_window] && [winfo exists $plot_window]) && ([winfo children $plot_window] !=  "")} {
        if {[winfo children $plot_window] == "$plot_window.domainf"} {
            return
        } else {
            set domain_form .domainf
        }
    } else {
        set domain_form $plot_window.domainf
        ::AIEnv::GUIManagement::ConfigureConsoleZone 1
    }
    if [winfo exists $domain_form] { form_kill $domain_form }
    
    set choices ""
    for {set i 1} {$i <= [ic_str_num_entities domain]} {incr i} { lappend choices $i }
   
    if {$domain_form == ".domainf"} {
        set d [form_init $domain_form "Domain List" "" {{}}]
    } else {
        set d [form_init_sub $domain_form]
    }
    if {$d != ""} {
        form_listbox $d.list "Domain List" $choices "aie_domain_form_update_number_list $d" \
                     "" 30x10 {0 0} ""  0 0 1
        form_button $d.done "Done" "aie_domain_form_done $d" {3 0 -pady 4 -sticky ew}
        form_finish +300+300
        if {$domain_form != ".domainf"} {
            pack $domain_form -side left -expand yes -fill both
        }
    }

    foreach n [array names str_number_visible domain,*] { unset str_number_visible($n) }
    set i 0
    foreach ch $choices {
	    set num [expr $i + 1]
	    set str_number_visible(domain,$num) $str_type_visible(domain)
	    if $str_number_visible(domain,$num) {
	        $d.list.list selection set $i
	    } else {
	        $d.list.list selection clear $i
	    }
        incr i
    }
}

proc aie_domain_form_done {w} {
    global domain_form str_type_visible str_number_visible plot_window
    if ![info exists domain_form] return
    for {set i 1} {$i <= [$w.list.list size]} {incr i} {
        set str_number_visible(domain,$i) $str_type_visible(domain) 
        ic_str_set_nums_visible domain "$i $str_number_visible(domain,$i)"
    }
    if {$domain_form == "$plot_window.domainf"} {
        ::AIEnv::GUIManagement::ConfigureConsoleZone 0
    }
    form_kill $domain_form; unset domain_form
}

proc aie_domain_form_update_number_list {w num} {
    global str_number_visible
    set selected [form_listbox_get_selected $w.list]
    for {set i 1} {$i <= [$w.list.list size]} {incr i} {
        if {[lsearch $selected $i] >= 0} {
            set str_number_visible(domain,$i) 1
        } else {
            set str_number_visible(domain,$i) 0
        }        
    }
    ic_str_set_nums_visible domain "$num $str_number_visible(domain,$num)"
}

proc aie_setup_domain_form_scanplanes {} {
    global scanp_form scanp plot_window 
     
    if {([info exists plot_window] && [winfo exists $plot_window]) && \
        ([winfo children $plot_window] !=  "")} {
        if {[winfo children $plot_window] == "$plot_window.scanp"} {
            return
        } else {
            set scanp_form .scanp
        }
    } else {
        set scanp_form $plot_window.scanp
    }
    if [winfo exists $scanp_form] { form_kill $scanp_form }
    if {$scanp_form == ".scanp"} {
        set d [form_init $scanp_form "Scan planes" "" {{}}]
    } else {
        set d [form_init_sub $scanp_form]
    }
    make_scanp_control $d
    set scanp(visible) 1
    set scanp(cur) ""
    form_finish +300+300
    if {$scanp_form == ".scanp"} {
        catch {wm protocol $scanp_form WM_DELETE_WINDOW "aie_domain_scanplanes_form_done"}
    }
    if {[trace vinfo scanp(cur)] != ""} {
        trace vdelete scanp(cur) w aie_scanplanes_trace_cur
    }
    trace variable scanp(cur) w aie_scanplanes_trace_cur
    aie_scanplanes_trace_cur "" "" ""
    ::AIEnv::GUIManagement::ConfigureConsoleZone 1; update
}

proc aie_scanplanes_trace_cur {name element op} {
    global scanp_form scanp
    
    if {$scanp_form == ".scanp"} {
        set w $scanp_form.main
    } else {
        set w $scanp_form
    }
    if {$scanp(cur) == ""} {
        $w.c2.up configure -state disabled
        $w.c2.down configure -state disabled
    } else {
        $w.c2.up configure -state normal
        $w.c2.down configure -state normal
    }
}

proc aie_domain_scanplanes_form_done {} {
    global scanp_form scanp
    if ![info exists scanp_form] return
    ic_str_scanp_configure "" -visible 0
    scanp_clear
    set scanp(visible) 0
    if {[trace vinfo scanp(cur)] != ""} {
        trace vdelete scanp(cur) w aie_scanplanes_trace_cur
    }
    form_kill $scanp_form; unset scanp_form
    ::AIEnv::GUIManagement::ConfigureConsoleZone 0 
}
proc aie_geom_placement {type names placement args} {
# generic GUI function
# placement: highlight | part | subset
# args: highlight -> color [""] width [4]
# args: subset -> subset_name [clear] | add
# args: part -> partname  
# examples:
# aie_geom_placement curve $list highlight color white width 5
# aie_geom_placement curve $list part PART1
# aie_geom_placement surface $list subset subs1
# aie_geom_placement surface $list subset sub2 add
	set color ""
	set width 4
	set clear 1
	set sub_name [lindex $args 0]

	switch $placement {
		highlight {
			foreach "n v" $args {set $n $v}
			ic_highlight $type $names width $width color $color
			}
		part {	
				set pname [aie_delete_any_space $sub_name toupper]
				foreach ent $names {
					ic_geo_set_part $type $ent $pname 0
				}
				aie_create_parts_in_tree_if_needed 
			}
		subset {
			if {[lsearch $args "add"] >= 0} {
				set clear 0
			}
			set sname [aie_delete_any_space $sub_name]
			if $clear {ic_geo_subset_clear $sname}
			foreach ent $names {
				ic_geo_subset_add_items $sname "$type $ent"
			}
			::AIEnv::GUIManagement::Tree::AddGroup geom_subset $sname 1
			::AIEnv::GUIManagement::Tree::ToggleGroupVisibility geom_subset $sname same	
		}
	}
}
proc aie_titleFrame_B3 {{dez ""} {proc aie_pop_title}} {
	if {$dez == ""} {
		set dez $::AIEnv::GUIManagement::ActiveDEZ
	}
	if {$dez  == "NULL"} return
	set v ::AIEnv::GUIManagement::DEZ::DEZData(${dez}-Win)
	if ![info exists $v] return
	set v [set $v].titleFrame
	foreach w "$v $v.title" {
		if ![winfo exists $w] return	
		bind $w <Button-3> "$proc %X %Y $dez"	
	}
}
proc aie_pop_inherit {} {
	global vid_options
		::AIEnv::GUIManagement::ToggleGrey createPointsFam $vid_options(inherit)
}
proc aie_pop_title {x y args} {
# VG: Draft of Beta feature. May be removed.
	global vid_options
	set w .vid_top_pop
	if [winfo exists $w] {destroy $w}
	set w [menu $w -tearoff 0]
	$w add checkbutton -label "Inherit part" -variable vid_options(inherit) -command {
		::AIEnv::GUIManagement::ToggleGrey createPointsFam $vid_options(inherit)
	}
	$w add checkbutton -label "Auxiliary pts" -variable vid_options(auxiliary)	
	tk_popup $w $x $y
}

proc status_message {txt {fopts ""} {lopts ""}} {		
	if {[string index $txt end] == "\n"} {
		set txt [string replace $txt end end]
	}	
	mess "$txt\n"
	return
}

proc aie_on_vid_mode {} {
#	ic_image delete vidpoint_im
	global vid_options
	if $vid_options(vid_mode) {
		aie_vid_button
		aie_vidrpl_gui 
		aie_vid_popmenu_do MTree
		set vid_options(auxiliary) 1
	} else {
		aie_vidrpl_interp_done
	}
}
proc aie_check_inherit_fam {{fam ""} {type ""} {list ""}} {
# change fam if a) inherit && b) valid  
# return 1 if changed
	global vid_options
	if ![info exists vid_options(inherit)] {return 0}
	if !$vid_options(inherit) {return 0}
	if {$fam == ""} {return $vid_options(inherit)}
	upvar $fam thefam
	foreach s $list {
		set name [ic_geo_check_objects_exist $type $s]
		if {$s != $name} continue
		set thefam [ic_geo_get_family $type $name]
		return 1
	}
	return 0
}

proc onGOptions_PartNameModify {dez val} {
    if {$val == "From screen"} {
		set p [geo_select_part_from_screen 1]
		setGOptionsDEZ set default_part_name [aie_default_part_name $p]	
    }
}

proc onsetGOptionsDEZLoad {} {
	global vid_options
	
    set PartList [aie_list_parts 1]
    set opt_inherit $vid_options(inherit)
    set default_part_name [aie_default_part_name]
    set map_global $map_tetin_sizes(global)
    set map_family $map_tetin_sizes(family)
    set map_ppoint $map_tetin_sizes(ppoint)
    set map_pcurves $map_tetin_sizes(pcurves)
    set map_mcurves $map_tetin_sizes(mcurves)
    set map_psurfaces $map_tetin_sizes(psurfaces)
    set map_msurfaces $map_tetin_sizes(msurfaces)
    set map_thincuts $map_tetin_sizes(thincuts)
    set map_densities $map_tetin_sizes(densities)
    set map_subsets $map_tetin_sizes(subsets)
    set map_mpoint $map_tetin_sizes(mpoint)
}

proc onsetGOptionsDEZOK {} {
    global vid_options map_tetin_sizes
    
    set default_part_name [aie_default_part_name $default_part_name]
    aie_geo_set_part_name $default_part_name
    set map_tetin_sizes(tetin) ""
    set map_tetin_sizes(doit) 0
    set map_tetin_sizes(global) $map_global
    set map_tetin_sizes(family) $map_family
    set map_tetin_sizes(ppoint) $map_ppoint
    set map_tetin_sizes(pcurves) $map_pcurves
    set map_tetin_sizes(mcurves) $map_mcurves
    set map_tetin_sizes(psurfaces) $map_psurfaces
    set map_tetin_sizes(msurfaces) $map_msurfaces
    set map_tetin_sizes(thincuts) $map_thincuts
    set map_tetin_sizes(densities) $map_densities
    set map_tetin_sizes(subsets) $map_subsets
    set map_tetin_sizes(mpoint) $map_mpoint
    aie_set_options
}

proc aie_set_opt_inherit {} {
	global vid_options
	set vid_options(inherit) $opt_inherit
}

proc onsetModelOptionsDEZLoad {} {
    global geo_cad

    if [info exists geo_cad(use_toptol_userset)] {
        aie_default_topo_tolerance set_user_mode_if_modified $geo_cad(toler)
    } else {
        aie_default_topo_tolerance
    }
    foreach {n v} [ic_set_meshing_params global 0] {
        if {$n == "gttol"} { set tritol $v }
        if {$n == "gtrel"} { set tritolabs $v }	
    } 
    set units [ic_geo_get_units]
    if {$units == ""} { set units unitless }
    set scale_unit 0
    set scale_sizes 0
    after 100 {
        ::AIEnv::GUIManagement::ToggleGrey modelunitsGeometryParamsScale 1
    }
}

proc onsetModelOptionsDEZOK {} {
    global geo_cad units_message tdv_current_viewer top_current replay_recording

    aie_default_topo_tolerance set_user_mode_if_modified $geo_cad(toler)
    set regenerate 0
    foreach {n v} [ic_get_meshing_params global 0] {
        if {$n == "gttol" && $v != "$tritol"} { set regenerate 1 }
        if {$n == "gtrel" && $v != "$tritolabs" } { set regenerate 1 }
    } 
    ic_set_meshing_params global 0 gttol $tritol gtrel $tritolabs
    foreach {n v} [ic_get_meshing_params global 0] {
        if {$n == "gttol"} { set tritol $v }
        if {$n == "gtrel"} { set tritolabs $v }	
    } 
    if $regenerate {
        ic_regenerate_tris
    }
    if {$units != ""} {
        if {$units == "unitless"} {
            ic_geo_set_units ""
            if [ic_geo_is_loaded] {
                set units_message ""
            }
        } else {
            set old_units [ic_geo_get_units]
            ic_geo_set_units $units
            if [ic_geo_is_loaded] {
                set units_message "Units: [ic_geo_get_units 1] "
            }
            if {!$scale_unit || $old_units == "" || $old_units == $units} return
            set scale [ic_geo_convert_units $old_units $units]
            if [ic_geo_is_loaded] {
                mess "Scaling geometry from \"$old_units\" to \"$units\"\n"
                foreach type "point curve surface material density" {
                    set objs [ic_geo_get_objects $type]
                    if {$objs != ""} {
                        ic_move_geometry $type names "$objs" scale "$scale $scale $scale" cent "0 0 0" detach 0
                    }
                }
                if $scale_sizes {
                    ic_geo_scale_meshing_params all $scale
                    foreach "n v" [ic_get_meshing_params global 0] {
                        if {$n == "gmax" && $v >= 0} {
                            set gmax [expr $v * $scale * 1.0]
                            ic_set_meshing_params global 0 gref $scale gmax $gmax
                            break
                        }
                    }
                }
                ic_geo_reset_data_structures
            }
            if {[ic_uns_is_loaded] && [ic_uns_non_empty_families] != ""} {
                mess "Scaling mesh from \"$old_units\" to \"$units\"\n"
                ic_uns_move_elements all scale "$scale $scale $scale" cent "0 0 0"
            }
            if [ic_hex_blocking_loaded] {
                mess "Scaling blocking from \"$old_units\" to \"$units\"\n"
                ic_geo_new_family __TEMP_BLOCK_SUBSET__
                ic_hex_create_subset display __TEMP_BLOCK_SUBSET__
                set blks [string trimright [ic_hex_select_blocks 1 no_highlight all] \n]
                eval ic_hex_subset_add_items __TEMP_BLOCK_SUBSET__ block [llength $blks] $blks
                if $replay_recording {
	                replay_record_command "replay_put ic_hex_create_subset display __TEMP_BLOCK_SUBSET__"
	                replay_record_command "replay_put ic_hex_subset_add_items __TEMP_BLOCK_SUBSET__ block [llength $blks] $blks"
                }
                ic_hex_transform_blocking $top_current scale 0 0 0 $scale $scale $scale m __TEMP_BLOCK_SUBSET__
                ic_geo_delete_family __TEMP_BLOCK_SUBSET__
                ic_hex_delete_subset __TEMP_BLOCK_SUBSET__
                if $replay_recording {
	                replay_record_command "replay_put ic_hex_delete_subset __TEMP_BLOCK_SUBSET__"
                }
                hex_update_display
            }
            tdv_scale_to_fit $tdv_current_viewer
        }
    } else {
        if [ic_geo_is_loaded] {
            set units_message ""
        }
    }
}

proc aie_compare_value {v txt} {
# v - num. value; txt - one or more "< value" pairs
# return 1 (TRUE) or 0 (FALSE)
# any error - return 0
	set what ""
	if {[llength $txt] == 1} {set txt "< $txt"}
	foreach {how vv} $txt {
		if {$how == "" || $vv == ""} break
		if [catch {if "!($v $how $vv)" {return 0}}] {return 0}
	}
	return 1
} 

proc aie_delAllDorm {} {
    set dez $::AIEnv::GUIManagement::ActiveDEZ
    if {$dez  == "NULL"} return
    set dez [string tolower $dez]
    # expect deletecurve... or deletepoint...
    set type [string range $dez 6 10] 
    if {$type != "point" && $type != "curve"} return
    set ents [ic_geo_get_dormant $type]
    set n [llength $ents]
    status_message "Done: $n ${type}(s)"
    if !$n return
    ic_undo_group_begin
    ic_delete_geometry $type names $ents 0 1
    ic_undo_group_end
    aie_delete_empty_parts 0
} 

proc aie_default_part_name {{part ""}} {
# 
# set/get default part name
# part name will be saved with other options on command "aie_set_options"
# 
	global vid_options
	if ![info exists vid_options(default_part)] {
			set vid_options(default_part) GEOM
	}
	if {($part != "") && ($part != "From screen")} {
		set part [aie_delete_any_space [string toupper $part]]
		if {$part != ""} {
			set vid_options(default_part) $part
		}		
	}
	return $vid_options(default_part)
}
proc aie_geo_set_part_name {{part ""}} {
# This proc used on..Load (without params) and on OK with user defined part
# set part name for active DEZ from next list: 
	set list "createPointsDEZ createCurvesDEZ createSurfsDEZ createFacetedDEZ repairGeomDEZ"
#  
#
	set valid_part 0
	if {($part != "") && ($part != "From screen")} {
		set part [aie_delete_any_space [string toupper $part]]
		if {$part != ""} {set valid_part 1}
	} 
	# For initial load all dez may be empty. Use default_part_name
	if {$part == "" && [info exists ::geo_part_name]} {
		set part $::geo_part_name
	}
	if {$part == ""} {
		set part [aie_default_part_name]
	}
	# use the same part_name for 5 geometry DEZs
	set ::geo_part_name $part
	return $part
} 
proc aie_default_topo_tolerance {{option ""} {value 0}} {
# Rules for topo tolerance:
# 0. Modes: auto [default] , user; auto: geo_cad(toptol_userset) = 0
# 1. Tolerance Value: geo_cad(toler)  
# 2. If (toptol_userset) == 1: Userset mode
# 3. If geo_cad(toler) == 0: Autoset mode [default]
# 4. If Autoset: call ic_geo_default_topo_tolerance
# 5. Value (toler) may be set in Settings->Model and/or Geometry->Repair->Topo
	global geo_cad

	set c $geo_cad(toler)
	if ![info exists geo_cad(toptol_userset)] {
	    ic_set_global geo_cad 0 toptol_userset
	    set geo_cad(toptol_userset) 0
	}
	if {$option == "set_user_mode_if_modified"} {
	    # 
		# check that new contents of geo_cad(toler) is a valid value.
        # geo_cad(toler) must be always valid.  
		# 
        if {([llength $c] == 1) && ([string is double $c] || [string is integer $c])} {
            ic_set_global geo_cad 1 toptol_userset
            set geo_cad(toptol_userset) 1
        } else {
            ic_set_global geo_cad 0 toptol_userset
            set geo_cad(toptol_userset) 0
        }
	} elseif {$option == "restore_geo_default_topo_tolerance"} {
	    ic_set_global geo_cad 0 toptol_userset
        set geo_cad(toptol_userset) 0
	}
	if {$geo_cad(toler) == 0} {
	    ic_set_global geo_cad 0 toptol_userset
	    set geo_cad(toptol_userset) 0
	}
	if !$geo_cad(toptol_userset) {
	    ic_set_global geo_cad [ic_geo_default_topo_tolerance] toler
		set geo_cad(toler) [ic_geo_default_topo_tolerance]
	}
	return $geo_cad(toler)
}

proc aie_solver_setup {} { 
    setSolverSettingsDEZ show
}

proc onsetSolverSettingsDEZLoad {} {
    global env solver_setup solver_type solver_setup_global
    global solution solver_info options beta_mode is_win 
    
    if {$solver_setup != "-1"} {
       set solve_format1 $solver_setup
    } else {
       set solve_format1 $solver_setup_global
    }

    set fea_solverList "NASTRAN"
    set fea_solver "NASTRAN"

    if [info exists env(AI_ENV_ANSYS)] {
        lappend fea_solverList "ANSYS"
        if {$solve_format1 == "1"} { set fea_solver "ANSYS" }
    }
    if [info exists env(AI_ENV_LSDYNA)] {
       lappend fea_solverList "LS-Dyna"
       if {$solve_format1 == "2"} { set fea_solver "LS-Dyna" }
    }
    if [info exists env(AI_ENV_ABAQUS)] {
       lappend fea_solverList "Abaqus"
       if {$solve_format1 == "3"} { set fea_solver "Abaqus" }
    }
    if [info exists env(AI_ENV_AUTODYN)] {
       lappend fea_solverList "AUTODYN"
       if {$solve_format1 == "4"} { set fea_solver "AUTODYN" }
    }
    lsort fea_solverList

    if ![info exists solver_info] {
        get_solver_info
    }
    
    set cfd_solverList ""   
    foreach sol [lsort [array names solver_info]] {
        if {$is_win && $sol == "CFX-TASCflow" && !$beta_mode} continue
        if {$sol == "ANSYS" || $sol == "ABAQUS" || $sol == "Nastran" || $sol == "LS-DYNA3D"} continue
        lappend cfd_solverList $sol
    }
    
    set cfd_solver "ANSYS Fluent" 
    if {[info exists options(default_solver)] && $options(default_solver) != ""} {
        if {$options(default_solver)  != "ANSYS" && $options(default_solver) != "ABAQUS" && $options(default_solver) != "Nastran" && $options(default_solver) != "LS-DYNA3D"} {
            set cfd_solver $options(default_solver)
        }
    } else {
        set options(default_solver) $cfd_solver
    }
    if {[info exists solution(solver)] && $solution(solver) != ""} {
        if {$options(default_solver)  != "ANSYS" && $options(default_solver) != "ABAQUS" && $options(default_solver) != "Nastran" && $options(default_solver) != "LS-DYNA3D"} {
            set cfd_solver $solution(solver)
        }
    } else {
        set solution(solver) $cfd_solver
    }
}

proc onsetSolverSettingsDEZOK {} {
    global env solver_setup solver_type solver_setup_global
    global solution solver_info options

    set fea_allowed 0
    if {[info exists env(AI_ENV_ANSYS)] || [info exists env(AI_ENV_LSDYNA)] || [info exists env(AI_ENV_ABAQUS)] ||  [info exists env(AI_ENV_AUTODYN)]} {
        set fea_allowed 1
    }
    if {[info exists env(AI_ENV_FEA)] || $fea_allowed == "1"} {
        set solve_format1 0
        if {$fea_solver == "NASTRAN"} {
            set solve_format1 0
            mess "Current Common Structural Solver is \"NASTRAN\"\n"
        }
        if {$fea_solver == "ANSYS"} {
            set solve_format1 1
            mess "Current Common Structural Solver is \"ANSYS\"\n"
        }
        if {$fea_solver == "LS-Dyna"} {
            set solve_format1 2
            mess "Current Common Structural Solver is \"LS-Dyna\"\n"
        }
        if {$fea_solver == "Abaqus"} {
            set solve_format1 3
            mess "Current Common Structural Solver is \"Abaqus\"\n"
        }
        if {$fea_solver == "AUTODYN"} {
            set solve_format1 4
            mess "Current Common Structural Solver is \"AUTODYN\"\n"
        }
        set solver_setup $solve_format1
        set solver_setup_global $solve_format1
    }

    if [info exists env(AI_ENV_CFD)] {
      if {$cfd_solver != ""} {
          catch { unset solution(solver) }
          catch { unset options(default_solver) }
          if ![info exists solver_info] { get_solver_info }
          if ![info exists solver_info($cfd_solver)] {
             mess "Unknown Output Solver $cfd_solver.  Please select a valid Output Solver\n" red
             return
          }
          solution_set_solver $cfd_solver 1
          set options(default_solver) $cfd_solver
       }
    }
    aie_set_options
}

proc aie_outputtab_update {} {
    global solution solver_info env options

    if {[info exists options(default_solver)] && ($options(default_solver) != "")} {
        if {[info exists solution(solver)] && ($solution(solver) == "")} {
            set solution(solver) $options(default_solver)
            get_solver_info
        }   
    }
}

proc onsetSolverDEZLoad {} {
    global env solver_setup solver_type solver_setup_global
    global solution solver_info options solver_set_default beta_mode is_win

    if ![info exists solver_info] {
        get_solver_info
    }
    
    set cfd_solverList ""   
    foreach sol [lsort [array names solver_info]] {
        if {$is_win && $sol == "CFX-TASCflow" && !$beta_mode} continue
        if {$sol == "ANSYS" || $sol == "ABAQUS" || $sol == "Nastran" || $sol == "LS-DYNA3D"} continue
        lappend cfd_solverList $sol
    }
    
    set cfd_solver "ANSYS Fluent" 
    if {[info exists options(default_solver)] && $options(default_solver) != ""} {
        if {$options(default_solver) != "ANSYS" && $options(default_solver) != "ABAQUS" && $options(default_solver) != "Nastran" && $options(default_solver) != "LS-DYNA3D"} {
            set cfd_solver $options(default_solver)
        }
    } else {
        set options(default_solver) $cfd_solver
    }
    if {[info exists solution(solver)] && $solution(solver) != ""} {
        if {$options(default_solver) != "ANSYS" && $options(default_solver) != "ABAQUS" && $options(default_solver) != "Nastran" && $options(default_solver) != "LS-DYNA3D"} {
            set cfd_solver $solution(solver)
        }
    } else {
        set solution(solver) $cfd_solver
    }

}
proc onsetSolverDEZAfterLoad {} {
    global env solver_setup solver_type solver_setup_global
    global solution solver_info options solver_set_default
   
    if {$cfd_solver == "ANSYS" || $cfd_solver == "ABAQUS" || $cfd_solver == "Nastran" || $cfd_solver == "LS-DYNA3D"} {
        set cfd_solver "ANSYS Fluent" 
    }
}

proc onsetSolverDEZOK {} {
    global env solver_setup solver_type solver_setup_global
    global solution solver_info options

    if [info exists env(AI_ENV_CFD)] {
      if {$cfd_solver != ""} {
          catch { unset solution(solver) }
          if {$solver_set_global == "1"} {
             catch { unset options(default_solver) }
          }
          if ![info exists solver_info] {
             get_solver_info
          }
          if ![info exists solver_info($cfd_solver)] {
             user_error "Unknown Output Solver $cfd_solver.\nPlease select a valid Output Solver."
             return
          }
          solution_set_solver $cfd_solver 1
          if {$solver_set_global == "1"} {
             set options(default_solver) $cfd_solver
          }
       }
    }

    if {$solver_set_global == "1"} {
        aie_set_options
    }

    aie_update_icons
}

proc aie_solution_select {} {
    global solver_set_default
    set solver_set_default 0
    setSolverDEZ show
}

proc onshellDiagnosticsDEZLoad {} {
    set showList {
        "Edges"
        "Edges and Faces"
        "Edges and 2 layers of Faces"
    }
}

proc onshellDiagnosticsDEZAfterLoad {} {
    global disp_options aie_meshTypeVis aie_shellDiagnosticDisplay
  
    if ![info exists diag_values_set] {
        set diag_values_set 1
        if [info exists disp_options(single_surfaces)] {
            set diagSingle $disp_options(single_surfaces)
        } else {
            set diagSingle 0
        }
        if [info exists disp_options(multiple_surfaces)] {
            set diagMulti $disp_options(multiple_surfaces)
        } else {
            set diagMulti 0
        }
        if [info exists disp_options(only_edges)] {
            set diagProblem $disp_options(only_edges)
        } else {
            set diagProblem 0
        }        
        set show_type Edges
        set diagOver 0
        set diagNonMani 0
        set diagTriangle 0
    }
    
    if {$diagProblem && ($diagSingle || $diagMulti)} {
        switch $show_type {
            "Edges" {
                set disp_options(uns_shell_diagnostic) 0
            }
            default {
                set disp_options(uns_shell_diagnostic) 1
            }
        }
    } else {
        set disp_options(uns_shell_diagnostic) 0
    }
    if {[trace vinfo show_type] != ""} {
        trace vdelete show_type w aie_shell_trace_show_type
    }
    trace variable show_type w aie_shell_trace_show_type
    aie_shell_trace_show_type "" "" ""
}

proc onshellDiagnosticsDEZUnLoad {} {
     if {[trace vinfo show_type] != ""} {
        trace vdelete show_type w aie_shell_trace_show_type
    }   
}

proc aie_shell_trace_show_type {{name ""} {element ""} {op ""}} {

    switch [shellDiagnosticsDEZ get show_type] {
        Edges {
            ::AIEnv::GUIManagement::ToggleGrey shellDiagnosticsOver 1
            ::AIEnv::GUIManagement::ToggleGrey shellDiagnosticsNonMani 1
            ::AIEnv::GUIManagement::ToggleGrey shellDiagnosticsTriangle 1
        }
        default {
            ::AIEnv::GUIManagement::ToggleGrey shellDiagnosticsOver 0
            ::AIEnv::GUIManagement::ToggleGrey shellDiagnosticsNonMani 0
            ::AIEnv::GUIManagement::ToggleGrey shellDiagnosticsTriangle 0
        }
    }
}

proc onshellDiagnosticsDEZOK {} {
    aie_createShellDiagnostics 1
}

proc aie_shell_show_diagnostics {} {
    shellDiagnosticsDEZ show
}

proc aie_createShellDiagnostics {{from_dez 0}} {
    global aie_meshDisplay aie_shellDiagnosticDisplay aie_meshTypeVis
    global disp_options fam_visible diagnostic_problems_resolved
    if ![shellDiagnosticsDEZ isbuilt] {
        if !$from_dez return
    }
    if [info exists aie_shellDiagnosticDisplay(running)] return
    set aie_shellDiagnosticDisplay(running) 1
    set diag_exists [shellDiagnosticsDEZ aie_existsShellDiagnostics]
    set diag_ret 1
    foreach type "diagSingle diagMulti diagOver diagNonMani diagTriangle" {
        set $type [shellDiagnosticsDEZ get $type]
        if [set $type] { set diag_ret 0 }
    }
    shellDiagnosticsDEZ aie_deleteShellDiagnostics   
    set onvals ""; set offvals ""; set setvals ""
    foreach type "node line tri quad hexa tetra penta pyra" {
        if ![info exists aie_meshTypeVis($type)] continue
        foreach tt [aie_listElementTypes $type] {
            lappend onvals $tt
            lappend offvals !$tt
            if $aie_meshTypeVis($type) {
                lappend setvals $tt
            }
        }
        set aie_shellDiagnosticDisplay(on) $onvals
        set aie_shellDiagnosticDisplay(off) $offvals
        set aie_shellDiagnosticDisplay(set) $setvals
    }
    set diagProblem [shellDiagnosticsDEZ get diagProblem]
    if !$diagProblem {
       if [info exists aie_shellDiagnosticDisplay(show_only_subsets)] {
           unset aie_shellDiagnosticDisplay(show_only_subsets)
       }
       aie_updateMeshVis
    } 
    if {$diag_ret == "1"} {
        if $from_dez {
            aie_updateMeshVis
            shellDiagnosticsDEZ setdirty
        } else {
            if {$diag_exists && ![info exists diagnostic_problems_resolved]} {
                mess "All diagnostic problems in the model appear to be resolved. Turning off the diagnostic display.\n" blue
                set diagnostic_problems_resolved 1
            }
        }
        shellDiagnosticsDEZ aie_deleteShellDiagnostics 1
        aie_changeMeshDisplay
        return
    }
    set diagnostic_created 0
    set show_type [shellDiagnosticsDEZ get show_type] 
    
    ic_undo_suspend    
    set active ""
    foreach p [array names fam_visible] {
        if {$p == "ORFN"} continue
        if $fam_visible($p) {
            lappend active $p
        }
    }
    set types $aie_shellDiagnosticDisplay(set)
    if {$active == "" || $types == ""} {
        shellDiagnosticsDEZ aie_deleteShellDiagnostics
        aie_updateMeshVis
        unset aie_shellDiagnosticDisplay(running)
        return
    }
    if $diagProblem {
        set use_map [ic_uns_subset_create_family_type $active $types 0 0]
    } else {
        set use_map visible
    }
    foreach {on use} "diagSingle single diagMulti multiple diagOver overlap \
                      diagNonMani nmanvert diagTriangle triangle_box" {
        if [set $on] {
            set type $use
        } else {
            continue
        }
        set subset [ic_uns_create_diagnostic_subset 0]
        set elems [ic_uns_diagnostic subset $use_map diag_type $type disp_subset $subset quiet 1 fams $active type $types]
        set elems [lindex $elems 0]
        if {[ic_uns_subset_list_types $subset] == ""} {
            ic_uns_subset_delete $subset
            shellDiagnosticsDEZ set $on 0
            if $from_dez {
                mess "No problems were found for "
                switch $use {
                    single {
                        mess "single edges\n"
                    }
                    multiple {
                        mess "multiple edges\n"
                    }
                    overlap {
                        mess "overlapping elements\n"
                    }
                    nmanvert {
                        mess "non-manifold elements\n"
                    }
                    triangle_box {
                       mess "triangle boxes\n"
                    }
                }
            }
            continue
        } else {
            set diagnostic_created 1
            if $from_dez {
                mess "$elems problems were found for "
                switch $use {
                    single {
                        mess "single edges\n" #ffdd00
                    }
                    multiple {
                        mess "multiple edges\n" cyan
                    }
                    overlap {
                        mess "overlapping elements\n" gray
                    }
                    nmanvert {
                        mess "non-manifold elements\n" magenta
                    }
                    triangle_box {
                       mess "triangle boxes\n" orange
                    }
                }
            }
            if {$show_type == "Edges"} {
                ic_uns_subset_delete $subset
                continue
            }
        }
        set aie_shellDiagnosticDisplay($type) [ic_uns_subset_create "" 0]
        ic_uns_subset_copy $aie_shellDiagnosticDisplay($type) $subset
        if {$type == "overlap" && $show_type == "Edges and Faces"} {
            ic_uns_subset_add_layer $aie_shellDiagnosticDisplay($type) 1 $active $types
        }
        if {$show_type == "Edges and 2 layers of Faces"} {
            set num 1
            if $diagOver { set num 2 }
            ic_uns_subset_add_layer $aie_shellDiagnosticDisplay($type) $num $active $types
        }
        switch $type {
            single { set color yellow }
            multiple { set color cyan }
            overlap { set color gray }
            nmanvert { set color magenta }
            triangle_box { set color orange }
        }
        if {$diagSingle || $diagMulti} {
            set disp_options(uns_shell_diagnostic) 1
        }
        if $diagProblem {
            lappend aie_shellDiagnosticDisplay(show_only_subsets) $aie_shellDiagnosticDisplay($type)
        }
        ic_uns_subset_color $aie_shellDiagnosticDisplay($type) $color
        ic_uns_subset_delete $subset
    }
    if {$use_map != "visible"} {
        if [ic_uns_subset_exists $use_map] {
            ic_uns_subset_delete $use_map
        }
    }    
    if {$show_type != "Edges"} {
        if {($diagSingle && [info exists aie_shellDiagnosticDisplay(single)]) && \
            ($diagMulti && [info exists aie_shellDiagnosticDisplay(multiple)])} {
            set elems ""
            foreach e [ic_uns_subset_list_elements $aie_shellDiagnosticDisplay(single)] {
                append elems "[lindex $e 1] "
            }
            set shared ""
            foreach e [ic_uns_subset_list_elements $aie_shellDiagnosticDisplay(multiple)] {
                if {[lsearch "$elems" [lindex $e 1]] >= 0} {
                    append shared "[lindex $e 1] "
                }
            }
            if {$shared != ""} {
                set subset [ic_uns_subset_create single_multiple 0]
                aie_mesh_subset_update_elements $subset $shared $types $active "0 1 2 3"
                set aie_shellDiagnosticDisplay(single_multiple) $subset
                ic_uns_subset_color $aie_shellDiagnosticDisplay(single_multiple) green
            }
        }
    }    
    ic_undo_resume
    if {$show_type == "Edges" && ($diagSingle || $diagMulti) && $diagnostic_created} {
        set aie_meshDisplay(only_edges) $diagProblem
    } else {
        set aie_meshDisplay(only_edges) 0
    }
    set aie_meshDisplay(single_surfaces) $diagSingle
    set aie_meshDisplay(multiple_surfaces) $diagMulti
    aie_changeMeshDisplay
    if {$show_type != "Edges"} {
       if {!$diagnostic_created && !$from_dez} {
           if {$diag_exists && ![info exists diagnostic_problems_resolved]} {
                mess "All diagnostic problems in the model appear to be resolved. Turning off the diagnostic display.\n" blue
                set diagnostic_problems_resolved 1
           }
           shellDiagnosticsDEZ aie_deleteShellDiagnostics 2
           return
       }
       if $diagProblem {
           set show $aie_shellDiagnosticDisplay(off)
       } else {
           set show $aie_shellDiagnosticDisplay(set)
       }
       if [shellDiagnosticsDEZ aie_updateShellDiagnostics $from_dez] {
           ic_uns_update_family_type visible $active $show update 0
           if [info exists diagnostic_problems_resolved] {
               unset diagnostic_problems_resolved
           }
       } elseif {!$from_dez} {
           if {($diag_exists && !$diagnostic_created) && ![info exists diagnostic_problems_resolved]} {
                mess "All diagnostic problems in the model appear to be resolved. Turning off the diagnostic display.\n" blue
                set diagnostic_problems_resolved 1               
           }
       }
    } else {
        if {$from_dez && $diagProblem} {
            aie_updateMeshVis
        }
        if {!$from_dez && !$diagnostic_created && ![info exists diagnostic_problems_resolved]} {
             mess "All diagnostic problems in the model appear to be resolved. Turning off the diagnostic display.\n" blue
             set diagnostic_problems_resolved 1
        }
    }
    if $diagnostic_created {
        if [info exists diagnostic_problems_resolved] {
            unset diagnostic_problems_resolved
        }
        if {$diagSingle || $diagMulti} {
            set disp_options(uns_shell_diagnostic) 1
        }
    } else {
        set disp_options(uns_shell_diagnostic) 0
        if $from_dez {
            mess "No problems were found\n"
            ic_uns_update_family_type visible $active $aie_shellDiagnosticDisplay(set) update 0
            aie_deleteShellDiagnostics 2
        }
    }
    if [info exists aie_shellDiagnosticDisplay(running)] {
        unset aie_shellDiagnosticDisplay(running)
    }
    shellDiagnosticsDEZ setdirty
}

proc aie_updateShellDiagnostics {{dez 0}} {
    global aie_meshDisplay aie_shellDiagnosticDisplay

    if ![shellDiagnosticsDEZ isbuilt] { return 0 }
    if ![info exists aie_shellDiagnosticDisplay] { return 0 }

    set show_only_subsets 0
    if [info exists aie_shellDiagnosticDisplay(single)] {
        set aie_meshDisplay(single_surfaces) 1
    } else {
        set aie_meshDisplay(single_surfaces) [shellDiagnosticsDEZ get diagSingle]
    }
    if [info exists aie_shellDiagnosticDisplay(multiple)] {
        set aie_meshDisplay(multiple_surfaces) 1
    } else {
        set aie_meshDisplay(multiple_surfaces) [shellDiagnosticsDEZ get diagMulti]
    }
    foreach type "single multiple single_multiple overlap nmanvert triangle_box" {
        if [info exists aie_shellDiagnosticDisplay($type)] {
            ic_uns_subset_configure $aie_shellDiagnosticDisplay($type) -draw_icons 1 -width 1
            ic_uns_subset_visible $aie_shellDiagnosticDisplay($type) 1
            set show_only_subsets 1
        }
    }
    if {!$show_only_subsets && [info exists aie_shellDiagnosticDisplay(show_only_subsets)]} {
        unset aie_shellDiagnosticDisplay(show_only_subsets)
    }
    return $show_only_subsets
}

proc aie_existsShellDiagnostics {} {
    global aie_shellDiagnosticDisplay
 
    if ![shellDiagnosticsDEZ isbuilt] { return 0 }
    if ![info exists aie_shellDiagnosticDisplay] { return 0 }

    foreach type "single multiple single_multiple overlap nmanvert triangle_box" {
        if [info exists aie_shellDiagnosticDisplay($type)] {
            return 1
        }
    }
    return 0
}

proc aie_displayShellDiagnostics {on} {
    global aie_shellDiagnosticDisplay select_action

    if [info exists select_action] {
        set last_select_action $select_action
    }
    if ![shellDiagnosticsDEZ isbuilt] return
    if ![info exists aie_shellDiagnosticDisplay] return
    foreach type "single multiple single_multiple overlap nmanvert triangle_box" {
        if [info exists aie_shellDiagnosticDisplay($type)] {
            ic_uns_subset_visible $aie_shellDiagnosticDisplay($type) $on
        }
    }
    if [info exists last_select_action] {
        set select_action $last_select_action
        unset last_select_action
    }
}

proc aie_deleteShellDiagnostics {{reset 0}} {
    global aie_meshDisplay aie_shellDiagnosticDisplay disp_options diagnostic_problems_resolved 

    if ![shellDiagnosticsDEZ isbuilt] return
    foreach type "single multiple single_multiple overlap nmanvert triangle_box" {
        if {[info exists aie_shellDiagnosticDisplay($type)] && \
            [ic_uns_subset_exists $aie_shellDiagnosticDisplay($type)]} {
            ic_uns_subset_delete $aie_shellDiagnosticDisplay($type)
            unset aie_shellDiagnosticDisplay($type)
        }
    }
    if [info exists aie_shellDiagnosticDisplay(show_only_subsets)] {
        unset aie_shellDiagnosticDisplay(show_only_subsets)
    }
    if $reset {
        foreach type "diagSingle diagMulti diagOver diagNonMani diagTriangle diagProblem" {
            shellDiagnosticsDEZ set $type 0
        }
        shellDiagnosticsDEZ set show_type Edges
        foreach type "single_surfaces only_edges multiple_surfaces" {
            set disp_options($type) 0
            set aie_meshDisplay($type) 0
        }
        set disp_options(uns_shell_diagnostic) 0
        if [info exists aie_shellDiagnosticDisplay] {
            unset aie_shellDiagnosticDisplay
        }
        if {$reset == "2" && [info exists diagnostic_problems_resolved]} {
            unset diagnostic_problems_resolved
        }
    }
}

proc aie_active_dez {} {
    if [info exists ::AIEnv::GUIManagement::ActiveDEZ] {
        return $::AIEnv::GUIManagement::ActiveDEZ
    } 
    return NULL
}

proc aie_update_dez_onerror {} {
    if [info exists ::AIEnv::GUIManagement::ActiveDEZ] {
        set dez $::AIEnv::GUIManagement::ActiveDEZ
	    if {$dez != "NULL"} {
	        $dez setdirty
 	    }
    }
}

proc aie_update_dez_value {dez param value} {
    global batch_mode

    if $batch_mode return
	if {[aie_active_dez] == $dez} {
	    $dez set $param $value
    }
}

proc aie_geo_set_grey {what on} {
# valid for active DEZ only; "on" may be 0/1/varname 
	if [info exists $on] {set on [set $on]}
	if {$on != "1"} {
		set on 0
	} 
	catch "::AIEnv::GUIManagement::ToggleGrey $what $on"
}

proc aie_gui_get {var} {
# This is a GUI version of "ic_gui_set" - to avoid records in replay file
# get value of GUI toplevel variable or array member; 
# set variable 0 if it's not defined
	if ![uplevel #0 info exists $var] {
		uplevel #0 set $var 0
	}
	return [uplevel #0 set $var]
}

proc aie_temporary_reset_record {{how resume}} {
    # off/resume - stop/resume records
    global va_set command_hook after_command_hook

    if {$how == "off"} {
	if [info exists command_hook] {
		set va_set(reset_command_hook) $command_hook	
		unset command_hook
	}
	if [info exists after_command_hook] {
		set va_set(reset_after_command_hook) $after_command_hook
		unset after_command_hook
	}	  
    } else {
	if [info exists va_set(reset_command_hook)] {
		set command_hook $va_set(reset_command_hook)
		unset va_set(reset_command_hook)
	}
	if [info exists va_set(reset_after_command_hook)] {
		set after_command_hook $va_set(reset_after_command_hook)
		unset va_set(reset_after_command_hook)
	}	  
    }
}

proc aie_val_calc_dialog {} {
    ::AIEnv::GUIManagement::ConfigureConsoleZone 1
    val_calc_dialog
}

proc aie_unset_global {name {field ""}} {
    if {$name == ""} { return 0 }
    global $name
    if {$field == ""} {
        if {[aie_get_global ${name}] != "___NA___"} {
            unset ${name}
        }
    } else {
        if {[aie_get_global ${name} $field] != "___NA___"} {
            unset ${name}($field)
        }
    }
    return 1
}

proc aie_set_global {name value {field ""}} {
    if {$name == ""} { return 0 }
    global $name
    if {$field == ""} {
        set ${name} $value
    } else {
        set ${name}($field) $value
    }
    return 1
}

proc aie_get_global {name {field ""}} {
    if {$name == "" && $field == ""} { return "___NA___" }
    global $name
    if {$field == ""} {
        if [info exists $name] {
            return "[set ${name}]"
        }
    } else {
        if [info exists ${name}($field)] {
            return "[set ${name}($field)]"
        }
    }
    return "___NA___"
}

proc aie_get_global_array_names {name} {
    if {$name == ""} { return "___NA___" }
    global $name
    if [array exists ${name}] {
        return "[array names ${name}]"
    }
    return "___NA___"
}

proc aie_get_global_array {name} {
    if {$name == ""} { return "___NA___" }
    global $name
    if [array exists ${name}] {
        return "[array get ${name}]"
    }
    return "___NA___"
}

proc aie_update_gui {{what ""}} {
    global batch_mode 
    variable ::AIEnv::GUIManagement::Tree::aieTree
    
    if $batch_mode return
    
    switch -- $what {
        geom {
            if ![ic_geo_is_loaded] return
            if [$::AIEnv::GUIManagement::Tree::aieTree exists geom_subsetNode] {
                $::AIEnv::GUIManagement::Tree::aieTree delete geom_subsetNode
            }
            aie_create_parts_in_tree_if_needed
            aie_update_icons geom
            aie_init_geom_subsets
            aie_initGeoVis
            aie_afterStuffLoaded
            return
        }
        mesh {
            if ![ic_uns_is_loaded] return
            InitUnsMeshDisplaySettings
            aie_after_open_mesh 0 0
            ic_uns_families_changed
            aie_afterStuffLoaded
            return
        }
        block {
            if ![ic_hex_blocking_loaded] return
            aie_hex_update_display
            aie_afterStuffLoaded
            return
        }
        group {
            aie_delete_empty_parts
            aie_part_update_nodes
            ::AIEnv::GUIManagement::Tree::RefreshParts
            return
        }
    }
}

#+++++++++++++++++++++++++++++++++++++++
#+++++++++++++++++++++++++++++++++++++++
# new MeshPro (faceted) stuff, June 2008, contact VG if problems
#+++++++++++++++++++++++++++++++++++++++
#+++++++++++++++++++++++++++++++++++++++
# family MP12_TMP
proc aie_mp12_create_temporary_curve {} {
# For usage during location selection
# uses global va_set array; uses permanent curve name "mp12_tmp_crv"
aie_temporary_reset_record off 
  ic_delete_geometry curve names mp12_tmp_crv 0
  set mp12_closed [set ::va_set(create_closed_curveFlag)]
  set mp12_smooth [set ::va_set(create_smooth_curveFlag)]  
  set pts [set ::va_set(global_coords)]
  set np [llength $pts]
  
  if {$np == 0} { aie_mp12_boundary_curve delete}
  if {$np == 1} { aie_mp12_boundary_curve create [set ::va_set(names_for_coords)]}  
  if {$np < 2} return
  # see below for number of points for open/closed curves

  if {!$mp12_closed} {
    # arc only from 3 points
    if {$mp12_smooth == 2 && $np < 3} return
    switch $mp12_smooth {
     0 {ic_geo_cre_bsp_crv_n_pnts MP12_TMP mp12_tmp_crv $pts 0.0001 1}
     1 {ic_geo_cre_bsp_crv_n_pnts MP12_TMP mp12_tmp_crv $pts 0.0001 3}
     2 {ic_geo_cre_arc_from_pnts MP12_TMP mp12_tmp_crv [lindex $pts 0] [lindex $pts 1] [lindex $pts 2]}
    } 
  } else {
  # $mp12_closed
    # for line and smooth connect [add] first point at the end   
    if {$mp12_smooth < 2} {
       set pts [lappend pts [lindex $pts 0]]    
    } else {
    # for circle allow 2 points if MP12_screen
     if {$np < 3 && ([ic_csystem_get MP12_screen] == "")} return 
    } 
   switch $mp12_smooth {
    0 {ic_geo_cre_bsp_crv_n_pnts MP12_TMP mp12_tmp_crv $pts 0.0001 1}
    1 {ic_geo_cre_bsp_crv_n_pnts MP12_TMP mp12_tmp_crv $pts 0.0001 3}
    2 {ic_curve circle MP12_TMP mp12_tmp_crv $pts}
   }
  }
 ic_highlight add mp12_tmp_crv color yellow
 aie_temporary_reset_record resume    
}
proc aie_mp12_boundary_curve {what {srf ""}} {
   # only one temporary curve with fixed name:
   # it will be deleted on cleaning! 
   set fam MP12_TMP
   set nam mp12_tmp_boundary
   if {$what == "delete"} {
     ic_delete_geometry curve names $nam 0
     return
   }
   if {[ic_geo_check_objects_exist curve $nam] == $nam} return
   set newc [ic_geo_extract_curves $srf 1 0 0]
   if {$newc == ""} return
   ic_geo_set_family  curve $fam names $newc 0
   ic_geo_set_name  curve $newc $nam 
   ic_geo_set_tag curve $nam use_first_surface 1 
   ic_highlight add $nam color red width 2 
}
#=======================================
proc aie_mp12_seg_surf_by_screen {dist} {
# dist - how far from curve to drill (nagative LCS Z!!!)
# part - where put new surfaces

   global va_set tdv_current_viewer
   set w $tdv_current_viewer

   set srfs [ic_geo_objects surface only_if_visible only_if_faceted]
    
   # curve was created in Z=0 LCS plane 
   ic_geo_duplicate curve mp12_tmp_crv mp12_tmp_crv1
   ic_move_geometry curve names mp12_tmp_crv1 translate "0 0 -$dist"
   
   ic_geo_create_surface_from_curves MP12_TMP mp12_tmp_srf 0.0001 "mp12_tmp_crv mp12_tmp_crv1"
   if ![llength [ic_geo_check_objects_exist surface mp12_tmp_srf]] {
     status_message "Cannot create intersections. Contact developer\n" red
     return
   }
   set newsrfs ""
   foreach srf $srfs {      
       set crvinter [ic_geo_intersect_surfaces MP12_TMP "mp12_tmp_srf $srf"]
       if {$crvinter != ""} {
         foreach crv $crvinter {
         update idletasks
         append newsrfs " [ic_geo_create_surface_segment $srf curve curves $crv]"
         }
       }
   }
   # DB keep surface for debugging:
   # ic_delete_geometry surface names mp12_tmp_srf 0
     
  return $newsrfs
}
#==============================
proc aie_mp12_repaire_seg_surf {part name {keep_old 0}} {
   set srf [lindex [set ::va_set(names_for_coords)] 0]
   set crv_shape [set ::va_set(create_smooth_curveFlag)]
    
   if {[ic_geo_lookup surface names $srf] == ""} {return "No srf"} 
   if {[ic_geo_get_object_type surface $srf] != "mesh"} {return "Not mesh srf"}    
   if {[ic_geo_lookup curve names mp12_tmp_crv] == ""} {return "No crv"}
   ic_delete_geometry curve names mp12_tmp_crv1 0

   
   # For better shape of new surface - split curve:
    set split_points ""   
   if {$crv_shape == 2} {
     foreach par {0.25 0.5 0.75} {
       lappend split_points [lindex [ic_geo_get_crv_pos $par mp12_tmp_crv] 0]
     }
   } else {
     # do not split at first point
     set split_points [lrange [set ::va_set(global_coords)] 1 end]
   } 
    set new_crvs [ic_geo_split_curve mp12_tmp_crv $split_points]

   set new_projected ""
   foreach crv $new_crvs {
     set new_p [ic_geo_project_curve_to_surface $crv $srf mp12_tmp_p_ MP12_TMP 1] 
     if {$new_p == ""} {
        lappend new_projected $crv
     } else {
       foreach c $new_p {
         lappend new_projected $c
       }     
     }
   }
   update idletasks 
   
     
   ic_surface bsinterp $part $name $new_projected btopo 0
 #  set newsrfs [ic_geo_create_surface_segment $srf curve curves $for_trim]
   set newsrfs [ic_geo_create_surface_segment $srf curve curves $new_projected]  
   if {$newsrfs == ""} {
      return "No trim"
   }
   if !$keep_old {
     ic_delete_geometry surface names [lrange $newsrfs 1 end] 0
   }
   return OK
 }   
#====================================
proc aie_mp12_set_facets_part_in_Z_dir {part srfs} {
global va_set tdv_default
# uses: va_set; crv_shape== 2 - circle
  set crv_shape [set ::va_set(create_smooth_curveFlag)]
 
       aie_mp12_set_tag_on_faceted faceted.surface $srfs  
       if {$crv_shape == 2} { # use true circle, center may be off 3 points!!!
        set data [ic_curve circle MP12_TMP mp12_tmp_crv $va_set(global_coords) only_data 1]       
       } else {  # use average center and data
       set data [ic_curve circle MP12_TMP mp12_tmp_crv $va_set(global_coords) only_data 1 maximum_radius 1]          
       }
       set selected  [eval va_get_faceted_in_circle faceted.surface $data]
       set nsel [llength $selected]
       if !$nsel return
       if {$part != ""} {
         ic_geo_set_family surface $part names $selected
       } else {
         ic_highlight surface $selected width 2 color ""
       }
       return $nsel 
}
#==============================

proc aie_mp12_clean {{on 0}} {
# delete temporary items
if {$on == "-1"} {set ::MP12_NO_CLEAN ""; status_message "Cleaning OFF" red}
if {$on ==  "1"} {catch "unset ::MP12_NO_CLEAN"; status_message "Cleaning ON" green}
if [info exists ::MP12_NO_CLEAN] return
aie_temporary_reset_record off
  ic_delete_geometry curve names "mp12_tmp_crv mp12_tmp_crv1" 0
  ic_delete_geometry surface names mp12_tmp_srf 0
  catch "ic_csystem_delete MP12_screen"
  # 
  ic_delete_geometry all families MP12_TMP 1 1
  status_message ""
  
# next is some old stuff, may be unused  
    global va_set
    foreach i [list curve_name surf_name n_slice width fillet] {
	set va_set($i) ""
    }
    ic_delete_geometry all families MPCHAR 1 1
    ic_delete_geometry all families MPTPTS 1 1
    ic_delete_geometry all families MPGUIDE 1 1 
    if [ic_undo_suspended] ic_undo_resume  
aie_temporary_reset_record resume    
}
#===========================
proc aie_mp12_set_lcs {{how use_if_exists}} {
# 1. - return box LCS Z size [normal screen] 
# 2.Screen LCS will be created outside bbox (before objects)
# 3. All objects will be at negative LCS Z coords
# 4. If lcs does not exists or how = "reset" - Recalculate and reset LCS & size 
 global va_set # keep LCS Z size instead of recalculate 
 
aie_temporary_reset_record off
    if ![info exists va_set(box_LCS_Z_size)] {
       set how "reset"
     }
    
    if {($how == "reset") || ([ic_csystem_get MP12_screen] == "")} {
      catch "ic_csystem_delete MP12_screen"
      catch "ic_csystem_delete MP12_screen_tmp"     
 
      
      aie_mp12_set_screen_lcs MP12_screen_tmp {0 0 0}
      
   # check bbox and create LCS outside bbox in screen plane 
   set bbox [ic_geo_model_bounding_box]
     if {$bbox == ""} {
     aie_temporary_reset_record resume   
      return 
   }
   foreach "min max" $bbox ""  
   foreach "x1 y1 z1" $min ""
   foreach "x2 y2 z2" $max ""

   set zmin  1000000.0
   set zmax -1000000.0

   foreach xyz {{$x1 $y1 $z1} {$x1 $y1 $z2} {$x1 $y2 $z1} {$x1 $y2 $z2}
       {$x2 $y1 $z1} {$x2 $y1 $z2} {$x2 $y2 $z1} {$x2 $y2 $z2}} {
       set xyz [subst $xyz]
       set z [lindex [ic_coords_into_local $xyz] 2]
       if {$z > $zmax} {set zmax $z}
       if {$z < $zmin} {set zmin $z}
    }
    #
    set va_set(box_LCS_Z_size) [expr $zmax - ($zmin)]
    set cloc [ic_coords_into_local {0 0 0}]
    set cnew [lreplace $cloc 2 2 $zmax]
    set cnew_glob [ic_coords_into_global $cnew]
 
    ic_csystem_delete MP12_screen_tmp
    aie_mp12_set_screen_lcs MP12_screen $cnew_glob 
    set va_set(screen_view) [ic_current_view]
           
    }
    ic_csystem_set_current MP12_screen 
    aie_temporary_reset_record resume 
    return  $va_set(box_LCS_Z_size)
}

#==========================
proc aie_mp12_set_tag_on_faceted {{tag geo_select_segment} {fsrfs ""}} {
 if {$fsrfs == ""} {
   set fsrfs [ic_geo_objects surface only_if_visible only_if_faceted]
 }
 if ![llength $fsrfs] {
   status_message "No faceted visible surfaces" red
   return
 }
 ic_geo_set_tag clear "" $tag 0
 foreach n $fsrfs {
    ic_geo_set_tag surface $n $tag 1
 }
 return $fsrfs
}
proc aie_mp12_set_screen_lcs {name orig} {
  ic_csystem_set_current global 
  set scr_z [val_get_screen_nrm]
  set scr_x [val_get_screen_dir right]
  set scr_y [ic_vcalc mult $scr_z $scr_x]
  ic_csystem_create $name cartesian $orig $scr_x $scr_y $scr_z
  ic_csystem_set_current $name
}
proc aie_mp12_create_2_temporary_curves {} { 
# offset and project basic curve:
set crv mp12_tmp_crv
if {[ic_geo_check_objects_exist curve $crv] == ""} {return}
 set srfs [set ::va_set(names_for_coords)]
 set np [llength $srfs]
 if !$np {return}
 incr np -1
 set xyz [lindex [set ::va_set(global_coords)] $np]
 set srf [lindex $srfs $np]
 set newc mp12_tmp_crv$np
 set xyz_crv [ic_geo_project_coords curve $crv $xyz]
 set dif [ic_vcalc diff $xyz_crv $xyz]
 set off [ic_vcalc len $dif]
 set dir [ic_vcalc dir $xyz_crv $xyz]
 set par_on_crv [ic_geo_find_nearest_crv_pnt $crv $xyz_crv]
 set tan_on_crv [ic_geo_get_crv_tan $par_on_crv $crv]
 set srf_norm [ic_vcalc product $dir $tan_on_crv ]
 set srf_norm [ic_vcalc nrm $srf_norm]
  
 set newc mp12_tmp_crv$np
 ic_delete_geometry curve names $newc 0
 
 set newpts ""
 for {set par 0.0} {$par <=1.0} {set par [expr $par + 0.2]} {
  set tan_on_crv [ic_geo_get_crv_tan $par $crv]
  set pnt_on_crv [lindex [ic_geo_get_crv_pos $par $crv] 0]
  set dir [ic_vcalc product $tan_on_crv $srf_norm]
  set dir [ic_vcalc nrm $dir]
  set add_vec [ic_vcalc smult $dir $off]
  lappend newpts [ic_vcalc sum $pnt_on_crv $add_vec]
  }
  set newc [ic_geo_cre_bsp_crv_n_pnts MP12_TMP $newc $newpts]  
  
 set new_pc [ic_geo_project_curve_to_surface $newc $srf ${newc}_p]
 if {$new_pc != ""} {
   ic_delete_geometry curve names $newc 0
 } else {
   set new_pc $newc
 }
 if {$new_pc != $newc} { 
  ic_delete_geometry curve names $newc 0 
  ic_geo_set_name curve $new_pc $newc
 }
 ic_highlight add $newc
 return $newc
}
#===========================
#=======================
proc aie_mp12_create_more_locations {crv1 crv2 par factors} {
if {[ic_geo_check_objects_exist curve $crv1] == ""} {status_message "No $crv1";return}
if {[ic_geo_check_objects_exist curve $crv2] == ""} {status_message "No $crv2";return}
set srf  [lindex [set ::va_set(names_for_coords)] 0]
if {[ic_geo_check_objects_exist surface $srf] == ""} {return}
set res ""
foreach fac $factors {
  set p1 [lindex [ic_geo_get_crv_pos $par $crv1] 0]
  set p2 [lindex [ic_geo_get_crv_pos $par $crv2] 0]
  set d [ic_vcalc diff $p1 $p2]
  set dsc [ic_vcalc smult $d $fac]
  set xyz [ic_vcalc sum $p1 $dsc]
  lappend res [ic_geo_project_coords surface $srf $xyz {0 0 0}] 
}
return $res

}
proc aie_mp12_show_presurface {{part ""} {name mp12_tmp_presrf}} {
 
 if {$part == ""} {
    set part MP12_TMP
 } 
 
 set n_cross 5
 set red [expr 1.0/$n_cross] 
 set fact0 {1.0 0.95 0.9 0.8 0.5 0.4 0.3}
 set fact1 {0.3 0.4 0.5 0.8 0.9 0.95 1.0}
 set cross_crvs ""
 set tol ""  
 for {set par 0} {$par <= 1.0} {set par [expr $par+$red]} {
  set list1 [aie_mp12_create_more_locations mp12_tmp_crv mp12_tmp_crv0 $par $fact0]
  set list2 [aie_mp12_create_more_locations mp12_tmp_crv mp12_tmp_crv1 $par $fact1]
  set pnts [append list1 " " $list2] 
  lappend cross_crvs [ic_geo_cre_bsp_crv_n_pnts MP12_TMP mp12_tmp_cross $pnts]  
  # calculate tol as 0.01*distance 1-st - last point of 1-st curve
   if {$tol == ""} {
    set dis [ic_vcalc distance [lindex $pnts 0] [lindex $pnts end]]
    set tol [expr 0.01*$dis] 
   }
 }
 set newsrf [ic_geo_cre_srf_loft_crvs $part $name $tol $cross_crvs] 
}  

# end of MP12 stuff






