# Library functions for the scripting library (scrib)
#
# File: scrib/lib/mesh_cleanup.tcl
#
# $Revision$ on $Date$
# 
# Copyright (c) 1993-2003 ICEM CFD Engineering
#
#--------------------------------------------------------------------


proc clean_bad_mesh_problems {subset } {

    foreach el [ic_uns_subset_list_elements $subset] {
	set type [lindex $el 0]
	set name [lindex $el 1]
	set nodes [lindex $el 2]
	switch $type {
	    TRI_3 {
		set tmpsubset [ic_uns_subset_create]
		ic_uns_subset_add_number $tmpsubset "$name" 1 TRI_3
		#ic_uns_swap_edges_node_numbers [find_max_edge $tmpsubset] 1
		set n_swap [find_max_edge $tmpsubset]
		ic_uns_subset_delete $tmpsubset		

		set nodesubset [ic_uns_subset_create]
		ic_uns_subset_add_node_numbers $nodesubset $n_swap
		set retval [ic_uns_swap_edges $nodesubset 1]
		mess "swapping edge $n_swap; $retval\n"
		#return
		ic_uns_subset_delete $nodesubset
	    }
	    QUAD_4 {
		set tmpsubset [ic_uns_subset_create]
		ic_uns_subset_add_number $tmpsubset "$name" 1 QUAD_4
		set retval [ic_uns_change_type $tmpsubset quad tri 0]
		mess "splitting quad $name; $retval\n"
		#return 
		ic_uns_subset_delete $tmpsubset		
	    }
	}
    }

}


proc find_max_edge {subset} {
#this will return the two nodes of the largest edge
    foreach el [ic_uns_subset_list_elements $subset] {
	set type [lindex $el 0]
	set name [lindex $el 1]
	set nodes [lindex $el 2]

	switch $type {
	    TRI_3 {
		set nodesubset [ic_uns_subset_create]
		ic_uns_subset_add_node_numbers $nodesubset $nodes
		set i 1
		foreach n [ic_uns_subset_list_elements $nodesubset] {
		    set p($i) [lindex $n 2]
		    set node($i) [lindex $n 1]
		    incr i
		}
		ic_uns_subset_delete $nodesubset
		set d1 [distance_between_two_XYZ_vals $p(1) $p(2)]
		set d2 [distance_between_two_XYZ_vals $p(1) $p(3)]
		set d3 [distance_between_two_XYZ_vals $p(3) $p(2)]
		set dist [list [list $d1 $node(1) $node(2)] [list $d2 $node(1) $node(3)] [list $d3 $node(3) $node(2)]]
		set order [lsort -decreasing -index 0 $dist]
		return [lrange [lindex $order 0] 1 2]
	    }
	     default {
		mess "code is not written for any elements but TRI_3"
	    }
	}
    }
}

proc distance_between_two_XYZ_vals {pt1 pt2} {
    set dist 0
    foreach i {0 1 2} {
	set p [expr {[lindex $pt2 $i] - [lindex $pt1 $i]}]
	set d$i [length_in_units $p %e]
	set dist [expr {$dist + $p * $p}]
    }
    set pdist [length_in_units [expr {sqrt($dist)}] %e]
    return $pdist
}


