On this page:

Sample models

The following sample models are available in <modeling tool instalation directory>\samples\CATIA Software Producer\

  • SysML Flashlight Tempo.mdzip
  • UML Lock Manager.mdzip
  • Contact Book - Cpp Reverse.mdzip

The CATIA Software Producer allows you to generate and build code from a UML or SysML model. You can generate code, for example, from the UML Class structure,  UML State Machine, or SysML Blocks. 

Key concepts and capabilities

CATIA Software Producer offers the following generation capabilities:

  • Generating C code from UML and SysML models.
  • Generating C++ code from UML and SysML models.
  • Generating Java code from UML classes.
  • Generating target dependent middleware code for AUTOSAR classic and adaptive.
  • Generating and compiling code for FMU.
  • Generating and compiling code to produce an executable for Windows, Linux, or a custom target.
  • Generating code from a model persisted as a file, or in TeamworkCloud, or the 3DEXPERIENCE Platform.
  • Generating code with traceability information, establishing the relation from the model items to the code.
  • Code revers from C++ to UML.

For more information about the Software Production Engineering application, see Software Production Engineering.

Prerequisites

When you launch any operation for the first time in your project, a dialog will open to configure the local workspace path, which will host generated resources.

Configuring the code generator

The principle 

The generated code is composed of multiple layers as shown on the schemas below.

When the user configures code generators, the generated files will contain the following part:


When the user configures application generators, the generated files will contain the following part:


To configure the code generator, you have to create a Code Generation Configuration Diagram.

Click the image to enlarge.

Code generation supported so far is C, C++, and Java. You can select them in the diagram palette.

A code generation configuration is composed of:

  • Elements
  • Local Path. A patch to your workspace.
  • SCM Configuration (optional)
  • Store Execution Summary in Model: set to false by default. Set to true, if you want an execution object to be created in your project (under the configuration element), so that you can view the execution summary of your configuration in the Code Generation Result Table.

 

Application production supported so far is FMU, AUTOSAR, Linux, Windows, and Custom Target.


An application production is composed of:

  • code generation configurations: their generated files are used to produce the application
  • top level element: only for FMU Production and AUTOSAR Generation configurations
  • local workspace path


  • store execution summary in model: by default set to false ; if set to true, an execution object will be created in your project (under the configuration element), so that you can view the execution summary of your configuration in the Code Generation Result Table.

  • generate code: by default set to true.

    • If set to true, the associated code generation configuration(s) will be launched and their results will be taken as inputs of the final operation.
    • If set to false, the inputs of the final operation are the current files stored under the folders referenced by the configurations.
  • parameters specifics to the selected operation:
    • in the example below: platform, include_souce, C_standard, Cpp_standar, debug
  • SCM Configuration (optional)

Code generation on the platform or locally

The code generation can be launched on the platform or locally.

The local code generation is available for:

  • Code Generation configurations (C Code Generation, Cpp Code Generation, Java Code Generation, and Component Tester)
  • Component Tester configuration in generation mode (default mode)


If you want to generate the code on the platform, you need to specify parameters of the configuration.


To launch the code generation on the platform


  1. In the Containment tree or on the diagram pane, right-click the needed configuration.
  2. From the shortcut menu, select Specification.
  3. In the Specification window, go to the Code Generation Configuration option group.
  4. Set the Execute On Cloud option to true.
  5. Click OK.

Before starting to work on code generation on the platform, first, you have to connect to 3DEXPERIENCE by entering the URL of the Software Producer cloud server. After that, you will be able to log in with your regular identifiers. You must have the Software Production Engineer Role. It will give you permission to use the service.

For information about how to authenticate with the 3DEXPERIENCE platform, see Authentication with 3DEXPERIENCE platform.

Specifying elements and configurations

You can specify “elements” or “topLevelElement” in two ways:

  • Drag and drop the element from the Containment tree to the desired configuration in the diagram
  • Open the Specification window of the configuration and edit the Element property.

You can specify “codeGenerationConfigurations” in two ways:

  • On the diagram, drag and drop the Code Generation Configuration to the application Production configuration.
  • Open the Specification window of the configuration and edit the Code Generation Configuration property.

Validating

You can check if your model is compatible with the code generation via the standard validation menu.


To run the validation


  1. In the Containment tree, right-click the code configuration.
  2. In the shortcut menu, select one of the following:
    1. Click Validate, and in the open Validation dialog, choose either all possible constraints or only Code Generation Constraints.
    2. Click Validate Element to run validation for a selected element only.


You can also use the Validate Diagram command, which you can find in the configuration diagram toolbar:

The results are displayed in the Validation Results window if there are any errors or warnings. 

The operation logs are displayed in the usual Software Producer logs window.

If you do not want to run the validation for code generation when calling the validation menu, you can choose to ignore a selected validation suite and/or validation rule. 


To ignore a validation suite or a validation rule


  1. In the modeling tool's main menu, click Options > Project.
  2. In the open Project Options dialog > Validation, specify the Ignored Validation Suites and/or Ignored Validation Rules.
The validation will still be triggered during code generation. If you want to hide the validation results at this point, set the Show Validation Report property to false in the Project Options > CATIA Software Producer Client (see Validation Results.). 


Validation is actually an SPO (Software Production Operation) launched in dry-run mode (no file generation, no credit consumption).


Executing Operations

To execute the code generator, you can run the generation from the following locations:

  • Main menu
  • Code generation diagram
  • Containment tree

Execution from the main menu

