# Meshing interface callbacks

proc onmeshLineDEZOK {} {
    busy 1
    set err_code 0
    aie_autosizing quad
    if {![ic_quad2 what "curves_only" entities $curvList]} {
        mess "Meshing completed.\n" blue
    }
    aie_updateMeshVis
    aie_update_icons mesh
    busy reset
}

proc onmeshQuadDEZLoad {} {
    global beta_mode env
    if {[info exists env(QUAD_DEBUG)]} {
        set typeList {
            "All Quad"
            "Quad w/one Tri"
            "Quad Dominant"
            "All Tri"
            "Tri (STL like)"
            "Tri (split STL)"
            "Tri (Delaunay)"
        }
    } else {
        set typeList {
            "All Quad"
            "Quad w/one Tri"
            "Quad Dominant"
            "All Tri"
            "Tri (STL like)"
            "Tri (Delaunay)"
        }
    }
    if ![info exists QuadMethod] {
        set QuadMethod 0
        meshQuadElType setvalue @2
        set projection 1
        set improvement 1
        set b_smooth 0
        set iterations 20
        set iters 20
        set use_surface_sizes 0
        set ignore [aie_default_topo_tolerance]
        set protect 0
        set simple_offset "Standard"
        set inner 0
        set max_area 0
        set max_length 0
        set min_angle 0
        set max_nodes 0
        set max_elements 0
        set enn 0
        set bunch 0
        set remove_old 1
        set accuracy 0.025
        set MaxDev 0
        set geo_tol 0
        set block 0.2
        set adjust_nodes_max 0
        set offset 0
        set offset_h 0.7
        set try_harder 1
        set pattern 150
        set board 0
        set breakpoint 0
        set time_max 0
        set ele_max 0
        set four 0
        set dormant 0
        set smoothdormant 0
        set debug 0
        set DelaunayFlag 0
        set ProximityFlag 0
        set VerboseFlag 0
        set ExpansionFactor 1.2
        set RebuildTopoFlag 0
        set MergeSurfFlag 0
        set TopoTolerance [aie_default_topo_tolerance]
        set loadFlag 1
    }
    set OffsetList {
        "Standard"
        "Simple"
        "Forced simple"
    }
    set AllowActiveReload 1
    if [info exists defineSurfMeshTVal] {
        meshQuadDEZ set defineSurfMeshTVal [meshQuadDEZ get defineSurfMeshTVal]
    } else {
        meshQuadDEZ set defineSurfMeshTVal 0
    }
    switch $defineSurfMeshTVal {
        1 {
            set typeList {
                "All Tri"
                "All Quad"
                "Quad Dominant"
            }
        }
        2 {
            set typeList {
                "All Quad"
                "Quad w/one Tri"
                "Quad Dominant"
                "All Tri"
                "Tri (STL like)"
            }
        }
    }

    if ![info exists env(AI_ENV_QUAD)] {
       ::AIEnv::GUIManagement::ToggleGrey defineSurfMeshPB 1
       ::AIEnv::GUIManagement::ToggleGrey defineSurfMeshHex 1
       if [info exists env(AI_ENV_TETRA)] {
          meshQuadDEZ set defineSurfMeshTVal 1
       }
    } else {
       ::AIEnv::GUIManagement::ToggleGrey defineSurfMeshPB 0
       ::AIEnv::GUIManagement::ToggleGrey defineSurfMeshHex 0
    }
    if ![info exists env(AI_ENV_TETRA)] {
       ::AIEnv::GUIManagement::ToggleGrey defineSurfMeshPI 1
    } else {
       ::AIEnv::GUIManagement::ToggleGrey defineSurfMeshPI 0
    }
}

proc onmeshQuadDEZAfterLoad {} {
    global env
    if {[trace vinfo elType] != ""} {
        trace vdelete elType w aie_quad_trace_elType
    }
    trace variable elType w aie_quad_trace_elType
    if {[trace vinfo defineSurfMeshTVal] != ""} {
        trace vdelete defineSurfMeshTVal w aie_quad_trace_projection
    }
    trace variable defineSurfMeshTVal w aie_quad_trace_projection
    if {[trace vinfo QuadMethod] != ""} {
        trace vdelete QuadMethod w aie_quad_trace_QuadMethod
    }
    trace variable QuadMethod w aie_quad_trace_QuadMethod
    foreach v {bunch protect ignore} {
        if {[trace vinfo $v] != ""} {
            trace vdelete $v w aie_quad_trace_bunch
        }
        trace variable $v w aie_quad_trace_bunch
    }
    foreach v {dormant smoothdormant} {
        if {[trace vinfo $v] != ""} {
            trace vdelete $v w aie_quad_trace_dormant
        }
        trace variable $v w aie_quad_trace_dormant
    }
    aie_quad_trace_elType "" "" ""
    aie_quad_trace_bunch "" "" ""
    aie_quad_trace_dormant "" "" ""
    if [info exists env(AI_ENV_BETA)] {
        set TopoTolerance [aie_default_topo_tolerance]
    }
}

proc onmeshQuadDEZUnLoad {} {
    if {[trace vinfo elType] != ""} {
        trace vdelete elType w aie_quad_trace_elType
    }
    if {[trace vinfo defineSurfMeshTVal] != ""} {
        trace vdelete defineSurfMeshTVal w aie_quad_trace_projection
    }
    if {[trace vinfo QuadMethod] != ""} {
        trace vdelete QuadMethod w aie_quad_trace_QuadMethod
    }
    foreach v {bunch protect ignore} {
        if {[trace vinfo $v] != ""} {
            trace vdelete $v w aie_quad_trace_bunch
        }
    }
    foreach v {dormant smoothdormant} {
        if {[trace vinfo $v] != ""} {
            trace vdelete $v w aie_quad_trace_dormant
        }
    }
}

proc aie_quad_trace_elType {name element op} {
    onMeshQuadElTypeModify meshQuadDEZ "[meshQuadDEZ get elType]"
}

proc aie_quad_trace_QuadMethod {name element op} {
    if {[meshQuadDEZ get QuadMethod] == "1"} {
        ::AIEnv::GUIManagement::ToggleGrey meshQuadSurfaceSizes 1
    } else {
        set val [meshQuadDEZ get elType]
        if {$val == "Tri (STL like)" || $val == "Tri (split STL)" || $val == "Tri (Delaunay)"} {
            ::AIEnv::GUIManagement::ToggleGrey meshQuadSurfaceSizes 1
        } else {
            ::AIEnv::GUIManagement::ToggleGrey meshQuadSurfaceSizes 0
        }
    }
}

proc aie_quad_trace_projection {{name ""} {element ""} {op ""}} {
    global env
    if [meshQuadDEZ get projection] {
        set val [meshQuadDEZ get elType]
        if {$val == "Tri (STL like)" || $val == "Tri (split STL)" || $val == "Tri (Delaunay)"} {
            ::AIEnv::GUIManagement::ToggleGrey meshQuadMaxDev 1
        } else {
            ::AIEnv::GUIManagement::ToggleGrey meshQuadMaxDev 0
        }
    } else {
        ::AIEnv::GUIManagement::ToggleGrey meshQuadMaxDev 1
    }
}

proc aie_quad_trace_bunch {{name ""} {element ""} {op ""}} {
    if [meshQuadDEZ get bunch] {
        if {[meshQuadDEZ get ignore] > 0} {
            ::AIEnv::GUIManagement::ToggleGrey meshQuadProtect 0
        } else {
            ::AIEnv::GUIManagement::ToggleGrey meshQuadProtect 1
        }
    } else {
        ::AIEnv::GUIManagement::ToggleGrey meshQuadProtect 1
    }
}

proc aie_quad_trace_dormant {{name ""} {element ""} {op ""}} {
    if [meshQuadDEZ get dormant] {
        ::AIEnv::GUIManagement::ToggleGrey meshQuadSmoothDormant 0
    } else {
        ::AIEnv::GUIManagement::ToggleGrey meshQuadSmoothDormant 1
    }
}

proc onMeshQuadElTypeModify {dez val} {
    global env beta_mode

    if {$val == "All Tri" || $val == "Tri (STL like)" || \
        $val == "Tri (split STL)" || $val == "Tri (Delaunay)"} {
        ::AIEnv::GUIManagement::ToggleGrey meshQuadBlock 1
        ::AIEnv::GUIManagement::ToggleGrey meshQuadAdjustNodesMax 1
    } else {
        ::AIEnv::GUIManagement::ToggleGrey meshQuadBlock 0
        ::AIEnv::GUIManagement::ToggleGrey meshQuadAdjustNodesMax 0
    }
    if {$val == "Tri (STL like)" || $val == "Tri (split STL)" || $val == "Tri (Delaunay)"} {
        ::AIEnv::GUIManagement::ToggleGrey meshQuadSurfaceSizes 1
        ::AIEnv::GUIManagement::ToggleGrey meshQuadMaxDev 1
        ::AIEnv::GUIManagement::ToggleGrey meshQuadHarder 1
        if {[info exists env(QUAD_DEBUG)]} {
            ::AIEnv::GUIManagement::ToggleGrey meshQuadInner 1
        }
    } else {
        aie_quad_trace_QuadMethod "" "" ""
        aie_quad_trace_projection "" "" ""
        ::AIEnv::GUIManagement::ToggleGrey meshQuadHarder 0
        if {[info exists env(QUAD_DEBUG)]} {
            ::AIEnv::GUIManagement::ToggleGrey meshQuadInner 0
        }
    }
    if {$val == "Tri (STL like)"} {
        ::AIEnv::GUIManagement::ToggleGrey meshQuadProject 1
    } else {
        ::AIEnv::GUIManagement::ToggleGrey meshQuadProject 0
    }
    if {$val == "Tri (Delaunay)"} {
        ::AIEnv::GUIManagement::ToggleGrey meshMaxArea 0
        ::AIEnv::GUIManagement::ToggleGrey meshMaxLength 0
        ::AIEnv::GUIManagement::ToggleGrey meshMinAngle 0
        ::AIEnv::GUIManagement::ToggleGrey meshMaxNodes 0
        ::AIEnv::GUIManagement::ToggleGrey meshMaxElements 0
    } else {
        ::AIEnv::GUIManagement::ToggleGrey meshMaxArea 1
        ::AIEnv::GUIManagement::ToggleGrey meshMaxLength 1
        ::AIEnv::GUIManagement::ToggleGrey meshMinAngle 1
        ::AIEnv::GUIManagement::ToggleGrey meshMaxNodes 1
        ::AIEnv::GUIManagement::ToggleGrey meshMaxElements 1
    }
    if {$val == "Tri (split STL)"} {
        ::AIEnv::GUIManagement::ToggleGrey meshQuadSmoothBoundary 1
    } else {
        ::AIEnv::GUIManagement::ToggleGrey meshQuadSmoothBoundary 0
    }
}

proc ondefineSurfMeshPILoad {} {
    set saved_typelist $typeList
    set typeList {
        "All Tri"
        "All Quad"
        "Quad Dominant"
    }
    meshQuadElType setvalue @0
    set AllowActiveReload 1
}

proc ondefineSurfMeshPIUnLoad {} {
    set typeList $saved_typelist
    meshQuadElType setvalue @2
}

proc ondefineSurfMeshHexLoad {} {
    set saved_typelist $typeList
    set typeList {
        "All Quad"
        "Quad w/one Tri"
        "Quad Dominant"
        "All Tri"
        "Tri (STL like)"
    }
    meshQuadElType setvalue @0
    set AllowActiveReload 1
}

proc ondefineSurfMeshHexUnLoad {} {
    set typeList $saved_typelist
    meshQuadElType setvalue @2
}

proc onmeshQuadDEZOK {} {
    global options env

    set err_code 0
    busy 1
    switch $defineSurfMeshTVal {
        0 {
            aie_autosizing quad
            if {(![info exists QuadMethod]) || ($QuadMethod == "")} {
                mess "Must select a Method to mesh.\n" red
                busy 0
                return
            }
            if {$debug > 0} {
                mess "Debug level = $debug\n" red
                mess "QuadMethod = $QuadMethod\n" red
            }
            switch $simple_offset {
                "Standard" { set use_simple_offset 0 }
                "Simple" { set use_simple_offset 1 }
                "Forced simple" { set use_simple_offset 2 }
                default { set use_simple_offset 0 }
            }
            switch $QuadMethod {
                0 {
                    set what surfaces
                    set entities $surfList
                    if {$surfList == ""} {
                        set entities [ic_geo_get_objects surface ""]
                    } else {
                        foreach srf $surfList {
                            if {[ic_geo_check_objects_exist surface $srf] == ""} {
                                mess "Error: No surface named \"$srf\".\n" red
                                busy 0
                                return
                            }
                        }
                    }
                }
                1 {
                    set what curves
                    set entities $curveList
                    if {$debug > 0} {
                        mess "curveList = $curveList\n" red
                    }
                    if {$curveList == ""} {
                        set entities [ic_geo_get_objects curve ""]
                        if {$debug} {
                            mess "curveList = $curveList\n" red
                        }
                    } else {
                        foreach crv $curveList {
                            if {[ic_geo_check_objects_exist curve $crv] == ""} {
                                mess "Error: No curve named \"$crv\".\n" red
                                busy 0
                                return
                            }
                        }
                    }
                }
                2 {
                    set what loops
                    set entities ""
                }
                3 {
                    set what native_surfaces
                    set entities $surfList
                    if {$surfList == ""} {
                        set entities [ic_geo_get_objects surface ""]
                    } else {
                        foreach srf $surfList {
                            if {[ic_geo_check_objects_exist surface $srf] == ""} {
                                mess "Error: No surface named \"$srf\".\n" red
                                busy 0
                                return
                            }
                        }
                    }
                }
                default {
                    set entities $surfList
                    if {$surfList != ""} {
                        foreach srf $surfList {
                            if {[ic_geo_check_objects_exist surface $srf] == ""} {
                                mess "Error: No surface named \"$srf\".\n" red
                                busy 0
                                return
                            }
                        }
                    }
                }
            }
            switch $elType {
                "All Quad"        {set type 4}
                "Quad w/one Tri"  {set type 1}
                "Quad Dominant"   {set type 2}
                "All Tri"         {set type 3}
                "Tri (STL like)"  {set type 5}
                "Tri (split STL)" {set type 7}
                "Tri (Delaunay)"  {set type 8}
                default {
                    mess "Quad meshing can't deal with type $elType ... using Quad Dominant.\n" red
                    set type 2
                }
            }
            if {$adjust_nodes_max} {
                set adjust_nodes 2
            } else {
                set adjust_nodes 0
            }
            if {$use_surface_sizes} {
                set inner -1
            } elseif {$inner < 0} {
                set inner 0
            }
            set error_subset "Failed_surfaces"
            set merge_dormant 1
            if $dormant {
                set merge_dormant 0
            }
            set ele_tol $ignore
            if $protect {
                set ele_tol [expr -abs($ignore)]
            }
            set err_code [ic_quad2 what $what entities $entities element $type \
                proj $projection iters -$iters conver $accuracy geo_tol $geo_tol \
                ele_tol $ele_tol dev $MaxDev improvement $improvement block $block \
                bunch $bunch debug $debug adjust_nodes $adjust_nodes \
                adjust_nodes_max $adjust_nodes_max try_harder $try_harder \
                error_subset $error_subset pattern $pattern big 1 board $board \
                remove_old -$remove_old inner $inner simple_offset $use_simple_offset \
                enn $enn b_smooth $b_smooth time_max $time_max ele_max $ele_max \
                four $four merge_dormant $merge_dormant max_length $max_length \
                max_area $max_area min_angle $min_angle max_nodes $max_nodes \
                max_elements $max_elements smoothdormant $smoothdormant \
                breakpoint $breakpoint freeb $freeb]
            if $err_code {
                if {[ic_geo_subset_get_items $error_subset] !=""} {
                    aie_subset_put_in_tree geom $error_subset
                } elseif {[ic_geo_subset_exists $error_subset] != 0} {
                    aie_delete_geom_subset $error_subset
                }
            } elseif {[ic_geo_subset_exists $error_subset] != 0} {
                aie_delete_geom_subset $error_subset
            }
            if {[ic_get_ignore_size] != 0} {
                if {$debug > 0} {
                    mess "set ignore_size to [ic_get_ignore_size]\n" red
                }
                set ignore [ic_get_ignore_size]
            }
        }
        1 {
            if {![ic_geo_is_loaded] || [ic_geo_get_objects surface] == ""} {
                mess "Error: No surfaces available.\n" red
                busy 0
                return
            }
            aie_autosizing tetra
            set args "tin uns run_cutter 1 fix_holes 1 write_volume 0 \
                n_tri_smoothing_steps 5 n_tri_smoothing_steps $iterations \
                in_process 1 log tetra_cmd0.log"
            if { [ info exists options(n_processors) ] && \
                    $options(n_processors) != "" } {
                append args " n_processors $options(n_processors)"
            }
            if ![eval ic_run_tetra $args] {
                busy reset
                return
            }
            if {$elType == "All Quad" || $elType == "Quad Dominant"} {
                set projectFlag 1
                set skew 160
                set warp 20
                if {$elType == "All Quad"} {
                    set quadrizationFlag 1
                } else {
                    set quadrizationFlag 0
                }
                ic_change_tri_quad proj $projectFlag quadrization $quadrizationFlag
            }
            #aie_afterStuffLoaded
        }
        2 {
            # remove existing mesh
            if [ic_uns_is_loaded] {
                if {$meshSurfs == ""} { # all
                    set surfs [ic_geo_get_objects surface]
                } else { # selected
                    foreach srf $meshSurfs {
                        if {[ic_geo_check_objects_exist surface $srf] == ""} {
                            mess "Error: No surface named \"$srf\".\n" red
                            busy 0
                            return
                        }
                    }
                    set surfs $meshSurfs
                }
                set delmaps ""
                foreach surf $surfs {
                    lappend delmaps [ic_uns_get_attached_elements surface $surf]
                }
                foreach elmap $delmaps {
                    ic_delete_elements subset $elmap no_undo 1
                    ic_uns_subset_delete $elmap
                }
            }
            aie_autosizing mapped
	        set version 110
            set failed_surfs [ic_run_mapped_based_mesher $elType $meshSurfs $MinEdge 0 $version]
	        aie_create_initial_assemblies
            if [llength $failed_surfs] {
                set ll ""
                foreach s $failed_surfs {set ll [concat $ll surface $s] }
                ic_geo_subset_add_items FAILED_SURFS $ll
                aie_subset_put_in_tree geom FAILED_SURFS
                mess "Adding failed surfaces $failed_surfs to FAILED_SURFS subset\n" red
            }
        }
        3 {
            global file_name is_win

            set is_modified [ic_geo_is_modified]
            aie_autosizing tetra
            set temp_tin_name afmesh_tmp.tin
            if {($file_name(tetin) == "") ||
                (![file exists $file_name(tetin)]) ||
                [ic_geo_is_modified]} {
                set tetinFN $temp_tin_name
                ic_save_tetin $tetinFN
            } else {
                set tetinFN $file_name(tetin)
            }
            set meshFN [file join $file_name(domains_dir) afmesh_tri.uns]

            if $is_win {
                set cmd [list ic_run_afmesh [win_shortname $tetinFN] \
                    [win_shortname [file dirname $meshFN]]/[file tail $meshFN]]
            } else {
                set cmd [list ic_run_afmesh $tetinFN $meshFN]
            }
            append cmd " geometry 1 surface 1"
            append cmd " verbose $VerboseFlag"
            append cmd " delaunay $DelaunayFlag"
            append cmd " proximity $ProximityFlag"
	    if {![catch {expr double($ExpansionFactor)} factor]} {
		append cmd " expand $factor"
	    }
	    append cmd " topo $RebuildTopoFlag"
#	    append cmd " join $MergeSurfFlag"
	    if {![catch {expr double($TopoTolerance)} tol]} {
	        append cmd " tol $tol"
	    }
            if [eval $cmd] {
                if $loadFlag {
		    ic_unload_mesh
		    set file_name(domain) $meshFN
		    if [aie_open_Mesh 0] {
			aie_afterStuffLoaded 0
		    }
                } else {
                    mess "Surface mesh saved in file: $meshFN\n"
                }
            }
            if [file exists $temp_tin_name] {cmd_rm $temp_tin_name}
            aie_no_autosizing
            ic_geo_set_modified $is_modified
            busy reset
            return
        }
    }

    # --> Run any (all)  meshing directives which have been defined... --jka
    #     perhaps this should go in ic_quad itself for regular med? xx --jka
    aie_connectors_exec

    if ![::AIEnv::GUIManagement::Tree::GetVisibility shell] {
	::AIEnv::GUIManagement::Tree::ToggleMeshVisible meshShellNode
    }
    ic_uns_families_changed
    aie_updateMeshVis
    if {!$err_code} {mess "Meshing completed.\n" blue}
    aie_update_icons mesh
    busy reset
}

proc onmeshTetDEZLoad {} {
    global file_name env

    set typeList {}
    if {[info exists env(AI_ENV_TETRA)]} {lappend typeList "Tetra"}
    if {[info exists env(AI_ENV_TETRA)] && [info exists env(AI_ENV_PRISM)]} {lappend typeList "Tetra + Prism Layers"}
    if {[info exists env(AI_ENV_TETRA)]} {lappend typeList "Hexa-Core"}
    if {[info exists env(AI_ENV_HEXA)]} {lappend typeList "Hexa-Dominant"}
    if {[info exists env(AI_ENV_BETA)]} {
        lappend typeList "Advancing Front"
        if {[info exists env(AI_ENV_PRISM)]} {
            lappend typeList "Advancing Front + Prism Layers"
        }
    }

    if {$meshType == ""} {
	set meshType [lindex $typeList 0]
    }
    set file_name(mesh_dir) $file_name(project_dir)
    set file_name(domains_dir) $file_name(project_dir)
    set AllowActiveReload 1

    set fix_holes 1
    set fixNMFlag 1
    set closeGapsFlag 0
    set saveTrisFlag 0

    if ![info exists meshTetMethodEGVal] {
        if {([ic_geo_is_loaded] && [ic_geo_get_objects surface] != "") && [ic_uns_is_loaded]} {
            set meshTetMethodEGVal 1
        } elseif {[ic_geo_is_loaded]} {
            set meshTetMethodEGVal 0
        } elseif {[ic_uns_is_loaded]} {
            set meshTetMethodEGVal 2
        }
    }

    meshTetDEZ setdirty
}

proc onmeshTetDEZAfterLoad {} {
    global file_name env

    if {!([ic_geo_is_loaded] && [ic_geo_get_objects surface] != "") && ![ic_uns_is_loaded]} {
	    msg ERROR  "No valid geometry or mesh file loaded"
	    meshTetDEZ unload
	    return
    }

    if {[trace vinfo meshTetMethodEGVal] != ""} {
        trace vdelete meshTetMethodEGVal w aie_trace_meshTetMethodEG
    }
    trace variable meshTetMethodEGVal w aie_trace_meshTetMethodEG
    aie_trace_meshTetMethodEG "" "" ""
    if {[trace vinfo batchFlag] != ""} {
        trace vdelete batchFlag w aie_trace_batchFlag
    }
    trace variable batchFlag w aie_trace_batchFlag
    meshTetDEZ onMeshVolTypeModify2
    if [info exists env(AI_ENV_BETA)] {
        set TopoTolerance [aie_default_topo_tolerance]
    }
}

proc onmeshTetDEZUnload {} {
    if {[trace vinfo meshTetMethodEGVal] != ""} {
        trace vdelete meshTetMethodEGVal w aie_trace_meshTetMethodEG
    }
    if {[trace vinfo batchFlag] != ""} {
        trace vdelete batchFlag w aie_trace_batchFlag
    }
}

proc aie_trace_batchFlag {name element op} {
    if [meshTetDEZ get batchFlag] {
	::AIEnv::GUIManagement::ToggleGrey meshTetbatchGI 0
	::AIEnv::GUIManagement::ToggleGrey meshTetSMbatchGI 0
    } else {
	::AIEnv::GUIManagement::ToggleGrey meshTetbatchGI 1
	::AIEnv::GUIManagement::ToggleGrey meshTetSMbatchGI 1
    }
}

proc aie_trace_meshTetMethodEG {name element op} {
    global env

    if {(![ic_geo_is_loaded] || ([ic_geo_get_objects surface] == ""))} {
        ::AIEnv::GUIManagement::ToggleGrey meshTetGeom 1
        ::AIEnv::GUIManagement::ToggleGrey meshTetGeomMesh 1
         meshTetDEZ set meshTetMethodEGVal 2
    } else {
        ::AIEnv::GUIManagement::ToggleGrey meshTetGeom 0
        ::AIEnv::GUIManagement::ToggleGrey meshTetGeomMesh 0
    }
    if ![ic_uns_is_loaded] {
        ::AIEnv::GUIManagement::ToggleGrey meshTetGeomMesh 1
        ::AIEnv::GUIManagement::ToggleGrey meshTetSurf 1
         meshTetDEZ set meshTetMethodEGVal 0
    } else {
        if {(![ic_geo_is_loaded] || ([ic_geo_get_objects surface] == ""))} {
            ::AIEnv::GUIManagement::ToggleGrey meshTetGeomMesh 1
        } else {
            ::AIEnv::GUIManagement::ToggleGrey meshTetGeomMesh 0
        }
        ::AIEnv::GUIManagement::ToggleGrey meshTetSurf 0
    }
    set method [meshTetDEZ get meshTetMethodEGVal]
    if [info exists env(AI_ENV_BETA)] {
        set meshing [meshTetDEZ get meshType]
        set types [meshTetDEZ get typeList]
        set n [lsearch -exact $types "Advancing Front"]
        if {$method == 1} {
            if {$n > 0} {
                meshTetDEZ set typeList [lreplace $types $n end]
            }
            if {[lindex $meshing 0] == "Advancing"} {
                set meshing Tetra
                meshTetDEZ set meshType $meshing
            }
        } elseif {$n < 0} {
            lappend types "Advancing Front"
            if {$method == 0 && [info exists env(AI_ENV_PRISM)]} {
                lappend types "Advancing Front + Prism Layers"
            }
            meshTetDEZ set typeList $types
        } elseif {$method == 2} {
            set n [lsearch -exact $types "Advancing Front + Prism Layers"]
            if {$n > 0} {
                meshTetDEZ set typeList [lreplace $types $n $n]
            }
            if {$meshing == "Advancing Front + Prism Layers"} {
                set meshing "Advancing Front"
                meshTetDEZ set meshType $meshing
            }
        }
        if {[lindex $meshing 0] == "Advancing"} {
            meshTetDEZ set batchFlag 1
        }
    }
    if ![meshTetDEZ get meshTetSmoothGGVal] {
	::AIEnv::GUIManagement::ToggleGrey meshTetSOpts 1
	::AIEnv::GUIManagement::ToggleGrey meshTetSMSOpts 1
    } else {
	::AIEnv::GUIManagement::ToggleGrey meshTetSOpts 0
	::AIEnv::GUIManagement::ToggleGrey meshTetSMSOpts 0
    }
    if ![meshTetDEZ get meshTetCrsGGVal] {
	::AIEnv::GUIManagement::ToggleGrey meshTetCOpts 1
	::AIEnv::GUIManagement::ToggleGrey meshTetSMCOpts 1
    } else {
	::AIEnv::GUIManagement::ToggleGrey meshTetCOpts 0
	::AIEnv::GUIManagement::ToggleGrey meshTetSMCOpts 0
    }
    if ![meshTetDEZ get meshTetStGGVal] {
	::AIEnv::GUIManagement::ToggleGrey meshTetTOpts 1
	::AIEnv::GUIManagement::ToggleGrey meshTetSMTOpts 1
    } else {
	::AIEnv::GUIManagement::ToggleGrey meshTetTOpts 0
	::AIEnv::GUIManagement::ToggleGrey meshTetSMTOpts 0
    }
    if ![meshTetDEZ get batchFlag] {
	::AIEnv::GUIManagement::ToggleGrey meshTetbatchGI 1
	::AIEnv::GUIManagement::ToggleGrey meshTetSMbatchGI 1
    } else {
	::AIEnv::GUIManagement::ToggleGrey meshTetbatchGI 0
	::AIEnv::GUIManagement::ToggleGrey meshTetSMbatchGI 0
    }
}

proc onmeshTetGeomLoad {} {
    set meshTetSmoothGGVal 1
    ::AIEnv::GUIManagement::ToggleGrey meshTetSmoothGG1 0
    ::AIEnv::GUIManagement::ToggleGrey meshTetSMSmoothGG 0
    if ![info exists loadFlag] {
        set loadFlag 1
        set numSmooth 5
        set smoothAR 0.4
        set coarsNumIter 2
        set coarsAR 0.1
        set meshTetStGGVal 0
        set STfactor 1.0
        set DelaunayFlag 0
        set ProximityFlag 0
        set VerboseFlag 0
        set ExpansionFactor 1.2
        set RebuildTopoFlag 0
        set MergeSurfFlag 0
    }
}

proc onmeshTetGeomMeshLoad {} {
    meshTetDEZ onmeshTetGeomLoad
}

proc onmeshTetSurfLoad {} {
    global num_material_points

    if {$scalefactor == ""} {set scalefactor 1}
    if {$tetexpand == ""} {set tetexpand 1}
    set family ""
    set meshall 0
    set floodfill 0
    set loadmesh 1
    set proximity 0
    set PartList [aie_list_parts 1]

    set mtls ""
    if [ic_geo_is_loaded] {
	foreach i [ic_geo_get_objects body] {
	  if {[ic_geo_get_family body $i] != "ORFN"} {
	    lappend mtls [ic_geo_get_family body $i]
	  }
	}
    }
    set num_material_points [llength $mtls]
    set nelems [expr [ic_count_elements pyra] + [ic_count_elements penta]]

    if {$num_material_points} {
	set family [lindex $mtls 0]
	if {$num_material_points > 1 && !$nelems} {
	    set meshall 1
	    set floodfill 1
	}
    }

    if {$nelems} {
	::AIEnv::GUIManagement::ToggleGrey meshRemeshAD 1
    } else {
	::AIEnv::GUIManagement::ToggleGrey meshRemeshAD 0
    }

    meshTetDEZ onMeshVolTypeModify2

    set AllowActiveReload 1
}

proc onMeshRemeshMFModify {dez val} {
    if {$val == "From screen"} {
	meshTetDEZ set family [geo_select_part_from_screen 1]
    }
}

proc onMeshVolTypeModify {dez val} {
    meshTetDEZ onMeshVolTypeModify2
}

proc onMeshVolTypeModify2 {} {
    global env
    if {$meshType == "Hexa-Dominant"} {
	::AIEnv::GUIManagement::ToggleGrey meshRemeshCenter 0
    } else {
	::AIEnv::GUIManagement::ToggleGrey meshRemeshCenter 1
    }

    set tri2tet_widgets {meshRemeshSF meshRemeshTF meshRemeshOpts}
    if  {$meshType == "Hexa-Dominant"} {
	lappend tri2tet_widgets meshRemeshHoles
    }
    if  {$meshType == "Hexa-Core" || $meshType == "Hexa-Dominant"} {
	set grey 1
    } else {
	set grey 0
    }

    foreach widget $tri2tet_widgets {
	::AIEnv::GUIManagement::ToggleGrey $widget $grey
    }

    if {[lindex $meshType 0] == "Advancing"} {
        foreach widget {meshFixHoles meshTetFixNMChk \
            meshTetCloseGapsChk meshTetSaveTrisChk} {
	    catch {::AIEnv::GUIManagement::ToggleGrey $widget 1}
        }
	::AIEnv::GUIManagement::ToggleGrey meshTetAFFR 0
        meshTetDEZ set meshTetSmoothGGVal 0
        meshTetDEZ set batchFlag 1
    } else {
        if [info exists env(AI_ENV_BETA)] {
            foreach widget {meshFixHoles meshTetFixNMChk \
                meshTetCloseGapsChk meshTetSaveTrisChk} {
                catch {::AIEnv::GUIManagement::ToggleGrey $widget 0}
            }
	    ::AIEnv::GUIManagement::ToggleGrey meshTetAFFR 1
        }
    }
}

