proc onmszGlobalDEZLoad {} {
    global env load_only_prism_params prism_parts prism_values
    global beta_mode

    if ![ic_geo_is_loaded] {
	    # we don't want to return here because we allow Global Mesh setup
	    # without geometry - Ganesan
	    mess "Warning: No geometry loaded\n" red
    }

    set curVals [ ic_get_meshing_params global 0 ]
    array set valArray $curVals

    if !$valArray(gref) {
	    set valArray(gref) 1.0
    }

    set globalSF [expr $valArray(gref) * 1.0]
    set maxSz [expr $valArray(gmax) / $globalSF]
# Max size of 0 now means autoassign mesh sizes
#    if {$maxSz == 0} {set maxSz 64}
    set minSize [expr $valArray(gnat) / $globalSF]
    if {$minSize == 0} {set minSize 1.0}

    if {[expr $valArray(gnat) / $globalSF] != 0} {
	    set natSzGGVal 1
	    ::AIEnv::GUIManagement::ToggleGrey natSzChkGI 0
    } else {
	    set natSzGGVal 0
	    ::AIEnv::GUIManagement::ToggleGrey natSzChkGI 1
    }

    set gnatref $valArray(gnatref)
    set gapNum $valArray(gcgap)
    set igwall $valArray(igwall)

    set intWalls ""
    #set splitWalls ""
    foreach f [ic_geo_list_families] {
	if {[ic_geo_get_family_param $f internal_wall] == "1"} {
	    set part [lindex [split $f :] 0]
	    lappend intWalls $part
	}
	# if {[ic_geo_get_family_param $f split_wall] == "1"} { lappend splitWalls $f }
    }

    set periodicTypeRotMVal 0
    array set data [ic_geo_get_periodic_data]
    # this is only for cfx right now
    if {$periodicTypeEGVal == ""} {
	    set base "0 0 0"
	    set axis "0 0 0"
	    set angle 0
    }
    set base $data(base)
    set axis $data(axis)
    set angle $data(angle)

    switch $data(type) {
	    none { set DefineperiodicGGVal 0 }
	    rot  { set DefineperiodicGGVal 1; set periodicTypeEGVal 0}
	    trans { set DefineperiodicGGVal 1; set periodicTypeEGVal 1}
    }

    if $DefineperiodicGGVal {
	    ::AIEnv::GUIManagement::ToggleGrey perGroup 0
    } else {
	    ::AIEnv::GUIManagement::ToggleGrey perGroup 1
    }

    # prism values
    aie_load_prism_params
    array set prism_values [ic_get_meshing_params prism 0]
    set GrowthLawList {linear exponential wb-exponential}
    set TgridSmoothingLevelList {Low Medium High}
    set tgrid_smoothing_level Medium
    foreach i [array names prism_values] {
	    if {$prism_values($i) != ""} {
		    set $i $prism_values($i)
	    }
    }
    if {![info exists TriQualityList]} {
        set TriQualityList [list inscribed_area inscribed_ratio laplace height_over_base skewness min_angle max_angle]
    }
    set triangle_quality inscribed_area
    
    set meshElemTypeList {
       "All Tri"
       "Quad w/one Tri"
       "Quad Dominant"
       "All Quad"
    }
    set meshElemMethodList {}
    if {[info exists env(AI_ENV_QUAD)]} {
       lappend meshElemMethodList "Autoblock"
       lappend meshElemMethodList "Patch Dependent"
    }
    if {[info exists env(AI_ENV_QUAD)]} {
       lappend meshElemMethodList "Patch Independent"
    }
    lappend meshElemMethodList "Shrinkwrap"
    if {[info exists env(AI_ENV_QUAD)] && $beta_mode} {
       lappend meshElemMethodList "Delaunay"
    }

    # Shell Meshing Parameters
    set OffsetList {
        "Standard"
        "Simple"
        "Forced simple"
    }

    set mappedMethodsList {
        "Free"
        "Some mapped"
        "Mostly mapped"
    }

    # patch dependent
    set proj_surf 1
    set impr_level 1
    set bound_smooth 0
    set surf_sizes 0
    set ign_size [aie_default_topo_tolerance]
    set protect_line 0
    set simple_offset2 "Standard"
    set max_area 0.0
    set max_length 0.0
    set min_angle 0.0
    set max_nodes 0
    set max_elements 0
    set bunch_respect 0
    set block_mapping 0.2
    set adjust_nodes_max 0
    set try_harder 1
    set mesh_dormant 0
    set smooth_dormant 0
    set free_bunch 0
    set snorm 1
    set quadratic 0
    # mapped
    set merge_surfs 1
    set mapped_method 1
    # shrinkwrap
    set shrinkwrap_nsmooth 5
    set shrinkwrap_projfactor 0.1

    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]]
    set mapped_method2 "Some mapped"
    if [info exists env(QUAD_DEBUG)] {
        set max_dev 0.0
    }

    set cartRefType {"Uniform" "2-to-1" "3-to-1"}
    set curVals [ ic_get_meshing_params global 0 ]
    array set valArray $curVals

    set fastTranFlag  $valArray(gfast)
    set gedgec $valArray(gedgec)

    set tgrid_n_ortho_layers 0
    set tgrid_fix_first_layer 0
    set tgrid_gap_factor 0.5
    set tgrid_enhance_norm_comp 0
    set tgrid_enhance_offset_comp 0
    set tgrid_max_cap_skew 0.98
    set tgrid_max_cell_skew 0.90

    # ----------------------------
    aie_update_thincuts
    aie_update_global_mesh_params
    # -------------------

    set PartList [aie_list_parts 1]
}

proc onmszGlobalDEZAfterLoad {} {
    global env valSurfaceArray beta_mode tetra_global_tet_type mesh_global_vol_type 
    global cart_global_cast_method

    # Shell Meshing Parameters
    catch { unset valSurfaceArray }
    array set valSurfaceArray [ic_get_meshing_params surface_global 0]
    foreach n [array names valSurfaceArray] {
        if {$n == "simple_offset"} {
            switch $valSurfaceArray($n) {
                0 { set simple_offset2 "Standard" }
                1 { set simple_offset2 "Simple" }
                2 { set simple_offset2 "Forced simple" }
            }
        } elseif {$n == "mapped_method"} {
            switch $valSurfaceArray($n) {
                0 { set mapped_method2 "Free" }
                1 { set mapped_method2 "Some mapped" }
                2 { set mapped_method2 "Mostly mapped" }
            }
        } elseif {$n == "adjust_nodes_max"} {
            # the gui uses percent
            set adjust_nodes_max [expr $valSurfaceArray($n) * 100.0]
        } else {
            if [info exists $n] {
                set $n $valSurfaceArray($n)
            }
        }
    }

    if [info exists valSurfaceArray(mesh_type)] {
        set mesh_type2 [aie_global_get_mesh_type_name $valSurfaceArray(mesh_type)]
    }
    if [info exists valSurfaceArray(mesh_method)] {
        set mesh_method2 [aie_global_get_mesh_method_name $valSurfaceArray(mesh_method)]
    }

    foreach v {bunch_respect protect_line ign_size} {
        if {[trace vinfo $v] != ""} {
            trace vdelete $v w aie_global_quad_trace_bunch_respect
        }
        trace variable $v w aie_global_quad_trace_bunch_respect
    }
    foreach v {mesh_dormant smooth_dormant} {
        if {[trace vinfo $v] != ""} {
            trace vdelete $v w aie_global_quad_trace_dormant
        }
        trace variable $v w aie_global_quad_trace_dormant
    }
    if {[trace vinfo mesh_method2] != ""} {
        trace vdelete mesh_method2 w aie_global_quad_trace_mesh_method2
    }
    trace variable mesh_method2 w aie_global_quad_trace_mesh_method2

    aie_global_quad_trace_proj_surf "" "" ""
    aie_global_quad_trace_bunch_respect "" "" ""
    aie_global_quad_trace_dormant "" "" ""
    aie_global_quad_trace_mesh_method2  "" "" ""

    if {[lsearch $meshElemMethodList $mesh_method2] < 0} {
       set mesh_method2 [lindex $meshElemMethodList 0]
    }
    if {$mesh_method2 == "Autoblock"} {mszGlobalDEZ set mszShellAdvancedVal 0}
    if {$mesh_method2 == "Patch Dependent"} {mszGlobalDEZ set mszShellAdvancedVal 1}
    if {$mesh_method2 == "Patch Independent"} {mszGlobalDEZ set mszShellAdvancedVal 2}
    if {$mesh_method2 == "Shrinkwrap"} {mszGlobalDEZ set mszShellAdvancedVal 3}
    if {$mesh_method2 == "Delaunay"} {mszGlobalDEZ set mszShellAdvancedVal 4}

    if ![info exists tetra_smooth] { set tetra_smooth 1 }
    if ![info exists tetra_smooth2] { set tetra_smooth2 1 }
    foreach v {tetra_smooth tetra_smooth2 tetra_coarsen} {
        if {[trace vinfo $v] != ""} {
            trace vdelete $v w aie_global_trace_tetra_gui_values
        }
        trace variable $v w aie_global_trace_tetra_gui_values
    }
    aie_global_trace_tetra_gui_values "" "" ""

    if {![info exists env(AI_ENV_QUAD)]} {
       ::AIEnv::GUIManagement::ToggleGrey mszShellAdvanced2 1
       ::AIEnv::GUIManagement::ToggleGrey mszShellAdvanced3 1
       if {$beta_mode} {::AIEnv::GUIManagement::ToggleGrey mszShellAdvanced6 1}
    }
    if {![info exists env(AI_ENV_TETRA)]} {
       ::AIEnv::GUIManagement::ToggleGrey mszShellAdvanced4 1
    }
    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 mxzGlobalTypeTetra 1
    }
    if {![info exists env(AI_ENV_TETRA)]} {
       ::AIEnv::GUIManagement::ToggleGrey mxzGlobalMeshTet 1
    }
    if {[info exists env(AI_ENV_ACADEMIC)]} {
       ::AIEnv::GUIManagement::ToggleGrey mxzGlobalTypeTetDel 1
    }
    if {[info exists env(AI_ENV_ACADEMIC)]} {
       ::AIEnv::GUIManagement::ToggleGrey mxzGlobalTypeTetAdv 1
    }
    if {[info exists env(AI_ENV_ACADEMIC)]} {
       ::AIEnv::GUIManagement::ToggleGrey mxzGlobalTypeTetTGrid 1
    }
    if {![info exists env(AI_ENV_HEXA)] || [info exists env(AI_ENV_ACADEMIC)]} {
       ::AIEnv::GUIManagement::ToggleGrey mxzGlobalMeshHybrid 1
    }
    if {(![info exists env(AI_ENV_TETRA)] && ![info exists env(AI_ENV_BFCART)] \
         && ![info exists env(AI_ENV_GLOBAL)]) || [info exists env(AI_ENV_ACADEMIC)]} {
       ::AIEnv::GUIManagement::ToggleGrey mxzGlobalMeshCart 1
    }
    if {![info exists env(AI_ENV_BFCART)]|| [info exists env(AI_ENV_ACADEMIC)]} {
       ::AIEnv::GUIManagement::ToggleGrey mxzGlobalCartBF 1
    }
    if {(![info exists env(AI_ENV_BFCART)] && ![info exists env(AI_ENV_GLOBAL)]) || [info exists env(AI_ENV_ACADEMIC)]} {
       if $beta_mode { ::AIEnv::GUIManagement::ToggleGrey mxzGlobalCartGlobal 1 }
    }
    if {![info exists env(AI_ENV_TETRA)] || [info exists env(AI_ENV_ACADEMIC)]} {
       ::AIEnv::GUIManagement::ToggleGrey mxzGlobalCartHexaCore 1
    }
    if {![info exists env(AI_ENV_PRISM)]} {
       ::AIEnv::GUIManagement::ToggleGrey mxzGlobalTypePrism 1
    } else {
        if {[trace vinfo tgrid_smoothing_level] != ""} {
            trace vdelete tgrid_smoothing_level w aie_global_prism_trace_pre_inflation
        }
        trace variable tgrid_smoothing_level w aie_global_prism_trace_pre_inflation
        aie_global_prism_trace_pre_inflation "" "" ""
        if {[trace vinfo triangle_quality] != ""} {
            trace vdelete triangle_quality w aie_global_prism_trace_ortho_weight
        }
        trace variable triangle_quality w aie_global_prism_trace_ortho_weight
        aie_global_prism_trace_ortho_weight "" "" ""
    }
    if [info exists ::tetra_global_tet_type] {
        set mszGlobalTetTypeVal $::tetra_global_tet_type
    } else {
        set mszGlobalTetTypeVal 0
    }
    if [info exists ::mesh_global_vol_type] {
        set mszGlobalVolumeTypeEGVal $::mesh_global_vol_type
    } else {
        set mszGlobalVolumeTypeEGVal 0
    }
    if [info exists ::cart_global_cast_method] {
        set mszGlobalMeshCartEGVal $::cart_global_cast_method
    } else {
        set mszGlobalMeshCartEGVal 0
    }
    
    foreach v {axis DefineperiodicGGVal} {
        if {[trace vinfo $v] != ""} {
            trace vdelete $v w aie_global_trace_periodic_gui_values
        }
        trace variable $v w aie_global_trace_periodic_gui_values
    }
    after 50 { ::AIEnv::GUIManagement::ToggleGrey perConvertFromLCStoGlobal 1 }
    
    if [aie_wb2_is_running] {
        after 100 {
            ic_wb2_update_parameters input
        }
    }
}

proc onmszGlobalTypeShellLoad {} {
    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]]
    if {[lsearch $meshElemMethodList $mesh_method2] < 0} {
       set mesh_method2 [lindex $meshElemMethodList 0]
    }
    if {$mesh_method2 == "Autoblock"} {mszGlobalDEZ set mszShellAdvancedVal 0}
    if {$mesh_method2 == "Patch Dependent"} {mszGlobalDEZ set mszShellAdvancedVal 1}
    if {$mesh_method2 == "Patch Independent"} {mszGlobalDEZ set mszShellAdvancedVal 2}
    if {$mesh_method2 == "Shrinkwrap"} {mszGlobalDEZ set mszShellAdvancedVal 3}
    if {$mesh_method2 == "Delaunay"} {mszGlobalDEZ set mszShellAdvancedVal 4}
}

proc aie_global_get_mesh_type_number {type} {
    set etyp 0
    switch $type {
        "All Quad" { set etyp 2 }
        "Quad w/one Tri" { set etyp 4 }
        "Quad Dominant" { set etyp 3 }
        "All Tri" { set etyp 0 }
    }
    return $etyp
}

proc aie_global_get_mesh_type_name {type} {
    set name "All Tri"
    switch -- $type {
        4 { set name "Quad w/one Tri" }
        3 { set name "Quad Dominant" }
        0 { set name "All Tri" }
        2 { set name "All Quad" }
    }
    return $name
}

proc aie_global_get_mesh_method_number {method} {
    set emethod 1
    switch $method {
        "Autoblock" { set emethod 0 }
        "Patch Dependent" { set emethod 1 }
        "Patch Independent" { set emethod 2 }
        "Delaunay" { set emethod 3 }
        "Shrinkwrap" { set emethod 4 }
    }
    return $emethod
}

proc aie_global_get_mesh_method_name {method} {
    global env
    if [info exists env(AI_ENV_QUAD)] {
       set name "Patch Dependent"
    } else {
       set name "Patch Independent"
    }
    switch -- $method {
        0 { set name "Autoblock" }
        1 { set name "Patch Dependent" }
        2 { set name "Patch Independent" }
        3 { set name "Delaunay" }
	4 { set name "Shrinkwrap" }
    }
    return $name
}

proc aie_global_quad_trace_proj_surf {{name ""} {element ""} {op ""}} {
    if {[info exists env(QUAD_DEBUG)]} {
        if [mszGlobalDEZ get proj_surf] {
            ::AIEnv::GUIManagement::ToggleGrey mszShellMaxDev 0
        } else {
            ::AIEnv::GUIManagement::ToggleGrey mszShellMaxDev 1
        }
    }
}

proc aie_global_quad_trace_bunch_respect {{name ""} {element ""} {op ""}} {
    if [mszGlobalDEZ get bunch_respect] {
        if {[mszGlobalDEZ get ign_size] > 0} {
            ::AIEnv::GUIManagement::ToggleGrey mszShellProtect 0
        } else {
            ::AIEnv::GUIManagement::ToggleGrey mszShellProtect 1
        }
    } else {
        ::AIEnv::GUIManagement::ToggleGrey mszShellProtect 1
    }
}

proc aie_global_quad_trace_dormant {{name ""} {element ""} {op ""}} {
    if [mszGlobalDEZ get mesh_dormant] {
        ::AIEnv::GUIManagement::ToggleGrey mszShellSmoothDormant 0
    } else {
        ::AIEnv::GUIManagement::ToggleGrey mszShellSmoothDormant 1
    }
}

proc aie_global_trace_tetra_gui_values {{name ""} {element ""} {op ""}} {
    if [mszGlobalDEZ get tetra_smooth] {
        ::AIEnv::GUIManagement::ToggleGrey mszTetVSI 0
        ::AIEnv::GUIManagement::ToggleGrey mszTetSAR 0
    } else {
        ::AIEnv::GUIManagement::ToggleGrey mszTetVSI 1
        ::AIEnv::GUIManagement::ToggleGrey mszTetSAR 1
    }
    if [mszGlobalDEZ get tetra_coarsen] {
        ::AIEnv::GUIManagement::ToggleGrey mszTetCNumIter 0
        ::AIEnv::GUIManagement::ToggleGrey mszTetCAR 0
    } else {
        ::AIEnv::GUIManagement::ToggleGrey mszTetCNumIter 1
        ::AIEnv::GUIManagement::ToggleGrey mszTetCAR 1
    }
    if [mszGlobalDEZ get tetra_smooth2] {
        ::AIEnv::GUIManagement::ToggleGrey meshDelRemeshVSI 0
        ::AIEnv::GUIManagement::ToggleGrey meshDelRemeshSAR 0
    } else {
        ::AIEnv::GUIManagement::ToggleGrey meshDelRemeshVSI 1
        ::AIEnv::GUIManagement::ToggleGrey meshDelRemeshSAR 1
    }
}

proc aie_global_quad_trace_mesh_method2 {{name ""} {element ""} {op ""}} {
    set m [mszGlobalDEZ get mesh_method2]
    switch $m {
       "Autoblock" { mszGlobalDEZ set mszShellAdvancedVal 0 }
       "Patch Dependent" { mszGlobalDEZ set mszShellAdvancedVal 1 }
       "Patch Independent" { mszGlobalDEZ set mszShellAdvancedVal 2 }
       "Shrinkwrap" { mszGlobalDEZ set mszShellAdvancedVal 3 }
       "Delaunay" { mszGlobalDEZ set mszShellAdvancedVal 4 }
    }
}

proc aie_global_prism_trace_pre_inflation {{name ""} {element ""} {op ""}} {
    set m [mszGlobalDEZ get tgrid_smoothing_level]
    switch $m {
       0 { mszGlobalDEZ set tgrid_smoothing_level Low }
       1 { mszGlobalDEZ set tgrid_smoothing_level Medium }
       2 { mszGlobalDEZ set tgrid_smoothing_level High }
    }
}

proc aie_global_prism_trace_ortho_weight {{name ""} {element ""} {op ""}} {
    if {[mszGlobalDEZ get triangle_quality] == "laplace"} {
        ::AIEnv::GUIManagement::ToggleGrey meshPrismOrtho 0
    } else {
        ::AIEnv::GUIManagement::ToggleGrey meshPrismOrtho 1
    }
}

proc aie_global_trace_periodic_gui_values {{name ""} {element ""} {op ""}} {
    if {[ic_csystem_get_current] == "global" || ($name == "::AIEnv::DEZ::mszGlobalDEZ::DefineperiodicGGVal")} {
        after 50 { ::AIEnv::GUIManagement::ToggleGrey perConvertFromLCStoGlobal 1 }
    } else {
        ::AIEnv::GUIManagement::ToggleGrey perConvertFromLCStoGlobal 0
    }
}

proc aie_global_scale_mapping {num {dez ""}} {}

proc aie_global_scale_adjust {num {dez ""}} {}

proc aie_global_scale_try_harder {num {dez ""}} {}

proc aie_global_scale_impr_level {num {dez ""}} {}

proc onmszGlobalIntWallsPick {} {
    global family_part_pre_select

    foreach fam $intWalls {
        set family_part_preselect($fam) 1
    }
}

proc onmszGlobalThinCutsFinish {} {
    if {[llength $thinCuts] == 2} {
        set thinCuts [list $thinCuts]
    }
}

proc aie_update_thincuts {} {
    set thincuts [ic_geo_get_thincuts]
    set w [mszGlobalDEZ pathIgnoreErrors mszThincuts]
    if {$thincuts == ""} {
        $w configure -background $::AIEnv::GUIManagement::GUIDisplayData("GUIBackground")
    } else {
        $w configure -background green
    }
}

proc aie_define_thincuts {} {
    global thincut_data

    set thincut_fams [ic_geo_get_thincuts]
    set thincut_data ""
    foreach tc $thincut_fams {
        set p1 [lindex [split [lindex $tc 0] :] 0]
        set p2 [lindex [split [lindex $tc 1] :] 0]
        lappend thincut_data "$p1 $p2"
    }

    if [futil_edit_list .thincuts "Thin cuts" thincut_data +400+200 aie_thincut_select] {
	    set thincut_fams ""
	    foreach tc $thincut_data {
	        set f1 [lindex [ic_geo_list_families_in_part [lindex $tc 0]] 0]
	        set f2 [lindex [ic_geo_list_families_in_part [lindex $tc 1]] 0]
	        lappend thincut_fams "$f1 $f2"
	    }

	    ic_geo_set_thincuts $thincut_fams
        mess "Thin cuts are defined for $thincut_data parts\n"
        mszGlobalDEZ aie_update_thincuts
    }
}

