/***********************************************************************
*
* ELMER, A Computational Fluid Dynamics Program.
*
* Copyright 1st April 1995 - , Center for Scientific Computing,
* Finland.
*
* All rights reserved. No part of this program may be used,
* reproduced or transmitted in any form or by any means
* without the written permission of CSC.
*
* Address: Center for Scientific Computing
* Tietotie 6, P.O. BOX 405
* 02101 Espoo, Finland
* Tel. +358 0 457 2001
* Telefax: +358 0 457 2302
* EMail: Jari.Jarvinen@csc.fi
************************************************************************/
/***********************************************************************
Program: ELMER Front
Module: ecif_userinterface_TCL.cpp
Language: C++
Date: 21.10.98
Version: 1.00
Author(s): Martti Verho
Revisions:
Abstract: Implementation
************************************************************************/
#include "../config.h"
#if defined(WIN32)
#include <direct.h>
#else
#include <unistd.h>
#endif
// NOTE: Include order is imporant here!
// Otherwise conflicts with Windows and Stl
#include "ecif_userinterface.h"
#include "ecif_userinterface_TCL.h"
// END NOTE
#include "ecif_body.h"
#include "ecif_bodyLayer.h"
#include "ecif_bodyElement.h"
#include "ecif_bodyElementGroup.h"
#include "ecif_bodyForce.h"
#include "ecif_boundaryCondition.h"
#include "ecif_constant.h"
#include "ecif_coordinate.h"
#include "ecif_control.h"
#include "ecif_datafile.h"
#include "ecif_equation.h"
#include "ecif_geometry.h"
#include "ecif_gridParameter.h"
#include "ecif_initialCondition.h"
#include "ecif_material.h"
#include "ecif_model.h"
#include "ecif_modelObject.h"
#include "ecif_process.h"
#include "ecif_renderer.h"
#include "ecif_renderer_OGL.h"
#include "ecif_solver.h"
#include "ecif_timer.h"
#include "ecif_timestep.h"
#ifdef UNIX
#include "ecif_renderer.h"
#endif
void Tcl_MainLoop();
int My_Tcl_AppInit(Tcl_Interp* interp);
void WishPanic _ANSI_ARGS_(TCL_VARARGS(char *,format));
int TkTest_Init(Tcl_Interp *interp);
void tcl_DisplayIdleProc(ClientData data);
void tcl_InterruptIdleProc(ClientData data);
void tcl_interrupt(ClientData data);
extern void display_system_msg(char* header);
extern void display_msg(char* header, char* msg);
extern UserInterface* TheUI = NULL;
ClientData displayIdleData;
ClientData interruptIdleData;
const int glob_flag = TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG;
const int int_ro_flag = TCL_LINK_INT | TCL_LINK_READ_ONLY;
const int str_ro_flag = TCL_LINK_STRING | TCL_LINK_READ_ONLY;
const char tclObjectSeparator = '!';
const char tclFieldSeparator = '&';
const char tclCmdSeparator = '@';
const char tclArgSeparator = '^';
const char subIdSep = '.';
const char sis = subIdSep;
const int isOK = 0;
// *****************************************
// =========================================
// UserInterface base class
// =========================================
void
UserInterface::errMsg(int err_level, char* str1, char* str2, char* str3, char* str4)
{
strstream strm;
if ( str1 != NULL ) strm << str1;
if ( str2 != NULL ) strm << str2;
if ( str3 != NULL ) strm << str3;
if ( str4 != NULL ) strm << str4;
strm << ends;
if ( strm.str() != NULL ) cerr << strm.str();
}
void
UserInterface::matcFileWasRead(char* filename)
{
strstream strm;
strm << "***MATC file loaded: " << filename << ends;
showMsg(strm.str());
}
// Simulate pause (in seconds)
void
UserInterface::pause(double seconds, bool show)
{
Timer timer;
strstream strm;
if ( show ) {
strm << "---Pause " << seconds << " seconds..." << ends;
showMsg(strm.str());
} else {
generateEvent();
update();
}
timer.start();
while ( timer.getLapTime(WALL_TIME) < seconds );
if ( show ) {
showMsg("---Pause done!...");
} else {
generateEvent();
update();
}
}
int
UserInterface::showMsg(char* msg, short extra_line_feeds, bool append)
{
cerr << msg << endl;
return 0;
}
// ----------------
// Batch-mode start
// ----------------
//
void
UserInterface::start(int argc, char** argv)
{
char* model_dir = NULL;
char* model_name = NULL;
char* mesh_name = NULL;
char* mesh_log = NULL;
for ( int i = 0; i < argc; i++) {
if ( LibFront::ncEqualPartial(argv[i], "model-directory=") ) {
char* tmp = LibFront::trimLeft(argv[i]);
tmp +=16;
update_dyna_string(model_dir, tmp);
} else if ( LibFront::ncEqualPartial(argv[i], "model-name=") ) {
char* tmp = LibFront::trimLeft(argv[i]);
tmp +=11;
update_dyna_string(model_name, tmp);
} else if ( LibFront::ncEqualPartial(argv[i], "mesh-name=") ) {
char* tmp = LibFront::trimLeft(argv[i]);
tmp +=10;
update_dyna_string(mesh_name, tmp);
} else if ( LibFront::ncEqualPartial(argv[i], "mesh-log=") ) {
char* tmp = LibFront::trimLeft(argv[i]);
tmp +=9;
update_dyna_string(mesh_log, tmp);
}
}
if ( model_name == NULL ||
mesh_name == NULL
) {
cerr << "Usage: ElmerFront --batch=1 "
<< "[--model-directory=dirname (default: cwd)] "
<< "<--model-name=name> "
<< "<--mesh-name=dirname> "
<< "[--mesh-log=filename (default: cerr)]"
<< endl;
delete[] model_dir;
delete[] model_name;
delete[] mesh_name;
delete[] mesh_log;
return;
}
if ( model_dir == NULL ) {
update_dyna_string(model_dir, "./");
}
strstream strm, strm1, strm2, strm3, strm4;
// Check that model file exists
//
strm << model_dir << "/" << model_name << ".emf" << ends;
// NOTE: Possible error message comes from control, no need to output here!
cerr << endl;
if ( !theControlCenter->readModelFile(strm.str(), false, true) ) {
cerr << endl;
return;
}
// Check that mesh directory exists (check by parts!)
//
strm1 << model_dir << "/MESHDIR" << ends; // Model's MESHDIR subdirectory
if ( !front_mkdir(strm1.str()) ) {
cerr << "***ERROR: Model's MESHDIR does not exist: " << strm1.str()
<< endl;
return;
}
strm2 << strm1.str() << '/' << mesh_name << ends; // Mesh-dir
if ( !front_mkdir(strm2.str()) ) {
cerr << "***ERROR: Mesh directory does not exist: " << strm2.str()
<< endl;
return;
}
// Create and save mif-file
//
strm3 << strm2.str() << '/' << model_name << ".mif" << ends; // Mif-filename
theControlCenter->saveMeshInputFile(strm3.str());
char curr_wd[1025];
front_getcwd(curr_wd, 1024);
// Go to mesh directory to start ElmerMesh2D
//
if ( !front_chdir(strm2.str()) ) {
cerr << "**ERROR: Cannot change to the mesh directory: " << strm2.str()
<< endl;
return;
return;
}
// Call: ElmerMesh2D mif-filename
//
//strm4 << strm3.str() << ends;
strm4 << model_name << ".mif" << ends;
Process* process = new Process("ElmerMesh2D", strm4.str());
if ( mesh_log != NULL ) {
process->setLogfile(mesh_log);
} else {
process->setShowConsole(true);
}
cerr << endl << "Calling: ElmerMesh2D " << strm4.str()
<< endl;
process->start();
// Back to current directory
//
if ( !front_chdir(curr_wd) ) return;
}
// =========================================
// UserInterface_TCL class
// =========================================
// Initialize class variables
Control* UserInterface::theControlCenter = NULL;
Tcl_Interp* UserInterface_TCL::theInterp = NULL;
char* UserInterface_TCL::controlSideScript = NULL;
char* UserInterface_TCL::tclScriptPath = NULL;
// Constructor
// ===========
UserInterface_TCL::UserInterface_TCL(Hinst application, char* ctrl_script):
UserInterface(application, NULL)
{
controlSideScript = ctrl_script;
tclScriptPath = NULL;
theInterp = createTclEnvironment(application);
if ( theInterp == NULL) {
exit(1);
}
// Hm... this is ugly, but we need
// a global UI object to give any message
// for interrupt handling
TheUI = this;
// *** Add new commands to the Tcl-enviromnment
createTclCommands(theInterp);
}
// Open a dialog in gui, where the user can accept list of parmaters
// ( ex. to be copied into model)
void
UserInterface_TCL::acceptEmfParameters(char* msg, int nof_params, char* pdatas, bool* accept_flags)
{
int i;
for (i = 0; i < nof_params; i++) {
accept_flags[i] = false;
}
ostrstream strm;
strm << msg << tclArgSeparator
<< pdatas << ends;
int rc = sendCommandToGui(theInterp, "Interface::acceptParameters", strm.str());
char* result = NULL;
Tcl_CreateTimerHandler(1, tcl_DisplayIdleProc, displayIdleData);
int event_types = TCL_ALL_EVENTS;
while ( Tcl_DoOneEvent(event_types) ) {
result = getCommandResults(theInterp);
if ( result != NULL && result[0] != '\0' ) break;
generateEvent();
}
if ( result == NULL || result[0] == '\0' ) return;
istrstream flags(result);
int flag;
for (i = 0; i < nof_params; i++) {
flags >> flag;
accept_flags[i] = bool(flag);
}
}
void
UserInterface_TCL::checkMeshInfoTs(char* ts) {
sendCommandToGui(theInterp,"Interface::checkMeshInfoTs", ts);
}
void
UserInterface_TCL::colorFileWasRead(char* filename)
{
sendCommandToGui(theInterp, "Interface::colorFileWasRead", filename);
}
// Menu state setting commands
// ===========================
// One option for one button
void
UserInterface_TCL::configureButtonOption(char* button, char* option, char* value)
{
ostrstream strm;
strm << button << tclArgSeparator
<< option << tclArgSeparator
<< value << ends;
sendCommandToGui(theInterp, "Interface::configureButtonOption", strm.str());
}
// State for buttons
void
UserInterface_TCL::configureButtons(char* buttons, int state)
{
ostrstream strm;
strm << buttons << tclArgSeparator
<< state << ends;
sendCommandToGui(theInterp, "Interface::configureButtons", strm.str());
}
// One option for one menu button
void
UserInterface_TCL::configureMenuButtonOption(char* menu, char* button, char* option, char* value)
{
ostrstream strm;
strm << menu << tclArgSeparator
<< button << tclArgSeparator
<< option << tclArgSeparator
<< value << ends;
sendCommandToGui(theInterp, "Interface::configureMenuButtonOption", strm.str());
}
// State for menu buttons
void
UserInterface_TCL::configureMenuButtons(char* menu, char* buttons, int state)
{
ostrstream strm;
strm << menu << tclArgSeparator
<< buttons << tclArgSeparator
<< state << ends;
sendCommandToGui(theInterp, "Interface::configureMenuButtons", strm.str());
}
Tcl_Channel
UserInterface_TCL::createFileChannel(Tcl_Interp* interp, Hfile native_handle)
{
Tcl_Channel channel = Tcl_MakeFileChannel((ClientData)native_handle, TCL_READABLE);
Tcl_SetChannelOption(interp, channel, "-blocking", "0");
Tcl_RegisterChannel(interp, channel);
return channel;
}
// REGISTRATION of new Tcl commands
// ================================
// Cover function to make writing interface a bit shorter.
void
UserInterface_TCL::createTclCommand(Tcl_Interp* interp, char* tcl_command, Tcl_CmdProc* cpp_func)
{
Tcl_CreateCommand(interp, tcl_command, cpp_func, (ClientData) NULL, (Tcl_CmdDeleteProc*) NULL);
}
#define TCL_FUNC_PROTO (int (*)(void*,Tcl_Interp*,int,const char**))
// For each command, there is also a cpp-function defined!!!
void
UserInterface_TCL::createTclCommands( Tcl_Interp* interp)
{
createTclCommand(interp, "cpp_doMatc", TCL_FUNC_PROTO from_tk_DoMatc);
// ------ File menu commands ------
createTclCommand(interp, "cpp_openCadFile", TCL_FUNC_PROTO from_tk_OpenCadFile);
createTclCommand(interp, "cpp_openModelFile", TCL_FUNC_PROTO from_tk_OpenModelFile);
createTclCommand(interp, "cpp_openMeshFile", TCL_FUNC_PROTO from_tk_OpenMeshFile);
createTclCommand(interp, "cpp_loadMesh", TCL_FUNC_PROTO from_tk_LoadMesh);
createTclCommand(interp, "cpp_unloadMesh", TCL_FUNC_PROTO from_tk_UnloadMesh);
createTclCommand(interp, "cpp_saveModelFile", TCL_FUNC_PROTO from_tk_SaveModelFile);
createTclCommand(interp, "cpp_saveMeshInputFile", TCL_FUNC_PROTO from_tk_SaveMeshInputFile);
createTclCommand(interp, "cpp_saveSolverInputFile", TCL_FUNC_PROTO from_tk_SaveSolverInputFile);
createTclCommand(interp, "cpp_saveElmerMeshFile", TCL_FUNC_PROTO from_tk_SaveElmerMeshFile);
createTclCommand(interp, "cpp_saveElmerPostMeshFile", TCL_FUNC_PROTO from_tk_SaveElmerPostMeshFile);
createTclCommand(interp, "cpp_saveThetisMeshFile", TCL_FUNC_PROTO from_tk_SaveThetisMeshFile);
createTclCommand(interp, "cpp_copyParameters", TCL_FUNC_PROTO from_tk_CopyParameters);
// Program exit.
createTclCommand(interp, "cpp_exit", TCL_FUNC_PROTO from_tk_Exit);
//------ Edit menu commands -------
createTclCommand(interp, "cpp_removeCadGeometry", TCL_FUNC_PROTO from_tk_RemoveCadGeometry);
createTclCommand(interp, "cpp_setMatcInputFileEmf", TCL_FUNC_PROTO from_tk_SetMatcInputFileEmf);
createTclCommand(interp, "cpp_setMatcInputFileSif", TCL_FUNC_PROTO from_tk_SetMatcInputFileSif);
createTclCommand(interp, "cpp_saveUserSettingsFile", TCL_FUNC_PROTO from_tk_SaveUserSettingsFile);
createTclCommand(interp, "cpp_updateCadGeometry", TCL_FUNC_PROTO from_tk_UpdateCadGeometry);
createTclCommand(interp, "cpp_setMeshInputUnit", TCL_FUNC_PROTO from_tk_SetMeshInputUnit);
//------ Display menu commands ------
createTclCommand(interp, "cpp_bodyDisplayPanelOk", TCL_FUNC_PROTO from_tk_ReadBodyDisplayData);
createTclCommand(interp, "cpp_boundaryDisplayPanelOk", TCL_FUNC_PROTO from_tk_ReadBoundaryDisplayData);
createTclCommand(interp, "cpp_rendererDisplayModel", TCL_FUNC_PROTO from_tk_RendererDisplayModel);
createTclCommand(interp, "cpp_rendererResetModel", TCL_FUNC_PROTO from_tk_RendererResetModel);
createTclCommand(interp, "cpp_rendererRotateModel", TCL_FUNC_PROTO from_tk_RendererRotateModel);
createTclCommand(interp, "cpp_rendererScaleModel", TCL_FUNC_PROTO from_tk_RendererScaleModel);
createTclCommand(interp, "cpp_rendererSetEditBoundaries", TCL_FUNC_PROTO from_tk_RendererSetEditBoundaries);
createTclCommand(interp, "cpp_rendererSetRotatePriorities", TCL_FUNC_PROTO from_tk_RendererSetRotatePriorities);
createTclCommand(interp, "cpp_rendererTranslateModel", TCL_FUNC_PROTO from_tk_RendererTranslateModel);
createTclCommand(interp, "cpp_vertexDisplayPanelOk", TCL_FUNC_PROTO from_tk_ReadVertexDisplayData);
//------ Data transfer and update from GUI ------
// Panel Ok
createTclCommand(interp, "cpp_bodyForcePanelOk", TCL_FUNC_PROTO from_tk_ReadBodyForceData);
createTclCommand(interp, "cpp_bodyParameterPanelOk", TCL_FUNC_PROTO from_tk_ReadBodyParameterData);
createTclCommand(interp, "cpp_bodyPropertyPanelOk", TCL_FUNC_PROTO from_tk_ReadBodyData);
createTclCommand(interp, "cpp_bodyPropertyPanelColorsOk", TCL_FUNC_PROTO from_tk_ReadBodyColors);
createTclCommand(interp, "cpp_bodyPropertyPanelNamesOk", TCL_FUNC_PROTO from_tk_ReadBodyNames);
createTclCommand(interp, "cpp_bodyPropertyPanelDeleteBodyOk", TCL_FUNC_PROTO from_tk_ReadBodyDeleteData);
createTclCommand(interp, "cpp_boundariesPanelOk", TCL_FUNC_PROTO from_tk_ReadBoundariesData);
createTclCommand(interp, "cpp_boundaryConditionPanelOk", TCL_FUNC_PROTO from_tk_ReadBoundaryConditionData);
createTclCommand(interp, "cpp_boundaryParameterPanelOk", TCL_FUNC_PROTO from_tk_ReadBoundaryParameterData);
createTclCommand(interp, "cpp_calculatorPanelOk", TCL_FUNC_PROTO from_tk_ReadCalculatorData);
createTclCommand(interp, "cpp_constantPanelOk", TCL_FUNC_PROTO from_tk_ReadConstantData);
createTclCommand(interp, "cpp_coordinatePanelOk", TCL_FUNC_PROTO from_tk_ReadCoordinateData);
createTclCommand(interp, "cpp_datafilePanelOk", TCL_FUNC_PROTO from_tk_ReadDatafileData);
createTclCommand(interp, "cpp_equationPanelOk", TCL_FUNC_PROTO from_tk_ReadEquationData);
createTclCommand(interp, "cpp_equationVariablesPanelOk", TCL_FUNC_PROTO from_tk_ReadEquationVariablesData);
createTclCommand(interp, "cpp_gridHPanelOk", TCL_FUNC_PROTO from_tk_ReadGridHData);
createTclCommand(interp, "cpp_gridParameterPanelOk", TCL_FUNC_PROTO from_tk_ReadGridParameterData);
createTclCommand(interp, "cpp_initialConditionPanelOk", TCL_FUNC_PROTO from_tk_ReadInitialConditionData);
createTclCommand(interp, "cpp_materialPanelOk", TCL_FUNC_PROTO from_tk_ReadMaterialData);
createTclCommand(interp, "cpp_meshDefinePanelOk", TCL_FUNC_PROTO from_tk_ReadMeshDefineData);
createTclCommand(interp, "cpp_modelParameterPanelOk", TCL_FUNC_PROTO from_tk_ReadModelParameterData);
createTclCommand(interp, "cpp_modelPropertyPanelOk", TCL_FUNC_PROTO from_tk_ReadModelPropertyData);
createTclCommand(interp, "cpp_processorPanelOk", TCL_FUNC_PROTO from_tk_ReadProcessorData);
createTclCommand(interp, "cpp_simulationParameterPanelOk", TCL_FUNC_PROTO from_tk_ReadSimulationParameterData);
createTclCommand(interp, "cpp_solverParameterPanelOk", TCL_FUNC_PROTO from_tk_ReadSolverData);
createTclCommand(interp, "cpp_solverControlPanelOk", TCL_FUNC_PROTO from_tk_ReadSolverControlData);
createTclCommand(interp, "cpp_timestepPanelOk", TCL_FUNC_PROTO from_tk_ReadTimestepData);
createTclCommand(interp, "cpp_userSettingPanelOk", TCL_FUNC_PROTO from_tk_ReadUserSettingsData);
// Older version data conversion save procs
createTclCommand(interp, "cpp_readConvertedEquationData", TCL_FUNC_PROTO from_tk_ReadConvertedEquationData);
// Flags and states
createTclCommand(interp, "cpp_checkMeshCornerElements", TCL_FUNC_PROTO from_tk_CheckMeshCornerElements);
createTclCommand(interp, "cpp_correctMeshZeroVelocityElements", TCL_FUNC_PROTO from_tk_CorrectMeshZeroVelocityElements);
createTclCommand(interp, "cpp_checkModelStatus", TCL_FUNC_PROTO from_tk_CheckModelStatus);
createTclCommand(interp, "cpp_putModelStatusMessage", TCL_FUNC_PROTO from_tk_PutModelStatusMessage);
createTclCommand(interp, "cpp_setFlagValue", TCL_FUNC_PROTO from_tk_SetFlagValue);
createTclCommand(interp, "cpp_setModelStatus", TCL_FUNC_PROTO from_tk_SetModelStatus);
// Other
createTclCommand(interp, "cpp_deleteParameters", TCL_FUNC_PROTO from_tk_ReadDeletedParamIds);
createTclCommand(interp, "cpp_readActiveMeshIndices", TCL_FUNC_PROTO from_tk_ReadActiveMeshIndices);
createTclCommand(interp, "cpp_readModelFileCreated", TCL_FUNC_PROTO from_tk_ReadModelFileCreated);
createTclCommand(interp, "cpp_readModelFileModified", TCL_FUNC_PROTO from_tk_ReadModelFileModified);
createTclCommand(interp, "cpp_readModelHasUserDefinitions", TCL_FUNC_PROTO from_tk_ReadModelHasUserDefinitions);
createTclCommand(interp, "cpp_readModelFileTime", TCL_FUNC_PROTO from_tk_ReadModelFileTime);
createTclCommand(interp, "cpp_readSelectionTolerances", TCL_FUNC_PROTO from_tk_ReadSelectionTolerances);
createTclCommand(interp, "cpp_readTimestamp", TCL_FUNC_PROTO from_tk_ReadTimestamp);
createTclCommand(interp, "cpp_resetAllBoundarySelections", TCL_FUNC_PROTO from_tk_ResetAllBoundarySelections);
createTclCommand(interp, "cpp_resetBoundarySelections", TCL_FUNC_PROTO from_tk_ResetBoundarySelections);
createTclCommand(interp, "cpp_setSelectionsToGui", TCL_FUNC_PROTO from_tk_SetSelectionsToGui);
createTclCommand(interp, "cpp_selectMeshBoundaryElements", TCL_FUNC_PROTO from_tk_SelectMeshBoundaryElements);
createTclCommand(interp, "cpp_combineBoundaries", TCL_FUNC_PROTO from_tk_CombineBoundaries);
createTclCommand(interp, "cpp_boundaryPanelNamesOk", TCL_FUNC_PROTO from_tk_ReadBoundaryNames);
createTclCommand(interp, "cpp_splitCombineBoundariesRedo", TCL_FUNC_PROTO from_tk_SplitCombineBoundariesRedo);
createTclCommand(interp, "cpp_splitCombineBoundariesUndo", TCL_FUNC_PROTO from_tk_SplitCombineBoundariesUndo);
createTclCommand(interp, "cpp_splitBoundary", TCL_FUNC_PROTO from_tk_SplitBoundary);
createTclCommand(interp, "cpp_stopEditMeshBoundaries", TCL_FUNC_PROTO from_tk_StopEditMeshBoundaries);
createTclCommand(interp, "cpp_restoreBoundaryNames", TCL_FUNC_PROTO from_tk_RestoreBoundaryNames);
createTclCommand(interp, "cpp_storeBoundaryNames", TCL_FUNC_PROTO from_tk_StoreBoundaryNames);
//------ List box selection routines ------
createTclCommand(interp, "cpp_bodySelected", TCL_FUNC_PROTO from_tk_BodySelected);
createTclCommand(interp, "cpp_boundarySelected", TCL_FUNC_PROTO from_tk_BoundarySelected);
createTclCommand(interp, "cpp_boundariesSelected", TCL_FUNC_PROTO from_tk_BoundariesSelected);
//------ Misc ------
createTclCommand(interp, "cpp_processExists", TCL_FUNC_PROTO from_tk_ProcessExists);
createTclCommand(interp, "cpp_processResume", TCL_FUNC_PROTO from_tk_ProcessResume);
createTclCommand(interp, "cpp_processSetPriorityLevel", TCL_FUNC_PROTO from_tk_ProcessSetPriorityLevel);
createTclCommand(interp, "cpp_processStart", TCL_FUNC_PROTO from_tk_ProcessStart);
createTclCommand(interp, "cpp_processStop", TCL_FUNC_PROTO from_tk_ProcessStop);
createTclCommand(interp, "cpp_processSuspend", TCL_FUNC_PROTO from_tk_ProcessSuspend);
createTclCommand(interp, "cpp_readUserSettingFiles", TCL_FUNC_PROTO from_tk_ReadUserSettingFiles);
createTclCommand(interp, "cpp_setCurrentDirectory", TCL_FUNC_PROTO from_tk_SetCurrentDirectory);
createTclCommand(interp, "cpp_readColorFile", TCL_FUNC_PROTO from_tk_ReadColorFile);
createTclCommand(interp, "cpp_readMatcFile", TCL_FUNC_PROTO from_tk_ReadMatcFile);
createTclCommand(interp, "cpp_updateMatcFile", TCL_FUNC_PROTO from_tk_UpdateMatcFile);
// Stop Front processing
createTclCommand(interp, "cpp_doBreak", TCL_FUNC_PROTO from_tk_DoBreak);
// Find color name for a hex-value color id
createTclCommand(interp, "cpp_colorHex2Name", TCL_FUNC_PROTO from_tk_ColorHex2Name);
}
// *** Function creates and initialises the TCL/Tk environment.
Tcl_Interp*
UserInterface_TCL::createTclEnvironment(Hinst application)
{
Tcl_SetPanicProc((void (*)(const char *, ...)) WishPanic);
// *** Create Tcl-interpreter and register command procedures
Tcl_FindExecutable( (char*) application );
Tcl_Interp* interp = Tcl_CreateInterp();
#ifdef TCL_MEM_DEBUG
Tcl_InitMemory(interp);
#endif
// *** Invoke application-specific initialization.
if (My_Tcl_AppInit(interp) != TCL_OK) {
WishPanic("My_Tcl_AppInit failed: %s\n", interp->result);
}
// Result value is the Tcl interpreter
return interp;
}
// Show error mesage box in gui
//
// NOTE: str1-str4 are for convenience only, tehy are combined into one string!
// NOTE: Use "////n" in cpp-side to deliver new lines into message-box
//
void
UserInterface_TCL::errMsg(int err_level, char* str1, char* str2, char* str3, char* str4)
{
ostrstream strm;
strm.unsetf(ios:: skipws);
strm << err_level << tclArgSeparator;
if (str1 != NULL) strm << str1;
if (str2 != NULL) strm << str2;
if (str3 != NULL) strm << str3;
if (str4 != NULL) strm << str4;
strm << ends;
sendCommandToGui(theInterp, "Interface::displayErrorMsg", strm.str());
}
// Convert field's gui-name (like "HEAT_EQUATION") to sif-name ("Heat Equation")
void
UserInterface_TCL::fieldNameGuiToSif(const char* gui_name, char* sif_name_buffer)
{
sendCommandToGui(theInterp, "Interface::fieldNameGuiToSif", gui_name);
strcpy(sif_name_buffer, getCommandResults(theInterp));
}
// Convert field's sif-name (like "Heat Equation") to gui-name ("HEAT_EQUATION")
void
UserInterface_TCL::fieldNameSifToGui(const char* sif_name, char* gui_name_buffer)
{
sendCommandToGui(theInterp, "Interface::fieldNameSifToGui", sif_name);
strcpy(gui_name_buffer, getCommandResults(theInterp));
}
// Call Elmer MATC from Gui
int
UserInterface_TCL::from_tk_DoMatc(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
char* data = getCommandArguments(interp);
char* result = mtc_domath(data);
// Write result for Gui
if ( result != NULL && result[0] != '\0' ) {
writeVariable(interp, "Info", "MATC_result", result);
} else {
writeVariable(interp, "Info", "MATC_result", " ");
}
return TCL_OK;
}
// A body was selected in the bodylist.
int
UserInterface_TCL::from_tk_BodySelected(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
istrstream in(getCommandArguments(interp));
int bd_id, lr_id;
in >> bd_id >> lr_id;
theControlCenter->selectBody(bd_id, lr_id);
return TCL_OK;
}
// One boundary was selected in the listbox
int
UserInterface_TCL::from_tk_BoundarySelected(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
//NOTE: For testing only one element at atime.
istrstream in(getCommandArguments(interp));
int bd1_id, lr1_id, bd2_id, lr2_id, bndr_id, accept_body_change, update_gui;
in >> bndr_id >> bd1_id >> lr1_id >> bd2_id >> lr2_id >> accept_body_change >> update_gui;
theControlCenter->selectBoundary(bndr_id, bd1_id, lr1_id, bd2_id, lr2_id,
(bool)accept_body_change, (bool)update_gui);
return TCL_OK;
}
// Group of boundaries were selected in the listbox
// NOTE !!!Works currently only for one boundary!!!
int
UserInterface_TCL::from_tk_BoundariesSelected(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
// NOTE: For testing only one element at a time.
istrstream in(getCommandArguments(interp));
int nof_boundaries;
in >> nof_boundaries;
int* bndr_ids = new int[nof_boundaries];
int* bd1_ids = new int[nof_boundaries];
int* lr1_ids = new int[nof_boundaries];
int* bd2_ids = new int[nof_boundaries];
int* lr2_ids = new int[nof_boundaries];
for (int i = 0; i < nof_boundaries; i++) {
in >> bndr_ids[i] >> bd1_ids[i] >> lr1_ids[i] >> bd2_ids[i] >> lr2_ids[i];
}
int accept_body_change, update_gui;
in >> accept_body_change >> update_gui;
theControlCenter->selectBoundaries(nof_boundaries, bndr_ids,
bd1_ids, lr1_ids,
bd2_ids, lr2_ids,
(bool)accept_body_change, (bool)update_gui);
return TCL_OK;
}
// Function calls the model to check if any mesh corner elements has zero-velocity
// resulting boundary conditions etc.
int
UserInterface_TCL::from_tk_CheckMeshCornerElements(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "CheckMeshCornerElements: Command not legal. No model exists!");
return TCL_OK;
}
model->classifyMeshCornerElements();
return TCL_OK;
}
// Function ask from the model the status and saves it (also into Gui side)!
int
UserInterface_TCL::from_tk_CheckModelStatus(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "CheckModelStatus: Command not legal. No model exists!");
return TCL_OK;
}
// Get current status
ecif_modelStatus status = model->checkStatus();
// Save in model
model->setModelStatus(status);
// Save in Gui
to_tk_WriteModelStatus(interp, *model);
return TCL_OK;
}
// Function starts boundary splitting
int
UserInterface_TCL::from_tk_CombineBoundaries(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "CombineBoundaries: Command not legal. No model exists!");
return TCL_OK;
}
int body1_id, body2_id;
istrstream in(getCommandArguments(interp));
in >> body1_id >> body2_id;
model->combineBoundaries(body1_id, body2_id);
return TCL_OK;
}
// Copy parameters from an emf-file.
int
UserInterface_TCL::from_tk_CopyParameters(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
char* emf_filename = getCommandArguments(interp);
#if defined(FRONT_DEBUG)
theControlCenter->copyParameters(emf_filename);
#else
try {
theControlCenter->copyParameters(emf_filename);
}
catch (...) {
TheUI->errMsg(0, "CopyParameters: processing error!");
}
#endif
return TCL_OK;
}
// Function calls the model to correct all zero-velocity (corner) elements
int
UserInterface_TCL::from_tk_CorrectMeshZeroVelocityElements(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "CorrectMeshZeroVelocityElements: Command not legal. No model exists!");
return TCL_OK;
}
model->correctMeshZeroVelocityElements();
return TCL_OK;
}
// Function closes renderer window.
int
UserInterface_TCL::from_tk_Exit(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
theControlCenter->Exit();
return TCL_OK;
}
// Read mesh for the (CAD) model from Elmer DB
int
UserInterface_TCL::from_tk_LoadMesh(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "LoadMesh: Command not legal. No model exists!");
return TCL_OK;
}
model->loadMesh();
return TCL_OK;
}
// Read a CAD-file.
int
UserInterface_TCL::from_tk_OpenCadFile(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
// First argument: cad filepath
// Second argument: cad type (Elmer etc.)
char* data = getCommandArguments(interp);
int oc_argc;
char** oc_argv;
int code = Tcl_SplitList(interp, data, &oc_argc, (const char ***) &oc_argv);
if (code != TCL_OK) return TCL_ERROR;
#if defined(FRONT_DEBUG)
theControlCenter->readCADFile(oc_argv[0], oc_argv[1]);
#else
try {
theControlCenter->readCADFile(oc_argv[0], oc_argv[1]);
}
catch (...) {
TheUI->errMsg(0, "Read Cad file: processing error!");
}
#endif
return TCL_OK;
}
// Read a mesh file.
int
UserInterface_TCL::from_tk_OpenMeshFile(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
// First argument is open mode: 1 = create new model, 0 do not create
// Second argument: mesh filepath
// Third argument: mesh type (Default, Ideas etc.)
char* data = getCommandArguments(interp);
int om_argc;
char** om_argv;
int code = Tcl_SplitList(interp, data, &om_argc, (const char ***) &om_argv);
if (code != TCL_OK)
return TCL_ERROR;
int mode = atoi(om_argv[0]);
#if defined(FRONT_DEBUG)
// Create new model
if ( mode == 1 ) {
theControlCenter->readMeshFile(om_argv[1], om_argv[2], true);
// Add new mesh (or update existing)
} else {
theControlCenter->readMeshFile(om_argv[1], om_argv[2], false);
}
#else
try {
// Create new model
if ( mode == 1 ) {
theControlCenter->readMeshFile(om_argv[1], om_argv[2], true);
// Add new mesh (or update existing)
} else {
theControlCenter->readMeshFile(om_argv[1], om_argv[2], false);
}
}
catch (...) {
TheUI->errMsg(0, "Read mesh file: processing error!");
}
#endif
return TCL_OK;
}
// Reads a ecif model file.
int
UserInterface_TCL::from_tk_OpenModelFile(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
char* in_filename = getCommandArguments(interp);
char* auto_load_mesh = (char *) Tcl_GetVar2(interp, "UserSetting", "AUTO_LOAD_MESH", glob_flag);
bool load_mesh = true;
if (auto_load_mesh != NULL)
load_mesh = atoi(auto_load_mesh);
theControlCenter->readModelFile(in_filename, load_mesh);
return TCL_OK;
}
// Function checks if process with id 'nbr' exists
int
UserInterface_TCL::from_tk_ProcessExists(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
int nbr = atoi(getCommandArguments(interp));
bool exists = theControlCenter->processExists(nbr);
strstream strm;
strm << nbr << ",exists" << ends;
writeVariable(interp, "ProcessTable", strm.str(), exists);
return TCL_OK;
}
// Function restarts a suspended external process with id 'nbr'
int
UserInterface_TCL::from_tk_ProcessResume(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
int nbr = atoi(getCommandArguments(interp));
theControlCenter->processResume(nbr);
return TCL_OK;
}
// Function restarts a suspended external process with id 'nbr'
int
UserInterface_TCL::from_tk_ProcessSetPriorityLevel(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
char* data = getCommandArguments(interp);
int pl_argc;
char** pl_argv;
int code = Tcl_SplitList(interp, data, &pl_argc, (const char ***)&pl_argv);
if (code != TCL_OK)
return TCL_ERROR;
int nbr = atoi(pl_argv[0]);
priorityLevel priority;
char* plevel = pl_argv[1];
if ( 0 == strcmp(plevel, "LOW_PRIORITY") )
priority = ECIF_LOW_PRIORITY;
else if ( 0 == strcmp(plevel, "LOWER_THAN_NORMAL_PRIORITY") )
priority = ECIF_LOWER_THAN_NORMAL_PRIORITY;
else if ( 0 == strcmp(plevel, "NORMAL_PRIORITY") )
priority = ECIF_NORMAL_PRIORITY;
else if ( 0 == strcmp(plevel, "HIGER_THAN_NORMAL_PRIORITY") )
priority = ECIF_HIGHER_THAN_NORMAL_PRIORITY;
else if ( 0 == strcmp(plevel, "HIGH_PRIORITY") )
priority = ECIF_HIGH_PRIORITY;
theControlCenter->processSetPriorityLevel(nbr, priority);
return TCL_OK;
}
// Function starts external process
int
UserInterface_TCL::from_tk_ProcessStart(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
//---Get process start-data
char* data = getCommandArguments(interp);
int pr_argc;
char** pr_argv;
int code = Tcl_SplitList(interp, data, &pr_argc, (const char ***) &pr_argv);
if (code != TCL_OK)
return TCL_ERROR;
char* command = pr_argv[0];
char* args = pr_argv[1];
int nbr = atoi(pr_argv[2]);
char* name = pr_argv[3];
priorityLevel priority;
char* plevel = pr_argv[4];
if ( 0 == strcmp(plevel, "LOW_PRIORITY") )
priority = ECIF_LOW_PRIORITY;
else if ( 0 == strcmp(plevel, "LOWER_THAN_NORMAL_PRIORITY") )
priority = ECIF_LOWER_THAN_NORMAL_PRIORITY;
else if ( 0 == strcmp(plevel, "NORMAL_PRIORITY") )
priority = ECIF_NORMAL_PRIORITY;
else if ( 0 == strcmp(plevel, "HIGER_THAN_NORMAL_PRIORITY") )
priority = ECIF_HIGHER_THAN_NORMAL_PRIORITY;
else if ( 0 == strcmp(plevel, "HIGH_PRIORITY") )
priority = ECIF_HIGH_PRIORITY;
char* logfile = pr_argv[5];
bool show_console = false;
if ( 0 == strcmp(logfile, "none") )
logfile = NULL;
else if ( 0 == strcmp(logfile, "shell") ) {
logfile = NULL;
show_console = true;
}
Process* process = new Process(command, args, nbr, name, priority, show_console, logfile);
// Try to create and start process
if ( theControlCenter->processStart(process) ) {
Hfile outputHandle = process->getOutputHandle();
ProcessId PID = process->getProcessId();
// Set logfile handle
// NOTE: use 0 here instead of NULL, because
// handle is int
if (outputHandle != 0) {
Tcl_Channel channel = NULL;
Timer ch_timer;
ch_timer.start();
// Try to open, max 30 seconds
while( channel == NULL && ch_timer.getLapTime(WALL_TIME) < 30 ) {
channel = createFileChannel(interp, outputHandle);
}
ch_timer.stop();
if (channel != NULL) {
char* channel_name = (char *) Tcl_GetChannelName(channel);
writeIdVariable(interp, "ProcessTable", process->ID(), "channel", channel_name);
} else {
strstream strm;
strm << "Could not open log file for the process " << process->ID() << ends;
theControlCenter->getGui()->showMsg(strm.str());
}
}
// Set process id (PID)
if ( PID != 0 ) {
writeIdVariable(interp, "ProcessTable", process->ID(), "pid", PID);
}
}
return TCL_OK;
}
// Function stops external process with id 'nbr'
int
UserInterface_TCL::from_tk_ProcessStop(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
int nbr = atoi(getCommandArguments(interp));
theControlCenter->processStop(nbr);
return TCL_OK;
}
// Function suspends external process with id 'nbr'
int
UserInterface_TCL::from_tk_ProcessSuspend(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
int nbr = atoi(getCommandArguments(interp));
theControlCenter->processSuspend(nbr);
return TCL_OK;
}
// Gets model status message from the model
int
UserInterface_TCL::from_tk_PutModelStatusMessage(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "PutModelStatusMessage: Command not legal. No model exists!");
return TCL_OK;
}
to_tk_WriteModelStatusMessage(interp, *model);
return TCL_OK;
}
// Gets active Solver mesh indices from gui
int
UserInterface_TCL::from_tk_ReadActiveMeshIndices(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadActiveMeshIndices: Command not legal. No model exists!");
return TCL_OK;
}
int nof_meshes;
int* mesh_indices = NULL;
readVariable(interp, "Model", "activeMeshIndices", nof_meshes, mesh_indices);
model->setActiveMeshIndices(nof_meshes, mesh_indices);
delete[] mesh_indices;
return TCL_OK;
}
// Function reads and updates body-colors data when OK-button
// is pressed in Tk/GUI body-names dialog.
int
UserInterface_TCL::from_tk_ReadBodyColors(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadBodyColors: Command not legal. No model exists!");
return TCL_OK;
}
Color4 color;
color[3] = MAX_NOF_COLOR_LEVELS;
int index = 0;
while (true) {
Body* body = model->getBody(index++);
if (body==NULL) break;
char* color_buffer = NULL;
int id = body->Id();
readIdVariable(interp, "ObjectTable", id, "clr", color_buffer);
if ( color_buffer == NULL ) continue;
// Skip leading Tcl # in color hex-values
char* tmp = color_buffer;
tmp++;
model->rgbHex2Color(6, tmp, color);
body->setColor(color);
delete[] color_buffer;
}
model->refreshRenderer();
return TCL_OK;
}
// Function reads and updates body data when OK-button
// is pressed in Tk/GUI edit bodies dialog.
int
UserInterface_TCL::from_tk_ReadBodyData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadBodyData: Command not legal. No model exists!");
return TCL_OK;
}
from_tk_ReadBodyColors(clientData, interp, argc, argv);
from_tk_ReadBodyNames(clientData, interp, argc, argv);
to_tk_WriteBodyLayerData(interp, *model);
to_tk_WriteBodyData(interp, *model);
return TCL_OK;
}
// Function reads body id to be deleted
int
UserInterface_TCL::from_tk_ReadBodyDeleteData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadBodyDeleteData: Command not legal. No model exists!");
return TCL_OK;
}
int body_id = NO_INDEX;
readVariable(interp, "BodyProperty", "objectId", body_id);
Body* body = model->getBodyById(body_id);
if ( body != NULL ) {
model->removeBody(body);
to_tk_WriteBodyLayerData(interp, *model);
to_tk_WriteBodyData(interp, *model);
to_tk_WriteBoundaryData(interp, *model);
to_tk_WriteElementGroupData(theInterp, *model);
}
return TCL_OK;
}
// Read body display list (from the BodyDisplay panel).
int
UserInterface_TCL::from_tk_ReadBodyDisplayData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadSelectedBodies: Command not legal. No model exists!");
return TCL_OK;
}
int index = 0;
while (true) {
Body* body = model->getBody(index++);
if (body==NULL) break;
int id = body->Id();
int display = 1;
readIdVariable(interp, "ObjectTable", id, "dspl", display);
if (display == 0) {
body->setDrawMode(DM_HIDDEN);
} else {
body->setDrawMode(DM_NORMAL);
}
}
model->refreshRenderer();
return TCL_OK;
}
// Function reads and updates body-force data when OK-button
// is pressed in Tk/GUI body-forces dialog.
int
UserInterface_TCL::from_tk_ReadBodyForceData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadBodyForceData: Command not legal. No model exists!");
return TCL_OK;
}
setParameterData(model, ECIF_BODY_FORCE, interp, "BodyForce");
//----ObjectTable size
int size;
int* ids = NULL;
readVariable(interp, "ObjectTable", "ids", size, ids);
for (int i = 0; i < size; i++) {
int id = ids[i];
char* tmp;
readIdVariable(interp, "ObjectTable", id, "tp", tmp);
//--Skip if not a body target group
if ( 0 != strcmp(tmp, "B") )
continue;
int pid;
readIdVariable(interp, "ObjectTable", id, "bf", pid);
//--Update body target group's body force-info
Body* bd = model->getBodyById(id);
if ( bd != NULL ) {
bd->setBodyForceId(pid);
}
}
model->updateParametersApplyCounts(ECIF_BODY_FORCE);
to_tk_WriteStatusBodyForces(interp, *model);
delete[] ids;
return TCL_OK;
}
// Function reads and updates body-parameter data when OK-button
// is pressed in Tk/GUI body-parameter dialog.
int
UserInterface_TCL::from_tk_ReadBodyParameterData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadBodyParameterData: Command not legal. No model exists!");
return TCL_OK;
}
setParameterData(model, ECIF_BODY_PARAMETER, interp, "BodyParameter");
//----ObjectTable size
int size;
char** ids = NULL;
readVariable(interp, "ObjectTable", "ids", size, ids);
for (int i = 0; i < size; i++) {
char* oid = ids[i];
int id = atoi(oid);
char* tmp;
readIdVariable(interp, "ObjectTable", oid, "tp", tmp);
//--Skip if not a body
if ( 0 != strcmp(tmp, "B") )
continue;
int pid;
readIdVariable(interp, "ObjectTable", oid, "bodyp", pid);
//--Update body's parameter-info
Body* body = model->getBodyById(id);
if ( body != NULL ) {
body->setBodyParameterId(pid);
}
}
for (int j = 0; j < size; j++) {
delete[] ids[j];
}
delete[] ids;
return TCL_OK;
}
// Function reads and updates body-names data when OK-button
// is pressed in Tk/GUI body-names dialog.
int
UserInterface_TCL::from_tk_ReadBodyNames(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadBodyNames: Command not legal. No model exists!");
return TCL_OK;
}
int index = 0;
while (true) {
Body* body = model->getBody(index++);
if (body==NULL) break;
char* name = NULL;
int id = body->Id();
readIdVariable(interp, "ObjectTable", id, "nm", name);
body->setName(name);
// Update also layer name if it is an implicit (logical) layer
BodyLayer* bl = (BodyLayer*)body->getLayer(0);
if ( bl != NULL && bl->getLayerType() == IMPLICIT_LAYER ) {
bl->setName(name);
writeIdVariable(interp, "ObjectTable", bl->Id(), "nm", name);
}
delete[] name;
}
return TCL_OK;
}
// Function updates mesh boundary vertices after boundaries panel split/combine
// operation when OK-button is pressed in Edit/Boundaries panel.
int
UserInterface_TCL::from_tk_ReadBoundariesData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadBoundariesData: Command not legal. No model exists!");
return TCL_OK;
}
model->setFlagValue(GEOMETRY_EDITED, GEOMETRY_EDITED_BOUNDARIES, true);
if ( !model->getFlagValue(GEOMETRY_TYPE_CAD) ) {
model->updateBoundaries();
return TCL_OK;
}
// Read discretation settings;
int cnt = 0;
linDeltaType* types = NULL;
double* valuesU = NULL;
int* useFixed = NULL;
bool* useFixedN = NULL;
int nof_vals;
int nof_fns;
char* type_str = NULL;
int index = 0;
while (true) {
BodyElement* be = model->getBoundary(index++);
if (be==NULL) break;
int id = be->Id();
readIdVariable(interp, "ObjectTable", id, "nofCmp", cnt);
readIdVariable(interp, "ObjectTable", id, "dscTp", type_str);
readIdVariable(interp, "ObjectTable", id, "dscU", nof_vals, valuesU);
readIdVariable(interp, "ObjectTable", id, "useFN", nof_fns, useFixed);
int nof_types = 0;
if ( type_str != NULL ) {
nof_types = strlen(type_str);
}
// Recode type characters
//
if ( nof_types > 0 ) {
types = new linDeltaType[nof_types];
for (int i = 0; i < nof_types; i++) {
if ( type_str[i] == 'H' ) {
types[i] = LIN_DELTA_H;
} else if ( type_str[i] == 'N' ) {
types[i] = LIN_DELTA_N;
} else if ( type_str[i] == 'U' ) {
types[i] = LIN_DELTA_U;
} else {
types[i] = LIN_DELTA_NONE;
}
}
}
// If data is technically correct, apply it
//
if ( (nof_vals == 0 || nof_vals == cnt) &&
(nof_types == 0 || nof_types == cnt) &&
nof_fns == cnt
) {
useFixedN = new bool[nof_fns];
for (int i = 0; i < nof_fns; i++) {
useFixedN[i] = (bool)useFixed[i];
}
be->setDiscretizationData(cnt, types, valuesU, NULL, useFixedN);
}
// Delete work arreis for next call
//
delete[] types; types = NULL;
delete[] valuesU; valuesU = NULL;
delete[] useFixedN; useFixedN = NULL;
delete[] type_str; type_str = NULL;
delete[] useFixed; useFixed = NULL;
}
model->updateCadGeometry();
return TCL_OK;
}
// Function reads and updates boundary conditions when OK-button
// is pressed in Tk/GUI boundary-condition dialog.
int
UserInterface_TCL::from_tk_ReadBoundaryConditionData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadBoundaryConditionData: Command not legal. No model exists!");
return TCL_OK;
}
//---Reset all boundary condition attachments
model->resetBoundaryConditions();
//---Boundary condition data
setParameterData(model, ECIF_BOUNDARY_CONDITION, interp, "BoundaryCondition");
MultiIdTable bcTable;
//---Update boundary element's condition ids
int size;
int* ids = NULL;
readVariable(interp, "ObjectTable", "ids", size, ids);
for (int i = 0; i < size; i++) {
char* tmp;
int id = ids[i];
int pid;
readIdVariable(interp, "ObjectTable", id, "bc", pid);
readIdVariable(interp, "ObjectTable", id, "tp", tmp);
// Read bc from boundary groups
if ( 0 == strcmp(tmp, "FG") ||
0 == strcmp(tmp, "EG") ||
0 == strcmp(tmp, "VG")
) {
bcTable.insert( std::pair<int const, int>(pid, id));
} else {
continue;
}
}
setBoundaryConditions(interp, model, bcTable);
// Update parameter apply count
model->updateParametersApplyCounts(ECIF_BOUNDARY_CONDITION);
// Update model's DiffuseGray radiation info
model->checkDiffuseGrayRadiation();
to_tk_WriteStatusBoundaryConditions(interp, *model);
delete[] ids;
return TCL_OK;
}
// Read boundary display list
int
UserInterface_TCL::from_tk_ReadBoundaryDisplayData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadBoundaryDisplayData: Command not legal. No model exists!");
return TCL_OK;
}
int index = 0;
while (true) {
BodyElement* be = model->getBoundary(index++);
if (be==NULL) break;
int id = be->Id();
int display = 1;
readIdVariable(interp, "ObjectTable", id, "dspl", display);
if (display == 0) {
be->setDrawMode(DM_HIDDEN);
} else {
be->setDrawMode(DM_NORMAL);
}
}
model->refreshRenderer();
return TCL_OK;
}
// Function reads and updates boundary name data when OK-button
// is pressed in Tk/GUI edit boundaries dialog.
int
UserInterface_TCL::from_tk_ReadBoundaryNames(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadBoundaryNames: Command not legal. No model exists!");
return TCL_OK;
}
int index = 0;
while (true) {
BodyElement* be = model->getBoundary(index++);
if (be==NULL) break;
char* name = NULL;
readIdVariable(interp, "ObjectTable", be->Id(), "nm", name);
be->setName(name);
// Update also group name if it is an implicit (logical) group
BodyElementGroup* beg = (BodyElementGroup*)be->getElementGroup();
if ( beg != NULL && beg->getGroupType() == IMPLICIT_GROUP ) {
beg->setName(name);
writeIdVariable(interp, "ObjectTable", beg->Id(), "nm", name);
}
delete[] name;
}
return TCL_OK;
}
// Function reads and updates boundary parameters when OK-button
// is pressed in Tk/GUI boundary-parameter dialog.
int
UserInterface_TCL::from_tk_ReadBoundaryParameterData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadBoundaryParameterData: Command not legal. No model exists!");
return TCL_OK;
}
//---Boundary parameter data
setParameterData(model, ECIF_BOUNDARY_PARAMETER, interp, "BoundaryParameter");
//---Update boundary element's boundary parameter id
int size;
char** ids = NULL;
readVariable(interp, "ObjectTable", "ids", size, ids);
for (int i = 0; i < size; i++) {
char* tmp;
char* oid = ids[i];
int id = atoi(oid);
readIdVariable(interp, "ObjectTable", id, "tp", tmp);
if ( 0 != strcmp(tmp, "F") &&
0 != strcmp(tmp, "E") &&
0 != strcmp(tmp, "V")
) {
continue;
}
int pid;
readIdVariable(interp, "ObjectTable", id, "bndrp", pid);
//--Update body's parameter-info
BodyElement* be = model->getBodyElementById(id);
if ( be != NULL ){
be->setBoundaryParameterId(pid);
}
}
for (int j = 0; j < size; j++) {
delete[] ids[j];
}
delete[] ids;
return TCL_OK;
}
// Function reads calulator solvers data from Tk.
int
UserInterface_TCL::from_tk_ReadCalculatorData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadCalculatorData: Command not legal. No model exists!");
return TCL_OK;
}
setParameterData(model, ECIF_CALCULATOR, interp, "Calculator");
return TCL_OK;
}
// Activate a color file read via Tk.
int
UserInterface_TCL::from_tk_ReadColorFile(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
//---Get tcl-data
char* fname = getCommandArguments(interp);
Model::readColorFile(fname);
return TCL_OK;
}
// Function reads physical constants data from Tk.
int
UserInterface_TCL::from_tk_ReadConstantData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadConstantData: Command not legal. No model exists!");
return TCL_OK;
}
setParameterData(model, ECIF_CONSTANT, interp, "Constant");
return TCL_OK;
}
// Function reads and updates equation data when OK-button
// is pressed in Tk/GUI equations dialog.
int
UserInterface_TCL::from_tk_ReadConvertedEquationData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadEquationData: Command not legal. No model exists!");
return TCL_OK;
}
setParameterData(model, ECIF_EQUATION, interp, "Equation");
model->updateParametersApplyCounts(ECIF_EQUATION);
return TCL_OK;
}
// Function reads coordinate system definition data from Tk.
int
UserInterface_TCL::from_tk_ReadCoordinateData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadCoordinateData: Command not legal. No model exists!");
return TCL_OK;
}
setParameterData(model, ECIF_COORDINATE, interp, "Coordinate");
return TCL_OK;
}
// Function reads datafile (result and input files) definition data from Tk.
int
UserInterface_TCL::from_tk_ReadDatafileData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadDatafileData: Command not legal. No model exists!");
return TCL_OK;
}
setParameterData(model, ECIF_DATAFILE, interp, "Datafile");
return TCL_OK;
}
// Function reads ids for deleted parameters when Ok-button is pressed in a panel
// where parameters were deleted.
int
UserInterface_TCL::from_tk_ReadDeletedParamIds(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
//---Get data-string as a "structured" list from Tcl.
//--First part of the data is panelt-type
//--Second part is the list of param-ids which were deleted
char* deletedList = getCommandArguments(interp);
//---Break this list into an array of strings, where the strings are
//the two parts mentioned above.
int all_argc;
char** all_argv;
int code = Tcl_SplitList(interp, deletedList, &all_argc, (const char ***) &all_argv);
if (code != TCL_OK)
return TCL_ERROR;
//---Panel type
ecif_parameterType param_type;
char* pt = all_argv[0];
if (0 == strcmp("IC", pt))
param_type = ECIF_INITIAL_CONDITION;
else if (0 == strcmp("BC", pt))
param_type = ECIF_BOUNDARY_CONDITION;
else if (0 == strcmp("EQ", pt))
param_type = ECIF_EQUATION;
else if (0 == strcmp("BF", pt))
param_type = ECIF_BODY_FORCE;
else if (0 == strcmp("MP", pt))
param_type = ECIF_MATERIAL;
else if (0 == strcmp("GR", pt))
param_type = ECIF_GRID_PARAMETER;
else if (0 == strcmp("GH", pt))
param_type = ECIF_GRID_H;
//---Param ids
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadDeletedParamIds: Command not legal. No model exists!");
return TCL_OK;
}
int ids_argc;
char** ids_argv;
code = Tcl_SplitList(interp, all_argv[1], &ids_argc, (const char ***) &ids_argv);
if (code != TCL_OK)
return TCL_ERROR;
for (int i=0; i<ids_argc; i++) {
istrstream in(ids_argv[i]);
int param_id;
in >> param_id;
model->deleteParameter(param_type, param_id);
}
// Tcl_SplitList allocates dynamic memory for its argument.
// We should free this memory, but the following call causes an error !
// free((char*) largv);
return TCL_OK;
}
// Function reads and updates equation data when OK-button
// is pressed in Tk/GUI equations dialog.
int
UserInterface_TCL::from_tk_ReadEquationData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadEquationData: Command not legal. No model exists!");
return TCL_OK;
}
setParameterData(model, ECIF_EQUATION, interp, "Equation");
//---ObjectTable size
int size;
int* ids = NULL;
readVariable(interp, "ObjectTable", "ids", size, ids);
for (int i = 0; i < size; i++) {
int id = ids[i];
char* tmp;
readIdVariable(interp, "ObjectTable", id, "tp", tmp);
//--Skip if not a body
if ( 0 != strcmp(tmp, "B") )
continue;
int pid;
//--Read variable values
readIdVariable(interp, "ObjectTable", id, "eq", pid);
//--Update body's equation-info
Body* bd = model->getBodyById(id);
if (bd != NULL ) {
bd->setEquationId(pid);
}
}
model->updateParametersApplyCounts(ECIF_EQUATION);
to_tk_WriteStatusEquations(interp, *model);
to_tk_WriteStatusBodyForces(interp, *model);
to_tk_WriteStatusBoundaryConditions(interp, *model);
to_tk_WriteStatusInitialConditions(interp, *model);
to_tk_WriteStatusMaterials(interp, *model);
to_tk_WriteStatusTimesteps(interp, *model);
to_tk_WriteStatusMeshes(interp, *model);
return TCL_OK;
}
// Function reads equation variables (like Advection Diffusion variables) definition data from Tk.
int
UserInterface_TCL::from_tk_ReadEquationVariablesData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadEquationVariablesData: Command not legal. No model exists!");
return TCL_OK;
}
setParameterData(model, ECIF_EQUATION_VARIABLE, interp, "EquationVariable");
return TCL_OK;
}
// Function reads and updates grid-param data when OK-button
// is pressed in Tk/GUI grid-control dialog.
int
UserInterface_TCL::from_tk_ReadGridHData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadGridHData: Command not legal. No model exists!");
return TCL_OK;
}
//----GridH data
setParameterData(model, ECIF_GRID_H, interp, "GridH");
//----GridH ids
int size = 0;
char** ids = NULL;
readVariable(interp, "ObjectTable", "ids", size, ids);
for (int i = 0; i < size; i++) {
char* oid = ids[i];
int id = atoi(oid);
char* tmp;
readIdVariable(interp, "ObjectTable", oid, "tp", tmp);
//--Skip if not a bodyelement
if ( 0 != strcmp(tmp, "F") &&
0 != strcmp(tmp, "E") &&
0 != strcmp(tmp, "V")
) {
continue;
}
// Read variable values
int nof_gids = 0;
int* gids;
int* mids;
int pid, bd_lid, bid;
readIdVariable(interp, "ObjectTable", oid, "ghIds", nof_gids, gids); // grid paramter ids
readIdVariable(interp, "ObjectTable", oid, "ghMshIndcs", nof_gids, mids); // mesh indices
BodyElement* be = model->getBodyElementById(id);
if ( be != NULL ) {
be->setGridHData(nof_gids, gids, mids);
}
}
return TCL_OK;
}
// Function reads and updates grid-param data when OK-button
// is pressed in Tk/GUI grid-param dialog.
int
UserInterface_TCL::from_tk_ReadGridParameterData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadGridParameterData: Command not legal. No model exists!");
return TCL_OK;
}
//----GridParameter data
setParameterData(model, ECIF_GRID_PARAMETER, interp, "GridParameter");
//----Body ids for GridParameters
int size = 0;
//int* ids = NULL;
int* ids = NULL;
readVariable(interp, "ObjectTable", "ids", size, ids);
for (int i = 0; i < size; i++) {
int id = ids[i];
char* tmp;
readIdVariable(interp, "ObjectTable", id, "tp", tmp);
//--Skip if not a body layer
//
if ( 0 != strcmp(tmp, "BL") ) continue;
// Read variable values
int nof_gids, nof_mids, nof_xids;
int* gids = NULL; // Grid parameter ids
int* mids = NULL; // Grid mesh indices
int* xids = NULL; // Exclude mesh indices
readIdVariable(interp, "ObjectTable", id, "grIds", nof_gids, gids); // grid paramter ids
readIdVariable(interp, "ObjectTable", id, "grMshIndcs", nof_mids, mids); // mesh indices
readIdVariable(interp, "ObjectTable", id, "excldMshIndcs", nof_xids, xids); // excluded mesh indices
BodyLayer* lr = model->getBodyLayerById(id);
if ( lr != NULL ){
lr->setGridParameterData(nof_gids, gids, mids);
lr->setExcludedMeshData(nof_xids, xids);
}
delete[] gids;
delete[] mids;
delete[] xids;
}
//to_tk_WriteStatusMeshParameter(interp, *model);
delete[] ids;
return TCL_OK;
}
// Function reads and updates body initial condition when OK-button
// is pressed in Tk/GUI init-condition dialog.
int
UserInterface_TCL::from_tk_ReadInitialConditionData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadInitialConditionData: Command not legal. No model exists!");
return TCL_OK;
}
setParameterData(model, ECIF_INITIAL_CONDITION, interp, "InitialCondition");
// ObjectTable data
int size;
int* ids = NULL;
readVariable(interp, "ObjectTable", "ids", size, ids);
for (int i = 0; i < size; i++) {
int id = ids[i];
char* tmp;
readIdVariable(interp, "ObjectTable", id, "tp", tmp);
//--Skip if not a body
if ( 0 != strcmp(tmp, "B") )
continue;
// Read variable values
int pid;
readIdVariable(interp, "ObjectTable", id, "ic", pid);
//--Update body's condition-info
Body* bd = model->getBodyById(id);
if ( bd != NULL ) {
bd->setInitialConditionId(pid);
}
}
model->updateParametersApplyCounts(ECIF_INITIAL_CONDITION);
to_tk_WriteStatusInitialConditions(interp, *model);
return TCL_OK;
}
// Activate a matc variable table file read via Tk.
// NOTE: No model is needed
int
UserInterface_TCL::from_tk_ReadMatcFile(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
//---Get tcl-data
char* fname = getCommandArguments(interp);
Model::readMatcFile(fname, NULL, false);
return TCL_OK;
}
// Function reads and updates body material parameter data when OK-button
// is pressed in Tk/GUI material-parameters dialog.
int
UserInterface_TCL::from_tk_ReadMaterialData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadMaterialData: Command not legal. No model exists!");
return TCL_OK;
}
setParameterData(model, ECIF_MATERIAL, interp, "Material");
//--ObjectTable size
int size;
int* ids = NULL;
readVariable(interp, "ObjectTable", "ids", size, ids);
for (int i = 0; i < size; i++) {
int id = ids[i];
char* tmp;
readIdVariable(interp, "ObjectTable", id, "tp", tmp);
//--Skip if not a body target group
if ( 0 != strcmp(tmp, "B") )
continue;
// Read variable values
int pid;
readIdVariable(interp, "ObjectTable", id, "mt", pid);
//--Update body's material-info
Body* bd = model->getBodyById(id);
if ( bd != NULL ) {
bd->setMaterialId(pid);
}
}
model->updateParametersApplyCounts(ECIF_MATERIAL);
to_tk_WriteStatusMaterials(interp, *model);
return TCL_OK;
}
// Function reads model created info from Tk.
int
UserInterface_TCL::from_tk_ReadModelFileCreated(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadModelFileCreated: Command not legal. No model exists!");
return TCL_OK;
}
//---Get tcl-data
char* data = getCommandArguments(interp);
//---Model file created info
model->setModelFileCreated(data);
return TCL_OK;
}
// Function reads model modified info from Tk.
int
UserInterface_TCL::from_tk_ReadModelFileModified(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadModelFileModified: Command not legal. No model exists!");
return TCL_OK;
}
//---Get tcl-data
char* data = getCommandArguments(interp);
//---Model file modified info
model->setModelFileModified(data);
return TCL_OK;
}
// Function reads model outfile save timestamp from Tk.
int
UserInterface_TCL::from_tk_ReadModelFileTime(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadModelFileTime: Command not legal. No model exists!");
return TCL_OK;
}
//---Get tcl-data
char* data = getCommandArguments(interp);
//---Model outfile timestamp
model->setModelFileTime(data);
return TCL_OK;
}
// Function reads model modified info from Tk.
int
UserInterface_TCL::from_tk_ReadModelHasUserDefinitions(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadModelHasUserDefinitions: Command not legal. No model exists!");
return TCL_OK;
}
//---Get tcl-data
bool has_defs = (bool) atoi(getCommandArguments(interp));
//---Model file modified info
model->setModelHasUserDefinitions(has_defs);
return TCL_OK;
}
// Function reads and updates model level meshH when ok is pressed
// is pressed in Tk/GUI meshdefine dialog.
int
UserInterface_TCL::from_tk_ReadMeshDefineData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
int i;
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadModelMeshHData: Command not legal. No model exists!");
return TCL_OK;
}
// Read mesh names and control
// ===========================
int nof_meshes = 0;
char** mesh_names = NULL;
double* mesh_hs = NULL;
double* mesh_fs = NULL;
readVariable(interp, "Model", "meshNames", nof_meshes, mesh_names);
readVariable(interp, "Model", "meshHs", nof_meshes, mesh_hs);
readVariable(interp, "Model", "meshFs", nof_meshes, mesh_fs);
model->setMeshNames(nof_meshes, mesh_names);
model->setMeshHs(nof_meshes, mesh_hs);
model->setMeshFs(nof_meshes, mesh_fs);
for (i = 0; i < nof_meshes; i++) {
delete[] mesh_names[i];
}
delete[] mesh_names;
delete[] mesh_hs;
delete[] mesh_fs;
// Read background mesh file info
// ==============================
//
// NOTE: Bg-files info is stored (in indexed form) in
// MeshDefine-array (Model-array contains equivalen "sparse" lists
// (except indices lists, which is always non-sparse)
int nof_files = 0;
int* mesh_bg_file_indices = NULL;
char** mesh_bg_files = NULL;
int* mesh_bg_act = NULL;
int* mesh_bg_ctrl = NULL;
readVariable(interp, "Model", "meshBgMeshFileIndices", nof_files, mesh_bg_file_indices);
readVariable(interp, "MeshDefine", "meshBgMeshFiles", nof_files, mesh_bg_files);
readVariable(interp, "MeshDefine", "meshBgMeshActives", nof_files, mesh_bg_act);
readVariable(interp, "MeshDefine", "meshBgMeshControls", nof_files, mesh_bg_ctrl);
if ( mesh_bg_file_indices == NULL ) {
nof_files = 0;
}
model->setMeshBgMeshFileIndices(nof_files, mesh_bg_file_indices);
model->setMeshBgMeshFiles(nof_files, mesh_bg_files);
model->setMeshBgMeshActives(nof_files, mesh_bg_act);
model->setMeshBgMeshControls(nof_files, mesh_bg_ctrl);
for (i = 0; i < nof_files; i++) {
delete[] mesh_bg_files[i];
}
delete[] mesh_bg_file_indices;
delete[] mesh_bg_files;
delete[] mesh_bg_act;
delete[] mesh_bg_ctrl;
//--Set current mesh info
int mesh_index = 0;
readVariable(interp, "Model", "currentMeshIndex", mesh_index);
model->setCurrentMeshIndex(mesh_index);
char* dir = NULL;
char* dir_abs = NULL;
//--Mesh directory
readVariable(interp, "ModelProperty", "CURRENT_MESH_DIRECTORY", dir);
readVariable(interp, "ModelProperty", "CURRENT_MESH_DIRECTORY,absolute", dir_abs);
model->setModelMeshDirectory(dir);
model->setModelMeshDirectoryAbs(dir_abs);
delete[] dir;
delete[] dir_abs;
return TCL_OK;
}
// Function reads user defined model parameters data from Tk.
int
UserInterface_TCL::from_tk_ReadModelParameterData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadModelParameterData: Command not legal. No model exists!");
return TCL_OK;
}
setParameterData(model, ECIF_MODEL_PARAMETER, interp, "ModelParameter");
return TCL_OK;
}
// Function reads and updates model properties (paths etc.)
int
UserInterface_TCL::from_tk_ReadModelPropertyData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadModelPropertyData: Command not legal. No model exists!");
return TCL_OK;
}
// Init reference buffers and flags
char* name1 = NULL; // Model name
char* name2 = NULL; // Problem name
char* desc1 = NULL;
char* desc2 = NULL;
char* dir1 = NULL; // Model Directory
char* dir2 = NULL; // Include Path
char* dir3 = NULL; // Results Directory
char* dir4 = NULL; // Log Directory
char* dir1_abs = NULL;
char* dir2_abs = NULL;
char* dir3_abs = NULL;
char* dir4_abs = NULL;
int dir2_save = 0;
int dir3_save = 0;
int dir4_save = 0;
//--Names
readVariable(interp, "ModelProperty", "MODEL_NAME", name1);
readVariable(interp, "ModelProperty", "PROBLEM_NAME", name2);
model->setModelNames(name1, name2);
//--Model and problem descriptions
readVariable(interp, "ModelProperty", "MODEL_DESCRIPTION", desc1);
readVariable(interp, "ModelProperty", "PROBLEM_DESCRIPTION", desc2);
model->setModelDescriptions(desc1, desc2);
//--Model directory, Mesh directory, Include path, results directory and temporary files directory info
readVariable(interp, "ModelProperty", "MODEL_DIRECTORY", dir1);
readVariable(interp, "ModelProperty", "MODEL_DIRECTORY,absolute", dir1_abs);
readVariable(interp, "ModelProperty", "INCLUDE_PATH", dir2);
readVariable(interp, "ModelProperty", "INCLUDE_PATH,absolute", dir2_abs);
readVariable(interp, "ModelProperty", "INCLUDE_PATH,model,save", dir2_save);
readVariable(interp, "ModelProperty", "RESULTS_DIRECTORY", dir3);
readVariable(interp, "ModelProperty", "RESULTS_DIRECTORY,absolute", dir3_abs);
readVariable(interp, "ModelProperty", "RESULTS_DIRECTORY,model,save", dir3_save);
readVariable(interp, "ModelProperty", "LOG_DIRECTORY", dir4);
readVariable(interp, "ModelProperty", "LOG_DIRECTORY,absolute", dir4_abs);
readVariable(interp, "ModelProperty", "LOG_DIRECTORY,model,save", dir4_save);
model->setModelFileDirectories(dir1, dir2, dir3, dir4);
model->setModelFileDirectoriesAbs(dir1_abs, dir2_abs, dir3_abs, dir4_abs);
model->setModelFileDirectoriesSave(dir2_save, dir3_save, dir4_save);
//--Delete buffers
delete[] name1; delete[] name2;
delete[] desc1; delete[] desc2;
delete[] dir1; delete[] dir2; delete[] dir3; delete[] dir4;
delete[] dir1_abs; delete[] dir2_abs; delete[] dir3_abs; delete[] dir4_abs;
return TCL_OK;
}
// Function reads processor (for parallel processing) settings from Tk.
int
UserInterface_TCL::from_tk_ReadProcessorData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
//---Get tcl-data
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadProcessorData: Command not legal. No model exists!");
return TCL_OK;
}
ParallelInfo pi;
int all_argc;
char **all_argv;
char* allData = getCommandArguments(interp);
int code = Tcl_SplitList(interp, allData, &all_argc, (const char ***) &all_argv);
if (code != TCL_OK)
return TCL_ERROR;
int index = 0;
pi.nofProcessors = atoi(all_argv[index++]);
//
model->setParallelInfo(pi);
return TCL_OK;
}
// Function set selection method in the renderer
int
UserInterface_TCL::from_tk_ReadSelectionTolerances(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Renderer* renderer = theControlCenter->getRenderer();
//---Get tcl-data
char* data = getCommandArguments(interp);
// Read toleracnes from gui, check values and
// store them in the model and update gui
char* normal_tol = (char *) Tcl_GetVar2(interp, "Info", "normalTolerance", TCL_GLOBAL_ONLY);
char* distance_tol = (char *) Tcl_GetVar2(interp, "Info", "distanceTolerance", TCL_GLOBAL_ONLY);
// Normal tolerance is degrees (0-45)
double normal_tolerance = atof(normal_tol);
if (normal_tolerance < 0)
normal_tolerance *= -1;
if (normal_tolerance > MAX_NORMAL_TOLERANCE)
normal_tolerance = MAX_NORMAL_TOLERANCE;
// Distance tolerance is relative (0-1)
double distance_tolerance = atof(distance_tol);
if (distance_tolerance < 0)
distance_tolerance *= -1;
if (distance_tolerance > MAX_DISTANCE_TOLERANCE)
distance_tolerance = MAX_DISTANCE_TOLERANCE;
strstream normal_strm;
normal_strm << normal_tolerance << ends;
strstream distance_strm;
distance_strm << distance_tolerance << ends;
NORMAL_TOLERANCE = normal_tolerance;
DISTANCE_TOLERANCE = distance_tolerance;
Tcl_SetVar2(interp, "Info", "normalTolerance", normal_strm.str(), TCL_GLOBAL_ONLY);
Tcl_SetVar2(interp, "Info", "distanceTolerance", distance_strm.str(), TCL_GLOBAL_ONLY);
return TCL_OK;
}
// Function reads user defined model parameters data from Tk.
int
UserInterface_TCL::from_tk_ReadSimulationParameterData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadSimulationParameterData: Command not legal. No model exists!");
return TCL_OK;
}
setParameterData(model, ECIF_SIMULATION_PARAMETER, interp, "SimulationParameter");
return TCL_OK;
}
// Function reads solver parameter data from Tk.
int
UserInterface_TCL::from_tk_ReadSolverData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadSolverData: Command not legal. No model exists!");
return TCL_OK;
}
setParameterData(model, ECIF_SOLVER, interp, "Solver");
return TCL_OK;
}
// Function reads solverControl parameter data from Tk.
int
UserInterface_TCL::from_tk_ReadSolverControlData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadSolverControlData: Command not legal. No model exists!");
return TCL_OK;
}
setParameterData(model, ECIF_SOLVER_CONTROL, interp, "SolverControl");
return TCL_OK;
}
// Function reads timestep parameter settings from Tk.
int
UserInterface_TCL::from_tk_ReadTimestepData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadTimestepData: Command not legal. No model exists!");
return TCL_OK;
}
setParameterData(model, ECIF_TIMESTEP, interp, "Timestep");
to_tk_WriteStatusTimesteps(interp, *model);
// NOTE: InitialCOndition status field depends also
// on Timestep-data (simulation type Steady State or Transient)
to_tk_WriteStatusInitialConditions(interp, *model);
return TCL_OK;
}
// Function reads model data related timestamp from Tk.
int
UserInterface_TCL::from_tk_ReadTimestamp(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadTimestamp: Command not legal. No model exists!");
return TCL_OK;
}
//---Get tcl-data
char* data = getCommandArguments(interp);
int ts_argc;
char** ts_argv;
int code = Tcl_SplitList(interp, data, &ts_argc, (const char ***) &ts_argv);
if (code != TCL_OK)
return TCL_ERROR;
//---Set timestamp
model->setTimestamp(ts_argv[0], ts_argv[1]);
return TCL_OK;
}
// Function reads user settings parameter values from Tk.
int
UserInterface_TCL::from_tk_ReadUserSettingsData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadUserSettingsData: Command not legal. No model exists!");
return TCL_OK;
}
setParameterData(model, ECIF_USER_SETTING, interp, "UserSetting");
return TCL_OK;
}
// Read vertex display list
int
UserInterface_TCL::from_tk_ReadVertexDisplayData(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ReadVertexDisplayData: Command not legal. No model exists!");
return TCL_OK;
}
int index = 0;
while (true) {
BodyElement* be = model->getVertex(index++);
if (be==NULL) break;
int id = be->Id();
int display = 1;
readIdVariable(interp, "ObjectTable", id, "dspl", display);
if (display == 0) {
be->setDrawMode(DM_HIDDEN);
} else {
be->setDrawMode(DM_NORMAL);
}
}
model->refreshRenderer();
return TCL_OK;
}
// Function for the user settings file reading
int
UserInterface_TCL::from_tk_ReadUserSettingFiles(ClientData clientData, Tcl_Interp* interp,
int argc, char* argv[])
{
// NOTE: These are needed for emf_readDataCB callback function
//
struct emf_ObjectData_X my_ObjectData;
emf_ObjectData = &my_ObjectData;
char* files = (char *) Tcl_GetVar2(interp, "Info", "userSettingFiles", glob_flag);
//---Break this list into an array of strings (paths)
int all_argc;
char** all_argv;
int code = Tcl_SplitList(interp, files, &all_argc, (const char ***) &all_argv);
if (code != TCL_OK) {
return TCL_ERROR;
}
// Read files
for (int i = 0; i < all_argc; i++) {
//--Set callback function
emf_readDataCB = readUserSettingsFileCallBack;
//--Start parser
int rc = emf_readData(all_argv[i], (void**)&interp, 0, NULL, 1);
strstream strm;
strm << "Reading settings file: " << all_argv[i] << ends;
writeVariable(interp, "Info", "userSettingFilesReadInfo", strm.str(), false);
}
return TCL_OK;
}
// Function removove Cad geometry from the model
int
UserInterface_TCL::from_tk_RemoveCadGeometry(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "RemoveCadGeometry: Command not legal. No model exists!");
return TCL_OK;
}
model->removeCadGeometry();
return TCL_OK;
}
// Function draws model when option is selected from menu.
int
UserInterface_TCL::from_tk_RendererDisplayModel(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
theControlCenter->displayModel();
return TCL_OK;
}
// Function rotates model in the display.
int
UserInterface_TCL::from_tk_RendererRotateModel(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Renderer* renderer = theControlCenter->getRenderer();
if (renderer == NULL)
return TCL_OK;
int all_argc;
char **all_argv;
char* allData = getCommandArguments(interp);
int code = Tcl_SplitList(interp, allData, &all_argc, (const char ***) &all_argv);
if (code != TCL_OK)
return TCL_ERROR;
int axis = atoi(all_argv[0]);
short direction = atoi(all_argv[1]);
renderer->rotate(axis, direction);
return TCL_OK;
}
// Function resets model display.
int
UserInterface_TCL::from_tk_RendererResetModel(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Renderer* renderer = theControlCenter->getRenderer();
if (renderer == NULL)
return TCL_OK;
renderer->reset();
return TCL_OK;
}
// Function scales model in the display.
int
UserInterface_TCL::from_tk_RendererScaleModel(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Renderer* renderer = theControlCenter->getRenderer();
if (renderer == NULL)
return TCL_OK;
int all_argc;
char **all_argv;
char* allData = getCommandArguments(interp);
int code = Tcl_SplitList(interp, allData, &all_argc, (const char ***) &all_argv);
if (code != TCL_OK)
return TCL_ERROR;
short direction = atoi(all_argv[0]);
renderer->scale(direction);
return TCL_OK;
}
// Set boundary edit mode
int
UserInterface_TCL::from_tk_RendererSetEditBoundaries(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Renderer* renderer = theControlCenter->getRenderer();
if (renderer == NULL)
return TCL_OK;
bool in_edit_mode = bool(atoi(getCommandArguments(interp)));
renderer->setEditBoundaries(in_edit_mode);
return TCL_OK;
}
// Set rotation priorities in the renderer
int
UserInterface_TCL::from_tk_RendererSetRotatePriorities(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Renderer* renderer = theControlCenter->getRenderer();
if (renderer == NULL)
return TCL_OK;
int all_argc;
char **all_argv;
char* allData = getCommandArguments(interp);
int code = Tcl_SplitList(interp, allData, &all_argc,(const char ***) &all_argv);
if (code != TCL_OK)
return TCL_ERROR;
int x = atoi(all_argv[0]);
int y = atoi(all_argv[1]);
int z = atoi(all_argv[2]);
renderer->setRotatePriorities(x, y, z);
return TCL_OK;
}
// Function tranlates model in the display.
int
UserInterface_TCL::from_tk_RendererTranslateModel(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Renderer* renderer = theControlCenter->getRenderer();
if (renderer == NULL)
return TCL_OK;
int all_argc;
char **all_argv;
char* allData = getCommandArguments(interp);
int code = Tcl_SplitList(interp, allData, &all_argc, (const char ***) &all_argv);
if (code != TCL_OK)
return TCL_ERROR;
int coordinate = atoi(all_argv[0]);
short direction = atoi(all_argv[1]);
renderer->translate(coordinate, direction);
return TCL_OK;
}
// Reset all boundary selctions
int
UserInterface_TCL::from_tk_ResetAllBoundarySelections(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ResetAllBoundarySelections: Command not legal. No model exists!");
return TCL_OK;
}
model->resetAllBoundarySelections(true);
return TCL_OK;
}
// Reset boundary selctions when a new boundary is selected
int
UserInterface_TCL::from_tk_ResetBoundarySelections(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ResetBoundarySelections: Command not legal. No model exists!");
return TCL_OK;
}
model->resetBoundarySelections(true, false, 0, (const int*)NULL, false);
return TCL_OK;
}
// Function sets original names for boundaries
int
UserInterface_TCL::from_tk_RestoreBoundaryNames(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "RestoreBoundaryNames: Command not legal. No model exists!");
return TCL_OK;
}
model->restoreBoundaryNames();
TheUI->updateBoundaryData(model);
return TCL_OK;
}
// Function saves external mesh in Elmer (DB) format
int
UserInterface_TCL::from_tk_SaveElmerMeshFile(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
char* mesh_dir = getCommandArguments(interp);
theControlCenter->saveElmerMeshFile(mesh_dir);
return TCL_OK;
}
// Function saves mesh result file in ElmerPost format
// (ie. activates its construction and saving by the model)
int
UserInterface_TCL::from_tk_SaveElmerPostMeshFile(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
char* out_filename = getCommandArguments(interp);
theControlCenter->saveElmerPostMeshFile(out_filename);
return TCL_OK;
}
// Function saves model file (emf-file)
int
UserInterface_TCL::from_tk_SaveModelFile(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "SaveModelFile: Command not legal. No model exists!");
return TCL_OK;
}
// Check if model file matc definitions (dependencies) should be kept
int drop_matc;
readVariable(interp, "Info", "dropModelMatcDefinitions", drop_matc);
if ( 0 == drop_matc ) {
model->setKeepMatcDefinitions(true);
} else {
model->setKeepMatcDefinitions(false);
}
char* emf_filename = getCommandArguments(interp);
theControlCenter->saveFrontModelFile(emf_filename);
return TCL_OK;
}
// Function saves mesh input file (mif-file)
int
UserInterface_TCL::from_tk_SaveMeshInputFile(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
char* mif_filename = getCommandArguments(interp);
theControlCenter->saveMeshInputFile(mif_filename);
return TCL_OK;
}
// Function saves solver input file.(sif-file)
int
UserInterface_TCL::from_tk_SaveSolverInputFile(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
char* sif_filename = getCommandArguments(interp);
theControlCenter->saveSolverInputFile(sif_filename);
return TCL_OK;
}
// Function saves mesh result file in Thetis format
// (ie. activates its construction and saving by the model)
int
UserInterface_TCL::from_tk_SaveThetisMeshFile(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
char* out_filename = getCommandArguments(interp);
theControlCenter->saveThetisMeshFile(out_filename);
return TCL_OK;
}
// Function saves user settings into (default) file
int
UserInterface_TCL::from_tk_SaveUserSettingsFile(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
char* filename = getCommandArguments(interp);
theControlCenter->saveUserSettingsFile(filename);
return TCL_OK;
}
// Function saves model ecf-file.
int
UserInterface_TCL::from_tk_SelectMeshBoundaryElements(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "SelectMeshBoundaryElements: Command not legal. No model exists!");
return TCL_OK;
}
char* type = getCommandArguments(interp);
if ( 0 == strcmp(type, "do") )
model->selectMeshBoundaryElements();
else if ( 0 == strcmp(type, "undo") )
model->selectMeshBoundaryElementsUndo();
else if ( 0 == strcmp(type, "redo") )
model->selectMeshBoundaryElementsRedo();
return TCL_OK;
}
// Change current working diredctory
int
UserInterface_TCL::from_tk_SetCurrentDirectory(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
char* dir = getCommandArguments(interp);
#if defined(WIN32)
_chdir(dir);
#else
chdir(dir);
#endif
return TCL_OK;
}
// Function sets a (predefined) flag in the model
// In Tk flags are named ModelFlags(drawBodies) (value 0/1)
// Flags are stored in the model in the ModelFlags array where
// indices are enums like DRAW_TARGET_BODIES
// Group name enum for this flag would be DRAW_TARGET
// Tk identifies the group and flag names for the cpp by
// using corresponding strings "DRAW_TARGET" and "DRAW_TARGET_BODIES"
int
UserInterface_TCL::from_tk_SetFlagValue(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "SetFlagValue: Command not legal. No model exists!");
return TCL_OK;
}
//---Get tcl-data
int all_argc;
char **all_argv;
char* allData = getCommandArguments(interp);
int code = Tcl_SplitList(interp, allData, &all_argc, (const char ***) &all_argv);
if (code != TCL_OK)
return TCL_ERROR;
bool data_ok = true;
//---First argument: flag group
flagGroup group;
if ( 0 == strcmp(all_argv[0], "DRAW_SOURCE") )
group = DRAW_SOURCE;
else if ( 0 == strcmp(all_argv[0], "DRAW_TARGET") )
group = DRAW_TARGET;
else if ( 0 == strcmp(all_argv[0], "GEOMETRY_TYPE") )
group = GEOMETRY_TYPE;
else if ( 0 == strcmp(all_argv[0], "SELECT_METHOD") )
group = SELECT_METHOD;
else if ( 0 == strcmp(all_argv[0], "SELECT_MODE") )
group = SELECT_MODE;
else if ( 0 == strcmp(all_argv[0], "SELECT_OBJECTS") )
group = SELECT_OBJECTS;
else if ( 0 == strcmp(all_argv[0], "LABEL_DISPLAY") )
group = LABEL_DISPLAY;
else {
group = FLAG_GROUP_UNKNOWN;
data_ok = false;
strstream strm;
strm << "Unknown flag group name: " << all_argv[0] << ends;
TheUI->showMsg(strm.str());
}
//---Second argument: flag name
flagName name;
if ( 0 == strcmp(all_argv[1], "DRAW_SOURCE_CAD") )
name = DRAW_SOURCE_CAD;
else if ( 0 == strcmp(all_argv[1], "DRAW_SOURCE_MESH") )
name = DRAW_SOURCE_MESH;
else if ( 0 == strcmp(all_argv[1], "DRAW_TARGET_BODIES") )
name = DRAW_TARGET_BODIES;
else if ( 0 == strcmp(all_argv[1], "DRAW_TARGET_SURFACES") )
name = DRAW_TARGET_SURFACES;
else if ( 0 == strcmp(all_argv[1], "DRAW_TARGET_EDGES") )
name = DRAW_TARGET_EDGES;
else if ( 0 == strcmp(all_argv[1], "SELECT_METHOD_SINGLE") )
name = SELECT_METHOD_SINGLE;
else if ( 0 == strcmp(all_argv[1], "SELECT_METHOD_ALL") )
name = SELECT_METHOD_ALL;
else if ( 0 == strcmp(all_argv[1], "SELECT_METHOD_BY_NEIGHBOR") )
name = SELECT_METHOD_BY_NEIGHBOR;
else if ( 0 == strcmp(all_argv[1], "SELECT_METHOD_BY_NORMAL") )
name = SELECT_METHOD_BY_NORMAL;
else if ( 0 == strcmp(all_argv[1], "SELECT_METHOD_BY_PLANE") )
name = SELECT_METHOD_BY_PLANE;
else if ( 0 == strcmp(all_argv[1], "SELECT_METHOD_BY_BOX") )
name = SELECT_METHOD_BY_BOX;
else if ( 0 == strcmp(all_argv[1], "SELECT_METHOD_BY_RECTANGLE") )
name = SELECT_METHOD_BY_RECTANGLE;
else if ( 0 == strcmp(all_argv[1], "SELECT_MODE_TOGGLE") )
name = SELECT_MODE_TOGGLE;
else if ( 0 == strcmp(all_argv[1], "SELECT_MODE_EXTEND") )
name = SELECT_MODE_EXTEND;
else if ( 0 == strcmp(all_argv[1], "SELECT_MODE_REDUCE") )
name = SELECT_MODE_REDUCE;
else if ( 0 == strcmp(all_argv[1], "SELECT_OBJECTS_EXTEND") )
name = SELECT_OBJECTS_EXTEND;
else if ( 0 == strcmp(all_argv[1], "SELECT_OBJECTS_TOGGLE") )
name = SELECT_OBJECTS_TOGGLE;
else if ( 0 == strcmp(all_argv[1], "LABEL_DISPLAY_NODE") )
name = LABEL_DISPLAY_NODE;
else if ( 0 == strcmp(all_argv[1], "LABEL_DISPLAY_ELEMENT") )
name = LABEL_DISPLAY_ELEMENT;
else if ( 0 == strcmp(all_argv[1], "LABEL_DISPLAY_VERTEX") )
name = LABEL_DISPLAY_VERTEX;
else if ( 0 == strcmp(all_argv[1], "LABEL_DISPLAY_EDGE") )
name = LABEL_DISPLAY_EDGE;
else if ( 0 == strcmp(all_argv[1], "LABEL_DISPLAY_FACE") )
name = LABEL_DISPLAY_FACE;
else if ( 0 == strcmp(all_argv[1], "LABEL_DISPLAY_BODY") )
name = LABEL_DISPLAY_BODY;
else {
name = FLAG_NAME_UNKNOWN;
data_ok = false;
strstream strm;
strm << "Unknown flag name: " << all_argv[1] << ends;
TheUI->showMsg(strm.str());
}
if (data_ok) {
bool value = bool(atoi(all_argv[2]));
model->setFlagValue(group, name, value);
}
return TCL_OK;
}
// Set Matc emf-input file name
int
UserInterface_TCL::from_tk_SetMatcInputFileEmf(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "SetMatcInputFileEmf: Command not legal. No model exists!");
return TCL_OK;
}
char* file = getCommandArguments(interp);
model->setMatcInputFileEmf(file);
return TCL_OK;
}
// Set Matc sif-input file name
int
UserInterface_TCL::from_tk_SetMatcInputFileSif(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "SetMatcInputFileSif: Command not legal. No model exists!");
return TCL_OK;
}
char* file = getCommandArguments(interp);
model->setMatcInputFileSif(file);
return TCL_OK;
}
// Set mesh input unit (for external mesh reading)
// NOTE: uses static model method!
//
int
UserInterface_TCL::from_tk_SetMeshInputUnit(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
char* value = getCommandArguments(interp);
double unit = atof(value);
if ( unit > 0 ) {
Model::setMeshInputUnit(unit);
} else {
Model::setMeshInputUnit(1.0);
}
return TCL_OK;
}
// Function set model status data from Tk.
int
UserInterface_TCL::from_tk_SetModelStatus(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "SetModelStatus: Command not legal. No model exists!");
return TCL_OK;
}
//---Get tcl-data
char* data = getCommandArguments(interp);
int st_argc;
char** st_argv;
int code = Tcl_SplitList(interp, data, &st_argc, (const char ***) &st_argv);
if (code != TCL_OK)
return TCL_ERROR;
//---Set model status
ecif_modelStatus status = (ecif_modelStatus)atol(st_argv[0]);
model->setModelStatus(status);
return TCL_OK;
}
// Function reads model outfile save timestamp from Tk.
int
UserInterface_TCL::from_tk_SetSelectionsToGui(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "SetSelectionsToGui: Command not legal. No model exists!");
return TCL_OK;
}
model->setSelectionsToGui();
return TCL_OK;
}
// Function starts boundary splitting
int
UserInterface_TCL::from_tk_SplitBoundary(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "SplitBoundary: Command not legal. No model exists!");
return TCL_OK;
}
int body1_id, body2_id;
istrstream in(getCommandArguments(interp));
in >> body1_id >> body2_id;
model->splitBoundary(body1_id, body2_id);
return TCL_OK;
}
// Function redes boundary splitting/combining
int
UserInterface_TCL::from_tk_SplitCombineBoundariesRedo(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "SplitCombineBoundariesRedo: Command not legal. No model exists!");
return TCL_OK;
}
model->splitCombineBoundariesRedo();
return TCL_OK;
}
// Function undoes boundary splitting/combining
int
UserInterface_TCL::from_tk_SplitCombineBoundariesUndo(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "SplitCombineBoundariesUndo: Command not legal. No model exists!");
return TCL_OK;
}
model->splitCombineBoundariesUndo();
return TCL_OK;
}
// Function send the stop editing message to the model
int
UserInterface_TCL::from_tk_StopEditMeshBoundaries(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "StopEditMeshBoundaries: Command not legal. No model exists!");
return TCL_OK;
}
char* mode = getCommandArguments(interp);
bool cancel_edit = false;
if ( LibFront::ncEqual(mode, "cancel") )
cancel_edit = true;
model->stopEditMeshBoundaries(cancel_edit);
return TCL_OK;
}
// Function accepts current names for boundaries
int
UserInterface_TCL::from_tk_StoreBoundaryNames(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "StoreBoundaryNames: Command not legal. No model exists!");
return TCL_OK;
}
model->storeBoundaryNames();
return TCL_OK;
}
// Function initiates interrupts processing by setting a proper stop flag on
int
UserInterface_TCL::from_tk_DoBreak(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
theControlCenter->setBreakValue(MESH_INPUT, true);
return TCL_OK;
}
// Delete mesh from the model data
int
UserInterface_TCL::from_tk_UnloadMesh(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "UnloadMesh: Command not legal. No model exists!");
return TCL_OK;
}
char* msg = getCommandArguments(interp);
model->unloadMesh(msg);
return TCL_OK;
}
// Update CAD geometry (based on Matc parameters)
int
UserInterface_TCL::from_tk_UpdateCadGeometry(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "UpdateCadGeometry: Command not legal. No model exists!");
return TCL_OK;
}
model->updateCadGeometry();
return TCL_OK;
}
// Function updates a matc file with user selcted definitions
int
UserInterface_TCL::from_tk_UpdateMatcFile(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
char* ud_data = getCommandArguments(interp);
int ud_argc;
char** ud_argv;
int code = Tcl_SplitList(interp, ud_data, &ud_argc, (const char ***) &ud_argv);
if (code != TCL_OK)
return TCL_ERROR;
char* filename = ud_argv[0];
char* mode = ud_argv[1];
char* mc_data = ud_argv[2];
int mc_argc;
char** mc_argv;
code = Tcl_SplitList(interp, mc_data, &mc_argc, (const char ***) &mc_argv);
Model::updateMatcFile(filename, mode, mc_argc, mc_argv);
return TCL_OK;
}
//-----------------------------------
void
UserInterface_TCL::generateEvent()
{
Tcl_Eval(theInterp, "Util::generateEvent");
}
char*
UserInterface_TCL::getCommandArguments(Tcl_Interp* interp)
{
return (char *) Tcl_GetVar2(interp, "Info", "arguments", glob_flag);
}
char*
UserInterface_TCL::getCommandResults(Tcl_Interp* interp)
{
return (char *) Tcl_GetVar2(interp, "Info", "results", glob_flag);
}
Renderer*
UserInterface_TCL::getRenderer()
{
return theControlCenter->getRenderer();
}
void
UserInterface_TCL::getCurrentTimestamp(char* buffer)
{
sendCommandToGui(theInterp, "Interface::setCurrentTimestamp");
char* ts = (char *) Tcl_GetVar2(theInterp, "Info", "currentTimestamp", glob_flag);
strcpy(buffer, ts);
}
bool
UserInterface_TCL::getEquationVarsVariable(const char* equation_name, char*& equation_vars_name)
{
// Panel names to check (Equation and generic)
char* panel_names[] = { "EQ", "#" };
int panel_count = 2;
for (int i = 0; i < panel_count; i++) {
strstream strm;
strm << panel_names[i] << "," << equation_name << "," << "EquationVars" << ends;
readVariable(theInterp, "Common", strm.str(), equation_vars_name);
if ( equation_vars_name != NULL ) {
return true;
}
}
return false;
}
// Check if an equation panel field (possibly for a specific equation) should
// be output into a solver section
//
bool
UserInterface_TCL::getIsSolverTargetField(const char* equation_name, const char* field_name)
{
if ( field_name == NULL ) return false;
ostrstream strm;
if ( equation_name != NULL ) {
strm << equation_name << tclArgSeparator;
} else {
strm << "" << tclArgSeparator;
}
strm << field_name << ends;
sendCommandToGui(theInterp, "Interface::getIsSolverTargetField", strm.str());
char* data = getCommandResults(theInterp);
int tf_argc;
char** tf_argv;
int code = Tcl_SplitList(theInterp, data, &tf_argc, (const char ***) &tf_argv);
if ( tf_argc == 0 ) {
return false;
}
return (bool)atoi(tf_argv[0]);
}
void
UserInterface_TCL::getMatcSifDefinitions(int& nof_defs, char**& defs)
{
readVariable(theInterp, "MatcDefinitions", "sifDefs", nof_defs, defs);
}
void
UserInterface_TCL::getMeshDirectoryInfo(char*& dir, char*& dir_abs)
{
readVariable(theInterp, "ModelProperty", "CURRENT_MESH_DIRECTORY", dir);
readVariable(theInterp, "ModelProperty", "CURRENT_MESH_DIRECTORY,absolute", dir_abs);
}
bool
UserInterface_TCL::getMeshInputFileName(char*& mif_file_name)
{
sendCommandToGui(theInterp, "Interface::getMeshInputFileName");
char* mif_fn = getCommandResults(theInterp);
if ( mif_fn == NULL ) {
return false;
}
mif_file_name = new char[1 + strlen(mif_fn)];
strcpy(mif_file_name, mif_fn);
return true;
}
void
UserInterface_TCL::getModelDirectoryInfo(char*& dir, char*& dir_abs)
{
readVariable(theInterp, "ModelProperty", "MODEL_DIRECTORY", dir);
readVariable(theInterp, "ModelProperty", "MODEL_DIRECTORY,absolute", dir_abs);
}
void
UserInterface_TCL::getModelNameInfo(char*& model_name, char*& problem_name)
{
readVariable(theInterp, "ModelProperty", "MODEL_NAME", model_name);
readVariable(theInterp, "ModelProperty", "PROBLEM_NAME", problem_name);
}
bool
UserInterface_TCL::getParameterFieldInfo(const char* parameter, const char* field, ParameterFieldInfo& finfo)
{
ostrstream strm;
strm << parameter << tclArgSeparator << field << ends;
sendCommandToGui(theInterp, "Interface::getParameterFieldInfo", strm.str());
char* data = getCommandResults(theInterp);
int fi_argc;
char** fi_argv;
int code = Tcl_SplitList(theInterp, data, &fi_argc, (const char ***) &fi_argv);
if ( fi_argc == 0 ) {
return false;
}
// NOTE: data order is fixed and data given by Gui should match this!!!
int idx = 0;
update_dyna_string(finfo.sifName, fi_argv[idx++]);
update_dyna_string(finfo.valueType, fi_argv[idx++]);
finfo.outputSif = (bool)atoi(fi_argv[idx++]);
finfo.outputSifType = (bool)atoi(fi_argv[idx++]);
finfo.alwaysOutput = (bool)atoi(fi_argv[idx++]);
finfo.isArray = (bool)atoi(fi_argv[idx++]);
finfo.isQuoted = (bool)atoi(fi_argv[idx++]);
// Note: these flags are by default turned off in the data
finfo.isFileName = (bool)atoi(fi_argv[idx++]);
finfo.isProcName = (bool)atoi(fi_argv[idx++]);
return true;
}
bool
UserInterface_TCL::getSolverKeywordTypeGiven(const char* parameter, const char* field)
{
ostrstream strm;
strm << parameter << tclArgSeparator << field << ends;
sendCommandToGui(theInterp, "Interface::getSolverKeywordTypeGiven", strm.str());
char* data = getCommandResults(theInterp);
int fi_argc;
char** fi_argv;
int code = Tcl_SplitList(theInterp, data, &fi_argc, (const char ***) &fi_argv);
if ( fi_argc == 0 ) {
return false;
}
return (bool)atoi(fi_argv[0]);
}
bool
UserInterface_TCL::getUseModelFileSettings()
{
int value;
readVariable(theInterp, "UserSetting", "DEFAULT_USE_MODEL_SETTINGS", value);
if (value == 0)
return false;
else
return true;
}
// Check if variable names should be added to equation names in
// Solver sif output
bool
UserInterface_TCL::getUseVariableNameInEquationName(const char* equation_name)
{
sendCommandToGui(theInterp, "Interface::getUseVariableNameInEquationName", equation_name);
bool use_var_name = atoi(getCommandResults(theInterp));
return use_var_name;
}
// *** Set values for Tcl-variables.
void
UserInterface_TCL::initTclVariables(Tcl_Interp* interp, const Model& model)
{
to_tk_WriteModelStatus(interp, model);
to_tk_WriteModelGeometryDimension(interp, model);
to_tk_WriteProcessorData(interp, model);
to_tk_WriteBodyLayerData(interp, model);
to_tk_WriteBodyData(interp, model);
to_tk_WriteBodyInfoData(interp, model);
// Do this after writing Body level data!!!
to_tk_WriteBoundaryData(interp, model);
to_tk_WriteElementGroupData(interp, model);
to_tk_WriteStats(interp, model);
to_tk_WriteControlParameters(interp, model);
// Process object table data in Gui side
sendCommandToGui(interp, "Interface::applyObjectTableData");
to_tk_WriteAllParamDataPre(interp, model);
to_tk_WriteAllParamDataPost(interp, model);
}
// Function makes two "separated" strings from object, elementd ids data
// Into body_ids: (Body-pair-ids, Nof-elements)
// Into elem_ids: (Body1-id, Body2-id, Element-id)
// Into bndr_ids: (Boundary condition id)
// Into grid_ids: (Grid-param id)
// id_set: the id-data, a set of ids-structures
void
UserInterface_TCL::listInnerIds(Model* model,
ostrstream& body_ids, ostrstream& elem_ids,
ostrstream& names,
ostrstream& bndr_ids,
const char obj_sep, const char fld_sep,
Ids3Set& id_set)
{
Ids3Set::iterator pos = id_set.begin();
Ids3Set::iterator end = id_set.end();
int elm_counter;
int object1_id, object2_id;
object1_id = -1;
// We collect unique ids of those bodies which have an
// inner boundary condition defined into this set
while (pos != end) {
Ids3 wid3 = *pos++;
//New object-pair was encountered
if (object1_id != wid3.id1 || object2_id != wid3.id2) {
//Write data after each 'real' new object
if (object1_id != -1) {
body_ids << 'I' << fld_sep;
body_ids << object1_id << fld_sep;
body_ids << object2_id << fld_sep;
body_ids << elm_counter;
body_ids << obj_sep;
}
//Update reference variables
object1_id = wid3.id1;
object2_id = wid3.id2;
elm_counter = 0;
}
elm_counter++;
//Write out element-row, boundary condtition and grid-param rows, Body2, Elm, Cond
BodyElement* be = model->getBoundaryById(wid3.id3);
int cid = be->getBoundaryConditionId();
elem_ids << 'I' << fld_sep;
elem_ids << wid3.id1 << fld_sep << wid3.id2 << fld_sep << wid3.id3;
names << be->getName();
bndr_ids << cid;
//We don't want to add a separator at the end of the string!!!
if (pos != end) {
elem_ids << obj_sep;
names << obj_sep;
bndr_ids << obj_sep;
}
}
//End of data. Write last object's data.
if (object1_id != -1) {
body_ids << 'I' << fld_sep;
body_ids << object1_id << fld_sep;
body_ids << object2_id << fld_sep;
body_ids << elm_counter;
}
body_ids << ends;
elem_ids << ends;
names << ends;
bndr_ids << ends;
}
// Function makes two "separated" strings from object, elementd ids data
// Into body_ids: (Body-id, Nof-elements)
// Into elem_ids: (Body-id, Element-id)
// Into bndr_ids: (Boundary condition id)
// id_set: the id-data, a set of ids-structures
void
UserInterface_TCL::listOuterIds(Model* model,
ostrstream& body_ids, ostrstream& elem_ids,
ostrstream& names,
ostrstream& bndr_ids,
const char obj_sep, const char fld_sep,
Ids2Set& id_set)
{
Ids2Set::iterator pos = id_set.begin();
Ids2Set::iterator end = id_set.end();
int elm_counter;
int object_id = -1;
// We collect unique ids of those bodies which have an
// outer boundary condition defined into this set
while (pos != end) {
Ids2 wid2 = *pos++;
//New object-pair was encountered
if (object_id != wid2.id1) {
//Write data after each 'real' new object
if (object_id != -1) {
body_ids << 'O' << fld_sep;
body_ids << object_id << fld_sep;
body_ids << elm_counter;
body_ids << obj_sep;
}
//Update reference variables
object_id = wid2.id1;
elm_counter = 0;
}
elm_counter++;
//Write out element, boundary condition and grid-param row. Body, Elm, Cond
BodyElement* be = model->getBoundaryById(wid2.id2);
int cid = be->getBoundaryConditionId();
elem_ids << 'O' << fld_sep;
elem_ids << wid2.id1 << fld_sep << wid2.id2;
names << be->getName();
bndr_ids << cid;
//We don't want to add a separator at the end of the string!!!
if (pos != end) {
elem_ids << obj_sep;
names << obj_sep;
bndr_ids << obj_sep;
}
}
//End of data. Write last object's data.
if (object_id != -1) {
body_ids << 'O' << fld_sep;
body_ids << object_id << fld_sep;
body_ids << elm_counter;
}
body_ids << ends;
elem_ids << ends;
names << ends;
bndr_ids << ends;
}
void
UserInterface_TCL::markSelectedBoundaries()
{
sendCommandToGui(theInterp, "Interface::markSelectedBoundaries", NULL);
}
void
UserInterface_TCL::matcFileWasRead(char* filename)
{
sendCommandToGui(theInterp, "Interface::matcFileWasRead", filename);
}
// Main function for the user settings file reading
void
UserInterface_TCL::readUserSettingsFile(Tcl_Interp* interp, char* filename)
{
struct emf_ObjectData_X my_ObjectData;
emf_ObjectData = &my_ObjectData;
/*Set callback function*/
//int my_readDataCB(void**);
emf_readDataCB = readUserSettingsFileCallBack;
/*-----Start parser*/
int rc = emf_readData(filename, (void**)&interp, 0, NULL, 1);
// No success
if (rc == 0) {
return;
}
strstream strm;
strm << "Reading settings file: " << filename << ends;
writeVariable(interp, "Info", "settingsFileReadInfo", strm.str(), false);
}
// This method gets one "field" at a time from the file
int
UserInterface_TCL::readUserSettingsFileCallBack(void** user_data)
{
UserInterface* gui = theControlCenter->getGui();
Tcl_Interp* interp = (Tcl_Interp*)*user_data;
// Global object pointing to the record, make
// a short hand for it
emf_ObjectData_X* od = emf_ObjectData;
const char* on = od->object_name;
int onl = od->object_name_length;
const char* fn = od->field_name;
int fnl = od->field_name_length;
const char* dt = od->data_type;
int dtl = od->data_type_length;
// Read data according to the object type
char fld[256];
bool logical_value;
bool to_upper = true;
char* str_val;
//-Default directory for Elmer models
if ( LibFront::in("Default Model Directory", fn) ) {
writeVariable(interp, "UserSetting", "DEFAULT_MODEL_DIRECTORY", (char*)od->data);
return 1;
}
//-Default directory for Elmer Cad files
if ( LibFront::in("Default Cad Files Directory", fn) ) {
writeVariable(interp, "UserSetting", "DEFAULT_CAD_FILES_DIRECTORY", (char*)od->data);
return 1;
}
//-Default directory for Elmer external mesh files
if ( LibFront::in("Default External Mesh Files Directory", fn) ) {
writeVariable(interp, "UserSetting", "DEFAULT_EXTERNAL_MESH_FILES_DIRECTORY", (char*)od->data);
return 1;
}
//-Default directory for Elmer input files files
if ( LibFront::in("Default Include Path", fn) ) {
writeVariable(interp, "UserSetting", "DEFAULT_INCLUDE_PATH", (char*)od->data);
return 1;
}
//-Results directory
if ( LibFront::in("Default Results Directory", fn) ) {
writeVariable(interp, "UserSetting", "DEFAULT_RESULTS_DIRECTORY", (char*)od->data);
return 1;
}
//-Default directory for Elmer output files
if ( LibFront::in("Default Log Directory", fn) ) {
writeVariable(interp, "UserSetting", "DEFAULT_LOG_DIRECTORY", (char*)od->data);
return 1;
}
//-Use model settings flag
if ( LibFront::in("Default Use Model Settings", fn) ) {
LibFront::setNumericData(logical_value, 0);
writeVariable(interp, "UserSetting", "DEFAULT_USE_MODEL_SETTINGS", logical_value);
return 1;
}
//-Auto load mesh file flag
if ( LibFront::in("Auto Load Mesh", fn) ) {
LibFront::setNumericData(logical_value, 0);
writeVariable(interp, "UserSetting", "AUTO_LOAD_MESH", logical_value);
return 1;
}
//-Auto save model file flag
if ( LibFront::in("Auto Save Model", fn) ) {
LibFront::setNumericData(logical_value, 0);
writeVariable(interp, "UserSetting", "AUTO_SAVE_MODEL", logical_value);
return 1;
}
//-Auto save solver input file flag
if ( LibFront::in("Auto Save Solver Input", fn) ) {
LibFront::setNumericData(logical_value, 0);
writeVariable(interp, "UserSetting", "AUTO_SAVE_SOLVER_INPUT", logical_value);
return 1;
}
//-External browser program command
if ( LibFront::in("Browser Command", fn) ) {
LibFront::setNumericData(logical_value, 0);
writeVariable(interp, "UserSetting", "BROWSER_COMMAND", (char*)od->data);
return 1;
}
//-External editor program command
if ( LibFront::in("Editor Command", fn) ) {
LibFront::setNumericData(logical_value, 0);
writeVariable(interp, "UserSetting", "EDITOR_COMMAND", (char*)od->data);
return 1;
}
//-Gebhardt factors run browse mode
if ( LibFront::in("Browse Mode Gebhardt Ffactors", fn) ) {
writeVariable(interp, "UserSetting", "BROWSE_MODE_GEBHARDT_FACTORS", (char*)od->data);
return 1;
}
//-Mesh run browse mode
if ( LibFront::in("Browse Mode Mesh", fn) ) {
writeVariable(interp, "UserSetting", "BROWSE_MODE_MESH", (char*)od->data);
return 1;
}
//-Procedure compiler run browse mode
if ( LibFront::in("Browse Mode Procedure Compiler", fn) ) {
writeVariable(interp, "UserSetting", "BROWSE_MODE_PROCEDURE_COMPILER", (char*)od->data);
return 1;
}
//-Solver run browse mode
if ( LibFront::in("Browse Mode Solver", fn) ) {
writeVariable(interp, "UserSetting", "BROWSE_MODE_SOLVER", (char*)od->data);
return 1;
}
//-View factors run browse mode
if ( LibFront::in("Browse Mode View Factors", fn) ) {
writeVariable(interp, "UserSetting", "BROWSE_MODE_VIEW_FACTORS", (char*)od->data);
return 1;
}
//-Font sizes (small, medium, large)
if ( LibFront::in("Font Sizes", fn) ) {
int count = od->data_length;
int* sizes = new int[count];
for (int i = 0; i < count; i++)
LibFront::setNumericData(sizes[i], i);
writeVariable(interp, "UserSetting", "FONT_SIZES", count, sizes);
delete[] sizes;
return 1;
}
//-UNKNOWN field, collect info in the gui-variable to
// be displayed later when all the nice gui machinery
// is loaded!
else {
strstream strm;
strm << "Unknown keyword: "
<< od->field_name
<< ends;
writeVariable(interp, "Info", "useSettingFilesErrorInfo", strm.str(), false);
}
return 1;
}
// ========
// Id Array
// ========
// Id array, integer id, single value
// ----------------------------------
void
UserInterface_TCL::readIdVariable(Tcl_Interp* interp, const char* array, int id, const char* variable,
char& value)
{
strstream field_name;
field_name << id << "," << variable << ends;
readVariable_impl_1(interp, array, field_name.str(), value);
}
void
UserInterface_TCL::readIdVariable(Tcl_Interp* interp, const char* array, int id, const char* variable,
char*& value)
{
strstream field_name;
field_name << id << "," << variable << ends;
readVariable_impl_1(interp, array, field_name.str(), value);
}
void
UserInterface_TCL::readIdVariable(Tcl_Interp* interp, const char* array, int id, const char* variable,
int& value)
{
strstream field_name;
field_name << id << "," << variable << ends;
readVariable_impl_1(interp, array, field_name.str(), value);
}
void
UserInterface_TCL::readIdVariable(Tcl_Interp* interp, const char* array, int id, const char* variable,
double& value)
{
strstream field_name;
field_name << id << "," << variable << ends;
readVariable_impl_1(interp, array, field_name.str(), value);
}
// Id array, integer id, list of values
// ------------------------------------
void
UserInterface_TCL::readIdVariable(Tcl_Interp* interp, const char* array, int id, const char* variable,
int& size, char**& values)
{
strstream field_name;
field_name << id << "," << variable << ends;
readVariable_impl_n(interp, array, field_name.str(), size, values);
}
void
UserInterface_TCL::readIdVariable(Tcl_Interp* interp, const char* array, int id, const char* variable,
int& size, int*& values)
{
strstream field_name;
field_name << id << "," << variable << ends;
readVariable_impl_n(interp, array, field_name.str(), size, values);
}
void
UserInterface_TCL::readIdVariable(Tcl_Interp* interp, const char* array, int id, const char* variable,
int& size, double*& values)
{
strstream field_name;
field_name << id << "," << variable << ends;
readVariable_impl_n(interp, array, field_name.str(), size, values);
}
// Id array, string id, single value
// ---------------------------------
void
UserInterface_TCL::readIdVariable(Tcl_Interp* interp, const char* array, const char* id, const char* variable,
char& value)
{
strstream field_name;
field_name << id << "," << variable << ends;
readVariable_impl_1(interp, array, field_name.str(), value);
}
void
UserInterface_TCL::readIdVariable(Tcl_Interp* interp, const char* array, const char* id, const char* variable,
char*& value)
{
strstream field_name;
field_name << id << "," << variable << ends;
readVariable_impl_1(interp, array, field_name.str(), value);
}
void
UserInterface_TCL::readIdVariable(Tcl_Interp* interp, const char* array, const char* id, const char* variable,
int& value)
{
strstream field_name;
field_name << id << "," << variable << ends;
readVariable_impl_1(interp, array, field_name.str(), value);
}
void
UserInterface_TCL::readIdVariable(Tcl_Interp* interp, const char* array, const char* id, const char* variable,
double& value)
{
strstream field_name;
field_name << id << "," << variable << ends;
readVariable_impl_1(interp, array, field_name.str(), value);
}
// Id array, string id, list of values
// -----------------------------------
void
UserInterface_TCL::readIdVariable(Tcl_Interp* interp, const char* array, const char* id, const char* variable,
int& size, char**& values)
{
strstream field_name;
field_name << id << "," << variable << ends;
readVariable_impl_n(interp, array, field_name.str(), size, values);
}
void
UserInterface_TCL::readIdVariable(Tcl_Interp* interp, const char* array, const char* id, const char* variable,
int& size, int*& values)
{
strstream field_name;
field_name << id << "," << variable << ends;
readVariable_impl_n(interp, array, field_name.str(), size, values);
}
void
UserInterface_TCL::readIdVariable(Tcl_Interp* interp, const char* array, const char* id, const char* variable,
int& size, double*& values)
{
strstream field_name;
field_name << id << "," << variable << ends;
readVariable_impl_n(interp, array, field_name.str(), size, values);
}
// Id2 array, integer id1, id2, single value
// -----------------------------------------
void
UserInterface_TCL::readId2Variable(Tcl_Interp* interp, const char* array, int id1, int id2, const char* variable,
char& value)
{
strstream field_name;
field_name << id1 << "," << id2 << "," << variable << ends;
readVariable_impl_1(interp, array, field_name.str(), value);
}
void
UserInterface_TCL::readId2Variable(Tcl_Interp* interp, const char* array, int id1, int id2, const char* variable,
char*& value)
{
strstream field_name;
field_name << id1 << "," << id2 << "," << variable << ends;
readVariable_impl_1(interp, array, field_name.str(), value);
}
void
UserInterface_TCL::readId2Variable(Tcl_Interp* interp, const char* array, int id1, int id2, const char* variable,
int& value)
{
strstream field_name;
field_name << id1 << "," << id2 << "," << variable << ends;
readVariable_impl_1(interp, array, field_name.str(), value);
}
void
UserInterface_TCL::readId2Variable(Tcl_Interp* interp, const char* array, int id1, int id2, const char* variable,
double& value)
{
strstream field_name;
field_name << id1 << "," << id2 << "," << variable << ends;
readVariable_impl_1(interp, array, field_name.str(), value);
}
// Id2 array, integer id1, id2, list of values
// -------------------------------------------
void
UserInterface_TCL::readId2Variable(Tcl_Interp* interp, const char* array, int id1, int id2, const char* variable,
int& size, char**& values)
{
strstream field_name;
field_name << id1 << "," << id2 << "," << variable << ends;
readVariable_impl_n(interp, array, field_name.str(), size, values);
}
void
UserInterface_TCL::readId2Variable(Tcl_Interp* interp, const char* array, int id1, int id2, const char* variable,
int& size, int*& values)
{
strstream field_name;
field_name << id1 << "," << id2 << "," << variable << ends;
readVariable_impl_n(interp, array, field_name.str(), size, values);
}
void
UserInterface_TCL::readId2Variable(Tcl_Interp* interp, const char* array, int id1, int id2, const char* variable,
int& size, double*& values)
{
strstream field_name;
field_name << id1 << "," << id2 << "," << variable << ends;
readVariable_impl_n(interp, array, field_name.str(), size, values);
}
// ============
// Normal array
// ============
// Single value
// ------------
void
UserInterface_TCL::readVariable(Tcl_Interp* interp, const char* array, const char* variable,
char& value)
{
readVariable_impl_1(interp, array, variable, value);
}
void
UserInterface_TCL::readVariable(Tcl_Interp* interp, const char* array, const char* variable,
char*& value)
{
readVariable_impl_1(interp, array, variable, value);
}
void
UserInterface_TCL::readVariable(Tcl_Interp* interp, const char* array, const char* variable,
int& value)
{
readVariable_impl_1(interp, array, variable, value);
}
void
UserInterface_TCL::readVariable(Tcl_Interp* interp, const char* array, const char* variable,
double& value)
{
readVariable_impl_1(interp, array, variable, value);
}
// List of values
// --------------
void
UserInterface_TCL::readVariable(Tcl_Interp* interp, const char* array, const char* variable,
int& size, char**& values)
{
readVariable_impl_n(interp, array, variable, size, values);
}
void
UserInterface_TCL::readVariable(Tcl_Interp* interp, const char* array, const char* variable,
int& size, int*& values)
{
readVariable_impl_n(interp, array, variable, size, values);
}
void
UserInterface_TCL::readVariable(Tcl_Interp* interp, const char* array, const char* variable,
int& size, double*& values)
{
readVariable_impl_n(interp, array, variable, size, values);
}
// *** Function sets single value to array-type Tcl variable.
template <class T > void
UserInterface_TCL::readVariable_impl_1(Tcl_Interp* interp, const char* array, const char* variable,
T& value)
{
Tcl_Obj* array_obj = Tcl_NewStringObj(NULL, 0);
Tcl_Obj* value_obj = NULL;
int tcl_flags = TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG;
// We have to create a tcl string-object to
// carry the variable names. Here we use a fully
// specified array name to create the name-object
tcl_flags |= TCL_PARSE_PART1;
strstream strm;
strm << array << "(" << variable << ")" << ends;
char* array_name = strm.str();
Tcl_SetStringObj(array_obj, array_name, strlen(array_name));
// Try to get existing variable handle
// NOTE! This does not seem to be working!!! At least not for
// strings like Default-directories in the settings files.
// They all get the last string values if this is used
// Try to get existing variable handle
;//value_obj = Tcl_ObjGetVar2(interp, array_obj, NULL, tcl_flags);
Tcl_ResetResult(interp);
// Update variable
value_obj = Tcl_ObjGetVar2(interp, array_obj, NULL, tcl_flags);
getTclObjValue(interp, value_obj, value);
}
// *** Function sets list of values to array-type Tcl variable.
template <class T > void
UserInterface_TCL::readVariable_impl_n(Tcl_Interp* interp, const char* array, const char* variable,
int& size, T*& values)
{
size = 0;
values = NULL;
Tcl_Obj* array_obj = Tcl_NewStringObj(NULL, 0);
Tcl_Obj* value_obj = NULL;
Tcl_Obj** list_val_obj = NULL;
int list_len = 0;
int tcl_flags = TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG;
tcl_flags |= TCL_PARSE_PART1;
tcl_flags |= TCL_LIST_ELEMENT;
tcl_flags |= TCL_APPEND_VALUE;
// In Tcl80 we have to create a tcl string-object to
// carry the variable names. Here we use a fully
// specified array name to create the name-object
strstream strm;
strm << array << "(" << variable << ")" << ends;
char* array_name = strm.str();
Tcl_SetStringObj(array_obj, array_name, strlen(array_name));
value_obj = Tcl_ObjGetVar2(interp, array_obj, NULL, tcl_flags);
// If unknown variables
if (value_obj == NULL) {
//strstream strm;
//strm << "ERROR: Cannot read variable: ";
//strm << array_name;
//strm << ends;
//UserInterface* gui = theControlCenter->getGui();
//gui->showMsg(strm.str());
return;
}
Tcl_ListObjGetElements(interp, value_obj, &list_len, &list_val_obj);
if (list_len == 0)
return;
// Allocate result array
size = list_len;
values = new T[size];
// Insert values
for (int i = 0; i < size; i++) {
getTclObjValue(interp, list_val_obj[i], values[i]);
//if ( list_val_obj[i]->length == 0 ) {
// values[i] = (T)0;
//}
}
}
// *** Save model property (DB-name, DB-path etc) data
// from the gui-side
void
UserInterface_TCL::saveModelPropertyData(Model* model)
{
sendCommandToGui(theInterp,"Interface::saveModelPropertyData");
}
void
UserInterface_TCL::selectBody(int bd1_id, int lr1_id, int bd2_id, int lr2_id, bool is_selected)
{
ostrstream strm;
strm << bd1_id << " " << lr1_id << " ";
strm << bd2_id << " " << lr2_id << " ";
strm << (int)is_selected << ends;
sendCommandToGui(theInterp, "Interface::selectBody", strm.str());
}
void
UserInterface_TCL::selectBoundary(int bndr_id, int bd1_id, int lr1_id, int bd2_id, int lr2_id, bool extend)
{
ostrstream strm;
strm << bndr_id << " ";
strm << bd1_id << " " << lr1_id << " ";
strm << bd2_id << " " << lr2_id << " ";
strm << extend << ends;
sendCommandToGui(theInterp, "Interface::selectBoundary", strm.str());
}
// Prefixed commands sent by clients
int
UserInterface_TCL::sendCommandToGui(const char* cmd, const char* arg)
{
if ( 0 == strcmp(cmd, "RESET_RENDERER") )
return sendCommandToGui(theInterp, "Interface::rendererReset", NULL);
else if ( 0 == strcmp(cmd, "SELECT_BODIES") )
return sendCommandToGui(theInterp, "Interface::displayBodySelectPanel");
else if ( 0 == strcmp(cmd, "SELECT_BOUNDARIES") )
return sendCommandToGui(theInterp, "Interface::displayBoundarySelectPanel");
else if ( 0 == strcmp(cmd, "SELECT_LABELS") )
return sendCommandToGui(theInterp, "Interface::displayLabelSelectPanel");
else if ( 0 == strcmp(cmd, "SET_ROTATE_PRIORITY_X") )
return sendCommandToGui(theInterp, "Interface::setRotatePriority", "X");
else if ( 0 == strcmp(cmd, "SET_ROTATE_PRIORITY_Y") )
return sendCommandToGui(theInterp, "Interface::setRotatePriority", "Y");
else if ( 0 == strcmp(cmd, "SET_ROTATE_PRIORITY_Z") )
return sendCommandToGui(theInterp, "Interface::setRotatePriority", "Z");
return false;
}
int
UserInterface_TCL::sendCommandToGui(Tcl_Interp* interp, const char* cmd, const char* arg)
{
int i, len, rc;
Tcl_ResetResult(interp);
char* exec = "gui_exec ";
{
Tcl_DString dstring;
char *buf;
ostrstream strm;
strm << exec;
strm << "\"";
strm << cmd;
if ( arg != NULL ) {
if ( arg[0] != '\0' ) {
strm << tclCmdSeparator << arg;
}
}
strm << "\"";
strm << ends;
buf = Tcl_ExternalToUtfDString(NULL, strm.str(), strlen(strm.str()), &dstring );
rc = Tcl_Eval( interp, buf );
Tcl_DStringFree( &dstring );
}
if (interp->result[0] != '\0') {
char err_buf[256];
err_buf[255] = '\0';
strncpy(err_buf, interp->result, 255);
char cmd_buf[256];
cmd_buf[255] = '\0';
strncpy(cmd_buf, cmd, 255);
char arg_buf[256];
arg_buf[0] = '\0';
if ( arg != NULL && arg[0] != '\0' ) {
arg_buf[255] = '\0';
strncpy(arg_buf, arg, 255);
}
// Replace quotes with spaces so that we can safetly use showMsg function
// to display the error message
len = strlen(err_buf);
for (i = 0; i < len; i++) {
if (err_buf[i] == '"')
err_buf[i] = ' ';
}
len = strlen(cmd_buf);
for (i = 0; i < len; i++) {
if (cmd_buf[i] == '"')
cmd_buf[i] = ' ';
}
len = strlen(arg_buf);
for (i = 0; i < len; i++) {
if (arg_buf[i] == '"')
arg_buf[i] = ' ';
}
UserInterface* gui = theControlCenter->getGui();
// Command info
strstream strm;
strm << "***WARNING INVALID COMMAND: " << cmd_buf;
if (arg != NULL)
strm << " (arg: " << arg_buf << ") ";
strm << " because:" << ends;
gui->showMsg(strm.str());
// Error info from Tcl
gui->showMsg(err_buf, 1);
return 0;
}
return 1;
}
// Function sets boundary conditions for parent object in model
//
void
UserInterface_TCL::setBoundaryConditions(Tcl_Interp *interp, Model* model,
MultiIdTable& bc_table)
{
MultiIdTable::iterator pos = bc_table.begin();
MultiIdTable::iterator end = bc_table.end();
while ( pos != end ) {
int pid = (*pos).first;
int beg_id = (*pos).second;
BodyElementGroup* beg = (BodyElementGroup*)model->getModelObjectById(beg_id);
if ( beg != NULL ) {
beg->setBoundaryConditionId(pid);
}
pos++;
}
}
#if 0
// Function sets boundary conditions for edges
// Not in use!
void
UserInterface_TCL::setBoundaryConditionsForEdges(Tcl_Interp *interp, Model* model,
MultiIdTable& bc_table)
{
MultiIdTable::iterator pos = bc_table.begin();
MultiIdTable::iterator end = bc_table.end();
while ( pos != end ) {
int pid = (*pos).first;
int be_id = (*pos).second;
BodyElement* be = model->getEdgeById(be_id);
if ( be != NULL ) {
be->setBoundaryConditionId(pid);
}
pos++;
}
}
// Function sets boundary conditions for faces
// Not in use!
void
UserInterface_TCL::setBoundaryConditionsForFaces(Tcl_Interp *interp, Model* model,
MultiIdTable& bc_table)
{
MultiIdTable::iterator pos = bc_table.begin();
MultiIdTable::iterator end = bc_table.end();
while ( pos != end ) {
int pid = (*pos).first;
int be_id = (*pos).second;
BodyElement* be = model->getFaceById(be_id);
if ( be != NULL ) {
be->setBoundaryConditionId(pid);
}
pos++;
}
}
// Function sets boundary conditions for vertices.
// Not in use!
void
UserInterface_TCL::setBoundaryConditionsForVertices(Tcl_Interp *interp, Model* model,
MultiIdTable& bc_table)
{
MultiIdTable::iterator pos = bc_table.begin();
MultiIdTable::iterator end = bc_table.end();
while ( pos != end ) {
int pid = (*pos).first;
int be_id = (*pos).second;
BodyElement* be = model->getVertexById(be_id);
if ( be != NULL ) {
be->setBoundaryConditionId(pid);
}
pos++;
}
}
#endif
void
UserInterface_TCL::setBoundarySelectionMode(int bndr_id, bool is_selected, bool do_update)
{
ostrstream strm;
strm << bndr_id << " " << (int)is_selected << " " << (int)do_update << ends;
sendCommandToGui(theInterp, "Interface::setBoundarySelectionMode", strm.str());
}
void
UserInterface_TCL::setCurrentMeshH(double mesh_h)
{
strstream strm;
strm << mesh_h << ends;
sendCommandToGui(theInterp,"Interface::setCurrentMeshH", strm.str());
}
void
UserInterface_TCL::setExceptionThrown()
{
sendCommandToGui(theInterp,"Interface::setExceptionThrown");
}
void
UserInterface_TCL::setInitialMeshH(double mesh_h)
{
strstream strm;
strm << mesh_h << ends;
sendCommandToGui(theInterp,"Interface::setInitialMeshH", strm.str());
}
void
UserInterface_TCL::setInitialState()
{
sendCommandToGui(theInterp,"Interface::setInitialState");
}
void
UserInterface_TCL::setMeshEdited()
{
sendCommandToGui(theInterp, "Interface::setMeshEdited", "");
}
void
UserInterface_TCL::setMeshExists()
{
sendCommandToGui(theInterp, "Interface::setMeshExists", "");
}
void
UserInterface_TCL::setMeshInputUnit(double unit)
{
ostrstream strm;
strm << unit << ends;
sendCommandToGui(theInterp, "Interface::setMeshInputUnit", strm.str());
}
void
UserInterface_TCL::setModelHasElmerMesh()
{
sendCommandToGui(theInterp, "Interface::setModelHasElmerMesh", "");
}
void
UserInterface_TCL::setModelHasMeshParameter()
{
sendCommandToGui(theInterp, "Interface::setModelHasMeshParameter", "");
}
void
UserInterface_TCL::setModelHasMatcDefinitions()
{
sendCommandToGui(theInterp, "Interface::setModelHasMatcDefinitions", "");
}
// Target data (database, solver etc.) needs update
void
UserInterface_TCL::setNeedsUpdate(const char* target)
{
sendCommandToGui(theInterp, "Interface::setNeedsUpdate", (char*)target);
}
int
UserInterface_TCL::setParameterData(Model* model, ecif_parameterType param_type,
Tcl_Interp* interp, const char* array_name)
{
// Read parameter ids
int size = 0;
int* ids = NULL;
readVariable(interp, array_name, "ids", size, ids);
// Mark parameter for update, so that non-set parameters
// can be deleted after update
model->processParametersBeforeUpdate(param_type);
char* data_buffer = "";
char* name_buffer = "";
int oid = NO_INDEX;
int prtag = NO_INDEX;
char* prtp = NULL;
objectType prtype = OT_NONE;
int pid;
int attach_mode;
for (int i = 0; i < size; i++) {
pid = ids[i];
//-Parameter-name
readIdVariable(interp, array_name, pid, "name", name_buffer);
//-Parent object id, tag and type
readIdVariable(interp, array_name, pid, "oid", oid);
if ( oid != NO_INDEX ) {
readIdVariable(interp, "ObjectTable", oid, "tg", prtag);
readIdVariable(interp, "ObjectTable", oid, "tp", prtp);
if (prtp != NULL ) {
if ( 0 == strcmp(prtp, "B") )
prtype = OT_BODY;
else if ( 0 == strcmp(prtp, "BL") )
prtype = OT_BODY_LAYER;
else if ( 0 == strcmp(prtp, "BP") )
prtype = OT_BODYPAIR;
else if ( 0 == strcmp(prtp, "F") )
prtype = OT_FACE;
else if ( 0 == strcmp(prtp, "E") )
prtype = OT_EDGE;
else if ( 0 == strcmp(prtp, "V") )
prtype = OT_VERTEX;
// NOTE: All these are marked as element groups in model
else if ( 0 == strcmp(prtp, "FG") )
prtype = OT_ELEMENT_GROUP;
else if ( 0 == strcmp(prtp, "EG") )
prtype = OT_ELEMENT_GROUP;
else if ( 0 == strcmp(prtp, "VG") )
prtype = OT_ELEMENT_GROUP;
else
prtype = OT_NONE;
}
}
//-Parameter data
readIdVariable(interp, array_name, pid, "data", data_buffer);
//---Save data into model
//model->setParameter(param_type, pid, oid, prtag, prtype, data_buffer, name_buffer);
model->setParameter(param_type, pid, oid, data_buffer, name_buffer);
/* delete[] data_buffer; data_buffer = NULL;
delete[] name_buffer; name_buffer = NULL;
delete[] prtp; prtp = NULL; */
}
// Delete "old" parameters, ie. those which were not set in this update
model->processParametersAfterUpdate(param_type);
delete[] ids;
return TCL_OK;
}
void
UserInterface_TCL::setParameterFieldValueState(int parameter_id, const char* field_name,
bool has_value, bool value_has_changed)
{
ostrstream strm;
strm << parameter_id << ' '
<< (char*)field_name << ' '
<< has_value << ' '
<< value_has_changed
<< ends;
sendCommandToGui(theInterp, "Interface::setParameterFieldValueState", strm.str());
}
void
UserInterface_TCL::setTimestamp(ecif_parameterType parameter, char* ts)
{
char* array = NULL;
char* field = NULL;
switch (parameter) {
case ECIF_GRID_PARAMETER:
array = "Model";
field = "MeshParameter,timestamp";
break;
}
if (array != NULL && field != NULL) {
writeVariable(theInterp, array, field, ts);
}
}
void
UserInterface_TCL::setWindowTitle(char* title)
{
sendCommandToGui( theInterp, "Util::setMainWindowTitle", title);
}
// Target data (database, solver etc.) was succesfully updated
void
UserInterface_TCL::setWasUpdated(const char* target)
{
sendCommandToGui(theInterp, "Interface::setWasUpdated", (char*)target);
}
int
UserInterface_TCL::showMsg(char* message, short extra_line_feeds, bool append)
{
// Replace double quotes with single quotes in order to show the
// message in Tcl
int len = strlen(message);
for (int i = 0; i < len; i++) {
if ( message[i] == '\"' ) {
message[i] = '\'';
}
}
ostrstream strm;
strm << message << tclArgSeparator;
strm << extra_line_feeds << tclArgSeparator;
strm << append;
strm << ends;
return sendCommandToGui(theInterp, "Interface::showMessage", strm.str());
}
void
UserInterface_TCL::showProgressMsg(Timer& timer, int frequency_nbr,
int nbr, int total_nbr,
char* text1, char* text2)
{
static char time_string[32];
// If no need to display progress message
if ( frequency_nbr > 0 &&
0 != (nbr % frequency_nbr) &&
nbr != total_nbr
)
return;
ostrstream strm;
strm << endl;
if (text1 != NULL)
strm << text1;
strm << total_nbr;
if (text2 != NULL)
strm << text2;
// If at the end (last item beig processed), display total time
if ( nbr == total_nbr ) {
double time = timer.getLapTime(WALL_TIME);
timer.formTimeString(time, time_string);
strm << " took " << time_string << ends;
showMsg(strm.str(), 0, false);
// Otherwise frequency criteria is met, display %-msg
} else {
double done = (int((1000.0 * nbr) / total_nbr)) / 10.0;
strm << "(";
strm << setiosflags(ios::right | ios::fixed);
strm << setw(4) << setprecision(1);
strm << done << "%)";
strm << ends;
// If first %-msg, append text
if (nbr == frequency_nbr) {
showMsg(strm.str(), 0, true);
// otherwise overwrite
} else {
showMsg(strm.str(), 0, false);
}
}
}
void
UserInterface_TCL::showUsedTimeMsg(double time, char* text,
short extra_line_feeds, bool append)
{
static char time_string[32];
formTimeString(time, time_string);
strstream strm;
strm << text
<< " took "
<< time_string
<< ends;
showMsg(strm.str(), extra_line_feeds, append);
}
void
UserInterface_TCL::showUsedTimeMsg(double time, char* text1, int nof_objects, char* text2,
short extra_line_feeds, bool append)
{
static char time_string[32];
formTimeString(time, time_string);
strstream strm;
strm << text1
<< " " << nof_objects << " "
<< text2
<< " took "
<< time_string
<< ends;
showMsg(strm.str(), extra_line_feeds, append);
}
void
UserInterface_TCL::start(int argc, char** argv)
{
char* elmer_home = (char *) Tcl_GetVar2(theInterp, "env", "ELMER_HOME", glob_flag);
char* elmer_front_home = (char *) Tcl_GetVar2(theInterp, "env", "ELMER_FRONT_HOME", glob_flag);
char front_tcl_path[] = "/tcl";
// ===================================
// SRCIPT FILE AND SCRIPT LIBRARY PATH
// ===================================
// These are buffers for the scriptfile and lib-path
// picking streams
char file_buffer[emf_MAX_STRING_LEN];
char lib_buffer[emf_MAX_STRING_LEN];
ostrstream file_strm(file_buffer, emf_MAX_STRING_LEN); // Start script name
ostrstream lib_strm(lib_buffer, emf_MAX_STRING_LEN); // Front TCL lib
bool path_found = false;
//---Find correct path for the start-script
//-1. try directly under local path:
if (!path_found) {
file_strm.seekp(0);
lib_strm.seekp(0);
file_strm << "./"
<< controlSideScript
<< ends;
lib_strm << "./"
<< ends;
// Try to open start-script!
printf("Trying %s\n",file_buffer);
if ( NULL != fopen(file_buffer, "r") ) {
path_found = true;
}
}
//-2. try directly under local TCL-path:
if (!path_found) {
file_strm.seekp(0);
lib_strm.seekp(0);
file_strm << "./tcl/"
<< controlSideScript
<< ends;
lib_strm << "./tcl/"
<< ends;
// Try to open start-script!
printf("Trying %s\n",file_buffer);
if ( NULL != fopen(file_buffer, "r") ) {
path_found = true;
}
}
//-3. try directly under ELMER_FRONT_HOME environment variables
if (!path_found) {
if (elmer_front_home != NULL) {
file_strm.seekp(0);
lib_strm.seekp(0);
file_strm << elmer_front_home
<< "/"
<< controlSideScript
<< ends;
lib_strm << elmer_front_home
<< "/"
<< ends;
printf("Trying %s\n",file_buffer);
// Try to open start-script!
if ( NULL != fopen(file_buffer, "r") ) {
path_found = true;
}
}
}
//-4. try TCL-path via ELMER_FRONT_HOME environment variables
if (!path_found) {
if (elmer_front_home != NULL) {
file_strm.seekp(0);
lib_strm.seekp(0);
file_strm << elmer_front_home
<< front_tcl_path << "/"
<< controlSideScript
<< ends;
lib_strm << elmer_front_home << "/"
<< front_tcl_path
<< "/"
<< ends;
printf("Trying %s\n",file_buffer);
// Try to open start-script!
if ( NULL != fopen(file_buffer, "r") ) {
path_found = true;
}
}
}
//-5. try TCL-path via installation prefix
if (!path_found) {
file_strm.seekp(0);
lib_strm.seekp(0);
file_strm << ELMER_FRONT_PREFIX
<< "/share/elmerfront"
<< front_tcl_path << "/"
<< controlSideScript
<< ends;
lib_strm << ELMER_FRONT_PREFIX
<< "/share/elmerfront/tcl/"
<< ends;
// Try to open start-script!
printf("Trying %s\n",file_buffer);
if ( NULL != fopen(file_buffer, "r") )
{
path_found = true;
}
}
//---Message to the user
// ERROR
if (!path_found) {
// Error message to file
((ofstream*)debugFile)->open("ElmerFront.log", ios::out);
if ( !debugFile->fail() ) {
*debugFile << "Can't run Elmer Front program." << endl;
*debugFile << "Script " << controlSideScript << " not found!" << endl;
}
// Error message to stdout
cerr << "Can't run Elmer Front program." << endl;
cerr << "Script " << controlSideScript << " not found!" << endl;
exit(1);
}
// OK
else {
cerr << "Running Elmer Front program." << endl
<< "Start script=" << file_buffer << endl;
}
//---We continue
//-Copy libpath-name to attribute *tclScriptPath*
int len = strlen(lib_buffer);
tclScriptPath = new char[len+1];
tclScriptPath[len] = '\0';
strcpy(tclScriptPath, lib_buffer);
//=====================
// LOAD GUI MAIN SCRIPT
//=====================
//---Load the SCRIPT specified in the fileName argument.
int code = Tcl_EvalFile(theInterp, file_buffer);
//--If we can't load the script (= start CONTROL-SIDE interpreter)
if (code != TCL_OK) {
char* p = (char *)Tcl_GetVar(theInterp, "errorInfo", glob_flag);
if ((p == NULL) || (*p == '\0')) {
p = theInterp->result;
}
((ofstream*)debugFile)->open("ElmerFront.log", ios::out);
*debugFile << "Can't run Elmer Front program. " << endl;
cerr << "Can't run Elmer Front program. " << endl;
*debugFile << "Not able to run Tcl-interpreter: " << p << endl;
cerr << "Not able to run Tcl-interpreter: " << p << endl;
exit(1);
}
//---Set path value for in the Tcl-environment (control-side, not GUI-side!)
writeVariable(theInterp, "Info", "frontScriptPath", tclScriptPath);
//---Set Elmer Front version numbers for the GUI-side
writeVariable(theInterp, "Info", "FRONT_PREVIOUS_INPUT_VERSION_NBR", -1);
writeVariable(theInterp, "Info", "FRONT_INPUT_VERSION_NBR", -1);
writeVariable(theInterp, "Info", "FRONT_MAIN_VERSION_NBR", ECIF_VERSION_NBR);
//---Handle posssible command line arguments
// NOTE: Check ecif_tclMainScript.tcl (proc handleCommandLineArguments)
// for available options!
// NOTE: We handle command line args here "quitely" to check if a settings-file name
// was given as an argument!
// NOTE: arguments will be reread in the gui-side, when all the nice
// message machinery has been loaded.
char* cmd_arguments = Tcl_Concat(argc, argv);
// Change to behave like Tcl-like dirnames
// NOTE: We should not use arguments which depend on back-slash!!!
for (int i = 0; i < strlen(cmd_arguments); i++) {
if ( cmd_arguments[i] == '\\' )
cmd_arguments[i] = '/';
}
// Transfer args to the gui side and read "quietly"
Tcl_SetVar2(theInterp, "Info", "commandLineArgs", cmd_arguments, glob_flag);
sendCommandToGui(theInterp, "handleCommandLineArgs");
//==========
// START GUI
//==========
//---Init Tk-environment
if (Tk_Init(theInterp) == TCL_ERROR) {
((ofstream*)debugFile)->open("ElmerFront.log", ios::out);
*debugFile << "Can't run Elmer Front program. " << endl;
cerr << "Can't run Elmer Front program. " << endl;
*debugFile << "Not able to run Tk-interpreter" << endl;
cerr << "Not able to run Tk-interpreter" << endl;
exit(1);
}
//---Start GUI
sendCommandToGui(theInterp, "startGUI", NULL);
Renderer_OGL::setRendererInfo();
//---Start Tcl-loop
while ( start_Tcl_MainLoop() );
}
bool
UserInterface_TCL::start_Tcl_MainLoop()
{
// Start Tcl-loop and don't continue when it is stops normally
Tcl_MainLoop();
return false;
}
int
UserInterface_TCL::from_tk_ColorHex2Name(ClientData clientData, Tcl_Interp *interp,
int argc, char* argv[])
{
Model* model = theControlCenter->getModel();
if (model == NULL) {
TheUI->errMsg(0, "ColorHex2Name: Command not legal. No model exists!");
return TCL_OK;
}
char buffer[64] = "";
char* hex_value = getCommandArguments(interp);
int code = model->rgbColor2Id(6, hex_value);
model->getColorName(code, buffer);
sendCommandToGui(interp, "Interface::getColorName", buffer);
return TCL_OK;
}
// Function writes all parameter data into Tk variables.
void
UserInterface_TCL::to_tk_WriteAllParamDataPre(Tcl_Interp* interp, const Model& model)
{
int nof_params = 20; // Nof parameters types
int nof_pstrms = 3; // Nof separate streams needed per parameter type
int ids_buffer[10000];
// NOTE: Keep these lists consistent!!!
//
ecif_parameterType param_types[] = {
ECIF_BODY_FORCE,
ECIF_BODY_PARAMETER,
ECIF_BOUNDARY_CONDITION,
ECIF_BOUNDARY_PARAMETER,
ECIF_CALCULATOR,
ECIF_CONSTANT,
ECIF_COORDINATE,
ECIF_DATAFILE,
ECIF_EQUATION,
ECIF_EQUATION_VARIABLE,
ECIF_GRID_H,
ECIF_GRID_PARAMETER,
ECIF_INITIAL_CONDITION,
ECIF_MATERIAL,
ECIF_MODEL_PARAMETER,
ECIF_SIMULATION_PARAMETER,
ECIF_SOLVER,
ECIF_SOLVER_CONTROL,
ECIF_TIMESTEP,
ECIF_USER_SETTING
};
char* param_arries[] = {
"BodyForce",
"BodyParameter",
"BoundaryCondition",
"BoundaryParameter",
"Calculator",
"Constant",
"Coordinate",
"Datafile",
"Equation",
"EquationVariable",
"GridH",
"GridParameter",
"InitialCondition",
"Material",
"ModelParameter",
"SimulationParameter",
"Solver",
"SolverControl",
"Timestep",
"UserSetting"
};
//Ups! An ugly cast needed owing to model's constant type. !!!***!!!
Model* mdl = (Model*) &model;
for (int i = 0; i < nof_params; i++) {
// Initial value
writeVariable(interp, param_arries[i], "ids", 0, (int*)NULL);
writeVariable(interp, param_arries[i], "nextNewParameterId", mdl->getNextNewParameterId(param_types[i]));
int index = 0;
while (true) {
Parameter* param = mdl->getParameter(index++, param_types[i]);
if (param==NULL) break;
int pid = param->ID();
ids_buffer[index - 1] = pid;
writeIdVariable(interp, param_arries[i], pid, "data", (char*)param->getValue());
writeIdVariable(interp, param_arries[i], pid, "name", (char*)param->getName());
writeIdVariable(interp, param_arries[i], pid, "oid", param->getParentId());
}
if (index > 1 ) {
writeVariable(interp, param_arries[i], "ids", index-1, ids_buffer);
}
}
// Process parameter data in Gui side
sendCommandToGui(interp, "Interface::applyAllParameterDataPre");
}
// Parameter mask related stuff
void
UserInterface_TCL::to_tk_WriteAllParamDataPost(Tcl_Interp* interp, const Model& model)
{
// Process parameter data in Gui side
sendCommandToGui(interp, "Interface::applyAllParameterDataPost");
// Write status for the following parameters
to_tk_WriteStatusEquations(interp, model);
to_tk_WriteStatusBodyForces(interp, model);
to_tk_WriteStatusBoundaryConditions(interp, model);
to_tk_WriteStatusInitialConditions(interp, model);
to_tk_WriteStatusMaterials(interp, model);
to_tk_WriteStatusTimesteps(interp, model);
to_tk_WriteStatusMeshes(interp, model);
}
// Write body layers to be used as Mesh structure panel objects
// NOTE: Layers are read via bodies and only unique layer-tags
// are inserted
//
void
UserInterface_TCL::to_tk_WriteBodyLayerData(Tcl_Interp* interp, const Model& model)
{
//Ups! An ugly cast needed owing to model's constant type. !!!***!!!
Model* mdl = (Model*) &model;
sendCommandToGui(interp, "Interface::resetObjectTableByType", "BL");
//----Loop all bodies
//
int index = 0;
while (true) {
Body* bd = mdl->getBody(index++);
if ( bd == NULL ) break;
// This is needed to store only unique layer tags
//
IdsSet layerTags;
std::pair<IdsSet::iterator, bool> lrPair;
//--Loop all layers in the body
//
for (int layer = 0; layer < bd->getNofLayers(); layer++) {
int lr_id = bd->getLayerId(layer);
BodyLayer* lr = mdl->getBodyLayerById(lr_id);
if (lr == NULL ) continue;
// Try to insert a new layer tag, check if it is already inserted
lrPair = layerTags.insert(lr->Tag());
// Layer tag exists for the body
if ( !lrPair.second ) continue;
int id = lr->Id();
const char* nm;
if ( lr->hasName() ) {
nm = lr->getName();
} else {
nm = bd->getName();
if ( bd->getNofLayers() > 1 ) {
strstream strm;
strm << nm << "-Lr" << lr->Tag() << ends;
nm = strm.str();
}
}
// Add layer id
writeVariable(interp, "ObjectTable", "ids", 1, &id, false);
writeIdVariable(interp, "ObjectTable", id, "tg", lr->getBodyTag());
writeIdVariable(interp, "ObjectTable", id, "tp", "BL");
if ( lr->isClosed() )
writeIdVariable(interp, "ObjectTable", id, "cl", "CSD");
else if ( lr->isOpen() )
writeIdVariable(interp, "ObjectTable", id, "cl", "OPN");
else
writeIdVariable(interp, "ObjectTable", id, "cl", "");
writeIdVariable(interp, "ObjectTable", id, "nm", nm);
writeIdVariable(interp, "ObjectTable", id, "bdId", lr->getBodyId());
writeIdVariable(interp, "ObjectTable", id, "sbIds", "");
writeIdVariable(interp, "ObjectTable", id, "sbTgs", "");
writeIdVariable(interp, "ObjectTable", id, "gr", NO_INDEX);
writeIdVariable(interp, "ObjectTable", id, "grIds", "");
writeIdVariable(interp, "ObjectTable", id, "grMshIndcs", "");
writeIdVariable(interp, "ObjectTable", id, "excldMsh", 0);
writeIdVariable(interp, "ObjectTable", id, "excldMshIndcs", "");
writeIdVariable(interp, "ObjectTable", id, "accptStrMsh", (int)bd->acceptsStructuredMesh(layer));
// NOTE: For layers sub ids are normal boundary ids (no groups etc.)
// because only htese are relevant in mesh structure panel where
// layer are used!
//
int nof_sb_ids;
int* sb_ids = NULL;
bd->getElementIds(layer, nof_sb_ids, sb_ids);
for (int i = 0; i< nof_sb_ids; i++) {
BodyElement* be = mdl->getBodyElementById(sb_ids[i]);
if ( be == NULL ) continue;
int be_id = be->Id();
int be_tg = be->Tag();
writeIdVariable(interp, "ObjectTable", id, "sbIds", 1, &be_id, false);
writeIdVariable(interp, "ObjectTable", id, "sbTgs", 1, &be_tg, false);
}
delete[] sb_ids;
int nof_gids = lr->getNofGridParameterIds();
if ( nof_gids > 0 ) {
writeIdVariable(interp, "ObjectTable", id, "grIds", nof_gids, lr->getGridParameterIds());
writeIdVariable(interp, "ObjectTable", id, "grMshIndcs", nof_gids, lr->getGridParameterMeshIndices());
}
int nof_mids = lr->getNofExcludedMeshes();
if ( nof_mids > 0 ) {
writeIdVariable(interp, "ObjectTable", id, "excldMshIndcs", nof_mids, lr->getExcludedMeshIndices());
}
}
}
}
// Function writes body-level data into Tk variables.
void
UserInterface_TCL::to_tk_WriteBodyData(Tcl_Interp* interp, const Model& model)
{
//Ups! An ugly cast needed owing to model's constant type. !!!***!!!
Model* mdl = (Model*) &model;
int nof_meshes = mdl->getNofMeshes();
char color_hex_string[6];
Color4 color;
// Clean old body object data
//
sendCommandToGui(interp, "Interface::resetObjectTableByType", "B"); // Body, normal close body
sendCommandToGui(interp, "Interface::resetObjectTableByType", "BP"); // Body, pair of non-virtual bodies
//----Loop all bodies
int index = 0;
while (true) {
Body* bd = mdl->getBody(index++);
if (bd==NULL) break;
int id = bd->Id();
// Body color
bd->getColor(color);
int color_id = mdl->rgbColor2Id(color);
mdl->rgbColorId2Hex(color_id, color_hex_string, 6);
// Add body id
writeVariable(interp, "ObjectTable", "ids", 1, &id, false);
// Init body variables in OBjectTable
//
// NOTE: Body/Bodypair subIds etc. for normal bodies are written
// via boundaries/boundary groups!
//
writeIdVariable(interp, "ObjectTable", id, "tg", bd->Tag());
writeIdVariable(interp, "ObjectTable", id, "tp", "B");
if ( !bd->isVirtual() ) {
if ( bd->isClosed() )
writeIdVariable(interp, "ObjectTable", id, "cl", "CSD");
else if ( bd->isOpen() )
writeIdVariable(interp, "ObjectTable", id, "cl", "OPN");
else
writeIdVariable(interp, "ObjectTable", id, "cl", "");
} else {
writeIdVariable(interp, "ObjectTable", id, "cl", "VIR");
}
writeIdVariable(interp, "ObjectTable", id, "nm", bd->getName());
writeIdVariable(interp, "ObjectTable", id, "blIds", ""); // Grid group ids
writeIdVariable(interp, "ObjectTable", id, "clr", color_hex_string);
writeIdVariable(interp, "ObjectTable", id, "msk", "");
writeIdVariable(interp, "ObjectTable", id, "prId", id); // Self reference!
writeIdVariable(interp, "ObjectTable", id, "pr1Id", id); // Self reference!
writeIdVariable(interp, "ObjectTable", id, "pr2Id", id); // Self reference!
writeIdVariable(interp, "ObjectTable", id, "sbIds", "");
writeIdVariable(interp, "ObjectTable", id, "sbTgs", "");
writeIdVariable(interp, "ObjectTable", id, "bodyp", bd->getBodyParameterId());
writeIdVariable(interp, "ObjectTable", id, "eq", bd->getEquationId());
writeIdVariable(interp, "ObjectTable", id, "mt", bd->getMaterialId());
writeIdVariable(interp, "ObjectTable", id, "ic", bd->getInitialConditionId());
writeIdVariable(interp, "ObjectTable", id, "bf", bd->getBodyForceId());
// Write layer info and grid info on each GridGroup
//
int layer = -1;
while (true) {
if (!bd->selectLayer(++layer)) break;
int layer_id = bd->getLayerId(layer);
int layer_tag = bd->getLayerTag(layer);
//--Add layer info for the body
writeIdVariable(interp, "ObjectTable", id, "blIds", 1, &layer_id, false);
}
// Body pairs for this body
// ========================
int bp_index = 0;
while (true) {
BodyPair* bp = mdl->getBodyPair(bp_index++);
if (bp==NULL) break;
const Body* body1;
const Body* body2;
bp->getBodies(body1, body2);
Body* bd1 = (Body*) body1;
Body* bd2 = (Body*) body2;
// "bd" must be the first body
if ( bd1 != bd ) {
continue;
}
int id = bp->Id();
writeVariable(interp, "ObjectTable", "ids", 1, &id, false);
writeIdVariable(interp, "ObjectTable", id, "tg", bp->Tag());
writeIdVariable(interp, "ObjectTable", id, "tp", "BP");
writeIdVariable(interp, "ObjectTable", id, "cl", "");
writeIdVariable(interp, "ObjectTable", id, "nm", bp->getName());
writeIdVariable(interp, "ObjectTable", id, "sbIds", "");
writeIdVariable(interp, "ObjectTable", id, "sbTgs", "");
writeIdVariable(interp, "ObjectTable", id, "msk", "");
writeIdVariable(interp, "ObjectTable", id, "prId", id); // Self reference!
writeIdVariable(interp, "ObjectTable", id, "pr1Id", bd1->Id());
writeIdVariable(interp, "ObjectTable", id, "pr2Id", bd2->Id());
} // All body-pairs for the body
} // All bodies
sendCommandToGui(interp, "Interface::applyBodyData");
}
// *** Write body level info to gui.
void
UserInterface_TCL::to_tk_WriteBodyInfoData(Tcl_Interp* interp, const Model& model)
{
const char* name;
RangeVector rv;
int nof_mesh_elements;
Model* mdl = (Model*) &model;
int index = 0;
while (true) {
Body* body = mdl->getBody(index++);
if (body==NULL) break;
int id = body->Id();
body->getRangeVector(rv);
nof_mesh_elements = body->getNofMeshElements();
writeIdVariable(interp, "ObjectTable", id, "mnX", rv[0]);
writeIdVariable(interp, "ObjectTable", id, "mxX", rv[1]);
writeIdVariable(interp, "ObjectTable", id, "mnY", rv[2]);
writeIdVariable(interp, "ObjectTable", id, "mxY", rv[3]);
writeIdVariable(interp, "ObjectTable", id, "mnZ", rv[4]);
writeIdVariable(interp, "ObjectTable", id, "mxZ", rv[5]);
writeIdVariable(interp, "ObjectTable", id, "nofMshElm", nof_mesh_elements);
}
}
// *** Write body level mesh info to gui.
void
UserInterface_TCL::to_tk_WriteBodyMeshInfoData(Tcl_Interp* interp, const Model& model)
{
char* name;
RangeVector rv;
int nof_mesh_elements;
Model* mdl = (Model*) &model;
int index = 0;
while (true) {
Body* body = mdl->getBody(index++);
if (body==NULL) break;
int id = body->Id();
nof_mesh_elements = body->getNofMeshElements();
writeIdVariable(interp, "ObjectTable", id, "nofMshElm", nof_mesh_elements);
}
}
// Function writes boundaries related data into Tk variables.
void
UserInterface_TCL::to_tk_WriteBoundaryData(Tcl_Interp* interp, const Model& model)
{
//Ups! An ugly cast needed owing to model's constant type. !!!***!!!
Model* mdl = (Model*) &model;
// Clean old boundary object data
//
sendCommandToGui(interp, "Interface::resetObjectTableByType", "V");
sendCommandToGui(interp, "Interface::resetObjectTableByType", "E");
sendCommandToGui(interp, "Interface::resetObjectTableByType", "F");
to_tk_WriteBoundaryElements(interp, mdl, OT_VERTEX);
to_tk_WriteBoundaryElements(interp, mdl, OT_EDGE);
to_tk_WriteBoundaryElements(interp, mdl, OT_FACE);
sendCommandToGui(interp, "Interface::applyBoundaryData");
}
// Function writes boundaries related data into Tk variables.
void
UserInterface_TCL::to_tk_WriteBoundaryElements(Tcl_Interp* interp, Model* model, objectType btype)
{
int nof_meshes = model->getNofMeshes();
bool only_active = true;
BodyElement* be = NULL;
int index = 0;
while (true) {
switch (btype) {
case OT_FACE:
be = model->getFace(index++, only_active);
break;
case OT_EDGE:
be = model->getEdge(index++, only_active);
break;
case OT_VERTEX:
be = model->getVertex(index++, only_active);
break;
}
if (be==NULL) break;
// Find parent for the boundary
//
int bd1_id = be->getParentId(1);
int bd2_id = be->getParentId(2);
int bd1_lr = be->getParentLayer(1);
int bd2_lr = be->getParentLayer(2);
Body* bd1 = model->getBodyById(bd1_id);
Body* bd2 = model->getBodyById(bd2_id);
BodyPair* bp = NULL;
bool is_intra_layer = be->isIntraLayerBoundary();
if ( bd1 != NULL && bd2 != NULL ) {
bp = model->getBodyPairById((const Body*)bd1, (const Body*)bd2);
}
int parent_oid;
if ( bp != NULL ) {
parent_oid = bp->Id();
} else if ( bd1 != NULL ) {
parent_oid = bd1->Id();
} else if ( bd2 != NULL ) {
parent_oid = bd2->Id();
} else {
parent_oid = NO_INDEX;
}
if ( parent_oid != NO_INDEX ) {
// NOTE: here body/body-pair sub-objects are normal boundaries!
// They are stored for parents in same ObjectTable variables
// as normal boundary groups (sbIds, sbTgs) !!!
//
int sub_oid = be->Id();
int sub_tag = be->Tag();
#if 0
// Info only to bodies
if ( bd1 != NULL && bd1_id != NO_INDEX ) {
writeIdVariable(interp, "ObjectTable", bd1_id, "sbIds", sub_oid, false);
writeIdVariable(interp, "ObjectTable", bd1_id, "sbTgs", sub_tag, false);
}
if ( bd2 != NULL && bd2_id != NO_INDEX ) {
writeIdVariable(interp, "ObjectTable", bd2_id,"sbIds", sub_oid, false);
writeIdVariable(interp, "ObjectTable", bd2_id, "sbTgs", sub_tag, false);
}
#endif
// Write subelement info into parent
writeIdVariable(interp, "ObjectTable", parent_oid, "sbIds", sub_oid, false);
writeIdVariable(interp, "ObjectTable", parent_oid, "sbTgs", sub_tag, false);
} // if parent-oid != NO_INDEX
// Store boundary data
// -------------------
int id = be->Id();
writeVariable(interp, "ObjectTable", "ids", 1, &id, false);
writeIdVariable(interp, "ObjectTable", id, "tg", be->Tag());
writeIdVariable(interp, "ObjectTable", id, "grpId", be->getElementGroupId());
writeIdVariable(interp, "ObjectTable", id, "cl", "");
writeIdVariable(interp, "ObjectTable", id, "msk", "");
writeIdVariable(interp, "ObjectTable", id, "nm", be->getName());
writeIdVariable(interp, "ObjectTable", id, "prId", parent_oid);
writeIdVariable(interp, "ObjectTable", id, "sbTgs", "");
writeIdVariable(interp, "ObjectTable", id, "sbIds", "");
writeIdVariable(interp, "ObjectTable", id, "bndrp", be->getBoundaryParameterId());
//writeIdVariable(interp, "ObjectTable", id, "bc", be->getBoundaryConditionId());
writeIdVariable(interp, "ObjectTable", id, "bc", NO_INDEX);
writeIdVariable(interp, "ObjectTable", id, "slctd", 0);
writeIdVariable(interp, "ObjectTable", id, "gh", NO_INDEX);
writeIdVariable(interp, "ObjectTable", id, "ghIds", "");
writeIdVariable(interp, "ObjectTable", id, "ghMshIndcs", "");
switch (btype) {
case OT_FACE:
writeIdVariable(interp, "ObjectTable", id, "tp", "F");
if ( be->isIntraLayerBoundary() ) {
writeIdVariable(interp, "ObjectTable", id, "cl", "ILB");
}
break;
case OT_EDGE:
writeIdVariable(interp, "ObjectTable", id, "tp", "E");
if ( model->getDimension() == ECIF_3D ) {
writeIdVariable(interp, "ObjectTable", id, "bc,vtbl", "");
} else if ( model->getDimension() == ECIF_2D ) {
// Init discretization data
writeIdVariable(interp, "ObjectTable", id, "nofCmp", "");
writeIdVariable(interp, "ObjectTable", id, "dscTp", "");
writeIdVariable(interp, "ObjectTable", id, "dscU", "");
writeIdVariable(interp, "ObjectTable", id, "dscV", "");
writeIdVariable(interp, "ObjectTable", id, "useFN", "");
if ( be->isIntraLayerBoundary() ) {
writeIdVariable(interp, "ObjectTable", id, "cl", "ILB");
}
}
break;
case OT_VERTEX:
writeIdVariable(interp, "ObjectTable", id, "tp", "V");
writeIdVariable(interp, "ObjectTable", id, "bc,vtbl", "");
//writeIdVariable(interp, "ObjectTable", id, "prIds", "");
break;
}
int nof_grid_hs = be->getNofGridHIds();
if ( nof_grid_hs > 0 ) {
writeIdVariable(interp, "ObjectTable", id, "ghIds", nof_grid_hs, be->getGridHIds());
writeIdVariable(interp, "ObjectTable", id, "ghMshIndcs", nof_grid_hs, be->getGridMeshIndices());
}
// Pick subelements ids
for (int i = 0; i < be->getNofSubElements(); i++) {
BodyElement* se = be->getSubElement(i);
// NOTE: this should not happend!
if ( se == NULL ) {
continue;
}
int se_tag = se->Tag();
int se_oid = se->Id();
writeIdVariable(interp, "ObjectTable", id, "sbTgs", se_tag, false);
writeIdVariable(interp, "ObjectTable", id, "sbIds", se_oid, false);
if ( btype == OT_EDGE ) {
writeIdVariable(interp, "ObjectTable", se_oid, "prIds", id, false);
}
}
// Set discretization data
//
if ( model->getDimension() == ECIF_2D && btype == OT_EDGE ) {
int cnt = 0;
linDeltaType* types = NULL;
double* valuesU = NULL;
double* valuesV = NULL;
bool* useFixedN = NULL;
strstream strm;
be->getDiscretizationData(cnt, types, valuesU, valuesV, useFixedN);
if ( cnt > 0 ) {
writeIdVariable(interp, "ObjectTable", id, "nofCmp", cnt);
for (int i = 0; i < cnt; i++) {
if ( types != NULL ) {
switch (types[i] ) {
case LIN_DELTA_NONE: strm << '-'; break;
case LIN_DELTA_H: strm << 'H'; break;
case LIN_DELTA_N: strm << 'N'; break;
case LIN_DELTA_U: strm << 'U'; break;
}
}
if ( valuesU != NULL ) {
writeIdVariable(interp, "ObjectTable", id, "dscU", valuesU[i], false);
}
if ( useFixedN != NULL ) {
writeIdVariable(interp, "ObjectTable", id, "useFN", (int)useFixedN[i], false);
}
}
if ( types != NULL ) {
strm << ends;
writeIdVariable(interp, "ObjectTable", id, "dscTp", strm.str());
}
}
} // Set discretization data
}
}
// Function writes boundary group related data into Tk variables.
void
UserInterface_TCL::to_tk_WriteElementGroupData(Tcl_Interp* interp, const Model& model)
{
//Ups! An ugly cast needed owing to model's constant type. !!!***!!!
Model* mdl = (Model*) &model;
// Clean old boundary object data
//
sendCommandToGui(interp, "Interface::resetObjectTableByType", "FG");
sendCommandToGui(interp, "Interface::resetObjectTableByType", "EG");
sendCommandToGui(interp, "Interface::resetObjectTableByType", "VG");
int index = 0;
while (true) {
BodyElementGroup* beg = mdl->getBodyElementGroup(index++);
if (beg==NULL) break;
if ( beg->getNofElements() == 0 ) continue;
// Parent info for the boundary group
//
int bd1_id = beg->getParentId(1);
int bd2_id = beg->getParentId(2);
int bd1_lr = beg->getParentLayer(1);
int bd2_lr = beg->getParentLayer(2);
Body* bd1 = mdl->getBodyById(bd1_id);
Body* bd2 = mdl->getBodyById(bd2_id);
BodyPair* bp = NULL;
if ( bd1 != NULL && bd2 != NULL ) {
bp = mdl->getBodyPairById((const Body*)bd1, (const Body*)bd2);
}
int parent_oid;
if ( bp != NULL ) {
parent_oid = bp->Id();
} else if ( bd1 != NULL ) {
parent_oid = bd1->Id();
} else if ( bd2 != NULL ) {
parent_oid = bd2->Id();
} else {
parent_oid = NO_INDEX;
}
if ( parent_oid != NO_INDEX ) {
// NOTE: here body/body-pair sub-objects are boundary groups!
// They are stored for parents in same ObjectTable variables
// as normal boundaries (sbIds, sbTgs) !!!
//
int sub_oid = beg->Id();
int sub_tag = beg->Tag();
// Write subelement info into parent
writeIdVariable(interp, "ObjectTable", parent_oid, "sbIds", sub_oid, false);
writeIdVariable(interp, "ObjectTable", parent_oid, "sbTgs", sub_tag, false);
}
const char* nm;
int tg;
// For an implicit group we use boundary's name and tag
if ( beg->isImplicit() ) {
BodyElement* be = (BodyElement*)beg->getElement(0);
if ( be != NULL ) {
nm = be->getName();
tg = be->Tag();
} else {
nm = "Unknown";
tg = NO_INDEX;
}
// For an explicit and virtual group we use its own name and tag
} else {
nm = beg->getName();
tg = beg->Tag();
}
// Store boundary group data
// -------------------------
int id = beg->Id();
writeVariable(interp, "ObjectTable", "ids", 1, &id, false);
writeIdVariable(interp, "ObjectTable", id, "tg", tg);
switch (beg->getElementType()) {
case OT_FACE:
writeIdVariable(interp, "ObjectTable", id, "tp", "FG");
break;
case OT_EDGE:
writeIdVariable(interp, "ObjectTable", id, "tp", "EG");
if ( mdl->getDimension() == ECIF_3D )
writeIdVariable(interp, "ObjectTable", id, "bc,vtbl", "");
break;
case OT_VERTEX:
writeIdVariable(interp, "ObjectTable", id, "tp", "VG");
writeIdVariable(interp, "ObjectTable", id, "bc,vtbl", "");
break;
}
if ( beg->isImplicit() )
writeIdVariable(interp, "ObjectTable", id, "cl", "IMP");
else if ( beg->isExplicit() )
writeIdVariable(interp, "ObjectTable", id, "cl", "EXP");
else if ( beg->isVirtual() )
writeIdVariable(interp, "ObjectTable", id, "cl", "VIR");
else
writeIdVariable(interp, "ObjectTable", id, "cl", "");
writeIdVariable(interp, "ObjectTable", id, "msk", "");
writeIdVariable(interp, "ObjectTable", id, "nm", nm);
writeIdVariable(interp, "ObjectTable", id, "prId", parent_oid);
writeIdVariable(interp, "ObjectTable", id, "mbrIds", "");
writeIdVariable(interp, "ObjectTable", id, "sbTgs", "");
writeIdVariable(interp, "ObjectTable", id, "sbIds", "");
writeIdVariable(interp, "ObjectTable", id, "bndrp", beg->getBoundaryParameterId());
writeIdVariable(interp, "ObjectTable", id, "bc", beg->getBoundaryConditionId());
writeIdVariable(interp, "ObjectTable", id, "slctd", 0);
// NOTE: We do not show subelements for virtual groups
//
// If ex. some vertices should also be available in the bc-panel, the user
// should make a virtual vertex-group and add this to the same body where
// this group is
//
if ( beg->isVirtual() ) continue;
// Store boundary and subelement (=subelements boundary group) info
// -----------------------------
// This is needed to store only unique sub-id entries
//
IdsSet subIds;
std::pair<IdsSet::iterator, bool> subPair;
for (int i = 0; i < beg->getNofElements(); i++) {
BodyElement* be = mdl->getBodyElementById(beg->getElementId(i));
// Store group's member (boundary) id
//
writeIdVariable(interp, "ObjectTable", id, "mbrIds", be->Id(), false);
for (int j = 0; j < be->getNofSubElements(); j++) {
BodyElement* se = be->getSubElement(j);
// Get sub-element boundary group ids
int sg_oid = se->getElementGroupId();
int sg_tag = se->getElementGroupTag();
// Try to insert a new sub-id and check if it is already inserted
subPair = subIds.insert(sg_oid);
// Sub-id already stored
if ( !subPair.second ) continue;
writeIdVariable(interp, "ObjectTable", id, "sbTgs", sg_tag, false);
writeIdVariable(interp, "ObjectTable", id, "sbIds", sg_oid, false);
}
}
} // All groups
}
// *** Function sets model status flag for gui.
void
UserInterface_TCL::to_tk_WriteControlParameters(Tcl_Interp* interp, const Model& model)
{
writeVariable(interp, "Info", "maxNormalTolerance", MAX_NORMAL_TOLERANCE);
writeVariable(interp, "Info", "maxDistanceTolerance", MAX_DISTANCE_TOLERANCE);
writeVariable(interp, "Info", "normalTolerance", NORMAL_TOLERANCE);
writeVariable(interp, "Info", "distanceTolerance", DISTANCE_TOLERANCE);
}
// *** Function sets model level objects/'elements' data for gui.
void
UserInterface_TCL::to_tk_WriteModelData(Tcl_Interp* interp, const Model& model)
{
int i;
const ModelInfo* mi = model.getModelInfo();
char* cval = NULL;
// Model input version numbers. Needed for possible old version
// conversion etc.
writeVariable(theInterp, "Info", "FRONT_PREVIOUS_INPUT_VERSION_NBR", mi->frontPreviousInputVersionNbr);
writeVariable(theInterp, "Info", "FRONT_INPUT_VERSION_NBR", mi->frontInputVersionNbr);
// Flag for using values in model
int use_model_settings = 0;
readVariable(interp, "UserSetting", "DEFAULT_USE_MODEL_SETTINGS", use_model_settings);
writeVariable(interp, "ModelProperty", "MODEL_NAME", mi->modelName);
writeVariable(interp, "ModelProperty", "PROBLEM_NAME", mi->problemName);
writeVariable(interp, "ModelProperty", "MODEL_DESCRIPTION", mi->modelDescription);
writeVariable(interp, "ModelProperty", "PROBLEM_DESCRIPTION", mi->problemDescription);
// Read values from model file
if (use_model_settings ) {
cval = mi->includePath;
if ( cval != NULL && cval[0] != '\0' ) {
writeVariable(interp, "ModelProperty", "INCLUDE_PATH", cval);
writeVariable(interp, "ModelProperty", "INCLUDE_PATH,model", cval);
writeVariable(interp, "ModelProperty", "INCLUDE_PATH,model,save", 1);
}
cval = mi->resultsDirectory;
if ( cval != NULL && cval[0] != '\0' ) {
writeVariable(interp, "ModelProperty", "RESULTS_DIRECTORY", cval);
writeVariable(interp, "ModelProperty", "RESULTS_DIRECTORY,model", cval);
writeVariable(interp, "ModelProperty", "RESULTS_DIRECTORY,model,save", 1);
}
cval = mi->temporaryFilesDirectory;
if ( cval != NULL && cval[0] != '\0' ) {
writeVariable(interp, "ModelProperty", "LOG_DIRECTORY", cval);
writeVariable(interp, "ModelProperty", "LOG_DIRECTORY.model", cval);
writeVariable(interp, "ModelProperty", "LOG_DIRECTORY,model,save", 1);
}
}
// History
writeVariable(interp, "Model", "created", mi->created);
writeVariable(interp, "Model", "modified", mi->modified);
writeVariable(interp, "Model", "hasUserDefinitions", mi->hasUserDefinitions);
// Source files
writeVariable(interp, "Model", "cadPath", mi->cadSourceFile);
writeVariable(interp, "Model", "meshPath", mi->meshSourceFile);
// Matc input files
writeVariable(interp, "Model", "matcInputFile_emf", mi->matcInputFile_emf);
writeVariable(interp, "Model", "matcInputFile_sif", mi->matcInputFile_sif);
// Timestamps
writeVariable(interp, "Model", "Database,timestamp", mi->databaseTs);
writeVariable(interp, "Model", "GebhardtFactors,timestamp", mi->gebhardtFactorsTs);
writeVariable(interp, "Model", "MeshParameter,timestamp", mi->meshParameterTs);
writeVariable(interp, "Model", "Mesh,timestamp", mi->meshTs);
writeVariable(interp, "Model", "Solver,timestamp", mi->solverTs);
writeVariable(interp, "Model", "Viewfactors,timestamp", mi->viewfactorsTs);
// Mesh names and control
// ======================
writeVariable(interp, "Model", "meshNames", "");
writeVariable(interp, "Model", "meshHs", "");
writeVariable(interp, "Model", "meshFs", "");
writeVariable(interp, "Model", "currentMeshIndex", mi->currentMeshIndex);
int nof_meshes = mi->nofMeshes;
for (i = 0; i < nof_meshes; i++) {
writeVariable(interp, "Model", "meshNames", mi->meshNames[i], false);
if ( mi->meshHs != NULL ) {
writeVariable(interp, "Model", "meshHs", mi->meshHs[i], false);
writeVariable(interp, "Model", "meshFs", mi->meshFs[i], false);
}
}
// Bg mesh files
// =============
writeVariable(interp, "Model", "meshBgMeshFileIndices", "");
writeVariable(interp, "Model", "meshBgMeshFiles", "");
writeVariable(interp, "Model", "meshBgMeshActives", "");
writeVariable(interp, "Model", "meshBgMeshControls", "");
int nof_files = mi->nofBgMeshFiles;
for (i = 0; i < nof_files; i++) {
writeVariable(interp, "Model", "meshBgMeshFileIndices", mi->meshBgMeshFileIndices[i], false);
writeVariable(interp, "Model", "meshBgMeshFiles", mi->meshBgMeshFiles[i], false);
writeVariable(interp, "Model", "meshBgMeshActives", mi->meshBgMeshActives[i], false);
writeVariable(interp, "Model", "meshBgMeshControls", mi->meshBgMeshControls[i], false);
}
// Apply data in Gui
sendCommandToGui(interp, "Interface::applyModelData");
}
// *** Function sets model status flag for gui.
void
UserInterface_TCL::to_tk_WriteModelStatus(Tcl_Interp* interp, const Model& model)
{
writeVariable(interp, "Model", "status", model.getModelStatus());
sendCommandToGui(interp, "Interface::applyModelStatus");
}
// *** Function writes model status message for gui.
void
UserInterface_TCL::to_tk_WriteModelStatusMessage(Tcl_Interp* interp, const Model& model)
{
ostrstream strm;
model.getModelStatusMessage(strm);
strm << ends;
writeVariable(interp, "Model", "statusMessage", strm.str());
}
// *** Function sets model geometry-dimesnion (2D/3D) variable for gui.
void
UserInterface_TCL::to_tk_WriteModelGeometryDimension(Tcl_Interp* interp, const Model& model)
{
if ( model.getDimension() == ECIF_2D)
writeVariable(interp, "Model", "GEOMETRY_DIMENSION", "2D");
else
writeVariable(interp, "Model", "GEOMETRY_DIMENSION", "3D");
sendCommandToGui(interp, "Interface::applyModelGeometryDimension");
}
// *** Function sets model flags for gui.
void
UserInterface_TCL::to_tk_WriteModelFlags(Tcl_Interp* interp, const Model& model)
{
Model* mdl = (Model*)&model;
writeVariable(interp, "ModelFlags", "GEOMETRY_TYPE_CAD", mdl->getFlagValue(GEOMETRY_TYPE_CAD));
writeVariable(interp, "ModelFlags", "GEOMETRY_TYPE_MESH", mdl->getFlagValue(GEOMETRY_TYPE_MESH));
writeVariable(interp, "ModelFlags", "GEOMETRY_EDITED_BODIES", mdl->getFlagValue(GEOMETRY_EDITED_BODIES));
writeVariable(interp, "ModelFlags", "GEOMETRY_EDITED_BOUNDARIES", mdl->getFlagValue(GEOMETRY_EDITED_BOUNDARIES));
writeVariable(interp, "ModelFlags", "DRAW_SOURCE_CAD", mdl->getFlagValue(DRAW_SOURCE_CAD));
writeVariable(interp, "ModelFlags", "DRAW_SOURCE_MESH", mdl->getFlagValue(DRAW_SOURCE_MESH));
writeVariable(interp, "ModelFlags", "DRAW_TARGET_BODIES", mdl->getFlagValue(DRAW_TARGET_BODIES));
writeVariable(interp, "ModelFlags", "DRAW_TARGET_SURFACES", mdl->getFlagValue(DRAW_TARGET_SURFACES));
writeVariable(interp, "ModelFlags", "DRAW_TARGET_EDGES", mdl->getFlagValue(DRAW_TARGET_EDGES));
writeVariable(interp, "ModelFlags", "LABEL_DISPLAY_NODE", mdl->getFlagValue(LABEL_DISPLAY_NODE));
writeVariable(interp, "ModelFlags", "LABEL_DISPLAY_ELEMENT", mdl->getFlagValue(LABEL_DISPLAY_ELEMENT));
writeVariable(interp, "ModelFlags", "LABEL_DISPLAY_VERTEX", mdl->getFlagValue(LABEL_DISPLAY_VERTEX));
writeVariable(interp, "ModelFlags", "LABEL_DISPLAY_EDGE", mdl->getFlagValue(LABEL_DISPLAY_EDGE));
writeVariable(interp, "ModelFlags", "LABEL_DISPLAY_FACE", mdl->getFlagValue(LABEL_DISPLAY_FACE));
writeVariable(interp, "ModelFlags", "LABEL_DISPLAY_BODY", mdl->getFlagValue(LABEL_DISPLAY_BODY));
sendCommandToGui(interp, "Interface::applyModelFlags");
}
// *** Function sets values for Tcl-variables in the Statistic-panel.
void
UserInterface_TCL::to_tk_WriteProcessorData(Tcl_Interp* interp, const Model& model)
{
const ParallelInfo* pi = model.getParallelInfo();
ostrstream strm;
strm << pi->nofProcessors;
strm << ends;
sendCommandToGui(interp, "Interface::getParallelInfo", strm.str());
}
// *** Function sets values for Tcl-variables in the Statistic-panel.
void
UserInterface_TCL::to_tk_WriteStats(Tcl_Interp* interp, const Model& model)
{
const ModelStatistics* mstats = model.getModelStatistics();
const ModelInfo* minfo = model.getModelInfo();
const MeshInfo* mesh_info = model.getMeshInfo();
writeVariable(interp, "Model", "nofBodies", mstats->nofBodies);
writeVariable(interp, "Model", "nofElements", mstats->nofOuterBoundaries + mstats->nofInnerBoundaries);
writeVariable(interp, "Model", "nofOuterBoundaries", mstats->nofOuterBoundaries);
writeVariable(interp, "Model", "nofInnerBoundaries", mstats->nofInnerBoundaries);
writeVariable(interp, "Model", "nofVertices", mstats->nofVertices);
writeVariable(interp, "Model", "minEdgeSize", minfo->minEdgeSize);
// Reasonable cad geometry
if (minfo->minX < minfo->maxX) {
writeVariable(interp, "Model", "minX", minfo->minX);
writeVariable(interp, "Model", "maxX", minfo->maxX);
writeVariable(interp, "Model", "minY", minfo->minY);
writeVariable(interp, "Model", "maxY", minfo->maxY);
writeVariable(interp, "Model", "minZ", minfo->minZ);
writeVariable(interp, "Model", "maxZ", minfo->maxZ);
// Mesh geometry
} else {
writeVariable(interp, "Model", "minX", mesh_info->minX);
writeVariable(interp, "Model", "maxX", mesh_info->maxX);
writeVariable(interp, "Model", "minY", mesh_info->minY);
writeVariable(interp, "Model", "maxY", mesh_info->maxY);
writeVariable(interp, "Model", "minZ", mesh_info->minZ);
writeVariable(interp, "Model", "maxZ", mesh_info->maxZ);
}
int nof_zv_elements = mesh_info->nofZeroVelocityElements;
int nof_sp_elements = mesh_info->nofSplittedElements;
writeVariable(interp, "Model", "nofMeshElements", mesh_info->nofBulkElements);
writeVariable(interp, "Model", "nofMeshSplittedElements", nof_sp_elements);
writeVariable(interp, "Model", "nofMeshZeroVelocityElements", nof_zv_elements);
writeVariable(interp, "Model", "nofMeshBndrElements", mesh_info->nofBoundaryElements);
writeVariable(interp, "Model", "nofMeshInnerBndrElements", mesh_info->nofInnerBndrElements);
writeVariable(interp, "Model", "nofMeshOuterBndrElements", mesh_info->nofOuterBndrElements);
writeVariable(interp, "Model", "nofMeshNodes", mesh_info->nofNodes);
sendCommandToGui(interp, "Interface::applyStatsData");
}
// *** Function sets model's bodyforce parameters' status field for gui.
void
UserInterface_TCL::to_tk_WriteStatusBodyForces(Tcl_Interp* interp, const Model& model)
{
const ModelStatistics* st = model.getModelStatistics();
int count = st->nofBodiesWithBodyForce;
writeVariable(interp, "Model", "nofBodiesWithBodyForce", count);
sendCommandToGui(interp, "Interface::setStatusBodyForces");
}
// *** Function sets model's material parameters' status field for gui.
void
UserInterface_TCL::to_tk_WriteStatusBoundaryConditions(Tcl_Interp* interp, const Model& model)
{
const ModelStatistics* st = model.getModelStatistics();
int count;
count = st->nofOuterBoundariesWithCondition;
writeVariable(interp, "Model", "nofOuterBoundariesWithCondition", count);
sendCommandToGui(interp, "Interface::setStatusOuterBoundaryConditions");
count = st->nofInnerBoundariesWithCondition;
writeVariable(interp, "Model", "nofInnerBoundariesWithCondition", count);
sendCommandToGui(interp, "Interface::setStatusInnerBoundaryConditions");
}
// *** Function sets model's equation parameters' status field for gui.
void
UserInterface_TCL::to_tk_WriteStatusEquations(Tcl_Interp* interp, const Model& model)
{
const ModelStatistics* st = model.getModelStatistics();
int count = st->nofBodiesWithEquation;
writeVariable(interp, "Model", "nofBodiesWithEquation", count);
sendCommandToGui(interp, "Interface::setStatusEquations");
}
// *** Function sets model's initial condition parameters' status field for gui.
void
UserInterface_TCL::to_tk_WriteStatusInitialConditions(Tcl_Interp* interp, const Model& model)
{
const ModelStatistics* st = model.getModelStatistics();
int count = st->nofBodiesWithInitialCondition;
writeVariable(interp, "Model", "nofBodiesWithInitialCondition", count);
sendCommandToGui(interp, "Interface::setStatusInitialConditions");
}
// *** Function sets model's material parameters' status field for gui.
void
UserInterface_TCL::to_tk_WriteStatusMaterials(Tcl_Interp* interp, const Model& model)
{
const ModelStatistics* st = model.getModelStatistics();
int count = st->nofBodiesWithMaterial;
writeVariable(interp, "Model", "nofBodiesWithMaterial", count);
sendCommandToGui(interp, "Interface::setStatusMaterials");
}
// *** Function sets model's meshes status field for gui.
void
UserInterface_TCL::to_tk_WriteStatusMeshes(Tcl_Interp* interp, const Model& model)
{
sendCommandToGui(interp, "Interface::setStatusMeshes");
}
// *** Function sets model's timestep parameter's status field for gui.
void
UserInterface_TCL::to_tk_WriteStatusTimesteps(Tcl_Interp* interp, const Model& model)
{
Model* mdl = (Model*) &model;
int count = mdl->getNofTimestepSteps();
writeVariable(interp, "Model", "nofTimesteps", count);
sendCommandToGui(interp, "Interface::setStatusTimestamps");
}
// Convert variable's gui-name (like "oxygen") to sif-name like ("OxyGen")
void
UserInterface_TCL::variableNameGuiToSif(const char* gui_name, char* sif_name_buffer)
{
sendCommandToGui(theInterp, "Interface::variableNameGuiToSif", gui_name);
strcpy(sif_name_buffer, getCommandResults(theInterp));
}
// Convert variables's sif-name (like "Some Quantity") to gui-name ("some_quantity")
void
UserInterface_TCL::variableNameSifToGui(const char* sif_name, char* gui_name_buffer)
{
sendCommandToGui(theInterp, "Interface::variableNameSifToGui", sif_name);
strcpy(gui_name_buffer, getCommandResults(theInterp));
}
// Id Array, integer id, single value
// ----------------------------------
void
UserInterface_TCL::writeIdVariable(Tcl_Interp* interp, const char* array, int id,
const char* variable,
const char* value,
bool reset)
{
strstream field_name;
field_name << id << "," << variable << ends;
writeVariable_impl_1(interp, array, field_name.str(), value, reset);
}
void
UserInterface_TCL::writeIdVariable(Tcl_Interp* interp, const char* array, int id,
const char* variable,
int value,
bool reset)
{
strstream field_name;
field_name << id << "," << variable << ends;
writeVariable_impl_1(interp, array, field_name.str(), value, reset);
}
void
UserInterface_TCL::writeIdVariable(Tcl_Interp* interp, const char* array, int id,
const char* variable,
ProcessId value,
bool reset)
{
strstream field_name;
field_name << id << "," << variable << ends;
writeVariable_impl_1(interp, array, field_name.str(), value, reset);
}
void
UserInterface_TCL::writeIdVariable(Tcl_Interp* interp, const char* array, int id,
const char* variable,
double value,
bool reset)
{
strstream field_name;
field_name << id << "," << variable << ends;
writeVariable_impl_1(interp, array, field_name.str(), value, reset);
}
// Id Array, integer id, list of values
// ------------------------------------
void
UserInterface_TCL::writeIdVariable(Tcl_Interp* interp, const char* array, int id,
const char* variable,
int size, const char** values,
bool reset)
{
strstream field_name;
field_name << id << "," << variable << ends;
writeVariable_impl_n(interp, array, field_name.str(), size, values, reset);
}
void
UserInterface_TCL::writeIdVariable(Tcl_Interp* interp, const char* array, int id,
const char* variable,
int size, const int* values,
bool reset)
{
strstream field_name;
field_name << id << "," << variable << ends;
writeVariable_impl_n(interp, array, field_name.str(), size, values, reset);
}
void
UserInterface_TCL::writeIdVariable(Tcl_Interp* interp, const char* array, int id,
const char* variable,
int size, const double* values,
bool reset)
{
strstream field_name;
field_name << id << "," << variable << ends;
writeVariable_impl_n(interp, array, field_name.str(), size, values, reset);
}
// Id Array, string id, single value
// ---------------------------------
void
UserInterface_TCL::writeIdVariable(Tcl_Interp* interp, const char* array, const char* id,
const char* variable,
const char* value,
bool reset)
{
strstream field_name;
field_name << id << "," << variable << ends;
writeVariable_impl_1(interp, array, field_name.str(), value, reset);
}
void
UserInterface_TCL::writeIdVariable(Tcl_Interp* interp, const char* array, const char* id,
const char* variable,
int value,
bool reset)
{
strstream field_name;
field_name << id << "," << variable << ends;
writeVariable_impl_1(interp, array, field_name.str(), value, reset);
}
void
UserInterface_TCL::writeIdVariable(Tcl_Interp* interp, const char* array, const char* id,
const char* variable,
ProcessId value,
bool reset)
{
strstream field_name;
field_name << id << "," << variable << ends;
writeVariable_impl_1(interp, array, field_name.str(), value, reset);
}
void
UserInterface_TCL::writeIdVariable(Tcl_Interp* interp, const char* array, const char* id,
const char* variable,
double value,
bool reset)
{
strstream field_name;
field_name << id << "," << variable << ends;
writeVariable_impl_1(interp, array, field_name.str(), value, reset);
}
// Id Array, string id, list of values
// -----------------------------------
void
UserInterface_TCL::writeIdVariable(Tcl_Interp* interp, const char* array, const char* id,
const char* variable,
int size, const char** values,
bool reset)
{
strstream field_name;
field_name << id << "," << variable << ends;
writeVariable_impl_n(interp, array, field_name.str(), size, values, reset);
}
void
UserInterface_TCL::writeIdVariable(Tcl_Interp* interp, const char* array, const char* id,
const char* variable,
int size, const int* values,
bool reset)
{
strstream field_name;
field_name << id << "," << variable << ends;
writeVariable_impl_n(interp, array, field_name.str(), size, values, reset);
}
void
UserInterface_TCL::writeIdVariable(Tcl_Interp* interp, const char* array, const char* id,
const char* variable,
int size, const double* values,
bool reset)
{
strstream field_name;
field_name << id << "," << variable << ends;
writeVariable_impl_n(interp, array, field_name.str(), size, values, reset);
}
// Id2 Array, integer id1,id2, single value
// ----------------------------------------
void
UserInterface_TCL::writeId2Variable(Tcl_Interp* interp, const char* array, int id1, int id2,
const char* variable,
const char* value,
bool reset)
{
strstream field_name;
field_name << id1 << subIdSep << id2 << "," << variable << ends;
writeVariable_impl_1(interp, array, field_name.str(), value, reset);
}
void
UserInterface_TCL::writeId2Variable(Tcl_Interp* interp, const char* array, int id1, int id2,
const char* variable,
int value,
bool reset)
{
strstream field_name;
field_name << id1 << subIdSep << id2 << "," << variable << ends;
writeVariable_impl_1(interp, array, field_name.str(), value, reset);
}
void
UserInterface_TCL::writeId2Variable(Tcl_Interp* interp, const char* array, int id1, int id2,
const char* variable,
ProcessId value,
bool reset)
{
strstream field_name;
field_name << id1 << subIdSep << id2 << "," << variable << ends;
writeVariable_impl_1(interp, array, field_name.str(), value, reset);
}
void
UserInterface_TCL::writeId2Variable(Tcl_Interp* interp, const char* array, int id1, int id2,
const char* variable,
double value,
bool reset)
{
strstream field_name;
field_name << id1 << subIdSep << id2 << "," << variable << ends;
writeVariable_impl_1(interp, array, field_name.str(), value, reset);
}
// Id2 Array, integer id1, id2, list of values
// -------------------------------------------
void
UserInterface_TCL::writeId2Variable(Tcl_Interp* interp, const char* array, int id1, int id2,
const char* variable,
int size, const char** values,
bool reset)
{
strstream field_name;
field_name << id1 << subIdSep << id2 << "," << variable << ends;
writeVariable_impl_n(interp, array, field_name.str(), size, values, reset);
}
void
UserInterface_TCL::writeId2Variable(Tcl_Interp* interp, const char* array, int id1, int id2,
const char* variable,
int size, const int* values,
bool reset)
{
strstream field_name;
field_name << id1 << subIdSep << id2 << "," << variable << ends;
writeVariable_impl_n(interp, array, field_name.str(), size, values, reset);
}
void
UserInterface_TCL::writeId2Variable(Tcl_Interp* interp, const char* array, int id1, int id2,
const char* variable,
int size, const double* values,
bool reset)
{
strstream field_name;
field_name << id1 << subIdSep << id2 << "," << variable << ends;
writeVariable_impl_n(interp, array, field_name.str(), size, values, reset);
}
// Array, single value
// -------------------
void
UserInterface_TCL::writeVariable(Tcl_Interp* interp,
const char* array, const char* variable,
const char* value,
bool reset)
{
writeVariable_impl_1(interp, array, variable, value, reset);
}
void
UserInterface_TCL::writeVariable(Tcl_Interp* interp,
const char* array, const char* variable,
int value,
bool reset)
{
writeVariable_impl_1(interp, array, variable, value, reset);
}
void
UserInterface_TCL::writeVariable(Tcl_Interp* interp,
const char* array, const char* variable,
double value,
bool reset)
{
writeVariable_impl_1(interp, array, variable, value, reset);
}
// Array, list of values
// ---------------------
void
UserInterface_TCL::writeVariable(Tcl_Interp* interp,
const char* array, const char* variable,
int size, const char** values,
bool reset)
{
writeVariable_impl_n(interp, array, variable, size, values, reset);
}
void
UserInterface_TCL::writeVariable(Tcl_Interp* interp,
const char* array, const char* variable,
int size, const int* values,
bool reset)
{
writeVariable_impl_n(interp, array, variable, size, values, reset);
}
void
UserInterface_TCL::writeVariable(Tcl_Interp* interp,
const char* array, const char* variable,
int size, const double* values,
bool reset)
{
writeVariable_impl_n(interp, array, variable, size, values, reset);
}
// *** Function sets single value to array-type Tcl variable.
template <class T > void
UserInterface_TCL::writeVariable_impl_1(Tcl_Interp* interp,
const char* array, const char* variable,
const T value, bool reset)
{
Tcl_Obj* array_obj = Tcl_NewStringObj(NULL, 0);
Tcl_Obj* value_obj = NULL;
int tcl_flags = TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG;
// We have to create a tcl string-object to
// carry the variable names. Here we use a fully
// specified array name to create the name-object
tcl_flags |= TCL_PARSE_PART1;
strstream strm;
strm << array << "(" << variable << ")" << ends;
char* array_name = strm.str();
Tcl_SetStringObj(array_obj, array_name, strlen(array_name));
// Try to get existing variable handle
// NOTE! This does not seem to be working!!! At least not for
// strings like Default-directories in the settings files.
// They all get the last string values if this is used
// Try to get existing variable handle
;//value_obj = Tcl_ObjGetVar2(interp, array_obj, NULL, tcl_flags);
Tcl_ResetResult(interp);
setTclObjValue(value_obj, value);
if (!reset) {
// Turn on the list append mode
tcl_flags |= TCL_LIST_ELEMENT;
tcl_flags |= TCL_APPEND_VALUE;
}
// Update variable
Tcl_ObjSetVar2(interp, array_obj, NULL, value_obj, tcl_flags);
}
// *** Function sets list of values to array-type Tcl variable.
template <class T > void
UserInterface_TCL::writeVariable_impl_n(Tcl_Interp* interp,
const char* array, const char* variable,
int size, const T* values,
bool reset)
{
Tcl_Obj* array_obj = Tcl_NewStringObj(NULL, 0);
Tcl_Obj* value_obj = NULL;
int tcl_flags = TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG;
tcl_flags |= TCL_PARSE_PART1;
// In Tcl80 we have to create a tcl string-object to
// carry the variable names. Here we use a fully
// specified array name to create the name-object
strstream strm;
strm << array << "(" << variable << ")" << ends;
char* array_name = strm.str();
Tcl_SetStringObj(array_obj, array_name, strlen(array_name));
// Reset variable
if (reset) {
setTclObjValue(value_obj, "");
Tcl_ObjSetVar2(interp, array_obj, NULL, value_obj, tcl_flags);
}
// Turn on the list append mode
tcl_flags |= TCL_LIST_ELEMENT;
tcl_flags |= TCL_APPEND_VALUE;
for (int i = 0; i < size; i++) {
value_obj = NULL;
// Try to get existing variable handle
// NOTE: This apparently does not work!!!
// Ref. comments for corresponding scalar method "..._impl_1"
//value_obj = Tcl_ObjGetVar2(interp, array_obj, NULL, tcl_flags);
Tcl_ResetResult(interp);
setTclObjValue(value_obj, values[i]);
// Update variable
Tcl_ObjSetVar2(interp, array_obj, NULL, value_obj, tcl_flags);
}
}
void
UserInterface_TCL::getTclObjValue(Tcl_Interp* interp, Tcl_Obj* value_obj, bool& value)
{
if (value_obj == NULL) {
return;
}
Tcl_GetBooleanFromObj(interp, value_obj, (int*)&value);
}
void
UserInterface_TCL::getTclObjValue(Tcl_Interp* interp, Tcl_Obj* value_obj, int& value)
{
if (value_obj == NULL) {
return;
}
Tcl_GetIntFromObj(interp, value_obj, &value);
}
void
UserInterface_TCL::getTclObjValue(Tcl_Interp* interp, Tcl_Obj* value_obj, long& value)
{
if (value_obj == NULL) {
return;
}
Tcl_GetLongFromObj(interp, value_obj, &value);
}
void
UserInterface_TCL::getTclObjValue(Tcl_Interp* interp, Tcl_Obj* value_obj, double& value)
{
if (value_obj == NULL) {
return;
}
Tcl_GetDoubleFromObj(interp, value_obj, &value);
}
void
UserInterface_TCL::getTclObjValue(Tcl_Interp* interp, Tcl_Obj* value_obj, char& value)
{
if (value_obj == NULL) {
return;
}
int len = 0;
char* tmp = Tcl_GetStringFromObj(value_obj, &len);
if (len > 0) {
value = tmp[0];
}
}
void
UserInterface_TCL::getTclObjValue(Tcl_Interp* interp, Tcl_Obj* value_obj, char*& value)
{
if (value_obj == NULL) {
return;
}
int len = 0;
char* tmp = Tcl_GetStringFromObj(value_obj, &len);
if (len > 0) {
value = new char[1 + len];
strcpy(value, tmp);
}
}
void
UserInterface_TCL::setTclObjValue(Tcl_Obj*& value_obj, const bool value)
{
// If this is new variable, we have to
// create a Tcl data-object
if (value_obj == NULL) {
value_obj = Tcl_NewBooleanObj(0);
}
// Set new value into data-object
Tcl_SetBooleanObj(value_obj, value);
}
void
UserInterface_TCL::setTclObjValue(Tcl_Obj*& value_obj, const int value)
{
// If this is new variable, we have to
// create a Tcl data-object
if (value_obj == NULL) {
value_obj = Tcl_NewIntObj(0);
}
// Set new value into data-object
Tcl_SetIntObj(value_obj, value);
}
void
UserInterface_TCL::setTclObjValue(Tcl_Obj*& value_obj, const ProcessId value)
{
// If this is new variable, we have to
// create a Tcl data-object
if (value_obj == NULL) {
value_obj = Tcl_NewIntObj(0);
}
// Set new value into data-object
Tcl_SetIntObj(value_obj, value);
}
void
UserInterface_TCL::setTclObjValue(Tcl_Obj*& value_obj, const long value)
{
// If this is new variable, we have to
// create a Tcl data-object
if (value_obj == NULL) {
value_obj = Tcl_NewLongObj(0);
}
// Set new value into data-object
Tcl_SetLongObj(value_obj, value);
}
void
UserInterface_TCL::setTclObjValue(Tcl_Obj*& value_obj, const double value)
{
// If this is new variable, we have to
// create a Tcl data-object
if (value_obj == NULL) {
value_obj = Tcl_NewDoubleObj(0);
}
// Set new value into data-object
Tcl_SetDoubleObj(value_obj, value);
}
void
UserInterface_TCL::setTclObjValue(Tcl_Obj*& value_obj, const char value)
{
char tmp[1];
tmp[0] = value;
// If this is new variable, we have to
// create a Tcl data-object
if (value_obj == NULL) {
value_obj = Tcl_NewStringObj(tmp, 1);
}
// Set new value into data-object
Tcl_SetStringObj(value_obj, (char*)tmp, 1);
}
void
UserInterface_TCL::setTclObjValue(Tcl_Obj*& value_obj, const char* value)
{
char* val;
int len;
if ( value == NULL ) {
val = "";
len = 0;
} else {
val = (char*)value;
len = strlen(val);
}
// If this is new variable, we have to
// create a Tcl data-object
if (value_obj == NULL) {
value_obj = Tcl_NewStringObj(val, len);
}
// Set new value into data-object
Tcl_SetStringObj(value_obj, val, len);
}
int
UserInterface_TCL::unknownFieldMsg(emf_ObjectData_X* object_data, bool is_fatal)
{
UserInterface* gui = theControlCenter->getGui();
strstream strm;
strm << "WARNING: Unknown field name for object "
<< object_data->object_name
<< ": "
<< object_data->field_name
<< ends;
gui->showMsg(strm.str());
if (is_fatal)
return !isOK;
else
return isOK;
}
void
UserInterface_TCL::update()
{
Tcl_Eval(theInterp, "update idletasks" );
}
// Class method
void
UserInterface_TCL::update(Tcl_Interp* interp)
{
Tcl_Eval(interp, "update idletasks" );
}
void
UserInterface_TCL::update(int counter, int update_interval)
{
if ( update_interval > 0 && 0 == counter % update_interval ) {
update();
}
}
// Update body data after split/comobine mesh boundaries
void
UserInterface_TCL::updateBodyData(Model* model)
{
to_tk_WriteBodyData(theInterp, *model);
to_tk_WriteBodyInfoData(theInterp, *model);
to_tk_WriteStats(theInterp, *model);
}
void
UserInterface_TCL::updateBoundaryData(Model* model)
{
to_tk_WriteBoundaryData(theInterp, *model);
to_tk_WriteElementGroupData(theInterp, *model);
to_tk_WriteStatusBoundaryConditions(theInterp, *model);
to_tk_WriteStats(theInterp, *model);
}
void
UserInterface_TCL::updateMeshZeroVelocityElements(int nof_zv_elements)
{
writeVariable(theInterp, "Model", "nofMeshZeroVelocityElements", nof_zv_elements);
}
// *** Update model data for the gui-side
void
UserInterface_TCL::updateModelData(Model* model)
{
theModel = model;
to_tk_WriteModelData(theInterp, *model);
// Set checked model file dir+name
sendCommandToGui(theInterp,"Interface::setModelFilePath");
}
void
UserInterface_TCL::updateModelFlags(Model* model)
{
to_tk_WriteModelFlags(theInterp, *model);
}
// *** Update model statistics for the gui-side
void
UserInterface_TCL::updateModelStatistics(Model* model)
{
to_tk_WriteStats(theInterp, *model);
to_tk_WriteBodyMeshInfoData(theInterp, *model);
}
// *** Update model status for the gui-side
void
UserInterface_TCL::updateModelStatus(Model* model)
{
to_tk_WriteModelStatus(theInterp, *model);
to_tk_WriteModelGeometryDimension(theInterp, *model);
to_tk_WriteProcessorData(theInterp, *model);
}
void
UserInterface_TCL::updateNextActiveSelectionTolerance(double tolerance)
{
ostrstream strm;
strm <<tolerance << ends;
sendCommandToGui(theInterp, "Interface::getNextActiveSelectionTolerance", strm.str());
}
// *** Update object data for the gui-side
void
UserInterface_TCL::updateObjectData(Model* model)
{
theModel = model;
writeVariable(theInterp, "ObjectTable", "ids", "");
writeVariable(theInterp, "ObjectTable", "count", 0);
to_tk_WriteBodyLayerData(theInterp, *model);
to_tk_WriteBodyData(theInterp, *model);
to_tk_WriteBodyInfoData(theInterp, *model);
// Do this after writing Body level data!!!
to_tk_WriteBoundaryData(theInterp, *model);
to_tk_WriteElementGroupData(theInterp, *model);
to_tk_WriteStats(theInterp, *model);
to_tk_WriteControlParameters(theInterp, *model);
// Process object table data in Gui side
sendCommandToGui(theInterp, "Interface::applyObjectTableData");
sendCommandToGui(theInterp,"Interface::createBodiesMenus");
}
// *** Update parameter data for the gui-side
void
UserInterface_TCL::updateParameterDataPre(Model* model)
{
to_tk_WriteAllParamDataPre(theInterp, *model);
}
// *** Update object and mask related parameter data for the gui-side
void
UserInterface_TCL::updateParameterDataPost(Model* model)
{
to_tk_WriteAllParamDataPost(theInterp, *model);
}
void
UserInterface_TCL::updateRendererInfo(const RendererInfo& rinfo)
{
int* i_val = NULL;
double* d_val = NULL;
char* s_val = NULL;
char* arr = "RendererInfo";
d_val = (double*) &rinfo.LINE_WIDTH_GRANULARITY;
writeVariable(theInterp, arr, "LINE_WIDTH_GRANULARITY", 1, d_val);
d_val = (double*) rinfo.LINE_WIDTH_RANGE;
writeVariable(theInterp, arr, "LINE_WIDTH_RANGE", 2, d_val);
}
// ********************************************
// ********* Tcl function definitions *********
// ********************************************
// *** Tcl_AppInit
int My_Tcl_AppInit(Tcl_Interp* interp)
{
if (Tcl_Init(interp) == TCL_ERROR) {
return TCL_ERROR;
}
//NOTE We do not start Tk here. It is started
// in the start() method just before menus etc. are
// ready to be built. This way we can (practically)
// make the tk initial console window invisble
//int Tklib_Init(Tcl_Interp *interp);
//Tcl_StaticPackage(interp, "Tklib", Tklib_Init, NULL);
//if (Tk_Init(interp) == TCL_ERROR) {
// return TCL_ERROR;
//}
#ifdef TK_TEST
//if (TkTest_Init(interp) == TCL_ERROR) {
// return TCL_ERROR;
//}
#endif /* TK_TEST */
return TCL_OK;
}
#if 0
// This stuff is a try to controlling
// Xwindows resource usage in the window loop
#ifdef UNIX
#include <signal.h>
#include <sys/time.h>
#include <unistd.h>
// Timer function to control Xwindows looping in Unix
static void timer_dummy() {}
static void timer_sig(int sig)
{
struct itimerval val;
int i;
val.it_interval.tv_sec = 0;
val.it_interval.tv_usec = 0;
val.it_value.tv_sec = 0;
val.it_value.tv_usec = 250000;
setitimer( ITIMER_REAL, &val, NULL );
signal( SIGALRM, timer_dummy );
}
#endif
#endif
// *** Main Window-program loop (Tk_MainLoop)
void
Tcl_MainLoop()
{
// This is needed at least for Unix, to prevent
// continuos cpu-cycle consumption
//#ifdef UNIX
// Tcl_CreateTimerHandler(1, tcl_DisplayIdleProc, displayIdleData);
//#else
// Tcl_CreateTimerHandler(1, tcl_DisplayIdleProc, displayIdleData);
//#endif
#if !defined(WIN32)
Tcl_CreateTimerHandler(1, tcl_DisplayIdleProc, displayIdleData);
#endif
int event_types = TCL_ALL_EVENTS;
//int event_types = TCL_WINDOW_EVENTS|TCL_FILE_EVENTS|TCL_TIMER_EVENTS;
//int event_types = 0;
// Tcl event loop
while ( Tcl_DoOneEvent(event_types) );
}
// Function simulates an interrupt with C++ exeception mechanism
// NOTE: This is called eg. from UserInterface_TCL::from_tk_ThrowException
void
tcl_interrupt(ClientData data)
{
#if defined(ELMER_FRONT_EXCEPTIONS)
// NOTE: You cannot throw execption within Gui, it will
// crash tcl-interperter sooner or later!!!
//throw E_ReadE;
#else
// Do nothing
TheUI->showMsg("Break not activated, sorry!");
#endif
}
// Tcl proc launched via tcl-timer
void
tcl_DisplayIdleProc(ClientData data)
{
//NOTE: In WIN32 we do not need a separate call to some window-proc
#if defined(UNIX)
Renderer* renderer = TheUI->getRenderer();
if (renderer != NULL) {
renderer->dummyWindowProc();
}
#endif
TheUI->update();
// Recreate tcl-timer so that I will be called again
Tcl_CreateTimerHandler(1, tcl_DisplayIdleProc, displayIdleData);
}
// Tcl proc launched via tcl-timer
void
tcl_InterruptIdleProc(ClientData data)
{
}
// *** WishPanic
void
WishPanic TCL_VARARGS_DEF(char *,arg1)
{
va_list argList;
char buf[1024];
char *format;
format = TCL_VARARGS_START(char *,arg1,argList);
vsprintf(buf, format, argList);
#if defined(WIN32)
MessageBeep(MB_ICONEXCLAMATION);
MessageBox(NULL, buf, "Fatal Tcl Error when running Elmer Front",
MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
#else
cerr << "Fatal Tcl error when running Elmer Front: " << endl
<< buf << endl;
#endif
exit(1);
}
syntax highlighted by Code2HTML, v. 0.9.1