
# DOC DONE

# This code creates the user interface for the mesh editor.
#
# Copyright (c) 1997 Pacific Marketing and Consulting, Inc,
#       and ICEM Systems, GmbH.  All rights reserved.
# Author:  Wayne A. Christopher, wayne@icemcfd.com
# $Revision$ on $Date$

# This file contains special comments of the form ## html ... which are
# used to automatically generate documentation

## <h3>Cartesian mesh editing and modification functions</h3>
## These functions are used to manipulate the <b>cart_file</b> data which
## is used by the <b>Global</b> mesher.  Note that the meshes output by
## <b>Global</b> global can be cylindrical in addition to purely Cartesian.
## The positions in X, Y, and Z appear in the cart file, together with
## information on the coordinate system.
## <p>
## In addition to the explicit stations, one or more <i>ranges</i> can be
## stored in the cart file.  These ranges specify a distribution of stations.
## When the list of stations is requested
## for a direction, or the file saved or displayed, these ranges will be
## evaluated to give the result.
## <p>
## Each range contains the following parameters.
## <ul>
## <li> <b>start</b> : the starting position for the range
## <li> <b>end</b> : the ending position for the range
## <li> <b>type</b> : one of the following values:
## <ul>
## <li> <b>uniform</b> : the stations are uniformly spaced in the region
## <li> <b>geo_start</b> : the spacing is geometric, from the start point
## <li> <b>geo_end</b> : the spacing is geometric, from the ending point
## back towards the start
## <li> <b>geo_both</b> : the spacing is geometric in both directions.
## <b>Currently unimplemented</b>
## <li> <b>explicit</b> : the specific list of stations is given
## <b>This option is currently unavailable from the <i>ic_</i> functions</b>
## </ul>
## <li> <b>count</b> : the number of stations for uniform spacing or
## an explicit list
## <li> <b>start_h</b> : the starting spacing if the type is <b>geo_start</b>
## or <b>geo_both</b>
## <li> <b>start_r</b> : the starting ratio between adjacent stations
## if the type is <b>geo_start</b> or <b>geo_both</b>
## <li> <b>end_r</b> :  the ending spacing if the type is <b>geo_end</b>
## or <b>geo_both</b>
## <li> <b>end_r</b> : the ending ratio between adjacent stations
## if the type is <b>geo_end</b> or <b>geo_both</b>
## <li> <b>comb</b> : how to combine this range with other ranges.
## If <b>comb</b> is 0 then the new stuff will wipe out all the old stuff
## in the regions where it covers it, if it's 1 then the old and new stuff
## gets merged, and if it's 2 then the new stuff will be used only in
## regions that are NOT inside a previous range where we also had a value of
## 2, but the old stuff will be always pulled in.  However the new stuff will
## always contribute its starting and ending points no matter what.
## <li> <b>max_h</b> : the maximum spacing for the entire range
## <li> <b>active</b> : 1 if this range is to be used, 0 if it's inactive
## </ul>

## Has cart file information been loaded into the program?

proc ic_cart_is_loaded {} {
    global cart_file
    
    return [expr {$cart_file != ""}]

}
set dont_record_command(ic_cart_is_loaded) 1

## Has the cart file info been modified?

proc ic_cart_is_modified {{set ""}} {
    global cart_file
    
    if {($cart_file != "") && ($set != "")} {	
	$cart_file configure -modified $set
    } else {
	return [expr {($cart_file != "") && [$cart_file get -modified]}]
    }
}
set dont_record_command(ic_cart_is_modified) 1

## Return the bounding box of the cart file stations.  The return value is
## a list of 2 triples: e.g. <tt>{0 0 0} {1 2 3}</tt>

proc ic_cart_get_bbox {} {
    global cart_file
    
    return [$cart_file get_bbox]
}
set dont_record_command(ic_cart_get_bbox) 1

## Unload the current cart file data

proc ic_cart_unload {} {
    global cart_file
    
    if {$cart_file != ""} {
	$cart_file delete
	set cart_file ""
    }
}

## Load cart data from the given file name.  It is not initially visible.

proc ic_cart_load {file} {
    global cart_file batch_mode
    global tdv_default
    
    set cart_file [cart_file -filename $file -visible 0]
    if !$batch_mode { $tdv_default add_image $cart_file }
    $cart_file load_cartfile $file
    set ss [$cart_file stats]
    mess "Cart file is loaded: size is [lindex $ss 0]x[lindex $ss 1]x[lindex $ss 2] = [lindex $ss 3] nodes\n"
    if {([$cart_file get -grid_type] == "cylindrical") &&
	([$cart_file get -from_ddn] == -1)} {
	mess "Warning: can't tell if this geometry has been translated to the new coordinate system already - assuming not.\n" red
	$cart_file configure -from_ddn 0
    }
}

## Write out cart data to the given file

proc ic_cart_save {file} {
    global cart_file
    
    if ![ic_cart_is_loaded] {
	mess "There is no Cartesian data to save\n" ; return	
    }
    
    $cart_file save_cartfile $file ""
    mess "Saved Cartesian data to $file\n"
    $cart_file configure -modified 0    
}

## Create an empty cart file with the boundary of the current viewable stuff
## as the stations.  There will be 2 stations in each of the 3 directions which
## are at the min and max of the visible area.  If the <b>from_proj</b>
## argument is 1, and a tetin file is loaded, then instead the geometry data
## will be used and a station will be created at each "key point" of
## the geometry.