proc onmeshTetDEZOK {} {
    global file_name tdv_default options aie_meshDisplay is_win
    global fam_visible
    global env

    # if running prism or advancing front inflation check for prism families
    if {[lindex $meshType end] == "Layers" &&
        [catch {aie_check_prism_params [lindex $meshType 0]} msg]} {
        msg ERROR $msg
        return
    }

    # check if an application is already running
    if [aie_check_application_running] return

    # save in case the user changes the value before application is done
    set mesh_type $meshType
    set is_batch $batchFlag
    set load_mesh $loadFlag
    set vis_geom $VisGeomFlag

    meshTetDEZ setdirty \# we want this DEZ to be active always

    switch $meshTetMethodEGVal {
	0 - 1 {

            if {[lindex $mesh_type 0] == "Advancing"} {
                set mesher afmesh
            } else {
                set mesher tetra
            }

	    if {$meshTetMethodEGVal == 1} {
                if {$mesher == "afmesh"} {
                    msg ERROR "Not implemented"
                    return
                }
		set use_surf 1
		if {$useMeshParts == ""} {
		    msg ERROR "No existing mesh part specified. Please run \"Tetra from Geometry\" \
                               if you don't have any existing mesh."
		    return
		}
	    } else {
		set use_surf 0
		set useMeshParts ""
	    }

	    set surf_mesh_only 0
	    if {((!$use_surf) && ([info exists surfMeshFlag]) && ($surfMeshFlag)) || \
		($mesh_type == "Hexa-Dominant")} {
		set surf_mesh_only 1
	    }
	    if !$is_batch {
                set vis_geom 0
                set partFlag 0
                set load_mesh 1
                if {$mesher == "afmesh"} {set is_batch 1}
            }
	    set temp_tetra_file temp_tetra.tin
            set is_modified [ic_geo_is_modified]

            if [aie_autosizing tetra 1] return

	    # Part by Part
	    if {$partFlag && $is_batch && $meshTetMethodEGVal == 0} {
                catch {unset assembly_parts}
		set assemblies ""
		set parts [aie_list_parts 0]
		foreach part $parts {
		    if {$vis_geom && !$fam_visible($part)} { continue }
		    set surfs [ic_geo_get_objects surface $part]
		    if ![llength $surfs] {continue}
		    set asmly [lindex [split $part /] 0]
		    if {[lsearch $assemblies $asmly] < 0} {
			lappend assemblies $asmly
                        set assembly_parts($asmly) ""
		    }
                    lappend assembly_parts($asmly) $part
		}
		set part_by_part 1
		set nruns [llength $assemblies]
                if {$nruns == 0} {
                    msg ERROR "No parts containing surfaces found."
                    return
                }
                if [ic_uns_is_loaded] {
                    aie_close_Mesh 0
                }
                # save current part visibility
                catch {unset part_visible}
		foreach part $parts {
                    set part_visible($part) $fam_visible($part)
                }
	    } else {
		set part_by_part 0
		set nruns 1
                if {$vis_geom && ![ic_geo_num_visible_objects surface 1]} {
                    msg ERROR "No surfaces are visible."
                    return
                }
	    }

            set found_live 0
	    if [ic_geo_is_loaded] {
		foreach mat [ic_geo_get_objects body] {
		    if {[ic_geo_get_family body $mat] != "ORFN"} {
                        if {!$vis_geom || [ic_geo_get_visibility body $mat]} {
			    incr found_live
                        }
		    }
		}
	    }

	    set errors ""
	    for {set i 0} {$i < $nruns} {incr i} {
		if $part_by_part {
		    set asmly  [lindex $assemblies $i]
		    mess "\n******* Meshing Assembly: $asmly **********\n"
		    ::AIEnv::GUIManagement::Tree::ToggleGroupVisibility part * 0
		    ::AIEnv::GUIManagement::Tree::ToggleGroupVisibility part $asmly 1
		    aie_updateGeoVis
                    # turn on all surfaces, curve and points in the part
                    foreach part $assembly_parts($asmly) {
                        # surfaces and attached curves and points
		        foreach surf [ic_geo_get_objects surface $part] {
			    ic_geo_temporary_visible surface $surf 1 1
			    foreach curve [ic_geo_boundary surface $surf] {
			        ic_geo_temporary_visible curve $curve 1 1
			        foreach point [ic_geo_boundary curve $curve] {
				    ic_geo_temporary_visible point $point 1 1
                                }
			    }
			}
                        #curves and attached points
			foreach curve [ic_geo_get_objects curve $part] {
			    ic_geo_temporary_visible curve $curve 1 1
			    foreach point [ic_geo_boundary curve $curve] {
				ic_geo_temporary_visible point $point 1 1
			    }
			}
                        # points
			foreach point [ic_geo_get_objects point $part] {
			    ic_geo_temporary_visible point $point 1 1
			}
		    }
		    ic_save_tetin $temp_tetra_file 1
		    set tetinFN $temp_tetra_file
		} elseif $vis_geom {
		    ic_save_tetin $temp_tetra_file 1
		    set tetinFN $temp_tetra_file
		} elseif {($file_name(tetin) == "") || (![file exists $file_name(tetin)]) ||
                          ($is_batch && [ic_geo_is_modified])} {
		    ic_save_tetin $temp_tetra_file
		    set tetinFN $temp_tetra_file
		} else {
		    set tetinFN $file_name(tetin)
		}
		set meshFN [file join $file_name(domains_dir) $mesher\_mesh.uns]

		if {($tetinFN == "") || (![file exists $tetinFN])} {
		    aie_no_autosizing
                    ic_geo_set_modified $is_modified
	            if [file exists $temp_tetra_file] {cmd_rm $temp_tetra_file}
		    msg ERROR  "No geometry file loaded\n"
		    return
		}

		if $is_win {
		    set cmd [list ic_run_$mesher [win_shortname $tetinFN] \
				 [win_shortname [file dirname $meshFN]]/[file tail $meshFN]]
		} else {
		    set cmd [list ic_run_$mesher $tetinFN $meshFN]
		}

                if {$mesher == "afmesh"} {
                    append cmd " geometry 1"
                    append cmd " verbose $VerboseFlag"
                    append cmd " delaunay $DelaunayFlag"
                    append cmd " proximity $ProximityFlag"
		    if {![catch {expr double($ExpansionFactor)} factor]} {
		        append cmd " expand $factor"
		    }
		    append cmd " topo $RebuildTopoFlag"
#		    append cmd " join $MergeSurfFlag"
		    if {![catch {expr double($TopoTolerance)} tol]} {
		        append cmd " tol $tol"
		    }
                    if {[lindex $mesh_type end] == "Layers"} {
                        append cmd " prism [aie_write_prism_params]"
                    }
                }
                append cmd " run_cutter 1 delete_auto 1"

		if { $fixNMFlag == 0 } {append cmd " fix_non_manifold 0"}
		if { $closeGapsFlag } {append cmd " closegaps 1"}
		if { $saveTrisFlag } {append cmd " save_all_triangles 1"}

		if {$use_surf && $useMeshParts != ""} {
		    if ![ic_uns_is_loaded] {
			aie_no_autosizing
                        ic_geo_set_modified $is_modified
	                if [file exists $temp_tetra_file] {cmd_rm $temp_tetra_file}
			mess "Error: No existing mesh available to use.\nPlease load the mesh first.\n" red
			return
		    }
		    set fm temp_trimesh.uns
		    cmd_rm $fm
		    ic_save_unstruct $fm 1 "" "" $useMeshParts
		    foreach fam $useMeshParts {
			if {$vis_geom && !$fam_visible($fam)} {
				continue
			} else {
				append cmd " use_existing \"$fam,$fm\""
			}
		    }
		}

		#Don't smooth or coarsen in Tetra process, since if Tetra leaks you are wasting time, let's do this after loading mesh.
		if $surf_mesh_only {
		    if $meshTetSmoothGGVal {
			append cmd " n_tri_smoothing_steps $numSmooth"
		    }
		    append cmd " write_volume 0"
		}
		if {$meshTetCrsGGVal && $is_batch} {
		    append cmd " run_coarsener 1 coarsen_aspect $coarsAR n_coarsen_iter $coarsNumIter"
		}
		if {$part_by_part || (!$load_mesh && $is_batch)} {
		    if $meshTetSmoothGGVal {
			append cmd " run_smoother [expr !$meshTetStGGVal] n_tri_smoothing_steps $numSmooth"
			append cmd " smoother_n_iter $numSmooth smoother_aspect $smoothAR"
		    }
		} elseif {$is_batch && $meshTetSmoothGGVal && $meshTetStGGVal} {
		    append cmd " run_smoother [expr !$meshTetStGGVal] n_tri_smoothing_steps $numSmooth"
		} else {
		    append cmd " run_smoother 0"
		}
		append cmd " fix_holes $fix_holes"

		#	if $autoOrphFlag {append cmd " auto_orphan 1"}
		#	if $saveTriFlag {append cmd " save_all_triangles 1"}
		if { [ info exists options(n_processors) ] && \
			 $options(n_processors) != "" } {
		    append cmd " n_processors $options(n_processors)"
		}
                if $is_batch {
                    append cmd " show_progress 1"
                } else {
		    append cmd " in_process 1"
                }

		if { $part_by_part || $found_live == 0 } {
		    append cmd " auto_vol 1"
		} else {
		    append cmd " auto_orphan 1"
		}

#		set logfile [cmd_tempfile tetra_cmd .log]
		set logfile tetra_cmd.log
		if $is_win {
		    set logfile [win_shortname [file dirname $logfile]]/[file tail $logfile]
		}
		append cmd " log $logfile"

		# Remove tetra_mesh.uns if it exists already
		if [file exists $meshFN] {cmd_rm $meshFN}

		#Mesh
		if [catch {eval $cmd} ok] return

                if {!$ok} {
                    if {$errors == ""} {set errors "meshing failed\n"}
                    if {$part_by_part} continue
		    aie_no_autosizing
                    ic_geo_set_modified $is_modified
                    if [file exists $temp_tetra_file] {cmd_rm $temp_tetra_file}
		    busy reset
		    return
		}

		if $use_surf {
		    cmd_rm temp_trimesh.uns
		}

		if {$is_batch && ![file exists $meshFN]} {
                    if {$part_by_part} continue
		    aie_no_autosizing
                    ic_geo_set_modified $is_modified
                    if [file exists $temp_tetra_file] {cmd_rm $temp_tetra_file}
                    return
		}
                # check for fixed.
                if {$mesher == "tetra"} {
                    set lf [ open $logfile ]
                    set fixed 0
                    while { ![eof $lf ] } {
                        set line [ gets $lf ]
                        if [ string match \
                            "*it appears the material point is located*" $line ] {
                            set fixed 1
                            break
                        }
                    }
                    close $lf
                    if { $fixed == 0 } {
                        # check for errors
                        set lf [ open $logfile ]
                        while { ![eof $lf] } {
                            set line [ gets $lf ]
                        if [ string match "*can reach material*" $line ] {
                                set line2 [ gets $lf ]
                                if [ string match "*check display*" $line2 ] {
                                    append errors "$line\n"
                                }
                            }
                        }
                        close $lf
                    }
                }
		if $part_by_part {
                    if $meshTetStGGVal {
                        if $is_win {
                            set meshfile [win_shortname [file dirname $meshFN]]/[file tail $meshFN]
                            set cmd [list ic_run_tri2tet $meshfile $meshfile \
                                         tetin [win_shortname $tetinFN]]
                        } else {
                            set cmd [list ic_run_tri2tet $meshFN $meshFN tetin $tetinFN]
                        }
                        if {![catch {expr double($STfactor)} factor]} {
                            append cmd " tetexpand $factor"
                        }
                        append cmd " show_progress 1"
                        if {![eval $cmd]} {
                            mess "Warning: Smooth transition failed\n" red
                        }
                    }
		    ic_uns_load [list $meshFN]
		}
	    }

	    aie_no_autosizing
            ic_geo_set_modified $is_modified

            if {$part_by_part} {
		foreach part [array names part_visible] {
                    catch {::AIEnv::GUIManagement::Tree::ToggleGroupVisibility \
                        part $part $part_visible($part)}
                }
                aie_updateGeoVis
                foreach asmly $assemblies {
                    ::AIEnv::GUIManagement::Tree::UpdateVisFlag part-$asmly
                }
		if [ic_uns_is_loaded] {
                    ic_save_unstruct $meshFN
                    if !$load_mesh {aie_close_Mesh 0}
		} else {
		    if [file exists $temp_tetra_file] {cmd_rm $temp_tetra_file}
		    busy reset
                    mess "No mesh was created.\n" red
                    return
                }
            }

            if {$is_batch && $load_mesh && !$part_by_part} {
#                if !$surf_mesh_only {ic_unload_mesh}
                ic_unload_mesh
	        ic_uns_load [list $meshFN]
	    }
            set mesh_loaded 0
	    if {!$is_batch || $load_mesh} {
		aie_initial_unsmesh_visibility 0
		aie_build_volumes
		aie_afterStuffLoaded 0
		aie_update_icons mesh
		if $surf_mesh_only {ic_save_unstruct $meshFN}
		set is_modified [ic_geo_is_modified]
		set mesh_loaded 1
	    }

	    if {($surf_mesh_only) && $mesh_type != "Hexa-Dominant"} {
                if [file exists $temp_tetra_file] {cmd_rm $temp_tetra_file}
		if !$load_mesh {
		    mess "Created surface tri mesh is saved in file: $meshFN\n"
		}
	        if [ic_uns_is_loaded] {
	            ::AIEnv::GUIManagement::ToggleGrey meshTetSurf 0
	            ::AIEnv::GUIManagement::ToggleGrey meshTetGeomMesh 0
	        }
		aie_connectors_exec
		return
	    }

            if {$errors == ""} {
                set do_smoothing $meshTetSmoothGGVal

                # quad boundary gives more hexas

                if {$mesh_type == "Hexa-Dominant" && $mesh_loaded} {
                    ic_delete_elements type TETRA_4
                    mess "smoothing surface mesh...\n" blue
                    ic_smooth_elements map all upto $smoothAR iterations $numSmooth \
                        fix_families $useMeshParts  smooth TRI_3 smooth QUAD_4
                    ic_change_tri_quad_2 all 1 0 0 -20 160 20 0
                    set do_smoothing 0
                }

	        if {!$part_by_part} {

                    # smooth surface mesh

                    if {$do_smoothing && $mesh_loaded} {
                        mess "smoothing surface mesh...\n" blue
                        ic_smooth_elements map all upto $smoothAR iterations $numSmooth \
                            fix_families $useMeshParts  smooth TRI_3 float TETRA_4 laplace 1
                    }

                    # run Delauney mesher if smooth transition specified

                    if {$meshTetStGGVal} {
                        if {$mesh_loaded} {
                            ic_save_unstruct $meshFN
                        }
                        if $is_win {
                            set meshfile [win_shortname [file dirname $meshFN]]/[file tail $meshFN]
                            set cmd [list ic_run_tri2tet $meshfile $meshfile \
                                     tetin [win_shortname $tetinFN]]
                        } else {
                            set cmd [list ic_run_tri2tet $meshFN $meshFN tetin $tetinFN]
                        }
                        if {![catch {expr double($STfactor)} factor]} {
                            append cmd " tetexpand $factor"
                        }
                        if {[llength  [ic_geo_list_families 1]] > 1} {
                            append cmd " keepall 1"
                        }
                        append cmd " show_progress 1"
                        if ![eval $cmd] {
                            mess "Warning: Smooth transition failed\n" red
                        } elseif {$load_mesh} {
                            ic_unload_mesh
                            set file_name(domain) $meshFN
                            if [aie_open_Mesh 0] {
                                if {$found_live > 1} {unstruct_consistent}
                                aie_afterStuffLoaded 0
                            }
                            set mesh_loaded 1
                        }
                    }
                }
            }

            if [file exists $temp_tetra_file] {cmd_rm $temp_tetra_file}

	    if !$load_mesh {
		mess "Created tetra mesh is saved in file: $meshFN\n"
                if $is_batch {aie_connectors_exec; return}
	    }

            if {$errors == ""} {

                # Run prism mesher if requested

                if {$mesh_type == "Tetra + Prism Layers"} {
                    ic_smooth_elements map all upto $smoothAR \
                        iterations $numSmooth prism_warp_weight 0.5 \
                        fix_families {} smooth TETRA_4 smooth TRI_3

                    if ![meshPrismDEZ isbuilt] {
                        meshPrismDEZ build
                    }
                    meshPrismDEZ set loadmesh $load_mesh
                    meshPrismDEZ apply
                }

                # create hexcore mesh if requested

                if {$mesh_type == "Hexa-Core"} {
                    mess "Creating Hexa-core mesh\n" blue
                    set hexcore_fams ""
                    set live_fams ""
                    foreach fam [ic_list_volume_families] {
                        if {$fam == "ORFN" || $fam == "VORFN"} continue
                        lappend live_fams $fam
                        if {$found_live == 0} {
                            lappend hexcore_fams $fam
                        } else {
                            set do_hexcore [ic_geo_get_family_param $fam hexcore]
                            if {$do_hexcore != "" && $do_hexcore != 0} {
                                lappend hexcore_fams $fam
                            }
                        }
                    }

                    if {$hexcore_fams == ""} {
                        if {[llength $live_fams] == 1} {
                            set hexcore_fams $live_fams
                        } else {
                            mess "Hexa-core volumes were not defined. Please define Hexa-core volumes under\n\
                                  Mesh => Set Meshing Params by Parts.\n" red
                        }
                    }

                    ic_uns_convert_tet2_hexcore $hexcore_fams
                }

                # Hexa-Dominant mesh

                if {$mesh_type == "Hexa-Dominant"} {
                    set live_fams ""
                    foreach fam [ic_geo_list_families 1] {
                        if {$fam == "ORFN" || $fam == "VORFN"} continue
                        lappend live_fams $fam
                    }

                    set hexdom_fam [lindex $live_fams 0]
                    if {$hexdom_fam == ""} {
                        set hexdom_fam [aie_new_part LIVE]
                    }
                    ic_mesh_hexdom $hexdom_fam 1
		    aie_create_initial_assemblies
                }

                #If not using surf mesh, smooth but only surf for Delauny

                if {!$meshTetStGGVal && !$part_by_part} {
                    # Marlow wanted to smooth TRI for prism meshing
                    set do_tri3 freeze
                    if {$mesh_type == "Tetra + Prism Layers"} {
                        set do_tri3 smooth
                    }

                    if $meshTetSmoothGGVal {
                        ic_smooth_elements map all upto $smoothAR \
                            iterations $numSmooth prism_warp_weight 0.5 \
                            fix_families {} smooth TETRA_4 freeze PENTA_6 \
                            $do_tri3 TRI_3
                    }

                    # This is what Marlow and Judd requested
                    if {$mesh_type == "Tetra + Prism Layers"} {
                        ic_smooth_elements map all upto 0.15 iterations 5 \
                            prism_warp_weight 0.5 fix_families {} \
                            smooth TRI_3 smooth PENTA_6 smooth TETRA_4 \
                            smooth PYRA_5
                    }

                    if $meshTetCrsGGVal {
                        ic_uns_coarsen all $coarsAR {} 0.1 $coarsNumIter 0 0 ""
                    }
                }
            }

            # aie_afterStuffLoaded used to reset modified flag
            ic_geo_set_modified $is_modified

	    #mess "$errors" red

	    if [ic_uns_is_loaded] {
	        ::AIEnv::GUIManagement::ToggleGrey meshTetSurf 0
	        ::AIEnv::GUIManagement::ToggleGrey meshTetGeomMesh 0
	        aie_updateMeshVis
	    }

	    if { $errors == "" } {aie_connectors_exec; return }

	    # turn on single  multiple
	    set aie_meshDisplay(single_edges) 1
#	    set aie_meshDisplay(multiple_edges) 1
	    aie_changeMeshDisplay

	    switch -- [ tk_dialog .tetra_load "Repair holes" \
			 "Your geometry has a hole, do you want to repair it?" \
			 "" -1 Yes No "Only Shells" ] {
			     -1 {
			        if [winfo exists .tetra_load] { destroy .tetra_load }
			        aie_connectors_exec
			        return 0
			     }
			     0 { }
			     1 { aie_connectors_exec; return 0 }
			     2 {
				 #Delete all volume elements
				 set temp_subset [ic_uns_subset_create rrr]
				 ic_uns_subset_add_families_and_types $temp_subset [ic_uns_subset_list_families all] TETRA_4
				 ic_delete_elements subset $temp_subset
				 ic_uns_subset_delete $temp_subset

				 mess "Only shell elements are kept\n" blue
				 aie_connectors_exec
				 return
			     }
			 }

	    # repair leak
	    unstruct_flood_fill no_repair
	    set aie_meshDisplay(single_surfaces) 1

	    aie_show_leaks

	    # bring up repair form.
	    if ![repairMeshDEZ isbuilt] {
		repairMeshDEZ build
	    }
	    repairMeshDEZ show
	    repairMeshDEZ set KeepConsistentFlag 1
	    repairMeshDEZ set elType "All Tri"
	    repairMeshDEZ set repairMeshRGVal 4
	    closeHoleMeshElemsPick pick
		aie_connectors_exec
	}
	2 {
	    #	Tet mesh from existing mesh

	    global file_name num_material_points env

	    if {![ic_uns_is_loaded]} {
		msg ERROR "You need to create or load an existing mesh first."
		return
	    }

            # Run hex-dom mesher
	    if {$mesh_type == "Hexa-Dominant"} {
		set live_fams ""
		foreach fam [ic_geo_list_families 1] {
		    if {$fam == "ORFN" || $fam == "VORFN"} continue
		    lappend live_fams $fam
		}
		if {$family != "" && ([lsearch "ORFN VORFN" $family] < 0)} {
		    if [ic_geo_check_part $family] {
		        set hexdom_fam $family
		    } else {
		        set hexdom_fam [aie_new_part [string toupper $family]]
		    }
		} else {
		    set hexdom_fam [lindex $live_fams 0]
		}
		if {$hexdom_fam == ""} {
		    if ![ic_geo_check_part LIVE] {
		        mess "Creating new volume part LIVE\n"
		    }
		    set hexdom_fam [aie_new_part LIVE]
		}
                # quad boundary gives more hexas
		ic_change_tri_quad_2 all 1 0 0 -20 160 20 0
		ic_mesh_hexdom $hexdom_fam $remeshCenter
		aie_create_initial_assemblies
		aie_connectors_exec
		return
	    }

            #Run hexa-core mesher
	    if {$mesh_type == "Hexa-Core"} {
		mess "Creating Hexa-core mesh\n" blue
		set hexcore_fams ""
		foreach fam [ic_list_volume_families] {
		    if {$fam == "ORFN" || $fam == "VORFN"} continue
		    set do_hexcore [ic_geo_get_family_param $fam hexcore]
		    if {$do_hexcore != "" && $do_hexcore != 0} {
			lappend hexcore_fams $fam
		    }
		}

		if {$hexcore_fams == ""} {
		    set hexcore_fams $family
		}

		if {$hexcore_fams == ""} {
		    set family [aie_new_part LIVE]
		    set hexcore_fams $family
		}

		ic_uns_convert_tet2_hexcore $hexcore_fams $fillholes
		aie_create_initial_assemblies
		aie_connectors_exec
		return
	    }

            if  {[lindex $mesh_type 0] == "Advancing"} {
                set mesher afmesh
            } else {
                set mesher tri2tet
            }

            # Run tri2tet mesher
	    set meshIN  $file_name(domain)
	    set meshOUT [file join $file_name(project_dir) $mesher\_mesh.uns]

            set recreate_subsets ""
            if {($mesh_type == "Tetra" || $mesh_type == "Tetra + Prism Layers" || \
                 $mesh_type == "Advancing Front + Prism Layers")} {
                catch {ic_uns_subset_delete tri2tet_errors}
                set recreate_subsets [aie_mesh_tet_get_existing_subsets]
            }

	    if {($meshIN == "") || ![file exists $meshIN] ||
		[ic_uns_is_modified]} {
		set tempfile [cmd_tempfile $mesher\_temp .uns]
		ic_save_unstruct $tempfile
		set meshIN $tempfile
	    } else {
		set tempfile ""
	    }

	    if $is_win {
		set cmd [list ic_run_$mesher [win_shortname $meshIN] \
		  [win_shortname [file dirname $meshOUT]]/[file tail $meshOUT]]
	    } else {
		set cmd [list ic_run_$mesher $meshIN $meshOUT]
	    }

            if {$mesher == "afmesh"} {
                append cmd " geometry 0 proximity $proximity"
            } else {
                if $fillholes {
                    append cmd " fillholes 1"
                }
                if {$scalefactor != ""} {append cmd " safety $scalefactor"}
                if {$meshall} {append cmd " keepall 1"}
                if [info exists env(TRI2TET_DEBUG)] {
                    if {$output != ""} {append cmd " output $output"}
                    if {$OFFfile != ""} {append cmd " offfile $OFFfile"}
                }
            }
            if {$tetexpand != ""} {append cmd " tetexpand $tetexpand"}
            if {$family != ""} {
                regsub -all " " [string toupper $family] _ fam
                append cmd " family $fam"
            }
            append cmd " verbose $verbose"
            set error_subset $mesher\_errors
            append cmd " show_progress 1"
            append cmd " errors $error_subset"
	    append cmd " fix_holes $fix_holes"

	    set recreate_subsets ""
	    catch {ic_uns_subset_delete tri2tet_errors}
	    set recreate_subsets [aie_mesh_tet_get_existing_subsets]

	    if {[eval $cmd] && [file exists $meshOUT]} {
		if $loadmesh {
		    aie_close_Mesh 0
		    set file_name(domain) $meshOUT
		    aie_open_Mesh 0
		    aie_afterStuffLoaded 0
                    set nelems [expr \
                        [ic_count_elements quad] + \
                        [ic_count_elements pyra] + \
                        [ic_count_elements penta] + \
                        [ic_count_elements hexa]]
		    if {$nelems > 0 && [ic_create_pyramids]} {
                        aie_updateMeshVis
			unstruct_consistent "" 0
		    }
		    if {$floodfill && $nelems == 0} {
			if $num_material_points {
			    unstruct_flood_fill no_repair
			} else {
			    unstruct_flood_fill autovol 1
			}
			aie_create_initial_assemblies
		    }
		} else {
		    mess "Created $mesher mesh is saved in file: $meshOUT\n"
		}
	    }
	    if {$tempfile != ""} {cmd_rm $tempfile}
	    set errors ""
            if [ic_uns_subset_exists $error_subset] {
                aie_subset_put_in_tree mesh $error_subset
		set errors $error_subset
            }
	   
            # Run prism mesher if requested
	    if {$errors == "" && ($mesh_type == "Tetra + Prism Layers" ||
                $mesh_type == "Advancing Front + Prism Layers")} {
		if ![meshPrismDEZ isbuilt] {
		    meshPrismDEZ build
		}
		meshPrismDEZ set loadmesh $loadmesh
		meshPrismDEZ apply
	    }
	    aie_connectors_exec

            if {$errors == "" && ($mesh_type == "Tetra" || $mesh_type == "Tetra + Prism Layers" || \
                $mesh_type == "Advancing Front + Prism Layers") && $recreate_subsets != ""} {
                aie_mesh_tet_reset_existing_subsets $recreate_subsets
            }
	}
    }
}

proc aie_mesh_tet_get_existing_subsets {} {
    set subsets ""
    foreach sub [ic_uns_subset_list] {
        set elems ""
        foreach e [ic_uns_subset_list_elements $sub] {
            append elems "[lindex $e 1] "
        }
        set types [ic_uns_subset_list_types $sub]
        set parts [ic_uns_subset_list_families $sub]
        if {$elems == "" || $types == "" || $parts == ""} continue
        lappend subsets "$sub [list $elems] [list $types] [list $parts]"
    }
    return $subsets
}

proc aie_mesh_tet_reset_existing_subsets {subsets} {
    foreach sub $subsets {
        set name [lindex $sub 0]
        set elems [lindex $sub 1]
        set types [lindex $sub 2]
        set parts [lindex $sub 3]
        set rsub [ic_uns_subset_create $name]
        aie_mesh_subset_update_elements $rsub $elems $types $parts "0 1 2 3"
        ::AIEnv::GUIManagement::Tree::AddGroup mesh_subset $rsub 0
        ::AIEnv::GUIManagement::Tree::ToggleGroupVisibility mesh_subset $rsub same
    }
}

