Chapter 14. Developing a Base Communication

Table of Contents

14.1. A Note on Base Types Checks
14.1.1. Base Connectors and Field Types
14.1.2. Overriding Base Type Checks
14.1.3. Implementing Base Type Checks
14.2. Developing the MLBaseOwner Module and the BaseMessenger Class
14.2.1. Creating the BaseCommunication Project in the Wizard
14.2.2. Adding New Files
14.2.3. Adding References to the New Files in MLBaseCommunication.pro
14.2.4. Adding Contents to BaseMessenger.h
14.2.5. Add Contents to BaseMessenger.cpp
14.2.6. Editing MLBaseCommunicationInit.cpp
14.2.7. Editing mlBaseOwner.h
14.2.8. Editing mlBaseOwner.cpp
14.2.9. Making MLBaseCommunication classes known
14.2.10. Adding an object wrapper for MLBaseCommunication objects
14.3. Developing the SoBaseReceiver Module
14.3.1. Creating the New Open Inventor Module with the Wizard
14.3.2. Editing SoBaseReceiver.pro
14.3.3. Edit SoBaseReceiver.h
14.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 14.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:

14.1. A Note on Base Types Checks

14.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 14.2. Mouse-over Information for Base Connectors

Mouse-over Information for Base Connectors

Figure 14.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.

In the following example, BaseBypass forwards the input Base type “WEM” and therefore cannot be connected to CSOManager, whose connector only allows “CSOList”:

Figure 14.4. Base Field Connection Checked for Type Compatibility

Base Field Connection Checked for Type Compatibility

14.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 the workspace: While drawing the connection with the mouse, override the blocking by pressing CTRL. The connection is established and drawn in red to signal the type incompatibility.

  • 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 in the .mlab file.

14.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 14.2.8.1, “Adding the construction of a new BaseMessenger Object” and Section 14.3.4, “Editing SoBaseReceiver.cpp.