Tcl
Tcl, as we have seen, is usually implemented as an interpreted language. A Tcl interpreter is built into HyperWorks, so you need no additional software to create or run Tcl scripts. You will usually store Tcl scripts in different files.
Since Tcl is interpreted, the entry point is the first function in the file that’s loaded.
Remember that Tcl has no data types – for Tcl, everything is a string of text.
It’s up to you, therefore, to anticipate what values a variable will hold and proceed accordingly. This is particularly important if you access the
HyperMesh database from your code. Before we review the commonly used HyperWorks functions provided by the Tcl API, we’ll look at some commonly used “intrinsic” commands are listed here. (Use one of the references listed at the end of this book for an introduction to Tcl itself.)
Remember that a hash-sign (“#”) is used for comments.
Common Tcl Commands
• set – to assign values to variables.
Example: set outputmessage “Command Failed”
assigns the data “Command Failed” to the variable named outputmessage.
• open – to open a file.
Example: open “datafile” r opens the file named datafile for read-only access, while open “datafile” w opens it for read-write access. If you use set filehandle [open “datafile” r] you can use close when you’re done with the datafile.
• Close – to close a file.
Example: If the handle of an open file is in the variable filehandle, use close $filehandle to close the file.
• puts – to send output to a file or to the screen.
Example: puts “Command Failed” writes “Command Failed”. If the string has been assigned to a variable
Managing the CAE Process Advanced Topics named outputmessage, you would use puts “The
contents of outputmessage are $outputmessage”. If the handle of an open file is in the variable filehandle, use puts $filehandle $outputmessage to write to the file.
• gets – to get a line from a file.
Example: if the file-handle is stored in the variable
filehandle, you can use gets $filehandle line1 to read the first line characters from the file and store it in the variable line1. gets returns –1 if the end of the file is reached.
• read – to get data from a file that’s already been opened.
Example: if the file-handle is stored in the variable filehandle, you can use set line1 [read $filehandle 80] to read the first 80 characters from the file and store these in the variable line1.
• exec – to execute an operating system command.
Example: use exec dir to list the contents of the current directory.
• expr – evaluate a command.
Example: expr acos(-1) returns π.
• exit: to end the application.
Example: exit –1 returns the value –1 to the calling application, if there is one. It’s up to the calling function to use the returned value.
• file: to work with file attributes.
Example: file exists nameoffile returns –1 if the file doesn’t exist. file mkdir dirname creates a folder named dirname.
• proc – to define a procedure
Example: A procedure can optionally take arguments, and usually returns a value to the caller. proc
nameofprocedure {argument1 argument2} { } defines a procedure named nameofprocedure that takes 2
arguments.
Advanced Topics Managing the CAE Process Since Tk is inbuilt into Tcl, you can build widgets by including Tk commands in your code. You should definitely review how to use the Tk commands button and message. Commands like menu and menubar are also useful to build slick interfaces quickly.
Common HyperWorks API Functions
The HyperWorks API provides a wide range of functions. You will need to browse through the list, of course, as you work on building code. Some commonly used API commands are listed here. Remember that we encountered “* commands” such as *createbutton when we discussed macros. When such commands are used in Tcl, the brackets should be replaced by spaces. For instance, the command to create a fillet is
*createfillet( lineid1, lineid2, radius, trim-option, quadrant)
when used in a macro, but is
*createfillet lineid1 lineid2 radius trim-option quadrant
when used in a Tcl script. Commands that start with hm are functions that are provided by the HyperWorks API.
• hm_allentitiesinfo: to get information on all entities
Example: hm_allentitiesinfo assemblies returns a list of all the assemblies in the database. The list is a string of characters that the calling script can parse.
• hm_answernext: to force a yes / no reply for the next prompt Example: *answer( ) cannot be used in Tcl scripts, so this function is provided.
• hm_blockmessages: to turn off or on the display of messages Example: use *hm_blockmessages 1 to turn off the display of messages in the message-bar, and
*hmblockmessages 1 to turn them on again.
• hm_errormessage: to display a message
Example: use *hm_errormessage “Command Failed” 10 to display the text “Command Failed” on the message bar and wait 10 seconds before removing the message.
Managing the CAE Process Advanced Topics
• hm_completemenuoperation: to clean up
Example: when working with HyperMesh, the graphics area is cleaned up after the menu is complete. When using Tcl, you may need to issue this command explicitly.
• hm_count: to count the number of entities of a given type
Example: hm_count nodes returns the number of nodes in the database.
• hm_entityincollector: to count the entities in a collector
Example: hm_entityincollector comp 1 nodes returns the number of nodes in the component collector whose id is 1.
• hm_entitymaxid: to get the largest label used for an entity type Example: hm_entitymaxid nodes returns the largest id used for nodes.
• hm_getcollectorname: to get the name of a collector, given the id Example: hm_getcollectorname comp 1 returns the name of the component collector whose id is 1.
• hm_getcompthickness: to get the thickness of a component collector
Example: hm_getcompthickness 1 returns the thickness assigned to the collector whose id is 1.
• hm_getentityvalue: to get specific information about an entity Example: hm_getentityvalue NODES $nodeId "x" 0 returns the x coordinate of the node whose id is in the variable nodeId.
• hm_nodevalue: to get the coordinates of a node
Example: hm_nodevalue $nodeId returns the x, y and z coordinates of the node whose id is in the variable nodeId.
• hm_nodelist: to get the list of nodes connected to an element Example: hm_nodelist $elemId returns the ids of all nodes connected to the element whose id is in the variable elemId.
• hm_getfloat: to get a floating point number from the user
Advanced Topics Managing the CAE Process Example: set tolerance [hm_getfloat “Tolerance”
“Enter value”] displays the caption “Tolerance”, issues the prompt “Enter Value” and stores the entered value in the variable tolerance.
• hm_getint: to get an integer from the user
Example: set nodeId [hm_getint “Node Selection”
“Enter id”] displays the caption “Node Selection”, issues the prompt “Enter id” and stores the entered value in the variable nodeId.
• hm_getstring: to get a text string from the user
Example: set compName [hm_getint “Component Name”
“Enter name”] displays the caption “Component Name”, issues the prompt “Enter name” and stores the entered value in the variable compName.
• hm_getfilename: to get a filename from the user
Example: set fileName [hm_getfilename “File Name”
“Enter name”] displays the caption “File Name”, issues the prompt “Enter name” and stores the entered value in the variable fileName.
• hm_info: to get information regarding the HyperWorks installation Example: hm_info ALTAIR_HOME returns the folder in which HyperWorks is installed. You can get the working directory, the path where the executables reside, the names of the executables, the name of the application the script is running in, the name of the current collector, the name of the currently running macro, etc.
In addition to the API itself, there are 4 variables that HyperWorks maintains:
::g_ConversionPrecision – the number of significant digits to which all floating point numbers returned by Tcl API functions will be rounded off ::g_hw_argc – the number of arguments passed by HyperWorks to the current script
::g_hw_argv – the list of arguments passed by HyperWorks to the current script.
Managing the CAE Process Advanced Topics
::g_hw_version – the version number of HyperWorks An Annotated Example
To put all this in proper context, let’s look at a real, working program. This example is a script to import all IGES files in a given folder into HyperMesh.
The lines in blue are the actual code, while comments are in italics and are indented for clarity.
# Display a message to the user, who can only click on “OK”.
tk_messageBox -title "Directions" -message "Pick a source directory. All IGES files \n in that directory will be imported." -type ok
# Display a Dialogue Box from which the user can select the file. Note that the code does not allow for the user clicking on “cancel”. The name of the chosen file is stored in the variable fileSource
set fileSource [tk_chooseDirectory mustexist true -title "Find Files In"]
# Define the variable named “format”, which we’ll use to build the filenames.
set format {#iges\\iges}
# Generate the file list. Remember that Unix is case sensitive, while Windows is not. Note how the loop is constructed. We search for files with the suffix igs or iges
foreach fileName [glob –nocomplain
$fileSource/*.{igs,iges}]
{
# Extract File Name Information set temp1 [file tail $fileName]
# Break the name at the “.”
set temp2 [split $temp1 .]
# We’ll use the filename to organize the data on import
set compName [lindex $temp2 0]
if {$fileName != ""}
{
# Set the state of the all component collectors: display of elements is off, display of geometry is on
*displaycollectorwithfilter components
"none" "" 0 1
Advanced Topics Managing the CAE Process
# Create a component collector with the name that’s given by the variable compName_surfs, and assign it a mat collector id = 1, and set the color to 1.
*collectorcreate components
"$compName\_surfs" "1" 1
# Create a component collector with the name that’s given by the variable compName_lines, and assign it a mat collector id = 2, and set the color to 1.
*collectorcreate components
"$compName\_lines" "2" 1
# Create a component collector with the name that’s given by the variable compName_points, and assign it a mat collector id = 3, and set the color to 1.
*collectorcreate components
"$compName\_points" "3" 1
# Run the Iges translator (we defined the variable named
“format” above). We do not want to overwrite any existing entities and use an automatic cleanup tolerance
*feinput "$format" "$fileName" 0 0 -1 1 0
# Now that the geometry’s imported, move the surfaces, points and lines to the corresponding collectors (we created them just before the import). surfaces / lines / points, the corresponding collector would be empty.
*EntityDeleteEmpty components 1 }
Managing the CAE Process Advanced Topics }
# Now that the import-and-organization is over, wind up by setting the color …
*autocolor components
# … and set the display-state of all component collectors – elements off, geometry on
*displaycollectorwithfilter components "all" "" 0 1 You could, of course, use ::hwat::io::LoadFilesFromDir to achieve the same affect with less code. Note that this function is a part of the
HyperWorks Automation Toolkit function.
Java
The APIs provided to the TCL modules is much smaller than the APIs provided for Java, largely because the Java development-paradigm allows the development of a wider range of applications than Tcl. Of course, Tcl applications can use
::hw::pmgr::PmgrExecuteJavaScript $id $strJavaCmd nSuccess
to do anything that the Java Beans can do.
The Java APIs support Swing (the JFC), and come with a set of libraries and beans that your application can use. If you’re using a Java IDE (such as Eclipse), you should add hwmutils.jar, hmsuite.jar, hwmetaphase.jar, and dbbeans.jar and all the jar files in the lib folder (the path depends on your installation - C:\Altair\hw8.0sr1\javaapps\WIN32\pmgr\lib for example) to the set of required libraries.
The supplied controls are in 3 classes – utility controls, database controls and HyperMesh specific controls. When you use the Process Studio to lay out the user-interface, the bindings decide the order in which the controls are called at run-time.
All the APIs provided by the Process Manager FrameWork are encapsulated in the interface IHWMFrameWork. To access the framework, beans should implement a class named com.altair.hwm.interfaces.IHWMControl. If it does, when the bean is instantiated, the Process Manager passes the
IHWMFrameWork instance to the SetFrameWork method (note that the bean’s constructor does not have access to the FrameWork). Beans that don’t implement this class don’t receive the FrameWork handle, but can do their own work, of course.
Advanced Topics Managing the CAE Process Among other facilities, the FrameWork provides access to
• a data model for beans to store and share data, using
IHWMDataModel. The DataModel is persistent – that is, it is saved with the process instance, so you can retrieve data from it when the process is restarted in a subsequent session.
• inter-process communications (such as connections to an RDBMS using JDBC and SQL, interfaces to other applications using sockets, connections to servers using SOAP, etc.) using IHWMCommMgr
• the Workflow – that is, the set of tasks that make up the process-tree – using IHWMWorkFlow
• the menus using IHWMMenuToolbarCustomizer
The package com.altair.hwm.beans.utils (in hwmutils.jar) contains several ready-made beans that implement the FrameWork and are consistent with the HyperWorks GUI. This means you should, as far as possible, use these as base classes, rather than using Swing components directly.
All in all, unless you have prior experience with Java or an object-oriented language like C++, you should look at Tcl as a preferred customization route.
Finally, remember that the API is for Java, not JavaScript - while Java and JavaScript share several vocabulary and syntax constructions, the languages are intended for very different purposes.
XML
HyperWorks uses XML to interface MotionSolve with MotionView, for
instance. XML provides several advantages to the programmer. You probably will not need to decipher the structure used by HyperWorks, but it’s
interesting anyhow to understand the how and why of XML.
Like other markup languages, XML uses tags liberally. But unlike HTML, which almost everyone who uses a computer has encountered, XML only defines the content, not the appearance. This is extremely significant since it allows for separation between form and data. The developer, therefore, has tremendous freedom. Unlike HTML, where the tags supported by the
Managing the CAE Process Advanced Topics language are predefined, XML allows you to define your own tags.
Remember that XML files are intended to be read by applications, not by humans. Since the XML file contains the tags you’ve defined, its easy to write an application to read the XML file. The XML “code” tells the application what the data means.
A Document Object Model, that helps process the contents using
relationships between objects in the hierarchy, can represent the structure inherent in the XML file.
Computers are useless. They can only give you answers.
Pablo Picasso