
# Scripting functions for autohexa.
#
# Copyright (c) 1999 ICEM CFD Engineering.  All rights reserved.
# Author:  Wayne A. Christopher, wayne@icemcfd.com
# $Revision: 401458 $ on $Date: 2004-11-17 19:54:38 -0500 (Wed, 17 Nov 2004) $

# All script commands begin with ax_, for AutoheXa.
#
# This file contains special comments of the form ## html ... which are
# used to automatically generate documentation

## <h2>Autohexa Scripting commands</h2>
## These commands are used for writing autohexa scripts, for macros and
## customized forms.

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

## <h3>Object creation and modification commands</h3>

## Create a new object and set its properties.  The arguments are:
## <ul>
## <li> <b>type</b> : the object type, e.g. block
## <li> <b>namebase</b> : the base string to make the name.  A suffix will
## be added if necessary to make the name unique
## <li> <b>shapetype</b> : what kind of shape to create for this object.
## The possible shapes depend on the object type and are from the
## following list:
## <b>container hexa sphere cad cyl circ none quad incline oval polygon
## pipe</b>
## <li> <b>objparams</b> : a list of param / value pairs that define the
## object data to set
## <li> <b>shparams</b> : a list of param / value pairs that define the
## shape data
## </ul>

proc ax_object_create {type namebase shapetype objparams shparams} {
    global ax_macro_group
    if [info exists ax_macro_group] {
	lappend objparams group $ax_macro_group
    }
    if {[db_get_name $namebase] == ""} {
	set name $namebase
    } else {
	set name [db_new_name $namebase]
    }
    set obj [edit_new $type $name]
    edit_modify_object $obj $objparams $shapetype $shparams
    if {[info command app_clean_up_$type] != ""} {
	app_clean_up_$type $obj
    }
    reconfigure_object $obj
    return $obj
}

## Modify some parameters of the given object.  This function takes an
## object handle (not a name) and a list of name/value pairs.

proc ax_object_modify_params {obj objparams} {
    foreach {p n} $objparams {
	switch $p {
	    name {
		edit_rename_object $obj [$obj getval name] $n
	    }
	    active {
		if {$n != [$obj si_value active]} {
		    global edit_current_active
		    set edit_current_active $n
		    edit_toggle_current_active $obj 0 1
		}
	    }
	}
    }
    eval $obj setval $objparams
    app_clean_up_[$obj getval obtype] $obj
    relabel_shapes $obj
    db_dirty mesh
}

## Modify some shape parameters of the given object.  This function takes an
## object handle and a section name and a list of name/value pairs.

proc ax_object_modify_shape_params {obj sect shparams} {
    global current_object edit_current_active
    
    set sh [$obj getval ${sect}_shape]
    if {$sh == ""} { error "no such shape" }
    eval $sh setval -noconstr $shparams
   
    make_visible $obj [$obj si_value active]
    
    if {$obj == $current_object} {
	set edit_current_active [$obj si_value active]
	edit_reset_params
    }
    
    db_dirty mesh
}

## Return an unused name that begins with <b>namebase</b>

proc ax_object_new_name {namebase} {
    global model_container
    return [$model_container new_name $namebase]
}

## List all the objects of the given type.  Returns a list of object
## handles<p>
## The things you can do with object handles should be documented somewhere
## but for now:
## <ul>
## <li> <b>$obj getval <i>param</i></b> : return the current value of a
## parameter, such as <b>name</b> or <b>body_shape</b>
## </ul>

proc ax_object_list {type} {
    return [db_list_objects $type]
}

## Given a name return the object for it.

proc ax_object_lookup {name} {
    return [db_get_name $name]
}

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

## <h3>Macro-specific commands</h3>

## Call this function before starting to create the objects for a macro.
## If inpart is 1 then the macro will create a part of the given name.
## If it is 0 then it will create a group instead.
## If <em>groupname</em> is given then it will use that one.