proc aie_thincut_select {var} {
    upvar \#0 $var lvar

    set f1 [select_families part 0 0 "Select the first part"]
    if {$f1 != ""} {
        set f2 [select_families part 0 0 "Select the second part"]
    }
    if {($f1 == "") || ($f2 == "")} return
    set lvar "$f1 $f2"
}

# All global mesh params should be updated here, but currently only some
proc aie_update_global_mesh_params {} {
    mszGlobalDEZ aie_reset_global_mesh_params

    foreach {n v} [ic_get_meshing_params variable 0] {
        set $n [join $v]
    }
}

proc aie_reset_global_mesh_params {} {
    global global_mesh_params

    foreach par [array names global_mesh_params] {
        catch {mszGlobalDEZ set $par [join $global_mesh_params($par)]}
    }
}

proc aie_get_global_mesh_params {var} {
    global global_mesh_params

    array set mpars {}
    foreach par [array names global_mesh_params] {
        set mpars($par) [join $global_mesh_params($par)]
    }

    foreach {n v} [ic_get_meshing_params variable 0] {
        set mpars($n) [join $v]
    }

    uplevel 1 array set $var [list [array get mpars]]
}

proc aie_set_global_mesh_params {type} {
    global global_mesh_params

    set mpars ""
    switch $type {
        "all" {
            set mpars [array names global_mesh_params]
        }
        default {
	        foreach par [array names global_mesh_params] {
                if [regexp ${type}_* $par] {
                    lappend mpars $par
                }
            }
        }
    }
    aie_get_global_mesh_params cur_mesh_params
    foreach par $mpars {
        set val [mszGlobalDEZ get $par]
        if {$val != "" && $val != $cur_mesh_params($par)} {
            set val [join [mszGlobalDEZ get $par]]
            if {[llength $val] > 1} {
                set val [list $val]
            }
            ic_set_meshing_params variable 0 $par $val
        }
    }
}

proc onmxzGlobalTypeTetraLoad {} {
    mszGlobalDEZ aie_update_thincuts
}

proc aie_global_periodic_convert {} {
     set lcs [ic_csystem_get_current]
     if {$lcs == "global"} {
        mess "No conversion needed, current coordinate system is $lcs\n"
        return
     } else {
        mess "Converting current coordinates from $lcs to global\n"
     }
     if {[mszGlobalDEZ get periodicTypeEGVal] == 0} {
        if {[mszGlobalDEZ get periodicTypeRotMVal] == 2} {
            if {$VecList == "" || [llength $VecList] <= 1} {
                mess "Select 2 points for vector\n" red
                return
            }
            set check [lindex $VecList 0]
            if {[llength $check] == 1} {
                if {[ic_geo_check_objects_exist point $check] == ""} {
                    mess "Do not exist: point $check\n" red
                    return
                }
            }
            set check [lindex $VecList 1]
            if {[llength $check] == 1} {
                if {[ic_geo_check_objects_exist point $check] == ""} {
                    mess "Do not exist: point $check\n" red
                    return
                }
            }
            set error [ic_v_calc vector diff $VecList 1]
            if $error {
                mess "Error in vector definition\n" red
                return
            }
            set vector [lindex [ic_virtual] 0]
            set axis $vector
            set base [lindex $VecList 0]
        }
     }
     set axis [ic_coords_dir_into_global $axis $lcs]
     mess "The axis is: $axis\n"
     if {[llength $base] == 1} {
        set base [ic_geo_get_point_location $base]
     }
     ::AIEnv::GUIManagement::ToggleGrey perConvertFromLCStoGlobal 1
}

proc onmszGlobalDEZOK {} {
    global env beta_mode prism_values prism_extras tetra_global_tet_type mesh_global_vol_type
    global cart_global_cast_method

    if {$mszGlobalTypeGGVal == 1} {
        # Quad settings
        set q_mesh_type [aie_global_get_mesh_type_number $mesh_type2]
        set q_mesh_method [aie_global_get_mesh_method_number $mesh_method2]
        switch $simple_offset2 {
            "Standard"      { set q_simple_offset 0 }
            "Simple"        { set q_simple_offset 1 }
            "Forced simple" { set q_simple_offset 2 }
            default         { set q_simple_offset 0 }
        }
        set q_bunch_respect $bunch_respect
        if !$bunch_respect {
            set q_protect_line 0
        } else {
            set q_protect_line $protect_line
        }
        set q_bound_smooth $bound_smooth
        set q_block_mapping $block_mapping
        set q_adjust_nodes_max [expr $adjust_nodes_max / 100.0]
        set q_proj_surf $proj_surf
        set q_surf_sizes $surf_sizes
        set q_ign_size $ign_size
        set q_try_harder $try_harder
        set q_impr_level $impr_level
        set q_mesh_dormant $mesh_dormant
        if !$mesh_dormant {
            set q_smooth_dormant 0
        } else {
            set q_smooth_dormant $smooth_dormant
        }
        set q_max_area $max_area
        set q_max_length $max_length
        set q_min_angle $min_angle
        set q_max_nodes $max_nodes
        set q_max_elements $max_elements
        set q_merge_surfs $merge_surfs
        switch $mapped_method2 {
            "Free" { set q_mapped_method 0 }
            "Some mapped" { set q_mapped_method 1 }
            "Mostly mapped" { set q_mapped_method 2 }
        }
        set q_free_bunch $free_bunch
        set q_snorm $snorm
        set q_quadratic $quadratic

        ic_set_meshing_params surface_global 0 mesh_type $q_mesh_type mesh_method $q_mesh_method\
                simple_offset $q_simple_offset bunch_respect $q_bunch_respect\
                protect_line $q_protect_line bound_smooth $q_bound_smooth block_mapping $q_block_mapping\
                adjust_nodes_max $q_adjust_nodes_max proj_surf $q_proj_surf surf_sizes $q_surf_sizes\
                ign_size $q_ign_size try_harder $q_try_harder impr_level $q_impr_level\
                mesh_dormant $q_mesh_dormant smooth_dormant $q_smooth_dormant max_area $q_max_area\
                max_length $q_max_length min_angle $q_min_angle max_nodes $q_max_nodes\
                max_elements $q_max_elements merge_surfs $q_merge_surfs mapped_method $q_mapped_method\
                free_bunch $q_free_bunch shrinkwrap_nsmooth $shrinkwrap_nsmooth shrinkwrap_projfactor \
                $shrinkwrap_projfactor snorm $q_snorm quadratic $q_quadratic
        mess "Shell Meshing Parameters defined\n" blue
        return
    }

	if {$mszGlobalTypeGGVal == 2} {
	    # volume meshing
	    set ::mesh_global_vol_type $mszGlobalVolumeTypeEGVal
	    switch $mszGlobalVolumeTypeEGVal {
		    0 {
		        aie_set_global_mesh_params tetra
		        set ::tetra_global_tet_type $mszGlobalTetTypeVal
		        if {$mszGlobalTetTypeVal == 0} {
		            ic_set_meshing_params global 0 gfast $fastTranFlag gedgec $gedgec
		        }
		    }
		    1 {
		        aie_set_global_mesh_params hybrid
		    }
		    2 {
		        aie_set_global_mesh_params cart
		        set ::cart_global_cast_method $mszGlobalMeshCartEGVal
		    }
	    }
	    mess "Volume Meshing Parameters defined\n" blue
	    return
	}

    if {$mszGlobalTypeGGVal == 3} {
        # Prism settings
        if {$law == "exponential" && $ratio_multiplier == 0} {
            mess "Warning: using \"Growth law: exponential\" together with \"Ratio multiplier: 0.0\" only works\
                in case of a mesh with existing prism elements\n" red
        }
	    foreach i {height layers ratio total_height law 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 prism_values($i) [set $i]

	    }
        if [catch {prism_check_params law $prism_values(law) \
                layers $prism_values(layers) height $prism_values(height) \
                ratio $prism_values(ratio) \
                total_height $prism_values(total_height)} msg] {
                msg ERROR $msg
        } else {
            if ![expr $tgrid_max_cap_skew >= 0.0 && $tgrid_max_cap_skew <= 1.0] {
                mess "Error: \"Max allowable Cap Skewness\" must be >= 0.0 and <= 1.0\n" red
                return
            }
            if ![expr $tgrid_max_cell_skew >= 0.0 && $tgrid_max_cell_skew <= 1.0] {
               mess "Error: \"Max allowable Cell Skewness\" must be >= 0.0 and <= 1.0\n" red
               return
            }
            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)
            # Additional Pre-Inflation parameters
            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 }
                default {
                    mess "Error: unknown value $tgrid_smoothing_level for \"Smoothing Level\" \n" red
                    return 
                }
            }
            ic_set_meshing_params variable 0 tgrid_n_ortho_layers $tgrid_n_ortho_layers \
                    tgrid_fix_first_layer $tgrid_fix_first_layer tgrid_gap_factor $tgrid_gap_factor \
                    tgrid_enhance_norm_comp $tgrid_enhance_norm_comp tgrid_enhance_offset_comp $tgrid_enhance_offset_comp \
                    tgrid_smoothing_level $tgrid_smoothing_level2 tgrid_max_cap_skew $tgrid_max_cap_skew \
                    tgrid_max_cell_skew $tgrid_max_cell_skew tgrid_last_layer_aspect $tgrid_last_layer_aspect \
                    triangle_quality $triangle_quality

        }
        mess "Prism Meshing Parameters defined\n" blue
        return
    }

    if {$mszGlobalTypeGGVal == 0} {
        set globalSF [scan $globalSF %f]
        set maxSz [scan $maxSz %f]
        set verify "globalSF maxSz"
        if $natSzGGVal {
            set minSize [scan $minSize %f]
            append verify " minSize"
        }
        foreach i $verify {
            if {![string is integer [set $i]] && ![string is double [set $i]] || [set $i] == ""} {
		        switch $i {
		            globalSF { set error "Scale Factor" }
		            maxSz { set error "Max Element" }
		            minSize { set error "Min Size Limit" }
		        }
		        mess "Error in \"$error\" Definition\n" red
		        return
            }
        }
        if $natSzGGVal {
	        if !$minSize {
	            msg ERROR "Please specify a valid minimum size for Natural size setting"
	            return
	        }
        }
        if {$maxSz == ""} { set maxSz 0.0 }
        set scldMax [expr $globalSF*$maxSz]
        set scldMinSize [expr $globalSF*$minSize]
        set ofact [ic_geo_get_ref_size]
        if {$globalSF <= 0} {
            msg ERROR "Please specify a valid scale factor"
            return
        }
        if {$globalSF != $ofact} {
            ic_geo_scale_meshing_params all $globalSF
        }

        # if enabled flag is on, set natural size, if not, natural size has to be 0
        if $natSzGGVal {
	        ic_set_meshing_params global 0 gref $globalSF \
	            gmax $scldMax gfast $fastTranFlag gedgec $gedgec \
	            gnat $scldMinSize gcgap $gapNum gnatref $gnatref igwall $igwall
        } else {
	        ic_set_meshing_params global 0 gref $globalSF \
	            gmax $scldMax gfast $fastTranFlag gedgec $gedgec \
	            gnat 0 gcgap $gapNum gnatref $gnatref
        }
        ic_geo_params_update_show_size ref $dspScaleFlag
        ic_geo_params_update_show_size max $dspSeedFlag
        ic_geo_params_update_show_size nat $dspNatFlag
        mess "Global Mesh Size defined\n" blue
    }
    
    if {[info exists DefineperiodicGGVal] && $mszGlobalTypeGGVal == 4} {
        # periodicity
        if $DefineperiodicGGVal {
            if {$periodicTypeEGVal == ""} {
                msg ERROR "Please specify the periodic type"
                return
            }
            if $periodicTypeEGVal {
                set type trans
            } else {
                set type rot
            }
        } else {
            set type none
        }
        if {[llength $base] == 1} {
            set base [ic_geo_get_point_location $base]
        }
        if {$VecList != ""} {
            if {[llength $VecList] <= 1} {
                mess "Select 2 points\n" red
                return
            }
            set check [lindex $VecList 0]
            if {[llength $check] == 1} {
                if {[ic_geo_check_objects_exist point $check] == ""} {
                    mess "Do not exist: point $check\n" red
                    return
                }
            }
            set check [lindex $VecList 1]
            if {[llength $check] == 1} {
                if {[ic_geo_check_objects_exist point $check] == ""} {
                    mess "Do not exist: point $check\n" red
                    return
                }
            }
            set error [ic_v_calc vector diff $VecList 1]
            if $error {
                mess "Error in vector definition\n" red
                return
            }
            set vector [lindex [ic_virtual] 0]
            mess "The axis is: $vector\n"
            set axis $vector
            set base [lindex $VecList 0]
            if {[llength $base] == 1} {
                set base [ic_geo_get_point_location $base]
            }
            set VecList ""
        }
        if {$axis == ""} {
            mess "Error: Please specify the axis\n" red
            return
        }
        if {$base == ""} {
            mess "Error: Please specify the base\n" red
            return
        }
        if {[info exists periodicTypeRotMVal] && ($periodicTypeRotMVal == "0" || $periodicTypeRotMVal == "2") && $periodicTypeEGVal == 0} {
            if {([string is double $angle] || [string is integer $angle])} {
                if {$angle < 0} {
                    mess "Error: Please specify a positive angle\n" red
                    return
                }
            } else {
                mess "Error: Please specify a valid positive angle\n" red
                return
            }
        }
        set axis [ic_coords_dir_into_global $axis global]
        set base [ic_coords_into_global $base global]
        if {[info exists periodicTypeRotMVal] && $periodicTypeRotMVal == "1" && $periodicTypeEGVal == 0} {
            if {$num_sectors == 0 || $num_sectors == ""} {
                 mess "Error: Please specify number of sectors\n" red
                 return
            }
            set angle [expr 360.0 / $num_sectors]
        }
        foreach t {type axis angle base} {
            set data($t) [set $t]
        }
        ic_geo_set_periodic_data [array get data]
        switch $type {
            rot {
                set type_used "Rotational periodic"
            }
            trans {
                set type_used "Translational periodic"
            }
            default {
                set type_used "None"
            }
        }
        mess "Periodicity defined (Type: \"$type_used\")\n" blue
        ::AIEnv::GUIManagement::ToggleGrey perConvertFromLCStoGlobal 1
        return
    }
}

proc onMszGlobalDEZUnLoad {} {

    if ![ic_geo_is_loaded] return
    
    set dspScaleFlag 0
    set dspSeedFlag 0
    set dspNatFlag 0
    ic_geo_params_update_show_size ref $dspScaleFlag
    ic_geo_params_update_show_size max $dspSeedFlag
    ic_geo_params_update_show_size nat $dspNatFlag
    foreach v {bunch_respect protect_line ign_size} {
        if {[trace vinfo $v] != ""} {
            trace vdelete $v w aie_global_quad_trace_bunch_respect
        }
    }
    foreach v {mesh_dormant smooth_dormant} {
        if {[trace vinfo $v] != ""} {
            trace vdelete $v w aie_global_quad_trace_dormant
        }
    }
    if {[trace vinfo mesh_method2] != ""} {
        trace vdelete mesh_method2 w aie_global_quad_trace_mesh_method2
    }
    foreach v {tetra_smooth tetra_smooth2 tetra_coarsen} {
        if {[trace vinfo $v] != ""} {
            trace vdelete $v w aie_global_trace_tetra_gui_values
        }
        trace variable $v w aie_global_trace_tetra_gui_values
    }
    if {[trace vinfo tgrid_smoothing_level] != ""} {
        trace vdelete tgrid_smoothing_level w aie_global_prism_trace_pre_inflation
    }
    if {[trace vinfo triangle_quality] != ""} {
        trace vdelete triangle_quality w aie_global_prism_trace_ortho_weight
    }
    foreach v {axis DefineperiodicGGVal} {
        if {[trace vinfo $v] != ""} {
            trace vdelete $v w aie_global_trace_periodic_gui_values
        }
        trace variable $v w aie_global_trace_periodic_gui_values
    }
}

proc aie_prism_extra_params {} {
    global prism_values prism_extras prism_extra_types beta_mode is_win env

    set names [lsort [array names prism_extras]]
    aie_prism_extra_params_defaults
    foreach i $names {
        if {[info exists prism_values($i)] && $prism_values($i) != ""} {
            if {$i == "use_prism_v10" && $is_win} {
                if !$beta_mode {
                    continue
                } else {
                    if ![file exists "$env(ICEM_ACN)/icemcfd/prism_v10.exe"] {
                        mess "\nNote that the executable \"prism_v10.exe\" (for option \"Use prism V10\") needs to be obtained from the \
                        ANSYS customer portal and copied to \"$env(ICEM_ACN)/icemcfd\"\n" blue
                    }        
                }
            }
            set prism_extras($i) $prism_values($i)
        }
    }

    set w .prism_extra
    if [winfo exists $w] {destroy $w}

    set buts [list [list Apply "aie_prism_extra_params_apply $w"] [list Dismiss "form_done $w"] \
             [list Defaults "aie_prism_extra_params_defaults"]]
    set d [form_init $w "Advanced Prism Meshing Parameters" "" $buts ]
    if {$d != ""} {
	set bg [$w cget -background]
        # do check buttons first
	    set ln 0
        set col 0
        foreach i $names {
            if {$i == "use_prism_v10"} {
                if {$is_win && !$beta_mode} continue
            }
            if {[lsearch $prism_extra_types $i] >= 0} {
                set lab {}
                foreach n [split $i _] {
                    lappend lab [string totitle $n]
                }
                form_checkbutton $d.c$ln$col $lab prism_extras($i) "$ln $col"
                incr col
                if {$col == 2} {
                    set col 0
                    incr ln
                }
            }
        }
        # do options that take a value
        if {$col} {incr ln}
        foreach i $names {
            if {[lsearch $prism_extra_types $i] < 0} {
                set lab {}
                foreach n [split $i _] {
                    lappend lab [string totitle $n]
                }
		        form_label $d.l$ln $lab "$ln 0"
		        form_entry $d.e$ln prism_extras($i) string "$ln 1"
            }
            incr ln
        }
	    form_finish +300+300
    }
}

proc aie_prism_extra_params_defaults {} {
    global prism_values prism_extras
    
    foreach i [array names prism_extras] {
        set prism_extras($i) ""
    }
    # default values
    foreach {i j} {delete_standalone 1 \
        extend_pyramids 1 \
        intermediate_write 1 \
        incremental_write 0 \
        max_jump_factor 5 \
        min_smoothing_steps 6 \
        min_smoothing_val 0.1 \
        refine_prism_boundary 1 \
        stair_step 1 \
        stop_columns 1 \
        blayer_2d 0 \
        use_prism_v10 0 \
        use_existing_quad_layers 0 \
        tetra_smooth_limit 0.3 \
        interpolate_heights 0 \
        verbosity_level 1} {
        if [info exists prism_extras($i)] {
            set prism_extras($i) $j
        }
    }
}

proc aie_prism_extra_params_apply {w} {
    global prism_values prism_extras is_win
    
    foreach i [array names prism_extras] {
        set prism_values($i) $prism_extras($i)
    }
    # check for unsupported params in v10
    set not_in_v10 {blayer_2d use_existing_quad_layers interpolate_heights verbosity_level incremental_write}
    set not_in_v10_win {stair_step stop_columns}
    if $prism_extras(use_prism_v10) {
	    foreach p $not_in_v10 {
	        if $prism_extras($p) {
		        mess "Warning: $p not supported in prism v10\n" red
		        set prism_extras($p) 0
		        set prism_values($p) $prism_extras($p)
	        }
	    }
	    if $is_win {
	        foreach p $not_in_v10_win {
	            if $prism_extras($p) {
		            mess "Warning: $p not supported in prism v10\n" red
		            set prism_extras($p) 0
		            set prism_values($p) $prism_extras($p)
	            }
	        }
	    }
    }
    if [mszGlobalDEZ isbuilt] {
        mszGlobalDEZ apply
    }
}

proc aie_curve_get_bunching_law_name { name } {
    if {$name == "default"} { return "BiGeometric" }
    switch $name {
        geo1 {
            return "Geometric1"
        }
        geo2 {
            return "Geometric2"
        }
        biexponential {
            #return "Biexponential"
            return ""
        }
        default {
            return ""
        }
    }
}

proc onmszCurveCopyPickFromFinish {} {
    foreach val "from_emax from_nmax from_ehgt from_hrat from_ewid from_emin from_edev \
                 from_law from_h1 from_h2 from_r1 from_r2 from_lmax" {
        set $val ""
    }
    if {$copyCurveFrom == ""} return
    if {[llength $copyCurveFrom] > 1} {
        mess "Only one source curve allowed for \"From Curve\".\n" red
        return
    }
    set params [ic_get_meshing_params curve $copyCurveFrom]
    set from_emax [lindex [aie_convert_relative "emax [lindex $params 1]" 1] 1]
    if {$from_emax == 0 || $from_emax == ""} {
        mess "No params found: Source curve $copyCurveFrom.\n" red
        set copyCurveFrom ""
        return
    }
    set from_ehgt [lindex [aie_convert_relative "ehgt [lindex $params 3]" 1] 1]
    set from_hrat [lindex $params 5]
    set from_ewid [lindex $params 7]
    set from_emin [lindex [aie_convert_relative "emin [lindex $params 11]" 1] 1]
    set from_edev [lindex [aie_convert_relative "edev [lindex $params 13]" 1] 1]
    set len [expr double([ic_geo_crv_length $copyCurveFrom])]
    set scale [ic_geo_get_ref_size]
    if {$scale == ""} { set scale 1.0 }
    if {[expr $from_emax * $scale] != 0} {
        set from_nmax [expr round ($len / ($from_emax * $scale)) + 1]
    }
    set bunching [ic_geo_get_curve_bunching $copyCurveFrom]
    if {$bunching != ""} {
        set law_bunching [lindex $bunching 1]
        set from_law [aie_curve_get_bunching_law_name $law_bunching]
        if {$from_law == ""} {
            mess "Note: Source curve bunching law not supported for \"Copy Parameters\".\n" red
            foreach val "from_law from_h1 from_h2 from_r1 from_r2 from_lmax" { set $val "" }
        }
        set from_h1 [lindex $bunching 5]
        set from_h2 [lindex $bunching 7]
        set from_r1 [lindex $bunching 9]
        set from_r2 [lindex $bunching 11]
        set from_lmax [lindex $bunching 13]
    } else {
        foreach val "from_law from_h1 from_h2 from_r1 from_r2 from_lmax" { set $val "" }
    }
}