proc ic_cart_initialize {from_proj {bbox ""}} {
    global cart_file projlib
    global tdv_default batch_mode
    
    set cart_file [cart_file -visible 0]
    if !$batch_mode {
	$tdv_default add_image $cart_file
    }

    if {$bbox == ""} {
	if $batch_mode {
	    set bb [ic_geo_model_bounding_box]
	} else {
	    set bb [$tdv_default bbox interesting]
	}
    } else {
	set bb $bbox
    }


    if {$bb == ""} { return 0 }
    foreach i {0 1 2} {
	if {$from_proj && [ic_geo_is_loaded]} {
	    set stats [ic_geo_get_keypoints $i 0.01 $bb]
	} else {
	    set stats [list [lindex [lindex $bb 0] $i] \
			   [lindex [lindex $bb 1] $i]]
	}
	$cart_file set_stations $i $stats
	mess "[lindex {I J K} $i] direction: [llength $stats] stations\n"
    }
    $cart_file configure -modified 1 -origin "0 0 0" -axis0 "1 0 0" \
	-axis1 "0 1 0" -axis2 "0 0 1"
}

## Return stats for the cart file.  4 integers are returned: the number of
## stations in each direction, followed by the number of nodes (i.e. the
## product of these three values).

proc ic_cart_stats {} {
    global cart_file
    return [$cart_file stats]
}
set dont_record_command(ic_cart_stats) 1

## Turn the cart file visibility on or off.

proc ic_cart_visible {on} {
    global cart_file
    if {$cart_file != ""} { $cart_file configure -visible $on }
}
set dont_record_command(ic_cart_visible) 1

## Return the type of the loaded cart file: either <b>cartesian</b> or
## <b>cylindrical</b>.

proc ic_cart_grid_type {} {
    global cart_file
    return [$cart_file get -grid_type]
}
set dont_record_command(ic_cart_grid_type) 1

## Set the type of the loaded cart file.  <i>type</i> must be either
## <b>cartesian</b> or <b>cylindrical</b>

proc ic_cart_set_grid_type {type} {
    global cart_file
    $cart_file configure -grid_type $type -modified 1
}

## Add one station to the cart file, based on the vector defined by
## <i>pt</i> and <i>vec</i>.  These are the values determined by screen
## selection.

proc ic_cart_add_screen {pt vec} {
    global cart_file
    
    $cart_file add_station_screen $pt $vec
    $cart_file configure -modified 1
}

## Select stations in the cart file via the screen, based on the vector
## defined by <i>pt</i> and <i>vec</i>.

proc ic_cart_select_screen {pt vec} {
    global cart_file
    
    $cart_file select_station_screen $pt $vec
}

## Delete the selected stations in the cart file, which have been previously
## defined using <b>ic_cart_select_screen</b>.

proc ic_cart_delete_selected {} {
    global cart_file
    
    set n [$cart_file delete_station_selected]
    mess "$n stations deleted\n"
    $cart_file configure -modified 1
}

## List the stations in a direction.  <i>dir</i> should be either 0, 1, or 2.

proc ic_cart_list_stations {dir} {
    global cart_file
    
    return [$cart_file list_stations $dir]
}
set dont_record_command(ic_cart_list_stations) 1

## Set the stations in a direction.  <i>dir</i> should be either 0, 1, or 2.
## <i>stats</i> is a list of floating point numbers which are the stations
## in that direction.

proc ic_cart_set_stations {dir stats} {
    global cart_file
    
    $cart_file set_stations $dir $stats
}

## List the ranges in a direction.  <i>dir</i> should be either 0, 1, or 2.
## The return value is a list of ranges, where each range has the format:<br>
## <i>start end type numpts start_h start_r end_h end_r comb max_h active</i>
## <br>The meaning of these parameters is described at the start of
## this section.

proc ic_cart_list_ranges {dir} {
    global cart_file
    
    return [$cart_file list_ranges $dir]
}
set dont_record_command(ic_cart_list_ranges) 1

## Set the ranges in a direction.  The <i>ranges</i> argument is a list of
## ranges as described above.

proc ic_cart_set_ranges {dir ranges} {
    global cart_file
    
    $cart_file set_ranges $dir $ranges
    $cart_file compute $dir [ic_geo_get_keypoints $dir 0.01]
    $cart_file configure -modified 1
}

## Get the axes of the cart file.  This returns a list of 4 triples:
## <i>origin axis0 axis1 axis2</i>

proc ic_cart_get_axes {} {
    global cart_file
    return [list [$cart_file get -origin] [$cart_file get -axis0] \
		[$cart_file get -axis1] [$cart_file get -axis2]]
}
set dont_record_command(ic_cart_get_axes) 1

## Set the axes of the cart file.  The arguments are the origin and the
## 3 cordinate axes, each of which is a list of 3 numbers.

proc ic_cart_set_axes {origin axis0 axis1 axis2} {
    global cart_file
    $cart_file configure -origin $origin -axis0 $axis0 \
	-axis1 $axis1 -axis2 $axis2 -modified 1
}

## Did this cart file come from DDN?  This matters because the cart files from
## DDN are written out together with the geometry pre-transformed into the
## given coordinate system, but other cart files are not.

proc ic_cart_is_from_ddn {} {
    global cart_file
    return [$cart_file get -from_ddn]
}
set dont_record_command(ic_cart_is_from_ddn) 1