proc ax_macro_start {inpart partname {groupname ""}} {
    global ax_macro_part ax_macro_group
    
    if $inpart {
	set ax_macro_part [part_begin_internal $partname]
	set ax_macro_group ""
	$ax_macro_part setval part_type internal
    } else {
	if {$groupname == ""} {
	    set ax_macro_group [coll_new_name group]
	} else {
	    set ax_macro_group $groupname
	}
	set ax_macro_part ""
    }
}

## Call this function after creating all the objects for a macro.

proc ax_macro_finish {} {
    global ax_macro_part ax_macro_group
    
    if {$ax_macro_part != ""} {
	part_end_internal
	foreach sub [$ax_macro_part list_contents] {
	    reconfigure_object $sub
	}
	set ax_macro_part ""
    }
    set ax_macro_group ""
}

## Add Load and Save buttons to a macro form.  The arguments are:
## <ul>
## <li> <b>w</b> : the name of a frame to be created to hold the buttons.
## <li> <b>data</b> : a global variable that contains the data to be saved or
## loaded.
## <li> <b>dir</b> : the default directory for load/save macro param files
## <li> <b>tabdata</b> : the row-column position of the widget.  See the
## form documentation for more details
## <li> <b>after_load</b> : a function to call after the load is done
## </ul>
## Also this function will add buttons with the option to create internal
## parts or not.  This affects the variables inpart and partname.

proc ax_macro_standard_buttons {w data dir tabdata {after_load ""}} {
    global $data
    
    set vars [array names $data]
    
    form_frame $w flat 0 $tabdata
    
    form_checkbutton $w.inpart "Create internal part" \
	${data}(inpart) {0 0 -cols -}
    form_label $w.partnamel "    Name" {1 0}
    form_entry $w.partname ${data}(partname) string {1 1}
    if {$dir != ""} {
	if {$after_load != ""} { set after_load "; $after_load" }
	form_frame $w.ls flat 0 {2 0 -cols -}
	form_button $w.ls.save "Save" "macro_save $data $dir \{$vars\}" {0 0}
	form_button $w.ls.rest "Load" \
	    "macro_load $data $dir \{$vars\} $after_load" {0 1}
    }
}

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

## <h3>Material commands</h3>

## Get a material object given its name and type.

proc ax_get_material {name type} {
    return [get_material $name $type]
}

## Get a floating point value for one of the values of a material.

proc ax_get_material_param {name type param} {
    set obj [get_material $name $type]
    return [get_constant_matval_object $obj $param]
}

## Make a new custom material that is the copy of an existing one.  If params
## are given they will be applied to this one.

proc ax_make_custom_material {orig newname {params ""}} {
    global current_phase
    
    if {[db_get_name $newname] != ""} {
	set newname [db_new_name $newname]
    }
    set s_mat [db_copy [get_material $orig] $newname [part_get_root]]
    eval $s_mat setval fixvals 0 mat_subtype Custom mat_custom 1 $params
    app_clean_up_material $s_mat
    if {$current_phase == "Custom"} { update_mtype material }
    return $s_mat
}

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

## <h3>Unit commands</h3>

## Get the default units of the given type.  Possible types are:<p>
## <b>length area volume 1/area speed acceleration angle time 1/time
## pressure temperature temp_change power heat power/volume power/area
## heat_flux heat_tr_coeff roughness vol_expansion density sp_heat
## conductivity resistance viscosity mass_flow mass_flow/area volume_flow
## diffusivity mol_weight e_resistance e_current turbulent_k turbulent_o
## emissivity losscoeff fan_curve conductance</b>

proc ax_units_get_default {type} {
    return [unit_get_default_choice $type]
}

## Convert the value, which is in the given units, to SI (the internal form).

proc ax_unit_to_si {val unit} {
    return [unit_convert $val $unit 0]
}

## Convert the value, which is in SI (the internal form), to the units given.

proc ax_unit_to_user {val unit} {
    return [unit_convert $val $unit 1]
}

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

## <h3>Form commands</h3>