proc onmszCurveCopyPickToFinish {} {
    set n [lsearch $copyCurveTo $copyCurveFrom]
    if {$n >= 0} {
        mess "Source curve $copyCurveFrom can not be target curve. Removed source curve from target curve(s).\n" red
        ic_show_geo_selected curve [lindex $copyCurveTo $n] 0
        set replaced [lreplace $copyCurveTo $n $n]
        set copyCurveTo $replaced
    }
    if {$copyCurveTo == ""} {
        mess "No target curve(s) selected.\n" red
    }
}

proc onmszCurveMousePickPick {} {
    global curve_param_directions
    if [info exists curve_param_directions] {
        aie_curve_show_directions $curve_param_directions 1
    }
}

proc onmszCurveMousePickFinish {} {
    global curve_param_par curve_param_directions

    if [info exists curve_param_par] {
        aie_curve_mouse_dynamic_done $curve_param_par $curveList 0 0
    }
    if [info exists curve_param_directions] {
        aie_curve_show_directions $curve_param_directions
    }
    if [aie_wb2_is_running] {
        aie_wb2_wb_parameter_input_geom_curve [mszCurveDEZ get curveList]
    }
    if {$curveList == ""} {
       foreach p {law h1 h2 r1 r2 lmax} {
           set $p ""
        }
        return
    }
    busy 1
    foreach s $curveList {
        ic_show_geo_selected curve $s 1
    }
    aie_update_mesh_params curve $curveList 
    busy 0
}

proc aie_curve_show_directions {{images ""} {off 0}} {
    global tdv_current_viewer curve_param_directions
    if {$images != ""} { 
        foreach c $images { $c clear_points }
    }
    if [info exists curve_param_directions] {
        foreach c $curve_param_directions { $c clear_points }
        unset curve_param_directions
    }
    if {![mszCurveDEZ get dirCurveFlag] || $off} return
    set w $tdv_current_viewer
    set curve_param_directions ""
    busy 1
    foreach c [mszCurveDEZ get curveList] {
        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 curve_param_directions $dir
    }
    busy reset
}

proc aie_curve_reverse_crv {} {
    global curve_param_directions

    foreach c [mszCurveDEZ get curveList] {
        ic_geo_reverse_crv $c
    }
    if [mszCurveDEZ get dirCurveFlag] {
        aie_curve_show_directions $curve_param_directions
    }
}

proc aie_curve_display_direction {x y on} {
    global tdv_current_viewer curve_param_dir

    if [info exists curve_param_dir] {
        $curve_param_dir clear_points
        unset curve_param_dir
    }
    set w $tdv_current_viewer
    if $on {
        set im(xyz) [aie_curve_get_dir_image "" $x $y]
        if {$im(xyz) == ""} break
        set curve_param_dir [tdv_poly_line_im -draw_dots 0 -width 3 -color yellow]
        $w add_image $curve_param_dir
        foreach p $im(xyz) { $curve_param_dir add_point $p }
    }
}

proc aie_curve_get_dir_image {c {x ""} {y ""}} {
    global tdv_current_viewer

    set w $tdv_current_viewer 
    set s1 0.4; set s2 0.5   
    if {$c != "" && $x == "" && $y == ""} {
        set pos [lindex [ic_geo_get_crv_pos 0.5 $c] 0]
        set sl [$w world2screen [lindex $pos 0] [lindex $pos 1] [lindex $pos 2]]
        set x [expr int([lindex $sl 0])]
        set y [expr int([lindex $sl 1])] 
    }
    set picked [$w pick $x $y geom_curve "" 0]
    set im(crv) [lindex $picked 0]
    if {$im(crv) == ""} { return "" }
    set xyz [lindex $picked 2]
    set dir [va_curve_dir [b $im(crv) get -name] $xyz direction]
    if {$dir == ""} { return "" }
    set s2w [$w screen2world 0 0]
    set p1 [lindex $s2w 0]; set p2 [lindex [$w screen2world 20 0] 0]
    set v1 [lindex $s2w 1]; set dist [ic_vcalc distance $p1 $p2]
    set v2 [ic_vcalc smult $dir $dist]
    set s3 [ic_vcalc smult [ic_vcalc nrm [ic_vcalc product $v2 $v1]] [expr $dist * $s1]] 
    set ph [ic_vcalc sum $xyz $v2]
    set p3 [ic_vcalc sum $ph [ic_vcalc smult $dir [expr $dist * $s2]]]
    set sum [ic_vcalc sum $ph $s3]; set diff [ic_vcalc diff $s3 $ph]
    return [list $xyz $p3 $sum $diff $p3]
}

proc aie_curve_display_param {on which only_one} {
    global tdv_current_viewer curve_param_im curve_param_val
    global tdv_pickable_tags curve_param_crv curve_param_pos

    if !$only_one {
        foreach crv [ic_geo_get_objects curve ""] {
            if [info exists curve_param_im($crv)] {
                $curve_param_im($crv) delete
                unset curve_param_im($crv)
            }
            if [info exists curve_param_val($crv)] {
                unset curve_param_val($crv)
            }
            if [info exists curve_param_crv($crv)] {
                unset curve_param_crv($crv)
            }
            if [info exists curve_param_pos($crv)] {
                unset curve_param_pos($crv)
            }
        }
    }

    if !$on {
        if [info exists tdv_pickable_tags($tdv_current_viewer)] {
            set tdv_pickable_tags($tdv_current_viewer) ""
        }
        return
    }

    set param $which

    if $only_one {
        switch $which {
            emax { set val [mszCurveDEZ get emax] }
            nmax { set val [mszCurveDEZ get nmax] }
            brat { set val [mszCurveDEZ get brat] }
            ehgt { set val [mszCurveDEZ get ehgt] }
            hrat { set val [mszCurveDEZ get hrat] }
            ewid { set val [mszCurveDEZ get ewid] }
            emin { set val [mszCurveDEZ get emin] }
            edev { set val [mszCurveDEZ get edev] }
        }
        set crv [mszCurveDEZ get curveList]
        if {[ic_geo_check_objects_exist curve $crv] == ""} return
        if [info exists curve_param_im($crv)] {
            $curve_param_im($crv) delete
            unset curve_param_im($crv)
            ic_geo_configure_one_object curve $crv draw_quad_size 0
        }
        if [info exists curve_param_pos($crv)] {
            set pos $curve_param_pos($crv)
        } else {
            set pos [lindex [ic_geo_get_crv_pos 0.5 $crv] 0]
        }
        set tmp($pos) 1
        if {$param != "brat"} {
            set im [tdv_text_im -color white -text " $val " -point "$pos" -fontsize 1 -y_dir_up 1]
        } else {
            set law [mszCurveDEZ get blaw]
            if {$law == ""} {
                set disp_val $val
            } else {
                set disp_val "$val ($law)"
            }
            set im [tdv_text_im -color white -text "$disp_val" -point "$pos" -fontsize 1 -y_dir_up 1]
        }
        set curve_param_im($crv) $im
        set curve_param_val($crv) $val
        set curve_param_crv($im) $crv
        $tdv_current_viewer add_image $curve_param_im($crv)
        $tdv_current_viewer add_tag $curve_param_im($crv) anno_pickable
        lappend tdv_pickable_tags($tdv_current_viewer) $curve_param_im($crv)
    } else {
        set scale [ic_geo_get_ref_size]
        if {$scale == ""} { set scale 1.0 }
        foreach crv [ic_geo_get_objects curve ""] {
            if {[ic_geo_check_objects_exist curve $crv] == ""} continue
            if {[ic_geo_get_visibility curve $crv] == 0} continue
            set pos [lindex [ic_geo_get_crv_pos 0.5 $crv] 0]
            if [info exists tmp($pos)] {
                set pos [lindex [ic_geo_get_crv_pos 0.4 $crv] 0]
            }
            if [info exists tmp($pos)] {
                set pos [lindex [ic_geo_get_crv_pos 0.6 $crv] 0]
            }
            set tmp($pos) 1
            set curve_param_pos($crv) $pos
            if {$param == "nmax"} {
                set len [expr double([ic_geo_crv_length $crv])]
                foreach {n v} [ic_get_meshing_params curve $crv] {
                    if {$n == "emax"} {
                        if {$v == 0} {
                            set val 2
                        } else {
                            set val [expr round ($len / $v) + 1]
                        }
                        break
                    }
                }
            } else {          
                if {$param != "brat"} {
                    foreach {n v} [ic_get_meshing_params curve $crv] {
                        if {$n == "$param"} {
                            switch $n {
                                emax - emin - ehgt - edev {
                                    set val [expr $v / ($scale + 0.0)]
                                }
                                default {
                                    set val $v
                                }
                            }
                            break
                        }
                    } 
                } else {
                    if ![info exists curve_param_val($crv)] {
                        set bunching [ic_geo_get_curve_bunching $crv]
                        if {$bunching == ""} {
                            set val 1.0
                            set law ""
                        } else {
                            set law [lindex $bunching 1]
                            if {[lindex $bunching 1] == "geo2"} {
                                set val [lindex $bunching 11]
                                set law Geometric2
                            } else {
                                set val [lindex $bunching 9]
                                if {$law == "geo1"} {
                                    set law Geometric1
                                } elseif {$law == "default"} {
                                    set law BiGeometric
                                }
                            }
                        }
                    } else {
                        set val $curve_param_val($crv)
                    }
                }
            }      
            if {$param != "brat"} {
                set im [tdv_text_im -color white -text " $val " -point "$pos" -fontsize 1 -y_dir_up 1]
            } else {
                if {$law == ""} {
                    set disp_val $val
                } else {
                    set disp_val "$val ($law)"
                }
                set im [tdv_text_im -color white -text "$disp_val" -point "$pos" -fontsize 1 -y_dir_up 1]
            }
            set curve_param_im($crv) $im
            set curve_param_val($crv) $val
            set curve_param_crv($im) $crv
            $tdv_current_viewer add_image $curve_param_im($crv)
            $tdv_current_viewer add_tag $curve_param_im($crv) anno_pickable
            lappend tdv_pickable_tags($tdv_current_viewer) $curve_param_im($crv)
        }
    }
}

proc aie_curve_mouse_dynamic {which} {
    global aie_ShowCurveQuadsCount aie_ShowCurveQuads
    global vam_events curve_param_par

    if $aie_ShowCurveQuadsCount {
        set reset_count 1
    } else {
        set reset_count 0
    }
    set aie_ShowCurveQuadsCount 0
    ::AIEnv::GUIManagement::Tree::ShowCurveQuadCount

    if $aie_ShowCurveQuads {
        set reset_size 1 
    } else {
        set reset_size 0
    } 
    
    switch $which {
        emax { set txt "maximum size" }
        nmax { set txt "number" }
        brat { set txt "bunching ratio" }
        ehgt { set txt "height" }
        hrat { set txt "ratio" }
        ewid { set txt "width" }
        emin { set txt "minimum size" }
        edev { set txt "maximum deviation" }
    }
    set banner_mess "Increment/Decrement $txt with Left/Right mouse button. Middle = done"   
    banner $banner_mess
    
    aie_curve_display_param 1 $which 0
    set curves [mszCurveDEZ get curveList]
    foreach item $curves { ic_show_geo_selected curve $item 0 } 
    
    set vam_events(delay_before) 600
    set vam_events(delay_between) 100
    
    set curve_param_par $which
    aie_curve_dynamic_binding $which "$curves" $reset_count $reset_size
    mszCurveDEZ setclean
}

proc aie_curve_mouse_dynamic_done {which curves reset_count reset_size} {
    global curve_param_sel aie_ShowCurveQuadsCount aie_ShowCurveQuads
    global curve_param_im curve_param_val curve_param_crv curve_param_par
    global curve_param_last
    
    vam_unset_timer
    aie_curve_default_binding
    aie_curve_display_direction "" "" 0
    mszCurveDEZ set curveList $curves
    aie_curve_display_param 0 $which 0
    if [info exists curve_param_sel] {
        if !$reset_size {
            ic_geo_configure_one_object curve $curve_param_sel draw_quad_size 0
        }
        ic_show_geo_selected curve $curve_param_sel 0
        unset curve_param_sel
    }
    if [info exists curve_param_par] { unset curve_param_par }
    if [info exists curve_param_last] { unset curve_param_last }
    foreach crv [array names curve_param_im] { unset curve_param_im($crv) }
    foreach crv [array names curve_param_val] { unset curve_param_val($crv) }
    foreach crv [array names curve_param_crv] { unset curve_param_crv($crv) }
    aie_update_mesh_params curve $curves
    if $reset_count {
        set aie_ShowCurveQuadsCount 1
        ::AIEnv::GUIManagement::Tree::ShowCurveQuadCount
    }
    if $reset_size {
        set aie_ShowCurveQuads 1
        ::AIEnv::GUIManagement::Tree::ShowCurveQuadSizes
    }
    mszCurveDEZ setclean
    banner ""  
}

proc aie_curve_default_binding {} {
    select_unset_bindings 0    
}

proc aie_curve_dynamic_binding {which curves reset_count reset_size} {
    global tdv_current_viewer select_in_dynamics
    
    set select_in_dynamics 0
    bind $tdv_current_viewer <Motion> "aie_curve_mouse_incr_decr_pos $tdv_current_viewer %x %y $which $reset_size"
    bind $tdv_current_viewer <ButtonPress-1> "aie_curve_mouse_incr_decr_wait $which press 1 %x %y %t"
    bind $tdv_current_viewer <ButtonPress-2> "aie_curve_mouse_dynamic_done $which [list $curves] $reset_count $reset_size"
    bind $tdv_current_viewer <ButtonPress-3> "aie_curve_mouse_incr_decr_wait $which press 3 %x %y %t"
    bind $tdv_current_viewer <ButtonRelease-1> "aie_curve_mouse_incr_decr_wait $which release 1 %x %y %t"
    bind $tdv_current_viewer <ButtonRelease-3> "aie_curve_mouse_incr_decr_wait $which release 3 %x %y %t"
    tdv_set_key_command F9 "aie_curve_mouse_incr_decr_F9 $which [list $curves] $reset_count $reset_size"
}

proc aie_curve_mouse_incr_decr_F9 {which curves reset_count reset_size} {
    global tdv_current_viewer select_in_dynamics_prev_banner select_in_dynamics
    
    vam_unset_timer
    if ![info exists select_in_dynamics] return
    if $select_in_dynamics {
	select_unset_bindings 0
	select_set_bindings F9 0 0 0 ""
	set select_in_dynamics 0
	if [info exists select_in_dynamics_prev_banner] {
	    banner $select_in_dynamics_prev_banner
	    unset select_in_dynamics_prev_banner
	}
	aie_curve_dynamic_binding $which "$curves" $reset_count $reset_size
    } else {
	tdv_dynamics_bindings $tdv_current_viewer
	tdv_cur $tdv_current_viewer dynamics
	bind $tdv_current_viewer c "do_center %x %y"
	set select_in_dynamics 1
	set select_in_dynamics_prev_banner [banner "Dynamics mode - hit F9 to return to selection mode."]
    }
}

proc aie_curve_mouse_incr_decr {crv clicked which} {
    global curve_param_val vam_events bunching_laws aie_ShowCurveQuads curve_param_last
    
    aie_update_mesh_params curve $crv  
    switch $which {
        emax { set button mszCurveSz }
        nmax { set button mszCurveNum }
        brat { set button mszCurveBRat }
        ehgt { set button mszCurveHgt }
        hrat { set button mszCurveRat }
        ewid { set button mszCurveWid }
        emin { set button mszCurveMinSz }
        edev { set button mszCurveDev }
    }

    if {$which == "brat"} {
        if {[mszCurveDEZ get blaw] == "Geometric2"} {
            set val [lindex [ic_geo_get_curve_bunching $crv] 11]
        } else {
            set val [lindex [ic_geo_get_curve_bunching $crv] 9]
        }
        set law_cur [mszCurveDEZ get blaw]
        if {$law_cur == ""} {
            set law_cur [lindex [ic_geo_get_curve_bunching $crv] 1]
            if {$law_cur != ""} {
                foreach name [array names bunching_laws] {
                    if {$law_cur == $bunching_laws($name)} {
                        mszCurveDEZ set blaw $name
			            break
                    }
                }
            }
        }
        if {$val != ""} {
            mszCurveDEZ set brat $val
        } else {
            mszCurveDEZ set brat 1.0
        }
        if {[info exists curve_param_last] && [mszCurveDEZ get blaw] == "Uniform"} {
            mszCurveDEZ set blaw $curve_param_last
            unset curve_param_last
        }
    } elseif {$which == "nmax"} {
        set tmax [mszCurveDEZ get emax]
        if {$tmax == "" || $tmax == 0} {
            mszCurveDEZ set nmax 2
        }
    }   

    switch $clicked {
        1 { [lindex [mszCurveDEZ pathIgnoreErrors $button] 1].arrup invoke }
        3 { [lindex [mszCurveDEZ pathIgnoreErrors $button] 1].arrdn invoke }
     }

     aie_curve_display_param 1 $which 1
     if {$which == "nmax"} {
         set args [aie_convert_relative "emax [mszCurveDEZ get emax]" 0]
         eval ic_set_meshing_params curve $crv $args
     } elseif {$which == "brat"} {
        set scale [ic_geo_get_ref_size]
        if {$scale == ""} { set scale 1.0 }
	set tmax [mszCurveDEZ get emax]
	if {$tmax == "" || $tmax == 0} {
           vam_unset_timer
           msg ERROR "Missing maximum element size"
           return
	}
        set l [expr double([ic_geo_crv_length $crv])]
        set n [expr round($l / ($tmax * $scale))]
        set nn [expr $n + 1]
        set r $curve_param_val($crv)
        set bname [mszCurveDEZ get blaw]
        if {$bname == ""} {
            vam_unset_timer
            msg ERROR "Missing bunching law"   
            return        
        }
        if {$bname != "Geometric1" && $bname != "Geometric2" && $bname == "Uniform" && \
            $bname != "BiGeometric"} {
            vam_unset_timer
            msg ERROR "Meshing law $bname currently not supported by \"Dynamic\" method for curve mesh parameters"
            return            
        }
        if {$bname == "Geometric1" || $bname == "Geometric2"} {
            set s [aie_curve_incr_decr_get_space $r $n $l]
        } elseif {$bname == "BiGeometric"} {
            if {[expr $n / 2] == [expr $n / 2.0]} {
                set s [aie_curve_incr_decr_get_space $r [expr $n / 2] [expr $l / 2.0]]
             } else {
                set s [aie_curve_incr_decr_get_space $r [expr round($n / 2.0)] [expr $l / 2.0] 1]
             }
        } elseif {$bname == "Uniform"} {
            set s 0.0
        }
        if {$s < 0} {
           vam_unset_timer
           msg ERROR "Unable to calculate space for ratio $r.\nSpacing is too small."
	   [lindex [mszCurveDEZ pathIgnoreErrors $button] 1].arrdn invoke
	   aie_curve_display_param 1 $which 1
	   ic_geo_configure_one_object curve $crv draw_quad_size 1
	   return 
        }
        if {$r == 1} {
            if {$bname == "Geometric1"} {
                mszCurveDEZ set blaw Geometric2
                set bname Geometric2
                mess "Bunching law reset to \"Geometric2\".\n"
            } elseif {$bname == "Geometric2"} {
                mszCurveDEZ set blaw Geometric1
                set bname Geometric1
                mess "Bunching law reset to \"Geometric1\".\n"
            } elseif {$bname != "Uniform"} {
                set curve_param_last $bname
                mszCurveDEZ set blaw Uniform
                set bname Uniform
                mess "Bunching law reset to \"Uniform\".\n"
            }
        } else {
            catch { unset curve_param_last }
        }
        if {$bname == "Geometric1"} {
            set h1 $s; set h2 0; set r1 $r; set r2 0
        } elseif {$bname == "Geometric2"} {
            set h1 0; set h2 $s; set r1 0; set r2 $r
        } else {
	    set h1 $s; set h2 $s; set r1 $r; set r2 $r
	}
	set lname $bunching_laws($bname)
	set args "$lname n $nn h1 $h1 h2 $h2 r1 $r1 r2 $r2 lmax 0.0"
	ic_geo_set_curve_bunching $crv [join $args]
	mszCurveDEZ set law [mszCurveDEZ get blaw]
	mszCurveDEZ set h1 $h1
	mszCurveDEZ set h2 $h2
	mszCurveDEZ set r1 $r1
	mszCurveDEZ set r2 $r2
	mszCurveDEZ set lmax 0.0
     } else {
         set args [aie_convert_relative "$which $curve_param_val($crv)" 0]
         eval ic_set_meshing_params curve $crv $args
     }
     aie_curve_display_param 1 $which 1
     if {$which == "brat"} {
         ic_geo_configure_one_object curve $crv draw_quad_size 1
     } else {
         if $aie_ShowCurveQuads {
             ic_geo_configure_one_object curve $crv draw_quad_size 1
         } else {
             ic_geo_configure_one_object curve $crv draw_quad_size 0
         }
     }
}

