Table of Contents
MLBaseOwner
Module and the BaseMessenger
ClassCMakeLists.txt
BaseMessenger.h
BaseMessenger.cpp
MLBaseCommunicationInit.cpp
mlBaseOwner.h
mlBaseOwner.cpp
MLBaseCommunication
classes knownMLBaseCommunication
objectsSoBaseReceiver
ModuleIn 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:
shows how to implement an ML module without any image processing functionality (no input/output image, hence no calculateOutputSubImage
etc.).
shows the use of an object derived from Base
for communication between two modules.
shows how to use an object derived from Base
in an ML module and in an Open Inventor module.
The class Base
is briefly referred to in the ML Guide, chapter “Base Objects”.
This will be our resulting network:
The data processing works as follows:
The ML module offers fields for parameterizing a simple scene.
The parameters are 'transported' by a Base object to another module.
The receiving Open Inventor module renders a simple scene on base of the parameters set in the module with fields.
The example will be implemented with these elements:
an MLBaseOwner
module
a BaseMessenger
class
a SoBaseReceiver
module
Why this way of implementation?
Separating the owner module from the receiver/visualization module is a lot more flexible than integrating the functionality — this way, it is possible to use several receivers/visualization modules with one messenger.
The separation also means that the receiver does not have to know anything about the owner.
Having an class derived from Base
enables wrapping it as a scripting object so it can be used in Python directly. Have a look at the scripting example for wrapping the BaseMessenger.
The example is created in the following chapters:
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.
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.
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.
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
”.
© 2024 MeVis Medical Solutions AG