Skip to content

Commit a5e28a5

Browse files
committed
Review comments resolved
1 parent 18e5959 commit a5e28a5

2 files changed

Lines changed: 38 additions & 41 deletions

File tree

mevislab.github.io/content/tutorials/image_processing/cpp_1.md

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: "Example 1: Creating a New ML Module for Adding Values"
2+
title: "Example 1: Creating a New ML Module for Adding a Value to Each Voxel"
33
date: 2026-03-15T08:56:33+02:00
44
status: "OK"
55
draft: false
@@ -8,36 +8,36 @@ tags: ["Advanced", "Tutorial", "Image Processing", "C++"]
88
menu:
99
main:
1010
identifier: "cpp1"
11-
title: "Example 1: Creating a New ML Module for Adding Values"
11+
title: "Example 1: Creating a New ML Module for Adding a Value to Each Voxel"
1212
weight: 602
1313
parent: "cpp"
1414
---
1515

16-
# Example 1: Creating a New ML Module for Adding Values
16+
# Example 1: Creating a New ML Module for Adding a Value to Each Voxel
1717

1818
## Precondition
1919
Make sure to have [cmake](https://cmake.org/download) installed. This example has been created using CMake Legacy Release (3.31.11).
2020

2121
## Introduction
22-
In this example, we develop our own C++ ML module which adds a constant value to each voxel of the given input image.
22+
In this example, we develop our own C++ ML module, which adds a constant value to each voxel of the given input image.
2323

2424
## Steps to Do
2525
### Create a new ML Module
2626
Before creating the module, make sure to have your own user package available. See [Package creation](tutorials/basicmechanisms/macromodules/package/) for details about Packages.
2727

28-
Use the *Project Wizard* via menu entry {{< menuitem "File" "Run Project Wizard ..." >}} to create a new ML module. Select *ML Module* and click *Run Wizard*.
28+
Use the *Project Wizard* via the menu entry {{< menuitem "File" "Run Project Wizard ..." >}} to create a new ML module. Select *ML Module* and click *Run Wizard*.
2929

3030
![ML Module Project Wizard](images/tutorials/image_processing/cpp/cpp1_1.png "ML Module Project Wizard")
3131

3232
Enter properties of your new module and give your module the name `SimpleAdd`. Make sure to select your user package and name your project *SimpleAdd*.
3333

3434
![ML Module Properties](images/tutorials/image_processing/cpp/cpp1_2.png "ML Module Properties")
3535

36-
Click *Next*. The next screen of the wizard allows you to define the inputs and outputs of your module. Select *Module Type* as *New style ML Module*, make sure to have one in- and one output and leave the rest of the settings unchanged.
36+
Click *Next*. The next screen of the Wizard allows you to define the inputs and outputs of your module. Select *Module Type* as *New style ML Module*, make sure to have one input and one output and leave the rest of the settings unchanged.
3737

3838
![ML Module Properties](images/tutorials/image_processing/cpp/cpp1_3.png "ML Module Properties")
3939

40-
Click *Next*. On the next screen, we can define some additional properties of our module. Select *Add activateAttachments()*, unselect *Acc configuration hints* and select *Add MDL window with fields*.
40+
Click *Next*. On the next screen, we can define some additional properties of our module. Select *Add activateAttachments()*, unselect *Add configuration hints* and select *Add MDL window with fields*.
4141

4242
![ML Module Additional Properties](images/tutorials/image_processing/cpp/cpp1_4.png "ML Module Additional Properties")
4343

@@ -49,7 +49,7 @@ Click *Next*. The Module Field Interface allows you to define additional fields
4949

5050
![ML Module Field Interface](images/tutorials/image_processing/cpp/cpp1_5.png "ML Module Field Interface")
5151

52-
Click *Create*. You see a screen showing the results of the module creation process. In case the Wizard finished succesfully, you can close the window. Additionally an explorer window opens showing the created folder containing your sources and the *CMakeLists.txt*.
52+
Click *Create*. You see a screen showing the results of the module creation process. In the case the Wizard finished succesfully, you can close the window. Additionally, an explorer window opens showing the created folder containing your sources and the *CMakeLists.txt*.
5353

5454
The foundation of the module has been created with the Wizard. From here on, the programming starts.
5555

@@ -62,13 +62,13 @@ Just make sure that the MLAB_ROOT environment variable is set on your system and
6262

6363
Open a commandline and change to your current module directory (the directory containing your *CMakeLists.txt* file). Enter **cmake . -G "Visual Studio 17"**. After execution, a lot of files are generated by CMake.
6464

65-
For further documentation about our use of CMake see: [CMake for MeVisLab - Documentation](https://mevislabdownloads.mevis.de/docs/current/MeVisLab/Resources/Documentation/Publish/SDK/CMakeManual/#mainBook).
65+
For further documentation about our use of CMake, see: [CMake for MeVisLab - Documentation](https://mevislabdownloads.mevis.de/docs/current/MeVisLab/Resources/Documentation/Publish/SDK/CMakeManual/#mainBook).
6666

6767
### Programming the Functions of the ML Module
68-
Open the file *ALL_BUILD.vcxproj* in your preferred C++ development environment. Select the file *mlSimpleAdd.cpp*.
68+
Open the file *ALL_BUILD.vcxproj* in your preferred C++ development environment. Select the file *mlSimpleAdd.cpp*.
6969

7070
{{<alert class="info" caption="Note">}}
71-
In the following code examples, the comment lines already available in the created .cpp file are added for better overview.
71+
In the following code examples, the comment lines already available in the created *.cpp* file are added for better overview.
7272
{{</alert>}}
7373

7474
#### Implementing *calculateOutputImageProperties*
@@ -92,14 +92,14 @@ void SimpleAdd::calculateOutputImageProperties(int /*outputIndex*/, PagedImage*
9292

9393
// Change properties of output image outputImage here whose
9494
// defaults are inherited from the input image 0 (if there is one).
95-
// get the constant add value
95+
// Get the constant add value.
9696
const MLdouble constantValue = _constantValueFld->getDoubleValue();
9797

98-
// get input image's min and max values
98+
// Get the input image's minimum and maximum values.
9999
const MLdouble inMinValue = getInputImage(0)->getMinVoxelValue();
100100
const MLdouble inMaxValue = getInputImage(0)->getMaxVoxelValue();
101101

102-
// set the output image's min and max values
102+
// Set the output image's minimum and maximum values.
103103
outputImage->setMinVoxelValue(inMinValue + constantValue);
104104
outputImage->setMaxVoxelValue(inMaxValue + constantValue);
105105

@@ -111,7 +111,7 @@ void SimpleAdd::calculateOutputImageProperties(int /*outputIndex*/, PagedImage*
111111
{{</highlight>}}
112112
113113
{{<alert class="info" caption="Note">}}
114-
*outputIndex* is the index number of the output connector. It is commented out in this example, because we only defined one output. In case of more than one outputs, uncomment this parameter.
114+
*outputIndex* is the index number of the output connector. It is commented out in this example, because we only defined one output. In the case of more than one outputs, uncomment this parameter.
115115
{{</alert>}}
116116
117117
#### Implementing *typedCalculateOutputSubImage*
@@ -124,7 +124,7 @@ Next, we are going to finally change the voxel values of the image. Open the fil
124124
```
125125
{{</highlight>}}
126126

127-
Then change the inner line of the loop, so that the constant value is added to the value of the input voxel:
127+
Then, change the inner line of the loop, so that the constant value is added to the value of the input voxel:
128128

129129
{{< highlight filename="mlSimpleAddOutputImageHandler.cpp" >}}
130130
```c++
@@ -136,20 +136,20 @@ Then change the inner line of the loop, so that the constant value is added to t
136136
```
137137
{{</highlight>}}
138138
139-
Compile the project (this includes all module files) in the development environment. Make sure to select a *Release* build.
139+
Compile the project in the development environment. Make sure to select a *Release* build.
140140
141-
### Use your module in MeVisLab
142-
Your compiled *.dll is available in your project directory under *Sources/lib*. In order to use it in MeVisLab, it needs to be copied to the *lib* folder of your user package.
141+
### Use Your Module in MeVisLab
142+
Your compiled **.dll* is available in your project directory under *Sources/lib*. In order to use it in MeVisLab, it needs to be copied to the *lib* folder of your user package.
143143
144144
You can either do this manually or via PostBuild step.
145145
146-
In case MeVisLab was running during development, restart MeVisLab and use your new module.
146+
In the case MeVisLab was running during development, restart MeVisLab and use your new module.
147147
148148
For testing purposes, you can use a `LocalImage` module and two `View2D` modules. Connect the `SimpleAdd` module to the second `View2D` and change the <field>Constant Value</field> field.
149149
150150
![Testing Network](images/tutorials/image_processing/cpp/cpp1_6.png "Testing Network")
151151
152-
The output image of the module `SimpleAdd` is automatically re-calculated on changing the field <field>Constant Value</field>. This is already implemented in the generated code of the file below:
152+
The output image of the module `SimpleAdd` is automatically recalculated on changing the field <field>Constant Value</field>. This is already implemented in the generated code of the file below:
153153
154154
{{< highlight filename="mlSimpleAdd.cpp" >}}
155155
```c++
@@ -177,5 +177,5 @@ The output image of the module `SimpleAdd` is automatically re-calculated on cha
177177

178178
## Summary
179179
* MeVisLab allows to develop your own C++ modules.
180-
* The Project Wizard already generates all necessary *.cpp and *.h files and a loop through all voxels of the input image.
181-
* Changes of user defined fields automatically lead to a recalculation of the input image.
180+
* The Project Wizard already generates all necessary \**.cpp* and \**.h* files and a loop through all voxels of the input image.
181+
* Changes of user-defined fields automatically lead to a recalculation of the input image.
Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: "Developing your own C++ Modules"
2+
title: "Developing Your Own C++ Modules"
33
date: 2026-03-15T08:56:33+02:00
44
status: "OK"
55
draft: false
@@ -8,32 +8,32 @@ tags: ["Advanced", "Tutorial", "Image Processing", "C++"]
88
menu:
99
main:
1010
identifier: "cpp"
11-
title: "Developing your own C++ Modules"
11+
title: "Developing Your Own C++ Modules"
1212
weight: 601
1313
parent: "imageprocessing"
1414
---
1515

16-
# C++ Module development
16+
# C++ Module Development
1717
## Introduction
18-
The development of your own C++ modules can be done by ML modules and by Inventor modules.
18+
The development of your own C++ modules can be done by ML modules and by Open Inventor modules.
1919

2020
{{<alert class="info" caption="Important Information">}}
2121
Make sure to use a compiler that is compatible to your currently installed MeVisLab version.
2222
{{</alert>}}
2323

24-
### ML modules on the C++ level
24+
### ML Modules on the C++ Level
2525
* Image processing modules are objects derived from class Module defined in the ML library and therefore are also called ML modules.
2626
* Image inputs and outputs are connectors to objects of class PagedImage, which are defined in the ML library.
2727
* Inputs and outputs for abstract data structures are connectors to pointers of objects derived from class Base and are called Base objects.
2828

29-
### Inventor modules on the C++-level:
30-
* Most Inventor modules are objects derived from class SoNode defined in the Open Inventor library.
31-
* Inventor inputs and outputs are connectors to objects derived from class SoNode defined in the Open Inventor library. Many Inventor modules will return themselves as outputs (“self”). On inputs, they may have connectors to child Inventor modules.
32-
* Some Inventor modules are objects derived from class SoEngine. They are used for calculations and return their output not via output connectors but via fields.
33-
* Inventor modules may also have input and output connectors to Base objects and Image objects.
34-
* All standard Inventor nodes defined in the Open Inventor library are available in MeVisLab as Inventor modules.
29+
### Open Inventor Modules on the C++ Level
30+
* Most Open Inventor modules are objects derived from class SoNode defined in the Open Inventor library.
31+
* Open Inventor inputs and outputs are connectors to objects derived from class SoNode defined in the Open Inventor library. Many Open Inventor modules will return themselves as outputs (“self”). On inputs, they may have connectors to child Open Inventor modules.
32+
* Some Open Inventor modules are objects derived from class SoEngine. They are used for calculations and return their output not via output connectors but via fields.
33+
* Open Inventor modules may also have input and output connectors to Base objects and Image objects.
34+
* All standard Open Inventor nodes defined in the Open Inventor library are available in MeVisLab as Open Inventor modules.
3535

36-
This chapter describes some examples for developing your own ML and Inventor modules.
36+
This chapter describes some examples for developing your own ML and Open Inventor modules.
3737

3838
## Some Tips for Module Design
3939
### Macro Modules or C++ Modules?
@@ -46,23 +46,20 @@ In [Example 2: Macro Modules](tutorials/basicmechanisms/macromodules/), we alrea
4646
* scripting possible on the module or network level
4747
* scripting supported by the Scripting Assistant View (basically a recorder for actions performed on the network)
4848

49-
**Disadvantages:**
50-
* With macros, only existing functionalities and algorithms can be used.
51-
5249
**Conclusion:**
5350
* For rapid prototyping based on existing image processing algorithms, use macros.
5451
* For implementing new image processing, write new ML or Open Inventor modules.
5552

5653
### Combining Functionalities
5754
It is possible to have ML and Open Inventor connectors in the same module. Two cases are possible:
5855
* Type 1: **ML -> visualization:** Image data or properties are displayed by a visualization module. Usually a <field>SoSFXVImage</field> field gets random access to an ML image by *getTile()*. Examples: `SoView2D`, `GlobalStatistics`.
59-
* Type 2: **visualization -> ML:** Modules generate an ML image from an Inventor scene. Examples: `VoxelizeInventorScene`, `SoExaminerViewer` (hidden functionality).
56+
* Type 2: **visualization -> ML:** Modules generate an ML image from an Open Inventor scene. Examples: `VoxelizeInventorScene`, `SoExaminerViewer` (hidden functionality).
6057

6158
Generally, however, it is not always a good solution to combine that, as the processes of image processing and image visualization are usually separated.
6259

6360
Therefore, rather separate the ML and Open Inventor functionalities into two modules. This way,
6461
* functionality is encapsulated and can be reused as module
6562
* modules for the single steps may already be available in MeVisLab and spare you a new development
6663

67-
## Code examples
68-
In addition to the tutorials in this chapter, you can find additional code examples in your MeVisLab installation directory.
64+
## Code Examples
65+
In addition to the tutorials in this chapter, you can find additional code examples in your MeVisLab installation directory.

0 commit comments

Comments
 (0)