proc meshHexGUI {} {
    global file_name tdv_default is_win env use_xwindows

    set mess {This will take you to Old Hexa Interface. You might prefer to use \
		  Blocking Tab to stay in the same interface... \
		  Are you sure you want to go to old interface?}

    set opt [tk_dialog .hexagui "Hexa GUI Warning" $mess "" -1 Yes No]
    if {$opt == -1} { if [winfo exists .hexagui] { destroy .hexagui; return } }
    if {$opt == 1} { return }

    if { $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 this_tetin $file_name(tetin)
    if { [ file isfile $this_tetin ] && \
		![file exists [file join $file_name(project_dir) [file tail $file_name(tetin)]]] } {
	msg ERROR "The geometry file is not in project directory, please save \
		the project first."
	return
    }

    if [ic_geo_is_modified] {
	aie_saveProject 1
    }

    set this_tetin $file_name(tetin)
    if {($this_tetin == "") || ![file exists $this_tetin]} {
	msg ERROR  "No geometry file loaded"
	return
    }

    set args "\"$file_name(project_dir)\" -tetin \"$this_tetin\" -domain_dir \"$file_name(domains_dir)\" -mesh_dir \"$file_name(mesh_dir)\" -use_file_suffixes"
    if $use_xwindows { append args " -x" }

    if ![geo_check_available_space] return
    set nf1 [domain_newest_file]

    set wait [run_application_before]
    if [catch {
	if $is_win {
	    runcom "\"$env(ICEM_ACN)/icemcfd/hexa\" -f \"$env(ICEM_ACN)/lib/guibase/guibase.tcl\" -tool \"$env(ICEM_ACN)/lib/hexa/hexa.tcl\" $args"
	} else {
	    runcom "\"$env(ICEM_ACN)/icemcfd/hex_gui\" $args"
	}
    } res] { mess $res\n red }
    run_application_after $wait

    #run_application_guibase icemcfd/hex_gui icemcfd/hexa HEXA_BIN lib/hexa/hexa.tcl 0 $args 1

    set nf2 [domain_newest_file]
    # No multi blocking
    if {[lindex $nf2 1] > [lindex $nf1 1]} {
	set to_load $file_name(domains_dir)/[lindex $nf2 0]
	set is_str 0
	set opt [tk_dialog .loadmesh "Load the new mesh" \
		"Load the new mesh file [file tail $to_load]?" "" -1 Yes No]
	switch -- $opt {
	    -1 { if [winfo exists .loadmesh] { top_destroy .loadmesh; return } }
	    0 {
		set file_name(domain) $to_load
		mess "loading $file_name(domain)\n" blue
		aie_open_Mesh 0
		aie_afterStuffLoaded 0
	    }
	    1 { return }
	}
	tdv_home $tdv_default
    }
}

proc onmeshHexDomDEZLoad {} {
    if {![ic_uns_is_loaded]} {
	msg ERROR "You need to create or load a surface mesh first."
	return
    }
    set types [ic_uns_subset_list_types all]
    set PartList [aie_list_parts 1]
    meshHexDomDEZ setdirty
    set AllowActiveReload 1
}

proc onmeshHexDomDEZApply {} {
	ic_mesh_hexdom $family
	aie_create_initial_assemblies

	::AIEnv::GUIManagement::Tree::AddGroup part $family
	::AIEnv::GUIManagement::Tree::ToggleGroupVisibility part $family 1
	aie_updateMeshVis

}

proc oncreateElemsDEZLoad {} {
    global uns_select_for

    set PartList [aie_list_parts 1]
    if ![info exists PickMethod] {
	    set createElemsRGVal -1
	    set PickMethod 0
	    set makeConsistent 0
	    set part MESH
	    set createAuto 0
	    set sortAuto 0
	    set inherit_part 1
    }
    set uns_select_for create
    set AllowActiveReload 1
}

proc onCreateElemsNameModify {dez val} {    
    if {$val == "From screen"} {
	    createElemsDEZ set part [geo_select_part_from_screen 1]
    }
}

proc oncreateElemsDEZUnLoad {} {
    global uns_select_for aie_temp_uns_map

    if [ic_uns_subset_exists $aie_temp_uns_map] {
        ic_uns_subset_delete $aie_temp_uns_map
        set aie_temp_uns_map ""
    }
    if {[trace vinfo createElemsRGVal] != ""} {
        trace vdelete createElemsRGVal w aie_trace_create_elems_automatically
    }
    if {[trace vinfo pointList] != ""} {
        trace vdelete pointList w aie_trace_create_elems_from_screen
    }
#    trace variable pointList w aie_trace_create_elems_from_screen
    set uns_select_for select
}

proc oncreateElemsDEZAfterLoad {} {
    global auto_pick_mode

    set pointList ""
    set elemList ""
    set edgeList ""
    set nodeList ""
    
    if {[trace vinfo createElemsRGVal] != ""} {
        trace vdelete createElemsRGVal w aie_trace_create_elems_automatically
    }
    trace variable createElemsRGVal w aie_trace_create_elems_automatically
    aie_trace_create_elems_automatically "" "" ""

    if {[trace vinfo pointList] != ""} {
        trace vdelete pointList w aie_trace_create_elems_from_screen
    }
    trace variable pointList w aie_trace_create_elems_from_screen

    if {$createElemsRGVal != -1 && $auto_pick_mode} {
	    set n [expr $createElemsRGVal + 1]
	    switch $PickMethod {
	        0 {createElemsNodesPick$n pick}
	        1 {createElemsPointsPick$n pick}
	        2 {createElemsScreenPick$n pick}
	        3 { 
		        if {$n == 7} {
		            createElemsFacesPick pick
		        } else {
		            createElemsElemsPick pick
		        }
	        }
	        4 {createElemsEdgePick pick}
	        5 {createElemsCurvePick pick}
	    }
    }
}

proc aie_trace_create_elems_automatically {{name ""} {element ""} {op ""}} {
    global take_first_press
    set n [createElemsDEZ get createElemsRGVal]
    if {$n == -1} return
    if {[createElemsDEZ get createAuto] && $n != 0} {
        set exact 1
        switch $n {
	        1 { set nv 2 }
	        2 { set nv 3 }
	        3 - 4 { set nv 4 }
	        5 { set nv 6 }
	        6 { set nv 5 }
	        7 { set nv 8 }
	        8 {set nv ANY; set exact 0}
        }
    } else {
        set nv ANY
        set exact 0
    }
    set n [expr $n + 1]
    ::AIEnv::GUIManagement::Picker::SetImpl createElemsNodesPick$n -key maxNumber $nv
    ::AIEnv::GUIManagement::Picker::SetImpl createElemsNodesPick$n -key requireExactNumber $exact
    ::AIEnv::GUIManagement::Picker::SetImpl createElemsPointsPick$n -key maxNumber $nv
    ::AIEnv::GUIManagement::Picker::SetImpl createElemsPointsPick$n -key requireExactNumber $exact
    ::AIEnv::GUIManagement::Picker::SetImpl createElemsScreenPick$n -key maxNumber $nv
    ::AIEnv::GUIManagement::Picker::SetImpl createElemsScreenPick$n -key requireExactNumber $exact
    switch [createElemsDEZ get PickMethod] {
        3 - 4 { if $exact { set nv 1 } }
    }
#   ::AIEnv::GUIManagement::Picker::SetImpl createElemsElemsPick -key maxNumber $nv
#   ::AIEnv::GUIManagement::Picker::SetImpl createElemsElemsPick -key requireExactNumber $exact
#   ::AIEnv::GUIManagement::Picker::SetImpl createElemsEdgePick -key maxNumber $nv
#   ::AIEnv::GUIManagement::Picker::SetImpl createElemsEdgePick -key requireExactNumber $exact
#   ::AIEnv::GUIManagement::Picker::SetImpl createElemsCurvePick -key maxNumber $nv
#   ::AIEnv::GUIManagement::Picker::SetImpl createElemsCurvePick -key requireExactNumber $exact
}

proc aie_trace_create_elems_from_screen {{name ""} {element ""} {op ""}} {
    global va_set

    if {[createElemsDEZ get PickMethod] == 2 && [createElemsDEZ get createAuto]} {
        set va_set(confirm) 0
    } elseif [info exists va_set(confirm)] {
        unset va_set(confirm)
    }
}

foreach n {1 2 3 4 5 6 7 8 9} {
    proc oncreateElemsNodesPick${n}Finish {} {
        global auto_pick_mode

        if {($auto_pick_mode || [createElemsDEZ get createAuto]) && $nodeList != ""} {
	        createElemsDEZ apply
        }
    }

    proc oncreateElemsPointsPick${n}Finish {} {
        global auto_pick_mode

        if {($auto_pick_mode || [createElemsDEZ get createAuto]) && $pointList != ""} {
	        createElemsDEZ apply
        }
    }

    proc oncreateElemsScreenPick${n}Finish {} {
        global auto_pick_mode

        if {($auto_pick_mode || [createElemsDEZ get createAuto]) && $pointList != ""} {	    
	        createElemsDEZ apply
        }
    }
}

proc oncreateElemsFacesPickFinish {} {
    global auto_pick_mode
    
    if {$auto_pick_mode && $faceList != ""} {	    
	    createElemsDEZ apply
    }
}

foreach n {1 2 3 4 5 6 7 8 9} {
    proc oncreateElemsNodesPick${n}Pick {} {
	if {[createElemsDEZ get createAuto] && ([createElemsDEZ get createElemsRGVal] != 0)} {	
	    after 250 {
	        select_toolbar_gray_child 1 polygon
	        select_toolbar_gray_child 1 circle
	        select_toolbar_gray_child 1 region_type
	        select_toolbar_gray_child 1 all
	        select_toolbar_gray_child 1 part
            }
        }
    }

    proc oncreateElemsPointsPick${n}Pick {} {
	if {[createElemsDEZ get createAuto] && ([createElemsDEZ get createElemsRGVal] != 0)} {	
	    after 250 {
	        select_toolbar_gray_child 1 polygon
	        select_toolbar_gray_child 1 circle
	        select_toolbar_gray_child 1 region_type
	        select_toolbar_gray_child 1 all
	        select_toolbar_gray_child 1 part
            }
        }
    }
}

proc oncreateElemsElemsPickFinish {} {
     global auto_pick_mode take_first_press

    if {($auto_pick_mode || [createElemsDEZ get createAuto]) && $elemList != ""} {
	    createElemsDEZ apply
    }
}

proc oncreateElemsEdgePickFinish {} {
     global auto_pick_mode take_first_press

    if {($auto_pick_mode || [createElemsDEZ get createAuto]) && $edgeList != ""} {
	    createElemsDEZ apply
    }
}

proc oncreateElemsCurvePickFinish {} {
     global auto_pick_mode

    if {($auto_pick_mode || [createElemsDEZ get createAuto]) && $curveList != ""} {
	    createElemsDEZ apply
    }
}

proc oncreateElemsDEZOK {} {
    global auto_pick_mode aie_temp_uns_map fam_visible
    
    if {$createElemsRGVal == -1} return    
    if ![ic_uns_is_loaded] { ic_uns_create_empty }
    switch $PickMethod {
	    1 - 2 {    
	        set nodeList [ic_uns_subset_create]
	        foreach ptt $pointList {
		        if {$PickMethod == 1 || ([llength $ptt] == 1)} {
		            set ptt [ic_geo_get_point_location $ptt]
		        }
		        set pt1 $ptt
		        if {$PickMethod == 2} {
		            set pt1 [ic_coords_into_global $ptt]
		        }
		        ic_uns_create_vertex $nodeList $pt1 2
	        }
	    }
	3 {

	    # create hexa from faces
	    if {$createElemsRGVal == 7} {
		    if {$part == "" || $part == "inherited" || $part == "INHERITED"} {
		        set inherit_part 1
		    } else {
		        set inherit_part 0
		    }

		    if { !$inherit_part } {
		        set name [aie_new_part $part]
		    } else {
		        set name [aie_new_part "CREATED_MATERIAL"]
		    }
		    ic_uns_create_hexa_from_faces all $faceList $inherit_part $name
		    aie_updateMeshVis

		    set elemList ""
		    aie_updateMeshVis
		    if $auto_pick_mode {
		        createElemsFacesPick pick
		    }
		    return
	    }

	    if {$createElemsRGVal != 1} {
	        mess "Only line elements is possible to create from edges\n" red
	        return 
	    }
	    if {$elemList == ""} {
	        mess "No element(s) selected. Use whole mesh\n" blue
		set sel_map all
		set all_elem 1
	    } else {
		set sel_map $elemList
		set all_elem 0
	    }
	    if { !$inherit_part } {
		set name [aie_new_part $part]
		aie_reset_icons $name
		aie_updateMeshVis
		aie_update_icons mesh
	    } else {
		set name ""
	    }
	    ic_uns_mesh_to_bars $sel_map $all_elem $inherit_part $name
	    set elemList ""
	    aie_updateMeshVis
	    if $auto_pick_mode {
		createElemsElemsPick pick
	    }
	    return
	}
	4 {
            if {$edgeList == ""} {
                mess "No edge(s) selected\n" red
                return
            }
            if {$createElemsRGVal != 1} {
                mess "Only line elements is possible to create from edges\n" red
                return
            }
            set nodeList $edgeList
        }
	5 {
	    if {$createElemsRGVal == 1 && $curveList != ""} {
                aie_autosizing quad
                set name [aie_new_part $part]
                if {![ic_quad2 what "curves_only" entities $curveList material $name]} {
                    mess "New BAR_2 Element(s) created\n" blue
                }
                set curveList ""
                aie_reset_icons $name
                aie_updateMeshVis
                aie_update_icons mesh
                if $auto_pick_mode {
	            set n [expr $createElemsRGVal + 1]
	            switch $PickMethod {
	                0 {createElemsNodesPick$n pick}
	                1 {createElemsPointsPick$n pick}
	                2 {createElemsScreenPick$n pick}
	                3 {createElemsElemsPick pick}
	                4 {createElemsEdgePick pick}
	                5 {createElemsCurvePick pick}
	            }
                }
                return
            }
	}
    }
    if {$nodeList == "" || ![ic_uns_subset_exists $nodeList] || ([ic_uns_subset_count_nodes $nodeList] < 1)} {
	if [ic_uns_subset_exists $nodeList ] {ic_uns_subset_delete $nodeList}
	set nodeList ""
	mess "No nodes selected\n" red
	return
    }

    if {$part == "From screen"} {
	set part [geo_select_part_from_screen 1]
	createElemsDEZ set part $part
    }

    set name [aie_new_part $part]

    set n_nodes [ic_uns_subset_count_nodes $nodeList]
    if {$createElemsRGVal == 8} {
	switch $n_nodes {
	    0 {return}
	    1 {set type NODE; set nv 1}
	    2 {set type BAR_2; set nv 2}
	    3 {set type TRI_3; set nv 3}
	    4 {
		set nv 4
		if {[ic_uns_dimension] < 3} {
		    set type QUAD_4
		} else {set type TETRA_4}
	    }
	    5 {set type PYRA_5; set nv 5}
	    6 - 7 {set type PENTA_6; set nv 6}
	    default {set type HEXA_8; set nv 8}
	}
    } else {
	switch $createElemsRGVal {
	    0 {set type NODE; set nv 1}
	    1 {set type BAR_2; set nv 2}
	    2 {set type TRI_3; set nv 3}
	    3 {set type QUAD_4; set nv 4}
	    4 {set type TETRA_4; set nv 4}
	    5 {set type PENTA_6; set nv 6}
	    6 {set type PYRA_5; set nv 5}
	    7 {set type HEXA_8; set nv 8}
	    default {
		mess "$createElemsRGVal Mesh type is not valid\n" red
		return
	    }
	}
    }

    if {($n_nodes < $nv) && ($nv != 1)} {
	mess "Error: Not enough nodes to create $type element\n" red
	ic_uns_subset_delete $nodeList
	return
    }
 
    set active_subsets ""
    catch { unset the_nodes }
    catch { unset use_active_subsets }
    foreach sub [ic_uns_subset_list_visible Selected] {
        set vis [expr [::AIEnv::GUIManagement::Tree::NodeVisibleStatus mesh_subset $sub 1] == 1]
        if !$vis continue
        if {$sub == $aie_temp_uns_map} continue
        lappend active_subsets $sub
        foreach n [ic_uns_subset_list_elements $sub] {
            append the_nodes($sub) "[lindex $n 3] "
        }
    }   
    if {$active_subsets == ""} {
        if {$aie_temp_uns_map == ""} {
	    set aie_temp_uns_map [ic_uns_create_selection_subset 1]
        }
        if {([info exists fam_visible($name)]) && ($fam_visible($name) == 1)} {
            set smap visible
        } else {
	   set smap $aie_temp_uns_map
        }
    } else {
        foreach n [ic_uns_subset_list_elements $nodeList] {
            lappend the_nodes($nodeList) [lindex $n 1]
        }
        if {[llength $active_subsets] == 1} {
            foreach sub $active_subsets {
                set use_active_subsets($sub) 1
            }
        } else {
            foreach sub $active_subsets {
                if ![info exists the_nodes($sub)] continue
                foreach n $the_nodes($nodeList) {
                    if {[lsearch $the_nodes($sub) $n] >= 0} {
                       set use_active_subsets($sub) 1
                       break
                    }
                }
            }
            if ![info exists use_active_subsets] {
                foreach sub $active_subsets {
                    set use_active_subsets($sub) 1
                }
            }
        }
    }
    
    if [info exists use_active_subsets] {
        set i 0
        foreach sub $active_subsets {
            if ![info exists use_active_subsets($sub)] continue
            if {$sub == $aie_temp_uns_map} continue
            if {$i == 1 && $added != ""} {
                ic_uns_subset_add_number $sub $added 1 MIXED
                if {( $type == "BAR_2" ) && ( $n_nodes > 2 )} {
	            # for line elements, if the user selects more than 2 nodes, a spider should be created.
	            mess "$sub: New Spider Element created\n"
	        } else {
                    mess "$sub: New $type Element created\n"
                }
            } else {
                if ![ic_uns_create_element $type $name $nodeList $makeConsistent $sub 0 0 1 $sortAuto] {
	            if {( $type == "BAR_2" ) && ( $n_nodes > 2 )} {
	                # for line elements, if the user selects more than 2 nodes, a spider should be created.
	                mess "$sub: New Spider Element created\n"
	            } else {
	                mess "$sub: New $type Element created\n"
	            }
	            set i 1
	            set added [lindex [lindex [ic_uns_subset_list_elements $sub] end] 1]
                } else {
                    ic_uns_subset_delete $nodeList
                    return
                }
            }
        }
    } else {
        if {$PickMethod == 4} {
            set elems [ic_uns_subset_list_elements $nodeList]
            set len_elems [expr [llength $elems] / 2]
            set i 0; set update 0
            foreach {n1 n2} [ic_uns_subset_list_elements $nodeList] { 
                set tmpmap [ic_uns_subset_create]
                set loc1 [lindex $n1 2]; set loc2 [lindex $n2 2]
                ic_uns_create_vertex $tmpmap $loc1 2; ic_uns_create_vertex $tmpmap $loc2 2
                set stat [ic_uns_create_element $type $name $tmpmap $makeConsistent $smap 0 0 $update $sortAuto]
                ic_uns_subset_delete $tmpmap
                if $stat {
                    ic_uns_subset_delete $nodeList
                    return
                }
                incr i
                if {$i == [expr $len_elems - 1]} { set update 1 }
            }
        } else {
            set stat [ic_uns_create_element $type $name $nodeList $makeConsistent $smap 0 0 1 $sortAuto]
        }
        if $stat {
	    ic_uns_subset_delete $nodeList
	    return
        } else {
	    # for line elements, if the user selects more than 2 nodes, a spider should be created.
	    # if selection is done by edges create only line elements
	    if {($type == "BAR_2" ) && ( $n_nodes > 2 ) && ($PickMethod != 4)} {
	        mess "New Spider Element created\n"
	    } else {
		if {$PickMethod == 4} {
		    mess "$i new $type Element(s) created\n"
		} else {
		    mess "New $type Element created\n"
		}
	    }
        }
    }
        
    aie_reset_icons $name
    aie_updateMeshVis
    aie_update_icons mesh

    if [ic_uns_subset_exists $nodeList ] {ic_uns_subset_delete $nodeList}   
    set pointList ""
    set elemList ""
    set edgeList ""
    set nodeList ""
    if $auto_pick_mode {
	    set n [expr $createElemsRGVal + 1]
	    switch $PickMethod {
	        0 {createElemsNodesPick$n pick}
	        1 {createElemsPointsPick$n pick}
	        2 {createElemsScreenPick$n pick}
	        3 {createElemsElemsPick pick}
	        4 {createElemsEdgePick pick}
	        5 {createElemsCurvePick pick}
	    }
    }
}

proc onextrudeMeshDEZLoad {} {
    global extcurve_directions
    if {![info exists extNumLay] || $extNumLay == ""} {
        set extNumLay 1
    }
    if {![info exists extProjFlag] || $extProjFlag == ""} {
        set extProjFlag 0
    }

    if ![info exists ElemExtRotateCenterEGVal] {
        set ElemExtRotateCenterEGVal 0
    }

    if {![info exists trans_rot_vec] || $trans_rot_vec == ""} {
        set trans_rot_vec "0 0 0"
    }

    if {![info exists spacing_transl_rot] || $spacing_transl_rot == ""} {
        set spacing_transl_rot 0.0
    }

    if {$extRotateAngle == ""} {
        set extRotateAngle 10.0
    }
    if {$extNumSpace == ""} {
        set spaceType fixed
        set extNumSpace 1
    }

    set PartList [aie_list_parts 1]
    lappend PartList inherited
    foreach t {Vol Side Top} {
        set ext${t}PartName inherited
    }
    if [ic_uns_is_loaded] {
        set vol [ic_list_volume_families]
        if {$vol != ""} {
            set newvol [aie_get_subset_families_only_with_dim all 3]
            if {$newvol != ""} {
                set extVolPartName $newvol
            } else {
                set extVolPartName [lindex $vol 0]
            }
            mess "Setting \"New volume part name\" to existing part \"$extVolPartName\"\n" blue
        } else {
            set extVolPartName FLUID
        }
    }
    
    set extTwist 0
    set AllowActiveReload 1
    foreach n "0 1 2 3" {
        set deleteElemChk${n}Val 0
        set delElemFlagCov$n 0
         ::AIEnv::GUIManagement::ToggleGrey deleteElemChkUnc$n 1
    }
    set degenerationTol "0.00001"
    set spaceType fixed
    set extCurve ""
    set CurveDirFlag 0
    set orientFlag 0
    set revDirFlag 0
    set extcurve_directions ""
}

proc onextrudeMeshDEZAfterLoad {} {
    aie_select_merge_degen
    if {[trace vinfo spaceType] != ""} {
        trace vdelete spaceType w aie_extrude_trace_spaceType
    }
    trace variable spaceType w aie_extrude_trace_spaceType
    aie_extrude_trace_spaceType "" "" ""
    if {[trace vinfo elemList] != ""} {
        trace vdelete elemList w aie_extrude_trace_elemList
    }
    trace variable elemList w aie_extrude_trace_elemList
}

proc aie_extrude_trace_spaceType {name element op} {
    if {[extrudeMeshDEZ get spaceType] == "bunching"} {
        ::AIEnv::GUIManagement::ToggleGrey extMeshNumLayTE2 1
    } else {
        ::AIEnv::GUIManagement::ToggleGrey extMeshNumLayTE2 0
    }
}

proc aie_extrude_trace_elemList {name element op} {
    set elems [extrudeMeshDEZ get elemList]
    if {$elems == ""} return
    set topp [aie_get_subset_families_only_with_dim $elems 2]
    if {$topp != ""} {
        extrudeMeshDEZ set extTopPartName ${topp}_2
        mess "Setting \"New top part name\" to ${topp}_2\n" blue
    }
}

proc onextrudeMeshDEZUnLoad {} {
    global extcurve_directions
    
    if [info exists extcurve_directions] {
        aie_extMesh_check_curve_dir $extcurve_directions
    }
    if {[trace vinfo spaceType] != ""} {
        trace vdelete spaceType w aie_extrude_trace_spaceType
    }
    if {[trace vinfo elemList] != ""} {
        trace vdelete elemList w aie_extrude_trace_elemList
    }
}

proc onselectExtrudeMerge {} {
    if ![info exists mergeEndFlag] {return}
    set grey 1
    if {$mergeEndFlag} {
        set grey 0
    }
    ::AIEnv::GUIManagement::ToggleGrey extDegenTol $grey
}

proc aie_select_merge_degen {} {
    extrudeMeshDEZ onselectExtrudeMerge
}

proc onextMeshCurveLoad {} {
    global auto_pick_mode
    if $auto_pick_mode {
        extMeshCurvePick pick
    }
}

proc onExtrudeMeshVolPartModify {dez val} {
    if {$val == "From screen"} {
        extrudeMeshDEZ set extVolPartName [geo_select_part_from_screen 1]
    }
}

proc onExtrudeMeshSidePartModify {dez val} {
    if {$val == "From screen"} {
        extrudeMeshDEZ set extSidePartName [geo_select_part_from_screen 1]
    }
}

proc onExtrudeMeshTopPartModify {dez val} {
    if {$val == "From screen"} {
        extrudeMeshDEZ set extTopPartName [geo_select_part_from_screen 1]
    }
}

proc onextrudeMeshDEZOK {} {
    global aie_listElementTypes

    foreach t {Vol Side Top} {
        set var ext${t}PartName
        if {[set $var] != "inherited"} {
            aie_new_part [set $var]
        }
    }

    set project 0
    set center "0 0 0"
    set axis "0 0 0"
    set delete 0
    set delete_cov 0
    switch $extrudeMeshEGVal {
	    0 {
	        set dir normal
	        set delete $deleteElemChk0Val
	        set delete_cov $delElemFlagCov0
	    }
	    1 {
	        if $orientFlag {
                set dir curve_axial
	        } else {
                set dir curve_normal
	        }
	        set project $extProjFlag
	        set delete $deleteElemChk1Val
	        set delete_cov $delElemFlagCov1
	    }
	    2 {
	        switch $extMeshVectorEGVal {
                0 {
                    if {$extVector == ""} {
                        msg ERROR "No vector specified for extrude by vector"
                        return
                    }
                    set dir $extVector
                }
                1 {
                    if {[llength $axisElemList] != 2} {
                        msg ERROR "No vector specified for extrude by vector. Need 2 points"
                        return
                    }
                    set pt1 [lindex $axisElemList 0]
                    set pt2 [lindex $axisElemList 1]
                    foreach i {1 2} {
                        set pt_axis [set pt$i]
                        if {[llength $pt_axis] == 1} {
                            set pt$i [ic_geo_get_point_location $pt_axis]
                        }
                    }
                    set dir ""
                    foreach i {0 1 2} {
                        lappend dir [expr [lindex $pt2 $i] - [lindex $pt1 $i]]
                    }
                }
                set dir [ic_coords_dir_into_global $dir]
	        }
	        set delete $deleteElemChk2Val
	        set delete_cov $delElemFlagCov2
	    }
	    3 {
	        if {$ElemExtRotateAxisOptionEGVal == ""} {
                msg ERROR "No axis specified for rotation"
                return
	        }
	        switch $ElemExtRotateCenterEGVal {
                0 { set center "0 0 0" }
                1 { set center [lindex $rotateCenterPnt	0]}
            }
	        if {[llength $center] == 1} {
                set center [ic_geo_get_point_location $center]
	        }
	        set center [ic_coords_into_global $center]
	        switch $ElemExtRotateAxisOptionEGVal {
                0 { set axis "1 0 0"}
                1 { set axis "0 1 0"}
                2 { set axis "0 0 1"}
                3 {
                    if {[llength $axisElemList] != 2} {
                        msg ERROR "No vector specified for rotation. Need 2 points"
                        return
                    }
                    set pt1 [lindex $axisElemList 0]
                    set pt2 [lindex $axisElemList 1]
                    foreach i {1 2} {
                        set pt_axis [set pt$i]
                        if {[llength $pt_axis] == 1} {
                            set pt$i [ic_geo_get_point_location $pt_axis]
                        }
                    }
                    set axis ""
                    foreach i {0 1 2} {
                        lappend axis [expr [lindex $pt2 $i] - [lindex $pt1 $i]]
                    }
                }
                set axis [ic_coords_dir_into_global $axis]
	        }
	        if $mergeEndFlag  {
                set dir rotate
	        } else {
                set dir rotate_nomerge
	        }
	        set delete $deleteElemChk3Val
	        set delete_cov $delElemFlagCov3
	        if $extMeshRotateTransVal {
	            if $extMeshRotateTransEGVal {
                    if {[llength $axisElemList] != 2} {
                        msg ERROR "No vector specified for translation. Need 2 points"
                        return
                    }
                    set pt1 [lindex $axisElemList 0]
                    set pt2 [lindex $axisElemList 1]
                    foreach i {1 2} {
                        set pt_axis [set pt$i]
                        if {[llength $pt_axis] == 1} {
                            set pt$i [ic_geo_get_point_location $pt_axis]
                        }
                    }
                    set axis_rot ""
                    foreach i {0 1 2} {
                        lappend axis_rot [expr [lindex $pt2 $i] - [lindex $pt1 $i]]
                    }
                    set trans_rot_vec [ic_coords_dir_into_global $axis_rot]
                } else {
                    if {$trans_rot_vec == ""} {
                        msg ERROR "No vector specified for translation."
                        return
                    }
                }
	        } else {
	            set trans_rot_vec "0 0 0"
	        }
        }
    }
    if {$dir == "normal" && $elemList != ""} {
        set cont_extrude 0
        foreach t [ic_uns_subset_list_types $elemList] {
            if {![regexp NODE+ $t] && ![regexp LINE_+ $t] && ![regexp BAR_+ $t]} {
	            set cont_extrude 1
	            break
            }
        }
        if !$cont_extrude {
            mess "Error: cannot extrude by element normal from node or bar elements\n" red
            return
        }
        
    }
    set space 1
    set space_func ""
    if {$extrudeMeshEGVal == 1 || $extrudeMeshEGVal == 3} {
        set extNumSpace 1
    }
    switch $spaceType {
        fixed {
            set space $extNumSpace
        }
        func - bunching {
            set space $spaceType
            set space_func $extNumSpace
            if {$dir == "curve_axial" && $extCurve != "" && $extrudeMeshEGVal == "1"} {
                set val 2
                set len [expr double([ic_geo_crv_length $extCurve])]
                foreach {n v} [ic_get_meshing_params curve $extCurve] {
                    if {$n == "emax"} {
                        if {$v == 0} {
                            set val 2
                        } else {
                            set val [expr round ($len / $v) + 1]
                        }
                        break
                    }
                }
                set extNumLay $val
            }
        }
    }
    
    if {$elemList == ""} {
        mess "No elements selected. Please select elements\n" red
        return
    }
    ic_extrude map $elemList \
            numlayers $extNumLay \
	        dir $dir  \
	        space $space \
	        space_func $space_func \
	        rpoint $center \
	        rdir $axis \
	        rangle $extRotateAngle \
	        volf $extVolPartName \
	        sidef $extSidePartName \
	        topf $extTopPartName \
	        curve $extCurve \
	        curvedir $revDirFlag \
	        twist $extTwist \
	        del_orig $delete \
	        del_covered $delete_cov \
	        degen_tol $degenerationTol \
	        trans_rot_vec $trans_rot_vec \
	        spacing_transl_rot $spacing_transl_rot \
	        project $project
	        
    ic_uns_subset_delete $elemList
    set elemList ""
    aie_create_parts_in_tree_if_needed
    aie_delete_empty_parts 0
    aie_updateMeshVis
}

proc aie_get_subset_families_only_with_dim {subset dim} {
    
    set fams [ic_uns_subset_list_families $subset]

    set parts2 ""
    foreach fam [ic_uns_list_families 2] {
        if {$fam == "ORFN"} continue
        lappend parts2 $fam
    }
    set parts3 ""
    foreach fam [ic_uns_list_families 3] {
        if {$fam == "ORFN"} continue
        lappend parts3 $fam
    }
    
    set parts ""
    if {$dim == "2"} {
        foreach fam $parts2 {
            if {[lsearch $parts3 $fam] < 0 && [lsearch $fams $fam] >= 0} {
                lappend parts $fam
            }
        }
    } elseif {$dim == "3"} {
        foreach fam $parts3 {
            if {[lsearch $parts2 $fam] < 0 && [lsearch $fams $fam] >= 0} {
                lappend parts $fam
            }
        }
    }

    foreach fam $parts {
        if {$dim == "2"} {
            if {[lsearch $parts3 $fam] < 0} {
                return $fam
            }
        } elseif {$dim == "3"} {
            if {[lsearch $parts2 $fam] < 0} {
                return $fam
            }
        }
    }
    
    return ""
}

proc aie_extMesh_check_curve_dir {{images ""}} {
    global tdv_current_viewer extcurve_directions
    if {$images != ""} {
        foreach c $images { $c clear_points }
        return;
    }
    if [info exists extcurve_directions] {
        foreach c $extcurve_directions { $c clear_points }
        unset extcurve_directions
    }
    set flag [extrudeMeshDEZ get CurveDirFlag]
    if !$flag return
    set w $tdv_current_viewer
    set extcurve_directions ""
    busy 1
    foreach c [extrudeMeshDEZ get extCurve] {
        if {[ic_geo_check_objects_exist curve $c] == ""} continue
        set im(xyz) [aie_curve_get_dir_image $c]
        if {$im(xyz) == ""} continue
        set dir [tdv_poly_line_im -draw_dots 0 -width 2 -color yellow]
        $w add_image $dir
        foreach p $im(xyz) { $dir add_point $p }
        lappend extcurve_directions $dir
    }
    busy reset
}


# -------------------------------------------------->
# Stuff for connectors. --jka

set ::aie_tree_nodes(connector) "Connectors"

proc aie_connectors_attribute_name {} { return "connector" }

proc aie_connectors_boco_name {} { return "CONNECTOR" }

proc aie_md_debug {text} {
    return
    mess "--> aie_md_debug: $text\n" purple
}

## given a handle like:
##    ARB_CURVES0
## it will return all families using it:
##   "FAM_74892:ARB_CURVES0 FAM_1234:ARB_CURVES0"

proc aie_connectors_get_fams_comprising {handle} {

    set fams ""
    foreach f [ic_geo_list_families] {
	if [string equal $handle [lindex [split $f :] end]] {
	    lappend fams $f
	}
    }

    return $fams
}

## given a famname like ABC:XYZ
## it will return the group name XYZ (for connectors)

proc aie_connectors_get_group_comprising {handle} {
    if {$handle == ""} return
    return [lindex [split $handle :] end]
}

proc aie_connectors_get_fams_for_group {groupname} {

    # huh? fixme!
    aie_md_debug "be careful calling aie_connectors_get_fams_for_group!"
    return [aie_connectors_get_fams_comprising $groupname]

    set fams [ic_boco_get_fams_of_part $groupname]
    # huh? fixme!
    foreach f [ic_geo_list_families] {
	set comparison [lindex [split $f :] 0]
	if [string equal $groupname $comparison] {
	    aie_md_debug "got it...\n"
	    lappend fams $f
	}
    }
    return $fams
}

proc aie_connectors_get_group_for_fam {famname} {

    # huh? fixme!
    aie_md_debug "be careful calling aie_connectors_get_group_for_fam!"
    return [aie_connectors_get_fams_comprising $famname]

    set groups [ic_boco_get_part_of_fam $famname]
    # huh? fixme!
    foreach f [ic_geo_list_families] {
	set comparison [lindex [split $f :] end]
	if [string equal $famname $comparison] {
	    aie_md_debug "got it $f for $famname...\n"
	    lappend groups $f
	}
    }
    return $groups
}

proc aie_connectors_exist_on_model {} {
    #set parts [aie_list_parts 0]
    set parts [ic_geo_list_families]
    foreach p $parts {
	if [aie_connnectors_does_group_have_directives $p] { return 1 }
    }
    return 0
}

proc aie_connnectors_does_group_have_directives {groupname} {

    aie_md_debug "trying to get directives groupname: $groupname"

    set has_directives 0

    set fams [aie_connectors_get_fams_comprising $groupname]
    if {"" == $fams} { set fams $groupname }

    aie_md_debug "part $groupname has $fams"

    foreach fam $fams {
	incr has_directives [expr {"" != [aie_connectors_get_directive_of_fam $fam]}]
    }

    return $has_directives
}

proc aie_connectors_get_directive_of_group {groupname} {
    set internalfamnames [aie_connectors_get_fams_comprising $groupname]
    if {"" == $internalfamnames} { set internalfamnames $groupname }
    return [aie_connectors_get_directive_of_fam $internalfamnames]
}

proc aie_connectors_get_directive_of_fam {famnames} {
    aie_md_debug "trying to get directives of fams: $famnames"
    return [ic_meshdirect_get_directive_of_fam $famnames]
}

proc aie_edit_connector {name} {

    aie_md_debug "in aie_edit_connector have $name"

    if {"*" == $name} {

	# as when the user if clicking on the topmost "Connectors" node in the tree

	global aie_connectors_global_edit_group
	if [info exists aie_connectors_global_edit_group] {
	    unset aie_connectors_global_edit_group ;#!! important --jka
	}

	defineConnectorsDEZ setclean
	defineConnectorsDEZ load

    } else {

	# clicking on the node of a particular group

	aie_connectors_edit_group_directives $name
    }
}

##

proc aie_connectors_edit_group_directives {name} {
    global aie_connectors_global_edit_group

    # this is just to ensure the DEZ load-renew...not good, but invisible to user xxx --jka
    # aie_edit_part $name

    aie_md_debug "trying to edit group $name"
    if [aie_connnectors_does_group_have_directives $name] {
	aie_md_debug "trying to get directives of fams: $name"
	set aie_connectors_global_edit_group $name
	defineConnectorsDEZ show
    } else {
	aie_md_debug "group $name does not seem to have directives"
	# otherwise, let them modify the part
	return [aie_edit_part $name]
    }
}

## this one is given tree-node-names; not the assumptions of the split command; see aie_tree.tcl

proc aie_connectors_tree_delete_all_directives {nodes} {
    aie_md_debug "trying to delete directives of nodes: $nodes"
    foreach n $nodes {
	set g [lindex [split $n -] end]
	aie_connectors_delete_group_directives $g
    }
    aie_tree delete connectorNode
}

proc aie_connectors_delete_group_directives {groupname} {

    aie_md_debug "aie_connectors_delete_group_directives"
    aie_md_debug "groupname = $groupname\n"
    set internalfamname [aie_connectors_get_fams_for_group $groupname]
    set directive [aie_connectors_get_directive_of_fam $internalfamname]
    if ![llength $directive] return
    ic_meshdirect_reset $directive $internalfamname

    set status [aie_connectors_get_directive_of_fam $internalfamname]
    if {"" == $status} {
	mess "Deleted $directive from part $groupname\n"
    } else {
	mess "Warning: could not delete $directive from part $groupname\n" red
    }

    # delete the entry from the tree
    aie_tree delete_group [aie_connectors_attribute_name] $groupname 1
}

proc aie_connectors_create_group_for_existing_fam {fam {sugg_group_name ""}} {
    global fam_visible

    if {![ic_geo_check_family $fam] && ![ic_uns_check_family $fam]} {
	return ""
    }

    if ![info exists fam_visible($fam)] {
	set fam_visible($fam) 1
    }

    if {"" != $sugg_group_name} {
	# put it in the connectors branch if not already
	set connode_len [string length $connode]
	set part_name $sugg_group_name
    } else {

	set part_name [aie_connectors_get_group_for_fam $fam]
	if {("" == $part_name) || ![string equal $part_name $fam]} {
	    set part_name "$fam"
	}
    }

    aie_connectors_register_new_result_group $part_name
    return $part_name
}

proc aie_connectors_register_resultfams_from_tetin {} {
    global fam_visible

    foreach fam [ic_geo_list_families] {
	if [string equal $fam ORFN] continue

	foreach dir [ic_meshdirect_available_directives_get] {
	    set poss_fam_name [ic_meshdirect_directive_get_val_by_tag $dir $fam result_fam]

	    if {"" != $poss_fam_name} {

		# this could maybe use aie_connectors_create_group_for_existing_fam proc above now
		if ![info exists fam_visible($poss_fam_name)] {
		    set fam_visible($poss_fam_name) 1
		}

		set poss_group_name [aie_connectors_get_group_for_fam $poss_fam_name] ;# note bug 7714
		if {("" != $poss_group_name) && [string equal $poss_group_name $poss_fam_name]} {
		    aie_connectors_register_new_result_group $poss_group_name
		}
	    }
	}
    }
}

proc aie_connectors_exec { {which_directives all} {which_fams all} } {

    if { ![ic_uns_is_loaded] || ![aie_connectors_exist_on_model] } {
	return 0
    }

    set args ""
    if [ic_meshdirect_param_requires_remeshing] {
	append args "-remesh_affected_elements "
    }

    if {("all" == $which_fams) || ("" == $which_fams)} {
	append args " -families \{[ic_geo_list_families]\}"
    } else {
	append args " -families \{$which_fams\}"
    }

    if [catch { ic_meshdirect_object_exec $which_directives $args} res] {
	mess "$res\n" red
	return 0
    }

    aie_connectors_display_results

    return 1
}

proc aie_connectors_load {} {

    set loc_type [aie_connectors_attribute_name]

    aie_md_debug "looking at families [ic_geo_list_families]"
    # there is currently a bug so that this list may be wrong...
    foreach f [ic_geo_list_families] {
	set directives [aie_connectors_get_directive_of_fam $f]
	if {"" != $directives} {
	    aie_md_debug "adding family $f to connectors node because of directives $directives\n"
	    set parent [lindex [split $f :] end]
	    set color [family_color_for_name $parent]
	    aie_tree add_group $loc_type [lindex [split $f :] end] 1 0 $color

	    foreach d $directives {
		ic_meshdirect_add_icon $d $f
	    }
	}
    }
    aie_md_debug "aie_connectors_load finished"
}

proc aie_connectors_unload {} {

    foreach f [ic_geo_list_families] {
	set directives [aie_connectors_get_directive_of_fam $f]
	foreach d $directives {
	    ic_meshdirect_delete_icon $d $f
	}
    }

    ::AIEnv::GUIManagement::Tree::clear [aie_connectors_attribute_name]
}

proc aie_connectors_activate_all_directives {on} {
    foreach f [ic_geo_list_families] {
	set directives [aie_connectors_get_directive_of_fam $f]
	foreach d $directives {
	    ic_meshdirect_directive_set_val_by_tag $d $f active $on
	}
    }
    # update the dez shown
    # apparently we don't want to show DEZ - see Bug 11902
    # defineConnectorsDEZ show
	aie_connectors_update_inactive_icons
}

proc aie_connectors_display_results {} {

    aie_connectors_register_resultfams_from_tetin

    aie_connectors_update_tree_groups

    # turn on the bars so they can see welds and stuff...
    global aie_meshTypeVis
    set aie_meshTypeVis(line) 2
    aie_updateMeshVis
}

# group is actually "family" now...

proc aie_connectors_get_group_predominant_entity_type {group} {

    # this is for arbitrary connectors. ideally they should only select one entity type,
    # and, ideally, we should be able to handle anything combination they can select, but,
    # for now, just do the most common types.

    set entityList [ic_geo_get_objects all $group]
    set typed_entityList [ic_geo_get_entity_types $entityList]

    foreach {n v} $typed_entityList {
	if ![info exists n_ent_types($n)] {
	    set n_ent_types($n) 1
	} else {
	    incr n_ent_types($n)
	}
    }

    if 1 {
	# if part contains all sort of ent_types, just consider the
	# highest dimension...(Bugzilla #6209)
	set entity_priority "surface curve point"
	set predominant_type ""
	foreach t $entity_priority {
	    if {[info exists n_ent_types($t)] && (0 < $n_ent_types($t))} {
		set predominant_type $t
		break
	    }
	}
    } else {
	# used to do it by the number of each entities...
	if {"" == $predominant_type} {
	    set max_ents_by_type 0
	    set predominant_type ""
	    foreach t [array names n_ent_types] {
		if {$n_ent_types($t) > $max_ents_by_type} {
		    set max_ents_by_type $n_ent_types($t)
		    set predominant_type $t
		}
	    }
	}
    }


    # if no predominant type found in the geometry, try getting it from the mesh

    if {("" == $predominant_type) && [ic_uns_is_loaded]} {
	foreach {dim type} {2 surface 1 curve 0 point} {
	    set dim_list [ic_uns_list_families $dim]
	    if {0 <= [lsearch $dim_list $group]} {
		# we can return now since we won't be ignoring any geom ents
		return $type
	    }
	}
    }

    if {"" == $predominant_type} {
	mess "Warning: could not get the predominant type of group $group\n" red
	return ""
    }

    set ignored_types ""
    foreach t [array names n_ent_types] {
	if {($n_ent_types($t) > 0) && (![string equal $t $predominant_type])} {
	    lappend ignored_types $t
	}
    }
    if {![string equal "" $ignored_types]} {
	mess "ignoring " red
	foreach it $ignored_types {
	    if {[info exists n_ent_types($it)] && (0 < $n_ent_types($it))} {
		mess "$n_ent_types($t) $it entities," red
	    }
	}
	mess "in connecting to part $group (chose highest dimension)\n" red
    }

    return $predominant_type
}

proc aie_connectors_create_new_source_group { basename entityList {type_to_use ""} } {
    # for example, arbConns may not have an entityList...
    if {"" == $entityList} {
	#?? set new_groups [aie_connectors_get_fams_for_group $basename]
	if {"" == $basename} {
	    mess "Error: must specify a groupname or entities for connectors source!\n" red
	    return ""
	}
	set famname [aie_connectors_get_fams_for_group $basename]
	#if { ("" == $famname) || [string equal $famname $basename]} { } see Bug_6423
	if {"" == $famname} {
	    mess "Error: could not get family for part $basename\n" red
	    return ""
	}
if 0 {
        set color [family_color_for_name [lindex [split [lindex $famname 0] :] 0]]
	aie_color_part $basename $color
	aie_tree add_group [aie_connectors_attribute_name] $basename 1 0 $color
	aie_md_debug "colored $basename with $color"
}
	return $famname
    }

    set loc_type      [aie_connectors_attribute_name]
    set loc_type_name [aie_connectors_boco_name]

    # see bug 6366
    if {"" == $type_to_use} {
	set typed_entityList [ic_geo_get_entity_types $entityList]
    } else {
	# last resort
	set typed_entityList ""
	foreach e $entityList {
	    if {"" != [ic_geo_check_objects_exist $type_to_use $e]} {
		append typed_entityList "$type_to_use $e "
	    }
	}
    }

    set bcs [list [list 1 $loc_type_name $basename]]
    set new_groups [ic_boco_set_for_objects $typed_entityList $bcs "" $basename]

    if {"" != $new_groups} {
	if 0 {
	    foreach ng $new_groups {
		set color [family_color_for_name [lindex [split $ng :] 0]]
		aie_color_part $ng $color
		aie_tree add_group $loc_type $ng 1 0 $color
		aie_md_debug "colored $ng with $color"
	    }
	} else {
	    set color [family_color_for_name [lindex [split [lindex $new_groups 0] :] 0]]
	    aie_color_part $basename $color
	    aie_tree add_group $loc_type $basename 1 0 $color
	    aie_md_debug "colored $basename with $color"
	}
    } else {
	set new_groups [aie_connectors_get_fams_for_group $basename]
    }

    return $new_groups
}

proc aie_connectors_result_group_default {directive} {
    if [string is integer $directive] {
	# then this is a dez switch value
	set directive [aie_connectors_get_switch_value_directive $directive]
    }
    if ![string equal -nocase "S" [string range $directive end end]] {
	append directive s
    }
    return "[string toupper ${directive}]"
}

proc aie_connectors_register_new_result_group {result} {

    set loc_type      [aie_connectors_attribute_name]
    set loc_type_name [aie_connectors_boco_name]

    set bcs [list [list 1 $loc_type_name $result]]
    #set new_group [ic_boco_set_for_objects "" $bcs MD ""] by wayne's request, 28.Apr.2003
    set new_group [ic_boco_set_for_objects "" $bcs "" $result]

    set color [family_color_for_name [lindex [split $result :] 0]]
    aie_color_part $result $color

    aie_md_debug "colored $result with $color"

    # register this part name as potential part for update after exec'ing mesh_direct
    aie_connectors_register_tree_groups $result

    return $result
}

# to add a list of potential new mesh parts, do: aie_connectors_manage_tree "fam1 famn famnplus1"
# to try adding that list potential new mesh parts to the tree, do: aie_connectors_manage_tree "fam1 famn famnplus1"

proc aie_connectors_register_tree_groups {newgroups} {
    global aie_connectors_potential_groups

    if {"" != $newgroups} {
	eval lappend aie_connectors_potential_groups $newgroups
    }
}

proc aie_connectors_update_tree_groups {} {
    global aie_connectors_potential_groups

    # RESULTS DO NOT GO INTO CONTACTS BRANCH< RATHER THE NORMAL PARTS
    #
    set loc_type part ;#[aie_connectors_attribute_name]

    if [info exists aie_connectors_potential_groups] {
	foreach p $aie_connectors_potential_groups {
	    #if {(0 < [ic_uns_lookup_family_pid $p]) && (0 < [ic_uns_count_in_families $p])} {
	    aie_tree add_group $loc_type $p
	    #} else {
	    #mess "will not add connector part $p to tree since no mesh elements in that family" red
	    #}
	}
	# reset
	set aie_connectors_potential_groups ""
    }
}

proc unused_aie_connnectors_is_group_a_connector {groupname} {
    set key [aie_connectors_tree_node_name]
    return [string equal -nocase -length [string length $key] $key $groupname]
}

proc unused_unused_aie_connnectors_is_group_a_connector_with_directives {groupname} {
    #if ![unused_aie_connnectors_is_group_a_connector $groupname] { return 0 }
    return [aie_connnectors_does_group_have_directives $groupname]
}

# this has to change if you ever change the order of exclusiveGroupItem s in dataEntryDialog xxx --jka

proc aie_connectors_get_directive_switch_value {directive} {
    switch -- $directive {
	connector  { set defineConnectorsTypeGGVal 0 }
	boltspider { set defineConnectorsTypeGGVal 1 }
	seamweld   { set defineConnectorsTypeGGVal 2 }
	spotweld   { set defineConnectorsTypeGGVal 3 }
	default    { set defineConnectorsTypeGGVal 0 }
    }
    return $defineConnectorsTypeGGVal
}

#

proc aie_connectors_get_switch_value_directive {dez_switch_value} {
    switch -- $dez_switch_value {
	0 { set directive  connector }
	1 { set directive  boltspider }
	2 { set directive  seamweld }
	3 { set directive  spotweld }
	default    { set directive boltspider }
    }
    return $directive
}

proc aie_connectors_redefinition_warning {part} {
    # this is ok now...
    return
    mess "\nWarning: To change the part name or part entities in redefining\
	  meshing directives, please use the \"Modify\" option\n" red
}

proc aie_connectors_spotweld_method_list {} {
    #return [ic_meshdirect_spotweld_types_verbose_list]
    # the exclusive Group depends on this list order!... :-(   --jka
    # and the internal mechanisms depend on the text!
    return [list "Point to point" "Mesh indpendenent line" "Mesh indpendenent hexa" "Area weld"]
}

proc aie_connectors_seamweld_method_list {} {
    #return [ic_meshdirect_seamweld_types_verbose_list]
    # the exclusive Group depends on this list order!... :-(   --jka
    # and the internal mechanisms depend on the text!
    return [list "Point to point" "Curtain Tris/Quads" "Glinka"]
}

proc aie_connectors_seamweld_subtype_list {} {
    # added for glinka subtypes --rpai
    return [list "tweld" "lapweld"]
}

proc aie_connectors_glinka_side_method_list {} {
    # the exclusive Group depends on this list order!... :-(   --jka
    # and the internal mechanisms depend on the text!
    return [list "Both directions" "Positive direction" "Negative direction"]
}

proc aie_connectors_uniquify_group_name {prefix} {
    foreach fam [ic_geo_list_families] {
	set comparison [lindex [split $fam :] end]
	set found($comparison) 1
    }
    for {set i 0} {[info exists found($prefix$i)]} {incr i} {}
    return $prefix$i
}

# these default names come from Bugzill #5976

proc aie_connectors_default_source_group_name {type} {
    set name_root ""
    switch -- $type {
	Arbitrary - connector {  set name_root  ARB_CURVES }
	Spiderweb - boltspider { set name_root BOLT_CURVES }
	SeamWeld - seamweld {    set name_root SEAM_CURVES }
	SpotWeld - spotweld {    set name_root SPOT_POINTS }
	default {		set name_root $type       }
    }
    if {"" != $name_root} {
	set name [aie_connectors_uniquify_group_name $name_root]
    } else {
	set name ""
    }

    return $name
}

proc aie_connectors_default_result_group_name {type} {
    set name_root ""
    switch -- $type {
	Arbitrary - connector {  set name_root ARB_WELD  }
	Spiderweb - boltspider { set name_root BOLT_WELD }
	SeamWeld - seamweld {    set name_root SEAM_WELD }
	SpotWeld - spotweld {    set name_root SPOT_WELD }
	default { set name_root $type }
    }

    if {"" != $name_root} {
	set name [aie_connectors_uniquify_group_name $name_root]
    } else {
	set name ""
    }
    return $name
}

proc aie_connectors_root_family_names_of_groups {parts} {

    set base_fams ""
    foreach p $parts {

	set targs [lindex [aie_connectors_get_fams_for_group $p] 0]

	set delim_ind [expr {[string first ":" $targs] - 1}]
	if {0 < $delim_ind} {
	    set base_fam [string range $targs 0 $delim_ind]
	} else {
	    set base_fam $targs
	}

	lappend base_fams $base_fam
    }
    return [lsort -unique $base_fams]
}

proc aie_connectors_root_family_names_of_fams {fams} {

    set base_fams ""
    foreach f $fams {
	set delim_ind [expr {[string first ":" $f] - 1}]
	if {0 < $delim_ind} {
	    set base_fam [string range $f 0 $delim_ind]
	} else {
	    set base_fam $f
	}
	lappend base_fams $base_fam
    }
    return [lsort -unique $base_fams]
}

proc aie_connectors_create_groups_for_imported_welds {} {

    set available_fams [ic_uns_list_families]
    set possible_weld_fam_roots [list MASTIC WSPOT]

    foreach pwfr $possible_weld_fam_roots {
	set ind [lsearch $available_fams ${pwfr}*]
	while {0 <= $ind} {
	    set fam_to_add [lindex $available_fams $ind]
	    aie_connectors_create_group_for_existing_fam $fam_to_add
	    set tind [lsearch [lrange $available_fams [expr $ind + 1] end] ${pwfr}*]
	    set ind [lsearch $available_fams [lindex [lrange $available_fams [expr $ind + 1] end] $tind]]
	}
    }
}

# this little TEMP util allows users to get at a new seamweld type that is too late to
# go into the gui

proc aie_connectors_define_seamwelds_as_quads {{parts all} {reset 0}} {

    if {"all" == $parts} {
	set parts [aie_list_parts 0]
    }
    set parts_on_which_set ""
    foreach p $parts {
	set locFamOnWhich [aie_connectors_get_fams_for_group $p]
	set cur_group_directive [aie_connectors_get_directive_of_fam $locFamOnWhich]
	if {"seamweld" == $cur_group_directive} {
	    if !$reset { set meth "curtain_quad" } else { set meth "standard" }
	    ic_meshdirect_directive_set_val_by_tag seamweld $locFamOnWhich method $meth
	    lappend parts_on_which_set $p
	}
    }

    if !$reset { set did "Set" } else { set did "Unset" }
    mess "$did quad connections on seamwelds in parts \{$parts_on_which_set\}\n" blue
}

# Added for Onyx Defect ID 33486 for marking inactive connectors in the tree.
# Uses a partial cut-paste from proc ondefineConnectorsDEZLoad to find out
# active/inactive state of each connector, Anand.
proc aie_connectors_update_inactive_icons {} {
    global aie_connectors_global_edit_group
	if ![info exists ::AIEnv::GUIManagement::Tree::aieTree] return
	set aieTree [set ::AIEnv::GUIManagement::Tree::aieTree]
	if {[info command $aieTree]==""} return
	::AIEnv::GUIManagement::Tree::doInsertIfNeeded connectorNode
	array set VisibilityImages [array get ::AIEnv::GUIManagement::Tree::VisibilityImages]
	set cons [$aieTree nodes connectorNode]
	foreach con $cons {
		regsub ^connector- $con "" groupOnWhich
		# locFamOnWhich could be a list of fams
		set locFamOnWhich [aie_connectors_get_group_for_fam $groupOnWhich]
		if {"" == $locFamOnWhich} {
			set locFamOnWhich $groupOnWhich
		}
		set cur_group_directive [aie_connectors_get_directive_of_fam $locFamOnWhich]
		if {"" != $cur_group_directive} {
			if {1 < [llength $locFamOnWhich]} {
				foreach fam $locFamOnWhich {
					if {"" != [aie_connectors_get_directive_of_fam $fam]} {
						set onefam $fam
						break
					} else {
                   		aie_md_debug "the family $fam did not have any directives, rather\
                                 		[aie_connectors_get_directive_of_fam $fam]"
						continue
					}
				}
			} else {
				set onefam $locFamOnWhich
			}
			set curDirectActive [ic_meshdirect_directive_get_val_by_tag $cur_group_directive \
									$onefam active]
			if !$curDirectActive {
   				if {[$aieTree itemcget $con -image]==$VisibilityImages(notVisImg)} {
					$aieTree itemconfigure $con -image $VisibilityImages(notVisInactiveImg)
				} elseif {[$aieTree itemcget $con -image]==$VisibilityImages(isVisImg)} {
					$aieTree itemconfigure $con -image $VisibilityImages(isVisInactiveImg)
				}
			} else {
   				if {[$aieTree itemcget $con -image]==$VisibilityImages(notVisInactiveImg)} {
					$aieTree itemconfigure $con -image $VisibilityImages(notVisImg)
				} elseif {[$aieTree itemcget $con -image]==$VisibilityImages(isVisInactiveImg)} {
					$aieTree itemconfigure $con -image $VisibilityImages(isVisImg)
				}
			}
		}
	}
}

# ------------ ondefineConnctorsDEZ* --->

# reset these as we move from one exclusive item to another...
# this is the list of exclusive group widgets

foreach w {Arbitrary Spiderweb SeamWeld SpotWeld SpotWeldFile} {
    # this "set $def stuff; eval $def" is to hardcode "w"'s val into the proc def"
    set def "proc ondefineConnectors${w}Load \{\} \{
	global aie_connectors_global_edit_group

	if !\[info exists aie_connectors_global_edit_group\] \{
	    set groupEntsOnWhich \"\"
	    set groupOnWhich \[aie_connectors_default_source_group_name $w\]
	    set groupResultName \[aie_connectors_default_result_group_name $w\]
	    set curDirectActive 1
	\}
    \}"
    eval $def
}