You can do one of the following:

  • launch the default action Execute Operation that will launch the operations
    • if Activate Smart Launch Mode is set to true in the environment options (Environment options dialog > CATIA Software Producer Client General Properties), operations will be launched only if a change was made in the model. By default, the property is set to false.
  • launch the Clean & Execute Operation that will delete your previously generated local files and cloud assets, then launch all the operations.
    • for the deletion of the local files: if files previously generated by this configuration are found, a dialog will be prompted to the user to confirm the deletion of local files.

      If you do not want to see this message again,  cancel the selection of the Show this message next time check box. If you want to see this message again, there is a dedicated Environment option to turn the message showing on (see Additional Information).


    • for the deletion of cloud assets: it will be done without asking for the confirmation of the user. 

Execution from a code generation diagram

Do one of the following:

  • On the diagram pane, right-click a configuration element, and from the shortcut menu, choose Software Code Generation > Execute Operation:

  • On the diagram pane, select a configuration element, and in the diagram toolbar, click Execute Selected Configuration:

Execution from Containment tree

  • In the Containment tree, right-click a configuration element, and from the shortcut menu, select Software Code Generation > Execute Operation > Execute Operation:

  • In the Containment tree, right-click an input element, and from the shortcut menu, select Software Code Generation > Execute with...:

The operation logs are displayed in the Software Producer Logs window.

Limitation

Currently, when a code generation is launched after renaming a class, the newly generated files reflect the new class names. However, the old files (corresponding to the previous class names) are not automatically deleted. This can lead to "outdated" files remaining in the output directory.

This limitation will be addressed in 2026x. 

Test Environment Generation

The Component Tester is an operation designed to support software development by providing a ready-to-use environment. This solution allows multiple ways to execute the application for testing purposes.

The Component Tester is generated by the Component Tester Generator. Based on the specified generation parameters, it can be used to:

  • Facilitate application development following code generation from a UML architecture
  • Support testing activities during software development

When you define the Component Tester parameters, you can generate the code. All files will be available in the Files tab.

From the Files tab, you can open the Tester with VS Code for further actions with the generated code. 

Opening files with VS Code works only if you set the value of the configuration parameter "ide" to "vscode" and have VS Code installed on your machine.


Cpp Code Reverse

The goal of the Cpp Code Reverse operation is to create the UML components from the existing C++ files.

For working with the code reverse, first, you need to specify the CppCodeReverse configuration.


To specify the code reverse configuration


  1. In the model, create a package for storing the configuration.
  2. In the package, create the Code Generation Configuration diagram.
  3. In the diagram, create the Cpp Code Reverse element.
  4. In the Containment tree, under the Model, create a package that will be used as a target package for the created UML elements.
  5. Drag the target package onto the Cpp Code Reverse element on the diagram pane to assign it as a target package.
  6. Double-click the Cpp Code Reverse element to open the Specification window.
  7. Specify the needed options.

Option nameDefault valueDescription
Create StrategyCreate element according to codeThe creation strategy defines if the elements newly added to the code file should be created in the model. If you do not want the new elements to be created after executing the code reverse, choose Ignore new element from code strategy.
Delete StrategyDelete element according to codeThe deletion strategy defines if the elements deleted from the code file should also be deleted from the model. If you do not want the elements to be deleted after executing the code reverse, choose Ignore deleted element from code strategy.
Update StrategyUpdate attribute according to codeThe update strategy defines if the attribute changes in the code file should be applied in the model. If you do not want the attribute changes to be applied after executing the code reverse, choose Ignore attribute changes from code strategy.
Define SymbolsNADefine the symbols to be expanded by the preprocessor when parsing files. 
Dry RunfalseIf this option is set to true, the operation will not modify the model after the execution. It only shows changes in the Software Producer Logs that would be made. 
Include DirectoriesNAInclude directories used by the parser for searching "#include" files.
VerbosefalseIf this option is set to true, every model creation, modification, and deletion is logged in the Software Producer Logs.
NameCpp code reverse element nameThe name of the Cpp code reverse element.
Target PackageTarget package nameThe elements, created after code reverse execution, will be stored in this package.
Reverse Local Path<sop.local.workspace.path>/<configuration.name>Define the path where the C++ source files are stored. By default, the path points to the location where the project is stored.

Code reverse example

You can find a sample model, Contact Book - Cpp Reverse, located in <installation_directory>\samples\CATIA Software Producer.

The files containing the C++ code and used in the sample are located in <installation_directory>\samples\CATIA Software Producer\Contact Book - Cpp Reverse\Contact Book.

You can use the files to try out the code reverse functionalities. Try deleting UML elements from the sample project and executing the CppCodeReverse configuration while changing various strategies. Also, try modifying the code files.

C++ to UML reverse process

The C++ to UML code reverse operation supports C++ files based on the latest C++ version: C++14, C++17, C++20. It does not imply that each new concept of a specific version is supported, but it reading the file should be available. Only header files are analyzed: .h and .hpp.

Supported elements

IconMeaning
(tick) Supported / Partially supported.
(error) Not supported.

Element

Status

Description

Class

(tick)

A declaration of a class in C++, used to define a custom type with members and methods.

Class member function declaration

(tick)

Declaration of a member function inside a class, without its complete definition.

Class member function definition

(tick)

The full definition of a member function, including its body, usually outside the class.

Class member variable

(tick)

Variable defined within a class, representing an object's state or property.

Namespace declaration

(tick)

A declaration of a namespace to organize classes and functions under a common name scope.

#include preprocessor directive

(error)

Preprocessor directive used to include header files or libraries.

Class constructor

(tick)

A special function is called when an object is created, used to initialize its members.

Class destructor

(tick)

A special function is called when an object is destroyed, used to release resources.

Global function declaration

(tick)

Declaration of a function defined outside any class.

Global function definition

(tick)

Full definition of a global function, including its body.

Alias (typedef & using)

(tick)

Declaration of a type alias using typedef or using to simplify complex types.

#define preprocessor directive

(error)

Preprocessor directive that defines a macro or symbolic constant.

Global variable

(tick)

Variable defined outside of any class or function, accessible globally in the program.

Union

(tick)

A special data type that allows storing different types of data in the same memory location.