proc aie_curve_mouse_incr_decr_wait {which what b x y t} {
    global tdv_current_viewer tdv_pickable_tags curve_param_crv vam_events

    vam_unset_timer
    set picked [$tdv_current_viewer pick $x $y $tdv_pickable_tags($tdv_current_viewer) "" 10]
    if {$picked == ""} return
    set im [lindex $picked 0]
    if ![info exists curve_param_crv($im)] return
    set crv $curve_param_crv($im)
    switch $what {
        press {
            switch $b {
                1 - 3 {
                    set vam_events(timer_command) [list aie_curve_mouse_incr_decr_doit $crv $b $which]
                    set vam_events(timer) $t
                    after $vam_events(delay_before) vam_set_timer 
                }
                default {
                    aie_curve_mouse_dynamic_done
                    return
                }
            }
        }
        release {
            switch $b {
                1 - 3 {
                    vam_unset_timer
                    aie_curve_mouse_incr_decr_doit $crv $b $which
                    mszCurveDEZ setclean
                }
                default {
                    aie_curve_mouse_dynamic_done
                    return
                }
            }
        }
    }
}

proc aie_curve_mouse_incr_decr_doit {crv click which} {
     mszCurveDEZ set curveList $crv
     aie_curve_mouse_incr_decr $crv [lindex $click 0] $which
     mszCurveDEZ set curveList ""
}

proc aie_curve_mouse_incr_decr_pos {w x y which reset_size} {
    global tdv_current_viewer tdv_pickable_tags curve_param_crv curve_param_sel
    
    if [info exists curve_param_sel] {
        ic_show_geo_selected curve $curve_param_sel 0
        if {$which == "brat" && !$reset_size} {
            ic_geo_configure_one_object curve $curve_param_sel draw_quad_size 0
        }
        unset curve_param_sel
    }
    tdv_update_track_mouse $w $x $y
    tdv_track_wb_mouse $w $x $y

    set picked [$tdv_current_viewer pick $x $y $tdv_pickable_tags($tdv_current_viewer) "" 10]
    if {$picked == ""} return
    set im [lindex $picked 0]
    if [info exists curve_param_crv($im)] {
        set crv $curve_param_crv($im)
    } else {
       return 
    }
    ic_show_geo_selected curve $crv 1
    if {$which == "brat"} {
        aie_curve_display_direction $x $y 1
    } else {
        aie_curve_display_direction "" "" 0
    }
    if {$which == "brat"} {
        ic_geo_configure_one_object curve $crv draw_quad_size 1
    }
    set curve_param_sel $crv
}

proc onmszCurveDEZLoad {} {
    global env

    if {![info exists env(AI_ENV_CFX)] && [ic_uns_is_loaded]} {
        if ![meshAutoDEZ isbuilt] {
	        meshAutoDEZ build
        }
        if ![mszGlobalDEZ isbuilt] {
	        mszGlobalDEZ build
        }
    }
}

proc onmszCurveDEZAfterLoad {} {
    global bunching_laws curve_properties

    set dirCurveFlag 0
    foreach name "emax nmax ehgt hrat ewid emin edev" {
        if {[trace vinfo $name] != ""} {
            trace vdelete $name w aie_curve_trace_emax_nmax
        }
        trace variable $name w aie_curve_trace_emax_nmax
    }
    if {[trace vinfo curveList] != ""} {
        trace vdelete curveList w aie_curve_trace_curveList
    }
    trace variable curveList w aie_curve_trace_curveList
    
    foreach var {emax_incr nmax_incr brat_incr ehgt_incr hrat_incr ewid_incr emin_incr edev_incr} {
        set $var [set curve_properties($var)]
    }
    foreach name "emax nmax brat ehgt hrat ewid emin edev" {
        aie_curve_incr_decr_properties $name
    }
    
    set prism_height_limit 0.0
    set PrismLawList {undefined linear exponential wb-exponential}
    set prism_law undefined
    
    set supported_laws ""
    foreach item [lsort [array names bunching_laws]] {
        switch $item {
            From-Graphs - On-Screen - Spline - Linear - FromEdgeSplits - UserDefined { continue }
            default { lappend supported_laws $item }
        }
    }
    set LawList $supported_laws
    if {$law == ""} { set law BiGeometric }
    set simpleLawList [list BiGeometric Geometric1 Geometric2 Uniform]
    
    if {[ic_geo_check_objects_exist curve $curveList] != ""} {
        aie_update_mesh_params curve $curveList
        if {$law != ""} {
            set blaw $law
        } else {
            set blaw ""
        }
    } else {
        set curveList ""
        set blaw ""
        foreach p {law h1 h2 r1 r2 lmax} {
            set $p ""
        }
    }
    
    if {![info exists adjustFlag] || ([llength $curveList] > 1)} { set adjustFlag 0 }
    if ![info exists mszCurveTypeGGVal] { set mszCurveTypeGGVal 0 }
    if {$dirCurveFlag && $curveList != ""} { aie_curve_show_directions }
    
    if [aie_wb2_is_running] {
        after 100 {
            ic_wb2_update_parameters input
            aie_wb2_wb_parameter_input_geom_curve [ mszCurveDEZ get curveList]
        }
    }
}

proc onmszCurveDEZUnLoad {} {
    global trace_emax_nmax_done curve_param_par curve_param_directions
    
    if [info exists curve_param_par] {
        aie_curve_mouse_dynamic_done $curve_param_par $curveList 0 0
    }
    foreach item $curveList {
        if {[ic_geo_check_objects_exist curve $item] == ""} continue
        ic_show_geo_selected curve $item 0
    }
    if {[info exists curve_param_directions] && $curveList != ""} {
        set dirCurveFlag 0
        aie_curve_show_directions $curve_param_directions
    }
    foreach name "emax nmax ehgt hrat ewid emin edev" {
        if {[trace vinfo $name] != ""} {
            trace vdelete $name w aie_curve_trace_emax_nmax
        }
    }
    catch { unset trace_emax_nmax_done }
}

proc onmszCurveTypeAdvancedLoad {} {
    global curve_param_directions
    set curves [mszCurveDEZ get curveList]
    if {$curves != ""} {
        ic_show_geo_selected curve $curves 0
    }
    if {[info exists curve_param_directions] && $curves != ""} {
        set dirCurveFlag 0
        aie_curve_show_directions $curve_param_directions
    }
    mszCurveDEZ setclean
}

proc onmszCurveTypeAdvancedUnLoad {} {
    mszCurveDEZ setdirty
}

proc onmszCurveTypeCopyLoad {} {
    set curves [mszCurveDEZ get curveList]
    if {$curves != ""} {
        ic_show_geo_selected curve $curves 0
    }
    if {$copyCurveFrom != ""} {
        if {[ic_geo_check_objects_exist curve $copyCurveFrom] == ""} {
            set copyCurveFrom ""
        }
    }
    foreach crv $copyCurveTo {
        if {[ic_geo_check_objects_exist curve $crv] == ""} {
            set copyCurveTo ""
            break
        }
    }
    if ![info exists copy_absolute] {
        set copy_absolute 0
    }
}

proc onmszCurveTypeCopyUnLoad {} {
    if {$copyCurveFrom != ""} {
        ic_show_geo_selected curve "$copyCurveFrom" 0
    }
    if {$copyCurveTo != ""} {
        ic_show_geo_selected curve "$copyCurveTo" 0
    }
}

proc aie_curve_trace_emax_nmax {name element op} {
    global trace_emax_nmax_done

    if {$element != ""} {
        set curves $element
    } else {
        set curves [mszCurveDEZ get curveList]
    }

    switch $name {
        ::AIEnv::DEZ::mszCurveDEZ::emax {
            set trace_emax_nmax_done emax
        }
        ::AIEnv::DEZ::mszCurveDEZ::nmax {
            set trace_emax_nmax_done nmax
        }
    }
    
    if {[llength $curves] > 1} return
    
    set scale [ic_geo_get_ref_size]
    if {$scale == ""} { set scale 1.0 }
    foreach item $curves { 
        set l [expr double([ic_geo_crv_length $item])]
        switch $name {
            ::AIEnv::DEZ::mszCurveDEZ::emax {
                set emax [mszCurveDEZ get emax]
                if {[expr ($emax * $scale) - 0.00001] > $l} {
	            vam_unset_timer
	            msg ERROR "Curve len is $l. Maximum size for curve $item must be <= curve length.\
                              Note that curve scale factor is $scale"
	            mszCurveDEZ set emax $l
                   set num [expr round($l / ($l * $scale)) + 1]
                   mszCurveDEZ set nmax $num
	            return
                }
                if {[expr ($emax * $scale)] == 0} return
                set num [expr round($l / ($emax * $scale)) + 1]
                if {$num < 2} {
	           vam_unset_timer
	           return
                }
            mszCurveDEZ set nmax $num
            }
            ::AIEnv::DEZ::mszCurveDEZ::nmax {
	        set nnmax [mszCurveDEZ get nmax]
                if {$nnmax < 2 || $nnmax == ""} {
	           vam_unset_timer
	           return
                }
	        mszCurveDEZ set emax [expr ($l/[expr $nnmax - 1]) / $scale]
            }
        }
    }
}

proc aie_curve_trace_curveList {name element op} {
    set len [llength [mszCurveDEZ get curveList]]
    if {$len > 1 || $len == 0} {
        ::AIEnv::GUIManagement::ToggleGrey mszCurveAdjust 1
        mszCurveDEZ set adjustFlag 0
    } elseif {$len == 1} {
        ::AIEnv::GUIManagement::ToggleGrey mszCurveAdjust 0
    }
    if {$len > 0} {
        ::AIEnv::GUIManagement::ToggleGrey mszCurveDir 0
        ::AIEnv::GUIManagement::ToggleGrey mszCurveDirReverse 0
        if [mszCurveDEZ get dirCurveFlag] {
            aie_curve_show_directions
        }
    } else {
        ::AIEnv::GUIManagement::ToggleGrey mszCurveDir 1
        ::AIEnv::GUIManagement::ToggleGrey mszCurveDirReverse 1
    }
}

proc aie_curve_incr_decr_properties {name} {
    global curve_properties
    
    set min 0.0; set max 10000
    switch $name {
        emax { set b mszCurveSz; set max 999999 }
        nmax { set b mszCurveNum; set min 2; set max 100000 }
        brat { set b mszCurveBRat; set min 1 }
        ehgt { set b mszCurveHgt }
        hrat { set b mszCurveRat }
        ewid { set b mszCurveWid; set min 0; set max 100 }
        emin { set b mszCurveMinSz }
        edev { set b mszCurveDev }
    }
    set v [mszCurveDEZ get ${name}_incr]
    switch $name {
        nmax - ewid {
            set v [expr round($v)]
            mszCurveDEZ set ${name}_incr $v
        }
    }    
    set w [lindex [mszCurveDEZ pathIgnoreErrors $b] 1]
    if {$v != ""} {
        SpinBox::configure $w -range "$min $max $v"
    } else {
        set v [lindex [SpinBox::cget $w -range] 2]
    }
    set curve_properties(${name}_incr) $v
}

proc aie_curve_incr_decr_get_space {ratio num len {not_even 0}} {
   
   set ratio [expr double($ratio)]
   set len [expr double($len)]
   
   if {$ratio == 1} {
       return [expr $len / $num]
   }
   switch $not_even {
       0 {
           set f [expr ((1.0 - $ratio) / (1.0 - pow($ratio, $num))) * $len]
       }
       1 {
           set f [expr $len * (2.0 * (1.0 - $ratio) / (2.0 - (1.0 + $ratio) * pow($ratio, $num-1.0)))] 
       }
   }
   return [expr $f - 0.0000001]
}

proc aie_curve_incr_decr_get_ratio {space num len {not_even 0}} {     
   set len [expr double($len)]
   set space [expr double($space)]
   if {$space == 0} { return 0 }
   set tol [expr 0.0000001 * $len]
   set end 10000
   set div [expr double($end/10.0)]
   while 1 {
       for {set i 2} {$i < $end} {incr i 1} {
           set ii [expr double($i/$div)]
           if {[expr (1.0 - pow($ii, $num))] == 0} continue
           switch $not_even {
               0 {
                   if {[expr (1.0 - pow($ii, $num))] == 0} continue
                   set f [expr ((1.0 - $ii) / (1.0 - pow($ii, $num))) * $len]
               }
               1 {
                   if {[expr (2.0 - (1.0 + $ii) * pow($ii, $num-1.0))] == 0} continue
                   set f [expr $len * (2.0 * (1.0 - $ii) / (2.0 - (1.0 + $ii) * pow($ii, $num-1.0)))]
               }
           }
           set diff [expr $f - $space]
           if {$diff <= $tol} {
               if {$f > 0} {
                   return $ii
               } else {
                   return [exp ($i - 1) / $div]
               }
           } else {
               if {$diff > 0.1} { incr i [expr round($diff*10)] }
           }
       }
       break
   }
   return 0
}

proc aie_curve_params_blank {} {
    global geo_params_blanked curve_param_sel curve_param_par

    set w [mszCurveDEZ pathIgnoreErrors mszCurveDone]
    if [info exists geo_params_blanked(curve)] {
        if {$geo_params_blanked(curve) == ""} {
            set geo_params_blanked(curve) [ic_geo_params_blank_done curve 0]
        } else {
            set geo_params_blanked(curve) [ic_geo_params_blank_done curve 1]
        }
    } else {
        set geo_params_blanked(curve) [ic_geo_params_blank_done curve 0]
    }
    if {$geo_params_blanked(curve) == ""} {
        $w configure -text "Blank curves with params"
    } else {
        $w configure -text "Unblank curves with params"
    }
    if [info exists curve_param_par] {
        aie_curve_display_param 1 $curve_param_par 0
    }
}

proc aie_curve_params_blank_update {} {
# blank if user set param in "Blank" mode
    global geo_params_blanked   
    set w [mszCurveDEZ pathIgnoreErrors mszCurveDone]
    set now [lindex [lindex [$w configure -text] end] 0]
    if {$now == "Blank"} return
    set geo_params_blanked(curve) [ic_geo_params_blank_done curve 0]
}

proc aie_curve_params_adjust {ref_crv} {

    if {$ref_crv == ""} { return "" }
    set adjust_curves ""
    set adjust_angle ""       
    set entities ""
    set pts($ref_crv) ""
    set pts_pos($ref_crv) ""
    foreach p {0 1} {
	if [catch {ic_geo_crv_get_end $ref_crv $p} pt] {
	    mess "Curve $ref_crv not associated.\n" red
	    return ""
	} else {
	    if {[lsearch $entities $pt] < 0} {
	        lappend entities $pt
	        lappend pts($ref_crv) $pt
	        lappend pts_pos($ref_crv) [ic_geo_get_point_location $pt]
	    }
	}
    }
    if {$entities != ""} {
        foreach crv [ic_geo_get_attached_entities incident point $entities] {
            if {[lsearch $ref_crv $crv] < 0 && [lsearch $adjust_curves $crv] < 0} {
                append adjust_curves " $crv"
            }
        }
    } else {
        return ""
    }
    set diff_dir ""
    set same_start ""
    set same_end ""
    set ref_pos_s [lindex $pts_pos($ref_crv) 0]
    set ref_pos_e [lindex $pts_pos($ref_crv) 1]
    set ref_pos_sn [lindex [ic_geo_get_crv_pos 0.1 $ref_crv] 0]
    set ref_pos_en [lindex [ic_geo_get_crv_pos 0.9 $ref_crv] 0]
    set failed_curves ""
    foreach crv $adjust_curves {
        set size [lindex [ic_get_meshing_params curve $crv] 1]
        if {$size == "" || $size == 0.0} {
            append failed_curves "$crv "
            continue
        }
        set cs [ic_geo_crv_get_end $crv 0]
        set ce [ic_geo_crv_get_end $crv 1]
        if {[lsearch $pts($ref_crv) $cs] != 0 && [lsearch $pts($ref_crv) $ce] != 1} {
            append diff_dir " $crv"
            if {[lsearch $pts($ref_crv) $cs] == 1} {
                set pos1 $ref_pos_e; set pos2 $ref_pos_en
                set pos3 [lindex [ic_geo_get_crv_pos 0.1 $crv] 0]
                append same_end " $crv"
            } else {
                set pos1 $ref_pos_s; set pos2 $ref_pos_sn
                set pos3 [lindex [ic_geo_get_crv_pos 0.9 $crv] 0]
                append same_start " $crv"
            }
        } else {
            if {[lsearch $pts($ref_crv) $cs] == 0} {
                set pos1 $ref_pos_s; set pos2 $ref_pos_sn
                set pos3 [lindex [ic_geo_get_crv_pos 0.1 $crv] 0]
                append same_start " $crv"
            } else {
                set pos1 $ref_pos_e; set pos2 $ref_pos_en
                set pos3 [lindex [ic_geo_get_crv_pos 0.9 $crv] 0]
                append same_end " $crv"
                
            }
        }
        set angle($crv) [ic_vcalc angle $pos1 $pos2 $pos3]
        if {$angle($crv) <= 120 && $angle($crv) >= 60} {
            append adjust_angle " $crv"
        }
    }
    if {$failed_curves != ""} {
        mess "Unable to adjust attached curve(s) [string trim $failed_curves].  Please set the \"Maximum Size\"\
              for this curve(s) before using the \"Adjust attached curves\" option.\n" red
    }
    return [list $adjust_angle $diff_dir $same_start $same_end]
}

proc aie_curve_params_copy {} {
    global bunching_laws

    set from [mszCurveDEZ get copyCurveFrom]
    if {$from == ""} {
        mess "No source curve selected.\n" red
        return
    }
    set to [mszCurveDEZ get copyCurveTo]
    if {$to == ""} {
        mess "No target curve(s) selected.\n" red
        return
    }
    if {[lsearch $to $from] >= 0} {
        mess "Source curve $from can not be target curve.\n" red
        return
    }
  
    set absolute [mszCurveDEZ get copy_absolute]
    set from_emax [mszCurveDEZ get from_emax]
    set from_nmax [mszCurveDEZ get from_nmax]
    set from_ehgt [mszCurveDEZ get from_ehgt]
    set from_hrat [mszCurveDEZ get from_hrat]
    set from_ewid [mszCurveDEZ get from_ewid]
    set from_emin [mszCurveDEZ get from_emin]
    set from_edev [mszCurveDEZ get from_edev]   
    set from_law [mszCurveDEZ get from_law]
    set from_h1 [mszCurveDEZ get from_h1]
    set from_h2 [mszCurveDEZ get from_h2]
    set from_r1 [mszCurveDEZ get from_r1]
    set from_r2 [mszCurveDEZ get from_r2]
    set from_lmax [mszCurveDEZ get from_lmax]
    set bunching [ic_geo_get_curve_bunching $from]
    set from_len [expr double([ic_geo_crv_length $from])]
    set scale [ic_geo_get_ref_size]
    if {$scale == ""} { set scale 1.0 }
    busy 1
    foreach crv $to {    
        set len [expr double([ic_geo_crv_length $crv])]
        set tmax [expr ($len / ($from_nmax - 1)) / $scale]
        set args [list emax $tmax emin $from_emin ehgt $from_ehgt edev $from_edev hrat $from_hrat ewid $from_ewid]
        set args [aie_convert_relative $args 0]
        eval ic_set_meshing_params curve $crv "$args"
        if {$bunching != ""} {
            set num_nmax [expr round($len / ($tmax * $scale)) + 1]
            set n [expr round($len / ($tmax * $scale))]
            if {$from_law == "Geometric1" || $from_law == "Geometric2" || $from_law == "Uniform"} {
                if {$from_law == "Geometric1" || $from_law == "Uniform"} {
                    if $absolute {
                        set r1 [aie_curve_incr_decr_get_ratio $from_h1 $n $len]
                        set r2 [aie_curve_incr_decr_get_ratio $from_h2 $n $len]
                    } else {
                        set h1 [aie_curve_incr_decr_get_space $from_r1 $n $len]
                        if {$from_r2 != 0} {
                            set h2 [aie_curve_incr_decr_get_space $from_r2 $n $len]
                        } else {
                           set  h2 0
                        }
                    }
                } elseif {$from_law == "Geometric2"} {
                    if $absolute {
                        set r1 [aie_curve_incr_decr_get_ratio $from_h1 $n $len]
                        set r2 [aie_curve_incr_decr_get_ratio $from_h2 $n $len]
                    } else {
                        set h2 [aie_curve_incr_decr_get_space $from_r2 $n $len]
                        if {$from_r1 != 0} {
                            set h1 [aie_curve_incr_decr_get_space $from_r1 $n $len]
                        } else {
                            set h1 0
                        }
                    }
                }
            } elseif {$from_law == "BiGeometric"} {
                if $absolute {
                    if {[expr $n / 2] == [expr $n / 2.0]} {
                        set r1 [aie_curve_incr_decr_get_ratio $from_h1 [expr round($n / 2.0)] [expr $len / 2.0]]
                        set r2 [aie_curve_incr_decr_get_ratio $from_h2 [expr round($n / 2.0)] [expr $len / 2.0]]
                    } else {
                        set r1 [aie_curve_incr_decr_get_ratio $from_h1 [expr round($n / 2.0)] [expr $len / 2.0] 1]
                        set r2 [aie_curve_incr_decr_get_ratio $from_h2 [expr round($n / 2.0)] [expr $len / 2.0] 1]
                    }
                } else {
                    if {[expr $n / 2] == [expr $n / 2.0]} {
                        set h1 [aie_curve_incr_decr_get_space $from_r1 [expr round($n / 2.0)] [expr $len / 2.0]]
                        set h2 [aie_curve_incr_decr_get_space $from_r2 [expr round($n / 2.0)] [expr $len / 2.0]]
                    } else {
                        set h1 [expr $len * ($from_h1 / $from_len)]
                        set h2 [expr $len * ($from_h2 / $from_len)]
                    }
                }
            } elseif {$from_law == "Biexponential" && 0} { 
            } else {
                mess "Source curve bunching law $from_law not supported for \"Copy Parameters\".\n" red
            }
	    if {$from_law != "" && $num_nmax > 1} {
	        set lname $bunching_laws($from_law)
	        if $absolute {
                set args "$lname n $num_nmax h1 $from_h1 h2 $from_h2 r1 $r1 r2 $r2 lmax $from_lmax"
	        } else {
	            set args "$lname n $num_nmax h1 $h1 h2 $h2 r1 $from_r1 r2 $from_r2 lmax $from_lmax"
	        }
	        ic_geo_set_curve_bunching $crv [join $args]
	    }            
        }
    }
    busy 0
    aie_update_mesh_params curve $to
    mess "Done copy curve parameters\n"
}