proc ondefineConnectorsDEZLoad {} {
    global aie_connectors_global_edit_group

    # There are two ways to enter, with or without aie_connectors_global_edit_group
    # aie_connectors_global_edit_group would have been set by aie_edit_group_directives proc,
    # and that happends from right-clicking on the tree-node for a Connectors-part.

    set aie_connectors_reediting_directive 0

    if [info exists aie_connectors_global_edit_group] {
        # here we are coming in from the tree and loading from stuff from the tetin
        # this has to map back to the DEZ internal name
        aie_md_debug "global edit group = $aie_connectors_global_edit_group\n"
        set groupOnWhich $aie_connectors_global_edit_group
        # this is for when a Part>Connector>PartName has been right-clicked in the tree--we are getting
        # out of proj what we've set for this Part before, so they can edit it...
        aie_connectors_redefinition_warning $groupOnWhich

        aie_md_debug "trying to re-edit directives of the global edit group: $groupOnWhich"

        # locFamOnWhich could be a list of fams
        set locFamOnWhich [aie_connectors_get_group_for_fam $groupOnWhich]
        if {"" == $locFamOnWhich} {
            set locFamOnWhich $groupOnWhich
        }

        # I think we should leave it blank since the targets are already created
        set groupEntsOnWhich ""
        # and selection modes to "by existing part" (always second [ind 0] in exclusive group
        set seamWeldSelectionMethod 1
        set spotWeldSelectionMethod 1
        set boltHoleSelectionMethod 1
        set arbConnSrcSelMethod  1
        set arbConnTrgSelMethod  1

        aie_md_debug "getting dirs for $locFamOnWhich..."
        set cur_group_directive [aie_connectors_get_directive_of_fam $locFamOnWhich]
        aie_md_debug "...got dir $cur_group_directive for $locFamOnWhich"

        set defineConnectorsTypeGGVal [aie_connectors_get_directive_switch_value $cur_group_directive]

        if {"" != $cur_group_directive} {
            if {1 < [llength $locFamOnWhich]} {
                foreach fam $locFamOnWhich {
                    if {"" != [aie_connectors_get_directive_of_fam $fam]} {
                        set onefam $fam
                        break
                    } else {
                        aie_md_debug "the family $fam did not have any directives, rather [aie_connectors_get_directive_of_fam $fam]"
                    }
                }
            } else {
                set onefam $locFamOnWhich
            }
            set curDirectActive [ic_meshdirect_directive_get_val_by_tag $cur_group_directive $onefam active]
            set internalResultName [ic_meshdirect_directive_get_val_by_tag $cur_group_directive $onefam result_fam]
            aie_md_debug "have internalResultName \"$internalResultName\""
            set groupResultName [aie_connectors_get_group_for_fam $internalResultName]
            if {"" == $groupResultName} {
                aie_md_debug "did not find group \"$groupResultName\"; using internalResultName $internalResultName"
                set groupResultName $internalResultName
            } else {
                aie_md_debug "got groupResultName $groupResultName"
            }
            aie_md_debug "loading data for $cur_group_directive on $groupResultName"
            set groupEntsOnWhich ""
            # these strings are defined in ic_meshdirect_sub_available_directives_get
            switch -- $cur_group_directive {
                "spotweld" {
                    set groupEntsOnWhich [ic_geo_get_objects point $locFamOnWhich]
                }
                "seamweld" - "boltspider" {
                    set groupEntsOnWhich [ic_geo_get_objects curve $locFamOnWhich]
                }
                "connector" {
                    set groupEntsOnWhich [ic_geo_get_objects all $locFamOnWhich]
                }
                default {
                    mess "Warning: I don't reconize the directive \"$cur_group_directive\"\n" red
                }
            }
            aie_md_debug "onefam = $onefam\n"
            set maxProjection [ic_meshdirect_directive_get_val_by_tag $cur_group_directive $onefam maxproj]
            set internalSplittingMethod [ic_meshdirect_directive_get_val_by_tag $cur_group_directive $onefam splitting]
            aie_md_debug "internalsplittingmethod = $internalSplittingMethod\n"
            set splittingMethod [ic_meshdirect_weld_splitting_verbose_get $internalSplittingMethod]
            set weldRadius [ic_meshdirect_directive_get_val_by_tag $cur_group_directive $onefam radius]
            set weldMethodInt [ic_meshdirect_directive_get_val_by_tag $cur_group_directive $onefam method]
            if {"" != $weldMethodInt} {
                switch -- $cur_group_directive {
                    "spotweld" {
                        set spotWeldMethod [ic_meshdirect_spotweld_types_verbose_get $weldMethodInt]
                        aie_md_debug "got tag spotWeldMethod \"$spotWeldMethod\""
                        if {"__none__" != $spotWeldMethod} {
                            set dumbSpotWeldMethod [lsearch [aie_connectors_spotweld_method_list] $spotWeldMethod]
                        } else {
                            set dumbSpotWeldMethod 0
                        }
                    }
                    "seamweld" {
                        set seamWeldMethod [ic_meshdirect_seamweld_types_verbose_get $weldMethodInt]
                        aie_md_debug "got tag seamWeldMethod \"$seamWeldMethod\""
                        if {"__none__" != $seamWeldMethod} {
                            set dumbSeamWeldMethod [lsearch [aie_connectors_seamweld_method_list] $seamWeldMethod]
                        } else {
                           set dumbSeamWeldMethod 0
                        }
                        if {"Glinka" == $seamWeldMethod} {
                            set internalGlinkaDiagsSide [ic_meshdirect_directive_get_val_by_tag $cur_group_directive $onefam glinka_side]
                            set internalGlinkaSubtype [ic_meshdirect_directive_get_val_by_tag $cur_group_directive $onefam glinka_subtype]
                            aie_md_debug "internalGlinkaSubtype = $internalGlinkaSubtype\n"
                            if {$internalGlinkaSubtype == ""} {
                                set glinkaSubType 0
                            } else {
                               set glinkaSubType [ic_meshdirect_glinka_subtype_verbose_get $internalGlinkaSubtype]
                            }
                            aie_md_debug "glinkaSubType = $glinkaSubType\n"
                            if {!$glinkaSubType} {
                                set glinkaDiagsSide [ic_meshdirect_glinka_side_verbose_get $internalGlinkaDiagsSide]
                            } else {
                                set glinkaDiagsOneSide [ic_meshdirect_glinka_side_verbose_get $internalGlinkaDiagsSide]
                            }
                            set glinkaOffsetNLayers [ic_meshdirect_directive_get_val_by_tag $cur_group_directive $onefam glinka_layers]
                            set glinkaOffsetHeight [ic_meshdirect_directive_get_val_by_tag $cur_group_directive $onefam glinka_height]
                            set glinkaOffsetHeightRatio [ic_meshdirect_directive_get_val_by_tag $cur_group_directive $onefam glinka_ratio]
                            set glinkaSpacing 0
                            set glinkaExtendType 1
                        }
                    }
                }
            } else {
                set dumbSpotWeldMethod 0
                set dumbSeamWeldMethod 0
            }
            set rbe3FamName [ic_meshdirect_directive_get_val_by_tag $cur_group_directive $onefam rbe3s]
            set rbe3PartName [aie_connectors_get_group_for_fam $rbe3FamName]

            # just load it into all of them...could be more selective here... --jka	    
            set generalTargetFams [ic_meshdirect_target_fam_vals_get $cur_group_directive $onefam]
            set arbConnTargetFam [aie_connectors_get_group_for_fam $generalTargetFams]
            set seamTargetFam $arbConnTargetFam
            set spotMultTargets $arbConnTargetFam
            set nRowsBars [ic_meshdirect_directive_get_val_by_tag $cur_group_directive $onefam rows_bars]
            if [string is integer $nRowsBars] {
                set boltHoleIsWasher [expr {1 < $nRowsBars}]
            } else {
                set boltHoleIsWasher 0
            }
            set boltHoleNQuadLayers [ic_meshdirect_directive_get_val_by_tag $cur_group_directive $onefam quad_layers]
        }

        if [info exists aie_connectors_global_edit_group] {
            unset aie_connectors_global_edit_group ;#!! important xxx --jka
        }
    } else {

       # we are coming into the DEZ with a blank slate      
       if ![info exists defineConnectorsTypeGGVal] {
           set defineConnectorsTypeGGVal 0
       }       
       set curDirectActive 1
       set groupEntsOnWhich ""
       set groupResultName [aie_connectors_result_group_default CONNECTION]
       set boltHoleNQuadLayers [expr { (2 == [ic_uns_dimension]) ? 2 : 0 }]
       set boltHoleIsWasher 0
       set glinkaSubType 0
    }

    # this is all generic stuff like lists

    set extra_args ""
    set group_list [aie_list_parts 0]
    
    set geom_type_list "point curve surface"
    set groupTypeOnWhich [lindex $geom_type_list 0]
    set groupTypeToWhich [lindex $geom_type_list 1]
    
    # for [seam|spot]-welding, get the types of spot welds available
    set possible_spot_weld_types [ic_meshdirect_spotweld_types_verbose_list]
    set possible_seam_weld_types [ic_meshdirect_seamweld_types_verbose_list]

    if {(![info exists spotWeldMethod]) || ("" == $spotWeldMethod)} {
        set spotWeldMethod [lindex $possible_spot_weld_types 0]
    }
    if {(![info exists seamWeldMethod]) || ("" == $seamWeldMethod)} {
        set seamWeldMethod [lindex $possible_seam_weld_types 0]
    }
    set dumbSpotWeldMethod [lsearch [aie_connectors_spotweld_method_list] $spotWeldMethod]
    set dumbSeamWeldMethod [lsearch [aie_connectors_seamweld_method_list] $seamWeldMethod]
    
    # get also the way in which nodes locations are forced into a mesh
    set possible_splitting_methods [ic_meshdirect_weld_splitting_verbose_list]
    
    if {![info exists splittingMethod] || ("" == $splittingMethod)} {
        set splittingMethod [lindex $possible_splitting_methods 0]
    }
    if {![info exists spotFileElSplitting] || ("" == $spotFileElSplitting)} {
        set spotFileElSplitting [lindex $possible_splitting_methods 0]
    }

    set glinka_sides [list "Both directions" "Positive direction" "Negative direction"]
    if {![info exists glinkaDiagsSide] || ("" == $glinkaDiagsSide)} {
        set glinkaDiagsSide [lindex $glinka_sides 0]
    }
    set glinka_one_side [list "Positive direction" "Negative direction"]
    if {![info exists glinkaDiagsOneSide] || ($glinkaDiagsOneSide == "")} {
        set glinkaDiagsOneSide [lindex $glinka_one_side 0]
    }

    set glinkaSpacing 0
    set glinkaExtendType 1

    # these are for the DEZ exlusive groups of selection methods
    if ![info exists seamWeldSelectionMethod] { set seamWeldSelectionMethod 0 }
    if ![info exists spotWeldSelectionMethod] { set spotWeldSelectionMethod 0 }
    if ![info exists boltHoleSelectionMethod] { set boltHoleSelectionMethod 0 }
    if ![info exists     arbConnSrcSelMethod] { set     arbConnSrcSelMethod 0 }
    if ![info exists     arbConnTrgSelMethod] { set     arbConnTrgSelMethod 0 }
#    if ![info exists SeamWeldingMethod] {set SeamWeldingMethod 0}

    if {![info exists spotFileReport] || ("" == $spotFileReport)} {
        set spotFileReport "./spot_welding_report.txt"
    }
    set AllowActiveReload 1
}


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

proc UpdateGlinkaWeldSpacingParams {groupitem} {
    global no_thickness_message
    if {[defineConnectorsDEZ get defineConnectorsTypeGGVal] != 2} return
    if {[defineConnectorsDEZ get dumbSeamWeldMethod] != 2} return
    
    if [aie_connector_glinka_get_thickness [ic_geo_get_objects surface]] {
        ::AIEnv::GUIManagement::ToggleGrey ajcSWDumbWidgetRadius 0
    } else {
        if {[defineConnectorsDEZ get glinkaSubType] == 0} {
            if ![info exists no_thickness_message] {
                ::AIEnv::GUIManagement::ToggleGrey ajcSWDumbWidgetRadius 1
                 mess "Existing surfaces contain no thickness.  Tent Weld sub-type T welds: \"Tent weld spacing\
                       by Weld fillet radius\" disabled\n" red
                 set no_thickness_message 1
            }
        } else {
           ::AIEnv::GUIManagement::ToggleGrey ajcSWDumbWidgetRadius 0
        }
    }
    
    namespace eval ::AIEnv::DEZ::defineConnectorsDEZ {
	
	set Radius 0
	set Height 0
        set HeightRatio 0
        set Thickness 0
        
        if {$glinkaOffsetNLayers == ""} {
            switch $glinkaSubType {
                0 { set NLayers 3; set type "T welds" }
                1 { set NLayers 2; set type "Lap welds" }
            }
            mess "Weld type \"$type\": Default $NLayers \"Number layers to toe\" assumed\n"
        } else {
            set NLayers $glinkaOffsetNLayers
        }
	if {$glinkaOffsetHeight != "" && $glinkaOffsetHeight} {
	    set Height $glinkaOffsetHeight
	}
	if {$glinkaOffsetHeightRatio != "" && $glinkaOffsetHeightRatio} {
	    set HeightRatio $glinkaOffsetHeightRatio
	}
	if {$glinkaOffsetRadius != "" && $glinkaOffsetRadius} {
	    set Radius $glinkaOffsetRadius
	}
        
        if {$groupEntsOnWhich != "" && $seamTargetFam != "" && $glinkaSubType == 0} {
            set surfaces [ic_geo_get_objects surface $seamTargetFam]
            set Thickness [aie_connector_glinka_get_thickness $surfaces]
            if {$Thickness == 0} {
                mess "Weld type \"T welds\": No thickness defined on target surfaces. \"Tent weld\
                     spacing by Weld fillet radius\" disabled\n" red
                ::AIEnv::GUIManagement::ToggleGrey ajcSWDumbWidgetRadius 1
                set glinkaSpacing 0
            }
        }
        
	if $glinkaSpacing {
             # height/ratio to radius
             if {$NLayers > 0 && !$Radius} {
                 if {$Height && $HeightRatio} {
                     set GPtimes [expr $NLayers - 1]
                     set GPratio $HeightRatio
                     if {$GPratio == 1} {
                         set glinkaOffsetRadius [expr $NLayers * $Height]
                     } else {
                         set nume [expr pow($GPratio,$NLayers)]
                         set nume [expr $nume - 1]
                         set dino [expr $GPratio - 1]
                         set glinkaOffsetRadius [expr 1.0 * $Height * $nume / $dino]
                     }
                 }
             } 
        } else {
            # onload or radius to height/ratio
            if {$NLayers > 0} {
                if $Radius {
                    if !$HeightRatio {
                        set HeightRatio 1 
                        set glinkaOffsetHeightRatio 1.2
                    }
                    set GPtimes [expr $NLayers - 1]
                    set GPratio $HeightRatio
                    if {$GPratio == 1 && $glinkaSubType == 1} {
                        set glinkaOffsetHeight [expr 1.0 * $Radius / $NLayers]
                    } else {
                        if {$glinkaSubType == 0 && $Thickness} {
                            set glinkaOffsetHeight [expr ((($Thickness / 2.0 ) + $Radius) / 3.0)]
                        } else {
                            set dino [expr pow($GPratio,$NLayers)]
                            set dino [expr $dino - 1]
                            set nume [expr $GPratio - 1]
                            set glinkaOffsetHeight [expr 1.0 * $Radius * $nume / $dino]
                        }
                    }
                }
            }
        }
    }
}

proc aie_connector_glinka_get_thickness {surfaces} {
    
    if {$surfaces == ""} { return 0 }
    set i 0
    set thickness 0
    foreach s $surfaces {
        set st [ic_geo_surface_thickness $s 2]
        if {$st != "0 0 0 0"} {
            foreach {t1 t2 t3 t4} $st {
                set t [expr ($t1 + $t2 + $t3 + $t4) / 4.0]
                incr i
            }
            set thickness [expr $t + $thickness]
        }
    }
    if {$thickness != 0} {
        set thickness [expr $thickness / $i]
    }
    return $thickness
}

proc onseamWeldSelEG0Ec3Finish {} {
    UpdateGlinkaWeldSpacingParams ""
}

proc ondefineConnectorsPart1Fam3Finish {} {
    UpdateGlinkaWeldSpacingParams ""
}

proc ondefineConnectorsDEZUnLoad {} { 
    global no_thickness_message
    if [info exists no_thickness_message] {
        unset no_thickness_message
    }    
}

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

proc ondefineConnectorsDEZOK {} {    
    global aie_connectors_global_edit_group
    # ^^^ this global since we can have entered the dez from the tree,
    # and have already gotten data from the proj_obj

    # --> defineConnectorsTypeGGVal
    # this switch statement maps the exclusive group stuff, so this is what needs to be
    # modified if the .ttkrf file is changed
    #
    if ![info exists defineConnectorsTypeGGVal] {
        mess "Error: can't get enough information from the data entered to define connectors...\n" red
        return -1
    }
    # aieconn_how_to_handle: how to handle this mode in this proc
    # md_type_to_execute: how to handle this mode within mesh_direct itself

    set groupOnWhich [string toupper $groupOnWhich]
        
    aie_md_debug "Debugging input params\n"
    aie_md_debug "groupOnWhich = $groupOnWhich\n"
    aie_md_debug "groupTypeOnWhich = $groupTypeOnWhich\n"
    aie_md_debug "groupTypeToWhich = $groupTypeToWhich\n"
    aie_md_debug "groupEntsOnWhich = $groupEntsOnWhich\n"
    aie_md_debug "groupResultName = $groupResultName\n"

    busy 1
       
    switch -- $defineConnectorsTypeGGVal {
        0 {
            set aieconn_how_to_handle   connector
            set md_type_to_execute      connector
            set expected_type           ""
            if {"" == $groupOnWhich} {
                set groupOnWhich [aie_connectors_default_source_group_name $aieconn_how_to_handle]
            }
        }
        1 {
            set aieconn_how_to_handle   boltspider
            set md_type_to_execute      boltspider
            set expected_type           curve
        }
        2 {
            set aieconn_how_to_handle   seamweld
            set md_type_to_execute      seamweld
            set expected_type           curve
        }
        3 {
            set aieconn_how_to_handle   spotweld
            set md_type_to_execute      spotweld
            set expected_type           point
            
            set is_embedded 1
            foreach p $groupEntsOnWhich {
                switch -- [aie_connector_point_embedded $p] {
                    -1 {
                        mess "Error: distance between source point $p and nearest surface is greater\
                              than the default topo tolerance of [aie_default_topo_tolerance]\n" red
                        set is_embedded 0
                    }
                    0 {
                        mess "Error: source point $p need to be in the same part like the surface\n" red
                        set is_embedded 0
                    }
                }
            }
            if !$is_embedded {
                mess "Error: unable to embed automatically selected source point(s)\n" red
                busy 0
                return 0
            }
        }
        4 {
            set md_type_to_execute spotweld
            if {(![info exists groupResultName]) || ("" == $groupResultName)} {
                set groupResultName [aie_connectors_default_result_group_name $md_type_to_execute]
            }
            set resultPart [aie_connectors_register_new_result_group $groupResultName]
            set split_tag [ic_meshdirect_weld_splitting_param_get $spotFileElSplitting]
            set args "-report_file $spotFileReport"
            if {"" != $spotFileMaxProj} { append args " -maxprojection $spotFileMaxProj" }
            if {"" != $resultPart} { append args " -spotweld_family $resultPart" }
            if {"" != $spotFileElSplitting} {
                set split_tag [ic_meshdirect_weld_splitting_param_get $spotFileElSplitting]
                append args " -element_splitting $split_tag" 
            }
            set status [eval ic_meshdirect_spotweld_file_import $spotFileName $args]
            aie_connectors_create_groups_for_imported_welds
            aie_connectors_display_results
            # we're done...
            busy 0
            return $status
        }
        default {
            mess "Error: can't get the connector type to create from data entered...returning." red
            busy 0
            return -1
        }
    }
    set groupTypeOnWhich $expected_type

    # again, some aie_connectors_global_edit_group logic ...
    # if we are arriving in this DEZ by modifying an existing one,
    # then we won't be editing the group name or enitities, rather using the existing 
    if {(![info exists aie_connectors_global_edit_group]) || ("" == $aie_connectors_global_edit_group)} {
        if {"" == $groupOnWhich} {
            set groupOnWhich [string toupper $md_type_to_execute]
        }
        #
        # --> FIXME: here we might want to check what kind of directive,
        # --> and see if any geometry modifications
        # --> have to made as, say, in the case of Glinka welds
        #
        set method_tag "__NONE__"
        switch -- $aieconn_how_to_handle {
        seamweld {
            set seamWeldMethod [lindex [aie_connectors_seamweld_method_list] $dumbSeamWeldMethod]
            set method_tag [ic_meshdirect_seamweld_types_param_get $seamWeldMethod]
            if {"glinka" == $method_tag} {
                set glinka_extra_args ""
                # we don't need to do glinka-side here, rather only params need for geo-creation --jka
                if {[info exists glinkaOffsetNLayers] && ("" != $glinkaOffsetNLayers)} {
                    append glinka_extra_args "md_seamweld_glinka_layers $glinkaOffsetNLayers "
                }
				if {$glinkaSpacing} {
					set glinkaSpacing 0
#					UpdateGlinkaWeldSpacingParams ""
				}
                if {[info exists glinkaOffsetHeight] && ("" != $glinkaOffsetHeight)} {
                    append glinka_extra_args "md_seamweld_glinka_height $glinkaOffsetHeight "
                }
                if {[info exists glinkaOffsetHeightRatio] && ("" != $glinkaOffsetHeightRatio)} {
                    append glinka_extra_args "md_seamweld_glinka_height_ratio $glinkaOffsetHeightRatio "
                }
                if {"" != $maxProjection} {
                    append glinka_extra_args "md_seamweld_maxprojection $maxProjection "
                }
                if {[info exists glinkaExtendType]} {
                    append glinka_extra_args "md_seamweld_extend_type $glinkaExtendType "
                }
                set target_fams [aie_connectors_root_family_names_of_groups $seamTargetFam]
                set groupEntsOnWhich [ic_meshdirect_seam_weld_glinka_geo_create_simplified $groupEntsOnWhich $target_fams $glinka_extra_args]
                if {$groupEntsOnWhich!=""} {::AIEnv::GUIManagement::Tree::ShowCurveQuadSizes}
            }
        }
        }
        # reset all entity meberships to one less than current, *if* they have a connetor def -- jka, 10 May 2004
        foreach tmpfam [aie_connectors_get_fams_comprising $groupOnWhich] {
            if {"" != [ic_meshdirect_get_directive_of_fam $tmpfam]} {
                ic_meshdirect_delete_icon $aieconn_how_to_handle $tmpfam
                foreach ent [ic_geo_get_objects $groupTypeOnWhich $tmpfam] {
                    set tmprootfam [aie_connectors_root_family_names_of_fams $tmpfam]
                    ic_geo_set_family $groupTypeOnWhich $tmprootfam names [list $ent] 0
                }
            }
        }

        if {$defineConnectorsTypeGGVal == 0} {
            if {$arbConnSrcSelMethod == 0} {
                if {$groupEntsOnWhich == ""} {
                    mess "Error: cannot continue connector definition as defined...missing source entity.\n" red
                    busy 0
                    return 0
                }
                set fam1 [ic_geo_get_part [lindex $groupEntsOnWhich 0] [lindex $groupEntsOnWhich 1]]
                set locFamOnWhich [aie_connectors_create_new_source_group $groupOnWhich $groupEntsOnWhich $expected_type]
            } elseif {$arbConnSrcSelMethod == 1} {
                set fam1 $arbConnSourceFam
                set predom_type [aie_connectors_get_group_predominant_entity_type $arbConnSourceFam]
                set predom ""
                foreach predom_name [ic_geo_get_objects $predom_type $arbConnSourceFam] {
                    append predom "$predom_type $predom_name "
                }
                set locFamOnWhich [aie_connectors_create_new_source_group $groupOnWhich $predom $expected_type]
            }
            if {$arbConnTrgSelMethod == 0} {
                if {$groupEntsToWhich == ""} {
                    mess "Error: cannot continue connector definition as defined...missing target entity.\n" red
                    busy 0
                    return 0
                }
                set fam2 [ic_geo_get_part [lindex $groupEntsToWhich 0] [lindex $groupEntsToWhich 1]]
            } elseif {$arbConnTrgSelMethod == 1} {
               set fam2 $arbConnTargetFam
            }
            if {$fam1 == $fam2} {
                mess "Error: cannot continue connector definition as defined...source and target must be in different parts.\n" red
                busy 0
                return 0
            } else {
                if {$arbConnTrgSelMethod == 0} {
                    catch { unset found }
                    foreach obj [ic_geo_get_objects all $fam2] {
                        if {[info exists found($obj)] && $obj == [lindex $groupEntsToWhich 1]} {
                            mess "Error: cannot continue connector definition as defined...target entity $obj exists twice in the same part.\n" red
                            busy 0
                            return 0
                        }
                        set found($obj) 1
                    }
                }
            }
        } else {
            set locFamOnWhich [aie_connectors_create_new_source_group $groupOnWhich $groupEntsOnWhich $expected_type] 
        }   

        switch $method_tag {
            glinka {
                if { ![ic_meshdirect_seam_weld_glinka_geo_valid $locFamOnWhich] } {
                    set md_execute_after_setting 0
                    set curDirectActive 0
                }
            }
        }
        if [info exists aie_connectors_global_edit_group] { unset aie_connectors_global_edit_group } ;#!! important --jka
    } else {
            set locFamOnWhich [aie_connectors_get_fams_for_group $aie_connectors_global_edit_group]
            set groupOnWhich $aie_connectors_global_edit_group
            if [info exists aie_connectors_global_edit_group] { unset aie_connectors_global_edit_group }
    }
    if {"" == $locFamOnWhich} {
        if {"" != $groupEntsOnWhich} {
            mess "Error: cannot continue connector definition without a group for the source entities: $groupEntsOnWhich\n" red
        } elseif {"" != $groupOnWhich} {
            mess "Error: cannot continue connector definition without a valid, existing group for the source entities: $groupOnWhich\n" red
        } else {
            mess "Error: cannot continue connector definition as defined...please check the input.\n" red
        }
        busy 0
        return 0
     } else {
        set some_fam_has_ents 0
        foreach f $locFamOnWhich {
            if ![ic_geo_family_is_empty $f] {
                set some_fam_has_ents 1
                break
             }
        }
        if !$some_fam_has_ents {
            mess "Error: cannot continue because source part $groupOnWhich has no entities...please check the input.\n" red
            busy 0
            return 0
        }
    }

    # this gets the new part name and signs it up for the tree for after execution
    if {(![info exists groupResultName]) || ("" == $groupResultName)} {
            set groupResultName [aie_connectors_default_result_group_name $md_type_to_execute]
    } 
    set resultPart [aie_connectors_register_new_result_group $groupResultName]
    if {1 != [llength $resultPart]} {
            mess "Warning: got multiple families for result part: $resultPart\n" red
            set resultPart [lindex $resultPart 0]
    }

    # try setting some of the values which are common to the various directives
    # we can set them by the common param names (active, maxproj, etc.) which map to 
    # the directive-specific names (md_spotweld_active, md_seamweld_maxproj, etc.)
    #
    foreach f $locFamOnWhich {
            # active
            ic_meshdirect_directive_set_val_by_tag $md_type_to_execute $f active $curDirectActive
            # maxproj
            if {"" != $maxProjection} { 
                ic_meshdirect_directive_set_val_by_tag $md_type_to_execute $f maxproj $maxProjection
            }
            # splitting
            if {"" != $splittingMethod} {
                set split_tag [ic_meshdirect_weld_splitting_param_get $splittingMethod]
                ic_meshdirect_directive_set_val_by_tag $md_type_to_execute $f splitting $split_tag
            }
            # radius
            if {"" != $weldRadius} {
                ic_meshdirect_directive_set_val_by_tag $md_type_to_execute $f radius $weldRadius
            }
            # rbe3_fam
            if {"" != $rbe3PartName} {
                set rbe3FamName [aie_connectors_register_new_result_group $rbe3PartName]
                ic_meshdirect_directive_set_val_by_tag $md_type_to_execute $f rbe3s $rbe3FamName
            }
     }

    # execute after defining if mesh is loaded and "active" tag is 1
    set md_execute_after_setting [expr {[ic_uns_is_loaded] && (0 != $curDirectActive)}]
    
    # now do the directive specific stuff ----
    set extra_args ""
    switch -- $aieconn_how_to_handle {
    connector {
        # Arbitary Connectors
        switch -- $arbConnSrcSelMethod {
            0 {
                set groupTypeOnWhich [lindex $groupEntsOnWhich 0]
            }
            1 {
                set groupTypeOnWhich [aie_connectors_get_group_predominant_entity_type $locFamOnWhich]
            }
        }
        set tmp_group_name [expr {("" != $arbConnTargetFam) ? $arbConnTargetFam: [string toupper $groupOnWhich]}]
        switch -- $arbConnTrgSelMethod {
            0 {
                set locFamToWhich [aie_connectors_create_new_source_group $tmp_group_name $groupEntsToWhich]
            }
            1 {
                set locFamToWhich $arbConnTargetFam
            }
        }
        if {"" == $locFamToWhich} {
            mess "Error: cannot continue without a group for the source entities:\n$groupEntsToWhich\n" red
            busy 0
            return 0
        }
        switch -- $arbConnTrgSelMethod {
            0 {
                set groupTypeToWhich [lindex $groupEntsToWhich 0]
            }
            1 {
                set groupTypeToWhich [aie_connectors_get_group_predominant_entity_type $locFamToWhich]
            }
        }
        set extra_args ""
        foreach f $locFamOnWhich {
            ic_meshdirect_arbitrary_connector_set $f $groupTypeOnWhich $locFamToWhich $groupTypeToWhich $resultPart $extra_args
        }
    }
    boltspider {
        set groupTypeOnWhich "curve"
        set extra_args ""
        if {[info exists boltHoleNQuadLayers] && ("" != $boltHoleNQuadLayers)} {
            append extra_args "n_quad_layers $boltHoleNQuadLayers "
        }
        if {[info exists boltHoleIsWasher] && (0 != $boltHoleIsWasher)} {
            append extra_args "md_spider_n_bar_rows 2 "
        }
        foreach f $locFamOnWhich {
            ic_meshdirect_boltspider_set $f $resultPart $extra_args
        }
    }
    seamweld {
        set groupTypeOnWhich "curve"
        set seamWeldMethod [lindex [aie_connectors_seamweld_method_list] $dumbSeamWeldMethod]
        set method_tag [ic_meshdirect_seamweld_types_param_get $seamWeldMethod]
        set extra_args "md_seamweld_method $method_tag "
        if {"glinka" == $method_tag} {
            append extra_args "md_seamweld_glinka_subtype [lindex [aie_connectors_seamweld_subtype_list] $glinkaSubType] "
            switch $glinkaSubType {
            0 {
                if {[info exists glinkaDiagsSide] && ("" != $glinkaDiagsSide)} {
                append extra_args "md_seamweld_glinka_side [ic_meshdirect_glinka_side_param_get $glinkaDiagsSide] "
                }
            }
            1 {
                if {[info exists glinkaDiagsOneSide] && ("" != $glinkaDiagsOneSide)} {
                append extra_args "md_seamweld_glinka_side [ic_meshdirect_glinka_side_param_get $glinkaDiagsOneSide] "
                }
            }
            }
            if {[info exists glinkaOffsetNLayers] && ("" != $glinkaOffsetNLayers)} {
                append extra_args "md_seamweld_glinka_layers $glinkaOffsetNLayers "
            }
            if {[info exists glinkaOffsetHeight] && ("" != $glinkaOffsetHeight)} {
                append extra_args "md_seamweld_glinka_height $glinkaOffsetHeight "
            }
            if {[info exists glinkaOffsetHeightRatio] && ("" != $glinkaOffsetHeightRatio)} {
                append extra_args "md_seamweld_glinka_height_ratio $glinkaOffsetHeightRatio "
            }
	}
	if {"" != $maxProjection} {
            append extra_args "md_seamweld_maxprojection $maxProjection "
	}
	set target_fams [aie_connectors_root_family_names_of_groups $seamTargetFam]
	set seamweld_status ""
	foreach f $locFamOnWhich {
            lappend seamweld_status [ic_meshdirect_seamweld_set $f $target_fams $resultPart $extra_args]
	}
	if {[lsearch $seamweld_status 0] < 0} {
            mess "Error: don't know how to create connectors of the sort: $aieconn_how_to_handle\n" red
            ic_meshdirect_reset seamweld "$groupOnWhich $locFamOnWhich"
            aie_tree delete_group [aie_connectors_attribute_name] $groupOnWhich 1
            busy 0
            return -1
	}
    }
    spotweld {
        set groupTypeOnWhich "point"
        if {1 > [llength $spotMultTargets]} {
            mess "Error: must specify at least one target part for spot-welding.\n" red
            busy 0
            return 0
        }
        # the exclusive Group depends on this list order!... :-(   --jka
        set spotWeldMethod [lindex [aie_connectors_spotweld_method_list] $dumbSpotWeldMethod]
        set method_tag [ic_meshdirect_spotweld_types_param_get $spotWeldMethod]
        foreach f $locFamOnWhich {
            ic_meshdirect_directive_set_val_by_tag $md_type_to_execute $f method $method_tag
        }
        set target_fams [aie_connectors_root_family_names_of_groups $spotMultTargets]
        set extra_args ""
        foreach f $locFamOnWhich {
            ic_meshdirect_spotweld_set $f $target_fams $resultPart $extra_args
        }
        # this should probably be moved to within the ic_meshdirect_seamweld_set proc above --jka
        if ![ic_uns_is_loaded] {
            foreach f $locFamOnWhich {
                set args "-source_family $f -target_parts [list $spotMultTargets] -max_projection $maxProjection"
                if [catch {eval ic_meshdirect_spot_weld_shadow_points_create $args} res] {
                    mess "$res\n" red
                }
            }
        }
        # have to make sure the shadow curves ($res) get added to loop on target surfs! fixme --jka
    }
    default {
        mess "Error: don't know how to create connectors of the sort: $aieconn_how_to_handle\n" red
        busy 0
        return -1
    }
    }
    # --> Execute the directives if a mesh is loaded, and not already done (as importing from file)
    set status 0
    if $md_execute_after_setting {
        #
        # run the n_quad_layers if so defined and the mesh has already been created.
        #
        if [string equal "boltspider" $md_type_to_execute] {
            if {0 < $boltHoleNQuadLayers} {
                foreach f $locFamOnWhich {
                    set stat [ic_quad_offset_curve_layers curve_family $f $boltHoleNQuadLayers]
                }
            }
        }
        #
        # which types to run? all if not specified otherwise
        #
        if {![info exists md_type_to_execute] || ("" == $md_type_to_execute)} {
            set md_type_to_execute all
        }
        foreach f $locFamOnWhich {
            set status [aie_connectors_exec $md_type_to_execute $f]
        }

# Update Glinka weld surface thicknesses
		if 0 {
			if {$aieconn_how_to_handle=="seamweld"} {
				set seamWeldMethod [lindex [aie_connectors_seamweld_method_list] $dumbSeamWeldMethod]
				set method_tag [ic_meshdirect_seamweld_types_param_get $seamWeldMethod]
				if {"glinka" == $method_tag} {
					set weld_thk 0
					foreach c $groupEntsOnWhich {
						set thk [ic_meshdirect_seam_weld_glinka_thickness_attached_to_curve $c 1]
						if !$weld_thk {set weld_thk $thk}
						if {$thk<$weld_thk} {set weld_thk $thk}
					}
					if !$weld_thk {
						mess "Please assign surface thicknesses & remesh for Glinka weld $groupOnWhich\n" red
					} else {
						set fams [ic_boco_get_fams_of_part $groupResultName]
						if {$fams!=""} {
							set map [ic_uns_subset_create_family_type $fams 2d 0 0]
							if {$map!=""} {
								ic_uns_thickness set $map $weld_thk
								ic_uns_subset_delete $map
							} else {
								mess "No shell elements found in part $groupResultName\n"
							}
						} else {
							mess "Empty part $groupResultName\n"
						}
					}
				}
			}
		}
        # Say what we'ere doing--we just ran it...
        mess "\nRan "
    } else {
        # Say what we'ere doing--we just defined it...(no mesh loaded or not an active directive)
        mess "\nDefined "
    }
    switch -- $defineConnectorsTypeGGVal {
        0 {
            set which_fam [lindex [split $locFamOnWhich :] 0]
            mess "Meshing Directive \"$md_type_to_execute\" on part \"$which_fam\" to create elements in part \"$groupResultName\"\n"
        }
        default {  
            mess "Meshing Directive \"$md_type_to_execute\" on part \"$groupOnWhich\" to create elements in part \"$groupResultName\"\n"
        }
    }
    # --> Reset some stuff in the UI, incrementing defaults
    if [info exists aieconn_how_to_handle] {
        set groupOnWhich    [aie_connectors_default_source_group_name $aieconn_how_to_handle]
        set groupResultName [aie_connectors_default_result_group_name $aieconn_how_to_handle]
        set groupEntsOnWhich ""
        set groupEntsToWhich ""
        set locFamOnWhich ""
        set locFamToWhich ""
    }
    busy reset
    aie_connectors_update_inactive_icons
    return $status
}