Struct

(tick)

A declaration of a structure in C++, used to group multiple variables under the same type.

Enum

(tick)

Declaration of an enumerated type, used to define a set of named constants.

@port

(error)

An annotation used to identify that a variable will be translated into a UML Port.

@getter:<var>

(error)

An annotation used to identify that an operation is a getter of a variable.

@setter:<var>

(error)

An annotation used to identify that an operation is a setter of a Port.

@agregation

(error)

Not supported.

@member

(error)

Not supported.

@association

(error)

Not supported.

@classifierBehavior

(error)

Not supported.


Comment handling

FunctionDescription

@generated_from, @generated_brief,
@reverse_ignore

For any element of the code, any comment except lines containing “@generated_from”, “@generated_brief”, and “@reverse_ignore” annotations are expected to be taken into account.

Documentation in the model

Comments found in the C++ source code will be handled in the UML model. Once processed, the comment will be written in the UML item Documentation/Comments property. Only Doxygen documentation is processed.

Example - The documentation in the Model
C++:
class test {
	public:
	/**
	This is 'a' attribute
	It helps to store the value as an int
	and it is public 
	*/
	int a;
}
UML:
[class] test
|-[property]a:int, documentation:” 	This is 'a' attribute
	It helps to store the value as an int
	and it is public 
”
Comment styles