proc onmszCurveDEZOK {} {
    global aie_meshParams env bunching_laws trace_emax_nmax_done aie_ShowCurveQuads

    if {$mszCurveTypeGGVal == 2} {
        aie_curve_params_copy
        return
    }
    
    if [info exists curveList] {
         if {$curveList == ""} {
            mess "No curve(s) selected.\n" red
            return
        }
    } else {
        return
    }
    set curve_list "$curveList"
    
    set adjust_curves ""
    set adjust_curves_dir ""
    set adjust_curves_start ""
    set adjust_curves_end ""
    catch { unset ref_crv }
    if $adjustFlag {
        set ref_crv [lindex $curveList 0]
        set curves [aie_curve_params_adjust $ref_crv]
        if {$curves != ""} {
            set adjust_curves [lindex $curves 0]
            set adjust_curves_dir [lindex $curves 1]
            set adjust_curves_start [lindex $curves 2]
            set adjust_curves_end [lindex $curves 3]
            append curve_list " $adjust_curves"
        }
    }   
    # Remember that all local variables are persistent!!
    catch { unset set_with_args }
    catch { unset adjust_hgt }
    catch { unset adjust_rat }

    set scale [ic_geo_get_ref_size]
    if {$scale == ""} { set scale 1.0 }

    set reset 0
    if $aie_ShowCurveQuads {
        set aie_ShowCurveQuads 0
        set reset 1
        ::AIEnv::GUIManagement::Tree::ShowCurveQuadSizes
    }

    foreach crv $curve_list {
	set tmax ""
	set maxsize($crv) [lindex [ic_get_meshing_params curve $crv] 1]
	if [info exists trace_emax_nmax_done] {
	    switch $trace_emax_nmax_done {
	        nmax {
	            if {$nmax < 2 || $nmax == ""} {
	                if {$emax == ""} {
	                    set tmax $maxsize($crv)
	                } else {
	                    set tmax $emax
	                }
	            } else {
	                set l [expr double([ic_geo_crv_length $crv])]
	                set tmax [expr ($l/[expr $nmax - 1]) / $scale]
	            }
	        }
	        emax {
	            if {$emax == ""} {
	                if {$nmax < 2 || $nmax == ""} {
	                    set tmax $maxsize($crv)
	                } else {
	                    set l [expr double([ic_geo_crv_length $crv])]
	                    set tmax [expr ($l/[expr $nmax - 1]) / $scale]
	                }
	            } else {
	                set tmax $emax
	            }    
	        }
	    }
	} else {
	    if {$emax == ""} {
	        set tmax $maxsize($crv)
	    } else {
	        set tmax $emax
	    }
	}
	set tmin $emin
	set tdev $edev
	set twid $ewid
	set thgt $ehgt
	set trat $hrat
	set twid $ewid
	set tlay $nlay
	set tprism_height_limit $prism_height_limit
	switch -- "$prism_law" {
        exponential { set tlaw 0 }
        linear { set tlaw 1 }
        wb-exponential { set tlaw 3 }
        default { set tlaw -1 }
    }
	
	if {$adjustFlag && ([lsearch $adjust_curves $crv] >= 0)} {
	    set adjust_hgt($crv) $ehgt
	    set adjust_rat($crv) $hrat
	    foreach {n v} [ic_get_meshing_params curve $crv] {
	        switch $n {
	            ehgt { set thgt $v }
	            hrat { set trat $v }
	            ewid { set twid $v }
	            nlay { set tlay $v }
	            emin { set tmin $v }
	            edev { set tdev $v }
	            prism_height_limit { set tprism_height_limit $v }
	        }
	    }
	}
	set args [list emax $tmax emin $tmin ehgt $thgt edev $tdev hrat $trat ewid $twid nlay $tlay prism_height_limit $tprism_height_limit law $tlaw]
	set args [aie_convert_relative $args 0]
	lappend set_with_args($args) $crv
	set bunching_old($crv) ""; set bunching_new($crv) ""
    }

    # Do it this way to minimize the number of ic_set_meshing_params calls that go into the replay file
    ic_save_model_for_undo
    
    if [aie_wb2_is_running] {
        aie_set_global wb_input_parameter_mode 1
    }
    foreach args [array names set_with_args] {
        eval ic_set_meshing_params curve \{$set_with_args($args)\} $args
    }
    if [aie_wb2_is_running] {
        aie_unset_global wb_input_parameter_mode
    }

    if {$adjustFlag && [info exists ref_crv]} {
        if {$law != ""} {
            set law_name $bunching_laws($law)
            set l [expr double([ic_geo_crv_length $ref_crv])]
            set max_size [lindex [ic_get_meshing_params curve $ref_crv] 1]
            set num_nmax [expr round($l / $max_size) + 1]
            if {$num_nmax < 2 || $num_nmax == ""} {
                set num_nmax 2
            }
            set hh1 $h1; set hh2 $h2
            set rr1 $r1; set rr2 $r2
            set llmax $lmax
            set h1_nlay 1; set h2_nlay 1
	    if {$hh1 == ""} { set hh1 0 }
	    if {$hh2 == ""} { set hh2 0 }
	    if {$rr1 == ""} { set rr1 2 }
	    if {$rr2 == ""} { set rr2 2 }
	    if {$llmax == ""} { set llmax 0 }
	    if [regexp {\*} $h1] {
	        regsub -all {\*} $h1 " " h1_new
	        set hh1 [lindex $h1_new 0]
	        set h1_nlay [expr int([lindex $h1_new 1])]
	    }
	    if [regexp {\*} $h2] {
	        regsub -all {\*} $h2 " " h2_new
	        set hh2 [lindex $h2_new 0]
	        set h2_nlay [expr int([lindex $h2_new 1])]
	    }
	    if {[expr ($h1_nlay + $h2_nlay)] > [expr $num_nmax - 2]} {
	        mess "Advanced Bunching Error: Number of layers > (Number of nodes - 2)\n" red
	        return
	    }
            set args "$law_name n $num_nmax h1 $hh1 h2 $hh2 r1 $rr1 r2 $rr2 lmax $llmax nlay1 $h1_nlay nlay2 $h2_nlay"
            ic_geo_set_curve_bunching $ref_crv [join $args]
        }
    }

    if {($law != "" && $mszCurveTypeGGVal == 0) || ($adjustFlag && $adjust_curves != "")} {
	if {$h1 == ""} { set h1 0 }
	if {$h2 == ""} { set h2 0 }
	if {$r1 == ""} { set r1 2 }
	if {$r2 == ""} { set r2 2 }
	if {$lmax == ""} { set lmax 0 }
	foreach crv $curve_list {
            set l [expr double([ic_geo_crv_length $crv])]
            set max_size [lindex [ic_get_meshing_params curve $crv] 1]
            if {$max_size == ""} {
	        msg ERROR "Maximum Size not set for curve $crv"
	        return
            }
            if {[expr ($max_size * $scale)] == 0} {
                mess "Warning: Curve $crv \"Maximum Size\" is 0, bunching params not in\
                      right range. Bunching params ignored.\n" red
                continue
            } else {
                set num_nmax [expr round($l / ($max_size)) + 1]
                if {$num_nmax < 2} {
		    mess "Warning: Curve $crv \"Number of Nodes\" is $num_nmax, bunching\
		          params not in right range. Bunching params ignored.\n" red
		    continue
                }
            }
            set lname ""
            if {!$adjustFlag && $mszCurveTypeGGVal == 0} {
                set lname $bunching_laws($law)
            }
	    set bunching_old($crv) [ic_geo_get_curve_bunching $crv]
	    if {$adjustFlag && ([lsearch $adjust_curves $crv] >= 0)} {
	        set adjust_law [lindex $bunching_old($crv) 1]
	        set h1 0; set h2 0; set r1 0; set r2 0
	        if {$adjust_law  != "" && $adjust_law  != "uniform"} {
	            if {$adjust_law == "geo1"} {
	                if {[lsearch $adjust_curves_start $crv] >= 0} {
	                    if {[lsearch $adjust_curves_dir $crv] >= 0} {
	                        set h2 $adjust_hgt($crv)
	                        set r2 $adjust_rat($crv)
	                        set h1 [lindex $bunching_old($crv) 5]
	                        if {$h1 == ""} { set h1 0 }
	                        set r1 [lindex $bunching_old($crv) 9]
	                        if {$r1 == ""} { set r1 0 }
	                        set lname default  
	                    } else {
	                        set h1 $adjust_hgt($crv)
	                        set r1 $adjust_rat($crv)	                        
	                        
	                        set h2 [lindex $bunching_old($crv) 5]
	                        if {$h2 == ""} { set h2 0 }
	                        set r2 [lindex $bunching_old($crv) 9]
	                        if {$r2 == ""} { set r2 0 }
	                        set lname $adjust_law
	                    }
	                } elseif {[lsearch $adjust_curves_end $crv] >= 0} {
	                    if {[lsearch $adjust_curves_dir $crv] >= 0} {
	                        set h1 $adjust_hgt($crv)
	                        set r1 $adjust_rat($crv)
	                        
	                        set h2 [lindex $bunching_old($crv) 5]
	                        if {$h2 == ""} { set h2 0 }
	                        set r2 [lindex $bunching_old($crv) 9]
	                        if {$r2 == ""} { set r2 0 }

	                        set lname $adjust_law
	                    } else {
	                        set h2 $adjust_hgt($crv)
	                        set r2 $adjust_rat($crv)
	                        set h1 [lindex $bunching_old($crv) 5]
	                        if {$h1 == ""} { set h1 0 }
	                        set r1 [lindex $bunching_old($crv) 9]
	                        if {$r1 == ""} { set r1 0 }	                        
	                        set lname default
	                    }
	                }
	            } elseif {$adjust_law == "geo2"} {
	                if {[lsearch $adjust_curves_end $crv] >= 0} {
	                    if {[lsearch $adjust_curves_dir $crv] >= 0} {
	                        set h1 $adjust_hgt($crv)
	                        set r1 $adjust_rat($crv)
	                        set h2 [lindex $bunching_old($crv) 7]
	                        if {$h2 == ""} { set h2 0 }
	                        set r2 [lindex $bunching_old($crv) 11]
	                        if {$r2 == ""} { set r2 0 }
	                        set lname default
	                    } else {
	                        set h2 $adjust_hgt($crv)
	                        set r2 $adjust_rat($crv)
	                        
	                        set h1 [lindex $bunching_old($crv) 7]
	                        if {$h1 == ""} { set h1 0 }
	                        set r1 [lindex $bunching_old($crv) 11]
	                        if {$r1 == ""} { set r1 0 }

	                        set lname $adjust_law
	                    }
	                } elseif {[lsearch $adjust_curves_start $crv] >= 0} {
                            if {[lsearch $adjust_curves_dir $crv] >= 0} {
	                        set h2 $adjust_hgt($crv)
	                        set r2 $adjust_rat($crv)
	                        
	                        set h1 [lindex $bunching_old($crv) 7]
	                        if {$h1 == ""} { set h1 0 }
	                        set r1 [lindex $bunching_old($crv) 11]
	                        if {$r1 == ""} { set r1 0 }

	                        set lname $adjust_law
	                    } else {
	                        set h1 $adjust_hgt($crv)
	                        set r1 $adjust_rat($crv)
	                        set h2 [lindex $bunching_old($crv) 7]
	                        if {$h2 == ""} { set h2 0 }
	                        set r2 [lindex $bunching_old($crv) 11]
	                        if {$r2 == ""} { set r2 0 }
                                set lname default
                            }
	                }
	            } else {
	                if {[lsearch $adjust_curves_start $crv] >= 0} {
	                    set h1 $adjust_hgt($crv)
	                    set h2 [lindex $bunching_old($crv) 7]
	                    if {$h2 == ""} { set h2 0 }
	                    set r1 $adjust_rat($crv)
	                    set r2 [lindex $bunching_old($crv) 11]
	                    if {$r2 == ""} { set r2 0 }
	                } elseif {[lsearch $adjust_curves_end $crv] >= 0} {
	                    set h2 $adjust_hgt($crv)
	                    set h1 [lindex $bunching_old($crv) 5]
	                    if {$h1 == ""} { set h1 0 }
	                    set r2 $adjust_rat($crv)
	                    set r1 [lindex $bunching_old($crv) 9]
	                    if {$r1 == ""} { set r1 0 }
	                }
	                set lname default
	            }
	        } else {
	            if {[lsearch $adjust_curves_start $crv] >= 0} {
	                if {[lsearch $adjust_curves_dir $crv] >= 0} {
	                    set lname geo2
	                } else {
	                    set lname geo1
	                }
	            } elseif {[lsearch $adjust_curves_end $crv] >= 0} {
	                if {[lsearch $adjust_curves_dir $crv] >= 0} {
	                    set lname geo1
	                } else {
	                    set lname geo2
	                }
	            }
	            if {$lname == "geo1"} {
	                set h1 $adjust_hgt($crv)
	                set r1 $adjust_rat($crv)
	            } else {
	                set h2 $adjust_hgt($crv)
	                set r2 $adjust_rat($crv)
	            }
	        }
	    }
	    if {$lname != "" && $num_nmax > 1} {
	        set h1_space $h1
	        set h1_nlay 1
	        set h2_space $h2
	        set h2_nlay 1
	        set use_nlayers 0
	        if [regexp {\*} $h1] {
	            regsub -all {\*} $h1 " " h1_new
	            set h1_space [lindex $h1_new 0]
	            set h1_nlay [expr int([lindex $h1_new 1])]
	            set use_nlayers 1
	        }
	        if [regexp {\*} $h2] {
	            regsub -all {\*} $h2 " " h2_new
	            set h2_space [lindex $h2_new 0]
	            set h2_nlay [expr int([lindex $h2_new 1])]
	            set use_nlayers 1
	        }
	        if {$use_nlayers && ([expr ($h1_nlay + $h2_nlay)] > [expr $num_nmax - 2])} {
	            mess "Advanced Bunching Error: Number of layers > (Number of nodes - 2)\n" red
	            return
	        }
	        set args "$lname n $num_nmax h1 $h1_space h2 $h2_space r1 $r1 r2 $r2 nlay1 $h1_nlay nlay2 $h2_nlay lmax $lmax"
	        ic_geo_set_curve_bunching $crv [join $args]
	    }
	    set bunching_new($crv) [ic_geo_get_curve_bunching $crv]
        }
        if !$mszCurveTypeGGVal {
            mess "Done setting curve bunching law.\n" blue
        }
    }
    if ![info exists env(AI_ENV_CFX)] {
	# Remove and remesh curves and adjacent surfaces and make consistent
	if {($remeshFlag) && ([ic_uns_is_loaded])} {
	    if [info exists surf_remesh] { unset surf_remesh }
	    if [info exists etype] { unset etype }

	    foreach curve $curve_list {
		if {($maxsize($curve) != $tmax) || ($bunching_old($curve) != $bunching_new($curve))} {
		    set elmap [ic_uns_get_attached_elements curve $curve]
		    if {$elmap != "" && ([ic_uns_subset_count_elements $elmap] > 0)} {
			ic_delete_elements subset $elmap
			mess "Removed mesh from curve: $curve\n" blue
			ic_uns_subset_delete $elmap
		    }
		    set surfs [ic_geo_incident curve $curve]
		    foreach surf $surfs {
			if ![info exists surf_remesh($surf)] {
			    set elmap [ic_uns_get_attached_elements surface $surf]
			    if {$elmap != "" && ([ic_uns_subset_count_elements $elmap] > 0)} {
				set surf_remesh($surf) 1
				# Find the type of elements to remesh
				set nquads 0; set ntris 0
				foreach el [ic_uns_subset_list_elements $elmap] {
				    if {([regexp TRI_+ [lindex $el 0]]) == 1} {
					incr ntris
				    } elseif {([regexp QUAD_+ [lindex $el 0]]) == 1} {
					incr nquads
				    }
				}
				if {($nquads) && (!$ntris)} {
                                   # Will generate all quad if node bunching is alright,
                                   # needed to prevent failure, bug 9509
                                   set etype($surf) "Quad w/one Tri"
				} elseif {($ntris) && (!$nquads)} {
				    set etype($surf) "All Tri"
				} else {
				    set etype($surf) "Quad Dominant"
				}
				if {$elmap != "" && ([ic_uns_subset_count_elements $elmap] > 0)} {
				    ic_delete_elements subset $elmap
				}
				mess "Removed mesh from surface: $surf\n" blue
				ic_uns_subset_delete $elmap
			    } else {
				set surf_remesh($surf) 0
			    }
			}
		    }
		}
	    }


        
	    set remeshed_any 0
	    meshAutoDEZ onmeshAutoSurfLoad
	    set reset_type [meshAutoDEZ get etype2]
	    set reset_method [meshAutoDEZ get emethod2]
	    meshAutoDEZ set etype2 "Quad Dominant"
	    meshAutoDEZ set emethod2 "Patch Dependent"
	    set surfaces ""
	    foreach surf [array names surf_remesh] {
	        if $surf_remesh($surf) {
	            append surfaces "surface $surf "
	            mess "Remeshing surface: $surf with $etype($surf) elements\n" blue
	        }
	    }
	    if {$surfaces != ""} {
	        meshAutoDEZ set geomEnts $surfaces
		meshAutoDEZ aie_compute_surface_mesh
		set remeshed_any 1
	    }
	    meshAutoDEZ set etype2 $reset_type
	    meshAutoDEZ set emethod2 $reset_method
	    meshAutoDEZ set geomEnts ""

	    if {$remeshed_any && ([ic_uns_dimension] == 3)} {
                set types [ic_uns_list_types]
                set has_hex 0; set has_prism 0
                foreach t $types {
	            if {[string range $t 0 3] == "HEXA"} {set has_hex 1 }
	            if {[string range $t 0 4] == "PENTA"} {set has_prism 1 }
                }
                set const_mess "Making volume mesh consistent with surface mesh elements ?"
                if {$has_hex || $has_prism} {
                    append const_mess "\nWarning: This operation will make the volume mesh inconsistent !"
                }
	        switch -- [tk_dialog .make_consistent "Make Volume Consistent" "$const_mess" "" -1 Yes No] {
	                -1 { if [winfo exists .make_consistent] { top_destroy .make_consistent } }
                    0 {
                        mess "Making volume mesh consistent with surface mesh elements\n" blue
                        busy 1
                        ic_uns_make_consistent all
                        busy 0
                    }
	        }
	    }
	}
    }
    if {$adjust_curves != ""} {
        mess "Adjusted attached curves $adjust_curves.\n" blue
    }
    aie_update_mesh_params curve $curveList
    catch { unset trace_emax_nmax_done }

    if $reset {
        set aie_ShowCurveQuads 1
        ::AIEnv::GUIManagement::Tree::ShowCurveQuadSizes
    }
    aie_curve_params_blank_update
    mess "Done setting curve mesh size.\n" blue
}

proc onmszSurfPickFinish {} {
    aie_update_mesh_params surface $surfList
    if [aie_wb2_is_running] {
        aie_wb2_wb_parameter_input_geom_surface $surfList
    }
}

proc onmszSurfDEZLoad {} {
    global env

    foreach par {emin erat edev ewid nlay} {
        if ![info exists $par] {
            set $par 0
        }
    }
    set surfElemTypeList {
        "All Tri"
        "Quad w/one Tri"
        "Quad Dominant"
        "All Quad"
        "NONE"
    }
    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"
    }
    if {[info exists env(AI_ENV_QUAD)]} {
       lappend surfElemMethodList "Delaunay"
    }
    lappend surfElemMethodList "NONE"
}

proc onmszSurfDEZAfterLoad {} {
    global env

    set etyp2 "NONE"
    set emethod2 "NONE"
    set remeshSurfFlag 0
    set prism_height_limit 0.0
    set PrismLawList {undefined linear exponential wb-exponential}
    set prism_law undefined
    
    if ![info exists env(AI_ENV_CFX)] {
        if ![meshAutoDEZ isbuilt] {
	        meshAutoDEZ build
        }
        if ![mszGlobalDEZ isbuilt] {
	        mszGlobalDEZ build
        }
    }
    if [aie_wb2_is_running] {
        after 100 {
            ic_wb2_update_parameters input
            aie_wb2_wb_parameter_input_geom_surface [mszSurfDEZ get surfList]
        }
    }
}

proc onmszSurfDEZUnLoad {} {
    set surfList ""
}