proc aie_connector_point_embedded {point} {

    set part [ic_geo_get_part point $point]
    set is_embedded 0
    foreach s [ic_geo_get_objects surface $part] {
        if $is_embedded break
        foreach p [ic_geo_surface_get_objects $s] {
            if {$point == $p} {
                set is_embedded 1
                break
            }
	}
    }
    if $is_embedded { return 1 }
    set surfaces [ic_geo_get_objects surface $part]
    if {$surfaces == ""} { return 0 }            
    set nearest [ic_geo_nearest_object surface $point]
    set s [lindex $nearest 0]
    set loc [lindex $nearest 1]
    if {($s != "") && ([ic_geo_get_part surface $s] == "$part")} {
        set dist [ic_geo_pnt_dist [ic_geo_get_point_location $point] $loc]
        if {$dist <= [aie_default_topo_tolerance]} {
            ic_geo_add_embedded_pnt $s $point
            return 1
        }
    }
    set loc1 [ic_geo_get_point_location $point]
    foreach s $surfaces {
        set loc2 [ic_geo_project_point surface $s $point]
        set dist [ic_geo_pnt_dist $loc1 $loc2]
        if {$dist <= [aie_default_topo_tolerance]} {
            ic_geo_add_embedded_pnt $s $point
            return 1
        }
    }
    return -1
}

###################### PRISM MESHER ##########################################

proc aie_prism_select_parts { } {
    global prism_family_on prism_values prism_families prism_parts
    global prism_family_height prism_family_ratio prism_family_n_layers

    set form_name .aie_prism
    if [winfo exists $form_name] {
	form_kill $form_name
    }
    aie_prism_update_params
    set buts [list {Accept prism_select_parts_doit} reset cancel]
    set w [form_init $form_name "Parts for prism layer" "" $buts]
    if {$w != ""} {
	set d [form_scroller $w.fr 400 {0 0}]
	set bg [$form_name cget -background]
	set ln 0

	form_label $d.fnl "Part" "0 0"
	form_label $d.fhl "Initial Height" "0 1"
	form_label $d.frl "Height Ratio" "0 2"
	form_label $d.fnuml "N Layers" "0 3"

	incr ln
	set scr $d

	set f0 $ln
	foreach ff $prism_parts {
	    form_checkbutton $scr.ff_$ln $ff prism_family_on($ff) "$ln 0 -fill both"
	    $scr.ff_$ln configure -background $bg
	    form_entry $scr.ffh_$ln prism_family_height($ff) string "$ln 1"
	    form_entry $scr.ffr_$ln prism_family_ratio($ff) string "$ln 2"
	    form_entry $scr.ffn_$ln prism_family_n_layers($ff) string "$ln 3"
	    incr ln
	}

	incr ln
	form_frame $d.allnone flat 0 "$ln 0 -cols 2"
	form_button $d.allnone.all "All" "prism_all 1" "$ln 0"
	form_button $d.allnone.none "None" "prism_all 0" "$ln 1"

	form_finish +300+300
	$scr configure -height [expr {[winfo reqheight $scr] + 1}]
    }
}

proc prism_select_parts_doit {} {
    global prism_family_on prism_families prism_parts
    global prism_family_height prism_family_ratio prism_family_n_layers

    set prism_families ""
    foreach ff $prism_parts {
        if {$prism_family_on($ff)} {
            lappend prism_families $ff
            ic_geo_set_prism_family_params $ff \
                height $prism_family_height($ff) \
                ratio $prism_family_ratio($ff) \
                n_layers $prism_family_n_layers($ff)
        }
    }
    ic_geo_set_prism_families $prism_families
    meshPrismDEZ setdirty
    meshAutoDEZ setdirty
    form_done .aie_prism
}

proc onmeshPrismDEZLoad {} {
    global file_name load_only_prism_params

    if $load_only_prism_params return

    set TriQualityList [list laplace height_over_base skewness min_angle max_angle inscribed_ratio]

    set file_name(project_dir) "."
    set file_name(mesh_dir) $file_name(project_dir)
    set file_name(domains_dir) $file_name(project_dir)
    set loadmesh 1
    set PartList [aie_list_parts 1]

    set AllowActiveReload 1
}

proc onmeshPrismDEZAfterLoad {} {
    global file_name load_only_prism_params
    global prism_values prism_params_file

    if !$load_only_prism_params {
	    if {![ic_uns_is_loaded]} {
	        msg ERROR "No Tetra Mesh available"
	        meshPrismDEZ hide
	        return
	    }
	    if {![ic_geo_is_loaded]} {
	        msg ERROR "No Geometry available"
	        meshPrismDEZ hide
	        return
	    }
    }

    meshPrismDEZ setdirty
    set file_name(prism_params) ""
    if {$file_name(tetin) != ""} {
	    set file_name(prism_params) [file root $file_name(tetin)].prism_params
	    if {$prism_params_file != $file_name(prism_params)} {
	        set prism_params_file $file_name(prism_params)
	        if [file exists $prism_params_file] {
		        aie_read_prism_params $prism_params_file
	        }
	    }
    }

    if [ic_geo_is_loaded] {
        foreach {n v} [ic_get_meshing_params prism 0] {
            if {![catch {expr double($v) > 0.0} valid] && $valid} {
                set prism_values($n) $v
            }
        }
    }
}

proc onMeshPrismVolPartModify {dez val} {
    if {$val == "From screen"} {
        mszGlobalDEZ set new_volume [geo_select_part_from_screen 1]
    }
}

proc onMeshPrismSidePartModify {dez val} {
    if {$val == "From screen"} {
        mszGlobalDEZ set side_family [geo_select_part_from_screen 1]
    }
}

proc onMeshPrismTopPartModify {dez val} {
    if {$val == "From screen"} {
        mszGlobalDEZ set top_family [geo_select_part_from_screen 1]
    }
}

proc aie_get_prism_family_params {part {use_def 0}} {
    global prism_values
    set height ""
    set ratio ""
    set n_layers ""
    foreach {p v} [ic_geo_get_prism_family_params $part] {
        set $p $v
    }
    if $use_def {
        if {[catch {expr double($height) == 0.0} zero] || $zero} {
            set height $prism_values(height)
        }
        if {[catch {expr double($ratio) == 0.0} zero] || $zero} {
            set ratio $prism_values(ratio)
        }
        if {[catch {expr int($n_layers) == 0} zero] || $zero} {
            set n_layers $prism_values(layers)
        }
    }
    return [list height $height ratio $ratio n_layers $n_layers]
}

# returns 0 for success, 1 for failure
proc onmeshPrismDEZOK {} {
    global file_name prism_values prism_mesh_loaded
    global prism_families prism_extras options is_win

    if [aie_check_application_running_and_wait] return
    
    if {[meshAutoDEZ get run_tgrid_inflation] == 1} {
    
        if {[ic_geo_get_prism_families] == ""} {
            msg ERROR "Please set the prism parts in the Part Mesh Setup"
            return 1
        }   

        mess "Running Fluent Meshing with Pre Inflation via the FieldMesher-Python-ExtensionModule...\n" blue

        if {[ic_count_elements 3d] == 0 && ![llength [ic_geo_get_objects material]]} {
            mess "Pre Inflation (Fluent Meshing) Error: No volume elements found and no material point found. Pre Inflation needs either a volume input\
            mesh or a material point\n" red
            return
        }
        
        aie_get_global_mesh_params cur_mesh_params
        foreach n {fillholes meshall floodfill verbose bgmesh tgrid_af} {
            set $n $cur_mesh_params(tetra_$n)
        }
        
        if {[meshAutoDEZ get prism_input] == "1"} {
            set meshIN $meshFile
        } else {
            set meshIN $file_name(domain)
        }
        if {($meshIN == "") || ![file exists $meshIN] || [ic_uns_is_modified]} {
            set temp_uns ___temp[pid]___.uns
            ic_save_unstruct $temp_uns 1 {} {} 
            set meshIN $temp_uns
        } else {
            set temp_uns ""
        }
        
        set meshOUT [file join $file_name(project_dir) prismPre.uns]
        set meshBACKUP ""
        if [file exists $meshOUT] {
            set meshBACKUP $meshOUT_[pid]_bak
            cmd_mv $meshOUT $meshBACKUP
            mess "Mesh file $meshOUT already exists! Moved to $meshBACKUP\n"
        }
        
        if $is_win {
            set cmd [list ic_run_fieldmesher [win_shortname $meshIN] [win_shortname [file dirname $meshOUT]]/[file tail $meshOUT]]
        } else {
            set cmd [list ic_run_fieldmesher $meshIN $meshOUT]
        }
        
        set temp_tin ___temp[pid]___.tin
        if {($temp_tin != "" && [ic_geo_is_loaded])} {
            ic_save_tetin $temp_tin
            append cmd " tetin $temp_tin"
        }
        append cmd " tgrid_prism 1"
        if [mszGlobalDEZ get tgrid_n_ortho_layers] {
            append cmd " tgrid_n_ortho_layers [mszGlobalDEZ get tgrid_n_ortho_layers]"
        }
        if [mszGlobalDEZ get tgrid_fix_first_layer] {
            append cmd " tgrid_fix_first_layer 1"
        }
        set tgrid_gap_factor [mszGlobalDEZ get tgrid_gap_factor]
        if {$tgrid_gap_factor >= 0.0 && $tgrid_gap_factor <= 2.0} {
            append cmd " tgrid_gap_factor $tgrid_gap_factor"
        }
        if [mszGlobalDEZ get tgrid_enhance_norm_comp] {
            append cmd " tgrid_enhance_norm_comp 1"
        }
        if [mszGlobalDEZ get tgrid_enhance_offset_comp] {
            append cmd " tgrid_enhance_offset_comp 1"
        }
        set tgrid_smoothing_level2 1
        switch [mszGlobalDEZ get tgrid_smoothing_level] {
            Low { set tgrid_smoothing_level2 0 }
            Medium { set tgrid_smoothing_level2 1 }
            High { set tgrid_smoothing_level2 2 }
        }
        append cmd " tgrid_smoothing_level $tgrid_smoothing_level2"
        set tgrid_max_cap_skew [mszGlobalDEZ get tgrid_max_cap_skew]
        if {$tgrid_max_cap_skew >= 0.0 && $tgrid_max_cap_skew <= 1.0} {
            append cmd " tgrid_max_cap_skew $tgrid_max_cap_skew"
        }
        set tgrid_max_cell_skew [mszGlobalDEZ get tgrid_max_cell_skew]
        if {$tgrid_max_cell_skew >= 0.0 && $tgrid_max_cell_skew <= 1.0} {
            append cmd " tgrid_max_cell_skew $tgrid_max_cell_skew"
        }
        set tgrid_last_layer_aspect [mszGlobalDEZ get tgrid_last_layer_aspect]
        if {([string is double -strict $tgrid_last_layer_aspect] || [string is integer -strict $tgrid_last_layer_aspect]) && \
            $tgrid_last_layer_aspect > 0} {
            append cmd " tgrid_last_layer_aspect $tgrid_last_layer_aspect"
        }
        append cmd " use_fluent 1"
        append cmd " show_progress 1"
        set error_subset prism_errors
        append cmd " verbose $verbose"
        set expansion_factor $cur_mesh_params(tetra_expansion_factor)
        if {$expansion_factor != ""} {
            append cmd " tetexpand $expansion_factor"
        }
        
        if {[meshAutoDEZ get frozenMeshVolParts] != ""} {
            append cmd " tgrid_frozen_parts [list [meshAutoDEZ get frozenMeshVolParts]]"
        }
        if {[meshAutoDEZ get run_tgrid_hexacore] == 1} {
            append cmd " tgrid_hexacore 1"
        }
        if {[meshAutoDEZ get run_tgrid_interactive] == 1} {
            append cmd " tgrid_interactive 1"
        }
        
        set ret 1
        if {[eval $cmd] && [file exists $meshOUT]} {
            if $loadmesh {
	            if [ic_uns_is_loaded] {
	                aie_close_Mesh 0
	            }
	            set file_name(domain) $meshOUT
	            mess "Loading $file_name(domain)\n"
	            aie_open_Mesh 0
	            aie_afterStuffLoaded 0
	            set prism_mesh_loaded 1
	            aie_updateMeshVis
	            ic_rm $meshOUT
            } else {
                mess "Created prism mesh is saved in file: $meshOUT\n" blue
            }
            set ret 0
        } else {
            mess "No prism mesh generated!\n" red
            if {$meshBACKUP != "" && [file exists $meshBACKUP]} {
                cmd_mv $meshBACKUP $meshOUT 
                mess "Backed up mesh $meshBACKUP moved back to $meshOUT\n"
            }
            return $ret
        }
        if {$temp_tin != ""} { ic_rm $temp_tin }
        if {$temp_uns != ""} { ic_rm $temp_uns }
        
        if {[meshAutoDEZ get loadmesh] != 1} { return $ret }
        
        mess "Create nodes and bars from topology...\n"
        set meshtopoang 27.0
        if ![repairGeomDEZ isbuilt] {
            repairGeomDEZ build
        }
        set geomtopoang [repairGeomDEZ get topoang]
        if {$geomtopoang > 0.0 && $geomtopoang < 90.0} {
            set meshtopoang [expr 0.9 * $geomtopoang]
        }
        set newfam "__TEMP_PTS_CRVS__"
        ic_uns_build_mesh_topo all -new_element_family $newfam -create_bars_family_intersection
        ic_uns_build_mesh_topo all -angle [expr 180 - $meshtopoang] -new_element_family $newfam -uncovered_element_family $newfam
        mess "Update node and bar associations...\n"
        set fams [ic_geo_list_families]
        set node_line_map [ic_uns_subset_create_family_type $fams {NODE LINE_2} 1 0 0]
        ic_uns_set_projected_family $node_line_map
        ic_uns_subset_delete $node_line_map
        mess "Remove nodes/lines that are not on points/curves...\n"
        ic_delete_elements family $newfam
        
        return $ret
    }
    
    if [catch aie_check_prism_params msg] {
	    msg ERROR $msg
	    return 1
    }

    if {$file_name(tetin) == "" && [ic_geo_is_loaded] && [meshAutoDEZ get prism_input] == "0"} {
        switch -- [tk_dialog .savegeom "Save Geometry" "Do you want to save the current Geometry?" "" -1 Yes No Cancel] {
	        0 { aie_save_geom }
	        1 { mess "Running prism without geometry\n" }
	        2 {
	            mess "Canceled by user\n" red
	            return 1
	        }
	    }
    }
    
    meshPrismDEZ setdirty
    
    set prism_families [ic_geo_get_prism_families]
    if {$prism_families == ""}  {
	    msg ERROR "Please define prism meshing parts"
	    return 1
    }

    if {[ic_uns_list_families 3] == ""} {
	    if {$prism_values(blayer_2d) == 0 && $prism_values(new_volume) == ""} {
	        mess "No part specified for volume elements\n" red
	        set vol_fam [lindex [ic_list_volume_families] 0]
	        if {$vol_fam == ""} {
		        set vol_fam CREATED_MATERIAL
		        set vol_fam [aie_new_part $vol_fam]
	        }
	        set prism_values(new_volume) $vol_fam
	        mess "Setting Part: $vol_fam for new volume elements\n" red
	    }
    }

    set surface_file \"$file_name(tetin)\"
    set input_file   \"$file_name(domain)\"
    set output_file  prism.uns
    set use_v10 $prism_extras(use_prism_v10)
    set temp_tin ""
    set temp_uns ""
    
    if {$file_name(tetin) == ""} {
        set surface_file ""
    } elseif {[ic_geo_is_modified] || ($use_v10) } {
        set temp_tin [cmd_tempfile temp_prism .tin]
        ic_save_tetin $temp_tin 0 0 "" "" $use_v10
        set surface_file $temp_tin
    }
    if {$file_name(domain) == "" || [ic_uns_is_modified]} {
        set temp_uns [cmd_tempfile temp_prism .uns]
        ic_save_unstruct $temp_uns
        set input_file $temp_uns
    } else {
	    if {$file_name(domain) == $output_file} {
	        cmd_mv $output_file prism_input.uns
	        set input_file prism_input.uns
	    }
    }
    ic_rm $output_file

    foreach i {new_volume side_family top_family} { set $i $prism_values($i) }

    if {$new_volume != ""} {
	    set new_volume [aie_new_part $new_volume]
        set prism_values(new_volume) $new_volume
    }
    if {$side_family != ""} {
	    set side_family [aie_new_part $side_family]
        set prism_values(side_family) $side_family
    }
    if {$top_family != ""} {
	    set top_family [aie_new_part $top_family]
        set prism_values(top_family) $top_family
    }

    if {$prism_values(init_dir_from_prev) != "" && $prism_values(init_dir_from_prev)} {
	    if {$smoothing_steps > 0} {
	        mess "Warning: smoothing_steps set to 0 for fixed marching direction\n"
	        set smoothing_steps 0
            set prism_values(smoothing_steps) 0
	    }
	    if {$first_layer_smoothing_steps <= 0} {
	        mess "Warning: first layer smoothing steps set to 1 for fixed marching direction\n"
	        set first_layer_smoothing_steps 1
            set prism_values(first_layer_smoothing_steps) 1
	    }
    }

    # dont write prism extra values if defaults

    aie_prism_extra_params_defaults
    foreach i [array names prism_extras] {
        if {![info exists prism_values($i)] ||
            $prism_values($i) == $prism_extras($i)} {
            set prism_values($i) ""
        }
    }

    if {$file_name(tetin) == ""} {
        set file_name(prism_params) [file root $file_name(domain)].prism_params
    } else {
        set file_name(prism_params) [file root $file_name(tetin)].prism_params
    }

    set ifile $file_name(prism_params)
    set logfile prism_cmd.log

    if {$is_win} {
        # need to create prism_params file to get shortname
        if {![file exists $ifile]} {
            close [open $ifile w]
        }
        foreach f {surface_file input_file ifile} {
            set fname [set $f]
            if {[llength $fname] > 1} {
                set $f [win_shortname $fname]
            }
        }
    }

    if {$surface_file == ""} {
        set cmd "ic_run_prism \"\" $input_file $output_file"
    } else {
        set cmd "ic_run_prism $surface_file $input_file $output_file"
    }
    append cmd " params $ifile log $logfile"
 
    if {$options(n_processors) != ""} {
        append cmd " n_processors $options(n_processors)"
    }
    
    foreach {n v} {into_orphan 0 init_dir_from_prev 0 smoothing_steps 12 \
        n_triangle_smoothing_steps 5 n_tetra_smoothing_steps 10 \
        first_layer_smoothing_steps 0 auto_reduction 0 verbosity_level 1 \
        delete_base_triangles 0 delete_standalone 1 do_checks 0 \
        do_not_allow_sticking 0 intermediate_write 1 incremental_write 0 \
        min_smoothing_steps 6 refine_prism_boundary 1 stair_step 1 stop_columns 1 \
        blayer_2d 0 use_prism_v10 0 use_existing_quad_layers 0 fillet 0.0 \
        ortho_weight 0.5 max_prism_angle 178.2 min_prism_quality 0.000001 \
        max_aspect_ratio 0.0 prism_height_limit 0.0 ratio_multiplier 1.0 \
        max_jump_factor 5.0 max_size_ratio 0.0 min_smoothing_val 0.1 \
        ratio_max 100.0 tetra_smooth_limit 0.3 interpolate_heights 0} {
        if {$prism_values($n) != "" && ![catch {\
            expr abs($v - $prism_values($n)) > 0} diff] && $diff} {
            append cmd " $n $prism_values($n)"
        }
    }
    foreach {n v} {new_volume "" side_family "" top_family "" triangle_quality inscribed_area} {
        if {$prism_values($n) != "" && $prism_values($n) != $v} {
            append cmd " $n $prism_values($n)"
        }
    }
    foreach ff $prism_families {
        set family $ff
        foreach {p v} [ic_geo_get_prism_family_params $ff] {
            if {$p == "law"} {
    	        switch -- "$v" {
    	            0 { set v exponential }
    	            1 { set v linear }
    	            3 { set v wb-exponential }
    	            default { continue }
    	       }
		       lappend family $p $v
            } else {
                if {![catch {expr double($v) > 0.0} ok] && $ok} {
                    lappend family $p $v
                }
            }
        }
        append cmd " family [list $family]"
    }

    busy reset
    if [catch $cmd result] {
        mess "Error: $result\n" red
        set result 0
    }

    if {$temp_tin != ""} {ic_rm $temp_tin}
    if {$temp_uns != ""} {ic_rm $temp_uns}

    if {!$result} {return 1}

    if ![file exists $output_file] {
	    set err_msg ""
	    if [file exists $logfile] {
	        set err "must specify a volume family name"
	        set fp [open $logfile]
	        while {[gets $fp line] >= 0} {
		        if {[regexp $err $line] > 0} {
		            set err_msg "Must specify the volume part name in Global Prism Mesh Params panel"
		            break
		        }
	        }
	        close $fp
	    }

	    if {$err_msg != ""} {
	        msg ERROR $err_msg
	    } else {
	        mess "Error: Prism mesher failed to create mesh\n" red
	    }
	    return 1
    }

    if $loadmesh {
	    if [ic_uns_is_loaded] {
	        aie_close_Mesh 0
	    }
	    set file_name(domain) $output_file
	    mess "Loading $file_name(domain)\n" blue
	    aie_open_Mesh 0
	    aie_afterStuffLoaded 0
	    set prism_mesh_loaded 1
	    aie_updateMeshVis
    }
    return 0
}

