Chapter 15. Developing a Base Communication

Table of Contents

15.1. A Note on Base Types Checks
15.1.1. Base Connectors and Field Types
15.1.2. Overriding Base Type Checks
15.1.3. Implementing Base Type Checks
15.2. Developing the MLBaseOwner Module and the BaseMessenger Class
15.2.1. Creating the BaseCommunication Project in the Wizard
15.2.2. Adding New Files
15.2.3. Adding References to the new Files in CMakeLists.txt
15.2.4. Adding Contents to BaseMessenger.h
15.2.5. Add Contents to BaseMessenger.cpp
15.2.6. Editing MLBaseCommunicationInit.cpp
15.2.7. Editing mlBaseOwner.h
15.2.8. Editing mlBaseOwner.cpp
15.2.9. Making MLBaseCommunication classes known
15.2.10. Adding an object wrapper for MLBaseCommunication objects
15.3. Developing the SoBaseReceiver Module
15.3.1. Creating the New Open Inventor Module with the Wizard
15.3.2. Editing CMakeLists.txt of SoBaseReceiver
15.3.3. Edit SoBaseReceiver.h
15.3.4. Editing SoBaseReceiver.cpp

In the following chapter, we will develop an ML module owning a Base object in combination with an Open Inventor module that will display the contents of the Base object.

Purpose of this example:

The class Base is briefly referred to in the ML Guide, chapter Base Objects.

This will be our resulting network:

Figure 15.1. Example Network for ML Module and an Open Inventor Module

Example Network for ML Module and an Open Inventor Module

The data processing works as follows:

The example will be implemented with these elements:

Why this way of implementation?

The example is created in the following chapters:

15.1. A Note on Base Types Checks

15.1.1. Base Connectors and Field Types

When drawing a connection in MeVisLab, it is checked whether the basic connector type fits (MLImage, Base, Open Inventor). If not, a “blocked” sign appears.

As Base objects can be of different derived types, it is possible to connect Base fields with incompatible types, which might result in errors. To prevent this, the allowed Base object type(s) can be added to the Base field in the C++ source of the module. The allowed Base types are then displayed in the mouse-over information of a Base connector. This is especially helpful in cases where more than one Base connector is available.

Figure 15.2. Mouse-over Information for Base Connectors

Mouse-over Information for Base Connectors

Figure 15.3. Mouse-over Information for Different Base Connectors in One Module

Mouse-over Information for Different Base Connectors in One Module

When connecting Base fields, the allowed types are checked and the connection is only possible for types in the allowed-list. This check also happens when connecting fields across macro modules, as the input/output fields of a macro “inherit” the allowed-list of the connected module fields.

While drawing a connection, the incompatible connectors are grayed out; if the connection is about to be dropped on an incompatible connector, the intermediate connection rendering is displayed in red.

Figure 15.4. Base Field Connection Checked for Type Compatibility

Base Field Connection Checked for Type Compatibility

15.1.2. Overriding Base Type Checks

Sometimes it is useful to establish a connection although the Base field types are not compatible. For example, if the allowed types are set incorrectly in C++ when the module is still in development.

Three override methods are available:

  • In scripting: Drawing the Base connection in scripting always works. However, scripting functions are available to check whether the types match: allowedTypesByString() and matchesTypes(MLABMLBaseField *field), see the MLABMLBaseField Class Reference.

  • In the .mlab file: Base connections can always be created by editing the .mlab file manually.

15.1.3. Implementing Base Type Checks

Implementing the Base typ check is done in the C++ source.

To add an allowed type to a Base field, add the following C++ template method:

_myBaseField->addAllowedType<CSOList>();

There is a convenience template function available to set the initial value and the allowed type at the same time, especially if the initial value is not NULL:

_myBaseField->setBaseValueAndAddAllowedType(&_myOutputValue);

This derives the allowed type from the argument, but the type can also be defined specifically:

_myBaseField->setBaseValueAndAddAllowedType<lutFunction>(&_mySpecialOutputLUT);

It is possible to write

_myBaseField->setBaseValueAndAddAllowedType<lutFunction>(NULL);

but this is basically the same as

_myBaseField->addAllowedType<lutFunction>();

To add an allowed type to a Base field of an Inventor module, add the following C++ template method:

_myBaseField.addAllowedType<CSOList>();   

The addition of checks for allowed Base types is demonstrated in the following example, see Section 15.2.8.1, “Adding the construction of a new BaseMessenger Object” and Section 15.3.4, “Editing SoBaseReceiver.cpp.