proc onmszSurfDEZOK {} {
    global env

    if {$surfList == ""} return
    foreach srf $surfList {
        if {[ic_geo_check_objects_exist surface $srf] == ""} {
            mess "Error: No surface named \"$srf\".\n" red
            return
        }
    }
    if ![info exists ewid] {set ewid 0}
    if ![info exists nlay] {set nlay 0}
    set remesh_possible 0
    if {$etyp2 == ""} {
        set etyp ""
    } else {
        set etyp [aie_surface_get_mesh_type_number $etyp2]
        set remesh_possible 1
    }
    if {$emethod2 == ""} {
        set emethod ""
    } else {
        set emethod [aie_surface_get_mesh_method_number $emethod2]
        set remesh_possible 1
    }
    switch -- "$prism_law" {
        exponential { set law 0 }
        linear { set law 1 }
        wb-exponential { set law 3 }
        default { set law -1 }
    }
    
    set args [list emax $emax emin $emin ehgt $ehgt edev $edev erat $erat ewid $ewid nlay $nlay hrat $hrat prism_height_limit $prism_height_limit law $law]
    if {$etyp != ""} {
        append args " etyp $etyp"
    }
    if {$emethod != ""} {
       append args " emethod $emethod"
    }
    set args [aie_convert_relative $args 0]

    if [aie_wb2_is_running] {
        aie_set_global wb_input_parameter_mode 1
    }

    eval ic_set_meshing_params surface \{$surfList\} $args
    
    if [aie_wb2_is_running] {
        aie_unset_global wb_input_parameter_mode
    }
    
    if {![info exists env(AI_ENV_CFX)] && $remeshSurfFlag && [ic_uns_is_loaded] && $remesh_possible} {
	    meshAutoDEZ onmeshAutoSurfLoad
	    mess "Remeshing surfaces: $surfList\n" blue
	    set remeshed_any 0
	    set surfaces ""
	    foreach surf $surfList {
	        append surfaces "surface $surf "
	        set remeshed_any 1
	    }
	    meshAutoDEZ set geomEnts "$surfaces"
	    meshAutoDEZ aie_compute_surface_mesh
        meshAutoDEZ set geomEnts ""
        aie_updateMeshVis
	    if {$remeshed_any && ([ic_uns_dimension] == 3)} {
            set types [ic_uns_list_types]
            set has_hex 0; set has_prism 0
            foreach t $types {
	            if {[string range $t 0 3] == "HEXA"} {set has_hex 1 }
	            if {[string range $t 0 4] == "PENTA"} {set has_prism 1 }
            }
            set const_mess "Making volume mesh consistent with surface mesh elements ?"
            if {$has_hex || $has_prism} {
                append const_mess "\nWarning: This operation will make the volume mesh inconsistent !"
            }
	        switch -- [tk_dialog .make_consistent "Make Volume Consistent" "$const_mess" "" -1 Yes No] {
	            -1 { if [winfo exists .make_consistent] { top_destroy .make_consistent } }
                0 {
                    mess "Making volume mesh consistent with surface mesh elements\n" blue
                    busy 1
                    ic_uns_make_consistent all
                    aie_updateMeshVis
                    busy 0
                }
	        }
	    }
    }
    aie_surface_params_blank_update
    mszSurfDEZ setdirty
    mess "Done setting surface mesh size.\n" blue
}

proc aie_surface_get_mesh_type_number {type} {
    set etyp -1
    switch $type {
        "All Quad" { set etyp 2 }
        "Quad w/one Tri" { set etyp 4 }
        "Quad Dominant" { set etyp 3 }
        "All Tri" { set etyp 0 }
    }
    return $etyp
}

proc aie_surface_get_mesh_type_name {type} {
    set name "NONE"
    switch -- $type {
        4 { set name "Quad w/one Tri" }
        3 { set name "Quad Dominant" }
        0 { set name "All Tri" }
        2 { set name "All Quad" }
    }
    return $name
}

proc aie_surface_get_mesh_method_number {method} {
    set emethod -1
    switch $method {
        "Autoblock" { set emethod 0 }
        "Patch Dependent" { set emethod 1 }
        "Patch Independent" { set emethod 2 }
        "Delaunay" { set emethod 3 }
        "NONE" { set emethod -1 }
    }
    return $emethod
}

proc aie_surface_get_mesh_method_name {method} {
    set name "NONE"
    switch -- $method {
        0 { set name "Autoblock" }
        1 { set name "Patch Dependent" }
        2 { set name "Patch Independent" }
        3 { set name "Delaunay" }
        -1 { set name "NONE" }
    }
    return $name
}

proc aie_surface_params_blank_update {} {
# blank if user set param in "Blank" mode
    global geo_params_blanked   
    set w [mszSurfDEZ pathIgnoreErrors mszSurfDone]
    set now [lindex [lindex [$w configure -text] end] 0]
    if {$now == "Blank"} return
    set geo_params_blanked(surface) [ic_geo_params_blank_done surface 0]
}

proc aie_surface_params_blank {} {
    global geo_params_blanked 
    
    set w [mszSurfDEZ pathIgnoreErrors mszSurfDone]
    if [info exists geo_params_blanked(surface)] {
        if {$geo_params_blanked(surface) == ""} {
            set geo_params_blanked(surface) [ic_geo_params_blank_done surface 0]
        } else {
            set geo_params_blanked(surface) [ic_geo_params_blank_done surface 1]
        }
    } else {
        set geo_params_blanked(surface) [ic_geo_params_blank_done surface 0]
    }
    if {$geo_params_blanked(surface) == ""} {
        $w configure -text "Blank surfaces with params"
    } else {
        $w configure -text "Unblank surfaces with params"
    }
}
 
proc onMszBodyDEZOK {} {
    set sf [ic_geo_get_ref_size ]
    set tsize [expr $sf*$size ]
    set objs [ic_geo_get_objects density]
    foreach body $bodyList {
	set boxname "$body.BOX"
	set box_exist 0
	foreach obj $objs {
	    if [string match $boxname $obj] {
		set box_exist 1
		break;
	    }
	}

	if !$box_exist {
	    set bbox [ic_geo_bounding_box "body $body"]
	    foreach xx { {1 0 0 1} {2 1 0 1} {3 1 1 1} {4 0 1 1} \
		    {5 0 0 0} {6 1 0 0} {7 1 1 0} {8 0 1 0} } {
		lappend pts [list \
			[lindex [lindex $bbox [lindex $xx 1]] 0] \
			[lindex [lindex $bbox [lindex $xx 2]] 1] \
			[lindex [lindex $bbox [lindex $xx 3]] 2]]
	    }
	    ic_geo_create_density $boxname $tsize $pts
	    mess "Created density box for body: $body with size: $tsize \
		    created\n" blue
	    ic_geo_update_visibility density "" 0
	}

	ic_set_meshing_params density $boxname emax $tsize \
		ehgt $height emin $minsize edev $dev erat $erat
    }
    #set bodyList ""
}

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

proc onMeshPartOptionsDEZLoad {} {
    set PartList [aie_list_parts 1]
}

proc onMeshPartOptionsDEZOk {} {
}

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

proc aie_density_color {} {
    set cur [ic_geo_get_density_color 1]
    set new [SelectColor .select_color -color $cur]
    if {[string length $new] > 7} {
        set new \#[string range $new 1 2][string range $new 5 6][string range $new 9 10]
    }
    ic_geo_set_density_color $new
}

proc aie_density_clear_all {} {
    global geo_create
    if {![info exists geo_create(density,npts)]} return
    for {set n 0} {$n < $geo_create(density,npts)} {incr n} {
        set geo_create(density,pt$n) ""
        update_screen_label_point "" geo_create(density,pt$n)
    }
    if [info exists pt] { unset pt }
}

proc aie_density_update_point {n pos} {
    global geo_create
    set geo_create(density,pt$n) $pos
    if {$pos == ""} {
        update_screen_label_point "" geo_create(density,pt$n)
    } else {
        update_screen_label_point "Pt[expr $n + 1]" geo_create(density,pt$n)
    }
}

proc aie_density_restore {} {
    global geo_create
    if {![info exists geo_create(density,name)]} return
    set name $geo_create(density,name)
    if {$name == "" || !$geo_create(density,changed)} return
    if {[ic_geo_check_objects_exist density $name] != ""} {
        ic_delete_geometry density names $name
    }
    ic_geo_create_density $name $geo_create(density,emax) \
        $geo_create(density,save) $geo_create(density,ewid) \
        $geo_create(density,erat)
    ic_geo_set_modified $geo_create(density,modified)
    set geo_create(density,name) ""
}

proc oncreateDensityDEZLoad {} {
    if {$name == ""} {set name [ic_geo_new_name density "density."]}
    if {$emax == ""} {
        foreach {n v} [ic_get_meshing_params global 0] {
            if {$n == "gmax"} {
                set emax [format "%.2g" [expr $v / (8.0 * [ic_geo_get_ref_size])]]
                break
            }
        }
    }
    if {$erat == ""} {set erat 0}
    if {$ewid == ""} {set ewid 0}
    set ptlist ""
    set entityList ""
    aie_density_clear_all
    if [info exists pt] { unset pt }
}

proc oncreateDensityPointsLoad {} {
    set ptlist ""
    aie_density_clear_all
}

proc oncreateDensityPointPtsFinish {} {
    global geo_create
    aie_density_clear_all
    set geo_create(density,npts) [llength $ptlist]
    for {set n 0} {$n < $geo_create(density,npts)} {incr n} {
        aie_density_update_point $n [lindex $ptlist $n]
    }
}

proc oncreateDensityEntityLoad {} {
    set entityList ""
    aie_density_clear_all
}

proc oncreateDensityDEZOK {} {
    global aie_geoTypeVis
    if {![info exists createDensityTypeEGVal]} return
    if {$createDensityTypeEGVal} {
        set entities ""
        foreach {t n} $entityList {
            if {$t == "body"} {
                set objs [ic_geo_body_lower_entities $n]
                if {$objs != ""} {
                    eval lappend entities $objs
                }
            } else {
                lappend entities $t $n
            }
        }
        if {$entities == ""} {
            mess "Error: no geometry entities specified\n" red
            return
        }
        set ptlist ""
        set bbox [ic_geo_bounding_box $entities]
        foreach xx { {1 0 0 1} {2 1 0 1} {3 1 1 1} {4 0 1 1} \
                     {5 0 0 0} {6 1 0 0} {7 1 1 0} {8 0 1 0} } {
            lappend ptlist [list \
                            [lindex [lindex $bbox [lindex $xx 1]] 0] \
                            [lindex [lindex $bbox [lindex $xx 2]] 1] \
                            [lindex [lindex $bbox [lindex $xx 3]] 2]]
        }
    } else {
        set npts [llength $ptlist]
        if {$npts < 1} {
            mess "Error: need to select at least 1 point for a density\n" red
            return
        }
    }
    set size [expr $emax * [ic_geo_get_ref_size]]
    if {[ic_geo_check_objects_exist density [list $name]] != ""} {
        ic_delete_geometry density names [list $name]
    }
    if {[ic_geo_create_density $name $size $ptlist $ewid $erat] == ""} return
    set name [ic_geo_new_name density "density."]
    set ptlist ""
    set entityList ""
    aie_density_clear_all
    set aie_geoTypeVis(density) 2
    aie_updateGeoVis density
}

proc oncreateDensityDEZCancel {} {
    aie_density_clear_all
}

proc onmodifyDensityDEZLoad {} {
    global geo_create
    
    if ![info exists geo_create(density,changed)] {
        set geo_create(density,changed) 0
    }
    foreach i {densityList emax ewid erat} {
        set $i ""
    }
    aie_density_clear_all
    aie_density_restore
    ::AIEnv::GUIManagement::ToggleGrey modifyDensityLoc 1
    if [info exists pt] { unset pt }
}

proc onmodifyDensityDEZAfterLoad {} {
    global auto_pick_mode
    
    if $auto_pick_mode { modifyDensityPick pick }
    
    if [aie_wb2_is_running] {
        after 100 {
            ic_wb2_update_parameters input
            aie_wb2_wb_parameter_input_geom_density [modifyDensityDEZ get densityList]
        }
    }
}

proc onmodifyDensityPickFinish {} {
    global geo_create

    if [aie_wb2_is_running] {
        aie_wb2_wb_parameter_input_geom_density $densityList
    }
    foreach i {emax ewid erat ptlist} {
        set $i ""
    }
    aie_density_clear_all
    aie_density_restore
    set modifyDensityLocVal 0
    set cnt [llength $densityList]
    if {$cnt == 1} {
        set name $densityList
        ::AIEnv::GUIManagement::ToggleGrey modifyDensityLoc 0
        set geo_create(density,name) $name
        set geo_create(density,npts) [ic_geo_num_nodes density $name]
        set geo_create(density,save) {}
        for {set n 0} {$n < $geo_create(density,npts)} {incr n} {
            set pt [ic_geo_get_node density $name $n]
            lappend geo_create(density,save) $pt
            aie_density_update_point $n $pt
        }
    } else {
        ::AIEnv::GUIManagement::ToggleGrey modifyDensityLoc 1
        if {$cnt == 0} return
        set name [lindex $densityList 0]
        set geo_create(density,name) ""
    }
    set geo_create(density,modified) [ic_geo_is_modified]
    set geo_create(density,changed) 0
    foreach {i v} [ic_get_meshing_params density $name] {
        switch $i {
            emax {set emax $v}
            ewid {set ewid $v}
            erat {set erat $v}
        }
    }
    foreach i {emax ewid erat} {
        set geo_create(density,$i) [set $i]
    }
    if {$cnt > 1} {
        for {set n 1} {$n < $cnt} {incr n} {
            foreach {i v} [ic_get_meshing_params density [lindex $densityList $n]] {
                switch $i {
                    emax {
                        if {$emax != "" && [expr $emax - $v != 0]} {
                            set emax ""
                        }
                    }
                    ewid {
                        if {$ewid != "" && [expr $ewid - $v != 0]} {
                            set ewid ""
                        }
                    }
                    erat {
                        if {$erat != "" && [expr $erat - $v != 0]} {
                            set erat ""
                        }
                    }
                }
            }
        }
    }
    if {$emax != ""} {
        set emax [format "%g" [expr $emax / [ic_geo_get_ref_size]]]
    }
}

proc onmodifyDensityScreenLoad {} {
    global geo_create select_action
    set name $geo_create(density,name)
    if {$name == ""} return
    while 1 {
        ic_geo_highlight_segments density $name remove nodes all
        set pts [geo_select_segments density $name node 1]
        set n [lindex $pts 0]
        if {$n == ""} return
        # switch automatically to screen selection
        after 250 { set select_action screen }
        select_move_geo_nodes density $name $n none [lindex $pts 1]
        if {$n == ""} return
        aie_density_update_point $n [ic_geo_get_node density $name $n]
        incr geo_create(density,changed)
    }
}

proc onmodifyDensityScreenUnLoad {} {
    select_geometry_force_done cancel
}

proc onmodifyDensityMoveLoad {} {
    global geo_create
    set name $geo_create(density,name)
    if {$name == ""} return
    while 1 {
        ic_geo_highlight_segments density $name remove nodes all
        select_geometry_bindings node 0
        set pts [geo_select_segments density $name node 1 0 0 0 1]
        select_geometry_bindings ""
        set n [lindex $pts 0]
        if {$n == ""} return
        banner "Select new location with left button, middle-done, right=cancel"
        set pt [lindex [va_create_xyz auto 1 0] 0]
        banner ""
        if {$pt != ""} {
            ic_geo_set_node density $name $n $pt
            aie_density_update_point $n $pt
            incr geo_create(density,changed)
        }
    }
}

proc onmodifyDensityMoveUnLoad {} {
    select_geometry_force_done cancel
}

proc onmodifyDensityAddLoad {} {
    global geo_create
    set name $geo_create(density,name)
    if {$name == ""} return
    while 1 {
        banner "Select locations to add with left button, middle-done, right=cancel"
        set pts [va_create_xyz auto ANY 0]
        banner ""
        if {[llength $pts] == 0 || [lindex $pts 0] == ""} return
        set ptlist {}
        for {set n 0} {$n < $geo_create(density,npts)} {incr n} {
            lappend ptlist $geo_create(density,pt$n)
        }
        foreach pt $pts {
            lappend ptlist $pt
            aie_density_update_point $n $pt
            incr n
        }
        set geo_create(density,npts) $n
        ic_delete_geometry density names $name
	    ic_geo_create_density $name $geo_create(density,emax) $ptlist
        geo_show_edit density $name 1
        incr geo_create(density,changed)
    }
}

proc onmodifyDensityAddUnLoad {} {
    select_geometry_force_done cancel
}

proc onmodifyDensityDeleteLoad {} {
    global geo_create
    set name $geo_create(density,name)
    if {$name == ""} return
    while 1 {
        set max_pts [expr [ic_geo_num_nodes density $name] - 1]
        if {$max_pts < 1} return
        ic_geo_highlight_segments density $name remove nodes all
        select_geometry_bindings node 0
        set pts [geo_select_segments density $name node $max_pts 0 0 0 1]
        select_geometry_bindings ""
        if {[llength $pts] == "" || [lindex $pts 0] == ""} return
        set cnt 0
        set ptlist ""
        for {set n 0} {$n < $geo_create(density,npts)} {incr n} {
            if {[lsearch $pts $n] < 0} {
                set pt $geo_create(density,pt$n)
                lappend ptlist $pt
                aie_density_update_point $cnt $pt
                incr cnt
            }
        }
        for {set n $cnt} {$n < $geo_create(density,npts)} {incr n} {
            aie_density_update_point $n ""
        }
        set geo_create(density,npts) $cnt
        ic_delete_geometry density names $name
        if {$ptlist == ""} return
	    ic_geo_create_density $name $geo_create(density,emax) $ptlist
        geo_show_edit density $name 1
        incr geo_create(density,changed)
    }
}

proc onmodifyDensityDeleteUnLoad {} {
    select_geometry_force_done cancel
}

proc onmodifyDensityDEZApply {} {
    global geo_create
    set args ""
    if {$emax != ""} { lappend args emax $emax }
    if {$erat != ""} { lappend args erat $erat }
    if {$ewid != ""} { lappend args ewid $ewid }
    if {$args == ""} return
    
    if [aie_wb2_is_running] {
        aie_set_global wb_input_parameter_mode 1
    }
    
    set args [aie_convert_relative $args 0]
    foreach d $densityList {
        if {[ic_geo_check_objects_exist density [list $d]] == ""} {
            mess "Error: density $d does not exist\n" red
        } else {
            eval ic_set_meshing_params density $d $args
        }
    }
    
    if [aie_wb2_is_running] {
        aie_unset_global wb_input_parameter_mode
    }
    set geo_create(density,changed) 0
}

proc onmodifyDensityDEZCancel {} {
    aie_density_restore
}

proc onmodifyDensityDEZUnLoad {} {
    select_geometry_force_done cancel
    aie_density_clear_all
}

proc ondeleteDensityDEZLoad {} {
    set densityList ""
    if [info exists pt] { unset pt }
}

proc ondeleteDensityDEZAfterLoad {} {
    global auto_pick_mode
    if $auto_pick_mode {deleteDensityPick pick}
}

proc ondeleteDensityPickFinish {} {
    global auto_pick_mode
    if {$auto_pick_mode && $densityList != ""} {deleteDensityDEZ apply}
}

proc ondeleteDensityDEZOK {} {
    global auto_pick_mode
    ic_delete_geometry density names $densityList
    mess "Deleted density \"$densityList\"\n"
    set densityList ""
    if $auto_pick_mode {deleteDensityPick pick}
}