## Create an edit form for a given shape type.  The arguments are:
## <ul>
## <li> <b>w</b> : this must be the name of a frame widget already created
## using <b>form_frame</b>
## <li> <b>type</b> : this is the type of the shape required.  Possible types
## are:<p>
## <b>container hexa sphere cad cyl circ none quad incline oval polygon
## pipe</b>
## <li> <b>varname</b> : this is the name of the global variable where the
## shape parameters are kept.  For example if the type is <b>quad</b> and the
## varname is <b>xxx_data</b> then the variables <b>xxx_data(xs)</b>, etc
## should be set before this function is called to some default values and
## will be modified as the user changes the entries.
## <li> <b>row</b> : what row to start with on the form.  Normally it would be
## 0 but could be greater if there is other stuff in the form already.
## </ul>

proc ax_form_edit_shape {w type varname row {change_plane_callback ""}} {
    if {$change_plane_callback != ""} {
	set nn [edit_${type}_form $w "" $varname $row $change_plane_callback]
    } else {
	set nn [edit_${type}_form $w "" $varname $row]
    }
    if {$type == "polygon"} { edit_poly_win_populate $w.f $varname }
    return $nn
}

## Create a unit entry widget.  This is similar to the form_ functions.  The
## arguments are:
## <ul>
## <li> <b>w</b> : the name of the widget to be created.  Should not already
## exist.
## <li> <b>var</b> : the variable to use for the value.  Note that the
## unit type, e.g. <b>m</b> for meters, will be stored in the variable
## <b><i>var</i>_units</b> (which should already be initialized, or if
## <b>var</b> is of the <b>form <i>array(key)</i></b> it will be stored in
## <b><i>array</i>_units(<i>key</i>)</b>.
## <li> <b>unittype</b> : type of units.  See <b>ax_units_get_default</b>
## for a list of types.
## <li> <b>tabgeo</b> : the row-column position of the widget.  See the
## form documentation for more details
## <li> <b>activedata</b> : the active specification for this widget.  See the
## form documentation for more details
## <li> <b>widget</b> : width of the entry
## </ul>

proc ax_form_unitentry {w var unittype tabgeo {activedata ""} {width 8}} {
    return [model_unitentry $w $var $unittype $tabgeo $activedata $width]
}

## Create a material entry widget.  This is similar to the form_ functions.
## The arguments are:
## <ul>
## <li> <b>w</b> : the name of the widget to be created.  Should not already
## exist.
## <li> <b>var</b> : the variable to use for the material name.
## <li> <b>mattype</b> : type of the material.  Can be:
# <b>solid fluid surface</b>
## <li> <b>tabgeo</b> : the row-column position of the widget.  See the
## form documentation for more details
## <li> <b>activedata</b> : the active specification for this widget.  See the
## form documentation for more details
## </ul>

proc ax_form_matentry {w var mattype tabgeo {activedata ""}} {
    return [model_matentry $w $var $mattype $tabgeo $activedata]
}

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

## <h3>Meshing</h3>

## Generate a grid 

proc ax_grid_generate {} {
    grid_generate
}

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

## <h3>Trials and expressions</h3>

## Reset the trial names to begin with <b>prefix</b>

proc ax_trial_set_names {prefix} {
    global expression_trial_prefix
    set expression_trial_prefix $prefix
    expression_set_trial_names 1 1
}

## How many trials are currently defined?

proc ax_expression_count_trials {} {
    return [expression_count_trials]
}

## Switch to the main version of a job

proc ax_switch_main_version {} {
    job_switch_version {} 1 1
}

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

## <h3>Misc</h3>

## Return various bits of information about the current state.
## <b>what</b> can be:
## <ul>
## <li> <b>diff_flag</b> : returns the current default for the start/end
## option : 0 means the current default is start/end and 1 means start/length
## </ul>

proc ax_info {what} {
    global job_diff_flag
    
    switch $what {
	diff_flag { return $job_diff_flag }
	default { error "unknown option" }
    }
}

## Print the given message to the message window or the standard output if
## the program is being run in batch mode.  There may be 1 or 2 arguments.  
## The first is the string and the second if given is the color to print 
## the message in.

proc ax_mess {args} {
    return [eval mess $args]
}