Doxygen comments delimiters (/** */, /*! */, ///, //!) are supported.

Example - Comment styles
/** block comment */
/*! block comment */
/// one line comment
//! one line comment


Supported C++ items

Supported C++ items for comments retrieval are class, struct, enum, union, typedef, attribute, function, and arguments.

Comment mapping

Only the last previous comment is taken into account. If there are several comment blocks before an item in C++ code, only the last is taken into account.

example - Comment mapping
C++:
int myFirstProperty
//comment1
//comment2
/** @brief my comment */
int myProperty;
uml:
[property]myproperty:int, documentation: ”my comment”


Doxygen command patterns

The supported Doxygen command patterns are @ and \ 

Example - Command patterns
C++:
/** @brief documentation*/
int myProperty;
uml:
[property]myproperty:int, documentation: ”documentation”


Comment with Doxygen syntax handling rules

Comments with Doxygen syntax will be handled with the following rules:

  • @param and \param commands will be retrieved, and their value will be set in the argument documentation attribute
  • @brief command will be retrieved
  • @return or @returns will be retrieved and its value will be set into the operation documentation of the return argument.
Example
C++:
/** 
 * @brief documentation of function
 * @param[in] param the first parameter
 * @return the return type
 */
int func(int param);
uml:
+class
|-[operation] func, documentation=”documentation of the funcrtion”
  |-[parameter] int, direction=return, documentation: ”the return type”
  |-[parameter] param:int, direction=in, documentation: ”the first parameter”
Other commands

Other commands (such as @author) will be added to the Item documentation as is.

Example
C++:
/** @author someone*/
int myProperty;
uml:
[property]myproperty:int, documentation: ”@author someone”


@param[in|out|inout]

@param[in|out|inout]: direction set by @param command will be taken into account to set direction in the UML argument.

C++:
/** 
 * @brief documentation of function
 * @param[out] param the first parameter
 */
int func(int* param);
uml:
+class
|-[operation] func, documentation=”documentation of the funcrtion”
  |-[parameter] int, direction=return
  |-[parameter] param:int, direction=out, documentation: ”the first parameter”


Code reverse behavior specification

The behavior of the code reverse depending on the Cpp element is described in the following table.

Function / ElementDescriptionExample

Namespace declaration

The inline namespace (Since C++11) is ignored during parsing.

A package with the stereotype “C++ Namespace” is expected to be created with the name of the namespace for any declared namespace in the code.


“unique namespace name” attribute of “C++ Namespace” stereotype of the created package will have the name of the namespace.
Namespace declaration
C++:
namespace ns1
{
  namespace ns2
    …
  {
}
UML:
RootPackage
|-[package]ns1 [[C++ Namespace]]
  |-[package]ns2 [[C++ Namespace]]

Namespace declaration since C++17
C++:
namespace ns1::ns2{
  …
}
UML:
RootPackage
|-[package] ns1 [[C++ Namespace]]
  |-[package]ns2 [[C++ Namespace]]
If a class is defined in a namespace, the UML class will be created under the package corresponding to the namespace.
Class declaration with namespace
C++:
namespace ns1 {
class MyClass{
};
}
UML:
RootPackage
|-ns1[package]
  |-[class]MyClass

 Class

A UML class is created for each declared Cpp class.
Class declaration
C++:
class MyClass{
};
UML:
RootPackage
|-[class]MyClass
InheritanceIf a class inherits from another class, a generalization relation is created from the class to the other class.

The visibility of the inheritance is used in the created generalization relation.

See: www.geeksforgeeks.org/visibility-modes-in-c-with-examples/

Class declaration with generalization
C++:
class B {};
class A : public B {
};
UML:
Nested Class

A declaration of a class/struct or union appearing within another class is known as a nested class. https://en.cppreference.com/w/cpp/language/nested_types


A UML class will be generated under the parent class for the Cpp nested class.


Abstract Class

A Class is abstract when all functions are defined as virtual. See virtual operation. 


Global functions and variablesA “global” Class is created without any name and with the “C++ Global” stereotype when code contains functions and variables declared outside any class (global functions and global variables).

The “global” Class is created under the root package.

C++ :
void globalFunction();
UML:


Class constructor

An operation with the stereotype “C++ Constructor” will be generated for any constructor declared in the code of the class.

Constructor
++:
class Door{
  Door();
};
UML :
[class]Door
|-[operation]Door [[C++ Constructor]]

The Initializer List of a constructor is replicated in the “Initialization list” field of the “C++ Constructor” stereotype applied to the operation.

Constructor with Initialization list
C++:
class Door{
  const int t;
  Door(int t):t(t){};
};
UML :
[class]Door
|-[operation]Door [[C++ Constructor,Initialization list=t(t)]]

The “explicit” specifier of a constructor is replicated in the “Explicit” field of the “C++ Constructor” stereotype applied to the operation.

Constructor with explicit specifier
C++:
class Door{
  explicit Door(){};
};
UML :
[class]Door
|-[operation]Door [[C++ Constructor,Explicit=true]]

Class destructor

An operation with the stereotype “C++ Destructor” will be generated for any destructor declared in the code of the class.

C++:
class Door{
  ~Door();
};
UML :
[class] Door
|-[operation] Door [[C++ Destructor]]

Variable (Class Member Variable and Global Variable)





A property is generated in the UML class for each member variable of the Cpp class.


Properties created from the reverse code analysis will keep the order in which they are read.


Visibility of the property is configured according to the declaration in the code for that variable.


The type of the variable is used to configure the type of the property.

Property
C++:
class Door{
private:
  bool isLocked;
};
UML :
[class] Door
|-[property] isLocked:bool, Visibility=private

The default value of the property is a string set as defined in the code.

Property
C++:
enum LockEnum { 
  Open, 
  Closed 
};

class Door{
	LockEnum lockStatus = Closed;
};
UML :
[class] Door
|-[property] lockedStatus:LockEnum,Default value=Closed

Pointer and reference declaration





“Type Modifier” attribute of the property will be set to “*” for a variable declared as a pointer.

Pointer and reference
C++:
class MyClass{
	chat *pointerVar;
int &referenceVar;
};
UML :
[class] MyClass
|-[property] pointerVar:char, type modifier=*
|-[property] referenceVar:int, type modifier=&

“Type Modifier” attribute of the property will be set to “&” for a variable declared as a reference.

“Type Modifier” attribute of the property will be set to “&&” for a variable declared as a rvalue reference.

“Type Modifier” attribute of the property will be set to “**” for a variable declared as a double pointer.

“Type Modifier” attribute of the property will be set to “*&” for a variable declared as a reference to a pointer.

List & Vector declaration

Multiplicity attribute of the property will be set to “*” for a variable declared as a list or a vector.

List declaration
C++:
#include <list>
class MyClass{
	std::list<bool> myList;
};
UML:
[class] MyClass
|-[property] myList:bool, multiplicity=*
List declaration
C++:
#include <vector>
class MyClass{
	std::vector<bool> myVector;
};
UML:
[class] MyClass
|-[property] myVector:bool, multiplicity=*

Array declaration

For a variable declared as an array, the corresponding property will be created with the stereotype “C++ Attributes,” and the “Array” attribute is set with the size of the array.

Array declaration
C++:
#include <array>
class MyClass{
	std::array<int,2> myArray;
};
UML:
[class] MyClass
|-[property] myArray:int [[C++ Attributes:Array=2]]

Const

For a variable declared as const, the corresponding property will be created with the “Is Read Only” attribute set to true.

Const declaration
C++:
class MyClass{
	const int myConst;
};
UML:
[class] MyClass
|-[property] myConst:int,”Is Read Only”=true

Static

For a variable declared with the storage class “static”, the corresponding property will be created with “Is Static” attribute set to true.

Static declaration
C++:
class MyClass{
	static int myStatic;
};
UML:
[class] MyClass
|-[property] myStatic:int,”Is Static”=true

Mutable

For a variable declared with the storage class “mutable”, the corresponding property will be created with the stereotype “C++ Attributes” and the “Mutable” attribute is set to true.

Mutable declaration
C++:
class MyClass{
	mutable int myMutable;
};
UML:
[class] MyClass
|-[property] myMutable:int,”Is Static”=true

Bit field

For a variable declared using a bit field pattern, the corresponding property will be created with the stereotype “C++ Attributes,” and the “Bit Field” attribute is set with the size of the bit field.

Bitfield declaration
C++:
class MyClass{
	int myVar:20;
};
UML:
[class] MyClass
|-[property] myVar:int [[C++ Attributes:”Bit Field”=20]]

Extern

For a variable declared with the storage class “extern”, the corresponding property will be created with the stereotype “C++ Extern”.

C++:

extern int myExtern;

UML:
[class] 
|-[property] myExtern:int [[C++ Extern]]

Function Declaration (Class Member Function & Global Function)


An operation is generated in the UML class for each member function of the Cpp class.


Visibility of the operation is configured according to the declaration in the code for that variable.

Function
C++:
class Door{
private:
  void lock();
};
UML :
[class] Door
|-[operation] lock:void, Visibility=private

Virtual

For a function declared as virtual, the corresponding operation will be created with the stereotype “C++ Operation,” and the “Virtual” attribute is set to true.

C++:
class Door{
private:
  virtual void lock();
};
UML :
[class] Door
|-[operation] lock:void[[C++ Operation, Inline=true]]

Volatile

For a function declared as volatile, the corresponding operation will be created with the stereotype “C++ Operation,” and the “Volatile” attribute is set to true.

C++:
class Door{
private:
  void lock() volatile;
};
UML :
[class] Door
|-[operation] lock:void[[C++ Operation, Volatile=true]]

Static

For a function declared with the storage class “static”, the corresponding operation will be created with the “Is Static” attribute set to true.

Static declaration
C++:
class MyClass{
	static void lock();
};
UML:
[class] MyClass
|-[operation] lock:void,”Is Static”=true

Const

For a function declared as const, the corresponding operation will be created with the “Is Query” attribute set to true.

C++:
class MyClass{
	void lock() const;
};
UML:
[class] MyClass
|-[operation] lock:void,”Is Query”=true

Operator

For a function having the name “operator<overloaded_operator>”, an operation will be created with the C++ Operator” stereotype. <overloaded_operator> can have the following values:

C++:
class MyClass{
	void operator+() const;
};
UML:
[class] MyClass
|-[operation] operator+:void[[C++ Operator]]

 Function Argument



For a function declaring a returned value, a parameter will be generated with direction set as “return”.


For each argument of a function, a parameter will be generated with direction set as “in” or “inout”.

Operation with arguments
C++:
class MyClass{
  bool myFct1(int arg);
  bool myFct2(int * arg);
  bool myFct3(const int * arg);
};
UML :
[class] MyClass
|-[operation] myFct1
  |-[parameter] bool, direction=return
  |-[parameter] arg, type=int, direction=in
|-[operation] myFct2
  |-[parameter] bool, direction=return
  |-[parameter] arg, type=int, modifier=*, direction=inout
|-[operation] myFct3
  |-[parameter] bool, direction=return
  |-[parameter] arg, type=int, modifier=*, direction=in

The type of the argument is used to configure the type of the parameter.

Operation with arguments
C++:
class MyClass{
  bool myFct(int arg);
};
UML :
[class] MyClass
|-[operation] myFct
  |-[parameter] bool, direction=return
  |-[parameter] arg, type=int, direction=in

Pointer and reference declaration


“Type Modifier” attribute of a parameter will be set to “*” for an argument declared as a pointer. 


“Type Modifier” attribute of parameter will be set to “&” for an argument declared as a reference. 

Pointer and reference
C++:
class MyClass{
	void myFct(int *pointer	Arg);
void myFct2(int &referenceArg);
};
UML :
[class] MyClass
|-[operation] myFct:void
  |-[parameter] : type=void, direction=return
  |-[parameter] pointerArg: type=int, direction=inout, type modifier=*
|-[operation] myFct2:void 
  |-[parameter] : type=void, direction=return
  |-[parameter] referencearg:int, direction=inout, type modifier=&

List declaration

Multiplicity attribute of parameter will be set to “*” for an argument declared as a list.

C++:
#include <list>
class MyClass{
	void myFct(std::list<bool> myList);
};
UML:
[class] MyClass
|-[operation] myFct:void
  |-[parameter] myList: type=bool, direction=in, multiplicity=*

Array declaration

For an argument declared as an array, the corresponding parameter will be created with the stereotype “C++ Attributes,” and the “Array” attribute is set with the size of the array.

C++:
#include <array>
class MyClass{
	void myFct(std::array<int,2> myArray);
};
UML:
[class] MyClass
|-[operation] myFct:void
  |-[parameter] myArray: type=int [[C++ Attributes:Array=2]]

Const

For an argument declared as const, the corresponding parameter will be created with direction set to “in”

C++:
class MyClass{
	void myFct(const int myConst);
};
UML:
[class] MyClass
|-[operation] myFct:void
  |-[parameter] myConst: type=int,”direction”=”in”

Variable length parameter list

For a variable length function, the latest parameter will be created with the name “…” without any type

C++:
class MyClass{
	void myFct(const int myConst, ...);
};
UML:
[class] MyClass
|-[operation] myFct:void
  |-[parameter] myConst: type=int,”direction”=true
  |-[parameter] …

Function Definition (Class Member Function & Global Function)

For the implementation body of a function, an opaque behavior will be generated, the language attribute will be set to “C++”, and the body attribute will be filled with the body of the function. This opaque behavior will be referenced by the operation with the “Method” attribute.  

Operation with behavior
C++:
void ClassA::myFct(){
  // This is the implementation of operation
}
UML:
[class] MyClass
|-[opaque behavior] myFctBeh, language=C++, body=“// This is the implementation of operation”
|-[operation] myFct:type=void, method=myFctBeh

Standard Data Types

When a model element  (eg, property, parameter) references a type, the reference is mapped to standard types for the following types:


Structure



A UML class with the stereotype “C++ Struct” will be created for each declared struct.


A property will be created for each field of the struct.

Structure definition
C++:
struct Struct{
  unsigned int data1;
};
UML: 
[class] Struct [[C++ Struct]]
|-[property]data1:type=C++ ANSI profile::datatypes::unsigned int

Enumeration





An enumeration will be generated for an enum in the code.


An enumeration literal with the stereotype “C++LiteralValue” will be generated for each field of the enum.


A value attribute of “C++LiteralValue” will be configured with the value of the field, if any.

C++:
enum ControlEnum{
	Idle,
	Open,
	Close
};
UML: 

Since C++11, an enum can be defined using enum class. Such a pattern will be supported when detecting enums in code.

C++:
Enum class ControlEnum{
	Idle,
	Open,
	Close
};
UML: 

Union

A UML class with the stereotype “C++ Union” will be created for each declared union.


A property will be created for each field of the union.

Union definition
C++:
union MyUnion{
  int intVal;
  float realVal;
  char charVal;
};
UML: 
[class] MyUnion [[C++ Union]]
|-[property]data1:type=C++ ANSI profile::datatypes::int
|-[property]data1:type=C++ ANSI profile::datatypes::float
|-[property]data1:type= UML Standard Profile::MagicDraw Profile::datatypes::char 

Alias (Typedef and Using)

For an alias to another type (via typedef or using), a Data Type will be generated and a generalization relation will be created between this Data Type and the Data Type source of the alias.

typedef declaration
C++:
class MyClass{
  typedef int myInt;
};
UML:
[class] MyClass
|-[data type] myInt
  |- [dependency] Target=”UML Standard Profile::MagicDraw Profile::datatypes::int”
Using declaration
C++:
class MyClass{
  using myInt = unsigned int;
};
UML:
[class] MyClass
|-[data type] myInt
  |- [dependency] Target=” C++ ANSI profile::datatypes::unsigned int”

typedef of an array

For an alias to another type (via typedef or using) declaring an array, a Data Type will be generated with the “C++ Attributes” and “Array” attribute is set with the size of the array and a generalization relation will be created between this Data Type and the Data Type source of alias.

C++:
class MyClass{
	typedef int array[3];
};
UML:
[class] MyClass
|-[data type] array [[C++ Attributes:Array=3]]
  |- [dependency] Target=”UML Standard Profile::MagicDraw Profile::datatypes::int”

typedef of a struct


 

For an alias (via typedef or using) declaring a struct, a class will be generated (same as for a Union).


For an alias (via typedef or using) declaring a struct, if the struct is anonymous, the created class will have the name of the alias with the suffix “Struct”.

Structure definition
C++:
typedef struct{
  unsigned int data1;
} MyStructStruct ;
UML: 
[data type] MyStructStruct 
|-[generalization] Target=<>
  |-[class] <> [[C++ Struct]]
    |-[property]data1:type=C++ ANSI profile::datatypes::unsigned int

typedef of an enum


 

For an alias (via typedef or using), declaring an enum, an enumeration will be generated (same as for Enumeration)


For an alias (via typedef or using) declaring an enum, if the enum is anonymous, the created enumeration will have the name of the alias with the suffix “Enum”.

enum definition
C++:
typedef enum {
	Idle,
	Open,
	Close
} Control;
UML: 

typedef of a union


 

For an alias (via typedef or using), declaring a union, a class will be generated (same as for Union)


For an alias (via typedef or using) declaring a union, if the unionenum is anonymous, the created class will have the name of the alias with the suffix “Union”.

Union definition
C++:
typedef union {
  int intVal;
  float realVal;
  char charVal;
} MyUnion;
UML:

[data type] MyUnion
|-[generalization] Target=<>
  |-[class] <>[[C++ Union]]
    |-[property]data1:type=C++ ANSI profile::datatypes::int
    |-[property]data1:type=C++ ANSI profile::datatypes::float
    |-[property]data1:type= UML Standard Profile::MagicDraw Profile::datatypes::char 

Limitations

In the following table, you can see functionalities that are not yet supported in the code reverse.

IconMeaning
(error)Not yet supported.
FunctionStatusDescription

Friend class

(error)

If a class is declared a friend to another one, a usage relation with the “C++ Friend” stereotype is expected to be generated.

C++:
class FriendClass{
	friend class ClassA;
}
UML:

 #Include preprocessor directive

(error)

If a file contains one or multiple class definitions and contains #include directives to other files containing class definitions, a usage relation is created for the corresponding UML classes and the targeted classes with the stereotype “C++ Include”.

(error)

If the #include directive is declared using <>, the “header include” attribute will be configured with the value “System Include“

(error)

If the #include directive is declared using “ “, the “header include” attribute will be configured with the value “User Include“

Variable supported by an association(error)

If the annotation @association is defined before the declaration of a variable and this variable is a pointer, a directed association relation will be created from the class to the type of the variable, and the role on the target will have the name of the variable.

Cpp:
class A {
  /* @association */
  B *a;
};
UML:

Flow Property variable(error)

If the annotation @port:<port_name> is defined before the declaration of a variable, a Property will be generated in an Interface referenced by a Port. A Port and an Interface will be created for each port_name. The <port_name> will be part of the prefix of the variable.

Cpp:
class A {
  /* @port:myPort */
  B myPort_myData;
};
UML:
[class] A
|-[port] myPort:myPortItf
[interface] myItf
|-[property]myData:B


Function pointer(error)

For a variable declared as a function pointer, the corresponding property will be created with the stereotype “C++ FunctionPtr,” and the signature attribute will be set with the signature definition.

C++:
class MyClass{
	void (*fctPtr)();
};
UML:
[class] MyClass
|-[property] fctPtr:void,[[C++ FunctionPtr]]


Multiple declarations(error)

For a variable declared with a complex collection of storage classes or declarations, the Type Modifier attribute will be used to register the complete declaration. “$” char replaces the type name.

const on pointer not yet supported: const int* const

C++:
class MyClass{
	const int* myConstPtr;
};
UML:
[class] MyClass
|-[property] myConstPtr:type=int, Type modifier=”const$*”
Friend(error)

For a function declared as a friend in a class, a usage relation with the “C++ Friend”  stereotype is created between the operation in the class declaring it and the current class.

C++:
class ClassC{
	friend void ClassD::func(Integer myParam);
};
UML:

Exception(error)

For a function declared with the suffix noexcept  (since C++11), the corresponding operation will be created with the stereotype “C++ Operation” and the “Throw exception” attribute is set to “none”.

C++:
class MyClass{
	void myOp() noexcept;
};
UML:
[class] MyClass
|-[operation] myOp:void[[C++ Operation, Throw exception=none]]
(error)For a function declared with the suffix noexcept (<condition>) (since C++11), the corresponding operation will be created with the stereotype “C++ Operation”, and the “Throw exception” attribute is set to “none”, and the condition will be configured somewhere.
(error)

For a function declaring an exception without any argument (C++98 and C++03 only), the corresponding operation will be created with the stereotype “C++ Operation” and the “Throw exception” attribute is set to “any”.

C++:
class MyClass{
	void myOp() throw();
};
UML:
[class] MyClass
|-[operation] operator+:void[[C++ Operation, Throw exception=any]]


(error)

For a function declaring an exception with arguments (C++98 and C++03 only), the corresponding operation will be created with the stereotype “C++ Operation”, “Throw exception” attribute is set to “any”, and “Raised exception” attribute is set with the value of the exception arguments.

C++:
class MyClass{
	void myOp() throw(std::exception);
};
UML:
[class] MyClass
|-[operation] operator+:void[[C++ Operation, Throw exception=any, Raised exception=std::exception]]
@getter(error)

For a function having annotation @getter before its declaration, the corresponding operation will be created with the stereotype “getter”, and “getter/setter for attribute” will be configured with the corresponding property. 

@setter(error)

For a function having annotation @setter before its declaration, the corresponding operation will be created with the stereotype “getter” and “getter/setter for attribute” will be configured with the corresponding property. 

Cpp:
class Door {
  ControlEnum WindowPosition;

  /* @setter:WindowPosition */
  void setWindowPosition(ControlEnum /*in*/ windowPosition);
		
  /* @getter:WindowPosition */
  ControlEnum getWindowPosition();
};

UML:

“C++ Parameter” and “volatile” attribute set to “true”(error)

For a return type declared with the modifier volatile, the corresponding return parameter will be created with the stereotype “C++ Parameter” and “volatile” attribute set to “true” 

C++:
class MyClass{
	volatile int method();
};
UML:
[class] MyClass
|-[operation] method
  |-[parameter]int, direction=return [[C++ Parameter:”volatile”=true]]

 #define preprocessor directive

(error)

A macro can be defined via a property with Is Read Only=true, but the C++ profile needs to be extended with a new stereotype “C++ Macro” to distinguish it from a regular const.

Another alternative is to use the notes to attach a const to a Class.

 Templates

(error)Not supported.

Software Governance

To commit elements from the modeling tool, you need to:

  • Associate a SCM repository to the model element
    • Using Connected Software Connectors
    • With a local configuration
  • Create an SCM Configuration element
  • Configure an SCM branch
    • Using Software Logical Items of Connected Software 
    • With a local configuration

SCM Repository association

Associating repository using Connected Software Connectors

To associate the SCM repository


  1. In the Containment tree, right-click Model.
  2. In the shortcut menu, click Software Code Generation > Associate SCM Repository.
  3. In the open Associate SCM Repository dialog, choose the needed repository,
  4. Click OK.

After you click OK in the Associate SCM Repository dialog, the repository information will be associated to the model via the «Connector» stereotype from the Embedded Software Profile:

  • repositoryHost: root url of the targeted Git server (ex: : https://gitlab.com)
  • repositoryPath: relative path of the repository (ex: SJA/cubesat-control)
  • repositoryToken: associate the access token to the repository (example: glpat-6_y_4y8hMDNDxWyaATi4)


To remove the association of the SCM repository


  1. In the Containment tree, right-click Model.
  2. In the shortcut menu, click Software Code Generation > Associate SCM Repository.
  3. In the open Associate SCM Repository dialog, click the selected repository for which you want to remove the association.
  4. Click OK.

When you click OK, the association will be removed and the branches will be detached from elements if there were any. 

Local Configuration

If Connected Software is not used, it is still possible to attach a repository to the model element.

To do so, associate the «Connector» stereotype from Embedded Software Profile to the model element and configure it as following:

  • repositoryHost: root url of the targeted Git server (ex: : https://gitlab.com)
  • repositoryPath: relative path of the repository (ex: SJA/cubesat-control)
  • repositoryToken: associate the access token to the repository (example: glpat-6_y_4y8hMDNDxWyaATi4)

SCM Configuration creation

It is necessary to associate a repository before attaching a branch from the configuration dialog.

From the diagram palette, the you can create a SCM Configuration that will contain a reminder of the repository path of the model: you cannot edit the repository here. If you need to change the repository, see SCM Repository association.

To use the SCM Configuration, you have to drag and drop the SCM configuration on the code configuration or application configuration that you wants to execute and commit:

SCM Branch Configuration

This is the branch to which you are going to commit the code.

It is necessary to associate a repository before attaching a branch from the configuration dialog.

With Software Logical Items of Connected Software

  • you can edit the branch in the Specification window by clicking the three dots in the branch value field:

 

  • When you click OK in the Associate Branch of Repository dialog, the branch information will be associated to the configuration via the «SoftwareLogicalItem» stereotype from Embedded Software Profile:
      • branchName: the branch name to target (example: “main”)
      • SoftwareLogicalItemId: ID of the logical Item linked to the branch (from Connected Software)

If if you remove the repository association, the branches will also be detached from elements if there were any. See SCM Repository association.

Local Configuration

The you can edit it in the branch:

  • branchName: the branch name to target (example: “main”)

Code persistency

Code generation is executed via the regular mechanism.


The code will be committed after a successful execution of code generation.

At execution phase, mandatory parameters are checked, if they are not present or are invalid, the operation is canceled and a message is printed (see an example below).

The mandatory parameters are:       

  • the repository path: must be present
  • the repository token: must be present
  • the repository host: must be present and must reference a valid URL (syntax check only)
  • the commit message: must be present
  • the commit author: must be present
  • the branch name: must be present

Local workspace of the software producer

Under the local workspace, you can find the generated files, if you have selected the download option and left the default location (as seen above) in the configurations. You can also find some other files under an “etc” folder:

  • <Local_workspace_path>
    • <configuration1_name>
    • <configuration2_name>
    • etc
      • json3
      • log4
      • operations
      • backup2
      • logs

1You can change the root of the local workspace path in the project options.

2By default, a backup of your downloaded files is saved in this folder so that in case something wrong happens with the download of new files, you can still reach your previous files. You can disable this option in the Project Options 

3SPO Report files are rotated by size and date so that you might see multiple report files here.

4Log files are rotated by size and date so that you might see multiple log files here.

Views

Files tab

The Files tab lists the existing configurations in the model and displays as children the files contained in the directory referenced by the configuration. This behavior is available for the code generation configuration and the reverse code configurations.

Configurations are greyed if they have no content (no files yet).


In the Files tab, double-click a file to see its content in a code viewer

You can select any file in the Files tab, and open the Specification of an element that was used to generate the file, or navigate to that element in the Containment tree. Right-click the file and from the shortcut menu, choose Select in Containment Tree. If there is more than one element in the file, you will be offered to choose the needed element.

You can activate the filter mode in the File tab to display the files impacted by the element which you select in the Containent tree.


To display files related with the selected element


  • In the Files tab toolbar, click Filter on Selection.


From the Files tab, you can open the generated files in the default editor configured for that file type on your machine. If no default application is associated with the file type, you will be prompted to choose one.

Code viewer

The code viewer opens when you double click a file in the Files tab. The code viewer is read-only.

In the open code viewer, you can see the highlighted markers where the selected element is used in the file.


To view the markers


  1. In the Files tab, right-click the needed file.
  2. In the shortcut menu, click Select in Containment Tree.

You can also navigate from the code viewer to the element in the Containment tree from which the code was generated.


To navigate to the element in the Containment tree


  1. In the open code viewer, hover over the id near the @generated_from.

  2. In the displayed tooltip, click the element name.

Software Producer Logs

In the Software Producer Log panel, you can see the messages of the running SPO.

In the following table, the actions to enhance the navigation in this window are explained:

IconNameDescription

Scroll to the Start

Scrolls to the tip of the panel.

Scroll to the EndScrolls to the bottom of the panel.

Lock PositionBy default, when some new logs are printed, the scrollbar goes down. If the user wants to prevent the panel to be scrolled automatically to the bottom, he can click on this button.

ClearClears the panel.

Show Log FileOpens the file where the logs are written (each project has its own log file).

Show TimestampAdds a timestamp as a prefix to the messages.

Show Additional MessagesShows more messages related to the SOP client.

Level combo boxShows the messages of the selected level, hide the others. By default, All levels is selected to display all types of messages. Other available types are: Info, Error, Warning.

FindHighlights the search results and navigate to them

A log file for general Software Producer messages not related to a specific project is stored next to the modeling tool log file.

At the bottom right corner of the modeling tool, in the progress bar, you can see whether the generation is running. After the generation is completed, the notification is displayed in case of failure or always if the verbose mode is activated (Environment Options > CATIA Software Producer Client General Properties > Notifications section).

Validation Results

When an operation produces a report, the plugin reads it and opens it in a Validation Result window if any element has a diagnostic associated.

A diagnostic is associated with a rule consisting of a severity, message, and source.

You can navigate to the source in the Containment tree.  If you need to show more details concerning the rule or open the full report, right-click the appropriate lines of the table.

You can turn off the Validation Results window's opening after the operation produces a report.


To turn the validation report off


  1. In the modeling tool main menu, click Options and select Project.
  2. Set the Show Validation Report property to false.


When you execute a configuration, before calling the operation the plugin checks the UML Completeness Constraints. If a mandatory property is missing (“elements” in the example below), a validation warning and a notification will be displayed informing which tag value(s) are missing.

Diagrams and Containment tree

The following commands are available from the diagrams toolbar or from the shortcut menu of the supported elements in the Containment tree:

Button

Description

Show in File Explorer

Open a location in your file system wherein the Software Production Operation results file is stored.

Execute Selected Configuration

Runs the code generation for the selected configuration.

Code Generation Result Table

When the option "storeExecutionSummaryInModel" is set to true in the configuration, the results of the execution of the configuration is saved as an object under the configuration inside the model.

You can have an overview of all of these execution objects in the Code Generation Result Table.


To create a table


  1. In the Containment tree, right-click a package.
  2. From the shortcut menu, select Create Diagram.
  3. Search for Code Generation Result Table and click it.

In the Containment tree on the above image, you can see under the configurations that new objects were created:

  • Configuration Execution: for example, "fmu" execution at 2024-08-23T12:47:14.008"
  • Operation Instance: for example, "FMU Middleware Generation"

Those objects are displayed in the Code Generation Result Table. Among other information you can see the duration of each operation and the total duration on the execution, same as for the status.

If you click the Open Logs in the Logs column,  you will see the logs of the selected operation.

If you click the location in the Local Result Path column, your file explorer is opened at the specified location.

Options

Project Options

You can specify Project Options for the CATIA Software Producer Client.

Option nameDefault valueDescription
Workspace path<project_directory>\<project_name>Local workspace path for this project. Bu default, it is next to the project file, and named after it. It is used by default in the local path property of the configurations, represented by the variable <sop.lokal.worspace.path>.
Backup propertytrueIf set to true, then before each generation, the code will be backed-up in the etc/backup folder of the local workspace.
Show validation reporttrueIf set to true, then each time a report will be generated by an operation, the Validation Results Window will be displayed.

Environment Options

You can specify Environment Options for the CATIA Software Producer Client and CATIA Software Producer Client General Properties.

A workspace is automatically created on our cloud servers for each of your projects using the widget. This workspace gathers the assets needed for the generation. A cloud workspace is automatically deleted after 30 days of inactivity. You can also delete it manually in the Environment Options dialog. If you delete the workspace, all the components will have to be regenerated on the cloud on your next session because you will not be able to push any files to a workspace through the plugin.

To monitor the CATIA Software Producer Client workspaces, you must login to the platform first.


Option nameDefault valueDescription
Enable Software GovernancetrueEnable Software Governance to manage generated code in SCM repositories. 
Activate Smart Launch ModefalseActivate Smart Launch Mode to execute the operations only when a change is detected.
Activate Verbose ModefalseActivate Verbose Mode to get more notifications during the generation process,
Show next time the question to clean lock filestrueIf set to false, deletion of local files previously generated by the configuration will be done (in the clean and full generated mode) without asking for it in a dialog to the user. 

Additional Information

You can switch projects (or even shut down your computer, saving your work first) while waiting for the generation result as it is running on the cloud and as the widget keeps the IDs of the cloud assets in the record files located in <local workspace path>\etc\operations\spoRecordFile.json (you will have access to it if you need it, for example, for the debugging purpose). When you come back, another dialog will tell you that operations were running while you were away and will propose you inspect the result and download it.