proc aie_update_mesh_params {type names} {
    global aie_meshParams env bunching_laws trace_emax_nmax_done

    if [info exists env(AI_ENV_LSTC)] {
        set pnames {emax ehgt}
    } else {
        set pnames {emax ehgt emin edev hrat ewid nlay}
    }

    if {$type == "curve"} {
        lappend pnames prism_height_limit
        lappend pnames law
    }

    if {$type == "surface"} {
        lappend pnames erat
        lappend pnames etyp
        lappend pnames emethod
        lappend pnames prism_height_limit
        lappend pnames law
    }

    foreach p $pnames {	set aie_meshParams($type,$p) "undef" }
    set fact [ic_geo_get_ref_size]
    foreach name $names {
	    set params [ic_get_meshing_params $type $name]
	    foreach {n v} [aie_convert_relative $params 1 $type] {
	        if [info exists aie_meshParams($type,$n)] {
		        if {($aie_meshParams($type,$n) == "undef") || ($aie_meshParams($type,$n) == $v)} {
		            set aie_meshParams($type,$n) $v
		        } else {
		            set aie_meshParams($type,$n) ""
		        }
	        }
	    }
    }

    foreach p $pnames {
	    if {$aie_meshParams($type,$p) == "undef"} {
	        set aie_meshParams($type,$p) ""
	    }
    }

    foreach p $pnames {
	    switch $type {
	        curve {
                if {$p == "law"} {
		            switch -- "$aie_meshParams(curve,$p)" {
		                0 { set prism_law exponential }
		                1 { set prism_law linear }
		                3 { set prism_law wb-exponential }
		                default { set prism_law undefined }
		            }
		            mszCurveDEZ set prism_law $prism_law
		        } else {
                    mszCurveDEZ set $p $aie_meshParams(curve,$p)
                }
	        }
	        surface {
		        if {$p == "etyp"} {
                    mszSurfDEZ set etyp2 [aie_surface_get_mesh_type_name $aie_meshParams(surface,$p)]
		        } elseif {$p == "emethod"} {
		            mszSurfDEZ set emethod2 [aie_surface_get_mesh_method_name $aie_meshParams(surface,$p)]
		        } elseif {$p == "law"} {
		            switch -- "$aie_meshParams(surface,$p)" {
		                0 { set prism_law exponential }
		                1 { set prism_law linear }
		                3 { set prism_law wb-exponential }
		                default { set prism_law undefined }
		            }
		            mszSurfDEZ set prism_law $prism_law
		        } else {
		            mszSurfDEZ set $p $aie_meshParams(surface,$p)
		        }
	        }
	    }
    }

    switch $type {
	    curve {
	        if {([llength $names] == 1) && ($aie_meshParams(curve,emax) != 0)} {
		        set l [expr double([ic_geo_crv_length [lindex $names 0]])]
		        set aie_meshParams(curve,nmax) [expr round($l / ($aie_meshParams(curve,emax)*$fact)) + 1]
		        mszCurveDEZ set nmax $aie_meshParams(curve,nmax)
	        } else {
		        if {[info exists trace_emax_nmax_done] && $trace_emax_nmax_done == "nmax"} {
		            set aie_meshParams(curve,nmax) [mszCurveDEZ get nmax]
		            mszCurveDEZ set emax ""
		        } else {
		            mszCurveDEZ set nmax ""
		            set aie_meshParams(curve,nmax) ""
		        }
	        }
	        foreach p {law h1 h2 r1 r2 lmax} {
		        mszCurveDEZ set $p ""
	        }
	        foreach name $names {
		        if {[info exists bunch_params_diff]} {
		            foreach p {law h1 h2 r1 r2 lmax} {
		                mszCurveDEZ set $p ""
		            }
		            unset bunch_params_diff
		            break
		        }
		        set bunch_params [ic_geo_get_curve_bunching $name]
		        if {[info exists bunch_params_last]} {
		            set bunch_params_cur [list [lrange $bunch_params 0 1] [lrange $bunch_params 4 end]]
		            if {$bunch_params_cur != $bunch_params_last} {
		                foreach p {law h1 h2 r1 r2 lmax} {
		                    mszCurveDEZ set $p ""
		                }
		                break
		            }
		        }
		        if {$bunch_params != ""} {
		            foreach {n v} $bunch_params {
			            set ${n}_cur $v
		            }
		            foreach p {h1 h2 r1 r2 lmax} {
			            mszCurveDEZ set $p [set ${p}_cur]
		            }
		            foreach "p1 p2" {nlay1 h1 nlay2 h2} {
		                if {[info exists ${p1}_cur] && [set ${p1}_cur] != 1} {
		                    mszCurveDEZ set $p2 "[set ${p2}_cur] * [set ${p1}_cur]"
		                }
		            }
		            foreach name [array names bunching_laws] {
			            if {$law_cur == $bunching_laws($name)} {
			                mszCurveDEZ set law $name
			                break
			            }
		            }
		        } else {
		            foreach p {law h1 h2 r1 r2 lmax} {
		                mszCurveDEZ set $p ""
		            }
		            break
		        }
		        set bunch_params_last [list [lrange $bunch_params 0 1] [lrange $bunch_params 4 end]]
	        }
	    }
	    surface {
            if {[llength $names] == 1 && [info exists params]} {
                foreach {n v} $params {
                    if {$n == "etyp"} {
                        set etype $v
                        mszSurfDEZ set etyp2 [aie_surface_get_mesh_type_name $etype]
                    }
                    if {$n == "emethod"} {
                        set emethode $v
                        mszSurfDEZ set emethod2 [aie_surface_get_mesh_method_name $emethode]
                    }
                    if {$n == "law"} {
		                switch -- "$v" {
		                    0 { set prism_law exponential }
		                    1 { set prism_law linear }
		                    3 { set prism_law wb-exponential }
		                    default { set prism_law undefined }
		                }
		                mszSurfDEZ set prism_law $prism_law
                    }
                }
            } elseif {[llength $names] > 1} {
                catch { unset last_type; unset last_method; unset last_law }
                catch { unset diff_type; unset diff_method; unset diff_law }
                foreach name $names {
	                foreach {n v} [ic_get_meshing_params surface $name] {
	                    if {$n == "etyp"} {
	                        if ![info exists last_type] {
	                            set last_type $v
	                        } else {
	                            if {$last_type != $v} {
	                                set diff_type 1
	                            }
	                        }
	                    }
	                    if {$n == "emethod"} {
	                        if ![info exists last_method] {
	                            set last_method $v
	                        } else {
	                            if {$last_method != $v} {
	                                set diff_method 1
	                            }
	                        }
	                    }
	                    if {$n == "law"} {
	                        if ![info exists last_law] {
	                            set last_law $v
	                        } else {
	                            if {$last_law != $v} {
	                                set diff_law 1
	                            }
	                        }
	                    }
	                }
                }
                if [info exists diff_type] {
                    mszSurfDEZ set etyp2 ""
                } elseif [info exists last_type] {
                    mszSurfDEZ set etyp2 [aie_surface_get_mesh_type_name $last_type]
                } else {
                    mszSurfDEZ set etyp2 NONE
                }
                if [info exists diff_method] {
                    mszSurfDEZ set emethod2 ""
                } elseif [info exists last_method] {
                    mszSurfDEZ set emethod2 [aie_surface_get_mesh_method_name $last_method]
                } else {
                    mszSurfDEZ set emethod2 NONE
                }
                if [info exists diff_law] {
                    mszSurfDEZ set prism_law ""
                } elseif [info exists last_law] {
		            switch -- "$last_law" {
		                0 { set prism_law exponential }
		                1 { set prism_law linear }
		                3 { set prism_law wb-exponential }
		                default { set prism_law undefined }
		           }
                   mszSurfDEZ set prism_law $prism_law
                } else {
                    mszSurfDEZ set prism_law undefined
                }
            }
        }
    }
}

proc aie_convert_relative {params to_gui {type ""}} {

    set fact [ic_geo_get_ref_size]
    set ret ""
    foreach {n v} $params {
	switch $n {
	    emax - emin - ehgt - edev {
		if {![string is integer $v] && ![string is double $v]} {
		    switch $n {
		        emax { set error "Maximum element size" }
		        emin { set error "Minimum size" }
		        ehgt { set error "Height" }
		        edev { set error "Maximum deviation" }
		    }
		    mess "Error in \"$error\" Definition\n" red
		    return ""
		}
		if {$n != "ehgt" && $v != ""} {
		    set v [format %g $v]
		    if $to_gui {
			set v [format %g [expr $v / ($fact + 0.0)]]
		    } else {
			set v [format %g [expr $v * $fact]]
		    }
		}
	    }
	}
	lappend ret $n $v
    }
    return $ret
}

proc aie_show_params {par {val ""}} {
    global str_option

    switch $par {
	ref {
	    if {$val == ""} {
		set val [mszGlobalDEZ get dspScaleFlag]
	    }
	}
	max {
	    if {$val == ""} {
		set val [mszGlobalDEZ get dspSeedFlag]
	    }
	}
	nat {
	    if {$val == ""} {
		set val [expr [mszGlobalDEZ get dspNatFlag] && [mszGlobalDEZ get natSzGGVal]]
	    }
	}
	default {
	    global aie_${par}Params
	    switch $val {
		tetra - hexa - quad - prism {
		    # if you set one, unset the others
		    foreach poss {tetra hexa quad prism} {
			if {$poss != $val} {
			    set aie_${par}Params($poss) 0
			}
		    }
		}
		default {
		    set val none
		    foreach poss {tetra hexa quad prism} {
			if {[info exists aie_${par}Params($poss)] && [set aie_${par}Params($poss)]} {
			    set val $poss
			    break
			}
		    }
		}
	    }
	    if {![info exists aie_${par}Params($val)] || ![set aie_${par}Params($val)]} {
		set val none
	    }
	    set str_option($par,sizes) $val
	}
    }
    ic_geo_params_update_show_size $par $val
    if {$par == "surface"} {
       foreach n {solid flat_wire grey_scale transparent} {
          set ::aie_SurfStyle($n) 0
       }
       set ::aie_SurfStyle(wire) 1
    }
}

# this is copied from med_gui/geometry_med.tcl proc geo_params_edit_allfamilies
# edited to work off parts.
# edited to fix the header line
# edited to make it faster
proc geo_params_edit_allparts {{with_prism 0}} {
    global mparams geo_command_mode options mainwindow_menubar
    global geo_params_blank_done geometry_mode
    global prism_family_on prism_values prism_families prism_parts
    global prism_family_height prism_family_ratio prism_family_n_layers
    global hexcore_family_backup prism_family_backup

    if [winfo exists .mparams_allfamily] { destroy .mparams_allfamily }
    set options(apply_all) 0
    set options(remove_all) 0
    geo_params_update_sizes allparts
    aie_hexacore_update_params
    if $with_prism {
        aie_prism_update_params
    }
    set sortedfams [lsort -dictionary [ic_geo_list_parts]]
    set solid_part_fams ""
    set non_solid_part_fams ""
    # surface parts
    set sfams [ic_uns_list_families 2]
    # volume parts
    set vfams [ic_list_volume_families]
    set svfams [concat $sfams $vfams]
    array set solid {}
    set hexa_core_exists 0
    foreach ff $sortedfams {
	if {$ff == "ORFN"} continue
	# ff is a part name, may be no such family (#57712)
	# check count_geom in families!
	  set ff_fams [ic_geo_list_families_in_part $ff]
	  set count_geom 0
	  foreach ff_f $ff_fams {
	      incr count_geom [ic_geo_count_in_family {surface curve point} $ff_f]
	  }
	# 
        set count_body [ic_geo_count_in_family body $ff]
        if {$count_body && $count_geom} {
            mess "Part $ff contains geometry and body in same part.  This is not recommended and could\
                  cause problems! Part $ff will be ignored.\n" red
            continue
        }
	set solid_part 0; set solid($ff) 0
	if !$count_geom {
	    if {$count_body || [lsearch $svfams $ff] > -1} {
		set solid_part 1
		set solid($ff) 1
	    } else {
		continue
	    }
	}
	if $solid_part {
	    lappend solid_part_fams $ff
	} else {
	    lappend non_solid_part_fams $ff
	}
        if {[lsearch $vfams $ff] > -1} {
            set hexa_core_exists 1
        }
    }
    set resortedfams ""
    foreach ff $non_solid_part_fams {
       lappend resortedfams $ff
    }
    foreach ff $solid_part_fams {
       lappend resortedfams $ff
    }
    set sortedfams $resortedfams
    if {$sortedfams == ""} {
       mess "No valid parts available!\n" red
       return
    }
    set w .mparams_allfamily
    set buts [list [list Apply "geo_params_edit_allparts_apply $with_prism; aie_update_mparams_highlight"] \
		   [list Dismiss "geo_params_edit_done family $w; geo_params_show_params_done"]]
    set ww [form_init $w "Mesh sizes for parts" "" $buts ]
    set nsurfs [ic_geo_num_objects surface]
    set ncurves [ic_geo_num_objects curve]
    set ngeo_ents [expr $nsurfs + $ncurves]
    set pa [tdv_active 0]
    if {$ww != ""} {
	form_frame $ww.labels flat 0 "0 0"
	set labels $ww.labels
	set d $ww.labels
	set bg [$w cget -background]
	set ln 0
	set ln_prism 1
	form_label $d.fnl "Part" "0 0"
	if $with_prism {
	    form_button $d.prism  "Prism" aie_prism_select_all-none "0 $ln_prism"
	    incr ln_prism
	}
        if $hexa_core_exists {
            form_button $d.hc "Hexa\n Core" aie_hexa_core_select_all-none "0 $ln_prism"
            $d.hc configure -width 5
            incr ln_prism
        }
	form_label $d.fsl "Max\nSize" "0 $ln_prism"
	incr ln_prism
	if {$ngeo_ents > 0} {
	    form_label $d.fhl "Height" "0 $ln_prism"
	    incr ln_prism
	    form_label $d.frl "Height\nRatio" "0 $ln_prism"
	    incr ln_prism
	    form_label $d.fwl "Num\nLayers" "0 $ln_prism"
	    incr ln_prism
	    form_label $d.ftl "Tetra\nSize Ratio" "0 $ln_prism"
            $d.ftl configure -anchor nw
	    incr ln_prism
	    form_label $d.ftw "Tetra\nWidth" "0 $ln_prism"
	    incr ln_prism
	    form_label $d.fm1 "Min Size\nLimit" "0 $ln_prism"
	    incr ln_prism
	    form_label $d.fdl "Max\nDeviation" "0 $ln_prism"
	    incr ln_prism
	    form_label $d.fil "Int\nWall" "0 $ln_prism"
	    incr ln_prism
	    form_label $d.fsplitl "Split\nWall" "0 $ln_prism"
	    incr ln_prism
	}

	incr ln
        set d [form_scroller $ww.fr 400 {1 0}]
	set scr $d
	set f0 $ln
	set sel ""

	set bg [$w cget -background]
	set ln 0
	set ln_prism 1
	foreach ff $sortedfams {
	    if {$ff == "ORFN"} continue
	    set solid_part $solid($ff)
	    lappend sel $ff
	    form_label $scr.fam_$ln $ff "$ln 0"
	    set hlbg $bg
	    set ln_prism 1
	    if !$solid_part {
		if {$mparams(${ff}_emax) == "" || $mparams(${ff}_ehgt) == "" || \
		    $mparams(${ff}_erat) == "" || $mparams(${ff}_emin) == "" || \
		    $mparams(${ff}_edev) == "" || $mparams(${ff}_ewid) == "" || \
		    $mparams(${ff}_hrat) == "" || $mparams(${ff}_nlay) == ""} {
		    set hlbg yellow
		}
	    }
	    $scr.fam_$ln configure -background $hlbg
	    if $with_prism {
		form_checkbutton $scr.prism_$ln "" prism_family_on($ff) "$ln 1 -fill both"
		set prism_family_backup($ff) $prism_family_on($ff)
		$scr.prism_$ln configure -background $bg -width 5
		incr ln_prism
		if [info exists prism_family_height($ff)] {
		    set mparams(${ff}_ehgt) $prism_family_height($ff)
		}
		if [info exists prism_family_ratio($ff)] {
		    set mparams(${ff}_hrat) $prism_family_ratio($ff)
		}
		if [info exists prism_family_n_layers($ff)] {
		    set mparams(${ff}_nlay) $prism_family_n_layers($ff)
		}
	    }
	    #{emax ehgt erat ewid emin edev internal_wall split_wall mom3d_no_adapt}
            if $hexa_core_exists {
	        if {[lsearch $vfams $ff] > -1} {
		    form_checkbutton $scr.hc_$ln "" mparams(${ff}_hexcore) "$ln $ln_prism -fill both"
		    set hexcore_family_backup($ff) $mparams(${ff}_hexcore)
		    $scr.hc_$ln configure -background $bg -width 5
	        } else {
		    form_label $scr.hc_$ln "" "$ln $ln_prism -fill both"
		    $scr.hc_$ln configure -background $bg -width 8
	        }
	        incr ln_prism
            }
	    form_entry $scr.fsl_$ln mparams(${ff}_emax) string "$ln $ln_prism"
	    $scr.fsl_$ln configure -width 10
	    incr ln_prism
	    if $solid_part {
		incr ln; continue
	    }
	    form_entry $scr.fnl_$ln mparams(${ff}_ehgt) string "$ln $ln_prism"
	    $scr.fnl_$ln configure -width 10
	    incr ln_prism
	    form_entry $scr.frl_$ln mparams(${ff}_hrat) string "$ln $ln_prism"
	    $scr.frl_$ln configure -width 10
	    incr ln_prism
	    form_entry $scr.fwl_$ln mparams(${ff}_nlay) string "$ln $ln_prism"
	    $scr.fwl_$ln configure -width 10
	    incr ln_prism
	    form_entry $scr.ftl_$ln mparams(${ff}_erat) string "$ln $ln_prism"
	    $scr.ftl_$ln configure -width 10
	    incr ln_prism
	    form_entry $scr.ftw_$ln mparams(${ff}_ewid) string "$ln $ln_prism"
	    $scr.ftw_$ln configure -width 10
	    incr ln_prism
	    form_entry $scr.fm1_$ln mparams(${ff}_emin) string "$ln $ln_prism"
	    $scr.fm1_$ln configure -width 10
	    incr ln_prism
	    form_entry $scr.fdl_$ln mparams(${ff}_edev) string "$ln $ln_prism"
	    $scr.fdl_$ln configure -width 10
	    incr ln_prism
	    form_checkbutton $scr.fil_$ln "" mparams(${ff}_internal_wall) "$ln $ln_prism -fill both"
	    $scr.fil_$ln configure -background $bg -width 3
	    incr ln_prism
	    form_checkbutton $scr.fsplitl_$ln "" mparams(${ff}_split_wall) "$ln $ln_prism -fill both"
	    $scr.fsplitl_$ln configure -background $bg -width 3
	    incr ln_prism
	    incr ln
	}

	set mparams(sel) $sel
	set geo_params_blank_done 0
	form_checkbutton $ww.showfactor "Show size params using reference size" options(show_factor) {31 0}
	$ww.showfactor configure -command "geo_params_update_sizes allparts; aie_hexacore_update_params; \
	                                   geo_params_show_params"
	form_checkbutton $ww.applyall "Apply inflation parameters to curves" options(apply_all) {40 0}
	form_checkbutton $ww.removeall "Remove inflation parameters from curves" options(remove_all) {50 0}
	$ww.applyall configure -command "geo_params_update_highlighting $scr \"$sortedfams\"; \
	                                 aie_params_curve_inflation_parameters apply_all"
	$ww.removeall configure -command "geo_params_update_highlighting $scr \"$sortedfams\"; \
	                                  aie_params_curve_inflation_parameters remove_all"
        form_label $ww.warn  \
		"Please note that highlighted parts have at least\
		one blank field because not all entities in that part\
		have identical entitiy parameters." {60 0}
	$ww.warn configure -background yellow
        set idx 0
        set minsize(0) 0
        foreach c [winfo children $scr] {
            set minsize($idx) [winfo reqwidth $c]
            if [string match "*fam_*" $c] {
                if {$minsize($idx) > $minsize(0)} {
                    set minsize(0) $minsize($idx)
                }
            }
            incr idx
        }
        set idx 0
        foreach c [winfo children $labels] {
            grid columnconfigure $labels $idx -minsize [expr $minsize($idx) + 6]
            incr idx
        }
	grid $ww.fr -row 1 -column 0 -sticky nw
        set mparams(win) $scr
        set mparams(sortedfams) $sortedfams
        tdv_active $pa
        geo_params_update_highlighting $mparams(win) $mparams(sortedfams)
        geo_params_show_params
	form_finish +10+300
    }
}

proc aie_prism_select_all-none {} {
    global prism_family_on

    if ![info exists prism_family_on] {
	return
    }

    # if any ON turn OFF everything
    set on 1    
    foreach fam [array names prism_family_on] {
	if $prism_family_on($fam) {
	    set on 0
	    break
	}
    }
    
    foreach fam [array names prism_family_on] {
	set prism_family_on($fam) $on
    }
}

proc aie_hexa_core_select_all-none {} {
    global mparams

    if {[llength [array names mparams *_hexcore]] < 1} {
	return
    }

    set on 1    
    foreach fam [array names mparams *_hexcore] {
	if $mparams($fam) {
	    set on 0
	    break
	}
    }
    
    foreach fam [array names mparams *_hexcore] {
	set mparams($fam) $on
    }
}

proc aie_params_curve_inflation_parameters {what} {
    global options

    switch $what {
        apply_all {
            if $options(apply_all) { set options(remove_all) 0 }
        }
        remove_all {
            if $options(remove_all) { set options(apply_all) 0 }
        }
    }
}

proc aie_update_mparams_highlight {} {
    global mparams

    set w $mparams(win)
    set m $mparams(sortedfams)
    if [winfo exists $w] {
	geo_params_update_highlighting $w $m
    }
}

proc geo_params_show_params {} {
    global options aie_surfaceParams aie_surface_tetra_size

    if ![info exists aie_surface_tetra_size] {
        set aie_surface_tetra_size $aie_surfaceParams(tetra)
    }
    if $options(show_factor) {
        set aie_surfaceParams(tetra) 1
    } else {
        set aie_surfaceParams(tetra) 0
    }
    aie_show_params surface tetra
}

proc geo_params_show_params_done {} {
    global aie_surfaceParams aie_surface_tetra_size
    global prism_family_on prism_family_backup
    global mparams hexcore_family_backup options

    set options(apply_all) 0
    set options(remove_all) 0
    if [info exists aie_surface_tetra_size] {
        set aie_surfaceParams(tetra) $aie_surface_tetra_size
        aie_show_params surface tetra
        unset aie_surface_tetra_size
    }
    if [info exists prism_family_backup] {
        foreach ff [array names prism_family_backup] {
            if [info exists prism_family_on($ff)] {
                set prism_family_on($ff) $prism_family_backup($ff)
            }
        }
        unset prism_family_backup
    }
    if [info exists hexcore_family_backup] {
        foreach ff [array names hexcore_family_backup] {
            if [info exists mparams(${ff}_hexcore)] {
                set mparams(${ff}_hexcore) $hexcore_family_backup($ff)
            }
        }
        unset hexcore_family_backup
    }
}

