Sunteți pe pagina 1din 355

Caesam SDK User's Guide

Copyright Samtech 2011


All rights reserved
Contents
1 Introduction..............................................................................................................................................10
1.1 Related documentation..............................................................................................................10
1.2 SDK users..................................................................................................................................11
1.3 Revision History........................................................................................................................11
1.3.1 Changes in version 5...................................................................................................11
1.3.2 Changes in Caesam Version 4....................................................................................13
1.3.3 Changes between revision Caesam Version 3 and Version 4.....................................14
1.3.4 Changes between Caesam Version 2 and Version 3...................................................15
2 Fundamental concepts..............................................................................................................................17
2.1 Analysis elements......................................................................................................................17
2.2 Analysis development................................................................................................................18
3 CAESAM plugins.....................................................................................................................................20
3.1 Plugin folder structure...............................................................................................................20
3.2 Plugin descriptor – The plugin.xml file.....................................................................................21
3.2.1 Caesam Version and Plugin Version...........................................................................21
3.2.2 Importing other plug-ins.............................................................................................21
3.2.3 Plug-in libraries..........................................................................................................22
3.2.4 Resources attached to a plug-in..................................................................................23
3.2.5 List of the classes defined in the plug-in ...................................................................24
3.2.6 Loading external shared libraries................................................................................26
3.2.7 Managing the Java CLASSPATH of the plugins .......................................................27
3.2.8 Defining new URL contexts.......................................................................................27
3.2.9 Specifying MIME types..............................................................................................28
3.3 Plugin loading strategies............................................................................................................28
4 Basic components of Caesam...................................................................................................................31
5 Type definition in CAESAM....................................................................................................................33
5.1 XML Classes.............................................................................................................................33
5.1.1 Type descriptor...........................................................................................................33
5.1.2 Caesam methods.........................................................................................................36
5.2 C++ classes................................................................................................................................43
5.3 Class relations............................................................................................................................46
5.4 Flags...........................................................................................................................................49
5.5 Resources...................................................................................................................................51
5.5.1 Class resources...........................................................................................................51
5.5.2 Member resources.......................................................................................................53
5.5.3 Accessing class and member resources from an instance..........................................54
5.6 Pre-defined types.......................................................................................................................55
5.7 Enumerations.............................................................................................................................64
6 Objects......................................................................................................................................................66
6.1 Smart Pointers............................................................................................................................66
6.2 Creating a new instance.............................................................................................................67
6.3 Setting and getting member values............................................................................................67
6.4 Calling a method .......................................................................................................................68
6.5 Copy and clone methods............................................................................................................68
6.6 Examining the object type.........................................................................................................70
6.7 Comparing Caesam objects.......................................................................................................70
6.8 Direct accessors for built-in types ............................................................................................70
6.9 Finding an object by its path in the object hierarchy ................................................................71
6.10 Other Caesam_Object services................................................................................................71
6.11 Global objects..........................................................................................................................72
6.11.1 Defining global objects.............................................................................................72
6.11.2 Using global objects to initialize members of other objects.....................................72
6.11.3 Accessing global objects...........................................................................................73
6.11.4 Redefining global objects.........................................................................................74
7 The Analysis dedicated objects................................................................................................................75
7.1 Results Handling .......................................................................................................................75
8 Error Handling..........................................................................................................................................78
9 Starting CAESAM and CAESAM Tools..................................................................................................80
9.1 Start-up options .........................................................................................................................80
9.2 Start up Commands...................................................................................................................82
10 Plugins....................................................................................................................................................84
10.1 Plugin types.............................................................................................................................84
10.2 Plugin architecture...................................................................................................................85
10.3 Include plugins........................................................................................................................87
10.4 External libraries......................................................................................................................87
10.5 Building a plugin.....................................................................................................................88
11 Table data structure.................................................................................................................................91
11.1 Caesam_Table..........................................................................................................................91
11.1.1 Caesam_Table API...................................................................................................93
11.1.2 XML Persistence.......................................................................................................97
11.1.3 Usage Scenarios........................................................................................................98
11.2 Caesam_TypedTable................................................................................................................99
11.2.1 Caesam_TypedTable API........................................................................................100
11.2.2 Usage Scenarios......................................................................................................100
11.3 ACD tables.............................................................................................................................106
11.4 Guidelines for optimal use of tables......................................................................................108
12 Tools.....................................................................................................................................................110
12.1 Number formatting................................................................................................................110
12.1.1 The CaesamRes_NumberFormat class...................................................................110
12.1.2 Different ways to define the format of a quantity member ....................................111
12.2 Unit system ...........................................................................................................................113
12.3 System utility classes.............................................................................................................113
12.4 Preferences.............................................................................................................................113
12.5 Queries...................................................................................................................................114
12.6 Logger tool............................................................................................................................115
12.6.1 The Log package: messages, bundles, printers and loggers...................................115
12.6.2 The Caesam_Message class....................................................................................117
12.6.3 The Caesam_Logger class......................................................................................117
12.6.4 The application logger............................................................................................117
12.6.5 The Task logger......................................................................................................118
12.6.6 The plug-in’s loggers..............................................................................................118
12.6.7 The logger macros..................................................................................................118
12.6.8 The com.samcef.caesam.CaesamLog Java class....................................................119
12.7 Message tool..........................................................................................................................119
12.7.1 The Log_Bundle class ...........................................................................................120
12.7.2 The Log_Message class..........................................................................................120
12.7.3 The Caesam_Message class....................................................................................121
12.7.4 Examples................................................................................................................121
12.8 OP2 access tool......................................................................................................................122
12.8.1 Required DATABLOCK in .op2 files.....................................................................122
12.8.2 The CaesamEO_ GlobalFEMModel class..............................................................123
12.8.3 The CaesamFEM_StaticAnalysis class..................................................................123
12.9 Tree model creation utility.....................................................................................................124
12.10 Operating System Tools.......................................................................................................125
13 Caesam commands...............................................................................................................................127
13.1 Discipline files.......................................................................................................................127
13.2 Commands for building a plugin...........................................................................................127
14 Persistency............................................................................................................................................130
14.1 Object persistence..................................................................................................................130
14.1.1 Caesam_Application::LoadObject, SaveObject ....................................................130
14.1.2 Caesam_CsmDocument::LoadDocument, SaveDocument....................................131
14.1.3 String serialization..................................................................................................132
14.1.4 Transient objects.....................................................................................................132
14.2 Persistence drivers.................................................................................................................133
14.2.1 Persistence driver for XML (Caesam_CsmDriver)................................................133
14.2.2 The SQL database persistence driver ....................................................................135
14.2.3 Registering persistence drivers...............................................................................136
14.3 Type versioning.....................................................................................................................136
14.3.1 Compatibility through class, member and method obsoletion...............................136
14.3.2 Compatibility through the Translate method..........................................................137
14.4 Universally Unique Identifiers..............................................................................................139
14.5 CAESAM Resource Locators................................................................................................140
14.6 Caesam URL Contexts..........................................................................................................140
14.6.1 Application (global) context map...........................................................................140
14.6.2 Model context map.................................................................................................142
14.6.3 User defined context maps.....................................................................................143
14.7 The CZM document...............................................................................................................144
14.7.1 Model items can have file resources.......................................................................145
14.7.2 Adding user files to the CZM.................................................................................145
15 Engineering Objects.............................................................................................................................146
15.1 Global FEM Management.....................................................................................................146
15.2 Topology................................................................................................................................147
15.3 Geometry...............................................................................................................................148
15.4 Load Case Management........................................................................................................149
15.5 FEM Solver Management......................................................................................................151
15.6 Results Management..............................................................................................................151
15.7 Collections.............................................................................................................................152
16 Analysis definition................................................................................................................................154
16.1 Dataset declaration ...............................................................................................................154
16.2 Dataset examples...................................................................................................................155
16.3 Analysis declaration..............................................................................................................156
16.4 Analysis examples.................................................................................................................157
16.5 Methods.................................................................................................................................159
16.6 Resources...............................................................................................................................159
16.7 Process template compatibility..............................................................................................160
17 Processes...............................................................................................................................................161
17.1 Analysis process....................................................................................................................162
17.1.1 Python implementation...........................................................................................162
17.1.2 Burst mode..............................................................................................................165
17.1.3 Other process Implementation................................................................................165
17.2 Operation Initialization Processes.........................................................................................165
17.3 Model processes....................................................................................................................166
17.3.1 Python implementation...........................................................................................166
17.4 Execution Context.................................................................................................................167
17.5 Process Registration..............................................................................................................167
17.5.1 The CaesamStd_ProcessParameter.........................................................................168
17.5.2 The Context settings...............................................................................................169
17.6 The Analysis Step Process.....................................................................................................169
18 Directories ...........................................................................................................................................171
18.1 Directory structure.................................................................................................................171
18.1.1 CaesamStd_Directory.............................................................................................171
18.1.2 CaesamStd_TypedDirectory...................................................................................173
18.1.3 CaesamStd_Group..................................................................................................173
18.1.4 CaesamStd_EOLibrary...........................................................................................173
18.2 Model predefined directories.................................................................................................173
18.3 Structural groups....................................................................................................................174
18.3.1 Creating structural groups......................................................................................174
19 Filters....................................................................................................................................................177
19.1 Disciplines ............................................................................................................................177
19.1.1 Implementing a custom discipline..........................................................................177
19.1.2 The default discipline.............................................................................................178
19.1.3 Declaring discipline instances................................................................................179
19.2 Editor filters...........................................................................................................................180
19.2.1 Implementing a custom editor filter.......................................................................180
19.2.2 Associating editor filters with Caesam types..........................................................182
20 Global Table Creation...........................................................................................................................183
20.1 Structure.................................................................................................................................183
20.2 Implementation......................................................................................................................184
20.3 Personalized table editor and customized toolbar.................................................................188
21 Maturity................................................................................................................................................190
21.1 Configurations.......................................................................................................................190
21.1.1 Functional Description...........................................................................................190
21.1.2 Architecture Overview...........................................................................................190
21.1.3 Business Architecture.............................................................................................191
21.2 Packages................................................................................................................................194
21.2.1 External References................................................................................................195
21.2.2 Circular Dependencies............................................................................................195
21.2.3 CPs and associations...............................................................................................195
21.2.4 Example for Maturity.............................................................................................195
21.2.5 Kernel Architecture................................................................................................196
21.2.6 Business Architecture.............................................................................................197
22 FEM......................................................................................................................................................202
22.1 FEM Topology.......................................................................................................................202
22.2 Relation with the Stress Model..............................................................................................202
22.3 Involved classes.....................................................................................................................203
22.4 Business Architecture............................................................................................................205
23 Display tools.........................................................................................................................................207
23.1 Associating a simplified graphic with an SE.........................................................................207
23.2 Using a predefined graphic driver.........................................................................................208
23.3 Create your own graphic driver.............................................................................................209
23.4 Create your own graphic 3D display in your EO Editor.......................................................211
24 Batch Tools...........................................................................................................................................213
24.1 Programming Interface..........................................................................................................213
24.1.1 Retrieving command line arguments......................................................................213
24.1.2 Starting and closing the application: CaesamScript_Application .........................214
24.1.3 Creating, opening and saving a session : CaesamScript_Document......................214
24.1.4 Selecting items from criteria : CaesamScript_Selection........................................214
24.1.5 Creating SEAs : CaesamScript_SEA......................................................................215
24.1.6 Creating and running analyses : CaesamScript_Analysis......................................216
24.1.7 Launching tasks : CaesamScript_Task...................................................................216
24.1.8 Going further .........................................................................................................217
24.1.9 Example..................................................................................................................217
24.2 Running analyses in batch.....................................................................................................217
24.3 BatchManager........................................................................................................................218
24.3.1 Processing the command line parameters...............................................................218
24.3.2 Creating a new BatchLauncher...............................................................................218
25 Job Submmission and Monitoring........................................................................................................221
25.1 Queue Configuration.............................................................................................................221
25.2 Customization of the ProcessTemplate..................................................................................223
25.3 Computing Resources Evaluation.........................................................................................224
26 Analysis interface definition.................................................................................................................226
26.1 Analysis Creation..................................................................................................................226
26.1.1 Class overview........................................................................................................228
26.1.2 FAQs ......................................................................................................................229
26.2 Editor definition.....................................................................................................................230
26.2.1 EditorData...............................................................................................................230
26.2.2 Default editor..........................................................................................................231
26.2.3 Custom Editor.........................................................................................................231
26.2.4 Integration of an editor...........................................................................................235
26.3 Form editors...........................................................................................................................237
26.4 Analysis editors.....................................................................................................................239
26.5 Tabular editors.......................................................................................................................241
26.5.1 Form Descriptors....................................................................................................241
26.5.2 Custom Tabular Editor Models...............................................................................242
26.5.3 Forcing The Default Model....................................................................................248
26.6 Editing Caesam tables and matrices in a custom Java editor................................................248
26.7 Author-defined table models.................................................................................................250
26.7.1 Overview................................................................................................................250
26.7.2 Custom editor table models....................................................................................250
26.7.3 Using your custom model in a Java editor..............................................................256
26.8 Caesam Graphical Meta Languages......................................................................................257
26.8.1 Quick start...............................................................................................................258
26.8.2 Reference of the standard tags................................................................................259
26.8.3 Extended tags..........................................................................................................265
26.8.4 How to....................................................................................................................269
26.9 Interface definition................................................................................................................272
26.9.1 Add a new xml tag in the plugin.xml file...............................................................272
26.9.2 Add commands in the specified 'PluginCommands' file........................................272
26.9.3 Accessing the selection from the task.....................................................................276
26.9.4 More examples of commands.................................................................................278
26.9.5 Add commandWidgets in the specified 'PluginCommands' file ............................279
26.10 Other Interface definition....................................................................................................283
27 EditorData.............................................................................................................................................286
27.1 EditorData services................................................................................................................286
27.1.1 Data services...........................................................................................................287
27.1.2 GUI services...........................................................................................................295
27.1.3 Reserved and deprecated methods..........................................................................296
28 Language Bindings...............................................................................................................................298
28.1 The CAESAM FORTRAN interface.....................................................................................298
28.1.1 How to call FORTRAN code..................................................................................301
28.2 The CAESAM PYTHON interface.......................................................................................303
29 Coding guidance...................................................................................................................................306
29.1 Environment variable............................................................................................................306
29.2 Macros...................................................................................................................................306
29.3 Access to OP2 results............................................................................................................307
29.4 Predefined inline functions and global constants..................................................................307
29.5 Layouts..................................................................................................................................312
30 Caesam object interfaces......................................................................................................................314
30.1 Defining an interface.............................................................................................................314
30.2 Using interfaces.....................................................................................................................316
31 Updating Caesam objects.....................................................................................................................321
31.1 Computing the value of a member in a getter method...........................................................321
31.2 Computing the value of a member while the object is being modified (OnMemberChanged).323
31.3 The Update method ..............................................................................................................325
32 Use of the generation tool for 2D Profile.............................................................................................327
33 Parametric design.................................................................................................................................331
33.1 Parametric interfaces.............................................................................................................331
33.2 Reference...............................................................................................................................334
34 Step by step Perspective.......................................................................................................................337
34.1 The <perspective> element....................................................................................................341
34.2 The <menu> element.............................................................................................................341
34.2.1 The <menu> in a <menubar>.................................................................................342
34.3 The <split_collection> element.............................................................................................344
34.4 The <editorsView> element...................................................................................................346
34.5 The <defaultTypeEditors> element.......................................................................................347
34.6 The <options> element..........................................................................................................347
34.6.1 The <step> element................................................................................................348
34.6.2 The <generalStep> element....................................................................................353
34.7 How to implement Sub-Steps................................................................................................353
Caesam SDK | 1 Introduction

1 Introduction
Caesam is an open platform developed by SamTech dedicated to the integration of customer analyses in
a framework.
The Caesam application provides a framework in which analysts can perform analytical processes. It
provides the means for them to select and define the input parameters, to execute the analysis operation
and to access and view the results. The framework provides consistency in operation and management
of the analyses and flexibility to accommodate the type of processes required in the environment.
The analyses are specified as ‘plugins’. The plugin defines the analysis process, the type of structural
elements that can be used in the analysis, the variables that can be used in the analyses and the output.
This documentation is aimed at the authors of the analyses i.e. the creators of the plugins. It provides a
guide on how to both define and integrate an analysis into the platform. Both the definition and the
integration must be made in the context of the Caesam model. The users of the SDK are expected to have
programming experience and an understanding of xml.

1.1 Related documentation


This document is a users guide for authors of analysis plugins. It describes the concepts involved and the
overall process required to create and integrate a plugin. There are a number of other documents that are
provided with the installation files. These documents can be accessed from the README.html file that
can be found at the highest level of the installation directory. The different types of documentation available
are outlined in the following subsections.

Caesam Command Language Reference Guide

This document tells you everything you need to know about the Caesam Command Language (CCL).

Beginners guide

This manual is aimed at those who are writing their first plugin. It describes all the basic concepts and
procedures required and uses a worked example as a guide to creating, adapting and enhancing a basic
plugin. It is assumed that readers of this manual are familiar with the basic concepts described in the
Beginner’s Guide.

Kernel C++ classes

This information is available in two formats; a set of html pages and direct access to the cdl files.
The linked collection of html files contains information on:
• Class Hierarchy : A structured list of Caesam classes presented in a hierarchical showing the
inheritance between them.
• Class List : A flat alphabetical list of classes along with a brief description and links to the details.
• Class Members : A list of members arranged according to name and type with information about the
classes to which they belong.
• File list : An alphabetical list of files
• File Members : A list of members with reference to the files they belong to.

GUI Java Classes

A collection of html documents describing all aspects of GUI Java classes. Details about the constructor
and the methods are provided for each class.

Kernel XMLClasses

A list of xml files which can be viewed in a browser or text editor.

page-10
1 Introduction | Caesam SDK

The Caesam Analysts online help

A user’s guide for the analyst who needs to use the framework to run an analysis process. This is a
collection of html pages that can be accessed directly from the Help menu of the application.

1.2 SDK users


This document lists the specific requirements necessary for authors to use the SDK to develop plugins.

Hardware

• Intel Pentium 4 processor (minumum)


• 1GB RAM (minimum)
• 2GB of available disk space
• 800 MB of available swap space
• Nvidia GeForce 4 and Quadro graphic card (see ReadMe Prerequisites for other configurations)

OS

• Windows XP-Pro

Software

• FlexLM (server) Vx - Provided with CAESAM delivery


• MS Visual Studio C++ compiler 8–2005 Express
• Intel Fortran compiler 9.1
• BDF / OP2 / Nastran 2005R3 (minimum)
• Patran V P2005R3 (minimum)
• FemWord Vx - Provided with femword plugin
• SAMCEF V12.1-02 - Provided with CAESAM delivery
• CAESAM V5.2.1 + Studio

Licence

• MS - Windows
• MSC - Nastran (optional)
• MSC - Patran (optional)
• SAMTECH - FemWord
• SAMTECH - SAMCEF
• SAMTECH - CAESAM SDK

1.3 Revision History


This section lists the changes that have taken place between CaesamVersion 6 and previous versions.

Changes in Version 6

• Parametric design
• Creation of plugins using Steps.
• ACD tables

1.3.1 Changes in version 5


The following changes were implemented in CaesamVersion 5

page-11
Caesam SDK | 1 Introduction

1.3.1.1 Kernel

Tabular data structure

• Caesam_Table: a container of primitive or object items organized in columns.


• Table descriptors can be defined dynamically or statically.
• Caesam_TypedTable: storage of objects of complex types (objects that have several members) into
the rows of a table.
• The possibility to define a custom column-to-member mapping.
• The platform EO type CaesamStd_LoadCaseTable has been modified (version #2) to make use of a
Caesam_TypedTable.
• A translate method allows loading and converting documents saved with previous versions.
• Helper methods for converting typed arrays of objects to tables (Caesam_TypedArray::ToTable(),
Caesam_EOArray::ToTable())

Global objects

• <namespace, variable, object> triplets are defined in an static tree at application level.
• Can be defined in typedesc files using the csm XML syntax.
• Can be used to initialize members of other objects by copy or by reference.

Class, member and method resources

• Can be defined in typedesc files or in C++.


• Resources are gouped in categories (GUI, UserResources, ...)
• Resources are accessed via a path (like GUI/EOCreationPath)
• GetResource/SetResource on Caesam_Class, Caesam_Member and Caesam_Method

Number formatting

• The new class CaesamRes_NumberFormat to define the precision, rounding mode and real to string
mode.
• The format of a member can be defined as a constant in typedesc files.
• The format of a member can be defined as number global objects in order to re-use the same format
for several members.
• The possibility to define or use a predefined physical dimension for quantity formatting.
• The predefined physical dimension formats can be modified from the preference dialog.

XML persistence

• Shorter XML attributes names (Type: "_T", Key : "_K", ...) and tags (<Items>: <_I>)
• When the type of a member or item matches the declared type the Type XML attribute can be omitted.
• Values of the primitive members can be written as attributes instead of tags.
• AfterRetrieval and BeforeStore are called when importing/exporting an EO the shared workspace

Adding user files to the CZM

• The user can add their own files and directories to the model (CZM) and package (CZP) archives.
• Each CaesamStd_item can have a resource URL that points to a directory located in a CZM context.
• The framework will automatically include the file directory at that location into the CZM or CZP
document.
• An author is able to attach custom files or directories to their objects (like Analysis, EOs, …).
• An author can specify whether to extract that resource from the document archive (IsManual flag).

page-12
1 Introduction | Caesam SDK

Store a document configuration file in the CZM

• The CaesamModel.xml is accompanied by a configuration file called CaesamModel.xml.config, which


tells Caesam what elements are needed in order to be able to load that file.
• Store the list of the classes necessary to load an instance file

Caesam_Quantity now has a series of subclasses

• For each dimension recognized by Caesam_Quantity there is a CaesamQty_<Dimension> class.


• For new developments it recommended the use of CaesamQty classed instead of Caesam_Quantity.

1.3.1.2 Jobs and analysis

• Add a method on analysis template to give the list of files to copy on the remote node
• It is also possible to define a method GetComputingResources on the ProcessTemplate to return
an estimation of the resources necessary to run an analysis.
• It is possible to write a IsParameterEquivalent method on a CaesamStd_ProcessParameter
to force an update of parameters in previously saved files In the case of a Step process definition, this
method is already written and the updating is automatic.

1.3.1.3 Plugin building

• By default plugins are built in optimized mode.


• The optimization level can be specified in the command line.

1.3.2 Changes in Caesam Version 4

Version 4.1.5

• Updated start-up options


• Updated information about java class path
• Added information about patches to overcome errors on SUN
• Find files tool
• GUI customization update

Version 4.1.4

• Maturity : Configurations and associations Packages Preference mechanism CaesamStd_Model: Find


by path accept now Name[a name] and UUID[a uuid]
• Global Table : Introduce objects to manage Global Table CaesamTable_Table,
CaesamTable_TableDescriptor, CaesamTable_TableCreator CaesamStd_LoadCaseTable: new Path=
LoadCase[loadcasename]/RF
• Fishtail : Class CaesamStd_AbstractFishTailDescriptor to describe a Fish tail view
• Caesam_Object : Find by a Path: now a registered method without argument can be started from a
path: Syntax: /@methodname
• FORTRAN : Add the capability for the plugins authors to call some CAESAM methods from
FORTRAN subroutines and functions.
• EXPORT/FORTRAN : Add EXPORT/FORTRAN into Caesam_<primitive>.cdl
• Process template : Correction: ProcessTemplate: Dependency: works now if the EO is an
CaesamStd_EOArray. The UpdateDepency method if called on each slave EO of the EOArray.
• Context : The CsmContext can be retrieved from the item : CaesamStd_Item::GetCsmContext() Useful
to retrieve the context of the document (Moxdel) Ex: Delete all files of an operation.
• Analysis files location : CaesamStd_Operation + CaesamStd_ProcessTemplate: GetProcessDirectory():
define where an analysis can store their internal files. The directory is created at the first RunTask

page-13
Caesam SDK | 1 Introduction

• Analysis files removal : CaesamStd_Item: BeforeRemove() & BeforeStore() : Goal : remove files or
purge files associated with an analysis
• Process_Analysis : suppressed csm:caesamprocesstmpdir and "csm:caesamprocessdir/" Replaced by
CaesamStd_DataSet::GetProcessDirectory()
• Memory management : Added a "Free Memory" test task in the example plugins.
• Caesam_Object : XML string serialization Added two new methods in Caesam_Application that can
be used to serialize and deserialize Caesam objects to/from an XML string
• ADBT : indexed cache
• Version compatibility : To preserve the binary compatibility (avoid the plugins recompilation and
linking), the classes that inherit from Caesam_Object can be extended via the Caesam_PrivateObject
• Database persistence : Added the boolean preference "Use database" which can be used to
enable/disable the use of a database for persisting the model.
• Batch Launcher/Manager : A new Batch Launcher/Manager system is available. It allows to launch
and stay informed of shell or user defined (e.g. Atome) batch executions.
• Predefined creator of tables : EOCreator: Create a table of all EO of a type for all members (EO and
Primitive) SECreator: Create a primary table of all SE of a Type FilterCreator: create a primary table
using the current filter.
• Add user files to CZM : The user can add his own files and directories to the model (CZM) and
package (CZP) archives.
• EO display : EO can be displayed from the property view: ex: CoordSystem. This functionality can
be extended by author.
• Python: CaesamAPI module : When importing the CaesamAPI, the Caesam_Application is now
started automatically.
• User load case : The new class "User Load Case" stores a type of Load (Thermal, Pressure, Mechanical,
...) and FEM results as explicit values given in a Comma-Separated Value files (.csv)
• Mathematical library : Added utility plugin com.samcef.caesam.asml which provide a samtech
implementation of fortran mathematic library imsl. This is described in a separate document.
• Csmmake : can now generate and use fortran 90 .mod files
• Global model : CaesamStd_Model: New method GetGlobalModel to retrieve CaesamStd_GlobalModel.
• Loggin messages : New macros to log messages in the CAESAM logger are available in Caesam.hxx
and are used in Caesam, CaesamStd, CaesamAPI, etc.
• CaesamEO_USEFEMLink : A new abstract EO type is introduced in the famework:
CaesamEO_UseFEMLink. This EO should serve as the base class for all EOs that are related to a
CaesamEO_FEMLink. The framework EO CaesamEO_ByElementBySE is an example.
• CaesamEO_ByElementBySE : CaesamEO_ByElementBySE is now inheriting from
CaesamEO_UseFEMLink.
• Backup : The internal CaesamAPI_Object::Backup(), CaesamAPI_Object::FatherChanged() methods
from CaesamAPI_Object are no longer exported to the Java GUI interface. The EditorData.Backup()
and EditorData.FatherChanged() have been removed.
• Filter : CaesamStd_NameFilter accepts * and ? wildcards
• GetStringMatrixProperties : Authors can redefine the Caesam method GetStringMatrixProperties
for objects declared in XML
• GetLinks : The new method CaesamStd_Configuration::GetLinks can be called on a configuration
to get all attached links
• CP Find : CaesamStd_CP::Find and CaesamStd_Operation::Find accept the following paths:
"/Link[<datasetkey>]" and "/Config(uration)[<datasetkey>]"

1.3.3 Changes between revision Caesam Version 3 and Version 4

New features

• CaesamTopology_Element : An Element is defined by a list of CAesamTopology_Node and not by


a list of node numbers (Integer)
• CaesamTopology_Mesh : new methods to manage new type of CaesamTopology_Element
• CaesamStd_Element : New type of Calculation Point. This object can hold a Map of EO and knowns
(have a pointer) a CaesamTopology_Element

page-14
1 Introduction | Caesam SDK

• CaesamEO_FEMLink : EO assigned to an SE. It describes the small mesh behind the SE.
• CaesamEO_ByElementBySE : EO which contains an EO for each element of the small mesh behind
the SE.
• Process_InitializeOperation : This task inherits from Process_Task. The goal is to be able to retrieve
some information from the operation when initializing a DataSet. (see Operation Initialization Process
on page 165.)
• GlobalLocalPost : A feature to select the display value type is available. Previously : Value Currently
: Value, LoadCase or Name
• Access the current GUI selection from tasks : It is now possible to access the whole GUI selection
from user-defined Caesam tasks. More accurately, one can access the current selection of the stress
model tree AND of the EO property view. This works only in combination with the new "plug-in
command mechanism". (See Interface definition on page 226.)
• Local contexts in analyses : When an analysis is run, you can use two new caesam contexts that are
local to this analysis: - caesamprocesstmpdir: points to a unique subdirectory in csm:documenttmp -
caesamprocessdir: points to a unique subdirectory in csm:documentexternalfiles
• Filter by analysis status : Filter type "By Analysis Status", next to "By Name" and "By Type". This
filter allows to filter analyses according to their status (and optionally to their type). The status can
be: Not yet computed / Failed / Out of date / Up to date. You can select one of several of these status.
The first 3 are selected by default
• Batch scripting : Caesam can be used in batch mode from python scripts (by importing the native
python module CaesamAPI). (See Batch tools on page 213.)
• ADBT : The CAESAM Abstract Database Toolkit (ADBT) enables you to use a relational database
as a persistent storage system for the CAESAM platform This is described in a separate document.

Improvements

• SetStringValue : can be safely used for enums derived from Caesam_String.


• Edit typed array : When editing a typed array of type A that contains only elements of type B (B of
course inherits from A), you also see the columns corresponding to members of type B.
• Debug/Memory Consumption : In menu "Debug/Memory Consumption", you can select some items
in the tree and/or property view and get information about their memory usage (grouped by type). To
obtain the memory usage of the whole model, just select the root node of the tree.
• Mimetype file chooser : When opening the file chooser for mimetype "FEMInput/BulkData", files
with extension ".dat" are accepted by the filter.
• Help : Associating a help URL to a Caesam type now also works with types inheriting from SEAType
and ProcessTemplate.
• Python Converters : These are located in the plugin: com.samcef.caesam.csmpython
• New FORTRAN subroutine : SUBROUTINE CAESAMFORTRANEXCEPTION(RoutinName,
MessageString) CHARACTER*(*) RoutinName, MessageString
• Class to handle coordinate systems : The class CaesamEO_CoordSystem handles local coordinate
systems.

1.3.4 Changes between Caesam Version 2 and Version 3


The following features were added:
• Unique identifier : for SE, SEA, Analysis, EO
• Version : Version of class and compatibility between versions. Versioning for object types.
• Flags : Method, Member, Instance flags can be changed by programming
• Context : Environment variables can be used in a URL. Array and Matrix.
• Path : Find an object directly in the object’s hierarchy via a Path. Versioning for object types.
• Pyramidal structure : SEA of SEA.
• Calculation Points : Operations performed on CPs.
• Analysis : Analysis of Analysis
• Process template : sub-operations
• Editor filter : see Filters on page 177.
• Disciplines : see Disciplines on page 177.

page-15
Caesam SDK | 1 Introduction

• OP2 API : The CaesamFEM_StaticAnalyis is shared by all operations via the CaesamFEM_Model
• Debug :
• Enable/Disable Debug Dialog : Display Logger & Exceptions
• Dump : XML Format
• Printable Dump : Text Format
• Display XML File
• csmmake : see Caesam Commands on page 127.
• Compiler version : Visual Studio 2005 Fortran compiler Intel 9
• Directories : See Directories on page 171
• Virtual methods and Process : See Processes on page 161
• EO Dependency :

page-16
2 Fundamental concepts | Caesam SDK

2 Fundamental concepts
This chapter describes the basic concepts that need to be understood by Caesam SDK authors. They are
presented from two aspects:
• those relating to the analysis itself,
• those related to the development of the plugin in which the analysis is realised, which is the main
objective of readers of this documentation.
It is recommended that users of the Caesam SDK read the "Beginner's Guide" which also introduces
concepts relating to the use of Caesam.

2.1 Analysis elements


Analyses in Caesam are based on Structural Elements (SEs). The Structural Element is the unit functional
element of the structure under analysis, and is not related to a single Finite Element. This can of course
be the complete structure, but can also be just parts of a structure as illustrated in the figure below, where
two SEs are shown: a plate and a rib.

Figure 1: Examples of SEs

For the purposes of the analysis Structural Elements can be grouped into Structural Element Assemblies
(SEAs). An example of an SEA is shown below, that is created from two plates and a rib in a particular
arrangement. The complete model to be analysed would be composed of a collection of SEAs and SEs.

Figure 2: Structural Element Assembly (SEA)

The essential components of any analysis are:


• the input parameters, which are used as a basis for the calculation and which can be edited by the
analyst, such as the weight, length, strength of the structural parts and the applied loads.
• the analysis, or calculation process
• the output, or results of the analysis, such as stresses and displacements.
In Caesam, both the input and the output parameters for an analysis are defined as in terms of Engineering
Objects (EOs) which must be specified by the author of the analysis.
Engineering objects (EOs) can be composed of members. So, for example, the material properties of a
plate could be defined as a single EO with members that such as Young's modulus, thermal conductivity,
mass density, and others, depending on the type of analysis.
The calculations performed by the Analysis process are related to the structural model through the concept
of the Calculation Point (CP). This is illustrated in the Figure below.

page-17
Caesam SDK | 2 Fundamental concepts

Figure 3: Calculation Point

This figure illustrates how the two types of SE are combined to create the SEA. The concept of the CP
relates this particular analysis to the particular structural element; in this example it the SEA, but it is
possible to perform an analysis on a CP that is based on a single SE. Each SE has an EO associated with
it that defines the material properties. The CP and the SEA define a path that identifies the components
in the analysis; thus the two plates can be identified as being the upper or lower plates relating to this
analysis.
The analysis process must be available in a programming language, which can be python, C++ or Fortran.
The results of the analysis, are also EOs of a type that defines them as output. The relationship between
the input and the output data is established by the path that is generated based on the CP and the EO as
shown above.
The specification of the analysis; i.e. the Structural Elements that form the Calculation Point (CP), the
EOs used to define the input paramters, the process used to calculate the results and the EOs containing
the results are all defined in the Analysis Template. The development of the analysis consists in creating
a plugin, which represents a collection of files in which all these required elements of the analysis are
defined.

2.2 Analysis development


Implementing an analysis in Caesam requires developing a "plugin" in which all the required analysis
parameters are defined. Caesam provides a framework in which the basic components of any analysis are
made available to the analyst through a consistent graphical user interface. This analysis can be an
complicated as is required but the absolutely essential elements of any analysis are:
• The Calculation Point (CP) - the structural element on which the calculation will be performed.
• the input data - EOs defining the engineering properties to be used in the analysis
• the calculation process
• the results of the calculation - EOs defining computed properties
The first stage in the analysis development process is to define these essential elements of the analysis.
The next stage is to create the necessary files that make up the plugin.
The CP, and the EOs make up the 'dataset'. The dataset and the process are linked through the "analysis
template".
The main objectives of the SDK user are:
• to create a plugin folder containing a file plugin.xml in which important elements of the plugin are
defined.
• to create the processes on page 161 that performs the calculation.
• to define the template on page 154.
• to define the types contained in the dataset.
Caesam provides a basic framework in which input data can be defined, the analysis run and read the
results, but in addition it provides plenty of opportunities to customise and improve the user interface for
a particular analysis. Full details on defining editors and adapting the framework interface for the analyst
are given in Interface definition on page 226.

page-18
2 Fundamental concepts | Caesam SDK

To create any plugin requires the creation of xml files. Basic computations can be performed in Python.
An understanding of xml and python are therefor pre-requisites for a Caesam plugin author.
Processes can also be run in C++, Java, and calls to Fortran can be made from a python script.
To create a more sophisticated and performant plugin it is recommended that you use C++. To adapt the
user editor interface, it is necessary to use Java.

Note: This manual does not cover the syntax of these languages, it refers to them only the
context of Caesam.

Getting started

It is recommended and assumed that you have read or understand the concepts described in the "SDK
Beginner's Guide". This takes you step by step through the process of creating and implementing a very
simple plugin.
In order to create a plugin you need an "SDK license". An SDK license includes a license to use "Caesam
Studio" which provides tools to help you build and modify a plugin. From Caesam Studio, you can launch
Caesam with the plugin you are building or editing.
To launch Caesam separately:
• On Windows
Execute the command caesam.cmd the Caesam installation directory.
• On a UNIX or LINUX operating system,
Use the C-shell script file named caesam.
Use the following start-up options : -nolog -sdk –plugin {directory where the plugin
folder is located}. The option –nolog is useful since it allows you to view messages in the terminal
window from which Caesam is launched; i.e. the DOS window on a PC or an xterm window on unix.
For all the information relating to starting Caesam see start up options on page 80.
The topics covering the fundamentals are :
• Caesam plugins on page 20.
• Type definition in Caesam on page 33.
• Manipulating Caesam objects on page 66.
• Analysis dedicated objects on page 75.
• The basic components of Caesam on page 31.
• Class member and method flags on page 49.

page-19
Caesam SDK | 3 CAESAM plugins

3 CAESAM plugins
The Caesam platform can be extended with new functionalities through the use of plugins. The Caesam
plugin system offers the possibility to register new data types implemented in XML, Python, Java and
C++.
A plugin is a folder that contains:
• A mandatory file called plugin.xml which is the plugin descriptor.
• TypeDesc libraries which are XML files for declaring new data types.
• Shared libraries for different platforms containing C++ class definitions.
• Java classes and Python scripts for defining methods.
• Specific editors for specifying different engineering object types.
• Plugin related resources like help files, general java resource files (.properties files, image files, …)

3.1 Plugin folder structure

Plugin folders identification

In order to be considered as a plugin, a folder must contain a valid “plugin.xml” file. If this file is missing
or its name is misspelled, the folder will be skipped. Although there is no restriction concerning the naming
of external plugins, the following points should be noted:
• The name of a plugin is identical to the folder name in which the plugin.xml file is located.
• The name of a plugin must be unique throughout the list of locations specified by the variable
CAESAM_PLUGIN_PATH. If duplicate plugin folders are encountered at these locations, Caesam
will always load the first one ignoring any others.
This behaviour is useful for sharing plugins between different members of a development team. Plugin
developers, may wish to have a local version of some plugins and a reference version that is shared with
other plugin developers. In order to accomplish this it is sufficient to add the path of a local plugins folder
to the CAESAM_PLUGIN_PATH before the path of the reference. In this way Caesam will first load
the plugins found in the local folder and then those found in the reference.

Note: Kernel plugins, which have a specific location relative to the application’s root,
should not be modified, moved or removed.

The location of the plugin folders

External plugins developed by CAESAM SDK users (authors) can be located anywhere, but NOT under
the CAESAM_ROOT folder. In order to be searched by CAESAM, the folder that contains plugin folders
must be added to the environment variable CAESAM_PLUGIN_PATH. Check the Caesam starting script
for an example.

Pre-defined plugin folders

CAESAM kernel plugins located in CAESAM_ROOT/plugins: this directory is internal to CAESAM,


and contains only mandatory plugins starting with "com.samcef.caesam". It should not be modified by
any other plugin.
CAESAM example plugins are located in CAESAM_HOME/examples/plugins and are provided as
examples. They are also part of the CAESAM delivery, but are not mandatory to start the application.
This directory should not be modified by any other plugin. Their names start with "com.samcef.caesam.test".

page-20
3 CAESAM plugins | Caesam SDK

3.2 Plugin descriptor – The plugin.xml file


The plugin.xml file is a configuration file that can be used for setting up plug-in related parameters such
as the list of libraries to load or the plug-in version, as well as application wide parameters (values that
are stored in application-level variables) like URL contexts, MIME types or system library path.
When initializing the plugin, the CAESAM kernel will first load the plugin.xml file, it will then try to
load all the imported plugins and then all the specified libraries (typedesc or shared).

3.2.1 Caesam Version and Plugin Version


The plugin system currently uses two versioning mechanisms:
• The <CsmVersion> tag,
is used for verifying if it is the same as the version of Caesam that is loading the plug-in.

Note: Note that the CsmVersion must match exactly the Caesam version, otherwise the
plug-in will not be loaded.

Whenever a new version of Caesam is installed, in order to make a plug-in developed with an older
version compatible, you must update the <CsmVersion> tag.
• The <Version> tag
allows the plug-in creator to trace different versions of the same plug-in over time and to force a given
version in the <Import> declarations. More information on importing plugins is given below.

<Instance Type="Caesam_Plugin">
<CsmVersion Type="Caesam_Version">2.0-15</CsmVersion>
<Version Type="Caesam_Version">1.0-3</Version>
</Instance>

3.2.2 Importing other plug-ins


It is common that a class defined in a plug-in A uses (for inheritance or member declaration) a class B
defined in another plug-in. In this case it is necessary to ensure that B is loaded before A, so that all types
defined in B are already registered at the moment when A is being loaded. In addition it may be necessary
to ensure that the version of the class it depends on is the one it needs.
This can be done by specifying the list of the required plug-ins in the <Import> tag of the plugin.xml.
Currently there are two accepted import syntaxes.

Simple import

Only the name of the plug-in is specified at import. No plug-in version verification is performed. The
Items of the Import array are of type Caesam_String.

<Import Type="Caesam_ObjectArray">
<Item Type="Caesam_String">com.samcef.caesam.test</Item>
</Import>

Import with plug-in version checking

The Item type is Caesam_PluginReference, which has a member PluginVersion and a member PluginName.
The version verification of the imported plug-in is accomplished by comparing the required and actual
plug-in version.

page-21
Caesam SDK | 3 CAESAM plugins

• The Major part of the plugin’s version must equal the major part of the required version.
• The minor part of the plugin’s version must be greater or equal than the minor part of the required
version.

<Import Type="Caesam_ObjectArray">
<Item Type="Caesam_PluginReference" PluginName="com.samcef.caesam.test"
PluginVersion="2.6-2" />
</Import>

In the example shown above the actual plugin version is 1.6-2. The major part is 2, the minor one is 6
and the third element (-2) represents the revision number which is not taken into account. This plugin can
be imported if the required version is any value between 2 and 2.6.
Two versions of the same plug-in are compatible as long as the major part of their versions remains
unchanged.

Note: The version validation algorithm may change in the future.

3.2.3 Plug-in libraries


The main feature of a plug-in is the ability to load collections of classes, which are defined either in XML
type descriptor files or in shared (dynamic) libraries. The plugin.xml file allows the declaration of a list
of mixed library types through the use of the <Libraries> member, which is an array of one or more items
of the type:
• TypedescLibrary : a URL relative to the plugin’s folder which points to a typedesc file (an XML file
for describing Caesam types)
• SharedLibrary : composed of four relative URLs (one for each platform), which point to the shared
library files (.so on Sun and Linux, .dll on Windows or .s1 on HPUX) that belong to the plug-in.
See Type definition in Caesam on page 33 for a complete explanation of how the two types of libraries
can be created and the design constraints.

<Instance Type="Caesam_Plugin">
<Libraries Type="Caesam_ObjectArray">
<Item Type="TypedescLibrary">Test.typedesc</Item>
<Item Type="SharedLibrary">
<Solaris Type="Caesam_Url">sun/libcom_samcef_caesam_test.so</Solaris>
<Windows Type="Caesam_Url">win/com_samcef_caesam_test.dll</Windows>
<Linux Type="Caesam_Url">lin/libcom_samcef_caesam_test.so</Linux>
<Hp Type="Caesam_Url">hp/libcom_samcef_caesam_test.sl</Hp>
</Item>
<Item Type="TypedescLibrary">Test2.typedesc</Item>
</Libraries>
</Instance>

For backward-compatibility reasons, the plugin.xml file can also contain a tag <Library>, which allows
a single library per plug-in to be loaded. In this case the type specified in the <Instance Type=””> tag
must be either TypedescPlugin or DllPlugin.

Important: This feature is obsolete and its use is discouraged.

Use Caesam_Plugin and <Libraries> instead.


An example of obsolete plugin definition is given below:

<Instance Type="TypedescPlugin">
<Library Type="Caesam_Url">test.typedesc</Library>
</Instance>

page-22
3 CAESAM plugins | Caesam SDK

<Instance Type="DllPlugin">
<Library Type="SharedLibrary">
<Windows Type="Caesam_Url">win/com_airbus_must_test.dll</Windows>
<Solaris Type="Caesam_Url">sun/libcom_airbus_must_test.so</Solaris>
<Linux Type="Caesam_Url">lin/libcom_airbus_must_test.so</Linux>
<Hp Type="Caesam_Url">hp/libcom_airbus_must_test.sl</Hp>
</Library>
</Instance>

3.2.4 Resources attached to a plug-in


A plug-in resource can be considered as a file, a folder or an object instance that contains data needed by
the plug-in and whose name and location is known. The Caesam plugin developer can define his own
resources at the plug-in level (the list of the resources is attached to a certain plugin instance) by using
the <Resources> member of Caesam_Plugin which is a map of <resource_name, resources_content>
pairs. The resource name is defined by the Key attribute and its content by the value.
The content of a resource can be of any registered type, meaning that a developer can store an instance
of any kind of Caesam object in a resource. The following example shows that it is possible to define a
resource as a Caesam_Url which points to an external file that contains the actual data or to store the data
inline.
The example below defines two resources : a URL type plug-in resource (the URL is relative to the
plugin’s folder and it implies that the path “resources/properties/” exists) and an inline resource containing
a list of strings.

<Instance Type="Caesam_Plugin">
<Resources Type="Caesam_ObjectMap">
<Item Key="Properties" Type="Caesam_Url">resources/properties</Item>
<Item Key="MyStringsResource" Type="Caesam_StringArray">
"STRING1";"STRING2";"STRING3"
</Item>
</Resources>
</Instance>

At the code level plug-in resources can be managed via the Caesam_Application API:

PTRMEM(Caesam_Application) aApplication = Caesam_Application::GetApplication();

PTRMEM(Caesam_Object) aPlugin =
aApplication->GetPlugins()->GetPlugin(thePluginName);

PTRMEM(Caesam_ObjectMap) aResources = Handle(Caesam_ObjectMap)::

DownCast( thePlugin->GetMember("Resources"));

PTRMEM(Caesam_Object) aResource = theResources->Get("MyStringsResource"));

Or by using the CaesamAPI::GetPluginResource method:

Handle(Caesam_Object) CaesamAPI::GetPluginResource
const STL_String& thePluginName, const STL_String& theResourceName);

Properties files

There are some pre-defined resources in Caesam and the framework uses them for different purposes.
One of them is “Properties” which is a URL to a plugin’s resource folder that contains java “.properties”
files.

page-23
Caesam SDK | 3 CAESAM plugins

The content of all the “.properties” files content must follow the grammar described below:
• Lines on which the first character is a # are interpreted as comment.
• Non-commented lines must follow the pattern "<KEY> = <VALUE>" with the restriction that <KEY>
can not contain any white space.
An example is given below:

# a commented line
# next line is a valid example
Create_analysis = Create Analysis
# next line is invalid : a white space occurs in the key
Create_analysis tip = Create an Analysis based on selected SEA's

Caesam expects to find the following ".properties" files at that location:


• Resources.properties
that contains key-value pairs used by Caesam mainly to translate texts (such as, Menu labels, dialog
window title, etc...)
• Icons.properties
that contains key-value pairs used by Caesam to find out which image/icon it must use for GUI
presentation purposes.
• Messages.properties
that contains key-value pairs used by Caesam to translate messages (such as dialog box messages,
etc...) Some or all of these files might be empty.
See sections Display EO Member Names on page 231 and Adding an About entry in the Help menu on
page 285 for examples on the use of these files.

3.2.5 List of the classes defined in the plug-in


In Caesam, new classes are defined in typedesc files or shared library files which can be moved from one
plug-in to another without major changes. Since the class registration mechanism is completely independent
of the plug-in system, it is necessary to define “plug-in – class” relationships. The <Classes> tag is used
to define the list of classes (together with class related information) that are defined in that plugin.
Adding a class to the plug-in Classes list is not mandatory but strongly recommended. Some API need
to know the data types defined in a given plug-in or from which plugin a class is coming from. If a class,
even if it is correctly registered, has not been listed in the <Classes> array of the plugin.xml file, no
correspondence between the class and the plug-in will be kept. This could impact several parts of the
application (for example a call to a CaesamClass->GetPlugin() will return NULL).

<Instance Type="Caesam_Plugin">
<Classes Type="Caesam_ObjectArray">
<Item Type="PluginClass">
<Class Type="Caesam_String">MyFirstType</Class>
</Item>
<Item Type="PluginClass">
<Class Type="Caesam_String">MySecondType</Class>
</Item>
</Classes>
</Instance>

Empty instances

In Caesam, object instances are created by invoking the Caesam_Application method NewObject
(theClassname). This method instantiates an object by calling the default Caesam_Object constructor that,
at its turn, calls the registered constructor of the given class (if the class is defined in C++ and has a valid
constructor). The freshly created instance has no member initialized (a call to GetMember on any of its
members will return NULL).

page-24
3 CAESAM plugins | Caesam SDK

Initialized instances

In some cases, it is desirable to provide default values for some or all members of a class. This can be
done via the Caesam default instances mechanism. A default instance is an object defined at design time,
having its members initialized with actual values and which is attached to a class declaration.
In the plugin.xml file a default instance can be assigned to a class by specifying the location of the XML
instance for that class in a <Default> tag. In order to understand how instances are stored in files refer to
the Chapter “Persistency mechanism”.
Consider a class called MyType defined in the typedesc file (MyTypeDefinitions.typedesc):

<Type>
<TypeDesc Name="MyType">
<Member Name="myNullMember" Type="Caesam_Quantity" />
<Member Name="myNonNullMember" Type="Caesam_Quantity" />
<Member Name="myUninitializedMember" Type="MyMemberType" />
<Member Name="myInitializedMember" Type="MyMemberType" />
</TypeDesc>
</Type>

A default instance for this class is declared in the plugin file (plugin.xml):

<Classes Type="Caesam_ObjectArray">
<Item Type="PluginClass">
<Class Type="Caesam_String">MyType</Class>
<Default Type="Caesam_Url">default/MyType.csm</Default>
</Classes>

This implies the existence of a file called MyType.csm in the folder “default” relative to the plugin’s
folder. The content of this file is an XML representation of an instance of MyType class.
The default values are defined in the XML file (MyType.csm):

<?xml version="1.0" encoding="iso-8859-1"?>


<Instance Type="MyType">
<myNonNullMember Type="Caesam_Quantity">
<Dimension Type="Caesam_String">LENGTH</Dimension>
<Value Type="Caesam_Double">30</Value>
</myNonNullMember>
<myUninitializedMember Type="MyMemberType" />
<myInitializedMember Type="MyMemberType" Initialize="TRUE" />
</Instance>

Now when Caesam_Application::NewObject (“MyType”) is called, it will return an initialized object,


which in fact is a full copy of the above default instance. This example contains four members, each of
which have a different initialization condition. The content of the returned object will be:
• myNonNullMember : This member will be initialized with a Caesam_Quantity having the
Dimension=”LENGTH” and Value=30.
• myNullMember : This member is missing from the default instance definition file (MyType.csm) so
it will be set to NULL.
• myUninitializedMember : This member is present in the default instance definition, but no value is
specified. It will contain a Caesam_Quantity instance (whose members will contain default values)
• myInitializedMember : This member is present in the default instance definition, but no value is
specified. Since it has the Initialize attribute set to TRUE it will be set to the default instance of
MyMemberType (assuming MyMemberType has a default instance defined).

Resources attached to a class

A class resource is similar to a plug-in resource; the only difference is that the resource is attached to a
class instead of being attached to a plug-in. Refer to section “Resources attached to a plug-in” on plug-in
resources for more details on how to define a resource.

page-25
Caesam SDK | 3 CAESAM plugins

There are some pre-defined class related keys that can be used for specifying different resources for each
declared type.

Resource name Description Accepted values

Help An URL that points to an html file which contains Caesam_Url


documentation about the current class. When
defining URLs remember to use CsmContext
instead of absolute paths.
EOEditor When creating a specific editor for a certain type Caesam_Url
of Engineering Object, the appropriate EOEditor
resource must be set to inform the framework of
its existence.
EOCreationPath During the creation of an EO, it is possible to Caesam_String
present the data in a hierarchical view (tree view).
This specifies a path for each plugin class. So, each
element of the path will constitute a node of the
tree and the type will be a leaf.
AnalysisCreationPath During the creation of an Analysis, it is possible Caesam_String
to present the data in a hierarchical view (tree
view). This specifies a path for each plugin class.
So, each element of the path will constitute a node
of the tree and the type will be a leaf .

The code below is an example of class resources definition:

<Classes Type="Caesam_ObjectArray">
<Item Type="PluginClass">
<Class Type="Caesam_String">MyType</Class>
<Resources Type="Caesam_ObjectMap">
<Item Key="Help"Type="Caesam_Url">csm:myPlugin/help/MyType.html</Item>
<Item Key="EOEditor"
Type="Caesam_Url">com.samcef.caesam.test.MyTypeEditor</Item>
<Item Key="EOCreationPath"
Type="Caesam_String">/samtech/example/profiles/</Item>
</Resources>
</Item>
</Classes>

3.2.6 Loading external shared libraries


Some plug-ins may utilize shared libraries, which are external to the plug-in library itself (such as third-party
tools). Since the system’s loader must be informed about the location of these libraries before invoking
them, there must be a generic a way to defining this location.
The <ExternalLibraries> tag of the Caesam_Plugin object in the plugin.xml file, asks CAESAM to
locate and pre-load a list of dynamic libraries.

<Instance Type="Caesam_Plugin">
<ExternalLibraries Type="Caesam_ObjectArray">
<Item Type="SharedLibrary">
<Solaris Type="Caesam_Url">csm:caesamtemp/sun/libtest.so</Solaris>
<Windows Type="Caesam_Url">csm:caesamtemp/win/test.dll</Windows>
<Linux Type="Caesam_Url">csm:caesamtemp/lin/libtest.so</Linux>
<Hp Type="Caesam_Url">csm:caesamtemp/hp/libtest.so</Hp>
</Item>

page-26
3 CAESAM plugins | Caesam SDK

</ExternalLibraries>
</Instance>

As you can see, the items of the array are of type “SharedLibrary” that allow the specification of a different
path for each platform. Caesam will load the libraries in the same order as they are listed, meaning that
it is up to the developer to arrange them so dependencies are satisfied.

3.2.7 Managing the Java CLASSPATH of the plugins


The CAESAM Java framework allows the implementation of specialized editors for any of the registered
classes. Since the editors are packages of Java classes and these packages are loaded dynamically by the
system (at runtime), the framework’s class loader needs to know where they are located.
The plugin.xml file allows the declaration of new Java package locations by the intermediary of the
<ClassPath> tag. The plugin’s ClassPath is an array of relative URLs that point to the folders where the
Java packages are located.

<ClassPath Type="Caesam_ObjectArray">
<Item Type="Caesam_Url">classes/</Item>
</ClassPath>

In addition to the definition of editors, Java can be used in the implementation of CAESAM static methods
that can be attached to classes declared in XML. See Declaring Caesam types with XML type descriptors
on page 33. Since the system uses the same Java class loader as for the editors, any class that implements
a CAESAM method must be added to the plugin’s ClassPath.

Loading referenced Java classes

To load java classes that are contained in directories that are referenced in the plugin.xml file, the usual
method is to use:

java.lang.Class.forName(String className)

However there are some restrictions when using this within Caesam, so it is recommended to use instead:

com.samcef.caesam.manager.PluginManager.loadClass(String className)

3.2.8 Defining new URL contexts


In order to add new global contexts or redefine existing ones, you can use the <CsmContext> tag in the
plugin.xml descriptor file as shown in the following example.
In the definition of a new context, the item’s Key is what follows after the “csm:” protocol and the item’s
value is the mapped absolute URL. An example of a context map definition is given below:

<Instance Type="Caesam_Plugin">
<CsmVersion Type="Caesam_Version">2.0-14</CsmVersion>
<CsmContext Type="Caesam_CsmContext">
<ContextMap Type="Caesam_TypedMap">
<Type Type="Caesam_String">Caesam_Url</Type>
<Item Key="mytemp" Type="Caesam_Url">file:/c/temp/</Item>
<Item Key="mydir" Type="Caesam_Url">csm:mytemp/test/</Item>
</ContextMap>
</CsmContext>
</Plugin>

page-27
Caesam SDK | 3 CAESAM plugins

Note:
• All contexts defined in plugin.xml files are stored in the same unique map
Caesam_Application::GetCsmContext() which is the application’s context map. See
Caesam URL Contexts on page 140 in the Chapter “Persistency mechanism” for more
information.
• Contexts are resolved recursively, so already defined contexts can be used in the
definition of the absolute paths. As shown in the above example: <Item Key="mydir"
Type="Caesam_Url">csm:mytemp/test/</Item> The URL “csm:mydir/file.txt” will be
converted to “file:/c/temp/test/file.txt”
• If contexts are defined in different plug-ins, the order in which they are added to the
global context map is the same as the order in which the plug-ins are loaded. Use the
<Import> mechanism to manage this order.

3.2.9 Specifying MIME types


MIME types are used by the Caesam_File utility class for specifying file types.
In Caesam MIME types are stored in an application level map. This map contains Caesam_MimeType
objects, which have a Name and a list of Caesam_MimeSubtype. This map can be accessed via the
following method:

Caesam_Application::GetMimeTypes() returns ObjectMap from Caesam;


---Purpose: Returns the list of the available MIME types.
--The MIME types are defined in the plugins.xml file of
--the each plugin.

The following example is the MIME type declaration part of a plugin.xml file.

<MimeTypes Type="Caesam_ObjectMap">
<Item Key="image" Type="Caesam_MimeType">
<Name Type="Caesam_String">image</Name>
<Subtypes Type="Caesam_ObjectMap">
<Item Key="gif" Type="Caesam_MimeSubtype">
<Name Type="Caesam_String">gif</Name>
<Extensions Type="Caesam_StringArray">"gif"</Extensions>
<Description Type="Caesam_String">GIF Image File</Description>
</Item>
<Item Key="jpeg" Type="Caesam_MimeSubtype">
<Name Type="Caesam_String">jpeg</Name>
<Extensions Type="Caesam_StringArray">"jpg"</Extensions>
<Description Type="Caesam_String">JPEG Image File</Description>
</Item>
</Subtypes>
</Item>
</MimeTypes>

3.3 Plugin loading strategies


Starting from version 5, plugins are not loaded completely at startup, but only when a class that belongs
to that plugin is instantiated for the first time. The plugin loading mechanism has been separated from
the class registration

Plugin loading (executed at startup)

At startup Caesam will build a list of all classes to register and the plugins they belong to.

page-28
3 CAESAM plugins | Caesam SDK

The steps perfomed by the plugin manager are:


• examine the plugin directories and read all the plugin.xml files
• load the specified typedesc libraries plus the CppClasses.typedesc
• the classes found in these typedesc files are "pre-registered" into the Caesam class registry. The
pre-registration consists in storing the class name, a pointer to the super class and the resources of the
class. The declared members are not added to the pre-registered class yet.

Note: that the registration of the classes found in the plug-in may be triggered at this step
if the plugin.xml file or one of the class resources contain at least one instance of a class
declared in the plug-in.

Plugin classes registration (executed when a class is instantiated for the first time)

When a class is invoked via a NewObject(classname), Caesam will register all classes declared in the
plugin that contains that class and will register all the classes found in the imported and included plug-ins.
The registration of the plugin classes consists in completing the class descriptors already present in the
class registry with the details found in the typedesc files and shared libraries (adding the class members,
default values, C++ pointers to getters/setters and methods ...).

Forcing the class registration of all plug-ins when Caesam starts

During development and debugging it may be neccesary to register the classes of all the plug-ins at startup
(this was the default behaviour prior to v5.1.0). This can be accomplished by adding the "-loadallplugins"
argument to the Caesam command line.

Forcing the registration of an individual plugin at startup

In some situations, authors may want to override the lazy class registration behaviour and force the full
loading of a plugin when Caesam starts. This can be accomplished by setting the attribute
ForceLoad="TRUE" in the plugin.xml file.
One application of this feature is the execution of author defined C++ code when Caesam is starting.
The following example shows the steps required to call a static method (MyClass::MyCppMethod())
at Caesam startup, just before the registration of some C++ classes.
1. Force the plugin loading at startup by setting ForceLoad="TRUE" in plugin.xml

<Instance Type="Caesam_Plugin" ForceLoad="TRUE">


...
</Instance>

2. Call the static method in the initialize() function of the plugin.

STL_EXPORT void initialize(


Caesam_Registry *theRegistry,
Caesam_Persistence *thePersistenceManager)
{
// Call your method before or after the class registration
MyClass::MyCppMethod();

// Register C++ classes


Profile::Register(theRegistry);
ProfileRectangle::Register(theRegistry);
...
}

page-29
Caesam SDK | 3 CAESAM plugins

Every registered C++ class MUST have a typedesc declaration.

The plugin lazy loading mechanism requires the registered C++ classes to be declared in typedesc files
(Caesam needs to know about the C++ classes defined in a plug-in without loading the library that defines
them).
The typedesc declaration of a C++ class has the same syntax as XML class declarations with the addition
of the attribute Implementation="CPP" (for XML classes the Implementation attribute can either contain
"XML" or it can be ommited).
Example:

<TypeDesc Name="Material" Implementation="CPP" Inherits="CaesamStd_EO">


<Member Name="young" Type="Caesam_Quantity" />
<Member Name="poisson" Type="Caesam_Quantity" />
<Member Name="elasticlimit" Type="Caesam_Quantity" />
</TypeDesc>

Note: that Caesam provides a tool for generating the XML declaration for C++ classes
that do not have a typedesc defined.

This tool is located in the Caesam menu under SDK > Registry > Generate typedesc files for C++
classes . This will generate a CppClasses.typedesc file for each selected plug-in. The CppClasses
generator only works when Caesam is started with the -loadallplugins option.

page-30
4 Basic components of Caesam | Caesam SDK

4 Basic components of Caesam


This section describes the fundamental concepts related to the Caesam kernel and plugin development.

C++ Macros for manipulating smart pointers in Caesam

• PTRMEM : Used to declare smart pointer variables or return values.


• PTRARG : A constant smart pointer (the pointed object cannot be changed) which is used for declaring
arguments.
• CSMCAST : Cast smart pointer arguments into standard pointers.

Standard C++ types available in Caesam

The table below lists standard types and their C++ equivalent.

Type Standard C++ equivalent

Standard_Boolean bool
Standard_Integer int
Standard_Real double
STL_String std::string

Pre-defined plugin resources

A list of pre-defined plugin resources is given below.


• PredifineResult :
• HelpURL :
• AboutURL :
• ToolTasks :
• PluginCommands :
• AfterRetrieval : The name of the task (as a Caesam_String) that should be executed after loading a
Caesam document. This feature allows plugin developers to perform specific operations on data after
a Caesam document is loaded.
• Preferences : A URL that points to a csm file containing a map of preferences. See Preferences on
page 113 for more details.

Pre-defined class resources

Resource name Description Accepted values

Help A URL that points to an html file which contains Caesam_Url


documentation about the current class. When
defining URLs remember to use CsmContext
instead of absolute paths.
EOEditor When creating a specific editor for a certain type Caesam_Url
of Engineering Object, the appropriate EOEditor
resource must be set to inform the framework of
its existence.

page-31
Caesam SDK | 4 Basic components of Caesam

Resource name Description Accepted values

EOCreationPath During the creation of an EO, it is possible to Caesam_String


present the data in a hierarchical view (tree view).
This specifies a path for each plugin class. So, each
element of the path will constitute a node of the
tree and the type will be a leaf.
AnalysisCreationPath During the creation of an Analysis, it is possible Caesam_String
to present the data in a hierarchical view (tree
view). This specifies a path for each plugin class.
So, each element of the path will constitute a node
of the tree and the type will be a leaf .

Pre-defined Caesam contexts

Below is a list of pre-defined Caesam contexts and a corresponding description.


• csm:caesamroot/ : root directory of the application
• csm:caesamhome/ : home directory of the Caesam application
• csm:userhome/ : user's home directory (the value defined in the environment variable called
'USER_HOME')
• csm:caesamtemp/ : which contains the value of the environment variable called 'TMPDIR'
• csm:document/ :
• csm:documentczm/ : this context can be used to add user directories and files to the document CZM
archive
• csm:documentexternalfiles/ : a directory that can be used to store files that should not be included
in the czm archive.

page-32
5 Type definition in CAESAM | Caesam SDK

5 Type definition in CAESAM


The Caesam SDK allows for the creation and integration of new classes (data types) without the need to
re-compile the entire Caesam desktop application. In Caesam, the term “class” is used to describe a
complex type, which is composed of a list of fields (called “members”) and a list of methods.
Currently there are two ways in which a new data type can be defined:
• Type descriptors defined in XML files (commonly referenced as TypeDesc).
• Caesam_Object C++ classes packaged in a shared (dynamic) library.
As both methods use the same underlying system, an object, whether it was defined with a TypeDesc or
as a C++ extension of the Caesam_Object, can be accessed via a common API from C++, Java, Python
and Fortran.
This section deals with the following issues:
• How to declare types in XML and how to define C++, Python, Java and Fortran methods.
• How to declare C++ classes
• Where and how the class declarations are stored (the class registry).
• How class descriptions can be accessed programmatically.

5.1 XML Classes


As stated previously a plugin can load TypeDesc libraries and shared libraries. A TypeDesc library is an
XML file composed of one or more Caesam class definitions.
Describing types using Caesam type descriptor XML files is suitable in several cases:
• For prototyping. Since no compilation is needed, types can be created and maintained more easily than
compiled C++ classes.
• For describing a type that has no methods. In terms of development time it is usually faster to write
an XML file that contains few tags that describe a list of members.
• For describing a type that has methods implemented in other languages. It is possible to have a Caesam
class with members declared in XML and methods implemented in Fortran, Python, Java or C++.

5.1.1 Type descriptor

Syntax

An XML type descriptor library file can contain one or several class declarations (TypeDesc). All these
declarations must be enclosed between an opening and closing <Type> tag.
Example of type descriptor library file (MyTypeDescriptors.typedesc):

<?xml version="1.0"?>
<Type>
"class descriptor"+
</Type>

Inside a type descriptor file, a Caesam type is declared with the <TypeDesc> tag having a “Name”
attribute, an “Inherits” attribute if it is a subclass of another class and a Boolean “Abstract” attribute.

<TypeDesc Name="a type" Inherits="its ancestor"


Abstract="TRUE|FALSE" >
"comments"?
"Attribute registration"*

page-33
Caesam SDK | 5 Type definition in CAESAM

"Method registration"*
</TypeDesc>

The ‘+’, ‘*’ and ‘?’ characters are used as in standard regular expressions to express strict multiplicity,
multiplicity and optional possibilities. Attribute and Method registration are described below. The complete
list of the attributes supported in <TypeDesc> is given in the table below.

Attribute Description Accepted values

Name The type identifier Any valid string


Inherits Specifies the name of the super class Must contain a type name that has
from which the current class inherits already been registered inside the same
plugin or in a different plugin. Use the
<Import> declarations to manage the
loading order of the plugins.
Abstract Specify whether the class is abstract or FALSE (default) TRUE
not. See Class relations on page 46 for
more information on Caesam abstract
classes.

Members declaration

A TypeDesc can contain one or several <Member> tags identified by their Name and their Type. Inside
a member declaration, a <Comments> tag can be used for documenting it.

<Member Name="a name" Type="its type">


"comments"?
</Member>+

A more specific example of the syntax for a definition involving two types (AbstractPlateShape and
SimplePlateGeometry) is given below.

<?xml version="1.0" encoding="iso-8859-1"?>


<Type>
<TypeDesc Name="AbstractPlateShape" Inherits="CaesamStd_EO" Abstract="True">
<Member Name="length" Type="Caesam_Quantity"/>
</TypeDesc>
<TypeDesc Name="SimplePlateGeometry" Inherits="CaesamStd_EO">
<Member Name="shape" Type="AbstractPlateShape"/>
</TypeDesc>
<Type>

Methods declaration

In TypeDesc, a Caesam method is declared with the <Method> tag having a “Name” attribute, a “Type”
attribute indicating whether the method is C++, Python or Java and a “Location” attribute for specifying
where the implementation of the method is found.
The following table lists all the attributes supported in the <Method> declaration.

Attribute Description Accepted values

Name The value specified by this attribute Any valid method name
must match the name of the method

page-34
5 Type definition in CAESAM | Caesam SDK

Attribute Description Accepted values

implemented in the class referenced in


the Location.
Type The type of the method. Cpp: the method Cpp Python Java Fortran
is defined in C++ Python: the method is
define in a Python script Java: the
method is defined in a Java class
Location According to the method’s type the A valid URL for Python or valid class
Location contain: Cpp: the name of a names for Cpp and Java
C++ class, which implements this
method. The C++ class must have
already been registered prior to this
declaration. Python: the absolute
location of the python file without the
“.py” extension. Note that the same
python file can contain several methods.
Java: The name of the class (without the
“.class” extension) which implements
this method. The package where the
class belongs must be present in the
CLASSPATH of the plugin. See
Managing the Java CLASSPATH on
page 27 of the plugins.
Function The attribute "Function" is used for It represents the name of a Fortran
registering Fortran methods. subroutine located in the first shared
library of the plugin
Abstract Specifies whether the method is abstract FALSE (default) TRUE
or not. Since an abstract method cannot
be called the attributes Type and
Location canAbstract be omitted. As any
other method (all Caesam methods are
virtual) an abstract method can be
redefined in a subclass.

In the following example, three methods are declared, which are implemented in Python, C++, Java and
Fortran. This declaration requires:
• The existence of a file called MyPythonFile.py in the directory designated by csm:temp. Inside this
file the implementation of the myPythonMethod is found.
• That a class CaesamCppClass has already been registered and it has a registered method named
myCppMethod
• A java class JavaClass is found in a package that has been added to the plugin’s Java CLASSPATH
and it has a method myJavaMethod.
• That a Fortran subroutine called myFortranSubroutine is present in a Fortran source file in the
src/pluginlib/fortran directory and that the plugin has been compiled.

<TypeDesc Name="PanelGeometry" Inherits ="CaesamGeometry">


<Member Name="Length" Type="Caesam_Double">
<Method Name="myPythonMethod" Type="Python" Location="csm:temp/MyPythonFile"
/>
<Method Name="myCppMethod" Type="Cpp" Location="CaesamCppClass" />
<Method Name="myJavaMethod" Type="Java" Location="JavaClass" />
<Method Name="myFortranMethod" Type="Fortran" Function="myFortranSubroutine"
/>
<Method Name="myAbstractMethod" Type="Java" Location="JavaClass"

page-35
Caesam SDK | 5 Type definition in CAESAM

Abstract="True"/>
</TypeDesc>

5.1.2 Caesam methods

5.1.2.1 Defining classes in C++

When implementing Caesam classes in C++, there are several restrictions that must be taken into account.
Some guidelines for designing C++ classes are presented in the following paragraphs.

Object constructor

In C++ the pointer “this” cannot be safely used inside the constructor definition of the class. Since
Caesam_Object methods like GetMember and SetMember make use of it they should never be called
within the constructor body. The constructor must be declared protected and a static method (called
NewInstance for example) for obtaining instances should be defined.
There can be several NewInstance methods defined, but one of them must have the prototype required
by the registration mechanism (Caesam_ConstrPtr):

typedef PTRMEM(Caesam_Object) (*Caesam_ConstrPtr)(PTRARG(Caesam_Object));

Every object derived from Caesam_Object has a method called GetClass() which must return the correct
type of the current instance. By default GetClass will always return Caesam_Object if it isn’t set. This is
why registered classes must set it with the appropriate value by calling SetClass in the constructor.

class MyClass : public MySuperClass{


PTRMEM(Caesam_Quantity) myLength;
protected:
MyClass(){
// we must set the class in the constructor
SetClass(GetRegisteredClass());
}
public:
/* We implement the creator method which
returns an initialized instance of the current class */
static PTRMEM(Caesam_Object) NewInstance(PTRARG(Caesam_Object) theArgument){
MyClass *myClassInstance = new MyClass ();
myClassInstance->InitInstance();
return myClassInstance;
}

Object initialize

Objects are now created with NewInstance and not via the C++ constructor, so when inheriting from a
class, we need to be able to initialize some of the super-class’ members explicitly. This is why we need
an initialization method, which can be called from derived classes. We must not forget to call the
InitInstance of the ancestor class (if there is one), so that our class behaves just like it had a real C++
constructor.

// We implement the method for initializing the class' members


void InitInstance(){
// we must call the initializer of our ancestor
MySuperClass::InitInstance();
// we initialize our length member
myLength = new Caesam_Quantity(5, "LENGTH");
}

page-36
5 Type definition in CAESAM | Caesam SDK

Member accessors

Although not mandatory we can define getters and setters for some or all of our members. If no accessor
is specified when registering a member, Caesam will write/read its value to/from its own map of values.
Apart from being defined, we must tell the registry to use them when someone calls GetMember or
SetMember method.

// The getter and the setter of the member "Length"


void SetLength(PTRARG(Caesam_Quantity) theLength){
myLength = theLength;
}
PTRMEM(Caesam_Quantity) GetLength(){
return myLength;
}

Setters and getters cannot be registered if they do not have the prototype (Caesam_MethodPtr) accepted
by the registration API. In this example, the getter and the setter of the Length member do not have the
correct prototype, so they will be wrapped into MyClass_SetLength and MyClass_GetLength.

static PTRMEM(Caesam_Object) MyClass_SetLength(


PTRARG(Caesam_Object) theInstance,
PTRARG(Caesam_Object) theArgument){
CSMCAST(MyClass, theInstance>
SetLength(Caesam_Quantity::Cast(theArgument));
return NULL;
}

static PTRMEM(Caesam_Object) MyClass_GetLength(


PTRARG(Caesam_Object) theInstance,
PTRARG(Caesam_Object) theArgument){
return CSMCAST(MyClass, theInstance)->GetLength();
}

Class registration

In order to be able to register a C++ class into the system, there must be a Caesam_Class instance for the
class that can be passed to the registration API. A method is defined GetRegisteredClass that returns a
static instance of the class. When creating the Caesam_Class it is necessary to pass several arguments
that describe the new type:
• The name of the class
• The Caesam_Class object of its ancestor
• A pointer to the our constructor method NewInstance
• A pointer to a destructor method which can be set to NULL since object de-allocation is handled via
smart pointers.

// GetRegisteredClass
static PTRMEM(Caesam_Class) GetRegisteredClass() {
static PTRMEM(Caesam_Class) aClass = Caesam_Class::New("MyClass",
MySuperClass::GetRegisteredClass(),
MyClass::NewInstance, NULL);
return aClass;
}

The class can now be registered using the Caesam_Registry::RegisterClass() method.

Standard_Boolean Caesam_Registry::RegisterClass(PTRARG(Caesam_Class)theClass);

page-37
Caesam SDK | 5 Type definition in CAESAM

For readability reasons all the registration methods can be grouped into one static method (named Register):

static void Register(Caesam_Registry *theRegistry) {


// we register the class
theRegistry->RegisterClass(GetRegisteredClass());
// we register the Length member without a getter/setter
theRegistry->RegisterMember("MyClass", "Length", "Caesam_Quantity", NULL,
NULL);
}
};

The complete example is therefore :

class MyClass : public MySuperClass{


PTRMEM(Caesam_Quantity) myLength;
protected:
MyClass(){
// we must set the class in the constructor
SetClass(GetRegisteredClass());
}

public:
/* We implement the creator method which
returns an initialized instance of the current class */
static PTRMEM(Caesam_Object) NewInstance(PTRARG(Caesam_Object)
theArgument){
MyClass *myClassInstance = new MyClass ();
myClassInstance->InitInstance();
return myClassInstance;
}

// We implement the method for initializing the class' members


void InitInstance(){
// we must call the initializer of our ancestor
MySuperClass::InitInstance();
// we initialize our length member
myLength = new Caesam_Quantity(5, "LENGTH");
}
// The getter and the setter of the member "Length"
void SetLength(PTRARG(Caesam_Quantity) theLength){
myLength = theLength;
}

PTRMEM(Caesam_Double) GetLength(){
return myLength;
}
// Because the getter and the setter of the Length member do not have the
// prototype required by the registration API, we have to wrap them into
// methods of type Caesam_MethodPtr
static PTRMEM(Caesam_Object) MyClass_SetLength(
PTRARG(Caesam_Object) theInstance,
PTRARG(Caesam_Object) theArgument){
CSMCAST(MyClass, theInstance)->
SetLength(Caesam_Quantity::Cast(theArgument));
return NULL;
}

static PTRMEM(Caesam_Object) MyClass_GetLength(


PTRARG(Caesam_Object) theInstance,
PTRARG(Caesam_Object) theArgument){
return CSMCAST(MyClass, theInstance)->GetLength();
}

// GetRegisteredClass
static PTRMEM(Caesam_Class) GetRegisteredClass() {

page-38
5 Type definition in CAESAM | Caesam SDK

static PTRMEM(Caesam_Class) aClass = new Caesam_Class("MyClass",


MySuperClass::GetRegisteredClass(),
MyClass::NewInstance, NULL);
return aClass;
}

static void Register(Caesam_Registry *theRegistry) {


// we register the class
theRegistry->RegisterClass(GetRegisteredClass());
// we register the Length member without a getter/setter
theRegistry->RegisterMember("MyClass", "Length", "Caesam_Quantity", NULL,
NULL);
}
};
return aClass;
}

5.1.2.2 Implementing Caesam methods

As mentioned previously, Caesam methods can be implemented in any of the four languages: C++, Python,
Java or Fortran. All methods must be static and they must have the following generic prototype
(conceptually the same in all four languages ):

Caesam_Object MethodName (Caesam_Object theInstance, Caesam_Object theArgument)

Since a Caesam method can be attached to any Caesam class via the class registration or TypeDesc
registration mechanisms, theInstance argument will contain the instance of the object that is calling the
method. The second argument, theArgument can be any Caesam_Object instance or NULL.
It is up to the implementation of the method to verify if the types of theInstance and theArgument
correspond to the expected ones and whether to accept NULL values or not.

Defining Caesam methods in C++

A method written in C++ must satisfy several conditions:


• It should either be a static method of a registered class or a registered standard C function
• It should have the following prototype

typedef PTRMEM(Caesam_Object) (*Caesam_MethodPtr)(PTRARG(Caesam_Object)


theInstance, PTRARG(Caesam_Object) theArgument);

An example of implementation is given below:

PTRMEM(Caesam_Object) ComputeArea(PTRARG(Caesam_Object) theInstance,


PTRARG(Caesam_Object) theArgument){
if(theInstance.IsNull()){
// we check if the received instance is no null
cout << "NULL Instance" << endl;
return NULL;
}

if(!theInstance->IsKindOf("MyClass")){
// we check if the instance is of the expected type or inherits from it
cout << "Invalid instance type: " << theInstance->GetTypeName() << ". ";
cout << "Expected Caesam_Quantity" << endl;
return NULL;
}

if(theArgument.IsNull()){

page-39
Caesam SDK | 5 Type definition in CAESAM

// let's say theArgument is required


cout << "The argument cannot be null" << endl;
return NULL;
}

if(!theArgument->IsKindOf("Caesam_Quantity")){
// we allow Caesam_Quantity only
cout << "Invalid argument type: " << theArgument->GetTypeName() << ". ";
cout << "Expected Caesam_Quantity" << endl;
return NULL;
}

// finally we have a valid instance and a valid quantity argument


// we compute an area from the two values
PTRMEM(Caesam_Double) aArea = new Caesam_Double(0);
PTRMEM(Caesam_Double) aLength = theInstance->GetDouble("Length");
if(!aLength.IsNull()){
Standard_Real aAreaValue = aLength->GetValue() *
theArgument->GetQuantityValue();
aArea->SetValue(aAreaValue);
}
return aArea;
}

Defining Caesam methods in Python

As shown previously it is possible to attach a Python method to a type defined with the TypeDesc (XML)
mechanism. The actual implementation of the method is a Python function defined in the script referenced
in the <Method> tag of the type declaration.
An example of python/MyPythonMethods.py file is given below:

from CaesamAPI import *;

def myPythonMethod(self,aArgument):
if(aArgument == None):
print "PythonMethod called with null argument"
return None
if(aArgument.IsKindOf("Caesam_Double")):
print "Method PythonMethod called with Caesam_Double argument " +
str(aArgument.GetDoubleValue())

Register this function as being a method of MyClass using the <Method> tag

<Type>
<TypeDesc Name="MyClass" Inherits="Caesam_Object">
<Member Name="myString" Type="Caesam_String" />
<Member Name="myQuantity" Type="Caesam_Quantity" />
<Method Name="myPythonMethod" Type="Python"
Location="csm:com.mycompany.myplugin/Python/MyPythonMethods" />
</TypeDesc>
</Type>

Defining Caesam methods in Java

In order to define a java method you must implement a class with one or several static methods that follow
the protocol: "public static Caesam_Object myJavaMethod(Caesam_Object, Caesam_Object)".
Example:

public class MyJavaMethods{

public static Caesam_Object myJavaMethod(Caesam_Object theInstance,

page-40
5 Type definition in CAESAM | Caesam SDK

Caesam_Object theArgument){
if(theArgument == null){
System.out.println("myJavaMethod called with null argument");
return null;
}

if(theArgument.IsKindOf("Caesam_Double")){
System.out.println("myJavaMethod called with Caesam_Quantity argument "
+ theArgument.GetDoubleValue());
return new Caesam_Double(theArgument.GetDoubleValue()*3);
}
return null;
}
}

The path containing the compiled Java classes must be added to the CLASSPATH. Edit the plugin.xml
file and add the “classes” folder in the <ClassPath> section.

<!-- Add the classes folder to the java classpath -->


<ClassPath Type="Caesam_ObjectArray">
<Item Type="Caesam_Url">classes/</Item>
</ClassPath>

Launch caesamsh.cmd This is the Caesam shell that initializes Caesam environment.
At the prompt type "sh compil-plugin.sh -release c:\myfullpluginpath". This will compile
any source found in src/java (for java classes).
If the compilation is successful, MyJavaMethods.class will be found in the "classes" folder.
As was required for the Python method it must be declared as being a method of MyClass. Edit the
previously created MyTypes.typedesc file and declare the method by using the <Method> tag.

<Type>
<TypeDesc Name="MyClass" Inherits="Caesam_Object">
<Method Name="myPythonMethod" Type="Python"
Location="csm:com.mycompany.myplugin/Python/MyPythonMethods" />
<Method Name="myJavaMethod" Type="Java" Location="MyJavaMethods" />
</TypeDesc>
</Type>

Defining Caesam methods in Fortran

In order to define a Fortran method you must implement a subroutine with the following signature:
"subroutine FortranSubroutine(theInstance, theArgument, theReturn)". The three arguments are:
• theInstance: the object on which the method is called (equivalent to self or this in object oriented
languages)
• theArgument: an argument can be of any type derived from Caesam_Object and it can contain any
user values. It is the task of author of this method to decide the type of the expected objects and its
content. This argument is not mandatory.
• theReturn: an argument that can be used to return a value. This argument is not mandatory and by
default it is set to null.
Example:

subroutine myFortranSubroutine(theInstance, theArgument, theReturn)


integer Caesam_Object_GetTypeName
integer aRetStat
type (transient_handle) theInstance, theArgument, theReturn
character(len=128) :: aInstanceType

aRetStat = Caesam_Object_GetTypeName(theInstance, aInstanceType)

page-41
Caesam SDK | 5 Type definition in CAESAM

print *, 'The instance type: ', aInstanceType


end subroutine myFortranSubroutine

Launch caesamsh.cmd This is the Caesam shell that initializes Caesam environment.
At the prompt type "sh compil-plugin.sh -release c:\myfullpluginpath". This will compile
any Fortran source found in src/pluginlib/fortran.
If the compilation is successful, myFortranSubroutine will be found in the plugin's shared library.
It is now neccessary to tell Caesam that the Fortran subroutine is a method of MyClass. Edit the previously
created MyTypes.typedesc file and declare the method by using the <Method> tag. Note that the declaration
of the Fortran method requires the presence of the attribute "Function", which is not the case for Python,
Java or Cpp methods. The value of Function represents the name of the Fortran subroutine.

<Type>
<TypeDesc Name="MyClass" Inherits="Caesam_Object">
<Method Name="myPythonMethod" Type="Python"
Location="csm:com.mycompany.myplugin/Python/MyPythonMethods" />
<Method Name="myJavaMethod" Type="Java" Location="MyJavaMethods" />
<Method Name="myFortranMethod" Type="Fortran" Function="myFortranSubroutine"
/>
</TypeDesc>
</Type>

5.1.2.3 The creation of a library of C++ classes and its integration into a plug-in

How the plugin system works

The Caesam plugin system will first read the plugin.xml file and will try to load all the libraries referenced
in the <Libraries> tag. For each shared library encountered it will perform the following tasks:
• Firstly it will compare the version of Caesam under which it was compiled with the running version
of Caesam. If the two versions do not match, the loader will consider that the plug-in is incompatible
with the current version of Caesam and will generate an exception.
• Secondly it will look for a function called initialize. If the library exports this function the plugin loader
will call it; otherwise Caesam will generate an exception.

How to create a shared library of C++ classes

The following steps should be followed in order to integrate C++ classes in Caesam via the plugin system:
1. Implement the C++ classes on page 43.
2. Implement the initialize() method to call the Register method of each of the classes to be registered.
3. Compile the classes and then link them in a shared library together with the provided CaesamKey.obj
so that the current Caesam version can be found by the system.
4. Add the URL that points to the library in the plugin.xml file under the tag <Libraries>.
5. Add the classes defined in this library to the list of classes defined under the <Classes> tag of the
plugin.xml file.
A typical implementation of the initialize and uninitialize functions is given below:

extern "C"{
STL_EXPORT void initialize(Caesam_Registry *theRegistry,
Caesam_Persistence *thePersistenceManager){
// Register the MyClass Object
MyClass::Register(theRegistry);
}

STL_EXPORT void uninitialize(Caesam_Registry *theRegistry,


Caesam_Persistence *thePersistenceManager) {
//Do some uninitialization if necessary

page-42
5 Type definition in CAESAM | Caesam SDK

return;
}
}

5.2 C++ classes


A declaration is equivalent to registering a class, member or method to the Caesam class registry. The
notion of “declaration” is used for describing the structure of a class and that of “definition” for referencing
its implementation.

Class declaration

Registering a C++ class in Caesam means informing the system of its existence, from which class it
derives and how an instance of that class can be created. This can be accomplished in 2 steps:
Step 1 : Create an instance of Caesam_Class that describes the C++ class to be registered.

Caesam_Class::New(const STL_String& theClassName,


PTRARG(Caesam_Class) theSuperClass,
const Caesam_ConstrPtr theConstructor,
const Caesam_MethodPtr theDestructor,
const Standard_Boolean theIsAbstract);
Purpose: Register a Caesam class

Argument Description Accepted values

theClassName The name under which the Any string


class should be registered
theSuperClass The ancestor of this class An instance of another registered Caesam_Class.
Usually this can be obtained with a call to:
MyAncestorClass::GetRegisteredClass()
theConstructor A pointer to a static method This method should have the Caesam constructor
that returns an instance of this prototype: typedef PTRMEM(Caesam_Object)
class. (*Caesam_ConstrPtr) (PTRARG(Caesam_Object));
theDestructor Not used NULL
A flag which specifies Standard_False (default) Standard_True
whether the class is abstract
or not. Note that an abstract
class cannot be instantiated
(NewObject will raise an
exception when attempting to
create an object of an abstract
type).

Returns true if the registration of the class succeeded.

Note: Please note for creating Caesam_Class instances one must always use the factory
method Caesam_Class::New instead of the constructor. Using the "new" operator with
Caesam_Class is forbidden.

page-43
Caesam SDK | 5 Type definition in CAESAM

Step 2 : Store the previously created class in the system’s registry by using:

Standard_Boolean
Caesam_Registry::RegisterClass(PTRARG(Caesam_Class)theClass);

Member declaration

A Caesam class can have one or several attributes (members) that must be registered along with the class.
The registration of C++ classes offers the possibility to specify member accessors (methods for indirectly
accessing the object’s members).
The API to be used for registering a member implemented in C++

Standard_Boolean Caesam_Registry::RegisterMember(
const STL_String& theClassName,
const STL_String& theMemberName,
const STL_String& theMemberType,
const Caesam_MethodPtr theGetterPtr,
const Caesam_MethodPtr theSetterPtr);

Purpose: To register a member of a class

Argument Description Accepted values

theClassName The name of the class to which the Any string


member belongs
theMemberName The name of the member under which Any valid method name
it should be registered
theMemberType The type of the member. This type should be a valid Caesam type,
which has already been registered (either
in C++ or in TypeDesc).
theGetter A static method pointer to the Get Caesam_MethodPtr
accessor of the field. This argument is
optional. If NULL, Caesam_Object will
use its internal member map for Get and
Set
theSetter A method pointer to the Set accessor of Caesam_MethodPtr
the field. This argument is optional. If
NULL, Caesam_Object will use its
internal member map for Get and Set

Returns true if the registration succeeded.


The setter and getter method pointers are optional, if they are set to NULL, the object will use an internal
map (the same as for members defined in XML files) for storing their values. If they are not NULL, the
generic accessors GetMember and SetMembers will call the registered getter and setter respectively.
The use of member setters and getters is recommended when special actions need to be performed before
retrieving or changing the value of a member (like input argument validation, internal state update or
other objects notification).
Although it is possible to have mixed null and non-null method pointers for the two arguments (like null
setter and non null getter or the vice versa) it should be avoided unless the mechanism is completely
understood. Example:

aRegistry->RegisterMember(
"MyClass",
"MyMember",

page-44
5 Type definition in CAESAM | Caesam SDK

"Caesam_String",
&MyMemberGetter,
&MyMemberSetter);

Methods declaration

In C++, a method declaration is equivalent to registering the method in the Caesam class registry. Refer
to Implementing Caesam methods on page 39 for details about the implementation of methods in different
languages.
The API to be used for registering a method implemented in C++ when the method pointer is
available

Standard_Boolean Caesam_Registry::RegisterMethod(
const STL_String& theClassName,
const STL_String& theMethodName,
const Caesam_MethodPtr theMethodPtr,
const Standard_Boolean theIsAbstract);
Purpose: Register a method of a class

• theClassName : the name of the class the method belongs to.


• theMethodName : the name of the method under which it should be registered.
• theMethod : a pointer to the method to be registered.
• theIsAbstract : (optional) If this argument is true, the method will be declared abstract.
Returns: true if the registration succeeded. Example:

theRegistry->RegisterMethod("MyClass", "MyMethod", &MyClass_MyMethod);

The API to be used for registering a method implemented in other languages than C++ or when
the method pointer is not available.
Internally, Caesam uses the same API for registering XML method declarations, which means that an
existing method can be registered from any language.

Standard_Boolean Caesam_Registry::RegisterMethod(
const STL_String& theClassName
const STL_String& theMethodName,
const STL_String& theMethodType,
const STL_String& theMethodLocation,
const Standard_Boolean theIsAbstract);
Purpose: Register a method of a class (source) as being a method of the current
class

Argument Description Accepted values

theClassName The name of the class to which the method is to be


assigned
theMethodName The name of the method under which it should be Any valid method name
registered. It must match the name of the method
implemented in the class referenced in the
Location.
theMethodType The type of the method. Cpp: the method is defined Cpp Python Java
in C++ Python: the method is defined in a Python
script Java: the method is defined in a Java class.

page-45
Caesam SDK | 5 Type definition in CAESAM

Argument Description Accepted values

theMethodLocation The name of the class (location/name of a script) A valid URL for Python
the method belongs to. According to the method’s or valid class names for
type the Location contains: Cpp: the name of a C++ Cpp and Java.
class, which implements this method. The C++
class must have already been registered prior to
this declaration. Python: the absolute location of
the python file without the “.py” extension. Note
that the same python file can contain several
methods. Java: The name of the class (without the
“.class” extension) which implements this method.
The package where the class belongs must be
present in the CLASSPATH of the plugin. See
Managing the Java CLASSPATH on page 27 .
theIsAbstract (optional) Specify whether the method is abstract or not. Since Standard_False (default)
an abstract method cannot be called the attributes Standard_True
Type and Location can be omitted. As any other
method (all Caesam methods are virtual) an abstract
method can be redefined in a subclass

Returns: Standard_True if the registration succeeded. Example:

theRegistry->RegisterMethod("MyClass", "MyMethod", "Java", “MyJavaClass”);

5.3 Class relations

Inheritance of Caesam classes

Some definitions follow:


• Pure XML class : a class defined in XML, which inherits from another XML class or a Caesam kernel
type. There is no C++ class in the inheritance tree.
• Pure C++ class : a class defined in C++, which inherits from another C++ class. There is no XML
class in the inheritance tree.
• Caesam kernel class : a class that was defined in the Caesam’s built-in plugins: Caesam, CaesamStd,

• Caesam inheritance : a class inherits from another class in Caesam sense if a the inheritance is declared
via the registration mechanism
• C++ inheritance : a class inherits from another class in C++ sense if the inheritance is declared using
the C++ language.
A class defined in Caesam, which derives from another registered class, will inherit all its members and
its methods from its super class. When declaring a new class without specifying an ancestor, the registration
mechanism will implicitly set it to Caesam_Object. In this way the subclass will benefit from all the
Caesam_Object API.
Methods redefinition: In Caesam all members are final (they cannot be redefined in the subclass) and
all methods are virtual (they can be redefined in the subclass). In other words, a class that inherits from
another one can overwrite the methods (both abstract and non-abstract) of the super-class, but not its
members. Method overwriting is performed on a name basis (the type of the overloaded method must not
necessarily match the type of the new method).
The instantiation mechanism: When calling the NewObject for instantiating an object, Caesam will
search for the first registered non-null constructor in the inheritance tree. If it is found, NewInstance will
use it to construct the object, if it is not found Caesam will construct a Caesam_Object. The searching is
performed from bottom to top: if the constructor of the first C++ class in the inheritance is NULL or it is
an XML class, Caesam will look at the constructor of the superclass and so on.

page-46
5 Type definition in CAESAM | Caesam SDK

Although it is possible to have inheritance (in the Caesam sense) between a C++ and an XML class, some
restrictions need to be considered before designing a plug-in. According to the place where the two classes
are defined (the subclass and the super-class), we distinguish two cases of inheritance:
Case 1: All classes in the inheritance tree are defined in the same plug-in or in Caesam kernel. This means
we have access to the C++ declaration the class; so real C++ inheritance is possible. Several cases of
inheritance:
• A.XML inherits from a pure B.XML. A will also be a pure XML class. An instance of A will be in
fact an instance of Caesam_Object.
• A.XML inherits from pure B.C++. At instantiation the returned object will be of type B in C++ sense
and of type A in Caesam sense.
• A.C++ inherits from a pure B.XML. When calling the NewInstance for instantiating an object of the
type A, Caesam will use the C++ constructor of the class A to build the object.
• A.C++ inherits from a pure B.C++. The class A must inherit from B in both Caesam and C++ sense.
When creating an instance of type A, Caesam will use the registered constructor for this class. If no
constructor has been specified for A, it will use the constructor of B.
• A.C++ inherits from B.XML inherits from C.C++. The class A must inherit from B in Caesam and
inherit from C in C++ sense. When creating an instance of type A, Caesam will use the registered
constructor for this class.
Case 2 : One of the super-classes in the inheritance tree is defined in a different plug-in.
To be able to have real C++ inheritance between two classes, the declaration of the super-class must be
available when compiling the subclass. In other words we need the include file where the super-class is
declared in order to be able to build our class.
If this include file is available (it may be delivered together with the plug-in binaries by the plug-in
developer) then the inheritance is possible, but note that by using an include file delivered with a different
plug-in implies making the two plug-ins binary dependent.

Caution: This could pose a serious problem concerning the maintenance and evolution
of a plug-in and it is recommended to avoid it whenever class composition or aggregation
can be used instead of inheritance.

Therefore, in the case where one class is defined in one plug-in and the superclass is defined in another
one, the last two cases of inheritance “A.C++ inherits from a pure B.C++” and “A.C++ inherits from
B.XML inherits from C.C++” are possible only if the super class declaration is available.

Class composition in Caesam

Composition is the process of constructing a new class composed of several other classes. The lifetime
of the objects used in the composition must be the same as the composite class. In Caesam this is achieved
by integrating the part objects in the whole as an “owned” private member and mapping the necessary
setters and getters of the current class to this internal object. The part object (internal member) can be of
any of the registered types, ranging from primitives (as in the following example) to arrays or maps of
objects.

/****************************************************
* The "part" class declaration
****************************************************/

class MyPartClass : public Caesam_Object{


protected:
MyPartClass(){
// we must set the class in the constructor
SetClass(GetRegisteredClass());
}
public:
/* We implement the creator method which
returns an initialized instance of the current class */
static PTRMEM(Caesam_Object) NewInstance(PTRARG(Caesam_Object) theArgument){

MyPartClass *myClassInstance = new MyPartClass ();

page-47
Caesam SDK | 5 Type definition in CAESAM

myClassInstance->InitInstance();
return myClassInstance;
}

// We implement the method for initializing the class' members


void InitInstance(){
// we initialize our length member
SetMember("Length", new Caesam_Double(0.5));
}

// GetRegisteredClass
static PTRMEM(Caesam_Class) GetRegisteredClass() {
static PTRMEM(Caesam_Class) aClass = Caesam_Class::New("MyPartClass",
NULL,
MyPartClass::NewInstance, NULL);
return aClass;
}

static void Register(Caesam_Registry *theRegistry) {


// we register the class
theRegistry->RegisterClass(GetRegisteredClass());
// we register the Length member without a getter/setter
theRegistry->RegisterMember("MyPartClass", "Length",
"Caesam_Double", NULL, NULL);
}
};

/****************************************************
* The "whole" class declaration
****************************************************/
class MyWholeClass : public Caesam_Object{
protected:
PTRMEM(Caesam_Object) myPartClassInstance;
MyWholeClass(){
SetClass(GetRegisteredClass());
}
public:

// The getter and the setter of the member "Length"


void SetLength(PTRARG(Caesam_Double) theLength){
myPartClassInstance->SetMember("Length", theLength);
}

PTRMEM(Caesam_Double) GetLength(){
return Caesam_Double::Cast(myPartClassInstance->GetMember("Length"));
}

/* We implement the creator method which


returns an initialized instance of the current class */
static PTRMEM(Caesam_Object) NewInstance(PTRARG(Caesam_Object) theArgument){

MyWholeClass *myClassInstance = new MyWholeClass ();


myClassInstance->InitInstance();
return myClassInstance;
}

/* We implement the method for initializing the class' members


We also initialize the part object */
void InitInstance(){
myPartClassInstance = Caesam_Application::GetApplication()-
>NewObject("MyPartClass", NULL);
}

// we implement wrappers for the class' members accessors


static PTRMEM(Caesam_Object) MyWholeClass_SetLength(
PTRARG(Caesam_Object) theInstance,
PTRARG(Caesam_Object) theArgument){

page-48
5 Type definition in CAESAM | Caesam SDK

CSMCAST(MyWholeClass, theInstance)-
>SetLength(Caesam_Double::Cast(theArgument));
return NULL;
}

static PTRMEM(Caesam_Object) MyWholeClass_GetLength(


PTRARG(Caesam_Object) theInstance,
PTRARG(Caesam_Object) theArgument){
return CSMCAST(MyWholeClass, theInstance)->GetLength();
}

// GetRegisteredClass
static PTRMEM(Caesam_Class) GetRegisteredClass() {
static PTRMEM(Caesam_Class) aClass = new
Caesam_Class("MyWholeClass",
NULL,
MyWholeClass::NewInstance, NULL);
return aClass;
}

static void Register(Caesam_Registry *theRegistry) {


// we register the class
theRegistry->RegisterClass(GetRegisteredClass());
// we register the members
theRegistry->RegisterMember("MyWholeClass", "Length", "Caesam_Double",
MyWholeClass::MyWholeClass_GetLength,
MyWholeClass::MyWholeClass_SetLength);
}
};

// we register the two classes


extern "C"{
STL_EXPORT void initialize(Caesam_Registry *theRegistry,
Caesam_Persistence *thePersistenceManager){
MyPartClass::Register(theRegistry);
MyWholeClass::Register(theRegistry);
}
}

// now we can use test our class. We create an instance


PTRMEM(Caesam_Object) aMyWholeClass = aApp->NewObject("MyWholeClass");
// want to check if the GetMember("Length") returns 0.5
cout << "MyWholeClass.Length = " << aMyWholeClass-
>GetDoubleValue("Length") << endl;
cout << "Should be 0.5" << endl;

Class aggregation in Caesam

Aggregation is the process of constructing a class from several different parts that are related in some
way with that class. The lifetime of the objects is not the same; one part object can live even after the
whole object has been destroyed. Cyclic dependencies between the part and the whole are forbidden.
In Caesam this is the handiest technique to be used since usually objects are composed of public members
that could hold these parts. By default, the method SetMember of the Caesam_Object stores a reference
to the object and not a copy of it; therefore the lifetime of the members is not bound to the lifetime of the
object.

5.4 Flags
Flags are used in Caesam for specifying binary attributes in class declarations and instances. Currently
there are 4 types of flags in Caesam:
• Class flags (Caesam_ClassFlag)
• Member flags (Caesam_MemberFlag)

page-49
Caesam SDK | 5 Type definition in CAESAM

• Method flags (Caesam_MethodFlag)


• Instance flags (Caesam_InstanceFlag)

Setting flags in the type description files

Flags can be specified in Caesam class declarations (typedesc or C++). Multiple flags can be separated
by the '|' symbol and the NOT symbol is '~'.
• class level : to specify if a class is abstract of obsolete

<Class ... ClassFlags="ABSTRACT|OBSOLETE">

• member level :to flag a member as read only, private, ...

<Member ...
MemberFlags="READ_ONLY|IMMUTABLE|PRIVATE|SHARED|OBSOLETE">

• method level : to specify if a method is abstract or obsolete

<Method MethodFlags="ABSTRACT|PRIVATE|OBSOLETE">

Example:

<Type>
<TypeDesc Name="MyClass" Inherits="Caesam_Object"
ClassFlags="ABSTRACT">
<Member Name="myPrivateInteger" Type="Caesam_Integer" MemberFlags="PRIVATE"/>
<Member Name="myReadonlyString" Type="Caesam_String" MemberFlags="READ_ONLY">
<Member Name="myReadOnlyPrivateString" Type="Caesam_String"
MemberFlags="PRIVATE|~READ_ONLY"/>
<Method Name="myMethod" Type="Python"
Location="csm:myplugin/python/myPython" MemberFlags="ABSTRACT"/>
</TypeDesc>
</Type>

Example of class registration with flags

Standard_Boolean Caesam_Registry::RegisterClass(
const STL_String& theClassName,
const STL_String& theSuperClassName,
const Caesam_ConstrPtr theConstr,
const Caesam_MethodPtr theDestr,
const STL_String& theClassFlags);
theRegistry->RegisterClass("MyClass", "MySuperClass", NULL, NULL, "ABSTRACT")

API for manipulating declaration flags

enumeration MemberFlagsEnum is
MEMBER_READ_ONLY,
MEMBER_IMMUTABLE,
MEMBER_PRIVATE,
MEMBER_SHARED,
MEMBER_OBSOLETE
end;
Caesam_Member::SetMemberFlag(Caesam_MemberFlagEnum theFlag)
Caesam_Member::ResetMemberFlag(Caesam_MemberFlagEnum theFlag)
Caesam_Member::MemberFlagIsSet(Caesam_MemberFlagEnum theFlag)

page-50
5 Type definition in CAESAM | Caesam SDK

enumeration ClassFlagsEnum is
CLASS_ABSTRACT,
CLASS_OBSOLETE
end;
Caesam_Class::SetClassFlag(ClassFlagsEnum theFlag)
Caesam_Class::ResetClassFlag(ClassFlagsEnum theFlag)
Caesam_Class::ClassFlagIsSet(ClassFlagsEnum theFlag)

enumeration MethodFlagsEnum is
METHOD_ABSTRACT,
METHOD_PRIVATE,
METHOD_OBSOLETE
end;
Caesam_Method::SetMethodFlag(Caesam_MethodFlagEnum theFlag)
Caesam_Method::ResetMethodFlag(Caesam_MethodFlagEnum theFlag)
Caesam_Method::MethodFlagIsSet(Caesam_MethodFlagEnum theFlag)

API for manipulating instance flags

These flags are stored at instance level and they can be set or reset via the Caesam_Object API:

Caesam_Object::SetInstanceFlag(Caesam_InstanceFlagEnum theFlag)
Caesam_Object::ResetInstanceFlag(Caesam_InstanceFlagEnum theFlag)
Caesam_Object::InstanceFlagIsSet(Caesam_InstanceFlagEnum theFlag)

5.5 Resources
Resources in Caesam are static instances associated with classes, members or methods. Their main purpose
is to allow authors to define constant values that are used by the platform to configure GUI elements,
format the display of members of numeric types and to define default instances of classes.
Resources can be defined in the declarations of the classes (both typedesc and C++) and they can be
accessed during the runtime.

5.5.1 Class resources


As from version 5.2.1 there are four pre-defined resource groups: Constant, GUI, Comment and
UserResources.

Note: that some new branches (such as Default) will be added in the future.

• GUI : the pre-defined class GUI resources (members of CaesamRes_ClassGUI) are:


• EOCreationPath: Caesam_String
• EOEditor: Caesam_String
• Editor: Caesam_String
• Help: Caesam_Url
• TableCreationPath: Caesam_String
• TableCreationClass: Caesam_String
• AnalysisCreationClass: Caesam_String
• AnalysisCreationPath: Caesam_String
• DisplayDriver: Caesam_String
• VisibilityFilter: Caesam_String
• FormDescriptor: Caesam_Url
• TabularEditorModel: Caesam_String

page-51
Caesam SDK | 5 Type definition in CAESAM

• EditabilityFilter: Caesam_String
• Comment : the Comment predefined resource can contain a description of the class.
• UserResources : Authors can define their own class resources, which are independent of the Caesam
platform, through the use of UserResources member. This can be a single object or a collection of
objects (map, array, ...).

Defining class resources in typedesc files

A Typedesc example is given below:

<TypeDesc Name="PanelProfile" Inherits="CaesamStd_EO">


<!-- Provide a description of the class as a Comment resource. -->
<Comment>The is an example of how to define class resources in typedesc
files</Comment>

<!-- Declaring the members of the PanelProfile class -->


<Member Name="thickness" Type="CaesamQty_LENGTH" />

<!-- Defining the EO creation path as a GUI (predefined) resource. -->


<GUI Type="CaesamRes_ClassGUI">
<EOCreationPath>/hidden/</EOCreationPath>
</GUI>

<!-- Defining a user resource. -->


<UserResources Type="AnyType">
...
</UserResources>

</TypeDesc

Defining resources of C++ classes.

Setting a class resource: Caesam_Class has a new method which allows the definition of class resource
when registering a class in C++:

SetResource(me:mutable;
theResourcePath: String from STL;
theResourceObject: Object from Caesam)
returns Boolean from Standard is redefined;

C++ Example:

Handle(Caesam_Class) PanelProfile::GetRegisteredClass(){
static Handle(Caesam_Class) aClass = Caesam_Class::New(
"PanelProfile",
CaesamStd_EO::GetRegisteredClass(),
CAESAMCONSTRUCTOR(PanelProfile::NewInstance), NULL);
return aClass;
}

void PanelProfile::Register(const Handle(Caesam_Registry)& theRegistry){


theRegistry->RegisterClass(GetRegisteredClass());
theRegistry->RegisterMember("PanelProfile", "thickness", "CaesamQty_LENGTH",
NULL, NULL);
GetRegisteredClass()->SetResource("GUI/EOCreationPath", new
Caesam_String(/hidden/));
}

page-52
5 Type definition in CAESAM | Caesam SDK

Accessing class resources: Note that when accessing a resources, the name of the resource must be a
valid object path (see Caesam_Object::FindObject for the correct syntax) that starts with one of the
predefined resource names Constant, GUI, Comment or UserResources.

HasResource(me;
theResourcePath: String from STL)
returns Boolean from Standard is redefined;
---Purpose: Returns true if there is a resource at the specified path

GetResource(me;
theResourcePath: String from STL)
returns Object from Caesam is redefined;
---Purpose: Find a resource by its path (like GUI/EOCreationPath). Returns

-- NULL if no resource has been found.

Important:
Prior to Caesam v5.2.1 class resources were declared in plugin.xml files under the
<Resources> tag as items of a Caesam_ObjectMap. In version 5 the class resource container
is not a Caesam_ObjectMap, but a Caesam_ClassResourceCollection which has some
pre-defined members (instead of keys) making the use of resources less prone to misspelling
errors.
In order to be backward compatible, Caesam still accepts the old style resource declaration
and will copy the items of the class resources map from plugin.xml to the corresponding
members of the CaesamRes_ClassGUI object. When accessing a resource with a name that
does not contain the '/' character, Caesam will assume it is located under the GUI branch.
GetResource("EOCreationPath") is equivalent to
GetResource("GUI/EOCreationPath").

5.5.2 Member resources


Just like classes, member declarations can include resources. They also have Constant, GUI, Comment
and UserResources, access methods like SetResource, HasResource and GetResource and they can be
defined both in typedesc and C++. See class resources for more details.
There are some pre-defined member Constant objects (subclasses of CaesamRes_Constant) that describe
the physical dimension and the formatting of members of numeric types (CaesamRes_QuantityConstant,
CaesamRes_DoubleConstant). These resources (like Constant/Format or Constant/PhysicalDimension)
are used by the platform when rendering numeric values.
Authors can define their own member resources, which are independent of the Caesam platform through
the use of UserResources tag. This can be a single object or a collection of objects (map, array, ...).

Defining member resources in typedesc files

Typedesc example:

<TypeDesc Name="PanelProfile" Inherits="CaesamStd_EO">


<Member Name="thickness" Type="CaesamQty_LENGTH">
<!-- Provide a description of the member as a Comment resource. -->
<Comment>The is an example of how to define member resources in typedesc
files</Comment>

<Constant Type="CaesamRes_QuantityConstant">
<!-- Define the formatting options of the thickness member as a Constant
resource. -->
<Format Precision="2" RoundingMode="CEIL" Real2StringMode="FIXED" />
</Constant>

page-53
Caesam SDK | 5 Type definition in CAESAM

<!-- Defining a user resource of the member. -->


<UserResources Type="AnyType">
...
</UserResources>
</Member>
</TypeDesc>

Defining resources of members declared in C++

C++ Example:

void PanelProfile::Register(const Handle(Caesam_Registry)& theRegistry){


theRegistry->RegisterClass(GetRegisteredClass());
theRegistry->RegisterMember("PanelProfile", "thickness", "CaesamQty_LENGTH",
NULL, NULL);
Handle(CaesamRes_QuantityConstant) aQuantityConstant = new
CaesamRes_QuantityConstant();
aQuantityConstant->SetFormat(CaesamRes_NumberFormat::GetDefaultFormat());
GetRegisteredClass()->GetMember("thickness")->SetResource("Constant",
aQuantityConstant);
}

5.5.3 Accessing class and member resources from an instance


In order to facilitate the manipulation of resources, Caesam_Object exposes several methods which are
shortcuts to the resource access methods presented above.

GetClassResource(me;
theResourcePath: String from STL)
returns Object from Caesam;
---Purpose: Returns the resource located at theResourcePath in the
-- resource objects hierarchy of the class. This method is a shortcut to
-- GetClass()->GetResource(theResourcePath)

SetClassResource(me;
theResourcePath: String from STL;
theResourceObject: Object from Caesam)
returns Boolean from Standard;
---Purpose: Sets the resource at theResourcePath for the specified class.
---Warning: Note that class resources are static. They are stored in the
definition of
-- the class and not in the object. Changing the value of a class
-- resource will impact the class of all the instances of this type. This
method
-- is a shortcut to GetClass()->SetResource(theResourcePath,
theResourceObject)

GetMemberResource(me;
theMemberName: String from STL;
theResourcePath: String from STL)
returns Object from Caesam;
---Purpose: Returns the resource located at theResourcePath in the resource

-- objects hierarchy of the member. This method is a shortcut to


-- GetClass()->GetMember(theMemberName)->GetResource(theResourcePath)

GetMemberResourceName(me;
theMemberName: String from STL;
theResourcePath: String from STL)
returns String from STL;
---Purpose: Returns the name of the global object defined at theResourcePath

page-54
5 Type definition in CAESAM | Caesam SDK

-- or empty string if the resource is null or it does not contain a global


object.
---Example: In the following member declaration we defined a resource named
"Constant"
-- that has a PhysicalDimension member which is initialized with a
-- reference to a global object.
-- <Member Name="RF" Type="CaesamQty_DIMENSIONLESS" >
-- <Constant Type="CaesamRes_QuantityConstant">
-- <PhysicalDimension Initialize="*physical.dimension.RF"/>
-- </Constant>
-- </Member>
-- Somewhere in the code we can find find out the name of that global
resource object.
-- o.GetMemberResourceName("RF", "Constant/PhysicalDimension") will return
"PhysicalDimension.RF".
-- EXPORT:
---Level: Public

SetMemberResource(me;
theMemberName: String from STL;
theResourcePath: String from STL;
theResourceObject: Object from Caesam)
returns Boolean from Standard;
---Purpose: Sets the resource at theResourcePath for the specified member.
---Warning: Note that member resources are associated to the member definition

-- and not the member instance. Changing the value of a member resource
-- will impact the class of all the instances of this type. This method
-- is a shortcut to
GetClass()->GetMember(theMemberName)->SetResource(theResourcePath,
theResourceObject)

GetMethodResource(me;
theMethodName: String from STL;
theResourcePath: String from STL)
returns Object from Caesam;
---Purpose: Returns the resource located at theResourcePath in the resource

-- objects hierarchy of the method. This method is a shortcut to


-- GetClass()->GetMethod(theMethodName)->GetResource(theResourcePath)

SetMethodResource(me;
theMethodName: String from STL;
theResourcePath: String from STL;
theResourceObject: Object from Caesam)
returns Boolean from Standard;
---Purpose: Sets the resource at theResourcePath for the specified method.
---Warning: Note that method resources are associated to the method definition

-- Changing the value of a method resource will impact all the instances
-- of this type. This method is a shortcut to
-- GetClass()->GetMethod(theMethodName)->SetResource(theResourcePath,
theResourceObject)

5.6 Pre-defined types

Caesam_Object

All registered types must be derived from Caesam_Object, which offers the following features.
• Instantiate registered types

page-55
Caesam SDK | 5 Type definition in CAESAM

• Access object’s members


• Call registered methods
• Examine the object’s type
• Make shallow or deep object copies
• Obtain the C++ primitive values via a set of “shortcut” accessors.
Caesam_Object has several virtual methods that can be redefined by authors:
• GetUserType : Returns the type (in the form of a STL string) of the current object for the user point
of view. Sometimes, the user type is different than the caesam type (ex: CaesamStd_SEA,
CaesamStd_Operation). By default, this method returns GetTypeName().
• ShortDesc : A short description of this object used for instance by Caesam_Message to insert this
object in a Logger or error message. By default it returns the type of the object and its address in
memory.
• Dump : This method should be used dump the caesam object content for debugging purposes. If not
redefined it returns the list of the members and their values.
• FindObject : This method can be used to find an object by its path relative to the current object (the
root). It can be redefined if in order to accept a different semantic of the path.
• :
Refer to Manipulating CAESAM_OBJECT on page 66 instances for more information.

Primitive types

In Caesam, primitive types are wrapper classes that implement the interface Caesam_Primitive. Some
features of primitive classes are:
• They must implement the abstract methods ToString and FromString in order to assure their textual
representation. Note that these methods are also used for persistence.
• They can have registered members and methods.
• All primitive classes implemented in the kernel have GetValue and SetValue
Table 1: Primitives defined in the Caesam kernel

Primitive class Description Accepted values Text format

Caesam_Boolean Wraps the type Standard_True “TRUE” “FALSE”


Standard_Boolean Standard_False
Caesam_BooleanArray Array of Standard_True TRUE;FALSE;TRUE
Standard_Boolean Standard_False
values
Caesam_Double Wraps the type Double values “732.103”
Standard_Real
type
Caesam_DoubleArray Array of Double values “732.103;7.12e4”
Standard_Real
type
Caesam_Integer Wraps the Standard_Integer Integer values “12000”
type
Caesam_IntegerArray Array of Integer values “12000;700;150”
Standard_Integer
values
Caesam_String Wraps String values “str”
STL_String

page-56
5 Type definition in CAESAM | Caesam SDK

Primitive class Description Accepted values Text format

Caesam_StringArray Array of String values “str1”;”str2”;”str3”


STL_String
values
Caesam_Date Date-time storage Date time “yyyy-mm-dd hh:mi:ss”
class
Caesam_Url Uniform (See Uniform resource locator on page 140 for more information.)
resource locator
Caesam_Version A version storage A version string “M.m-R”
class having 3
fields: Major,
minor and
revision

Caesam_Quantity

Caesam_Quantity is a special kind of primitive type in Caesam that can be used to store and manipulate
real numbers defined by a unit. In addition to the double value, Caesam_Quantity has a dimension and
optionally: a GUI unit, a minimum value and a maximum value.
Starting with Caesam 5.1.0, Caesam_Quantity has a series of subclasses (one for each dimension recognized
by Caesam). Please consult the CaesamQty package documentation for a complete list.

Note: that for new developments, these specialized classes (e.g. CaesamQty_LENGTH)
should be preferred over the direct use of Caesam_Quantity.

Improvements of the CaesamQty_<Dimensions> are listed below:


• Superior memory and speed performance: the dimension is not stored in a string member which
counts for a smaller memory footprint. For Caesam_Quantities, every instance contains a string that
identifies the Dimension of the quantity.
• Simpler definition of members of quantity type: the CaesamQty classes don't need the Dimension
member to be set, since its value is contained in the class definition itself. Consequently, specifying
the dimension of a quantity member in a default file is no longer neccessary.
• Stronger type checking: once a member is defined as a CaesamQty_<DIMENSION>, its type can
no longer be changed during the runtime. The Caesam_Quantity dimension could be changed anytime
through a call to SetDimension.
Except for the constructors, CaesamQty_<Dimension> and Caesam_Quantity share the same public
methods. In the following example the two equivalent methods of constructing a LENGTH quantity is
shown.

// creating a length quantity using the CaesamQty_LENGTH class


Handle(CaesamQty_LENGTH) aLength = new CaesamQty_LENGTH(3.52);

// creating a length quantity using the Caesam_Quantity class


Handle(CaesamQuantity) aLength = new Caesam_Quantity(3.52, "LENGTH");

page-57
Caesam SDK | 5 Type definition in CAESAM

Table 2: Caesam_Quantity methods

Methods Description

GetValue, SetValue (required) Accessors for the double value stored by the
quantity object. The value field always contains a
value (the default is 0.0)
GetDimension, SetDimension (required) Accessors of the Dimension field. Since Dimension
is a required field, it will contain “UNKNOWN”
by default. The list of the accepted dimension
values is documented further in this chapter.
GetMin, SetMin, GetMax, SetMax (optional) Methods for storing minimum and maximum
values for the quantity object. The Min and Max
are used by the framework to validate value entered
by the user. Note that these fields are optional and
should be set only when this verification is
necessary in order to reduce memory consumption.
GetGuiUnit, SetGuiUnit (optional) When set, the GuiUnit field will indicate to the
framework in which unit system the quantity value
should be displayed.
Note that this field is optional and should be set
only when the Caesam default unit system is not
appropriate. Also note that this field is used by the
GUI framework only. Setting it will NOT convert
the internal value of the quantity to the specified
units

Table 3: The list of the Quantity by dimension classes

Quantity Description

CaesamQty_DIMENSIONLESS
CaesamQty_MASS
CaesamQty_LENGTH
CaesamQty_TIME
CaesamQty_THERMODYNAMIC_TEMPERATURE
CaesamQty_PLANE ANGLE
CaesamQty_AREA LENGTH**2
CaesamQty_VOLUME LENGTH**3
CaesamQty_INERTIA LENGTH**4
CaesamQty_ANGULAR SPEED PLANEANGLE/TIME
CaesamQty_SPEED LENGTH/TIME
CaesamQty_ACCELERATION
CaesamQty_FREQUENCY

page-58
5 Type definition in CAESAM | Caesam SDK

Quantity Description

CaesamQty_VOLUMIC_MASS MASS/VOLUME
CaesamQty_MOMENT_OF _INERTIA MASS*LENGTH**2
CaesamQty_FORCE
CaesamQty_MOMENT_OF_A_FORCE FORCE*LENGTH
CaesamQty_PRESSURE FORCE/AREA
CaesamQty_LINEIC_FORCE FORCE/LENGTH
CaesamQty_ROTATION_ACCELERATION ANGLE/TIME**2
CaesamQty_THERMAL_CONDUCTIVITY POWER/LENGTH/TEMP
CaesamQty_THERMAL_CONVECTIVITY POWER/AREA/TEMP
CaesamQty_POWER
CaesamQty_SURFACIC_POWER POWER/AREA
CaesamQty_VOLUMIC_POWER POWER/VOLUME
CaesamQty_LINEIC_POWER POWER/LENGTH
CaesamQty_TRANSLATION_STIFFNESS FORCE/LENGTH
CaesamQty_ROTATION_STIFFNESS FORCE*LENGTH/ANGLE
CaesamQty_COEFFICIENT_OF_LINEAR_INFLATION 1/TEMPERATURE
CaesamQty_ENERGY
CaesamQty_DYNAMIC_VISCOSITY FORCE/AREA/TIME
CaesamQty_THERMICAL_MASSIC_CAPACITY POWER/MASS/TEMP
CaesamQty_MEMORY
CaesamQty_MASS_FLOW MASS/TIME or
FORCE/(LENGTH/TIME)
CaesamQty_INFORMATION amount of information (bytes)
CaesamQty_ACOUSTIC_IMPEDANCE MASS/(AREA*TIME)
CaesamQty_ACOUSTIC_ADMITTANCE (AREA*TIME)/MASS
CaesamQty_PIEZOELECTRICITY CHARGE ELECTRIC/FORCE
CaesamQty_ELECTRIC_POTENTIAL
CaesamQty_ELECTRIC_CHARGE
CaesamQty_VOLUME_FLOW
CaesamQty_LINEIC_ELECTRIC_CHARGE_DENSITY
CaesamQty_SURFACIC_ELECTRIC_CHARGE_DENSITY

page-59
Caesam SDK | 5 Type definition in CAESAM

Quantity Description

CaesamQty_VOLUMIC_ELECTRIC_CHARGE DENSITY
CaesamQty_VOLUMIC_FORCE
CaesamQty_DIELECTRIC_PERMITTIVITY
CaesamQty_THERMICAL_VOLUMIC_CAPACITY
CaesamQty_COMPLIANCE
CaesamQty_KINETIC MOMENT
CaesamQty_QUANTITY_OF_MOVEMENT
CaesamQty_LINEIC_MASS
CaesamQty_SURFACIC_MASS MASS/LENGTH**2
CaesamQty_SQUARE_VELOCITY
CaesamQty_SQUARE_PRESSURE
CaesamQty_LINEIC_ENERGY_DENSITY
CaesamQty_SURFACIC_ENERGY_DENSITY
CaesamQty_VOLUMIC_ENERGY_DENSITY
CaesamQty_PERFECT_GAS_CONSTANT
CaesamQty_AMOUNT_OF_SUBSTANCE
CaesamQty_INVERSE_TIME
CaesamQty_DAMPING
CaesamQty_CURVATURE
CaesamQty_ELECTRIC_RESISTANCE
CaesamQty_INDUCTANCE
CaesamQty_ELECTRIC_CAPACITANCE
CaesamQty_ELECTRIC_CONDUCTANCE
CaesamQty_MAGNETIC_PERMEABILITY
CaesamQty_CONDUCTIVITY
CaesamQty_CURRENT_DENSITY
CaesamQty_THERMAL_SURFACE_CHARGE_DENSITY
CaesamQty_MAGNETIC_FLUX_DENSITY
CaesamQty_INVERSE_POWER 1/POWER
CaesamQty_INVERSE_ENERGY 1/ENERGY

page-60
5 Type definition in CAESAM | Caesam SDK

Quantity Description

CaesamQty_STRESS_INTENSITY_FACTOR MASS*TIME**-2*
LENGTH**-(1/2)
CaesamQty_UNKNOWN The unit is unknown or not
managed by Caesam. Example;
Length**0.5

Table 4: Converting quantities from and to strings

Method Description

FromString ToString Converts a string into a quantity (and vice versa) and sets the internal
members. The accepted format:
"VALUE;DIMENSION;[MIN];[MAX];[UNIT]"
Last 3 params are optional.
Examples of quantities represented as strings: "3.21;LENGTH"
"3.21;LENGTH;0.1;10" "3.21;LENGTH;0.1;10;mm" Whitespaces between
values and the ';' separator are ignored.

When editing Caesam XML files manually, quantities must be expressed in one of the accepted forms.
Example:

<Instance Type="PanelProfile">
<thickness Type="Caesam_Quantity">2;LENGTH</thickness>
</Instance>

Table 5: Quantity arrays and matrices

Class name Description

Caesam_QuantityArray An array of real numbers that has a dimension, GUI unit, minimum
and a maximum value. The Value field is an array of double values,
Min, Max and GuiUnit are the same as in Caesam_Quantity.
Caesam_QuantityMatrix A matrix of doubles that has a dimension, GUI unit, minimum and
a maximum value

Object Arrays

Object arrays are indexed collections of Caesam Objects.


Table 6: Object arrays

Array type Description Ancestor class

Caesam_ObjectArray Array of Caesam_Objects Caesam_Object


Caesam_TypedArray Same as Caesam_ObjectArray, but with Caesam_ObjectArray
an additional member called “Type”,
which be used to restrict the type of
objects that can be stored in the map

page-61
Caesam SDK | 5 Type definition in CAESAM

An example of how to use an Caesam_TypedArray is given below:

PTRMEM(Caesam_TypedArray) aTypedArray = new Caesam_TypedArray("Caesam_Double");

aTypedArray->Append(new Caesam_Double(2.3));
aTypedArray->Append(new Caesam_Double(6.8));
aTypedArray->Append(new Caesam_Double(3.1));
Standard_Integer aItemsCount = aTypedArray->Size();
for (Standard_Integer i=0; i<aItemsCount; i++){
PTRMEM(Caesam_Double) aDouble = Caesam_Double::Cast(aTypedArray->Get(i));
cout << "Item["<< i << "]=" << aDouble->GetValue() << endl;
}
/* Will print
Item[0]=2.3
Item[1]=6.8
Item[2]=3.1
*/

Arrays can have a fixed size, either at creation by passing a integer value to the constructor or through
the SetSize method. This is also true for primitive arrays. Arrays with a fixed size do not allow Append,
Insert, Remove or Set beyond the current size.

Object Matrices

Object matrices are bi-dimensional indexed collections of Caesam Objects.


There is a matrix class corresponding to each array class in Caesam: Caesam_ObjectMatrix,
Caesam_TypedMatrix, Caesam_DoubleMatrix, Caesam_IntegerMatrix, Caesam_StringMatrix and
Caesam_BooleanMatrix.
An example of how to use a Caesam_DoubleMatrix is given below:

PTRMEM(Caesam_DoubleMatrix) aDoubleMatrix = new Caesam_DoubleMatrix();


aDoubleMatrix->Set(0,2,2.3);
aDoubleMatrix->Set(2,1,6.8);
Standard_Integer aRowCount = aDoubleMatrix->RowCount();
Standard_Integer aColCount = aDoubleMatrix->ColumnCount();
for (Standard_Integer i=0; i<aRowCount; i++)
for (Standard_Integer j=0; j<aColCount; j++){
Standard_Real aDouble = aDoubleMatrix->Get(i,j);
cout << "Item["<< i << "," << j << "]=" << aDouble << endl;
}
/* Will print
Item[0,0]=0.0
Item[0,1]=0.0
Item[0,2]=2.3
Item[1,0]=0.0
Item[1,1]=0.0
Item[1,2]=0.0
Item[2,0]=0.0
Item[2,1]=6.8
Item[2,2]=0.0 */

Matrices can also have a fixed size.

Object Maps

Maps are collections of <key, value> pairs offering mechanisms for storing, iterating and retrieving
objects. All map classes defined in Caesam can store any type of objects that derive from Caesam_Object.
According to the type of the key, we can distinguish two kinds of maps in Caesam:
• Derived from Caesam_PrimitiveObjectMap which have keys of primitive types
• Caesam_ObjectObjectMap which have both keys and values of type Caesam_Object

page-62
5 Type definition in CAESAM | Caesam SDK

Table 7: Object arrays

Map type Description Ancestor class

Caesam_StringObjectMap <STL_String, Caesam_Object> Caesam_PrimitiveObjectMap


pairs
Caesam_IntegerObjectMap <Standard_Integer, Caesam_PrimitiveObjectMap
Caesam_Object> pairs
Caesam_DoubleObjectMap <Standard_Real, Caesam_Object> Caesam_PrimitiveObjectMap
pairs
Caesam_ObjectMap Identical to Caesam_PrimitiveObjectMap
Caesam_StringObjectMap
Caesam_TypedObjectMap Same as Caesam_ObjectMap
Caesam_StringObjectMap, but
with an additional member called
Type, which can be used to restrict
the type of objects that can be
stored in the map.
Caesam_ObjectObjectMap Both keys and values are of type Caesam_Iterator
Caesam_Object. Internally, the key
is represented as the object address
in memory.

An example is given below

PTRMEM(Caesam_StringObjectMap)
aObjectMap = new Caesam_StringObjectMap();
aObjectMap->Put("aQuantity", new Caesam_Quantity(5, "LENGTH"));
aObjectMap->Put("aDate", new Caesam_Date());
aObjectMap->Put("aDouble", new Caesam_Double(2.3));

Iterating by keys signifies obtaining an array with all the keys that were stored in the map and then retrieve
their associated objects.
• Disadvantage: There is an overhead added by the key search.
• Advantage: Items are returned in the order they have been added
An example of iterating using keys is given below:

// Iterate using keys


Handle(Caesam_StringArray) aKeys = aObjectMap->Keys();
Standard_Integer aKeysCount = aKeys->Size();
for (int i=0; i<aKeysCount; i++){
STL_String aKey = aKeys->Get(i);
PTRMEM(Caesam_Object) aValue = aObjectMap->Get(aKey);
}
// Items are returned in this order: aQuantity, aDate, aDouble

Caesam_Iterator – Obtains the Iterator object from the map instance and then use the iterator methods to
retrieve the key and value pair of the current object.
• Advantage: Faster than iterating by keys
• Disadvantage: Does not preserve the order in which the items were added. Items are always arranged
in ascending order by key.

page-63
Caesam SDK | 5 Type definition in CAESAM

An example of using the Caesam_Iterator is given below:

// Iterate using Caesam_Iterator"


Handle(Caesam_Iterator) aIt = aObjectMap->Iterator();
while(aIt->Next()){
STL_String aKey = aIt->First()->GetStringValue();
PTRMEM(Caesam_Object) aValue = aIt->Second();
}
// Items are returned in this order: aDate, aDouble, aQuantity

5.7 Enumerations
Starting with Caesam 5.5 it is possible to define enumerated values on a member of a class directly in
typedesc files. This can be accomplished by implementing a new type in a typedesc and declare a list of
possible values for that type and use that type in the declaration of a member. In Caesam 6.2.1 a new
feature has been added which allows the definition of dynamic enumerations as user defined methods
(GetEnumeration).

Define the enumerated type in a typedesc file

Static enumerations
The enumerated type must inherit from a class registered in Caesam (usually a primitive type). The list
of values is defined as a map of <string key, value> pairs placed within the tag <Enumeration> under the
typedesc.
Example:

<!-- Declare the enumeration class -->


<TypeDesc Name="Transverse_LoadCaseStatusEnum" Inherits="Caesam_String">
<!-- Define the list of possible values as a map -->
<Enumeration>
<Item Key="Unknown" Type="Transverse_LoadCaseStatusEnum" >Unknown</Item>
<Item Key="Nominal" Type="Transverse_LoadCaseStatusEnum" >Nominal</Item>
<Item Key="Ultimate" Type="Transverse_LoadCaseStatusEnum" >Ultimate</Item>

</Enumeration>
</TypeDesc>

Dynamic enumerations
Starting with Caesam 6.2.1 it also possible to build the list of the enumerated values dynamically in a
user defined GetEnumeration method.
<!-- Declare the enumeration class-->
<TypeDesc Name="Transverse_LoadCaseStatusDynamicEnum" Inherits="Caesam_String">
<!-- Declared the GetEnumeration method -->
<Method Name="GetEnumeration" Type="Python"
Location="csm:com.samcef.caesam.example/python/Validation_DynamicEnumType" />
</TypeDesc>
def GetEnumerationValues(theInstance, theArgument):
aEnum = Caesam_ObjectMap()
aEnum.Put("DYNAMIC ENUM KEY 1", NEW_OBJECT("Caesam_String", "DYNAMIC ENUM VALUE 1"))

aEnum.Put("DYNAMIC ENUM KEY 2", NEW_OBJECT("Caesam_String", "DYNAMIC ENUM VALUE 2"))

aEnum.Put("DYNAMIC ENUM KEY 3", NEW_OBJECT("Caesam_String",


theInstance.GetStringValue("anotherMember")))
return aEnum

Declaring a member of an enumerated type

Now that we have the enumeration defined we can use it to declare a member to which we would like to
attach the list of values.

page-64
5 Type definition in CAESAM | Caesam SDK

Example:
<TypeDesc Name="Transverse_UnitaryLoadCase" Inherits="CaesamLC_UnitaryLoadCase" >
<Member Name="Status" Type="Transverse_LoadCaseStatusEnum" />
<Member Name="Temperature" Type="Caesam_Double" />
<Member Name="aMember" Type="Transverse_LoadCaseStatusDynamicEnum" />
</TypeDesc>

Defining a static enumeration as a member resource

Starting with V6.2.1 it possible to define the list of enumerated values directly as a resource of the member
without having to define an enumerated type.
Example:
<TypeDesc Name="Transverse_UnitaryLoadCase" Inherits="CaesamLC_UnitaryLoadCase" >
<Member Name="Status" Type="Caesam_String">
<Enumeration>
<Item Key="Unknown" Type="Caesam_String" >Unknown</Item>
<Item Key="Nominal" Type="Caesam_String" >Nominal</Item>
<Item Key="Ultimate" Type="Caesam_String" >Ultimate</Item>
</Enumeration>
</Member>
</TypeDesc>

Enumerations can also be defined using the Enum attribute of the <Member> typedesc declaration. This
enum is an array of strings representing the values of the enum using the Caesam_StringArray syntax.
Internally this list is converted to an ObjectMap with both the key and the value containing the same
string.
Example:

<TypeDesc Name="Material" Inherits="CaesamStd_EO">


<Member Name="aMember" Type="Caesam_String" Enum="value 1;value 2" />
</TypeDesc>

This list can be retrieved from a Caesam_Object using the GetMemberEnumValues(theMember) method.

Defining a dynamic enumeration as a member resource

Caesam allows the definition of a "enumeration getter" method for each member. The implementation of
this getter should return a map of <key,value> pairs.
<TypeDesc Name="Transverse_UnitaryLoadCase" Inherits="CaesamLC_UnitaryLoadCase" >
<Member Name="Status" Type="Caesam_String">
<Enumeration Getter="@GetMemberEnumeration" />
</Member>
<Method Name="GetMemberEnumeration" Type="Python"
Location="csm:com.samcef.caesam.example/python/CaesamLC_UnitaryLoadCase" />
</TypeDesc>
def GetMemberEnumeration(theInstance, theArgument):
aEnum = Caesam_ObjectMap()
aEnum.Put("GETTER ENUM KEY 1", NEW_OBJECT("Caesam_String", "GETTER ENUM VALUE 1"))

aEnum.Put("GETTER ENUM KEY 2", NEW_OBJECT("Caesam_String", "GETTER ENUM VALUE 2"))

aEnum.Put("GETTER ENUM KEY 3", NEW_OBJECT("Caesam_String",


theInstance.GetStringValue("anotherMember")))
return aEnum

This list can be retrieved from a Caesam_Object using the GetMemberEnumValues(theMember) method.

page-65
Caesam SDK | 6 Objects

6 Objects
This section refers to C++

6.1 Smart Pointers


In Caesam, memory management is handled using reference counted smart pointers. An object’s lifetime
is managed internally, so that no explicit destruction of the created instances is required. In order to benefit
from this feature, all instances must be stored using this kind of pointer. To do this use the pre-defined
macros for declaring Caesam_Object smart pointers.

Macros for manipulating smart pointers

• PTRARG(Caesam_Object) A constant smart pointer (the pointed object cannot be changed) which is
used for declaring arguments.
• PTRMEM(Caesam_Object) used to declare smart pointer variables or return values.
Registered C++ classes must communicate (i.e. accept arguments and return values) with the kernel API
only via smart pointers. This is why in the implementation of a class it is necessary to cast a
PTRARG(Caesam_Object) or PTRMEM(Caesam_Object) argument into a pointer of our own type. For
this purpose use the CSMCAST macro.
• CSMCAST(MyClass, PTRMEM(Caesam_Object)) Cast smart pointer arguments into standard pointers.

Accessing members and methods via smart pointers

• Use the “.” operator for accessing members and methods of the smart pointer
IsNull() will return Standard_True if the actual object equals null. Note that when creating a smart
pointer without initializing it, the actual object is automatically set to null. Example:

PTRMEM(Caesam_Object) aObject;
aObject.IsNull(); // will return true

• Use the “–>” operator for accessing members and methods of the actual object

PTRMEM(Caesam_Double) aDoubleObject = new Caesam_Double(5.0);


if( ! aObject.IsNull() ){
cout << aDoubleObject->GetValue() << endl;
}
// will print 5.0

An example of class implementation where smart pointers are used is given below:

class MyClass : public Caesam_Object{


Standard_Real myWidth, myHeight
public:
MyClass(const Standard_Real aWidth, const Standard_Real aHeight){
myWidth = aWidth;
myHeight = aHeight;
}
static PTRMEM(Caesam_Object) ComputeArea(
PTRARG(Caesam_Object) theInstance,
PTRARG(Caesam_Object) theArgument)
{
// we check if the instance is not null
if(theInstance.IsNull()){
return NULL;
}

page-66
6 Objects | Caesam SDK

// We must obtain a real pointer of type MyClass to the instance


MysClass *aMyClassInstance = CSMCAST(MysClass, theInstance);
// We compute the area
Standard_Real aArea = aMyClassInstance->myHeight *
aMyClassInstance->myWidth;
//As said before, a class can only accept and return smart
// pointers to Caesam_Objects so we wrap the real value
// into a Caesam_Double
PTRMEM(Caesam_Object) aAreaObject = new Caesam_Double(aArea);
return aAreaObject;
}
};
CaesamAPI_Application::GetApplication();
aApp = Caesam_Application::GetApplication();
PTRMEM(Caesam_Object) aMyClassInstance = new MyClass(2.0, 5.0);
PTRMEM(Caesam_Object) aAreaObject = MyClass::ComputeArea(aMyClassInstance,
NULL);
PTRMEM(Caesam_Double) aAreaDoubleObject = Caesam_Double::Cast(aAreaObject);

cout << aAreaDoubleObject->GetValue() << endl;


// will print 10.0

Note: This is a simple example to illustrate the use of smart pointers only. Type verification
of arguments has been deliberately omitted. A more rigorous definition of a C++ class is
given below.

6.2 Creating a new instance


A Caesam_Object instance can be created in several ways:
• Using a C++ constructor when it is available. All the classes defined in the Caesam package (i.e. those
that begin with “Caesam_”, such as primitives, arrays, etc.) have public constructors therefore they
can be instantiated by using the object instantiation syntax proper to the language. Example:
• C++: PTRMEM(Caesam_Quantity) aObject = new Caesam_Quantity(2.0, “LENGTH”);
• Python: aObject = Caesam_Quantity(2.0, “LENGTH”)
• Java: Caesam_Object aObject = new Caesam_Quantity(2.0, “LENGTH”)
• Using the NewInstance method of the class when the declaration of the class is available. This is only
possible when the instantiation of the class is made inside the code of plugin where the class is declared
or, if the include file containing its declaration can accessed
• Using the Caesam_Application::NewObject method. This is the recommended method for creating
objects of registered types, which are not declared in the same plugin and only the class name is known.
Example:

PTRMEM(Caesam_Object) anArgument = Caesam_Double(2.0);


PTRMEM(Caesam_Object) aClassInstance =
Caesam_Application::GetApplication()->NewObject("MyClassName", anArgument);

NewInstance : Creates a new object instance having the type specified by theClass. This method will call
the appropriate constructor for each registered type and initialize it with the default value if
theSetDefaultValue is true.

6.3 Setting and getting member values


Methods and descriptions follow.

page-67
Caesam SDK | 6 Objects

• GetMember : Purpose: Returns the value of the member specified by theName argument. If the
object’s class has a getter defined for that member it will call it and if it doesn’t GetMember will
retrieve the value stored in the Caesam_Object’s internal member map. Warning: Note that GetMember
returns a reference (not a copy) of the member value. If the returned value is assigned to another object
using SetMember for instance the other object will reference to the same value. When values need to
be transferred between objects by copy the Clone method must be used. Example:
aObject->SetMember("Value", anotherObject->GetMember("Value")->Clone())
• SetMember : Purpose: Sets the member specified by theName argument with a reference to the
theObject. If the object’s class has a setter defined for that member it will call it. If it does not,
SetMember will store the value of the member in the Caesam_Object’s internal member map.
• UnsetMember : Purpose: Sets the member specified by theName argument to NULL.
• MemberIsSet : Purpose: Returns Standard_True if the member is not NULL. Warning: Some
Caesam_Objects have default instances, which automatically set some or all of the members with
non-null values. Therefore one should not make assumptions about the state of a member, but should
always use MemberIsSet.
• GetMemberNames : Gets a string array containing the names of the object's members.
GetMemberNames will return the list of all the object's class and superclasses members. This is
equivalent with to ->GetClass()->GetMemberNames()

6.4 Calling a method


A list of Methods and descriptions follow.
• CallMethod : Purpose: Call the method of the current object, specified by theMethodName and having
theArgument. CallMethod can be used on any registered method of any class.
Examples: aPanel->CallMethod("ComputeArea", NULL) aMath->CallMethod("Square", new
Caesam_Double(2.32))
• GetMethodNames : Purpose: Get a string array containing the names of the object's methods.
GetMethodNames will return the list of all the object's class and superclasses methods. This is equivalent
to ->GetClass()->GetMethodNames()

6.5 Copy and clone methods


A list of methods and descriptions follow.
• Copy : The purpose of the Copy method is to copy the content of an input object to the current object,
member-to-member, item-to-item.

virtual void Copy(


PTRARG(Caesam_Object) theInputObject,
const Standard_Boolean theIsShallowCopy);

The Copy method can copy objects in two ways: Deep copy: If theIsShallowCopy is not set, Copy
performs a deep copy of the input object by calling Copy recursively on each member/item of the
object. Shallow copy: If theIsShallowCopy flag is set the Copy will only assign the members/items
of the input object to the corresponding members/items of the current object.
• Clone : Create copies of the current object. The Clone method is capable of making a deep clone of
an object by copying all its members recursively into a new instance or a shallow clone by assigning
member references to the members of the new instance of the same type.
• Redefining the behaviour of the Copy/Clone methods : When the default member-to-member and
item-to-item object cloning algorithm is not appropriate, authors can re-define the CopyInternal virtual

page-68
6 Objects | Caesam SDK

method of Caesam_Object. Internally, the Caesam_Object::Copy and Caesam_Object::Clone methods


use CopyInternal.

virtual void CopyInternal(


PTRARG(Caesam_Object) theInputObject,
const Standard_Boolean theIsShallowCopy,
PTRARG(Caesam_ObjectObjectMap) theCopiedObjectsMap);

The purpose of CopyInternal is to copy the content of an input object to the current object,
member-to-member, item-to-item. - Deep copy: If theIsShallowCopy is not set, CopyInternal performs
a deep copy of the input object by calling CopyInternal recursively on each member/item of the object.
- Shallow copy: If theIsShallowCopy flag is set the CopyInternal will only assign the members/items
of the input object to the corresponding members/items of the current object. - The copied objects map
contains the objects that have already been copied (this map should be passed when calling CopyInternal
recursively)
Some things authors should remember when re-implementing the CopyInternal method
• If the memberwise copy is still needed, authors should first call the CopyInternal method of the
super class and then implement their own copying. The reason for that is the default implementation
of the CopyInternal does more than just copying members. If the default copy is not called, the
redefined CopyInternal may need to re-implement some of its functionality. Please read below in
order to understand the internals of Caesam_Object::CopyInternal.
• The re-defined CopyInternal must implement both the shallow and deep copy modes.
• Once an object (a member or an item) has been visited it must be added to theCopiedObjectsMap.
This map is shared with other CopyInternal calls and is used by Caesam to avoid copying an object
more than once and to avoid cycling indefinitely.
• When copying arrays the current container is resized (truncated or grown) to the size of theInput
array and then items are copyied one by one.
• When copying maps all the keys of theInput map that are not found in the current map are removed
from the current map. After copying the current map will have the same size as theInputMap.
• If theInputObject is the owner of a copied member or an item , the current object should become
the owner of these items
Example:

void MyClass::CopyInternal(PTRARG(Caesam_Object) theInputObject,


const Standard_Boolean theIsShallowCopy,
PTRARG(Caesam_ObjectObjectMap) theCopiedObjectsMap)
{
// exit if there is nothing to copy
if (theInputObject.IsNull()) return;

// optionally check if the input object type matches the current object
type
if (!theInputObject->IsKindOf(MyClass::GetRegisteredClass())){
CSM_LOG_ERROR("MyClass", "CopyInternal", "Incompatible types")
return;
}
// call parent copy
Caesam_Object::CopyInternal(theInputObject, theIsShallowCopy,
theCopiedObjectsMap);

// your own copy implementation


...
}

page-69
Caesam SDK | 6 Objects

6.6 Examining the object type


A list of methods and descriptions follow.
• GetClass : Returns the type (in the form of a Caesam_Class) of the current object. The returned class
can be used to find detailed information about the type.
• GetTypeName : Returns the class name (in the form of a STL string) of the current object. This is
equivalent to ->GetClass()->GetName()
• IsInstanceOf : Checks if the current object is an instance of a registered type.
Example:

PTRMEM(Caesam_Object) aObject;
aObject =
NewInstance(Caesam_Double::GetRegisteredClass());
aObject->IsInstanceOf("Caesam_Double")
Will return Standard_True;

• IsKindOf : Verifies if the current object is an instance of a registered type or from a type derived from
it. This method is equivalent to calling the HasType method of the
class:this->GetClass()->HasType(theClassName)
Example:

PTRMEM(Caesam_Object) aObject;
aObject =
NewInstance(Caesam_Double::GetRegisteredClass());
aObject->IsKindOf("Caesam_Primitive")
Will return Standard_True;

6.7 Comparing Caesam objects


A list of methods and descriptions follow.
• IsSame : Checks if two handles reference the same object. This method is equivalent to a pointer
comparison.
• Equals : Checks if the content of the two objects are the same. The equals method tries to make a
member-to-member correspondence between the two objects and to call Equals on each member.
Equals will return false as soon as two non-equal members are found. Note that this method is virtual.
It should be redefined by any object that does not follow the member-to-member comparison model.

6.8 Direct accessors for built-in types


GetInteger(“theMember”) : Caesam_Integer
GetIntegerValue(“theMember”) : int
SetIntegerValue(“theMember”,5)
GetDouble (“theMember”): Caesam_Double
GetDoubleValue(“theMember”) : double
SetDoubleValue(“theMember”,20.)
GetQuantity (“theMember”) : Caesam_Quantity
GetQuantityValue(“theMember”) : double
SetQuantityValue(“theMember”,”aString”)

page-70
6 Objects | Caesam SDK

6.9 Finding an object by its path in the object hierarchy


Every subclass Caesam_Object implement a Find(thePath) method which can be used to find an object
in the object's hierarchy. The instance (this) on which the Find method is called is considered as the root
of the tree (whether the path starts with a slash '/' or not). If the path equals the "/" the current object is
returned.
If one of the members or items referenced by one of the elements of the path does not exist or is NULL
Find method will raise an exception.

Standard semantic of the path

Currently the Caesam_ObjectPath syntax accepts 3 types of elements


• members, which are separated by the slashes: /member/
• array items, represented by indexes enclosed in square brackets: [5]
• map items, represented by keys enclosed in square brackets: [akey]
Examples:
aObject->Find("myQuantity/Value"); // Retrieve the member called "Value" of a quantity object
aObject->Find("AnArrayMember[5]"); // Retrieve the 5th item of an array member
aObject->Find("AMapMember[key1]"); // Retrieve the object located under the key "key1" of the map
member
aObject->Find("AMapMember[key1][0]"); // Retrieve the first item of the array located under the key
"key1"

Custom semantic of the path

Some classes overload the Find method in order to accept a different semantic. Although an object can
still be accessed by its standard path, having a shorter or more meaningful path element can help.
Classes that accept different semantics:
• CP : EO[eokey], Operation[operationname]
• SE : idem CP
• SEA: idem CP + CP[cpkey]
• Operation: Operation[suboperationkey]
• DataSet : EO[eokey], Operation[suboperationkey], ProcessParameter[processparameterkey]
• Directory:
• By name: SubDir/SubSubDir/Item
• By the Children member: Children[SubDir]/Children[SubSubDir]/Children[Item]
• By child index: Children[0]/Children[1]/Children[3]
• Model:
• Access via the root directory: Root/...
• Shortcuts to the predefined subdirectories: SERoot/..., SEARoot/..., OperationRoot/..., GroupRoot/...,
EORoot/...
• Direct access by the item key (i.e. the UUID): [UUID]
• Access through the map member: CsmMbr_KeyMap[UUID]
• EOLibrary:
• Direct access by the EO name: [theEOName]
• As a directory: see above

6.10 Other Caesam_Object services


A list of methods and descriptions follow.
• GetEnumValues : Returns the enumeration associated with the current object's class. To find out
which is the enumeration for a given type, look in the plugin.xml file in the appropriate plugin directory.

page-71
Caesam SDK | 6 Objects

Under each Item of the <Classes> tag you can find the <Enumeration> tag pointing to the enumeration
instance of the object. Will return NULL object if there is no enumeration associated with the class.

6.11 Global objects


Global objects are <namespace, variable, object> triplets defined in an static tree at application level.
They are organized in a hierarchy of namespaces and can be referenced by names of the form
"namespace.variable".
The main features of the global objects are:
• they are complex objects that can be defined in XML
• they can be used to initialize members of other objects either by copy or by reference
• they are accessible from everywhere (they are managed by Caesam_Application)
• they are available anytime. Once defined in a typedesc, they are added to the global object manager
right immediately after the classes in the typedesc are registered. This makes it possible to use them
in the initialization of class or member resources. See examples below.

6.11.1 Defining global objects


Global objects are defined in typedesc files by using the <Instance> tag and using the same syntax as for
csm files. In addition to the Type and InstanceFlags, global instances have another two attributes:
Namespace and Name which are used to identify them inside the collection of global objects.
An example of typedesc with a global object definition is given below.

<Type>

<!--
We want to define a global object named "Thickness" which belongs
to the "caesam.examples.numberformats" namespace
-->

<Instance Namespace="caesam.examples.numberformats" Name="Thickness"


Type="CaesamRes_NumberFormat">
<Precision>4</Precision>
<RoundingMode>CEIL</RoundingMode>
<Real2StringMode>FIXED</Real2StringMode>
</Instance>

</Type>

6.11.2 Using global objects to initialize members of other objects


Once defined, the global objects can be used to initialize members of other objects, either by copy or by
reference. This can be accomplished through the use of the Initialize XML attribute or programatically.

Initializing a member with a copy of a global object

If the Initialize attribute contains the name of the global object ("namespace.variable") the member will
be set with a copy of the global object

<Instance Type="MyClass">
<Format Initialize="caesam.examples.numberformats.Thickness"/>
</Instance>

page-72
6 Objects | Caesam SDK

The above XML example is equivalent to writing:

Handle(Caesam_Object) aNumberFormat = aApp->NewObject("MyClass");


aNumberFormat->SetMember("Format",
aApp->FindGlobalObject
("caesam.examples.numberformats.Thickness")->Clone());

Initialize a member with a reference to a global object

If the Initialize attribute contains the name of the global object prefixed by an asterisk
("*namespace.variable") the member will contain a reference to the global object.

<Instance Type="MyClass">
<Format Initialize="*caesam.examples.numberformats.Thickness"/>
</Instance>

The previous XML example is equivalent to writing:

Handle(Caesam_Object) aNumberFormat = aApp->NewObject("MyClass");


aNumberFormat->SetMember("Format",
aApp->FindGlobalObject("caesam.examples.numberformats.Thickness"));

6.11.3 Accessing global objects


Global objects are managed via methods of the Caesam_Application class:

GetGlobalObject (me:mutable;
theGlobalObjectNamespace: String from STL;
theGlobalObjectName: String from STL)
returns Object from Caesam;
---Purpose: Find an object by its name in the specified namespace

GetGlobalObjectName (me:mutable;
theGlobalObject: Object from Caesam)
returns String from STL;
---Purpose: Find the name of a global object

FindGlobalObject (me:mutable;
theFullGlobalObjectName: String from STL)
returns Object from Caesam;
---Purpose: Returns the object located at theFullGlobalObjectName. The full
name must
-- contain a string like "namespace.objectname" starting from the root
-- namespace.

GlobalObjectExists (me;
theGlobalObjectNamespace: String from STL;
theGlobalObjectName: String from STL)
returns Boolean from Standard;
---Purpose: Returns true if a global object with that name exists

SetGlobalObject (me:mutable;
theGlobalObjectNamespace: String from STL;
theGlobalObjectName: String from STL;
theGlobalObject: Object from Caesam)

page-73
Caesam SDK | 6 Objects

returns Boolean from Standard;


---Purpose: Add or replace a global object

GetGlobalObjectNames (me;
theNameSpace: String from STL)
returns StringArray from Caesam;
---Purpose: Returns the list of object names that belong to a namespace

RemoveGlobalObject (me:mutable;
theGlobalObjectNamespace: String from STL;
theGlobalObjectName: String from STL)
returns Boolean from Standard;
---Purpose: Remove a global object

6.11.4 Redefining global objects


When a global object is defined more than once (in one or more plug-ins), Caesam will keep the value of
the last definition.
Some notes about global object redefinition:
• Redefining a global object will replace the existing object with the new one.
• The order in which global objects are (re)defined depends on the order in which the plug-ins are loaded.
Since the order is not guaranteed by default, authors should always insure that plug-ins that redefine
global objects are loaded at the right moment. The loading order can be controlled via <Import> or
<Include> tags.
• Redefining global objects will have an impact on all objects that reference it. All the member that have
a "*namespace.variable" style initializer will point to the new value of the variable.

page-74
7 The Analysis dedicated objects | Caesam SDK

7 The Analysis dedicated objects


It is strongly recommended that you take a look at the various SDK examples, in particular the
SuperstiffenerAnalysis.

The Model

CaesamStd_Model is the global container used to store the data. The usual way to store data in the Model
is to use the Put method in a Process_Model specialized class. The model can also contain some more
complex objects like the CaesamStd_EOLibrary. The Model is available from all the Process_Task
inherited classes. Only the Process_Model type of process should modify the Model.
For the other classes, it should be use mainly to retrieve information such as a CsmContext or the
EOLibrary.

The EO Library

The EO Library can be retrieved from the Model by calling the GetEOLibrary() method. As its name
implies, this object is made to store a set of EOs. These EOs can subsequently be used to build an SE. In
most cases EOs from the library are used by making a reference to them.

The Mesh

The CaesamStd_GFEM is the object provided to store a MESH. It is relatively straightforward to use.

The SE Topology

The CaesamStd_SETopology is the object used to store the topology of the various SEs.

CaesamStd_Location

The CaesamStd_Location is used to set a reference to a Topology element.


Consider for example, the case where an SE is topologically equivalent to 10 FEM elements. You must
set to this SE a CaesamStd_Location containing these 10 elements. The same thing should be done the
other sense: you should set an equivalent CaesamStd_Location to the FEM entity to be able to find its
corresponding SE.

The DataSet

The DataSet is in fact a collection of EOs. Since V6, a DataSet can be declared as any other Caesam class:
the class members are the EOs making up the dataset. But you can also add undeclared EOs to a DataSet.
In this case, a map made up of (Name, EO) pairs will be used, the Name being the key referencing the
EO (this is however less efficient regarding memory). The DataSet is used as argument to the Run method
in the Process_Analysis. It is the Input/Output object for an analysis.

Load cases

Caesam is able to manage some files as load case inputs. The objects used for this are located in the
CaesamLC package. The load cases can be retrieved from XML files or Msc Nastran Op2 files. You can
then use them in your own Process_Analysis.

7.1 Results Handling


Some of the predefined Result objects are inheriting from CaesamStd_Result. To be able to use them in
a DataSet, you must create a CaesamStd_EO having a CaesamStd_Result as member. Many of these
“wrapper” EO are already defined in the com.samcef.library.EO plugin. You can also create your own
EOs to store whatever you want as a result.

page-75
Caesam SDK | 7 The Analysis dedicated objects

You should keep in mind that the lifespan of the results must be managed. If you want to reset or clear
some results, it is up to you to do it. If your results are stored on files, you will probably have to delete
some files at a given time. The framework will not carry out these actions for you.

Reports

The CaesamEO_Report (defined in com.samcef.caesam.library.EO) has a CaesamPrimitive_Report


member (defined in com.samcef.caesam.library.primitives).
This EO allows you to store an URL of an HTML file. When selected in the EO property view, the HTML
file is rendered in the output viewer. Currently the only report format supported is HTML, and the current
viewer is only able to render a rather basic HTML.

Samcef Field .sfr files

Caesam uses the Samcef Field result format. This kind of result can be displayed using the
CaesamEO_FEMResult object (com.samcef.caesam.library.EO).

Op2 results

Op2 files are not endian neutral. They are incompatible between platforms of different endianness, which
means that you cannot read an op2 file written on a Pentium based PC on an HP or Sun workstation and
vice-versa.
• Local results
The class CaesamFEM_StaticAnalysis is able to read the fluxes and forces from an Op2 file for a
given element. Results are returned in a Caesam_QuantityArray.
• Global results
Caesam is also able to translate some op2 files into its own sfr file format.
To be able to import an Op2 you must have:
• An Op2 file containing a FEM mesh (the Model)
• An Op2 file containing some results
A single file containing both parts of information is also valid and should simply be used two times
as input. You can call the task python:CaesamProcess_ConvertOp2ToSFR in com.samcef.library.EO.
The input dataset for this task is a DataSet with one CaesamEO_GlobalResultOp2 object named
GlobalOp2. On exit, a CaesamEO_FemResult is added to the DataSet. You just have to add this object
to your current DataSet to be able to display the retrieved op2 results.

Function graphs

The CaesamPrm_Function class is a base class defining a Function.


The CaesamEO_Plot (defined in com.samcef.caesam.library.EO) can be used in DataSets. It has a member
typed as CaesamPrm_DiscreteFunction, one function specialisation made to be able to store an array of
point-defined functions. This object is simply making cubic spline interpolations between the given points.
You can store and display several functions, displayed on one single graph.
For example you can initialise a discrete function as shown below:

PTRMEM(CaesamPrm_DiscreteFunction) aFunction =
CaesamPrm_DiscreteFunction::NewInstance();

PTRMEM(Caesam_QuantityArray)
aX= new Caesam_QuantityArray();
aX->SetGuiUnit("s");
aX->SetDimension("TIME");
for(int u=0;u<200;u++){
aX->Append(u);
}
aX->SetMax(199);
aX->SetMin(0);

page-76
7 The Analysis dedicated objects | Caesam SDK

PTRMEM(Caesam_QuantityArray) aY= new Caesam_QuantityArray();


aY->SetGuiUnit("mm");
aY->SetDimension("LENGTH");

for( i=1;i<=200;i++){
double v=(sin(4.*3/i)*(1+(double)i/200.));
aY->Append(v);
if(aY->GetMax()<v)aY->SetMax(v);
if(aY->GetMin()>v)aY->SetMin(v);
}

aFunction->SetMember("CsmMbr_X",aX);
aFunction->SetYn(0,aY);
aFunction->SetMember("CsmMbr_Title",new Caesam_String("Result Function"));
aFunction->SetMember("CsmMbr_XLegend",new Caesam_String("Time"));
PTRMEM(Caesam_StringArray) aSa= new Caesam_StringArray();
aSa->Append("Displacement");
aFunction->SetMember("CsmMbr_YLegends",aSa);
aPlot->SetMember("Function",aFunction);
aPlot->ClearStatus();
aPlot->SetUptodate(Standard_True);

You can also use a “Discrete Function” defined in XML.

page-77
Caesam SDK | 8 Error Handling

8 Error Handling
This section deals with aspects of error handling.

The Caesam_Status

The Caesam_Status and derivated classes are containers to store messages and involved objects coming
from errors and warnings.
A Caesam_Status is instantiated with a Caesam_Message and an optional Log_Logger instance to get
properties bundle used for internationalization. See Caesam_Message on page 121 and Log_Logger on
page 115 for details.
The Caesam_Object(s) attached to the message, if any, are can be retrieved with the method
GetInvolvedObject
A Caesam_Status is also a container for other Caesam_Status, which can themselves contain other
Caesam_Status, etc. : each Caesam_Status is thus a node of a tree-like structure.
If the Caesam_Status instantiation is caused by another Caesam_Status, the method SetCausedBy can be
invoked to store this cause. This mechanism allows the get some kind of call stack trace when examining
the status content.

The Caesam_Status derivated classes

The Caesam_Status has many derivated classes. Some on them are defined in

C++: class Status;


-- root class class ErrorStatus;
class ProgramErrorStatus;
--- Something is wrong with the program.Bad argument, invalid resources, ...
class MissingEnvVarStatus;
--- a environment variable is missing
class RunTimeErrorStatus;
class UserErrorStatus;
--- User Error. Bad Value, , ...
class InvalidStatus;
--- Invalid Object . Bad members, ..
class UndefinedStatus;
--- Not yet defined Object. To be computed or defined by user, ...

The other derivated classes are defined in XML language in the file Status.typedesc of the plugin
com.samcef.caesam.library.status Plug-in authors can themselves add sub-type to those existing types if
needed. One of the methods NewInstance In the class Caesam_Status accepts as argment the name of any
class inheriting from Caesam_Status, creating an instance of that class.

Exception : the Caesam_Failure class

The Caesam_Failure is the abstract base class for exception. It wraps a Caesam_Status describing the
error. The method GetStatus gives access the wrapped status. Inside a catch block, the static method
Caught gives access of the last thrown exception. The returned value may be null if the last thrown
exception is not of kind Caesam_Failure.

The Caesam_Failure derivated classes

All successors of Caesam_Failure have a method Raise. This method throws an exception which can be
caught by the enclosing try/catch block.
• Caesam_ErrorException : abnormal failure indicating a severe error. Contain a Caesam_ErrorStatus.
• Caesam_Exception : failure that indicates conditions that we usually might want to catch. Contain
a Caesam_Status
• Caesam_RunTimeException : exception that can be thrown during the normal operation . Contain
a Caesam_RunTimeErrorStatus

page-78
8 Error Handling | Caesam SDK

C++ example

try {
...
Caesam_Message aMes(
"thisClass", "thisMethod",”some message”);
Handle(Caesam_ErrorStatus)
aErrorStatus = Caesam_ErrorStatus::NewInstance(aMes);
Caesam_ErrorException::Raise(aErrorStatus);
}
catch(Caesam_RunTimeException) {
// common error
Handle(Caesam_RunTimeException)
aFailure = Caesam_RunTimeException::Caught();
if (!aFailure.IsNull()) {
STL_String aRunTimeMes = aFailure->GetRunTimeStatus()->GetMessage();
....
}
}
catch(Caesam_ErrorException) {
// severe error
Handle(Caesam_ErrorException)
aFailure = Caesam_ErrorException::Caught();
if (!aFailure.IsNull()) {
STL_String aRunTimeMes = aFailure->GetError()->GetMessage();
...
}
}
catch(Standard_Failure) {
// severe error from ouside CAESAM specific code
Handle(Standard_Failure) aFailure = Standard_Failure::Caught();
if (!aFailure.IsNull()) {
Caesam_Message aMes(
"thisClass", "thisMethod",aFailure->GetMessageString());
Handle(Caesam_ErrorStatus)
aErrorStatus = Caesam_ErrorStatus::NewInstance(aMes);
....
Caesam_ErrorException::Raise(aErrorStatus);
}
}
catch (...) {
// unexpected failure
...
}

page-79
Caesam SDK | 9 Starting CAESAM and CAESAM Tools

9 Starting CAESAM and CAESAM Tools

Starting on Windows

On the Windows operating system, a command a DOS-command file named caesam.cmd can be started
as any command file by double-clicking on it from the file navigator. A shortcut to that file is created on
the desktop by the installation procedure to facilitate an easy start and to define the starting directory.

Starting on UNIX / LINUX

On a UNIX or LINUX operating system, this command is a C-shell script file named caesam. It can be
started in the same way as any executable file by entering the file path in a terminal window or by clicking
on it in a file browser. A symbolic link to that file may be created on the desktop window (if the window
manager allows it) to facilitate an easy start. Shell aliases may also be defined to shorten the command
to be entered in the terminal windows.

9.1 Start-up options


All the optional arguments (named options) of the caesam command start with the hyphen (-) character.
All available options and arguments are displayed with the -help flag of the caesam command :
caesam [-h or -help or -? or -hX] [-shell] [-python] [-nolog] [-log logFilePath]
[-plugin PluginDir] [-anydiscipline] [-examples] [-sdk] [-tr debugOptions] [advanced
Options] [-- application Options] [file file ...]
Starts the CAESAM Graphical User Interface, unless the Python mode (-python) or Shell mode (-shell)
is selected. The options are:

Table 8: Start uup options

Option Description

-h this help message

-? this help message

-help this help message

-hX help on advanced and application options

-shell shell mode: launches a shell with the CAESAM environment -python
starts the PYTHON mode

-nolog do not redirect outputs to the log file (see below)

-log logFilePath set the log file path. Default is the value of the CAESAM_LOG
environment variable, if it is set, or ~/caesam_log.txt otherwise

-plugin PluginDir append the given PluginDir to the plug-in directory paths (see below)

-anydiscipline loads the <CAESAMInstallDir>\anydiscipline.plugins.cmd command


file "anydiscipline" may by any character string valid in a file name
(see below)

-examples loads the 'examples' discipline containing some example plugins

page-80
9 Starting CAESAM and CAESAM Tools | Caesam SDK

Option Description

-sdk use the CAESAM SDK license

-lic licenseID set the license ID (may be a file path or a license server id)

-tr debugOptions... one or several of the following debugging options separated by


spaces:
• all : all debugging options
• ais : AIS debug mode
• g : graphic debug mode
• c : CSF debug mode
• s : selection debug mode
• r : resource verbose mode
• f : FDB (file I/O) debug mode
• l : trace dynamic library loading
• [0-9] : debug level (0 = no debug, 1 = Step, 2 = trace main values,
3 = more, etc.)

Arguments are : file file ... are any CAESAM document file paths

caesam –hX

caesam [-test system|caesam|java|viewer] [-g] [-u directoryPath] [-mem] [-p libraryName]


[-cp classpath] [-ld ldLibraryPath] [-s classname] -vmdef name value [+help]
[+X][JavaVMOptions] [-- applicationOptions]
Advanced options are:
Table 9: Advanced start-up options

Option Description

-test system|caesam|java|viewer test if Java VM can be started or caesam loaded or system accessed
or viewer displayed
-s classname start the 'static void main(String[])' method of the given class
-cp classpath prepend the given classpath in front of the CLASSPATH
-ld ldLibraryPath prepend the given path in front of the LD_LIBRARY_PATH
-u directoryPath add directoryPath/sun/lib to LD_LIBRARY_PATH and
directoryPath/drv to CLASSPATH
-vmdef name value set a Java system property
-g disable the Just-In-Time Java compiler
-collect[=collect options] enter performance data collection mode with collect command (SUN
o nly). Optional collect options may be added after the = character
If option equals ENABLED, data collection is enabled when starting
By default, data collection is disabled when starting.
-mem Open CasCade optimized memory management mode and malloc/free
tracing

page-81
Caesam SDK | 9 Starting CAESAM and CAESAM Tools

Option Description

-p libraryName (on SUN only) generates a .profile file of the given library (e.g
TKCaesam): see gprof

JavaVMOptions

One or more Java VM option preceded by the + sign. Use +help or +X to get available options.
For example :
+help : to get available Java VM options
+verbose:jni : to get verbose jni loading

Application options

The -- separator is used to separate the application options from other options
-locale languageCode countryCode : set language to languageCode (a lowercase two-letter code
as defined by ISO-639-1, e.g. zh) and countryCode (a uppercase two-letter code as defined by ISO-3166,
e.g. CN)

Avoiding the log file

The -nolog flag is useful to avoid redirection of the printouts to the log file Caesam_log.txt located in the
user home directory. The full path to the user home directory is displayed in the starting window when
the application starts.

Adding a plugin

The -plugin pluginDirectoryPathflag asks the application to load all the plugins located in the given
pluginDirectoryPath. Several -plugin flags can be added on the same command line to account for plugins
located at various locations.

Adding a discipline

The –anydiscipline flag asks the application to load all the plugins described in the anydiscipline.plugins.csh
(on UNIX/LINUX) and anydiscipline.plugins.cmd (on Windows) files. The anydiscipline.plugins.csh (on
UNIX/LINUX) and anydiscipline.plugins.cmd (on Windows) files have to be located in the CAESAM
installation directory. 'anydiscipline' may be any character string valid in a file name and identifying a
discipline.
If, in the anydiscipline.plugins.csh (on UNIX/LINUX) and anydiscipline.plugins.cmd (on Windows) files,
the addPlugin variable value, is defined, it will be prepended to the CAESAM_PLUGIN_PATH, allowing
plugins related to some discipline to be loaded. The addPlugin variable is a list of directories separated
by the colon (:) character on UNIX and by the semi-colon (;) character on Windows.
If some plug-in requires some environment variables to be set or modified, they have to be defined or
modified in this anydiscipline.plugins.csh(or .cmd) file. For example, the PATH environment variable
on Windows or the LD_LIBRARY_PATH environment variable on UNIX/LINUX may be modified by
adding some directories containing dynamically loaded object libraries. As other example, if some plug-in
uses site-dependant URL’s to locate directories containing finite element result file, those URL’s may be
defined via environment variables defined in the anydiscipline.plugins.csh(or .cmd) file.

9.2 Start up Commands


This section lists some alternative start up commands.

page-82
9 Starting CAESAM and CAESAM Tools | Caesam SDK

The caesamsh command

The caesamsh command is a shortcut to caesam –shell When the -shell flag is set in the caesam command
line ("caesam -shell ..."), a command interpreter with the CAESAM environment is started. On the
Windows operating system a shortcut to that file is be created on the desktop to enable an easy start by
double-clicking. Dragging an executable file on the shortcut icon will start that executable.

The caesampy command

The caesampy command is a shortcut to caesam –python


When the -python flag is set in the caesam command line ("caesam -python ..."), the PYTHON interpreter
is started within the CAESAM environment. If a PYTHON (*.py) file path name is provided on the
command line, the PYTHON interpreter will execute that file.
On the Windows operating system, a shortcut to that file is created on the desktop so that simply dragging
a PYTHON file on the shortcut icon will start the execution of that file by the PYTHON interpreter

The caesamCheckSum command

The caesamCheckSum command is described in Building a plugin on page 88.

page-83
Caesam SDK | 10 Plugins

10 Plugins
This chapter is concerned with the construction and deployment of plugins. It describes:
• The types of plugin
• Files and libraries associated with plugins
• How to compile a plugin

The platform dependent files

Platform-dependent files (the “binaries”) are grouped into directories having a name that identifies the
platform : the “”.
Currently recognized names are:
• wnt - for x86-32 bits Windows platforms
• lin - for x86-32bits LINUX platforms
• hp - for HP-UX PA-RISC 64 bits platforms
• sun - for SUN/Solaris SPARC 32 bits platforms

10.1 Plugin types


Three types of plugins are possible. The type of the plugin must be specified in <Instance Type=”<plugin
type>”> tag of the plugin.xml file.

Caesam_Plugin

A Caesam plugin, with java, C++, python or/and typedesc classes definition. This is the most common
plugin type.
Examples of Caesam_Plugins :
<caesam installation directory>/examples/com.samcef.caesam.test.process
<caesam installation
directory>/examples/com.samcef.caesam.example.firsttest
<caesam installation
directory>/examples/com.samcef.caesam.test.transverse
<caesam installation directory>/examples/com.samcef.caesam.test.debug

Caesam_UtilityPlugin

A Utility plugin which can contain an utility library used by any other plugin.
Examples of Caesam_UtilityPlugin :
<caesam installation
directory>/examples/com.samcef.caesam.test.mylibrary

Caesam_PythonModulePlugin

A Python module written in native language.


Example of Caesam_PythonModulePlugin:

<caesam installation directory>/examples/com.samcef.caesam.test.mypythonmodule

You must declare a tag:


<PythonExportPath Type="Caesam_ObjectArray">
<!-- We have a platform specific fortran library located in the lib folder
-->
<Item Type="SharedLibrary">

page-84
10 Plugins | Caesam SDK

<Solaris Type="Caesam_Url">sun/lib/</Solaris>
<Hp Type="Caesam_Url">hp/lib/</Hp>
<Linux Type="Caesam_Url">lin/lib/</Linux>
<Windows Type="Caesam_Url">wnt/lib/</Windows>
</Item>
<!-- We also have a simple python module that we would like to be able to
import some python code -->
<Item CheckVersion="FALSE" OnLoad="" Type="SharedLibrary">
<Solaris Type="Caesam_Url">python/mypythonmodule/</Solaris>
<Hp Type="Caesam_Url">python/mypythonmodule/</Hp>
<Linux Type="Caesam_Url">python/mypythonmodule/</Linux>
<Windows Type="Caesam_Url">python/mypythonmodule/</Windows>
</Item>
</PythonExportPath>

10.2 Plugin architecture


The current plugin directory architecture is shown below.
Note in the current version, the presence of the pluginlib directory under src, which contains source files
for the plugin or a utility library or a python module.

build.xml Build file for csmmake mandatory

plugin.xml Plugin description file mandatory

about Default location for about optional


menu

default optional

jars Default location for optional


external jars files

help Default location for optional


plugin help

sdk Location where automatic generated


documentation is
generated (helpsdk)

python Recommended directory optional


for python process

resources optional

properties optional

sun Where compiled objects generated


are put on sunOS

lib Libraries generated

bin Binaries generated

obj Objects (.o) generated

page-85
Caesam SDK | 10 Plugins

hp Where compiled objects generated


are put on HP-UX

lib Libraries generated

bin Binaries generated

obj Objects (.o) generated

wnt Where compiled objects generated


are put on Windows

lib Libraries generated

bin Binaries generated

obj Objects (.o) generated

classes Location where compiled generated


java classes are put

src optional

pluginlib Plugin OR Utility OR optional


Pythonmodule sources

inc optional

executable Source of test executables optional

myExec1 Directory name = name of optional


the executable in arch/bin

inc optional

java Java sources optional

bin Binaries which are simply optional


copied into /arch/bin

sun optional

wnt optional

hp optional

lib Libraries which are optional


simply copied into
/arch/bin

sun optional

wnt optional

hp optional

classes Classes (or jar) which are optional


simply copied into
/classes

page-86
10 Plugins | Caesam SDK

10.3 Include plugins


A plugin can now include another plugin which must be to compiled with and linked to the sources of
the included plugin.
The plugin included by another is like any other plugin. The plugin.xml can contain <Libraries> or
<ClassPath> definitions which will be used by the includer plugin.
The plugin which does the inclusion must contain the tags <Include> to specify what plugins needs to be
included. The included plugin <Libraries> and/or <ClassPath> will be add to compilation/link command
line during execution of csmmake.
Example, ${CAESAM_HOME}/examples/SDK/plugins/com.samcef.caesam.test.mylibrary/plugin.xml
contains :

<Libraries Type="Caesam_ObjectArray">
<Item CheckVersion="FALSE" OnLoad="" Type="SharedLibrary">
<Solaris Type="Caesam_Url">sun/lib/libcom_samcef_caesam_test_mylibrary.s
<Linux Type="Caesam_Url">lin/lib/libcom_samcef_caesam_test_mylibrary.so
</Linux>
<Windows Type="Caesam_Url">wnt/lib/com_samcef_caesam_test_mylibrary.dll
</Windows>
</Item>
</Libraries>

${CAESAM_HOME}/examples/SDK/plugins/
com.samcef.caesam.test.myutilities/plugins.xml includes com.samcef.caesam.test.mylibrary.
It must contain :

<Include Type="Caesam_ObjectArray">
<Item Type="Caesam_String">com.samcef.caesam.test.mylibrary</Item>
</Include>

When you define an include tag, you must add the corresponding import tag in plugin.xml to tell caesam
to load the utility library first.
The include feature, enables you to pass your own objects between two plugins without using the Caesam
API. However this feature should be used with caution.

Note: This feature should only be used when it is not possible to use the Caesam
mechanism.

It could be used, for example, to call a utility method defined in a utility plugin because this method is
used by more than one plugin.

10.4 External libraries


A plugin can contain external libraries or binaries.
If a plugin contains an external libraries, it must be placed in <plugin_root>/src/lib/<arch>, having <arch>
in sun, wnt, hp. Binaries can be put in <plugin_root>/src/bin/<arch> and java classes in
<plugin_root>/src/classes. The content of these directories will be copied into <plugin_root>/<arch>/lib,
<plugin_root>/<arch>/bin and <plugin_root>/classes.
So the plugin.xml file of a plugin containing an external library in /src/lib must contain:

<Libraries Type="Caesam_ObjectArray">
<Item CheckVersion="FALSE" OnLoad="" Type="SharedLibrary">

page-87
Caesam SDK | 10 Plugins

<Solaris Type="Caesam_Url">sun/lib/libmyexternalLib.so</Solaris>
<Hp Type="Caesam_Url">hp/lib/libmyexternalLib.sl</Hp>
<Linux Type="Caesam_Url">lin/lib/libmyexternalLib.so</Linux>
<Windows Type="Caesam_Url">wnt/lib/myexternalLib.dll</Windows>
</Item>
</Libraries>

The same mechanism exists for java. These must be placed in the directory <plugindir>/src/classes. Use
the plugin.xml <classpath> tag to declare to caesam what to include in the runtime classpath.
The plugin.xml file of a plugin containing external java classes in /src/classes must contain:

<ClassPath Type="Caesam_ObjectArray">
<Item Type="Caesam_Url">classes/</Item>
</ClassPath>

10.5 Building a plugin


This section lists the compilers and compilation flags required to compile plugins.

Pre-requisites for SunOS 5.8

Flag Compiler

CC Sun C++ 5.5 2003/03/12


C Sun C 5.5 2003/03/12
Fortran Sun Fortran 95 7.1 2003/03/12
C flags -KPIC -xchip=ultra -xarch=v8 -dalign -Usun
-xdebugformat=stabs -DSOLARIS -DDEB

C++ flags -KPIC -xchip=ultra -xarch=v8 -vdelx -library=stlport4


-features=no%conststrings -features=tmplife -DSOLARIS
-DCSFDB -DHAVE_WOK_CONFIG_H
-DNo_Exception -DHAVE_CONFIG_H –Usun

Fortran flags -mt -PIC

Pre-requisites for WINDOWS 32 (Intel x86)

Flag Compiler

C/C++ Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for
80x86
Fortran Intel Fortran Compiler Version 9.1
Linker Microsoft (R) Incremental Linker Version 6.00.8447
C flags -nologo -MD -W3 -Zm1000 -GX -DWNT -DWINDOWS -D_WINDOWS
-DWIN32 -DNoUnder -DNDEBUG -DNo_Exception -DCSFDB -U_DEBUG

page-88
10 Plugins | Caesam SDK

Flag Compiler

C++ flags -nologo -MD -W3 -Zm1000 -GX -DWNT -DWINDOWS -D_WINDOWS
-DWIN32 -DNoUnder -DNDEBUG -DNo_Exception -DCSFDB -U_DEBUG
Fortran flags /nologo /libs:dll /Qextend-source /us /warn:argument_checking /warn:nofileopt
/assume:underscore /names:lowercase /U_DEBUG /DWNT

Mandatory files

In the root of the plugin directory structure, as well as the mandatory plugin.xml file describing the plugin
content, another mandatory file, named checksum.txt is required to ensure that the directory content has
not been modified since the last build by a non-authorized user. Without a valid checksum.txt file, a plugin
cannot be loaded.
Furthermore, the dynamic loaded object library of a dllPlugin must include the CaesamKey object file
providing the CAESAM version used when linking the plugin library.

The plugin names

A plugin name (and the dynamic loaded object library of a dllPlugin) must be unique among all possible
name. It is recommended that the plugin name is a dot separated sequence of words, starting with the
domain name of the firm in reverse order (domain names are unique), followed by the product name,
followed by some discipline identification.
For example, the kernel plugins of CAESAM are named :
com.samcef.caesam.eoeditors
com.samcef.caesam.library.EO
com.samcef.caesam.library.primitives
com.samcef.caesam.model
com.samcef.caesam.prm
com.samcef.caesam.process
com.samcef.caesam.std
com.samcef.caesam.topology
It is recommended NOT to use plugin name that is suffix of any existing plugin names. For example usage
of com.samcef.caesam.test.transverse.material is STRONGLY DISCOURAGED since it is a suffix of
com.samcef.caesam.test.transverse.

Plugin's java source code folder structure

In all plugins, the java code, classes and resources must be organized in a java package using the same
plugin name as the ROOT PACKAGE.
For example consider the plugin com.samcef.caesam.test.transverse
The java code must be contained in a folder structure that matches, i.e.
com.samcef.caesam.test.transverse/src/java/com/samcef/caesam/test/transverse or any descendant package
of this one e.g.
com.samcef.caesam.test.transverse.material
com.samcef.caesam.test.transverse.profile
com.samcef.caesam.test.transverse.profile.properties
The same applies to resources and classes.
It is also important that the package definition is correctly defined. In the example above, the package
must be defined as: package com.samcef.caesam.test.transverse
This ensures that when the compilation takes place that the classes will be placed in the correct folder
structure: com.samcef.caesam.test.transverse/classes/java/com/samcef/caesam/test/transverse

page-89
Caesam SDK | 10 Plugins

There is a risk that if the package definition does not follow the correct plugin structure that classes with
the same name will have the same class path. In this case only one will ever be loaded.

The checksum.txt file and the caesamCheckSum command

The caesamCheckSum command provided in the CAESAM SDK delivery enables building the
checksum.txt file to be built for one or more plugins. This utility is located in the CAESAM root directory
and takes as arguments a list of plugin directories paths (wild cards may be used in directory names). On
the Windows platforms, a shortcut to caesamCheckSum named “CAESAM CheckSum” is added on the
desktop window by the CAESAM installation.
For example, to build the checksum files for all the plugins located in the “myplugdir” directory:
• on Windows platforms
enter the following command in a console window: caesamCheckSum
C:\mydisk\caesam\V2.0\myplugdir\*
• on UNIX/LINUX platforms
enter the following command in a terminal window: caesamCheckSum
/home/someuser/caesam/V2.0/myplugdir/*
Running the caesamCheckSum utility requires having a CAESAM_SDK license.

The CaesamKey object file

Every plugin shared object library must include the CaesamKey object file providing the CAESAM
version used when linking the plugin library.
This file is named CaesamKey.obj on Windows platforms and CaesamKey.o on UNIX/LINUX platform.
Without a valid CaesamKey file, a plugin cannot be loaded. This file is provided with the CAESAM SDK
delivery in the <CAESAMInstallDir>/CAESAM/<platformID>/obj directory. Here, the <platformID> is
one of the names given in the introduction to the section on plugins on page 84.

page-90
11 Table data structure | Caesam SDK

11 Table data structure


Caesam tables consist of a set of classes that offer the possibility to define and store data in a tabular
structure.
The figure below gives an overview of the Caesam Table data structure.

Figure 4: Caesam Table Overview

This chapter describes :


• Caesam_Table on page 91
• Caesam_TypedTable on page 99
• Guidelines for optimal use of tables on page 108

11.1 Caesam_Table
Caesam_Table is a container of primitive or object items organized in columns.

Main features

• Data is organized in columns that have a name and a type, an index for faster searching and a default
value.
• The structure of the table (column names, column types, …) is kept in a table descriptor that can be
provided dynamically (through coding), statically (as a class resource) or automatically deducted from
the structure of a Caesam class (Caesam_TypedTable).

page-91
Caesam SDK | 11 Table data structure

• Columns are typed. Only values that match the specified type can be stored in that column.
• Tables are optimized for minimal memory consumption. Storing an integer value in a cell corresponds
to allocating a standard int.
• Table values can be accessed individually through type specific getters or setters (like GetQuantityItem
and SetQuantityItem).
• Items can also be obtained as Caesam objects via the generic accessors (GetItem and SetItem). -
Caesam_Table offers the possibility to retrieve or modify an entire row (GetRow/SetRow) at once.

Table descriptors

The Caesam_TableDescriptor is an object that we associate with a Caesam_Table and which describes
the structure of the table. The table descriptor contains a list of column descriptors
(Caesam_ColumnDescriptor) that define:
• The name of the column
• What type of values does the column store
• Flags that indicates whether the columns should be indexed or if they are primary keys.
• A default value for the column.

Table vs matrix

Although it has an API which is similar with that of Caesam matrix, a table has some features that a matrix
does not have:
• A matrix does not offer the possibility to configure the columns. In a table, columns are completely
described through the column descriptors fields (name, type, devault value).
• Matrices cannot store heterogenous primitive values optimally. The table's columns are vectors of
primitive values (Standard_Boolean, Standard_Integer, Standard_Real, STL_String), whereas the
matrix can only contain items of a unique type or objects that inherit from a unique class.

page-92
11 Table data structure | Caesam SDK

11.1.1 Caesam_Table API

Table items getters

GetBooleanItem(me; theRow: Integer from Standard;


theColumn: Integer from Standard)returns Boolean from Standard;
---Purpose: Returns the boolean item at position <row, column>

GetIntegerItem(me; theRow: Integer from Standard;


theColumn: Integer from Standard) returns Integer from Standard;
---Purpose: Returns the integer item at position <row, column>

GetDoubleItem(me; theRow: Integer from Standard;


theColumn: Integer from Standard) returns Real from Standard;
---Purpose: Returns the double item at position <row, column>

GetStringItem(me; theRow: Integer from Standard;


theColumn: Integer from Standard) returns String from STL;
---Purpose: Returns the string item at position <row, column>

GetQuantityItem(me; theRow: Integer from Standard;


theColumn: Integer from Standard) returns Real from Standard;
---Purpose: Returns the quantity item at position <row, column>

GetObjectItem(me; theRow: Integer from Standard;


theColumn: Integer from Standard) returns Object from Caesam;
---Purpose: Returns the object item at position <row, column>

Table items setters

SetBooleanItem(me:mutable; theRow: Integer from Standard;


theColumn: Integer from Standard;
theBooleanValue: Boolean from Standard);
---Purpose: Store the boolean value at the position <row, column> in the
table. If the row index is greater than the size of the column, the column
will be filled with false values up to the index.

SetIntegerItem(me:mutable;
theRow: Integer from Standard;
theColumn: Integer from Standard;
theIntegerValue: Integer from Standard);
---Purpose: Store the integer value at the position <row, column>

SetDoubleItem(me:mutable;
theRow: Integer from Standard;
theColumn: Integer from Standard;

page-93
Caesam SDK | 11 Table data structure

theDoubleValue: Real from Standard);


---Purpose: Store the double value at the position <row, column>

SetStringItem(me:mutable;
theRow: Integer from Standard;
theColumn: Integer from Standard;
theStringValue: String from STL);
---Purpose: Store the string value at the position <row, column>

SetQuantityItem(me:mutable;
theRow: Integer from Standard;
theColumn: Integer from Standard;
theQuantityValue: Real from Standard);
---Purpose: Store the quantity value at the position <row, column>

SetObjectItem(me:mutable;
theRow: Integer from Standard;
theColumn: Integer from Standard;
theItemObject: Object from Caesam);
---Purpose: Store the object at the position <row, column>

Table items getters with column name

GetBooleanItem(me;
theRow: Integer from Standard;
theColumnName: String from STL)
returns Boolean from Standard;
---Purpose: Returns the boolean item at position <row, column name>

Warning: The Get<...>Item(rowIndex, columnName) methods are slower than their Get<...>Item(rowIndex,
columnIndex) counterparts. When used in loops it is better to first obtain the column index and than use
the latter method. See below:

Standard_Integer aLengthColumnIndex = aTable->GetColumnIndex("Length");


while(aLength/1000 > 0.02){
aLength = aTable->GetQuantityValue(aLengthColumnIndex);

GetIntegerItem(me;
theRow: Integer from Standard;
theColumnName: String from STL)
returns Integer from Standard;
---Purpose: Returns the integer item at position <row, column name>

GetDoubleItem(me;
theRow: Integer from Standard;
theColumnName: String from STL)
returns Real from Standard;
---Purpose: Returns the double item at position <row, column name>

GetStringItem(me;
theRow: Integer from Standard;
theColumnName: String from STL)

page-94
11 Table data structure | Caesam SDK

returns String from STL;


---Purpose: Returns the string item at position <row, column name>

GetQuantityItem(me;
theRow: Integer from Standard;
theColumnName: String from STL)
returns Real from Standard;
---Purpose: Returns the quantity item at position <row, column name>

GetObjectItem(me;
theRow: Integer from Standard;
theColumnName: String from STL)
returns Object from Caesam;
---Purpose: Returns the object item at position <row, column name>

Table items setters with column name

SetBooleanItem(me:mutable;
theRow: Integer from Standard;
theColumnName: String from STL;
theBooleanValue: Boolean from Standard);
---Purpose: Store the boolean value at the position <row, column name> in
the table. If the row index is greater than the size of the column, the column
will be filled with false values up to the index.

Example: aTable->SetBooleanItem(10, "IsValid", Standard_True);


Warning! The Set<...>Item(rowIndex, columnName, value) methods are slower than their
Set<...>Item(rowIndex, columnIndex, value) counterparts.
When a you need to set many item values it is better to obtain the column index and than use the
Set<...>Item(rowIndex, columnIndex) method. See below:

Standard_Integer aColumnIndex = aTable->GetColumnIndex("IsValid");


for(i=0; i<1000; ++i){
aTable->SetBooleanItem(i, aColumnIndex, Standard_True);
}
SetIntegerItem(me:mutable;
theRow: Integer from Standard;
theColumnName: String from STL;
theIntegerValue: Integer from Standard);
---Purpose: Store the integer value at the position <row, column name>

SetDoubleItem(me:mutable;
theRow: Integer from Standard;
theColumnName: String from STL;
theDoubleValue: Real from Standard);
---Purpose: Store the double value at the position <row, column name>

SetStringItem(me:mutable;
theRow: Integer from Standard;
theColumnName: String from STL;

page-95
Caesam SDK | 11 Table data structure

theStringValue: String from STL);


---Purpose: Store the string value at the position <row, column name>

SetQuantityItem(me:mutable;
theRow: Integer from Standard;
theColumnName: String from STL;
theQuantityValue: Real from Standard);
---Purpose: Store the quantity value at the position <row, column name>

SetObjectItem(me:mutable;
theRow: Integer from Standard;
theColumnName: String from STL;
theItemObject: Object from Caesam);
---Purpose: Store the object at the position <row, column name>

Table info

Table info includes number of rows, column names, column type.

GetColumnCount(me)
returns Integer from Standard;
---Purpose: Returns the number of columns in the table
-- EXPORT:

GetColumn(me;
theColumnIndex: Integer from Standard)
returns Column from Caesam;
---Purpose: Find a column by index
-- EXPORT:

GetColumn(me;
theColumnName: String from STL)
returns Column from Caesam;
---Purpose: Find a column by its name
-- FORTRAN: GetColumnByName
-- EXPORT:

GetColumnItemType(me;
theColumnName: Integer from Standard)
returns Class from Caesam;
---Purpose: Gets a column type
-- EXPORT:

GetColumnIndex(me;
theColumnName: String from STL)
returns Integer from Standard;
---Purpose: Find the index of a column by its name
-- EXPORT:

GetColumnNames(me)
returns StringArray from Caesam;

page-96
11 Table data structure | Caesam SDK

---Purpose: Return an array containing the names of the columns


-- EXPORT:

GetColumnDefaultValue(me;
theColumnIndex: Integer from Standard)
returns Object from Caesam;
---Purpose: Find the default value for a column.
-- EXPORT:

GetRowCount(me)
returns Integer from Standard;

11.1.2 XML Persistence


Below is an example of table descriptor file:

<Instance Type="Caesam_TableDescriptor">
<RowObjectType Type="Caesam_String">Node</RowObjectType>
<ColumnDescriptors Type="Caesam_ObjectMap" KeepKeyOrder="TRUE">
<Item Key="CsmMbr_Name" Type="Caesam_ColumnDescriptor">
<Name Type="Caesam_String">CsmMbr_Name</Name>
<Item Type Type="Caesam_String">Caesam_String</ItemType>
</Item>
<Item Key="NodeId" Type="Caesam_ColumnDescriptor">
<Name Type="Caesam_String">NodeId</Name>
<Item Type Type="Caesam_String">Caesam_Integer</ItemType>
</Item>
<Item Key="X" Type="Caesam_ColumnDescriptor">
<Name Type="Caesam_String">X</Name>
<Item Type Type="Caesam_String">Caesam_Quantity</ItemType>
</Item>
<Item Key="Y" Type="Caesam_ColumnDescriptor">
<Name Type="Caesam_String">Y</Name>
<Item Type Type="Caesam_String">Caesam_Quantity</ItemType>
<Default Type="Caesam_Quantity">200;LENGTH</Default>
</Item>
<Item Key="Z" Type="Caesam_ColumnDescriptor">
<Name Type="Caesam_String">Z</Name>
<Item Type Type="Caesam_String">Caesam_Quantity</ItemType>
</Item>
</ColumnDescriptors>
</Instance>

Below is an example of an instance file containing a Caesam_Table:

<Instance Type="Caesam_TypedTable">
<Columns Type="Caesam_ObjectArray" >
<VariableSize Type="Caesam_Integer">5</VariableSize>
<Item Index="0" Type="Caesam_StringColumn" >
<Items Type="Caesam_StringArray">6::"Node1";"Node2";"";"";"";"Node5"</Items>

</Item>
<Item Index="1" Type="Caesam_IntegerColumn" >
<Items Type="Caesam_IntegerArray">6::6001;6002;0;0;0;6005</Items>
</Item>
<Item Index="2" Type="Caesam_QuantityColumn" >
<Items Type="Caesam_QuantityArray" >
<Values Type="Caesam_DoubleArray">2::3.223;5.12</Values>
</Items>

page-97
Caesam SDK | 11 Table data structure

</Item>
<Item Index="3" Type="Caesam_QuantityColumn" >
<Items Type="Caesam_QuantityArray" >
<Dimension Type="Caesam_String">LENGTH</Dimension>
<Values Type="Caesam_DoubleArray">6::12.31;16.1;200;200;200;11.6</Values>
</Items>
</Item>
<Item Index="4" Type="Caesam_QuantityColumn" >
<Items Type="Caesam_QuantityArray" >
<Values Type="Caesam_DoubleArray">6::0.8;0.6;0;0;0;0.5</Values>
</Items>
</Item>
</Columns>
</Instance>
</Caesam>

11.1.3 Usage Scenarios


This section illustrates the use of tables. Two scenarios are presented.

Scenario 1 : Creating a Caesam_Table with two columns A and B of type integer and
quantity respectively and with a primary key set to A.

In this example we will create the table descriptor programmatically before instantiating the table.
Create the table descriptor

Handle(Caesam_TableDescriptor) aTableDescriptor = new Caesam_TableDescriptor();

Define an Id column

Handle(Caesam_ColumnDescriptor) aIdColumn = new Caesam_ColumnDescriptor();


aIdColumn ->SetName(“Id”);
aIdColumn ->SetType(“Caesam_Integer”);
aIdColumn ->SetIsPrimaryKey(Standard_True);
aTableDescriptor->SetColumnDescriptor(aIdColumn);

Define an “A” quantity column with a default of value of 0.0 and LENGTH dimension

Handle(Caesam_ColumnDescriptor) aAColumn = new Caesam_ColumnDescriptor();


aAColumn ->SetName(“A”);
aAColumn ->SetType(“Caesam_Quantity”);
aAColumn ->SetDefaultValue(new Caesam_Quantity(0.0, “LENGTH”));
aTableDescriptor->SetColumnDescriptor(aAColumn);

Define a “B” quantity column

Handle(Caesam_ColumnDescriptor) aBColumn = new Caesam_ColumnDescriptor();


aBColumn ->SetName(“B”);
aBColumn ->SetType(“Caesam_Quantity”);
aTableDescriptor->SetColumnDescriptor(aBColumn);

Handle(Caesam_Table) aTable = new CaesamTable(aTableDescriptor);

Scenario 2: Table with a static descriptor

Instead of creating the table descriptor every time the table object is instantiated, it is possible to define
it statically, as a resource in the declaration of the table class. In terms of speed and memory performance,
it is better to define descriptors this way whenever possible.

page-98
11 Table data structure | Caesam SDK

In this example we want a Caesam_Table with two columns A and B of type integer and quantity
respectively and with a primary key set to A and a static table descriptor.
Declare a new table class named MySimpleTable in typedesc (this class must inherit from Caesam_Table).

<Typedesc Name=”MySimpleTable” Inherits=”Caesam_Table”>


</Typedesc>

Add the class in the plugin.xml file and attach a resource called “TableDescriptor” to the class.

<Classes Type="Caesam_ObjectArray">
<Item Type="PluginClass">
<Class Type="Caesam_String">MySimpleTable</Class>
<Resources Type="Caesam_ObjectMap">
<Item Key="TableDescriptor">default/MyTableDescriptor.csm</Item>
</Resources>
</Item>
</Classes>

Create the MyTableDescriptor.csm resource file and define the columns of the table: a Id column of
integer type, which plays the role of row identifier, a column named “A” of quantity type and a column
B of string type. We will also define a default value for the A column.

<Instance Type=”MyTableDescriptor”>
<ColumnDescriptors Type="Caesam_ColumnDescriptorMap">
<Item Key="NodeId" Type="Caesam_ColumnDescriptor">
<Name Type="Caesa_String">Id</Name>
<IsIndexed Type="Caesa_Boolean">TRUE</IsIndexed>
<IsPrimaryKey Type="Caesa_Boolean">TRUE</IsPrimaryKey>
<ItemType Type="Caesa_Type">Caesam_Integer</ItemType>
</Item>
<Item Key="A" Type="Caesam_ColumnDescriptor">
<Name Type="Caesa_String">A</Name>
<ItemType Type="Caesa_Type">Caesam_Quantity</ItemType>
<Default Type=”Caesam_Quantity”>0;LENGTH</Default>
</Item>
<Item Key="B" Type="Caesam_ColumnDescriptor">
<Name Type="Caesa_String">B</Name>
<ItemType Type="Caesa_Type">Caesam_String</ItemType>
</Item>
</ColumnDescriptors>
</Instance>

Now we can instantiate our own table class, which will have the descriptor we’ve defined.

Handle(Caesam_Table) aTable = Caesam_Table::Cast(NewObject(“MySimpleTable”));

11.2 Caesam_TypedTable
Caesam_TypedTable has been designed to allow the storage of objects of complex types (objects that has
several members) into the rows of a table. This means that the table can store one Caesam_Object per
row, one member per column. The mapping between an object and a row is defined in an object of
Caesam_TypedTableDescriptor type.
The typed descriptors are used to describe a typed table and in addition to the functionality provided by
Caesam_TableDescriptor they define the type of objects that can be stored as rows of the table. This
information is used by the Caesam_TypedTable to convert table rows to objects and viceversa.
By default Caesam_TypedTableDescriptor uses a member-to-column mapping, but when necessary this
can be redefined to other mapping strategies (instead of members we could have items of an array or of
a map). See the usage scenario for more information.

page-99
Caesam SDK | 11 Table data structure

11.2.1 Caesam_TypedTable API


In addition to the methods exposed by the Caesam_Table class, Caesam_TypedTable offers ways of
storing and retrieving table rows in the form of Caesam objects.

Create (theRowObjectType: Class from Caesam)


returns mutable TypedTable from Caesam;
---Purpose: Caesam_TypedTable constructor with a row object type.

GetRowObject(me:mutable;
theRowIndex: Integer from Standard)
returns Object from Caesam;
---Purpose: Returns a row of the table in the form of a Caesam_Object.

The returned instance is of the type declared in the constructor. If theRowIndex is outside the column’s
limits, GetRowObject will return NULL.

GetRowObject will search the internal cache for this object and return it if
found or create a new one with values stored at theRowIndex.

SetRowObject(me:mutable;
theRowIndex: Integer from Standard;
theRowObject: Object from Caesam)
returns Boolean from Standard;
---Purpose: Stores the values of the members in the row located at the
specified index.

If the size of the columns is less that the index the table will be filled with the corresponding default values
up to the index. If a member of theRowObject is NULL, SetRowObject will store a default value in the
corresponding column.
Note that the type of theRowObject must match the type defined in the table descriptor.

AddRowObject(me:mutable;
theRowObject: Object from Caesam)
returns Boolean from Standard;
---Purpose: Appends a row to the table and store the values of the members
in that row.

If a member of theRowObject is NULL, SetRowObject will store a default value in the corresponding
column.
Note that the type of theRowObject must match the type defined in the table descriptor.

SetRowObjectType(me:mutable;
theRowObjectType: Class from Caesam);
---Purpose: Sets the type of the row object.

Changing the row object type at runtime will clear all the table values and re-create the columns.

GetRowObjectType(me)
returns Class from Caesam;
---Purpose: Returns object type associated to the table.

11.2.2 Usage Scenarios


This section illustrates the use of Caesam_TypedTables. Three scenarios are presented:

page-100
11 Table data structure | Caesam SDK

• Scenario 1: Creating a table of objects with default member-to-column mapping


• Scenario 2: Table of objects with specific member/item-to-column mapping
• Scenario 3: Converting an existing array of EOs into a table of EOs

Scenario 1 : Creating a table of objects with default member-to-column mapping

This means that the table will be able to store one Caesam_Object per row, one member per column.
This can be achieved through the use of the Caesam_TypedTable class with a row object type as argument.
This will create a default descriptor with a member-to-column mapping.
In the following example we will create a table capable of storing rows of type Node. The Node class that
we would like to store in the table has four members: an identifier (which will become a row identifier)
and three quantities:
• Member name - Member type
• NodeId - Caesam_Integer
• X - Caesam_Quantity
• Y - Caesam_Quantity
• Z - Caesam_Quantity
In order to have a table that can store object of type Node, we need to create a Caesam_TypedTable with
the name of the class as argument.
Create a Caesam_TypedTable with the name of the class as argument

Handle(Caesam_ TypedTable) aTableOfNodes = new Caesam_Table(“Node”);

This will automatically create table descriptor with four columns, one for each member of the Node class,
having the same name as the member. Since the Node class has four members NodeId:Integer, X:Quantity,
Y:Quantity and Z:Quantity the corresponding columns will be:

NodeId X Y Z

Caesam_IntegerArray Caesam_QuantityArray Caesam_QuantityArray Caesam_QuantityArray

Note that for Caesam_QuantityArray columns the members Dimension, Min, Max, GuiUnit will have
the same values as those declared in the default instance of the Node class for the corresponding members
of Caesam_Quantity type.
An alternative way to create the table Create a Caesam_TypedTable with a static descriptor.
Create a Caesam_TypedTable with a static descriptor
Instead of letting the constructor create the table descriptor every time the table object is instantiated, it
is possible to make a static declaration declaration of the table class. The table instance will be created
faster and will consume less memory.
To do this you need to declare a new table class named Caesam_NodeTable in typedesc (this class must
inherit from Caesam_ TypedTable).

<Typedesc Name=”MyNodeTable” Inherits=”Caesam_TypedTable”>


</Typedesc>

Also instead of passing the row object type as an argument to the constructor, we can have a default file
for this type with the RowObjectType member set to Node. Example of default XML file
(default/MyNodeTable.csm):

<Instance Type="MyNodeTable">
<RowObjectType Type="Caesam_String">Node</RowObjectType>
</Instance>

page-101
Caesam SDK | 11 Table data structure

Add the class in the plugin.xml file and attach a resource called “TableDescriptor” to the class.

<Classes Type="Caesam_ObjectArray">
<Item Type="PluginClass">
<Class Type="Caesam_String">MyNodeTable</Class>
<Resources Type="Caesam_ObjectMap">
<Item Key="TableDescriptor">/default/MyNodeTableDescriptor.csm</Item>
</Resources>
</Item>
</Classes>

Create the MyNodeTableDescriptor.csm resource file and define the columns of the table.

<Instance Type=”Caesam_TypedTableDescriptor”>
<RowObjectType Type="Caesam_Stirng">Node</ RowObjectType >
<ColumnDescriptors Type="Caesam_ColumnDescriptorMap">
<Item Key="NodeId" Type="Caesam_ColumnDescriptor">
<Name Type="Caesa_String">NodeId</Name>
<IsIndexed Type="Caesa_Boolean">TRUE</IsIndexed>
<IsPrimaryKey Type="Caesa_Boolean">TRUE</IsPrimaryKey>
<ItemType Type="Caesa_Type">Caesam_Integer</ItemType>
</Item>
<Item Key="X" Type="Caesam_ColumnDescriptor">
<Name Type="Caesa_String">X</Name>
<ItemType Type="Caesa_Type">Caesam_Quantity</ItemType>
<Default Type=”Caesam_Quantity”>0;LENGTH</Default>
</Item>
<Item Key="Y" Type="Caesam_ColumnDescriptor">
<Name Type="Caesa_String">Y</Name>
<ItemType Type="Caesa_Type"> Caesam_Quantity </ItemType>
<Default Type=”Caesam_Quantity”>0;LENGTH</Default>
</Item>
<Item Key="Z" Type="Caesam_ColumnDescriptor">
<Name Type="Caesa_String">Z</Name>
<ItemType Type="Caesa_Type"> Caesam_Quantity</ItemType>
<Default Type=”Caesam_Quantity”>0;LENGTH</Default>
</Item>
</ColumnDescriptors>
</Instance >

Setting and retrieving objects stored in the table


// Store a node object at line 10 of the table

aTableOfNodes ->SetRowObject(10, aNode);

// Retrieving the object stored at row 10. Only use GetRowObject if you need the entire row. Otherwise
for obtaining individual items use GetIntegerItem and GetQuantityItem.

Handle(Node) aNode = aTableOfNodes->GetRowObject(10);

// Retrieving the real value that corresponds to the X member of the line 10. This corresponds to the the
row 10, column 1

Standard_Real aRealValue = GetQuantityItem(10, 1);

// Or retrieve the same value by using the column name

Standard_Real aRealValue = GetQuantityItem(10, “X”);

page-102
11 Table data structure | Caesam SDK

Scenario 2 : Table of objects with specific member/item-to-column mapping

When the default member-to-column mapping is not appropriate for the type of object to store, we can
re-define the methods that map the objects to columns.
There are two methods that used internally by Caesam_TypedTable, one for filling the members of an
object with values found in the table and the other for copying values from the object to the table columns:

RetrieveRowObject(me;
theRowIndex: Integer from Standard;
theObject: Object from Caesam)
returns Boolean from Standard is virtual;
---Purpose: Sets the member of theObject with the values found in the the
corresponding columns declared in the table descriptor. By default
TableDescriptor uses a member-to-column mapping, but this method can be
re-defined for other mapping types (instead of members we could have items
of an array or of a map).

StoreRowObject(me:mutable;
theRowIndex: Integer from Standard;
theObject: Object from Caesam)
returns Boolean from Standard is virtual;
---Purpose: Stores the values of the members in the corresponding columns
of the table
By default TableDescriptor uses a member-to-column mapping,
but this method can be re-defined for other mapping types
(instead of members we could have items of an array or of a map).

Let’s say that the Node class instead of having four members NodeId, X, Y and Z as in the previous case,
now has an integer member NodeId and a member XYZ of type Caesam_QuantityArray which holds the
values (X at position 0, Y at position 1 and Z at position 2). We want to store Node objects into a table
with four columns NodeId, X, Y, Z.
The structure of the Node class:
• Member name - Member type
• NodeId - Caesam_Integer
• XYZ - Caesam_ObjectArray
We want to create a table associated to this object, which would have the following structure: The structure
of the desired Caesam_TypedTable(Node) is :

NodeId X Y Z

Caesam_IntegerArray Caesam_QuantityArray Caesam_QuantityArray Caesam_QuantityArray

It is clear that the member-to-column mapping is not what we want since that would give a table with
two columns, one NodeId (IntegerArray) and a second one XYZ of type Caesam_ObjectArray.
In order to define our own mapping we need to: Declare a new table class named NodeTable
This class must inherit from Caesam_ TypedTable. Since we need to re-define some virtual methods we
will implement this class in C++.

class NodeTable : public Caesam_TypedTable{


// Implement registration methods and redefine the virtual ones (see below)
};

Define the table descriptor for the Caesam_NodeTable.


In the plugin.xml file define a resource named “TableDescriptor” for the class Caesam_NodeTable and
create an XML resource file that contains an instance of Caesam_TypedTableDescriptor to define the
structure of your table.

page-103
Caesam SDK | 11 Table data structure

Add the class in the plugin.xml file and attach a resource called “TableDescriptor” to the class.

<Classes Type="Caesam_ObjectArray">
<Item Type="PluginClass">
<Class Type="Caesam_String">NodeTable</Class>
<Resources Type="Caesam_ObjectMap">
<Item Key="TableDescriptor">/default/NodeTableDescriptor.csm</Item>
</Resources>
</Item>
</Classes>

Create the NodeTableDescriptor.csm resource file and define the columns of the table.

<Instance Type=”Caesam_TypedTableDescriptor”>
<RowObjectType Type="Caesam_Stirng">Node</ RowObjectType >
<ColumnDescriptors Type="Caesam_ColumnDescriptorMap">
<Item Key="NodeId" Type="Caesam_ColumnDescriptor">
<Name Type="Caesa_String">NodeId</Name>
<IsIndexed Type="Caesa_Boolean">TRUE</IsIndexed>
<IsPrimaryKey Type="Caesa_Boolean">TRUE</IsPrimaryKey>
<ItemType Type="Caesa_Type">Caesam_Integer</ItemType>
</Item>
<Item Key="X" Type="Caesam_ColumnDescriptor">
<Name Type="Caesa_String">X</Name>
<ItemType Type="Caesa_Type">Caesam_Quantity</ItemType>
<Default Type=”Caesam_Quantity”>0;LENGTH</Default>
</Item>
<Item Key="Y" Type="Caesam_ColumnDescriptor">
<Name Type="Caesa_String">Y</Name>
<ItemType Type="Caesa_Type"> Caesam_Quantity </ItemType>
<Default Type=”Caesam_Quantity”>0;LENGTH</Default>
</Item>
<Item Key="Z" Type="Caesam_ColumnDescriptor">
<Name Type="Caesa_String">Z</Name>
<ItemType Type="Caesa_Type"> Caesam_Quantity</ItemType>
<Default Type=”Caesam_Quantity”>0;LENGTH</Default>
</Item>
</ColumnDescriptors>
</Instance>

Implement the RetrieveRowObject and StoreRowObject methods.

// This method copies values from the object to the columns, declared
// in the table descriptor, at the position indicated by theRowIndex.
Standard_Boolean Caesam_NodeTable::StoreRowObject(
const Standard_Integer theRowIndex,
const Handle(Caesam_Object)& theObject){
// copy the NodeId member value to the table cell
SetItem(theRowIndex, “NodeId”, theObject->GetMember(“NodeId”));
// copy the values from the XYZ member to the table cells
Handle(Caesam_ObjectArray) aXYZMember =
Caesam_ObjectArray::Cast(theObject->GetMember(“XYZ”));
SetItem(theRowIndex, “X”, aXYZMember ->Get(0));
SetItem(theRowIndex, “Y”, aXYZMember ->Get(1));
SetItem(theRowIndex, “Z”, aXYZMember ->Get(2));
return Standard_True;
}

// This method copies values from a row to an object


Standard_Boolean Caesam_NodeTable::RetrieveRowObject(
const Standard_Integer theRowIndex,
const Handle(Caesam_Object)& theObject) const{
// copy the NodeId column value to the object member

page-104
11 Table data structure | Caesam SDK

theObject->SetMember(“NodeId”, GetItem(theRowIndex, “NodeId”);


// copy the row values to the XYZ member
Handle(Caesam_ObjectArray) aXYZMember =
Caesam_ObjectArray::Cast(theObject->GetMember(“XYZ”));
aXYZMember->Set(0, GetItem(theRowIndex, “X”))
aXYZMember->Set(1, GetItem(theRowIndex, “Y”))
aXYZMember->Set(2, GetItem(theRowIndex, “Z”))
return Standard_True;

Scenario 3 : Converting an existing array of EOs into a table of EOs

In order to help authors converting arrays of objects to tables two new methods were added:
• The Caesam_TypedArray::ToTable() method.
Its purpose is to create a Caesam_TypedTable object with one column for each member of the typed
object and store the object as rows in the table. The table will have as many rows as items in the
TypedArray.
• The Caesam_EOArray::ToTable() method.
Its purpose is to create a Caesam_TypedTable object with one column for each member of the EO
object and store the EO as rows in the table. The table will have as many rows as items in the EOArray.
In the following example we want to convert the member "plies" of the class StackingSequence from a
CaesamStd_EOArray type to a Caesam_TypedTable.
Step 1. Declare the class obsolete and add a translate method

<TypeDesc Name="StackingSequence#0" Inherits="CaesamStd_EO"


ClassFlags="OBSOLETE" >
<Member Name="plies" Type="CaesamStd_EOArray"/>
<Translate Name="StackingSequenceTranslate0To1" Type="Python"

Location="csm:com.samcef.caesam.test.transverse/python/StackingSequenceTranslate0To1"/>

</TypeDesc>

Step 2. Declare the new version of the class. Note that the type of the plies member becomes
Caesam_TypedTable.

<TypeDesc Name="StackingSequence#1" Inherits="CaesamStd_EO" >


<Member Name="plies" Type="Caesam_TypedTable"/>
</TypeDesc>

Step 3. Implement the StackingSequenceTranslate0To1 python method

from CaesamAPI import *


def StackingSequenceTranslate0To1(theStackingSequence0, theEmptyArg):
print "StackingSequence0To1:Start"

# Create an instance of the new version of the StackingSequence class


aStackingSequence1 =
Caesam_Application.GetApplication().NewObject("StackingSequence#1", None,
True)

# Set plies member with the table containing the objects from the EO array.
# Note that the ToTable() method can be used to transform the EOArray to a
Caesam_TypedTable
aStackingSequence1.SetMember("plies",
theStackingSequence0.GetMember("plies").ToTable())

print "StackingSequence0To1:End"

# return the new StackingSequence


return aStackingSequence1

page-105
Caesam SDK | 11 Table data structure

Note: In order to help authors converting EO arrays into tables of EO, a pre-defined translate method is
provided. (CaesamStd_EOArray::TranslateToTable). This method can be used in the declaration of
obsolete classes. Example:

<TypeDesc Name="BoltArray" Inherits="CaesamStd_EOArray" ClassFlags="OBSOLETE">

<Translate Name="TranslateToTable" Type="Cpp" Location="CaesamStd_EOArray"/>


</TypeDesc>

11.3 ACD tables


This document describes the definition of ACD tables. It refers to the plugin com.samcef.caesam.acd
See also : com.samcef.caesam.test.acd/readme.txt

Purpose

The plugin com.samcef.caesam.acd contains material to create an ACD table. ACDTableCreator contains
the code that builds an ACD table. The source code is available here to allow authors to look at the way
the table is actually built. Nevertheless, the code requires advanced knowledge of the way a Caesam model
is implemented and stored.
If the author's purpose is to extend the ACD table, there is no need to dig into ACDTableCreator. In this
case you can use CustomACDTableCreator (located in com.samcef.caesam.test.acd/) which can be looked
into as an extension example.

ACD table specifications

The Inputs of an ACD table are either all the analyses of the model or selected analysis (see ACD Options).
By default, all RFs of analyses of the same type are compared to find the most critical one (the minimum
RF). (See ACD Options for different comparison mechanisms and/or keeping several RFs.
The table contains one row is created for each critical RF; in other words, a (default) ACD table contains
the same number of rows as the types of analysis available.
The table contains up to 10 columns (it may be less depending on options and/or hidden columns). These
are :
1. Analysis Type (example: StaticPanel)
2. Analysis (name, example: Static_ST-P2)
3. Support (name, example: Panel2)
4. LoadCase (name, example: Combined_Ther05_Meca15_Pres075)
5. Failure Criteria (aka RF Name, example: RF_X)
6. RF (value, example: 1.3)
7. Failure Mode (string value)
8. Allowable (value, example: 5.2kPa)
9. Applied Load (value, example 4.8kN)
10. Loading Type (string value, example: X)
Critical values are found in the analyses, in the following two EOs:
• EO.1 -"TableResult" of type CaesamStd_LoadCaseTable.
Requirements for the content of this EO are identical to the requirements for the creation of Post RF
table (eg dimensionless quantities, with a "PhysicalDimension.RF" physical dimension).
• EO.2 -"CriticalResult" of type ACDCriticalResult.
ACDCriticalResult is defined in the ACD extension, in ACD.typedesc. 7 members are defined:
• EO.2.1-"LoadCase", of type CaesamStd_LoadCase. If it is set, it must contain the critical LoadCase
of the analysis.
• EO.2.2-"FailureMode", of type Caesam_String.
• EO.2.3-"Allowable", of type Caesam_Quantity. It can be of any dimension.
• EO.2.4-"LoadingType", of type Caesam_String.

page-106
11 Table data structure | Caesam SDK

• EO.2.5-"RFName", of type Caesam_String.


• EO.2.6-"RF", of type CaesamQty_DIMENSIONLESS. If it is not set, its value will be searched
for in TableResult.
• EO.2.7-"AppliedLoad", of type Caesam_Quantity. It can be of any dimension (even when for a
given analysis, it is expected to be of the same dimension as "Allowable").
The author of an analysis CAN fill in this EO. The existence of the "CriticalResult" EO is NOT mandatory
to create an ACD table. When it is created, each member setting is optional. If a value is not found, it will
not be displayed. If an analysis does not contain a CriticalResult EO, then its critical RF will be taken as
the minimum RF (possibly bounded by criteria, as RF > 0) of the Table result.
However, any analysis containing a CriticalResult EO will ALWAYS be considered as MORE CRITICAL
than any analysis that does not contain a CriticalResult EO, whatever the values of the RFs may be.

Important: The "RF" value of CriticalResult can be different from the RF value found in
TableResult for the same criteria. This allows authors to "tune" the actual RF in
CriticalResult (for instance, by taking Design Factors into account).

As of Caesam v6.2.2-01, there is a restriction on CriticalResult: its RF, "RFName", must be found in
TableResult (even if the RF valuse are different). This restriction is due to the current implementation of
the table. It has been designed to support several options on page 107, some of which are not compatible
with a single "CriticalResult" for a given analysis. For example, there is an option the N minimum RFs
(N > 1) ; or there is an option to consider LoadCase separately. As a consequence, the implementation of
the ACD table must be reviewed to allow a "CriticalResult" related to a RF (name) that is not found in
TableResult.

Creating a default ACD table

Three possibilities are provided for the analyst to create a default table:
(a) From the main menu, Data->Table->Create ACD Table
(b) From the main menu, Data->Table->Create Global Table. Under ACD, choose the creator to build
the table (eg ACDTableCreator).
(c) If the example plugin com.samcef.test.process.perspective is loaded, go through the perspective
view, then Global Table tab. Click on "ACD" button.

Note: Methods (a) and (c) create default tables. Method (b) allows the user to define
options.

ACD Options

The following ACD options can be set when the ACD table is created via the menu Data->Table->Create
Global Table.
ACD Default When this option is selected, the default settings are applied (see 2 -> 5 below)
Extended By default this is set to true (checked).
Columns When selected, "Failure Mode", "Allowable", "Applied Load" & "Loading Type"
columns are added.
By Support By default this is set to false (unchecked)
When selected, RFs are considered separately when they apply on a different support.
By Operation By default this is set to true (checked)
When selected, RFs are considered separately when they apply on a different analysis
type.
By Loadcase By default this is set to false (unchecked)
When selected, RFs are considered separately when they apply on a different loadcase.

page-107
Caesam SDK | 11 Table data structure

Keep 1 minimum RF
This gives the number of minimum RFs to keep per sets of grouped RFs (ie the sets
are determined by the checkboxes selection).

See ACDTableCreator.hxx header for information on the way to set those options programmatically.

Extended ACD tables

There are 3 ways in which the ACD table can be extended:


1. Programmatically - Inherits from ACDTableCreator
Use CustomACDTableCreator (located in com.samcef.caesam.test.acd/) as an example. Note how
the "extension" code is implemented outside the table creator, through an interface. Whenever possible,
this way of extension is very recommended. It produces more modular code, since the extension logic
is in the re-usable interface implementation, rather than being tight to the only table creator, if it were
written in a Update() re-implementation.
2. Through the GUI - Adding a column and saving the descriptor
Create an ACD table ; even empty, its content is meaningless to generate a descriptor.
- Click on the "Show table descriptor" icon in the toolbar just above the table layout.
- In the "Table properties" dialog, select the "Full Path" tab.
- If the example plugin com.samcef.caesam.test.acd is loaded, expand the "Paths from existing
columns", and select "Analysis->CaesamStd_Operation:ICustomACD->Admissible". Otherwise,
choose any path (possibly with customized/newly defined author's interface). - Click on "Add column"
button and close the dialog.
- From the main menu, save the new descriptor: "Data->Table->Export Table descriptor". To test the
saved descriptor:
- Open a new model, possibly run analyses, and create the table from the table descriptor, from the
main menu: "Data->Table->Create Global Table from descriptor" and select the saved descriptor.
An example of such a saved descriptor can be found in
com.samcef.caesam.test.acd/descriptors/CustomACDDescriptor.csm. Note that this file has been
manually edited to make it clearest to be read.
3. Manually creating an instance of a descriptor (reserved for advanced users)
Use com.samcef.caesam.test.acd/descriptors/CustomACDDescriptor.csm as an example. Through
the GUI, from the main menu: "Data->Table->Create Global Table from descriptor" and select the
created descriptor file.

11.4 Guidelines for optimal use of tables


Always use the "by column index" item accessors in preference to those with a column name
When you know you are going to iterate through the items of a Caesam_Table, always obtain the indexes
of the columns you need before entering the loop and then use those indexes to access or modify items.
The "by column name" accessors are slower than the methods that have a column index as argument.
Example:

Standard_Integer aLengthColumnIndex = aTable->GetColumnIndex("Length");


while(aLength/1000 > 0.02){
aLength = aTable->GetQuantityValue(aLengthColumnIndex);
}

Always use type specific item accessors in preference to the generic GetItem
Methods like GetQuantityItem or GetStringItem are faster than the generic GetItem. Caesam_Table
provides generic methods like GetItem for obtaining items of any type. But since this method always
return a Caesam_Object, when called for a column of primitive types it will create an instance of the
corresponding Caesam_Primitive class.

page-108
11 Table data structure | Caesam SDK

As a rule, only use GetItem when you need a primitive object (Caesam_Quantity) instead of a primitive
value (Standard_Real). Otherwise always use primitive value accessors (GetQuantityItem).
Avoid the unnecessary retrieval of an entire row
Retrieving an entire row object from the table (GetRowObject) is slow (a new row object and an instance
for each member are created and initialized when you do this). Although the table has an internal cache
of objects that speeds up subsequent calls, GetRowObject remains a CPU consuming operation.
Unless you REALLY need the row values in the form of an object (in which case you should use
Get/SetRowObject), it is preferable to use the table methods that access the columns individually (like
Get/SetQuantityItem) which are much faster (there is no object creation or initialization involved when
retrieving primitive items).
RetrieveRowObject and StoreRowObject are advanced methods
RetrieveRowObject and StoreRowObject are virtual methods that should only be used when inheriting
from Caesam_TypedTable and when you want to redefine the column-to-member mapping. Note that
defining a new column mapping is an advanced feature of Caesam_TypedTable. For more information
refer to the usage scenario "Table of objects with specific member/item-to-column mapping.".

page-109
Caesam SDK | 12 Tools

12 Tools
This chapter briefly describes some tools available with the Caesam platform.

12.1 Number formatting


Starting with version 5.2.1 of Caesam, the format in which numeric values are displayed can be defined
as Constant resources in typedesc files on a per member basis.
The member resource can be either an instance of CaesamRes_DoubleConstant or
CaesamRes_QuantityConstant. Both these classes have a member Format that can be used to set the
precision, rounding mode and display mode of a double or quantity respectively. Another way to define
a format of a quantity member is through the use of the PhysicalDimension member of the
CaesamRes_QuantityConstant class that can made to point to a predefined global PhysicalDimension
object. Further details are given below.
Examples of quantity member format definitions:

<TypeDesc Name="Result" Inherits="CaesamStd_Result">


<Member Name="maxDisplacement" Type="Caesam_Quantity"/>
<Member Name="RF" Type="CaesamQty_DIMENSIONLESS" >
<Constant Type="CaesamRes_QuantityConstant">
<PhysicalDimension Initialize="*PhysicalDimension.RF"/>
</Constant>
<Comment>The declaration of the Result class </Comment>
</Member>
</TypeDesc>

<TypeDesc Name="PanelProfile" Inherits="CaesamStd_EO">


<Member Name="thickness" Type="CaesamQty_LENGTH">
<Constant Type="CaesamRes_QuantityConstant">
<!-- the format is CaesamRes_NumberFormat instance. -->
<Format Precision="2" RoundingMode="CEIL" Real2StringMode="FIXED" />
</Constant>
</Member>
</TypeDesc>

<TypeDesc Name="PanelProfile" Inherits="CaesamStd_EO">


<Member Name="thickness" Type="CaesamQty_LENGTH">
<Constant Type="CaesamRes_QuantityConstant">
<!-- The format is a reference to a global object. -->
<Format Initialize="*caesam.examples.numberformats.Thickness" />
</Constant>
</Member>
</TypeDesc>

12.1.1 The CaesamRes_NumberFormat class

Members

• Precision : integer number, defines the number of decimals to display


• RoundingMode : enumeration can take one of the three values:
• NEAREST: the FLOOR or CEIL rounded value nearest to x

page-110
12 Tools | Caesam SDK

• FLOOR: rounding downwards : rounded value will be not greater than x.


• CEIL: rounding upwards: rounded value will be not less than x.
• Real2StringMode :
• ENGINEERING: enumeration the exponent of 10 is multiple of 3 (written if not null) (format
[-]***.******e*)
• FIXED: no exponent of 10 (format [-]****.******)
• SCIENTIFIC: always an exponent of 10 and 1 decimal digit before the decimal separator (format
[-]*.******e+**)

Methods

• Member accessors that manipulate enumerations : Get/SetPrecision, Get/SetRoundingMode,


Get/SetReal2StringMode
• Member accessors that manipulate strings : Get/SetPrecisionString, Get/SetRoundingModeString,
Get/SetReal2StringModeString
• GetDefaultFormat : Returns the default instance of the CaesamRes_NumberFormat class

DoubleToString(me:mutable;
theValue: Real from Standard)
returns String from STL is virtual;
---Purpose: formats the real value using the specified precision, rounding

-- mode and real2string mode

12.1.2 Different ways to define the format of a quantity member

By providing a number format constant

This example shows how to create an instance of a number formatCaesamRes_NumberFormat to set the
Precision, RoundingMode and Real2StringMode members.

<TypeDesc Name="PanelProfile" Inherits="CaesamStd_EO">


<Member Name="thickness" Type="CaesamQty_LENGTH">
<Constant Type="CaesamRes_QuantityConstant">
<!-- the format is CaesamRes_NumberFormat instance. -->
<Format Precision="2" RoundingMode="CEIL" Real2StringMode="FIXED" />
</Constant>
</Member>
</TypeDesc>

Through the redefinition of the DoubleToString

This example shows how to define a new class that inherits from CaesamRes_NumberFormat and redefines
the DoubleToString method. This is useful when a different formatting algorithm is needed.

class MyQuantityNumberFormat : public CaesamRes_NumberFormat{


virtual STL_String DoubleToString(const Standard_Real theValue){
char aString[64];
sprintf(aString, "%.15g", theDouble);
return aString;
}
}
- now the new class can be used in the typedesc
<Format Type="MyQuantityNumberFormat" />

page-111
Caesam SDK | 12 Tools

By referencing a pre-defined global number format

This example shows how to define and use a global object of a CaesamRes_NumberFormat type in order
to re-use the same format for several members. An example of the typedesc file is given below

<Type>
<Instance Namespace="caesam.examples.numberformats" Name="Thickness"
Type="CaesamRes_NumberFormat">
<Precision>2</Precision>
<RoundingMode>CEIL</RoundingMode>
<Real2StringMode>FIXED</Real2StringMode>
</Instance>
<TypeDesc Name="PanelProfile" Inherits="CaesamStd_EO">
<Member Name="thickness" Type="CaesamQty_LENGTH">
<Constant Type="CaesamRes_QuantityConstant">
<!-- Define the formatting options of the thickness member as a reference
to the global object. -->
<Format Initialize="*caesam.examples.numberformats.Thickness" />
</Constant>
</Member>
</TypeDesc>
</Type>

By referencing a pre-defined global physical dimension

This example shows how to use a pre-defined (or user defined) physical dimension in the member
declaration. When formatting the member value, Caesam will use the format of the physical dimension
global object. The declarations of the predefined physical dimensions (PhysicalDimension.RF,
PhysicalDimension.Strain, PhysicalDimension.Force and PhysicalDimension.Stress) can be found in the
plugin com.samcef.caesam.resource/GlobalResources.typedesc.
In the following example we set the PhysicalDimension resource of the RF member with a reference to
a pre-defined global physical dimension.

<TypeDesc Name="Result" Inherits="CaesamStd_Result">


<Member Name="maxDisplacement" Type="Caesam_Quantity"/>
<Member Name="RF" Type="CaesamQty_DIMENSIONLESS" >
<Constant Type="CaesamRes_QuantityConstant">
<PhysicalDimension Initialize="*PhysicalDimension.RF"/>
</Constant>
<Comment>The declaration of the Result class </Comment>
</Member>
</TypeDesc>

Authors can re-define these paltform PhysicalDimensions in their plugins. Refer to Redefining global
objects on page 74 for more information about the implications of global object redefinition.

Via the preference dialog

Predefined physical dimension formats can be modified in the preference dialog. Physical dimensions
such as precision, number notation, number rounding mode and unit are available for editing in the
preferences dialog.
There are three categories of physical dimension formats:
• the global physical dimension (Format/PhysicalDimension) which sets the number formatting options
for all the quantities and real values displayed by Caesam
• platform predefined physical dimensions formats:
• Format/PhysicalDimension/DimensionLess/RF
• Format/PhysicalDimension/Force/LoadForce
• Format/PhysicalDimension/Pressure/LoadPressure
• Format/PhysicalDimension/Pressure/Modulus
• Format/PhysicalDimension/Pressure/Stress

page-112
12 Tools | Caesam SDK

• physical dimension formats set by the authors (any entry under a Format/[Subgroup] category)

12.2 Unit system


The Caesam Unit System Caesam_UnitSystem is a class for managing Unit Systems in Caesam. Caesam
uses only one unit system at a time that is set globally and can be changed through the GUI via “Unit
Preferences” or programmatically via SetDefaultUnitSystem.
Caesam supports the following unit systems: "mm,kg,s,A" "m,kg,s,A" "mm,t,s,A" "mm,kg,N,deg",
"micron,g,s,A" "micron,mg,ms,mA".
When saving a document, Caesam stores the current unit system in the file header. At load time, Caesam
will try to convert all the quantity values from the saved unit system to the global Caesam unit system.
The Caesam_UnitSystem class has several methods for converting real values from a unit system into
another (Convert, ConvertObject, ConvertToUnit)

12.3 System utility classes


This sections provides a list of system utility class names with an accompanying description.

Utility class name Description

Caesam_OSDFile A class for file and directory manipulation:


Mkdir, Exists, IsDirectory, Name, Extension,
Remove, RemoveDirectory, Move, Copy, Size,
CreateNewFile, GetSystemPath

Caesam_OSDProcess A set of system process tools:


UserId, UserName, ProcessId, CurrentDirectory

Caesam_OSDHost Carries information about a host:


SystemVersion, HostName, InternetAddress,
EthernetAddress, SystemType

12.4 Preferences
Starting with version 4.1 Caesam offers a system for managing Caesam platform preferences as well as
user defined preferences. This includes the following features :
• All preference in Caesam are handled by an application level preference manager which can be obtained
by calling: Caesam_PreferenceManager::GetPreferenceManager().
• A preference is identified by its path in the application’s preference tree.
• Preference values are typed (they can be of any registered Caesam type)
• When edited interactively (Edit>Preferences), the modified preferences are saved in the file
csm:userhome/CaesamPreferences.csm. When modified programmatically, the author must call
SaveUserPreferences.

Defining preferences and their default values

This can be accomplished by adding in a plugin.xml file a “Preferences” resource that points to a csm file
contining a map of preferences.

page-113
Caesam SDK | 12 Tools

The plugin.xml file:

<Resources Type="Caesam_ObjectMap">
<Item Key="Preferences" Type="Caesam_Url">Preferences.csm</Item>
</Resources>

The Preferences.csm file:

<Instance Type="Caesam_ObjectMap">
<Item Key="Caesam/MyPreferences/MyBooleanPreference"
Type="Caesam_Boolean">FALSE</Item>
</Instance>

Changing and retrieving preference values at runtime

Preferences can be manipulated via two methods of Caesam_Preference: SetData(thePath, theValue) and
GetData(thePath).

Caesam_PreferenceManager::GetApplicationPreference()-
>SetData("Caesam/MyPreferences/MyBooleanPreference",
new Caesam_Boolean(Standard_False));

Standard_Integer aMyBooleanPreference
=Caesam_PreferenceManager::GetApplicationPreference()-
>GetData("Caesam/MyPreferences/MyBooleanPreference")-
>GetBooleanValue();

12.5 Queries
Caesam queries are utility classes for finding Caesam objects by specific criteria. The same query object
must be able to search both a model stored in memory (a model that was loaded from an XML file for
instance) and a model stored in a relational database (via specific SQL queries).
Queries can be implemented by inheriting from one of the abstract classes:

Caesam_Query

The top level query class having an abstract method Execute(). A class derived from this represents a
general purpose query and has no XML/memory or relational database specifics.

Note: Authors should NOT derive their classes directly from it except for implementing
low level and general purpose queries.

Caesam_ObjectQuery

A class derived from it must implement two methods ExecuteDb and ExecuteCsm, one for querying. An
object stored in a database and the other for searching for an object in memory. Classes derived from it
are low-level queries that don't have "root" object on which the query is applied.

CaesamStd_ModelQuery

This class should be used for queries that need to walk the entire model (db or memory). Derived classes
must re-implement two methods:
• GetFilter() that returns an AbstractItemFilter (for models stored in memory the ExecuteCsm method
will apply this filter on the specified model) and

page-114
12 Tools | Caesam SDK

• ExecuteDb which is the equivalent for database models. This methods receive as argument a db
persistence driver containing a handle to the connection of the database. This offers the possibility to
directly execute SQL queries.
Both ExecuteCsm and ExecuteDb methods return an array containing the found objects. Note that the
model must be set prior to calling Execute() method.

CaesamStd_ModelMapQuery

The same as above but the queries are limited to objects stored in the CsmMbr_KeyMap member of the
CaesamStd_Model Two example queries can be found in examples/com.samced.test.db/src/pluginlib/cxx
• TestDb_FindModelItemByType: an example of CaesamStd_ModelQuery query that finds all objects
of a given type (including inherited ones) in the entire model.
• TestDb_FindModelMapItemByType: an example of CaesamStd_ModelMapQuery query that finds
all objects of a given type and which are stored in the map of the model (CsmMbr_KeyMap)

12.6 Logger tool


A logger is a tool that sends messages on output streams, provided that the level of the messages is above
some threshold defined in the logger. Logger classes are available from C++, Java and PYTHON languages.

12.6.1 The Log package: messages, bundles, printers and loggers


The classes Message, Logger and Printer are defined in the Log package (see the HTML or CDL
documentation for this package).

12.6.1.1 The Log_Message and Log_Bundle classes

The Log_Message and Log_Bundle classes are described in the Message Tool on page 119 section.

12.6.1.2 The Log_Printer class

The Log_Printer is an interface (abtract class) with the Println() method to be called when a message is
sent by a logger. For example, the implementing classes Log_StdOutPrinter and Log_StdErrPrinter write
the texts on the standard output and standard error output stream respectively of the current process.
The Log_ SocketPrinter implementing class allows to communicate to another process using the TCP/IP
stream socket protocol. An IP host name and a port number must be given at creation time: a process on
the given host must be listening on the given port.

12.6.1.3 The Log_Logger class

Basically, a logger has a level (only messages with level above that level are sent) and has a set of printers,
each printer is connected to an output stream, typically a file or the standard output stream (the console).
A message itself is an instance of the Log_Message class and is basically a container for text strings.
Each logger has a unique name, level and a list of printers. It may also have a properties bundle (##see
Log_Bundle in the MessageTool documentation) used to translate the message into a local language.
A logger may be put in quiet mode : nothing is sent to the printers, but all pending messages are
accumulated in a local file. When quiet mode is switched off, all the pending messages are sent to the
printers.
A logger may be put in no-header-printed mode : the printer name, the class name and the method name
are not printed in the message.
A logger may also have a parent from which it inherits the printers and the following attributes: level,
quietModeStatus, headerPrintStatus. When a message is sent to a logger, it is automatically sent to the
ancestors of that logger.

page-115
Caesam SDK | 12 Tools

Each logger may be retrieved by its name.

The logger levels

: The Log_Level enumeration defined as follows with increasing verbosity:


• FATAL
• SEVERE
• ERROR : any error
• WARNING
• INFO : any information
• VERBOSE : verbose mode
• DEBUG : for debug purpose
• TRACE : very verbose: trace instructions

The Log() method

Log(theMessage: Message from Log;


theLevel: Level from Log)
returns Boolean from Standard;

Log() is the main method of the Log_Logger class. If the level of the message is above the current logger
level, this method translates the message text in the locale language (if a properties bundle is defined)
and sends it to each printer.
The sent message has the following format:

%%%theLevel: hh:mm:ss YYYY-MM-DD : theLoggerName :::


theClassName::theMethod:translatedTextIncludingArguments

The hh:mm:ss is the time (hour:minutes:second) and YYYY-MM-DD is the date (year-month-day)

The Split method

Split(myclass;
theMessageText: String from STL;
theLevel, theDate, theLoggerName, theClassName, theMethod, theText:out String
from STL);

This static method splits a translated message text into several parts. It may be used to post-process a sent
message.
theMessageText is the full text of the message (translated in local language if a properties bundle is
defined for the logger) and is assumed to be in the following format (as output by the Log method):

%%%theLevel: theDate : theLoggerName ::: theClassName::theMethod:theText

theDate is the sent time of Message in the format hh:mm:ss YYYY-MM-DD.


theLevel is the value of the Level enumeration of Log : 'FATAL', 'SEVERE', 'ERROR', etc. theMethod
is the issuer of the message theText is the message content.

The AddPrinter method

AddPrinter(me: mutable;.thePrinter: Printer from Log);


returns Boolean from Standard;

This method adds a printer (an output channel) to the logger. For example, if the printer is file printer, it
provides a trace of all message sent in a file.

page-116
12 Tools | Caesam SDK

12.6.1.4 The Log_Logger macros

A set of macros defined in Log_Macros.hxx for convenience:


• SAM_LOG_IFLEVEL (level,logger,message) : log the given message at the given level to the given
logger
• SAM_LOG_FATAL (logger, message) : log the given message at the FATAL level to the given logger
• SAM_LOG_SEVERE (logger, message) : log the given message at the SEVERE level to the given
logger
• SAM_LOG_ERROR (logger, message) : log the given message at the ERROR level to the given logger
• SAM_LOG_WARNING (logger, message) : log the given message at the WARNING level to the
given logger
• SAM_LOG_INFO (logger, message) : log the given message at the INFO level to the given logger
• SAM_LOG_VERBOSE (logger, message) : log the given message at the VERBOSE level to the given
logger
• SAM_LOG_DEBUG (logger, message) : log the given message at the DEBUG level to the given
logger
• SAM_LOG_TRACE (logger, message) : log the given message at the TRACE level to the given logger

12.6.2 The Caesam_Message class


The Caesam_Message class is described in the MessageTool documentation.

12.6.3 The Caesam_Logger class


The Caesam_Logger class is a Caesam_Object wrapping a Log_Logger. It can thus be added as member
of any Caesam_Object. The GetLogger() method provides access to the Log_Logger instance.

12.6.4 The application logger


The Caesam_Application class has a static logger. This logger is child of the Log::Default logger containing
printer : the standard output printer. It can be used to output messages on the console.
Messages issued from plugin implementation classes should preferably be sent to the plugin logger (see
below). The GetLogger() method gives access to the application logger.
Some application logger macros to log message on the application logger are available in Caesam.hxx
and are used in the CAESAM platform implementation.
Hereafter * means one of the following strings: FATAL SEVERE ERROR WARNING INFO VERBOSE
DEBUG TRACE
• CSM_LOG_*(class, method, text) : build a message from the class, method, text arguments and
sends it to the CAESAM application logger
• CSM_LOG_*_MES (message) : sends a message to the CAESAM application logger. The macros
CSM_LOG_*_MES macros allows to give a message as argument, but its use is discouraged, as the
message is to be built before the macro evaluation. The CSM_LOG_*_ARGS are preferred.
• CSM_LOG_*_ARGS(class, method, text, args) : build a message from the class, method, text and
args arguments and send it to the CAESAM application logger.
The args are appended to the message with the << overloaded operator.
For example: Standard_Integer aImportTotal, aTotal; ...

CSM_LOG_INFO_ARGS("CaesamAPI_EOLibrary",
"Import",
"Successfully imported %1% of the %2% EOs",
aImportTotal << aTotal);

page-117
Caesam SDK | 12 Tools

The arguments aImportTotal and aTotal are appended to the message. The preceding code expands to:

if ((Log_INFO) <= Caesam_Application::GetLogLevel()) {


Caesam_Message aTmpLogMessage("CaesamAPI_EOLibrary",
"Import",
"Successfully imported %1% of the %2% EOs");
aTmpLogMessage << aImportTotal << aTotal;
Caesam_Application::GetApplication()->GetLogger()->Log(aTmpLogMessage,
(Log_INFO));
}

12.6.5 The Task logger


The Process_Task class has a static logger (the same for all Process_Task instances) used to output task
messages. This logger is the child of the Log::Default logger containing one printer : the standard output
printer.
This logger is triggered each time the PutMessage() method of Process_Task is called.

12.6.6 The plug-in’s loggers


Each Caesam_Plugin has a logger stored in the member “Logger” of each Caesam_Plugin instance. This
logger is child of the Log::Default logger containing one printer : the standard output printer. It can be
used to output on the console the messages issued from plugin implementation classes.
A plugin author can add a printer to this logger or add a child to this logger.
A plugin logger may be retrieved from any object with the GetPluginLogger() method of the class
Caesam_Class . For example:

PTRMEM(Caesam_Logger) aPluginLogger =
aObject->GetClass()->GetPluginLogger();

12.6.7 The logger macros


Some macros to log message on the any logger are available in Caesam.hxx. For example, they may be
used to log message on a plugin logger. Hereafter * refers to one of the following strings: FATAL SEVERE
ERROR WARNING INFO VERBOSE DEBUG TRACE
• CSM_LOG_*_LOGGER(class, method, text) : builds a message from the class, method, text
arguments and sends it to the logger
• CSM_LOG_*_LOGGER_ARGS(class, method, text, args) : builds a message from the class,
method, text and args arguments and sends it to the logger.
The args are appended to the message with the << overloaded operator. For example: Standard_Integer
aImportTotal, aTotal;

PTRMEM(Caesam_Logger) aPluginLogger =
aObject->GetClass()->GetPluginLogger();
...
CSM_LOG_INFO_LOGGER_ARGS(aPluginLogger,
"Task_BuildLibrary",
"Import",
"Successfully imported %1% of the %2% mat",
aImportTotal << aTotal);

The arguments aImportTotal and aTotal are appended to the message.

page-118
12 Tools | Caesam SDK

The precedent code expands to

if ((Log_INFO) <= aPluginLogger->GetLevel()) {


Caesam_Message aTmpLogMessage("CaesamAPI_EOLibrary", "Import",
"Successfully imported %1% of the %2% EOs");
aTmpLogMessage << aImportTotal << aTotal;
Caesam_Application::GetApplication()->GetLogger()-> Log(aTmpLogMessage,
(Log_INFO));
}

12.6.8 The com.samcef.caesam.CaesamLog Java class


The com.samcef.caesam.CaesamLog Java class is a wrapper around the methods:
• Log_Logger.log
• Log_Logger.getLevel
• new Caesam_Message
It can be used to send messages from the Java code.

Java example
Here is a Java code example:

CaesamLog.isDebug()) {
CaesamLog.logDebug(CaesamLog.class, "main", "test of log");
}
...
Log_Logger aPluginLogger = aObject.GetClass().GetPluginLogger();
...
if (CaesamLog.isInfo(aPluginLogger)) {
Caesam_Message aMessage =
new Caesam_Message(thisClass.class,
"thisMethod",
"a message with 2 args %1% and %2%");
aMessage.AddIntArgument(120);
aMessage.AddObjectArgument(anyCaesamObject);
CaesamLog.logInfo(aPluginLogger, aMessage);
}

C++ example
Here is a C++ code example:
Standard_Integer aImportTotal, aTotal;

PTRMEM(Caesam_Logger) aPluginLogger =
aObject->GetClass()->GetPluginLogger();
...
CSM_LOG_INFO_LOGGER_ARGS(aPluginLogger,
"Task_BuildLibrary",
"Import",
"Successfully imported %1% of the %2% mat",
aImportTotal << aTotal);

12.7 Message tool


The message tool is a text utility to compose messages. An localisation tool (the Log_Bundle) is also
provided to translate a message into alocal language.

page-119
Caesam SDK | 12 Tools

The Bundle and Message classes are part of the Log package. The Caesam_Message from the Caesam
package provides an extension of the Log_Message class to convert Caesam_Object to string.
The Caesam_Message and Log_Bundle classes are also available from Java code.

12.7.1 The Log_Bundle class


A bundle is a map between key (string) and values (string) which can be used for localization purposes.
A key-value pair is called a property. The key is some English text and the corresponding value is its
translation into another language. A bundle is thus required for each language.
The keys and values may be loaded from a bundle text file with the following format (see the GetBundle()
method in the kernel C++ classes HTML documentation for a full description of the file format) :
• The key contains all of the characters in the line starting with the first non-white space character and
up to, but not including, the first unescaped '=', ':', or white space character other than a line terminator.
• Any white space after the key is skipped; if the first non-white space character after the key is '=' or
':', then it is ignored and any white space characters after it are also skipped. All remaining characters
on the line become part of the associated element string; if there are no remaining characters, the
element is the empty string "".

12.7.2 The Log_Message class


A Log_Message is container for formatted text, i..e. with variable fields with a localization capability.
Like in the format of the print function, the formatted text may contain some special conversion keys
starting and ending with the % character (the variable fields) each of which result in fetching the
corresponding argument.
For localization purposes, the formatted text may be a key in which has to be translated into a local
language before being displayed.
The ToString() method accounts for the bundle given as argument (if not null) : if the formatted text is a
key in the bundle, it will be replaced by its corresponding value before performing the argument
substitution.

The Log_Message constructor

Create(theClassName, theMethodName, theFormattedText: String from STL)

If theFormattedText starts with $, it means that it is a key in some properties bundle that as to be translated.
If the (translated) theFormattedText contains fields surrounded by the % delimiters, those fields will be
replaced by the text of the corresponding argument(s):
%N% (N is a strictly positive integer) means the Nth argument
%*% means all arguments
%N-% means the Nth argument and all the following ones
%-N% means the first argument up to (and including) the Nth argument (i.e. means %1-N%)
The argument index starts at 1. The %% means the % character (not an argument index).

Adding arguments to a message

Arguments may be appended to the message with the AddArgument methods, or, for convenience, with
the overloaded << operator.

page-120
12 Tools | Caesam SDK

Here is an example of a formatted text with three arguments:

Log_Message aMessage(“MyClassName”,
“MyMethodName”,
”value out of range: got %1% but valid range
is [%2%..%3%]”);
aMessage << aGotInteger << aLowerBound << aUpperBound;

From Java code, a method is defined for each type of argument to be added.

The ToString() method

ToString(theBundle: Bundle from Log;


IsHeaderDisplayed: Boolean = Standard_True)
returns String from STL;

The ToString() method of the given bundle translates the formatted text (if it starts with the $ character)
then substitutes the arguments (if any) and returns the built string.
If theBundle is null, or does not contain the formatted text as key, the formatted text is not translated.
If IsHeaderDisplayed is true, the name of the class and the method prefixes the output string.s
Once this method is called, the addArgument cannot be called: it triggers an invalid state error.

12.7.3 The Caesam_Message class


The class Caesam_Message extends the Log_Message class by adding an overloading of the << operator
for Caesam_Object’s.
The appended object may be retrieved with the GetObjects() method.
Any Caesam_Object can be appended as argument with << : the virtual ShortDesc() method will be called
to get a string from the Caesam_Object.
Below is an example of a formatted text with two arguments:

Caesam_Message aMessage(“MyClassName”,
“MyMethodName”,
”the received argument has a wrong type. Got
%1% but expecting %2%);
aMessage << aObject-> GetTypeName() << aObject;

12.7.4 Examples

C++

Log_Message

Log_Message aMessage(“MyClassName”,
“MyMethodName”,
”value out of range: got %1% but valid range
is [%2%..%3%]”);
aMessage << aGotInteger << aLowerBound << aUpperBound;
std::cout
<< aMessage.ToString(NULL, Standard_False)
<< std::endl;

page-121
Caesam SDK | 12 Tools

Caesam_Message

// here is part of the BundleFilePath_fr.properties file


ERR_WRONG_ARGUMENT_TYPE = \
ERREUR: L'argument n'a pas le bon type. Re\ufffdu %1%, attendu
%2%

PRTMEM(Log_Bundle) aFrenchBundle =
Log_Bundle ::GetBundle(“BundleFilePath_fr.properties”);

Caesam_Message aMessage(“MyClassName”,
“MyMethodName”,
” $ERR_WRONG_ARGUMENT_TYPE”);
aMessage << aObject-> GetTypeName() << aObject;
std::cout
<< aMessage.ToString(aFrenchBundle, Standard_True)
<< std::endl;

Java

Log_Bundle aFrenchBundle =
Log_Bundle.GetBundle(“BundleFilePath_fr.properties”);
Caesam_Message aMessage =
new Caesam_Message(“MyClassName”,
“MyMethodName”,
”$ERR_WRONG_ARGUMENT_TYPE”);
aMessage. AddStringArgument(aObject.GetTypeName());
aMessage. AddObjectArgument (aObject);
System.out.println(aMessage.ToString(aFrenchBundle, true);

12.8 OP2 access tool


This section describes the tool to access results from a NASTRAN .op2 file. It is assumed that there exists
an .op2 file, called “FEMModel” containing the mesh and some .op2 files called ‘result files’ containing
results from finite element calculation analyses. An FEMModel can itself be a result file if it contains the
mesh and some FEM results.

12.8.1 Required DATABLOCK in .op2 files


The model op2 file
The model .op2 file must contain the mesh definition:
• GEOM2 : element connectivity
• one of the following (exclusively)
• CSTM or CSTMS (coordinate system transformation matrix) + BGPDT or BGPDTS (basic grid
point definition) or (exclusively)
• GEOM1 (image of bulk data grid point geometry : nodes coordinates + coordinate systems defined
via nodes.

Note: that only CORD2R coordinate systems are currently accounted for.

The result .op2 file


For the result .op2 file, no mandatory DATABLOCK is required.
The following DATABLOCKS, if present, are loaded: OEF1X,
OGPFB1,OES1X1,OSTR1X,OUGV1,OUGV2,OPG1,OPG2

page-122
12 Tools | Caesam SDK

For .op2 post processing, the DATABLOCK (composite stress tensor), OES1C if present, is also loaded
For automatic computed load cases creation from .op2 files, the DATABLOCK CASECC must be present
in the result .op2 files.

12.8.2 The CaesamEO_ GlobalFEMModel class


This class contains an identification of the .OP2 file defining the FEMModel, i.e. containing the mesh.
This class has the following members:
• ModelLocation : URL to the .op2 file
• UnitSystem: unit system of the .op2 file
An instance of the CaesamEO_GlobalFEMModel can be retrieved from the CaesamStd_Model instance
with the call

CaesamEO_GlobalFEMModel::Cast(
aStdModel->GetGlobalModel()->GetReferenceEO("CaesamEO_GlobalFEMModel"));

12.8.3 The CaesamFEM_StaticAnalysis class


Access to .op2 file content is provided by the CaesamFEM_StaticAnalysis class.
The file ProcessTest_SMOP2FluxSuperStiffener.cxx in the directory
Src/pluginlib/cxx of the plugin com.samcef.caesam.test.process from the
examples/plugin directory of CAESAM distribution may serve as example.

The CaesamFEM_StaticAnalysis creator

The creator CaesamFEM_StaticAnalysis::NewInstance (const Handle(CaesamFEM_Model)&)


takes a CaesamFEM_Model as argument.
This instance is created by the one of the following methods of the CaesamEO_GlobalFEMModel class:

GetCaesamFEMModel(theCsmContext: CsmContext from Caesam)

returns Model from CaesamFEM;

GetCaesamFEMModel(theCsmContext: CsmContext from Caesam;


theSelectedElements: IntegerArray from Caesam;
theSelectedNodes: IntegerArray from Caesam =
NULL)

returns Model from CaesamFEM;


It gets an instance of an opened FEM model file, accounting for the current value of the "ModelLocation"
member and the given context. To speed up the FEM model file opening/scanning, the CaesamFEM_Model
is instantiated only once: subsequent calls to this method return always the same CaesamFEM_Model.
To speed up the file loading and to reduce memory resource consumption, a list of element numbers may
be provided: only those elements will be accounted for. A null or empty IntegerArray means all elements.
The nodes of the elements given in theSelectedElements are automatically selected, but a list of additional
node numbers may be provided A null or empty IntegerArray means all nodes of the selected elements
or all nodes of the mesh if theSelectedElements is null or empty. The elements and nodes of the current
mesh model can be retrieved from the CaesamStd_GFEM instance with the GetMesh() method:

PTRMEM(CaesamTopology_Mesh) aMesh = aCaesamStdGFEM ->GetMesh();


if (!aMesh.IsNull()) {
aSelectedElems = aMesh->GetElementsNumbers();
}

page-123
Caesam SDK | 12 Tools

The CaesamStd_GFEM instance itself can retrieved from the CaesamStd_Model instance with

CaesamStd_GFEM::Cast(
aCaesamStdModel->GetGlobalModel()->GetReferenceEO("CaesamStd_GFEM"));

The CaesamFEM_StaticAnalysis methods

All the methods are described in the .cdl or HTML documentation of the class.
They all take a CaesamStd _LoadCase instance as argument and this argument contains the path(es) to
the .OP2 file(s) to be scanned.
They return Caesam_Quantity or Caesam_QuantityArray instance, or NULL object if the result is not
found in the .OP2 file(s)

The GetStatus() method

The GetStatus() method inherited from CaesamFEM_Analysis class returns a description on the last error,
or null if the last call was successful.
Testing this status after each call to CaesamFEM_StaticAnalysis is highly recommended.

12.9 Tree model creation utility


Since V5, a new utility is available to authors, that will allow them to easily build a tree model based on
a tree descriptor. To achieve this, you must use the class CaesamAPI_TreeDescriptorBasedTreeModel
that works on a tree descriptor.
This utility can be useful if you are in a situation where you have to organize items of the Caesam model
in a tree, based on some properties.
For example, you could want to organize loadcases according to their skill, physic and so on. This is
exactly what we do in the load case set editor (when editing loadcases in tree mode), and we use the utility
described in this chapter to achieve this.
You could also use this utility to organize items into a hierarchy of directories or (structural) groups,
based on some properties.
The properties used to organize the items must be expressed with Caesam paths (remember that Caesam
paths can also contain calls to registered methods). The tree descriptor, which is the XML file describing
the tree structure, is thus based on Caesam paths.
For a simple static tree, this descriptor is nothing more that a list a paths. The following example shows
a descriptor for a tree grouping load cases by skill then by physic, then by status.
<Instance Type="CaesamStd_PathTreeDescriptor">
<CsmMbr_Paths>Skill;Physic;Status</CsmMbr_Paths>
</Instance>

You can also introduce a dynamical behaviour: this means that the tree structure becomes different
according to a given criterium. For example, if you want to group according to physic and status only for
loadcases with skill "Static", you can make the following descriptor:
<Instance Type="CaesamStd_PathTreeDescriptor">
<CsmMbr_Paths>Skill</CsmMbr_Paths>
<CsmMbr_Nodes>

<Item Type="CaesamStd_PathTreeDescriptor">
<CsmMbr_Value>St*t?c</CsmMbr_Value>
<!-- You see that the discriminant values can contain wildcards -->
<CsmMbr_Paths>Physic;Status</CsmMbr_Paths>
</Item>

<Item Type="CaesamStd_PathTreeDescriptor">
<CsmMbr_Value>*</CsmMbr_Value>

page-124
12 Tools | Caesam SDK

</Item>

</CsmMbr_Nodes>
</Instance>

Now you can use this XML tree descriptor to produce the tree model.
CaesamAPI_TreeDescriptorBasedTreeModel will in fact produce a tree that organizes the model items
matching the given filter, according to the given tree descriptor.
Behind each node is this tree, you will find all items that are under this node. To get these items, use the
GetItems() method on the treenode. For leaf nodes there will be only one item that can be obtained with
GetItem().
Here is an example of how to use it. In this example we use the tree model to create hierarchical groups
for organizing loadcases. We also show how to simply print the tree to standard output.

// recursive method that prints the tree to standard output


void ShowTree(const Handle(CaesamStd_TreeNode)& theTreeNode, int theDepth=0)
{
if (!theTreeNode.IsNull()) {

// display a line for the treenode


for (int aDepthIndex = 0; aDepthIndex < theDepth; aDepthIndex++) cout << " ";
cout << theTreeNode->GetLabel();
if (!theTreeNode->IsLeaf()) cout << " (" << theTreeNode->GetItems()->Size() << " items)";
cout << endl;

// recursion on children
for (int aChildIndex = 0; aChildIndex < theTreeNode->GetChildCount(); aChildIndex++)
ShowTree(theTreeNode->GetChild(aChildIndex), theDepth+1);
}
}

// recursive method that creates the groups


void CreateGroups(const Handle(CaesamStd_Directory)& theFatherGroup, const Handle(CaesamStd_TreeNode)&
theTreeNode)
{
if (!theTreeNode.IsNull()) {

if (theTreeNode->IsLeaf()) theFatherGroup->AppendChild(theTreeNode->GetItem());
else {

Handle(CaesamStd_Directory) aGroup =
theFatherGroup->AppendChildDirectory(theTreeNode->GetLabel());

// recursion on children
for (int aChildIndex = 0; aChildIndex < theTreeNode->GetChildCount(); aChildIndex++)
CreateGroups(aGroup, theTreeNode->GetChild(aChildIndex));
}
}
}

// load tree descriptor from XML file


Handle(CaesamStd_TreeDirectory) aLCTreeDesciptor = CaesamStd_TreeDirectory::Cast(
CaesamAPI_Application::GetApplication()->LoadObject("csm:userhome/LCTreeDescriptor.csm")
);

// create tree model for organizing unitary loadcases


Handle(CaesamStd_TreeModel) aTreeModel = new CaesamAPI_TreeDescriptorBasedTreeModel(
aStdModel,
new CaesamStd_TypeFilter("CaesamLC_UnitaryLoadCase"),
aLCTreeDesciptor
);

// prints the tree to standard output


ShowTree(aTreeModel->GetRoot());

// create hierarchical groups


CreateGroups(aStdModel->GetGroupDirectory(), aTreeModel->GetRoot());

12.10 Operating System Tools


A C++ utility is available to provide directory Browsing: FEATools: FindFile

page-125
Caesam SDK | 12 Tools

Operating like a UNIX find utility, this command descends recursively a directory hierarchy from the
given path seeking files that match some criteria, and calling a given function for each file found
• FindFiles : (theDirPath: AsciiString from TCollection; theInstancePtr: Address rom Standard; theAction:
FindFileAction from FEATools; theSkippedDir: MapOfAsciiString from FEATools; theKindOfFile:
KindFile from OSD = OSD_FILE; theFollowSymbLink: Boolean from Standard = Standard_False;
theMaxDepth: Integer from Standard = 0);
• theDirPath : root of directory hierarchy to be browsed
• theInstancePtr : any pointer, will be the first argument to the called function (it allows to pass a class
instance to the function: may be NULL)
• theAction : the function to be called when a match is found
• theSkippedDir : directory names to be skipped
• theKindOfFile : kind of file to be found.
• theFollowSymbLink : if symbolic links are followed (UNIX only)
• theMaxDepth : maximum depth the hierarchy to be browsed ( if <= 0 : no limit)

Example

-- static void FindFileAction(const Standard_Address


theInstance,const Standard_CString theFileName) {
-- // called foreach file
-- cout << " Processing " << theFileName
<< endl;
-- someClass *aInstancePtr = (someClass *)theInstance;
-- theInstance->someMethod(...);
-- ....
-- }
--
-- {
-- ...
-- FEATools_MapOfAsciiString aMapOfAsciiString;
-- FEATools_FindFileAction aFindFileAction =
(FEATools_FindFileAction) FEATools_CheckSum::FindFileAction;
-- FEATools::FindFiles("some dir", this, aFindFileAction,

aMapOfAsciiString);
-- ...
-- }

page-126
13 Caesam commands | Caesam SDK

13 Caesam commands
This section describes commands that are provided for defining disciplines and building plugins.
In addition, the caesam command is the most important one because it is the script used to start the Caesam
application. Various set of options are provided to help you configure Caesam with your own set of
plugins.

13.1 Discipline files


Discipline files is the mechanism provided to help you launching caesam with your set of plugins. A script
file with the name discipline.plugins.csh on UNIX and discipline.plugins.cmd on Windows has to be
placed in the caesam installation directory. When this is done, you can launch the caesam command with
option –discipline, the discipline file is sourced before launching caesam.
The –anydiscipline caesam command flag asks the application to load all the plugins described in the
anydiscipline.plugins.csh (on UNIX/LINUX) and anydiscipline.plugins.cmd (on Windows) files. The
anydiscipline.plugins.csh (on UNIX/LINUX) and anydiscipline.plugins.cmd (on Windows) files have to
be located in the CAESAM installation directory. 'anydiscipline' may be any character string valid in a
file name and identifying a discipline.
If, in the anydiscipline.plugins.csh (on UNIX/LINUX) and anydiscipline.plugins.cmd (on Windows) files,
the addPlugin variable value, is defined, it will be prepended to the CAESAM_PLUGIN_PATH, allowing
plugins related to some discipline to be loaded. The addPlugin variable is a list of directories separated
by the colon (:) character on UNIX and by the semi-colon (;) character on Windows.
An example discipline file on UNIX: examples.plugins.csh is given below.

#
# environment file for examples discipline
# the addPlugin variable value will be prepended to the
# CAESAM_PLUGIN_PATH
# Define the location of plugins which have to to loaded set addPlugin =
"$CAESAM_HOME/examples/plugins"

An example discipline file on Windows examples.plugins.cmd is given below:

REM
REM plugins examples environment for CAESAM
REM the addPlugin variable is a ; separated list of directories
REM containing the plugins
REM set addPlugin=%CAESAM_HOME%examples\plugins\

If some plugins require some environment variables to be set or modified, they have to be defined or
modified in this anydiscipline.plugins.csh(or .cmd) file. For example, the PATH environment variable
on Windows or the LD_LIBRARY_PATH environment variable on UNIX/LINUX may be modified by
adding some directories containing dynamically loaded object libraries. As another example, if a plugin
uses site-dependant URL’s to locate directories containing a finite element result file, those URL’s may
be defined via environment variables defined in the anydiscipline.plugins.csh(or .cmd) file.

13.2 Commands for building a plugin


CAESAM provides five commands for an integrated build system for plugins.
CAESAM provides an integrated build system for plugins. The following commands are provided :
• csmnewplugin : create a new empty plugin with correct directories

page-127
Caesam SDK | 13 Caesam commands

• csmmake : make a specific plugin


• csmmakeall : make all plugins in a given directory
• CAESAMMakeChecksum- caesamCheckSum : compute checksum for a plugin or a set of plugins

csmnewplugin

csmnewplugin is a tool for generating a new plugin directory architecture. If launched without any
arguments, it enters an interactive mode and guides the user in the creation of the plugin. The available
options are:

-help Show help about available options


-type <plugintype> Create a plugin of the given type : caesam : Caesam_Plugin pythonmodule :
Caesam_PythonModulePlugin utility : Caesam_UtilityPlugin
-java Put java sources directory in new plugin architecture
-pluginlib Put pluginlib directory in new plugin architecture
-executable Put a sample executable in new plugin architecture

You can specify destination directory and plugin name on the command line:

Csmnewplugin [options] [DEST_DIR] [PLUGIN_NAME]

[DEST_DIR]: the location where you want to put the new plugin
[PLUGIN_NAME]: the name of the new plugin (tld.company.package)

csmmake

The csmmake is a command designed to build a caesam plugin. It is based on the ant software
(http:://ant.apache.org). To use the csmmake procedure, your plugin must contain a build.xml file. This
file is used to initialize the csmmake tool. It can also be used to access to advanced compilation features
specific to your plugin (change compilators options, add defines, … - see paragraph 7.3.5.2 about csmmake
advanced configuration). If your plugin does not contain this file, it will be copied the first time you
execute csmmake, you can also find it in the caesam distribution (<Caesam Install
Directory>/SDK/template/files/build.xml). To use csmmake you must have the CAESAM environment
defined. To do so, you have to run the caesamsh script described in paragraph 7.1.3. Csmmake handles
dependencies between plugins, for this feature to work, all dependants plugins must be in the
CAESAM_PLUGIN_PATH environment variable. This can be done by using discipline file (paragraph
7.2) with caesamsh command or by using –plugin option followed by the plugins root directory (available
for caesamsh command and csmmake/csmmakeall command).
Example csmmake launch on windows:

C:\>C:\CAESAM\caesamsh –plugin C:\CAESAM\examples\plugins

C:\>c:\CAESAM\csmmake –sourcedir
C:\CAESAM\examples\plugins\com.samcef.caesam.test.transverse

Example csmmake launch on UNIX:

# /usr/caesam/caesamsh –plugin /usr/caesam/examples/plugins


# /usr/caesam/csmmake –sourcedir
/usr/caesam/examples/plugins/com.samcef.caesam.test.transverse

page-128
13 Caesam commands | Caesam SDK

Table 10: Available options

-sourcedir <plugin path> Specify which plugin to compile. Must be an absolute path to the plugin
directory. If not specified, then the current directory is build.
-plugin <plugin root Add the specified path to the CAESAM_PLUGIN_PATH making it
path> available for plugin dependency loading.
-g Compile the plugin in debug mode
-O Set optimization to default level (2) (default if none option specified)
-O1 Set optimization to level 1
-O2 Set optimization to level 2
-O3 Set optimization to level 3
-O4 Set optimization to level 4
-O0 Disable optimization flag
-deploy <deploy Create a copy of the plugin in the given directory without sources but with
directory> pluginlib includes. Rebuild checksums after copying

When selecting -O (or no specific option), plugin defined level is used. To force optimization to level 2,
you must use -O2.
You can set optimization level for each plugin. Add the following line into the plugin build.xml file.
<property name="compiler.optimize.level" value="3" /> (value contain the optimization level in 0,1,2,3,4)
This value will be used by csmmake if no other level is given in command line.
Limitation:
This new command depends on csm_compilers.xml file, if you use your own one, you have to use the
one from the distribution to benefit new optimization level configuration. If you really needs your own
csm_compilers.xml please merge it with the distribution.

page-129
Caesam SDK | 14 Persistency

14 Persistency
This chapter deals with all aspects of Persistency.

14.1 Object persistence


In Caesam, any Caesam_Object can be stored into a file. Currently there are two ways of doing it:
• Using the Caesam_Application::Save[Load]Object() for storing objects as they are
• Using the more advanced class Caesam_CsmDocument, which adds a Caesam_CsmHeader to the
object’s instance

14.1.1 Caesam_Application::LoadObject, SaveObject

LoadObject

Handle(Caesam_Object) Caesam_Application::LoadObject(const STL_String& theUrl);

Argument Description Accepted values

theUrl Represents the source URL from Caesam_Url Instance.


which the object should be read. It
should point to an absolute resource 1. As for version 2.1 of Caesam, only the
location and should have a valid protocol “file” is implemented and it
protocol. corresponds to reading an XML object
instance.
2. Starting with version 4.2 Caesam can save
objects to an SQLite database via the protocol
“sqliteapi”

Returns the instance of the loaded Caesam_Object.

SaveObject

void Caesam_Application::SaveObject(const STL_String& theUrl, const Handle(Caesam_Object)&


theObject);

Argument Description Accepted values

theUrl Represents the destination URL to Caesam_Url Instance.


which the object should be written. It
should point to an absolute resource 1. As for version 2.1 of Caesam, only the
location and should have valid protocol “file” is implemented and it
protocol. corresponds to writing an XML object
instance
2. Starting with version 4.2 Caesam can save
objects to an SQLite database via the protocol
“sqliteapi”.

theObject The instance of the object to be A Caesam_Object instance


persisted. If the object is null, there
will be output.

page-130
14 Persistency | Caesam SDK

When using the “file” protocol ( see Persistence driver for XML on page 130 (Caesam_CsmDriver)) it is
possible to write an XML instance to the standard output by using the special resource identifier
“file:stdout”.

Example

:
// we obtain the Caesam application instance
aApp = Caesam_Application::GetApplication();
// we save an initialized quantity object into a file in XML format
PTRMEM(Caesam_Object) aObject = new Caesam_Quantity(0.5, "LENGTH");
aApp->SaveObject("file:/tmp/aQuantity.xml", aObject);
// we load the saved object and we display it to the console
aObject = aApp->LoadObject("file:/tmp/aQuantity.xml");
aApp->SaveObject("file:stdout", aObject);
// the last line will print to the console the object in XML:

<?xml version="1.0" encoding="utf-8"?>


<Caesam Version="2.0" xmlns="http://www.samcef.com/caesam/2.0">
<Instance Type="Caesam_Quantity" Id="1d29f8">
<Value Id="1d2a38" Type="Caesam_Double">0.5</Value>
<Dimension Id="1d4d88" Type="Caesam_String">LENGTH</Dimension>
</Instance>
</Caesam>

14.1.2 Caesam_CsmDocument::LoadDocument, SaveDocument

Caesam_CsmDocument is a special kind of persistence class. Apart from the instance of the object it also
stores a header containing information such as the user who created the instance, creation and modification
date and the unit system in which the values are expressed.
A CsmDocument is composed of:
• A <Header> section of type Caesam_CsmHeader which has the following fields: Title, CsmVersion,
CreatedBy, CreationDate, LastModifiedBy, LastModificationDate andUnitSystem.
• A <Data> section that holds the actual object instance
When loading a CsmDocument (via LoadDocument), Caesam verifies the version and the unit system.
If the saved unit system and version do not match Caesam’s current unit system and version respectively,
an exception will be raised. An example of CsmHeader in XML is given below.

Example

<?xml version="1.0" encoding="utf-8"?>


<Caesam Version="2.0" xmlns="http://www.samcef.com/caesam/2.0">
<Instance Type="Caesam_CsmDocument" Id="1784330">
<Header Type="Caesam_CsmHeader">
<Title Type="Caesam_String"></Title>
<CsmVersion Type="Caesam_Version">2.0-14</CsmVersion>
<CreatedBy Type="Caesam_String">fernea</CreatedBy>
<CreationDate Type="Caesam_Date">2006-03-30 10:18:13</CreationDate>
<LastModifiedBy Type="Caesam_String">fernea</LastModifiedBy>
<LastModificationDate Type="Caesam_Date">2006-03-30
10:18:42</LastModificationDate>
<UnitSystem Type="Caesam_UnitSystem">
<Name Type="Caesam_String">mm,kg,N,deg</Name>
</UnitSystem>
</Header>
<Data Id="3d53d8" Type="CaesamStd_EOLibrary">
<!-- the actual object instance XML goes here -->

page-131
Caesam SDK | 14 Persistency

</Data>
</Instance>

14.1.3 String serialization


Caesam_Application offers two methods that can be used to serialize and deserialize Caesam objects
to/from an XML string. The syntax of the string XML is the same as the one used for persisting objects
in csm files.

LoadObjectFromString(me: mutable;
theXMLString: String from STL)
returns Object from Caesam;
---Purpose: Create a Caesam_Object from an XML string
---Level: Public

SaveObjectToString(me: mutable;
theObject: Object from Caesam)
returns String from STL;
---Purpose: Returns the XML representation of the Caesam_Object in a string
-- EXPORT:
---Level: Public

14.1.4 Transient objects


Starting with version 5.2.1, instances flagged as TRANSIENT are not saved.

Properties of transient objects

• a transient instance is not saved during a SaveObject operation


• none of the members of the transient instance will be saved even if the member objects are not flagged
as transient. This implies that objects that we want to be persisted must be attached to a perisistent
object tree.
• transient instances are always read from files. This feature can be useful when defining transient values
in default instance files. See the example below.
• an object not flagged as transient is by default persistent

Available methods

Caesam_Object::IsTransient()
Caesam_Object::SetIsTransient(Standard_Boolean)

Example : Defining a transient instance in a csm file

<Instance Type="Bolt">
<diameter Type="CaesamQty_LENGTH">
<Value Type="Caesam_Double">5</Value>
</diameter>
<length Type="CaesamQty_LENGTH">
<Value Type="Caesam_Double">5</Value>
</length>
<Comment Type="Caesam_String" InstanceFlags="TRANSIENT">Default instance
for the Bolt#1 class</Comment>
</Instance>

page-132
14 Persistency | Caesam SDK

14.2 Persistence drivers


Behind the higher-level API mentioned in the previous paragraphs, the persistence of objects is
accomplished using specialized classes called drivers. A driver is a class that implements the Caesam_Driver
interface (having an abstract method for reading and one for writing) and which has been registered into
the system as a handler of a specific URL protocol.

14.2.1 Persistence driver for XML (Caesam_CsmDriver)


Version 2.1 Caesam is delivered with a predefined persistence driver capable of handling Caesam XML
files. Caesam_CsmDriver is the driver registered for the “file” protocol. It can be used for reading and
writing Caesam_Object instances in XML format.

The Caesam XML file structure

Any XML persisted instance must contain at least two declarations:


• The xml declaration which specifies the character encoding of the content

<?xml version="1.0" encoding="utf-8"?>

• The <Caesam> tag which identifies the file format as being Caesam 2.0 and set the default namespace
for the file. While loading the file, the XML driver will check the file format version against the
supported version of Caesam (2.0).

<Caesam Version="2.0" xmlns="http://www.samcef.com/caesam/2.0">

The actual XML representation of the persisted object goes inside the Caesam tag and must be enclosed
in <Instance> tags. Note that there can be only one <Instance> per file. To store multiple objects, use the
pre-defined collection classes Caesam_ObjectArray or Caesam_ObjectMap. As the following example
shows, an instance is composed of the list of its member instances.

<?xml version="1.0" encoding="utf-8"?>


<Caesam Version="2.0" xmlns="http://www.samcef.com/caesam/2.0">

<Instance Type="ARegisteredType">
<aMember Type="TheMemberType">
<!-- the member instance-->
</aMember>
</Instance>

In a Caesam XML file, it is possible to specify whether an object should be initialized with its corresponding
default values prior to setting its members to new values. By setting the "Initialize" attribute of an
<Instance> or a <member> tag, you can decide if an object should be initialized or not. Accepted values
are TRUE and FALSE.

Note: that not setting the “Initialize” attribute is equivalent to setting Initialize="FALSE".

<Instance Type="MyType">
<MyMember Type="MyMemberType" Initialize="TRUE">
</Instance>

page-133
Caesam SDK | 14 Persistency

XML representation of different object types defined in Caesam

Primitives Any object that inherits from Caesam_Primitive, which requires the implementation of two
abstract methods ToString and FromString, can be represented as a simple string so there are no delimiting
tags between values. Examples of primitive classes: Caesam_Integer, Caesam_Double or the arrays of
primitives like Caesam_IntegerArray or Caesam_DoubleArray.
Examples of primitives XML instances:

<Instance Type="Caesam_String">a string</Instance>


<Instance Type="Caesam_StringArray">"a string";"another string"</Instance>
<Instance Type="Caesam_Double">25.3</Instance>
<Instance Type="Caesam_DoubleArray">22.3;15.1</Instance>

Object arrays In XML, object arrays are represented as a collection of <Item> tags, which have a Type
attribute and optionally an Index attribute:

<Instance Type="Caesam_ObjectArray">
<Item Index="2" Type="Caesam_String">a value2</Item>
<Item Index="1" Type="Caesam_String">a value1</Item>
</Instance>

Object maps A map represents a collection of <Key, Value> pairs. For maps derived from
Caesam_PrimitiveObjectMap (maps that have keys of primitive types) these pairs are represented as
<Item> tags, which have a Key and a Type attributes:

<Instance Type="Caesam_StringObjectMap">
<Item Key="akey1" Type="Caesam_String">a value1</Item>
<Item Key="akey2" Type="Caesam_String">a value2</Item>
</Instance>

XML representation of different object types defined in Caesam

Identifiers When saved using the Caesam API, persisted Caesam objects have unique identifiers assigned.
Their role is to identify individual objects in the file’s scope. Objects identifiers are expressed using the
“Id” attribute in the xml files. Their values are not retained between successive Load/Save operations of
the same xml file. For this reason it is not possible to rely on the Ids to reference Caesam objects from
external locations. Moreover, these identifiers are guaranteed to be unique in the document’s scope but
not globally.

<Instance Id="#100" Type="Caesam_String">a string</Instance>

References The persistence module resolves object references in the following manner: it checks whether
an object has already been stored in the current file and if it was, the persistence driver stores a reference
to it. Inside an XML Caesam_Object instance, references are defined by the “Reference” attribute.
In the following example we have added an item to a map, which simply points to the previously defined
object having the id “#100”:

<Instance Type="Caesam_StringObjectMap">
<Item Reference="#100" Key="akey1" Type="Caesam_String" />
<Item Key="akey2" Type="Caesam_String">a value2</Item>
</Instance>

External references An external reference refers to defining a pointer to an object stored in a different
file (other than current one). In a future version of Caesam, the IDs, which for now are the hexadecimal
representation of the object’s addresses in memory, may be replaced with GUIDs (Global Unique
Identifiers) whose values are permanent (i.e. they do not change from one instance to another). This will
open the possibility of referencing an individual object from and external XML file such as :
file:csmroot/CaesamModel.xml?Id=5431c0-2a902d-7c0002-2388d9

page-134
14 Persistency | Caesam SDK

14.2.2 The SQL database persistence driver


Starting with version 4.1 Caesam offers a a mechism to store the objects of the model into a relational
database. By setting the preference “Persistency/UseDatabaseForNewDocument” to TRUE when a new
document is created it will automatically be connected to a database.

Object / relational mapping

This defines mappings between Caesam classes and SQL tables, object members and table columns. This
is accomplished with a set of tables that can store objects in a generic manner.

The Object table contains one entry for each object of the model stored in the database.
• UUID : The UUID of the instance
• ClassName : The Caesam type (registered class) of the instance.
• ClassVersion : The version of the class
• MemberValue : This field contains the value of the object if it is of primitive type.
• InstanceFlags : The instance flags
The ObjectMembers table is used to store members, array and map items and their association with the
container object.
• ObjectContainerId : The UUID of the container object (the object to which the member or item
belongs)
• ObjectMemberIndex : This field contains the name of the member, the index in the array (for
Caesam_ObjectArray containers) or the item’s key (for Caesam_PrimitiveObjectMap, and
Caesam_ObjectObject map instances)
• IndexType : Identifies the type of the “member”. Possible values: “M”: the entry represents a
Caesam_Object member “K”: the entry denotes an array item or a map item
• MemberUUID : The identifier of the member instance
• ClassName : The type of the member instance.
• MemberFlags : Flags of the member
• SetOwner : Indicates that the container object (identified by ObjectContainerId) is the owner of the
member.
The ClassDescription table contains hierarchy of the the registered classes in Caesam.
• ClassName : The name of the class (it always corresponds to a registered class)
• HierarchyLevel : The position in the inheritance tree starting from the base type (the one that inherits
directly from Caesam_Object)
• SuperClassName : The name of the ancestor class
• :
The ClassMemberDescription table contains the list of members for each registered class.
• MemberName : The name of the member.
• ClassName : The class to which the member belongs.

page-135
Caesam SDK | 14 Persistency

Database views

Views are pre-defined queries which are stored in the database and that can be used to find objects on a
per type basis. The views columns correspond to object members. For container types (arrays and maps)
an additional view is defined ant its name is composed of the name of the type and the “_Items” suffix
(e.g. Caesam_ObjectArray_Items).
The views are a simpler way to retrieve data when the type of the searched object is known.

14.2.3 Registering persistence drivers


The registration of a driver is performed in the body of the initialize function of a plug-in, by utilizing
the Caesam_Persistence API and consists in associating a protocol identifier with a driver class.
As an example:

extern "C"{
STL_EXPORT void initialize(Caesam_Registry *theRegistry,
Caesam_Persistence *thePersistenceManager){
// First we register the class that inherits from Caesam_Driver
Caesam_CsmDriver::Register(theRegistry);
// Register the persistence driver for the “file” protocol
thePersistence->RegisterDriver("file", "Caesam_CsmDriver");
}

When asked to load or to save an instance, the persistence manager will look at the protocol specified in
the URL, locate the appropriate driver for it and forward the URL to driver’s Load method.
In the following example LoadObject will use Caesam_CsmDriver for reading the specified csm file.

PTRMEM(Caesam_Application) aApp = Caesam_Application::GetApplication();


PTRMEM(Caesam_Object) aLoadedInstance = aApp->LoadObject
("file:/tmp/anXmlFile.csm");

14.3 Type versioning


Caesam data types evolve in time; they can undergo modifications like adding a new member, renaming
or removing a member, replacing a method etc.
As objects can be persisted into files, Caesam must be able to load files containing instances of previous
versions of a type.
Data type evolution is achieved in Caesam by implementing a method for translating one type into another.
This method will be called every time an old version instance needs to be converted to a new type instance
(one such case is loading Caesam files that use old versions of a type). If a type has a Translate method,
LoadObject will create an object of the old type and will return the instance returned by the Translate
method.
Currently Caesam offers two systems for assuring compatibility with previous type declarations.

14.3.1 Compatibility through class, member and method obsoletion


Sometimes a member, a method or an entire class are no longer needed. Instead of removing them, the
OBSOLETE flag should be used. Currently we can specify OBSOLETE flags for classes, members and
methods.

page-136
14 Persistency | Caesam SDK

Obsolete classes

An obsolete class cannot be used (instantiated) in Caesam anymore. Usually an obsolete class provides
a translate method, in which case Caesam will convert an instance of the old version of type to an instance
of the new version.
Example:

<TypeDesc Name="Class1" Inherits="Caesam_Object"


ClassFlags=”OBSOLETE”/>
<Member Name="myInteger" Type="Caesam_Integer" />
<Member Name="myQuantity" Type="Caesam_Quantity" />
</TypeDesc>

Obsolete members and methods

In the following example we remove the member Caesam_Integer:myInteger (set the obsolete flag) from
the class declaration and we add the member Caesam_String:myString.

<TypeDesc Name="Class1" Inherits="Caesam_Object">


<Member Name="myInteger" Type="Caesam_Integer"
MemberFlags=”OBSOLETE”/>
<Member Name="myString" Type="Caesam_String" />
<Member Name="myQuantity" Type="Caesam_Quantity" />
<Method Name="myMethod" Type="Python" Location=”python/test”
MethodFlags=”OBSOLETE” />
</TypeDesc>

Note: Starting with version 4.2.1 of Caesam, adding or removing a member from a class
does not require a Translate method or the OBSOLETE flag. As long as existing members
are not altered, Caesam will be able to load an old instance file.

14.3.2 Compatibility through the Translate method


Caesam offers the possibility to translate an obsolete type into a new type by the implementation of a
"Translate" method. The new class can have a different name from the old class or it can preserve the
same name and assign a version number to it.

Class naming

1. The new class has a different name from the class it obsoletes. Example: MyClass becomes
MyNewClass
2. The class name can be preserved (Caesam 3.0.2 and higher) but a version must be specified in the
declaration of the class by appending ‘#’ followed by an integer value to the name of the class.
Example: MyClass#0 becomes MyClass#1
When using class versioning there are several assumptions that need to be taken into account.

Declaration (Typedesc files, RegisterClass)

If the version is omitted from the type name in a member declaration omit, the last version of the class is
assumed. In other words, you are not forced to change member declarations when the new type obsoletes
the member’s type if it preserves its name. In the following example we have AClass declaration that has

page-137
Caesam SDK | 14 Persistency

aMember of type MyVersionedClass. Since a version is not explicitly specified MyVersionedClass#1 is


assumed.

<TypeDesc Name="MyVersionedClass#0" ClassFlags="OBSOLETE">


<Member Name="myInteger" Type="Caesam_Integer" />
<Translate Name="MyVersionedClass0To1" Type="Java"
Location="com.samcef.caesam.test.translate/MyTranslations"/>
</TypeDesc>

<TypeDesc Name="MyVersionedClass#1">
<Member Name="myString" Type="Caesam_String" />
</TypeDesc>

<TypeDesc Name="AClass" >


<Member Name="aMember" Type=" MyVersionedClass " />
</TypeDesc>

Class version when using Caesam_Application::NewObject

With NewObject you can use the class name (MyClass in this case) without the version number. If the
version number is not specified, the latest (non-obsolete) version of the type is assumed.

Note: that the "standard" NewObject method cannot be used to create an instance of an
obsolete type.

Caesam_Application::NewObject
(const STL_String& theClassName,
PTRARG(Caesam_Object) theArgument)

will raise an error if the type specified by theClassName is obsolete.


In some special cases, like within the implementation body of a Translate method, it may be necessary
to be able to instantiate an obsolete type. This can be accomplished by setting theAllowObsolete flag of
the NewObject method to true.

Caesam_Application::NewObject
( const STL_String& theClassName,
PTRARG(Caesam_Object) theArgument,
Standard_Boolean theAllowObsolete)

Class versions in instance files

In instance files the version of the class should always be specified. If missing, version ‘#0’ is assumed.

Adding OBSOLETE flags and Translate methods in Typedesc file


Define the translate method that converts from version 0 to version 1 of MyVersionedClass
(MyVersionedClass#0 => MyVersionedClass#1). This method is implemented in the MyTranslations
java class.
The version of a class is specified as an integer number after the # sign <TypeDesc
Name="MyVersionedClass#0" ClassFlags="OBSOLETE">

<Member Name="myInteger" Type="Caesam_Integer" />


<Translate Name="MyVersionedClass0To1" Type="Java"

page-138
14 Persistency | Caesam SDK

Location="com.samcef.caesam.test.translate/MyTranslations"/>
</TypeDesc>

<TypeDesc Name="MyVersionedClass#1">
<Member Name="myString" Type="Caesam_String" />
</TypeDesc>

Implementing the Translate method (C++, Python, Java)

public class MyTranslations {

static Caesam_Object MyVersionedClass0To1 (Caesam_Object


theMyClass0Instance, Caesam_Object theArgument){
System.out.println("--------------------------
MyTranslations::MyVersionedClass0To1---------------------------");
if(theMyClass0Instance == null){
return null;
}
Caesam_Object aMyClass1Instance = null;
try {
CaesamAPI_Application.Start();
Caesam_Application aApp = Caesam_Application.GetApplication();

// we create an instance of the new type


aMyClass1Instance = aApp.NewObject("MyClass#1",
new Caesam_String(""),true);
// We could also have written: aApp.NewObject("MyClass") because
a class name without version is interpreted as the non-obsolete
version
of the class
// we convert the member myInteger to myString
Caesam_Object aIntegerObject =
theMyClass0Instance.GetMember("myInteger");
if(aIntegerObject != null){
Caesam_Integer aMyInteger =
Caesam_Integer.Cast(aIntegerObject);
Caesam_String aMyString = new
Caesam_String(aMyInteger.ToString());
aMyClass1Instance.SetMember("myString", aMyString);
}
}catch (Exception theException) {
theException.printStackTrace();
}
// return the new type instance
return aMyClass1Instance;
}
}

14.4 Universally Unique Identifiers


(UUIDs) Instances must have unique identifiers for different reasons:
• For comparing objects that come from different sources (split/merge operations)
• For referencing objects located in external files via queries stored in Caesam_Url.
UUIDs are used for managing data transfers between Caesam and remote processes and for identifying
objects in external repositories.
The allocation of UUID to CaesamStd_Item objects

page-139
Caesam SDK | 14 Persistency

Caesam_Object

By default the UUID member of the Caesam_Object is NULL, but it can be set with a value obtained via
the provided generator. Example:

Handle(Caesam_Object) aObject = new Caesam_Quantity();


aObject->SetUUID(Caesam_UUID::Generate());

When an item is cloned, the cloned item will get a different UUID.

CaesamStd_Item

Each CaesamStd_Item has a UUID field that is always initialized. This member is flagged as
READ_ONLY, therefore once allocated it cannot be changed. In order to allow a SetMember(“UUID”)
you must call aStdItem->UseFlags(Standard_False).
The UUID of a CaesamStd_Item is generated in the constructor (NewInstance). When loaded from a file
the UUID field of the object will be set to the saved value.

CaesamStd_Model

UUIDs are now used as keys for items in the model.

14.5 CAESAM Resource Locators


An URL identifies a resource and provides a means of locating the resource by describing its primary
access mechanism
Caesam can deal with absolute and relative URLs (those which point to arbitrary locations unknown by
Caesam) and context based URLs which identify resources that are known and can be managed by Caesam.
As a general rule Caesam developers should always use context based URLs for storing resource locations
and should avoid manipulating absolute paths in the code, configuration files or persisted instances. The
Caesam SDK offers several classes (such as Caesam_Url and Caesam_CsmContext) for manipulating
resources.

14.6 Caesam URL Contexts


A Caesam URL context can be seen as a shortcut to a resource location, which once defined can be used
in the definition of other resource locations relative to it. In order to be treated as contexts, these shortcuts
must be prefixed by the “csm:” protocol. In the following example: csm:caesamroot/test/ the
“csm:caesamroot” string is considered as a context.
Caesam contexts are pairs of keys and absolute URLs and these pairs can be stored in several different
maps. According to the scope of these maps they can be classified as:
• Global or Application contexts map (there is only one map defined per application instance)
• Model contexts map (one context map per model or per open document)
• User defined context maps (can be as many as needed, but should be avoided when the mechanism is
not completely understood)

14.6.1 Application (global) context map


The application map is a static list of predefined contexts, which is initialized at the application start-up.
Most of the hard-coded contexts correspond to some environment variables that are set in the initialization
script of Caesam. The global context map can be used anywhere in the application since it can be retrieved
via the method Caesam_Application::GetCsmContext().
The table below lists the predefined URL contexts of Caesam.

page-140
14 Persistency | Caesam SDK

CsmContext Description

csm:caesamroot/ root directory of the application

csm:caesamhome/ home directory of the Caesam application

csm:userhome/ user's home directory (the value defined in the environment variable
called 'USER_HOME')

csm:caesamtemp/ which contains the value of the environment variable called 'TMPDIR'

Apart from these values, the global map also contains the <plugin.name, plugin.URL> pairs of all the
loaded plugins. This allows the use of a "shortcut" to a plugin's directory.
Example : csm:com.samcef.caesam.test/ will map the absolute path

/c:/CAESAM/examples/plugins/com.samcef.caesam.test/

Tip: We strongly recommend using the csm:pluginname context every time a subdirectory
of a plug-in folder needs to be referenced. In this way, the URL will be correctly resolved
even if the plug-in location changes at any given moment (it may be moved to another
folder).

Declaring global contexts

In order to add new global contexts or redefine existing ones, you can either use the CsmContext tag in
the plugin.xml descriptor or to use the Caesam_CsmContext API as shown in the following example:

PTRMEM(Caesam_CsmContext) aAppContext = Caesam_Application::


GetCsmContext();
if(!aAppContext->HasContext("mycontext")){
aAppContext->SetContext("mycontext", new
Caesam_Url("file:/temp/"));
}
PTRMEM(Caesam_Url) anAbsoluteUrl = aAppContext->Resolve(new
Caesam_Url("csm:mycontext/test/"));
cout << "Resolve(csm:mycontext/test/)=" << anAbsoluteUrl->ToString()
<< endl;
// will print Resolve(csm:mycontext/test/)=file:/temp/test/

Using global contexts – Resolving “relative” URLs

Caesam offers two classes for dealing with context-based URLs: CsmContext and Caesam_Url
The purpose of CsmContext is to keep a map of contexts to absolute paths and to translate URLs that
contain contexts in absolute paths. The CsmContext class has a method called “Resolve” for converting
a “relative” (a URL with context) into an absolute one and a method called “Unresolve” for converting
an absolute URL to a context-based one.

Note: that these methods resolve URLs that use global contexts only and not document
(or model) related context and they should be used with care.

page-141
Caesam SDK | 14 Persistency

A better alternative is to use the CaesamAPI_Object::Resolve and CaesamAPI_Object::Resolve methods


(see Model context map on page 142 for more information).

Resolve( theUnresolvedUrl: Url from Caesam)


returns Url from Caesam;
---Purpose: Resolve a "csm:" url.
-- This method will replace the context with the corresponding
-- absolute path. Resolve will compare each registered context
-- (via the SetContext method) with the beginning of the URL's path.
-- As soon as a match is found it will return a new URL having the
context
-- replaced with the real path.
---Example: csm:caesamroot/apath/afile will be replaced with
/c:/caesam/apath/afile
Unresolve(theAbsoluteUrl: Url from Caesam)
returns Url from Caesam;
---Purpose: Unresolve an absolute (resolved) URL like "file:/path/"
into a "csm:" url that contains a context. Note that if there are
overlapping paths (two or more contexts partially map the same path)
the longest path that matches will be used.

Example
Suppose that the caesamroot is mapped to the directory "file:/c:/caesam/".
Create a new URL that contains an absolute path:

Handle(Caesam_Url) aAbsolutePath = new


Caesam_Url(“file:/c:/caesam/apath/afile.txt”);

Now call the unresolved method on the created Url and print the result

Handle(Caesam_Url) aRelativeUrl =
Caesam_Url::Unresolve(aAbsoluteUrl);

The resulting URL will contain: "csm:caesamroot/apath/afile.txt"


These two methods can be found in Caesam_Url, which are the equivalent to writing

Caesam_Application::GetCsmContext()->Resolve(theCsmUrl)

and

Caesam_Application::GetCsmContext()->Unresolve(theAbsoluteUrl)

respectively.
Although usually the model’s context map is used since it contains all the predefined contexts, it is
possible to create and use several instances of the Caesam_CsmContext. Refer to User defined
context maps on page 143 for further information.

14.6.2 Model context map


Because documents have their own working folders, every open Caesam document (or model) has its
own map of contexts. At the initialization of the model, its map of contexts is populated with the global
contexts first and then with the contexts owned by the document (see the table below). In this way the
Resolve and Unresolved methods of the CaesamAPI_Model class can be used to resolve global contexts
also.

page-142
14 Persistency | Caesam SDK

Table 11: Model related context variables

CsmContext Description

csm:document/ directory of the current opened document

csm:documenttmp/ temporary directory associated with the opened


document

csm:documentexternalfiles/ directory to store external file which depend of the


model

The CaesamAPI_Model context related methods

Resolve(me: mutable; theUnresolvedUrl: Url from Caesam)


returns Url from Caesam;
---Purpose: Resolve a "csm:" url.

This method will replace the context with the corresponding absolute path. This method resolves model
contexts as well as global ones.

Example
csm:caesam_root/apath/afile will be replaced with /c:/caesam/apath/afile

Unresolve(me: mutable; theResolvedUrl: Url from Caesam) returns Url


from Caesam;
---Purpose: Unresolve an absolute URL like "file:/path/" into a "csm:"
url.
---This method unresolves model contexts as well as global ones.

Example: /c:/caesam/apath/afile will be replaced with csm:caesam_root/apath/afile

14.6.3 User defined context maps


As mentioned before, an unlimited number of Caesam_CsmContext instances can be created. Remember
that a Caesam_CsmContext represents a storage map of <context, absolute urls>. This means that a user
can create his own map of contexts, completely independently of the application map or the model map,
and then use it to resolve or unresolve specific URLs.
Note that when a fresh new instance of CsmContext is created, it does not contain any URL, it is up to
the developer to add his own context / path pairs either by using the CsmContext API or by loading a
persisted instance of CsmContext.

Environment variables in URL contexts

It is possible to use environment variables in all Caesam URLs. These variables are replaced by their
content in the method Caesam_CsmContext::Resolve. You can thus also define Caesam contexts in terms
of an environment variable.
Variables can be delimited with {} in cases where the end of the variable name is an ambiguous:
file:{$CAESAM_PLUGIN_PATH}SomeDirectory/SomeFile.ext.
For completeness, it is also possible to have an indirection level greater than 1. The following URL will
be the equivalent to the previous one if the variable MYVAR is defined as "CAESAM_PLUGIN_PATH":
file:{$$MYVAR}SomeDir/SomeFile.ext.

page-143
Caesam SDK | 14 Persistency

Caesam_CsmContext methods

SetContext(thecontext: String from STL;


thePath: Url from Caesam);
---Purpose: Set a <context, path> pair in the internal map

GetContext( thecontext: String from STL)


returns Url from Caesam;
---Purpose: Get a <context> from the internal map

HasContext( thecontext: String from STL)


returns Boolean from Standard;
---Purpose: Returns true if <theContext> is defined the internal
map

GetContextMap()
returns TypedMap from Caesam;
---Purpose: Returns the internal map containing the context/url pairs

Resolve( theUnresolvedUrl: Url from Caesam)


returns Url from Caesam;

Unresolve(theAbsoluteUrl: Url from Caesam)


returns Url from Caesam;

Loading a persisted Caesam_CsmContext map

The file MyCsmContexts.csm contains

<Instance Type="Caesam_CsmContext">
<ContextMap Type="Caesam_TypedMap">
<Type Type="Caesam_String">Caesam_Url</Type>
<Item Key="mytemp" Type="Caesam_Url">file:/c/temp/</Item>
<Item Key="mydir" Type="Caesam_Url">csm:mytemp/test/</Item>
</ContextMap>
</Instance>

// Load the context map


Handle(Caesam_Object) aCsmContextObject =
LoadObject("csm:com.samcef.caesam.plugin/resources/MyCsmContexts.csm");

Handle(Caesam_CsmContext) myCsmContext =
Handle(Caesam_CsmContext)::DownCast(aCsmContextObject);
// Create a new relative url
Handle(Caesam_Url) aRelativeUrl =
new Caesam_Url("csm:mydir/myfile.txt");
// Resolve the relative url
Handle(Caesam_Url) aAbsoluteUrl =
myCsmContext->Resolve(aRelativeUrl);
//The aAbsoluteUrl will contain file:/c/temp/test/myfile.txt

14.7 The CZM document


Caesam saves its model in a .czm file which is an zip archive that can contain:

page-144
14 Persistency | Caesam SDK

• An XML (or sqlite) file representing the CaesamStd_Model


• User files that were attached to model items

14.7.1 Model items can have file resources


Each CaesamStd_Item can have a file (or directory) resource attached to it.
This resource is defined by a URL that points to a location (preferably relative to a Caesam context) and
it benefits from two features:
• The resource of an item is deleted when the item is removed from the model. This is the default
behaviour implemented by the BeforeRemove virtual method, which can be overriden. See
CaesamStd_Item::SetFileResource, GetFileResource and BeforeRemove
• If the resource URL begins with a CZM context (like csm:documentczm) the file will automatically
added to the document .czm and the package .czp archives.

14.7.2 Adding user files to the CZM


The author can add his own files and directories to the model CZM and the package CZP archives by
setting the file resource of a CaesamStd_Item with an URL that points to a directory located in a CZM
context.
As for version 4.1 of Caesam the only CZM context available is csm:documentczm which is a folder
inside the temporary folder of the current document.
When saving the model, Caesam will automatically include the file directory at that location into the CZM
document. When opening a CZM file Caesam will extract the user files to the specified directory.

page-145
Caesam SDK | 15 Engineering Objects

15 Engineering Objects
This section describes the concepts relating to Engineering Object.
The Caesam SDK libraries provide a set of predefined EO available to authors. The Caesam framework
is aware of the following set of EOs, which it is able to manage, display and edit. All these objects inherit
from CaesamStd_EO and can be stored in the CaesamStd_DataSet container used in operations.

15.1 Global FEM Management


These objects relate to the management of the Global FEM

CaesamStd_GFEM (cxx)

This object inherits from CaesamStd_Topology. It contains the description of the topology of the FEM
Mesh (Nodes and elements). It is used to manage the Global FEM of a stress model. The object must be
assigned to the CP CaesamStd_GlobalModel. Only one object is allowed in any one document.
The main methods are:
• AddNode(Id,X,Y,Z)
• AddLine(Id, Node1, Node2)
• AddTria(Id, Node1, Node2, Node3)
• AddQuad(Id, Node1, Node2, Node3, Node4)
• GetElements(): returns ObjectArray
• GetNodes(theElemId): returns the list of nodes for the specified element.
For more methods, refer to the cdl documentation available from the Help menu in the user interface.

CaesamStd_Location (cxx)

This object is obsolete. It was used to make the link between SE and the list of FEM Elements used by
this SE. It has been replaced by CaesamEO_FEMLink.

CaesamEO_FEMLink (cxx)

This object inherits from CaesamStd_EO. It is used to describe the small mesh, which is behind the SE.
The main methods are:
• AddElement(theCaesamStd_Element)
• GetElements() returns ArrayOfCaesamStd_Element
• GetElement(theElementID) returns CaesamStd_Element
##See chapter “FEM Model Access”, section “FEM Related EOs” for details on this EO. ##

CaesamEO_ByElementBySE (cxx)

This object inherits from CaesamStd_EO. It is used to associate one EO of a specific type with each FEM
element linked to the SE. For example, it can be used to associate a composite stacking sequence for each
element of the FEM mesh used by the SE. The relation with the mesh is made using a CaesamEO_FEMLink
object (see section 10.1.3. “CaesamEO_FEMLink” above.) The main methods are:
• SetFEMLink(theCaesamEO_FEMLink)
• SetEOType(theEOType)
• SetEO(theElementID, theCaesamStd_EO) : associate a EO to a specific element.
• SetEOForAllElement(theCaesamStd_EO) : Associate the same EO to all elements
• GetEO(theElementId) returns CaesamStd_EO
##See chapter “FEM Model Access”, section “FEM Related EOs” for details on this EO.

page-146
15 Engineering Objects | Caesam SDK

CaesamEO_GlobalFEMModel (cxx)

This object inherits from CaesamStd_EO. It describes the main FEM result file (OP2 Nastran or Samcef
SFR) which contains the mesh description (nodes and elements). This object must be assigned to the
unique CP CaesamStd_Global. It is used by Caesam to optimize access to FEM Result files (OP2, SFR)
associated with load cases.
This object also describes the units system used by FEM result files. The main methods are:
• SetDataFile(theCaesam_File)
• SetUnitSystem(theCaesam_UnitSystem)
• GetCaesamFEMModel(theCsmContext): returns Model from CaesamFEM
For more methods, refer to the cdl documentation available from the Help menu in the user interface.
(CaesamEO_GlobalFEMModel.cdl)

CaesamEO_BDFBuilder

This object allows the creation of a Bulk Data File (bdf) from a main model (BDF) and loading case BDF.
The main methods are:
• SetMergedFilePath(theMergedFilePath): defines the merged BDF file.
• SetGFEMFile(GFEMFile): defines the main (Model) BDF file.
For more methods, refer to the cdl documentation available from the Help menu in the user interface.

15.2 Topology
These objects manage the representation of the topology of the Stress Model. Some tools are also available
in order to manage the GFEM.

CaesamTopology_Element

This object inherits from the class CaesamTopology. It defines an FEM Element defined by an ID, a type,
and an Array of nodes. The main methods are:
• NewQuad(Id, Node1,Node2,Node3,Node4), NewTria(Id, Node1, Node2, Node3): creates a quadrangle
or a triangle element defined by 4 or 3 nodes
• SetNumber(Id): sets the Id of the Element
• GetNodes(): returns the array of CaesamTopology_Node composing the element
• GetNodeNumbers(): returns the node numbers composing the element.
For more methods, refer to the cdl documentation available from the Help menu in the user interface.

CaesamTopology_Node

This object inherits from class CaesamTopology. It defines a FEM Node defined by a ID, X, Y Z. The
main methods are:
• SetNumber(Id): sets the number of the node
• SetCoord(X, Y, Z): sets the coordinate of the node by the values given.
• GetCoord(): returns the coordinate of the node in Caesam_DoubleArray form.
For more methods, refer to the cdl documentation available from the Help menu in the user interface.

CaesamTopology_Mesh

This object inherits from CaesamTopology. It is the basic class to manage a mesh (Nodes, Elements).
The main methods are:
For the Nodes
• AddNodes(theNodes): adds a list of Nodes. If the node already exists (same number), it is replaced.
The argument (theNodes) is a Caesam_ObjectArray of CaesamTopology_Node
• GetNodesNumbers(): returns the list of all CaesamTopology_Node Numbers.
For the Element

page-147
Caesam SDK | 15 Engineering Objects

• AddElement(Element): adds an element in the Mesh. The argument (Element) is a


CaesamTopology_Element
• AddLine(Id, Node1, Node2): adds an element in the Mesh.
• AddTria(Id, Node1, Node2, Node3): adds an element in the Mesh.
• AddQuad(Id, Node1,Node2, Node3,Node4): adds an element in the Mesh. Returns an Element from
CaesamTopology
For more methods, refer to the cdl documentation available from the Help menu in the user interface.

CaesamTopology_Location

This object inherits from CaesamTopology. It finds the position of the SE in the GFEM or in the SE
Topology. The main methods are:
• Create() : Create the CaesamTopology_Location
• Add(Shape):

15.3 Geometry
EOs relating to geometry

CaesamStd_SETopology (cxx)

This object inherits from CaesamStd_EO. It contains the description of the topology of the structural
elements SE(nodes and elements). In version 4.1.1, an SE can only be represented by a line, a triangle or
a quadrangle. A more realistic representation of SE can achieved using a Display Driver.
The CaesamStd_SETopology must be assigned to the CP CaesamStd_GlobalModel. Only one can be
document.
Main methods are:
• AddNode(Id,X,Y,Z) • AddLine(Id, Node1, Node2)
• AddTria(Id, Node1, Node2, Node3)
• AddQuad(Id, Node1, Node2, Node3, Node4)
For more methods, refer to the cdl documentation available from the Help menu in the user interface.

CaesamEO_CoordSystem (cxx)

This class inherits from CaesamStd_EO. It describes a right-handed coordinate system in 3D space. It
may be used to define coordinates in a local system. A coordinate system is defined by:
• Its origin (also referred to as its "Location point"),
• Two orthogonal unit vectors, termed respectively the "X Direction" (also referred to as the "main
Direction"), and the "Y Direction".
The third unit vector, "Z Direction" is always equal to the cross product of its "X Direction" and "Y
Direction". Whenever "main Direction" is modified, the "Y Direction" and the "Z Direction" are
recomputed. However, when either the "Y Direction" or the "Z Direction" is modified the "main Direction"
is not modified.
The main methods are:
• SetLocation(X, Y, Z): changes the "Location" of the point (origin)
• SetXDirection(theDir): sets the X Direction
• GetTransformation(): returns the 3D-displacement transformation defined by this coordinate system
and the Global coordinate system (when this system is defined).
• Transform(thePX,thePY,thePZ, theTargetCoordSystem): displaces the Point (thePx, thePY, thePZ)
defined in the axis system into the axis system defined by the TargetCoordSystem.
Rotate methods are also available that operate similarly. For more methods, refer to the cdl documentation
available from the Help menu in the user interface.

page-148
15 Engineering Objects | Caesam SDK

CaesamEO_Direction

This class inherits from CaesamStd_EO. It describes a direction in 3D space. It has a member Direction,
which is a DoubleArray with three coordinates. The main methods are:
• SetDirection(X,Y,Z)
• GetDirection(): returns a Caesam_DoubleArray

15.4 Load Case Management


Caesam provides a set of classes to manage load cases. A number of different type of load cases inherits
from the class CaesamStd_LoadCase and there is a class to store a selection of load cases. A load case
can be related to a FEM result described in a OP2 from Nastran or in an SFR from Samcef. External loads
will be retrieved using information found in these objects.

CaesamStd_LoadCase (cxx)

This is the basic class of all type of load cases. It is a deferred class. A state can be associated with each
load case (NotComputed, ComputedUpToDate, ComputedOutOfDate, ComputedWithErrors) The main
methods are:
• SetState(theState): sets the state using one do the strings given above.
• GetState() : returns a string corresponding to the state.

CaesamLC_UnitaryLoadCase

This class inherits from the deferred class CaesamLC_ComputedLoadCase . It associates a result file
(OP2 or SFR) with a load case. The computed file is the result of only one type of Load (Thermal, Pressure,
Mechanical ...). This class defines:
• The FEM result file (OP2 or SFR)
• The FEM Load case ID in the result file
• The FEM data file which describes this load case (BDF or Samcef Bank)
• The physical type of load case (MECHANICAL, THERMAL, PRESSURE, FUEL).
The main methods are:
• GetResultFile(): returns a Caesam_File
• GetLoadCaseId(): returns an Integer
• GetDataFile(): returns a Caesam_File
• GetPhysic(): returns String corresponding to the physical load type.
For more methods, refer to the cdl documentation available from the Help menu in the user interface.

CaesamLC_RealLoadCase

This class inherits from the deferred class CaesamLC_ComputedLoadCase. A real load case is a load
case which is the result of a real study. It is a combination of unitary loads. The thermal and pressure
loads are already computed in their own CaesamLC_UnitaryLoadCase.
The mechanical part can be retrieved if the program subtracts the thermal and pressure parts. This class
defines:
• The FEM result file of the real load case(OP2 or SFR)
• The FEM Load case ID in the result file
• The FEM data file which describes this load case (BDF or Samcef Bank)
• The thermal load case and the used coefficient
• The pressure load case and the used coefficient
Main methods are:
• GetResultFile(): returns a Caesam_File
• GetLoadCaseId(): returns an Integer
• GetDataFile(): returns a Caesam_File
• GetThermalLC(): returns CaesamLC_UnitaryLoadCase

page-149
Caesam SDK | 15 Engineering Objects

• GetThermalCoeff(): returns Real


• GetPressureLC(): returns a CaesamLC_UnitaryLoadCase
• GetPressureCoeff(): returns Real

CaesamLC_CombinedLoadCase

This class inherits from the deferred class CaesamLC_ComputedLoadCase. It describes a linear combination
of load cases and its factors. Combined load cases accept any type of CaesamStd_LoadCase. The main
methods are:
• Append(theCaesamStd_LoadCase, theFactor) • GetLoadCase(Index): returns the load case corresponding
to the index For more methods, refer to the cdl documentation available from the Help menu in the user
interface.

CaesamStd_LoadCaseSet

This class inherits from CaesamStd_EOArray .This class contains a list of selected load cases used by an
analysis. The main Methods are:
• Append(theCaesamStd_LoadCase)
• Size(): returns an Integer corresponding to the number of load cases
• GetLoadCase(theIndex): returns CaesamStd_LoadCase
For more methods, refer to the cdl documentation available from the Help menu in the user interface.

Tools

The following classes are tools to manage load cases


CaesamLC_LoadCaseExplorers
This class allows the creation of an iterator on all CaesamLC_ComputedLoadCase from any type of load
cases (combined or not). The main methods are:
• More(): returns a Boolean
• Next():
• GetLoadCase(): returns CaesamLC_ComputedLoadCase
• GetFactor(): returns Real
For more methods, refer to the cdl documentation available from the Help menu in the user interface.
CaesamFEM_StaticAnalysis
This class inherits from the CaesamFEM_model. It allows access to Static Analysis. It can read the fluxes
and forces from a CaesamStd_LoadCase for a given element. The results are returned in a
Caesam_QuantityArray. In version 4.1.1, this class works for FEM Result of type OP2 (Nastran result
file). The main methods are:
• GetElem2DMatCoordTheta(ElemId): returns the angle between the element coordinate and the material
coordinate for 2D element
• GetElem2DFluxInElemCoord (thePhysics, ElemId, FiberSurface, The LoadCase): returns the stresses
on a non-composite 2D element. Stress tensor components are not rotated in some axes systems: values
are returned as loaded from result file (mostly, they are in element local axes). This returns the total
values for a specific type of LoadCase matching the given physical load type, or for all physical load
typs if thePhysics == "".
• GetElem2DFluxInElemCoord(ElemId): shorcut to GetElem2DFluxInElemCoord("", theElementID,
theLoadCase)
For more methods, refer to the cdl documentation available from the Help menu in the user interface.
CaesamFEM_OP2Descriptor.
This command enables you to retrieve CaseControl from an op2 file. This new command calls method
from the new class. This class is available to the author (C++/python/FORTRAN). An example of python
using this class can be found in
<caesam>/plugins/com.samcef.caesam.lc/python/CaesamLC_OP2ToUnitaryLC.py

page-150
15 Engineering Objects | Caesam SDK

15.5 FEM Solver Management

CaesamEO_SamcefAnalysis (xml)

This object is the EO that defines the input for a SAMCEF analysis. The main members are:
• BankFile : Caesam_Url
• Module: CaesamEnum_AnalysisType (LINEARSTATIC, MODAL, STEADYSTATETHERMAL,,
IMP:LICIT, ROTOR, SAMCEFRESULT, …)
• MeshBankName : Caesam_String : Input in the BankFile

CaesamEO_NastranAnalysis (xml)

This object is the EO that defines the input for a NASTRAN analysis. It defines all BDF files used (The
main + auxiliary files used to define load cases) and the solution name (ex: sol101) The main members
are:
• BDFFile : Caesam_Url
• auxBDFFiles : Caesam_ObjectArray (Array of Caesam_Url)
• Sol: Caesam_String

CaesamEO_SAMRESRequest

This EO is the EO that defines the input of the SAMRES program. It defines the list of requests. The main
members are:
• Requests : Caesam_TypedArray (Array of CaesamPrimitives_SAMRESRequest)
The main members of CaesamPrimitives_SAMRESRequest are:
• Request: Caesam_String : the samres request
• Rank : Caesam_String
• Dimension: CaesamEnum_Dimension (LENGTH, FORCE, PRESSURE, …)

CaesamEO_LogFileSolver (xml)

This class contains the logfile of the solver (SAMCEF or NASTRAN) The main member is:
• LogFile: Caesam_Url

15.6 Results Management


The following objects inherit from CaesamStd_Result.

CaesamStd_Result (cxx)

Abstract class of all type of results.

CaesamEO_SAMCEFResult (xml)

This class is generated by a SAMCEF Analysis. It contains the URL to the directory of SFR files The
main members are:
• Location : Caesam_File
• Module: CaesamEnum_AnalysisType (LINEARSTATIC, MODAL, STEADYSTATETHERMAL,
IMPLICIT, ROTOR, SAMCEFRESULT, …)

CaesamEO_SAMRESResult

This EO is the EO that defines the output of the SAMRES program. It defines the list of results. The main
Members are:

page-151
Caesam SDK | 15 Engineering Objects

• Results: Caesam_TypedArray (Array of CaesamPrimitives_Field)


• The main members of CaesamPrimitives_SAMRESField are:
• Support: Caesam_IntegerArray
• SupportType: CaesanEnum_FieldSupportType (Node, Element, ElementNode, ElementPly,
ElementNodePly)
Inherited classes from CaesamPrimitives_SAMRESField are:
• CaesamPrimitives_PointWiseScalarField Member: Value = Caesam_Quantity
• CaesamPrimitives_PointWiseVectorField Member: Value = Caesam_QuantityArray
• CaesamPrimitives_PointWiseTensor2DField Member: Value = Caesam_QuantityArray
• CaesamPrimitives_PointWiseTensor3DField Member: Value = Caesam_QuantityArray

CaesamEO_Plot (xml)

See the section Function Graphs on page 76.

CaesamEO_Report

See Reports on page 76.

CaesamEO_GlobalResultOp2

See the paragraph "Global results" in Reports on page 76 .

CaesamStd_LoadCaseTable (cxx)

1This class inherits from CaesamStd_EOArray . It contains a list of results defined by the class
CaesamEO_LoadCaseItem or derived for a set of CaesamStd_LoadCase. It is like a Map of results with
a load case as the key. The main methods are:
• SetLoadCaseItemType(theType) : Type of the class that inherits of CaesamEO_LoadCaseItem that
contains results associated to a load case
• Set(theCaesamStd_LoadCase, theMemberName in the CaesamEOLoadCaseItem, theValue)
• Get(theCaesamStd_LoadCase, theMemberName) returns theValue
For more methods, refer to the cdl documentation available from the Help menu in the user interface.

CaesamEO_LoadCaseItem

All classes used by CaesamStd_LoadCaseTable must inherit from this class. The item defined in this class
is displayed on the CaesamStd_LoadCaseTable. The item of type Caesam_Quantity is displayed in the
post-processing table when the analyst selects it.

15.7 Collections
These Collections are used to store EO but they also inherit from CaesamStd_EO. They can be saved
with the CaesamStd_DataSet.

CaesamStd_EOMatrix

This class inherits from CaesamStd_EO. It allows to store CaesamStd_EO in matrix form. The main
methods are:
• GetEO(RowId,ColumnId): Returns the Engineering Object associated to the Row and the Column.
• GetEOType(): returns the type of The EO stored in the CaesamStd_EOMatrix.
• SetEOType(EOtype): Set the type of the EO which will be stored in the the CaesamStd_EOMatrix
For more methods, refer to the cdl documentation available from the Help menu in the user interface.

page-152
15 Engineering Objects | Caesam SDK

CaesamStd_EOMap

This class inherits from Caesam_ObjectMap. It allows to store CaesamStd_EO in map form. Access to
the object stored in the structure is achieved by keys (String). The main methods are:
• Put (key, theEO): put the EO in the map referenced by the key.
• GetEO(key): retrieves the EO referenced by the key in the CaesamStd_EOMap
For more methods, refer to the cdl documentation available from the Help menu in the user interface.

CaesamStd_EOArray

This class inherits from CaesamStd_EO. It allows to store Eos in an Array. The main methods are:
• Append(EO): appends the EO to the Array
• AppendArray(EOArray): append the EOArray to the Array
• Set(EO, Index): sets the EO given in argument into the Array referenced by the index given.
• GetEOType(): returns the type of the EO stored in the Array.
For more methods, refer to the cdl documentation available from the Help menu in the user interface.

page-153
Caesam SDK | 16 Analysis definition

16 Analysis definition
The main aim of using Caesam is to perform a computation. These computations are achieved by running
an “Analysis”. These analyses can be written in C++, Java or Python. FORTRAN is available from C++
or Python. In this chapter we explain how to link the data model with some computation code using an
analysis. Then we will look at how to implement your own computation code.
To declare an analysis and make the link between this analysis and the Caesam data model, three things
must be done (a commented example is given for each):
• Declare a class inheriting from CaesamStd_DataSet: this dataset class will be defining the EO mapping
(input/output) between the stress data model and the analysis, and also the GUI used to view and edit
these EOs.
• Declare a class inheriting from CaesamStd_Operation: this class will be used to declare methods (eg.
callback methods such as BeforeRun, BeforeRemove etc.) and resources (such as editors). One particular
resource is the "process template".
• Associate a process template with this operation class: the process template makes the link between
the operation class and the dataset class. It also allows defining the following properties:
• the type of CP (Calculation Point) on which the analysis can operate
• the process task used when running the analysis
• the process task used when initializing the analysis (optional)
• the process directory used to store analysis files (optional)
• a property view management class (optional)
• associated files and computing resources (for the job mode)

16.1 Dataset declaration


The first step is to register a typedesc Caesam class inheriting from CaesamStd_DataSet. This class should
contain one member for each EO that can be placed in the analysis dataset. The name of the member will
become the dataset key. This key will be used in the process to access the EO.
IMPORTANT: The type of the member should be the allowed type of EO preceded by a *. This means
that the member is a Caesam reference: a dataset entry can indeed point to an EO directly (shared or
local) or to another dataset entry (ie. an EO on the support CP).
If the dataset entry is to be an array of EOs (typically if the EO support is an array of CP, eg. in a RibBay),
then the member must be declared as being of type Caesam_ReferenceArray, and its type specified (and
optionally its initial or fixed size too) in the default instance of the class (still in the typedesc).
A member resource called “DSAttributes” will be used to allow the specification of the following
dataset-specific attributes (all of which are optional):
Label: Path of the EO in the tree displayed in the property view, or "HIDDEN" (default is
"/").
ArgType: IN for input EOs, OUT for output EOs (default is IN). When the data relating to an
ouput EO first appears, it will be preceded by an icon that indicates that results must
first be computed.
SupportPaths: Path from the analysis to the EO's support (SE or SEA). By default, there is no
support, meaning that this EO is local to the analysis, typically some parameters of
this analyis. The "root" of this path is the operation. To reach an EO on the analysis'
CP, juste use "CP" as support path. To reach an EO on some underlying SE, you can
use a path such as "CP/CP[LeftPanel]" if the analysis' CP is e.g. a SuperStiffener
composed of two panels and one stringer. See below for more examples.

page-154
16 Analysis definition | Caesam SDK

EOPaths: Path to the EO on the support (default is no support). Typically, this path will be
*EO[<key>] where <key> is the key used to reference the EO in the SE or SEA's
dataset.
Slaves: List of dataset keys which depend on this one. Each time the EO for this dataset key
is modified or replaced, a method called "UpdateDependency" will be called for all
its slaves.

16.2 Dataset examples


The following example represents a typical Buckling analysis on a SuperStiffener with geometry and
material input EOs coming from the underlying SEs, and the load EO coming from the SEA. When the
stringer geometry is modified, we wish to call UpdateDependency on the left and right panel geometry
EOs. There is one local input EO (ie. without support) representing the load cases to apply. And finally
there are two output (and thus obviously local) result EOs.
<TypeDesc Name="BucklingSuperStiffener_DataSet"
Inherits="CaesamStd_DataSet">

<Member Name="LeftPanelGeometry" Type="*PanelGeometry">


<DSAttributes Label="Geometry/LeftPanel"
SupportPaths="CP/CP[LeftPanel]"
EOPaths="*EO[PanelGeometry]" />
</Member>

<Member Name="RightPanelGeometry" Type="*PanelGeometry">


<DSAttributes Label="Geometry/RightPanel"
SupportPaths="CP/CP[RightPanel]"
EOPaths="*EO[PanelGeometry]" />
</Member>

<Member Name="StringerGeometry" Type="*StringerGeometry">


<DSAttributes Label="Geometry/Stringer"
SupportPaths="CP/CP[Stringer]"
EOPaths="*EO[StringerGeometry]"
Slaves="LeftPanelGeometry;RightPanelGeometry" />
</Member>

<Member Name="LeftPanelMaterial" Type="*Material">


<DSAttributes Label="Material/LeftPanel"
SupportPaths="CP/CP[LeftPanel]"
EOPaths="*EO[Material]" />
</Member>

<Member Name="RightPanelMaterial" Type="*Material">


<DSAttributes Label="Material/RightPanel"
SupportPaths="CP/CP[RightPanel]"
EOPaths="*EO[Material]" />
</Member>

<Member Name="StringerMaterial" Type="*Material">


<DSAttributes Label="Material/Stringer"
SupportPaths="CP/CP[Stringer]"
EOPaths="*EO[Material]" />
</Member>

<Member Name="Load" Type="*Load">


<DSAttributes Label="Loads/Explicit Load"
SupportPaths="CP"
EOPaths="*EO[Load]" />
</Member>

<Member Name="LoadCaseSet" Type="*CaesamStd_LoadCaseSet">


<DSAttributes Label="Loads/LoadCases" />
</Member>

<Member Name="Result" Type="*Result">


<DSAttributes ArgType="OUT" Label="Results/Result" />
</Member>

page-155
Caesam SDK | 16 Analysis definition

<Member Name="TableResult" Type="*BucklingLoadCaseResult">


<DSAttributes ArgType="OUT"
Label="Results/TableResult" />
</Member>
</TypeDesc>

The following example is of an analysis operating on a HoledRibBay SEA. It shows how to declare an
array of EOs, with the type and size defined in the default instance of the class.
<TypeDesc Name="HoledRibBayBuckling_DataSet"
Inherits="CaesamStd_DataSet">

<Member Name="SuperstiffenerLoad" Type="Caesam_ReferenceArray">


<DSAttributes Label="Geometry/Stiffener"
SupportPaths="CP/CP[SS]"
EOPaths="*EO[Load]" />
</Member>

<Member Name="Load" Type="*Load">


<DSAttributes ArgType="OUT"
Label="Global Bay Buckling Load" />
</Member>

<Default Type="HoledRibBayBuckling_DataSet">
<SuperstiffenerLoad>
<Type>*Load</Type>
<VariableSize>0</VariableSize>
</SuperstiffenerLoad>
</Default>

</TypeDesc>

16.3 Analysis declaration


The second step is to declare a class, inheriting from CaesamStd_Operation, representing the analysis
itself. This class will typically be declared in the same typedesc file as the related dataset class. It is
recommended to have a distinct typedesc file for each analysis (containing one dataset class and one
operation class), though this is not mandatory.
A class resource named “ProcessTemplate” will be associated with this class. This process template
responsible for declaring:
• The name of the dataset class (declared as seen above)
• The type of CP on which the analysis can operate (a Structural Element Assembly (SEA) and an
Structural Element (SE) are a type of Calculation Point).
• The process directory used to store analysis files (attribute CsmMbr_ProcessDirectory).
If this attribute is defined in the template, then at the moment when an analysis is created, the program
will create a directory with the same name as the analysis in the location specified by the URL.
If the URL starts with csm:documentczm then the directory and its contents will be saved in the Caesam
czm session.
If the analysis is renamed, then the directory associated with that analysis is also renamed. If the
analysis is deleted, then the directory is deleted too.
In order to recover the name of the directory from an analysis you can use the method
GetProcessDirectory() on the object CaesamStd_DataSet. Example: PTRMEM(Caesam_Url)
anAnalysisUrl = theDataSet->GetProcessDirectory();
• The process task used when running the analysis. The process description is made from the name of
a registered process, the path to a python script or the full name of a Java class. See Process Registration
on page 167 for information on registering a process. An analysis process task must be of type "Analysis".
• The process task used when initializing the analysis (optional). The purpose of this process is to
initialize the DataSet; for example it allows you to assign dynamically computed default values to

page-156
16 Analysis definition | Caesam SDK

EOs. This initialization process is always executed on the local machine with the whole stress model
available; the analysis process on the other hand may be executed on a remote machine where only
the DataSet is available. An initialization process task can be of two types:
• “Analysis”,
in this case your process is a Process_Analysis. The only available data is the DataSet
• “InitializeOperation”
your process is a Process_InitalizeOperation process. The available data are the CP and the DataSet.
For more information on the way to implement these processes see Operation Initialization Process
on page 165
• If applicable, the sub-operations descriptor (CsmMbr_SubOperationSetDescriptor). The sub-operations
describe a hierarchy of operations (an operation "tree") from which the principle operation can obtain
data. In practical terms, the principle operation has access to the DataSets of the sub-operations.
The format of this section is presented in the second example below. Each sub-operation gets a key
(CsmMbr_OperationKey), has a type (CsmMbr_OperationType) and is operating on a support defined
by a path (CsmMbr_CPPath), relative to the analysis. If the CP (SEA or SE) indicated by this path has
no operation, a new one of the required type will be created. If the CP has several operations of this
type, the first one will be used. And if the CP is an array of CP's, then the corresponding array of
operations will be accessible.
Using the CsmMbr_OperationTreeDescriptor you can indicate how these sub-operations should be
displayed as a tree. If the CsmMbr_OperationTreeDescriptor is not present in the process template, a
view will be generated automatically using the keys of the operation set descriptor. To override this
behaviour, include the CsmMbr_OperationTreeDescriptor but do not include any items.
CsmMbr_OperationTreeDescriptor defines a tree in which each leave represents a sub-operation. For
each key associated with a sub-operation, a label is given. The label will appear in the left column of
the sub-operation view in the CÆSAM GUI. See the second example below for the syntax of this tree
descriptor.
• An optional property view management class.
The aim of this functionality is to allow the author to activate or deactivate the editing of certain EOs
according to the context. A context could be the value of another EO or an active step.
To achieve this it is necessary to define a class that inherits from the
CaesamStd_AbstractPropertyViewManagement class and to redefine the method IsDataSetKeyUseful()
which returns true or false if the EO has been edited or not. An instance of this class can then be
referenced in the process template, using the CsmMbr_PropertyViewManagement attribute. This is
demonstrated in the first example below.
• Optional associated files: the CsmMbr_Files tag allows you specifying a list of files produced by the
analysis, and that should be transmitted back to the local machine after the analysis has been run as a
job on a remote machine.
Other resources as well as methods can also be attached to this class. For example, it is here that the
analysis creation path, or the SwiXML editors associated with this kind of analysis, would be declared
(see below "Methods" and "Resources").

16.4 Analysis examples


The following example shows the declaration of the Buckling analysis corresponding to the first example
of dataset shown above. It can be seen that the process template associates the type of dataset
BucklingSuperStiffener_DataSet declared above with this type of operation. It also indicates that the
operation can operate on SEAs of type SuperStiffener and gives the process directory as well as the
initialization and analysis tasks.

page-157
Caesam SDK | 16 Analysis definition

Two methods are associated with this type of analysis: BeforeRun and AfterRun wich are called by the
framework.
<!--- Implement a BucklingSuperStiffenerPropertyViewManagement class to manage the
property view of a BucklingSuperStiffener -->
<TypeDesc Name="BucklingSuperStiffenerPropertyViewManagement"
Inherits="CaesamStd_AbstractPropertyViewManagement" >
<Method Name="IsDataSetKeyUseful" Type="Python"
Location="csm:com.samcef.caesam.test.process/python/BucklingSuperStiffenerPropertyViewManagement"/>
</TypeDesc>

<TypeDesc Name="BucklingSuperStiffener" Inherits="CaesamStd_Operation">

<Method Type="Python" Name="BeforeRun"


Location="csm:com.samcef.caesam.test.process/python/BckMethods"/>

<Method Type="Python" Name="AfterRun"


Location="csm:com.samcef.caesam.test.process/python/BckMethods"/>

<ProcessTemplate

DataSetType="BucklingSuperStiffener_DataSet"
CsmMbr_CPTypeName="SuperStiffener"
CsmMbr_ProcessDirectory="csm:documentczm/Analysis/Buckling">

<!--- Associate a BucklingSuperStiffenerPropertyViewManagement to manage the property


view of a BucklingSuperStiffener -->
<CsmMbr_PropertyViewManagement Type="BucklingSuperStiffenerPropertyViewManagement"/>

<InitializationTask CsmMbr_TaskLocation="myRegisteredProcessName"
CsmMbr_TaskType="Analysis"/>

<CsmMbr_ProcessTask CsmMbr_TaskLocation="myRegisteredProcessName"
CsmMbr_TaskType="Analysis"/>

<CsmMbr_Files>
<Item Type="CaesamStd_FileDeclaration"
CsmMbr_Url="csm:caesamprocessdir/SuperStiffener.html" CsmMbr_ArgType="OUT"/>
</CsmMbr_Files>

</ProcessTemplate>

<GUI Type="CaesamRes_ClassGUI">
<AnalysisCreationPath>...</AnalysisCreationPath>
<SwiXMLEditors>...</SwiXMLEditors>
<Editor Type="Caesam_String">...</Editor>
<FormDescriptor>...</FormDescriptor>
<TabularEditorModel>...</TabularEditorModel>
</GUI>

</TypeDesc>

The second example corresponds to the second example of dataset declaration given above. Note the use
of the sub operation set and tree descriptor, and of a specific Java analysis creation class.
<TypeDesc Name="HoledRibBayBuckling" Inherits="CaesamStd_Operation" >

<ProcessTemplate
DataSetType="HoledRibBayBuckling_DataSet"
CsmMbr_CPTypeName="HoledRibBay"
CsmMbr_ProcessDirectory="csm:documentczm/Analysis/Buckling/HoledRibBay/">
<CsmMbr_ProcessTask CsmMbr_TaskLocation="..." CsmMbr_TaskType="Analysis"/>

<CsmMbr_SubOperationSetDescriptor>
<CsmMbr_ItemArray>
<Item
Type="CaesamStd_OperationItem"
CsmMbr_OperationKey="SS"
CsmMbr_OperationType="BucklingSuperStiffener"
CsmMbr_CPPath="CP/CP[SS]"/>
</CsmMbr_ItemArray>
</CsmMbr_SubOperationSetDescriptor>

page-158
16 Analysis definition | Caesam SDK

<CsmMbr_OperationTreeDescriptor>
<CsmMbr_Nodes>
<Item Type="CaesamStd_TreeDirectory"
CsmMbr_Name="ASubDirectory">
<CsmMbr_Nodes>
<Item
Type="CaesamStd_AnalysisLeafDescriptor"
CsmMbr_DataSetKey="SS"
CsmMbr_Label="SS"
/>
</CsmMbr_Nodes>
</Item>
</CsmMbr_Nodes>
</CsmMbr_OperationTreeDescriptor>

</ProcessTemplate>

<GUI Type="CaesamRes_ClassGUI"
AnalysisCreationPath="/Example/RibBay/"
AnalysisCreationClass="com.samcef.caesam.process.HoledRibayCreation">
</GUI>

</TypeDesc>

16.5 Methods
Below is the list of framework methods that can be declared on the operation class (or in one case on the
dataset class):
• BeforeStore / AfterStore (CaesamStd_Operation). These methods expect no parameter. They are
called before and after each session save operation executed by the user. The author can for example
remove the files related to an analysis that do not need to be saved – such as working files for example.
• BeforeRemove (CaesamStd_Operation). This method expects no parameter. It is called before the
analyst deletes an analysis. The author can for example remove all the files or the links related to an
analysis.
• BeforeRun /AfterRun (CaesamStd_Operation): These methods expect one parameter which is the
CaesamStd_Model.
• GetFilesArray (CaesamStd_Operation): This method expects no parameter. You can redefine this
method if you need something more dynamic than the CsmMbr_Files tag in the process template. In
other words, this methods allows to build a dynamic list of files that must be transmitted back after an
execution as a remote job.
• GetComputingResources (CaesamStd_Operation): This method expects no parameter. Its role is
to return the estimated computing resources that will be taken by the analysis executed as a job. It
must return an object of class ProcBase_Resources having the following members: Memory
(CaesamQty_MEMORY), DiskSpace (CaesamQty_MEMORY), Licenses (Caesam_StringArray),
Time (CaesamQty_TIME).If the dataset entry is to be an array of EOs (typically if the EO support is
an array of CP, eg. in a RibBay), then the member must be declared as being of type
Caesam_ReferenceArray, and its type specified (and optionally its initial or fixed size too) in the
default instance of the class (still in the typedesc).
• BeforeJobRun / AfterJobRun (CaesamStd_Dataset): these methods must be declared on the dataset
class, since they must be called on the remote machine on which only the dataset is transferred. They
take no parameter.

16.6 Resources
Below is the list of analysis-specific GUI resources that can be associated with an operation class:
• AnalysisCreationPath. Allows you to specify the name of the directory in which the analysis appears
in the Caesam menus Analysis > Create analysis and Analysis –> Create Standalone Analysis.

page-159
Caesam SDK | 16 Analysis definition

• AnalysisCreationClass. Allows you to associate a java class that completes the menu for the creation
of an analysis and, in the case of the Standalone analyses, launches a special task. In effect, this requests
the creation of supplementary objects such as SEs, SEAs and EO required for the analysis.
Other generic resources such as Editor, SwiXMLEditor, FormDescriptor, TabularEditorModel, can also
be associated with an operation class. See Analysis Interface Definition on page 226 for more details on
these resources.

16.7 Process template compatibility


In order to assure the compatibility between releases, the authors may be required to provide a method
to convert an old analysis instance to a new one. To achieve this, the generic Caesam translation mechanism
can be used with operation and/or dataset classes as well.
How to translate an old analysis instance to a new one:
1. Flag the old operation class as being obsolete: MyOperation#0 OBSOLETE
2. Declare a new version of a the operation class (like MyOperation#1)
3. Implement a Translate method on the MyOperation#0 class.

Note: Adding a Translate method on an analysis is not necessary if the only change is a
modification in the process template, e.g. a new process directory that has been defined,
the process task that has changed. It is also not necessary when steps have been added or
removed, or when keys have been added or removed from the dataset. Indeed, when reading
an old csm file that contains some analysis based on an old version, the platform will detect
these changes and will handle them correctly. So, a Translate method is necessary only if
a deeper change has been brought to the dataset structure, and a mapping must be done
between the old data structure and the new one.

page-160
17 Processes | Caesam SDK

17 Processes
Processes In Caesam, “Processes” are used to achieve a task as illustrated in the figure below.

Figure 5: Process overview

The Caesam author is primarily interested in three main Task types:


• Process_Model, used to initialize the CaesamStd_Model
• Process_Analysis used to create an “Analysis”.
• Process_InitializeOperation, used to initialize the DataSet of an Analysis.
The base Caesam “Tasks” do nothing, you need to extend them.
The “Model Process” is used to initialise the model, it can create new objects (SE, SEA, EOs,…..) and
put them in the model using the “Put” method. Processes can be nested using the “RunTask” method.
They can be written in C++, Java or Python.

Important: The extension of the Process_Task inherited class is only partial. You should
only override the methods given in the “Your_Process_” classes in the UML diagram. They
are the only one called by the kernel. If you override any other method in Python or Java,
these methods will not be called by the Caesam kernel.

Tasks are volatiles objects, the framework instantiates them and calls the Run method. At the end of the
Run method they are deleted from memory.
Please note that it is possible to register the Run method in a Caesam_Object using a Caesam_Method
member. For example, It allows you to define a type inheriting from Process_Analysis in an xml typedesc
and then implement the Run method in FORTRAN.
For example an Analysis process can be run on several thousands of input datasets. If your process
generates some result files, it must be able to manage them during their entire lifespan. If each dataset
needs its own result file, it is up to the task to generate a correct file name for each one of them. If at the
launch of an Analysis the results must be destroyed, it is up to the process to do that.

Feedback for the user

The basic method by which the Process communicates with the user is through the “PutMessage” method.
This method will print a message to the standard output, and the Execution window. For processes accessed
through the “Tool Task” menu, any message delivered by the process will be displayed in a dialog box
when the process is complete.

page-161
Caesam SDK | 17 Processes

For an Analysis process, validation of the computation is achieved by calling the ClearStatus method on
the input DataSet. In the same vein, setting an ErrorStatus on a dataset will mark it as incorrect. The status
of an Analysis is the status of its DataSet.
If you catch exceptions in your process, you must bear in mind that in this case Caesam will not be
informed of the problem. It is sometimes interesting to “re-raise” an exception to inform Caesam that
something abnormal occurred (such as syntax error while running a Python process).

Error handling

The FORTRAN subroutine

SUBROUTINE CAESAMFORTRANEXCEPTION(RoutinName, MessageString) CHARACTER*(*)


RoutinName, MessageString

is available for the CAESAM plugin developers calling FORTRAN subroutines or functions from PYTHON
code.
RoutinName is the name of the calling FORTRAN subroutine or function
MessageString is a English text describing the error.
A call to this subroutine never returns, but stops the current FORTRAN code execution and throws a
PYTHON exception. This exception can then be caught by the calling PYTHON code to signal a severe
error.
This new subroutine has to be called when a severe error occurred in the FORTRAN code and must
replace the STOP instruction, as this instruction kills the current process and thus the CAESAM session
itself.

17.1 Analysis process


Analysis Processes encapsulates the data transformation aspects.
• Analysis Processes act on a datasets and can CRUD EO
• Analysis Processes can be nested, and may have Fortran routines embedded or generate text output.
In this section emphasis will be placed on the Python implementation of processes. For equivalent
constructions see sections on C++ on page 165 and Java on page 165 respectively. From a very general
point of view, analysis processes transform datasets. For performance purposes, it is possible to launch
a process on an array of dataset to perform a burst mode. This is described in the section Burst mode on
page 165.

17.1.1 Python implementation


A first approach focuses on an analysis working on a single dataset. As already noted, processing extensions
of the platform belong to the ‘refinement method’ of extension.

Note: All analysis processes are descendants of the Process_Analysis class.

In Python this is expressed by refining the type Process_Analysis and explicating the Run method:

from CaesamAPI import *


class «Process name»(Process_Analysis):
def Run(self,theDataSet):
«Process body»

Body instruction set

The Body instruction set can be separated into four types:


• Interface with Datasets

page-162
17 Processes | Caesam SDK

• CRUD an object
• Process call
• Native implementation instructions with features that will be described such as :
• Text generation
• Fortran embedding

Body taxonomy

These bodies can be separated into two classes:


• Elementary processes that embed a given elemental (basic) algorithm for data transformation. They
can be separated into three parts:
• Input mapping in which data from the dataset are converted into the actual variables of the
implementation.
• Transformation the actual algorithm or computation either text generation, embedded Fortran or
other native python features (sample calculation, system interaction,…)
• Output mapping in which data computed in the implementation are set back into the EO of the
dataset
• Composed processes that embed several other processes, which can themselves be either composed
or elementary.

Dataset Interface

Datasets are a map of EOs, therefore, their interface is the standard CAESAM interface for a map:
1. Get an object from the dataset

«EO variable» = theDataSet.Get(«EO Key»)

2. Put an object in the dataset

theDataSet.Put(«EO Key», «variable»)

CRUD EO

Create, Read, Update and Delete and Engineering object.


• Create an EO : An analysis can Create an EO. «EO variable» = self.NewEO(«EO Type», «EO
identifier»)
• Read an EO : An analysis can read EO content: «variable» =

«EO variable».Get(“«member name»”)

In Python it is also possible to get directly the value of a member using a shortcut:

«variable» = «EO variable».«member name»

When the member is a Primitive, it possible to get actual values to members, updating them as follows
:
• If the member is a CAESam_Integer: «integer» = «EO variable».GetMember(«integer
member»).GetValue()
• If the member is a CAESam_String: «string» = «EO variable».GetMember(«string
member»).GetValue()
• If the member is a CAESam_Quantity: «float»=«EO variable».GetMember(«member
name»).GetValue(«unit»)
The getter is parameterized by a unit, thus making the unit management transparent to the author.
• Calling a method on an EO :

page-163
Caesam SDK | 17 Processes

An analysis can invoke methods on an EO:

«variable» = «EO variable».CallMethod(«method name»,«parameter»)

In python it is also possible to directly use the «method name» as a shortcut:

«variable» = «EO variable».«method name»(«parameter»)

• Update a EO : An analysis can modify an EO that is linking with other EO:

«EO variable».SetMember(«member name»,«parameter»)

When the member is a Primitive, it possible to give actual values to members, updating them as follows:
• If the member is a CAESam_Integer. «EO variable».GetMember(«integer
member»).SetValue(«integer»)
• If the member is a CAESam_String «EO variable».GetMember(«string
member»).SetValue(«string»)
• If the member is a CAESam_Quantity «EO variable».GetMember(«member
name»).SetValue(«float», «unit»)
In a similar way to the getter, the setter is parameterized by a unit, thus making unit management
transparent to the author.
• Delete an EO : Normally deletion is not done directly, but through a garbage collecting strategy.

Managing sub-processes

The management of sub-processes is a key feature aimed at promoting a structured approach to


implementing processes. It allows testing of small ‘chunks’ and their proper integration in an iterative
fashion which is a established means to shorten integration time. The construction proposed here is not
mandatory for the platform but is recommended based on experience.
In order to promote a repetitive way to implement sub-processes and be logically close to a graphical
block-scheme approach, the following methodology has been developed and implemented.
For each sub-process we can associate a dataset.

«a dataset» = self.NewDataset()

Then each required EO can be transferred from the composed process to the sub-process. In general,
names are preserved i.e. («local name» = «global name»):

«a dataset».Put(«local name», theDataSet.Get(«global name»))

For each required EO that can be transferred from one sub-process to another sub-process, this is the
syntactic equivalent of drawing a labelled edge between two blocks representing the dataset and thus the
analysis:

«a dataset».Put(«name», «another dataset».Get(«name»))

The sub-process is then launched:

self.RunTask("«processname», «a dataset»)

In the case of a Python process, «a location» is an absolute path to python file, without its .py extension..
In most case you should use the “csm:” protocol to resolve the path at runtime.

Standard Python Extensions

Several Python extensions modules are included in the Caesam SDK.

page-164
17 Processes | Caesam SDK

• Numeric : is a Python module dedicated to scientific numerical computing. You can find more
information on Numeric at: http://www.numpy.org
• F2PY : is a set of tools that allows you to create Python modules from FORTRAN code source. It
generates all the interfacing code needed to call FORTRAN routines from Python.

17.1.2 Burst mode


In some cases, it is interesting to be able to launch a unique Analysis with several datasets. If a Process
Analysis is able to handle an array of datasets, it should override the HasBurstMode method and make it
return the True value.
In this case, the input parameter of the Run must be changed to an array of datasets. In Python, you should
do something like this:

from CaesamAPI import *


class «Process name»(Process_Analysis):
def HasBurstMode(self):
return True
def Run(self,theDatasetArray):

17.1.3 Other process Implementation


In the previous section, some examples of processes written in Python were given, but they can be written
in C++ or Java. The translation from python is straight forward, the main difference is that in those
languages you must declare objects before using them.

Java processes

import com.samcef.caesam.jnicaesam.*;
public class «Process name» extends Process_Analysis
{
Public Process Name (CaesamStd_Model theModel){
super(theModel);
}
public void Run(CaesamStd_DataSet aDataSet)
{ «Process body» }
}

The main difference resides in the location methodology:

RunTask("java:«a classname»", «a dataset»)

C++ processes

The main difference resides in the location methodology. In C++, processes are compiled and registered,
therefore the RunTask method can cite only the process name.

RunTask("«a process name»", «a dataset»)

17.2 Operation Initialization Processes


The aim of an “Operation Initialization process is to initialize the DataSet during the creation of an Analysis
instance.
The Run method of an Process_InitializeOperation process receives a Caesam_ObjectMap object.

page-165
Caesam SDK | 17 Processes

This map contains the following key.data pairs:


CP The CP of the Analysis.
DataSet The DataSet
These objects can be directly accessed by the two methods:

GetCP()

GetDataSet()

These methods are the most popular way to access these data.

17.3 Model processes


The aim of a “Model” process is to initialize the Model.

17.3.1 Python implementation


In Python, you must override the Run method defined in Process_Model.

from CaesamAPI import *


class «Process name»(Process_Model):
def Run(self,theModel):
«Script body»

Although the Model is given as parameter, most of the methods used to initialize the model (like Put, for
example) are defined in the Process_Model.
You should be aware that Python is considerably slower than C++. If you have to initialise a large model,
it is strongly recommended that you to use C++.

Initialising a Model

The Model is a map of EOs, therefore, it uses the standard CAESAM interface for a map:
1. Get an object from the model «object variable» = self.Get(«Object Key»)
2. Put an object in the model. «Object Key» = self.Put(«object variable»)

Adding an EO

This part is very close to analysis situation, except regarding the registration, as mentioned above.

«a EO»= self.NewEO(«a EO type», «a EO name»);


«update EO values»
«a EO key»=self.Put(«a EO»);

Adding an SE

The Model core structure is very simple; a collection of reference EO can be associated with each SE

«a SE»= self.NewSE(«a SE type», «a SE name»);


«a SE».AddReferenceEO(«for each reference EO»);
«a SE key»=self.Put(«a SE»);

page-166
17 Processes | Caesam SDK

Creating a Mesh

aFEM=CaesamStd_GFEM.NewInstance()
aFEM.SetName("GFEM")aFEM.AddNode(1,0.,0.,0.)
aFEM.AddNode(20,1.,0.,0) aFEM.AddLine(5,1,20)
self.Put(aFEM)

Creating an SE Topology

aSETopology.SetName(“aTopology”)
aSETopology.AddNode(1,0.,0.,0.)
aSETopology.AddNode(2,0.,0.,0.)
aSETopology.AddLine(1,1,2)
self.Put(aSETopology)

Adding an SEA

An SEA is a map of SEs.

«a SEA»= self.NewSEA(«a SEA type», «a SEA name»);


«a SEA».SetSE("«for each SE key»",«its corresponding SE»);
«a SEA key»=self.Put(«a SEA»);

17.4 Execution Context


This feature allows the Analyst to choose the way he wants the process to be launched. There are currently
two contexts: Foreground (Process_CaesamContext) and Background (Process_ShellContext) context.
The CaesamStd_Model is not available in the Background context. This means that you should explicitly
specify the available context types for a registered process if one of the contexts does not apply to a
specific process. The context choice is only relevant for Process_Analysis processes.

17.5 Process Registration


It is recommended that you “Register” your process instances.
Registering involves adding a <Processes> </Process> member to the plugin.xml file. The
Process member is a Caesam_Url use to locate a file containing a Caesam_ObjectArray of
ProcReg_Definition. The base class for process registry is ProcReg_Definition. This class has a
ProcessName member. This member is used as a key to find the ProcRef_Definition in the Process
Registry.

<Instance Type="Caesam_ObjectArray">
<Item ….>
</Instance>

Once a Process has been registered using a ProcReg_Definition instance, it can be launched or used
through its ProcessName. You can use it in the process templates as a replacement for the old TaskLocation
string.

page-167
Caesam SDK | 17 Processes

Caesam comes with a set of ProcReg_Definition specialized for Python, Java or Cpp. For example, to
register an instance of a python process, you should define an instance of ProcReg_PythonDefinition.

<Item Type="ProcReg_PythonDefinition">
<ProcessName Type="Caesam_String">TestAfterRetrieval</ProcessName>
<Url Type="Caesam_Url">file:csm:com.samcef.caesam.test.process/python/TestAf
terRetrieval</Url>
</Item>

17.5.1 The CaesamStd_ProcessParameter


The ProcessParameter is a feature of the ProcReg_Registry. The ProcessParameter is an object associated
with a registered process instance. There are two kinds of parameters:
• User editable parameter stored in a map (ProcessParameterSet) which is a part of the DataSet.
• PrivateParameter only available to a Process_Task. It cannot be directly modified by the user.
These parameters are available when the Process is executed.

User Editable Parameter

A User Editable Parameter is returned by the registered method ProcReg::NewProcessParameter.


If you want to set a specific parameter instance:

<Parameter type=”myprocessparametertype”>
<MemberName …..>
</Parameter>

If a simple instance of a registered type is suitable, just set the DefaultProcessParameterType member:

<DefaultProcessParameterType
Type=”Caesam_String”>myprocessparametertype</>

The user editable parameter is stored in the CaesamStd_ProcessParameterSet object linked to the DataSet.
The key used to store/retrieve the parameter is currently its type.
The easiest way to retrieve a parameter is to call:
CaesamStd_ProcessParameterSet::GetOperationTaskParameter() on a ProcessParameterSet.
By default the CaeamStd_ProcessParameter contains the name of the process (i.e. the registered name of
the process). A CaesamStd_Process_Parameter can be retrieved by calling on the CaesamStd_DataSet
the GetProcesssParameter(typename: STL_String) where the typename is the type of the
CaesamStd_ProcessParameter. You can retrieve the ProcReg_Definition of a given Process name by
calling the ProcReg_Registry::GetProcessDefinition(ProcessName) method.

Private Parameter

The Private parameter is an instance of a Parameter used to specify a generic Process_Task. It can be
retrieved using the

Process_Task::GetPrivateParameter()

To add a Parameter to a registered process, you just have to set the PrivateParameter member. As an
illustration of the use of a private parameter, you can consider a task used to generate a result report. You
can write a generic task that takes a template as private parameter. Afterwards, you just a register some
processes that all run the same code, but with a different private parameter (the template in this case).

page-168
17 Processes | Caesam SDK

Updating ProcessParameters

The ProcessParemeters are updated to their latest version on file loading if their method
IsParemeterEquivalent(theSavedParameter) returns a Caesam_Boolean of value False. If a True value is
retrieved, the saved Parameter is not updated.
The only currently checked parameter is the CaesamStd_StepProcessParameter. It will be replaced by
the current registered one if the <Step> member is not the same (i.e. different step count, step names,
optional or fatal flags).
The default method returns false.
If your process parameter (inheriting from CaesamStd_ProcessParameter) is subject to change and should
be updated you should also add the method IsParameterEquivalent to it.

17.5.2 The Context settings


Not every task is able to run in all contexts. You can define ONE of the two members to specify the
contexts suitable for a specific process instance. (See Execution Context on page 167).

AllowedContexts (type=Caesam_StringArray)

DeniedContexts (type=Caesam_StringArray)

The strings array are made of the type name of the contexts.

17.6 The Analysis Step Process


The Analysis process is a Process_Analysis made up of sub-processes. An example of registration of the
Steps follows.
The first big implementation for the new registry architecture is the ProcReg_StepDefinition. An example
of the registration is given below:

<Item Type="ProcReg_StepDefinition">
<ProcessName Type="Caesam_String">SuperStiffenerAnalysisInSteps</ProcessName>
<Steps Type="Caesam_ObjectArray">
<Item Type="ProcReg_StepStep">
<Step Type="Caesam_String">CheckSuperStiffener</Step>
<Optional Type="Caesam_Boolean">False</Optional>
<Fatal Type="Caesam_Boolean">True</Fatal>
</Item>
<Item Type="ProcReg_StepStep">
<Step Type="Caesam_String">SMRFSuperStiffener</Step>
<Optional Type="Caesam_Boolean">False</Optional>
<Fatal Type="Caesam_Boolean">True</Fatal>
</Item>
<Item Type="ProcReg_StepStep">
<Step Type="Caesam_String">SMHTMLReport</Step>
<Optional Type="Caesam_Boolean">True</Optional>
<Fatal Type="Caesam_Boolean">False</Fatal>
</Item>
</Steps>
</Item>

Each <Step> denotes the CsmMbr_ProcessName of a registered ProcReg_Definition.


The <Optional> member is used to specify if the execution of the step is optional. This is related to the
step editor. An optional step may be skipped by the analyst.
If the <Fatal> member is True, the next steps will not be executed if this step reports a non cleared
status.

page-169
Caesam SDK | 17 Processes

The DataSet is shared by all the steps.


Internally, ProcReg_StepDefinition inherits from ProcReg_CppDefinition. It launches the
Process_AnalysisStep Task.
The Process_AnalysisStep retrieves a CaesamStd_StepProcessParameter that contains information on the
steps.

page-170
18 Directories | Caesam SDK

18 Directories
Directories and groups allow a user to organize objects in the model in a structured hierarchical way.
Thus SEs, SEAs and Operations can be organised in a structured manner through a set of directories and
sub-directories.
Some predefined directories are provided in the model and the EO Shared Workspace is also presented
as a tree structure. Additional directories and sub-directories can be created in the model by authors as
required. Authors and analysts are able to create and manage hierarchical groups that can contain items
of different types. This directory structure can be shown in the GUI by selecting the view “By Hierarchy”.
This chapter describes the general directory structure for the model and for the EO Shared workspace in
particular. It also lists pre-defined model directories.

18.1 Directory structure


Info about CaesamStd_Directory, CaesamStd_TypedDirectory, CaesamStd_Group, CaesamStd_EOLibrary

The following example illustrates how to create and fill groups.


Note that groups, unlike directories, can also be created in the GUI by the analyst.

aGroupRoot = GetModel().GetGroupDirectory()
aTopGroup = aGroupRoot.AppendChildDirectory("Panels & Stringers")
aPanelGroup = aTopGroup.AppendChildDirectory("Panels")
aPanelGroup.AppendChildren(aPanelBranch.GetAllChildItems(None))
aStringerGroup = aTopGroup.AppendChildDirectory("Stringers")
aStringerGroup.AppendChildren(aStringerBranch.GetAllChildItems(None))

18.1.1 CaesamStd_Directory
This is the base class for all directories and groups in Caesam. It can contain any object that inherits from
CaesamStd_Item. Since CaesamStd_Directory is itself inheriting from CaesamStd_Item, a directory can
contain other directories (which are called its subdirectories).

Adding children

Children can be added to a directory with the following methods:

AppendChild(CaesamStd_Item theChild)
InsertChild(CaesamStd_Item theChild, Standard_Integer theIndex)
SetChild(CaesamStd_Item theChild, Standard_Integer theIndex)
AppendChildren(CaesamStd_ItemArray theChildren)
SetChildren(CaesamStd_ItemArray theChildren)

A child can be a simple item or a subdirectory. In the latter case, the following shortcut methods can also
be used:

AppendChildDirectory(STL_String theName)
InsertChildDirectory(STL_String theName, Standard_Integer theIndex)
SetChildDirectory (STL_String theName, Standard_Integer theIndex)

These methods will create a subdirectory with the given name. They are redefined in all classes inheriting
from CaesamStd_Directory in order to create a directory that can be safely used as a subdirectory.
CaesamStd_TypedDirectory in particular (see below) will create a directory of the correct type.

page-171
Caesam SDK | 18 Directories

Retrieving children

The following two methods allow the retrieval of a direct child of a directory either by its index or by its
name. Since child items are kept internally in a map, retrieval by name is efficient. The retrieved object
can be either a CaesamStd_Directory or any CaesamStd_Item.

CaesamStd_Item GetChild(Standard_Integer theIndex)


CaesamStd_Item GetChild(STL_String theName)

The following methods allow you to get a list of all the direct children of a directory (items and/or
subdirectories), optionally filtered through a CaesamStd_AbstractItemFilter. If a filter is given to
GetChildren, it is also possible to filter subdirectories.

CaesamStd_ItemArray GetChildren(CaesamStd_AbstractItemFilter theFilter,


Standard_Boolean theFilterDirectories)
CaesamStd_ItemArray GetChildItems(CaesamStd_AbstractItemFilter theFilter)
CaesamStd_ItemArray GetChildDirectories()

The following method allows the retrieval of all direct and indirect items of a directory (by recursively
browsing all subdirectories), with an optional filter.

CaesamStd_ItemArray GetAllChildItems(CaesamStd_AbstractItemFilter theFilter)

Exclusivity and indexation

The CaesamStd_Directory creator takes an optional argument theIndexItems. If not given, it defaults to
Standard_False. If this argument is set to Standard_True, the directory will keep an internal map of all
items found in the directory or in its subdirectories.
This map will be used for two things:
• to ensure that the same item cannot be put twice into the directory or in one of its subdirectories
• to allow the rapid retrieval of an item in the directory or in one of its subdirectory
It is possible to toggle this feature on or off after creation using the following method:

SetExclusive(theExclusive: Standard_Boolean)

Finding items in a directory

All nodes in a CaesamStd_Directory inherit from CaesamStd_Item that has a member called
CsmMbr_Name. The value of this member is used to identify the node among the children subdirectories
of the directory.
CaesamStd_Directory redefines the default Find method for accessing objects by their path. Items can be
accessed in three ways (that can be mixed):
• By their name:

SubDir/SubSubDir/Item

• By the child member (a map):

Children[SubDir]/Children[SubSubDir]/Children[Item]

• By the child index:

Children[0]/Children[1]/Children[3]

page-172
18 Directories | Caesam SDK

18.1.2 CaesamStd_TypedDirectory
A typed directory ensures that only items of a given type (or of an inherited type) can be added to the
directory. Only typed subdirectories of the same type (or an inherited type) can be used as a subdirectory
of a typed directory.

18.1.3 CaesamStd_Group
A group is a tree that can contain items of mixed types and also duplicate items. New groups can be
created and managed at runtime, via an API or GUI.

18.1.4 CaesamStd_EOLibrary
CaesamStd_EOLibrary inherits from CaesamStd_EODirectory, which is itself a typed directory with the
fixed type CaesamStd_EO. The EO library is an exclusive directory that cannot contain duplicate items
with the same name.

Importing an EO library

When an EO library is imported, the loaded library will be merged into the current one. Subdirectories
with the same name will be recursively merged. If some items cannot be imported, because their name is
already used by another EO (or because they don’t have a name at all), a warning message will be displayed
showing all engineering objects that couldn’t be imported with the reason why they were rejected.

Finding items in an EO library

EOs in the library can be accessed in two ways:


• directly by the EO name: [theEOName]
• as a directory as described above.

18.2 Model predefined directories


The Caesam model has some predefined (sub)directories.
• Root directory : returned by GetRootDirectory()
• “SE Root” : returned by GetSEDirectory()
• “SEA Root” : returned by GetSEADirectory()
• “Analysis Root” : returned by GetOperationDirectory()
• “Run Root” : returned by GetRunDirectory()
• “Group Root” : returned by GetGroupDirectory()
• “EO Shared Workspace” : returned by GetEOLibrary()

Finding items in the model

CaesamStd_Model redefines the default Find method for accessing objects by their path. Items in the
model can be accessed in the following ways:
• Direct access by their key (i.e. the UUID): [UUID]
• Access via the root directory: Root/...
• Shortcuts to the predefined subdirectories:
SERoot/..., SEARoot/..., OperationRoot/..., RunRoot/..., GroupRoot/... and EOLibrary/...
• Access through the map member: CsmMbr_KeyMap[UUID]

page-173
Caesam SDK | 18 Directories

The following example illustrates how a model process can hierarchically organize structural elements
in the model predefined directories. The same applies to SEAs, analyses and EOs.

aSERoot = GetModel().GetSEDirectory()
aPanelBranch = aSERoot.AppendChildDirectory("Panels")
aPanelBranch.AppendChild(NewSE("Panel", "Panel1"))
aPanelBranch.AppendChild(NewSE("Panel", "Panel2"))
aStringerBranch = aSERoot.AppendChildDirectory("Stringers")
aStringerBranch.AppendChild(NewSE("Stringer","Stringer1"))
aStringerBranch.AppendChild(NewSE("Stringer","Stringer2"))

18.3 Structural groups

Overview

Structural groups are a special kind of groups, and as such inherit all features of groups (i.e. items can be
hierarchically organized).
The specificity of a structural group is that the contents displayed in the GUI will vary according to the
current view. For example, in view by analysis you will see the analysis related to the SEs in the structural
group.
More precisely, here is how a structural group works:
• When adding/removing items in a structural group, it's not these items that are added/removed, but
well the SEs behind these items. This means that whatever items you add/remove in a structural group,
they will be first transformed into the underlying SEs. It is these SEs that are really stored in the group,
hence the name "structural" group.
• The displayed contents of a structural group depend on the current view. In view by analysis e.g., you
will see all analysis either directly operating on the SEs in the stuctural group, or operating on a SEA
that is it self defined on these SEs, and so on.
For example, if you add a BucklingSuperStiffener analysis in an empty structural group, the left and right
panels as well as the stringer will be stored in the structural group, not the analysis. If we see this group
in view by analysis, we'll of course see the analysis we added, but also other analyses directly or indirectly
using the same underlying SEs.
The model has a structural group root, which can be obtained with method GetStructuralGroupDirectory().
The task "Init SuperStiffeners" from our example plugins create some structural groups for test purposes.
There is a limitation with elements: there is currently no efficient way of getting the SE from an element.
This means that if you add/remove an element to/from a structural group, nothing will happen.

18.3.1 Creating structural groups

Abstract platform task

Structural groups can not be created using the GUI yet. But authors can create them: some specific tools
exist in the SDK for this purpose.
Of course, authors can directly use the GetStructuralGroupDirectory() method and then use the standard
directory API to add and remove children in this root structural group.
But there exist an abstract task aimed at easing the author's work when creating structural groups. This
task is registered under the name CaesamTask_AbstractStructuralGroupCreator.
This task has one abstract method named GetSEGroups, which takes a CaesamStd_SE as parameter, and
must return the list of the names of the groups in which the SE can be found (Caesam_StringArray).
A group name can in fact be a full path, e.g. GroupLevel1/GroupLevel2/GroupLevel3/GroupName. The
task will take care of creating the corresponding group's hierarchy.

page-174
18 Directories | Caesam SDK

As often in Caesam, you can redefine the method GetSEGroups either in pure C++, or with a registered
Caesam method written in Python or Java.

Example tasks

Two examples of tasks built upon this abstract task can be found in plugin com.samcef.caesam.test.process:
ProcessTest_StructuralGroupCreator and ProcessTest_StructuralGroupCreatorPython.
These 2 examples do the same thing, but the first one is impemented in C++ and the second one in Python.
They will deduce the structural groups hierarchy directly from the SE names. The frame number is used
to split a barrel into transversal sections, and the stringer number to split the same barrel into longitudinal
sections.
You can try out these examples by importing our example SimpleBarrel GFEM model found in
examples/BulkData/SimpleBarrel, and then execute the task "Tools > Tasks > Create Structural Groups
From SE Name (C++/Python)"
For the source files of these examples, see in examples/plugins/com.samcef.caesam.test.process/ :

- Process.typedesc (declaration of ProcessTest_StructuralGroupCreatorPython)


- python/ProcessTest_StructuralGroupCreatorMethods.py
- src/pluginlib/inc/ProcessTest_StructuralGroupCreator.hxx
- src/pluginlib/cxx/ProcessTest_StructuralGroupCreator.cxx
- resources/Commands.csm (GUI menus)

The source code of the python example is reproduced below:


from CaesamAPI import *
import re

def GetSEGroups(theInstance, theSE):

aFrameNumber = 0
aStringerNumber = 0

if aFrameNumber == 0 and aStringerNumber == 0:


matches = re.findall(".*-FR-([0-9]*)-[0-9]*-STR-([0-9]*)-[0-9]*", theSE.GetName())
for match in matches:
aFrameNumber = match[0]
aStringerNumber = match[1]

if aFrameNumber == 0 and aStringerNumber == 0:


matches = re.findall(".*-STRINGER-([0-9]*)-FR-([0-9]*)-[0-9]*", theSE.GetName())
for match in matches:
aStringerNumber = match[0]
aFrameNumber = match[1]

if aFrameNumber == 0 and aStringerNumber == 0:


matches = re.findall(".*-FRAME-([0-9]*)-STR-([0-9]*)-[0-9]*", theSE.GetName())
for match in matches:
aFrameNumber = match[0]
aStringerNumber = match[1]

aGroupPaths = Caesam_StringArray()
aGroupPaths.FromString("Barrel/TSections/Section" + str(aFrameNumber) + ";Barrel/LSections/Section"
+ str(aStringerNumber))
return aGroupPaths

Predefined platform task

We just saw how we can write our own tasks to create structural groups. But Caesam already provides
one useful implementation, based on a input text file describing the groups.
This task is registered under the name CaesamTask_StructuralGroupCreatorFromFile. It takes as parameter
an URL that must point to a text file, which contains a list of blocks with the following format (one block
= one group):

<group_path>:
<se_mask1>
...
<se_maskn>

page-175
Caesam SDK | 18 Directories

Here, group_path represents a group name, with possible parent groups (e.g.
GroupLevel1/GroupLevel2/GroupLevel3/GroupName). Adnd se_mask represents a SE name in which
the wildcards '*' and '?' can be used.
Here is an example of such an input file. You can find the full file in
examples/BulkData/SimpleBarrel/Groups.txt.

Barrel/TSections/Section1/Panels:
SAM-PANEL-FR-01-*
SAM-PANEL-FR-02-*
SAM-PANEL-FR-03-*
SAM-PANEL-FR-04-*
SAM-PANEL-FR-05-*
SAM-PANEL-FR-06-*

Barrel/TSections/Section1/Stringers:
SAM-STRINGER-*-FR-01
SAM-STRINGER-*-FR-02
SAM-STRINGER-*-FR-03
SAM-STRINGER-*-FR-04
SAM-STRINGER-*-FR-05
SAM-STRINGER-*-FR-06

Barrel/TSections/Section1/Frames:
SAM-FRAME-01-*
SAM-FRAME-02-*
SAM-FRAME-03-*
SAM-FRAME-04-*
SAM-FRAME-05-*
SAM-FRAME-06-*

Using these tasks

We now know that the platform provides a ready-to-use task ,and we also know how to create our own
tasks.
We still have to use these tasks. A first way is to add some menu items in the GUI that will run these
tasks. This is what we've done for our two examples described above. See "Interface Definition" in chapter
"Analysis Interface Definition" for explanations on how to do this.
But we could also call some task from another task. For example, it would make sense to create the
structural groups at the same time as importing the GFEM model.
To demonstrate this, we have modified our example GFEM import task (found in plugin
examples/com.samcef.caesam.test.gfem). We've added a parameter to the task, which is a Caesam_File
that must point to a text file with the format described above.
Then we fetch this parameter and run the platform task in our C++ code as follows (see "Programming
interface" in chapter "Batch Tools" for more information on running tasks"):
Handle(Caesam_File) aGroupFile = Caesam_File::Cast(aUserParameter->GetMember("GroupFile"));

// run platform task CaesamTask_StructuralGroupCreatorFromFile


// to create structural groups from the group file, and 'forward' messages
if (!aGroupFile.IsNull() && !aGroupFile->GetUrl().IsNull()) {
aStatus = CaesamScript_Task::RunTask(GetModel(),
"CaesamTask_StructuralGroupCreatorFromFile", GetModel(), aGroupFile->GetUrl(), NULL);
aMessages = aStatus->GetMessages();
for (int aIndex = 0; aIndex < aMessages->Size(); aIndex++)
PutMessage(aMessages->Get(aIndex));
}

page-176
19 Filters | Caesam SDK

19 Filters
Filters in Caesam are used to hide data or display it as read only.
A discipline is a special filter that can be used in the whole application to specify whether a type, and
optionally which of its members, should be visible. A discipline can be selected in the status bar of the
main window from those that have been defined in the loaded plug-ins.
Editor filters are used to customize the default editor. There are two types of editor filters:
• editability filters : that indicate whether a member should be editable or not
• visibility filters : that indicate whether a member should be shown or hidden
Authors can implement their filters in pure C++ and directly redefine the virtual C++ method Matches
(which is of course faster), or declare their filter in XML and redefine the Caesam method Matches in
Python, Java or use an existing C++ method.

19.1 Disciplines
These can be used to filter the type names and optionally their members at several places in the application.
Base class CaesamStd_AbstractDicipline
Arguments theType and theMember are STL_String containing respectively the name of the
type being filtered and the name of one of its members. The member name can be
empty in which case it means the application just wants to know about the type.

19.1.1 Implementing a custom discipline


A discipline can be made by declaring a new type inheriting from CaesamStd_AbstractDiscipline
and by redefining the method Matches (C++ or Caesam) to implement a specific behaviour.
Let us imagine a very simple custom discipline type, having one member “SubTypeName”. The goal of
this discipline is to reject analyses whose process template does not contain the substring given by
“SubTypeName”. This discipline can be declared in XML and implemented in python, as shown here:

<TypeDesc Name="CustomPythonDiscipline"
Inherits="CaesamStd_AbstractDiscipline" >
<Member Name="SubTypeName" Type="Caesam_String"/>
<Method Name="Matches" Type="Python"
Location="csm:
com.samcef.caesam.test.transverse/python/CustomPythonDisciplineMethods"/>
</TypeDesc>

def Matches(theCustomPythonDiscipline, thePair):

# get typename to check and subtypename of this discipline


aTypeName = thePair.GetFirst().GetStringValue();
aSubTypeName =
theCustomPythonDiscipline.GetStringValue("SubTypeName");
# if type does not inherit from process template always accept
aRegistry = Caesam_Application.GetApplication().GetRegistry()
aClass = aRegistry.GetClass(aTypeName)
if (not aClass.HasType("CaesamStd_ProcessTemplate")) :
return Caesam_Boolean(True);
# accept if subtypename found in typename
return Caesam_Boolean(aTypeName.find(aSubTypeName) != -1);

We can see that the Caesam method Matches gets as argument a Caesam_Pair, whose first item is a
Caesam_String representing the type name being filtered, and whose second item is a Caesam_String

page-177
Caesam SDK | 19 Filters

representing the member name being filtered (can be empty if not applicable). In this example, the member
name is ignored, since we are concerned only about the type.
Below is the same discipline declared and implemented C++. Note that we directly redefine the C++
virtual method Matches that takes two strings and returns a boolean. We could also register a Caesam
method as in python but it would of course be less efficient.

class CustomCppDiscipline: public CaesamStd_AbstractDiscipline {


public:
CustomCppDiscipline() {}

// redefine the c++ Matches method


virtual Standard_Boolean Matches(const STL_String& theTypeName,
const STL_String& theMemberName) {

// get subtypename of this discipline


Handle(Caesam_Object) aSubTypeName = GetMember("SubTypeName");
if (aSubTypeName.IsNull()) return Standard_True;

// if type does not inherit from process template always accept


Handle(Caesam_Registry) aRegistry =
Caesam_Application::GetApplication()->GetRegistry();
Handle(Caesam_Class) aClass = aRegistry->GetClass(theTypeName);
if (!aClass->HasType(“CaesamStd_ProcessTemplate”))
return Standard_True;

// accept if subtypename found in typename


return (theTypeName.find(aSubTypeName->GetStringValue())
!= STL_String::npos);
}
static PTRMEM(Caesam_Object)
NewInstance(PTRARG(Caesam_Object) theObject) {
return new CustomCppDiscipline();
}
static void Register(Caesam_Registry *theRegistry) {
theRegistry->RegisterClass(GetRegisteredClass());
theRegistry->RegisterMember("CustomCppDiscipline",
"SubTypeName", "Caesam_String", NULL, NULL);
}

static PTRMEM(Caesam_Class) GetRegisteredClass() {


static PTRMEM(Caesam_Class) aClass =
new Caesam_Class("CustomCppDiscipline",
CaesamStd_AbstractDiscipline::GetRegisteredClass(),
CAESAMCONSTRUCTOR(CustomCppDiscipline::NewInstance), NULL);
return aClass;
}
};

19.1.2 The default discipline


A default discipline implementation is also provided by the class CaesamStd_DefaultDiscipline.
This is a general implementation that should cover most needs. The class
CaesamStd_DefaultDiscipline has the following members :
• FilteredBaseTypes : Caesam_StringArray : this member indicates which types should be further
investigated. For other types the Matches method will always return true. You can use * for 'all types'
and ~ to explicitly exclude a type: "*;~CaesamStd_CP" means that everything but CPs will be filtered
by the discipline. If you do not specify this member, it will default to
"CaesamStd_EO;CaesamStd_ProcessTemplate", which means that only EOs and analyses will be
filtered by the discipline.

page-178
19 Filters | Caesam SDK

• ‘Plugins’ : Caesam_StringArray : This member indicates which plugins are allowed by the discipline.
For types NOT defined in those plugins, the Matches method will return false. You can use * for 'all
plugins' and ~ to explicitly exclude a plugin. If you don't specify this member, it will default to "*".
• ‘VisibleTypes’ : Caesam_TypedMap with type Caesam_StringArray : this member contains the
names of the accepted types. For each type, you can specify which members should be visible.
The way the Matches method works is summarized below:

Question Yes No

1. Does the type inherit from one the filtered base types ? Continue True

2. Does the type come from an allowed plugin ? Continue False

3. Is the member VisibleTypes used ? Continue True

4. Is the type explicitly declared in the visible types ? Continue False

5. Is the membername declared visible for this type ?* True False

19.1.3 Declaring discipline instances


All (default and custom) discipline instances must be put in a .csm file containing an instance of
Caesam_ObjectMap, where the key is the name of the discipline and the value is an instance of a class
inheriting from CaesamStd_AbstractDiscipline.
Below is an example of such a file containing examples of four discipline declarations.

Table 12:

Buckling This is an example of a default discipline (i.e. an instance of


CaesamStd_DefaultDiscipline) called ‘Buckling’. This disciplines specifies
that - EOs of types Ply and StackingSequence are hidden - Visible process
templates are explicitly listed. - All other types (not inheriting from
CaesamStd_ProcessTemplate, Ply or StackingSequence) are visible.

Transverse This is another example of a that filters all items (except directories) and
accepts only those whose type is defined in plugin
com.samcef.caesam.test.transverse.

Static (python) This is an instance of CustomPythonDiscipline that rejects analyses and


process templates that do not contain the word 'Static'.

Static (c++) This is an instance of CustomCppDiscipline with the same behaviour.

<Instance Type="Caesam_ObjectMap">

<Item Key="Buckling" Type="CaesamStd_DefaultDiscipline">

<!--- EOs of type Ply and StackingSequence are hidden. -->


<!--- Visible process templates are explicitely listed. -->
<FilteredBaseTypes Type="Caesam_StringArray">
CaesamStd_ProcessTemplate;Ply;StackingSequence

*
This is applicable only if the application wants to know about a specific member. This feature is not used
by the GUI yet.

page-179
Caesam SDK | 19 Filters

</FilteredBaseTypes>

<VisibleTypes Type="Caesam_TypedMap">
<Type Type="Caesam_String">Caesam_StringArray</Type>
<Item Key="BucklingSuperStiffener" Type="Caesam_StringArray"/>
<Item Key="SuperStiffenerTemplate" Type="Caesam_StringArray"/>
<Item Key="RibBayTemplate" Type="Caesam_StringArray"/>
<Item Key="HoledRibBayBuckling" Type="Caesam_StringArray"/>
<Item Key="StringerTemplate" Type="Caesam_StringArray"/>
</VisibleTypes>
</Item>

<Item Key="Transverse" Type="CaesamStd_DefaultDiscipline">

<FilteredBaseTypes Type="Caesam_StringArray">
~CaesamStd_Directory;*
</FilteredBaseTypes>

<Plugins Type="Caesam_StringArray">
com.samcef.caesam.test.transverse
</Plugins>
</Item>

<Item Key="Static (python)" Type="CustomPythonDiscipline">


<SubTypeName Type="Caesam_String">Static</SubTypeName>
</Item>

<Item Key="Static (c++)" Type="CustomCppDiscipline">


<SubTypeName Type="Caesam_String">Static</SubTypeName>
</Item>
</Instance>

The csm file containing the disciplines must be declared in the plugin resources in the plugin.xml file, as
follows:

<Resources Type="Caesam_ObjectMap">
<Item Key="Disciplines" Type="Caesam_Url">
resources/disciplines.csm
</Item>
</Resources>

19.2 Editor filters


Specifies whether an edited object is visible or editable
Editor filters are used to specify if a given member of an edited object should be visible or hidden, and
editable or not, based on the current state of the object.
Base class: CaesamStd_AbstractEditorFilter
Arguments theObject is the edited object and thePath is a STL_String containing a Caesam path
to some child object inside the edited object. Currently the path can only be a member
name, but the filter implementation can already handle other cases.

19.2.1 Implementing a custom editor filter


To define an editor filter you have to declare a new type inheriting from
CaesamStd_AbstractEditorFilter and to redefine the C++ virtual method Matches or the Caesam
abstract method Matches.

page-180
19 Filters | Caesam SDK

Below is an example of a user-defined editor filter for PanelGeometry, declared in XML and implemented
in Python, that disables members “width” and “length” if “fixedsize” is true.

<TypeDesc Name="PanelGeometryEditabilityFilter"
Inherits="CaesamStd_AbstractEditorFilter">
<!—- Caesam_Boolean Matches(Caesam_Pair theCandidate) -->
<Method Name="Matches"
Type="Python"
Location="csm:com.samcef.caesam.test.transverse
/python/PanelGeometryEditabilityFilterMethods"/>
</TypeDesc>

def Matches(thePanelGeometryEditabilityFilter, thePair):

aPanelGeometry = thePair.GetFirst()
aPath = thePair.GetSecond().GetStringValue()

if (aPath == "width" or aPath == "length"):


aFixedsize = aPanelGeometry.GetStringValue("fixedsize")
if ( aFixedsize == "True" ): return Caesam_Boolean(False)
return Caesam_Boolean(True)

You can see that the Caesam method Matches gets as argument a Caesam_Pair, whose first item is a
Caesam_Object representing the edited object being filtered, and whose second item is a Caesam_String
representing the path inside the object (i.e. a member name). Below is a visibility filter for type Ply,
declared and implemented in C++. This filter hides the member “orientation” if “isotropic” is true. Note
that we directly redefine the C++ virtual method Matches that returns a Standard_Boolean. We could also
register a Caesam method as in python but it would be less efficient.

class PlyVisibilityFilter: public CaesamStd_AbstractEditorFilter {


public:

virtual Standard_Boolean Matches(PTRARG(Caesam_Object) theObject,


const STL_String &thePath) {

if (thePath == "orientation")
if (theObject->GetStringValue("isotropic") == "True")
return Standard_False; return Standard_True;
}

static PTRMEM(Caesam_Object)
NewInstance(PTRARG(Caesam_Object) theObject) {
return new PlyVisibilityFilter();
}

static void Register(Caesam_Registry *theRegistry) {


theRegistry->RegisterClass(GetRegisteredClass());
}

static PTRMEM(Caesam_Class) GetRegisteredClass() {


static PTRMEM(Caesam_Class) aClass =
new Caesam_Class("PlyVisibilityFilter",
CaesamStd_AbstractEditorFilter::GetRegisteredClass(),
CAESAMCONSTRUCTOR(PlyVisibilityFilter::NewInstance), NULL);
return aClass;
}
};

page-181
Caesam SDK | 19 Filters

19.2.2 Associating editor filters with Caesam types


The defined filters must then be declared in the resources associated with the plug-in class for which it
has been made (in the plugin.xml file), as follows :

<Item Type="PluginClass">
<Class Type="Caesam_String">PanelGeometry</Class>
<Default Type="Caesam_Url">default/PanelGeometry.csm</Default>
<Resources Type="Caesam_ObjectMap">
<Item Key="VisibilityFilter" Type="Caesam_String">
PanelGeometryVisibilityFilter
</Item>
<Item Key="EditabilityFilter" Type="Caesam_String">
PanelGeometryEditabilityFilter
</Item>
</Resources>
</Item>

<Item Type="PluginClass">
<Class Type="Caesam_String">Ply</Class>
<Default Type="Caesam_Url">default/Ply.csm</Default>
<Resources Type="Caesam_ObjectMap">
<Item Key="VisibilityFilter" Type="Caesam_String">
PlyVisibilityFilter
</Item>
<Item Key="EditabilityFilter" Type="Caesam_String">
PlyEditabilityFilter
</Item>
</Resources>
</Item>

Each time a change occurs to the EO, the EditorData has to consult the editor filters to find out if a visibility
or editability change has occurred. If this is the case, the EditorData will notify the Editor that it has to
update its GUI to reflect the new visibility and editability state of its edited data.

Note: This mechanism is limited to the first level of member of the Edited object: this
means that the filter mechanism won't work neither on "member of member", nor on item
of "collection member" like array, map and matrix.

page-182
20 Global Table Creation | Caesam SDK

20 Global Table Creation


A new GlobalTable template can be defined by an author, and all plugins can contain the implementation
of this new GlobalTable template. As soon a new template is defined and compiled into a plugin, the
GlobalTable creation dialog box presents this new template for the creation of a GlobalTable by the
analyst.

20.1 Structure
A GlobalTable template is defined by:
GlobalTable which describes the content of each column of the table.
descriptor
GlobalTable which describes how to fill ‘Primary’ columns. (Non primary columns can be
initialization computed automatically by the framework.)
method
Attributes for More information is given in the section on Implementation.
GUI presentation
For each column, the GlobalTable descriptor contains the number of column and the following properties:

Table 13:

Property Description

ColumnName the name of the column

ColumnPath the means to compute the content of the column (for primary column, the
path is empty)
• Path syntax : [RefColumn]/<relative path>
• Relative path syntax :

<Member name>, EO[<EO name], <Array name>[<array id>],

$<column name>, @<method name>, :<configuration>

Example :

[Analysis]/EO[TableResult]/LoadCase[$LoadCase]
/$ResultName[Geometry]/@surface

ColumnType the type of content of all cells in the column

ColumnRenderer the ‘display value’ of the object which is displayed in the cell
(Name, Type, Value,
…)

ColumnSelected (TRUE this optional setting defines whether the column is initially displayed or not.
/ FALSE)

page-183
Caesam SDK | 20 Global Table Creation

20.2 Implementation
As described above, the implementation of a global table consists of:
• the declaration of the template
• the description of the template
• the declaration of the GUI attributes
In addition you can:
• use Java to add panels to specify parameters relating to the table creation.

Declaration of the new GlobalTable template

Enter in the .../CppClasses.typedesc file:

<TypeDesc
Name="XXX_YYYTableCreator"
Implementation="CPP"
Inherits="CaesamTable_TableCreator">
</TypeDesc>

Enter in the .../src/pluginlib/cxx/XXXPlugin.cxx file:

#include <XXX_YYYTableCreator.hxx>

extern "C"{
STL_EXPORT void initialize
(Caesam_Registry *theRegistry,
Caesam_Persistence *thePersistenceManager)
{
XXX_YYYTableCreator::Register(theRegistry);
}
}

GlobalTable template description

Enter in the .../src/pluginlib/cxx/XXX_YYYTableCreator.cxx file:


Standard methods available are:
• NewInstance
• InitInstance
• Register
• GetRegisteredClass
• XXX_YYYTableCreator
Specific methods available are:
• Initialize : which defines the Table structure.
Create GlobalTable descriptor

Handle(CaesamTable_TableDescriptor) aTableDescriptor =
CaesamTable_TableDescriptor::NewInstance();

For each column:

aTableDescriptor->AddColumn();
aTableDescriptor->SetColumnName(aColumnIndex,"LoadCase");
aTableDescriptor->SetColumnPath(aColumnIndex,"");
aTableDescriptor->SetColumnType(aColumnIndex,"CaesamStd_LoadCase");

page-184
20 Global Table Creation | Caesam SDK

aTableDescriptor->SetColumnRenderer(aColumnIndex,"Name");
aTableDescriptor->SetColumnSelected(aColumnIndex,Standard_True);

For the table

aTableDescriptor->SetTableCreator(this);
Handle(CaesamTable_Table)
aTable=CaesamTable_Table::NewInstance(aTableDescriptor);
aTable->SetName("GlobalTableTest");

• Update : to create all rows and fill the Primary columns with content
For each line:

theTable->SetPrimaryObject(aRow,aElementColumn,aElementStd);
theTable->SetPrimaryObject(aRow,aLoadCaseColumn,aLoadCase);
theTable->SetPrimaryObject(aRow,aFXColumn,
new Caesam_Quantity(aQuantityArray->Get(0),
aQuantityArray->GetDimension()));
theTable->SetPrimaryObject(aRow,aFYColumn,
new Caesam_Quantity(aQuantityArray->Get(1),
aQuantityArray->GetDimension()));
theTable->SetPrimaryObject(aRow,aFZColumn,
new Caesam_Quantity(aQuantityArray->Get(2),
aQuantityArray->GetDimension()));

GUI attributes declaration

Enter in the .../plugin.xml file:

<Classes Type="Caesam_ObjectArray">
<Item Type="PluginClass">
<Class Type="Caesam_String">XXX_YYYTableCreator</Class>
<Resources Type="Caesam_ObjectMap">
<Item Key="TableCreationPath"
Type="Caesam_String">/<WWWTableCreationDialogBox_TreeDir>/
</Item>
</Resources>
</Item>
</Classes>

Panels to define table creation parameters

You can use Java, to add your own GUI components, that contain parameters relating to the creation of
a GlobalTable.
You must create a Java class that inherits from
com.samcef.caesam.data.table.AbstractDataTableCreation. This implies that you redefine
two methods:

public abstract JPanel getPanel();

This method is called when you click on a type of global table in the tree. The class to instantiate is
provided by the tag “Class” located in the plugin.xml file. The class is loaded and getPanel() is called.

public abstract void create( String theName);

This method is called in the last step of global table creation. In this method you can use all of the
parameters provided by getPanel().

page-185
Caesam SDK | 20 Global Table Creation

This is illustrated with the following simple example.

public class PrimarySEDataTableCreator extends AbstractDataTableCreation


{
JComboBox myComboChoice = null;
CaesamTable_TableCreator myTable_TableCreator = null;
private UtilResource myResource;

private JCheckBox myChkSelection = new JCheckBox();

public PrimarySEDataTableCreator() {}

@Override
public void create( String theName)
{
CaesamAPI_Model aModel = myCaesamModel.getAPIModel();
// Open a transaction
aModel.OpenTransaction("Tr"+ System.currentTimeMillis());
try
{
if ( myTable_TableCreator== null )
myTable_TableCreator =
CaesamAPI_GlobalTableCreator.CreateTableCreator(myType);

if ( myChkSelection.isSelected() &&
CaesamAPI_GlobalTableCreator.IsSelectionAvailable
(myTable_TableCreator, myCaesamModel.getTreeViewSelection()
.getStdItemArraySelection() ))

CaesamAPI_GlobalTableCreator.SetSelection
(myTable_TableCreator, myCaesamModel.getTreeViewSelection()
.getStdItemArraySelection());

CaesamAPI_GlobalTableCreator.SetPrimaryTableType
(myTable_TableCreator, (String) myComboChoice.getSelectedItem());

page-186
20 Global Table Creation | Caesam SDK

CaesamAPI_GlobalTable.CreateTable(myCaesamModel.getStdModel()
,myTable_TableCreator,
myCaesamModel.getStdModel().CreateUniqueName(theName));
}
catch ( Exception e )
{
System.out.println("%%%ERROR:
PrimarySEDataTableCreator:create: "+ e );
e.printStackTrace();
}
finally
{
aModel.CommitTransaction();
myCaesamModel.getSelectionManager().selectCreatedObject
("CaesamTable_Table");
}

@Override
public JPanel getPanel()
{
JPanel aPanel = new JPanel(new BorderLayout());
myResource = UtilPackageResource.getResource(DataTablePanel.class);
myTable_TableCreator = CaesamAPI_GlobalTableCreator.
CreateTableCreator(getType());

Caesam_StringArray aArray =
CaesamAPI_GlobalTableCreator.GetPrimaryTableTypeList
(myCaesamModel.getStdModel(), myTable_TableCreator);
myComboChoice = new JComboBox( toVector(aArray));
myComboChoice.addItemListener( new ItemListener()
{
public void itemStateChanged(ItemEvent e)
{
CaesamAPI_GlobalTableCreator.SetPrimaryTableType
(myTable_TableCreator, (String) myComboChoice.getSelectedItem());
myChkSelection.setEnabled
(CaesamAPI_GlobalTableCreator.IsSelectionAvailable
(myTable_TableCreator, myCaesamModel.getTreeViewSelection()
.getStdItemArraySelection() ));
}
}
);

aPanel.add("Center",myComboChoice);
aPanel.add("South",myChkSelection);

myChkSelection.setText(myResource.getString
("LBL_RESTR_SELECTION"));
CaesamAPI_GlobalTableCreator.SetPrimaryTableType
(myTable_TableCreator, (String) myComboChoice.getSelectedItem());
myChkSelection.setEnabled
(CaesamAPI_GlobalTableCreator.IsSelectionAvailable
(myTable_TableCreator, myCaesamModel.getTreeViewSelection()
.getStdItemArraySelection() ));

return aPanel;
}

private Vector<String> toVector( Caesam_StringArray aArray )


{
Vector<String> aVector = new Vector<String>();
for ( int i=0; i< aArray.Size(); i++)
aVector.add(aArray.Get(i));

page-187
Caesam SDK | 20 Global Table Creation

return aVector;
}

Some portions of the code require an explanation…


At the beginning of the create method, you can see that we use myCaesamModel. This member is set by
the framework. Normally this member is never null.

20.3 Personalized table editor and customized toolbar

Create a personalized table editor

This section describes how to develop your own tabular editor. In your plugin, for a table creator, you
can specify a Java class that will be the editor of the table.
To do this, add the Item Key :
Key : TableEditorClass
Type : Caesam_String
Value : A class of your plugin that derived from DataTableEditor
Example :

<Item Key="TableEditorClass"
Type="Caesam_String">com.samcef.caesam.process.LoadCaseTableEditor</Item>

After that, create a class derived from DataTableEditor in your plugin.

Customize the toolbar

• Remove buttons in the toolbar


To customize the toolbar, you must redefine the method customizeToolBar. This allows you to hide
buttons with the appropriate method.

public void customizeToolBar() {


}

All methods used to hide a button start with "hide".


• Add new button in the toolbar
The method getToolbar() gives you access to the toolbar, so alowing you to easily add your own
component or actions to the toolbar.
Example : In the following example, we create a table editor that hides the print button, the export button,
the import button and adds a custom action.

@Override
public void customizeToolBar() {
this.hideImportAction();
this.hideExportAction();
this.hidePrintAction();
this.hideScreenCaptureAction();
if ( this.getToolbar() != null )
this.getToolbar().add(new MyLoadCaseTableAction());
}

page-188
20 Global Table Creation | Caesam SDK

The complete code for this example is given below :

package com.samcef.caesam.process;
import javax.swing.JOptionPane;
import javax.swing.AbstractAction;
import javax.swing.Action;
import java.awt.event.ActionEvent;
import com.samcef.caesam.resource.IconManager;
import com.samcef.caesam.table.DataTableEditor;

public class LoadCaseTableEditor extends DataTableEditor {


public LoadCaseTableEditor() {
}
/* * @see com.samcef.caesam.table.DataTableEditor#customizeToolBar() */
@Override
public void customizeToolBar() {
this.hideImportAction();
this.hideExportAction();
this.hidePrintAction();
this.hideScreenCaptureAction();
if ( this.getToolbar() != null )
this.getToolbar().add(new MyLoadCaseTableAction());
}
private class MyLoadCaseTableAction extends AbstractAction {
static final String ID = "MyLoadCaseTableAction";
public MyLoadCaseTableAction() {
putValue(Action.NAME, "MyActioName");
putValue(Action.SHORT_DESCRIPTION, "MyActionDescription");
putValue(Action.SMALL_ICON,
IconManager.getIcon("new")
);
}
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "actionPerformed on
MyLoadCaseTableAction");
}
}
}

page-189
Caesam SDK | 21 Maturity

21 Maturity
Maturity allows analysts to exchange information and work in an iterative manner.
Two new concepts have been introduced in Caesam V4. Combined with packages on page 194, these
concepts will allow a team of analysts to exchange and try out each other's results. In other words, it will
allow the use of Caesam in an iterative process. These new concepts are:
Association association between a Calculation Point (which may be a Finite Element, a Structural
Element, a Structural Element Assembly) and an Engineering Object, for a given
dataset key. One can for example define an association between a Panel and the
material Steel, for the key 'Material'. Sometimes we'll use the word 'link' as a synonym
for association, in particular for authors.
Configuration a set of associations, with a name. This name is free, but it could be something like
"Draft", "Released", "Under Validation", etc. All associations must be contained in
only one configuration. A configuration cannot contain several associations for the
same CP and dataset key. A Panel can for example be associated with Steel for
configuration ‘Released’ and with Aluminium for configuration ‘Draft’.
It is important to understand that the use of these concepts is in no way mandatory, they only offer new
possibilities to the analyst as we'll see below.

21.1 Configurations
Introduction to configurations

21.1.1 Functional Description


The basic idea behind associations is that you can have several candidate EOs for the same dataset key
of a CP. Among those candidates, only one can be used at a time on the CP: which will be referred to as
the "reference" EO. The goal is double:
• An analyst can easily select another candidate for several CPs, e.g.: use the Material defined for
configuration ‘Draft’ on all selected Panels.
• Analyses can use a given candidate, different of the one currently used by the CP. This is a way for
analyses to share an EO, without necessarily using this EO in the support CP (i.e. without influencing
other analyses). Just as for CPs, an analyst can easily select a candidate for several analyses, e.g.: for
all selected BucklingSuperStiffener analyses, use the Material defined for configuration ‘Draft’ from
its left panel.

21.1.2 Architecture Overview


A configuration is represented by a CaesamStd_Configuration object that is nothing more than an item
with a name.
An association between a CP and an EO is represented by a CaesamStd_Link object that contains the
following information: the CP and dataset key to which the association is related, the configuration and
a reference to some EO.
New methods on CaesamStd_CP will allow selecting the association to use in the CP. In the CP, the
dataset reference for a given key will point to the reference of the currently selected link.
In an analysis, the dataset reference for a given dataset item can point to:

page-190
21 Maturity | Caesam SDK

1. the reference of the support CP's dataset 2. the reference of the support CP's currently selected link 3.
the reference of another link of the support CP 4. an EO contained in the shared workspace 5. a local copy
of the EO 6. the reference of the dataset of another analysis
The support path in process templates will allow indicating a preferred association to use (cf 3).
Note that the 6th possibility is not yet implemented in author methods (and thus obviously not in the GUI),
and will maybe never be, as it's not very useful to the analyst for practical purposes. All these issues are
summarized in the following schema.

Figure 6: Possible items that an analysis data set can point to

21.1.3 Business Architecture

Configurations

A new configuration can be created with CreateConfiguration that takes the name of the new configuration.
If a configuration with this name already exists, this one is returned.

CaesamStd_Model::CreateConfiguration(theName): aConfiguration

page-191
Caesam SDK | 21 Maturity

GetLinks allows getting all links of a configuration.

CaesamStd_Configuration::GetLinks(theKey): aItemArray

IsUsed returns true if one of the links is used (see IsUsed method on CaesamStd_Link below).

CaesamStd_Configuration::IsUsed(): aBoolean

CP API

The existing methods SetReferenceEO(theKey, theEO) and AddReferenceEO(theEO) still keep the same
effect. These methods do not create any link: the reference EO is directly attached to the CP for the given
key. But if there already is a link in use on the CP, this link will get updated.

CaesamStd_CP::SetReferenceEO(theKey, theEO): aLink


CaesamStd_CP::AddReferenceEO(theEO): aLink

SetEO allows creating or updating a link, but without making it the reference. This method creates a link
for the given configuration between the CP and theEO, for the given dataset key. The key can be omitted,
in which case it is set to the EO's type name. If a link for this configuration already exists for the key, its
referenced EO is changed. The created or updated link is returned.

CaesamStd_CP::SetEO(theConfiguration, theEO): aLink


CaesamStd_CP::SetEO(theConfiguration, theKey, theEO) aLink

SetReferenceLink allows making a link the reference for a given CP and dataset key. The link can be
given directly or through its configuration and dataset key. If the passed link object is not attached to the
CP on which the method is called, an exception is raised.

CaesamStd_CP::SetReferenceLink(theLink)
CaesamStd_CP::SetReferenceLink(theConfiguration, theKey)

SetReferenceEO and AddReferenceEO are used to create/update a link and make it the reference, in one
operation. These methods are functionally equivalent to calling SetReferenceLink on the link returned
by SetEO.

CaesamStd_CP::SetReferenceEO(theConfiguration, theKey, theEO): aLink


CaesamStd_CP::AddReferenceEO(theConfiguration, theEO): aLink

GetReferenceEO returns the currently used EO for a key, whether it comes from a link or not.

CaesamStd_CP::GetReferenceEO(theKey): aEO

GetReferenceLink returns the currently used link for a given key, which could be NULL.

CaesamStd_CP::GetReferenceLink(theConfiguration): aLink

GetLink allows retrieving a link by its configuration and dataset key.

CaesamStd_CP::GetLink(theConfiguration, theKey): aLink

GetEO allows retrieving an EO by the configuration and dataset key.

CaesamStd_CP::GetEO(theConfiguration, theKey): aEO

page-192
21 Maturity | Caesam SDK

Additional methods allow knowing if a CP has links, to get the dataset keys or configurations for which
there are links, and to get all links for a given dataset key or configuration.

CaesamStd_CP::HasLinks(): aBoolean
CaesamStd_CP::GetLinkKeys(): aStringArray
CaesamStd_CP::GetLinkConfigurations(): aObjectArray
CaesamStd_CP::GetLinks(theKey): aItemArray
CaesamStd_CP::GetLinks(theConfiguration): aItemArray

CaesamStd_Link

The creation of a new link happens through the methods SetEO, SetReferenceEO and AddReferenceEO
on a CP.
Once a link has been created you can access its data as follows:

CaesamStd_Link::GetCP(): aCP
CaesamStd_Link::GetConfiguration(): aConfiguration
CaesamStd_Link::GetDataSetKey(): aKey
CaesamStd_Link::GetEO(): aEO
CaesamStd_Link::GetEORef(): aReference

SetEO allows changing the EO referenced by a link.

CaesamStd_Link::SetEO(theEO)

SetConfiguration allows changing the configuration of a link.

CaesamStd_Link::SetConfiguration(theConfiguration)

Select allows making this link the reference for its CP and dataset key.

CaesamStd_Link::Select()

IsSelected returns true if the link is currently the reference for its CP and dataset key.

CaesamStd_Link::IsSelected(): aBoolean

IsUsed returns true if the link is used in its CP, an analysis, or a CaesamEO_ByElementBySE.

CaesamStd_Link::IsUsed(): aBoolean

Paths

The method Find on CaesamStd_CP and CaesamStd_Operation accept paths that will return the currently
used link or configuration.

aLink = aCP.Find("Link[Material]")
aConfiguration = aCP.Find("Config(uration)[Material]")
aLink = aOperation.Find("Link[LeftPanelMaterial]")
aConfiguration = aOperation.Find("Config(uration)[LeftPanelMaterial]")

The methods Find and SetByPath on CaesamStd_CP also accept paths that refer to the EO for a specific
association. This can be done by adding a configuration selector just after the dataset key when referring
to an EO on a CP. If this association does not exist, it is simply ignored.

aEO = aCP.Find("EO[Material:Draft]")
aCP.SetByPath("EO[Material:Draft]", anotherEO)

page-193
Caesam SDK | 21 Maturity

Process Template

The process template can also refer to a specific association when defining the support for a given EO.
Again, if this association does not exist when the analysis is created, it is simply ignored.
Example: we have a Buckling analysis on a SuperStiffener, with a dataset key LeftPanelMaterial that
should be linked to the Draft version of the Material of the supporting panel. This is then the declaration
for the corresponding CaesamStd_DataSetItem in the process template file.

<CsmMbr_DataSetKey Type="Caesam_String">
LeftPanelMaterial
</CsmMbr_DataSetKey>
<CsmMbr_EOType Type="Caesam_String">
Material </CsmMbr_EOType>
<CsmMbr_SupportPaths Type="Caesam_StringArray">
CP/CP[LeftPanel]
</CsmMbr_SupportPaths>
<CsmMbr_EOPaths Type="Caesam_StringArray">
*EO[Material:Draft]
</CsmMbr_EOPaths>

Maturity and packages

The notion of maturity is closely related to the notion of package. Indeed, the links between some CPs
and their released EOs could be in a read-only package, while the links between the same CPs and their
draft EOs could be stored in another read/write package.
The links will by default be put into the same package as their configuration. This means that when creating
a new link or when calling SetConfiguration on a link, it will be put into the same package as the
configuration.
In the paths accepted by CaesamStd_CP::Find and CaesamStd_CP::SetObjectByPath, you can if needed
also specify the package in which the configuration can be found. The package name must be inserted
between the dataset key and the configuration name. This can be useful if there are several configurations
with the same name but in different packages:

aEO = aCP.Find("EO[Material:Package1:Draft]")
aCP.SetByPath("EO[Material:Package1:Draft]", aEO)

21.2 Packages
A package is a collection of items, such as SEs, EOs, or anything else that can be put in a Caesam model.
The Caesam framework does not enforce in any way what items can be put together in a package. It is
up to the authors and/or analysts to build packages that make sense for them. Note that an item in the
session can belong to only one package.
A package can for example represent:
• A given part of a fuselage’s structure (SEs and SEAs)
• A library of official materials
• Analyses and results from a given analyst, etc.
Packages are stored into archive files with the extension '.czp'. Such an archive contains an XML file
representing an instance of the package object, an information text file, another text file listing the
dependencies (see below), and an icon. This archive will also contain the resource files associated with
the items contained in the package. For example, if you have an HTML report attached to some analysis
in the package, this report will be saved into the czp archive.

page-194
21 Maturity | Caesam SDK

21.2.1 External References


Caesam objects stored in a given package can contain references to objects stored in other packages. One
of the main services offered by packages is the automatic handling of these so-called external references.
The external references are handled in a transparent manner, with no modification needed from the authors.
When a package is exported, if it uses objects from another package, external references are automatically
created. When the package is imported, the external references are resolved. If some packages are needed
by the imported package, they can be automatically loaded if the user selected the appropriate option, and
if they were not moved from their expected location (which is saved as an unresolved Caesam URL).
The only case where an author could be required to make some adaptations is when a there is an undesired
circular dependency between objects that need to be in separate packages.

21.2.2 Circular Dependencies


If package A has a reference to package B, and package B to package C, and package C to package A,
we have a circular dependency. Packages with circular dependencies can still be imported, but all packages
involved in the circular dependency must of course always be imported simultaneously.
Having a circular dependency can mean that the separation between packages makes no sense regarding
the business and that the packages involved in the circular dependency should be merged, or that some
objects should be put in another package.
But sometimes this circular dependency can and thus should be avoided. This was for example the case
in the framework, where an analysis knows the CP it is built upon, but where the CP also knows the list
of analyses that are using it. This implies an undesired circular dependency if we try to put the CPs and
the analyses in different packages. We indeed don’t want to be forced to import the package containing
analyses when we import the package containing CPs.
The solution is simple: the member of CP holding the list of operations has to be declared transient, and
must be filled in the CaesamStd_Operation::AfterRetrieval method (this can also be done in the
AfterRetrieval process of the related plug-in).

21.2.3 CPs and associations


A special case where a circular dependency must be avoided is between CPs and their associations.
Imagine a package containing CPs and a package containing associations defined on these CPs. Of course,
the package containing associations cannot be loaded without the CPs (an association doesn't make sense
without its CP).
But when we import the package containing CPs, we do not want the package containing associations to
be loaded. In other words, we don’t want to keep in this package the information of which associations
were used by the CPs.
Thus, when a package containing CPs is exported, and if the CPs currently use some associations that are
in another package, any external dependence to the package containing associations is broken. The first
time a package containing an association for a given CP and dataset key is imported, this association will
become the active one.

21.2.4 Example for Maturity


What an analyst typically will do is to propose an EO to be attached to a given CP. The EO can come
from an official EO library, or it can be a customized EO created by the analyst. In the latter case, the
customized EO is stored in the analyst package. The proposed association between the CP and the EO
will always be in the analyst package.
A possible situation could involve following packages:

page-195
Caesam SDK | 21 Maturity

• 'Official Material Library': contains all official materials (steel etc.)


• 'A/C Section 12 Roof Reference': contains all CPs (SEs and SEAs) that make up the 12th section of
the fuselage roof. It also contains the released associations between these CPs and the official EOs.
• 'A/C Section 12 Roof User Draft': contains the draft workspace of some analyst working on the 12th
section of the fuselage roof. It can contain draft EOs, draft associations between CPs and official or
draft EOs, and analyses.
Such a situation is illustrated in the figure below.

Figure 7: Example Packages

If a Caesam user imports package 'A/C Section 12 Roof Reference’, the package 'Official Material Library'
must also be imported because the loaded package contains associations referencing EOs from the official
library. In an analogous manner, if a Caesam user loads package ' A/C Section 12 Roof User Draft’, both
packages 'A/C Section 12 Roof Reference' and 'Official Material Library' must also be loaded.
If a Caesam user loads the package 'A/C Section 12 Roof Reference’, only released associations will be
loaded and selectable in the property view. If the user loads the package ' A/C Section 12 Roof User Draft',
both released and draft associations will be selectable.

21.2.5 Kernel Architecture


A new object is introduced at the kernel level: Caesam_ExternalReference. Such a reference contains an
UUID, allowing the identification of the referenced object, as well as the object’s type name.

page-196
21 Maturity | Caesam SDK

Any member or array, map or matrix item can be replaced by an external reference. To allow using external
references without modifying any plug-in code, we do the following:
• IsKindOf & IsInstanceOf applied on an external reference check the referenced object’s type name
• SetMember called with an external reference does never use the registered setter

21.2.6 Business Architecture


A new type is defined in XML: CaesamStd_PackageReference that inherits from
Caesam_ExternalReference, and simply adds a member containing the referenced package name. A new
type CaesamStd_Package is defined. Classes CaesamStd_Model and CaesamStd_Package have a common
superclass: CaesamStd_ItemCollection. A czp archive contains an XML file that represents an instance
of CaesamStd_Package. The possible operations on a package are detailed below.
• Creating a package on page 197
• Creating packages by walking down items on page 197
• Managing the contents of a package on page 198
• Accessing the contents of a package on page 198
• Exporting a package on page 198
• Python module for getting information about exported packages on page 199
• Importing a package on page 199
• Importing several packages simultaneously on page 200
• High-level task for importing packages on page 200

Creating a package

CaesamStd_Model::CreatePackage(thePackageName, thePackageUrl): aPackage


CaesamStd_Model::CreatePackage(thePackageName,
thePackageUrl,
theFilter): aPackage
CaesamStd_Model::CreatePackage(thePackageName,
thePackageUrl,
theTypes,
theMatchAllTypes=False): aPackage

When creating a package, you must give a name and URL. The URL is needed so that packages that
would reference this package before it is saved can have the chance to know where it will be stored. The
last two versions of CreatePackage are shortcuts for creating and filling a package in one operation (see
Fill method below in Managing the contents of a package).

Creating packages by walking down items

CaesamStd_Model::CreatePackages(theItems,
theDispatchRequests,
theWalkDownItems)

This method can be used to create one or several packages by starting from the given items, walk them
down by following members and containers (arrays, matrices and maps), and dispatching the found items
that are not in some package yet. If theWalkDownItems is false, only the items will be dispatched, not
their members etc.
The dispatch requests must be put into an object array containing objects of the type:

<TypeDesc Name="CaesamStd_PackageDispatchRequest">
<Member Name="PackageName" Type="Caesam_String"/>
<Member Name="PackageUrl" Type="Caesam_String"/>

page-197
Caesam SDK | 21 Maturity

<Member Name="PackageFilter" Type="CaesamStd_AbstractItemFilter"/>


</TypeDesc>

Dispatching an item means browsing the dispatch requests: the item goes into the first dispatch request
whose filter accepts it.

Managing the contents of a package

CaesamStd_Package::Put(theItem)
CaesamStd_Package::Remove(theItem)
CaesamStd_Package::Clear() CaesamStd_Package::Fill(theFilter,
theStealItems=False)
CaesamStd_Package::Fill(theTypes,
theMatchAllTypes=False,
theStealItems=False)

An item can be put in the package using the Put method. You can also fill the packages with all items of
the session that match a given filter. If the parameter theStealItems is set to true, items that are already in
a package are moved to this package.
A shortcut is provided to add all items of the given types, e.g.:
• adding all Panels and Stringers:

aPackage.Fill("Panel;Stringer")

• adding all EOs except load cases:

aPackage.Fill("CaesamStd_EO;~CaesamStd_LoadCase", True)

If you need more complex filter combinations, you can manually build and combine your filters. For
example, let's say you want to add all EOs, except load cases, but well unitary load cases:

f1=CaesamStd_UserTypeFilter.
GetCompoundUserTypeFilter("CaesamStd_EO;~CaesamStd_LoadCase",True)
f2=CaesamStd_UserTypeFilter.
GetCompoundUserTypeFilter("CaesamLC_UnitaryLoadCase")
aFilter=CaesamStd_CompoundItemFilter(False)
aFilter.AddFilter(f1) aFilter.AddFilter(f2)
aPackage.Fill(aFilter)

Accessing the contents of a package

CaesamStd_Package::GetContent(theFilter): CaesamStd_ItemArray
CaesamStd_Package::GetFirstContent(theFilter): CaesamStd_Item

The GetContent method allows retrieving the list of all items that match a filter (a null filter retrieves all
items). The GetFirstContent returns the first matching item.

Exporting a package

CaesamStd_Package::Export() CaesamStd_Model::ExportPackage(thePackage)

Exporting a package means:


• Replacing all objects that are stored in other packages by a CaesamStd_PackageReference
• Saving the package to a XML file put in czp archive

page-198
21 Maturity | Caesam SDK

Export proceeds as follows:


• Starts from the items contained in the package and walk down members and container items
• For each object A, we decide what to do with it
• if A is in the package being exported, we go on (if A is an EO from the shared workspace, we also
take note of the subdirectory in which it has been put)
• owner = first owner of A that has been explicitly put in a package (can of course not exist)
• if A or its owner has been put in another package, we replace it by an external reference
• otherwise we take it with us and, if A belongs to the model, we add it to the additional items
• Dependencies are stored in a member of the package object (number of external references by package
then by type name). These dependencies can be accessed with the following methods on
CaesamStd_Package:

GetDependentPackages(): aPackageNames
GetDependentPackageUrl(thePackageName): aPackageUrl
GetDependenciesByType(thePackageName): aObjectMap

• The package instance is saved to a temporary XML file which is zipped into a czp archive
• A text file PackageInfo.txt is also put into the czp archive. This file contains the name of the package
and the list of all packages it depends on. For each package it depends on, we also give: the expected
URL and the number of referenced objects by type. This file can be used for showing information
outside Caesam about the dependencies of a package.

Note: that if you create only one package, and you export it, it will never have any external
dependencies. But if you create a second package after exporting the first one, and export
the first again, it then maybe will have external references to the second one.

Python module for getting information about exported packages

The ExportPackageHelper python module (from CsmPython import ExportPackageHelper) contains 3


useful functions for getting information about exported packages.

ExportPackageHelper.GetPackageInfo(thePackage):

returns a string containing information about the package URL, its items and additional items and the
external dependencies.

ExportPackageHelper.GetCyclesAndTree(theStdModel, theExportedPackageNames):

returns a string containing information about the possible circular dependencies detected between the
exported packages, as well as the tree of dependencies.

ExportPackageHelper.ShowCyclesAndTree(theProcessModel,
theExportedPackageNames):

displays the information returned by GetCyclesAndTree using the Process_Model::PutMessage method.

Importing a package

CaesamStd_Model::ImportPackage(thePackageUrl,
theOnCollision,
theCreateDirectories,
theReadOnly): aPackage

Importing a package means:


• Loading the package from a XML file.

page-199
Caesam SDK | 21 Maturity

• Resolving all external references (i.e. replace with the corresponding object). If some external references
could not be resolved, a Caesam_RunTimeException is raised, containing a
CaesamStd_UnresolvedReferencesStatus, that itself contains the list of missing packages.
• Putting loaded items in the session model. The EOs that were shared are put back into the shared
workspace, in their original subdirectory if any. If theCreateDirectories is true, the method will also
create a subdirectory for the other imported items (SEs, SEAs, analyses and groups).
Sometimes a collision can occur (an item in the imported package and an item in the session have the
same UUID). This can happen if two packages with common items have been created and are later imported
in a same session. When a collision occurs, the parameter theOnCollision indicates what to do:
• ‘STOP’: stop with an exception
• ‘KEEPCURRENT’: replace the package item with the one in the session
• ‘REPLACECURRENT’: replace the existing session item with the one from the package
• ‘DUPLICATEIMPORTED’: make them two distinct items (i.e. duplicate the package item)
If the parameter theReadOnly is true, the imported package itself and all its items are flagged with
Caesam_Instance_READ_ONLY. Caesam makes the following verifications, regarding this flag:
• You cannot edit a read-only EO (nb: custom editors must check this with EditorData.IsEditable).
• You cannot rename a read-only item
• You cannot delete a read-only item or package
• You cannot replace the EO used by a read-only association
• You cannot add/remove associations to/from a read-only configuration
• You cannot add/remove items to/from a read-only package
• Read-only packages are ignored by the tasks ‘Export All/Selected Packages’

Importing several packages simultaneously

CaesamStd_Model::ImportPackages(theImportRequests): aPackages

You can specify several packages to import simultaneously in an array. This is especially useful if you
need to import packages that present a circular dependency. The import requests must then be put into an
object array containing objects of the type:

<TypeDesc Name="CaesamStd_PackageImportRequest">
<Member Name="PackageUrl" Type="Caesam_Url"/>
<Member Name="OnCollision"
Type="CaesamStd_PackageImportRequest_OnCollision"/>
<Member Name="CreateDirectories" Type="Caesam_Boolean"/>
<Member Name="ReadOnly" Type="Caesam_Boolean"/>
</TypeDesc>

High-level task for importing packages

The task python:csm:com.samcef.caesam.packages/python/Task_ImportPackages can be used to import


a list of packages. This task takes a parameter of the type:

<TypeDesc Name="Argument_ImportPackages">
<Member Name="AutoLoad" Type="Caesam_Boolean"/>
<Member Name="Packages" Type="Caesam_TypedArray"/>
</TypeDesc>

The member ‘AutoLoad’ allows specifying if you want to automatically load packages on which the
imported packages depend. The member ‘Packages’ is an array that must contain the import requests
(similar to the ones that must be passed to the method ImportPackages described above), i.e. objects of
the type:

<TypeDesc Name="Argument_ImportPackage"
Inherits="CaesamStd_PackageImportRequest">
</TypeDesc>

page-200
21 Maturity | Caesam SDK

Examples of Packages
Package creation commands must be adapted to the specific iterative process that the packages will
be used in.
Two sample package creation tasks are defined in the plug-in com.samcef.caesam.test.packages
(start Caesam with -examples). These tasks are good examples for authors to see how to use packages,
but they are also fully functional. These tasks are available in menu Maturity/Examples.
• Create Package from Selection :
Creates a package containing the items selected in the SM tree. This task takes as argument a
package name and an URL. If the package name is already used, the existing package is updated.
Also available in the popup menu of a SM tree selection.
• Create Packages by Type :
Creates one or several packages containing all items of the given types. This task takes as argument
an array of (PackageName, PackageUrl, Types, MatchAllTypes), and corresponds to the method
Fill described above. When a package name is already used, the existing package is updated. If
an item was already in a package, it is not influenced.

page-201
Caesam SDK | 22 FEM

22 FEM
This chapter describes different aspects of working with an FEM (Finite Elemetn Model) in Caesam.

22.1 FEM Topology


The classes in the CaesamTopology Package are used to define a finite element mesh
(CaesamTopology_Mesh, CaesamTopology_Node et CaesamTopology_Element).
Internally, the mesh element is stored in an object called CaesamTopology_Mesh. This class contains the
list of nodes and the list of finite elements.
A node (CaesamTopology_Node) is defined by an identifier (> 0) and the three coordinates (X,Y,Z). An
element is defined by an ordered list of nodes and an identifier (>0). In the current version, three types
of topology exist for defining an element (Line : 2 nodes, Triangle: 3 nodes, Quadrangle: 4 nodes)

The object CaesamTopology_Mesh is used by CAESAM to hold and draw the finite element.
This object is also used to represent the topology of the structural elements (SEs) using the methods
SetTopology() and GetTopology() of the class CaesamStd_SE.

22.2 Relation with the Stress Model


This is shown in the Figure below

page-202
22 FEM | Caesam SDK

To make the connection between the finite element mesh and the stress model three types of object are
used:
• The mesh CaesamTopology_Mesh can be recovered via the EO CaesamStd_GFEM related to the
model via the global model (CP) CaesamStd_GlobalModel
• Each Calculation Point (CP) of the type CaesamStd_Element has a link to the topology of the elements
(see the methods SetElement() and GetElement())
• The CaesamEO_FEMLink object allows you to make an association between an SE and the list of
finite elements that refer to that SE
• The CaesamEO_ByElementBySE object allows you to associate a different EO to every finite element
associated with an SE.

22.3 Involved classes


The following diagram shows the relations between the involved classes defined in the framework.

page-203
Caesam SDK | 22 FEM

CaesamEO_FEMLink

This object inherits from CaesamStd_EO. It is used to describe the small mesh, which is behind the SE.
It makes the link between a SE and the list of finite elements used by this SE (it associates a list of
CaesamStd_Element to a CaesamStd_CP). Some tools are implemented to retrieve all nodes, the corner
nodes, the elements …

CaesamEO_UseFEMLink

A new abstract EO type is introduced in the framework: CaesamEO_UseFEMLink. This EO should serve
as the base class for all EOs that are related to a CaesamEO_FEMLink.
The framework EO CaesamEO_ByElementBySE is one example. The composite EOs PanelDivision,
PanelDivisionLoad and PanelDivisionLaminate should also inherit from CaesamEO_UseFEMLink.
When an EO inherits from CaesamEO_UseFEMLink, the framework is able to:
• Warn the EO when the related FEMLink is modified. To achieve this, the EO (e.g. PanelDivision)
should define and implement a Caesam method called “FEMLinkModified”, taking no argument.
• Know that this EO should maybe follow some specific rules. For example:
• EO Shared Workspace: these EOs should be shared in the workspace, because they are related a
specific FEMLink, and thus to a specific SE or CP.
• Packages: for the same reason, when a baseline or user packages are created, these EOs should not
be put in the same package as other EOs (such as materials and profiles).

Note: Note that since version 4.1.2, EO’s inheriting from CaesamEO_UseFEMLink can
be used with configurations, as any other EO.

CaesamEO_ByElementBySE

We just saw that CaesamEO_ByElementBySE is an example of EO inheriting from


CaesamEO_UseFEMLink. The goal of CaesamEO_ByElementBySE is to associate an EO of a given
type to each finite element behind a SE or CP.
For a given element, the associated EO can be:
• a local EO
• an EO contained in the shared workspace
• following the element: whatever EO is used by the element, we follow
• following a specific configuration defined on the element

page-204
22 FEM | Caesam SDK

Note: Note that in version 4.1.2 the first possibility is not yet made possible by the GUI
editor.

22.4 Business Architecture

CaesamEO_FEMLink API

The main methods are:

AddElement(theCaesamStd_Element)
GetElements() returns ArrayOfCaesamStd_Element
GetElement(theElementID) returns CaesamStd_Element

For more methods, refer to the cdl documentation available from the Help menu in the user interface.
(CaesamEO_FEMLink.cdl)

CaesamEO_UseFEMLink API

The methods SetEOFEMLink and GetEOFEMLink allows setting and getting the associated
CaesamEO_FEMLink.

CaesamEO_ByElementBySE API

All methods described below:


• are also registered as Caesam methods
• take an argument theElement which can be: a CaesamStd_Element, a CaesamTopology_Element or
an integer.
In methods SetEO and LinkToElement, if theElement is passed as a CaesamTopology_Element and the
corresponding CaesamStd_Element does not exist in the CaesamEO_FEMLink, it is created.
SetEO allows you to assign either a local EO or an EO from the shared workspace to a given element of
the FEMLink. If the passed EO is not local and is not coming from the shared workspace, a warning will
be displayed.

CaesamEO_ByElementBySE::SetEO(theElement, theEO)

SetEOForAllElement allows assigning the same local EO or shared EO to all elements of the FEMLink.

CaesamEO_ByElementBySE::SetEOForAllElement(theEO)

LinkToElement allows linking the EO for a given element to the EO currently used in the dataset of the
CaesamStd_Element (with the dataset key being the declared EO type). If the EO used in the dataset of
the element is modified or replaced with another EO, it will follow. If the CaesamStd_Element has no
EO for the dataset key being the declared EO type, this method has no effect.

CaesamEO_ByElementBySE::LinkToElement(theElement)

LinkToElement can also take an additional parameter, which indicates a specific configuration. This
allows linking the EO for a given element to the EO associated with the CaesamStd_Element for this
configuration (with the key being the declared EO type). If the EO associated with the element for this
configuration is modified or replaced with another EO, it will follow. If the CaesamStd_Element has no
associated EO for the given configuration, this method has no effect.

CaesamEO_ByElementBySE::LinkToElement(theElement, theConfiguration)

page-205
Caesam SDK | 22 FEM

LinkToElementForAllElement allows linking to the EO in the CaesamStd_Element, for all elements of


the FEMLink.

CaesamEO_ByElementBySE::LinkToElementForAllElement()
CaesamEO_ByElementBySE::LinkToElementForAllElement
(theConfiguration)

GetEO returns the EO assigned to a given element of the FEMLink. This will return the EO, whether it
is a local one, a shared one or coming from the element’s dataset or associations.

CaesamEO_ByElementBySE::GetEO(theElement): aEO

GetEOs returns the EOs assigned to each element of the FEMLink, in an array.

CaesamEO_ByElementBySE::GetEOs(): aEOArray

IsLinkedToElement enables you to know if the EO is linked to the EO used in the dataset of the
CaesamStd_Element, or to the EO associated with the CaesamStd_Element for the given configuration.

CaesamEO_ByElementBySE::IsLinkedToElement(theElement): aBoolean
CaesamEO_ByElementBySE::IsLinkedToElement(theElement, theConfiguration):
aBoolean

SetEO also has a second signature, that makes a reference to an EO (*CaesamStd_EO). This method
allows linking the EO for a given element to some other EO. This method is reserved for advanced use
only. The methods LinkToElement should indeed cover common use.

CaesamEO_ByElementBySE::SetEO(theElement, theEORef)

GetEOReferenceOwner will return the owner of the reference we are pointing to, for a given element.

GetEOReferenceOwner(theElementNumber): aItem

This owner can be:


• The CaesamEO_ByElementBySE itself, if the EO is local or from the shared workspace.
• The corresponding CaesamStd_Element, if LinkToElement has been used without giving a specific
configuration.
• A CaesamStd_Link defined on the CaesamStd_Element, if LinkToElement has been used with a
specific configuration
• Anything else, if SetEO taking a reference has been used directly.

page-206
23 Display tools | Caesam SDK

23 Display tools
This chapter describes how an author can associate a 3D graphic to SE, SEA and EO and how to create
a 3D View in your own EO editor.
You can associate two types of drawing with an SE:
• A simplified, rapid drawing of a finite element type (Line, Triangle, Quadrangle) by using the classes
CaesamTopology_Node, CaesamTopology_Element and CaesamTopology_Mesh
• A more complex drawing by installing a graphic driver associated with the SE. For that you need to
write and implement a class which inherits from the class CaesamPrsStd_Driver or to use a predefined
driver supported by the Caesam platform (Iges, Step or BRep file)
When associating a drawing with other types of CP or the EO, it is also possible to associate a graphic
driver to them as is the case for the SE. The analyst can activate the advanced graphic using the menu
"Display/Custom Representation".

23.1 Associating a simplified graphic with an SE


You can associate a representation of the finite element type associated with the SE to the stress model.
In the same way as for a finite element mesh you can associate an CaesamTopology_Element element
with each SE. These elements are saved in CaesamTopology_Mesh (See FEM Topology on page 202).
This object Mesh is associated with the stress model via CaesamStdt_GlobalModel and the EO
CaesamStd_SETopology.
To associate an element with an SE, use the method SetTopology(theTopologyElement) of the class
CaesamStd_SE.

page-207
Caesam SDK | 23 Display tools

23.2 Using a predefined graphic driver


In the current version, three graphic drivers are available on the platform for drawing a CP (SE, SEA or
a Global Model) or an EO. These three drivers allow you to draw a file of types BRep, IGES or Step at
the location of the CP or the EO.
To associate a driver it is necessary to add the resource “DisplayDriver” to the definition of the class in
the plugin.xml file. This resource specifies the URL of the file that contains the name of the IGES, BREP
or Step file.
An example of resource in the plugin.xml is given below.

<Item Type="PluginClass">
<Class Type="Caesam_String">Panel</Class>
<Resources Type="Caesam_ObjectMap">
<Item Key="DisplayDriver"
Type="Caesam_Url">csm:com.samcef.caesam.test.transverse
/resources/display/PanelDisplayDriver.csm</Item>
</Resources>
</Item>

The referenced file describes the type of driver used and associated data.

<Instance Type="CaesamPrsStd_BRepFile">
<File Type="Caesam_File">
<MimeType Type="Caesam_String">model/brep</MimeType>
<Url
Type="Caesam_Url">csm:com.samcef.caesam.test.transverse/resources/display/Panel.brep</Url>

</File>
<Material Type="Caesam_String">GOLD</Material>
</Instance>

The three types of driver available are:


• CaesamPrsStd_BRepFile: which allows you to associate a BRep file with a CP or an EO
• CaesamPrsStd_IgesFile: which allows you to associate an IGES file with a CP or an EO
• CaesamPrsStd_StepFile: which allows you to associate an Step file with a CP or an EO
These three types of file can be created using a programme such as SAMCEF Field.
The <File> tag, specifies the URL of the associated file. The <Material> tag specifies the colour
associated with the drawing.
The available colours are:
• "DEFAULT”
• "BRASS”
• "BRONZE”
• "COPPER”
• "GOLD”
• "PEWTER”
• "PLASTER”
• "PLASTIC"
• "SILVER"
• "STEEL"
• "STONE"
• "SHINY_PLASTIC”
• "SATIN"
• "METALIZED"

page-208
23 Display tools | Caesam SDK

• "NEON_GNC"
• "CHROME"
• "ALUMINIUM"
• "OBSIDIAN"
• "NEON_PHC"
• "JADE"
If an object of the type CaesamEO_CoordSystem is associated with the CP (SE, SEA) then the driver
uses this coordinate system in the placement of the graphical representation. Thus it is possible to create
a graphical object at the origin and then to place it in the correct position using the coordinate system
associated with the SE or the SEA.
The Coordinate system associated with an EO is the same the system belonging to the SE or the SEA to
which the EO is applied.

23.3 Create your own graphic driver


An author can also associate his own graphic driver with a CP (SE, SEA, GlobalModel) or with an EO.
In order to do this, you must develop and implement a class that inherits from the class CaesamPrsSt_Driver
and most importantly the Update() method.

Example The driver CaesamPrsStd_CoordSystem associates the type CaesamEO_CoordSystem to an


EO.

#include <CaesamEO_CoordSystem.hxx>
#include <FEATools_AISTrihedron.hxx>
#include <CaesamStd_Link.hxx>
//===========================================================
//function : Update
//purpose : ======================================
Standard_Boolean CaesamPrsStd_CoordSystem::Update (const Handle(Caesam_Object)&
theObject,
Handle(AIS_InteractiveObject)& theAIS)
{
cout
<<"CaesamPrsStd_CoordSystem::Update:theObject="<<theObject->GetTypeName();
if(theObject.IsNull()) return Standard_False;
if(!theObject->IsKindOf("CaesamStd_Link")) return Standard_False;
cout <<"CaesamPrsStd_CoordSystem::Update:After KindOf"<<endl;

Handle(CaesamStd_Link) aLink=CaesamStd_Link::Cast(theObject);
if(aLink.IsNull()) return Standard_False;

Handle(CaesamEO_CoordSystem)
aCoordSystem=CaesamEO_CoordSystem::Cast(aLink->GetEO());
if(aCoordSystem.IsNull()) return Standard_False;

Handle(FEATools_AISTrihedron) aAIS=new
FEATools_AISTrihedron(aCoordSystem->GetCoordSystem());

page-209
Caesam SDK | 23 Display tools

if (!theAIS.IsNull()) {
aAIS->SetDisplayMode(theAIS->DisplayMode());
}
else {
aAIS->SetDisplayMode(0);
}
cout <<"CaesamPrsStd_CoordSystem::Update:end"<<endl;
theAIS = aAIS;
return Standard_True;
}
//===============================================================
//function : CaesamPrsStd_CoordSystem //purpose :
//===============================================================
CaesamPrsStd_CoordSystem::CaesamPrsStd_CoordSystem() {
SetClass(GetRegisteredClass()); }

//===============================================================
//function : Register //purpose :
//===============================================================

void CaesamPrsStd_CoordSystem::Register(const Handle(Caesam_Registry)&


theRegistry)
{
theRegistry->RegisterClass(GetRegisteredClass());
}
//===============================================================
//function : GetRegisteredClass
//purpose :
//===============================================================
Handle(Caesam_Class)
CaesamPrsStd_CoordSystem::GetRegisteredClass()
{ static PTRMEM(Caesam_Class) aClass = new
Caesam_Class("CaesamPrsStd_CoordSystem ",
CaesamPrsStd_Driver::GetRegisteredClass(),
CaesamPrsStd_CoordSystem::NewInstance,
NULL);
return aClass; }

//===============================================================
//function : NewInstance //purpose :
//===============================================================
Handle(Caesam_Object) CaesamPrsStd_CoordSystem::NewInstance(const
Handle(Caesam_Object)& theObject)
{
if (theObject.IsNull()) {
PTRMEM(Caesam_Object) aCoordSystem = new CaesamPrsStd_CoordSystem();

CSMCAST(CaesamPrsStd_CoordSystem, aCoordSystem)->InitInstance();
return aCoordSystem;
}
//==============================================================
//function : //purpose :
//==============================================================
void CaesamPrsStd_CoordSystem::InitInstance()
{ CaesamPrsStd_Driver::InitInstance();
}

The method Update, gets the object to the drawn and creates a graphical object of the type
AIS_InteractiveObject from the graphical library of Open-Cascade.
An object of the type AIS_InteractiveObject can be created using the tools available from Open-Cascade.
For example a Box can be created using the following classes.

BRepPrimAPI_MakeBox aBox(100.,100.,300.);
Handle(AIS_Shape) anAISShape = new AIS_Shape(aBox.Shell());

page-210
23 Display tools | Caesam SDK

In the case of an EO the returned object is a CaesamStd_Link. This object contains the EO to be represented
as well as the support (SE, Element, SEA) on which it must be drawn. An EO can actually be represented
on several supports. The driver is associated with the class via the resource “DisplayDriver” specified in
the plugin.xml file.

<Item Type="PluginClass">
<Class Type="Caesam_String">CaesamEO_CoordSystem</Class>
<Resources Type="Caesam_ObjectMap">
<Item Key="Editor"
Type="Caesam_String">com.samcef.caesam.editors.CaesamEOCoordSystemEditor</Item>

<Item Key="EOCreationPath" Type="Caesam_String">/Axis/</Item>


<Item Key="DisplayDriver"
Type="Caesam_String">CaesamPrsStd_CoordSystem</Item>
</Resources>

23.4 Create your own graphic 3D display in your EO Editor


It is also possible for an author to create a 3D graphical representation of an EO in the EO editor driven
by the use of graphical libraries provided by Open-Cascade.
To do this follow the steps below.
1. Create a Java component containing the 3D view.

import com.samcef.caesam.dialog.display3d.Display3dComponent;
Display3dComponent aDisplay3d = new Display3dComponent();
aTabbedPane.add("3D", aDisplay3d);

2. Each time that the drawing must be updated, call a method on one of the objects by passing 3D
CaesamDisplay_Viewer3D

myEditorData.CallMethod("Display3d",myDisplay3d.getDisplayer());
// add data visualization
myDisplay3d.fitAll();
// Fits all data visualizations to view and updates view.

3. Implement a method in C++ that updates the 3D graphical window.

example: draw a box for a profile.

PTRMEM(Caesam_Boolean)
ProfileRectangle::Display3d(PTRARG(Caesam_Object) theDisplayer)
{
Standard_Real aHeight=myHeight->GetQuantityValue();
if(aHeight<=Precision::Confusion())
aHeight=1;//Just to display something
Standard_Real aWidth=myWidth->GetQuantityValue();
if(aWidth<=Precision::Confusion())
aWidth=1;//Just to display something
BRepPrimAPI_MakeBox aBox(aHeight,aWidth,Max(aHeight,aWidth)*2);
Handle(AIS_Shape) aShape = new AIS_Shape(aBox.Shell());
aShape->SetDisplayMode(AIS_Shaded);
// aShape->SetMaterial(Graphic3d_NOM_SILVER);
Handle(CaesamDisplay_Viewer3D) aViewer3D =
CSMCAST(CaesamDisplay_Viewer3D, theDisplayer);
aViewer3D->Reset(); // remove all already displayed objects
aViewer3D->Show(aShape);

page-211
Caesam SDK | 23 Display tools

return new Caesam_Boolean(Standard_True);


}

This example can be found in the plugin com.samcef.caesam.test.transverse

page-212
24 Batch Tools | Caesam SDK

24 Batch Tools
This chapter covers the use of Caesam functionalities inside python scripts in general, and batch scripts
in particular. Note that, although we focus on python scripts, all functionalities can also be used from
C++ or Java.
We will also have a look at the batch managing system dedicated to launching some batch scripts written
in Python. As we already know, all Caesam kernel classes (package Caesam), business classes (packages
CaesamStd, CaesamEO, CaesamLC...), and some API classes (package CaesamAPI) are exported as a
native python module (CaesamAPI.py), allowing authors to use them in their Python scripts, which can
be used as registered Caesam methods, analyses or model processes.
Beyond that, authors can also write standalone python scripts (and C++ or Java applications) to use Caesam
in batch mode. This implies that Caesam must provide high-level batch-oriented functionalities. This is
the goal of the CaesamScript package, which gives the possibility to the script author to do whatever can
be done inside an interactive session. Note that some functions are still missing in CaesamScript, mainly
the multi-editing of EOs.
An important goal of the Caesam batch-scripting interface is simplicity. It must be usable by analysts
with little or no programming experience (in particular object oriented programming).

Note: That CaesamScript is not solely intended for batch scripts, but can also be used for
all kinds of scripts.

It can for example be used in scripts called when a task is invoked from the GUI (in the new task plug-in
system, see Interface definition on page 226). In this case, CaesamScript allows the script author access
to the current GUI selection.

24.1 Programming Interface


Batch functionalities are available from python simply by importing the native CaesamAPI module: from
CaesamAPI import *. Functionalities are divided into a number of classes, each one taking care of a
certain type of tasks. All functions can be called in python in two ways: using the full notation
CLASS.FUNCTION, or with the equivalent shortcut CS_FUNCTION. These functions (in fact static
methods) can also be used from C++ (CLASS::FUNCTION) and Java (CLASS.FUNCTION). Below is
the complete definition of the batch interface. Optional parameters are put into brackets.

24.1.1 Retrieving command line arguments


A simple function is available to be able to retrieve “named” argument from the command line. By named
argument we mean an argument starting with a “-“ and a name. These argument can be used alone, or
paired with a value. For example you could use a “-debug” flag and a “-precision” argument that takes
an additional value. The method to use is:

GetCommandLineArgument(theArgumentName)

“theArgumentName” is the argument as it is used in the command line (e.g. “-debug”).


The return value is:
• None if the argument is not present on the command line
• True if the argument is present on the line but is not followed by a value
• The value following the argument if there is a value.

page-213
Caesam SDK | 24 Batch Tools

24.1.2 Starting and closing the application: CaesamScript_Application

StartApplication(): boolean

Starts the Caesam application and loads all plugins. This is optional, as the application is anyway started
when you first create or load a document.

CloseApplication(): boolean

Closes the application and all open documents. This is optional, as the application and the open documents
are anyway closed when the process ends.

24.1.3 Creating, opening and saving a session : CaesamScript_Document


You can create, open and save a document (a czm file) through the following simple methods. These
methods can take an optional directory, used for storing temporary files (default is the current directory).
The user must of course have read/write rights on this directory. This directory can be given as an url
using caesam contexts (csm:userhome) and/or environment variables (file:$HOME).

NewDocument([theTempDir]): aModel

Create an empty model.

LoadDocument(theUrl[, theTempDir]): aModel

Load a model from a czm document.

CloseDocument(theModel): boolean

Close the document: the document’s temporary directory is deleted, as well as the external files directory
if it is empty.

Note: When the batch process exists, all documents that are still open are automatically
closed.

SaveDocument(theModel[, theUrl][, theTempDir]): boolean

Save the model in a czm file. Directories are created on the file system if needed. If no url is given, the
loaded document is overwritten (if we are saving a new document, the url must be given).
If there are some external files attached to the document, they are copied in the same directory as the
target file.

24.1.4 Selecting items from criteria : CaesamScript_Selection


You can select items by similar criteria as those provided by the SM tree filters in the GUI. All selection
methods return a selection object than can be used as an input for almost all other methods.

page-214
24 Batch Tools | Caesam SDK

All selection methods take an argument theSource, which can be either a model or an existing selection.
This allows applying several filters in a chain. You can also combine selections with operators +(union),
-(difference) and *(intersection).

SelectByName(theSource, theName[, theExactMatch]): aSelection

Get all items whose name contains theName, if theExactMatch is false or omitted. If theExactMatch is
true, the item name must be equal to theName.

SelectByType(theSource, theTypeNames[, theAcceptSubTypes]): aSelection


theTypeNames

is a ;-separated list of type names. This method will get all items whose type is equal to or inherits from
one of these type names, if theAcceptSubTypes is true or omitted.
If theAcceptSubTypes is false, the item’s type must be exactly equal to one of these type names.

SelectNotYetComputedAnalyses(theSource[, theTypes]): aSelection

Get all analyses that have never run. Analysis types (a ;-separated list of process templates) are optional.

SelectFailedAnalyses(theSource[, theTypes]): aSelection

Get all analyses that have run but have failed. Analysis types are optional.

SelectOutofdateAnalyses(theSource[, theTypes]): aSelection

Get all analyses that have succeeded but are no more up to date. Analysis types are optional.

SelectUptodateAnalyses(theSource[, theTypes]): aSelection

Get all analyses that have succeeded and are still up to date. Analysis types are optional.

SelectToBeComputedAnalyses(theSource[, theTypes]): aSelection

This function is equivalent to

SelectNotYetComputedAnalyses + SelectFailedAnalyses + SelectOutofdateAnalyses.


Select(theSource, theFilter): aSelection

This is a general selection method that keeps all items that pass a given filter, which must be an instance
of any class inheriting from CaesamStd_AbstractItemFilter. It can be null (None in python), in which
case all items are returned. You can combine filters by using a CaesamStd_CompoundItemFilter
(AND/OR/XOR).

24.1.5 Creating SEAs : CaesamScript_SEA


You can create a SEA on some selected CPs.

CreateSEA(theModel, theSEAType, theSelection[, theName]): aSelection

Create a SEA of the given type on the CPs contained in the selection. The returned selection contains the
created SEA.

page-215
Caesam SDK | 24 Batch Tools

If the selected CPs cannot be used to create a SEA of the required type, an error is displayed and the
returned selection is empty.
A unique name will be created for the SEA, based on the given one. The name is optional: if not given,
the SEA type is used.

24.1.6 Creating and running analyses : CaesamScript_Analysis


You can create standalone analyses and analyses on existing CPs.

CreateStandaloneAnalysis(theModel, theType [, theName]): aSelection

Create a standalone analysis of the given type. The returned selection contains the created analysis. A
unique name will be created for the analysis, based on the given one. The name is optional: if not given,
the typename (process template) is used.

CreateAnalyses(theModel, theType, theSelection[, theName]): aSelection

Create an analysis of the given type on each CP contained in the selection. The returned selection contains
the created analyses. If the passed selection contains objects other than CPs, or CPs incompatible with
the process template, they are just ignored. A unique name will be created for each analysis, based on the
given one. The name is optional: if not given, the typename (process template) is used.

RunAnalyses(theModel, theSelection): aSelection

Sequentially run all analyses in the selection and return a selection containing all analyses that did not
succeed.

24.1.7 Launching tasks : CaesamScript_Task


You can run tasks just as you do from the GUI. You can run tasks defined for the old task plug-in system,
as well for the new one ( see the section “Interface definition on page 272” ).
This new system in particular allows the task to receive the whole selection (tree and property view) as
well as another parameter (which can be an URL, a string or any user-defined class). The old system
(Menu_Tools_Task.csm) only allowed getting the tree selection, a string or an url (but not at the same
time).

RunTask(theModel, theTaskName, theArgument, theParameter): aStatus

Run a task with given argument and parameter. The argument must be the model for all tasks inheriting
from Process_Model. The returned status can be used as follows:
• aStatus.IsOK() :
returns a boolean indicating if the task has been successful or not
• aStatus.GetMessages() :
returns a string array containing all messages pushed by the task with PutMessage.

RunTask(theModel, theTaskName, theArgument, theParameter,


theSelection):aStatus

Run a task designed for the new GUI task plugin system, i.e. a task that expects as parameter a map with
two entries: “UserTaskParameter” and “Selection”. The selection can be set null (None in python) if it is
not used by the task.

page-216
24 Batch Tools | Caesam SDK

24.1.8 Going further


Methods NewDocument and LoadDocument both return a CaesamStd_Model, allowing the script author
to access advanced functionalities if needed. You can also get access to the items contained in a selection
as follows :

aCaesamStd_ItemArray = aSelection.GetSMTreeSelection()

This can be useful for editing the items (since high-level multi-edition of EOs is not yet implemented),
but also for passing a selection to some task that doesn’t use the new system, and thus still expects an
item array containing the selected items. Also note that a CaesamStd_ItemArray can be used as a source
in all selection methods.

24.1.9 Example

This example shows how to run all unfinished damage tolerance and buckling analyses from an
existing CZM, and save the session.

# load model from an existing czm


aModel =CS_LoadDocument(“file:/mydir/mymodel.czm”)

# select all analyses that must be recomputed


aAnalyses = CS_SelectToBeComputedAnalyses(aModel)

# recompute needed damage tolerance and buckling analyses


CS_RunAnalyses(aModel, CS_SelectByType(aAnalyses, “DamageTol;Buckling”))

# save model to a new czm


CS_SaveDocument(aModel, “file:/mydir/mymodelafterrun.czm”)

A complete example demonstrating most of the available methods can be found in the examples
directory of the Caesam delivery: examples/batch/BatchExample.py

24.2 Running analyses in batch


A useful example can be found in examples/batch/BatchRunAnalyses.py The script usage is the following:

Usage:
BatchRunAnalyses.py [ options ] -input input_czm_url -output [ output_czm_url
]

Description:
This script loads the czm document given by input_czm_url.
It then runs all analyses that are not up to date, and saves the updated
document.
If the output_czm_url is specified, it is used for saving.
Otherwise the loaded document is overwritten.
The input/output_czm_url can be a Caesam url, or a unix or windows-style path.
Temporary files are created in the user's home directory.

Options:
-h, -help: Displays this help
-t, -type, -types: Specify the type(s) of the analyses you want to run.

page-217
Caesam SDK | 24 Batch Tools

You can specify several types by separating them with a ';'.


If omitted, all analyses that are not up to date will be run.

24.3 BatchManager
It is possible to launch a script, and to follow its progression status from a central application: the
BatchManager.
You can launch the batch manager by running Caesam with the –batch option. All the arguments following
–batch will be passed to the batch manager.

CaesamBatch action [arguments]


actions:
list
launch -launcher launchername -job jobname -script scriptname [args]
remove jobname
removeall
stop jobname
abort jobname
epilog jobname

The aim of the BatchManager is to allow the user to launch several kinds of computations from an
application. The Batch system is also expendable to be able to use your own batch queue.
The default “launcher” is named “Shell” and simply launches an python script into a sub-shell.

24.3.1 Processing the command line parameters


The BatchManager only handle and processes parameters prefixed with a “-“ . All the parameters are put
in a map and can be accessed from your python script using the GetCommandLineArgument. So if you
want to use a script using the Batch system you should just take care using “-“ prefixed arguments. These
arguments can be followed by a value argument. GetCommandLineArgument(“-argument”) returns:
• True if the argument is present and not followed by a value
• None if the argument is absent from the command line
• The value following “-argument” if the argument is followed by a value

24.3.2 Creating a new BatchLauncher


It is possible to add a new BatchLauncher type in the Caesam BatchManager. To extend the BatchLauncher
you must extend two classes:
• BatchLauncher_AbstractLauncher on page 218
• BatchLauncher_JobData on page 219

BatchLauncher_AbstractLauncher

page-218
24 Batch Tools | Caesam SDK

This class defines the interface you must define to plug a new BatchLauncher in the Batch Manager. It
can be extended in C++, using virtual methods or in Python and Java using registered methods.
Most of the methods work by taking a BatchLauncher_JobData object in input. If the output object is
modified, the method is expected to return the true value. For example, if the “Remove” is called and the
Launcher is not able to remove the job, it is expected to return a false value and make no change to the
input object.
The situation is a little different if you use the Registered method system. In this case, you receive the
JobData, modify it if necessary, and then return the object. Caesam will check the input and return the
object for changes.
You must of course give your launcher a name. It should be returned by the method GetLauncherName.
The String returned by this method will be the one the user is going to use. You are not supposed to return
a kind of classname.
If the “action” is unsuccessful, you are expected not to modify the object. You can do it, but in this case
the Batch Manager will not consider it as being an error condition.
The Epilog actions are reserved for “post-computation” actions such as removing a task from a remote
queue or copying some result files.

BatchLauncher_LauncherINput

This object is the input of the Launch method in the Launcher. It contains several members set by the
Manager. The members are in fact made out of the command line parameters used to launch a script. You
should access them through its setters/getters.
If you need more parameters, you can access all the parameters you need from the GetAgument(s) methods.
All additional parameters (i.e. also the parameters that the script will use) are stored in this map.

BatchLauncher_JobData

page-219
Caesam SDK | 24 Batch Tools

This class is used to store information about a job.


It is created by the Launch operation in the Launcher in itself, and then stored on disk by the BatchManager.
Its constructor takes a LauncherInput objects, used to initialialize its inputData member.
This object is modified by the Launcher object, and controlled by the Manager.
If your launcher needs some specific information to keep track of a job, you must store them in an object
that inherits from this object. It is the object used to process all the Manager commands.
The Status is a single String. Each “command” method like status, stop must be able to work using data
stored in a specialized version of BatchLauncher_JobData.

Integrating a new Launcher

The CaesamBatch application is a special application that only loads by default a single plugin. This is
made to be able to start it very quickly. It means that if you want to extend it, you must create.
If you want to extend it, you must:
1. Create a new plugin with your own BatchLauncher_AbstractLauncher implementation.
2. Put the plugin along the other plugins in a directory listed in the CAESAM_PLUGIN_PATH.
3. Define the environment variable CAESAM_BATCH_PLUGIN and set its value to the name of your
plugin. If you have any additional plugins, you must separate them with “;”.

page-220
25 Job Submmission and Monitoring | Caesam SDK

25 Job Submmission and Monitoring


In Caesam, it is possible to submit and monitor jobs given to a DRM (Distributed Resources Management)
system. To be able to use this feature Caesam must be configured according to your DRM. The analyses
must be customised to allow their submission on a remote host.
The Job Management is designed to be independent from the DRM used on different sites. It means that
some customisation must be done before being able to submit jobs to a given DRM.
Interfacing Caesam with a DRM not included with Caesam requires the implementation of a DRM interface
in Python,Java or C++.

25.1 Queue Configuration


Even if your DRM is not supported by Caesam, you can still interface it with your DRM. This is done by
implementing the methods of DRM_DrmPythonInterface. You can have a look at the default
implementation in the plugin com.samcef.caesam.batchlauncher. In the typedesc file you will
find the following type:

<TypeDesc Name="BatchLauncher_PythonDrmInterface" Inherits=


"DRM_DrmPythonInterface">
<Method Name="RunJob" Type="Python" Location=
"csm:com.samcef.caesam.batchlauncher/python/DRMInterface"/>
// Input: Caesam_String: DRM_DrmaaJobTemplate,
Output: Caesam_String: JOBID
<Method Name="JobPS" Type="Python" Location=
"csm:com.samcef.caesam.batchlauncher/python/DRMInterface"/>
// Input: CaesamPair(Caesam_String:
JOBID,Caesam_String:Job_WorkingDirectory)
Output: Caesam_Integer(ProcBase_State value)
<Method Name="JobControl" Type="Python" Location=
"csm:com.samcef.caesam.batchlauncher/python/DRMInterface"/>
// Input: Caesam_Pair(Caesam_String: JOBID,Caesam_Integer(DRM_Control
value),
Output: Caesam_Boolean(success)
</TypeDesc>

All you have to do is create a new type instead of BatchLauncher_PythonDrmInterface and implement
these 3 methods. Then you must set the name of this new type in the CAESAM_JOB_DRMCLASSNAME
environment variable.

Note: that it also possible to implement these methods in java or C++.

Once Caesam has been interfaced to your DRM, it is necessary to tell Caesam how to handle the jobs on
your site.
This customization consists mainly in describing the available computing queues and how to submit a
job to these queues.
This configuration is done in a directory. The directory must be set in an environment variable whose
name is CAESAM_JOB_CONFIGURATION.
A second variable is available to specify a directory containing the jobs templates. The Caesam interface
will present the analyst with a list of job template names. This list of templates is generated by simply
taking the names of all the subdirectories of the directory specified in the CAESAM_JOB_TEMPLATES
environment variable.
The last environment variable that you have to set is the CAESAM_JOB_WD . It is the path to the directory
where the files are exchanged with the DRM. This directory should be available for both the batch system

page-221
Caesam SDK | 25 Job Submmission and Monitoring

and the submission host. As the DRM system must copy data back to this directory, the directory must
be available until the result are merged. It cannot be located on a laptop that you disconnect from the
network for example.
This customization should be done by an author having some knowledge of the on-site DRM.
Most of the configuration data must follow the following format:

key = value

The general description of the file structure is the following one:

jobs_configuration
/queues

The configuration.txt file contains the following information:

Table 14: configuration.txt

Key Value

drm.jobs.defaultemplate The name of the default template located in the


CAESAM_JOB_TEMPLATE directory.

drm.jobs.defaultqueue The name of the default queue located in the


/queues directory.

The /queuesdirectory contains some information about the available queues. Each queue configuration
is written in a different file.

Table 15: Queue configuration

Key Value

drm.queue.name The name of the queue.

drm.queue.maxtime The maximum allowed job time in minutes on that queue.

drm.queue.mintime The minimum allowed job time in minutes on that queue. You
can use this value to avoid a short job submission on a queue
with a slow data connection.

drm.queue.powerfactor The queue power factor.

drm.queue.architecture The architecture of the queue (SUN,AIX,HPUX,WNT,...).

You can also choose your own prefix for the job names, using the variable CAESAM_JOB_NAMEPREFIX.
By default, the user name is used. An incremented counter number is added to this suffix.
From a data flow point of view the role that the script launched by the RunJob call must be able to fulfil
is shown in the figure below.

page-222
25 Job Submmission and Monitoring | Caesam SDK

Figure 8: Job Script Role

The script CaesamJobSGERun.ksh is an example of a typical job run script.


Once the files present in the working directory have been copied to the remote host, the job script must
execute the command "CaesamJob > LogStdOut.log". After that the content of the dctczm and the files
Messages.csm Status.csm LogStdOut.log ResultDataSets.csm must be copied back in the OUTPUT
directory located in the working directory on the submission host.

25.2 Customization of the ProcessTemplate


Remote execution of analyses in job mode is done without using the Model. The dataset is the only
available object on the remote host. A Process_Analyses that you want to run in a Job should not use the
Model. The only exception to this rule is the GetCsmContext() method. All the files should be referenced
using contexts.
To remotely execute an Analysis, Caesam needs to create and retrieve persistant objects. In order to do
this efficiently, Caesam needs to know about the input and output objects of the analyses.
The inputs/output specification is done at two levels:
• The EO level where you specify EOs considered as input or output.
• The File level where you can specify that some additional files are considered as input or output for
your job.
For the EO level, you just need to set the CsmMbr_ArgType member:

<CsmMbr_ArgType Type="Caesam_String">OUT</CsmMbr_ArgType>

The Meaning of the ArgType Value is as follows:

Table 16: CsmMbr_ArgType

Value Meaning

IN The EO is an INPUT EO. The value will be available in the dataset copied remotely.

OUT The EO is an OUTPUT EO. The value will be copied from the executing host to
the submitting host after the job execution.

INOUT The EO is an INPUT-OUTPUT EO. The value will be copied between both hosts
before and after the job execution.

page-223
Caesam SDK | 25 Job Submmission and Monitoring

All the CaesamStd_Parameters are available for the analysis.


If you want to copy some files, you must set a value to the CsmMbr_Files member of the Process_Template,
or implement a GetFilesArray method to do it dynamically. This method should return a
Caesam_ObjectArray of CaesamStd_FileDeclaration.

<CsmMbr_Files Type="Caesam_OjectArray">
<Item Type="CaesamStd_FileDeclaration">
<CsmMbr_Url Type="Caesam_Url">
<put a Caesam_Url instance here (it can contains csm context etc...)>
</File>
<CsmMbr_ArgType Type="Caesam_String">IN </FileType>
</Item>
</CsmMbr_Files>

Description of CaesamStd_FileDeclaration members:


CsmMbr_Url is a required member. It must contain the URL of the file relating to the analysis you want
to copy. By default CAESAM uses a internal system for the conversion of contexts.
If the file must be copied to a place that the author wants to specify (mainly for the files “IN”), it is possible
to use the CsmMbr_DestinationUrl member. In this case, the author must manage this destination himself
in the analysis (e.g. by using a context managed by an environment variable). CsmMbr_ArgType can
take the values "IN", "OUT" or "INOUT". An "IN" file is a file which serves as INPUT for an analysis,
it will be copied from the local CAESAM to the remote CaesamJob. The "OUT" files are remote files
that are returned at the execution of the remote CaesamJob. The INOUT files are copied in both directions.

25.3 Computing Resources Evaluation


DRM systems are used to optimize the use of computing resources. To provide the analyst and possibly
the DRM a good estimation of the resources required for a computation, the author should give an idea
of the resources needed .
Specifying required resources is done in the process template. It can be done using two different modes:
• A static way - where you can specify your resources if they are independent from the inputs.
• A dynamic way - if the resources consumed are dependent on the input. In this case, you must define
a GetComputingResources method.
As an example, if the computation time is dependant on the number of loadcases in the input, it means
that the time resources will vary dynamically according to the input data.
If you can use a static member to define the resources required by your process, you can simply define
the member <ComputingResources>
If you want the resource evaluation to be dynamic, then you must redefine the method
GetComputingResources. This method will be called with the CaesamStd_Operation of the selected
analyses. Please note that sonce this method is called during the initialization of the submit editor it should
be fast; you just need to return an estimation. The method must return a ProcBase_Resources object.
The ProcBase_Resources object contains the following data:
• MemorySpace (Caesam_Quantity)
• DiskSpace (Caesam_Quantity)
• Time (Caesam_Quantity)
• Licences (Caesam_StringArray)
For the time resources, the author will need to specify them in Caesam Standard Seconds. A Standard
Caesam Second is a reference time on a reference machine.
This allows Caesam to provide the Analyst with an estimation of the power needed on different systems,
which can vary greatly in terms of calculation power.
The computing power can be estimated by running the CaesamPowerFactor utility. This command will
return a number. That is the power factor of the system you ran it under. This power factor correction

page-224
25 Job Submmission and Monitoring | Caesam SDK

give you the number you must multiply your actual computation time by to have it expressed in Standard
Caesam Seconds.
CaesamPowerFactor is a rather crude benchmark and will only provide an overall idea of the power of
the system.
If you give a computation time on a system as an argument to the CaesamPowerFactor utility, it will
return the time in Standard Caesam Seconds.

Note: Please keep in mind that these times are only gross estimations.

page-225
Caesam SDK | 26 Analysis interface definition

26 Analysis interface definition


This section describes how to adapt the user interface for the analyst, either by creating specific editors
or by adding functionalities to the Caesam application. These new functionalities will be presented to the
user in menus.
The following topics are covered:
• Creating an analysis on page 226
• Defining an editor on page 230
• Interface definition on page 272
• Defining other interface elements on page 283

26.1 Analysis Creation


This section describes all steps to write your own class to create an analysis
There are some constraints involved in this. Your class must extend AbstractAnalysisCreation or
DefaultAnalysisCreation located in the package : com.samcef.caesam.modules.analysis.command.
What's the difference?
When you create an analysis, there are two creation states : standalone and non-standalone. If you want
to control the creation of both states, extend AbstractAnalysisCreation. For other cases, extend
DefaultAnalysisCreation. DefaultAnalysisCreation includes the “default” process creation. If you only
write a specific process for standalone and use the default process for other cases, you should extend
DefaultAnalysisCreation If you want to control all process, extend AbstractAnalysisCreation.
By extending one of these classes, you have to redefine two methods :
• public void create(String theType, String theName)
• public JPanel getPanel()
After the creation of the table, specify your class name in the file plugin.xml, in the tag :
<AnalysisCreationClass>.

<Item Type="PluginClass">
<Class Type="Caesam_String">HoledRibBayBuckling</Class>
<Default Type="Caesam_Url">templates/HoledRibBayBuckling.csm</Default>
<Resources Type="Caesam_ObjectMap">
<Item Key="AnalysisCreationPath"
Type="Caesam_String">/Example/RibBay/</Item>
<Item Key="AnalysisCreationClass"
Type="Caesam_String">com.samcef.caesam.process.HoledRibayCreation</Item>
</Resources>
</Item>

Let's analyze a simple example, that comes from the test.process plugin. In this example, the class extends
DefaultAnalysisCreation because only the standalone mode is delegate to a python task. As you can see
at the beginning of the create method, we test if it's standalone. If not, we call the super.create method.
We call the create of the DefaultAnalysisCreation class. Similarly in getPanel(), if it's not the standalone
mode, we call the parent method.

package com.samcef.caesam.process;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import com.samcef.caesam.jnicaesam.CaesamAPI_Task;
import com.samcef.caesam.jnicaesam.Caesam_Integer;

page-226
26 Analysis interface definition | Caesam SDK

import com.samcef.caesam.jnicaesam.Caesam_String;
import com.samcef.caesam.jnicaesam.Caesam_Pair;

import com.samcef.caesam.modules.analysis.command.DefaultAnalysisCreation;

import java.util.ArrayList;
import com.samcef.caesam.CaesamModel;
import com.samcef.caesam.jnicaesam.CaesamStd_CP;
import com.samcef.caesam.jnicaesam.CaesamAPI_Model;
import com.samcef.caesam.jnicaesam.CaesamAPI_Operation;
import com.samcef.caesam.jnicaesam.CaesamStd_CP;
import com.samcef.caesam.jnicaesam.CaesamStd_ItemArray;

/**
* Sample class that allow to create mutiple HoledRibayCreation.
* This class is derived from DefaultAnalysisCreation *
* HoledRibayCreation
*/
public class HoledRibayCreation extends DefaultAnalysisCreation
{

/**
* Field where user set the number of analysis to create
*/
private JTextField myNumberCreationField;

/**
* This method will be called on Ok or Apply action in the dialog
*/
@Override
public void create(String theType, String theName)
{
// if not standalone mode, call the parent method.
if (!isStandalone())
{
super.create(theType, theName);
return;
}

// Gets number, and control that this is a numeric value


int nb = 1;
try { nb = Integer.parseInt(myNumberCreationField.getText()); }
catch ( Exception e ) {

// if not, force to 1 and error


System.out.println("%%%ERROR: HoledRibayCreation:create: " +e );
nb = 1;
}

// Run the python task with a Caesam_Pair parameter


String aTaskName = "python:csm:com.samcef.caesam.test.process
/python/HoledRibBayBucklingCreate";
Caesam_Pair aParameter = new Caesam_Pair(new Caesam_Integer(nb),
new Caesam_String(theName));
CaesamAPI_Task aTaskAPI = new CaesamAPI_Task(myCaesamModel.getStdModel());
aTaskAPI.RunTask(aTaskName, myCaesamModel.getStdModel(), aParameter);
aTaskAPI.RemoveTask(aTaskName);
}

/**
* This method creates a panel that will be added in the analysis
creation dialog.
*/
@Override

page-227
Caesam SDK | 26 Analysis interface definition

public JPanel getPanel()


{
// if non standalone mode, return an empty panel
if (!isStandalone()) return super.getPanel();

// int standalone mode, display a textfield for the number of ss


myNumberCreationField = new JTextField();
myNumberCreationField.setColumns(10);
JPanel panel = new JPanel();
panel.add(new JLabel("Number of SuperStiffeners : "));
panel.add(myNumberCreationField);
return panel;
}
}

26.1.1 Class overview


An overview of the classes is shown in the Figure below.

Figure 9: Overview of classes used for Analysis Creation

Members

• myCPArray : CP array. Null in standalone mode


• myCaesamModel : Caesam Model. Setted by Caesam (never null in the create method)

Methods

JPanel getPanel : returns a JPanel that contains all field used for the parameters void create : creates the
analyse boolean isStandalone : returns true if the creation will be made in standalone mode. boolean
isParameterValid returns true if all user entries are valid. By default, this method returns true, except if
you redefine it to control parameters.
The figure below shows an example of a sequential scheme.

page-228
26 Analysis interface definition | Caesam SDK

Figure 10: Example of a sequence

26.1.2 FAQs
This section provides some answers relating Analysis Creation
The figure below shows an example of a sequential scheme.

How to know if you are in standalone mode ?

To know if you are in standalone mode, use the call isStandalone().

if ( isStandalone() )
... // code for standalone mode
else
... // code for non-standalone mode

How can I control user entries ?

You can redefine the isParameterValid method. Process all your tests in this method. Return true if
all is correct or false if not. At start of the create method, call isParameterValid first. If it returns false,
quit the create method.

@Override
public void create(String theType, String theName)
{
if ( !isParameterValid() )
return;
}

page-229
Caesam SDK | 26 Analysis interface definition

How can I implement a custom process for standalone and use the default for the non
standalone mode ?

Your class can extend DefaultAnalysisCreation. In the create method, begin with this line :

if (!isStandalone())
{
super.create(theType, theName);
return;
}

After that, write your own code, for the standalone mode. If you don't want to extend
DefaultAnalysisCreation, write this code to create a analysis with like in DefaultAnalysisCreation

// Creation operation (non-standalone)


int aSeaArraySize = myCPArray.size();
CaesamStd_ItemArray aItemArray = new
CaesamStd_ItemArray("CaesamStd_CP",aSeaArray Size);
for(int j=0; j< aSeaArraySize; j++)
{
aItemArray.Set(myCPArray.get(j),j);
}
myCaesamAPIOperation.AddOperation(theName,
theType, aItemArray);

A better way is to extend DefaultAnalysisCreation

26.2 Editor definition


In the Caesam framework, data visualization and editing is mainly performed by an "Editor". Editors
allow analysts to define the data values required for their analysis. An editor is a visual Java component
with four components (javax.swing.JComponent), typically Jpanels, that appear in the editing panels in
the CAESAM application.
Initially, the Caesam GUI provides two editing panels:
• one to view/edit tree model selected items; the Tree Editor panel,
• another to view/edit selected items' details, or properties; the Property Editor panel
Additionally, Caesam allows a user to edit any tree item, no matter which tree items are selected. It should
also be mentioned that editors are used when EO are created interactively or before the execution of
'Caesam Tasks', thus allowing the user the opportunity to set some parameters to be used by this task.
Editors are used primarily to edit Engineering Objects (EO): in which case they are termed an “EO Editor”,
but the editor mechanism is not restricted to EOs: any kind of data in Caesam can be edit using an editor.
From here on the terms “Editor” and “EO Editor” to denote the same concept. A default editor on page
231 is provided for data input but authors can develop their own custom editors, and easily integrate them
in the Caesam application. See also developing a custom editor on page 231 and an example of the definition
of a custom editor on page 236.

26.2.1 EditorData
Editors edit com.samcef.caesam. editors. EditorData objects.
EditorData is a proxy on a CaesamAPI_Object instance, providing the same services as this class.
EditorData also intercepts calls to the CaesmAPI_Object and adds some functionalities if necessary. This
is especially the case for notifications to the user interface that a data has changed. Because EditorData
provides additional services, it is strongly discouraged to bypass it (accessing directly the encapsulated
CaesamAPI_Object instance). Note: In previous version, data used by EOEditorData were EOEditorData.

page-230
26 Analysis interface definition | Caesam SDK

EOEditorData has been replaced by EditorData, but this change has been done in a backward compatible
way, so the old editor will still work without changes. EditorData provides the following functionalities:

Read-only EOs

EditorData objects can be set read-only using the setEditable(Boolean) method. This causes standard
widgets to be automatically disabled, and the setters to throw a PropertyVetoException if a member is
modified.

Type Modification

It is possible to change the type of an EO at runtime, using the ChangeType(String) method. Of course,
there are some restrictions on the type that can be used: the destination type should be a subtype of the
original one. The list of available types for such a modification can be retrieved using the
getAvailableTypes() function. The base type of the hierarchy can be retrieved using getDeclaredType()
.

Note: The old method, getBaseType() , that provides the same service is still available for
backward compatibility.

26.2.2 Default editor


A default editor can be used to edit EOs for which no dedicated editor is provided. The default editor
simply displays a table with one row for each member of the object, and two columns: one for the member
name, and one for the member value. The default editor supports:
• editing members of all the types supported by the listed widgets on page 232.
• arrays of caesam object (EditorData.IsObjectArray() == true)
• maps of caesam objects.
In all cases, the editor supports:
• inserting,
• removing selected items
• copy/paste of values
• visually sorting of the elements.

EO Member Names Display

Member names displayed by the default EO editor can be customized using a properties file, to provide
local descriptions or translations. This properties file is called Resources.properties, and it is located in
the root of the plugin where the edited type is defined. For each member, the key to be used is: Type
name. Member name. For example: Geometry.height = The Geometry height See section Properties files
on page 23 for general information about this syntax.

Known limitations

Multi-edition of EO arrays only works on the first EO arrays. This limitation will be fixed in a future
release.

26.2.3 Custom Editor


When the default editor is not sufficient, it is possible to define a Custom Editor for any given type of
EO.

page-231
Caesam SDK | 26 Analysis interface definition

Layout

The general layout of an EO editor is shown in Figure below. It consists of : • a “tool panel” (top) • a
“choice panel”(left) • an “image panel” (centre) • an “editor panel” (right)

Figure 11: Layout for a custom EO editor

At least one of the choice, image and editor panels should be not null. As a consequence, up to three
panels may be null. The editor container does not impose the size of the panels, and you should also bear
in mind that panels can be resized by the user at runtime. The exact content of the panels is defined by
the editor author, according to needs.

Implementation of the Interface

The editor components should only implement the interface com.samcef.caesam.editors.Editor.


The editor is not required to be a subclass of any particular class. The editor itself is not even required to
be a visual component. The table below describes the methods to be implemented.
• public String getTitle() : Returns the title of the editor to be displayed on the editor container, e.g.
“Material definition Editor”
• public void setEO(EditorData) : Sets the EO object to be edited.
• public void stateChanged(ChangeEvent) : This method will be called by the application to notify
the editor of a change in the state of the edited object (for example, after a result has been computed)
• public JComponent getChoicePanel() : Returns a javax.swing.JComponent object that will be used
by the GUI to present possible values (choices) for the edited EO
• public JComponent getEditorPanel() : Returns a javax.swing.JComponent object that will be used
by the GUI to edit the EO members.
• public JComponent getImagePanel() : Returns a javax.swing.JComponent object that will be used
by the GUI to display an image about the edited EO. This image will give some information to the
user about the meaning of the parameters of the EO
• Public JComponent getToolPanel() : Returns a javax.swing.JComponent displayed horizontally on
top of the three others. It can be used to display a tool bar, for example.

Default Widgets

A library of visual components is available for use to edit EditorData members. They are grouped in the
com.samcef.caesam.dialog package. Currently the following widgets exist:
• CaesamDlgBooleanInput : This component is used to edit the member of a CaesamAPI_Object,
which is a Boolean (EditorData.IsBoolean() returns true).
• CaesamDlgDoubleInput : This component is used to edit the member of a CaesamAPI_Object,
which is a double (EditorData.IsDouble() returns true).
• CaesamDlgDoubleArrayInput : This component is used to edit the member of a CaesamAPI_Object,
which is a double (EditorData.IsDoubleArray() returns true).
• CaesamDlgIntegerInput : This component is to used to edit an integer member, for which
EditorData.IsInteger() returns true.
• CaesamDlgIntegerArrayInput : This component is used to edit an integer array member, for which
EditorData.IsIntegerArray() returns true.
• CaesamDlgTextLineInput : This edits a string member (IsString() == true)

page-232
26 Analysis interface definition | Caesam SDK

• CaesamDlgQuantityInput : This edits a quantity member, for which EditorData.IsQuantity() returns


true.
• CaesamDlgQuantityArrayInput : This edits a quantity member, for which
EditorData.IsQuantityArray() returns true.
• CaesamDlgStringArrayInput : This edits a member, which is a reference on another object coming
from a list of predefined values. So for example, it can display a list of materials, from which the
analyst can select the required item.
• CaesamDlgURLInput : This edits a URL (EditorData.IsUrl() returns true). It permits the entry
directly of a URL, or to chose a file on the file system.
• CaesamDlgFileInput : Edits an File (EditorData.IsFile() returns true). It permits to select the file
mime type and to enter the file URL, either directly or by choosing a file on the file system.
• CaesamDlgDateInput : Edits a Date (EditorData.IsDate() returns true). It permits to edit date object
based on the format "yyyy-MM-dd HH:mm:ss".
• CaesamDlgFunctionInput : Show a Function (EditorData.IsFunction () returns true). It permits to
display function object.
A function object, can contain information to draw several functions. In this case each function has its
own color and legend .

Custom Widgets

This section describes widgets that can be used to customise an editor.


Custom Inputs
These allow you to integrate custom input components into an editor. You can add a new Editor Input
Component or overwrite an existing one, but in all cases you have to create your own Editor Input
Component. An Editor Input Component is a java class that extends the abstract class: AbstractCustomInput.
You have to overwrite 4 methods. Below is an example of custom editor input in con.samcef.caesam.dialog.
CaesamCustomDlgSample.

public class AirbusCustomInput extends AbstractCustomInput{

@Override
public void setData(EditorData theData, String theMemberName) {
super.setData(theData, theMemberName);
}

@Override
protected JComponent[] createComponents() {
}

@Override
public Object getValue() {
}

@Override
public void setValue(Object theObject) {
}
}

To use your new input class, add the “CellEditors” Item in the resource tag of a plugin.xml file, as shown
in the example below:

<Resources Type="Caesam_ObjectMap">
<Item ...</Item>
<Item Key="CellEditors" Type="Caesam_ObjectMap">
<Item Key="Caesam_String" Type="Caesam_String">com...
AirbusCustomInput </Item>
</Item>
</Resources>

Matrix headers and labels

page-233
Caesam SDK | 26 Analysis interface definition

The default headers and labels, for matrix objects are, 1, 2, 3…It is now possible to to set specific headers
or labels for a matrix member.
You just need to a <Resource> to the plugin.xml file, as illustrated below. This example adds a
“MatrixLabel” Item.

<Resources Type="Caesam_ObjectMap">
<Item Key="MatrixLabel" Type="Caesam_ObjectMap">
<Item Key="aCaesamTypedMatrix" Type="Caesam_ObjectMap">
<Item Key="colLabel"
Type="Caesam_StringArray">;header1;header2;header3</Item>
<Item Key="rowLabel"
Type="Caesam_StringArray">Label1;Label2;Label3</Item>
</Item>
</Item>
</Resources>

Use defaultEditor in a custom editor:


There are two ways to use the default Editor in a custom Editor. The easy way is to instantiate the
com.samcef.caesam.editors.CaesamDlgInputPanel. In this class the setEditorData method allows you to
set the EditorData and the getPanel method gives you the defaultEditorComponent.

public void setEO(EditorData theData) {


DialogInputListener aDialogInputListener = new
DialogInputListener(){

public void formatChanged(DialogInputEvent theEvent) {


//...
}

public void invalidValueError(DialogInputEvent theEvent) {


//...
}

public void valueChanged(DialogInputEvent theEvent) {


//...
}

};
CaesamDlgInputPanel myDefaultEditor = new
CaesamDlgInputPanel(theData,aDialogInputListener);
}

The other way consists to create your own table that has the same behavior than the default Editor. This
way is more powerful because you create your own table model, but it requires more effort. To do this,
you have to extend the CaesamEditorTable. The CaesamEditorTable uses the Caesam default cell Renderer
and cell Editor, but you can also overwrite it by calling the putTableCellEditor and putTableCellRenderer
methods.

Arrays and Maps of Objects

There are two components that can be used for dealing with these.
• com.samcef.caesam.dialog.table.APIObjectArrayTable This component is for editing object arrays
(including EO) ( IsObjectArray() returns true). It is a specialization of JTable. This component by
default permits sorting on columns and copy/paste.
• APIObjectMapTable This component is for editing Object Maps (including EO).

Developer’s Notes

Components : CaesamDlg classes extend the common components that exist in the package
com.samcef.devkit.dialog. CaesamDlg classes are not themselves javax.swing.Component subclasses.
They encapsulate a Component. To get the component (for example, to display it in a JPanel), use the
getComponent() method.

page-234
26 Analysis interface definition | Caesam SDK

Events : CaesamDlg inputs already have listeners to update the edited object when the user enters a value.
No additional code is needed, but event listeners can be added using addInputListener(DialogInputListener).
Constructors : All widgets have the same constructor arguments:

theLabel: String: label to be displayed for the widget


theData: EditorData: object for which a member should be edited
theMemberName: String: the name of the member to edit.

EO Setter The EO edited by the widget can be modified by calling the setData(EditorData,String) method.
This method permits the editing of different EO objects using the same editor instance.
Factory : a Factory class which instantiates the widget corresponding to an EO member type is available:
com.samcef.caesam.dialog.CaesamDlgFactory
Use in JTable : The widgets in com.samcef.caesam.dialog do not implement the TableCellEditor or
TableCellRenderer interfaces. A component encapsulating a
com.samcef.devkit.dialog.DialogInputComponent has been created to implement those interfaces. It is:
com.samcef.caesam.dialog.table.CaesamDlgCellInput

26.2.4 Integration of an editor


The integration of a custom editor is straightforward. All you need to do is to copy the editor and its
dependencies in a directory, and then configure the related plugin to use it. It is also possible to use the
Eclipse Integration.

Installation

Amongst other things, this chapter explains:


• The coding rules that your editor code should conform to.
• Where to put your editor java sources and all its dependencies (jars and resources (gif, txt, etc)).
• How to compile your java code within your plugin.

Configuration

The editor should be registered inside the plugin.xml, as shown in the example code below for
com.samcef.caesam.test.profile.ProfileEOEditor editor:

<Item Type="PluginClass">
<Class Type="Caesam_String">Profile</Class>
<Resources Type="Caesam_ObjectMap">
<Item Key="Editor"
Type="Caesam_String">com.samcef.caesam.test.profile.ProfileEOEditor
</Item>
</Resources>
</Item>

Note: In the above xml fragment, the Item Key="Editor" replace the old Item
Key="EOEditor", but the old key “EOEditor” is still supported for backward compatibility

Eclipse Integration

In future releases, Caesam SDK will be delivered with an integrated development Environment, Caesam
Studio, based on the Eclipse IDE. Caesam Studio will allow users to develop their own plugin, including
Caesam Editor.

page-235
Caesam SDK | 26 Analysis interface definition

Example
The code below shows an extremely simplified sample implementation of an EO editor. This
“Material editor” is made to designed allow the entry of the Young’s Modulus value (the “young”
member) of a Material engineering object. package com.samcef.caesam.test.profile;

import javax.swing.JComponent;
import javax.swing.event.ChangeEvent;
import com.samcef.caesam. editors.AbstractEOEditor;
import com.samcef.caesam. editors. EditorData;

/**
* Sample class for EO Editor development.
*/
public class MaterialEOEditor extends AbstractEditor {

@SuppressWarnings("unused")
static final private String SCCSID = "@(#)
MaterialEOEditor.java 2.0-3, 04/07/06@(#)";

// Editor panel
private MaterialEditorPanel myEditorPanel;

private EditorData myEditorData;

/**
* Already create the visual panel
* (it might be shown before the EO is set)
*/
public MaterialEOEditor() {
myEditorPanel = new MaterialEditorPanel(null);
}

/**
* Returns the panel used for EO edition
*/
@Override
public JComponent getEditorPanel() {
return myEditorPanel;
}

/**
* Title of the editor
*/
public String getTitle() {
return "Material EO Editor";
}

/**
* Sets the edited object
*/
public void setEO(EditorData theEditorData) {
myEditorData = theEditorData;
myEditorPanel.setEO(theEditorData);
}

@Override
public void stateChanged(ChangeEvent theEvent) {
// update GUI;
}
}

page-236
26 Analysis interface definition | Caesam SDK

26.3 Form editors


An author can associate a FormDescriptor to any object type.
This will generate a form that will be used when editing an object of this type (as well from the property
view as from the tree view).
You can see this as a technique for customizing the default editor without writing any Java code. The
resulting editor will in particular look like the default editor, using the same "table" approach. For a more
powerful XML form definition, see section "SwiXML Editors" below.
The generated form editor supports multi-edition. In other words, you can edit several items at the same
time through a form.
Another advantage of form descriptors is that they can also be used to edit the objects through a table.
The form descriptor is then used to describe the columns of this table. See section "Tabular Editors"
below.

Writing a form descriptor

A form descriptor is basically a list of groups of field descriptors. Each group has a label and each field
descriptor in it is composed of a label and a path:
• if the path points to a Cesam primitive, an ad hoc input field will be added to the generated form
• if the path points to some EO, the user will be able to choose between all EOs of compatible types in
the shared workspace
• if the path points to an object of another type, the user won't be able to edit this object and will just
see its read-only string representation
Note that if the path points to a null object, the form editor won't be able to create a new object of the
expected type. This is a limitation that must be removed in the future.
You can also, for each field, specify a second path (optional member "SetPath") that will be used when
a value is changed. This e.g. allows to obtain the value for a given column by calling a method, and to
handle modifications by calling another method. This feature is available in form editors as well as in
form tabular editors.
Each field can also be set as read-only or editable. If the path uses a Caesam method (@method), the
corresponding field will always be read-only, unless you specified a non-empty "SetPath" value.
And finally, if you don't specifiy a label for some of your fields, Caesam will see if the field's path is a
simple member. If it's the case, the label will be the translated member name.
We thus see that using a form editor allows to easily customize the default editor:
• related fields can be grouped under a same label
• you can choose which members should be visible and/or editable
• you edit objects inside members (any object that can be reached with a Caesam path)
• you can use methods for getting and setting the value of a field

Declaring a form descriptor

The url containing the instance of the form descriptor must be associated to the EO type through a resource
named "FormDescriptor".

Example

An example of a form descriptor has been made for editing EOs of type PanelGeometry.
See files in examples/plugins/com.samcef.caesam.test.transverse/ :

- plugin.xml (association of the form descriptor with PanelGeometry)


- resources/PanelGeometryFormDescriptor.csm

Below, you'll see a simplified version of this XML form descriptor.

page-237
Caesam SDK | 26 Analysis interface definition

Here we have 2 groups: "Shape and Dimensions" (containing the 3 fields "length", "width" and
"curvedshape") and "Other" (containing the 3 fields damagecoeff, stressintensityfactor and inverseenergy).
As we said above, since all fields are members, we don't need to specify a label, as the default will be the
translated membername.

<Instance Type="CaesamStd_FormDescriptor">

<Title Type="Caesam_String">Panel Geometry</Title>


<FieldGroups Type="Caesam_TypedArray">
<Type Type="Caesam_String">CaesamStd_FieldGroup</Type>

<Item Type="CaesamStd_FieldGroup">
<Label Type="Caesam_String">Shape and Dimensions</Label>
<FieldDescriptors Type="Caesam_TypedArray">
<Type Type="Caesam_String">CaesamStd_FieldDescriptor</Type>

<Item Type="CaesamStd_FieldDescriptor">
<Path Type="Caesam_String">length</Path>
<Type Type="Caesam_String">CaesamQty_LENGTH</Type>
</Item>

<Item Type="CaesamStd_FieldDescriptor">
<Path Type="Caesam_String">width</Path>
<Type Type="Caesam_String">CaesamQty_LENGTH</Type>
</Item>

<Item Type="CaesamStd_FieldDescriptor">
<Path Type="Caesam_String">curvedshape</Path>
<Type Type="Caesam_String">CaesamEnum_TrueFalse</Type>
</Item>

</FieldDescriptors>
</Item>

<Item Type="CaesamStd_FieldGroup">
<Label Type="Caesam_String">Other</Label>
<FieldDescriptors Type="Caesam_TypedArray">
<Type Type="Caesam_String">CaesamStd_FieldDescriptor</Type>

<Item Type="CaesamStd_FieldDescriptor">
<Path Type="Caesam_String">damagecoeff</Path>
<Type Type="Caesam_String">Caesam_Quantity</Type>
</Item>

<Item Type="CaesamStd_FieldDescriptor">
<Path Type="Caesam_String">stressintensityfactor</Path>
<Type Type="Caesam_String">CaesamQty_STRESS_INTENSITY_FACTOR</Type>
</Item>

<Item Type="CaesamStd_FieldDescriptor">
<Path Type="Caesam_String">inverseenergy</Path>
<Type Type="Caesam_String">CaesamQty_INVERSE_ENERGY</Type>
</Item>

</FieldDescriptors>
</Item>

</FieldGroups>
</Instance>

An example of using a second path for setting a value has been made in BucklingFormDescriptor. You
can change the panel surface and the modified value will be passed to method SetSurface defined on
PanelGeometry (see section "Analysis Editors" below).

page-238
26 Analysis interface definition | Caesam SDK

26.4 Analysis editors


Before Caesam V5, only EOs could be edited in the GUI. Editing an analysis consisted of editing all its
EOs in the property view.
Now, analysis can be direclty edited in the tree editor or by selecting the command "Edit' in the right-click
popup menu (or by double-clickng one analysis).
But to edit an analysis like that, the author must associate an editor to its analysis template. A first way
of doing this is by writing its own Java editor, just as for EOs.
But the generic form editor, described in previous section for editing EOs, can also be used for editing
CP's or analysis. All you need to do is to associate a form descriptor to your analysis template.

Form descriptor example

An example of a form descriptor has been made for editing analyses of type BucklingSuperStiffener. The
url containing the instance of the form descriptor must be associated to the analysis template through the
resource "FormDescriptor".
As we already said in previous section, this example demonstrates the use of a second path for setting a
value. You can indeed change the panel's surface and the modified value will be passed to method
SetSurface defined on PanelGeometry.
Below is a simplified version of this form descriptor, showing some interesting parts.
For the complete sources, see files in examples/plugins/com.samcef.caesam.test.process/ :

plugin.xml
resources/BucklingFormDescriptor.csm

<Instance Type="CaesamStd_FormDescriptor">

<Title>Buckling Analysis Quick Edit</Title>

<FieldGroups Type="Caesam_TypedArray">
<Type>CaesamStd_FieldGroup</Type>

<Item Type="CaesamStd_FieldGroup">
<Label>Supports</Label>

<FieldDescriptors Type="Caesam_TypedArray">
<Type>CaesamStd_FieldDescriptor</Type>

<Item Type="CaesamStd_FieldDescriptor">
<Label>SuperStiffener</Label>
<Path>CP</Path>
<Type>SuperStiffener</Type>
<Editable>FALSE</Editable>
</Item>

</FieldDescriptors>
</Item>

<Item Type="CaesamStd_FieldGroup">
<Label>Super Stiffener Dimensions</Label>

<FieldDescriptors Type="Caesam_TypedArray">
<Type>CaesamStd_FieldDescriptor</Type>

<Item Type="CaesamStd_FieldDescriptor">
<Label>Left Panel Surface</Label>
<Type>CaesamQty_AREA</Type>
<InitiallyEnabled>TRUE</InitiallyEnabled>
<Path Type="S">EO[LeftPanelGeometry]/@ComputeSurface
</Path>
<SetPath>
EO[LeftPanelGeometry]/@SetSurface
</SetPath>
</Item>

<Item Type="CaesamStd_FieldDescriptor">
<Label>Left Panel Thickness</Label>
<Path>EO[LeftPanelProfile]/thickness</Path>
<Type>CaesamQty_LENGTH</Type>

page-239
Caesam SDK | 26 Analysis interface definition

<InitiallyEnabled>FALSE</InitiallyEnabled>
<NumberFormat Initialize="*caesam.examples.numberformats.Thickness"/>
</Item>

</FieldDescriptors>
</Item>

<Item Type="CaesamStd_FieldGroup">
<Label>Super Stiffener Material</Label>

<FieldDescriptors Type="Caesam_TypedArray">
<Type>CaesamStd_FieldDescriptor</Type>

<Item Type="CaesamStd_FieldDescriptor">
<Label>Left Panel Material</Label>
<Path>EO[LeftPanelMaterial]</Path>
<Type>Material</Type>
</Item>

</FieldDescriptors>
</Item>

</FieldGroups>
</Instance>

Custom Java analysis editor

If you need more customization, you can implement your own analysis editor in Java.
The class EditorDataAnalysis implements some analysis-specific services (such as following the CP for
a given key) that can be used in a custom analysis editor.
Note: don't use the class CaesamAPI_AnalysisObject directly in your custom analysis editors (as we did
before V5.2), use EditorDataAnalysis instead.
For getting and setting EOs in analyses, you can use the generic services on EditorData:

EditorData Find(String thePath)

Purpose: returns another EditorData built by applying the given path

EditorData Find(String thePath, String theSetPath)

Purpose: same as above, but with two paths: the first one is used to obtain the value and the second one
to set the modified value.

void Set(Caesam_Object theData)

Purpose: replaces all objects inside this EditorData with the given one

void Set(EditorData theData)

Purpose: replaces each object inside this EditorData with the object at the same index in the given
EditorData

Custom Java editor example

Below is an example of a template you could use to create your own analysis editor

public class CustomAnalysisEditor extends AbstractEditor {

private EditorData myData;


private EditorDataAnalysis myEditorDataAnalysis;
private JPanel myEditorPanel;
private JScrollPane myScrollPane = new JScrollPane();

public String getTitle() {

page-240
26 Analysis interface definition | Caesam SDK

return "Custom Java Analysis Editor";


}

public void setEO(EditorData theData) {


myData = theData;
myEditorDataAnalysis = myData.GetAnalysis();
updatePanel();
}

@Override
public JComponent getEditorPanel() {
if (myEditorPanel == null) {
myEditorPanel = new JPanel();
myScrollPane.setViewportView(myEditorPanel);
}
return myScrollPane;
}

private void updatePanel(){


myEditorPanel.removeAll();
myEditorPanel.add(...);
}
}

An example of such a custom editor has been made for the BucklingSuperStiffener analysis.
This custom editor implementation does basically the same as the form descriptor mentioned above. In
particular, the method EditorData.Find(theGetPath, theSetPath) is used for editing the panel's surface.
But this custom Java editor adds some features that cannot be achieved with a form descriptor, namely:
• When selecting a material from the SWS, the values for Young, Poisson and elastic limit are displayed
in the drop down list.
• It proposes an additional entry [Follow CP] in the Material drop down list, as well as one additional
entry for each configuration defined on the support Panel for Material. To achieve this, we use the
services provided by EditorDataAnalysis, whose instance is obtained with EditorData.GetAnalysis()
See files in examples/plugins/com.samcef.caesam.test.process/ :

plugin.xml
src/java/com/samcef/caesam/process/BucklingSuperStiffenerAnalysisEditor.java

26.5 Tabular editors


Tabular editors are used to edit all selected items in one table. Typically, there is one row per item, although
this is not strictly mandatory.
You can customize the tabular editor in two ways

26.5.1 Form Descriptors


A first way is to associate a XML FormDescriptor to the object type. This form descriptor will then be
used when editing objects of this type: each path in the form descriptor will become a column in the table.
See section "Form Editors" in this chapter for details on how to create and associate a form descriptor.
You can test this feature by selecting the tabular editor for PanelGeometry EOs and BucklingSuperStiffener
analyses. Indeed, these objects both have a form descriptor associated (declared resp. in
com.samcef.caesam.test.transverse and in com.samcef.caesam.test.process).
In a form descriptor, you can specify that a column should be editable or not, and thata column should
be initially enabled or not.

page-241
Caesam SDK | 26 Analysis interface definition

You can also specify the number format to be used for each column (member "NumberFormat" in
CaesamStd_FieldDescriptor).
Also, when a tabular editor is based on a form descriptor, the groups declared in the descriptor are also
used to group the column headers. The table will thus in this case have two levels of column headers.
Note that authors should specify the type of their fields/columns in form descriptors (member "Type" in
CaesamStd_FieldDescriptor). If the field/column type is not or wrongly defined in the form descriptor,
Caesam will try to deduce it from the column contents.
Specifying the type in the form descriptor has two goals:
• it avoids that the framework has to deduce the type from the column contents
• if all values are NULL in a column, the form tabular editor will be able to create a new object of the
good type

26.5.2 Custom Tabular Editor Models


If you need more customization than the one offered by form descriptors, you can implement your own
tabular editor model. Currently, this can only be done in C++. In future versions, it should be possible to
do this also in Python or Java.
Defining a custom tabular editor model basically consists in specifying the columns to propose, to give
the table contents and to handle modifications done by the user.

Mandatory methods

To make a custom tabular editor model, you must create and register a new Caesam object type inheriting
from CaesamStd_AbstractTabularEditorModel, and at least implement the following 6 abstract methods.
In any of these methods, you can use the method GetEditedItems(), that returns a CaesamStd_ItemArray
containing the items the user wants to edit.

void Initialize()

This method is called by the framework just before the editor is displayed for a given selection. Here, you
can initialize any data you would need in the other methods described below.

Handle(Caesam_Object) GetValueAt(const Standard_Integer theRow, const


Standard_Integer theColumn)

This method is called by the framework to obtain the content of the visible table cells. It must return a
Caesam_Object. This object will be rendered to the user as a string (see GetCellRenderer below), and
edited with a cell editor that is suitable for the object's type.
In your implementation of GetValueAt, you can use the utility methods GetValueByPath if you want to
specify columns that can be obtained from another column via a path. In this case, the path must be of
the form [<RefColname>]/....

Standard_Boolean SetValueAt(const Standard_Integer theRow, const


Standard_Integer theColumn, const Handle(Caesam_Object)& theValue)

This method is called when the user has modified a cell value via the cell editor. It must return a boolean
indicating if the update was successful.
In your implementation of SetValueAt, you can use the utility methods SetValueByPath if you want to
specify columns that can be obtained from another column via a path.

Standard_Integer GetColumnCount()
STL_String GetColumnName(const Standard_Integer theColumnIndex)
Handle(Caesam_Class) GetColumnClass(const Standard_Integer theColumnIndex)

page-242
26 Analysis interface definition | Caesam SDK

These methods are called by the framework to know respectively: the total number of columns, the class
and the name of each column.
You can also specify column grouping: to achieve this, you just have to let the method GetColumnName
return something as "Group/SubGroup/ColumnName".

Optional methods

You can further customize your tabular editor model by redefining the following methods. A default
implementation is proposed for these methods and it is thus optional to redefine them.

Standard_Integer GetRowCount()

Redefine this method if you want to change the default behaviour, which is to have one row for each
edited item.

Handle(CaesamStd_Item) GetEditedItem(const Standard_Integer theRowIndex)

This method must return the item associated to given row. It has a default implementation based on the
assumption that 1 row = 1 item. If you override GetRowCount to change this default behaviour, you
MUST also redefine this method.

STL_String GetRowName(const Standard_Integer theRowIndex)

Redefine this method to customize the row labels. By default the row label is the row number.

Handle(Caesam_ObjectMap) GetCellEnumeratedValues(const Standard_Integer theRow,


const Standard_Integer theColumn)

This method allows specifying a closed list of predefined values for some cells, from which the user can
choose from.

STL_String GetCellRenderer(const Standard_Integer theRow, const


Standard_Integer theColumn)

Redefine this method if you want to use a specific renderer for the object returned by GetValueAt.
Valid renderer are:
• For all types: Type, UserType, Path, UUID
• For all primitives: Value
• For all items: Name, Package
• For links: Configuration

Standard_Boolean IsCellEditable(const Standard_Integer theRow, const


Standard_Integer theColumn)

Redefine this method if you want to make some cells read-only.

Standard_Boolean IsColumnInitiallyEnabled(const Standard_Integer


theColumnIndex)

Redefine this method if you want some columns to be disabled by default (i.e. when the table if first
displayed). Columns that are disabled by default can be displayed by the user by selecting them in the
“table descriptor” dialog.

STL_String GetCellDimension(const Standard_Integer theRowIndex , const


Standard_Integer theColumnIndex)
STL_String GetCellUnit( const Standard_Integer theRowIndex , const
Standard_Integer theColumnIndex)

page-243
Caesam SDK | 26 Analysis interface definition

Redefine these methods if you have some columns for which GetValueAt does not return a
Caesam_Quantity, but for which you still want the user to be able to see/change the unit (i.e. columns
that "semantically" contain quantities).
Note that in this case, it's up the the author to use GetQuantityColumnUnit (i.e. the unit chosen by the
user) in GetValueAt, SetValueAt and if need be in GetCellEnumeratedValues.

Handle_Caesam_Object GetColumnDefaultValue(const Standard_Integer


theColumnIndex)

Redefine this method if you want a specific default value to be used when GetValueAt returns null.

Standard_Boolean CanInsertRows()
Standard_Boolean InsertRow(const Standard_Integer theRowIndex)

Redefine these methods if you want to add support for row insertion in your model. By default, row
insertion is not supported.

Standard_Boolean CanRemoveRows()
Standard_Boolean CanRemoveRow(const Standard_Integer theRowIndex)
Standard_Boolean RemoveRow(const Standard_Integer theRowIndex)

Redefine these methods if you want to override the default behaviour of the 'Remove Row' command,
which is to remove the corresponding item from the model (and a row can be removed only if the
corresponding item is not in use).

Standard_Boolean CanInsertColumns()
Standard_Boolean InsertColumn(const Standard_Integer theColumnIndex)
Standard_Boolean CanRemoveColumns()
Standard_Boolean CanRemoveColumn(const Standard_Integer theColumnIndex)
Standard_Boolean RemoveColumn(const Standard_Integer theRowIndex)

Similarly, redefine these methods if you want to support adding and removing columns in your model.
By default, column insertion and removal are not supported.

Handle(CaesamRes_NumberFormat) GetCellNumberFormat(const Standard_Integer


theRow,const Standard_Integer theColumn)

Redefine this method (which returns a CaesamRes_NumberFormat object) to specify a custom number
formatting to be used. The default implementation of this method returns NULL, which means that the
default number format will be used (this default number format can be modified in the preferences).

Declaring a custom model

To declare a custom tabular editor model, all you have to do is to associate a resource named
“TabularEditorModel” to the object type(s) you want to edit with your model. This resource is a string,
which must be the name of a caesam class inheriting from CaesamStd_AbstractTabularEditorModel.

Examples

An example of a custom tabular editor model has been made for editing EOs of type StackingSequence.
Each stacking sequence will thus be represented as one row in the table. More precisely, this example
model allows editing the list of ply orientations and thicknesses as strings with format ".../.../...".
This example also demonstrates some of the optional methods that can be redefined:
• GetCellDimension/Unit: user can change the unit in which orientations and thicknesses are expressed
• GetCellEnumeratedValues: some predefined ply orientations are proposed to the user
• IsCellEditable, GetCellRenderer, IsColumnInitiallyEnabled
Columns are also grouped in sections (see implementation of GetColumnName).
The source code of this example tabular editor model is reproduced below

page-244
26 Analysis interface definition | Caesam SDK

You'll find the source files in examples/plugins/com.samcef.caesam.test.transverse/ :

plugin.xml
src/pluginlib/inc/StackingSequenceTabularEditorModel.hxx
src/pluginlib/cxx/StackingSequenceTabularEditorModel.cxx

#define COLCOUNT 6
#define COLINDEX_NAME 0
#define COLINDEX_THICKNESS 1
#define COLINDEX_ORIENTATION 2
#define COLINDEX_MATERIAL 3
#define COLINDEX_MATERIAL_PACKAGE 4 // to demonstrate GetCellRenderer
#define COLINDEX_MATERIAL_POISSON 5 // to demonstrate Get/SetValueByPath

//=======================================================================
//function : Initialize
//purpose :
//=======================================================================

void StackingSequenceTabularEditorModel::Initialize()
{
// here you can do some initialization using GetEditedItems
}

//=======================================================================
//function : GetColumnCount
//purpose :
//=======================================================================

Standard_Integer StackingSequenceTabularEditorModel::GetColumnCount() const


{
return COLCOUNT;
}

//=======================================================================
//function : GetValueAt
//purpose :
//=======================================================================

Handle(Caesam_Object) StackingSequenceTabularEditorModel::GetValueAt(const Standard_Integer theRowIndex, const


Standard_Integer theColumnIndex) const
{
Handle(CaesamStd_Item) aEditedSequence = GetEditedItems()->GetItem(theRowIndex);
if (theColumnIndex == COLINDEX_NAME) return new Caesam_String(aEditedSequence->GetName());
else {

Handle(Caesam_TypedTable) aPlies = Caesam_TypedTable::Cast(aEditedSequence->GetMember("plies"));


if (!aPlies.IsNull()) {

if (theColumnIndex == COLINDEX_THICKNESS) {
STL_String aThickness = "";
for (Standard_Integer aPlyIndex = 0; aPlyIndex < aPlies->GetRowCount(); aPlyIndex++) {
Handle(CaesamStd_EO) aPly = CaesamStd_EO::Cast(aPlies->GetRowObject(aPlyIndex));
if (!aThickness.empty()) aThickness += "/";
aThickness +=
CaesamRes_NumberFormat::GetDefaultFormat()->DoubleToString(aPly->GetQuantity("thickness")->GetValue(GetQuantityColumnUnit(theColumnIndex)));

}
return new Caesam_String(aThickness);
}

else if (theColumnIndex == COLINDEX_ORIENTATION) {


STL_String aOrientation = "";
for (Standard_Integer aPlyIndex = 0; aPlyIndex < aPlies->GetRowCount(); aPlyIndex++) {
Handle(CaesamStd_EO) aPly = CaesamStd_EO::Cast(aPlies->GetRowObject(aPlyIndex));
if (!aOrientation.empty()) aOrientation += "/";
aOrientation +=
CaesamRes_NumberFormat::GetDefaultFormat()->DoubleToString(aPly->GetQuantity("orientation")->GetValue(GetQuantityColumnUnit(theColumnIndex)));

}
return new Caesam_String(aOrientation);
}

else if (theColumnIndex == COLINDEX_MATERIAL || theColumnIndex == COLINDEX_MATERIAL_PACKAGE) {


Handle(CaesamStd_EO) aCommonMaterial = NULL;
for (Standard_Integer aPlyIndex = 0; aPlyIndex < aPlies->GetRowCount(); aPlyIndex++) {
Handle(CaesamStd_EO) aPly = CaesamStd_EO::Cast(aPlies->GetRowObject(aPlyIndex));
Handle(CaesamStd_EO) aMaterial = CaesamStd_EO::Cast(aPly->GetMember("material"));
if (aCommonMaterial.IsNull()) aCommonMaterial = aMaterial;
else if (!aMaterial.IsNull() && !aCommonMaterial->IsSame(aMaterial)) {
CSM_LOG_VERBOSE_ARGS("StackingSequenceTabularEditorModel", "GetValueAt", "The material on %1% is not the same
on all plies. If you select another material, it will be appied on all plies.", aEditedSequence->GetName());
break;
}
}
return aCommonMaterial;
}

else if (theColumnIndex == COLINDEX_MATERIAL_POISSON) {


return GetValueByPath(theRowIndex, "[Material]/poisson");
}
}
}

return NULL;
}

page-245
Caesam SDK | 26 Analysis interface definition

//=======================================================================
//function : SetValueAt
//purpose :
//=======================================================================

Standard_Boolean StackingSequenceTabularEditorModel::SetValueAt(const Standard_Integer theRow, const Standard_Integer


theColumn, const Handle(Caesam_Object)& theValue)
{
// get object edited at the given row
Handle(CaesamStd_Item) aEditedSequence = GetEditedItems()->GetItem(theRow);
if (theColumn == COLINDEX_NAME) aEditedSequence->SetName(theValue->GetStringValue());
else {

Handle(Caesam_TypedTable) aPlies = Caesam_TypedTable::Cast(aEditedSequence->GetMember("plies"));


if (aPlies.IsNull()) return Standard_False;

// set the selected material on each ply


if (theColumn == COLINDEX_MATERIAL) {
for (Standard_Integer aPlyIndex = 0; aPlyIndex < aPlies->GetRowCount(); aPlyIndex++)
aPlies->SetObjectItem(aPlyIndex, aPlies->GetColumnIndex("material"), theValue);
}

// set the material's poisson value


else if (theColumn == COLINDEX_MATERIAL_POISSON) {
return SetValueByPath(theRow, "[Material]/poisson", theValue);
}

else {

// split the string with format ../../..


Handle(Caesam_StringArray) aParts = Caesam_String::Split(theValue->GetStringValue(), "/");
if (aParts->Size() != aPlies->GetRowCount()) {
CSM_LOG_ERROR_ARGS("StackingSequenceTabularEditorModel", "SetValueAt", "You're trying to assign value %1% but the
sequence has only %2% plies."
"This example editor cannot change the number of plies in the sequence yet.", theValue->GetStringValue() <<
aPlies->GetRowCount());
return Standard_False;
}

Caesam_Double aTmpDouble;

if (theColumn == COLINDEX_THICKNESS) {

// assign resp. thickness to each ply


for (Standard_Integer aPlyIndex = 0; aPlyIndex < aPlies->GetRowCount(); aPlyIndex++) {
Standard_Integer aPlyColumnIndex = aPlies->GetColumnIndex("thickness");
aTmpDouble.FromString(aParts->Get(aPlyIndex));
Handle(Caesam_Quantity) aQuantity = Caesam_Quantity::Cast(aPlies->GetItem(aPlyIndex, aPlyColumnIndex));
aQuantity->SetValue(aTmpDouble.GetValue(), GetQuantityColumnUnit(theColumn));
aPlies->SetQuantityItem(aPlyIndex, aPlyColumnIndex, aQuantity->GetValue());
}
}

else if (theColumn == COLINDEX_ORIENTATION) {

// assign resp. orientation to each ply


for (Standard_Integer aPlyIndex = 0; aPlyIndex < aPlies->GetRowCount(); aPlyIndex++) {
Standard_Integer aPlyColumnIndex = aPlies->GetColumnIndex("orientation");
aTmpDouble.FromString(aParts->Get(aPlyIndex));
Handle(Caesam_Quantity) aQuantity = Caesam_Quantity::Cast(aPlies->GetItem(aPlyIndex, aPlyColumnIndex));
aQuantity->SetValue(aTmpDouble.GetValue(), GetQuantityColumnUnit(theColumn));
aPlies->SetQuantityItem(aPlyIndex, aPlyColumnIndex, aQuantity->GetValue());
}
}
}
}

return Standard_True;
}

//=======================================================================
//function : GetColumnName
//purpose :
//=======================================================================

STL_String StackingSequenceTabularEditorModel::GetColumnName(const Standard_Integer theColumnIndex) const


{
if (theColumnIndex == COLINDEX_NAME) return "Name";
else if (theColumnIndex == COLINDEX_THICKNESS) return "Properties/Per ply/Tickness";
else if (theColumnIndex == COLINDEX_ORIENTATION) return "Properties/Per ply/Orientation";
else if (theColumnIndex == COLINDEX_MATERIAL) return "Properties/For all plies/Material";
else if (theColumnIndex == COLINDEX_MATERIAL_PACKAGE) return "Properties/For all plies/Material Package";
else if (theColumnIndex == COLINDEX_MATERIAL_POISSON) return "Properties/For all plies/Poisson";
return "";
}

//=======================================================================
//function : GetColumnClass
//purpose :
//=======================================================================

Handle(Caesam_Class) StackingSequenceTabularEditorModel::GetColumnClass(const Standard_Integer theColumnIndex) const


{
if (theColumnIndex == COLINDEX_NAME) return Caesam_String::GetRegisteredClass();
else if (theColumnIndex == COLINDEX_THICKNESS) return Caesam_String::GetRegisteredClass();
else if (theColumnIndex == COLINDEX_ORIENTATION) return Caesam_String::GetRegisteredClass();
else if (theColumnIndex == COLINDEX_MATERIAL) return
Caesam_Application::GetApplication()->GetRegistry()->GetClass("Material");
else if (theColumnIndex == COLINDEX_MATERIAL_PACKAGE) return
Caesam_Application::GetApplication()->GetRegistry()->GetClass("Material");
else if (theColumnIndex == COLINDEX_MATERIAL_POISSON) return Caesam_Quantity::GetRegisteredClass();
return NULL;

page-246
26 Analysis interface definition | Caesam SDK

//=======================================================================
//function : GetCellEnumeratedValues
//purpose :
//=======================================================================

Handle(Caesam_ObjectMap) StackingSequenceTabularEditorModel::GetCellEnumeratedValues(const Standard_Integer theRow,


const Standard_Integer theColumn) const
{
if (theColumn == COLINDEX_ORIENTATION) {

// build the list of possible values for orientation, for the given row (expressed in to current column unit)
// remember that each row represents a stacking sequence, possibly with different sizes
Handle(Caesam_ObjectMap) aEnumeratedValues = new Caesam_ObjectMap();
Handle(CaesamStd_Item) aEditedSequence = GetEditedItems()->GetItem(theRow);
Handle(Caesam_TypedTable) aPlies = Caesam_TypedTable::Cast(aEditedSequence->GetMember("plies"));
for (Standard_Integer aAngle = 45; aAngle <= 90; aAngle+=45) {
STL_String aPossibleValue = "";
for (Standard_Integer aPlyIndex = 0; aPlyIndex < aPlies->GetRowCount(); aPlyIndex++) {
Standard_Real aConvertedValue = UnitsAPI::AnyToAny(aAngle * aPlyIndex % 360, "deg",
(char*)GetQuantityColumnUnit(theColumn).c_str());
if (!aPossibleValue.empty()) aPossibleValue += "/";
aPossibleValue += CaesamRes_NumberFormat::GetDefaultFormat()->DoubleToString(aConvertedValue);
}
aEnumeratedValues->Put(aPossibleValue, new Caesam_String(aPossibleValue));
}

return aEnumeratedValues;
}

return NULL;
}

//=======================================================================
//function : GetCellRenderer
//purpose :
//=======================================================================

STL_String StackingSequenceTabularEditorModel::GetCellRenderer(const Standard_Integer theRow,const Standard_Integer


theColumn) const
{
// the abstract table model allows us to have different renderers for each row,
// but we don't use this feature: the renderer here depends only on the column
if (theColumn == COLINDEX_MATERIAL_PACKAGE) return "Package";
return "";
}

//=======================================================================
//function : IsCellEditable
//purpose :
//=======================================================================

Standard_Boolean StackingSequenceTabularEditorModel::IsCellEditable(const Standard_Integer theRow, const Standard_Integer


theColumn) const
{
if (theColumn == COLINDEX_MATERIAL_PACKAGE) return Standard_False;
return Standard_True;
}

//=======================================================================
//function : IsColumnInitiallyEnabled
//purpose :
//=======================================================================

Standard_Boolean StackingSequenceTabularEditorModel::IsColumnInitiallyEnabled(const Standard_Integer theColumnIndex)


const
{
if (theColumnIndex == COLINDEX_MATERIAL_PACKAGE) return Standard_False;
return Standard_True;
}

//=======================================================================
//function : GetCellDimension
//purpose :
//=======================================================================

STL_String StackingSequenceTabularEditorModel::GetCellDimension(const Standard_Integer theRowIndex, const


Standard_Integer theColumnIndex) const
{
Handle(CaesamStd_Item) aEditedSequence = GetEditedItems()->GetItem(theRowIndex);
Handle(Caesam_TypedTable) aPlies = Caesam_TypedTable::Cast(aEditedSequence->GetMember("plies"));
if (theColumnIndex == COLINDEX_THICKNESS || theColumnIndex == COLINDEX_ORIENTATION) {
Handle(Caesam_Quantity) aDefaultQuantity =
Caesam_Quantity::Cast(aPlies->GetColumnDefaultValue(aPlies->GetColumnIndex(theColumnIndex == COLINDEX_THICKNESS ?
"thickness" : "orientation")));
if (aDefaultQuantity.IsNull()) {
CSM_LOG_ERROR("StackingSequenceTabularEditorModel", "GetCellDimensionreturn", "Could not find default quantity
for thickness column"); return "";
}
return aDefaultQuantity->GetDimension();
}
return CaesamStd_AbstractTabularEditorModel::GetCellDimension(theRowIndex, theColumnIndex);
}

//=======================================================================
//function : GetCellUnit
//purpose :
//=======================================================================

STL_String StackingSequenceTabularEditorModel::GetCellUnit(const Standard_Integer theRowIndex, const Standard_Integer


theColumnIndex) const

page-247
Caesam SDK | 26 Analysis interface definition

{
Handle(CaesamStd_Item) aEditedSequence = GetEditedItems()->GetItem(theRowIndex);
Handle(Caesam_TypedTable) aPlies = Caesam_TypedTable::Cast(aEditedSequence->GetMember("plies"));
if (theColumnIndex == COLINDEX_THICKNESS || theColumnIndex == COLINDEX_ORIENTATION) {
Handle(Caesam_Quantity) aDefaultQuantity =
Caesam_Quantity::Cast(aPlies->GetColumnDefaultValue(aPlies->GetColumnIndex(theColumnIndex == COLINDEX_THICKNESS ?
"thickness" : "orientation")));
if (aDefaultQuantity.IsNull()) {
CSM_LOG_ERROR("StackingSequenceTabularEditorModel", "GetCellDimensionreturn", "Could not find default quantity
for thickness column"); return "";
}
return aDefaultQuantity->GetGuiUnit();
}
return CaesamStd_AbstractTabularEditorModel::GetCellUnit(theRowIndex, theColumnIndex);
}

//=======================================================================
//function : NewInstance
//purpose :
//=======================================================================

Handle(Caesam_Object) StackingSequenceTabularEditorModel::NewInstance(PTRARG(Caesam_Object) theArgument)


{
PTRMEM(Caesam_Object) aStackingSequence = new StackingSequenceTabularEditorModel();
if (theArgument.IsNull()) return aStackingSequence;
Standard_ConstructionError::Raise("StackingSequenceTabularEditorModel: argument should be NULL");
return NULL;
}

//=======================================================================
//function : GetRegisteredClass
//purpose :
//=======================================================================

Handle(Caesam_Class) StackingSequenceTabularEditorModel::GetRegisteredClass()
{
static Handle(Caesam_Class) aClass =
Caesam_Class::New("StackingSequenceTabularEditorModel", CaesamStd_AbstractTabularEditorModel::GetRegisteredClass(),

CAESAMCONSTRUCTOR(StackingSequenceTabularEditorModel::NewInstance), NULL);
return aClass;
}

//=======================================================================
//function : Register
//purpose :
//=======================================================================

void StackingSequenceTabularEditorModel::Register(const Handle(Caesam_Registry)& theRegistry)


{
theRegistry->RegisterClass(StackingSequenceTabularEditorModel::GetRegisteredClass());
}

Another example tabular editor model has been made for editing buckling analyses. This model does
basically the same as the XML form descriptor we mentionned above. But it also demonstrates how to
program the creation of stand alone analysis when inserting rows in the table.
See files in examples/plugins/com.samcef.caesam.test.process/ :

plugin.xml
src/pluginlib/inc/BucklingSuperStiffenerTabularEditorModel.hxx
src/pluginlib/cxx/BucklingSuperStiffenerTabularEditorModel.cxx

26.5.3 Forcing The Default Model


By default, the default tabular editor model is not proposed when there is a custom Java editor for the
object type. This has been done because, if the author has written a custom Java editor for his object, we
assume that the default tabular editor may be inappropriate.
But you can force the default tabular editor model to be proposed, even if there is a custom Java editor,
by defining the resource TabularEditorModel="DEFAULT".
This is demonstrated for the type Material (see com.samcef.caesam.test.tranverse/plugin.xml).

26.6 Editing Caesam tables and matrices in a custom Java editor


The default editor Caesam provides a way of editing objects of type Caesam_(Typed)Table, as well as
all kinds of matrices (Caesam_Object/Typed/String/Integer/Boolean/Double/QuantityMatrix). But it is

page-248
26 Analysis interface definition | Caesam SDK

also possible to embed Caesam_Table or matrices in your own editors. To achieve this, you can use the
following code to create the Java tables, that you can then add to any JPanel:

APIObjectCaesamTable aTable = new APIObjectCaesamTable(aEditorData,


aTableMemberName);
APIObjectMatrixTable aTable = new APIObjectMatrixTable(aEditorData,
aMatrixMemberName);

The example TestCaesamTableEditor in plugin com.samcef.caesam.test.table demonstrates how to have


2 tables editing the same underlying Caesam_Table but showing different columns. Note that if e.g. a
row is inserted or removed (or if a cell is modified) in one table, the row will automatically appear or
disappear (or the cell will automatically be updated) in the other table.
This example also demonstrates how to simply group columns in the Caesam_TypedTable editor. Note
that the nested column headers have to be rebuilt each time SetEO is called.
public class TestCaesamTableEditor extends AbstractEditor {

APIObjectCaesamTable myTable;
APIObjectCaesamTable myTable2;
EditorData myData;
JPanel myPanel = null;

public String getTitle(){


return "Test Caesam Table Editor";
}

public JComponent getEditorPanel() {


if (myPanel == null) myPanel = new JPanel(new BorderLayout());
return myPanel;
}

public void setEO(EditorData theData) {


if (myData != theData) {
myData = theData;
createOrUpdateTables();
createNestedHeaders();
}
}

private void createOrUpdateTables() {

if (myTable == null) {

// get an EditorDataTable (i.e. table model) on our Caesam_Table member


EditorDataTable aModel = myData.GetTable("table");

// create a table and disable (hide) the 2nd column


myTable = new APIObjectCaesamTable(myData,"table",aModel);
myTable.setColumnEnabled(1, false);

// create another table that shows only the first 2 columns


myTable2 = new APIObjectCaesamTable(myData,"table",aModel);
myTable2.setColumnEnabled(2, false);
myTable2.setColumnEnabled(3, false);

// add both tables in a panel


JPanel aPanel = new JPanel(new BorderLayout());
aPanel.add(new JScrollPane(myTable), BorderLayout.WEST);
aPanel.add(new JScrollPane(myTable2), BorderLayout.EAST);

getEditorPanel().add(new JScrollPane(aPanel), BorderLayout.CENTER);


}

else {

myTable.setEditorData(myData);
myTable.setColumnEnabled(1, false);

myTable2.setEditorData(myData);
myTable2.setColumnEnabled(2, false);
myTable2.setColumnEnabled(3, false);
}
}

private void createNestedHeaders() {

// create the customized header


JExtendedTableHeader header = myTable.getExtendedTableHeader();
ExtendedTableHeaderModel model = header.getExtendedModel();
DefaultTableHeaderNode section1 = new DefaultTableHeaderNode("sous section1");
DefaultTableHeaderNode section2 = new DefaultTableHeaderNode("sous section2");
DefaultTableHeaderNode section3 = new DefaultTableHeaderNode("section");
section1.addChild(model.getColumnHeader(0));
section2.addChild(model.getColumnHeader(1));
section2.addChild(model.getColumnHeader(2));
section3.addChild(section1);
section3.addChild(section2);
}

page-249
Caesam SDK | 26 Analysis interface definition

You can test this editor by creating and editing an EO of type "TestCaesamTableInheritance".
In future version, the same possibilities will exist for arrays and maps.

26.7 Author-defined table models

26.7.1 Overview
Since Caesam V5, tables in Caesam can be driven by author-defined table models. Currently, this can
only be done in C++. In future versions, it should be possible to do this also in Python or Java.
There are two kinds of tables that can be driven by an author model:
1. Tabular editors
These editors are used to edit all selected items in one table. Typically, there is one row per item,
although this is not strictly mandatory.
A first way to customize the tabular editors is to associate a FormDescriptor to the object type. Each
path in the form descriptor will become a column in the table. If you need more customization, you
can implement your own tabular editor model.
For more details on using form descriptors and writing custom tabular editor models, see section
"Tabular Editors" in chapter "Analysis Interface Definition".
2. Editor tables
Authors can make custom table models for editing data (EOs, analyses and CPs) with a "tabular
character". An editor table model, contrary to a tabular editor model, edits exactly 1 object as a table.
If you edit several items you will have several "layers" in your table. In this case, only common rows
and columns will be editable (other cells will be grayed) and you will see "..." in cells for which the
value is not the same in all layers. These multi-edition issues are handled by the framework and must
not be addressed by the author of the table model.

26.7.2 Custom editor table models

Mandatory methods

To make your own custom editor table model, you must create a new Caesam object type inheriting from
CaesamStd_AbstractEditorTableModel, and at least implement the following 10 abstract methods.
In any of these methods, you can use the method GetEditedObject(), that returns the Caesam_Object the
user wants to edit.

void Initialize()

This method is called by the framework just before the editor is displayed for a given object. Here, you
can initialize any data you would need in the other methods described below.

Handle(Caesam_Object) GetValueAt(const Standard_Integer theRow, const


Standard_Integer theColumn)

This method is called by the framework to obtain the content of the visible table cells. It must return a
Caesam_Object. This object will be rendered to the user as a string (see GetCellRenderer below), and
edited with a cell editor that is suitable for the object's type.

page-250
26 Analysis interface definition | Caesam SDK

In your implementation of GetValueAt, you can use the utility methods GetValueByPath if you want to
specify columns that can be obtained from another column via a path. In this case, the path must be of
the form [<RefColname>]/....

Standard_Boolean SetValueAt(const Standard_Integer theRow, const


Standard_Integer theColumn, const Handle(Caesam_Object)& theValue)

This method is called when the user has modified a cell value via the cell editor. It must return a boolean
indicating if the update was successful.
In your implementation of SetValueAt, you can use the utility methods SetValueByPath if you want to
specify columns that can be obtained from another column via a path.

Standard_Integer GetRowCount()

This method is called by the framework to know the total number of rows.

Standard_Integer GetColumnCount()
STL_String GetColumnName(const Standard_Integer theColumnIndex)
Handle(Caesam_Class) GetColumnClass(const Standard_Integer theColumnIndex)

These methods are called by the framework to know respectively: the total number of columns, the class
and the name of each column.
You can also specify column grouping: to achieve this, you just have to let the method GetColumnName
return something as "Group/SubGroup/ColumnName".

STL_String
CaesamStd_AbstractTabularEditorModel::GetQuantityColumnDimension(const
Standard_Integer theColumnIndex) const
STL_String CaesamStd_AbstractTabularEditorModel::GetQuantityColumnUnit(const
Standard_Integer theColumnIndex) const
Standard_Boolean
CaesamStd_AbstractTabularEditorModel::SetQuantityColumnUnit(const
Standard_Integer theColumnIndex, const STL_String& theUnit)

Redefine these methods to return the dimension .


These methods are called by the framework to get the dimension and unit of your quantity columns, and
when the user changes the unit of a column.

Optional methods

You can further customize your tabular editor model by redefining the following methods. A default
implementation is proposed for these methods and it is thus optional to redefine them.

STL_String GetRowName(const Standard_Integer theRowIndex)

Redefine this method to customize the row labels. By default the row label is the row number.

Handle(Caesam_ObjectMap) GetCellEnumeratedValues(const Standard_Integer theRow,


const Standard_Integer theColumn)

This method allows specifying a closed list of predefined values for some cells, from which the user can
choose from.

STL_String GetCellRenderer(const Standard_Integer theRow, const


Standard_Integer theColumn)

page-251
Caesam SDK | 26 Analysis interface definition

Redefine this method if you want to use a specific renderer for the object returned by GetValueAt.
Valid renderer are:
• For all types: Type, UserType, Path, UUID
• For all primitives: Value
• For all items: Name, Package
• For links: Configuration

Standard_Boolean IsCellEditable(const Standard_Integer theRow, const


Standard_Integer theColumn)

Redefine this method if you want to make some cells read-only.

Standard_Boolean IsColumnInitiallyEnabled(const Standard_Integer


theColumnIndex)

Redefine this method if you want some columns to be disabled by default (i.e. when the table if first
displayed). Columns that are disabled by default can be displayed by the user by selecting them in the
“table descriptor” dialog.

Handle_Caesam_Object GetColumnDefaultValue(const Standard_Integer


theColumnIndex)

Redefine this method if you want a specific default value to be used when GetValueAt returns null.

Standard_Boolean CanInsertRows()
Standard_Boolean InsertRow(const Standard_Integer theRowIndex)

Redefine these methods if you want to add support for row insertion in your model. By default, row
insertion is not supported.

Standard_Boolean CanRemoveRows()
Standard_Boolean CanRemoveRow(const Standard_Integer theRowIndex)
Standard_Boolean RemoveRow(const Standard_Integer theRowIndex)

Redefine these methods if you want to override the default behaviour of the 'Remove Row' command,
which is to remove the corresponding item from the model (and a row can be removed only if the
corresponding item is not in use).

Standard_Boolean CanInsertColumns()
Standard_Boolean InsertColumn(const Standard_Integer theColumnIndex)
Standard_Boolean CanRemoveColumns()
Standard_Boolean CanRemoveColumn(const Standard_Integer theColumnIndex)
Standard_Boolean RemoveColumn(const Standard_Integer theRowIndex)

Similarly, redefine these methods if you want to support adding and removing columns in your model.
By default, column insertion and removal are not supported.

Handle(CaesamRes_NumberFormat) GetCellNumberFormat(const Standard_Integer


theRow,const Standard_Integer theColumn)

Redefine this method (which returns a CaesamRes_NumberFormat object) to specify a custom number
formatting to be used. The default implementation of this method returns NULL, which means that the
default number format will be used (this default number format can be modified in the preferences).

Example custom table model

An example has been made of such a custom C++ table model. This example model is made for editing
EOs that are composed of two integer arrays (LoadIDs and ElementIDs) and one Caesam_TypedTable

page-252
26 Analysis interface definition | Caesam SDK

representing loads (Nx/Ny/Nz). It will display these 3 members as one single table, looking like this
(assuming we have 3 LoadIDs and 2 ElementIDs) :

LOAD_1 ELEMENT_1 NX_11 NY_11 NZ_11


LOAD_1 ELEMENT_2 NX_12 NY_12 NZ_12
LOAD_2 ELEMENT_1 NX_21 NY_21 NZ_21
LOAD_2 ELEMENT_2 NX_22 NY_22 NZ_22
LOAD_3 ELEMENT_1 NX_31 NY_31 NZ_31
LOAD_3 ELEMENT_2 NX_32 NY_32 NZ_32

The source code of this example editor table model is reproduced below
You'll find the source files in examples/plugins/com.samcef.caesam.test.table/ :

table.typedesc (declaration of our test object type)


src/puginlib/inc/TestCustomEditorTableModel.hxx
src/puginlib/cxx/TestCustomEditorTableModel.cxx

#define COLCOUNT 5
#define COLINDEX_LOAD_ID 0
#define COLINDEX_ELEMENT_ID 1
#define COLINDEX_NX 2
#define COLINDEX_NY 3
#define COLINDEX_NZ 4

//=======================================================================
//function : Initialize
//purpose :
//=======================================================================

void TestCustomEditorTableModel::Initialize()
{
myLoadIDs = Caesam_IntegerArray::Cast(GetEditedObject()->GetMember("LoadIDs"));
myElementIDs = Caesam_IntegerArray::Cast(GetEditedObject()->GetMember("ElementIDs"));
myLoadTable = Caesam_TypedTable::Cast(GetEditedObject()->GetMember("Loads"));
}

//=======================================================================
//function : GetColumnCount
//purpose :
//=======================================================================

Standard_Integer TestCustomEditorTableModel::GetColumnCount() const


{
return COLCOUNT;
}

//=======================================================================
//function : GetRowCount
//purpose :
//=======================================================================

Standard_Integer TestCustomEditorTableModel::GetRowCount() const


{
if (myLoadIDs.IsNull() || myElementIDs.IsNull()) return 0;
return myLoadIDs->Size() * myElementIDs->Size();
}

//=======================================================================
//function : GetValueAt
//purpose :
//=======================================================================

Handle(Caesam_Object) TestCustomEditorTableModel::GetValueAt(const Standard_Integer theRowIndex, const Standard_Integer


theColumnIndex) const
{
if (theColumnIndex == COLINDEX_LOAD_ID) {
if (myElementIDs.IsNull() || myElementIDs->Size() == 0) return NULL;
Standard_Integer aIndexInLoadIDs = theRowIndex / myElementIDs->Size();
if (myLoadIDs.IsNull() || myLoadIDs->Size() <= aIndexInLoadIDs) return NULL;
return new Caesam_Integer(myLoadIDs->Get(aIndexInLoadIDs));
}
else if (theColumnIndex == COLINDEX_ELEMENT_ID) {
if (myElementIDs.IsNull() || myElementIDs->Size() == 0) return NULL;
Standard_Integer aIndexInElementIDs = theRowIndex % myElementIDs->Size();
if (myElementIDs->Size() <= aIndexInElementIDs) return NULL;
return new Caesam_Integer(myElementIDs->Get(aIndexInElementIDs));
}
else if (theColumnIndex >= COLINDEX_NX) {
return myLoadTable->GetItem(theRowIndex, theColumnIndex - COLINDEX_NX);
}
return NULL;
}

//=======================================================================
//function : SetValueAt
//purpose :
//=======================================================================

Standard_Boolean TestCustomEditorTableModel::SetValueAt(const Standard_Integer theRowIndex, const Standard_Integer

page-253
Caesam SDK | 26 Analysis interface definition

theColumnIndex, const Handle(Caesam_Object)& theValue)


{
if (theColumnIndex == COLINDEX_LOAD_ID) {
if (myElementIDs.IsNull() || myElementIDs->Size() == 0) return NULL;
Standard_Integer aIndexInLoadIDs = theRowIndex / myElementIDs->Size();
if (myLoadIDs.IsNull() || myLoadIDs->Size() <= aIndexInLoadIDs) return NULL;
myLoadIDs->Set(theValue->GetIntegerValue(), aIndexInLoadIDs);
return Standard_True;
}
else if (theColumnIndex == COLINDEX_ELEMENT_ID) {
if (myElementIDs.IsNull() || myElementIDs->Size() == 0) return NULL;
Standard_Integer aIndexInElementIDs = theRowIndex % myElementIDs->Size();
if (myElementIDs->Size() <= aIndexInElementIDs) return NULL;
myElementIDs->Set(theValue->GetIntegerValue(), aIndexInElementIDs);
return Standard_True;
}
else if (theColumnIndex >= COLINDEX_NX) {
return myLoadTable->SetItem(theRowIndex, theColumnIndex - COLINDEX_NX, theValue);
}
return Standard_False;
}

//=======================================================================
//function : GetColumnName
//purpose :
//=======================================================================

STL_String TestCustomEditorTableModel::GetColumnName(const Standard_Integer theColumnIndex) const


{
if (theColumnIndex == COLINDEX_LOAD_ID) return "Load ID";
else if (theColumnIndex == COLINDEX_ELEMENT_ID) return "Element ID";
else if (theColumnIndex == COLINDEX_NX) return "Loads/Nx";
else if (theColumnIndex == COLINDEX_NY) return "Loads/Ny";
else if (theColumnIndex == COLINDEX_NZ) return "Loads/Nyz";
return "";
}

//=======================================================================
//function : GetColumnClass
//purpose :
//=======================================================================

Handle(Caesam_Class) TestCustomEditorTableModel::GetColumnClass(const Standard_Integer theColumnIndex) const


{
if (theColumnIndex == COLINDEX_LOAD_ID) return Caesam_Integer::GetRegisteredClass();
else if (theColumnIndex == COLINDEX_ELEMENT_ID) return Caesam_Integer::GetRegisteredClass();
else if (theColumnIndex == COLINDEX_NX) return Caesam_Quantity::GetRegisteredClass();
else if (theColumnIndex == COLINDEX_NY) return Caesam_Quantity::GetRegisteredClass();
else if (theColumnIndex == COLINDEX_NZ) return Caesam_Quantity::GetRegisteredClass();
return NULL;
}

//=======================================================================
//function : GetQuantityColumnDimension
//purpose :
//=======================================================================

STL_String TestCustomEditorTableModel::GetQuantityColumnDimension(const Standard_Integer theColumnIndex) const


{
if (theColumnIndex >= COLINDEX_NX) {
Handle(Caesam_QuantityColumn) aQuantityColumn = Caesam_QuantityColumn::Cast(myLoadTable->GetColumn(theColumnIndex
- COLINDEX_NX));
if (!aQuantityColumn.IsNull() && !aQuantityColumn->GetItems().IsNull() &&
aQuantityColumn->GetItems()->DimensionIsSet())
return aQuantityColumn->GetItems()->GetDimension();
}

return "";
}

//=======================================================================
//function : GetQuantityColumnUnit
//purpose :
//=======================================================================

STL_String TestCustomEditorTableModel::GetQuantityColumnUnit(const Standard_Integer theColumnIndex) const


{
if (theColumnIndex >= COLINDEX_NX) {
Handle(Caesam_QuantityColumn) aQuantityColumn = Caesam_QuantityColumn::Cast(myLoadTable->GetColumn(theColumnIndex
- COLINDEX_NX));
if (!aQuantityColumn.IsNull() && !aQuantityColumn->GetItems().IsNull() &&
aQuantityColumn->GetItems()->DimensionIsSet())
return aQuantityColumn->GetItems()->GetGuiUnit();
}

return "";
}

//=======================================================================
//function : SetQuantityColumnUnit
//purpose :
//=======================================================================

Standard_Boolean TestCustomEditorTableModel::SetQuantityColumnUnit(const Standard_Integer theColumnIndex, const


STL_String& theUnit)
{
if (theColumnIndex >= COLINDEX_NX) {
Handle(Caesam_QuantityColumn) aQuantityColumn = Caesam_QuantityColumn::Cast(myLoadTable->GetColumn(theColumnIndex
- COLINDEX_NX));
if (!aQuantityColumn.IsNull() && !aQuantityColumn->GetItems().IsNull() &&
aQuantityColumn->GetItems()->DimensionIsSet()) {
aQuantityColumn->GetItems()->SetGuiUnit(theUnit);

page-254
26 Analysis interface definition | Caesam SDK

return Standard_True;
}
}

return Standard_False;
}

//=======================================================================
//function : AddLoadID
//purpose :
//=======================================================================

Standard_Boolean TestCustomEditorTableModel::AddLoadID(const Standard_Integer theLoadID)


{
// add load ID
myLoadIDs->Append(theLoadID);

// add a line in table for each element


for (Standard_Integer aIndex = 0; aIndex < myElementIDs->Size(); aIndex++) {
if (!myLoadTable->InsertRowObject(Caesam_Application::GetApplication()->NewObject("LoadRowObject"),
myLoadTable->GetRowCount()))
return Standard_False;
}

// since we added rows without going through the framework methodInsertRow, we must explicitely warn our listeners

return FireTableRowsInserted(myLoadTable->GetRowCount() - myElementIDs->Size(), myLoadTable->GetRowCount() - 1);


}

//=======================================================================
//function : AddElementID
//purpose :
//=======================================================================

Standard_Boolean TestCustomEditorTableModel::AddElementID(const Standard_Integer theElementID)


{
// add element ID
myElementIDs->Append(theElementID);

// add a line in table for each load


Standard_Integer aRowIndex = myElementIDs->Size() - 1;
for (Standard_Integer aIndex = 0; aIndex < myLoadIDs->Size(); aIndex++) {

if (!myLoadTable->InsertRowObject(Caesam_Application::GetApplication()->NewObject("LoadRowObject"), aRowIndex))
return Standard_False;

// since we added a row without going through the framework methodInsertRow, we must explicitely warn our listeners

if (!FireTableRowsInserted(aRowIndex, aRowIndex)) return Standard_False;


aRowIndex += myElementIDs->Size();
}

return Standard_True;
}

//=======================================================================
//function : AddLoadID (static Caesam wrapper)
//purpose :
//=======================================================================

Handle(Caesam_Object) TestCustomEditorTableModel::AddLoadID(const Handle(Caesam_Object)& theInstance, const


Handle(Caesam_Object)& theArgument)
{
if (theArgument.IsNull() || !theArgument->IsKindOf(Caesam_Integer::GetRegisteredClass())) {
CSM_LOG_ERROR("TestCustomEditorTableModel", "AddElementID", "Wrong argument: expected be a Caesam_Integer"); return
NULL; }
return new Caesam_Boolean(CSMCAST(TestCustomEditorTableModel, theInstance)->AddLoadID(theArgument->GetIntegerValue()));
}

//=======================================================================
//function : AddElementID (static Caesam wrapper)
//purpose :
//=======================================================================

Handle(Caesam_Object) TestCustomEditorTableModel::AddElementID(const Handle(Caesam_Object)& theInstance, const


Handle(Caesam_Object)& theArgument)
{
if (theArgument.IsNull() || !theArgument->IsKindOf(Caesam_Integer::GetRegisteredClass())) {
CSM_LOG_ERROR("TestCustomEditorTableModel", "AddElementID", "Wrong argument: expected be a Caesam_Integer"); return
NULL; }
return new Caesam_Boolean(CSMCAST(TestCustomEditorTableModel,
theInstance)->AddElementID(theArgument->GetIntegerValue()));
}

//=======================================================================
//function : NewInstance
//purpose :
//=======================================================================

Handle(Caesam_Object) TestCustomEditorTableModel::NewInstance(PTRARG(Caesam_Object) theArgument)


{
if (!theArgument.IsNull()) Standard_ConstructionError::Raise("TestCustomEditorTableModel: argument should be NULL");

return new TestCustomEditorTableModel();


}

//=======================================================================
//function : GetRegisteredClass
//purpose :
//=======================================================================

Handle(Caesam_Class) TestCustomEditorTableModel::GetRegisteredClass()

page-255
Caesam SDK | 26 Analysis interface definition

{
static Handle(Caesam_Class) aClass =
Caesam_Class::New("TestCustomEditorTableModel", CaesamStd_AbstractEditorTableModel::GetRegisteredClass(),
CAESAMCONSTRUCTOR(TestCustomEditorTableModel::NewInstance), NULL);
return aClass;
}

//=======================================================================
//function : Register
//purpose :
//=======================================================================

void TestCustomEditorTableModel::Register(const Handle(Caesam_Registry)& theRegistry)


{
theRegistry->RegisterClass(TestCustomEditorTableModel::GetRegisteredClass());
theRegistry->RegisterMethod("TestCustomEditorTableModel","AddLoadID", &TestCustomEditorTableModel::AddLoadID);
theRegistry->RegisterMethod("TestCustomEditorTableModel","AddElementID", &TestCustomEditorTableModel::AddElementID);
}

26.7.3 Using your custom model in a Java editor


The next step is to write a custom Java editor in which you will be able to create one or more tables that
are built upon your custom C++ table model. This is very simple and is done with only one line of code.

APIObjectCustomTable aTable = new APIObjectCustomTable(aEditorData[,


aMemberName], "TestCustomEditorTableModel");

This line will create a APIObjectCustomTable (inherits from JTable) based on our C++ model. The
constructor of this class takes an instance of EditorData, an optional membername, and the name of you
registered C++ table model. As we mentioned in the overview, the multi-edition issues (remember that
you EditorData can contain several objects) are handled by the framework.
NB: the constructor also has an optional boolean parameter theAutoAdaptDimensionsToCellEditors,
which defaults to true. If you set this to false, the table won't try to adpat its cell dimensions to the cell
editors. This can be useful if you have big tables, for a better performance.
As we saw in previous chapter, you can also create several tables working on the same model. And you
can the for example, as we also saw in previous chapter, show different columns in these tables. To achieve
this, you can use the following code:

EditorDataTable aCustomTableModel =
aEditorData.GetCustomEditorTableModel(aMemberName,
"TestCustomEditorTableModel");
APIObjectCustomTable aTable1 = new APIObjectCustomTable(aEditorData,
aMemberName, aCustomTableModel);
APIObjectCustomTable aTable2 = new APIObjectCustomTable(aEditorData,
aMemberName, aCustomTableModel);
aTable1.setColumnEnabled(1, false);
aTable2.setColumnEnabled(2, false);

Example Java editor

We have written an example Java editor TestCustomTableEditor.java that will make use of our example
C++ editor table model shown above.
This editor also demonstrates how to call specific methods that have been registered on the author table
model. Here we added two buttons to insert a new Load or Element ID: the needed lines are then
automatically added in the Caesam_TypedTable. To do this, you'll see that we need to access the table
model with GetEditorDataTable(), and then call CallMethod() on this model.
To test this editor, just create an EO of type TestCustomTable and edit it.
The source code of this example Java editor is reproduced below

page-256
26 Analysis interface definition | Caesam SDK

You'll find the source files in examples/plugins/com.samcef.caesam.test.table/ :

plugin.xml (association of the editor with our test object)


src/java/com/.../TestCustomTableEditor.java

public class TestCustomTableEditor extends AbstractEditor


{
APIObjectCustomTable myTable = null;
JPanel myPanel = new JPanel(new BorderLayout());
EditorData myData;

public String getTitle() { return "Test Custom Table Editor"; }


public JComponent getEditorPanel() { return myPanel; }

public void setEO(EditorData theData)


{
myData = theData;
if (myTable == null) {

// create a custom table based on my custom C++ model


myTable = new APIObjectCustomTable(myData, "TestCustomEditorTableModel");
myPanel.add(new JScrollPane(myTable), BorderLayout.CENTER);

// add buttons to add loads and elements


JPanel aButtonPanel = new JPanel();
aButtonPanel.add(new JButton(new AddLoadAction()));
aButtonPanel.add(new JButton(new AddElementAction()));
myPanel.add(aButtonPanel, BorderLayout.NORTH);
}
else myTable.setEditorData(myData);
}

private int getIDFromUser(String message)


{
int aID = 0;
String aIDStr = JOptionPane.showInputDialog(null, message, 0);
try { if (aIDStr != null) aID = Integer.parseInt(aIDStr); } catch (NumberFormatException ex) { aID = 0; }
if (aID == 0) JOptionPane.showMessageDialog(null, "Please type a valid integer value > 0", "Error",
JOptionPane.ERROR_MESSAGE);
return aID;
}

protected class AddLoadAction extends AbstractAction


{
public AddLoadAction() {
this.putValue(AbstractAction.NAME, "Add load");
this.putValue(AbstractAction.SHORT_DESCRIPTION, "Add load");
this.putValue(AbstractAction.SMALL_ICON, new ImageIcon());
}

public void actionPerformed(ActionEvent e)


{
// get load ID from user
int aLoadID = getIDFromUser("Enter load ID");
if (aLoadID == 0) return;

// call method and update table


myTable.getEditorDataTable().callMethod("AddLoadID", new Caesam_Integer(aLoadID));
myTable.getEditorDataTable().fireTableDataChanged();
}
}

protected class AddElementAction extends AbstractAction


{
public AddElementAction() {
this.putValue(AbstractAction.NAME, "Add element");
this.putValue(AbstractAction.SHORT_DESCRIPTION, "Add element");
this.putValue(AbstractAction.SMALL_ICON, new ImageIcon());
}

public void actionPerformed(ActionEvent e)


{
// get element ID from user
int aElementID = getIDFromUser("Enter element ID");
if (aElementID == 0) return;

// call method and update table


myTable.getEditorDataTable().callMethod("AddElementID", new Caesam_Integer(aElementID));
myTable.getEditorDataTable().fireTableDataChanged();
}
}
}

26.8 Caesam Graphical Meta Languages


This chapter provides an introduction to methods that permit authors to define a Caesam Editor through
CCL commands or XML file. These methods were initially based on SwiXML, a light-weight free library,
designed by Wolf Paulus, that allows one to define a Swing graphical interfaces from an xml files (see
http://www.swixml.org/).

page-257
Caesam SDK | 26 Analysis interface definition

The default set of tags of SwiXML, that can be used in xml files, has been increased with tags designed
especially to interface, in XML, Caesam EO and the GUI of Caesam plateform, and to describe graphical
interfaces for forms. All tags, described in this chapter, are specific to Caesam.
In your own editors you can also use tags that have been defined in SwiXML which are in one to one
correspondence with Java Swing classes (label, textarea, panel ...).
To see the latest information on GUI in Caesam, have a look on the plugin example of SwiXML:
com.samcef.caesam.test.swixml.
In this section we first give a short example on how to use the XML GUI description language, then will
follow the references both on basic and extended tags or commands. A set of how to answers to technical
problems closes the topics.

26.8.1 Quick start


In our short example, we assume that the following EO has been defined in the typedesc of a plugin:

<TypeDesc Name="TestObjectForSwiXMLEditor" Inherits="CaesamStd_EO">


<member Name="aCaesamQuantity" Type="Caesam_Quantity"/>
<member Name="aCaesamEnumeration" Type="Caesam_String"/>
<member Name="aCaesamString" Type="Caesam_String"/>
<member Name="aCaesamObjectMap" Type="Caesam_ObjectMap"/>
<method Name="GetMap" Type="Python"
Location"csm:com.samcef.caesam.test.swixml/python/Map"
</TypeDesc>

First step: indicate the location and the key of the editor to Caesam through the plugin.xml
file

The first thing you have to do is to specify in the plugin.xml file the location of your GUI XML description
file and its key. For this, specify in the plugin.xml file the location of your XML file, and its associated
key.

<Item Type="PluginClass">
<Class Type="Caesam_String">TestObjectForSwiXMLEditor<Class>
<Default Type="Caesam_Url">default/TestObjectForSwiXMLEditor.csm</Default>
<Resources Type="Caesam_ObjectMap">
<Item Key="SwiXMLEditors" Type="Caesam_ObjectMap">
<Item Key="TestSwiXMLEditor" Type="CaesamRes_SwiXMLEditor"
Initialize="TRUE" XMLDescriptor="csm:com.samcef.caesam.test.swixml

/resources/TestSwiXMLEditor.xml"/>
</Item>
</Item>
</Item>

Second step: write your xml GUI description file

The content of the file TestSwiXMLEditor.xml will be the following:

1 <scrollpane border="emptyborder(0,0,0,0)" >


2 <mainblock title="Simple editor">
3 <block title="Simple Caesam Examples" columns="fj">
4 <label text="A caesam quantity" /><csmwidget path="aCaesamQuantity" />
5 <label text="A caesam enumeration" /><csmwidget path="aCaesamEnumeration"
/>
6 <block>
7 </mainblock>
8 </scrollpane>

The editor associated with this XML descriptor will have the following appearance:

page-258
26 Analysis interface definition | Caesam SDK

Note:
• You can change the content of your xml GUI description file without restarting Caesam.
For this two preferences can help authors to manage the way editors are reloaded. In
the standard way, in order to speed-up the load of an editor that has already been loaded,
CAESAM avoids to completely rebuild an editor. But if you want to write and test an
interface in the same time, you have to stop this lazy reload operation by specifying it
in the preferences (Edit>Preferences>SwiXMLEditor>Debug).
• Error messages are mostly displayed in the editor.

The <mainblock> and <block> tags define the layout of the editor. These two structures both allow to
have a title attribute. The “title” of the <mainblock> tag is the “title” of the editor.
The default layout associated with these structural tags is a vertical layout. Components are added one
after an other from top to bottom. They occupy all width they can and their height is their preferred height.
But if a columns attribute is specified (in our example the <block> beginning on row 3 contains a
columns attribute equal to "fj"), the layout associated with the structure is a columns layout.
The column layouts are particularly adapted to design forms. You specify the number of columns and the
policy used to compute the width and object positions of each columns with a string of characters. In this
string the character j stands for justify, f for fixed, c for center, and l and r respectively for left and
right. Each letter specify the way the cell of a column is aligned. Thus if a structural object contains the
attribute columns="ljrc" it means that the content of this object will be structured in four columns; in
the first column, objects will be left aligned, in the second objects will be justified, in the third right aligned
.... In general justification f and c give better results.
The common tags used to access to Caesam data are csmwidget and csmeditor. The first one,
csmwidget, permits one to display the content of elementary Caesam_Object like, Caesam_Quantity,
Caesam_Integer, Caesam arrays .... and provides for each of these object their default widget (that is the
widget returned by the CaesamDlgFactory Class). The second one csmeditor, permits one to obtain
the Caesam editor associated with a given Caesam object. It is particularly useful if you want to have the
editor of a given CaesamStd_EO. In order to specify the object on which this tag points, you must define
a path to a member of the current object by specifying the content of the attribute path. In our example
row 4 and 5, the path content are resp. aCaesamQuantity and aCaesamEnumeration which are the
names of the members of the EO TestObjectForSwiXMLEditor.

26.8.2 Reference of the standard tags


We first give the set of tags that have been defined for Caesam specific needs and their specific attributes.
Detailed definitions of each attribute can be found in: Table 21: Attribute meanings. Detailed definition
of each tag can be found in: Default editor tags on page 263. Detailed definition of the specification of
SwiXML files in the plugin.xml file can be found in: Declaration of the editor on page 262.

Tags and attributes Reference - Resume

All tags defined for Caesam inherit from JPanel. Thus, they all support the attributes of the tag panel:
background, font, border, layout, name, ... (see http://www.swixml.org/tagdocs/index.html/
for a complete description of the attributes of the panel).

page-259
Caesam SDK | 26 Analysis interface definition

Table 17: Accessing Caesam object members

Tag name Specific Attributes Brief description

csmWidget path, scrollpane, valuechanged, display members or sub members


unitstyle.
csmDescription path, wrap display the content of the path in
a label
csmEnumeration path, scrollpane, valuechanged, display members or sub members
predefinedvalues. with combo box
csmBoxes path, scrollpane, layout, display members or sub members
valuechanged, representation. with boxes
csmEditor * path, scrollpane, editorkey, access to the editor of an EO
editorclass. member
csmEditors ** path, scrollpane, uselayout. display the editor for each item
of an array
csmMemberlabel path access to the name of an EO
member
csmResource path, plugin, iconkey, access to a plugin resource, icon
messagekey, resourcetype or messages
csmTypeSelector path, types permit to change an EO value
according with a list of EO class

* the difference between csmeditor and csmwidget is important only with Caesam_Item (EO). Other
Caesam Primitives do not have any Editors but have an associated widget.
** caesameditors is used with the CaesamStd_Items and the CaesamStd_EOArray.
Table 18: Layout construction

Tag name Specific Attributes

mainblock titlekey, iconkey (not necessarly used), close (not


necessarly used), columns.
block titlekey, iconkey (not necessarly used), close (not
necessarly used), columns.
subblock titlekey, iconkey (not necessarly used), close (not
necessarly used), columns.
details title

Table 19: Panel

Tag name Specific Attributes

tablepanel columns
verticalpanel
verticalscrollpane

page-260
26 Analysis interface definition | Caesam SDK

Table 20: Control structure conditional statement

Tag name Specific Attributes

switch path.
case value, columns.
default columns.
if condition.
then columns.
else columns.

The table below lists all the attributes given above and describes their meaning
Table 21: Attribute meanings

Attribute Meaning

path A relative path to a Caesam_Object. The slash “/” permits to separate


members, the square brackets "[", "]" to refer to the terms of an array, and
the "@" a function. For example: "young" stands for the member of the
current object, “material/young” stands for the member young of the child
material of the current object, "materials[0]/young", stands for the young
member of the first element of the array materials, "material/@thickness"
call the method thickness of the member material and returns its value.
condition Conditions are strings that respect the following grammar:
• expression -> term operator expression
• term -> factor booloperator term
• operator -> EQ | NE | LE | LT | GE | GT
• boolOperator -> OR | AND
• factor -> ( expression )|‘String’ | valid_path | Integer | Real
For example, the following conditions are good: “2 EQ 3.0”, “bladetype
EQ ‘Beams’”, “Young LE Poisson” …
value A string. Take note that in the current version, the value of an enumeration
is a string, not the key of one of the values of the enumeration.
plugin A plugin name (string)
messagekey, titlekey, A valid key to a plugin resource. If no plugin have been specified, use the
iconkey default plugin.
columns Associates a table layout to the content of the tag. These layout are special
layout especially designed for the needs of Caesam. But you are not obliged
to use them; if you want to use a BorderLayout for example, use the
standard SwiXML way: use the attribut 'layout="BorderLayout"'. A string
defines the width of the columns. Two different formats can be used:
• Justify layout
columns=”clrjf”
Each letter corresponds to how the column is justified. The ‘c’ stands
for “center justification”, the ‘l’ for “left justification", the ‘j’ for
“justify” and the ‘f’ for “fixed size”.
• Proportional layout
columns=”1;2;3;4.1233”

page-261
Caesam SDK | 26 Analysis interface definition

Attribute Meaning

The real values are summed and the width of each column is the
proportion of its width to the total.

scrollpane A Boolean that indicates if a scrollpane must be used on the object. This
is mandatory for the csmwidgets that contain tables.
uselayout This can have one of the following string values: TabbedPane, Block,
SubBlock or Nothing. It changes the container and the appearance of
multiple editors.
dependentpath A list of valid path separated by semicolumns, that gives the set of EO
member that may change the value of this csm widget or enumeration.
valuechanged It defines an ordered list of methods to call, path of objects to update and
path of object references changed when the value of the editor is updated.
The path of objects to update are prefixed with a star *.

predefinedvalues Valid path of a Caesam_ObjectMap (it can be either a Caesam_ObjectMap


or a method that returns a Caesam_ObjectMap). This map gives the possible
values that can be taken by the object. The objects of this map must be of
the type of the object pointed by the widget.
editorkey Valid key of a SwiXML editor
editorclass Valid java class whose name is given in the form com.samcef.caesam ...
unitstyle Only for csmwidget. This can have one of the following string values:
default, combobox, invisible or behindvalue (not implement yet). It changes
the visibility and the appearance of member unit.
representation Only for csmboxs. This can have one of the following string values: default
or radiobutton. It changes the appearance of the items' type in the box.
resourcetype Only for csmresource. This can have one of the following string values:
default, image or text. If do not define this attribute, the default type is
image. Normally, the attribute should combine with the use of path attribute.

Tags and attributes Reference - Declaration of the editor

The declaration of the editor is made through the plugin.xml file in the following way.

<Item Type="PluginClass">
<Class Type="Caesam_String">TestObjectForSwiXMLEditorClass>
<Default Type="Caesam_Url">default/TestObjectForSwiXMLEditor.csm</Default>
<Resources Type="Caesam_ObjectMap">
<Item Key="SwiXMLEditors" Type="Caesam_ObjectMap">
<Item Key="TestSwiXMLEditor1" Type="CaesamRes_SwiXMLEditor"
Initialize="TRUE"

XMLDescriptor="csm:com.samcef.caesam.test.swixml/resources/TestSwiXMLEditor.xml"/>

<Item Key="TestSwiXMLEditor2" Type="CaesamRes_SwiXMLEditor"


Initialize="TRUE"

XMLDescriptor="csm:com.samcef.caesam.test.swixml/resources/SecondSwixmlEditor.xml"/>

</Item>
</Resources>
</Item>

page-262
26 Analysis interface definition | Caesam SDK

Note that you can define multiple keys in this SwiXML map, and then define multiple editors for a same
Caesam Class.

Default editor tags

The <csmwidget> tag associates the default editor with a member of the current editor. It has the following
syntax:

<csmwidget path="valid_path_to_a_member" scrollpane="true">

Note that in order to put a scroll pane on this object you have to use the attribute scrollpane=”true”.
It is mandatory when the path points to a table. For a table, this is the only way to have the header.
The path is a mandatory attribute.If the path does not exist the editor produces an error. If the path points
to an object that has predefined values (either an enumeration object or an object that links to other object),
a different tag can be used:

<csmboxwidget path=”valid_path_to_a_member”>

This tag produces a check box for each predefined value. You can customize the layout used by the
checkboxes in the following way:

<csmboxwidget path=”valid_path_to_a_member” layout=”GridLayout(2,4)”>

If you want the Preferred Editor of a Caesam class instead of the default editor of the object, you can use:

<csmeditor path=”valid path to a member”/>

If you are dealing with an array use the csmeditors tag instead:

<csmeditors path=”valid_path_to_an_eoarray” useLayout=”nothing”/>

The mandatory attribute “path” has to point to an EOArray, otherwise an error is displayed. The optional
attribute useLayout contains a String that influences the structure of the layout used to display the
different editors. The different Eos are displayed in a TabbedPane by default in the standard case. By
assigning uselayout with one of the following Strings: nothing, subblock, block and tabbedpane,
you can define a different arrangements for different editors.
If you want to have the label of the member of an editor you must use the tag csmmemberlabel:

<csmmemberlabel path=”valid member”/>

If you want to manage the type of the member of an editor use the tag:

<csmtypeselector path="aPly" types="Ply2;Ply3"/>

This permits the analyst to change the type of the member “aPl” according to the values contained in the
types attribute.

Conditional and Iterative Layout tags

The “If then else” statement


The structure of the “if then else” is simple:

<if condition="Young EQ 2.0">


<then>
<label text="THEN PANEL"/>
<!-- components placed in the then panel -->

page-263
Caesam SDK | 26 Analysis interface definition


</then>
<else>
<label text="ELSE PANEL" />
<!—components placed in the else panel -->

</else>
</if>

The <if> tag contains one mandatory attribute: “condition”. The condition is a string that contains
two terms and a comparison operator as described in the table Attribute meanings. on page 261
Examples of good conditions are:

"2 EQ 3.0"
"bladetype EQ ‘Beams’"
“Young LE Poisson”

Note that the condition “Young LE Poisson” means that the value of the Young member of this
EO is less than or equal to the value of the Poisson member. The condition“Young
LE ‘Poisson’” means that the value of the Young coefficient is less than the ‘Poisson’ string.
Of course the panels that are placed in the <then> tag will be displayed if the condition is true and those
contained in the <else> tag will be displayed otherwise. The two tags <then> and <else> produce two
panels with a vertical layout.
The “switch case” layout
The structure of the “switch case” layout is defined as follows:

<switch path="blademodeltype">
<case value="Beams">
<label text="CASE Beams"/>
<!-- components placed in the case beam panel -->
</case>
<case value="Super Element">
<label text="CASE Super element"/>
<!-- components placed in the case super element panel -->
</case>
<default>
<label text="DEFAULT "/>
<!-- components placed in the default panel -->
</default>
</switch>

The switch tag contains one mandatory attribute: the path attribute that must contain a valid path to a
member of the current editor data.

<switch path="blademodeltype">

The case tag contains one mandatory attribute: a value that can be taken by the object contained in the
path. This value can be either a String or an Integer.

Layout tags

Layout tags allow you to arrange the data in different areas. These concerned tags are: <mainblock>,
<block> and <subblock>.
They each have the same syntax:

<block title="Title of the block”>

page-264
26 Analysis interface definition | Caesam SDK

They each produce a panel with a title, that has a vertical layout in which objects are added from top to
bottom. These tags and the <then>, <else> and <case> tags share the “column” and the “scrollpane”
attributes described in the table Table 21: Attribute meanings.
There are also the two tags <tablepanel> and <verticalpanel> that enables you to create
multi-column panel with columns and a single-column panel respectively.

26.8.3 Extended tags


Extendeds tags cover the tags dedicated to the tables, curves display and file management. They are
powerful and versatile, and can answer to a large range of problems and configurations. The allow to
view the same Table w The first set of tags is dedicated to the display of table. Some of them,
csmTableComposer, answers quickly to the need of display configuration for GUI prototyping. Whereas
the other, csmTable and csmTableChart permit to display correctly a Caesam Table that have been well
defined. The second set of tags provide a set of mecanisms that permit to manage file and display their
content.

The Tables extended Tags

If the tag csmTable is dedicated to the Caesam Tables, the tag csmTableComposer can be used both
with tables, arrays and maps. It can also mix the content of different tables arrays and maps. But if it is
encouraged to use the tag csmTable instead of the csmwidget for tables, the tag csmTableComposer
must be used with precautions: it must not answers to the need of types reorganization or rewrite with
Caesam Tables.
Table 22: The extended tags based on Tables, Arrays and Maps

Tag Name Specific Attributes Type of valid path Brief description

csmTable Path, RowConditions, Caesam Table Display Caesam Table


Views,
ColumnJustifications,
ColumnEditor,
ColumnTitles,
TitleJustifications,
GenerateEvents,
HideToolBtn,
AddToolBtn,
DisplayColor
csmTableComposer Paths, Members, All linear agregate Compose a Caesam
Rowconditions, Views, Caesam Object (Table, Table from various
ColumnJustifications, Arrays, and Map) object and display it
ColumnEditor,
ColumnTitles,
TitleJustifications
csmTableChart Path, XIndex, YIndices, Caesam Table Display charts based on
ChartType, Caesam Table
BarOrientation,
XAxisType,
YAxesType
csmDualPanel SelectableObjectPath, All linear agregate
SelectedObjectPath, Caesam Object
LeftTitle, RightTitle

And the three following tables explain the role of the different attributes.

page-265
Caesam SDK | 26 Analysis interface definition

Table 23: Specific attributes meaning of the TableComposer

Attribute Meaning

Paths List of path name separated with semi columns. To each object declared in
the arrays attribute is associated a unique number: its position in the list. This
position can be re-used by the member attribute. One must provide to each
object a KeyColumn. The key column of a map is its key. The key column
of an Array or of a CaesamStd_EOArray is specify by a memberName placed
after a # char. The key column of a Table is specify by a number placed after
a # char.
For example:
paths="array1#member1;array2#member2;map1;table#colNum "

Where member1, member2, and colNum are used as the primary keys.

Members List of member names separated with semi columns. The member has to be
specified in the following way:
arrayNumber:memberName
or
mapNumber:memberName
If no number is specified, tag assumes that the member belongs to the first
array of the list. For example, the following specifications are correct:

3:thickness, 2:young, young

For the map the "2:#" character can be used in order to represent the value
of the key. If a member has to be displayed according to a given condition,
the condition is specified after the member between two enclosing brackets
"{" "}".
If the tag does not contain any "members" attribute all members of the array
are used.

Table 24: Specific attributes meaning of the Table

Attribute Meaning

HideToolBtn Hide the existing table toolbar buttons by its action id separated with semi
columns. All the table toolbar buttons' action id listed below:
ImporItemAboveAction
ImporItemBelowAction
ImporMultipleItemsAction
RemoveSelectedItemsAction
EditionModeAction
CopyAction
PasteAction
ImportAction
ExportTableAction
For example:
hideToolBtn="CopyAction;PasteAction"

page-266
26 Analysis interface definition | Caesam SDK

Attribute Meaning

AddToolBtn Add customized buttons to table toolbar separated with semi columns. To
each object declared in the array should provide 3 attributes:
icon, which is defined in Icons.properties file under plugin's properties folder;

tip, which is defined in Resources.properties file under plugin's properties


folder;
path, which is the method path of click action.
For example:
addToolBtn="icon=ICO_TEST,tip=TIP_TEST,path=@MyTestToolbarDialog"

DisplayColor This can have one of the following string values: Yes, No, or Default. It
decides if one of the table columns will be displayed in colors.

Table 25: Specific Attributes of the display of Tables (Table and TableComposer)

Attribute Meaning

RowConditions Conditions on the cells of a row, separated with semi-columns according


with a condition that may depends on the value of other cells in the row.
For this, the $ contextual symbol may be used to prefix the column number
of the cells. The number that follows the $ is the column number. Syntax
is similar to the condition of the if/then/else tags.
For instance the following condition is correct

rowconditions=";;;$0 GE 1000;;"

and means that in a table that contains six columns, a cell contained in the
four-th column is displayed only if the content of the first column ($0) is
greater than 1000.

Views The views defined for the table composer. This is defined by a semi-column
separated ordered list of views among:
• LAYOUT
• STANDARD_TABLE
• GLOBAL_TABLE
The default is the list that contains the standard table. The layout view can
only be used with table with less than 64 rows or columns, otherwise an
error message is displayed.

ColumnJustifications List of letters that defines the justification of each column. The "lrcf"
code is used to determine the layout policy.

ColumnEditors List of letters that defines the editor factory of each columns b (for box
widget factory useful for the checkbox) or s (for standard widget factory).

ColumnTitles The title of the columns separated with semi columns.

TitleJustifications The standard "lrc" code can be used. The default value is center (c) for
all columns.

page-267
Caesam SDK | 26 Analysis interface definition

Attribute Meaning

GenerateEvents By default the table events are not generated for convenience. This tag
permits to force to generate them.

Table 26: Table Attribute meanings of Table chart

Attribute Meaning

XIndex An integer that identifies the column number of the table used for the
abscissae.
YIndices A semi column separated list of column numbers of the table used for the
ordinate.
CharType A constant that stand for the chart type used to display the graph. The
following values are correct:
• LINE_CHART
• BAR_CHART
• SCATTER_CHART
• PIE_CHART

Table 27: Table Attribute meanings of Dual Panel selector

Attribute Meaning

SelectableObjectPath Path to an array. The content of this array is not modified by the tag.
SelectedObjectPath Path to an array. This array contains the list of objects displayed in the
right part of the dual panel. This is the user selection.
LeftTitle Title placed above the left part of the dual panel.
RightTitle Title placed above the right part of the dual panel.

The extended Tags based on Files

The extended tags permits author to manage access to external files. These tags allow users to select a set
of files and to display their content. This Caesam provides tody the possibility to display jpg and crv files.
The table that follows describes these different tags:
Table 28: The extended tags based on Table Arrays and Maps

Tag Name Specific Attributes Brief description

csmFileChooser RootPath, Root, Display an arborescence that


SelectedFilesPath, permits user to select a set of files
RecursiveFilter, FilterPath, Filter
csmImageDisplayer Path, Scale. (to be uniformized Permit to display the content of
with csmCurveDisplayer) a set of image files.
csmCurveDisplayer Files, FilesPath, Display charts based on Caesam
ImageOutputPath, Table
ImageOutputFile.

page-268
26 Analysis interface definition | Caesam SDK

And the following table describes the meaning of each attributes.


Table 29: Specific attribute meaning of the File Selector

Attribute Meaning

RootPath, Root The value RootPath must point to a valid Caesam URL or the value of
Root must be a valid Caesam URL. Anyway the URL pointed by one of
these variable is the root of the subtree displayed by the csmFileChooser.

SelectedFilesPath The value of SelectedFilesPath must be a path of an array or a map


that will contain the names of the files selected by the table composer.

RecursiveFilter Equal false if one want to view files that are contained only in the root
directory.
Filter, FilterPath An expression that describe a file name filter used to select the files in the
tree, or the path to a Caesam_String that defines a filter. Each filters can
be specified as a REGEX pattern in the Java sens, thus have a look on the
documentation page of the java class Pattern in order to define and check
your own REGEXs.

Table 30: Specific attribute meaning of the Curve File Viewer

Attribute Meaning

FilesPath, Files The value RootPath must point to a valid Caesam URL or the value of
Root must be a valid Caesam URL. Anyway the URL pointed by one of
these variable is the root of the subtree displayed by the csmFileChooser.

SelectedFilesPath The value of SelectedFilesPath must be a path of an array or a map


that will contain the names of the files selected by the table composer.

RecursiveFilter Equal false if one want to view files that are contained only in the root
directory.
Filter, FilterPath An expression that describe a file name filter used to select the files in the
tree, or the path to a Caesam_String that defines a filter. Each filters can
be specified as a REGEX pattern in the Java sens, thus have a look on the
documentation page of the java class Pattern in order to define and check
your own REGEXs.

26.8.4 How to

How to create my own tags for XML?

The content of this section may change in the future, use this method at your own risks. It is based on an
example provided in the com.samcef.caesam.test.swixml plugins.
Registering the new class
In order to register your own SwiXML tag, you have to call the static method:

SwiXMLEditor.addNewTag(String tagName, Class tagClass)

Where the tagName is the name you decide to associate with your class, and tagClass is the class name
associated with your object. Note that SwiXML is not case sensitive. The case of tagName is thus of no
importance. Since this method has to be called at the initialization of Caesam the best way to ensure it,

page-269
Caesam SDK | 26 Analysis interface definition

is to call the method in a block launch before the creation of a caesam document. The
IDocumentListener interface can help us to do that. It permits to add a listener on the CaesamDocument,
and provides method called before the creation of the document. It is declared in the resource section of
the "plugin.xml" file:

<Resources Type="Caesam_ObjectMap">
<Item Key="DocumentListener"
Type="Caesam_String">com.samcef.caesam.test.swixml.DocumentListener</Item>
</Resources>

The body of the document listener will be the following:

public class DocumentListener implements IDocumentListener {


/** Method called before the creation of the document. */
public void beforeDocumentCreation() {
// Register the new tag:
SwiXMLEditor.addNewTag("MyDateTag", MyDateTag.class);
}
/** Method called when the document is created. */
public void documentCreated(CaesamModel aCaesamModel) {}
}

Tag Implementation
The SwiXml engine has been used to manage the description of interfaces based on XML files. Thus new
tags are defined in Caesam like in SwiXml. Then a tag class named Xxx follows the two rules:
• The Xxx class must be a JComponent.
• For each method of the class Xxx that begins with set: setYyy(String zzz) the tag XxxYyy provides
an attribute Yyy whose content is transferred to the setYyy method.
For example:

Class test extends JPanel{


public void setTitle(String title){
add(new JLabel(title));
}
}

provides a tag whose syntax will be:

<test title="MonTitre"/>

and who will display a JLabel whose content will be title.


In order to obtain an EditorData from a CaesamPath, Caesam provides the following interface:

public interface ICaesamTag {


public void assignPathSolver(PathSolver theSolver);
}

This interface provides one method that is called one time at the initialization of the editor after the calls
of the setYyy methods.
The method assignPathSolver takes one argument: a PathSolver. The PathSolver is the keystone
of the connection between Caesam EditorData and SwiXML object. The PathSolver permits through
the following methods to access to a unique editor data in the SwiXML editors, and to obtain resources:

public EditorData getEditor(String path);


public EditorData getEditorWithDeclaredType(String path, String declaredType);
public String getPluginName();
public Caesam_Url resolveUrl(Caesam_Url anUrl);

page-270
26 Analysis interface definition | Caesam SDK

It is crucial to understand that the getEditor method returns the same editor data object each time it is
called. It means that if two tag classes ask the PathSolver for a same path, the two classes associated
with these tags will receive the same editor data, and must use it to listen for the changes of these
EditorData. Thus the tag class must implement both ICaesamTag and ChangeListener interfaces.
The life cycle of a new java tag class is as follows:

Figure 12:

Due to the reload mecanism a class has to listen for changes of the editor data and change its content
without rebuilding it.

How to manage Conditional enumeration value?

In what follows we describe how to change dynamically the values of an enumeration in Caesam GUI
description. We assume that a TestObjectForSwiXMLEditor type is defined as in the previous section
has been defined.
The csmenumeration permits one to manage enumeration in Caesam. Its syntax is defined as follows:

<csmenumeration path="Valid_Path" predefinedvalues="aCaesamObjectMap"/>

This tag permits to define the value of a Caesam_Object pointed by Valid_Path, with the predefined
values contained by the attribute predefinedvalues. In a certain way it allows to manipulate
enumerations without defining them in the plugin.xml file. In what follows we show how to define XML
GUI description file in order to allow to interactively change the possible values of an enumeration.
We assume that the method getMapMethod of our previous example is defined as follows:

def GetMap(theInstance, theThickness):


aInteger = int(theInstance.GetMember("aCaesamQuantity").GetValue())
aMap = theInstance.GetMember("aCaesamObjectMap")
aMap.Clear() # Clear the map do not create a new one !!!
if (anInteger.GetValue() % 2 == 0):
# If the integer part of anInteger is even fill the map with aa, bb, cc
aMap.Put("aa", Caesam_String("Test"))
aMap.Put("bb", Caesam_String("Test2"))
aMap.Put("cc", Caesam_String("Test3"))
else:
# if it is odd, fill the map with Toto, Titi, Tata
aMap.Put("Toto", Caesam_String("aa"))
aMap.Put("Titi", Caesam_String("OK"))
aMap.Put("Tata", Caesam_String("Blabla"))
return aMap

The method GetMap modifies the content of the map. Note that in this method, no instance of object is
created, and it is recommended to never create object in methods managed by a SwiXML object but
manipulates instances with GetMember and SetMember methods. In fact all objects referenced by a path
in a GUI XML description file must not be changed through a python method otherwise tags are unable
to recover references of these object.
Our xml file contains the following code:

1 <block title="Test dynamic calls to object">


2 <textarea text="When the following integer is odd the {aa, bb, cc} map is

page-271
Caesam SDK | 26 Analysis interface definition

selected.
When it is even, it is the {Tata, Titi, Toto}." opaque="false"/>
3 <csmwidget path="aCaesamInteger" valueChanged="@GetMap;aCaesamString"/>
4 <csmenumeration path="aCaesamString" predefinedvalues="aCaesamObjectMap"/>
5 </block>

On the row 3 of this example, the tag csmwidget contains an attribute valuechanged whose value is
@GetMap;aCaesamString. The valueChanged attribute is used to define the action triggered by the
modification of the value of a widget. It defines an ordered list of methods to call, objects to update and
object references changed when the value of the editor is updated. Methods to call are prefixed with an
@. In our example (row 3), when the value of aCaesamInteger is changed, the method GetMap, and then
all csmwidget, csmenumeration, ... that refer to aCaesamString are updated. Thus the content of the
enumeration defined on row 4 is updated.
When a method changes the reference of an object member, you can specify it by putting a star * before
the path of the reference that has changed.

26.9 Interface definition


The "plug-in command mechanism" allows authors to add new commands to the Caesam GUI. Authors
can use this mechanism to launch a Caesam Task and specify the parameter type (as a Caesam _Object
Type). When the task is launched, an editor will prompt the user to edit the task parameter. This editor is
chosen from among those available, based on the task parameter type. If no suitable editor is found, the
default editor (formerly used for EO edition), will be used to enable the user to edit the parameter before
launching the task. Adding new commands, requires the following steps:
• Add a new xml tag in the plugin.xml file. on page 272
• Add commands in the specified 'PluginCommands' file. on page 272
• Add commandWidgets in the specified 'PluginCommands' file. on page 279

26.9.1 Add a new xml tag in the plugin.xml file


Under the <Resources> xml tag, add an Item tag with Key="PluginCommands" and value pointing to a
csm file specified as shown below:

<Resources Type="Caesam_ObjectMap">
<Item Key="Properties" Type="Caesam_Url">resources/properties</Item>
<Item Key="PredefineResult" Type="Caesam_Url">
resources/Menu_Result_Show.csm
</Item>
<Item Key="HelpURL"
Type="Caesam_Url">resources/Menu_Help_Url.csm</Item>
<Item Key="AboutURL"
Type="Caesam_Url">resources/Menu_About_Url.csm</Item>
<Item Key="Disciplines"
Type="Caesam_Url">resources/disciplines.csm</Item>
<Item Key="ItemFilters"
Type="Caesam_Url">resources/itemfilters.csm</Item>
<Item Key="PluginCommands"
Type="Caesam_Url"> resources/CaesamPluginCommands.csm
</Item>
</Resources>

26.9.2 Add commands in the specified 'PluginCommands' file


(Here, resources/CaesamPluginCommands.csm): Here is a sample csm file that illustrates how to add a
command in caesam. This file can be found in :
<CAESAM_HOME_DIR>\examples\plugins\com.samcef.caesam.test.transverse\resources\CaesamPluginCommands.csm.

page-272
26 Analysis interface definition | Caesam SDK

The file starts with an instance of 'CaesamMvc_PluginCommands'. Then the 'Commands' section declares
all commands the author wants to create.

<Instance Type="CaesamMvc_PluginCommands">
<!— Commands are objects that contain author functionality -->
<Commands Type="Caesam_ObjectArray">
<!— The array must contain only objects of type Caesam_MVCPluginCommand
-->

Here, we define a new command called DUMP_SELECTION_CMD command:

Note: that in a single 'PluginFileCommands', command keys must be unique.

<!-- A Plugin command : there can be many commands-->


<Item Type="CaesamMvc_PluginCommand">
<!-- CommandKey must be have a unique key -->
<CommandKey Type="Caesam_String">DUMP_SELECTION_CMD</CommandKey>

A Java class must be specified. The user can either use a predefined Java command, or write his own Java
command. For the moment, the only predefined command available is the “TaskCommand” class which
allows to add a command that triggers a Caesam Task, possibly with a parameter.

<!-- Class must extend


com.samcef.caesam.modules.pluginCommand.DefaultCommand -->
<Class Type="Caesam_String">
com.samcef.caesam.modules.pluginCommand.command.TaskCommand
</Class>

26.9.2.1 Writing a Plugin Command

To write a Plugin command, the author must create a Java class that inherits from the class
com.samcef.caesam.modules.pluginCommand.DefaultCommand and references them in the plugin
command csm file

<!-- Class must extend


com.samcef.caesam.modules.pluginCommand.DefaultCommand -->
<Class Type="Caesam_String">
com.samcef.caesam.modules.pluginCommand.command.TestCommand
</Class>

The only method that must be implemented is executeCommands(). Below is a sample command that
fetches some parameters and displays them in a dialog box.

package com.samcef.caesam.modules.pluginCommand.command;

import java.util.HashMap;

import javax.swing.JOptionPane;

import com.samcef.caesam.jnicaesam.Caesam_Object;
import com.samcef.caesam.modules.pluginCommand.DefaultCommand;

/**
* TestCommand
*
* @author Dal Farra
*/

page-273
Caesam SDK | 26 Analysis interface definition

public class TestCommand extends DefaultCommand {

@SuppressWarnings("unused")
private static final String SCCSID = "@(#) TestCommand.java 4.0-1,
05/11/07@(#)";

public TestCommand(String theCommandKey) {


super(theCommandKey);
}

@Override
protected boolean executeCommand(HashMap<String, Object> commandParameters)
{

StringBuilder buffer = new StringBuilder("Command '"+getCommandKey()+


"' was invoked with the following parameters:\n\n");

buffer.append("'Param_1' = '").append(((Caesam_Object)commandParameters
.get("Param_1")).GetString().GetValue()).append("\'\n");

buffer.append("'Param_2' = '").append(((Caesam_Object)commandParameters
.get("Param_2")).GetInteger().GetValue()).append("\'\n");

buffer.append("'Param_3' = '").append(((Caesam_Object)commandParameters
.get("Param_3")).GetURL().GetValue()).append("\'\n");

JOptionPane.showMessageDialog(
getCaesamModel().getCaesamFrame(),
buffer.toString(),
getPluginResource().getString("MY_USER_DEFINED_COMMAND_DIALOG_TITLE"),
JOptionPane.INFORMATION_MESSAGE);
return true;
}
}

26.9.2.2 Plugin Command Enablers

A command has a status (enabled or disabled): the author can control the command status thanks to
command enablers.
Currently, only one kind of commandEnablers is available: the selectionEnabler, which keeps an eye on
the current selections.
They are 2 main selections:
• The Stress Model tree selection,which is observed by the 'SMTreeSelectionTypes'.
• The PropertyView Selection, which is observed by the 'PropertySelectionTypes'
Both of them are Caesam_StringArray.The suntax of Caesam_StringAray is the following: One single,
for instance ‘Panel’, String value is written like this:

<SMTreeSelectionTypes
Type="Caesam_StringArray">Panel</SMTreeSelectionTypes>

If the StringArray contains many values, let’s say Panel, Material and Profile, the syntax is the following:

<SMTreeSelectionTypes Type="Caesam_StringArray">
Panel;Material;Profile </SMTreeSelectionTypes>

page-274
26 Analysis interface definition | Caesam SDK

Here, the DUMP_SELECTION_CMD only use 'SMTreeSelectionTypes' and the types for which the
command is enabled are '*', which means, that, no matter what the stress model tree selection contains,
the DUMP_SELECTION_CMD is enabled. This implies that the selection must be non-empty!

<!-- CommandEnablers -->


<!-- Drives the enabled/disabled state of the command -->
<!-- If CommandEnabler is not specified (or is empty), -->
<!-- the command is always enabled. When a command state change,
-->
<!-- all related widgets change their visual states -->
<!-- accordingly, i.e., if the command is disabled, -->
<!-- menu items and toolbar buttons gray out and popup menu
item -->
<!-- dissepear from PopupMenu. If the command is enabled, -->
<!-- menu items and toolbar buttons get back to active state
-->
<!-- and popup menu item are back in PopupMenu -->
<CommandEnablers Type="CaesamMvc_PluginCommand_CommandEnablers">
<!-- Selection Enabler -->
<!-- used by class com.samcef.caesam.modules.pluginCommand.DefaultCommand
-->
<!-- Enable the command when the selection corresponds to given
type(s) -->
<!-- "SMTreeSelectionTypes" specify which type(s) -->
<!-- the SM Tree selection must contain to enable the command
-->
<!-- "PropertySelectionTypes" specify the type(s) -->
<!-- that Property View selection must contain to enable the command -->
<SelectionEnabler Type="CaesamMvc_PluginCommand_SelectionEnabler">
<SMTreeSelectionTypes Type="Caesam_StringArray">*</SMTreeSelectionTypes>
</SelectionEnabler>
</CommandEnablers>

26.9.2.3 Plugin Command Parameters

Commands (either built-in or created by the author) can receive parameters embedded in a ‘Parameters’
xml tag. For the TaskCommand, there are two parameters:
• The Task parameter, which specify the Caesam Task to be launched
• The UserTaskParameter, which specify the Type of the parameter that will be passed to the Caesam
task (specified by the Task parameter).
In the example below, we do not specify a UserTaskParameter (empty string). The task will thus be run
directly, without prompting the user. See 19.3.4 for an example where the user task parameter is used.

<!-- Command Parameters -->


<!-- User defined parameter can be added -->
<Parameters Type="Caesam_ObjectMap">
<!-- Task -->
<!-- used by class com.samcef.caesam.modules.pluginCommand.TaskCommand-->
<!-- specify the unique identifier of the Caesam Task to execute-->
<!-- This task will receive a Caesam_Task_Parameter object containing the -->
<!-- following member -->
<!-- a CaesamScript_Selection object named 'Selection'containing -->
<!-- the selected items in SMTree and Property View -->
<!-- a Caesam_Object named 'UserTaskParameter' corresponding to the -->
<!-- UserTaskParameter edited parameter -->
<Item Key="Task" Type="Caesam_String">
python:csm:com.samcef.caesam.test.transverse/python/Task_DumpSelection
</Item>
<!-- UserTaskParameter -->
<!-- used by class com.samcef.caesam.modules.pluginCommand.TaskCommand
-->
<!-- specifiy the Type of parameter (a GUI will be presented

page-275
Caesam SDK | 26 Analysis interface definition

to the user -->


<!-- accordingly to the specified type) -->
<!-- When user GUI interaction is completed, the Task will
receive the -->
<!-- 'user GUI encoded value' whithin its parameter -->
<Item Key="UserTaskParameter" Type="Caesam_String"></Item>
</Parameters>
</Item>

For the author defined commands, it is up to the user to create his own commands. An example of
user-defined command parameters is given below:

<Item Type="CaesamMvc_PluginCommand">
<CommandKey Type="Caesam_String">MY_USER_DEFINED_CMD</CommandKey>
<Class Type="Caesam_String">
com.samcef.caesam.modules.pluginCommand.command.TestCommand</Class>
<Parameters Type="Caesam_ObjectMap">
<Item Key="Param_1" Type="Caesam_String">a String</Item>
<Item Key="Param_2" Type="Caesam_Integer">10</Item>
<Item Key="Param_3" Type="Caesam_Url">htpp://www.samcef.com/</Item>
</Parameters>
</Item>

Parameters Param_1, Param_2 and Param_3 have been defined Caesam_String, Caesam_Integer and
Caesam_Url respectively.
To get those parameters from the java code of the command, the author can fetch them from the HashMap
passed as argument to the executeCommand Method as shown here:

@Override
protected boolean executeCommand(HashMap<String, Object> commandParameters)
{

StringBuilder buffer = new StringBuilder("Command '"+getCommandKey()+


"' was invoked with the following parameters:\n\n");

buffer.append("'Param_1' = '").append(((Caesam_Object)commandParameters
.get("Param_1")).GetString().GetValue()).append("\'\n");

buffer.append("'Param_2' = '").append(((Caesam_Object)commandParameters
.get("Param_2")).GetInteger().GetValue()).append("\'\n");

buffer.append("'Param_3' = '").append(((Caesam_Object)commandParameters
.get("Param_3")).GetURL().GetValue()).append("\'\n");

JOptionPane.showMessageDialog(
getCaesamModel().getCaesamFrame(),
buffer.toString(),
getPluginResource().getString("MY_USER_DEFINED_COMMAND_DIALOG_TITLE"),
JOptionPane.INFORMATION_MESSAGE);
return true;
}

26.9.3 Accessing the selection from the task


The Caesam task, specified under the Task parameter, will always receive as parameter a map containing
two entries:
• a parameter accessed with the key "UserTaskParameter": an object of the type specified by
UserTaskParameter.
• a parameter accessed with the key "Selection": an object of the type CaesamScript_Selection.

page-276
26 Analysis interface definition | Caesam SDK

From this CaesamScript_Selection object, the task can obtain the following information:
• GetSMTreeSelection() :
CaesamStd_ItemArray containing all items selected in the Stress Model Tree.
• GetPropertyKeys() :
a Caesam_StringArray containing the keys of the selected properties in the PropertyView table. If we
are seeing the properties of the shared workspace, the key is the EO name. If we are seeing the properties
of a CP or analysis (i.e. a dataset), the key is the dataset key.
• GetPropertySelection() :
Caesam_ObjectArray containing objects of type CaesamScript_EOProperty, each representing the
value of the nth selected line in the PropertyView table (n being the index in the array). This
CaesamScript_EOProperty in turn provides following methods:
• IsFromDataset(): true if this property represents a dataset entry
• IsFromSharedWorkspace(): true if this property represents a shared EO
• GetDatasetKey(): return the dataset key for this property Returns an empty string if this property
represents a shared EO
• GetEOs(): return an item array containing the underlying EOs If the property represents a shared
EO, this array always contains exactly one EO, which can also be obtained with GetEO().
• IsFromDataset():
• IsFromDataset():
These considerations are illustrated in the script associated with the command DUMP_SELECTION_CMD:
examples/plugins/com.samcef.caesam.test.transverse/python/Task_DumpSelection.py

aParameterMap = self.GetParameter()
aSelection = aParameterMap.Get("Selection");

aSMTreeSelection = aSelection.GetSMTreeSelection()
for i in range(aSMTreeSelection.Size()):
aItem = aSMTreeSelection.GetItem(i)
self.PutMessage(" - Item "+str(i+1)+" : Name = "+aItem.GetName())

aPropertyKeys = aSelection.GetPropertyKeys()
for i in range(aPropertyKeys.Size()):
self.PutMessage(" - Key "+str(i+1)+" : "+aPropertyKeys.Get(i))

aPropertySelection = aSelection.GetPropertySelection()
for i in range(aPropertySelection.Size()):

aProperty = aPropertySelection.Get(i)
self.PutMessage("\n - EOProperty "+str(i+1)+" : ")

if (aProperty.IsFromDataset()):
self.PutMessage("From DataSet [Key="+Property.GetDatasetKey()+"]")

if (aProperty.IsFromSharedWorkspace()):
self.PutMessage("From EO SW [Name="+aProperty.GetEO().GetName()+"]")

aEOs = aProperty.GetEOs()
for j in range(aEOs.Size()):
if (j > 0): aMessage += ", "
aMessage += aEOs.Get(j).GetName();
self.PutMessage(aMessage)

page-277
Caesam SDK | 26 Analysis interface definition

26.9.4 More examples of commands

CREATE_SEAPANEL_CMD

This command is enabled when "Panel"s are selected in the property view, and it triggers the caesam task
createSEAPanels. Let us note that no user defined parameters are passed to the task.

<Item Type="CaesamMvc_PluginCommand">
<CommandKey Type="Caesam_String">CREATE_SEAPANEL_CMD</CommandKey>
<Class Type="Caesam_String">
com.samcef.caesam.modules.pluginCommand.command.TaskCommand
</Class>
<CommandEnablers Type="CaesamMvc_PluginCommand_CommandEnablers">
<SelectionEnabler Type="CaesamMvc_PluginCommand_SelectionEnabler">
<SMTreeSelectionTypes Type="Caesam_StringArray">Panel</SMTreeSelectionTypes>

</SelectionEnabler>
</CommandEnablers>
<Parameters Type="Caesam_ObjectMap">
<Item Key="Task" Type="Caesam_String">
python:csm:com.samcef.caesam.test.transverse/python/Task_CreateSEAPanels
</Item>
</Parameters>
</Item>

IMPORT_EO_CMD

This command is always enabled. We specify here Caesam_File as UserTaskParameter, which will make
Caesam display a file chooser to select a file on the file system. The selected file will then be passed to
the Task_ImportEO python task.

<Item Type="CaesamMvc_PluginCommand">
<CommandKey Type="Caesam_String">IMPORT_EO_CMD</CommandKey>
<Class Type="Caesam_String">
com.samcef.caesam.modules.pluginCommand.command.TaskCommand
</Class>
<Parameters Type="Caesam_ObjectMap">
<Item Key="UserTaskParameter" Type="Caesam_String">Caesam_File</Item>
<Item Key="Task" Type="Caesam_String">
python:csm:com.samcef.caesam.test.transverse/python/Task_ImportEO
</Item>
</Parameters>
</Item>

DUMP_MATERIAL_CMD.

This command is enabled only when Materials are selected in the PropertyView, and gets no user defined
parameter.

<Item Type="CaesamMvc_PluginCommand">
<CommandKey Type="Caesam_String">DUMP_MATERIAL_CMD</CommandKey>
<Class Type="Caesam_String">
com.samcef.caesam.modules.pluginCommand.command.TaskCommand
</Class>
<CommandEnablers Type="CaesamMvc_PluginCommand_CommandEnablers">
<SelectionEnabler Type="CaesamMvc_PluginCommand_SelectionEnabler">
<PropertySelectionTypes Type="Caesam_StringArray">
Material
</PropertySelectionTypes>
</SelectionEnabler>

page-278
26 Analysis interface definition | Caesam SDK

</CommandEnablers>
<Parameters Type="Caesam_ObjectMap">
<Item Key="Task" Type="Caesam_String">
python:csm:com.samcef.caesam.test.transverse/python/Task_DumpMaterial
</Item>
</Parameters>
</Item>
</Commands>

26.9.5 Add commandWidgets in the specified 'PluginCommands' file


Command widgets present commands in the GUI, and allows the user to trigger them. All caesam widgets
need to refer exactly on a command previously defined in the same plugin command file, using the
'CommandKey' tag.

<!-- CommandWidgets are GUI element (MenuItem, Buttons, etc..)


that make commands available to the user through the GUI -->
<!-- Author will add commandWidget where they want
in the GUI, and connect them to a given command. -->
<!-- The link between CommandWidgets and commands is the 'commandKey' -->
<CommandWidgets Type="CaesamMvc_PluginCommand_Widgets">

There are three kinds of command widgets: • Menu (see section 19.3.5.1) • MenuItems (see section
19.3.5.2) • ToolBar Buttons (see section 19.3.5.3) • PopupMenuItems (see section 19.3.5.4)

Menus

These are present in the main menu bar of Caesam Declaring a Menu is done by specifying:
• The Id of the new Menu (NewMenuID)
• The id of the menu in which the Menu will be added (ParentMenuId)
The list of Menu Id is accessed by selecting the "Debug" menu -> "MVC Model Info" menu item and
MVC Model: the here is the task sub menu id: TASK_SUBMENU_VIEW

Figure 13: MVC Model Info

page-279
Caesam SDK | 26 Analysis interface definition

Note: If the Debug" menu is not available, use the "Tools"-> "Debug Level" menu Item
to set the debug level to a positive (non-null) value: this will display the debug menu.

Here is an example that illustrates how to:


• Create a user defined menu ‘MY_USER_DEFINED_MENU_VIEW‘ that will be added in the main
menu bar (reference by ‘MENU_VIEW’)
• Add a sub menu ‘MY_USER_DEFINED_SUBMENU_VIEW’ in the newly created menu
(‘MY_USER_DEFINED_MENU_VIEW‘)

<Menus Type="Caesam_ObjectArray">
<!-- only contains CaesamMvc_PluginCommand_Menu Objects -->

<Item Type="CaesamMvc_PluginCommand_Menu">
<NewMenuId Type="Caesam_String">MY_USER_DEFINED_MENU_VIEW</NewMenuId>
<ParentMenuId Type="Caesam_String">MENU_VIEW</ParentMenuId>
</Item>

<Item Type="CaesamMvc_PluginCommand_Menu">
<NewMenuId Type="Caesam_String">MY_USER_DEFINED_SUBMENU_VIEW</NewMenuId>
<ParentMenuId Type="Caesam_String">MY_USER_DEFINED_MENU_VIEW</ParentMenuId>
</Item>
</Menus>

The resulting GUI is shown below.

Figure 14: Menu Entries in the GUI

MenuItems

These are present in the main menu bar of Caesam Declaring a MenuItem is done by specifying:
• The key of command to be triggered (CommandKey)
• The id of the menu in which the MenuItem will be added (MenuId) the list of Menu Id is available by
clicking the "Debug" menu -> "MVC Model Info" menu item and clicking on the Views tab.
An illustration of this is shown below.

page-280
26 Analysis interface definition | Caesam SDK

Figure 15: MVC Model with TASK_SUBMENU_VIEW selected

Note: If the Debug" menu is not available, use the "Tools"-> "Debug Level" menu Item
to set the debug level to a positive (non-null) value: this will display the debug menu.

Here is the way to declare the MenuItems section:

<!-- only contains CaesamMvc_PluginCommand_MenuItem Objects -->


<MenuItems Type="Caesam_ObjectArray">

And here, we add a menuItem under the Tools/Task menu (for which we have just checked the menu
view ID)

<Item Type="CaesamMvc_PluginCommand_MenuItem">
<CommandKey Type="Caesam_String">DUMP_SELECTION_CMD</CommandKey>
<MenuId Type="Caesam_String">TASKS_SUBMENU_VIEW</MenuId>
</Item>

Here are some more examples of MenuItem

<Item Type="CaesamMvc_PluginCommand_MenuItem">
<CommandKey Type="Caesam_String">CREATE_SEAPANEL_CMD</CommandKey>
<MenuId Type="Caesam_String">TASKS_SUBMENU_VIEW</MenuId>
</Item>
<Item Type="CaesamMvc_PluginCommand_MenuItem">
<CommandKey Type="Caesam_String">IMPORT_EO_CMD</CommandKey>
<MenuId Type="Caesam_String">TASKS_SUBMENU_VIEW</MenuId>
</Item>
</MenuItems>

This is illustrated in the picture below

page-281
Caesam SDK | 26 Analysis interface definition

Figure 16: Illustration of MenuItems

ToolBar Buttons

Tool bar buttons can be added, even easily than MenuItems, since MenuId does not need to be specified.
Only command keys must be specified.

<!-- only contains CaesamMvc_PluginCommand_ToolBarButton Objects-->


<ToolBarButtons Type="Caesam_ObjectArray">
<Item Type="CaesamMvc_PluginCommand_ToolBarButton">
<CommandKey Type="Caesam_String">DUMP_SELECTION_CMD</CommandKey>
</Item>
<Item Type="CaesamMvc_PluginCommand_ToolBarButton">
<CommandKey Type="Caesam_String">CREATE_SEAPANEL_CMD</CommandKey>
</Item>
<Item Type="CaesamMvc_PluginCommand_ToolBarButton">
<CommandKey Type="Caesam_String">IMPORT_EO_CMD</CommandKey>
</Item>
</ToolBarButtons>

This is illustrated below.

Figure 17: Illustration of Toolbar buttons and Popup MenuItems

PopupMenuItems

Popup menu items are added by specifying command keys and a 'AddInPopupMenuOf' that makes possible
to select in which popup menu the new popup menu item must be presented.

page-282
26 Analysis interface definition | Caesam SDK

This can be any combination of "SMTreeView" "PropertyView" and "3DView" (';' separated)

<!-- only contains CaesamMvc_PluginCommand_PopupMenuItem Objects-->


<PopupMenuItems Type="Caesam_ObjectArray">
<Item Type="CaesamMvc_PluginCommand_PopupMenuItem">
<CommandKey Type="Caesam_String">DUMP_SELECTION_CMD</CommandKey>
<!-- AddInPopupMenuOf -->
<!-- used by class com.samcef.caesam.modules.pluginCommand.DefaultPlugin-->
<!-- specifiy the view(s) for which PopupMenu will display
<AddInPopupMenuOf Type="Caesam_StringArray">
SMTreeView;PropertyView
</AddInPopupMenuOf>
</Item>
<Item Type="CaesamMvc_PluginCommand_PopupMenuItem">
<CommandKey Type="Caesam_String">CREATE_SEAPANEL_CMD</CommandKey>
<AddInPopupMenuOf Type="Caesam_StringArray">
SMTreeView;3Dview
</AddInPopupMenuOf>
</Item>
<Item Type="CaesamMvc_PluginCommand_PopupMenuItem">
<CommandKey Type="Caesam_String">DUMP_MATERIAL_CMD</CommandKey>
<AddInPopupMenuOf Type="Caesam_StringArray">PropertyView</AddInPopupMenuOf>
</Item>
</PopupMenuItems>
</CommandWidgets>
</Instance>

26.10 Other Interface definition


The old way to adapt interface menus by the addition of the following items is still possible:
• A predefined result in “Result Menu”
• A Task in the “Tools Menu”
• A help page in “Help Menu”
• An “About” entry in “Help Menu”
These items can be added via any plugin.

Add a predefined result to the Result Menu

To add a predefined result involves two steps.


1. Add a resource to the plugin.xml file.
This resource contains the path to find the Menu_Result_Show.csm.

<Resources Type="Caesam_ObjectMap">
<Item Key="PredifineResult"
Type="Caesam_Url">resources/Menu_Result_Show.csm</Item>
<Item Key="ToolTasks"
Type="Caesam_Url">resources/Menu_Tools_Task.csm</Item>
<Item Key="HelpURL" Type="Caesam_Url">resources/Menu_Help_Url.csm</Item>

<Item Key="AboutURL"
Type="Caesam_Url">resources/Menu_About_Url.csm</Item>
</Resources>

2. Edit the “Menu_Result_Show.csm” file.


Add a <item> tag that contains the new values in the <Instance Type="Caesam_ObjectArray">
tag.
An item needs:
• A label
• An OperationType: Nothing if “by SE”

page-283
Caesam SDK | 26 Analysis interface definition

• An EOType
• A MemberName
• A Criteria: Nothing if “by SE”
An example is shown below.

<Instance Type="Caesam_ObjectArray">
<Item Type="CaesamPrimitives_ResultMenuItem">
<Label Type="Caesam_String">PanelProfile_thickness</Label>
<OperationType Type="Caesam_String"></OperationType>
<EOType Type="Caesam_String">PanelProfile</EOType>
<MemberName Type="Caesam_String">thickness</MemberName>
<Criteria Type="Caesam_String"></Criteria>
</Item>
</Instance>

Add a Task to the Tools Menu

To add a predefined result involves two steps.


1. Add a resource to the plugin.xml file.
This resource contains the path to find the Menu_Tools_Task.csm.

<Resources Type="Caesam_ObjectMap">
<Item Key="PredifineResult"
Type="Caesam_Url">resources/Menu_Result_Show.csm</Item>
<Item Key="ToolTasks"
Type="Caesam_Url">resources/Menu_Tools_Task.csm</Item>
<Item Key="HelpURL"
Type="Caesam_Url">resources/Menu_Help_Url.csm</Item>
<Item Key="AboutURL"
Type="Caesam_Url">resources/Menu_About_Url.csm</Item>
</Resources>

2. Add a task in the Menu_Tool_Task.csm file.


For example:

<Instance Type="Caesam_ObjectArray">
<Item Type="CaesamPrimitives_MenuTask">
<Label Type="Caesam_String">InitModelSuperStiffeners</Label>
<TaskLocation
Type="Caesam_String">CaesamSamples_SuperStiffenerModel</TaskLocation>
<InputType Type="Caesam_String">CaesamStd_Model</InputType>
</Item>
</Instance>

Add a help page to the Help Menu

To add a predefined result involves two steps.


1. Add a resource to the plugin.xml file.
This resource contains the path to find the Menu_Help_Url.csm.

<Resources Type="Caesam_ObjectMap">
<Item Key="PredifineResult"
Type="Caesam_Url">resources/Menu_Result_Show.csm</Item>
<Item Key="ToolTasks"
Type="Caesam_Url">resources/Menu_Tools_Task.csm</Item>
<Item Key="HelpURL" Type="Caesam_Url">resources/Menu_Help_Url.csm</Item>

<Item Key="AboutURL"

page-284
26 Analysis interface definition | Caesam SDK

Type="Caesam_Url">resources/Menu_About_Url.csm</Item>
</Resources>

2. Add a help page in the Menu_Help_Url.csm.csm file.


For example:

<Instance Type="Caesam_ObjectMap">
<Item Key="help1" Type="Caesam_Url">
csm:com.samcef.caesam.test.airbus/help/HelpTest.html
</Item>
</Instance>

Add an ‘About’ entry the Help Menu

To add a predefined result involves three steps.


1. Add a resource to the plugin.xml file.
This resource contains the path to find the Menu_About_Url.csm.

<Resources Type="Caesam_ObjectMap">
<Item Key="PredifineResult"
Type="Caesam_Url">resources/Menu_Result_Show.csm</Item>
<Item Key="ToolTasks"
Type="Caesam_Url">resources/Menu_Tools_Task.csm</Item>
<Item Key="HelpURL"
Type="Caesam_Url">resources/Menu_Help_Url.csm</Item>
<Item Key="AboutURL"
Type="Caesam_Url">resources/Menu_About_Url.csm</Item>
</Resources>

2. Add an ‘About’ entry in the Menu_About_Url.csm.csm file.


For example add an 'about_1' url key pointing to 'AboutTest.html':

<Instance Type="Caesam_ObjectMap">
<Item Key="about_1"
Type="Caesam_Url">csm:com.samcef.caesam.test.airbus/about/AboutTest.html

</Item>
</Instance>

3. Provide the menu item text, and possibly a tool tip.


This achieved by updating the "Properties" of this plugin using the newly created key(s):
Use "MNU_<key>" to specify which text must appear on the new menu item added in the 'Help
Menu'.
Use "TIP_<key>" to specify which tool tip must appear over the new menu item when the mouse
hovers a few second above the item.
Use "ACC_<key>" to specify the accelerator key associated with the command. Don't forget to use
upper case character: control A, control shift B, control alt E, alt F12 ... in accelerator definition,
otherwise the accelerator will not be taken into account.
Use "MNE_<key>" to specify the mnemonic key associated with the command (one char only).
Here is the code for the 'about_1' key example.

MNU_about_1 = About the Test plugin


TIP_about_1 = About the Test plugin

page-285
Caesam SDK | 27 EditorData

27 EditorData
Caesam allows authors to create their own data types and associate their own Editor with it. During editing,
these editors do not work on a Caesam_Object, but on an EditorData Object.

EditorData concept

Let’s explain the connection between EditorData and Caesam_Object. One EditorData contains exactly
one CaesamAPI_Object.
This single CaesamAPI_Object contains an array of Caesam_Object of the same type (though the array
may possibly only contain one object).
The goal of CaesamAPI_Object is to manage several Caesam_Object and present them as a single only
one single Caesam_Object. The goal of EditorData is to provide functionality on top of CaesamAPI_Object
such as:
• add some GUI notification behavior when data edits occur
• add data filtering behavior
Take care of some EditorContext hints to present data (the Caesam_Object managed by the
CaesamAPI_Object) such as:
• Show data as read-only
• Hide some data accordingly to the related filter

Note: Note: Even if an EditorData object does not contain Caesam_Objects directly, but
a CaesamAPI_Object that contains Caesam_Objects, we will allow this shortcut: “An
EditorData contains Caesam_Objects”.

Editor impact

Editor works on EditorData, which delegates data related work to CaesamAPI_Object, which finally,
manages several Caesam_Object. This has the following implication for Editor; even though editors work
on a single data, EditorData object, they perform multi-editing, because one single EditorData modification
can lead the modification of all underlying Caesam_Objects.

Multi-Edition

Editors are fed with exactly one EditorData. This EditorData contains exactly one CaesamAPI_Object.
This CaesamAPI_Object contains an array of EO objects (possibly containing only one object).
The number of Caesam_Object edited in this array depends on:
• The number of selected tree nodes in the Stress Model tree (upper left panel of Caesam Main window)
N for example
• The number of selected rows in the property view (lower left table panel), M for example.
The number of Caesam_Object edited by an Editor (via EditorData and CaesamAPI_Object) is NxM.

27.1 EditorData services


EditorData provides different kind of services depending on the data they manage.
They are two main categories of services:
• Data related services, which allow identifying, access and modifying data. These services are the most
important for authors.
• GUI related services, which are more closely related to the internal mechanism of Caesam GUI. Authors
will rarely use those services.

page-286
27 EditorData | Caesam SDK

Note: Most of the EditorData methods are provided in two manners: one with a String
parameter called ‘theMemberName’, and the other without this parameter.

This means that the method will either affect a member of the current EditorData called ‘theMemberName’,
or the EditorData itself. If ‘theMemberName’ is null (or is an empty string), the method will work on the
EditorData itself, as if the ‘without memberName’ equivalent method had been called. Important note
Initially, EditorData was designed with an ‘open door’ to the underlying CaesamAPI_Object, which, in
turn, gives access to the underlying Caesam_Objects. Since EditorData provides many services, it is
strongly discouraged to bypass it (accessing directly the encapsulated Caesam_Objects), even if the API
still allows that (for backward compatibility reasons).

27.1.1 Data services


This section describes how to identify, access and modify data.

27.1.1.1 Identifying data

The first thing to do to use EditorData is to know what kind of data it contains. The main method to
achieve this is GetType.

String GetTypeName()
// ! will be replaced by GetType() in next release
!
String GetType(String theMemberName)

This method returns the name of the data type of EditorData, which is the same as all underlying
Caesam_Objects. The example below shows how to find out if an EditorData contains Caesam_Boolean
objects.

boolean containsBoolean = theEditorData.GetType().equals(“Caesam_Boolean”);

IsKind is the main method to know if data is of a given type, or of a type that inherits of this given type
(passed as argument to the IsKind method).

boolean IsKind(String theType)


boolean IsKind(String theMemberName, String theType)

For primitive and some built-in data types, a set of shortcut methods is available in EditorData.

Boolean IsBoolean()
Boolean IsBoolean(String theMemberName)
Boolean IsDate()
Boolean IsDate(String theMemberName)
boolean IsDouble()
boolean IsDouble(String theMemberName)
boolean IsDoubleArray()
boolean IsDoubleArray(String theMemberName)
boolean IsEO()
boolean IsEO(String theMemberName)
boolean IsFile()
boolean IsFile(String theMemberName)
boolean IsFunction()
boolean IsFunction(String theMemberName)
boolean IsInteger()
boolean IsInteger(String theMemberName)
boolean IsIntegerArray()
boolean IsIntegerArray(String theMemberName)

page-287
Caesam SDK | 27 EditorData

boolean IsObjectArray()
boolean IsObjectArray(String theMemberName)
boolean IsObjectMap()
boolean IsObjectMap(String theMemberName)
boolean IsObjectMatrix()
boolean IsObjectMatrix(String theMemberName)
boolean IsQuantity()
boolean IsQuantity(String theMemberName)
boolean IsQuantityArray()
boolean IsQuantityArray(String theMemberName)
boolean IsString()
boolean IsString(String theMemberName)
boolean IsStringArray()
boolean IsStringArray(String theMemberName)
boolean IsTypedArray() // Typed arrays have a constraint on the data they
contain
boolean IsTypedArray(String theMemberName)
boolean IsTypedMap() // Typed maps have a constraint on the data they contain

boolean IsTypedMap(String theMemberName)


boolean IsURL()
boolean IsURL(String theMemberName)

Useful information (including constraints on data) can be obtained on EditorData using different methods.

Data string representation

The well-known toString java method provides a String representation according to the contained data
type. toStringForCopy provides a string representation suitable for copy/paste operation for primitive
Caesam data type only (Caesam_Integer, Caesam_Double, etc)!

String toString() String toStringForCopy()


//Returns a String representation of this object to be used in copy/paste,
using local units (and not user units) when relevant (for quantities for
instance)

Multi editing info

Since EditorData allows multi editing, it is important to know if the edited Caesam_Object has the same
type/value, etc.

boolean IsSameType() // true if all Caesam_objects are of the same type


boolean IsSameValue() // true if all Caesam_objects have the same value
boolean IsSameValue(String theMemberName) // true if all Caesam_objects of
member EditorData “theMemberName” have the same value

boolean IsMultiEdition() // return true if EditorData contains more than 1


Caesam_Object

Data access

EditorData can have some of its members that are null. To handle this, Editor should always first check
that member is not null using the MemberIsSet method.
MemberIsSet(String theMemberName) will return true if all ‘theMemberName‘members of underlying
Caesam_Objects are not null. In other words, if at least one of the underlying object has a null
‘theMemberName‘member, the method MemberIsSet(String theMemberName) will return false.
EditorData objects can be read-only. This causes all standard widgets provided in the sdk
(com.samcef.caesam.dialog.* classes) to be automatically disabled. Moreover, a java

page-288
27 EditorData | Caesam SDK

java.beans.PropertyVetoException will be thrown if the EditorData (or its members) is modified: use
isEditable methods first to check if it is the case.

Boolean MemberIsSet(String theMemberName)


Boolean isEditable()
boolean isEditable(String theMemberName)

Enumeration

Some data can take its value among an enumeration of values. The 2 following methods can be used to
know if an EditorData take its value from a set of predefined values (enumeration).

Boolean HasPredefinedValues()
Boolean HasPredefinedValues(String theMemberName)

Note: EditorData which have predefined values can be managed with setUsedPredefinedKey
and getUsedPredefinedKey as explained later.

Container size constraint

Finally some methods provide information related to the type of Caesam_Object: Following data containers
can provide information about their size using hasFixedSize:

Caesam_ObjectArray
Caesam_BooleanArray // not yet available: should be available in a future
version
Caesam_IntegerArray // doesn’t work in current Caesam version: ok in next
version
Caesam_DoubleArray // doesn’t work in current Caesam version: ok in next
version
Caesam_StringArray // doesn’t work in current Caesam version: ok in next
version
Caesam_TypedArray
Caesam_EOArray

Caesam_ObjectMatrix
Caesam_BooleanMatrix // not yet available: should be available in a future
version
Caesam_IntegerMatrix // doesn’t work in current Caesam version: ok in next
version
Caesam_DoubleMatrix // doesn’t work in current Caesam version: ok in next
version
Caesam_StringMatrix // doesn’t work in current Caesam version: ok in next
version
Caesam_TypedMatrix
Caesam_EOMatrix

Boolean hasFixedSize()

Context of Edition

When it is edited, the EditoData has an EditorContext object associated to it. This object allows the
EditorData to behave in a specific way according to the context of current edition (internal API). The

page-289
Caesam SDK | 27 EditorData

EditorContext also gives access to the shared workspace library and the Caesam model (main data container
of current Caesam document).

EditorContext getEditorContext()

27.1.1.2 Accessing data

Accessing Data EditorData accessor methods do not give access to the underlying Caesam_Object. Instead,
they provides new EditorData object that contains 'N child Caesam_Object' of the N Caesam_Object
managed by the initial EditorData.
This means that Editors only have to know the EditorData interface to work on the underlying
Caesam_Objects.

Member access

The most important accessor methods available in EditorData are:

Caesam_StringArray GetMembers() // gives the list of member names, usable by


getMember(…)
EditorData GetMember(String theMemberName)
EditorData GetMember(String theMemberName, boolean theCreateIfNull)

The two arguments GetMember method allows you to create the member if it was null if theCreateIfNull
is true. To know if a member is null use the MemberIsSet method.

Tip: EditorData (and some of its member) can be hidden: this means that your GUI should
not show those EditorData. The IsVisible method presented in the GUI services chapter
explains this in detail.

Primitive data

Caesam framework proposes the usual primitive data. As a consequence, EditorData provides methods
to handle them, i.e., Boolean, Double, Integer, String:

Boolean GetBooleanValue()
Boolean GetBooleanValue(String theMemberName)
double GetDoubleValue()
double GetDoubleValue(String theMemberName)
int GetIntegerValue()
int GetIntegerValue(String theMemberName)
String GetStringValue()
String GetStringValue(String theMemberName)

Two additional primitive data types are available: Date and Url

String GetDateValue()
String GetDateValue(String theMemberName)
String GetUrlValue()
String GetUrlValue(String theMemberName)
String GetResolvedUrlValue()
String GetResolvedUrlValue(String theMemberName)

Note: url value can have a ‘csm:…/’ prefix denoting a Caesam Context.
GetResolvedUrlValue() ‘resolve’ this ‘…’ context and gives a valid url (whitout ‘csm’
prefix)

page-290
27 EditorData | Caesam SDK

Structured Primitive data

Two more structured primitive data types are available: Caesam_File and Caesam_Quantity Caesam_File
provides Mime type info.

Caesam_StringArray GetFileExtensions(String theMemberName)


String GetFileMimeType(String theMemberName)
Caesam_StringArray GetFileMimeTypes(String theMemberName)
String GetFileValue()
String GetFileValue(String theMemberName)
String GetResolvedFileValue()
String GetResolvedFileValue(String theMemberName)

Note: As for URL, file value can have a ‘csm:…/’ prefix denoting a Caesam Context.
GetResolvedFileValue() ‘resolve’ this ‘…’ context and gives a valid file (whitout ‘csm’
prefix)

Caesam_Quantity is suitable to represent any numerical values with dimension and units (distance in
meters, temperature in Fahrenheit, etc..)

String GetQuantityDimension()
String GetQuantityDimension(String theMemberName)
double GetQuantityMax()
double GetQuantityMax(String theMemberName)
double GetQuantityMin()
double GetQuantityMin(String theMemberName)
String GetQuantityUnit()
String GetQuantityUnit(String theMemberName)
double GetQuantityValue()
double GetQuantityValue(String theMemberName)

Moreover, those values can be bounded: use the following method to check if min and/or max are available
on Caesam_Quantities:

boolean HasQuantityMax()
boolean HasQuantityMax(String theMemberName)
boolean HasQuantityMin()
boolean HasQuantityMin(String theMemberName)

Enumeration

As explained earlier, some data can take its value from a set of enumerated values, thanks to the
HasPredefinedValues method. The following 3 methods can be used to know which value an EditorData
takes out of the set of possible predefined values (enumeration).

String GetUsedPredefinedKey()
String GetUsedPredefinedKey(String theMemberName)
Caesam_StringArray GetPredefinedKeys() // get all the keys of all
predefinedValue available

Note: This method gives only the ‘key’ of the predefined value (i.e. a string), not the value
itself. This key will used by the SetUsedPredefinedKey method as explained later.

Primitive Data Container

Caesam also provides standard container data type as: Array, Map and Matrix.

page-291
Caesam SDK | 27 EditorData

Note: BooleanArray is not yet available: it will be available in a future version of Caesam.

int GetDoubleArraySize()
int GetDoubleArraySize(String theMemberName)
double GetDoubleArrayValue(int theIndex)
double GetDoubleArrayValue(String theMemberName, int theIndex)
double[] getDoubleArrayValues(String theMemberName)
int GetIntegerArraySize()
int GetIntegerArraySize(String theMemberName)
int GetIntegerArrayValue(int theIndex)
int GetIntegerArrayValue(String theMemberName, int theIndex)
int[] getIntegerArrayValues(String theMemberName)

String GetQuantityArrayDimension()
String GetQuantityArrayDimension(String theMemberName)
int GetQuantityArraySize()
int GetQuantityArraySize(String theMemberName)
String GetQuantityArrayUnit()
String GetQuantityArrayUnit(String theMemberName)
double GetQuantityArrayValue(int theIndex)
double GetQuantityArrayValue(String theMemberName, int theIndex)
double[]getQuantityArrayValues(String theMemberName)
int GetStringArraySize()
int GetStringArraySize(String theMemberName)
String GetStringArrayValue(int theIndex)
String GetStringArrayValue(String theMemberName, int theIndex)

Note: QuantityArray instance have one single Unit and Dimension info shared by all the
Caesam_Quantity it holds.

General Data Container

Caesam Array, Map and Matrix can hold any kind of Caesam_Object: First, let’s highlight that a data
container can give information about what kind of data they contain.

String GetObjectType(String theMemberName)


Caesam_StringArray GetObjectTypeMembers(String theMemberName)
// the list of member of type of contained data

Note: At the Caesam_Object level, each container exists in 2 styles: typed or untyped.

For instance, Array exists as CaesamObject_Array (untyped array) and CaesamTyped_Array, which adds
a constraint on the type of object it can hold.
GetObjectType and GetObjectTypesMambers still work, no matter on which kind of container (typed or
not) the method is invoked.

Note: Type_Matrix is not yet available: it will be available in a future version of Caesam.

For Array support, EditorData provides the following methods:

int GetObjectArraySize()
int GetObjectArraySize(String theMemberName)
EditorData GetObject(int theIndex)
EditorData GetObject(int theIndex, boolean theCreateIfNull)
EditorData GetObject(String theMemberName, int theIndex)
EditorData GetObject(String theMemberName, int theIndex, boolean
theCreateIfNull)

page-292
27 EditorData | Caesam SDK

Map support is possible using the following methods:

EditorData GetObject(String theKey)


EditorData GetObject(String theKey, boolean theCreateIfNull)
EditorData GetObject(String theMemberName, String theKey)
EditorData GetObject(String theMemberName, String theKey, boolean
theCreateIfNull)
Caesam_StringArray GetObjectMapKeys()
Caesam_StringArray GetObjectMapKeys(String theMemberName)

Matrix support is possible using the following methods:

int GetMatrixColumnCount()
int GetMatrixColumnCount(String theMemberName)
EditorData GetMatrixItem(int theRow, int theColumn)
EditorData GetMatrixItem(int theRow, int theColumn, boolean theCreateIfNull)

EditorData GetMatrixItem(String theMemberName, int theRow, int theColumn)


EditorData GetMatrixItem(String theMemberName, int theRow, int theColumn,
boolean theCreateIfNull)
int GetMatrixRowCount()
int GetMatrixRowCount(String theMemberName)

27.1.1.3 Modifying data

The ultimate goal of editing is to modify data. The 3 possibilities are:


• Modifying values
• Changing Data Types
• Invoking methods (which can possible modify data)

Data Modification

Member

void SetMember(String theMemberName, Caesam_Object theObject)


void SetMember(String theMemberName, EditorData theValue)

Primitive data

void SetBooleanValue(boolean theValue)


void SetBooleanValue(String theMemberName, boolean theValue)
void SetDoubleValue(double theValue)
void SetDoubleValue(String theMemberName, double theValue)
void SetIntegerValue(int theValue)
void SetIntegerValue(String theMemberName, int theValue)
void SetStringValue(String theValue)
void SetStringValue(String theMemberName, String theValue)

boolean SetDateValue(String theDate)


boolean SetDateValue(String theDate, String theMemberName)
void SetUrlValue(String theValue)
void SetUrlValue(String theMemberName, String theValue)
void SetResolvedUrlValue(String theValue)
void b(String theMemberName, String theValue)

page-293
Caesam SDK | 27 EditorData

Structured Primitive data

void SetFileMimeType(String theMemberName, String theValue)


void SetFileValue(String theMemberName, String theValue)
void SetResolvedFileValue(String theValue)
void SetResolvedFileValue(String theMemberName, String theValue)
void SetQuantityUnit(String theUnit)
void SetQuantityUnit(String theMemberName, String theUnit)
void SetQuantityValue(double theValue)
void SetQuantityValue(String theMemberName, double theValue)

Enumeration

void SetUsedPredefinedKey(String theKey)


voidvSetUsedPredefinedKey(String theMemberName, String theKey)

Primitive Data Container

void SetDoubleArrayValue(int theIndex, double theValue)


void SetDoubleArrayValue(String theMemberName, int theIndex, double
theValue)
void setDoubleArrayValues(String theMemberName, double[] theValues) Sets
a hole array of doubles
void SetIntegerArrayValue(int theValue, int theIndex)
void SetIntegerArrayValue(String theMemberName, int theValue, int theIndex)

void setIntegerArrayValues(String theMemberName, int[] theValues) Sets a


hole array of integers
void AppendQuantityArrayValue(String theMemberName, double theValue)
void ClearQuantityArray(String theMemberName)
void InsertQuantityArrayValue(String theMemberName, double theValue, int
theIndex)
void RemoveQuantityArrayValue(String theMemberName, int theIndex)
void SetQuantityArrayDimension(String theMemberName, String theUnit)
void SetQuantityArrayUnit(String theUnit)
void SetQuantityArrayUnit(String theMemberName, String theUnit)
void SetQuantityArrayValue(double theValue, int theIndex)
void SetQuantityArrayValue(String theMemberName, double theValue, int
theIndex)
void setQuantityArrayValues(String theMemberName, double[] theValues)
void SortQuantityArray(String theMemberName)
void SetStringArrayValue(String theValue, int theIndex)
void SetStringArrayValue(String theMemberName, String theValue, int
theIndex)

General Data Container


Array

EditorData AppendObject(String theMemberName)


EditorData AppendObject(String theMemberName, CaesamAPI_Object theObj)
EditorData InsertObject(String theMemberName, int theIndex)
EditorData InsertObjects(String theMemberName, int theIndex, int aCount)
boolean MoveObject(String theMemberName, int theIndex1, int theIndex2)
boolean RemoveObject(int theIndex)
boolean RemoveObject(String theMemberName, int theIndex)

Map

EditorData AddObject(String theMemberName, String theKey)


boolean RemoveObject(String theKey)
boolean RemoveObject(String theMemberName, String theKey) Matrix

Matrix modification methods are not yet implemented.

page-294
27 EditorData | Caesam SDK

Data Type Modification

It is possible to change the type of an EditorData at runtime, using

String ChangeType(String theNewType)

This means that all Caesam_Objects contained in the EditorData will be replaced by new instances of
type ‘theNewType’.
Of course, there are some restrictions on the type that can be used: the destination type should be a subtype
of the original one. The list of available types for such a modification can be retrieved using the
getAvailableTypes() function.

String[] getAvailableTypes()

The base type of the hierarchy can be retrieved using

String getDeclaredType()

Note: Note: that setDaclaredType must not be called: it is reserved for internal use only!

void setDeclaredType(String theDeclaredType) // for internal


use only

Method Invocation

If you want to invoke a method on them, you can use CallMethod("yourMethodDefinedOnYourEO")


method on EditorData: this method will call "yourMethodDefinedOnYourEO" on all NxM EO Objects
(you just need to register this method in the Caesam Registry).

EditorData CallMethod(String theMethodName)


EditorData CallMethod(String theMethodName, Caesam_Object theArgument)

27.1.2 GUI services


EditorData can request to be hidden (not visible in the GUI). The following methods are available to
check that:

Boolean IsVisible()
// check if this object is visible

boolean IsVisible(String theMemberName)


//check if member 'theMemberName' of object is visible. Even if this method
returns false, the editor can still consult this object values etc..

EditorData can inform any ‘listener’ object that it internal changes.


Listeners can add themselves in the list of listener using addChangeListener method and remove themselves
from this list using removeChangeListener.
In the mean time, any change occurring on this EditorData object will cause the stateChanged method of
all registered listener to be invoked.

void addChangeListener(javax.swing.event.ChangeListener theListener)


Adds a change listener to the list of listeners to be notified of a change
in this object's state

page-295
Caesam SDK | 27 EditorData

Note: a listener is added in the list of listeners only if it is not yet


present in it.
void stateChanged()
Notifies the change listeners that the state of the encapsulated
CaesamAPI_Object has changed.
void removeChangeListener(javax.swing.event.ChangeListener theListener)
Removes a change listener to the list of listeners to be notified of a
change in this object's state

27.1.3 Reserved and deprecated methods


For backward compatibility reasons, some methods are still present in the EditorData interfaces, but must
not be used by client code: The following methods give access to the underlying CaesamAPI_Object and
Caesam_Objects: using these methods is strongly discouraged since:
• The Caesam_Object GetMember() & Callmethod() allows to perform any operation on underlying
objects due to the Caesam reflexivity mechanism
• EditorData provides many automatic services triggered when data are accessed/ modified: accessing
objects directly will cause those services not to be triggered and the ‘EditorData level’ (impacting the
GUI) could become inconsistent with the ‘Caesam_Object level’, i.e., the value of underlying objects.

int Size() // get the number underlying Caesam_Objects


Caesam_Object Get(int theIndex)
CaesamAPI_Object getCaesamApiObject() // Accesses directly the encapsulated
API_Object.
CaesamAPI_Object GetCaesamAPIObject(int theIndex)
CaesamAPI_Object GetCaesamAPIObject(String theMemberName, int theIndex)
void Set(int theIndex, Caesam_Object theValue)

The following methods are for internal use only:

Boolean IsLoadCaseCommon(CaesamStd_EO theLoadCase)


boolean IsLoadCaseContained(CaesamStd_EO theLoadCase)
boolean IsLoadCaseSet()
CaesamStd_EO GetLoadCase(int theLCSIndex, int theIndex)
int GetLoadCaseSetSize(int theLCSIndex)
void AppendLoadCase(CaesamStd_EO theLoadCase)
void AppendLoadCases(CaesamStd_EOArray theLoadCaseArray)
void RemoveLoadCase(CaesamStd_EO theLoadCase)
void RemoveLoadCases(CaesamStd_EOArray theLoadCaseArray)
void setDeclaredType(String theBaseType)
void Backup() // undo redo related
void clearMemberCache()
void initializeOrderedTypesSet()
// related to changeType()
CaesamStd_AbstractEditorFilter getVisibilityFilter()
void setVisible(boolean theIsVisible)
// override any Visibility filter
void setVisibilityFilter(CaesamStd_AbstractEditorFilter theFilter)
CaesamStd_AbstractEditorFilter getEditabilityFilter()
void setEditable(boolean theIsEditable) // ovverride any editability filter!

void setEditabilityFilter(CaesamStd_AbstractEditorFilter theFilter)


boolean isStateChangedDisabled()
int compareTo(Object o)
// Comparable implementation for EditorData comparison
boolean CheckValidity()
// trigger author define validity method
void setEditorContext(EditorContext theContext)
void setIsRootEditorData(boolean theIsRootEditorData)
void setString(String theMemberName, String theValue)

page-296
27 EditorData | Caesam SDK

Sets the value of a member represented by a String (


used for pasting data from the clipboard).
void disableStateChanged()
void enableStateChanged(boolean theRefresh)
void FatherChanged()
void removeAllChangeListeners()

The following SetEditable method is incompatible with current EditorData member creation mechanism,
which means that it must not be used by client code:

void setEditable(String theMemberName, boolean theIsEditable)

The following methods are deprecated have been replaced by other methods:

String getBaseType() replaced by getDeclaredType()


boolean getEditable() replaced by isEditable()
boolean IsEOMember(String theMemberName) replaced by IsEo(String theMemberName)

void setBaseType(String theBaseType) replaced by setDeclaredType(String)


void stateChanged(ChangeEvent theEvent) replaced by stateChanged()
boolean ChangeType(CaesamStd_EO theEO) replaced by ChangeType(String)
String GetMemberType(String theMemberName) replaced by GetType(String
theMemberName)
Caesam_StringArray GetPredefinedValues() replaced by GetPredefinedKeys()

page-297
Caesam SDK | 28 Language Bindings

28 Language Bindings
This chapter describes the interfaces that can be used to call Caesam methods.

28.1 The CAESAM FORTRAN interface


This provides the capability for plugins authors to call some CAESAM methods from FORTRAN
subroutines and functions.
Not all methods of all classes of the CAESAM platform are available in the FORTRAN language: only
the methods tagged as EXPORT in the .cdl class description are exported to the FORTRAN language
(see the cdl classes in the SDK documentation).
The file
"{CAESAMInstallationDirectory}/examples/plugins/SMRFSuperStiffener.f"
in the plugin "com.samcef.caesam.test.process.callfortranprocess_pythonlib"
may serve as FORTRAN source code template.

Using Caesam objects in FORTRAN code

The following rules are applied:


• Each object inheriting from "Caesam_Object" (more generally, inheriting from the root class
"Standard_Transient") is handled in the FORTRAN API may a variable of type "transient_handle".
A variable of type "transient_handle" does not need to be initialized, but must be released at the end
of the FORTRAN function or subroutine (see here after). Otherwise, memory losses will occur during
CAESAM execution.
• Enumeration values are translated in FORTRAN constant integers in the caesamf module.
• Each FORTRAN function wrapping a C++ class instance method has as the first argument (named
"SELF") the current object instance (the "this" pointer in object oriented language). Of course,
FORTRAN functions wrapping a class methods (also called static methods) do not have this first
additional argument.
• For methods returning something (i.e. not "void" methods), an additional output argument is appended
to the argument list in the FORTRAN wrapping function. This additional argument will receive the
returned method value.
• Each FORTRAN function wrapping a C++ method returns a integer value (theReturnStatus) , which
is 0 in case of success and not null otherwise.

Important: It is highly recommended to test the return status after each call of a FORTRAN
function wrapping a C++ method.

The Caesam Fortran API

The first function listed below gives access to a message of the corresponding to theReturnStatus of the
FORTRAN API interface Purpose.
Access to last message

INTEGER FUNCTION CSMF_GETMESSAGE(


INTEGER, INTENT(IN):: THERETURNSTATUS,
CHARACTER(LEN=*),INTENT(INOUT)::THEMESSAGESTRING,
INTEGER, INTENT(OUT):: THEUSEDLEN)

loads in theMessageString the message text corresponding to theReturnStatus.


Additional functions

page-298
28 Language Bindings | Caesam SDK

The following additional functions (functions starting with the csmf_ prefix) also belong to this CAESAM
FORTRAN API.

INTEGER FUNCTION CSMF_NEW_CAESAM_STATUS( CHARACTER(LEN=*),
INTENT(IN)::THECLASS, CHARACTER(LEN=*), INTENT(IN)::THEMETHOD,
CHARACTER(LEN=*), INTENT(IN)::THEFORMATTEDTEXT,
TYPE(TRANSIENT_HANDLE), INTENT(INOUT)::THESTATUS)

returns a new Handle_Caesam_Message built from the class name, the method name and the formatted
text (see Caesam_Message documentation). This function can be used to build a status when a status
is required (for exceptions, SetStatus methods, etc.)

INTEGER FUNCTION CSMF_STR_TRUELEN(
CHARACTER(LEN=*), INTENT(IN):: THESTRING)

returns the true length of a FORTRAN string, removing trailing white spaces.

INTEGER FUNCTION CSMF_HANDLE_ISNULL(
TYPE(TRANSIENT_HANDLE), INTENT(IN):: THEOBJECT,
LOGICAL, INTENT(OUT):: THEBOOL)

tests if a handle is null, i.e. is not assigned or points to nothing



INTEGER FUNCTION CSMF_HANDLE_PRINT(
TYPE(TRANSIENT_HANDLE), INTENT(IN):: THEOBJECT,
CHARACTER(LEN=*), INTENT(INOUT):: THERETSTRING,
INTEGER, INTENT(OUT):: THEUSEDLEN)

converts a handle value (an address) to a FORTRAN string in the 0x* format and returns the number
of characters in the theUsedLen

INTEGER FUNCTION CSMF_HANDLE_FREE(
TYPE(TRANSIENT_HANDLE),INTENT(INOUT)::THEOBJECT)

releases a handle (equivalent to assign a handle to NULL)



INTEGER FUNCTION CSMF_HANDLE_FREE_MESSAGE(
TYPE(TRANSIENT_HANDLE),INTENT(INOUT) ::THEOBJECT,
CHARACTER(LEN=*), INTENT(IN) :: THEROUTIN,
CHARACTER(LEN=*), INTENT(IN) :: THESUFFIX,
INTEGER, INTENT(IN) ::THEUNIT)

releases a handle and writes an error message (if any) on the given unit prefixed by the routin name
and followed by the given suffix
The CSMF package contains a convenience set of functions (class methods) available in
FORTRAN/C++/PYTHON for plugin's authors. The function

Integer CSMF_LastError(integer RETURN)

returns in RETURN the execution status of the last CSMF call. Null means successfull call. The error
codes are available as parameters whose names start with CSMF_
INTERNAL CAESAM FORTRAN API for debugging purpose only:

page-299
Caesam SDK | 28 Language Bindings


LOGICAL FUNCTION CSMF_HANDLE_IS_ASSIGNED(
TYPE (TRANSIENT_HANDLE), INTENT(IN) ::THEHANDLE)

this if the handle as been assigned at least once (for debugging purposes only)

SUBROUTINE CSMF_HANDLE_SETQ(
TYPE(TRANSIENT_HANDLE), INTENT(INOUT)::THEOBJECT,
TYPE(TRANSIENT_HANDLE), INTENT(IN) :: THESOURCE)

handles assignation called by the the operator = between handles



SUBROUTINE CSMF_HANDLE_INIT(
TYPE(TRANSIENT_HANDLE),INTENT(INOUT):: THEOBJECT)

handle initialization to null if not yet initialiazed. called by the operator new initialization is automatic:
it is not necessary to initialize each transient_handle variable

Mathematical constants available in FORTRAN API

The following mathematical constants are declared in the caesamf_module


Table 31: Some mathematical constants

Type Variable Name Value Comment

double CSMF_PI_VALUE 3.14159265358979323846 pi value in double


precision precision
double CSMF_E_VALUE 2.71828182845904523536 e value in double
precision precision
double CSMF_DEG_RAD 0.017453292519943296 pi/180 = # of radians in
precision one degree
double CSMF_PI_180 0.017453292519943296 pi/180 = # of radians in
precision one degree
double CSMF_180_PI 57.29577951308232088 180/ PI = # of degrees
precision in one radian
double CSMF_RAD_DEG 57.29577951308232088 180/ PI = # of degrees
precision in one radian
double CSMF_SQRT2 1.41421356237309504880 square root of 2
precision
double CSMF_LN2 0.69314718055994530942 ln(2)
precision
double CSMF_DBLE_MAX 1.7976931348623157D308 max double value
precision
double CSMF_DBLE_MIN 2.2250738585072014D-308 min double value
precision
double CSMF_DBLE_EPSILON 2.2204460492503131D-16 Smallest double such
precision that 1.0 +
DBL_EPSILON !=1.0
real CSMF_FLT_MAX 3.402823466E38 max real value

page-300
28 Language Bindings | Caesam SDK

Type Variable Name Value Comment

real CSMF_FLT_MIN 1.175494351E-38 min real value


real CSMF_FLT_EPSILON 1.192092896E-07 Smallest float such that
1.0 + DBL_EPSILON
!=1.0
integer CSMF_INT_MAX 2147483647 max integer value
integer CSMF_INT_MIN -2147483648 min integer value
integer CSMF_DBL_DIG 15 # of decimal digits for
double precision
integer CSMF_FLT_DIG 6 # of decimal digits for
simple precision

Developing rules

The FORTRAN developer must follow the steps given below:


• Use the FORTRAN caesamf module which contains an interface with the declarations of all the
CAESAM FORTRAN functions, the values of the CAESAM parameters (previously defined in
caesam_enums.h) and the types Transient_Handle and Transient_Ref. It also contains the CSMF_*
constants defined above.
• Release each variable of type transient_handle at the end of the subroutine or function with one of the
following strategies:
• by assigning the variable to a NULL handle (i.e. a transient_handle variable assigned to nothing)
• by calling the function CSMF_HANDLE_FREE(THEOBJECT)
• by calling the subroutine CSMF_HANDLE_FREE_MESSAGE(THEOBJECT, THEROUTIN,
THESUFFIX,THEUNIT

Documentation

The HTML CAESAM FORTRAN API documentation may be found in URL "file:{CaesamInstall
Directory}/doc/Fortran/Wrapping/html/files.html"
The HTML documentation of the CAESAM classes (including inherited methods) may be found in URL
"file:{CaesamInstallDirectory}/doc/sdkdoc/index.html"

28.1.1 How to call FORTRAN code


This explains how to call FORTRAN functions and subroutines from a plugin.

Direct FORTRAN call from C++.

A FORTRAN subroutine or function may be directly called from C or C++ code accounting for the
following rules:
• all the externals names (functions, subroutines and commons) are lower case and have an underscore
character ('_') suffix appended
• in C++ code, all the externals names (functions, subroutines and commons) have to be declared as
extern "C"
• the functions and subroutines arguments are always references (pointers), except for the character
string lengths (see hereafter)
• for each the character*(*) argument , an additional integer containing the length of the character string
is added at the end of the arguments list

page-301
Caesam SDK | 28 Language Bindings

Invoking a FORTRAN subroutine registered in as method in an object type

One or several FORTRAN subroutine(s) can be registered in an object type with the following syntax in
a .typedesc file

<Method Name="method name" Type="Fortran" Function="fortran subroutine name"/>

A registered subroutine can be invoked from C++, FORTRAN or PYTHON code with one of the
CallMethod methods of Caesam_Object:

using Handle_Caesam_Object Caesam_Object::CallMethod(const STL_String&


theMethodName):

aObjectInstance->callMethod("method name")

or

using Handle_Caesam_Object Caesam_Object::CallMethod(const STL_String&


theMethodName,const Handle_Caesam_Object& theArgument)

aObjectInstance->callMethod("method name", anArgumentObject)

The registered FORTRAN function must have the following signature

SUBBROUTINE anySubroutineName(theThisInstance, theArgumentInstance,


theReturnedObject)
type (transient_handle),intent(in)::theThisInstance, theArgumentInstance
type (transient_handle),intent(out)::theReturnedObject

Calling FORTRAN from PYTHON

• The FORTRAN subroutine or function must be part of a Caesam_PythonModulePlugin so that an


interface between the FORTRAN will be automatically generated at the plugin compilation time by
the csmmake or csmmakeall utilities, by calling a FORTRAN - PYTHON wrapper called f2py
• The PYTHON FORTRAN interface maps any CAESAM object argument or returned value into a
string identifying the object (the "object ID"). The FORTRAN can retrieve the corresponding
transient_handle by calling the function

INTEGER FUNCTION CAESAM_OBJECT_OBJECTFROMID(theObjectID, THEOBJECT)


CHARACTER(LEN=*), INTENT(IN) :: theObjectID,
TYPE(TRANSIENT_HANDLE), INTENT(OUT):: THEOBJECT

Running a FORTRAN Process

A FORTRAN subroutine can be registered as the "Run" method of a Process_Analysis. When the analysis
is runned from the Run button of the GUI interface, or when the Run method of a Process_Analysis
instance is called, the registered FORTRAN subroutine will be invoked. Registering the Run method can
be done in a .typedesc file as follow

<TypeDesc Name="myAnalysisType" Inherits="Process_Analysis" >


...
<Method Name="Run" Type="Fortran" Function="MyFORTRANAnalysisSubroutine"
/>
...
</TypeDesc>

page-302
28 Language Bindings | Caesam SDK

The registered FORTRAN subroutine signature must be like this:

SUBBROUTINE MyFORTRANAnalysisSubroutine(theAnalysis, theDataSet)


type (transient_handle),intent(in)::theAnalysis, theDataSet

28.2 The CAESAM PYTHON interface


The Python conversion toolkit. The Python converters are located in the plugin:
com.samcef.caesam.csmpython From a Python point of view, they are in a python package called
CsmPython. The Python converters are made to ease the conversion between Caesam, Python and Numeric
objects.
The toolkit supports:
• Primitive types
• One dimension arrays
• Matrices (and string arrays) limited to rank 2 (two dims)
There are 3 converters modules:
• CaesamConverter: Used to Convert from Python and Numeric to Caesam Objects
• PythonConverter: Used to Convert from Python to CaesamObjects
• NumericConverter: Used to Convert Python and Caesam Objects to Numeric objects
The base method for all the module is :

def Convert(Object,Type=None)
returns ConvertedObject

Object is the InputObject.


Type is away to force the type of the return object Primitive type. It is the Python type. It can be int, float
(and bool for Caesam and Python objects). The default value is None and means that the type will be the
best one available.
For the CaesamConverter you have some additional parameters:

def Convert(Object,Type=None,theDimension=None)

Where theDimension is the dimension used for Caesam Quantities.


A more detailed description follows.
CaesamConverter : This method you should use.

def Convert(theNumericObject,theForcedType=None,theDimension=None):

theNumericObject is a Python or numeric object. theForcedType the typing is automatic, but by


putting a Python type (ie: float, int) you can change the type of the conversion result. theDimension
creates a Quantity object of that dimension.

if isinstance(theForcedType(),int) and theDimension is not None:


raise "CaesamConverter - We cannot create a Quantity with an int type"
return ToCaesam(theNumericObject,theDimension,theForcedType)

def ConvertToDouble(theNumericObject,theDimension=None):
return Convert(theNumericObject,float,theDimension)

def ConvertToInteger(theNumericObject):
return Convert(theNumericObject,int,None)

page-303
Caesam SDK | 28 Language Bindings

def ConverToQuantity(theNumericObject,theDimension):
return Convert(theNumericObject,float,theDimension)

PythonConverter

def Convert(theCaesamObject,forcedtype=None):

The theCaesamObject is the input caesam_object The forcedtype= the python type is the (int,
float, bool) you want in return. It returns a Python translated object

def ConvertToDouble(theCaesamObject):
return Convert(theCaesamObject,float)
def ConvertToInteger(theCaesamObject):
return Convert(theCaesamObject,int)
def ConvertToBoolean(theCaesamObject):
return Convert(theCaesamObject,bool)

NumericConverter

def Convert(theObject,forcedtype=None)
def ConvertToDouble(theObject):
return Convert(theObject,float)
def ConvertToInteger(theObject):
return Convert(theObject,int)

Note: The Default converter will convert the string array to the size of the longest string
in the array.

Usually, you will have to specify the maximum size of the string you want to allocate in the array. In this
case you should call:

def ConvertToString(theObject,theSize=None)

This is a special method for Numeric. If you want to specify a maximum string size, you must call this
function. Note that the NumericConverter will perform the double column swapping necessary for matrices
itself. Rank 2 matrices from the converter should only be used for calling directly Fortran code through
F2Py. You should not try to manipulate them directly in python as their row order is modified to overcome
a limitation of F2Py.

Raising a PYTHON exception from FORTRAN code

The following FORTRAN subroutine

SUBROUTINE CAESAMFORTRANEXCEPTION(RoutinName, MessageString)


CHARACTER*(*) RoutinName, MessageString

is available in any FORTRAN subroutines/function called from PYTHON code.


RoutinName is the name of the calling FORTRAN subroutine or function
MessageString is a English text describing the error
A call to this subroutine never returns, but stops the current FORTRAN code execution and throws a
PYTHON exception.
This exception can then be caught by the calling PYTHON code to signal a severe error.
The call to this subroutine never returns. Thus, before calling it all variables of type "transient_handle",
must be released. This subroutine has to be called when a severe error occurs in the FORTRAN code and

page-304
28 Language Bindings | Caesam SDK

must replace the STOP instruction, as this instruction kills the current process and thus the CAESAM
session itself.
It replaces the previous subroutine

SUBROUTINE ERROR(MessageString)
CHARACTER*(*), MessageString

which is now deprecated but maintained for backwards compatibility.

Raising C++ exception from FORTRAN code

The author can call the Raise method from one of the Caesam_Exception class

integer aretstat
type(transient_handle) aHandleStatus
aretstat = csmf_new_caesam_status( &
‘thisclass’,’this method’,’this is a message text’,aHandleStatus)
if (aretstat.ne.0) goto 9999
call caesam_exception_raise(aHandleStatus)

The call to caesam_exception_raise never returns. The thrown exception will be caught at some
upper level in the call stack. Thus, before throwing an exception all variables of type "transient_handle",
must be released.

page-305
Caesam SDK | 29 Coding guidance

29 Coding guidance
A number of suggestions to provide guidance in coding
Portability: The code must be portable across platforms. The Open CasCade layer and the CAESASM
layer provide wrapper around the platform-specific function.
C++ exceptions on SUN workstations: The throw instruction or a call to the Raise() method may cause
a possible BUS error or Segmentation Violation error on SUN. It seems that string concatenations in
argments of methods called before the throw instruction (or a Raise call) may cause severe problem on
SUN workstation. This a bug in the SUN C++ compiler 5.5 (Studio 8). It can be fixed using the following
patches: 112763-15 and 113817-21

29.1 Environment variable


The script that starts caesam sets a variable STATION in the environment that calls one of four values:
• sun
• hp
• lin
• wnt
This variable can therefore be used within the CAESAM environment.
On UNIX/Linux there is no general environment variable in which the system can automatically detect
the station. It is necessary to use the command uname –s
On Windows, the variable OS calls Windows_NT

29.2 Macros
This section provides some information on using macros.

Logger macros

New macros for Logger handling are available in Caesam.hxx and are used in Caesam, CaesamStd,
CaesamAPI, etc.
For performance purpose, the comparison of logger level to the given level is performed before creating
the message. The CSM_LOGGER macro is still available, but becomes obsolete.
The CSM_LOG_* macros are still available as before (* means FATAL, SEVERE, ERROR, WARNING,
INFO, VERBOSE, DEBUG, TRACE).
The new macros CSM_LOG_*_ARGS macros allows to append arguments to the automatically built
message. For example:

Standard_Integer aImportTotal, aTotal;


...
CSM_LOG_INFO_ARGS
("CaesamAPI_EOLibrary",
"Import",
"Successfully imported %1% of the %2% EOs", aImportTotal << aTotal);
// The arguments aImportTotal and aTotal are appended to the message.

The precedent code expands to


if ((Log_INFO) <= Caesam_Application::GetLogLevel())
{
Log_Message aTmpLogMessage
("CaesamAPI_EOLibrary", "Import", "Successfully imported %1% of the %2%
EOs");

page-306
29 Coding guidance | Caesam SDK

aTmpLogMessage << aImportTotal << aTotal;


Caesam_Application::GetApplication()->GetLogger()->Log(aTmpLogMessage,
(Log_INFO));
}

The new macros CSM_LOG_*_MES macros allows to give a Caesam_Message as argument, but its use
is discouraged, as the message is to be built before the macro evaluation. The CSM_LOG_*_ARGS are
preferred.

Using macros in C/C++ language

Caution: The use of macros use is highly discouraged

Since the macro names are blindly substituted everywhere this may cause name collision. it is recommended
that you use C++ inline functions instead.
By convention (since the beginning of the C language in 1978 ! ), macros name are in uppercase, to avoid
name collision and bad substitution. Avoid using macro names such as min or max (lowercase names)

29.3 Access to OP2 results


The only way of reaching results in OP2 is to use the methods of the CaesamFEM_StaticAnalysis class.
For example CaesamFEM_StaticAnalysis::GetElem2DFluxInMatCoord.
It is the role of the reader of the OP2 called by the methods of the CaesamFEM_StaticAnalysis class to
use memory-masks in order to optimize the access time to information, whatever the way in which it is
present in the OP2 and whatever the way in which one calls CaesamFEM_StaticAnalysis: the developer
should not be worried some.
In this case, one uses map templates standard STL of C++
The software is optimized and functions well in so far as one Re-instantie not several times
CaesamFEM_Model (call in CaesamFEM_Model::NewInstance) given like argument in
CaesamFEM_StaticAnalysis::NewInstance. This instantiation of the model clot the files and gives the
memory-masks to zero. Then, with the first access to the OP2, one reads again them, the analysis and
recomputes the memory-masks, which can take time.
A problem of performance can come because of several times Re-instantier CaesamFEM_Model with
same file OP2 if several analyses are made. Only one instantiation should be enough, because the OP2
of the model and the OP2 of the load boxes do not change from one analysis to another.
CaesamFEM_Model should be instantiated in CaesamStd_Model (and thus only once) when one gives
file OP2 of the model. And this CaesamFEM_Model would be reached via (API around) this
CaesamStd_Model. It is a development to be envisaged.

29.4 Predefined inline functions and global constants


In the CAESAM SDK, the following functions and constants (including Min and Max) are available.

Standard_Real is equivalent to double

In Standard_Real.hxx include file (Standard_Real is equivalent to double)

const Standard_Real PI;


const Standard_Real PI180;

page-307
Caesam SDK | 29 Coding guidance

(See the documentation on math.h)

Standard_Real ACos (const Standard_Real );


Standard_Real ASin (const Standard_Real );
Standard_Real ATan2 (const Standard_Real , const Standard_Real );
Standard_Real NextAfter (const Standard_Real , const Standard_Real );
Standard_Real Sign (const Standard_Real , const Standard_Real );
Standard_Real ATanh (const Standard_Real );
Standard_Real ACosh (const Standard_Real );
Standard_Real Log (const Standard_Real );
Standard_Real Sqrt (const Standard_Real );

RealSmall Returns the smallest positive real

Standard_Real RealSmall()

Abs Returns the absolute value of a real

Standard_Real Abs(const Standard_Real Value)

IsEqual Returns Standard_True if two reals are equal-

Standard_Boolean IsEqual (const Standard_Real Value1,


const Standard_Real Value2)

IsSimilar Returns Standard_True if two reals are equal

Standard_Boolean IsSimilar(const Standard_Real One,


const Standard_Real Two)

RealDigit Returns the number of digits of precision in a real

Standard_Integer RealDigits()

RealEpsilon Returns the minimum positive real such that 1.0 + x is not equal to 1.0

Standard_Real RealEpsilon()

RealFirst Returns the minimum negative value of a real

Standard_Real RealFirst()

RealFirst10Exp Returns the minimum value of exponent(base 10) of a real.

Standard_Integer RealFirst10Exp()

RealLast Returns the maximum value of a real

Standard_Real RealLast()

page-308
29 Coding guidance | Caesam SDK

RealLast10Exp Returns the maximum value of exponent(base 10) of a real.

Standard_Integer RealLast10Exp()

RealMantissa Returns the size in bits of the matissa part of a real.

Standard_Integer RealMantissa()

RealRadix Returns the radix of exponent representation

Standard_Integer RealRadix()

RealSize Returns the size in bits of an integer

Standard_Integer RealSize()

IntToReal Converts an integer to a real

Standard_Real IntToReal(const Standard_Integer Value)

ATan Returns the value of the arc tangent of a real

Standard_Real ATan(const Standard_Real Value)

Ceiling Returns the smallest integer not less than a real

Standard_Real Ceiling (const Standard_Real Value)

Cos Returns the cosine of a real

Standard_Real Cos (const Standard_Real Value)

Cosh Returns the hyperbolic cosine of a real

Standard_Real Cosh (const Standard_Real Value)

Epsilon Returns a real + the smallest real positive value

Standard_Real Epsilon (const Standard_Real Value)

Exp Returns the exponential function of a real

Standard_Real Exp (const Standard_Real Value)

Floor Return the largest integer not greater than a real

Standard_Real Floor (const Standard_Real Value)

page-309
Caesam SDK | 29 Coding guidance

IntegerPart Returns the integer part of a real

Standard_Real IntegerPart (const Standard_Real Value)

Log10 Returns the base-10 logarithm of a real

Standard_Real Log10 (const Standard_Real Value)

Max Returns the maximum value of two reals

Standard_Real Max (const Standard_Real Val1,


const Standard_Real Val2)

Min Returns the minimum value of two reals

Standard_Real Min (const Standard_Real Val1,


const Standard_Real Val2)

Pow Returns a real to a given power

Standard_Real Pow (const Standard_Real Value, const


Standard_Real P)

RealPart Returns the fractional part of a real.

Standard_Real RealPart (const Standard_Real Value)

RealToInt Returns the integer part of a real (in an integer)

Standard_Integer RealToInt (const Standard_Real Value)

Round Returns the nearest integer of a real

Standard_Real Round (const Standard_Real Value)

Sin Returns the sine of a real

Standard_Real Sin (const Standard_Real Value)

Sinh Returns the hyperbolic sine of a real

Standard_Real Sinh(const Standard_Real Value)

ASinh Returns the hyperbolic arc sine of a real

Standard_Real ASinh(const Standard_Real Value)

page-310
29 Coding guidance | Caesam SDK

Square Returns a real to the power 2

Standard_Real Square(const Standard_Real Value)

Tan Returns the tangent of a real

Standard_Real Tan (const Standard_Real Value)

Tanh Returns the hyperbolic tangent of a real

Standard_Real Tanh (const Standard_Real Value)

Standard_Integer is equivalent to int

In Standard_Integer.hxx include file (Standard_Integer is equivalent to int)

Standard_Integer CharToInt (const Standard_Character me);


Standard_Integer CharToInt (const Standard_CString me);

Abs Returns the absolute value of an Integer

Standard_Integer Abs (const Standard_Integer Value)

Hascode Computes a hascoding value for a given Integer

Standard_Integer HashCode(const Standard_Integer me,


const Standard_Integer Upper)

IsEqual Returns Standard_True if two integers are equal

Standard_Boolean IsEqual(const Standard_Integer One,


const Standard_Integer Two)

IsSimilar Returns Standard_True if two integers are equal

Standard_Boolean IsSimilar (const Standard_Integer One,


const Standard_Integer Two)

IsEven Returns Standard_True if an integer is even

Standard_Boolean IsEven (const Standard_Integer Value)

IsOdd Returns Standard_True if an integer is odd

Standard_Boolean IsOdd (const Standard_Integer Value)

Max Returns the maximum integer between two integers

Standard_Integer Max (const Standard_Integer Val1,


const Standard_Integer Val2)

page-311
Caesam SDK | 29 Coding guidance

Min Returns the minimum integer between two integers

Standard_Integer Min (const Standard_Integer Val1,


const Standard_Integer Val2)

Modulus Returns the remainder of division between two integers

Standard_Integer Modulus (const Standard_Integer Value,


const Standard_Integer Divisor)

Square Returns the square of an integer

Standard_Integer Square(const Standard_Integer Value)

IntegerFirst Returns the minimum value of an integer

Standard_Integer IntegerFirst()

IntegerLast Returns the maximum value of an integer

Standard_Integer IntegerLast()

IntegerSize Returns the size in digits of an integer

Standard_Integer IntegerSize()

29.5 Layouts
Advice to authors about layout managers
There are some missing features in the default swing layouts; for example, Swing does not provide a
Vertical Layout Manager. Caesam authors must use the most adapted layouts in order to create Editors.
Three layout managers published in Caesam API are described here that can be used to improve EO
editors: the VerticalLayout the TwoColumnLayout and the TableLayout.

VerticalLayout

The VerticalLayout is a simple layout that adds component from top to bottom, one component on each
row. The component takes its preferred height but occupies the complete width. This component must be
used when one want add multiple tables or fields instead of using a FlowLayout.

page-312
29 Coding guidance | Caesam SDK

Figure 18: Vertical layout description

TableLayout

The table layout manager is a table-like layout manager. A double array defines the number and the width
of each row of a table. The width of each column is defined proportionally from the double array given
to the constructor (the width of a column equals the ratio of the width of a column to the sum of the width
of all columns). For example, the following container:

JPanel contentPanel = new JPanel(new TableLayout(new


double[]{30.,40.,78.},14,1));
f.getContentPane().add(contentPanel);

contentPanel.add(new JLabel("Column 30."));


contentPanel.add(new JLabel("Column 40. "));
contentPanel.add(new JLabel("Column 78."));

contentPanel.add(new JLabel("Un long test"));


contentPanel.add(new JTextField("contenu du test"));
contentPanel.add(new JTextField("contenu du test 3"));

contentPanel.add(new JLabel("Un long test"));


contentPanel.add(new JTextField("contenu du test"));
contentPanel.add(new JTextField("contenu du test 3"));

produces the following result:

Figure 19: Example of table layout

TwoColumnLayout

The two column layout adds components in a 2-column-table. It is a particular case of the TableLayout
that has been implemented for speed reasons. If the number of component is odd the behaviour is
undefinedOB.

page-313
Caesam SDK | 30 Caesam object interfaces

30 Caesam object interfaces


The main goal of the object interfaces is to offer the possibility of accessing the content of an object
through different sets of API. (i.e. a general use interface, several GUI interfaces, one for
importing/exporting from Excel, a reporting interface, …).
An interface resembles a class, with the particularity that its member values are not actually stored in the
instance, but they are computed or retrieved from an external source on the fly via accessors and mutators.
Interfaces can be use in the following cases:
• When the value of a member needs to be computed from other non-constant values. We could have a
member Area with a ComputeArea getter method which would compute it when
GetInterfaceMember(“Area”) is invoked.
• When the value of a member is stored outside the model and it needs to be obtained on-demand (like
a material in a database or some engineering value in an external file).
• When the content of an object needs to be viewed from different perspectives (object viewers, editors,
reporting, …)

30.1 Defining an interface


Just like a class declaration, interfaces can be declared in typedesc files or in C++, and they consists in a
name, an ancestor class and a list of members and methods. In addition, an interface declaration must also
specify the name of the interfaced class and the getter and setter methods for its members.
Example:

<Interface Name="MaterialInterface" InterfacedClass="Material"


Inherits="Caesam_InterfaceObject">
<Method Name="GetPoissonValue" Type="Python"
Location="csm:com.samcef.caesam.test.interfaces
/python/MaterialInterfaceMethods" />
<Method Name="SetPoissonValue" Type="Python"
Location="csm:com.samcef.caesam.test.interfaces
/python/MaterialInterfaceMethods" />
<Member Name="PoissonValue" Type="Caesam_Double"
Getter="@GetPoissonValue" Setter="@SetPoissonValue" />
</Interface>

The interface descriptor

As show in the previous example, an interface declaration starts with an <Interface> tag which can have
the following attributes:
Table 32: Attributes of the <interface> tag

Attribute Description

Name: [required] The name of the interface. This name must be unique for the same interfaced
class, but it can repeat among different interfaced classes.
InterfacedClass: The name of the class to which this interface is attached. An interface can be
[required] defined on any registered class with the constraint that this class should be
declared before being used in the interface declaration
Inherits: An interface must always inherit from Caesam_InterfaceObject or from one
of the pre-defined interface types.
• Caesam_APIInterface:

page-314
30 Caesam object interfaces | Caesam SDK

Attribute Description

general purpose, gives access to the internal data of the object in a different
manner
• Caesam_GUIInterface:
an interface used by the GUI to display data of an object in different forms
(equivalent to the perspectives).
• Caesam_StorageInterface:
an interface that can be used to persist the data of an object under a
different structure (we could imagine subclasses like
Caesam_ExcelInterface, …).
• Caesam_UserInterface:
a user defined interface

Other more specialized pre-defined interfaces like Caesam_TableInterface could be envisioned in the
future.

The interface member descriptor

An interface member declaration is composed of a name and two methods (a getter and a setter): one that
retrieves a desired value and the other that changes it. The accepted syntax for these method declarations
is:

@[ClassName.]MethodName([ArgumentType:]'ArgumentValue', ...)

• A getter or setter declaration must always start with the '@' symbol.
• ClassName: the name of the class to which the method belongs. This part of the declaration is optional.
If the class name is not specified, the MethodName refers to a method of the interface class.
• MethodName:[required] the name of the registered method.
• ArgumentType: the declaration can contain one or more static arguments which are sent to the method
when it is invoked. If the argument type is not specified, Caesam_String is used by default. These
arguments can be obtained as an object array by calling the
Caesam_InterfaceMember::GetGetterArgument. Note that the setters will always receive the value in
the first position of the array and then the static arguments.
• ArgumentValue: argument values must always be enclosed in simple quotes. Although they are static,
these values are passed to the method every time it is called.
In the following example we have a GetPoissonValue method which returns the value from the member
poisson and SetPoissonValue which sets this value.

<Interface Name="MaterialInterface" InterfacedClass="Material"


Inherits="Caesam_InterfaceObject">
<Method Name="GetPoissonValue" Type="Python"
Location="csm:com.samcef.caesam.test.interfaces
/python/MaterialInterfaceMethods" />
<Method Name="SetPoissonValue" Type="Python"
Location="csm:com.samcef.caesam.test.interfaces
/python/MaterialInterfaceMethods" />
<Member Name="PoissonValue" Type="Caesam_Double"
Getter="@GetPoissonValue" Setter="@SetPoissonValue" />
</Interface>

The getter and setter methods

The getters and setters are registered methods that can be implemented in C++, Java, Python or Fortran.
These methods receive the interfaced object as the first argument and an array of parameters as the second

page-315
Caesam SDK | 30 Caesam object interfaces

argument. This array contains the parameters declared in the interface descriptor in the order of the
declaration. When registered as a setter, the first item of the array will contain the value to set.

def GetPoissonValue(theMaterial, theArgumentList):


#print "MaterialInterfaceMethods.py:GetPoissonValue()"
try:
return Caesam_Double(theMaterial.GetMember("poisson").GetValue())
except Exception, ex:
print traceback.format_exc()
print '%%%ERROR: MaterialInterfaceMethods.py:exception occured :' + str(ex)

return None

def SetPoissonValue(theMaterial, theArgumentList):


#print "MaterialInterfaceMethods.py:SetPoissonValue()"
try:
# theArgumentList is an object array containing the arguments declared
# in the typedesc and the value in the first position
theMaterial.SetMember("poisson",
CaesamQty_DIMENSIONLESS(theArgumentList.Get(0).GetValue())
return None
except Exception, ex:
print traceback.format_exc()
print '%%%ERROR: MaterialInterfaceMethods.py:exception occured : ' + str(ex)

return None

Pre-defined getter / setter methods

Caesam provides some pre-defined access methods which can be reused by authors in their interface
definitions.
• GetByPath(theInstance, thePath) : retrieves the value located at thePath in the model. If the path
doesn’t start by an element separator it means the path is relative to the object on which the interface
is invoked.
• SetByPath(theInstance, thePath, aValue) : sets the value located at thePath in the model
In the following example, instead of using GetPoissonValue and SetPoissonValue as show previously,
we use the predefined GetByPath and SetByPath methods (which in this example have the same effect):

<Interface Name="MaterialInterface" InterfacedClass="Material"


Inherits="Caesam_InterfaceObject">
<Member Name="PoissonValue" Type="Caesam_Double"
Getter=”@Caesam_InterfaceObject.GetByPath('poisson')
Setter=”@Caesam_Interface.SetByPath('poisson') />
</Interface>

Declaring an interface in C++

TBD

30.2 Using interfaces

API for getting the available interfaces of a class/object

Table 33:

Caesam_Class: AddInterface(me: mutable; theInterface: Interface from Caesam) returns


Boolean from Standard;

page-316
30 Caesam object interfaces | Caesam SDK

Purpose: Adds an interface to the class. Raises an exception if the class already has an
inteface with that name.
EXPORT:
Level: Public

Table 34:

Caesam_Class: HasInterface(me; theInterfaceName: String from STL) returns Boolean from


Standard;
Purpose: Returns true the class has an interface with that name
EXPORT:
Level: Public

Table 35:

Caesam_Class: GetInterface(me; theInterfaceName: String from STL) returns Interface from


Caesam;
Purpose: Returns an interface by its name
EXPORT:
Level: Public

Table 36:

Caesam_Class: GetInterfaces(me:mutable) returns StlInterfaceMap from Caesam;


C++: return &
Purpose: Returns the map of interfaces
EXPORT:
Level: Public

Table 37:

Caesam_Class: GetInterfaceNames(me) returns StringArray from Caesam;


Purpose: Returns an array containing the names of the interfaces of this class
EXPORT:
Level: Public

page-317
Caesam SDK | 30 Caesam object interfaces

Manipulating interface members via Get/SetInterfaceMember

Table 38:

Caesam_Class: GetInterfaceMember(me:mutable;
theInterfaceName: String from STL;
theMemberName: String from STL)
returns Object from Caesam;
Purpose: Returns the value of a member of an interface defined on this object.
theInterfaceName: the name of the selected interface
theMemberName: the name of member of the interface get

EXPORT:
Level: Public

Table 39:

Caesam_Class: SetInterfaceMember(me:mutable;
theInterfaceName: String from STL;
theMemberName: String from STL)
theMemberValue: Object from Caesam)
returns Boolean from Standard
Purpose: Sets the value of a member of an interface defined on this object
theInterfaceName: the name of the selected interface
theMemberName: the name of member of the interface to set
theMemberValue: the object passed to the setter of the member

EXPORT:
Level: Public

Caesam_Class:
Purpose:
EXPORT:
Level:

Example:

#Initialize an instance of Material. This will be the interfaced object


Material = aApp.NewObject("Material")
aMaterial.SetMember("poisson", CaesamQty_DIMENSIONLESS(0.001))
aMaterial.SetMember("young", CaesamQty_PRESSURE(0.002))
aMaterial.SetMember("elasticlimit", CaesamQty_PRESSURE(0.777))

print "Initial values of the Material"


print " PoissonValue: " + str(aMaterial.GetMember("poisson").GetValue())
print " YoungValue: " + str(aMaterial.GetMember("young").GetValue())
print " ElasticLimitValue: " +
str(aMaterial.GetMember("elasticlimit").GetValue())

# Using SetInterfaceMember and GetInterfaceMember

page-318
30 Caesam object interfaces | Caesam SDK

print "Set the value of the poisson member via the


MaterialInterface::SetPoissonValue interface: 0.111"
aMaterial.SetInterfaceMember("MaterialInterface", "PoissonValue",
Caesam_Double(0.111))
print "PoissonValue: " + str(aMaterial.GetInterfaceMember("MaterialInterface",
"PoissonValue").GetValue())

Accessing a member of an interface via a path

On the interfaced object call Find with a path to the interface member that you want to access. The name
of the interface must be prefixed with a ':' symbol (e.g. “:MaterialInterface/PoissonValue”).

# Using Caesam_Object.Find(aPath)
print "Get the value of the members via
Caesam_Object.Find(:MaterialInterface/PoissonValue)"
print "PoissonValue: " +
str(aMaterial.Find(":MaterialInterface/PoissonValue").GetValue())

Creating an instance of the interface

By creating an instance of interface, it is possible to access its members with the standard Get/SetMember
methods. Note that this may be slower than calling Get/SetInterfaceMember directly on the interfaced
object, but it benefits from all the Caesam_Object services (the "interface object" may be saved to a file
or edited using a Caesam editor).
For creating instances of an interface, two Caesam_Object methods are available:
Table 40:

Caesam_Class: NewInterfaceObject(me;
theInterface: Interface from Caesam)
returns InterfaceObject from Caesam;
Purpose: This method creates an instance of an interface class (a
Caesam_InterfaceObject) that was registered for this type. Also it sets the
interfaced object to This
EXPORT:
Level: Public

Table 41:

Caesam_Class: NewInterfaceObject(me;
theInterfaceName: String from STL)
returns InterfaceObject from Caesam;
Purpose: This method creates an instance of an interface class (a
Caesam_InterfaceObject) that was registered for this type. Also it sets the
interfaced object to This.
EXPORT:
FORTRAN: NewInterfaceObject_Name
Level: Public

page-319
Caesam SDK | 30 Caesam object interfaces

Example:

# Create an instance of the interface from the Material object


aMaterialInterface = aMaterial.NewInterfaceObject("MaterialInterface")
if(aMaterialInterface == None):
print "TestMaterialInterface.py: Material does not have an interface named
MaterialInterface"
else:
print "Set the value of the poisson member via MaterialInterface::SetMember
interface:"
print "PoissonValue: 0.123"
aMaterialInterface.SetMember("PoissonValue", Caesam_Double(0.123))
print "Poisson member value obtained by calling MaterialInterface::GetMember
on the interface object:"
print " PoissonValue: " +
str(aMaterialInterface.GetMember("PoissonValue").GetValue())

page-320
31 Updating Caesam objects | Caesam SDK

31 Updating Caesam objects


This section discusses several different techniques for detecting object changes and updating objects.
Updating an object refers to computing one or more members whose values may depend on other member
values (i.e. a member Panel.Surface that is computed from Panel.length and Panel.width).
Techniques for objects updating are :
• Interface members : The value of a member can be computed in the getter method of the member
either every time the member is accessed or only when the object has been modified.
• Interceptor methods : An author can register a custom OnMemberChanged handler method that
updates the value of one or more members.
• The Update method : The Update method of Caesam_Object checks if the objects have been modified
and then calls a user-defined registered Update method.
• The IsModified flag : Using the IsModified flag to decide when an object needs to be updated and
compute only those members that are needed.

31.1 Computing the value of a member in a getter method


Starting with Caesam 5.3.1 Caesam allows the definition of getter and setter methods for the members of
a class. These methods can be used to perform custom actions when a member is being accessed or
modified. The following examples show how the value of member can be computed at the moment it is
being accessed.

The member is computed every time it is accessed

In the following example we create a StackingSequence class which has several plies. We also want a
member thickness that returns the total thickness of the stacking (the sum of the thicknesses of its plies).
We want to make sure that if the thickness of one of the plies changes, the total thickness is updated.
This can be accomplished through the definition of a member "thickness" with the following features:
• is an interface member:
it has a getter which computes it when GetMember is called
• is flagged READ_ONLY:
only the GetThickness method can change its value, not the user
• is flagged TRANSIENT:
since it is computed on the fly, it makes no sense to persist its value

<TypeDesc Name="StackingSequence" Inherits="CaesamStd_EO" >


<Member Name="plies" Type="Caesam_TypedTable" />
<Method Name="GetThickness" Type="Python"
Location="csm:com.samcef.caesam.test.transverse
/python/StackingSequenceMethods"/>
<Method Name="SetThickness" Type="Python"
Location="csm:com.samcef.caesam.test.transverse
/python/StackingSequenceMethods"/>
<Member Name="thickness" Getter="@GetThickness"
Setter="@SetThickness" Type="CaesamQty_LENGTH"
MemberFlags="READ_ONLY|TRANSIENT" />
</TypeDesc>

The getter method implementation

def GetThickness(theStackingSequence, theEmptyArg):


print "StackingSequence::GetThickness"
aTotalThicknessQty = None

page-321
Caesam SDK | 31 Updating Caesam objects

aPlies = theStackingSequence.GetMember("plies")
if (aPlies != None and aPlies.GetRowCount() > 0):
# accumulate the total thickness in a variable
aTotalThickness = 0
for i in range(aPlies.GetRowCount()):
aTotalThickness = aTotalThickness + aPlies.GetQuantityItem(i, "thickness")

# create a new CaesamQty object to store the total thickness.


# We create a clone of an item in order to have the same (if any) GUI units,

# min and max fields as those in the table.


aTotalThicknessQty = aPlies.GetItem(0,
aPlies.GetColumnIndex("thickness")).Clone()
aTotalThicknessQty.SetValue(aTotalThickness)
return aTotalThicknessQty
def SetThickness(theStackingSequence, theEmptyArg):
# thickness is computed on the fly
return NULL

Note: that aStackingSequence.GetMember("thickness") will re-compute the


member every time it is called, which can lead to performance issues. Therefore this method
is not appropriate when the computation of member's value is CPU intensive. See the
section "The member is computed only if the object it depends on has been changed" below
for an alternative solution.

The member is computed only if the object it depends on has been changed

In this example we define an interface member "surface" (an interface member has a getter that is invoked
by GetMember). But in this case we do not want to compute the surface on every call, therefore we need
a secondary private member named computed_surface which will store the intermediary value of the
surface. The getter of the surface member will update the private member if the length or the width
changed.

<!-- In the typedesc definition of the class -->


<TypeDesc Name="PanelGeometry" Inherits="CaesamStd_EO" >
<!-- Declare the getter method that will be called when the member is
accessed.-->
<Method Name="GetSurface" Type="Python"
Location="csm:com.samcef.caesam.test.transverse
/python/PanelGeometryMethods"/>
<Method Name="SetSurface" Type="Python"
Location="csm:com.samcef.caesam.test.transverse
/python/PanelGeometryMethods"/>
<Member Name="length" Type="CaesamQty_LENGTH" />
<Member Name="width" Type="CaesamQty_LENGTH" />
<!-- Declare the surface member. Since this member is computed we can flag it
as read only in order to inform users that modifying it would have no effect
and transient that should instruct Caesam not be saved it.-->
<Member Name="surface" Getter="@GetSurface"
Setter="@SetSurface" Type="CaesamQty_AREA" MemberFlags="READ_ONLY|TRANSIENT"
/>
<!-- Now we declare the private surface member that will store the actual value
-->
<Member Name="computed_surface" Type="CaesamQty_AREA" MemberFlags="PRIVATE"
/>
</TypeDesc>

In the implementation of the getter we use the Caesam_Object::IsModified method to check if the panel
geometry object has changed. If it did, we re-compute the surface and store it in the private member.

Note: that the IsModified flag is set by Caesam when a member, item or value of the object
has been changed via a SetMember, Put, Append, Set or SetValue method. This flag is

page-322
31 Updating Caesam objects | Caesam SDK

saved together with the object, so that when loaded back, the instance is found in the same
state as before the save.

def GetSurface(thePlateGeometry, theEmptyArg):


print "PlateGeometryMethods.py:GetSurface "
aLength = thePlateGeometry.GetMember("length")
aWidth = thePlateGeometry.GetMember("width")
if(aLength == None or aWidth == None):
return None
aSurfaceQty = thePlateGeometry.GetMember("private_surface")
if(thePlateGeometry.IsModified()):
# the object has been modified, re-compute the surface
if(aSurfaceQty == None):
aSurfaceQty = CaesamQty_AREA(aLength.GetValue() * aWidth.GetValue())
else:
aSurfaceQty.SetValue(aLength.GetValue() * aWidth.GetValue())
# store the new value in the private_surface member
thePlateGeometry.SetInternalMember("private_surface", aSurfaceQty);
# flag thePlateGeometry as not modified so that next time we get here
# we don't compute the private_surface again if the object hasn't changed
# in the mean time.
thePlateGeometry.SetIsModified(False)
return aSurfaceQty
def SetSurface(theStackingSequence, theSurface):
# surface is a computed member, we don't do anything on set
return NULL

31.2 Computing the value of a member while the object is being


modified (OnMemberChanged)
Caesam allows the registration of a custom method that is called when a member of an object changes
(i.e. the SetMember method is invoked). An interceptor method is defined as a standard registered Caesam
method and a resource named OnMemberChanged. A user can define interceptor methods on an entire
class, in wich case it will be called for every member change or on a specific member.

Declaring interceptors on a per member basis

In the following example we declare a PanelGeometry class with three members: length, width and a
surface which is the product of the first two. We want to make sure that the surface is re-computed every
time the length or the width member changes.

<!-- In the typedesc definition of the class -->


<TypeDesc Name="PanelGeometry" Inherits="CaesamStd_EO" >
<!-- Declare the method that will be called when a member changes. This method
will re-compute and set the surface member -->
<Method Name="ComputeSurface" Type="Python"
Location="csm:com.samcef.caesam.test.transverse
/python/PanelGeometryMethods"/>
<!-- Declare the length and width members and through the OnMemberChanged tag
specify the name of the method that should be called when the length or width
changes. -->
<Member Name="length" Type="CaesamQty_LENGTH">
<OnMemberChanged>ComputeSurface</OnMemberChanged>
</Member>
<Member Name="width" Type="CaesamQty_LENGTH">
<OnMemberChanged>ComputeSurface</OnMemberChanged>
</Member>
<!-- Declare the surface member. Since this member is computed we can flag it
as read only in order to inform users that modifying it would have no
effect.-->

page-323
Caesam SDK | 31 Updating Caesam objects

<Member Name="surface" Type="CaesamQty_AREA" MemberFlags="READ_ONLY" />


</TypeDesc>

Declaring an interceptor for an entire class

Instead of having one interceptor for each member we can declare one interceptor for all the members of
the class.

Note: An OnMemberChanged at the class level will be called by every SetMember invoked
on that object. In order to avoid performance problems, the interceptors should always be
defind at member level unless one really needs to handle all the member modifications at
once.

Example:

<!-- In the typedesc definition of the class -->


<TypeDesc Name="PanelGeometry" Inherits="CaesamStd_EO" >
<!-- Declare the method that will be called when any of the member changes.
This method will re-compute and set the surface member -->
<Method Name="ComputeSurface" Type="Python"
Location="csm:com.samcef.caesam.test.transverse
/python/PanelGeometryMethods"/>
<!-- Specify the name of the method to be called when a member changes as a
class resource -->
<OnMemberChanged>ComputeSurface</OnMemberChanged>
<!-- Declare the length and width members -->
<Member Name="length" Type="CaesamQty_LENGTH" />
<Member Name="width" Type="CaesamQty_LENGTH" />
<!-- Declare the surface member. -->
<Member Name="surface" Type="CaesamQty_AREA" MemberFlags="READ_ONLY" />
</TypeDesc>

Implementing the interceptor method

The OnMemberChanged is a registered method that receives the instance as first argument and the name
of the member that has been changed as a second argument. It is up the the user to choose which members
should be handled by this interceptor and how.

Note: that as an alternative to ComputeSurface, we could have defined individual methods


for each member (OnLengthChanged, OnWidthChanged) if the handling logic required it.

Example:

def ComputeSurface(thePanelGeometry, theMemberName):


print "PanelGeometryMethods.py:ComputeSurface: " + theMemberName.GetValue()

if(theMemberName.GetValue() == "length" or theMemberName.GetValue() ==


"width"):
# If the the length or the width member have changed re-compute the surface

aLength = thePanelGeometry.GetMember("length")
aWidth = thePanelGeometry.GetMember("width")
if(aLength != None and aWidth != None):
aSurface = aLength.GetValue() * aWidth.GetValue()
else:
aSurface = 0
# Set the surface member. We need to disable the instance flags in order
to
# set a read-only member, otherwise Caesam would raise an error saying that

page-324
31 Updating Caesam objects | Caesam SDK

# a read-only member cannot be changed.


thePanelGeometry.SetInternalMember("surface", CaesamQty_AREA(aSurface));

31.3 The Update method


At some point during the run-time (i.e. before running an analysis) we may need to compute the value of
a member from the values of other members, but only if the objects that it depends on have changed. We
have shown previously that this can be achieved through a getter or the OnMemberChanged method. The
downside of this technique is that these methods are triggered by Caesam and it makes it difficult to
control the moment when the computation occurs. Therefore, in some case (i.e. when the updating of the
member takes a lot of time) it preferable to compute the member only when it is needed.
For this purpose, Caesam provides the following methods:
• Caesam_Object::Update(theForceUpdate) : Purpose: Update will call a registered method "Update"
if there is one. Authors can define their own Update methods by simply registering them together with
their class. The user defined Update method will be called only if the IsModified flag is set this flag
will be reset on the exit of this method.
• Caesam_Object::IsModified : Purpose: can be used to find out if the instance has been modified.
The IsModified flag can be set or reset directly (SetIsModified) or indirectly by calling one of the
methods:
Caesam_Object::SetMember
Caesam_[Primitive]::SetValue
Caesam_[Primitive]ObjectMap::Put
Caesam_ObjectArray::Append/Set/Remove
• Caesam_Object::SetIsModified(Standard_Boolean theIsModified) : Purpose: changes the state of
the IsModified instance flag
Examples are given in the sections below.

Declaring an Update method

<!-- Defining an Update method on the class -->


<TypeDesc Name="PanelGeometry" Inherits="CaesamStd_EO" >
<!-- Declare the method that will be called by Caesam_Object::Update. This
method will re-compute and set the surface member.-->
<Method Name="Update" Type="Python"
Location="csm:com.samcef.caesam.test.transverse
/python/PanelGeometryMethods"/>
<!-- Declare the length and width members -->
<Member Name="length" Type="CaesamQty_LENGTH" />
<Member Name="width" Type="CaesamQty_LENGTH" />
<!-- Declare the surface member. -->
<Member Name="surface" Type="CaesamQty_AREA" MemberFlags="READ_ONLY" />
</TypeDesc>

Update method implementation

def Update(thePanelGeometry, theEmptyArg):


print "PanelGeometryMethods.py:Update: "
aLength = thePanelGeometry.GetMember("length")
aWidth = thePanelGeometry.GetMember("width")
if(aLength != None and aWidth != None):
aSurface = aLength.GetValue() * aWidth.GetValue()
else:
aSurface = 0

page-325
Caesam SDK | 31 Updating Caesam objects

# Set the surface member. We need to use SetInternalMember in order to


disable
# the instance flags , otherwise Caesam would raise an error saying that
# a read-only member cannot be changed.
thePanelGeometry.SetInternalMember("surface", CaesamQty_AREA(aSurface)

Calling the Update method

It is the user's logic which decides when the update method is called. In the following example we will
update the panel geometry prior to executing the actual code of an analysis.

class PanelAnalysis(Process_Analysis):
def Run(self, theDataSet):
aPanelGeometry = theDataSet.FindEO("EO[PanelGeometry]")
aPanelGeometry.Update()
...

Partial object updates

An alternative to using the Update method (which may compute more members than neccessary) it possible
perform a partial update by using the IsModified flag to see if the object has changed and to compute
only the members that are needed.
Example:

class PanelAnalysis(Process_Analysis):
def Run(self, theDataSet):
aPanelGeometry = theDataSet.FindEO("EO[PanelGeometry]")
# check if the object if the object has been changed
if(aPanelGeometry.IsModified()):
# the object has changed, we recompute the surface and store it in the
member
aPanelGeometry.SetInternalMember("surface",
aPanelGeometry.CallMethod("ComputeSurface"))
# Set the object as not modified so that next time we get here
# we don't compute the surface again if the object hasn't changed
# in the mean time.
aPanelGeometry.SetIsModified(False)

page-326
32 Use of the generation tool for 2D Profile | Caesam SDK

32 Use of the generation tool for 2D Profile


The tool for the generation of profile2D in the plugin “com.samcef.caesam.test.transverse”is in Caesam
in the package: com.samcef.devkit.profile.tools2D

Creating the Data Providers

Data Providers must be created for each kind of profile We must create a class that implements the
IGraphic2DDataProvider interface. This class must treat an instance of EditorData and must translate this
one into a graphical representation using a class that implements IGraphic2DDescriptor.
For example we can take the ProfileTDataProvider class. This one must treat an EditorData that contains
the five following parameters:
• the length of the web,
• the length of the flange,
• the thickness of the web
• the thickness of the flange
• the conge (the concave moulding)
When we affect an EditorData via the setEditorData method to this Data Provider, we initialize the values
of these parameters and we compute all the needed points to represent this ProfileT into the
provideRepresentation method. We follow the same procedure for the Rectangle Profile and the Circle
Profile.
The class Profile2DDelegateManager
The class Profile2DDelegateManager must manage the different kind of Data Providers. When we need
to have a ProfileTDataProvider, we ask it to this class that returns the instance of this class. It’s every
times the same instance.
The class ProfileEOEditor
In the class ProfileEOEditor, we create an instance of ProfileJPanel2D.
When the internal structure of the EditorData changes, we affect the new EditorData to the
IGraphic2DDataProvider asked to the Profile2DDelegateManager for the kind of edited profile.
Finally we set the new data provider to the ProfileJPanel2D instance. When we change a value in the
EditorData, we pass this EditorData to the ProfileJPanel2D to update the displayed representation.
Note: We must specify in the TransverseCpp.typedesc which class implements a kind of profile by setting
the tag.

<TypeDesc Name="ProfileCircle" Implementation="CPP" Inherits="Profile">


. . .
<UserResources Type="Caesam_ObjectMap">
<Item Key="Graphic2DDataProvider"
Type="Caesam_String">
com.samcef.caesam.transverse.profile.ProfileCircleDataProvider
</Item>
</UserResources>
. . .
</TypeDesc>

Building a Profile

This section describes how to build a Profile using the Graphic2DDescriptor into the ProfileTDataProvider
class. Assume that we want to draw a T Profile.

page-327
Caesam SDK | 32 Use of the generation tool for 2D Profile

As seen in the figure above, we have values for the five parameters of such a profile. We must now
translate these five parameters into a set of coordinates that will graphically represent the profile. We will
use a Graphic2DDescriptor to represent the structure of a profile. We compute all the coordinates of the
tops of the figure and we create some points in the Graphic2DDescriptor:
Step 1:
We create the tops of the figure from the down left top.

Point2D aPoint1 = new Point2D.Double(0,height);


Point2D aPoint2 = new Point2D.Double(0,myWeb);
Point2D aPoint3 = new Point2D.Double((myFlanges-myWebThickness)/2,myWeb);
Point2D aPoint4 = new Point2D.Double((myFlanges-myWebThickness)/2,0);
Point2D aPoint5 = new Point2D.Double(width-(myFlanges-myWebThickness)/2,0);
Point2D aPoint6 = new Point2D.Double(width-(myFlanges-myWebThickness)/2,myWeb);
Point2D aPoint7 = new Point2D.Double(width,myWeb);
Point2D aPoint8 = new Point2D.Double(width,height);

Step 2:
We add the tops to the Graphic2DDescriptor with information about the kind of joint between them
(rounded corner…)

myGraphic2DDescriptor.addPoint2D(aPoint1);
myGraphic2DDescriptor.addPoint2D(aPoint2);
myGraphic2DDescriptor.addPoint2D(aPoint3,myConge,myConge);
myGraphic2DDescriptor.addPoint2D(aPoint4);
myGraphic2DDescriptor.addPoint2D(aPoint5);
myGraphic2DDescriptor.addPoint2D(aPoint6,myConge,myConge);
myGraphic2DDescriptor.addPoint2D(aPoint7);
myGraphic2DDescriptor.addPoint2D(aPoint8);

To specify the rounded corners for the Point3 and Point6, we specify the distances between the point and
the previous point and between the point and the next point. So we specify the “conge” for these two
points. A curve is used to connect the two segments.
Step 3:
Add the line comments
Line2DDescriptor aLine1 =
new Line2DDescriptor(aPoint4,aPoint5, "Web Thick.",
Color.blue,Color.black,Profile2DDelegateArrowHelper.LABEL_LINE_WITH_ARROW);
Line2DDescriptor aLine2 =
new Line2DDescriptor(aPoint5,aPoint6, "Web",
Color.blue,Color.black,Profile2DDelegateArrowHelper.LABEL_LINE_WITH_ARROW);
Line2DDescriptor aLine3 =
new Line2DDescriptor(aPoint7,aPoint8, "Flange Thick.",

page-328
32 Use of the generation tool for 2D Profile | Caesam SDK

Color.blue,Color.black,Profile2DDelegateArrowHelper.LABEL_LINE_WITH_ARROW);
Line2DDescriptor aLine4 =
new Line2DDescriptor(aPoint1,aPoint8, "Flange",
Color.blue, Color.black,Profile2DDelegateArrowHelper.LABEL_LINE_WITH_ARROW);
Line2DDescriptor aLine5 =
new Line2DDescriptor(aPoint2,aPoint7,"",Color.black,
Color.black,Profile2DDelegateArrowHelper.TYPE_CUSTOM_LINE_WITHOUT_ARROW);

myGraphic2DDescriptor.addArrow("Line 1", aLine1, Line2DDescriptor.TOP_LINE);


myGraphic2DDescriptor.addArrow("Line 2", aLine2, Line2DDescriptor.RIGHT_LINE);
myGraphic2DDescriptor.addArrow("Line 3", aLine3, Line2DDescriptor.RIGHT_LINE);
myGraphic2DDescriptor.addArrow("Line 4", aLine4, Line2DDescriptor.DOWN_LINE);
myGraphic2DDescriptor.addArrow("Line 5", aLine5, Line2DDescriptor.CENTER_LINE);

To add a line on the figure, we must create an instance of Line2DDescriptor that will represent these lines
on the figure. The first four Line2DDescriptor are the label lines that will show what the parameters
represent. The fifth is the line that will show the base of the web on the profile T. When we add a
Line2DDescriptor we must define the position of the line (the last parameter of the addArrow method)

The Line2DDescriptor class

This class is used to describe a « comment line » on a specific profile. It extends the Java2D Line2D class.
A line can be characterized by:
• A unique String key that identifies the line in a set of lines
• The two points (Point2D) that are the extreme points
• A String label that’s the displayed label on the line
• The colour (class Color) of the line
• The colour (class Color) of the label on the line
• The type of the line
• The location of the line.
The unique String key can be used to retrieve a line in a set of lines and for example to update it.
The Type of the line can be:
• Profile2DDelegateArrowHelper.LABEL_LINE_WITH_ARROW:
A plain line with two arrows on the extreme points.
• Profile2DDelegateArrowHelper.LABEL_LINE_WITHOUT_ARROW:
A plain line without arrow on the extreme points
• Profile2DDelegateArrowHelper.TYPE_CUSTOM_LINE:
A non-plain line with arrows on the extreme points.
• Profile2DDelegateArrowHelper.TYPE_CUSTOM_LINE_WITHOUT_ARROW:
A non-plain line without arrows on the extreme points.
The location of the line can be:
• Line2DDescriptor.CENTER_LINE:
The line will be displayed exactly on the coordinates of the two points.
• Line2DDescriptor.RIGHT_LINE:
The line will be displayed with a translation from left to right on the X axis.
• Line2DDescriptor.LEFT_LINE:
The line will be displayed with a translation from right to left on the X axis.
• Line2DDescriptor.TOP_LINE:
The line will be displayed with a translation from down to up on the Y axis.
• Line2DDescriptor.DOWN_LINE:
The line will be displayed with a translation from up to down on the Y axis.
An example is shown below.

page-329
Caesam SDK | 32 Use of the generation tool for 2D Profile

Web Thick is a top line


Web is a right line
Flange Thick is a right line
Flange is a down line

page-330
33 Parametric design | Caesam SDK

33 Parametric design

Introduction

From version 6.0, CAESAM integrates an important new feature: parametric design capabilities. The
main idea behind parametric design is to allow the user to launch iterative runs. This means that after
having identified some design variables among the wide range of parameters associated with a given task
or analysis, the latter will be run several times, the difference from one run to the next one being some
changes in the values of the design variables. These changes and the successive values of design variables
may be generated either 'a priori' or it can be the output of calling some optimization algorithm driving
the process. In both cases, some design criteria are also identified in the output of the task and in the case
of optimization their values are used to generate the values of the design variables for the next iteration.
In addition to the usual stress model (structural elements, assemblies, analyses ...), a CAESAM session
with parametric design will involve the following components:
• A simulation workflow, that is a list of all analysis instances having to be run. In the current version
the worklow is "flat" in the sense that it is made of independent analyses, without any priority rule or
chaining. Each workflow runs in its own Caesam Configuration (see the Maturity chapter for more
information).
• A set of design variables and a set of design criteria, built upon inspection of all analyses used in the
workflow.
• An iterative engine selected to drive the iterative process and to update the values of the design variables.
In the current version, the only engines available are the parametric study and optimization algorithms
from BOSS quattro.
As usual in CAESAM, authors play an important role by preparing the required material for running
parametric design loops. In this context, they will do an important preliminary work to identify candidates
for design variables among the input parameters of the tasks and symmetrically candidates for design
criteria among their output. Technically speaking, the definition of these candidates will be made through
parametric interfaces, as described below.

33.1 Parametric interfaces


Authors must write parametric interfaces to enable parametric design capabilities. Parametric interfaces
are actually Caesam Interfaces (for an in-depth description of Caesam Interfaces, authors are referred to
the SDK manual).
Three types of objects can have a parametric interface:
• CaesamStd_SE.
You can add an interface to a CaesamStd_SE or CaesamStd_SEA. This is typically to define candidates
for design variables.
• CaesamStd_Operation.
Mainly for results or analyses data.
• CaesamStd_EO.
Should be used when polymorphism is needed (e.g. your SE has a profile that can be of different
types).
To enable the use of a given analysis in a workflow for parametric design, authors must create at least
one such interface that inherits from “CaesamStd_Operation:ParametricInterface” on a
CaesamStd_Operation.

Defining a parametric interface

In CAESAM 6.0, interfaces can be seen has a typed hierarchy that is similar to the hierarchy of the normal
classes. Interfaces are defined in a typedesc file – just like normal classes.

page-331
Caesam SDK | 33 Parametric design

Parametric interfaces can be defined in any plugin, as long as the required plugins are imported. One
possibility, for example, is to create some specific plugins that only contain parametric interfaces which
extend existing analyses (defined in other plugins). Another one is to complete an existing plugin with
the addition of a parametric interface for the analyses defined therein.

Specifying candidates for design variables in an Analysis

The root parametric interface – based on the CaesamStd_Operation objects – is


CaesamStdOperation:ParametricAnalysis. Below is an example of an interface defined on an analysis:

<Interface Name="Simple" InterfacedClass="StiffenedPanel_Analysis"


Inherits="CaesamStd_Operation:ParametricInterface">
<Member Name="alpha" Type="CaesamQty_PLANE_ANGLE">
<Parametric Type="Parametric_Resource" Initial="40"
LowerBound="0" UpperBound="45" ValuePath="EO[Impactor]/alpha"
EOKey="Impactor">
</Parametric>
</Member
</Interface>

The meaning of the different elements of this interface set out in this code are described in more detail
below.
First of all, an interface with a name is created. The name in this case is “Simple” and the importance
of naming interfaces is explained in the section on Naming on page 334. Then the class (StiffenedPanel
Analysis), on which the interface is defined and the inherited interface
(CaesamStdOperation:ParametricInterface) are specified. The choice of the latter depends on
the interfaced class. In the above example, since Stiffened- Panel Analysis inherits from
CaesamStd_Operation, the interface CaesamStd_Operation:ParametricInterface is used.
Next the members are defined. These are the candidates for design variables which will be seen by the
analyst. In practice, members are defined through a “Parametric Resource” in the Parametric tag of the
interface.
The “Parametric Resource” is a type dedicated exclusively to the specification of the properties of the
considered variable/function.

Note: that in the current version of CAESAM the only supported parameter type is Caesam
Quantity (and its sub-types, like CaesamQty_PLANE_ANGLE in the above example).
This however covers the vast majority of design variables and simulation responses.

To define a candidate for a design variable, a value for the ValuePath member must be set. This path
is set relative to the object used for defining the variable (StiffenedPanel_Analysis) in this case.
It is also possible use a Setter and a Getter in an interface. In this case the ValuePath member does not
have to be set.
The EOKey member is optional and used to specify the key of the used EO. This key will be used when
creating the Parametric Configuration. If this EOKey member is not present, the parametric engine will
modify the model directly, not a dedicated configuration of it. It is possible to use EOKey with a
Getter/Setter.
The members Initial (initial value for variable), LowerBound and UpperBound are optional, but it
is recommended to set them because this will help the Analyst to configure a parametric design loop.

Parametric Interfaces and EOs

It is possible to base an interface on an EO.


Defining an interface on a EO should only be done when you want an EO to expose different variables
according to its type. You could use an EO named “Profile” that could be of type “TopHatProfile” or
“TProfile” where the two profiles do not have the same variables.

page-332
33 Parametric design | Caesam SDK

To achieve that, you must, first of all, tell Caesam which EO to take in consideration in an interface defined
on a CaesamStd_SE or CaesamStd_Operation.

<Interface Name="Simple" InterfacedClass="Stiffener"


Inherits="CaesamStd_SE:ParametricInterface" >
<Member Name="Profile" Type="CaesamStd_EO" >
<Parametric Type="Parametric_Resource" EOKey="Profile" ></Parametric>
</Member>
</Interface>

The member has the name of the Key of EO you want to use. Note that this member has a CaesamStd_EO
type.
If an EO can be accessed both by an Analysis and an SE, you should only declare it in one interface. In
such a case, the preferred interface is the SE. When creating the variables, Caesam will look for an interface
defined on the actual EO instance. If needed, the EOKey must be defined in this first interface. Then an
interface should be defined for each possible EO type.

<Interface Name="Simple" InterfacedClass="TProfile"


Inherits="CaesamStd_EO:ParametricInterface" >
<Member Name="A" Type="CaesamQty_LENGTH" >
<Parametric Type="Parametric_Resource" LowerBound="4.57"
UpperBound="63.00" Initial="8.2" ValuePath="A"></Parametric>
</Member>
<Member Name="B" Type="CaesamQty_LENGTH" >
<Parametric Type="Parametric_Resource" LowerBound="6.09"
UpperBound="13.00" Initial="9" ValuePath="B"></Parametric>
</Member>
<Member Name="C" Type="CaesamQty_LENGTH" >
<Parametric Type="Parametric_Resource"
LowerBound="1.02" UpperBound="2.00"
Initial="1.5" ValuePath="C"></Parametric>
</Member>
</Interface>

<Interface Name="Simple" InterfacedClass="TopHatProfile"


Inherits="CaesamStd_EO:ParametricInterface" >
<Member Name="A" Type="CaesamQty_LENGTH" >
<Parametric Type="Parametric_Resource" LowerBound="5.00"
UpperBound="50.80" Initial="8.2" ValuePath="A"></Parametric>
</Member>
<Member Name="B" Type="CaesamQty_LENGTH" >
<Parametric Type="Parametric_Resource" LowerBound="6.00"
UpperBound="16.96" Initial="9" ValuePath="B"></Parametric>
</Member>
</Interface>

You can also use a Getter/Setter in the interface of the EO.


The support used for the EO defined variable will be the SE/Operation on which they are instantiated.
This concludes the description of the technical means to specify candidates for design variable. It must
be stressed that writing such a parametric interface is the only way to declare what can be used as parameters
by Analysts.

Specifying candidates for design criteria in an Analysis

As mentioned above, the candidates for design criteria are identified among the output responses (results)
computed by an analysis. An example of this is shown below:

<Interface Name="Simple" InterfacedClass="StaticPanel"


Inherits="CaesamStd_Operation:ParametricInterface">
<Member Name="MaximumStress" Type="CaesamQty_PRESSURE">
<Parametric Type="Parametric_Resource" Role="Minimize" LowerBound="0.01"
ResultPath="EO[Results]/MaxStress"
</Parametric>

page-333
Caesam SDK | 33 Parametric design

</Member>
</Interface>

The main difference between the definition of a candidate for design variableand a design criteria is that
the parametric resource has a ResultPath member (instead of a ValuePath). This member is mandatory.
You can also use a Getter instead of a ResultPath member. The Members Role, LowerBound and
UpperBound are optional. They are useful solely in the case of optimization, as will be further detailed
in the section on Criteria on page 335.

Global Mass

Every workflow is automatically assigned a GlobalMass criteria with a minimize role. Its value is the
mass of all the SEs used in the workflow.
To be able to use this criteria you must define the Mass method on your SEs. The Mass method takes a
NULL argument and must return a CaesamQty MASS object. It can be implemented using a virtual C++
method or by registering a Caesam method. If one of the SEs involved in a workflow has no Mass method,
the global mass will return a NaN value.
The Mass method can also be defined in the Parametric Interface defined on a SE. In this case, if a Mass
method already exists on the SE the interface method will override it.

Interface naming

As could be seen in the examples above, the interfaces have a name. However “naming” is more than
simply giving a name when it comes to parametric interfaces, as is explained below.

Note: Naming parametric interface allows you to have several parametric interfaces (with
different names) associated with the same analysis. The principle is that the list of candidates
for design variables and design criteria may be different depending on the Analysis objective
or the design stage at which it is used. For instance, if a single interface – named
"PreliminaryDesign" – is created for a given analysis, CAESAM will use this interface and
the Analyst will only have access to the variables and criteria listed in this interface. If in
however there is an additional parametric interface – named "DetailedDesign" – associated
with the same analysis, the Analyst must choose one or the other and will then have access
to the candidates defined in the selected interface.

Note: that the contents of the interfaces associated to the same analysis may overlap.

In other words, a second interface defined for a given analysis may not only be used to change the list of
existing variables or criteria, but it can also introduce new values for default values (variables), role
(criteria) or bounds (both). This therefore allows you to create many different interfaces for the same
analyses. You can thus change the available variables, their default range or set some different criteria.
To increase the list of available variables and/or criteria for parametric design, the easiest way can be to
create a parametric interface that inherits from a previously defined one. Note however that in this case,
the current version of CAESAM does not allow to you redefine a member already defined in the inherited
interface.
Note finally that the various parametric interfaces can be shared between different plugins. A new interface
can be added to a new plugin without interfering with the existing interfaces.

33.2 Reference

Variables

The object used in the Parametric resource can have many members that can be set according to the
targeted use of the interface. In the typedesc file, all member values are written as strings. A list of the
members used for defining candidates for design variables is given below.

page-334
33 Parametric design | Caesam SDK

Name Mandatory Type Description


(internal)

ValuePath Yes(*) String A string representing a path to the data from the object on
which the interface is defined
InitialValue No Double Initial value for used for iterations
LowerBound No Double Lower bound on the value of the variable
UpperBound No Double Upper bound on the value of the variable
EOKey No String The Key of the EO you want to save to the Parametric
Configuration

(*) Can be replaced by a Getter/Setter in the Interface


In the current CAESAM version, lower and upper bounds are only used for optimization, but in future
they will also play a role when a generator for values of design variables will be called (e.g. Monte Carlo,
Design of Experiments).
Candidates for design variables can be created on:
• CaesamStd_SE
• CaesamStd_Operation
When an operation (task or analysis) is selected for parametric design, the algorithm for variable creation
first looks at parametric interfaces defined on the considered operation, then it looks if the associated
CP’s have an interface (with the same name!) defined.
While doing parametric loops, variables are associated with their supports. Supports are used to generate
the unique name of the instance of a variable (e.g.Panel12thickness) and to build tables showing the
evolution of the value of a variable over iterations. It is important to note that these supports can only be
analyses or SEs. To conclude, note that in the current version of CAESAM the different values are written
and read from the CaesamStd_Model, even if they are in the “SharedWorkspace”.

Criteria

Criteria can only be used if the parametric interface is created on a CaesamStd_Operation. The object
used in the Parametric resource can have many members that can be set according to the targeted use of
the interface. In the typedesc file, all member values are written as strings. A list of the members used for
defining candidates for design criteria is given below.

Name Mandatory Type (internal) Description

ResultPath Yes (*) String A string representing a path to the result value
Role No String Used for optimization. Valid values are: Minimize,
Maximize, LowerBound, UpperBound, Interval.
LoadCasePath No String A String representing a Path to the LoadCaseSet of
the analysis
LowerBound No Double A lowerbound used for optimization
UpperBound No Double A upperbound used for optimization

(*) Can be replaced by a Getter/Setter in the Interface


The Role member is used only for optimization. The meaning of the five possible values given in the
above table are listed below. ( f denotes the design criterion under study)
• Minimize: the aim is to find the lowest possible value for f
• Maximize: the aim is to find the largest possible value for f

page-335
Caesam SDK | 33 Parametric design

• LowerBound: the aim is to satisfy the inequality

for a given value of a (lower bound)


• UpperBound: the aim is to satisfy the inequality

for a given value b (upper bound)


• Interval: the aim is to satisfy the inequalities

for given values of a and b

Note: Note that when the role is set to Minimize or Maximize, the LowerBound and
UpperBound fields will be ignored, even though they are still present in the graphical user
interface.

Using Load Cases

Load cases can be exploited in the framework of parametric design, although there are a few restrictions
on their use:
• All analyses used in a “WorkFlow” must have the same loadcases.
• The results should be stored in a "TableResult".
If a result depending on load cases must be used, the LoadCasePath member must be set in the parametric
interface (e.g. LoadCasePath="EO[LoadCases]"). The Result- Path must contain a path to a TableResult.
To specify a column of the TableResult, it is sufficient to prefix it with /LoadCase/[columnname], as
suggested in the example below, where the "RF" column has been selected:

<Interface Name="Simple" InterfacedClass="StaticPanel"


Inherits="CaesamStd_Operation:ParametricInterface">
<Member Name="Rfs" Type="CaesamQty_DIMENSIONLESS">
<Parametric Type="Parametric_Resource" Role="LowerBound"
LoadCasePath="EO[LoadCaseSet]" LowerBound="1.0"
ResultPath="EO[TableResult]/LoadCase/RF"> </Parametric>
</Member>
</Interface>

page-336
34 Step by step Perspective | Caesam SDK

34 Step by step Perspective


A "step-by-step" perspective enables you to create a perspective in which each of the steps required to
complete a task are presented as a number of "tabs" within the user interface. An example of the GUI
representation of a step-by-step perspective is shown in the figure below.

To understand how the step-by-step perspective mechanism works, you can refer to the example plugin:
com.samcef.caesam.test.process.perspective. This example plugin only defines a new perspective.
The plugin.xml file, uses the <Perspectives> tag to define one or several perspectives. The <Properties>
tag allows you to define the path to the following properties files:
• Icons.properties
• Resources.properties

<Resources Type="Caesam_PluginResourceCollection">
<GUI Type="CaesamRes_PluginGUI">
<Perspectives Type="Caesam_ObjectArray">
<Item Type="Caesam_Url">
csm:com.samcef.caesam.test.process.perspective/resources/myPerspective.xml
</Item>
</Perspectives>
<Properties Type="Caesam_Url"> /resources/properties
</Properties>
</GUI>
</Resources>

In the example shown above, the perspective is described in the file "myPerspective.xml". This example
perspective xml file is given below.
Example of perspective xml file
<?xml version="1.0" encoding="UTF-8"?>

<perspective id="PROCESS_STEP_PERSPECTIVE" title="TIT_PERSPECTIVE"


small_icon="ICO_PERSPECTIVE_SMALL" big_icon="ICO_PERSPECTIVE_BIG">

<!--
the tag split collection allows to specify some split_item that can be

page-337
Caesam SDK | 34 Step by step Perspective

used for the gui of the steps.


-->

<split_collection>

<!-- Default UI representation used for this perspective -->


<split_item id="myDefaultSplit" default="true">
<split orientation="HORIZONTAL" dividerpercentage="60">
<split orientation="VERTICAL" dividerpercentage="50">
<panel viewid="CAESAM_FRAME_STEP_MODEL_VIEW"/>
<panel viewid="CAESAM_FRAME_STEP_EDITOR_VIEW"/>
</split>
<panel viewid="CAESAM_FRAME_DISPLAY_VIEW"/>
</split>
</split_item>

<!-- UI Representation used for Material Step -->


<split_item id="myMaterialSplit" default="false">
<split orientation="HORIZONTAL" dividerpercentage="50">
<panel viewid="CAESAM_FRAME_STEP_MODEL_VIEW"/>
<panel viewid="CAESAM_FRAME_STEP_EDITOR_VIEW"/>
</split>
</split_item>

<!-- UI Representation used for the General Information Step -->


<split_item id="myGeneralInfoSplit" default="false">
<split orientation="HORIZONTAL" dividerpercentage="0">
<panel viewid="CAESAM_FRAME_STEP_MODEL_VIEW"/>
<panel viewid="CAESAM_FRAME_STEP_EDITOR_VIEW"/>
</split>
</split_item>

<!-- UI Representation used for the GFEM Split -->


<split_item id="myGFEMSplit" default="true">
<split orientation="HORIZONTAL" dividerpercentage="50">
<panel viewid="CAESAM_FRAME_STEP_EDITOR_VIEW"/>
<panel viewid="CAESAM_FRAME_DISPLAY_VIEW"/>
</split>
</split_item>

</split_collection>

<!--
The tag editorsView allows to specify for some specific component, the
location of the created view for theses components. (The specified views must
be present in the split_item to have a good representation).
-->
<editorsView>
<propertyView>CAESAM_FRAME_STEP_EDITOR_VIEW</propertyView>
<default>CAESAM_FRAME_STEP_EDITOR_VIEW</default>
<cclConsoleOutputEditorView>CAESAM_FRAME_STEP_EDITOR_VIEW</cclConsoleOutputEditorView>
<cclConsoleInputEditorView>CAESAM_FRAME_DISPLAY_VIEW</cclConsoleInputEditorView>
<cclTerminalEditorView>CAESAM_FRAME_STEP_EDITOR_VIEW</cclTerminalEditorView>
<itemEditorView>CAESAM_FRAME_STEP_EDITOR_VIEW</itemEditorView>
<chartEditorView>CAESAM_FRAME_STEP_EDITOR_VIEW</chartEditorView>
<statisticEditorView>CAESAM_FRAME_STEP_EDITOR_VIEW</statisticEditorView>
</editorsView>

<!--
The Tag defaultTypeEditors can be used as a child of the tag perspective
to specify the default editors for some types that will be used for
this perspective.
-->
<defaultTypeEditors>
<defaultEditor type="Panel">Panel SwiXML Editor</defaultEditor>
</defaultTypeEditors>

<!--
Options allows to specify the steps for this perspective
and some other options like the editor view that we want.
-->
<options>

<!--
Steps allows to define the different steps that we want in the
defined perspective.
-->
<!-- STEPS REPRESENTATION -->
<steps representation="tab">

<!-- **** ELEMENT **** -->


<generalStep id="BY_ELEMENT_CMD" title="TIT_STEP_GFEM" icon="ICO_GFEM">
<step id="BY_ELEMENT_CMD" title="TIT_STEP_GFEM" icon="ICO_GFEM">
<toolbar>/toolbars/gfem.xml</toolbar>
<display3D>GFEM</display3D>
<views>STEP_TABLE_VIEW</views>

page-338
34 Step by step Perspective | Caesam SDK

<editors>
<defaultTypeEditors>
<defaultEditor type="CaesamStd_Element">CaesamGFEM_Element</defaultEditor>
</defaultTypeEditors>
</editors>
</step>

<!-- **** CQUAD4Table **** -->


<step id="BY_CQUAD4Table_CMD" title="TIT_STEP_CQUAD4" icon="ICO_CQUAD4" split_id="myGFEMSplit">
<propertyView>HIDDEN</propertyView>
<dataview>BY_LIST_CMD</dataview>
<typefilter>CaesamFEM_CQUAD4Table</typefilter>
<selectionfilter type="type">CaesamFEM_CQUAD4Table</selectionfilter>
<views>STEP_TREE_VIEW</views>
</step>

<!-- **** CRODTable **** -->


<step id="BY_CRODTable_CMD" title="TIT_STEP_CROD" icon="ICO_CROD" split_id="myGFEMSplit">
<propertyView>HIDDEN</propertyView>
<dataview>BY_LIST_CMD</dataview>
<typefilter>CaesamFEM_CRODTable</typefilter>
<selectionfilter type="type">CaesamFEM_CRODTable</selectionfilter>
<views>STEP_TREE_VIEW</views>
</step>
</generalStep>

<!-- **** LOADCASE **** -->


<step id="BY_LOADCASE_CMD" title="TIT_STEP_LOADCASE" icon="ICO_LOADCASE_SMALL">
<propertyView>HIDDEN</propertyView>
<toolbar>/toolbars/loadcases.xml</toolbar>
<views>STEP_TREE_VIEW;STEP_TABLE_VIEW</views>
</step>

<!-- **** MATERIAL **** -->


<step id="BY_MATERIAL_CMD" title="TIT_STEP_MATERIAL" split_id="myMaterialSplit">
<propertyView>HIDDEN</propertyView>
<dataview>BY_EOLIBRARY_CMD</dataview>
<typefilter>Material</typefilter>
<toolbar>/toolbars/eo.xml</toolbar>
<views>STEP_TREE_VIEW;STEP_TABLE_VIEW</views>
<editors>
<tabularEditor>Material:Material</tabularEditor>
</editors>
</step>

<!-- **** TAB GEOMETRY WITH SE (Panel, Stringer , Frame) AND SEA **** -->
<generalStep id="GSTEP_GEOMETRY" title="TIT_STEP_GEOMETRY" icon="ICO_GEOMETRY">

<!-- **** SE **** -->


<step id="BY_SE_CMD" title="TIT_STEP_SE" icon="ICO_SE">
<propertyView>CAESAM_FRAME_STEP_EDITOR_VIEW</propertyView>
<toolbar>/toolbars/se.xml</toolbar>
<views>STEP_TREE_VIEW</views>
<display3D>TOPOLOGY;GFEM</display3D>
<selectionfilter type="type">CurvedPanel</selectionfilter>
</step>

<!-- **** PANEL **** -->


<step id="BY_PANEL_CMD" title="TIT_STEP_PANEL" icon="ICO_PANEL">
<propertyView>CAESAM_FRAME_STEP_EDITOR_VIEW</propertyView>
<dataview>BY_SE_CMD</dataview>
<typefilter>Panel</typefilter>
<views>STEP_TREE_VIEW;STEP_TABLE_VIEW;STEP_FISHTAIL_VIEW</views>
<editors>
<defaultTypeEditors>
<defaultEditor type="Panel">UIPanel</defaultEditor>
</defaultTypeEditors>
<tabularEditor>Panel:UIPanel</tabularEditor>
<fishtailEditor>UIPanelFishTailWorkbook</fishtailEditor>
</editors>
</step>

<!-- **** STRINGER **** -->


<step id="BY_STRINGER_CMD" title="TIT_STEP_STRINGER" icon="ICO_STRINGER">
<dataview>BY_SE_CMD</dataview>
<typefilter>Stringer</typefilter>
<views>STEP_TREE_VIEW;STEP_TABLE_VIEW;STEP_FISHTAIL_VIEW</views>
<editors>
<defaultTypeEditors>
<defaultEditor type="Stringer">UIStringer</defaultEditor>
</defaultTypeEditors>
<tabularEditor>Stringer:UIStringer</tabularEditor>
<fishtailEditor>EOStringerFishTailWorkbook</fishtailEditor>
</editors>
</step>

<!-- **** FRAME **** -->

page-339
Caesam SDK | 34 Step by step Perspective

<step id="BY_FRAME_CMD" title="TIT_STEP_FRAME" icon="ICO_FRAME">


<dataview>BY_SE_CMD</dataview>
<typefilter>Frame</typefilter>
<views>STEP_TREE_VIEW;STEP_TABLE_VIEW</views>
</step>

</generalStep>

<!-- **** SEA **** -->


<step id="BY_SEA_CMD" title="TIT_STEP_SEA" icon="ICO_SEA">
<toolbar>/toolbars/sea.xml</toolbar>
<views>STEP_TREE_VIEW;STEP_TABLE_VIEW</views>
</step>

<!-- **** ANALYSIS **** -->


<step id="BY_ANALYSIS_CMD" title="TIT_STEP_ANALYSIS" icon="ICO_ANALYSIS">
<toolbar>/toolbars/analysis.xml</toolbar>
<views>STEP_TREE_VIEW;STEP_TABLE_VIEW</views>
</step>

<!-- **** RUN **** -->


<step id="BY_RUN_CMD" title="TIT_STEP_RUN" icon="ICO_RUN">
<propertyView>HIDDEN</propertyView>
<toolbar>/toolbars/empty.xml</toolbar>
<views>STEP_TREE_VIEW</views>
</step>

<!-- BY GLOBAL TABLE -->


<step id="BY_GLOBAL_TABLE_CMD" title="TIT_STEP_GLOBAL_TABLE" icon="ICO_TABLE" >
<propertyView>HIDDEN</propertyView>
<views>STEP_TREE_VIEW</views>
<toolbar>/toolbars/globalTables.xml</toolbar>
<display3D>CUSTOM</display3D>
</step>

<!-- WORKBOOK EXAMPLE -->


<step id="BY_WORKBOOK_CMD" title="TIT_STEP_WORKBOOK">
<propertyView>HIDDEN</propertyView>
<dataview>BY_SE_CMD</dataview>
<typefilter>Panel</typefilter>
<views>STEP_TABLE_VIEW</views>
<editors>
<tabularEditor>PanelWorkbook</tabularEditor>
</editors>
</step>

</steps>
</options>

</perspective>

The root element of the perspective xml file is the <perspective> tag. The <perspective> element contains
child elements that describe the different aspects of the perspective. These are:

The <menu> element


The <split_collection> element
The <editorsView> element
The <defaultTypeEditors> element
The <options> element

Each of these elements are described in the sections below.

Important: In this document frequent reference is made to the "id" of a Caesam command.
To view the list of all the available commands, and their "ids" select SDK > Display
Caesam Commands. This will open a window in which all the details of the available
commands are listed.

page-340
34 Step by step Perspective | Caesam SDK

34.1 The <perspective> element


This is the root element.
<perspective id="STEP_PERSPECTIVE" title="TIT_PERSPECTIVE"
small_icon="ICO_PERSPECTIVE_SMALL"
big_icon="ICO_PERSPECTIVE_BIG">

</perspective>

The attributes of the <perspective> elements are listed below:

Table 42: Attributes of the <perspective> elements

Attribute Description

id Defines the identifier of this perspective. The identifier must be unique.

title Defines the name of the perspective. This name will be used in the shortcut
to access to this perspective (button next to the Caesam logo, sub-menu in
the display menu, …). You must specify a key of a resource present in the
file Resource.properties. If the specified key is not found in this file, the key
will be used.

small_icon Defines the small icon that will be associated with this perspective. The value
of this attribute is a key present in the file Icons.properties.

big_icon Defines a big icon that will be associated with this perspective. This can be
used with the shortcut of the perspectives (CTRL+P). The value of this
attribute is a key present in the file Icons.properties

Remark: The icons are located in a sub-directory named “icons” of the properties directory.

34.2 The <menu> element


In the xml file describing the perspective, it is possible to include a <menu>tag that will specify the url
of another xml file that defines a menubar associated with this perspective.
The <menu> tag accepts a attribute path:

<menu path="/menu/menu.xml"/>

Structure of the specified (menu) xml file


The main tag is the <menubar>. The <menubar> contains a number of <menu>, <menuitems> and
<separators> tags. Each of these elements is described in the sections below.

<?xml version="1.0" encoding="UTF-8"?>


<menubar>
<menu order="1" id="MY_PERSPECTIVE_FILE_MENU_VIEW"
label="TIT_MENU_FILE" icon="">
<menuitem order="0" parent="MY_PERSPECTIVE_FILE_MENU_VIEW"
id="SESSION_FILE_NEW" icon="ICO_NEW"/>
<menuitem order="1" parent="MY_PERSPECTIVE_FILE_MENU_VIEW"
id="SESSION_FILE_OPEN" icon="ICO_OPEN"/>
<menuitem order="2" parent=”MY_PERSPECTIVE_FILE_MENU_VIEW"
id="OPEN_RECENT_FILE_VIEW"/>
<menuitem order="3" parent="MY_PERSPECTIVE_FILE_MENU_VIEW"

page-341
Caesam SDK | 34 Step by step Perspective

id="DOCUMENT_FILE_CLOSE" icon="ICO_CLOSE"/>
<separator order="4" />
<menuitem order="5" parent="MY_PERSPECTIVE_FILE_MENU_VIEW"
id="DOCUMENT_FILE_SAVEAS" icon="ICO_SAVEAS"/>
<menuitem order="6" parent="MY_PERSPECTIVE_FILE_MENU_VIEW"
id="DOCUMENT_FILE_SAVE" icon="ICO_SAVE"/>

<separator order="7"/>

<menu order="8" id="MY_PERSPECTIVE_IMPORT_SUBMENU_VIEW"


parent="MY_PERSPECTIVE_FILE_MENU_VIEW"
label="TIT_MENU_IMPORT"
icon="ICO_IMPORT">
<menuitem order="0"
parent="MY_PERSPECTIVE_IMPORT_SUBMENU_VIEW"
id="IMPORT_EO_CMD" icon="ICO_IMPORT_EO"/>

<menuitem order="1"
parent="MY_PERSPECTIVE_IMPORT_SUBMENU_VIEW"
id="IMPORT_SHARED_WORKSPACE_CMD" icon="ICO_IMPORT_SHARED"/>
</menu>

<menu order="9" id="MY_PERSPECTIVE_EXPORT_SUBMENU_VIEW"


parent="MY_PERSPECTIVE_FILE_MENU_VIEW"
label="TIT_MENU_EXPORT"
icon="ICO_EXPORT">
<menuitem order="0"
parent="MY_PERSPECTIVE_EXPORT_SUBMENU_VIEW"
id="EXPORT_EO_CMD" icon="ICO_EXPORT_EO"/>
<menuitem order="1"
parent="MY_PERSPECTIVE_EXPORT_SUBMENU_VIEW"
id="EXPORT_SHARED_WORKSPACE_CMD" icon="ICO_EXPORT_SHARED"/>
</menu>

<separator order="10"/>

<menuitem order="11" parent="MY_PERSPECTIVE_FILE_MENU_VIEW"


id="PAGE_SETUP_CMD" icon="" />
<menuitem order="12" parent="MY_PERSPECTIVE_FILE_MENU_VIEW"
id="PRINT_CMD" icon="ICO_PRINT"/>

<separator order="13" />


<menuitem order="99"
parent="MY_PERSPECTIVE_FILE_MENU_VIEW"
id="SESSION_FILE_QUIT" icon="ICO_QUIT"/>

</menu>

</menubar>

34.2.1 The <menu> in a <menubar>


The <menu> element contains the definition of the contents of a menu: <menuitem> and <separator>.
The possible attributes of <menu> are listed in the table below.

Table 43: Attributes of <menu> element

Attribute Description

order Defines the position of the current menu

page-342
34 Step by step Perspective | Caesam SDK

Attribute Description

id Specifies the id of the menu. Prefix your id by the id of your perspective:


MY_PERSPECTIVE_ID_MY_MENU_ID

label Allows to specify a title for this menu

icon Allows to specify an icon for this menu

mne Allows to specify a mnemonic for this menu

parent Specifies the parent menu (in which the current menu is set).

The <menuitem> element

One <menuitem> tag is required for each of the items that can be clicked in the menu. The possible
attributes of <menuitem> are listed in the table below.
Table 44: Attributes of <menu> element

Attribute Description

order Defines the position of the current menu item in the menu
parent Specify the parent menu (in which the current menuitem is set).
id Specifies the id of the command that will be called when this menu item is
clicked
label Allows to specify a title for this menu item
icon Allows to specify an icon for this menu item
tooltip Allows to specify a tooltip for this menu item
mne Allows to specify a mnemonic for this menu item
keystroke Allows to specify a shortcut for this menu item

The <separator> element

The <separator> is used to draw a horizontal line that divides the menu items into groups.
The attributes of the <separator> are listed below.
Table 45: Attributes of the <separator>

Attribute Description

order Defines the position of the current separator in the current menu

Note: All the labels, icons, tooltips, mnemonics use the resources management system.

page-343
Caesam SDK | 34 Step by step Perspective

If you want to use the menus Display, Result or Window, the following code is required

<menu order="3" id="DISPLAY_MENU_VIEW"/>


<menu order="5" id="RESULT_MENU_VIEW"/>
<menu order="9" id="WINDOW_MENU_VIEW"/>

If you want to use the Open Recent command, the following statement is required:

<menuitem order="2" parent="THE_PARENT_ID" id="OPEN_RECENT_FILE_VIEW"/>

For these 4 specific items the value of the id attribute is fixed.

34.3 The <split_collection> element


The <split_collection> element defines a set of UI representations that can be used in each step of this
perspective. You can see an example of the use of the <split_collection> element below:

<split_collection>
<split_item id="FIRST_SPLIT" default="true">
<split orientation="HORIZONTAL" dividerlocation="750">
<split orientation="VERTICAL" dividerlocation="350">
<panel viewid="CAESAM_FRAME_STEP_MODEL_VIEW"/>
<panel viewid="CAESAM_FRAME_STEP_EDITOR_VIEW"/>
</split>
<panel viewid="CAESAM_FRAME_DISPLAY_VIEW"/>
</split>
</split_item>

<split_item id="LAST_SPLIT" >
<split orientation="HORIZONTAL" dividerlocation="400">
<split orientation="VERTICAL" dividerlocation="220">
<panel viewid="CAESAM_FRAME_STEP_MODEL_VIEW"/>
<panel viewid="CAESAM_FRAME_STEP_EDITOR_VIEW"/>
</split>
</split>
</split_item>
</split_collection>

The <split_collection> element has only the <split_item>as child element.

The <split_item> element

The <split_item> element defines a UI representation. The attributes of the <split_item> element are listed
below:
Table 46: Attributes of the <split_item> element

Attribute Description

id Defines the identifier of this split item. It is mandatory to specify this id if


we want to make reference to this split_item
default Optional attribute that can be equals to “true” or “false”. If true, it means that
this split_item is used as default representation for a step that does not specify
a split_item id. If no <split_item> tag specifies a true value for the default
attribute, the default split is the last one. If several <split_item> tags specify
a true value for the default attribute, it is also the last one that will be used
as default.

The <split_item> element has only the <split> child element.

page-344
34 Step by step Perspective | Caesam SDK

The <split> element

The <split> element defines the organization of the different views (3D View, Editor View, Model View,
…) on the screen. The definition of the split tag is the same of the java swing definition of a JSplitpane.

<split orientation="HORIZONTAL" dividerlocation="750">


<split orientation="VERTICAL" dividerlocation="350">
<panel viewid="CAESAM_FRAME_STEP_MODEL_VIEW"/>
<panel viewid="CAESAM_FRAME_STEP_EDITOR_VIEW"/>
</split>
<panel viewid="CAESAM_FRAME_DISPLAY_VIEW"/>
</split>

The attributes of the <split> element are listed below.


Table 47: Attributes of the <split> element

Attribute Description

orientation defines the orientation of the split: HORIZONTAL or VERTICAL


dividerlocation defines the location of the divider used in the JSplitPane (in pixels).
dividerpercentage defines the location of the divider used in the JSplitPane (in percentage
between 0 and 100).

Child elements of the <split> element

The <split> element can have the following child elements.


<split> allows the possibility of a recursive architecture
<panel> defines the structure of a particular panel.
<panel viewid="CAESAM_FRAME_DISPLAY_VIEW"/>

It is necessary to define what (i.e. which view) will be located in a specific panel.
To do this, the <panel> tag accepts the attribute "viewid" which specifies the unique
identifier of the Caesam view that will be located in this panel.
In a step perspective, only the following views can be used:
• CAESAM_FRAME_DISPLAY_VIEW
• CAESAM_FRAME_STEP_MODEL_VIEW
• CAESAM_FRAME_STEP_EDITOR_VIEW
as illustrated below.

page-345
Caesam SDK | 34 Step by step Perspective

34.4 The <editorsView> element


This element specifies which views can be used to create new tabs.

<editorsView>
<propertyView>CAESAM_FRAME_EDITOR_VIEW</propertyView>
<default>CAESAM_FRAME_EDITOR_VIEW</default>
<cclConsoleOutputEditorView>
CAESAM_FRAME_TREE_VIEW
</cclConsoleOutputEditorView>
<cclConsoleInputEditorView>
CAESAM_FRAME_DISPLAY_VIEW
</cclConsoleInputEditorView>
<cclTerminalEditorView>
CAESAM_FRAME_PROPERTY_VIEW
</cclTerminalEditorView>
<itemEditorView>CAESAM_FRAME_TREE_VIEW</itemEditorView>
<chartEditorView>CAESAM_FRAME_PROPERTY_VIEW</chartEditorView>
<statisticEditorView>CAESAM_FRAME_EDITOR_VIEW</statisticEditorView>
</editorsView>

The following child elements are accepted:


• propertyView : the default view used for the property view in this perspective
• default : the default view used to create a new tab
• cclConsoleOutputEditorView : the default view used to keep the tab of the output CCL console.
• cclConsoleInputEditorView : the default view used to keep the tab of the input CCL console.
• cclTerminalEditorView : the default view used to keep the tab of the CCL terminal
• itemEditorView : the default view used to keep the tab used to edit an item in a separated tab
• chartEditorView : the default view used to keep the tab to create a chart
• statisticEditorView : the default view used to keep the tab to display the statistics.
This element and all the its child elements are optional.

page-346
34 Step by step Perspective | Caesam SDK

If the tag default is not specified, the default view will be CAESAM_FRAME_EDITOR_VIEW. If a
child tag other than default is not present, the value of the default tag is used for this child tag.

34.5 The <defaultTypeEditors> element


The <defaultTypeEditors> element allows to define the default editor the will be used for a specific type
of Caesam_Object. It's done by type of object with the tag <defaultEditor>. For example, you can choose
the SwiXml editor by default, or a Java made editor, or a tabular editor, ...

<defaultTypeEditors>
<defaultEditor type="Panel">Panel SwiXML Editor</defaultEditor>
</defaultTypeEditors>

In this case, for the perspective, we select the SwiXml editor named 'Panel SwiXml Editor' as the default
editor for the type 'Panel'. But if you want to use the editor generated by the CCL Command 'UIPanel'
you can write the following lines.

<defaultTypeEditors>
<defaultEditor type="Panel">UIPanel</defaultEditor>
</defaultTypeEditors>

And if you want the tabular editor generated by this command, it's possible by adding ':TABULAR' at
the end of the specified editor.

<defaultTypeEditors>
<defaultEditor type="Panel">UIPanel:TABULAR</defaultEditor>
</defaultTypeEditors>

34.6 The <options> element


The <options> element contains child elements that define the structure of the perspective

The <steps> element

The <steps> element contains all the steps that will be present in the created perspective.
<steps representation="tab">
<step id= ....
</step>
<step id= ....
</step>
<generalStep id= ....
</generalStep>
</steps>

The <steps> element has one attribute :


Table 48: Attribute of the <steps> element

Attribute Description Values

representation defines the UI "tab": this is the default value and means that each
representation of all the step appears in a labeled tab as shown in the figure
steps

page-347
Caesam SDK | 34 Step by step Perspective

Attribute Description Values

above. In addition a toolbar appears for each step


below the row of tabs.
"button": this value should be used when the
toolbar is not required.

The <steps> element has the following child elements, both of which are described below.
- the <step> element
- the <generalStep> element

34.6.1 The <step> element


The <step>element defines a particular step. An example of a <step> is given below.
<step id="BY_RESULT_GLOBAL_TABLE_CMD" icon="ICO_RESULT"
title="TIT_STEP_RESULT" split_id="FIRST_SPLIT">
<userfilter>Result*</userfilter>
<views>STEP_TREE_VIEW;STEP_FISHTAIL_VIEW</views>
</step>

The <step> element has the following attributes:

Table 49: Attributes of the <step> element

Attribute Description

id the unique identifier for this step in this perspective

icon the associated icon for this step (key of an icon


present in the Icons.properties file)

tooltip the associated tooltip for this step (key of a label


present in the Resources.properties file)

title the title of this step (key of a resource present in


the Resource.properties file).

split_id optional, it allows to specify the UI representation


for this step by reference to a split_item defined in
the split_collection tag. If this attribute is not
specified, the default split is used for this step.

The <step> element has the following child elements.

<dataview>

In Caesam, there is a set of predefined dataviews.

page-348
34 Step by step Perspective | Caesam SDK

For each dataview, there is an id:


• By List : BY_LIST_CMD
• By SE : BY_SE_CMD
• By SEA : BY_SEA_CMD
• By Analysis : BY_ANALYSIS_CMD
• By Element : BY_ELEMENT_CMD
• By Run : BY_RUN_CMD
• By EO : BY_EOLIBRARY_CMD
• By LoadCase : BY_LOADCASE_CMD
• By Global Table : BY_GLOBAL_TABLE_CMD
• By Hierarchy : BY_HIERARCHY_CMD
• By Group : BY_GROUP_CMD
• By Package : BY_PACKAGE_CMD
• By Configuration : BY_CONFIGURATION_CMD
So, if you want a step that has the same behaviour than the "By SE", you can create a step with the
id="BY_SE_CMD".
More precisely, if you want a step that has the same behaviour than the “BY_SE” but only for the Panel,
you can use the <dataview> element with the <typefilter> element as shown below:

<!-- PANEL -->


<step id="STEP_PANEL_ID " title="TIT_STEP_BY_PANEL" icon="ICO_PANEL">
<dataview>BY_SE_CMD</dataview>
<typefilter>CurvedPanel</typefilter>
<toolbar>/toolbars/panel.xml</toolbar>
</step>

Attention: the value of the attribute id of a step must be UNIQUE in the perspective.

If you create a new id like as in the example above, you can see that this new dataview appears in the
following combobox:
To avoid having clashes between the created dataviews, the id of the commands has the following structure
: PerspectiveId + “_” + StepId.

<views>

This defines the available views for this step; there are three values:
STEP_TREE_VIEW (tree view)
STEP_TABLE_VIEW (table view)
STEP_FISHTAIL_VIEW (fishtail view)

page-349
Caesam SDK | 34 Step by step Perspective

If this attribute is not specified, the three views are available. The different values must be separated by
a semicolon “;”

<namefilter>

This can be used to specify a label filter for the items that will be displayed for this step.

<typefilter>

This can be used to specify a particular type of items that will be displayed for this step.

<filter>

This can specify a reference to a global filter defined in a typedesc for examples. (ex:
filter="caesam.perspectiveFilter.myFilter").

<selectionfilter>

This can be set to specify the filter used to select automatically some items in the tree for this step. Three
syntaxes are available:
1. Selection Filter on the Name:

<selectionfilter type="name">Panel_*</selectionfilter>

2. Selection Filter on the Type:

<selectionfilter type="type">CurvedPanel</selectionfilter>

3. Selection Filter with an instance of a Global Filter:

<selectionfilter>com.samcef.caesam.myPerspective.selectionfilter.MyGlobalFilter</selectionfilter>

The <selectionfilter> tag accepts also the attribute recursive that can be TRUE or FALSE. This onne can
be used to specify if the selection must be done at the first level of the tree or also at the lower levels.

<treeRepresentation>

This can specify the representation of the tree (By Type, By List, By Zone, By Group). The possible value
are the following: TYPE, LIST, ZONE, GROUP

<treeRepresentation>TYPE</treeRepresentation>

<editors>

This can specify a set of editors for this step. The possible children are:
1. <defaultTypeEditors> : can be used to define default editors for this step.
2. tabularEditor: (previously named cclEditor) see below.
3. fishtailEditor : can be used to specify a FishtailWorkbook.
<tabularEditor> can be used to specify a table model that will be used to display the table in the table
view. The value of tabularEditor can be a CCL DEFAULT command, an Interface or a class implementing
a table model. It can also do a reference to a workbook descriptor to include a workbook into the table

page-350
34 Step by step Perspective | Caesam SDK

view of this step. As a simple example, if we define a SimpleMaterial CCL command for the material, it
can be used in a step as shown below (the interfaced class must be specified before the interface):
1. Create a step like that shown below:

<!-- EO -->
<step id="BY_EOLIBRARY_CMD" title="TIT_STEP_EO"
icon="ICO_EO">
<views>STEP_TREE_VIEW;STEP_TABLE_VIEW</views>
<display3D>TOPOLOGY</display3D>
<editors>
<tabularEditor>Material:MyCustomMaterial</tabularEditor>
</editors>
</step>

2. Create a Default CCL Command like that shown below:

<Command Name="MyCustomMaterial"
InterfacedClass="Material"
Inherits="Caesam_Object:CaesamCmd_Creator"
Export="Material" Dictionary="examples2" Default="TRUE">
<Member Name="young" Type="CaesamQty_PRESSURE" Path="young" />
<Member Name="poisson" Type="CaesamQty_DIMENSIONLESS" Path="poisson"
/>
</Command>

3. Now in Caesam, we have the required columns for the “Material” for this step.

<display3D>

This allows you to customize the 3D View. The following options are possible for the 3D views:
• Topology
• GFEM
• Custom
• Filtered Entities
This element accepts the following values or a combination of values separated by a semicolon ‘;’:
• Topology => TOPOLOGY
• GFEM => GFEM
• Custom => CUSTOM
• Filtered Entities => FILTERED

page-351
Caesam SDK | 34 Step by step Perspective

By default, if this element is not specified, the default value is TOPOLOGY.

<step id="BY_ELEMENT_CMD" title="TIT_STEP_GFEM" icon="ICO_GFEM">


<display3D>GFEM;TOPOLOGY</display3D>
</step>

<toolbar>

This specifies the xml file that contains actions that will be available in the toolbar for this step.

<step id="BY_SE_CMD" icon="ICO_SE " title="TIT_STEP_SE">


<toolbar>/toolbars/se.xml</toolbar>
</step>

An example of the "se.xml" file defining the contents of the toolbar is:

<?xml version="1.0" encoding="UTF-8" ?>


<toolbar>
<command id="CREATE_SEA_CMD" />
<command id="DUMP_SELECTION_CMD" />
</toolbar>

This file provides two commands. To override or to provide a specific icon, a specific title or tooltip for
a particular command, then the following code can be used:

<command id="CAESAM_TEST_GFEM_IMPORT_CMD" title="IMPORT_GFEM"


icon="ICO_DOCUMENT_IMPORT" tooltip="IMPORT_GFEM"/>

<menu>

This specifies the path to a file that describes the menu bar that will be used for this step.

<step id="BY_ELEMENT_CMD" title="TIT_STEP_GFEM" icon="ICO_GFEM">


<menu path="/menu/menuElement.xml"/>
<display3D>GFEM</display3D>
</step>

<propertyView>

This specifies the location of the property view for this step.

<step id="BY_SE_CMD" icon="ICO_SE " title="TIT_STEP_SE">


<propertyView>CAESAM_FRAME_STEP_EDITOR_VIEW</propertyView>
<toolbar>/toolbars/se.xml</toolbar>
</step>

It means that the propertyView will be display in the CAESAM_FRAME_STEP_EDITOR_VIEW view.


If you don't want to display the property view for a particular step you can use the value HIDDEN.

<step id="BY_RUN_CMD" title="TIT_STEP_RUN" icon="ICO_RUN">


<propertyView>HIDDEN</propertyView>
<toolbar>/toolbars/empty.xml</toolbar>
<views>STEP_TREE_VIEW;STEP_TABLE_VIEW</views>
</step>

By default, the location of the property view for a particular step will be the value of the tag
<propertyView> defined in the tag <editorsView> .

page-352
34 Step by step Perspective | Caesam SDK

<minimizeEditor>

This specifies the behaviour of the CAESAM_FRAME_STEP_EDITOR_VIEW view when we choose


the TABLE_VIEW for the step. The default value is FALSE, but if you set the value to TRUE the editor
view will be minimized when you go in the TABLE_VIEW.

34.6.2 The <generalStep> element


A general step is a set of steps, so allowing a number of steps to be grouped in a single tab.
<!-- TAB GEOMETRY WITH SE AND SEA -->
<generalStep id="GSTEP_GEOMETRY" title="TIT_STEP_GEOMETRY"
icon="/icons/geometry.png">

<!-- SE -->
<step id="BY_SE_CMD" title="TIT_STEP_SE" icon="ICO_SE">
<toolbar>/toolbars/se.xml</toolbar>
</step>

<!-- SEA -->


<step id="BY_SEA_CMD" title="TIT_STEP_SEA" icon="ICO_SEA">
<toolbar>/toolbars/sea.xml</toolbar>
<views>STEP_TREE_VIEW;STEP_TABLE_VIEW</views>
</step>

</generalStep>

The <generalStep> element has the following attributes:

Table 50: Attributes of the <generalStep> editor

Attribute Description

id specifies this general step of this tab

icon specifies the icon used for this tab

tooltip specifies the tooltip used for this tab

title the title of this general step

General consideration

The id given to a perspective must be unique in Caesam.


The id of a step or a global step must be unique in a Perspective.
All the title and the icon attributes must refer to a key in the resources files.

34.7 How to implement Sub-Steps

Presentation

In a perspective, there is the possibility to define sub-steps. In fact, a general step groups some steps in a
single tab

On the above picture, you can see a step named "Model" that contains three sub-steps:
• Panel

page-353
Caesam SDK | 34 Step by step Perspective

• Stringer
• Frame
At each time, there is only one sub-step that is active. In this case, it's the step "Panel" that is active. The
XML that generates this representation is the following:
<!-- **** TAB GEOMETRY WITH SE (Panel, Stringer, Frame) **** -->
<generalStep id="GSTEP_GEOMETRY" title="TIT_STEP_GEOMETRY"
icon="ICO_GEOMETRY">

<!-- *** PANEL *** -->


<step id="BY_PANEL_CMD" title="TIT_STEP_PANEL" icon="ICO_PANEL">
...
</step>

<!-- *** STRINGER *** -->


<step id="BY_STRINGER_CMD" title="TIT_STEP_STRINGER" icon="ICO_STRINGER">
...
</step>

<!-- *** FRAME *** -->


<step id="BY_FRAME_CMD" title="TIT_STEP_FRAME" icon="ICO_FRAME">
...
</step>

</generalStep>

Toolbar with a sub-step

There is the possibility to define a toolbar for each sub-step. This toolbar is only available if the sub-step
is activated (the first button is pressed).
<!-- *** PANEL *** -->
<step id="BY_PANEL_CMD" title="TIT_STEP_PANEL" icon="ICO_PANEL">
<toolbar>/toolbar/panel.xml</toolbar>
</step>

Figure 20: The Sub-Step Panel is active

Figure 21: The Sub-Step Stringer is active

Example of the general Step "Model"

Example of the general Step "Model" in the perspective defined in the example plugin:
com.samcef.caesam.test.process.perspective

page-354
34 Step by step Perspective | Caesam SDK

The sub-step panel allows to show all the panels in a table and to select them and edit them into Tree
Editor View.

page-355

S-ar putea să vă placă și