proc aie_read_prism_params {params_file {load 0}} {
    global file_name prism_families prism_parts
    global prism_family_on prism_family_height prism_family_ratio
    global prism_family_n_layers prism_values prism_extras

    if {[catch {open $params_file r} fp]} return
    if $load { mess "Reading prism parameter file $params_file\n" }

    if ![mszGlobalDEZ isbuilt] {
        mszGlobalDEZ build
    }
    if ![meshPrismDEZ isbuilt] {
        meshPrismDEZ build
    }

    set prism_parts ""
    set parts [aie_list_parts 0]
    foreach name $parts {
	    if {[lsearch $parts $name/*] < 0} {
	        lappend prism_parts $name
	        set prism_family_family 0
	        set prism_family_part 0
	    }
    }
    aie_prism_extra_params_defaults
    foreach i [array names prism_extras] {
        set prism_values($i) $prism_extras($i)
    }
    set nfams [llength [ic_geo_get_prism_families]]
    set pfams ""

    while { [gets $fp line] >= 0 } {
        set var [lindex $line 0]
        set val [lrange $line 1 end]
        if {$val == "" || $val == "on"} {
            set val 1
        }
        if {$val == "off"} {set val 0}
        if {$var == "family"} {
            if {!$nfams || $load} {
                if {[llength $val] > 1} {
                    set f [lindex $val 0]
                    set part [lindex [split $f :] 0]
                    set prism_family_on($part) 1
                    set pv [lrange $val 1 end]
                    foreach {p v} $pv {
                        set prism_family_${p}($f) $v
                        set prism_family_${p}($part) $v
                    }
                } else {
                    set prism_family_on($val) 1
                    set part [lindex [split $val :] 0]
                    set prism_family_on($part) 1
                    foreach p {height ratio n_layers} {
                        set prism_family_${p}($val) ""
                        set prism_family_${p}($part) ""
                    }
                    if {[lsearch $pfams $val] < 0} { lappend pfams $val }
                }
                if {[lsearch $pfams $part] < 0} { lappend pfams $part }
            }
            continue
        }

        if {![catch {meshPrismDEZ set $var $val}] || ![catch {mszGlobalDEZ set $var $val}] ||
             [info exists prism_extras($var)]} {
            set prism_values($var) $val
        }
    }
    close $fp
    mszGlobalDEZ setdirty
    meshPrismDEZ setdirty

    if [ic_geo_is_loaded] {
        ic_set_meshing_params prism 0 \
            law $prism_values(law) \
            layers $prism_values(layers) \
            height $prism_values(height) \
            ratio $prism_values(ratio) \
            total_height $prism_values(total_height) \
            prism_height_limit $prism_values(prism_height_limit) \
            max_prism_height_ratio $prism_values(max_aspect_ratio) \
            stair_step $prism_values(stair_step) \
            auto_reduction $prism_values(auto_reduction) \
            min_prism_quality $prism_values(min_prism_quality) \
            max_prism_angle $prism_values(max_prism_angle) \
            fillet $prism_values(fillet) \
            tetra_smooth_limit $prism_values(tetra_smooth_limit) \
            n_tetra_smoothing_steps $prism_values(n_tetra_smoothing_steps) \
            n_triangle_smoothing_steps $prism_values(n_triangle_smoothing_steps)
        if {(!$nfams || $load) && $pfams != ""} {
            foreach fam $pfams {
                set params ""
                if {[info exists prism_family_height($fam)] && \
                    $prism_family_height($fam) != ""} {
                    lappend params height $prism_family_height($fam)
                }
                if {[info exists prism_family_ratio($fam)] && \
                    $prism_family_ratio($fam) != ""} {
                    lappend params ratio $prism_family_ratio($fam)
                }
                if {[info exists prism_family_n_layers($fam)] && \
                    $prism_family_n_layers($fam) != ""} {
                    lappend params n_layers $prism_family_n_layers($fam)
                }
                if {$params != ""} {
                    eval ic_geo_set_prism_family_params $fam $params
                }
            }
            ic_geo_set_prism_families $pfams
        }
    }
}

proc aie_check_prism_params {{mesher Tetra}} {
    global prism_values prism_family_on

    # check for global settings - only with Advancing Front
    # since Tetra prism will work without anything set
    if {$mesher == "Advancing" || $mesher == "afmesh"} {
        set cnt 0
        if {[info exists prism_values(law)] &&
            $prism_values(law) != ""} {
            foreach i {height total_height layers ratio} {
                if {[info exists prism_values($i)] &&
                    $prism_values($i) != ""} {
                    incr cnt
                }
            }
        }
    } else {
        set cnt 3
    }

    # check for prism families
    set prism_families [ic_geo_get_prism_families]
    set nfam [llength $prism_families]

    if {$cnt < 3} {
        set msg "Please set up the global prism meshing parameters"
        if {!$nfam} {append msg "\nand select the prism parts"}
        return -code error $msg
    }
    if {!$nfam} {
        return -code error "Please set the prism parts in the Part Mesh Setup"
    }

    # check global prism settings
    set law $prism_values(law)
    if [catch {prism_check_params law $law height $prism_values(height) \
        ratio $prism_values(ratio) layers $prism_values(layers)} msg] {
        return -code error "global settings : $msg"
    }

    # check the prism family parameters
    foreach ff $prism_families {
        array set params [aie_get_prism_family_params $ff 1]
        if [catch {prism_check_params law $law height $params(height) \
            ratio $params(ratio) layers $params(n_layers)} msg] {
            return -code error "$part : $msg"
        }
    }
}

proc aie_write_prism_params {} {
    global file_name prism_values par_type prism_mesh_loaded
    global prism_family_on prism_families prism_parts
    global prism_family_height prism_family_ratio prism_family_n_layers
    global prism_extra_name prism_extra_value
    global prism_extras prism_extra_types

    set prism_families ""
    foreach part [ic_geo_list_parts] {
	    if {([info exists prism_family_on($part)]) && ($prism_family_on($part) == 1)} {
	        foreach f [ic_geo_list_families_in_part $part] {
		        lappend prism_families $f
		        set prism_family_on($f) 1
		        set prism_family_height($f) $prism_family_height($part)
		        set prism_family_ratio($f) $prism_family_ratio($part)
		        set prism_family_n_layers($f) $prism_family_n_layers($part)
	        }
	    }
    }
    if {$prism_families == ""}  {
	    msg ERROR "Please define prism meshing parts"
	    return ""
    }

    set prism_values(surface_file) \"$file_name(tetin)\"
    set prism_values(input_file)   \"$file_name(domain)\"
    set prism_values(output_file)  prism.uns
    if {$prism_values(input_file) == $prism_values(output_file)} {
        set prism_values(input_file) prism_input.uns
    }

    if {$prism_values(init_dir_from_prev) != ""} {
	if {$prism_values(smoothing_steps) == "" ||
            $prism_values(smoothing_steps)  > 0} {
            set prism_values(smoothing_steps) 0
        }
	if {$prism_values(first_layer_smoothing_steps) == "" ||
            $prism_values(first_layer_smoothing_steps) <= 0} {
            set prism_values(first_layer_smoothing_steps) 1
	}
    }
    foreach i [array names prism_values] {
        set par_type($i) 1
    }

    foreach i {init_dir_from_prev into_orphan do_not_allow_sticking \
        graphics do_checks print_memory_usage delete_base_triangles} {
        set par_type($i) logical
    }

    # dont write prism extra values if defaults

    aie_prism_extra_params_defaults
    foreach i [array names prism_extras] {
        if {[info exists prism_values($i)] &&
            $prism_values($i) == $prism_extras($i)} {
            set prism_values($i) ""
        }
    }

    # extra args
    set prism_extra_name [mszGlobalDEZ get prism_extra_name]
    set prism_extra_value [mszGlobalDEZ get prism_extra_value]

    if {$prism_parts == ""} {
        set basename $file_name(settings)
    } else {
        set basename $file_name(tetin)
    }
    if {$basename == ""} {set basename untitled}
    set ifile [file root $basename].prism_params
    write_prism_params $ifile
    return $ifile
}

proc aie_prism_compute_params {} {
    global prism_values cprism_values

    set args ""
    foreach var {height ratio layers total_height law} {
	    set prism_values($var) [mszGlobalDEZ get $var]
	    if {$prism_values($var) != ""} {
            lappend args $var $prism_values($var)
	    }
    }
    if [catch {eval prism_compute_params $args} msg] {
        msg ERROR $msg
    } else {
        set var [lindex $msg 0]
        set val [lindex $msg 1]
        set prism_values($var) $val
        mszGlobalDEZ set $var $val
    }
}

## If global max mesh size is set to 0 or "" set to size based off bbox
## args are type; type can be quad or tetra

proc aie_autosizing {type {chkmax 0}} {
    global autosize_is_set autosize_type

    if ![ic_geo_is_loaded] { return 0 }

    # If Global Max Size is set to 0, we should run autosizing

    set gmax 0
    foreach {u v} [ ic_get_meshing_params global 0 ] {
        if {$u == "gmax"} {
            if {$v != ""} {set gmax $v}
            break
        }
    }

    # if all mesh sizes are > 1/10 the bounding box diagonal, warn user

    if [expr $gmax >= 0.0] {
        set autosize_is_set 0
        if {[expr $gmax > 0.0] && (!$chkmax)} { return 0 }
        # max_size is 0.1 of the diagonal
        set bbox [ic_geo_model_bounding_box ]
        set dist [eval ic_vcalc distance $bbox]
	    set max_size [expr 0.1 * $dist]
        if [expr $gmax > 0.0 && $gmax < $max_size] {return 0}
        foreach s [ic_geo_get_objects surface ""] {
	        set size [lindex [ic_get_meshing_params surface $s] 1]
            if [expr $size > 0.0 && $size < $max_size] {
		        return 0
	        }
        }

	    foreach c [ic_geo_get_objects curve ""] {
	        set size [lindex [ic_get_meshing_params curve $c] 1]
            if [expr $size > 0.0 && $size < $max_size] {
		        return 0
	        }
        }
        set opt [tk_dialog .autosize "Mesh Size" \
           "The mesh size appears to be inadequate to represent the geometry.\
            Do you want to run with autosizing?" "" 0 "Yes" "No" "Cancel"]
        if {$opt == -1} { if [winfo exists .autosize] { top_destroy .autosize; return 1 } }
        if {$opt == 2} { return 1 }
        if {$opt == 1} {
            mess "Warning: mesh size may be inadequate to represent the geometry\n" red
            return 0
        }
    }
    set autosize_is_set 1

    switch $type {
        tetra - mapped - Shrinkwrap {
	        set autosize_type [list tetra [ic_geo_is_modified] $gmax]
	        set default_size [expr [ic_geo_default_topo_tolerance] * 50 / [ic_geo_get_ref_size]]
	        set new_size $default_size

	        # if no surfaces have sizes assigned, use default size, else use largest size assigned to surfaces
	        foreach s [ic_geo_get_objects surface ""] {
		        set size [lindex [ic_get_meshing_params surface $s] 1]
		        if {$size < 1e-38} {
		            break
		        } elseif {$size > $new_size} {
		            set new_size $size
		        }
	        }

	        mess "Warning: Using automatic sizing; \n" red
	        if {$new_size == $default_size} {
		        if {$type == "Shrinkwrap"} {
		            set bbox [ic_geo_bounding_box all]
		            if {$bbox != ""} {
			            set dxyz [ic_vcalc diff [lindex $bbox 0] [lindex $bbox 1]]
			            set lmax 0.0
			            foreach l $dxyz {
			                if {$l > $lmax} {set lmax $l}
			            }
			            set new_size [format %3g [expr 0.75 * $lmax / 64.0]]
		            }
		            mess "Setting global max size based off bounding box diagonal * 0.015625\n"
		        } else {
		            mess "Setting global max size based off bounding box diagonal * 0.025 \n"
		        }
	        } else {
		        mess "Setting global max size based off largest mesh size on surface $new_size \n"
	        }
	        mess "using $new_size for global max size\n"
	        ic_set_meshing_params global 0 gmax $new_size
	    }
	    quad {
	        set autosize_type [list quad [ic_geo_is_modified] $gmax]
	        set default_size [expr [ic_geo_default_topo_tolerance] * 25 / [ic_geo_get_ref_size]]
	        set new_size $default_size

	        foreach c [ic_geo_get_objects curve ""] {
		        set size [lindex [ic_get_meshing_params curve $c] 1]
		        if {$size < 1e-38} {
		            break
		        } elseif {$size > $new_size} {
		            set new_size $size
		        }
	        }
	        mess "Warning: Using automatic sizing; \n" red
	        if {$new_size == $default_size} {
		        mess "Setting global max size based off bounding box diagonal * 0.0125 \n"
	        } else {
		        mess "Setting global max size based off largest mesh size on surface $new_size \n"
	        }
	        mess "using $new_size for global max size\n"
	        ic_set_meshing_params global 0 gmax $new_size
	    }
	    default {
	        mess "type $type is not supported\n"
	        set autosize_is_set 0
	    }
    }
    return 0
}

## This procedure removes autosizing if set
## args are type; type can be quad or tetra

proc aie_no_autosizing {} {
    global autosize_is_set autosize_type
    if {![info exists autosize_is_set] || !$autosize_is_set} return
    switch [lindex $autosize_type 0] {
	tetra {
	    ic_set_meshing_params global 0 gmax [lindex $autosize_type 2]
	}
	quad {
	    ic_set_meshing_params global 0 gmax [lindex $autosize_type 2]
	}
	default {
	    mess "type $type is not supported\n"
	}
    }
    ic_geo_set_modified [lindex $autosize_type 1]
    set autosize_is_set 0
}


## This looks at geometry and sets up sizes if no sizes are assigned
##  args are type,
##  type is what mesher to use, currently can be quad or tetra
proc aie_autosizing_old {type} {
    global autosize_is_set
    switch $type {
	tetra {
	    set SETUM 1
	    foreach s [ic_geo_get_objects surface ""] {
		set size [lindex [ic_get_meshing_params surface $s] 1]
		if {$size > 1e-020} {
		    set SETUM 0
		    break
		}
	    }

	    # skip auto sizing if natural size is set. User may want to run
	    # only with natural size.
	    set vals [ ic_get_meshing_params global 0 ]
	    array set params $vals
	    if {$params(gnat) != 0} {
		set SETUM 0
	    }
            # skip if default size is greater than or equal to global size
	    set default_size [expr [ic_geo_default_topo_tolerance] * 50]
            if {$params(gmax) > 0 && $default_size >= $params(gmax)} {
                 set SETUM 0
            }

	    if $SETUM {
                set autosize_is_set [list tetra [ic_geo_is_modified]]
#		mess "Warning: Running tetra with automatic sizing\n" red
		mess "Warning: Using automatic sizing\n" red
		foreach s [ic_geo_get_objects surface ""] {
		    ic_set_meshing_params surface $s emax $default_size
		}
	    }
	}
	quad {
	    set SETUM 1
	    foreach c [ic_geo_get_objects curve ""] {
		set size [lindex [ic_get_meshing_params curve $c] 1]
		if {$size > 1e-020} {
		    set SETUM 0
		    break
		}
	    }
	    if $SETUM {
                set autosize_is_set [list quad [ic_geo_is_modified]]
		#Simon wants that if any surfaces have sizes the attached curves should get this size.
		set SETOFFSURFS 0
		foreach s [ic_geo_get_objects surface ""] {
		    set size [lindex [ic_get_meshing_params surface $s] 1]
		    if {$size > 1e-020} {
			set SETOFFSURFS 1
			break
		    }
		}

		set default_size [expr [ic_geo_default_topo_tolerance] * 25]
		foreach c [ic_geo_get_objects curve ""] {
		    if $SETOFFSURFS {
			set size $default_size
			foreach s [ic_geo_incident curve $c] {
			    set nsize [lindex [ic_get_meshing_params surface $s] 1]
			    if {($nsize > 1e-020) && ($nsize < $size)} {
				set size $nsize
			    }
			}
			ic_set_meshing_params curve $c emax $size
		    } else {
			ic_set_meshing_params curve $c emax $default_size
		    }
		}
	    }
	}
	default {
	    mess "type $type is not supported\n"
            set SETUM 0
	}
    }
    return $SETUM
}

proc aie_no_autosizing_old {} {
    global autosize_is_set
    if {![info exists autosize_is_set] || $autosize_is_set == ""} return
    switch [lindex $autosize_is_set 0] {
	tetra {
	    foreach s [ic_geo_get_objects surface ""] {
		ic_set_meshing_params surface $s emax 0
	    }
	}
	quad {
	    foreach c [ic_geo_get_objects curve ""] {
		ic_set_meshing_params curve $c emax 0
            }
	}
	default {
	    mess "type $type is not supported\n"
	}
    }
    ic_geo_set_modified [lindex $autosize_is_set 1]
    unset autosize_is_set
}

proc aie_check_application_running {} {
    if [interp exists batch_interp] {
        return [batch_interp eval {
	    global application_running
            if [info exists application_running] {
	        set mess "An application ($application_running) is currently running."
	        set ret [tk_dialog .tivc "Terminate" $mess "" 0 \
                    "Wait for it to finish" "Terminate it"]
            if {$ret == -1} { if [winfo exists .tivc] { top_destroy .tivc; return 1 } }
	        if { !$ret } {return 1}
	        catch {application_terminated 0}
            }
            return 0
        }]
    }
    return 0
}

proc aie_check_application_running_and_wait {} {
    if [interp exists batch_interp] {
        return [batch_interp eval {
	    global application_running
            if [info exists application_running] {
	            set mess "An application ($application_running) is currently running."
	            set ret [tk_dialog .tivc "Wait" $mess "" 0 "Wait for it to finish"]
                if {$ret == -1} { if [winfo exists .tivc] { top_destroy .tivc; return 1 } }
                return 1
            }
            return 0
        }]
    }
    return 0
}

proc onmeshAutoDEZLoad {} {
    if ![info exists meshAutoWhatVal] {
        set meshAutoWhatVal 1
        set volmesh_type 0
        set tetra_method 0
        set tetra_input 0
        set prism_input 0
        set loadFlag 1
        set loadmesh 1
        set use_fluent_executable 1
        set run_inflation 0
        set run_prism 0
        set run_tgrid_inflation 0
        set run_tgrid_hexacore 0
        set run_tgrid_interactive 0
		set frozenMeshVolParts ""
    }
    if {$volmesh_type == 2 } {
        meshAutoDEZ onmeshCartLoad
    }
    meshAutoDEZ setdirty
    set PartList [aie_list_parts 1]
    lappend PartList inherited
    set AllowActiveReload 1
}

proc onmeshAutoDEZAfterLoad {} {
    global env surfaceMeshArray tetra_global_tet_type mesh_global_vol_type
    global cart_global_cast_method beta_mode

    if ![info exists meshAutoWhatVal] { set meshAutoWhatVal 1 }
 
    if [info exists ::tetra_global_tet_type] {
        set tetra_method $::tetra_global_tet_type
    }
    if [info exists ::mesh_global_vol_type] {
        set volmesh_type $::mesh_global_vol_type
    }
    if [info exists ::cart_global_cast_method] {
        if {$::cart_global_cast_method <=1} {
            set cart_method $::cart_global_cast_method
        }
    }

    ::AIEnv::GUIManagement::ToggleGrey meshAutoVolume 0

    meshAutoDEZ aie_set_automesh_input
    meshAutoDEZ onmeshAutoSurfLoad
    meshAutoDEZ onmeshCartInit
    
    if {![info exists env(AI_ENV_TETRA)] && ![info exists env(AI_ENV_HEXA)] && ![info exists env(AI_ENV_BFCART)] && ![info exists env(AI_ENV_GLOBAL)]} {
       ::AIEnv::GUIManagement::ToggleGrey meshAutoVolume 1
    }
    if {![info exists env(AI_ENV_TETRA)]} {
       ::AIEnv::GUIManagement::ToggleGrey meshTetraMixed 1
    }
    if {[info exists env(AI_ENV_ACADEMIC)]} {
       ::AIEnv::GUIManagement::ToggleGrey meshTetraDel 1
    }
    if {[info exists env(AI_ENV_ACADEMIC)]} {
       ::AIEnv::GUIManagement::ToggleGrey meshTetraAdv 1
    }
    if {[info exists env(AI_ENV_ACADEMIC)]} {
       ::AIEnv::GUIManagement::ToggleGrey meshTetraTGrid 1
    }
    if {![info exists env(AI_ENV_HEXA)] || [info exists env(AI_ENV_ACADEMIC)]} {
       ::AIEnv::GUIManagement::ToggleGrey meshHybrid 1
    }
    if {(![info exists env(AI_ENV_BFCART)] && ![info exists env(AI_ENV_GLOBAL)]) || [info exists env(AI_ENV_ACADEMIC)]} {
       ::AIEnv::GUIManagement::ToggleGrey meshCart 1
       if $beta_mode { ::AIEnv::GUIManagement::ToggleGrey meshCartGlobal 1 }
    }
    if {![info exists env(AI_ENV_BFCART)] || [info exists env(AI_ENV_ACADEMIC)]} {
       ::AIEnv::GUIManagement::ToggleGrey meshCartBF 1
    }
    if {![info exists env(AI_ENV_PRISM)]} {
       ::AIEnv::GUIManagement::ToggleGrey meshAutoPrism 1
    }
       
    if [info exists env(AI_ENV_PRISM)] {
        if {$run_inflation == 0} {
            ::AIEnv::GUIManagement::ToggleGrey meshPrismLayersPrePost 1
            set run_prism 0
            set run_tgrid_inflation 0
        } else {
            ::AIEnv::GUIManagement::ToggleGrey meshPrismLayersPrePost 0
            if {$run_pre_or_post_inflation == "pre"} {
                set run_prism 0
                set run_tgrid_inflation 1
            } else {
                set run_prism 1
                set run_tgrid_inflation 0
            }
        }
        if {[trace vinfo run_inflation] != ""} {
            trace vdelete run_inflation w aie_wb_trace_tgrid_inflation_state
        }
        trace variable run_inflation w aie_wb_trace_tgrid_inflation_state
        if {[trace vinfo run_pre_or_post_inflation] != ""} {
            trace vdelete run_pre_or_post_inflation w aie_wb_trace_tgrid_inflation_state
        }
        trace variable run_pre_or_post_inflation w aie_wb_trace_tgrid_inflation_state
        if {[trace vinfo run_prism] != ""} {
            trace vdelete run_prism w aie_wb_trace_tgrid_inflation_state
        }
        trace variable run_prism w aie_wb_trace_tgrid_inflation_state
    }  
    
    if ![mszGlobalDEZ isbuilt] {
        mszGlobalDEZ build
    }
    
    if [info exists env(AI_ENV_PRISM)] {
        if {$run_pre_or_post_inflation == "pre"} {
            meshAutoDEZ set run_pre_or_post_inflation pre
        } else {
            meshAutoDEZ set run_pre_or_post_inflation post
        }
    }
}

proc aie_wb_trace_tgrid_inflation_state {{name ""} {element ""} {op ""}} {
    global env 

    if ![info exists env(AI_ENV_PRISM)] return
    if {$name == ""} {
        if {[meshAutoDEZ get run_prism] == 0 && [meshAutoDEZ get run_tgrid_inflation] == 0} {
            meshAutoDEZ set run_inflation 0
            ::AIEnv::GUIManagement::ToggleGrey meshPrismLayersPrePost 1
        } else {
            meshAutoDEZ set run_inflation 1
            ::AIEnv::GUIManagement::ToggleGrey meshPrismLayersPrePost 0
        }
        if {[meshAutoDEZ get run_pre_or_post_inflation] == "pre"} {
            ::AIEnv::GUIManagement::ToggleGrey meshPrismTGridTGHC 0
            ::AIEnv::GUIManagement::ToggleGrey meshPrismTGridTGIN 0
        } else {
            ::AIEnv::GUIManagement::ToggleGrey meshPrismTGridTGHC 1
            ::AIEnv::GUIManagement::ToggleGrey meshPrismTGridTGIN 1
            meshAutoDEZ set run_tgrid_hexacore 0
            meshAutoDEZ set run_tgrid_interactive 0
        }
        return
    }
    if {$name != "run_inflation" && [lindex [split $name ::] end] == "run_inflation"} {
        if {[meshAutoDEZ get run_inflation] == 0} {
            if {[meshAutoDEZ get run_prism] != 0} { meshAutoDEZ set run_prism 0 }
            if {[meshAutoDEZ get run_tgrid_inflation] != 0} { meshAutoDEZ set run_tgrid_inflation 0 }
            ::AIEnv::GUIManagement::ToggleGrey meshPrismLayersPrePost 1
        } else {
            ::AIEnv::GUIManagement::ToggleGrey meshPrismLayersPrePost 0
            if {[meshAutoDEZ get run_pre_or_post_inflation] == "pre"} {
                if {[meshAutoDEZ get run_prism] != 0} { meshAutoDEZ set run_prism 0 }
                if {[meshAutoDEZ get run_tgrid_inflation] != 1} { meshAutoDEZ set run_tgrid_inflation 1 }
                if {[meshAutoDEZ get loadmesh] != 1}  { meshAutoDEZ set loadmesh 1 }
            } else {
                if {[meshAutoDEZ get run_prism] != 1} { meshAutoDEZ set run_prism 1 }
                if {[meshAutoDEZ get run_tgrid_inflation] != 0} { meshAutoDEZ set run_tgrid_inflation 0 }
            }
        }
    }
    if {$name != "run_pre_or_post_inflation" && [lindex [split $name ::] end] == "run_pre_or_post_inflation"} {
        if {[meshAutoDEZ get run_pre_or_post_inflation] == "pre"} {
             if {[meshAutoDEZ get run_prism] != 0} { meshAutoDEZ set run_prism 0 }
             if {[meshAutoDEZ get run_tgrid_inflation] != 1} { meshAutoDEZ set run_tgrid_inflation 1 }
             if {[meshAutoDEZ get loadmesh] != 1}  { meshAutoDEZ set loadmesh 1 }
             ::AIEnv::GUIManagement::ToggleGrey meshPrismTGridTGHC 0
             ::AIEnv::GUIManagement::ToggleGrey meshPrismTGridTGIN 0
        } else {
            if {[meshAutoDEZ get run_prism] != 1} { meshAutoDEZ set run_prism 1 }
            if {[meshAutoDEZ get run_tgrid_inflation] != 0} { meshAutoDEZ set run_tgrid_inflation 0 }
            ::AIEnv::GUIManagement::ToggleGrey meshPrismTGridTGHC 1
            ::AIEnv::GUIManagement::ToggleGrey meshPrismTGridTGIN 1
            meshAutoDEZ set run_tgrid_hexacore 0
            meshAutoDEZ set run_tgrid_interactive 0
        }
    }
    if {$name != "run_prism" && [lindex [split $name ::] end] == "run_prism"} {
        if {[meshAutoDEZ get run_tgrid_inflation] != 0} { meshAutoDEZ set run_tgrid_inflation 0 }
    }
}

proc aie_set_automesh_input {} {
    global env

    if $meshAutoWhatVal {
        if [info exists tetra_method] {
            if {$tetra_method != 0} {
                set tetra_input [ic_uns_is_loaded]
            }
        }
    }
    if {([info exists tetra_method]) && $tetra_method == 0} {
        if {([info exists tetra_input]) && ($tetra_input == 3)} {
            ::AIEnv::GUIManagement::ToggleGrey meshTetOctLoad 0
        } else {
            ::AIEnv::GUIManagement::ToggleGrey meshTetOctLoad 1
        }
    }
    # Prism can be available for FEA
    if [info exists env(AI_ENV_PRISM)] {
        if ![ic_geo_is_loaded] {
            set status 0
        } elseif {[ic_geo_is_loaded] && [ic_geo_get_objects surface] != ""} {
            set status 0
        } else {
            set status 1
        }
        foreach i {Oct Del Adv} {
            ::AIEnv::GUIManagement::ToggleGrey meshTet${i}Prism $status
        }
        ::AIEnv::GUIManagement::ToggleGrey meshAutoPrism $status
    }
    if {[ic_list_volume_families] != ""} {
        set family inherited
    } else {
        set family CREATED_MATERIAL
    }
    aie_wb_trace_tgrid_inflation_state "" "" ""
}

proc onmeshAutoSurfLoad {} {
    global env surfaceMeshArray beta_mode

    set surfElemTypeList {
	    "All Tri"
	    "Quad w/one Tri"
	    "Quad Dominant"
	    "All Quad"
    }
    set surfElemMethodList {}
    if {[info exists env(AI_ENV_QUAD)]} {
       lappend surfElemMethodList "Autoblock"
       lappend surfElemMethodList "Patch Dependent"
    }
    if {[info exists env(AI_ENV_QUAD)]} {
       lappend surfElemMethodList "Patch Independent"
    }
    lappend surfElemMethodList "Shrinkwrap"
    if {[info exists env(AI_ENV_QUAD)] && $beta_mode} {
       lappend surfElemMethodList "Delaunay"
    }

    # if called from Surface/Curve Mesh Size skip this
    if {[aie_active_dez] == "meshAutoDEZ"} {
#        meshAutoDEZ aie_set_automesh_input
    }
    if {[info exists env(AI_ENV_QUAD)] || [info exists env(AI_ENV_TETRA)]} {
        catch { unset surfaceMeshArray }
        # just in case that shell meshing params was never set -> use the defaults
        set surfaceMeshArray(ign_size) [aie_default_topo_tolerance]
        array set surfaceMeshArray {
            proj_surf 1
            impr_level 1
            bound_smooth 0
            surf_sizes 0
            protect_line 0
            simple_offset 0
            max_area 0.0
            max_length 0.0
            min_angle 0.0
            max_nodes 0
            max_elements 0
            bunch_respect 0
            block_mapping 0.2
            adjust_nodes_max 0
            try_harder 1
            mesh_dormant 0
            smooth_dormant 0
            mesh_type 3
            mesh_method 0
            merge_surfs 1
            mapped_method 1
            free_bunch 0
            snorm 1
            quadratic 0
            shrinkwrap_nsmooth 5
            shrinkwrap_projfactor 0.1
        }
        set mapped_method 1
        set remove_old 1
        set sm_method 0

        array set surfaceMeshArray [ic_get_meshing_params surface_global 0]
    }
    if [info exists env(QUAD_DEBUG)] {
        set four 0
        set enn 0
        set inner 0
        set iters 20
        set geo_tol 0.0
        set pattern 150
        set time_max 0
        set ele_max 0
        set board 0
        set breakpoint 0
        set debug 0
        set max_dev 0.0
        set accuracy 0.025
    }

    set etype2 [aie_global_get_mesh_type_name [aie_get_default_surface_mesh_type]]
    set emethod_tmp [aie_global_get_mesh_method_name [aie_get_default_surface_mesh_method]]
    if {[lsearch $surfElemMethodList $emethod_tmp] < 0} {
        set emethod2 [lindex $surfElemMethodList 0]
    } else {
        set emethod2 $emethod_tmp
    }
    # if called from Surface/Curve Mesh Size skip this
    if {[aie_active_dez] == "meshAutoDEZ"} {
        set input 0
        if ![info exists set_surfparams_type] {
            set set_surfparams_type 0
            set set_surfparams_method 0
            ::AIEnv::GUIManagement::ToggleGrey meshSurfType 1
            ::AIEnv::GUIManagement::ToggleGrey meshSurfMethod 1
        }
        foreach n "set_surfparams_type set_surfparams_method" {
            if {[trace vinfo $n] != ""} {
                trace vdelete $n w aie_surface_mesh_trace_type_method
            }
            trace variable $n w aie_surface_mesh_trace_type_method
        }
        foreach n "etype2 emethod2" {
            if {[trace vinfo $n] != ""} {
                trace vdelete $n w aie_surface_mesh_trace_etype2_emethod2
            }
            trace variable $n w aie_surface_mesh_trace_etype2_emethod2
        }
    }
}

proc aie_surface_mesh_trace_type_method {name element op} {
    if [meshAutoDEZ get set_surfparams_type] {
        ::AIEnv::GUIManagement::ToggleGrey meshSurfType 0
    } else {
        ::AIEnv::GUIManagement::ToggleGrey meshSurfType 1
    }
    if [meshAutoDEZ get set_surfparams_method] {
        ::AIEnv::GUIManagement::ToggleGrey meshSurfMethod 0
    } else {
        ::AIEnv::GUIManagement::ToggleGrey meshSurfMethod 1
    }
}

proc aie_surface_mesh_trace_etype2_emethod2 {name element op} {
    global warning_message_printed

    if [info exists warning_message_printed] return
    set warning_message_printed 1
    if {[meshAutoDEZ get set_surfparams_method] && [meshAutoDEZ get set_surfparams_type]} {
        if {[meshAutoDEZ get emethod2] == "Delaunay"} {
            set t [meshAutoDEZ get etype2]
            if {$t== "All Quad" || $t== "Quad w/one Tri"} {
                after 10 { meshAutoDEZ set etype2 "Quad Dominant" }
                mess "Warning: \"Delaunay\" mesh method can't deal with mesh type \"$t\"...using \"Quad Dominant\"\n" red
            }
        }
    }
    after 100 { unset warning_message_printed }
}

proc aie_volume_mesh_trace_hexa_core {name element op} {
return
    if {[meshAutoDEZ get run_hexacore]} {
        ::AIEnv::GUIManagement::ToggleGrey meshUseAdvDelaunay 1
    } else {
        ::AIEnv::GUIManagement::ToggleGrey meshUseAdvDelaunay 0
    }
}

# returns 0 for success, others for failure
proc aie_compute_surface_mesh {{volume_mesh ""}} {
    global env options surfaceMeshArray beta_mode is_win

    foreach n [array names surfaceMeshArray] {
        if {$n == "mesh_type" || $n == "mesh_method"} continue
        set v $surfaceMeshArray($n)
        set $n $v
    }

    if ![info exists patch_dependent] {
        # Mesh Type and Mesh Method are always defined here
        array set surfMeshGlobals [ic_get_meshing_params surface_global 0]

        if !$set_surfparams_type {
            if [info exists surfMeshGlobals(mesh_type)] {
                set surfaceMeshArray(mesh_type) $surfMeshGlobals(mesh_type)
            } else {
                set surfaceMeshArray(mesh_type) [aie_get_default_surface_mesh_type $volume_mesh]
            }
        } else {
            set surfaceMeshArray(mesh_type) [aie_global_get_mesh_type_number $etype2]
        }
        if !$set_surfparams_method {
            if [info exists surfMeshGlobals(mesh_method)] {
                set surfaceMeshArray(mesh_method) $surfMeshGlobals(mesh_method)
            } else {
                if {$volume_mesh == "hexdom" || $volume_mesh == "tetra"} {
                    set surfaceMeshArray(mesh_method) [aie_get_default_surface_mesh_method 1]
                } else {
                    set surfaceMeshArray(mesh_method) [aie_get_default_surface_mesh_method $volume_mesh]
                }
            }
        } else {
            set surfaceMeshArray(mesh_method) [aie_global_get_mesh_method_number $emethod2]
        }
    }

    if [info exists surfaceMeshArray(mesh_type)] {
        set v $surfaceMeshArray(mesh_type)
        set mesh_type [aie_global_get_mesh_type_name $v]
    } else {
        set mesh_type "NONE"
    }
    if [info exists surfaceMeshArray(mesh_method)] {
        set v $surfaceMeshArray(mesh_method)
        set mesh_method [aie_global_get_mesh_method_name $v]
    } else {
        set mesh_method "NONE"
    }

    if {[aie_active_dez] != "meshAutoDEZ"} {
        # if called from Surface/Curve Mesh Size use
        # selected surfaces as input and use
        # "Patch Dependent" as mesh method
        set use_input 3
        set reset_bunch_respect $bunch_respect
        set bunch_respect 1
        set reset_mesh_method $mesh_method
        set mesh_method "Patch Dependent"
        set use_big 1
    } else {
        set use_input $input
        set use_big 1
    }

    switch $mesh_method {
        "Patch Dependent" - "Delaunay" {
            if {(![info exists sm_method]) || ($sm_method == "")} {
                mess "Please select a mesh boundary method.\n" red
                return 1
            }
            if ![info exists env(QUAD_DEBUG)] {
                set four 0
                set enn 0
                set inner 0
                set iters 20
                set geo_tol 0.0
                set pattern 150
                set time_max 0
                set ele_max 0
                set board 0
                set breakpoint 0
                set debug 0
                set accuracy 0.025
                set geo_tol 0
                set max_dev 0.0
            }
        }
        "Patch Independent" - "Autoblock" {
            if {![ic_geo_is_loaded] || [ic_geo_get_objects surface] == ""} {
                mess "Error: No surfaces available.\n" red
                return 1
            }
            if {$mesh_method == "Autoblock"} {
                set min_edge $ign_size
            }
        }
    }
    set err_code 0
    set sm_method 0
    set curveSMList ""
    set only_visible 0
    if ![info exists patch_dependent] {
        set surfSMList ""
        switch $use_input {
            0 { # all
                switch $mesh_method {
                    "Patch Dependent" - "Delaunay" - "Autoblock" {
                        set surfSMList ""
                    }
                    "Patch Independent" {
                        set surfSMList [ic_geo_get_objects surface ""]
                    }
                }
            }
            1 { # visible
                set surfSMList [ic_geo_list_visible_objects surface]
                switch $mesh_method {
                    "Patch Dependent" - "Delaunay" {
                        if {$surfSMList == ""} {
                            set curveSMList [ic_geo_list_visible_objects curve]
                            if {$curveSMList == ""} {
                                # maybe only visible geometry subset(s) available
                                foreach sub [ic_geo_subset_list] {
                                    if {[expr [::AIEnv::GUIManagement::Tree::NodeVisibleStatus geom_subset $sub 1] == 1]} {
                                        foreach {t n} [ic_geo_subset_get_items $sub] {
                                            if {$t == "curve"} {
                                                lappend curveSMList $n
                                            } elseif {$t == "surface"} {
                                                lappend surfSMList $n
                                            }
                                        }
                                    }
                                }
                                if {$surfSMList != ""} {
                                    set curveSMList ""
                                }
                            }
                        }
                    }
                    "Patch Independent" - "Autoblock" {
                        if {$mesh_method == "Patch Independent"} {
                            set only_visible 1
                        }
                        if {$surfSMList == ""} {
                            foreach curve [ic_geo_list_visible_objects curve] {
                                foreach surf [ic_geo_incident curve $curve] {
                                    if {[lsearch "$surfSMList" $surf] < 0} {
                                        lappend surfSMList $surf
                                    }
                                }
                            }
                            if {$surfSMList == ""} {
                                # maybe only visible geometry subset(s) available
                                foreach sub [ic_geo_subset_list] {
                                    if {[expr [::AIEnv::GUIManagement::Tree::NodeVisibleStatus geom_subset $sub 1] == 1]} {
                                        foreach {t n} [ic_geo_subset_get_items $sub] {
                                            if {$t == "surface"} { lappend surfSMList $n }
                                        }
                                    }
                                }
                                if {$surfSMList == ""} {
                                    mess "Error: There are no surfaces or curves visible.\n" red
                                    return 1
                                }
                            } else {
                                mess "Warning: No surfaces visible - using surfaces attached\
                                      to visible curves.\n" red
                            }
                        }                 
                    }
                }
            }
            2 { # Part by part
                set surfSMList [ic_geo_get_objects surface $geomParts]
            }
            3 { # From screen
                if {$mesh_method == "Autoblock" || $mesh_method == "Patch Independent"} {
                    catch { unset ignore_selected_curves }
                    foreach {type name} $geomEnts {
                        if {$type == "surface"} {
                            set ignore_selected_curves 1
                            break
                        }
                    }
                }
                foreach {type name} $geomEnts {
                    if {$type == "surface"} {
                        if {[lsearch "$surfSMList" $name] < 0} {
                            lappend surfSMList $name
                        }
                    } elseif {$type == "curve"} {
                        if {($mesh_method == "Autoblock" || $mesh_method == "Patch Independent") && \
                            ![info exists ignore_selected_curves]} {
                            foreach surf [ic_geo_incident curve $name] {
                                if {[lsearch "$surfSMList" $surf] < 0} {
                                    set curves_selected 1
                                    lappend surfSMList $surf
                                }
                            }
                        } else {
                            lappend curveSMList $name
                        }
                    }
                }
                switch $mesh_method {
                    "Patch Independent" - "Autoblock" {
                        if {$surfSMList != "" && [info exists curves_selected]} {
                            mess "Warning: No surfaces selected - using surfaces attached\
                                  to selected curves.\n" red
                            unset curves_selected
                            catch { unset ignore_selected_curves }
                        }
                    }
                }
            }
        }
    }
    switch $mesh_method {
        "Patch Dependent" - "Delaunay" - "Autoblock" - "Patch Independent" {
            set slen [llength $surfSMList]
            set clen [llength $curveSMList]
            if {($slen == 0) && ($clen > 0)} {
                set sm_method 1
                switch $use_input {
                    1 {
                        if {$mesh_method != "Patch Independent"} {
                            mess "Using visible curves to create surface mesh.\n" blue
                        }
                    }
                }
            } elseif {($slen > 0) && ($clen > 0)} {
                set curveSMList ""
                switch $use_input {
                    1 {
                        mess "Using visible surfaces to create surface mesh.\n" blue
                    }
                }
            } elseif {($slen == 0) && ($clen == 0)} {
                switch $use_input {
                    1 {
                        mess "Error: There are no surfaces or curves visible.\n" red
                        return 1
                    }
                }
            } elseif {($slen > 0) && ($clen == 0)} {
                switch $use_input {
                    2 {
                        if {$mesh_method == "Patch Independent"} {
                            mess "Using all surfaces from part(s) $geomParts to create surface mesh.\n" blue
                        }
                    }
                }
            }
        }
    }
    switch $mesh_method {
        "Patch Dependent" - "Delaunay" {
            if [aie_autosizing quad] {
                mess "Canceled by user\n" red
                return 1
            }
            if {$debug > 0} {
                mess "Debug level = $debug\n" red
                mess "sm_method = $sm_method\n" red
            }
            switch $sm_method {
                0 {
                    set what surfaces
                    set entities $surfSMList
                    if {$surfSMList == ""} {
                        switch $use_input {
                            0 { # All
                                set entities ""
                                if {[ic_geo_get_objects surface ""] == ""} {
                                    if {[ic_geo_get_objects curve ""] == ""} {
                                        mess "Error: Neither surface(s) nor curve(s) found.\n" red
                                        busy 0
                                        return 1
                                    } else {
                                        set what curves
                                    }
                                }
                            }
                        }
                    } else {
                        foreach srf $surfSMList {
                            if {[ic_geo_check_objects_exist surface $srf] == ""} {
                                mess "Error: No surface named \"$srf\".\n" red
                                busy 0
                                return 1
                            }
                        }
                    }
                }
                1 {
                    set what curves
                    set entities $curveSMList
                    if {$debug > 0} {
                        mess "curveSMList = $curveSMList\n" red
                    }
                    if {$curveSMList == ""} {
                        set entities [ic_geo_get_objects curve ""]
                        if {$debug} {
                            mess "curveSMList = $curveSMList\n" red
                        }
                    } else {
                        foreach crv $curveSMList {
                            if {[ic_geo_check_objects_exist curve $crv] == ""} {
                                mess "Error: No curve named \"$crv\".\n" red
                                busy 0
                                return 1
                            }
                        }
                    }
                }
                2 {
                    set what loops
                    set entities ""
                }
                3 {
                    set what native_surfaces
                    set entities $surfSMList
                    if {$surfSMList == ""} {
                        set entities [ic_geo_get_objects surface ""]
                    } else {
                        foreach srf $surfSMList {
                            if {[ic_geo_check_objects_exist surface $srf] == ""} {
                                mess "Error: No surface named \"$srf\".\n" red
                                busy 0
                                return 1
                            }
                        }
                    }
                }
                default {
                    set entities $surfSMList
                    if {$surfSMList != ""} {
                        foreach srf $surfSMList {
                            if {[ic_geo_check_objects_exist surface $srf] == ""} {
                                mess "Error: No surface named \"$srf\".\n" red
                                busy 0
                                return 1
                            }
                        }
                    }
                }
            }
            #
            #   Apply mesh type and mesh method to all selected surfaces if requested
            #
            if {$what == "surfaces"} {
                if $set_surfparams_type {
                    if {$use_input == 0 && $entities == "" && $meshAutoWhatVal == 0} {
                        ic_set_meshing_params surface [ic_geo_get_objects surface ""] etyp [aie_global_get_mesh_type_number $etype2]
                    } else {
                        ic_set_meshing_params surface $entities etyp [aie_global_get_mesh_type_number $etype2]
                    }
                }
                if $set_surfparams_method {
                    if {$use_input == 0 && $entities == "" && $meshAutoWhatVal == 0} {
                        ic_set_meshing_params surface [ic_geo_get_objects surface ""] emethod [aie_global_get_mesh_method_number $emethod2]
                    } else {
                        ic_set_meshing_params surface $entities emethod [aie_global_get_mesh_method_number $emethod2]
                    }
                }
            }

            if {$mesh_method == "Delaunay"} {
                set type 8
            } else {
                switch $mesh_type {
                    "All Quad"        {set type 4}
                    "Quad w/one Tri"  {set type 1}
                    "Quad Dominant"   {set type 2}
                    "All Tri"         {set type 3}
                    "Tri (STL like)"  {set type 5}
                    "Tri (split STL)" {set type 7}
                    "Tri (Delaunay)"  {set type 8}
                    default {
                        mess "Warning: Quad meshing can't deal with type $mesh_type...using \"Quad Dominant\"\n" red
                        set type 2
                    }
                }
            }
            if {$adjust_nodes_max} {
                set adjust_nodes 2
            } else {
                set adjust_nodes 0
            }
            if {$surf_sizes} {
                set inner -1
            } elseif {$inner < 0} {
                set inner 0
            }
            set error_subset "Failed_surfaces"
            set dormant 1
            if $mesh_dormant {
                set dormant 0
            }
            set ele_tol $ign_size
            if $protect_line {
                set ele_tol [expr -abs($ign_size)]
            }
            if {$what == "curves"} {
                set inner 0
                set block_mapping 0.0
                set adjust_nodes 0
                set adjust_nodes_max 0.0
                set remove_old 0
            } elseif {$remove_old != 1} {
                mess "Reset remove_old parameter from $remove_old to 1.\n" red
                set remove_old 1
            }
            if {$mesh_method != "Delaunay"} {
                set max_length 0.0
                set max_area 0.0
                set min_angle 0.0
                set max_nodes 0
                set max_elements 0
            } else {
                set inner 0
                set max_dev 0.0
            }
            set n_threads 0
            if {[info exists options(n_processors)] && $options(n_processors) > 1} {
                set n_threads $options(n_processors)
            }
            if {![info exists patch_dependent] && ![info exists patch_independent]} {
                switch $use_input {
                    1 {
                        set not_visible_surfaces ""
                        foreach s [ic_geo_get_objects surface ""] {
                            if {[lsearch $entities $s] < 0} {
                                lappend not_visible_surfaces $s
                            }
                        }
                        if {$not_visible_surfaces == "" && ($surfSMList != "" || $curveSMList != "")} {			
                            catch { unset mesh_restore_invisible }
                            set savemap [ic_uns_subset_create]
                            ic_uns_create_selection_edgelist 1
                            ic_uns_subset_configure $savemap -draw_nodes 1
                            ic_uns_subset_visible $savemap 0
                            ic_uns_subset_make_all $savemap
                            ic_uns_subset_subtract_from $savemap visible
                            ic_uns_uniqify $savemap
                            ic_uns_create_selection_edgelist 0
                            if [ic_uns_subset_count_elements $savemap] {
                                set found_shell 0
                                set types_shell [ic_uns_subset_list_types $savemap]
                                foreach t "TRI_3 TRI_6 QUAD_4 QUAD_8 QUAD_9" {
                                    if {[lsearch $types_shell $t] >= 0} {
                                        set found_shell 1
                                        break
                                    }
                                }
                                if $found_shell {
                                    set temp_unvisible_mesh ___temp_unvisible_mesh[pid].uns
                                    ic_save_unstruct $temp_unvisible_mesh 0 "" "" "" $savemap
                                    set mesh_restore_invisible 1
                                }
                            }
                            ic_uns_subset_delete $savemap
                        } elseif {($surfSMList != "" || $curveSMList != "")} {
                            set merge_invisible_mesh 1
                        }
                        unset not_visible_surfaces
                    }
                }
            }
            meshAutoDEZ setclean
            set err_code [ic_quad2 what $what entities $entities element $type \
                proj $proj_surf conver $accuracy geo_tol $geo_tol ele_tol $ele_tol \
                dev $max_dev improvement $impr_level block $block_mapping \
                bunch $bunch_respect debug $debug adjust_nodes $adjust_nodes \
                adjust_nodes_max $adjust_nodes_max try_harder $try_harder \
                error_subset $error_subset pattern $pattern big $use_big board $board \
                remove_old -$remove_old inner $inner simple_offset $simple_offset \
                enn $enn b_smooth $bound_smooth time_max $time_max ele_max $ele_max \
                four $four merge_dormant $dormant max_length $max_length \
                max_area $max_area min_angle $min_angle max_nodes $max_nodes \
                max_elements $max_elements smoothdormant $smooth_dormant \
                breakpoint $breakpoint freeb $free_bunch n_threads $n_threads \
                snorm $snorm shape $quadratic]
            switch $use_input {
                1 {
                    if [info exists mesh_restore_invisible] {
    		            ic_uns_load $temp_unvisible_mesh 3 1 {} 0
    		            ic_rm $temp_unvisible_mesh
    		            unset mesh_restore_invisible
                    }
                    if [info exists merge_invisible_mesh] {
    		            ic_uns_merge_nodes all by_min_edge2
    		            unset merge_invisible_mesh
                    }
                }
            }
            if $err_code {
                if {[ic_geo_subset_get_items $error_subset] !=""} {
                    aie_subset_put_in_tree geom $error_subset
                } elseif {[ic_geo_subset_exists $error_subset] != 0} {
                    aie_delete_geom_subset $error_subset
                }
            } elseif {[ic_geo_subset_exists $error_subset] != 0} {
                aie_delete_geom_subset $error_subset
            }
            if {[ic_get_ignore_size] != 0} {
                if {$debug > 0} {
                    mess "set ignore_size to [ic_get_ignore_size]\n" red
                }
                set ign_size [ic_get_ignore_size]
            }
            meshAutoDEZ setdirty
        }
        "Patch Independent" {
            if [aie_autosizing tetra 1] {
                mess "Canceled by user\n" red
                busy reset
                return 1
            }
            set args "tin uns run_cutter 1 fix_holes 1 write_volume 0 \
                n_tri_smoothing_steps 20 in_process 1 log tetra_cmd0.log"
            if {[info exists options(n_processors)] && $options(n_processors) != ""} {
                # work-a-round for windows 64 bit multi processors machines in case of 
                # bunch_respect set to 1 and unstruct mesh is loaded
                if {$is_win && [ic_uns_is_loaded] && $bunch_respect} {
                    append args " n_processors 1"
                } else {
                    append args " n_processors $options(n_processors)"
                }
            }
            if [info exists patch_independent] { unset patch_independent }
            if [info exists patch_dependent] { unset patch_dependent }
            foreach surf $surfSMList {
                if $set_surfparams_type {
                    ic_set_meshing_params surface $surf etyp [aie_global_get_mesh_type_number $etype2]
                }
                if $set_surfparams_method {
                    ic_set_meshing_params surface $surf emethod [aie_global_get_mesh_method_number $emethod2]
                }
                foreach {n v} [ic_get_meshing_params surface $surf] {
                    switch $n {
                        "emethod" { set m $v }
                    }
                }
                if {$m == 2 || $m == -1} {
                    lappend patch_independent $surf
                } else {
                    lappend patch_dependent $surf
                }
            }
            if [info exists patch_independent] {
                if [info exists patch_dependent] {
                    ic_geo_temporary_visible surface $patch_dependent 0 1
                }
                set CurveMeshParts ""
                set bmaps ""
                set given_bars ""
                if {$beta_mode && [ic_uns_is_loaded] && $bunch_respect} {
                    foreach s $patch_independent {
                        foreach c [ic_geo_boundary surface $s 0 0 1] {
                            lappend CurveMeshParts [ic_geo_get_family curve $c]
                            lappend bmaps [ic_uns_get_attached_elements curve $c]
                        }
                        set CurveMeshParts [lsort -unique $CurveMeshParts]
                    }
                    if {$CurveMeshParts != ""} {
                        set given_bars temp_given_bars.uns
                        ic_save_unstruct $given_bars 1 "" {LINE_2} $CurveMeshParts $bmaps
                        foreach fam $CurveMeshParts {
                            append args " use_existing \"$fam,$given_bars\""
                        }
                        append args " no_replacement 1"
                    }
                }
                if $only_visible {
                    #
                    #   "Visible"
                    #
                    if ![::AIEnv::GUIManagement::Tree::GetVisibility curve] {
                        ic_geo_temporary_visible curve [ic_geo_get_objects curve ""] 1 1
                    }
                    if ![::AIEnv::GUIManagement::Tree::GetVisibility surface] {
                        ic_geo_temporary_visible surface $patch_independent 1 1
                    }
                    set use_temp_file 1
                    if {$beta_mode && [ic_uns_is_loaded] && $bunch_respect} {
                        set unvisible_surfaces ""
                        foreach s [ic_geo_get_objects surface ""] {
                            if {[lsearch $patch_independent $s] < 0} {
                                lappend unvisible_surfaces $s
                            }
                        }
                        if [info exists mesh_restore] { unset mesh_restore }
                        if {$unvisible_surfaces != ""} {
                            set savemaps ""
                            foreach s $unvisible_surfaces {
                                set map [ic_uns_get_attached_elements surface $s]
                                lappend savemaps $map
                                foreach c [ic_geo_boundary surface $s 0 0 1] {
                                    set map2 [ic_uns_get_attached_elements curve $c]
                                    lappend savemaps $map2
                                    foreach p [ic_geo_boundary curve $c 0 0 0] {
                                        set map3 [ic_uns_get_attached_elements point $p]
                                        lappend savemaps $map3
                                    }
                                }
                            }
                            if {$savemaps != ""} {
                                set temp_unvisible_mesh ___temp_unvisible_mesh[pid].uns
                                ic_save_unstruct $temp_unvisible_mesh 0 "" "" "" $savemaps
                            }
                            foreach elmap $savemaps {
                                ic_delete_elements subset $elmap no_undo 1
                                ic_uns_subset_delete $elmap
                            }
                            if [info exists savemaps] {
                                unset savemaps
                            }
                            set mesh_restore 1
                        }
                    }
                } elseif {$use_input == 2 || $use_input == 3} {
                    #
                    #   "Part by part" or "From screen"
                    #
                    set temp_unvisible ""
                    foreach s [ic_geo_get_objects surface ""] {
                        if {[lsearch $patch_independent $s] < 0} {
                            lappend temp_unvisible $s
                        }
                    }
                    if {$use_input == 2} {
                        if ![::AIEnv::GUIManagement::Tree::GetVisibility surface] {
                            ic_geo_temporary_visible surface $patch_independent 1 1
                        }
                    }
                    if [info exists mesh_restore] { unset mesh_restore }
                    if {[ic_uns_is_loaded] && $temp_unvisible != ""} {
                        set delmaps ""
                        foreach s $patch_independent {
                            set map [ic_uns_get_attached_elements surface $s]
                            lappend delmaps $map
                            if {!$bunch_respect} {
                                foreach c [ic_geo_boundary surface $s 0 0 1] {
                                    set map2 [ic_uns_get_attached_elements curve $c]
                                    lappend delmaps $map2
                                    foreach p [ic_geo_boundary curve $c 0 0 0] {
                                        set map3 [ic_uns_get_attached_elements point $p]
                                        lappend delmaps $map3
                                    }
                                }
                            }
                        }
                        foreach elmap $delmaps {
                            ic_delete_elements subset $elmap no_undo 1
                            ic_uns_subset_delete $elmap
                        }
                        if [info exists delmaps] {
                            unset delmaps
                        }
                        set mesh_restore 1
                    }
                    if [info exists mesh_restore] {
                        set temp_unvisible_mesh ___temp_unvisible_mesh[pid].uns
                        ic_save_unstruct $temp_unvisible_mesh
                    }
                    if {$temp_unvisible != ""} {
                        if ![::AIEnv::GUIManagement::Tree::GetVisibility curve] {
                            ic_geo_temporary_visible curve [ic_geo_get_objects curve ""] 1 1
                        }
                        if [::AIEnv::GUIManagement::Tree::GetVisibility surface] {
                            ic_geo_temporary_visible surface $temp_unvisible 0 1
                        }
                        set use_temp_file 1
                    } else {
                        unset temp_unvisible
                    }
                }
                if [info exists use_temp_file] {
                    set tempfilename "__temp_visible_surfaces[pid].tin"
                    ic_save_tetin $tempfilename 1
                    if [file exists $tempfilename] {
                        append args " input_geometry \"$tempfilename\""
                    }
                }
                mess "Running patch independent mesher...\n" blue
                busy reset
                if ![eval ic_run_tetra $args] {
                    if [info exists patch_dependent] {
                        if [::AIEnv::GUIManagement::Tree::GetVisibility surface] {
                            ic_geo_temporary_visible surface $patch_dependent 1 1
                        }
                        unset patch_dependent
                    }
                    if [info exists use_temp_file] {
                        if $only_visible {
                            if ![::AIEnv::GUIManagement::Tree::GetVisibility curve] {
                                ic_geo_temporary_visible curve [ic_geo_get_objects curve ""] 0 1
                            }
                        } elseif {($use_input == 2 || $use_input == 3) && [info exists temp_unvisible]} {
                            if ![::AIEnv::GUIManagement::Tree::GetVisibility surface] {
                                ic_geo_temporary_visible surface $temp_unvisible 1 1
                            }
                            unset temp_unvisible
                            if {$use_input == 2} {
                                if ![::AIEnv::GUIManagement::Tree::GetVisibility surface] {
                                   ic_geo_temporary_visible surface $patch_independent 0 1
                                }
                            }
                        }
                        if [file exists $tempfilename] {
                            ic_rm $tempfilename
                        }
                        if [info exists mesh_restore] {
                            ic_unload_mesh 1
                            ic_uns_load $temp_unvisible_mesh 3 1 {} 0
                            ic_rm $temp_unvisible_mesh
                            unset mesh_restore
                        }
                        unset use_temp_file
                    }
                    unset patch_independent
                    busy reset
                    return 1
                }
                if {$given_bars != "" && [file exists $given_bars]} {
                    ic_rm $given_bars
                }
                if [info exists use_temp_file] {
                    if $only_visible {
                        if ![::AIEnv::GUIManagement::Tree::GetVisibility curve] {
                            ic_geo_temporary_visible curve [ic_geo_get_objects curve ""] 0 1
                        }
                        if ![::AIEnv::GUIManagement::Tree::GetVisibility surface] {
                             ic_geo_temporary_visible surface $patch_independent 0 1
                        }
                        if [info exists mesh_restore] {
                            ic_uns_load $temp_unvisible_mesh 3 1 {} 0
                            ic_rm $temp_unvisible_mesh
                        }
                    } elseif {($use_input == 2 || $use_input == 3) && [info exists temp_unvisible]} {
                        if [::AIEnv::GUIManagement::Tree::GetVisibility surface] {
                            ic_geo_temporary_visible surface $temp_unvisible 1 1
                        }
                        if [info exists mesh_restore] {
                            ic_uns_load $temp_unvisible_mesh 3 1 {} 0
                            ic_rm $temp_unvisible_mesh
                        }
                        unset temp_unvisible
                        if {$use_input == 2} {
                            if ![::AIEnv::GUIManagement::Tree::GetVisibility surface] {
                               ic_geo_temporary_visible surface $patch_independent 0 1
                            }
                        }
                    }
                    if {$bmaps != ""} {
                        # given bar elements already came back from Tetra
                        foreach elmap $bmaps {
                            if ![ic_uns_subset_exists $elmap] continue
                            ic_delete_elements subset $elmap no_undo 1
                            ic_uns_subset_delete $elmap
                        }
                        if [info exists bmaps] {
                            unset bmaps
                        }
                        if [info exists mesh_restore] {
                            ic_uns_merge_nodes all by_min_edge
                            #   not such elegant ... but existing mesh
                            #   has been renumbered when being reloaded
                        }
                    }
                    if [file exists $tempfilename] {
                        ic_rm $tempfilename
                    }
                    unset use_temp_file
                }
                if {($mesh_type == "All Quad" || $mesh_type == "Quad Dominant" || \
                     $mesh_type == "Quad w/one Tri")} {
                    set proj_flag 1
                    if {$mesh_type == "All Quad"} {
                        set quad_flag 1
                    } else {
                        set quad_flag 0
                    }
                    if ![info exists mesh_restore] {
                        if {[lsearch "[ic_uns_subset_list_types all]" TRI_3] >= 0} {
                            ic_change_tri_quad proj $proj_flag quadrization $quad_flag
                        }
                    } else {
                        foreach surf $patch_independent {
                            set map [ic_uns_get_attached_elements surface $surf]
                            set types [ic_uns_subset_list_types $map]
                            if {[lsearch $types "TRI_3"] >= 0} {
                                ic_change_tri_quad_2 $map 1 0 0 -1 160 20 0
                            }
                            ic_uns_subset_delete $map
                        }
                    }
                }
                if [info exists patch_dependent] {
                    if [::AIEnv::GUIManagement::Tree::GetVisibility surface] {
                        ic_geo_temporary_visible surface $patch_dependent 1 1
                    }
                }
                if [info exists mesh_restore] {
                    unset mesh_restore
                }
            }
            if [file exists ./tetra_cmd0.log] {
                rm_tmp_file ./tetra_cmd0.log
            }
            if [info exists patch_dependent] {
                set surfaceMeshArray(mesh_method) 1
                if [info exists patch_independent] {
                     set backup_bunch_respect $bunch_respect
                     set backup_protect_line $protect_line
                     set surfaceMeshArray(bunch_respect) 1
                     set surfaceMeshArray(protect_line) 1
                }
                set backup_surfs $surfSMList
                set surfSMList $patch_dependent
                meshAutoDEZ aie_compute_surface_mesh
                set surfaceMeshArray(mesh_method) 2
                if [info exists patch_independent] {
                    set surfaceMeshArray(bunch_respect) $backup_bunch_respect
                    set surfaceMeshArray(protect_line) $backup_protect_line
                    unset backup_bunch_respect
                    unset backup_protect_line
                    unset patch_independent
                }
                set surfSMList $backup_surfs
                unset backup_surfs
                unset patch_dependent
                set skip_mess 1
            }
        }
        "Autoblock" {
            if [ic_uns_is_loaded] {
                if {$surfSMList == ""} {
                    set surfs [ic_geo_get_objects surface]
                } else {
                    foreach srf $surfSMList {
                        if {[ic_geo_check_objects_exist surface $srf] == ""} {
                            mess "Error: No surface named \"$srf\".\n" red
                            busy 0
                            return 1
                        }
                    }
                    set surfs $surfSMList
                }
                set delmaps ""
                foreach surf $surfs {
                    set map [ic_uns_get_attached_elements surface $surf]
                    lappend delmaps $map
                    foreach curve [ic_geo_boundary surface $surf 0 0 1] {
                        set map2 [ic_uns_get_attached_elements curve $curve]
                        lappend delmaps $map2
                        foreach point [ic_geo_boundary curve $curve 0 0 0] {
                            set map3 [ic_uns_get_attached_elements point $point]
                            lappend delmaps $map3
                        }
                    }
                }
                foreach elmap $delmaps {
                    ic_delete_elements subset $elmap no_undo 1
                    ic_uns_subset_delete $elmap
                }
            } else {
                if {$surfSMList == ""} {
                    set surfs [ic_geo_get_objects surface]
                } else {
                    set surfs $surfSMList
                }
            }
            #
            #   Apply mesh type and mesh method to all selected surfaces if requested
            #
            if $set_surfparams_type {
                ic_set_meshing_params surface $surfs etyp [aie_global_get_mesh_type_number $etype2]
            }
            if $set_surfparams_method {
                ic_set_meshing_params surface $surfs emethod [aie_global_get_mesh_method_number $emethod2]
            }
            if [aie_autosizing mapped] {
                mess "Canceled by user\n" red
                return 1
            }
            if [info exists mapped_based] { unset mapped_based }
            if [info exists patch_dependent] { unset patch_dependent }
            foreach surf $surfs {
                foreach {n v} [ic_get_meshing_params surface $surf] {
                    switch $n {
                        "emethod" { set m $v }
                    }
                }
                if {$m == 0 || $m == -1} {
                    lappend mapped_based $surf
                } else {
                    lappend patch_dependent $surf
                }
            }
            if [info exists mapped_based] {
                set mode -mixed
                switch $mapped_method {
                    0 { set mode -unstruct }
                    1 { set mode -mixed }
                    2 { set mode -mapped }
                }
                if {$mapped_method == 0} {
                    set no_merge 1
                } else {
                    set no_merge !$merge_surfs
                }
                if [info exists backup_gcgap] { unset backup_gcgap }
                foreach {n v} [ic_get_meshing_params global 0] {
                    if {$n == "gcgap"} {
                        set backup_gcgap $v
                    }
                }
                set version 110
                mess "Running auto block mesher...\n" blue
                set failed_surfs [ic_run_mapped_based_mesher $mesh_type $mapped_based $min_edge $mode $no_merge $version]
                aie_create_initial_assemblies
                if [llength $failed_surfs] {
                    set ll ""
                    foreach s $failed_surfs {
                        set ll [concat $ll surface $s]
                    }
                    ic_geo_subset_add_items FAILED_SURFS $ll
                    aie_subset_put_in_tree geom FAILED_SURFS
                    mess "Adding failed surfaces $failed_surfs to FAILED_SURFS subset\n" red
                } else {
                    if [info exists backup_gcgap] {
                        ic_set_meshing_params global 0 gcgap $backup_gcgap
                        unset backup_gcgap
                    }
                    set subsets_to_merge ""
                    foreach surf $mapped_based {
                        foreach {n v} [ic_get_meshing_params surface $surf] {
                            switch $n {
                                "etyp" { set m $v }
                            }
                        }
                        if {($m == -1 && $mesh_type == "All Tri") || $m == 0} {
                            set map [ic_uns_get_attached_elements surface $surf]
                            set types [ic_uns_subset_list_types $map]
                            if {[lsearch $types "QUAD_4"] >= 0} {
                                append subsets_to_merge "$map "
                            }
                        }
                    }
                    if {$subsets_to_merge != ""} {
                        if {[llength $subsets_to_merge] == 1} {
                            ic_uns_change_type [lindex $subsets_to_merge 0] quad tri 1
                            if [ic_uns_subset_exists [lindex $subsets_to_merge 0]] {
                                ic_uns_subset_delete [lindex $subsets_to_merge 0]
                            }
                        } else {
                            set merged_subset [lindex $subsets_to_merge 0]
                            foreach map [lrange $subsets_to_merge 1 end] {
                                ic_uns_subset_add_from $merged_subset $map
                            }
                            ic_uns_change_type $merged_subset quad tri 1
                            if [ic_uns_subset_exists $merged_subset] {
                                ic_uns_subset_delete $merged_subset
                            }
                        }
                    }
                }
            }
            if [info exists patch_dependent] {
                set surfaceMeshArray(mesh_method) 1
                if [info exists mapped_based] {
                     set backup_bunch_respect $bunch_respect
                     set backup_protect_line $protect_line
                     set surfaceMeshArray(bunch_respect) 1
                     set surfaceMeshArray(protect_line) 1
                }
                set backup_surfs $surfSMList
                set surfSMList $patch_dependent
                meshAutoDEZ aie_compute_surface_mesh
                set surfaceMeshArray(mesh_method) 0
                if [info exists mapped_based] {
                    set surfaceMeshArray(bunch_respect) $backup_bunch_respect
                    set surfaceMeshArray(protect_line) $backup_protect_line
                    unset backup_bunch_respect
                    unset backup_protect_line
                    unset mapped_based
                }
                set surfSMList $backup_surfs
                unset backup_surfs
                unset patch_dependent
                set skip_mess 1
            }
        }
        "Shrinkwrap" {
            global file_name

            if [aie_autosizing Shrinkwrap 1] {
                mess "Canceled by user\n" red
                return 1
            }
            aie_get_global_mesh_params cur_mesh_params
            set gmax 0
            foreach {u v} [ ic_get_meshing_params global 0 ] {
                if {$u == "gmax"} {
                if {$v != ""} {set gmax $v}
                break
            }
        }
        set fam "inherited"
        if {$use_input == 2} { # Part by Part
            if {$geomParts == ""} {
                msg ERROR "No input geometry parts selected for shrinkwrap meshing"
                aie_no_autosizing
                return 1
            }

            catch {unset assembly_parts}
            set assemblies ""
            foreach part $geomParts {
                set surfs [ic_geo_get_objects surface $part]
                if ![llength $surfs] {
                    mess "Warning: Part $part doesn't contain any surfaces\n" red
                    continue
                }
                set asmly [lindex [split $part /] 0]
                if {[lsearch $assemblies $asmly] < 0} {
                    lappend assemblies $asmly
                    set assembly_parts($asmly) ""
                }
                lappend assembly_parts($asmly) $part
                set assemblies ""
                set parts $geomParts
                foreach part $parts {
                    set surfs [ic_geo_get_objects surface $part]
                    if ![llength $surfs] continue
                    set asmly [lindex [split $part /] 0]
                    if {[lsearch $assemblies $asmly] < 0} {
                        lappend assemblies $asmly
                    }
                    set part_by_part 1
                    set nruns [llength $assemblies]
                }
            }
        } else {
            set part_by_part 0
            set nruns 1
        }

        set force_load 0
        set temp_c3dshrink_file temp_c3dshrink.tin
        for {set ii 0} {$ii < $nruns} {incr ii} {
            if {$use_input == 3} { # selected
                ic_save_tetin $temp_c3dshrink_file 0 0 "" $geomEnts
                set tetinFN $temp_c3dshrink_file
                set force_load 1
            } elseif {$use_input == 2} { # part by part
                set input_ents ""
                set asmly  [lindex $assemblies $ii]
                mess "\n******* Meshing Assembly: $asmly **********\n"
                foreach part $assembly_parts($asmly) {
                    # surfaces and attached curves and points
                    foreach surf [ic_geo_get_objects surface $part] {
                        lappend input_ents surface $surf
                        foreach curve [ic_geo_boundary surface $surf] {
                            lappend input_ents curve $curve
                            foreach point [ic_geo_boundary curve $curve] {
                                lappend input_ents point $point
                            }
                        }
                    }

                    #curves and attached points
                    foreach curve [ic_geo_get_objects curve $part] {
                        lappend input_ents curve $curve
                        foreach point [ic_geo_boundary curve $curve] {
                            lappend input_ents point $point
                        }
                    }

                    # points
                    foreach point [ic_geo_get_objects point $part] {
                        lappend input_ents point $point
                    }
                }
                set temp_c3dshrink_file temp_c3dshrink.tin
                ic_save_tetin $temp_c3dshrink_file 0 0 "" $input_ents
                set tetinFN $temp_c3dshrink_file
                set force_load 1
            } elseif {$use_input == 1} { #visible
                if {![ic_geo_num_visible_objects surface 1]} {
                    msg ERROR "No surfaces are visible"
                    aie_no_autosizing
                    return 1
                }
                ic_save_tetin $temp_c3dshrink_file 1
                set tetinFN $temp_c3dshrink_file
                set force_load 1
            } elseif {($file_name(tetin) == "") || ([ic_geo_is_modified])} {
                ic_save_tetin $temp_c3dshrink_file
                set tetinFN $temp_c3dshrink_file
            } else {
                set tetinFN $file_name(tetin)
            }
            if {($tetinFN == "") } {
                msg ERROR  "No geometry file loaded\n"
                aie_no_autosizing
                return 1
            }
            set size $gmax

            ic_undo_suspend
            set mtype 0
            switch $mesh_type {
                "Quad Dominant" {set mtype 0}
                "All Tri" {set mtype 1}
                "All Quad" {set mtype 2}
                default {
                    mess "Warning: Mesh type: $mesh_type not supported for shrinkwrap.  Setting mesh type as Quad Dominant.\n" red
                }
            }
            busy reset
            ic_hexcart_shrinkwrap $tetinFN $size \
                $cur_mesh_params(shrinkwrap_projfactor) \
                $cur_mesh_params(shrinkwrap_nsmooth) $fam $force_load \
                $mtype
            ic_undo_resume
            aie_create_initial_assemblies

            catch {file delete $temp_c3dshrink_file}
        }
        aie_no_autosizing
    }
    }
    if {[aie_active_dez] != "meshAutoDEZ"} {
        # if called from Surface/Curve Mesh Size reset
        set bunch_respect $reset_bunch_respect
        set mesh_method $reset_mesh_method
    }
    aie_connectors_exec
    if ![::AIEnv::GUIManagement::Tree::GetVisibility shell] {
        ::AIEnv::GUIManagement::Tree::ToggleMeshVisible meshShellNode
    }
    ic_uns_families_changed
    if !$err_code {
        switch $mesh_method {
            "Patch Dependent" {
                if ![info exists skip_mess] {
                    mess "Surface Meshing completed\n" blue
                } else {
                    unset skip_mess
                }
            }
            default {
                mess "Surface Meshing completed\n" blue
            }
        }
    }
    busy reset
    return $err_code
}

proc onmeshAutoVolumeLoad {} {
    meshAutoDEZ aie_set_automesh_input
}

proc onmeshTetraOctLoad {} {
    meshAutoDEZ aie_set_automesh_input
}

proc aie_update_octree_grey {} {
    global env
    
    if { [info exists tetra_method] && $tetra_method == 0} {
        if {$tetra_input == 3} {
            ::AIEnv::GUIManagement::ToggleGrey meshTetOctLoad 0
        } else {
            ::AIEnv::GUIManagement::ToggleGrey meshTetOctLoad 1
	    }
	    if {$tetra_input == 0} {
	        if [meshAutoDEZ get meshTetUseExistVal] {
	            set off 0
	        } else {
	            set off 1
	        }
	    } else {
	        set off 1
	    }
	    ::AIEnv::GUIManagement::ToggleGrey meshTetOctUseMeshParts $off
	    if {$tetra_input == 1} {
	        if [meshAutoDEZ get meshTetUseExist2Val] {
	            set off 0
	        } else {
	            set off 1
	        }
	    } else {
	        set off 1
	    }
	    ::AIEnv::GUIManagement::ToggleGrey meshTetOctUseMeshParts2 $off
        # if {[info exists env(AI_ENV_CFD)] && [info exists env(AI_ENV_PRISM)]}
        # Prism can be available for FEA
        if {[info exists env(AI_ENV_PRISM)]} {
	        if {$tetra_input == 3} {
	            set run_prism 0
	            ::AIEnv::GUIManagement::ToggleGrey meshTetOctPrism 1
	        } else {
	            if {[ic_geo_is_loaded] && [ic_geo_get_objects surface] != ""} {
		            ::AIEnv::GUIManagement::ToggleGrey meshTetOctPrism 0
                }
            }
	    }
    }
}

proc onmeshTetOctAllLoad {} {
    meshAutoDEZ aie_update_octree_grey
}

proc onmeshTetOctVisLoad {} {
    meshAutoDEZ aie_update_octree_grey
}

proc onmeshTetOctPartLoad {} {
    meshAutoDEZ aie_update_octree_grey
}

proc onmeshTetOctBatchLoad {} {
    meshAutoDEZ aie_update_octree_grey
}

proc aie_compute_tetra_octree_mesh {} {
    global file_name tdv_default options aie_meshDisplay is_win
    global fam_visible options env

    if {![info exists run_prism]} {set run_prism 0}
    # if running prism or advancing front inflation check for prism families
    if {$run_prism && [catch {aie_check_prism_params Tetra} msg]} {
	    msg ERROR $msg
	    return
    }

    # check if an application is already running
    if [aie_check_application_running] return

    set temp_tetra_file temp_tetra.tin
    set existing_mesh_file ""
    set is_modified [ic_geo_is_modified]

    aie_get_global_mesh_params cur_mesh_params

    set is_batch $cur_mesh_params(tetra_batch)
    set nruns 1
    set part_by_part 0
    set assemblies ""
    set input_ents ""
    set tetinFN $file_name(tetin)
    set meshFN [file join $file_name(domains_dir) tetra_mesh.uns]
    set vis_geom 0
    set surf_mesh_only 0
    set load_mesh 1
    set use_surf 0
    set from_file 0

    switch $tetra_input {
	    0 { #"All"
	    
	    }
	    1 { #"Visible"
            if {![ic_geo_num_visible_objects surface 1]} {
                msg ERROR "No surfaces are visible."
                return
            }
	        set vis_geom 1
	    }
	    2 { #"Part by Part"
	        if {$geomParts == ""} {
		        msg ERROR "No input geometry parts selected for tetra meshing"
		        return
	        }

	        catch {unset assembly_parts}
	        set assemblies ""
	        foreach part $geomParts {
		        set surfs [ic_geo_get_objects surface $part]
		        if ![llength $surfs] {
		            mess "Warning: Part $part doesn't contain any surfaces\n" red
		            continue
		        }
		        set asmly [lindex [split $part /] 0]
		        if {[lsearch $assemblies $asmly] < 0} {
		            lappend assemblies $asmly
		            set assembly_parts($asmly) ""
		        }
		        lappend assembly_parts($asmly) $part
	        }

	        set part_by_part 1
	        set nruns [llength $assemblies]
	        if {$nruns == 0} {
		        msg ERROR "No parts containing surfaces found."
		        return
	        }
	    }
	    3 { #"From File"
	        if {$tetinFile == ""} {
		        msg ERROR "No input geometry file selected."
		        return
	        }
            if {![file exists $tetinFile]} {
                msg ERROR "geometry input file $tetinFile does not exist"
                return
            }
	        set is_batch 1
            set from_file 1
	        set load_mesh $loadFlag
	    }
    }
    if {$meshTetUseExistVal || $meshTetUseExist2Val} { # from existing
	    if {$useMeshParts == ""} {
	        msg ERROR "No existing mesh part specified. Please run \"Tetra from Geometry\" if you don't have any existing mesh."
	        return
	    }
	    if ![ic_uns_is_loaded] {
	        mess "Error: No existing mesh available to use.\nPlease load the mesh first.\n" red
	        return
	    }
        if $vis_geom {
            set count 0
	        foreach fam $useMeshParts {
		        if {$fam_visible($fam)} {
		            incr count
		        }
	        }
            if {!$count} {
                mess "Warning: No existing mesh parts are visible.\n" red
            }
	    }
	    set use_surf 1
    }

    # don't do auto sizing if from file - ONYX 45986
    if {!$from_file && [aie_autosizing tetra 1]} {
        mess "Canceled by user\n" red
        return
    }
    set found_live 0
    if {!$from_file && [ic_geo_is_loaded]} {
	    foreach mat [ic_geo_get_objects body] {
	        if {[ic_geo_get_family body $mat] != "ORFN"} {
		        if {!$vis_geom || [ic_geo_get_visibility body $mat]} {
		            incr found_live
		        }
	        }
	    }
    }

    if {[ic_uns_is_loaded] && !$use_surf && (!$is_batch || $load_mesh)} {
        set opt [tk_dialog .unsOverwrite "Mesh Exists" "Mesh Already Exists" "" 1 "Merge" "Replace" "Cancel"]
        if {$opt == -1} { if [winfo exists .unsOverwrite] { top_destroy .unsOverwrite; aie_no_autosizing; return } }
        if {$opt == 0} {
            set existing_mesh_file [cmd_tempfile temp_tetra .uns]
            ic_save_unstruct $existing_mesh_file
        } elseif {$opt == 2} {
            aie_no_autosizing
            return
        } elseif {$opt == 1 && $tetra_input != 3} {
            ic_unload_mesh
            aie_delete_empty_parts
        }
    }

    # no busy during tetra process
    # can't seem to terminate process with busy set
    busy reset
    set errors 0
    for {set ii 0} {$ii < $nruns} {incr ii} {
	    if $part_by_part {
	        set input_ents ""
	        set asmly  [lindex $assemblies $ii]
	        mess "\n******* Meshing Assembly: $asmly **********\n"
	        foreach part $assembly_parts($asmly) {
		        # surfaces and attached curves and points
		        foreach surf [ic_geo_get_objects surface $part] {
		            lappend input_ents surface $surf
		            foreach curve [ic_geo_boundary surface $surf] {
			            lappend input_ents curve $curve
			            foreach point [ic_geo_boundary curve $curve] {
			                lappend input_ents point $point
			            }
		            }
		        }
		        # curves and attached points
		        foreach curve [ic_geo_get_objects curve $part] {
		            lappend input_ents curve $curve
		            foreach point [ic_geo_boundary curve $curve] {
			            lappend input_ents point $point
		            }
		        }
		        # points
		        foreach point [ic_geo_get_objects point $part] {
		            lappend input_ents point $point
		        }

		        # mat points
		        foreach body [ic_geo_get_objects body $part] {
		            lappend input_ents body $body
		        }
	        }
	        ic_save_tetin $temp_tetra_file 0 0 "" $input_ents
	        set tetinFN $temp_tetra_file
	    } elseif $vis_geom {
	        ic_save_tetin $temp_tetra_file 1
	        set tetinFN $temp_tetra_file
	    } elseif $from_file {
	        set tetinFN $tetinFile
	    } elseif {($file_name(tetin) == "") || (![file exists $file_name(tetin)]) || ($is_batch && [ic_geo_is_modified])} {
	        ic_save_tetin $temp_tetra_file
	        set tetinFN $temp_tetra_file
	    } else {
	        set tetinFN $file_name(tetin)
	    }

	    if {($tetinFN == "") || (![file exists $tetinFN])} {
	        aie_no_autosizing
	        ic_geo_set_modified $is_modified
	        if [file exists $temp_tetra_file] {cmd_rm $temp_tetra_file}
            if {$existing_mesh_file != ""} {cmd_rm $existing_mesh_file}
            busy reset
	        msg ERROR  "No geometry file loaded\n"
	        return
	    }

	    if $is_win {
	        set cmd [list ic_run_tetra [win_shortname $tetinFN] [win_shortname [file dirname $meshFN]]/[file tail $meshFN]]
	    } else {
	        set cmd [list ic_run_tetra $tetinFN $meshFN]
	    }

	    # load only some geometry in process
	    if {!$is_batch && $tetra_input != 0} {
	        append cmd " input_geometry  \"$tetinFN\""
	    }
	    append cmd " run_cutter 1 delete_auto 1"

	    if { $cur_mesh_params(tetra_fix_nmanifold) == 0 } {append cmd " fix_non_manifold 0"}
	    if { $cur_mesh_params(tetra_close_gaps) } {append cmd " closegaps 1"}
	    if { $cur_mesh_params(tetra_save_tris) } {
	        append cmd " save_all_triangles 1"
	        set surf_mesh_only 1
        }

        set csys [ic_csystem_get_current]
        if $cur_mesh_params(tetra_use_active_lcs) {
            if {$csys == "global"} {
                mess "Warning: although the option is turned on,\n" red
                mess "         no local coordinate system is active.\n" red
                mess "         Global system is used for tetra-octree mesh\n" red
            } else {
                append cmd " use_local_csystem $csys"
            }
        }
    
	    if $use_surf {
	        set fm temp_trimesh.uns
	        cmd_rm $fm
	        ic_save_unstruct $fm 1 "" "" $useMeshParts
	        foreach fam $useMeshParts {
		        if {$vis_geom && !$fam_visible($fam)} {
		            continue
		        } else {
		            append cmd " use_existing \"$fam,$fm\""
		        }
	        }
	    }

	    # Don't smooth or coarsen in Tetra process, since if Tetra leaks you are wasting time, 
	    # let's do this after loading mesh.
	    if $surf_mesh_only {
	        if $cur_mesh_params(tetra_smooth) {
		        append cmd " n_tri_smoothing_steps $cur_mesh_params(tetra_smooth_niter)"
	        }
	        append cmd " write_volume 0"
	    }
	    if {$cur_mesh_params(tetra_coarsen) && $is_batch} {
	        append cmd " run_coarsener 1 coarsen_aspect $cur_mesh_params(tetra_coarsen_aspect) n_coarsen_iter $cur_mesh_params(tetra_coarsen_niter)"
	    }
        # need to smooth in batch process, since from file tetin may be
        # different than the current geometry - Onyx 50950
	    if {$from_file || ($is_batch && !$load_mesh)} {
	        if $cur_mesh_params(tetra_smooth) {
		        append cmd " run_smoother 1 n_tri_smoothing_steps $cur_mesh_params(tetra_smooth_niter)"
		        append cmd " smoother_n_iter  $cur_mesh_params(tetra_smooth_niter) smoother_aspect $cur_mesh_params(tetra_smooth_aspect)"
	        }
            set did_smoothing 1
	    } else {
	        append cmd " run_smoother 0"
            set did_smoothing 0
	    }
    	append cmd " fix_holes $cur_mesh_params(tetra_fix_holes)"

	    if { [ info exists options(n_processors) ] &&  $options(n_processors) != "" } {
	        append cmd " n_processors $options(n_processors)"
	    }
	    if $is_batch {
	        append cmd " show_progress 1"
	    } else {
	        append cmd " in_process 1"
	    }

	    if { $part_by_part || $found_live == 0 } {
	        append cmd " auto_vol 1"
	    } else {
            # don't use auto_orphan - if tetra leaks and cutter finds an interior
            # closed volume, then all other surface elements will be deleted.
            # Maybe we should enable this if fix_holes (do_repair) is enabled
    #	    append cmd " auto_orphan 1"
	    }
        if [info exists env(TETRA_ADVANCED_OPTS)] {
            append cmd " run_cutter $cur_mesh_params(tetra_run_cutter)"
            append cmd " save_all_triangles $cur_mesh_params(tetra_save_tris)"
            append cmd " auto_orphan $cur_mesh_params(tetra_auto_orphan)"
            append cmd " parallel_verbose $cur_mesh_params(tetra_parallel_verbose)"
        }

	    set logfile tetra_cmd.log
	    if $is_win {
	        set logfile [win_shortname [file dirname $logfile]]/[file tail $logfile]
	    }
	    append cmd " log $logfile"

	    # Remove tetra_mesh.uns if it exists already
	    if [file exists $meshFN] {cmd_rm $meshFN}
	    if [file exists tetra_mesh${ii}.uns] {cmd_rm tetra_mesh${ii}.uns}
	    # Mesh
	    mess "Running tetra\n" blue
	    if [catch {eval $cmd} ok] {set ok 0}

	    if $use_surf {
	        cmd_rm temp_trimesh.uns
	    }
	    if {!$ok} {
	        aie_no_autosizing
	        ic_geo_set_modified $is_modified
	        if [file exists $temp_tetra_file] {cmd_rm $temp_tetra_file}
                if {$existing_mesh_file != ""} {
                    ic_load_unstruct $existing_mesh_file
                    cmd_rm $existing_mesh_file
                }
	            busy reset
	            return
	        }
	        if {$is_batch && ![file exists $meshFN]} {
	            aie_no_autosizing
	            ic_geo_set_modified $is_modified
	            if [file exists $temp_tetra_file] {cmd_rm $temp_tetra_file}
	            busy reset
	            return
	        }

	        # check for fixed.
	        set lf [ open $logfile ]
	        set fixed 0
	        while { ![eof $lf ] } {
	            set line [ gets $lf ]
	            if [ string match "*it appears the material point is located*" $line ] {
		        set fixed 1
		        break
	        }
	    }
	    close $lf
	    if { $fixed == 0 } {
	        # check for errors
	        set lf [ open $logfile ]
	        while { ![eof $lf] } {
		        set line [ gets $lf ]
		        if [ string match "*can reach material*" $line ] {
		            set line2 [ gets $lf ]
		            if [ string match "*check display*" $line2 ] {
			            incr errors
		            }
		        }
	        }
	        close $lf
	    }
	    if $part_by_part {
	        ic_save_unstruct tetra_mesh${ii}.uns
	    }
    }

    if $part_by_part {
        ic_unload_mesh
	    for {set ii 0} {$ii < $nruns} {incr ii} {
	        ic_load_unstruct tetra_mesh${ii}.uns
            cmd_rm tetra_mesh${ii}.uns
	    }
    }

    if {$is_batch && $load_mesh} {
	    ic_unload_mesh
	    ic_uns_load [list $meshFN]
    }

    if {$existing_mesh_file != ""} {
        ic_load_unstruct $existing_mesh_file
        cmd_rm $existing_mesh_file
    }

    aie_no_autosizing
    ic_geo_set_modified $is_modified

    if [file exists $temp_tetra_file] {cmd_rm $temp_tetra_file}
    if {!$load_mesh && $is_batch} {
	    mess "Created tetra mesh is saved in file: $meshFN\n" blue
	    aie_connectors_exec
	    busy reset
        return
    }

    if {$part_by_part} {
	    if [ic_uns_is_loaded] {
	        ic_save_unstruct $meshFN
	    } else {
	        busy reset
	        mess "No mesh was created.\n" red
	        return
	    }
    }

    if {!$is_batch || $load_mesh} {
            aie_initial_unsmesh_visibility 0
            aie_afterStuffLoaded 0
            aie_update_icons mesh
            if $surf_mesh_only {ic_save_unstruct $meshFN}
                set is_modified [ic_geo_is_modified]
        }
        
        foreach sub [ic_uns_subset_list] {
            if [ic_uns_subset_exists "$sub"] {
                aie_subset_put_in_tree mesh "$sub"
                mess "New mesh subset \"$sub\" created\n" blue
            }
        }

        if {$surf_mesh_only} {
	    if !$load_mesh {
	        mess "Created surface tri mesh is saved in file: $meshFN\n" blue
	    }
	    aie_connectors_exec
	    busy reset
	    return
    }

    # Onyx 42867 - cutter may not report any leaks, however there may
    # still be a hole in the surface mesh where interior tetrahedra
    # have not been generated by tetra. If everything is OK, there
    # should not be any single edges and the check for them is fast.

    # single edges would be valid if there are internal walls defined this
    set int_walls 0
    foreach f [ic_geo_list_families] {
	    if {[ic_geo_get_family_param $f internal_wall] == "1"} {
	        set int_walls 1
	        break
	    }
    }

    set single_edges 0
    if {!$errors && !$int_walls} {
        set single_diag [ic_uns_diagnostic diag_type single quiet 1]
        if {$single_diag != ""} {
            set single_edges [lindex $single_diag 0]
            if {$single_edges > 0} {incr errors}
        }
    }

    if {!$errors} {
        set fix_fams ""
        if $use_surf {
            set fix_fams $useMeshParts
        }
        
        set n_processors 1
        if { [ info exists options(n_processors) ] &&  $options(n_processors) != "" } {
            set n_processors $options(n_processors)
        }        

        if {!$did_smoothing && $cur_mesh_params(tetra_smooth)} {
	        mess "Smoothing surface mesh...\n" blue
	        ic_smooth_elements map all upto $cur_mesh_params(tetra_smooth_aspect) iterations \
		        $cur_mesh_params(tetra_smooth_niter) fix_families $fix_fams n_processors $n_processors \
                smooth TRI_3 float TETRA_4 laplace 1
	    }

	    # Run prism mesher if requested
	    set stat 0
	    if $run_prism {
	        ic_smooth_elements map all upto $cur_mesh_params(tetra_smooth_aspect) \
		        iterations $cur_mesh_params(tetra_smooth_niter) prism_warp_weight 0.5 \
		        fix_families $fix_fams n_processors $n_processors \
                        smooth TETRA_4 smooth TRI_3

	        if ![meshPrismDEZ isbuilt] {
		        meshPrismDEZ build
	        }
	        meshPrismDEZ set loadmesh $load_mesh
	        set stat [meshPrismDEZ apply]
	    }
        if {$run_hexacore && !$stat} {
	        meshAutoDEZ aie_compute_hexacore_mesh
	        set stat $hexacore_status
	    }

	    if {!$part_by_part && !$stat} {
	        # Marlow wanted to smooth TRI for prism meshing
	        # turned off as requested by Simon

	        if {$cur_mesh_params(tetra_smooth) && !$run_prism} {
		        ic_smooth_elements map all upto $cur_mesh_params(tetra_smooth_aspect) \
		            iterations $cur_mesh_params(tetra_smooth_niter) prism_warp_weight 0.5 \
		            fix_families $fix_fams n_processors $n_processors \
                            smooth TETRA_4 float PENTA_6 freeze TRI_3

                ic_smooth_elements map all upto $cur_mesh_params(tetra_smooth_aspect) \
                    iterations $cur_mesh_params(tetra_smooth_niter) prism_warp_weight 0.5 \
                    fix_families $fix_fams metric Quality n_processors $n_processors \
                    smooth TETRA_4 smooth TRI_3 float PENTA_6
	        }

	        if $cur_mesh_params(tetra_coarsen) {
		        ic_uns_coarsen all $cur_mesh_params(tetra_coarsen_aspect) \
		            {} 0.1 $cur_mesh_params(tetra_coarsen_niter) 0 0 ""
	        }
	    }
    }

    ic_geo_set_modified $is_modified
    if [ic_uns_is_loaded] {
	    aie_updateMeshVis
    }
    busy reset
    if {!$errors} {
        if [file exists $logfile] {
            rm_tmp_file $logfile
        }
        aie_connectors_exec
        return
    }

    set msg "Your geometry has a hole, do you want to repair it?"
    # can't do this test if cutter indicates a leak.
    # need to figure out some other way of determining if the
    # interior is covered by tetrahedra or not
    if {$single_edges} {
        set uncovered [ic_uns_diagnostic diag_type uncovered quiet 1]
        if {$uncovered != "" && [lindex $uncovered 0] > 0} {
            append msg "\n\nNOTE:There are missing internal tetrahedra."
            append msg "\nRecommend you keep only the shell mesh,"
            append msg "\nfix it, and then remesh the interior."
        }
    }

    # turn on single
    set aie_meshDisplay(single_edges) 1
    aie_changeMeshDisplay

    switch -- [ tk_dialog .tetra_load "Repair holes" $msg "" -1 Yes No "Only Shells" ] {
         -1 {
            if [winfo exists .tetra_load] { destroy .tetra_load }
            aie_connectors_exec; return 0
         }
		 0 { set keep_vol 1 }
		 1 { aie_connectors_exec; return 0 }
		 2 {
             # Delete all volume elements
			 set temp_subset [ic_uns_subset_create rrr]
			 ic_uns_subset_add_families_and_types $temp_subset [ic_uns_subset_list_families all] TETRA_4
			 ic_delete_elements subset $temp_subset
			 ic_uns_subset_delete $temp_subset
			 mess "Only shell elements are kept\n" blue
             set keep_vol 0
        }
	}

    # create material points
    if {!$is_batch && $keep_vol} {
        set lf [ open $logfile ]
        while { ![eof $lf ] } {
            set line [ gets $lf ]
            if [ string match "*adding new material point *" $line ] {
                set mtlname [lindex $line 4]
                if {[string first / $mtlname] >= 0} {
                    set mtlfam [lindex [split $mtlname /] 0]
                } else {
                    set mtlfam [lindex [split $mtlname .] 0]
                }
                set loc [string trim [lindex [split $line "\("] 1]]
                set mtlpnt [string range $loc 0 end-1]
                catch {ic_geo_cre_mat $mtlfam $mtlname $mtlpnt}
            }
            if [ string match "*removing material point *" $line ] {
                set mtlname [lindex $line end]
                catch {ic_delete_material $mtlname}
            }
        }
        close $lf
        # seems we need to call make consistent when using existing meshs
        if $use_surf {ic_uns_make_consistent all "" 0}
    }

    # repair leak
    set aie_meshDisplay(single_surfaces) 1
    if {$keep_vol} {
        aie_show_materials
        unstruct_flood_fill no_repair
    }
    aie_show_leaks

    # bring up repair form.
    if ![repairMeshDEZ isbuilt] {repairMeshDEZ build}
    repairMeshDEZ show
    repairMeshDEZ set KeepConsistentFlag $keep_vol
    repairMeshDEZ set elType "All Tri"
    repairMeshDEZ set repairMeshRGVal 4
    closeHoleMeshElemsPick pick
    aie_connectors_exec
}

proc onmeshTetraDelLoad {} {
    set family ""
    set meshall 0
    set floodfill 0
    set loadmesh 1
    set PartList [aie_list_parts 1]
    lappend PartList inherited
    meshAutoDEZ aie_set_automesh_input
}

proc onmeshTetraAdvLoad {} {
    set family ""
    set meshall 0
    set floodfill 0
    set loadmesh 1
    set PartList [aie_list_parts 1]
    lappend PartList inherited
    meshAutoDEZ aie_set_automesh_input
}

proc onmeshTetraTGridLoad {} {
    set family ""
    set meshall 0
    set floodfill 0
    set loadmesh 1
    set PartList [aie_list_parts 1]
    lappend PartList inherited
    meshAutoDEZ aie_set_automesh_input
}

proc aie_mesh_fill_volume {mesher {only_parts ""}} {
    global env beta_mode file_name options

    aie_get_global_mesh_params cur_mesh_params
    set temp_tetra_file __temp_tetra_[pid].tin
    foreach n {fillholes meshall floodfill verbose bgmesh tgrid_af} {
        set $n $cur_mesh_params(tetra_$n)
    }
    set mtls ""
    foreach fam [ic_list_volume_families] {
        if {$fam != "ORFN" && $fam != "VORFN"} {
            lappend mtls $fam
        }
    }
    set num_material_points [llength $mtls]
    if {$tetra_input == 3} {
        set meshIN $meshFile
    } else {
        set meshIN $file_name(domain)
    }

    set meshOUT [file join $file_name(project_dir) $mesher\_mesh.uns]
    set meshBACKUP ""
    if {[file exists $meshOUT]} {
        set meshBACKUP $meshOUT\_bak
        cmd_mv $meshOUT $meshBACKUP
        mess "Mesh file $meshOUT already exists! Will be moved to $meshBACKUP\n"
    }
    set error_subset $mesher\_errors

    catch {ic_uns_subset_delete $error_subset}
    set recreate_subsets [aie_mesh_tet_get_existing_subsets]

    if {($meshIN == "") || ![file exists $meshIN] || [ic_uns_is_modified]} {
        set tempfile [cmd_tempfile $mesher\_temp .uns]
        ic_save_unstruct $tempfile 1 {} {} $only_parts
        set meshIN $tempfile
    } else {
        set tempfile ""
    }

    if $is_win {
        if {$mesher != "tgrid"} {
            set cmd [list ic_run_$mesher [win_shortname $meshIN] [win_shortname [file dirname $meshOUT]]/[file tail $meshOUT]]
        } else {
            set cmd [list ic_run_fieldmesher [win_shortname $meshIN] [win_shortname [file dirname $meshOUT]]/[file tail $meshOUT]]
        }
    } else {
        if {$mesher != "tgrid"} {
            set cmd [list ic_run_$mesher $meshIN $meshOUT]
        } else {
            set cmd [list ic_run_fieldmesher $meshIN $meshOUT]
        }
    }

    if {$mesher == "afmesh"} {
        append cmd " geometry 0 proximity $cur_mesh_params(tetra_proximity_check)"
    } else {
        if {$mesher != "tgrid"} {
            if $fillholes {
                append cmd " fillholes 1"
            }
            append cmd " safety $cur_mesh_params(tetra_memory_scale)"
            if $meshall {
                append cmd " keepall 1"
            }
        } else {
            if {($temp_tetra_file != "" && [ic_geo_is_loaded])} {
                ic_save_tetin $temp_tetra_file
                append cmd " tetin $temp_tetra_file"
            }
        }
        if [info exists env(TRI2TET_DEBUG)] {
            if {$singlefamily} {append cmd " singlefamily 1"}
            if {$output != ""} {append cmd " output $output"}
            if {$OFFfile != ""} {append cmd " offfile $OFFfile"}
        }
    }

    if {$mesher == "tri2tet"} {
        set expansion_factor $cur_mesh_params(tetra_spacing_factor)
        set run_adv_delaunay $cur_mesh_params(tetra_run_adv_delaunay)
        if $run_adv_delaunay {
            append cmd " use_tg_tri2tet 1"
            set tg_adv_delaunay_af $cur_mesh_params(tetra_tg_adv_delaunay_af)
            if $tg_adv_delaunay_af {
                append cmd " use_tg_tgrid_af 1"
            }
        }
    } else {
        set expansion_factor $cur_mesh_params(tetra_expansion_factor)
    }
    if {$expansion_factor != ""} {
        append cmd " tetexpand $expansion_factor"
    }
    
    catch { unset floodfill_inherited; unset floodfill_overwrite }
    if {$mesher != "tgrid"} {
        set vfam $family
        if {$vfam == "inherited"} {
            set vfam [lindex $mtls 0]
            if {$vfam != ""} {
                if !$floodfill {
                    set floodfill 1
                    set floodfill_inherited 1
                }
            }
        }
        if {$vfam == ""} {
            set vfam CREATED_MATERIAL
        } else {
            if {$family != "inherited" && $floodfill} {
                set floodfill_overwrite 1
            }
        }
        set vfam [aie_new_part $vfam]

        append cmd " family $vfam"
        append cmd " bgmesh $cur_mesh_params(tetra_bgmesh)"
    } else {
        if {$family == "inherited"} {
            if {!$floodfill && $num_material_points} {
                set floodfill 1
                set floodfill_inherited 1
            }
        } else {
             if {$floodfill && $num_material_points} {
                set floodfill_overwrite 1
            }
        }
    }
	
    if {$mesher == "tgrid" && $frozenMeshVolParts != ""} {
        append cmd " tgrid_frozen_parts \{$frozenMeshVolParts\}"
    }

    if {$mesher == "tgrid" && $run_tgrid_hexacore} {
        append cmd " tgrid_hexacore 1"
    }

    if {$mesher == "tgrid" && $run_tgrid_interactive} {
        append cmd " tgrid_interactive 1"
    }

    if {$mesher == "tgrid" && $run_tgrid_inflation} {
        if {[ic_count_elements 3d] == 0 && ![llength [ic_geo_get_objects material]]} {
            mess "Pre Inflation (Fluent Meshing) Error: No volume elements found and no material point found. Pre Inflation needs either a volume input\
            mesh or a material point\n" red
            return
        }
        append cmd " tgrid_prism 1"
        if [mszGlobalDEZ get tgrid_n_ortho_layers] {
            append cmd " tgrid_n_ortho_layers [mszGlobalDEZ get tgrid_n_ortho_layers]"
        }
        if [mszGlobalDEZ get tgrid_fix_first_layer] {
            append cmd " tgrid_fix_first_layer 1"
        }
        set tgrid_gap_factor [mszGlobalDEZ get tgrid_gap_factor]
        if {$tgrid_gap_factor >= 0.0 && $tgrid_gap_factor <= 2.0} {
            append cmd " tgrid_gap_factor $tgrid_gap_factor"
        }
        if [mszGlobalDEZ get tgrid_enhance_norm_comp] {
            append cmd " tgrid_enhance_norm_comp 1"
        }
        if [mszGlobalDEZ get tgrid_enhance_offset_comp] {
            append cmd " tgrid_enhance_offset_comp 1"
        }
        set tgrid_smoothing_level2 1
        switch [mszGlobalDEZ get tgrid_smoothing_level] {
            Low { set tgrid_smoothing_level2 0 }
            Medium { set tgrid_smoothing_level2 1 }
            High { set tgrid_smoothing_level2 2 }
        }
        append cmd " tgrid_smoothing_level $tgrid_smoothing_level2"
        set tgrid_max_cap_skew [mszGlobalDEZ get tgrid_max_cap_skew]
        if {$tgrid_max_cap_skew >= 0.0 && $tgrid_max_cap_skew <= 1.0} {
            append cmd " tgrid_max_cap_skew $tgrid_max_cap_skew"
        }
        set tgrid_max_cell_skew [mszGlobalDEZ get tgrid_max_cell_skew]
        if {$tgrid_max_cell_skew >= 0.0 && $tgrid_max_cell_skew <= 1.0} {
            append cmd " tgrid_max_cell_skew $tgrid_max_cell_skew"
        }
        set tgrid_last_layer_aspect [mszGlobalDEZ get tgrid_last_layer_aspect]
        if {([string is double -strict $tgrid_last_layer_aspect] || [string is integer -strict $tgrid_last_layer_aspect]) && \
            $tgrid_last_layer_aspect > 0} {
            append cmd " tgrid_last_layer_aspect $tgrid_last_layer_aspect"
        }
    }

    if {$mesher == "tgrid"} {
        append cmd " use_fluent 1"
    }

    append cmd " show_progress 1"
    append cmd " errors $error_subset"
    append cmd " verbose $verbose"

    if {$only_parts != ""} {
        mess "*********** Meshing Part: $only_parts ************\n"
    }
    if {$mesher == "tri2tet"} {
        mess "Running delaunay mesher...\n" blue
    } elseif {$mesher == "afmesh"} {
        mess "Running advancing front mesher...\n" blue
    } elseif {$mesher == "tgrid"} {
        if {[meshAutoDEZ get run_tgrid_inflation] == 1} {
            mess "Running Fluent Meshing with Pre Inflation via the FieldMesher-Python-ExtensionModule...\n" blue
        } elseif {[meshAutoDEZ get run_prism] == 1} {
            mess "Running Fluent Meshing with Post Inflation via the FieldMesher-Python-ExtensionModule...\n" blue
        } else {
            mess "Running Fluent Meshing via the FieldMesher-Python-ExtensionModule...\n" blue
        }
    } 

    if {[eval $cmd] && [file exists $meshOUT]} {
        if {$loadmesh || ($tetra_input == 0 && $mesher == "tri2tet")} {
            set file_name(domain) $meshOUT
            if {$only_parts != ""} {
                ic_delete_elements family $only_parts
                ic_load_unstruct $meshOUT
            } else {
                aie_close_Mesh 0
                ic_uns_load \"$meshOUT\" 3 1 {} 0
            }
            aie_afterStuffLoaded 0
            set nelems [expr \
                        [ic_count_elements quad] + \
                        [ic_count_elements pyra] + \
                        [ic_count_elements penta] + \
                        [ic_count_elements hexa]]
            if {$nelems > 0 && [ic_create_pyramids]} {
                aie_updateMeshVis
                unstruct_consistent "" 0
            }
            
            if {$mesher == "tri2tet"} {
                if {[info exists cur_mesh_params(tetra_smooth2)] && $cur_mesh_params(tetra_smooth2)} {
                    mess "Smoothing surface mesh...\n" blue
                    ic_smooth_elements map all upto $cur_mesh_params(tetra_smooth_aspect2) iterations \
                        $cur_mesh_params(tetra_smooth_niter2) n_processors $options(n_processors) \
                        smooth TETRA_4 smooth TRI_3 float PENTA_6 
                }
            }
            if {$floodfill && ($mesher == "tri2tet" || $mesher == "afmesh" || $mesher == "tgrid") && $num_material_points > 0} {
                set only_mat 0
                if [info exists floodfill_overwrite] {
                    mess "Global flood fill overrides given Volume part name \"$family\" (for material points)\n" blue
                    unset floodfill_overwrite
                    set only_mat 1
                }
                if [info exists floodfill_inherited] {
                    mess "Volume part name \"inherited\" runs flood fill (only for material points)\n" blue
                    unset floodfill_inherited
                    set only_mat 1
                }
                set num_real_mat_points [llength [ic_uns_list_material_families]]
                mess "Number of material points: $num_real_mat_points\n" blue
                if {!$num_real_mat_points && $meshall} {
                    unstruct_flood_fill autovol
                    aie_delete_materials
                } else {
                    ic_flood_fill_mesh 0 $only_mat
                }
            } elseif {$floodfill && ($mesher == "tri2tet" || $mesher == "tgrid") && $num_material_points == 0 && $family == "inherited"} {
                if {[ic_uns_list_material_families] == "" && ![info exists floodfill_inherited]} {
                    mess "Global \"Flood fill\" and Volume part name \"inherited\" runs flood fill without existing material point\n" blue
                    unstruct_flood_fill autovol
                    aie_delete_materials
                }
            }
            aie_create_initial_assemblies
        } else {
            mess "Created $mesher mesh is saved in file: $meshOUT\n" blue
        }
        if {$verbose && $mesher == "tgrid"} { mess "Current work around for Fluent Meshing: create line and node elements:\n" }
        set build_mesh_topo 1
        if {$build_mesh_topo && $mesher == "tgrid"} {
            mess "Create nodes and bars from topology...\n"
            set meshtopoang 27.0
            if ![repairGeomDEZ isbuilt] {
                repairGeomDEZ build
            }
            set geomtopoang [repairGeomDEZ get topoang]
            if {$geomtopoang > 0.0 && $geomtopoang < 90.0} {
                set meshtopoang [expr 0.9 * $geomtopoang]
            }
            set newfam "__TEMP_PTS_CRVS__"
            ic_uns_build_mesh_topo all -new_element_family $newfam -create_bars_family_intersection
            ic_uns_build_mesh_topo all -angle [expr 180 - $meshtopoang] -new_element_family $newfam -uncovered_element_family $newfam
            mess "Update node and bar associations...\n"
            set fams [ic_geo_list_families]
            set node_line_map [ic_uns_subset_create_family_type $fams {NODE LINE_2} 1 0 0]
            ic_uns_set_projected_family $node_line_map
            ic_uns_subset_delete $node_line_map
            mess "Remove nodes/lines that are not on points/curves...\n"
            ic_delete_elements family $newfam
        }
    } else {
        mess "No $mesher mesh generated!\n" red
        if {$meshBACKUP != "" && [file exists $meshBACKUP]} {
            cmd_mv $meshBACKUP $meshOUT 
            mess "Backed up mesh $meshBACKUP moved back to $meshOUT\n"
        }
    }


    if {$tempfile != ""} { cmd_rm $tempfile }
    if {$mesher == "tgrid"} {
        if {$temp_tetra_file != "" && [file exists $temp_tetra_file]} { 
            cmd_rm $temp_tetra_file
        }
    }
    set errors ""
    if [ic_uns_subset_exists $error_subset] {
        aie_subset_put_in_tree mesh $error_subset
        set errors $error_subset
    }

    return $errors
}

proc aie_compute_tetra_mesh {method} {
    global file_name env
    global is_win prism_values

    set existing_volume_fams [ic_list_volume_families]
    set num_material_points [llength $existing_volume_fams]
    if {([info exists prism_values]) && $prism_values(new_volume) != ""} {
        lappend existing_volume_fams $prism_values(new_volume)
    }

    set mesher ""
    switch $method {
        "octree" {
            return [meshAutoDEZ aie_compute_tetra_octree_mesh]
        }
        "delaunay" {
            set mesher tri2tet
        }
        "advfront" {
            set mesher afmesh
        }
        "tgrid" {
            set mesher tgrid
        }
    }

    if ![info exists run_prism] { set run_prism 0 }
    if ![info exists run_tgrid_inflation] { set run_tgrid_inflation 0 }

    # from file
    if {$tetra_input == 3} {
        if {$meshFile == "" || ![file exists $meshFile]} {
            msg ERROR "No existing mesh file given"
            return
        }
        set create_surfmesh 0
        # if not loading mesh disable prism/hexacore
        if {!$loadmesh} {
            set run_prism 0
            set run_hexacore 0
        }
    }

    # if running prism check for prism families
    if {$run_prism && [catch {aie_check_prism_params $mesher} msg]} {
        msg ERROR $msg
        return
    }

    if {$run_tgrid_inflation && $mesher == "tgrid" && [catch {aie_check_prism_params $mesher} msg]} {
        msg ERROR $msg
        return
    }

    # check if an application is already running
    if [aie_check_application_running] return

    set nrun_parts ""
    if {$tetra_input == 2} { # enclosed parts
        if {$enclosedParts == ""} {
            msg ERROR "No enclosed part selected"
            return
        }
        set geomParts ""
        set nrun_parts $enclosedParts
        foreach part $enclosedParts {
            set count [ic_uns_count_elements_in_family $part]
            if {!$count} {
                lappend geomParts $part
            }
        }

        if [llength $geomParts] {
            set create_surfmesh 1
        } else {
            set create_surfmesh 0
        }
    }

    # check if mesh exists
    if $create_surfmesh {
        if {$tetra_input == 0 && ([ic_uns_is_loaded])} {
            ic_unload_mesh
        }
        meshAutoDEZ onmeshAutoSurfLoad
        set stat [meshAutoDEZ aie_compute_surface_mesh tetra]
        if $stat {
            mess "Surface meshing failed\n" red
            return
        }
    }

    if {$tetra_input != 3 && ![ic_uns_is_loaded]} {
        msg ERROR "Please Load/Generate Surface Mesh first"
        return
    }

    # run delaunay/adv. front
    # Don't run this for hexacore since it's going to throw away volume mesh anyway
    # Delaunay can mesh the whole domain at once
    set errors ""
    set recreate_subsets ""
    if {$nrun_parts != ""} {
        set nruns [llength $nrun_parts]
    } else {
        set nruns 1
    }

    # can't seem to terminate process with busy set
    busy reset
    for {set ii 0} {$ii < $nruns} {incr ii} {
        set ipart [lindex $nrun_parts $ii]
        if {$method == "delaunay"} {
            if { (!$run_hexacore) || ($num_material_points > 1 && ![ic_count_elements tetra]) || ($run_prism && ![ic_count_elements quad])} {
                set errors [meshAutoDEZ aie_mesh_fill_volume $mesher $ipart]
            }
        } else {
            set errors [meshAutoDEZ aie_mesh_fill_volume $mesher $ipart]
        }
    }
    # Run prism mesher if requested
    if {$errors == "" && $run_prism} {
        if ![meshPrismDEZ isbuilt] {
            meshPrismDEZ build
        }
        meshPrismDEZ set loadmesh $loadmesh
        meshPrismDEZ apply
    }
    set prism_values(new_volume) ""
    if {$errors == "" && $mesher == "tri2tet" && $run_hexacore} {
        if {$tetra_input == 3 && $method == "delaunay" && $loadmesh} {
            mess "Using mesh file $meshFile\n" 
            if [ic_uns_is_loaded] {
                ic_unload_mesh 1
            }
            ic_uns_load [list $meshFile] 3 1
        }
        meshAutoDEZ aie_compute_hexacore_mesh
        if $loadmesh {
            aie_create_parts_in_tree_if_needed
            aie_update_parts_in_tree_if_needed
        }
    }
    aie_create_initial_assemblies
    aie_connectors_exec

    if {$errors == "" && $recreate_subsets != ""} {
        aie_mesh_tet_reset_existing_subsets $recreate_subsets
    }
    busy reset
}

proc onmeshAutoPrismLoad {} {
    global env load_only_prism_params prism_parts prism_values

    if {[ic_geo_is_loaded] && [ic_geo_get_objects surface] == ""} {
        set msg "No surfaces in geometry."
        if [ic_uns_is_loaded] {
            append msg " Load appropriate geometry or convert the mesh to facets."
        }
        msg ERROR "$msg before running prism"
        return
    }

    if ![meshPrismDEZ isbuilt] {
	    meshPrismDEZ build
    }

    set loadmesh 1
    if [ic_uns_is_loaded] {
        set prism_input 0
    } else {
        set prism_input 1
    }
    
    # prism values
    aie_load_prism_params
    foreach i {init_dir_from_prev \
	    min_prism_quality ortho_weight fillet max_prism_angle \
	    max_aspect_ratio prism_height_limit ratio_multiplier \
	    new_volume side_family top_family into_orphan \
		n_triangle_smoothing_steps triangle_quality n_tetra_smoothing_steps \
		smoothing_steps first_layer_smoothing_steps} {
	    set $i $prism_values($i)
    }
    set run_pre_or_post_inflation post
}

proc aie_compute_prism_mesh {} {
    global file_name

    set modified 0
    if {$prism_input == 1} { #from file
	    if {$meshFile == ""} {
	        msg ERROR "No input mesh selected for prism"
	        return
	    }
        if {![file exists $meshFile]} {
            msg ERROR "input mesh file $meshFile does not exists"
            return
        }
        set file_name(domain) $meshFile
        if [ic_uns_is_loaded] {
            if {!$loadmesh} {set modified [ic_uns_is_modified]}
            ic_uns_set_modified 0
        }
    } else {
        if {![ic_uns_is_loaded]} {
	        msg ERROR "No input mesh is loaded for prism"
	        return
        }
    }

    meshPrismDEZ set loadmesh $loadmesh
    meshPrismDEZ apply
    ic_uns_set_modified $modified
}

proc aie_compute_extprism_mesh {} {

    if $ext_method {
        meshAutoDEZ aie_compute_extruded_mesh
    } else {
        meshAutoDEZ aie_compute_prism_mesh
    }
}

proc onmeshHexaCoreLoad {} {

    meshAutoDEZ aie_set_automesh_input
    set PartList [aie_list_parts 1]
    set family [lindex [ic_list_volume_families] 0]
}

proc aie_compute_hexacore_mesh {} {
    # Run hexa-core mesher
    mess "Creating Hexa-core mesh\n" blue
    set hexcore_fams ""
    set hexacore_status 0
    foreach fam [ic_list_volume_families] {
        if {$fam == "ORFN" || $fam == "VORFN"} continue
        set do_hexcore [ic_geo_get_family_param $fam hexcore]
        if {$do_hexcore != "" && $do_hexcore != 0} {
            lappend hexcore_fams $fam
        }
    }
    if {$hexcore_fams == ""} {
        set hexcore_fams [ic_list_volume_families]
        # remove exisiting
        set new_fams ""
        set exfams ""
        if [info exists existing_volume_fams] {
            set exfams $existing_volume_fams
        }
        foreach fam $hexcore_fams {
            if {[lsearch $exfams $fam] == -1} {
                lappend new_fams $fam
            }
        }
        set hexcore_fams $new_fams
    }

    if {$hexcore_fams == ""} {
        set mtls ""
        if [ic_geo_is_loaded] {
            foreach bdy [ic_geo_get_objects body] {
                if {[ic_geo_get_family body $bdy] != "ORFN"} {
                    lappend mtls [ic_geo_get_family body $bdy]
                }
            }
        }
        set num_material_points [llength $mtls]
        if {$num_material_points > 1} {
            mess "Warning: No volume part selected for hexa-core mesh\n" red
            return
        } elseif {$family == "inherited"} {
            set hexcore_fams [lindex [ic_list_volume_families] 0]
        } else {
            set hexcore_fams $family
        }
    }

    if {$hexcore_fams == ""} {
        set family [aie_new_part CREATED_MATERIAL]
        set hexcore_fams $family
    }
    aie_get_global_mesh_params cur_mesh_params

    set fill_holes $cur_mesh_params(cart_fillholes)
    set tratio [aie_cart_reftype $cur_mesh_params(cart_tratio)]
    set bbox ""
    if {($cur_mesh_params(cart_user_bbox)) && $cur_mesh_params(cart_bbox) != ""} {
        set bbox $cur_mesh_params(cart_bbox)
    }

    set csys [ic_csystem_get_current]
    if $cur_mesh_params(cart_csys) {
        if {$csys == "global"} {
              mess "Warning: although the option is turned on,\n" red
              mess "         no local coordinate system is active.\n" red
              mess "         Global system is used for hexa-core mesh\n" red
        }
    }
    set conformal $cur_mesh_params(cart_conformal)

    set use_tg_tri2tet $cur_mesh_params(tetra_run_adv_delaunay)

    set hexacore_status [ic_uns_convert_tet2_hexcore $hexcore_fams \
            $fill_holes $tratio $bbox $csys $conformal $use_tg_tri2tet]
}

proc onmeshHexaDomLoad {} {
    meshAutoDEZ aie_set_automesh_input
    set PartList [aie_list_parts 1]
}

proc aie_compute_hexdom_mesh {} {

    # check if an application is already running
    if [aie_check_application_running] return

    if $create_surfmesh {
        if [ic_uns_is_loaded] {
            ic_unload_mesh
        }
        meshAutoDEZ onmeshAutoSurfLoad
        set stat [meshAutoDEZ aie_compute_surface_mesh hexdom]
        if $stat {
            mess "Surface meshing failed\n" red
            return
        }
    }

    if ![ic_uns_is_loaded] {
        msg ERROR "Please Load/Generate Surface Mesh first"
        return
    }
     # Run hex-dom mesher
    set live_fams ""
    set hex_flood_fill 0
    foreach fam [ic_geo_list_families 1] {
        if {$fam == "ORFN" || $fam == "VORFN"} continue
        lappend live_fams $fam
    }
    if {$family != "" && $family != "inherited" && ([lsearch "ORFN VORFN" $family] < 0)} {
        if [ic_geo_check_part $family] {
            set hexdom_fam $family
        } else {
	        set hexdom_fam [aie_new_part [string toupper $family]]
        }
    } else {
        if {$family == "inherited"} {
            if {[ic_geo_list_families 1] != ""} {
                set hex_flood_fill 1
            }
        }
	    set hexdom_fam [lindex $live_fams 0]
    }
    if {$hexdom_fam == ""} {
        if ![ic_geo_check_part LIVE] {
            mess "Creating new volume part LIVE\n"
        }
        set hexdom_fam [aie_new_part LIVE]
    }

    aie_get_global_mesh_params cur_mesh_params

    # quad boundary gives more hexas
    ic_change_tri_quad_2 all 1 0 0 -20 160 20 0
    mess "Running hexa-dominant mesher...\n" blue
    ic_mesh_hexdom $hexdom_fam $cur_mesh_params(hybrid_remeshCenter)
    if $hex_flood_fill { ic_flood_fill_mesh }
    aie_create_initial_assemblies
    aie_connectors_exec
}

proc onmeshAutoDEZOK {} {
    global env aie_meshStyle quality_metric_created auto_pick_mode

    if {$meshAutoWhatVal == -1} return
    switch $meshAutoWhatVal {
        0 { # Surface Mesh
	        meshAutoDEZ aie_compute_surface_mesh
        }
        1 { # Volume Mesh
	        meshAutoDEZ aie_compute_volume_mesh
        }
        2 { # Prism Mesh
	        meshAutoDEZ aie_compute_prism_mesh
        }
    }
    
    if {$meshAutoWhatVal == 1 && $volmesh_type == 0 && $tetra_method == 0} {
        catch { unset quality_metric_created }
    }
    aie_updateMeshVis
    if $aie_meshStyle(color_by_quality) {
        aie_changeMeshDisplay style color_by_quality 1
    }
    aie_update_icons mesh
    aie_delete_empty_parts
    if {[TreeStack peek_one] != "meshAutoDEZ_Tree" && $auto_pick_mode} {
        meshAutoDEZ load
    }
    meshAutoDEZ setdirty
    if [ic_uns_is_loaded] {
        aie_viewInfo mesh
    }
    mess "Finished compute mesh\n" blue
    busy reset
}

proc aie_compute_volume_mesh {} {
    global env catch quality_metric_created

    if ![info exists tetra_method] return
    set create_surfmesh !$tetra_input

    switch $volmesh_type {
	    0 { # Tetra / Mixed
	        if {![info exists env(AI_ENV_TETRA)]} {
	            msg ERROR "Can not run this application with this Licensing"
	            return 1
	        }
	        switch $tetra_method {
		        0 { # Tetra Mesh (Octree)
		            meshAutoDEZ aie_compute_tetra_mesh octree
		        }
		        1 { # Tetra Mesh (Delaunay)
		            if {[info exists env(AI_ENV_ACADEMIC)]} {
		                msg ERROR "Can not run this application with this Licensing"
		                return 1
		            }
		            meshAutoDEZ aie_compute_tetra_mesh delaunay
		        }
		        2 { # Tetra Mesh (Advancing front)
		            if {[info exists env(AI_ENV_ACADEMIC)]} {
		                msg ERROR "Can not run this application with this Licensing"
		                return 1
		            }
		            meshAutoDEZ aie_compute_tetra_mesh advfront
		        }
		        3 { # Tetra Mesh (ANSYS TGrid)
		            if {[info exists env(AI_ENV_ACADEMIC)]} {
		                msg ERROR "Can not run this application with this Licensing"
		                return 1
		            }
		            meshAutoDEZ aie_compute_tetra_mesh tgrid
		        }
	        }
	    }
	    1 { # Hexa-Dom
	        if {![info exists env(AI_ENV_HEXA)] || [info exists env(AI_ENV_ACADEMIC)]} {
	            msg ERROR "Can not run this application with this Licensing"
	            return 1
	        }
	        meshAutoDEZ aie_compute_hexdom_mesh
	    }
	    2 { # cartesian
	        if {[info exists env(AI_ENV_ACADEMIC)]} {
	            msg ERROR "Can not run this application with this Licensing"
	            return 1
	        }
            meshAutoDEZ setclean; busy reset
            meshAutoDEZ aie_compute_cartesian_mesh
            meshAutoDEZ setdirty
	    }
    }
}

proc onmeshAutoDEZUnLoad {} {
    global surfaceMeshArray
    
    set cartfile_visible 0
    ic_cart_visible 0
    catch { unset surfaceMeshArray }
    foreach n "set_surfparams_type set_surfparams_method" {
        if {[trace vinfo $n] != ""} {
            trace vdelete $n w aie_surface_mesh_trace_type_method
        }
    }
    foreach n "etype2 emethod2" {
        if {[trace vinfo $n] != ""} {
            trace vdelete $n w aie_surface_mesh_trace_etype2_emethod2
        }
    }
    if {[trace vinfo run_inflation] != ""} {
        trace vdelete run_inflation w aie_wb_trace_tgrid_inflation_state
    }
    if {[trace vinfo run_pre_or_post_inflation] != ""} {
        trace vdelete run_pre_or_post_inflation w aie_wb_trace_tgrid_inflation_state
    }
    if {[trace vinfo run_prism] != ""} {
        trace vdelete run_prism w aie_wb_trace_tgrid_inflation_state
    }
}

proc onsurfMeshDefaultsDEZLoad {} {
    global env beta_mode

    set meshElemTypeList {
        "All Tri"
        "Quad w/one Tri"
        "Quad Dominant"
        "All Quad"
    }
    set meshElemMethodList {
        "Autoblock"
        "Patch Dependent"
        "Patch Independent"
        "Shrinkwrap"
        "Delaunay"
    }

    set mesh_type2 "Quad Dominant"
    set mesh_method2 "Autoblock"
}

proc onsurfMeshDefaultsDEZAfterLoad {} {
    set mesh_type2 [aie_global_get_mesh_type_name [aie_get_default_surface_mesh_type]]
    set mesh_method2 [aie_global_get_mesh_method_name [aie_get_default_surface_mesh_method]]
}

proc onsurfMeshDefaultsDEZOK {} {
    global env valSurfaceArray

    set q_mesh_type [aie_global_get_mesh_type_number $mesh_type2]
    set q_mesh_method [aie_global_get_mesh_method_number $mesh_method2]

    set valSurfaceArray(mesh_type) $q_mesh_type
    set valSurfaceArray(mesh_method) $q_mesh_method

    ic_set_meshing_params surface_global 0 mesh_type $q_mesh_type mesh_method $q_mesh_method
}

# This should be based on licensing
proc aie_get_default_surface_mesh_type {{volume_mesh ""}} {
    global env valSurfaceArray

    catch { unset valSurfaceArray }
    array set valSurfaceArray [ic_get_meshing_params surface_global 0]
    if [info exists valSurfaceArray(mesh_type)] {
        set q_mesh_type $valSurfaceArray(mesh_type)
    } else {
	if {$volume_mesh == "tetra"} {
	    set mesh_type2 "All Tri"
	} else {
	    set mesh_type2 "Quad Dominant"
	}
	set valSurfaceArray(mesh_type) [aie_global_get_mesh_type_number $mesh_type2]
	set q_mesh_type $valSurfaceArray(mesh_type)
    }

    return $q_mesh_type
}

# This should be based on licensing
proc aie_get_default_surface_mesh_method {{volume_mesh ""}} {
    global env valSurfaceArray

    catch { unset valSurfaceArray }
    array set valSurfaceArray [ic_get_meshing_params surface_global 0]
    set set_by_user 0
    if [info exists valSurfaceArray(mesh_method)] {
        set q_mesh_method $valSurfaceArray(mesh_method)
	set set_by_user 1
    } else {
	set mesh_method2 "Patch Dependent"
	set q_mesh_method [aie_global_get_mesh_method_number $mesh_method2]
    }

# check appropriate lic available
    set method [aie_global_get_mesh_method_name $q_mesh_method]
    if {$method == "Patch Dependent"} {
	if ![info exists env(AI_ENV_QUAD)] {
	    set method "Shrinkwrap"
	    if $set_by_user {
		mess "Warning: No quad licensing available, mesh method set to $method\n" red
	    }
	}
    }

    if {$method == "Patch Independent"} {
	if ![info exists env(AI_ENV_QUAD)] {
	    set method "Shrinkwrap"
	    if $set_by_user {
		mess "Warning: No tetra licensing available, mesh method set to $method\n" red
	    }
	}
    }

    set valSurfaceArray(mesh_method) [aie_global_get_mesh_method_number $method]
    set q_mesh_method $valSurfaceArray(mesh_method)
    return $q_mesh_method
}

proc onmeshVolFromSurfDEZLoad {} {
    set PartList [aie_list_parts 1]
    set loadmesh 1
}

proc onmeshVolFromSurfDEZAfterLoad {} {
    if ![ic_uns_is_loaded] {
        meshVolFromSurfDEZ unload
        mess "Surface mesh is not loaded\n" red
        return
    }
}

proc onmeshVolFromSurfDEZOK {} {
    global file_name env beta_mode

    switch $tetra_method {
        0 {set mesher tri2tet}
        1 {set mesher afmesh}
        2 {set mesher tgrid}
    }

    set modified [ic_uns_is_modified]
    set meshIN  $file_name(domain)
    set meshOUT [file join $file_name(project_dir) $mesher\_mesh.uns]
    set meshBACKUP ""
    if {[file exists $meshOUT]} {
        set meshBACKUP $meshOUT\_bak
        cmd_mv $meshOUT $meshBACKUP
        mess "$meshOUT already exists! Will be moved to $meshBACKUP\n"
   }
    
    set tempfile ""

    if {$meshIN == "" || ![file exists $meshIN] || $modified || $mesher == "tgrid"} {
        set tempfile [cmd_tempfile $mesher\_temp .uns]
        if {$mesher == "tgrid"} {
            ic_save_unstruct $tempfile 0 "" {LINE_2 TRI_3 QUAD_4}
        } else {
            ic_save_unstruct $tempfile
        }
        set meshIN $tempfile
        ic_uns_set_modified $modified
    }

    if $is_win {
        set cmd [list ic_run_$mesher [win_shortname $meshIN] [win_shortname [file dirname $meshOUT]]/[file tail $meshOUT]]
    } else {
        set cmd [list ic_run_$mesher $meshIN $meshOUT]
    }

    if {$mesher == "tri2tet"} {
        if {$scalefactor != ""} {append cmd " safety $scalefactor"}
        if [info exists env(TRI2TET_DEBUG)] {
            if {$output != ""} {append cmd " output $output"}
            if {$OFFfile != ""} {append cmd " offfile $OFFfile"}
        }
    }
    if {$mesher == "afmesh"} {
        append cmd " geometry 0 proximity $proximity"
    } else {
        append cmd " bgmesh $bgmesh"
        if {$bgfile != ""} {append cmd " bgfile $bgfile"}
    }
    if {$family != ""} {
        regsub -all " " [string toupper $family] _ fam
        append cmd " family $fam"
    }
    if {$tetexpand != ""} {append cmd " tetexpand $tetexpand"}
    if {$global_spacing != ""} {append cmd " spacing $global_spacing"}
    if {$fillholes} {append cmd " fillholes 1"}
    if {$meshall} {append cmd " keepall 1"}
    append cmd " verbose $verbose"
    set error_subset $mesher\_errors
    append cmd " show_progress 1"
    append cmd " errors $error_subset"
    set progenv [string toupper "$mesher\_TEST"]
    if {[info exists env($progenv)] && $env($progenv) != ""} {
        append cmd " progenv $progenv"
    }

    catch {ic_uns_subset_delete $error_subset}
    if {[eval $cmd] && [file exists $meshOUT]} {
        if $loadmesh {
            aie_close_Mesh 0
            set file_name(domain) $meshOUT
            aie_open_Mesh 0
            aie_afterStuffLoaded 0
            set nelems [expr \
                [ic_count_elements quad] + \
                [ic_count_elements pyra] + \
                [ic_count_elements penta] + \
                [ic_count_elements hexa]]
            if {$nelems > 0 && $mesher != "tgrid" && [ic_create_pyramids]} {
                aie_updateMeshVis
                unstruct_consistent "" 0
            }
            if {$floodfill} {
                ic_flood_fill_mesh
                aie_create_initial_assemblies
            }
        } else {
            mess "Created $mesher mesh is saved in file: $meshOUT\n"
        }
    } else {
        mess "No $mesher mesh generated!\n" red
        if {$meshBACKUP != "" [file exists $meshBACKUP]} {
            cmd_mv $meshBACKUP $meshOUT 
            mess " Backed up mesh $meshBACKUP moved back to $meshOUT\n"
        }
    }
    if {$tempfile != ""} {cmd_rm $tempfile}
    if [ic_uns_subset_exists $error_subset] {
        aie_subset_put_in_tree mesh $error_subset
    }
}

proc onmeshAdvFrontDEZLoad {} {
    set LoadFlag 1
}

proc onmeshAdvFrontDEZAfterLoad {} {
    if ![ic_geo_is_loaded] {
        meshAdvFrontDEZ unload
        mess "Geometry is not loaded\n" red
        return
    }
}

proc onmeshAdvFrontDEZOK {} {
    global file_name is_win

    # if running prism or advancing front inflation check for prism families
    if {$InflateFlag && [catch {aie_check_prism_params afmesh} msg]} {
        msg ERROR $msg
        return
    }

    # check if an application is already running
    if [aie_check_application_running] return

    set is_modified [ic_geo_is_modified]
    if [aie_autosizing tetra] {
        mess "Canceled by user\n" red
        return
    }
    set temp_tin_name afmesh_tmp.tin
    if {($file_name(tetin) == "") || (![file exists $file_name(tetin)]) || [ic_geo_is_modified]} {
        set tetinFN $temp_tin_name
        ic_save_tetin $tetinFN
    } else {
        set tetinFN $file_name(tetin)
    }
    if {$SurfOnlyFlag} {
        set meshFN [file join $file_name(domains_dir) afmesh_tri.uns]
    } else {
        set meshFN [file join $file_name(domains_dir) afmesh_mesh.uns]
    }

    if $is_win {
        set cmd [list ic_run_afmesh [win_shortname $tetinFN] \
            [win_shortname [file dirname $meshFN]]/[file tail $meshFN]]
    } else {
        set cmd [list ic_run_afmesh $tetinFN $meshFN]
    }
    append cmd " geometry 1"
    append cmd " surface $SurfOnlyFlag"
    append cmd " verbose $VerboseFlag"
    append cmd " keepfiles $KeepFlag"
    append cmd " delaunay $DelaunayFlag"
    append cmd " proximity $ProximityFlag"
    append cmd " topo $RebuildTopoFlag"
#    append cmd " join $MergeSurfFlag"
    if {![catch {expr double($TopoTolerance)} tol]} {
        append cmd " tol $tol"
    }
    if {![catch {expr double($ExpansionFactor)} factor]} {
        append cmd " expand $factor"
    }
    if {$InflateFlag} {
        append cmd " prism [aie_write_prism_params]"
    }

    if [eval $cmd] {
        if $LoadFlag {
            ic_unload_mesh
            set file_name(domain) $meshFN
            if [aie_open_Mesh 0] {
                aie_afterStuffLoaded 0
            }
        } else {
            mess "Mesh saved in file: $meshFN\n"
        }
    }
    if [file exists $temp_tin_name] {cmd_rm $temp_tin_name}
    aie_no_autosizing
    ic_geo_set_modified $is_modified
}