proc geo_params_edit_allparts_apply {{with_prism 0}} {
    global mparams prism_family_backup hexcore_family_backup
    global prism_family_on prism_values prism_families prism_parts
    global prism_family_height prism_family_ratio prism_family_n_layers

    set prism_families ""
    foreach ff [ic_geo_list_parts "" 1] {
        if {$ff == "ORFN"} continue
        set ff_fams [ic_geo_list_families_in_part $ff]
	      set count_geom 0
	      foreach ff_f $ff_fams {
	        incr count_geom [ic_geo_count_in_family {surface curve point} $ff_f]
	      }
        set count_body [ic_geo_count_in_family body $ff]
        if {$count_body && $count_geom} continue
	if $with_prism {
	    if {[info exists prism_family_on($ff)] && ($prism_family_on($ff) == 1)} {
		set prism_family_backup($ff) $prism_family_on($ff)
		lappend prism_families $ff
		if [info exists mparams(${ff}_ehgt) ] { set prism_family_height($ff) $mparams(${ff}_ehgt) }
		if [info exists mparams(${ff}_hrat) ] { set prism_family_ratio($ff) $mparams(${ff}_hrat) }
		if [info exists mparams(${ff}_nlay) ] { set prism_family_n_layers($ff) $mparams(${ff}_nlay) }
	    } elseif {[info exists prism_family_on($ff)]} {
	        set prism_family_backup($ff) $prism_family_on($ff)
	    }
	}
        if !$count_geom continue
	set mparams(selfam) $ff
	if [info exists mparams(${ff}_hexcore)] {
	    set hexcore_family_backup($ff) $mparams(${ff}_hexcore)
	}
   	set pnames {emax ehgt erat hrat ewid nlay emin edev internal_wall split_wall}
	foreach p $pnames {
	    set mparams($p) $mparams(${ff}_$p)
	}
	geo_params_edit_apply part
    }
    aie_hexacore_parts_apply
    if $with_prism {
        ic_geo_set_prism_families $prism_families
    }
}

# Hexa-core meshing with tetra

proc aie_hexacore_parts_define {} {
    global mparams

    if [winfo exists .mparams_hexacore] { destroy .mparams_hexacore }
    aie_hexacore_update_params
    set w .mparams_hexacore

    set buts [list [list Apply "aie_hexacore_parts_apply"] dismiss]
    set ww [form_init $w "Hexa-core Mesh sizes for parts" "" $buts ]
    if {$ww != ""} {
	set d [form_scroller $ww.fr 400 {0 0}]
	set bg [$w cget -background]
	set ln 0

	form_label $d.fnl "Part" "$ln 0"
	form_label $d.fsl "Min. Hexa Size" "$ln 1"
	form_label $d.hexc "Hexa-core" "$ln 2"

	incr ln

	set scr $d
	set f0 $ln
	set sel [lsort -dictionary [ic_list_volume_families]]
	foreach ff $sel {
	    if {$ff == "ORFN" || $ff == "VORFN"} continue
	    form_label $scr.fam_$ln $ff "$ln 0"
	    form_entry $scr.hcs_$ln mparams($ff\_hexsize) string "$ln 1"
	    form_checkbutton $scr.hc_$ln "" mparams($ff\_hexcore) "$ln 2 -fill both"
	    $scr.hc_$ln configure -background $bg
	}
	set mparams(sel) $sel
	form_finish +300+300
    }
}

proc aie_hexacore_update_params {} {
    global mparams options

    if $options(show_factor) {
	set fact [ic_geo_get_ref_size]
    } else {
	set fact 1.0
    }
    foreach fam [ic_list_volume_families] {
	if {$fam == "ORFN" || $fam == "VORFN"} continue
	if ![info exists mparams($fam\_hexcore)] { continue }
	foreach n {emax hexcore} {
	    set v [ic_geo_get_family_param $fam $n]
	    if {$v != ""} {
		if {$n == "emax"} {
		    set mparams($fam\_$n) [expr $v / $fact]
		} else {
		    set mparams($fam\_$n) $v
		}
	    }
	}
    }
}

proc aie_hexacore_parts_apply {} {
    global mparams options

    if $options(show_factor) {
	set fact [ic_geo_get_ref_size]
    } else {
	set fact 1.0
    }
    foreach ff [ic_list_volume_families] {
	if {$ff == "ORFN" || $ff == "VORFN"} continue
	if ![info exists mparams($ff\_hexcore)] { continue }
	if {$mparams($ff\_emax) == ""} {
	    set mparams($ff\_emax) 0
	}
	set emax [expr $mparams($ff\_emax) * $fact]
	ic_geo_set_family_params $ff \
	    emax $emax \
	    hexcore $mparams($ff\_hexcore)
    }
}


proc aie_geo_params_edit_allparts {} {

    if {![ic_geo_is_loaded] && ![ic_uns_is_loaded] && \
        ![ic_str_is_loaded] && ![ic_hex_blocking_loaded]} {
        mess "No Geometry or Mesh is loaded!\n" red
        return
    }
    geo_params_edit_allparts 1

}

proc aie_load_prism_params {{from_prj 0}} {
    global env load_only_prism_params prism_parts
    global prism_family_on prism_values prism_families batch_mode
    global prism_family_height prism_family_ratio prism_family_n_layers

    # Prism can be available for FEA too.
    #if ![info exists env(AI_ENV_CFD)] return
    # backwards compatibility for prism. Need to get prism families
    # and params, and write then to to tetin file
    if {$from_prj} {
        set prism_parts ""
        set prism_families ""
        if {[ic_geo_is_loaded] && [array exists prism_family_on]} {
            foreach ff [ic_geo_list_parts] {
                if {[info exists prism_family_on($ff)] && $prism_family_on($ff) == 1} {
                    lappend prism_families $ff
                }
            }
            if {$prism_families != ""} {
                ic_geo_set_prism_families $prism_families
            } else {
                # no prism settings
                return
            }
            set params ""
            foreach i {law height ratio layers total_height} {
                if {[info exists prism_values($i)]} {
                    lappend params $i $prism_values($i)
                }
            }
            if {$params != ""} {
                eval ic_set_meshing_params prism 0 $params
            }
        }
        catch {array unset prism_family_on}
        catch {array unset prism_family_height}
        catch {array unset prism_family_ratio}
        catch {array unset prism_family_n_layers}
    }
    if {$prism_parts == "" && !$batch_mode} {
        set load_only_prism_params 1
        if ![meshPrismDEZ isbuilt] {
            meshPrismDEZ build
        }
        meshPrismDEZ onmeshPrismDEZAfterLoad
        set load_only_prism_params 0
    }
}

proc aie_mesh_prism_params {} {
    global prism_values prism_extras prism_extra_types
    set params_file [tk_getOpenFile -initialdir $file_name(project_dir) \
        -filetypes {{{Prism Parameter Files} {*.prism_params}} \
        {{All files} *}} -initialfile $file_name(prism_params)]

    if {$params_file != "" && [file exists $params_file]} {
	    aie_read_prism_params $params_file 1
        foreach i [array names prism_extras] {
            set prism_extras($i) $prism_values($i)
        }
        set var [mszGlobalDEZ get PrismExtraName]
        if {$var != "" && [info exists prism_extras($var)]} {
            if {[lsearch $prism_extra_types $var] < 0} {
                mszGlobalDEZ set PrismExtraValue $prism_extras($var)
            } else {
                mszGlobalDEZ set PrismExtraEnabled $prism_extras($var)
            }
        }
    }
}

######################## Advanced Meshing Controls #####################

proc onadvMeshParamsDEZLoad {} {
    global env load_only_prism_params prism_parts prism_values
    global beta_mode

    if ![ic_geo_is_loaded] {
        msg ERROR "No geometry available"
        return
    }

    if [info exists env(AI_ENV_CFD)] {
        set meshElemTypeList {
	    "All Tri"
	    "Quad w/one Tri"
	    "Quad Dominant"
	    "All Quad"
        }
        set meshElemMethodList {
	    "Autoblock"
	    "Patch Dependent"
	    "Patch Independent"
	    "Shrinkwrap"
	    "Delaunay"
        }
        set OffsetList {
            "Standard"
            "Simple"
            "Forced simple"
        }

        # patch dependent
        set proj_surf 1
        set impr_level 1
        set bound_smooth 0
        set surf_sizes 0
        set ign_size [aie_default_topo_tolerance]
        set protect_line 0
        set simple_offset2 "Standard"
        set max_area 0.0
        set max_length 0.0
        set min_angle 0.0
        set max_nodes 0
        set max_elements 0
        set bunch_respect 0
        set max_dev 0.0
        set block_mapping 0.2
        set adjust_nodes_max 0
        set try_harder 1
        set mesh_dormant 0
        set smooth_dormant 0
        #set mesh_type2 "Quad Dominant"
        #set mesh_method2 "Autoblock"
        set free_bunch 0
        # mapped
        set merge_surfs 1
        set mapped_method 1
	set shrinkwrap_nsmooth 5
	set shrinkwrap_projfactor 0.1
    }

    set curVals [ ic_get_meshing_params global 0 ]
    array set valArray $curVals

    set fastTranFlag  $valArray(gfast)
    set gedgec $valArray(gedgec)

     # ----------------------------
    advMeshParamsDEZ aie_update_thincuts
    advMeshParamsDEZ aie_update_global_mesh_params
    # -------------------

    #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)
    }
}

proc onadvMeshParamsDEZAfterLoad {} {
    global env valSurfaceArray

    if ![info exists env(AI_ENV_CFD)] return

    catch { unset valSurfaceArray }
    array set valSurfaceArray [ic_get_meshing_params surface_global 0]
    foreach n [array names valSurfaceArray] {
        if [info exists $n] {
            if {$n == "simple_offset"} {
                switch $valSurfaceArray($n) {
                    0 { set simple_offset2 "Standard" }
                    1 { set simple_offset2 "Simple" }
                    2 { set simple_offset2 "Forced simple" }
                }
            } else {
                set $n $valSurfaceArray($n)
            }
        }
    }

    if {0} {
    if [info exists valSurfaceArray(mesh_type)] {
        set mesh_type2 [aie_global_get_mesh_type_name $valSurfaceArray(mesh_type)]
    }
    if [info exists valSurfaceArray(mesh_method)] {
        set mesh_method2 [aie_global_get_mesh_method_name $valSurfaceArray(mesh_method)]
    }
    }

    set pars {shrinkwrap_projfactor shrinkwrap_nsmooth}
    foreach p $pars {
	if [info exists valSurfaceArray($p)] {
	    set $p $valSurfaceArray($p)
	}
    }

    foreach v {bunch_respect protect_line ign_size} {
        if {[trace vinfo $v] != ""} {
            trace vdelete $v w aie_global_quad_trace_bunch_respect
        }
        trace variable $v w aie_global_quad_trace_bunch_respect
    }
    foreach v {mesh_dormant smooth_dormant} {
        if {[trace vinfo $v] != ""} {
            trace vdelete $v w aie_global_quad_trace_dormant
        }
        trace variable $v w aie_global_quad_trace_dormant
    }
    foreach v {tetra_smooth tetra_smooth2 tetra_coarsen} {
        if {[trace vinfo $v] != ""} {
            trace vdelete $v w aie_global_trace_tetra_gui_values
        }
        trace variable $v w aie_global_trace_tetra_gui_values
    }
    aie_global_trace_tetra_gui_values "" "" ""
    aie_global_quad_trace_proj_surf "" "" ""
    aie_global_quad_trace_bunch_respect "" "" ""
    aie_global_quad_trace_dormant "" "" ""
}

proc onadvMeshParamsDEZOK {} {
    global env

        if {$advMeshParamsGGVal == 0} { 	# Quad settings
            switch $simple_offset2 {
                "Standard"      { set q_simple_offset 0 }
                "Simple"        { set q_simple_offset 1 }
                "Forced simple" { set q_simple_offset 2 }
                default         { set q_simple_offset 0 }
            }
            set q_bunch_respect $bunch_respect
            if !$bunch_respect {
                set q_protect_line 0
            } else {
                set q_protect_line $protect_line
            }
            set q_bound_smooth $bound_smooth
            set q_block_mapping $block_mapping
            set q_adjust_nodes_max $adjust_nodes_max
            set q_proj_surf $proj_surf
            set q_surf_sizes $surf_sizes
            set q_max_dev $max_dev
            set q_ign_size $ign_size
            set q_try_harder $try_harder
            set q_impr_level $impr_level
            set q_mesh_dormant $mesh_dormant
            if !$mesh_dormant {
                set q_smooth_dormant 0
            } else {
                set q_smooth_dormant $smooth_dormant
            }
            set q_max_area $max_area
            set q_max_length $max_length
            set q_min_angle $min_angle
            set q_max_nodes $max_nodes
            set q_max_elements $max_elements
            set q_merge_surfs $merge_surfs
            set q_mapped_method $mapped_method
            set q_free_bunch $free_bunch

            ic_set_meshing_params surface_global 0 \
                simple_offset $q_simple_offset bunch_respect $q_bunch_respect\
                protect_line $q_protect_line bound_smooth $q_bound_smooth block_mapping $q_block_mapping\
                adjust_nodes_max $q_adjust_nodes_max proj_surf $q_proj_surf surf_sizes $q_surf_sizes\
                max_dev $q_max_dev ign_size $q_ign_size try_harder $q_try_harder impr_level $q_impr_level\
                mesh_dormant $q_mesh_dormant smooth_dormant $q_smooth_dormant max_area $q_max_area\
                max_length $q_max_length min_angle $q_min_angle max_nodes $q_max_nodes\
                max_elements $q_max_elements merge_surfs $q_merge_surfs mapped_method $q_mapped_method\
                free_bunch $q_free_bunch shrinkwrap_nsmooth $shrinkwrap_nsmooth shrinkwrap_projfactor \
		$shrinkwrap_projfactor
	    return
        }

	if {$advMeshParamsGGVal == 1} { # volume meshing
	    switch $mszGlobalVolumeTypeEGVal {
		0 {
		    aie_set_global_mesh_params tetra
		    ic_set_meshing_params global 0 gfast $fastTranFlag gedgec $gedgec
		}
		1 {
		    aie_set_global_mesh_params hybrid
		}
		2 {
		    aie_set_global_mesh_params cart
		}
	    }
	}

        if {$advMeshParamsGGVal == 2} { 	# Prism settings
	    global prism_values prism_extras
	    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 prism_values($i) [set $i]
	    }
	    return
        }
}

proc onadvMeshParamsDEZUnLoad {} {
   foreach v {bunch_respect protect_line ign_size} {
        if {[trace vinfo $v] != ""} {
            trace vdelete $v w aie_global_quad_trace_bunch_respect
        }
    }
    foreach v {mesh_dormant smooth_dormant} {
        if {[trace vinfo $v] != ""} {
            trace vdelete $v w aie_global_quad_trace_dormant
        }
    }
    foreach v {tetra_smooth tetra_smooth2 tetra_coarsen} {
        if {[trace vinfo $v] != ""} {
            trace vdelete $v w aie_global_trace_tetra_gui_values
        }
        trace variable $v w aie_global_trace_tetra_gui_values
    }
}

proc aie_prism_update_params {} {
    global prism_family_on prism_family_backup
    global prism_family_height prism_family_ratio prism_family_n_layers
    global options

    if $options(show_factor) {
	set fact [ic_geo_get_ref_size]
    } else {
	set fact 1.0
    }

    foreach ff [ic_geo_list_parts] {
        set prism_family_on($ff) 0
        set prism_family_height($ff) 0
        set prism_family_ratio($ff) 0
        set prism_family_n_layers($ff) 0
        foreach {p v} [ic_geo_get_prism_family_params $ff] {
            if {$p == "height"} {
                if {![catch {expr $v / $fact} val]} {
                    set v [format "%g" $val]
                }
            }
            set prism_family_${p}($ff) $v
        }
    }
    set prism_families [ic_geo_get_prism_families]
    foreach ff $prism_families {
        set prism_family_on($ff) 1
    }
}

# Only prism parts control
proc aie_edit_prism_parts {} {
    global mparams geo_command_mode options mainwindow_menubar
    global geo_params_blank_done geometry_mode
    global prism_family_on prism_values prism_families prism_parts
    global prism_family_height prism_family_ratio prism_family_n_layers
    global hexcore_family_backup prism_family_backup
    global options

    if {![ic_geo_is_loaded]} {
        msg ERROR "no geometry is loaded"
        return
    }

    set w .prism_parts
    if [winfo exists $w] { destroy $w }
    geo_params_update_sizes allparts
    aie_prism_update_params
    set buts [list [list Apply "aie_edit_prism_parts_apply"]  [list Dismiss "form_done $w"]]
    set ww [form_init $w "Select prism parts" "" $buts]
    if {$ww != ""} {
	form_frame $ww.labels flat 0 "0 0"
	set labels $ww.labels
	set d $ww.labels
	set bg [$w cget -background]

	form_label $d.fnl "Part" "0 0"
        form_button $d.fsl  "Select" aie_prism_select_all-none "0 1"
	form_label $d.fhl "Height" "0 2"
	form_label $d.frl "Height Ratio" "0 3"
	form_label $d.fwl "Num Layers" "0 4"

        set d [form_scroller $ww.fr 400 {1 0}]
	set scr $d
	set sel ""
	set sortedfams [lsort -dictionary [ic_geo_list_parts]]
	set solid_part_fams ""
	set non_solid_part_fams ""
	set svfams [ic_list_volume_families]
	array set solid {}
	foreach ff $sortedfams {
	    if {$ff == "ORFN"} continue
            if {[ic_geo_count_in_family {surface curve point} $ff] && [ic_geo_count_in_family body $ff]} {
                mess "Part $ff contains geometry and body in same part.  This is not recommended and could\
                      cause problems! Part $ff will be ignored.\n" red
                continue
            }
	    set solid_part 0
	    set solid($ff) 0
	    if {([ic_geo_get_objects surface $ff] == "") && \
		([ic_geo_get_objects curve $ff] == "") && \
		([ic_geo_get_objects point $ff] == "")} {
		if {[ic_geo_get_objects body $ff] != "" || \
			[lsearch $svfams $ff] > -1} {
		    set solid_part 1
		    set solid($ff) 1
		} else {
		    continue
		}
	    }
	    if $solid_part {
	        lappend solid_part_fams $ff
	    } else {
	        lappend non_solid_part_fams $ff
	    }
	}

	set resortedfams ""
	foreach ff $non_solid_part_fams {
	    lappend resortedfams $ff
	}
	foreach ff $solid_part_fams {
	    lappend resortedfams $ff
	}
	set sortedfams $resortedfams
	set bg [$w cget -background]
	set ln 0
	foreach ff $sortedfams {
	    if {$ff == "ORFN"} continue
	    set solid_part $solid($ff)
	    lappend sel $ff
	    form_label $scr.fam_$ln $ff "$ln 0"
	    form_checkbutton $scr.prism_$ln "" prism_family_on($ff) "$ln 1 -fill both"
            $scr.prism_$ln configure -background $bg -width 2
	    set prism_family_backup($ff) $prism_family_on($ff)
	    if $solid_part {
		incr ln; continue
	    }
	    if [info exists prism_family_height($ff)] {
		set mparams(${ff}_ehgt) $prism_family_height($ff)
	    }
	    if [info exists prism_family_ratio($ff)] {
		set mparams(${ff}_hrat) $prism_family_ratio($ff)
	    }
	    if [info exists prism_family_n_layers($ff)] {
		set mparams(${ff}_nlay) $prism_family_n_layers($ff)
	    }
	    form_entry $scr.fnl_$ln mparams(${ff}_ehgt) string "$ln 2"
	    $scr.fnl_$ln configure -width 12
	    form_entry $scr.frl_$ln mparams(${ff}_hrat) string "$ln 3"
	    $scr.frl_$ln configure -width 12
	    form_entry $scr.fwl_$ln mparams(${ff}_nlay) string "$ln 4"
	    $scr.fwl_$ln configure -width 12
	    incr ln
	}
	form_checkbutton $ww.showfactor "Show size params using ref size" options(show_factor) {31 0}
	$ww.showfactor configure -command "geo_params_update_sizes allfamilies; geo_params_show_params"
        set idx 0
        set minsize(0) 0
        foreach c [winfo children $scr] {
            set minsize($idx) [winfo reqwidth $c]
            if [string match "*fam_*" $c] {
                if {$minsize($idx) > $minsize(0)} {
                    set minsize(0) $minsize($idx)
                }
            }
            incr idx
        }
        set idx 0
        foreach c [winfo children $labels] {
            grid columnconfigure $labels $idx -minsize [expr $minsize($idx) + 6]
            incr idx
        }
        grid $ww.fr -row 1 -column 0 -sticky nw
	set mparams(sel) $sel
	form_finish +10+300
    }
}

proc aie_edit_prism_parts_apply {} {
    global mparams prism_family_backup hexcore_family_backup
    global prism_family_on prism_values prism_families prism_parts
    global prism_family_height prism_family_ratio prism_family_n_layers

    set prism_families ""
    # don't change other parameters
    foreach p {emax emin edev erat ewid etyp internal_wall split_wall} {
        set mparams($p) ""
    }
    foreach ff [ic_geo_list_parts] {
        if {$ff == "ORFN"} continue
        if {[info exists prism_family_on($ff)] && ( $prism_family_on($ff) == 1 )} {
	        set prism_family_backup($ff) $prism_family_on($ff)
	        lappend prism_families $ff
	        if [info exists mparams(${ff}_ehgt) ] {set prism_family_height($ff) $mparams(${ff}_ehgt) }
	        if [info exists mparams(${ff}_hrat) ] {set prism_family_ratio($ff) $mparams(${ff}_hrat) }
	        if [info exists mparams(${ff}_nlay) ] {set prism_family_n_layers($ff) $mparams(${ff}_nlay) }
	    } elseif {[info exists prism_family_on($ff)]} {
	        set prism_family_backup($ff) $prism_family_on($ff)
	    }
	    if {([ic_geo_get_objects surface $ff] == "") && ([ic_geo_get_objects curve $ff] == "") && ([ic_geo_get_objects point $ff] == "")} continue
	    set mparams(selfam) $ff
   	    set pnames {ehgt hrat nlay}
	    foreach p $pnames {
	        set mparams($p) $mparams(${ff}_$p)
	    }
	    geo_params_edit_apply part
    }
    ic_geo_set_prism_families $prism_families
}


