diff --git a/mevislab.github.io/content/examples/basic_mechanisms/contour_filter/index.md b/mevislab.github.io/content/examples/basic_mechanisms/contour_filter/index.md index 4f5bfc392..0079a1aa1 100644 --- a/mevislab.github.io/content/examples/basic_mechanisms/contour_filter/index.md +++ b/mevislab.github.io/content/examples/basic_mechanisms/contour_filter/index.md @@ -11,7 +11,7 @@ This example shows how to create a contour filter. Images are loaded via `ImageLoad` module and visualized unchanged in a `View2D` module *View2D1*. Additionally, the images are modified by a local macro module `Filter` and shown in another `View2D` viewer *View2D*. -In order to display the same slice (unchanged and changed), the module `SyncFloat` is used to synchronize the field value *startSlice* in both viewers. The `SyncFloat` module duplicates the value *Float1* to the field *Float2* if it differs by *Epsilon*. +In order to display the same slice (unchanged and changed), the module `SyncFloat` is used to synchronize the field value startSlice in both viewers. The `SyncFloat` module duplicates the value Float1 to the field Float2 if it differs by Epsilon. ![Screenshot](examples/basic_mechanisms/contour_filter/image.png) diff --git a/mevislab.github.io/content/examples/basic_mechanisms/macro_modules_and_module_interaction/example1/index.md b/mevislab.github.io/content/examples/basic_mechanisms/macro_modules_and_module_interaction/example1/index.md index aa3f30bbd..5dc96939d 100644 --- a/mevislab.github.io/content/examples/basic_mechanisms/macro_modules_and_module_interaction/example1/index.md +++ b/mevislab.github.io/content/examples/basic_mechanisms/macro_modules_and_module_interaction/example1/index.md @@ -10,7 +10,7 @@ This example contains an entire package structure. Inside, you can find the exam ## Summary A new macro module `Filter` has been created. Initially, macro modules do not provide an own panel containing user interface elements such as buttons. The *Automatic Panel* is shown on double-clicking the module providing the name of the module. -In this example we update the *.script* file of the `Filter` module to display the kernel selection field of the `Convolution` module within its network. +In this example we update the *.script* file of the `Filter` module to display the Kernel field of the `Convolution` module within its network. {{}} Changes applied to fields in the macro module's panel are applied to their internal network as well. diff --git a/mevislab.github.io/content/tutorials/basicmechanisms.md b/mevislab.github.io/content/tutorials/basicmechanisms.md index b3ecdcb43..63ecf6740 100644 --- a/mevislab.github.io/content/tutorials/basicmechanisms.md +++ b/mevislab.github.io/content/tutorials/basicmechanisms.md @@ -27,11 +27,11 @@ Additional information on the basics of MeVisLab are explained {{< docuLinks "/R ### Loading Data {#TutorialLoadingData} First, we need to load the data we would like to work on, e.g., a CT scan. In MeVisLab, modules are used to perform their associated specific task: they are the basic entities you will be working with. Each module has a different functionality for processing, visualization, and interaction. Connecting modules enables the development of complex processing pipelines. You will get to know different types of modules throughout the course of this tutorial. -Starting off, we will add the module `ImageLoad` to our network to load our data. The module can be found by typing its name into the search bar on the top-right corner and is added to your network by clicking it. +Starting off, we will add the module `ImageLoad` to our network to load our data. The module can be found by typing its name into the search bar on the top-right corner and is added to your network by clicking it {{< mousebutton "left" >}}. ![Search for ImageLoad](images/tutorials/basicmechanics/BM_01.png "Search for ImageLoad") -Next, we select and load the data we'd like to process. Double-click the module `ImageLoad` to open its panel. You can browse through your folders to select the data you'd like to open. Example data can be found in the MeVisLab DemoData directory *$(InstallDir)/Packages/MeVisLab/Resources/DemoData* located in the MeVisLab installation path. Select a file, for example, an MRI scan of a shoulder *Shoulder_Fracture.tif*. The image is loaded immediately and basic information of the loaded image can be seen in the Panel. +Next, we select and load the data we'd like to process. Double-click {{< mousebutton "left" >}} the module `ImageLoad` to open its panel. You can browse through your folders to select the data you'd like to open. Example data can be found in the MeVisLab DemoData directory *$(InstallDir)/Packages/MeVisLab/Resources/DemoData* located in the MeVisLab installation path. Select a file, for example, an MRI scan of a shoulder *Shoulder_Fracture.tif*. The image is loaded immediately and basic information of the loaded image can be seen in the Panel. {{}} There also are modules to load multiple other formats of data. These are the most common ones: @@ -45,7 +45,7 @@ For a more detailed description on loading DICOM images, see {{< docuLinks "/Res [//]: <> (MVL-651) ### The Output Inspector and the Module Inspector {#The_Output_Inspector_and_the_Module_Inspector} -To inspect and visualize the loaded data, we can use the Output Inspector located in the {{< docuLinks "/Resources/Documentation/Publish/SDK/MeVisLabManual/ch04s09.html" "Views" >}} area. You can already interact with the image using the mouse wheel {{< mousebutton "middle" >}} and mouse buttons {{< mousebutton "left" >}} / {{< mousebutton "right" >}}. To preview the image, click on the triangle on the top side of the module `ImageLoad`, which offers the module's output. All module outputs can be found at the top side of the respective module. +To inspect and visualize the loaded data, we can use the Output Inspector located in the {{< docuLinks "/Resources/Documentation/Publish/SDK/MeVisLabManual/ch04s09.html" "Views" >}} area. You can already interact with the image using the mouse wheel {{< mousebutton "middle" >}} and mouse buttons {{< mousebutton "left" >}} / {{< mousebutton "right" >}}. To preview the image, click {{< mousebutton "left" >}} on the triangle on the top side of the module `ImageLoad`, which offers the module's output. All module outputs can be found at the top side of the respective module. You can now inspect your image in 2D: @@ -53,9 +53,9 @@ You can now inspect your image in 2D: ![Output Inspector](images/tutorials/basicmechanics/BM_03.png "Output Inspector") -Your image does not look like this? One reason might be that the slice of the image you are looking at has no information. Click on the Output Inspector and scroll through the slices (this process is called "Slicing") by using the mouse wheel {{< mousebutton "middle" >}}. Still not seeing anything? Then, try to adjust the contrast of the given image by keeping the right mouse button {{< mousebutton "right" >}} pressed while moving the mouse. +Your image does not look like this? One reason might be that the slice of the image you are looking at has no information. Click {{< mousebutton "left" >}} on the Output Inspector and scroll through the slices (this process is called "Slicing") by using the mouse wheel {{< mousebutton "middle" >}}. Still not seeing anything? Then, try to adjust the contrast of the given image by keeping the right mouse button {{< mousebutton "right" >}} pressed while moving the mouse. -You are not restricted to 2D. The Output Inspector offers a 3D View of most loaded images. Try to click on the 3D tab located in the Output Inspector. The 3D display of the image can be rotated by left-clicking on the image and moving the courser around. The little cube in the lower right corner of the viewer shows the orientation of the image. +You are not restricted to 2D. The Output Inspector offers a 3D View of most loaded images. Try to click {{< mousebutton "left" >}} on the 3D tab located in the Output Inspector. The 3D display of the image can be rotated by left-clicking {{< mousebutton "left" >}} on the image and moving the courser around. The little cube in the lower right corner of the viewer shows the orientation of the image. {{}} * A = anterior, front @@ -66,7 +66,7 @@ You are not restricted to 2D. The Output Inspector offers a 3D View of most load * F = feet {{}} -Below the Output Inspector, you'll find the Module Inspector. The Module Inspector displays properties and parameters of the selected module. Parameters are stored in so called **Fields**. Using the Module Inspector, you can examine different fields of your `ImageLoad` module. The module has, for example, the fields *filename* (the path the loaded image is stored in), as well as *sizeX*, *sizeY*, and *sizeZ* (the extent of the loaded image). +Below the Output Inspector, you'll find the Module Inspector. The Module Inspector displays properties and parameters of the selected module. Parameters are stored in so called **Fields**. Using the Module Inspector, you can examine different fields of your `ImageLoad` module. The module has, for example, the fields filename (the path the loaded image is stored in), as well as sizeX, sizeY, and sizeZ (the extent of the loaded image). ![Module Inspector](images/tutorials/basicmechanics/BM_04.png "Module Inspector") @@ -79,7 +79,7 @@ The module `View2D` has one input connector for voxel images (triangle-shaped) You can now display the loaded image in the newly added viewer module by connecting the output of the module `ImageLoad` to the input connector of the module `View2D`. Follow these steps to do so: -1. Click the output connector of `ImageLoad`. +1. Click {{< mousebutton "left" >}} the output connector of `ImageLoad`. 2. Keep the left mouse button {{< mousebutton "left" >}} pressed while dragging the connection to the input connector of `View2D` (white line). @@ -89,7 +89,7 @@ You can now display the loaded image in the newly added viewer module by connect ![Establish connection](images/tutorials/basicmechanics/BM_06.png "Establish connection") -Although the connection is established, no image rendering has started yet. To initialize rendering, open the `View2D` panel by double-clicking on the module. Similar to the Output Inspector, you can scroll through the slices and set different levels of contrast. The amount of displayed annotations is altered by pressing {{< keyboard "A" >}} on the keyboard (annotation-mode). +Although the connection is established, no image rendering has started yet. To initialize rendering, open the `View2D` panel by double-clicking {{< mousebutton "left" >}} on the module. Similar to the Output Inspector, you can scroll through the slices and set different levels of contrast. The amount of displayed annotations is altered by pressing {{< keyboard "A" >}} on the keyboard (annotation-mode). ![View2D Panel](images/tutorials/basicmechanics/BM_07.png "View2D Panel") @@ -104,17 +104,17 @@ Connecting, Disconnecting, Moving, and Replacing Connections is explained in mor [//]: <> (MVL-653) ### Image Processing {#TutorialImageProcessing} -An average kernel will be used to smooth the image as our next step will be to actually process our image. Add the `Convolution` module to your workspace and disconnect the `View2D` module from the `ImageLoad` module by clicking on the connection and pressing {{< keyboard "DEL" >}}. Now, you can build new connections from the module `ImageLoad` to the module `Convolution` and the `Convolution` module to `View2D`. +An average kernel will be used to smooth the image as our next step will be to actually process our image. Add the `Convolution` module to your workspace and disconnect the `View2D` module from the `ImageLoad` module by clicking {{< mousebutton "left" >}} on the connection and pressing {{< keyboard "DEL" >}}. Now, you can build new connections from the module `ImageLoad` to the module `Convolution` and the `Convolution` module to `View2D`. ![Convolution Module](images/tutorials/basicmechanics/BM_08.png "Convolution Module") -Open the panel of the `Convolution` module by double-clicking it. The panel allows configuration of the module. You can adjust parameters or select a kernel. We will be using the *3x3 Average Kernel* for now. +Open the panel of the `Convolution` module by double-clicking {{< mousebutton "left" >}} it. The panel allows configuration of the module. You can adjust parameters or select a kernel. We will be using the *3x3 Average Kernel* for now. ![Select a Kernel](images/tutorials/basicmechanics/BM_09.png "Select a Kernel") The module `View2D` is now displaying the smoothed image. -To compare the processed and unprocessed image, click on the output connector of the module `ImageLoad` to display the original image in the Output Inspector. The Output Inspectors greatest advantage is that it's able to display the output of any connector in the process chain (as long as an interpretable format is used). Simply click the connector or connection to find out more about the module's output. +To compare the processed and unprocessed image, click {{< mousebutton "left" >}} on the output connector of the module `ImageLoad` to display the original image in the Output Inspector. The Output Inspectors greatest advantage is that it's able to display the output of any connector in the process chain (as long as an interpretable format is used). Simply click {{< mousebutton "left" >}} the connector or connection to find out more about the module's output. You can also inspect changes between processed (output connector) and unprocessed (input connector) images by adding a second or even third viewer to your network. "Layers" of applied changes can be inspected next to each other using more than one viewer and placing as well as connecting them accordingly. We will be using a second `View2D` module. Notice how the second viewer is numbered for you to be able to distinguish them better. It might be important to know at this point that numerous connections can be established from one output connector but an input connector can only receive one stream of data. Connect the module `ImageLoad` to the second viewer to display the images twice. You can now scroll through the slices of both viewers and inspect the images. @@ -129,26 +129,26 @@ In order to practice establishing parameter connections, add the `SyncFloat` mod ![SyncFloat Module](images/tutorials/basicmechanics/BM_11.png "SyncFloat Module") -We will be synchronizing the *startSlice* fields of our viewers to be able to directly compare the effect our processing module has on the slices: -Right-click the viewer `View2D` to open its context menu and select {{< menuitem "Show Window" "Automatic Panel" >}}. +We will be synchronizing the startSlice fields of our viewers to be able to directly compare the effect our processing module has on the slices: +Right-click {{< mousebutton "right" >}} the viewer `View2D` to open its context menu and select {{< menuitem "Show Window" "Automatic Panel" >}}. ![Automatic Panel View2D](images/tutorials/basicmechanics/BM_12.png "Automatic Panel View2D") Doing so shows all parameter fields of the module `View2D`. -Search for the field *startSlice*. The field indicates which slice is currently shown in the viewer. If you scroll through the slices of an image, the value of *startSlice* changes. +Search for the field startSlice. The field indicates which slice is currently shown in the viewer. If you scroll through the slices of an image, the value of startSlice changes. -Now, double-click the module `SyncFloat` to open its panel. +Now, double-click {{< mousebutton "left" >}} the module `SyncFloat` to open its panel. -Click on the label *startSlice* in the automatic panel of the module `View2D`, keep the button pressed, and drag the connection to the label *Float1* in the panel of the module `SyncFloat`. +Click {{< mousebutton "left" >}} on the label startSlice in the automatic panel of the module `View2D`, keep the button pressed, and drag the connection to the label Float1 in the panel of the module `SyncFloat`. ![Synchronize StartSlice](images/tutorials/basicmechanics/BM_13.png "Synchronize StartSlice") -The connection is drawn as a thin gray arrow between both modules with the arrowhead pointing to the module that receives the field value as input. The value of the field *startSlice* is now transmitted to the field *Float1*. Changing *startSlice* automatically changes *Float1*, but not the other way round. +The connection is drawn as a thin gray arrow between both modules with the arrowhead pointing to the module that receives the field value as input. The value of the field startSlice is now transmitted to the field Float1. Changing startSlice automatically changes Float1, but not the other way round. ![Parameter Connection StartSlice](images/tutorials/basicmechanics/BM_14.png "Parameter Connection StartSlice") -We will now establish a connection from the module `SyncFloat` to the second viewer, `Viewer2D1`. In order to do that, open the automatic panel `View2D1`. Draw a connection from the label `Float2` of the panel of the module `SyncFloat` to the label *startSlice* in the automatic panel of the module `View2D1`. Lastly, implement a connection between the parameter fields *startSlice* of both viewers. Draw the connection from `View2D1` to `View2D`. +We will now establish a connection from the module `SyncFloat` to the second viewer, `Viewer2D1`. In order to do that, open the automatic panel `View2D1`. Draw a connection from the label Float2 of the panel of the module `SyncFloat` to the label startSlice in the automatic panel of the module `View2D1`. Lastly, implement a connection between the parameter fields startSlice of both viewers. Draw the connection from `View2D1` to `View2D`. ![Synchronize both directions](images/tutorials/basicmechanics/BM_15.png "Synchronize both directions") @@ -159,15 +159,15 @@ As a result, scrolling through the slices with the mouse wheel {{< mousebutton " It is also possible to use the predefined module `SynchroView2D` to accomplish a similar result.(`SynchroView2D`'s usage is described in more detail in [this chapter](tutorials/visualization/visualizationexample1/) ). ### Grouping Modules {#TutorialGroupingModules} -A contour filter can be created based on our previously created network. To finalize the filter, add the modules `Arithmetic2` and `Morphology` to your workspace and connect the modules as shown below. Double-click the module `Arithmetic2` to open its panel. Change the field *Function* of the module `Arithmetic2` to use the function *subtract* in the panel of the module. The contour filter is done now. You can inspect each processing step using the Output Inspector by clicking on the input and output connectors of the respective modules. The final results can be displayed using the viewer modules. If necessary, adjust the contrast by pressing the right mouse button and moving the cursor. +A contour filter can be created based on our previously created network. To finalize the filter, add the modules `Arithmetic2` and `Morphology` to your workspace and connect the modules as shown below. Double-click {{< mousebutton "left" >}} the module `Arithmetic2` to open its panel. Change the field Function of the module `Arithmetic2` to use the function subtract in the panel of the module. The contour filter is done now. You can inspect each processing step using the Output Inspector by clicking {{< mousebutton "left" >}} on the input and output connectors of the respective modules. The final results can be displayed using the viewer modules. If necessary, adjust the contrast by pressing the right mouse button and moving the cursor. ![Grouping modules](images/tutorials/basicmechanics/BM_17.png "Grouping modules") -If you'd like to know more about specific modules, search for help. You can do this by right-clicking the module and select help, which offers an example network and further information about the selected module in particular. +If you'd like to know more about specific modules, search for help. You can do this by right-clicking {{< mousebutton "right" >}} the module and select {{< menuitem "Help" >}}, which offers an example network and further information about the selected module in particular. ![Module Help](images/tutorials/basicmechanics/BM_18.png "Module Help") -To be able to better distinguish the image processing pipeline, you can encapsulate it in a group: select the three modules, for example, by dragging a selection rectangle around them. Then, right-click the selection to open the context menu and select {{< menuitem "Add to New Group" >}}. +To be able to better distinguish the image processing pipeline, you can encapsulate it in a group: select the three modules, for example, by dragging a selection rectangle around them. Then, right- {{< mousebutton "right" >}} the selection to open the context menu and select {{< menuitem "Add to New Group" >}}. ![Add modules to new group](images/tutorials/basicmechanics/BM_19.png "Add to new group") @@ -192,12 +192,12 @@ You have probably already noticed how the modules differ in color. Each color re * Green modules are Open Inventor modules: they enable visual 3D scene graphs. * Brown modules are called macro modules. Macro modules encapsulate a whole network in a single module. -To condense our filter into one single module, we will now be creating a macro module out of it. To do that, right-click on the group's title and select *Convert To Local Macro*. Name your new macro module and finish. You just created a local macro module. Local macros can only be used from networks in the same or any parent directory. +To condense our filter into one single module, we will now be creating a macro module out of it. To do that, right-click {{< mousebutton "right" >}} on the group's title and select {{< menuitem "Convert To Local Macro" >}}. Name your new macro module and finish. You just created a local macro module. Local macros can only be used from networks in the same or any parent directory. ![Convert to local macro](images/tutorials/basicmechanics/BM_21.png "Convert to local macro") ![Your first local macro](images/tutorials/basicmechanics/BM_22.png "Your first local macro") -Right-click the macro module and select *Show Internal Network* to inspect and change the internal network. You can change the properties of the new macro module by changing the properties in the internal network. You can, for example, right-click the module `Convolution` and change the kernel. These changes will be preserved. +Right-click {{< mousebutton "right" >}} the macro module and select {{< menuitem "Show Internal Network" >}} to inspect and change the internal network. You can change the properties of the new macro module by changing the properties in the internal network. You can, for example, click {{< mousebutton "left" >}} the module `Convolution` and change the kernel. ![Internal Network of your local macro](images/tutorials/basicmechanics/BM_23.png "Internal Network of your local macro") diff --git a/mevislab.github.io/content/tutorials/basicmechanisms/coordinatesystems/coordinatesystems2.md b/mevislab.github.io/content/tutorials/basicmechanisms/coordinatesystems/coordinatesystems2.md index 31a89fa19..d54567cd6 100644 --- a/mevislab.github.io/content/tutorials/basicmechanisms/coordinatesystems/coordinatesystems2.md +++ b/mevislab.github.io/content/tutorials/basicmechanisms/coordinatesystems/coordinatesystems2.md @@ -49,11 +49,11 @@ Another option for Python is [pydicom](https://pydicom.github.io/). {{}} ## Orthogonal Views -The module `OrthoView2D` provides a 2D view displaying the input image in three orthogonal viewing directions. By default, the view is configured as *Cube* where the transverse view is placed in the top right segment, sagittal in bottom left, and coronal in bottom right segment. Use the left mouse button to set a position in the data set. This position will be displayed in all available views and is available as field *worldPosition*. +The module `OrthoView2D` provides a 2D view displaying the input image in three orthogonal viewing directions. By default, the view is configured as *Cube* where the transverse view is placed in the top right segment, sagittal in bottom left, and coronal in bottom right segment. Use the left mouse button to set a position in the data set. This position will be displayed in all available views and is available as field worldPosition. ![OrthoView2D](images/tutorials/basicmechanics/OrthoView2D.png "OrthoView2D") -As already learned in the previous example [1.1: MeVisLab Coordinate Systems](tutorials/basicmechanisms/coordinatesystems/coordinatesystems), world and voxel positions are based on different coordinate systems. Selecting the top left corner of any of your views will not show a world position of (0, 0, 0). You can move the mouse cursor to the voxel position (0, 0, 0) as seen in the image information of the viewers in brackets *(x, y, z)*. The field *worldPosition* then shows the location of the image in world coordinate system (see `Info` module). +As already learned in the previous example [1.1: MeVisLab Coordinate Systems](tutorials/basicmechanisms/coordinatesystems/coordinatesystems), world and voxel positions are based on different coordinate systems. Selecting the top left corner of any of your views will not show a world position of *(0, 0, 0)*. You can move the mouse cursor to the voxel position *(0, 0, 0)* as seen in the image information of the viewers in brackets *(x, y, z)*. The field worldPosition then shows the location of the image in world coordinate system (see `Info` module). ![OrthoView2D Voxel- and World Position](images/tutorials/basicmechanics/OrthoView2D_WorldPosition.png "OrthoView2D Voxel- and World Position") diff --git a/mevislab.github.io/content/tutorials/basicmechanisms/macromodules.md b/mevislab.github.io/content/tutorials/basicmechanisms/macromodules.md index 1e8483517..89cb286fe 100644 --- a/mevislab.github.io/content/tutorials/basicmechanisms/macromodules.md +++ b/mevislab.github.io/content/tutorials/basicmechanisms/macromodules.md @@ -98,7 +98,7 @@ Parameter Fields allow users to control the behavior of the internal network. Th You have two options when adding fields to your macro module: * **Define your own fields:** You can define your own fields by specifying their name, type, and default value in the *.script* file. This allows you to provide custom parameters for your macro module, tailored to your specific needs. These parameters can be use as input from the user or output from the modules processing. -* **Reuse fields from the internal network:** Instead of defining your own field, you can expose an existing field from one of the modules of your internal network. To do this, you reference the *internalName* of the internal field you want to reuse. This makes the internal field accessible at the macro module level, allowing users to interact with it directly without duplicating parameters. Changes of the field value are automatically applied in your internal network. +* **Reuse fields from the internal network:** Instead of defining your own field, you can expose an existing field from one of the modules of your internal network. To do this, you reference the internalName of the internal field you want to reuse. This makes the internal field accessible at the macro module level, allowing users to interact with it directly without duplicating parameters. Changes of the field value are automatically applied in your internal network. ![Inputs, Outputs, and Fields](images/tutorials/basicmechanics/fields.png "Inputs, Outputs, and Fields") diff --git a/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/guidesign.md b/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/guidesign.md index 5b4f481d4..6742050de 100644 --- a/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/guidesign.md +++ b/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/guidesign.md @@ -34,7 +34,7 @@ More information about GUI design in MeVisLab can be found {{< docuLinks "/Resou ### Creation of a Module Panel In [Example 2.2](tutorials/basicmechanisms/macromodules/globalmacromodules) we created the global macro module `Filter`. By now, this module does not have a proper panel. When double-clicking {{< mousebutton "left" >}} the module, the *Automatic Panel* is shown. -The *Automatic Panel* contains fields, as well as module inputs and outputs. In this case, no fields exists except the *instanceName*. Accordingly, there is no possibility to interact with the module. Only the input and the output of the module are given. +The *Automatic Panel* contains fields, as well as module inputs and outputs. In this case, no fields exists except the instanceName. Accordingly, there is no possibility to interact with the module. Only the input and the output of the module are given. ![Automatic Panel](images/tutorials/basicmechanics/GUI_10.png "Automatic Panel") @@ -65,7 +65,7 @@ Interface { {{}} ##### Module Inputs and Outputs -To create an input/output, you need to define a *Field* in the respective input/output section. Each input/output gets a name (here *input0/output0*) that you can use to reference this field. The module input maps to an input of the internal network. You need to define this mapping. In this case, the input of the macro module `Filter` maps to the input of the module `Convolution` of the internal network (*internalName = Convolution.input0*). Similarly, you need to define which output of the internal network maps to the output of the macro module `Filter`. In this example, the output of the internal module `Arithmethic2` maps to the output of our macro module `Filter` (*internalName = Arithmetic2.output0*). +To create an input/output, you need to define a *Field* in the respective input/output section. Each input/output gets a name (here input0/output0) that you can use to reference this field. The module input maps to an input of the internal network. You need to define this mapping. In this case, the input of the macro module `Filter` maps to the input of the module `Convolution` of the internal network (internalName = Convolution.input0). Similarly, you need to define which output of the internal network maps to the output of the macro module `Filter`. In this example, the output of the internal module `Arithmethic2` maps to the output of our macro module `Filter` (internalName = Arithmetic2.output0). Creating an input/output causes: 1. Input/output connectors are added to the module. @@ -76,7 +76,7 @@ Creating an input/output causes: ![Internal Network of your macro module](images/tutorials/basicmechanics/BM_23.png "Internal Network of your macro module") ##### Module Fields -In the *Parameters* section, you can define *fields* of your macro module. These fields may map to existing fields of the internal network (*internalName = ...* ), but they do not need to and can also be completely new. You can reference these fields when creating a panel, to allow interactions with these fields. All fields appear in the *Automatic Panel*. +In the *Parameters* section, you can define *fields* of your macro module. These fields may map to existing fields of the internal network (internalName = ...), but they do not need to and can also be completely new. You can reference these fields when creating a panel, to allow interactions with these fields. All fields appear in the *Automatic Panel*. ### Module Panel Layout To create your own user interface, we need to create a {{< docuLinks "/Resources/Documentation/Publish/SDK/MDLReference/index.html#mdl_Window" "Window" >}}. A window is one of the layout elements that exist in MDL. These layout elements are called {{< docuLinks "/Resources/Documentation/Publish/SDK/MDLReference/index.html#Controls" "controls" >}}. The curled brackets define the window section, in which you can define properties of the window and insert further controls like a {{< docuLinks "/Resources/Documentation/Publish/SDK/MDLReference/index.html#mdl_Box" "Box" >}}. @@ -186,19 +186,13 @@ You can add the module `GUIExample` to your workspace and play around with is. {{}} #### Access to Existing Fields of the Internal Network -To interact with fields of the internal network in your user interface, we -need to access these fields. To access the field of the internal module -`Convolution`, which defines the kernel, we need to use the internal -network name. To find the internal field name, open the internal network of the macro module `Filter` (click on the module using the middle mouse button {{< mousebutton "middle" >}}). +To interact with fields of the internal network in your user interface, we need to access these fields. To access the field of the internal module `Convolution`, which defines the Kernel, we need to use the internal network name. To find the internal field name, open the internal network of the macro module `Filter` (click on the module using the middle mouse button {{< mousebutton "middle" >}}). -Then, open the panel of the module `Convolution` and right-click {{< mousebutton "right" >}} the field title *Use* of the box *Predefined Kernel* and select *Copy Name*. You now copied the internal network name of the field to your clipboard. The name is made up of *ModuleName.FieldName*, in this case *Convolution.predefKernel*. +Then, open the panel of the module `Convolution` and right-click {{< mousebutton "right" >}} the field title Use of the box *Predefined Kernel* and select Copy Name. You now copied the internal network name of the field to your clipboard. The name is made up of *ModuleName.FieldName*, in this case Convolution.predefKernel. ![Convolution Module](images/tutorials/basicmechanics/Convolution.png "Convolution Module") -In the panel of the module `Convolution`, you can change this variable *Kernel* via a drop-down menu. In -MDL, a drop-down menu is called a {{< docuLinks "/Resources/Documentation/Publish/SDK/MDLReference/index.html#mdl_ComboBox" "ComboBox" >}}. We can take over the field *predefKernel*, its drop-down menu and all its properties by -creating a new field in our panel and reference to the internal -field *Convolution.predefKernel*, which already exist in the internal network. +In the panel of the module `Convolution`, you can change this variable Kernel via a drop-down menu. In MDL, a drop-down menu is called a {{< docuLinks "/Resources/Documentation/Publish/SDK/MDLReference/index.html#mdl_ComboBox" "ComboBox" >}}. We can take over the field predefKernel, its drop-down menu and all its properties by creating a new field in our panel and reference to the internal field Convolution.predefKernel, which already exist in the internal network. Changes of the properties of this field can be done in the curled brackets using tags (here, we changed the title). @@ -220,7 +214,7 @@ Window MyWindowName { ![Selecting the kernel](images/tutorials/basicmechanics/SelectingKernel.png "Selecting the kernel") -As an alternative, you can define the field *kernel* in the *Parameters* section, and reference the defined field by its name. The result in the panel is the same. You can see a difference in the automatic panel. All fields that are defined in the interface in the *Parameters* section appear in the automatic panel. Fields of the internal network, which are used but not declared in the section *Parameters* of the module interface, do not appear in the automatic panel. +As an alternative, you can define the field kernel in the *Parameters* section, and reference the defined field by its name. The result in the panel is the same. You can see a difference in the automatic panel. All fields that are defined in the interface in the *Parameters* section appear in the automatic panel. Fields of the internal network, which are used but not declared in the section *Parameters* of the module interface, do not appear in the automatic panel. {{< highlight filename="Filter.script" >}} ```Stan @@ -272,7 +266,7 @@ Window MyWindowName { ``` {{}} -The *wakeupCommand* defines a Python function that is executed as soon as the Window is opened. The Button *command* is executed when the user clicks on the Button. +The *wakeupCommand* defines a Python function that is executed as soon as the Window is opened. The Button *command* is executed when the user clicks {{< mousebutton "left" >}} on the Button. Both commands reference a Python function that is executed whenever both actions (open the Window or click the Button) are executed. diff --git a/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/helpfiles.md b/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/helpfiles.md index 6db1b06dc..0cee8f097 100644 --- a/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/helpfiles.md +++ b/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/helpfiles.md @@ -37,13 +37,7 @@ We will start by creating a help file using the built-in text editor {{< docuLin ![Edit module help file via MATE](images/tutorials/basicmechanics/GUI_07.png "Edit module help file via MATE") -When creating the help file of a module, all important information of the -module down to the field specifications are extracted and created automatically. Thus, the -basic module information is always available in the module -help. Additional documentation should be added by the module's author. On the left -side, you can find the outline of the help file. Each section can be -edited. In this example, we added the purpose of the module -to the help file. +When creating the help file of a module, all important information of the module down to the field specifications are extracted and created automatically. Thus, the basic module information is always available in the module help. Additional documentation should be added by the module's author. On the left side, you can find the outline of the help file. Each section can be edited. In this example, we added the purpose of the module to the help file. ![Edit module help file via MATE](images/tutorials/basicmechanics/GUI_08.png "Edit module help file via MATE") @@ -69,7 +63,7 @@ Depending on the way the macro module was created, more or less features are aut {{}} ### Creation of an Example Network -To add an example network to your module, you need to add a reference to the respective *.mlab* file to the module definition file (*.def*). Open the file *Filter.def*. You can find the line *exampleNetwork = "$(LOCAL)/networks/FilterExample.mlab"*, which defines the reference to the *.mlab* file containing the example network. By default, the name of the example network is *ModulenameExample.mlab*. An *.mlab* file containing only the module *Filter* is created inside the folder *networks*. +To add an example network to your module, you need to add a reference to the respective *.mlab* file to the module definition file (*.def*). Open the file *Filter.def*. You can find the line *exampleNetwork = "$(LOCAL)/networks/FilterExample.mlab"*, which defines the reference to the *.mlab* file containing the example network. By default, the name of the example network is *ModulenameExample.mlab*. An *.mlab* file containing only the module `Filter` is created inside the folder *networks*. It is possible that the reference to the example network or the file *FilterExample.mlab* is missing. One reason could be that its creation was not selected when creating the macro module. In this case, add the reference and the file manually. diff --git a/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/itemmodelview.md b/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/itemmodelview.md index cbfda6c6d..1fde27d0b 100644 --- a/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/itemmodelview.md +++ b/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/itemmodelview.md @@ -97,7 +97,7 @@ Interface { ``` {{}} -If you now open your panel, you should see the *Input* *inImage* and the just created *Fields*. The *Field* *id* is necessary to identify unique objects in your *ItemModel* later. In order to make this example easier to understand, we defined all types of the *Fields* as *String*. You can also use different types, if you like. +If you now open your panel, you should see the *Input* inImage and the just created *Fields*. The *Field* id is necessary to identify unique objects in your *ItemModel* later. In order to make this example easier to understand, we defined all types of the *Fields* as *String*. You can also use different types, if you like. ![Module Input and Fields](images/tutorials/basicmechanics/ItemModel_5.png "Module Input and Fields") @@ -128,7 +128,7 @@ Window { ``` {{}} -Every *Field* that we defined in the *Parameters* section is now used as a column in our view. The *Field* *id* has been defined to be the *idAttribute*. If you now open your panel, MeVisLab will complain that you did not define the *Field* *myItemModel*. You have to add a *Field* with this name to your *Parameters* section or as an *Output Field*. We will add an *Output Field*, so that our model can also be used by other modules, if necessary. The type is *MLBase*. +Every *Field* that we defined in the *Parameters* section is now used as a column in our view. The *Field* id has been defined to be the idAttribute. If you now open your panel, MeVisLab will complain that you did not define the *Field* myItemModel. You have to add a *Field* with this name to your *Parameters* section or as an *Output Field*. We will add an *Output Field*, so that our model can also be used by other modules, if necessary. The type is *MLBase*. {{< highlight filename="MyItemModelView.script" >}} ```Stan @@ -145,7 +145,7 @@ Your module now also shows an output *MLBase* object and the columns you defined ![Module Output and Columns](images/tutorials/basicmechanics/ItemModel_6.png "Module Output and Columns") ### Fill Your Table with Data -We want to get the necessary information from the defined input image *inImage*. We want the module to update the content whenever the input image changes. Therefore, we need a *Field Listener* calling a Python function whenever the input image changes. Add it to your *Commands* section. +We want to get the necessary information from the defined input image inImage. We want the module to update the content whenever the input image changes. Therefore, we need a *Field Listener* calling a Python function whenever the input image changes. Add it to your *Commands* section. {{< highlight filename="MyItemModelView.script" >}} ```Stan @@ -254,7 +254,7 @@ class MyItemModel: ``` {{}} -You can see that the above Python code uses a field *selection* that contains the ID of the selected item in our table. We have to add this *Field* to our *.script* file, too. +You can see that the above Python code uses a field selection that contains the ID of the selected item in our table. We have to add this *Field* to our *.script* file, too. {{< highlight filename="MyItemModelView.script" >}} ```Stan @@ -364,7 +364,7 @@ If you now open the panel of your module, you can already see the results. The first line shows the information of the patient, the study and the series and each child item represents a single slice of the image. ## Interact With Your Model -We can now add options to interact with the *ItemModelView*. Open the *.script* file of your module and go to the *Commands* section. We add a *FieldListener* to our *selection* field. Whenever the user selects a different item in our view, the Python function *itemClicked* in the *FieldListener* is executed. +We can now add options to interact with the *ItemModelView*. Open the *.script* file of your module and go to the *Commands* section. We add a *FieldListener* to our selection field. Whenever the user selects a different item in our view, the Python function *itemClicked* in the *FieldListener* is executed. {{< highlight filename="MyItemModelView.script" >}} ```Stan @@ -406,7 +406,7 @@ The *itemClicked* function uses *id* from the selected item to get the value of ![Clicked Item](images/tutorials/basicmechanics/ItemModel_8.png "Clicked Item") -The problem is that the *Field* *selection* also changes whenever a new item is added to the model. Your debug output is already flooded with SOP Instance UIDs without interaction. +The problem is that the *Field* selection also changes whenever a new item is added to the model. Your debug output is already flooded with SOP Instance UIDs without interaction. ![Debug Output](images/tutorials/basicmechanics/ItemModel_9.png "Debug Output") diff --git a/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/pythonscripting.md b/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/pythonscripting.md index 0061dfb35..c0c117915 100644 --- a/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/pythonscripting.md +++ b/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/pythonscripting.md @@ -110,7 +110,7 @@ If you now use the menu item {{< menuitem "Scripting" "Start Network Script" >}} Under {{< menuitem "View" "Views" "Scripting Assistant" >}} you can find the view *Scripting Assistant*. In this view, the actions you execute in the workspace are translated into Python script. -For example: Open the *Scripting Assistant*. Add the module `WEMInitialize` to your workspace. You can select a *Model*, for example, the cube. In addition, you can change the *Translation* and press *Apply*. All these actions can be seen in the *Scripting Assistant* translated into Python code. Therefore, the *Scripting Assistant* is a powerful tool to help you to script you actions. +For example: Open the *Scripting Assistant*. Add the module `WEMInitialize` to your workspace. You can select a Model, for example, the cube. In addition, you can change the Translation and press *Apply*. All these actions can be seen in the *Scripting Assistant* translated into Python code. Therefore, the *Scripting Assistant* is a powerful tool to help you to script you actions. ![Scripting Assistant](images/tutorials/basicmechanics/Scripting_01.png "Scripting Assistant") diff --git a/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/scriptingexample1.md b/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/scriptingexample1.md index f0bbfc3a7..b9d45e868 100644 --- a/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/scriptingexample1.md +++ b/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/scriptingexample1.md @@ -30,8 +30,8 @@ In this example, we like to dynamically change the color of a cube in an Open In ### Scripting Using the Module `RunPythonScript` Open the panel of `RunPythonScript`. There is an option to display input and output fields. For that, tick the box *Fields* on the top left side of the panel. -You can also name these fields individually by ticking the box *Edit field titles*. Call the first input field *TimeCounter* and draw a parameter connection from the field *Value* of the panel of `TimeCounter` to the input field *TimeCounter* of the module `RunPythonScript`. -We can name the first output field *DiffuseColor* and draw a parameter connection from this field to the field *Diffuse Color* in the panel of the module `SoMaterial`. +You can also name these fields individually by ticking the box *Edit field titles*. Call the first input field TimeCounter and draw a parameter connection from the field Value of the panel of `TimeCounter` to the input field TimeCounter of the module `RunPythonScript`. +We can name the first output field DiffuseColor and draw a parameter connection from this field to the field Diffuse Color in the panel of the module `SoMaterial`. ![TimeCounter](images/tutorials/basicmechanics/Scripting_07.png "TimeCounter") @@ -49,7 +49,7 @@ updateOutputValue("DiffuseColor", str(red) + " " + str(green) + " " + str(blue)) ``` {{}} -To update the output field *DiffuseColor*, it is important to use the methods *updateOutputValue(name, value)* or *setOutputValue(name, value)* instead of simply assigning a value to the output field. +To update the output field DiffuseColor, it is important to use the methods *updateOutputValue(name, value)* or *setOutputValue(name, value)* instead of simply assigning a value to the output field. You can now see a color change in the viewer `SoExaminerViewer` every time the `TimeCounter` counts. diff --git a/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/scriptingexample2.md b/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/scriptingexample2.md index 72974f9c7..8877b139f 100644 --- a/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/scriptingexample2.md +++ b/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/scriptingexample2.md @@ -85,28 +85,18 @@ Window { ![Panel with Tabs and Viewers](images/tutorials/basicmechanics/PanelWithTabsAndViewers.png "Panel with Tabs and Viewers") ### Edit Viewer Settings in the Panel -You may want to change the design setting of the right viewer. This is -still possible via the internal network of the macro module. Open the -internal network either via the context menu or using the middle mouse -button {{< mousebutton "middle" >}} and click on the module. After that, open the automatic panel of -the module `SoExaminerViewer` via context menu {{< menuitem "Show Windows" "Automatic Panel" >}} and change the field *decoration* to *False*. Keep in mind, as we did not create CSOs by now, the right viewer stays black. +You may want to change the design setting of the right viewer. This is still possible via the internal network of the macro module. Open the internal network either via the context menu or using the middle mouse button {{< mousebutton "middle" >}} and click on the module. After that, open the automatic panel of the module `SoExaminerViewer` via context menu {{< menuitem "Show Windows" "Automatic Panel" >}} and change the field decoration to *False*. Keep in mind, as we did not create CSOs by now, the right viewer stays black. ![Change viewer settings](images/tutorials/basicmechanics/ChangeViewerSettings.png "Change viewer settings") ![Changed viewer settings](images/tutorials/basicmechanics/ChangedViewerSettings.png "Changed viewer settings") ### Selection of Images -Next, we like to add the option to browse through the folders and select -the image, we like to create CSOs from. This functionality is already given in the internal network in the module `LocalImage`. We can copy this functionality from `LocalImage` and add this option to the panel above both viewers. But, how should we know, which field name we -reference to? To find this out, open the -internal network of your macro module. Now you are able to open the panel of -the module `LocalImage`. Right-click {{< mousebutton "right" >}} the desired field: In this case, right-click the label -*Name:*. Select *Copy Name*, to copy the internal name of this field. +Next, we like to add the option to browse through the folders and select the image, we like to create CSOs from. This functionality is already given in the internal network in the module `LocalImage`. We can copy this functionality from `LocalImage` and add this option to the panel above both viewers. But, how should we know, which field name we reference to? To find this out, open the internal network of your macro module. Now you are able to open the panel of the module `LocalImage`. Right-click {{< mousebutton "right" >}} the desired field: In this case, right-click the label Name. Select {{< menuitem "Copy Name" >}}, to copy the internal name of this field. ![Copy the field name](images/tutorials/basicmechanics/GUI_Exp_09.png "Copy the field name") -Now, you can add this field as a new field to your window by pasting the -name. All field settings are taken over from the internal field from the module `LocalImage`. +Now, you can add this field as a new field to your window by pasting the name. All field settings are taken over from the internal field from the module `LocalImage`. {{< highlight filename="IsoCSOs.script" >}} ```Stan @@ -142,8 +132,7 @@ Window { ![Add name field](images/tutorials/basicmechanics/AddNameField.png "Add name field") ### Add Buttons to Your Panel -As a next step, we like to add a *Browse\...* button, like in the module -`LocalImage`, and also a button to create the CSOs. +As a next step, we like to add a *Browse\...* button, like in the module `LocalImage`, and also a button to create the CSOs. To create the *Browse\...* button: @@ -153,11 +142,10 @@ To create the *Browse\...* button: To create the Iso Generator Button: -We like to copy the field of the *Update* button from the internal module -`IsoCSOGenerator`, but not its layout so: +We like to copy the field of the *Update* button from the internal module `IsoCSOGenerator`, but not its layout so: -1. Create a new Field in the interface, called *IsoGenerator*, which contains the internal field *Update* from the module `IsoCSOGenerator`. -2. Create a new Button in your Window that uses the field *IsoGenerator*. +1. Create a new Field in the interface, called IsoGenerator, which contains the internal field apply from the module `CSOIsoGenerator`. +2. Create a new Button in your Window that uses the field IsoGenerator. After these steps, you can use the Iso Generator button to create CSOs. @@ -230,16 +218,13 @@ def fileDialog(): ![Automatically generate CSOs based on Iso value](images/tutorials/basicmechanics/GUI_Exp_14.png "Automatically generate CSOs based on Iso value") ### Colorizing CSOs -We like to colorize the CSO we hover over with our -mouse in the 2D viewer. Additionally, when clicking a CSO with the left mouse button {{< mousebutton "left" >}}, this CSO shall be colorized in the 3D viewer. This functionality can be implemented via Python -scripting (even though MeVisLab has a build-in function to do that). We -can do this in the following way: +We like to colorize the CSO we hover over with our mouse in the 2D viewer. Additionally, when clicking a CSO with the left mouse button {{< mousebutton "left" >}}, this CSO shall be colorized in the 3D viewer. This functionality can be implemented via Python scripting (even though MeVisLab has a build-in function to do that). We can do this in the following way: 1. Enable the View *Scripting Assistant*, which translates actions into Python code. ![Scripting Assistant](images/tutorials/basicmechanics/GUI_Exp_15.png "Scripting Assistant") -2. Enable a functionality that allows us to notice the ID of the CSO we are currently hovering over with our mouse. For this, open the internal network of our macro module. We will use the module `SoView2DCSOExtensibleEditor`. Open its panel and select the tab *Advanced*. You can check a box to enable *Update CSO id under mouse*. If you now hover over a CSO, you can see its ID in the panel. We can save the internal network to save this functionality, but we can also solve our problem via scripting. The Scripting Assistant translated our action into code that we can use. +2. Enable a functionality that allows us to notice the ID of the CSO we are currently hovering over with our mouse. For this, open the internal network of our macro module. We will use the module `SoView2DCSOExtensibleEditor`. Open its panel and select the tab *Advanced*. You can check a box to enable Update CSO id under mouse. If you now hover over a CSO, you can see its ID in the panel. We can save the internal network to save this functionality, but we can also solve our problem via scripting. The Scripting Assistant translated our action into code that we can use. ![Enabling CSO id identification](images/tutorials/basicmechanics/GUI_Exp_16.png "Enabling CSO id identification") @@ -319,8 +304,7 @@ def colorizeCSO(): ``` {{}} -Reload your module ({{< keyboard "F5" >}}) and open the panel. After generating CSOs, the CSO under your mouse is marked. Clicking this CSO {{< mousebutton "left" >}} enables the marking in the 3D viewer. If you like, you can add some settings to your *Settings* -page. For example: +Reload your module ({{< keyboard "F5" >}}) and open the panel. After generating CSOs, the CSO under your mouse is marked. Clicking this CSO {{< mousebutton "left" >}} enables the marking in the 3D viewer. If you like, you can add some settings to your *Settings* page. For example: {{< highlight filename="IsoCSOs.script" >}} ```Stan diff --git a/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/viewerexample.md b/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/viewerexample.md index 7f25e1e7d..a82f6fcee 100644 --- a/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/viewerexample.md +++ b/mevislab.github.io/content/tutorials/basicmechanisms/macromodules/viewerexample.md @@ -63,7 +63,7 @@ Now, right-click on your *MyViewerApplication* and select {{< menuitem "Related {{< docuLinks "/Resources/Documentation/Publish/SDK/MeVisLabManual/ch26.html" "MATE">}} opens showing your script file. You already learned how to create simple UI elements in [Example 2.4](tutorials/basicmechanisms/macromodules/guidesign). Now, we will create a little more complex UI including your `View2D` and `View3D`. -First we need a new *Field* in your *Parameters* section. Name the field *filepath* and set *internalName* to *ImageLoad.filename*. +First we need a new *Field* in your *Parameters* section. Name the field filepath and set internalName to ImageLoad.filename. {{< highlight filename="MyViewerApplication.script" >}} ``` Stan @@ -79,7 +79,7 @@ Interface { ``` {{}} -We now reuse the *filepath* field from the `ImageLoad` module for our interface. Add a *Window* and a *Vertical* to the bottom of your *.script* file. Add the just created parameter field *filepath* inside your *Vertical* as seen below. +We now reuse the filepath field from the `ImageLoad` module for our interface. Add a *Window* and a *Vertical* to the bottom of your *.script* file. Add the just created parameter field filepath inside your *Vertical* as seen below. {{< highlight filename="MyViewerApplication.script" >}} ``` Stan @@ -98,14 +98,16 @@ Commands { } Window { - Vertical { - Field filepath {} - } + Category { + Vertical { + Field filepath {} + } + } } ``` {{}} -If you now double-click {{< mousebutton "left" >}} on your module, you can see your just created filepath field. +If you now double-click {{< mousebutton "left" >}} on your module, you can see your just created filepath field. ![Filepath field in UI](images/tutorials/basicmechanics/SimpleApp_08.png "Filepath field in UI") @@ -114,35 +116,37 @@ Next, we will add your 2D and 3D viewers and a *Button* to your *Window*. Change {{< highlight filename="MyViewerApplication.script" >}} ``` Stan Window { - Vertical { - Horizontal { - Field filepath {} - Button { - title = "Reset" - - } + Category { + Vertical { + Horizontal { + Field filepath {} + Button { + title = "Reset" + + } + } + Horizontal { + Viewer View2D.self { + type = SoRenderArea + pw = 400 ph = 400 + expandX = yes + expandY = yes + } + Viewer View3D.self { + pw = 400 ph = 400 + expandX = yes + expandY = yes + } + } + } } - Horizontal { - Viewer View2D.self { - type = SoRenderArea - pw = 400 ph = 400 - expandX = yes - expandY = yes - } - Viewer View3D.self { - pw = 400 ph = 400 - expandX = yes - expandY = yes - } - } - } } ``` {{}} We have a vertical layout having two items placed horizontally next to each other. The new *Button* gets the title *Reset* but does nothing yet, because we did not add a Python function to a command. -Additionally, we added the `View2D` and the `View3D` to our *Window* and defined the *height*, *width*, and the *expandX/Y* property to *yes*. This leads our viewers to resize together with our *Window*. +Additionally, we added the `View2D` and the `View3D` to our *Window* and defined the height, width, and the expandX/Y property to *yes*. This leads our viewers to resize together with our *Window*. {{}} Additional information about the `View2D` and `View3D` options can be found in the MeVisLab {{< docuLinks "/Resources/Documentation/Publish/SDK/MDLReference/index.html#mdl_Viewer" "MDL Reference">}} @@ -196,7 +200,7 @@ Commands { ``` {{}} -In the above example, we react on changes of the field *startSlice* of the module `View2D`. Whenever the field value (currently displayed slice) changes, the Python function *printCurrentSliceNumber* is executed. +In the above example, we react on changes of the field startSlice of the module `View2D`. Whenever the field value (currently displayed slice) changes, the Python function *printCurrentSliceNumber* is executed. In your Python file `MyViewerApplication.py`, you can now add the following: @@ -211,7 +215,7 @@ Scrolling through slices in the `View2D` module now logs a message containing th ## Summary * You can add any viewers to your application UI by reusing them in MDL. -* Parameter fields using the *internalName* of an existing field in your network allows reusing this UI element in your own UI. Changes in your UI are applied to the field in the module. +* Parameter fields using the internalName of an existing field in your network allows reusing this UI element in your own UI. Changes in your UI are applied to the field in the module. * Field Listeners allow reacting on changes of a field value in Python. {{< networkfile "examples/basic_mechanisms/viewer_application/viewerexample.mlab" >}} diff --git a/mevislab.github.io/content/tutorials/dataobjects/contours/contourexample6.md b/mevislab.github.io/content/tutorials/dataobjects/contours/contourexample6.md index 01d24b810..8bdb4b7bd 100644 --- a/mevislab.github.io/content/tutorials/dataobjects/contours/contourexample6.md +++ b/mevislab.github.io/content/tutorials/dataobjects/contours/contourexample6.md @@ -76,7 +76,7 @@ If you want to define your static text as a parameter in multiple labels, you ca ![User Data](images/tutorials/dataobjects/contours/Ex6_Parameters.png "User Data") -You can also add multiple CSO editors to see the different options. Add the `SoCSORectangleEditor` module to your workspace and connect it to the `SoGroup` module. As we now have two different editors, we need to tell the `CSOLabelRenderer` which CSO is to be rendered. Open the panel of the `SoCSODistanceLineEditor`. You can see the field *Extension Id* set to *distanceLine*. Open the panel of the `SoCSORectangleEditor`. You can see the field *Extension Id* set to *rectangle*. +You can also add multiple CSO editors to see the different options. Add the `SoCSORectangleEditor` module to your workspace and connect it to the `SoGroup` module. As we now have two different editors, we need to tell the `CSOLabelRenderer` which CSO is to be rendered. Open the panel of the `SoCSODistanceLineEditor`. You can see the field Extension Id set to *distanceLine*. Open the panel of the `SoCSORectangleEditor`. You can see the field Extension Id set to *rectangle*. ![Extension ID](images/tutorials/dataobjects/contours/Ex6_ExtensionID.png "Extension ID") @@ -100,11 +100,11 @@ deviceOffsetY = 0 ![SoCSORectangleEditor](images/tutorials/dataobjects/contours/Ex6_LineAndRectangle.png "SoCSORectangleEditor") -If you now draw new CSOs, you will notice that you still always create distance lines. Open the panel of the `SoView2DCSOExtensibleEditor`. You can see that the *Creator Extension Id* is set to *__default*. By default, the first found eligible editor is used to create a new CSO. In our case this is the `SoCSODistanceLineEditor`. +If you now draw new CSOs, you will notice that you still always create distance lines. Open the panel of the `SoView2DCSOExtensibleEditor`. You can see that the Creator Extension Id is set to *__default*. By default, the first found eligible editor is used to create a new CSO. In our case this is the `SoCSODistanceLineEditor`. ![SoCSORectangleEditor](images/tutorials/dataobjects/contours/Ex6_DefaultExtension.png "SoCSORectangleEditor") -Change *Creator Extension Id* to *rectangle*. +Change Creator Extension Id to *rectangle*. ![SoCSORectangleEditor & SoView2DCSOExtensibleEditor ](images/tutorials/dataobjects/contours/Ex6_8.png "SoCSORectangleEditor & SoView2DCSOExtensibleEditor") @@ -113,7 +113,7 @@ Newly created CSOs are now rectangles. The label values are shown as defined in ![Labeled Rectangle in View2D](images/tutorials/dataobjects/contours/Ex6_9.png "Labeled Rectangle in View2D") {{}} -The *Length* attribute in the context of rectangles represents the perimeter of the rectangle, calculated as *2a + 2b*, where *a* and *b* are the lengths of the two sides of the rectangle. +The *Length* in the context of rectangles represents the perimeter of the rectangle, calculated as *2a + 2b*, where *a* and *b* are the lengths of the two sides of the rectangle. {{}} You will find a lot more information in the `CSOInfo` module for your rectangles. The exact meaning of the values for each type of CSO is explained in the table below. diff --git a/mevislab.github.io/content/tutorials/dataobjects/contours/contourexample7.md b/mevislab.github.io/content/tutorials/dataobjects/contours/contourexample7.md index 31c85fae8..d86083a85 100644 --- a/mevislab.github.io/content/tutorials/dataobjects/contours/contourexample7.md +++ b/mevislab.github.io/content/tutorials/dataobjects/contours/contourexample7.md @@ -52,7 +52,7 @@ The behavior of your network does not change. You can still draw the same CSOs a Open the context menu of your `csoList` module {{< mousebutton "right" >}} and select {{}}. -The MeVisLab text editor MATE opens, showing your *.script* file. You can see the output of your module as *CSOListContainer.outCSOList*. We want to define a threshold for the color of our CSOs. For this, add another field to the *Parameters* section of your script file named *areaThreshold*. Define the *type* as *Float* and *value* as *2000.0*. +The MeVisLab text editor MATE opens, showing your *.script* file. You can see the output of your module as *CSOListContainer.outCSOList*. We want to define a threshold for the color of our CSOs. For this, add another field to the *Parameters* section of your script file named areaThreshold. Define the type as *Float* and value as *2000.0*. In order to call Python functions, we also need a Python file. Add a *Commands* section and define the *source* of the Python file as *$(LOCAL)/csoList.py*. Also add an *initCommand* as *initCSOList*. The initCommand defines the Python function that is called whenever the module is added to the workspace or reloaded. @@ -77,9 +77,9 @@ Commands { ``` {{}} -Right-click {{< mousebutton "right" >}} on the *initCSOList* command and select {{}}. The Python file and the function are generated automatically. +Right-click {{< mousebutton "right" >}} on the *initCSOList* command and select {{< menuitem "Create Python Function initCSOList" >}}. The Python file and the function are generated automatically. -Back in MeVisLab, the new field *areaThreshold* can be seen in Module Inspector when selecting your module. The next step is to write the Python function *initCSOList*. +Back in MeVisLab, the new field areaThreshold can be seen in Module Inspector when selecting your module. The next step is to write the Python function *initCSOList*. ### Write Python Script Whenever the local macro module is added to the workspace or reloaded, new CSOLists shall be created and we need a possibility to update the lists whenever a new CSO has been created or existing contours changed. @@ -107,7 +107,7 @@ def _getCSOList(): The function gets the current CSOList from the output field of the `CSOListContainer`. Initially, it should be empty. If not, we want to start with an empty list; therefore, we remove all existing CSOs. -We also create two new CSO lists: one list for small contours, one list for larger contours, depending on the defined *areaThreshold* from the modules parameter. +We also create two new CSO lists: one list for small contours, one list for larger contours, depending on the defined areaThreshold from the module's fields. Additionally, we also want to define different colors for the CSOs in the lists. Small contours shall be drawn in green, large contours shall be drawn in red. @@ -138,7 +138,7 @@ The function gets all currently existing CSOs from the `CSOListContainer`. Then, The *csoFinished* function again needs all existing contours. We walk through each CSO in the list and remove it from all groups. As we do not know which CSO has been changed from the notification, we evaluate the area of each CSO and add them to the correct list again. -The function *getAreaThreshold* returns the current value of our parameter field *areaThreshold*. +The function *getAreaThreshold* returns the current value of our parameter field areaThreshold. Now, we can call our functions in the *initCSOList* function and test our module. diff --git a/mevislab.github.io/content/tutorials/dataobjects/curves/curvesexample1.md b/mevislab.github.io/content/tutorials/dataobjects/curves/curvesexample1.md index 2320f86f2..bfc0a786a 100644 --- a/mevislab.github.io/content/tutorials/dataobjects/curves/curvesexample1.md +++ b/mevislab.github.io/content/tutorials/dataobjects/curves/curvesexample1.md @@ -38,7 +38,7 @@ Double-click {{}} on the `CurveCreator` module and open the ![CurveCreator Module](images/tutorials/dataobjects/curves/CurveCreatorModule.png "CurveCreator Module") -You can see a large input field *Curve Table*. Here you can enter the x- and y-values of your curve. The values of the first column will become the x-values and the 2nd any further column will become the y-series. Comment lines start with a '#' character. +You can see a large input field Curve Table. Here you can enter the x- and y-values of your curve. The values of the first column will become the x-values and the second column will become the y-series. Comment lines start with a '#' character. Enter the following into the *Curve Table*: {{< highlight filename="Curve Table" >}} diff --git a/mevislab.github.io/content/tutorials/dataobjects/markerobjects.md b/mevislab.github.io/content/tutorials/dataobjects/markerobjects.md index b14c4c4d7..bca3d3ebc 100644 --- a/mevislab.github.io/content/tutorials/dataobjects/markerobjects.md +++ b/mevislab.github.io/content/tutorials/dataobjects/markerobjects.md @@ -21,7 +21,7 @@ To create markers, you can use a marker editor, for example, the `SoView2DMarker ![Create Markers](images/tutorials/dataobjects/markers/DO_Markers_01.png "Create Markers") -Using the `StylePalette` module, you can define a style for your markers. In order to set different styles for different markers, change the field *Color Mode* in the panel of `SoView2DMarkerEditor` to *Index*. +Using the `StylePalette` module, you can define a style for your markers. In order to set different styles for different markers, change the field Color Mode in the panel of `SoView2DMarkerEditor` to *Index*. ![Style of Markers](images/tutorials/dataobjects/markers/DO_Markers_08.png "Style of Markers") diff --git a/mevislab.github.io/content/tutorials/dataobjects/markers/markerexample1.md b/mevislab.github.io/content/tutorials/dataobjects/markers/markerexample1.md index 96da8809d..2fbe51ec5 100644 --- a/mevislab.github.io/content/tutorials/dataobjects/markers/markerexample1.md +++ b/mevislab.github.io/content/tutorials/dataobjects/markers/markerexample1.md @@ -43,12 +43,12 @@ Now, we can place as many red markers as we like, using the left mouse button {{ ![Two Types of Markers](images/tutorials/dataobjects/markers/DO_Markers_05.png "Two Types of Markers") ### Calculate the Distance Between Markers -We like to calculate the minimum and maximum distance of the green marker to all red markers. In order to do this, add the module `DistanceFromXMarkerList` and connect it to `RedMarkerList`. Open the panels of `DistanceFromXMarkerList` and `GreenMarkerList`. Now, draw a parameter connection from the coordinate of the green marker, which is stored in the field *Current Item -> Position* in the panel of `GreenMarkerList`, to the field *Position* of `DistanceFromXMarkerList`. You can now press *Calculate Distance* in the panel of `DistanceFromXMatkerList` to see the result, meaning the distance of the green marker to all red markers in the panel of `DistanceFromXMarkerList`. +We like to calculate the minimum and maximum distance of the green marker to all red markers. In order to do this, add the module `DistanceFromXMarkerList` and connect it to `RedMarkerList`. Open the panels of `DistanceFromXMarkerList` and `GreenMarkerList`. Now, draw a parameter connection from the coordinate of the green marker, which is stored in the field *Current Item* Position in the panel of `GreenMarkerList`, to the field Position of `DistanceFromXMarkerList`. You can now press *Calculate Distance* in the panel of `DistanceFromXMatkerList` to see the result, meaning the distance of the green marker to all red markers in the panel of `DistanceFromXMarkerList`. ![Module DistanceFromXMarkerList](images/tutorials/dataobjects/markers/DO_Markers_06.png "Module DistanceFromXMarkerList") ### Automation of Distance Calculation -To automatically update the calculation when placing a new marker, we need to tell the module `DistanceFromXMarkerList` **when** a new green marker is placed. Open the panels of `DistanceFromXMarkerList` and `GreenMarker` and draw a parameter connection from the field *Currently busy* in the panel of `GreenMarker` to *Calculate Distance* in the panel of `DistanceFromXMarkerList`. If you now place a new green marker, the distance from the new green marker to all red markers is calculated automatically. +To automatically update the calculation when placing a new marker, we need to tell the module `DistanceFromXMarkerList` **when** a new green marker is placed. Open the panels of `DistanceFromXMarkerList` and `GreenMarker` and draw a parameter connection from the field Currently busy in the panel of `GreenMarker` to Calculate Distance in the panel of `DistanceFromXMarkerList`. If you now place a new green marker, the distance from the new green marker to all red markers is calculated automatically. ![Calculation of Distance between Markers](images/tutorials/dataobjects/markers/DO_Markers_07.png "Calculation of Distance between Markers") {{}} diff --git a/mevislab.github.io/content/tutorials/dataobjects/surfaces/surfaceexample3.md b/mevislab.github.io/content/tutorials/dataobjects/surfaces/surfaceexample3.md index 6a715e94f..283bf6449 100644 --- a/mevislab.github.io/content/tutorials/dataobjects/surfaces/surfaceexample3.md +++ b/mevislab.github.io/content/tutorials/dataobjects/surfaces/surfaceexample3.md @@ -64,7 +64,7 @@ Add the modules `WEMInitialize`, `SoWEMRenderer`, and `SoBackground` to your wor ![WEMLoad and SoWEMRenderer](images/tutorials/dataobjects/surfaces/WEMExample3_5.png "WEMLoad and SoWEMRenderer") -You can see the WEM and interact with it in the viewer (zoom, move, and rotate). In the case the object does not rotate around its center, trigger the field *viewAll* of the `SoExaminerViewer`. +You can see the WEM and interact with it in the viewer (zoom, move, and rotate). In the case the object does not rotate around its center, trigger the field viewAll of the `SoExaminerViewer`. Add a `WEMBulgeEditor` and a `SoWEMBulgeEditor` to your network and connect them as seen below. diff --git a/mevislab.github.io/content/tutorials/dataobjects/surfaces/surfaceexample4.md b/mevislab.github.io/content/tutorials/dataobjects/surfaces/surfaceexample4.md index 9c54f5b92..40356991e 100644 --- a/mevislab.github.io/content/tutorials/dataobjects/surfaces/surfaceexample4.md +++ b/mevislab.github.io/content/tutorials/dataobjects/surfaces/surfaceexample4.md @@ -46,7 +46,7 @@ We want to move the object when dragging the plane. Thus, we need to modify the ![Interactive dragging of objects](images/tutorials/dataobjects/surfaces/DO10_03.png "Interactive dragging of objects") -As a next step, we want to adapt the size of the plane to the size of the object we have. Add the modules `WEMInfo` and `DecomposeVector3` to your workspace and open their panels. The module `WEMInfo` presents information about the given WEM, for example, its position and size. The module `DecomposeVector3` splits a 3D vector into its components. Now, draw a parameter connection from *Size* of `WEMInfo` to the vector in `DecomposeVector3`. As a next step, open the panel of `SoCube` and draw parameter connections from the fields *Y* and *Z* of `DecomposeVector3` to *Height* and *Depth* of `SoCube`. Now, the size of the plane adapts to the size of the object. +As a next step, we want to adapt the size of the plane to the size of the object we have. Add the modules `WEMInfo` and `DecomposeVector3` to your workspace and open their panels. The module `WEMInfo` presents information about the given WEM, for example, its position and size. The module `DecomposeVector3` splits a 3D vector into its components. Now, draw a parameter connection from *Size* of `WEMInfo` to the vector in `DecomposeVector3`. As a next step, open the panel of `SoCube` and draw parameter connections from the fields Y and Z of `DecomposeVector3` to Height and Depth of `SoCube`. Now, the size of the plane adapts to the size of the object. ![Interactive dragging of objects](images/tutorials/dataobjects/surfaces/DO10_04.png "Interactive dragging of objects") @@ -59,7 +59,7 @@ For changing the visualization of the dragger plane, add the modules `SoGroup`, ![Interactive dragging of objects](images/tutorials/dataobjects/surfaces/DO10_06.png "Interactive dragging of objects") -We want to switch the visualization of the plane dependent on the mouse position in the viewer. In other words, when hovering over the plane, the plane should be visible, when the mouse is in another position and the possibility to drag the object is not given, the plane should be invisible. We use the module `SoMaterial` to edit the appearance of the plane. Open the panel of the module `SoMITranslate1Dragger`. The box of the field *Highlighted* is ticked when the mouse hovers over the plane. Thus, we can use the field's status to switch between different presentations of the plane. In order to do this, open the panel of `SoSwitch` and draw a parameter connection from *Highlighted* of `SoMITranslate1Dragger` to *Which Child* of `SoSwitch`. +We want to switch the visualization of the plane dependent on the mouse position in the viewer. In other words, when hovering over the plane, the plane should be visible, when the mouse is in another position and the possibility to drag the object is not given, the plane should be invisible. We use the module `SoMaterial` to edit the appearance of the plane. Open the panel of the module `SoMITranslate1Dragger`. The box of the field Highlighted is ticked when the mouse hovers over the plane. Thus, we can use the field's status to switch between different presentations of the plane. In order to do this, open the panel of `SoSwitch` and draw a parameter connection from Highlighted of `SoMITranslate1Dragger` to Which Child of `SoSwitch`. ![Interactive dragging of objects](images/tutorials/dataobjects/surfaces/DO10_06_02.png "Interactive dragging of objects") @@ -74,19 +74,19 @@ When hovering over the plane, the plane becomes visible and the option to move t #### Interactive Object Translation in Three Dimensions We do not only want to move the object in one direction, we like to be able to do interactive object translations in all three dimensions. For this, copy the modules responsible for the translation in one direction and change the properties to enable translations in other directions. -We need to change the size of `SoCube1` and `SoCube2` to form planes that cover surfaces in x- and z-, as well as x- and y-directions. To do that, draw the respective parameter connections from `DecomposeVector3` to the fields of the modules `SoCube`. In addition, we need to adapt the field *Direction* in the panels of the modules `SoMITranslate1Dragger`. +We need to change the size of `SoCube1` and `SoCube2` to form planes that cover surfaces in x- and z-, as well as x- and y-directions. To do that, draw the respective parameter connections from `DecomposeVector3` to the fields of the modules `SoCube`. In addition, we need to adapt the field Direction in the panels of the modules `SoMITranslate1Dragger`. ![Interactive dragging of objects](images/tutorials/dataobjects/surfaces/DO10_09.png "Interactive dragging of objects") Change width, height, and depth of the three cubes, so that each of them represents one plane. The values need to be set to (0, 2, 2), (2, 0, 2), and (2, 2, 0). -As a next step, we like to make sure that all planes always intersect the object, even though the object is moved. To do this, we need to synchronize the field *Translation* of all `SoMIDraggerContainer` modules and the module `WEMModify`. Draw parameter connections from one *Translation* field to the next, as shown below. +As a next step, we like to make sure that all planes always intersect the object, even though the object is moved. To do this, we need to synchronize the field Translation of all `SoMIDraggerContainer` modules and the module `WEMModify`. Draw parameter connections from one Translation field to the next, as shown below. ![Interactive dragging of objects](images/tutorials/dataobjects/surfaces/DO10_10.png "Interactive dragging of objects") -We like to close the loop, so that a change in one field *Translation* causes a change in all the other *Translation* fields. To do this, we need to include the module `SyncVector`. The module `SyncVector` avoids an infinite processing loop causing a permanent update of all fields *Translation*. +We like to close the loop, so that a change in one field Translation causes a change in all the other Translation fields. To do this, we need to include the module `SyncVector`. The module `SyncVector` avoids an infinite processing loop causing a permanent update of all fields Translation. -Add the module `SyncVector` to your workspace and open its panel. Draw a parameter connection from the field *Translation* of the module `SoMIDraggerContainer2` to *Vector1* of `SyncVector`. The field *Vector1* is automatically synchronized to the field *Vector2*. Now, connect the field *Vector2* to the field *Translate* of the module `WEMModify`. Your synchronization network is now established. +Add the module `SyncVector` to your workspace and open its panel. Draw a parameter connection from the field Translation of the module `SoMIDraggerContainer2` to *Vector1* of `SyncVector`. The field Vector1 is automatically synchronized to the field Vector2. Now, connect the field Vector2 to the field Translate of the module `WEMModify`. Your synchronization network is now established. ![Interactive dragging of objects](images/tutorials/dataobjects/surfaces/DO10_11.png "Interactive dragging of objects") @@ -94,7 +94,7 @@ To enable transformations in all directions, we need to connect the modules `SoM ![Interactive dragging of objects](images/tutorials/dataobjects/surfaces/DO10_12.png "Interactive dragging of objects") -As a next step, we like to enlarge the planes to make them exceed the object. For that, add the module `CalculateVectorFromVectors` to your network. Open its panel and connect the field *Size* of `WEMInfo` to *Vector 1*. We like to enlarge the size by one, so we add the vector (1, 1, 1), by editing the field *Vector 2*. Now, connect the *Result* to the field *V* of the module `DecomposeVector3`. +As a next step, we like to enlarge the planes to make them exceed the object. For that, add the module `CalculateVectorFromVectors` to your network. Open its panel and connect the field Size of `WEMInfo` to Vector 1. We like to enlarge the size by one, so we add the vector (1, 1, 1), by editing the field Vector 2. Now, connect the Result to the field V of the module `DecomposeVector3`. ![Interactive dragging of objects](images/tutorials/dataobjects/surfaces/DO10_13.png "Interactive dragging of objects") diff --git a/mevislab.github.io/content/tutorials/dataobjects/surfaces/surfaceexample5.md b/mevislab.github.io/content/tutorials/dataobjects/surfaces/surfaceexample5.md index b1f6a416c..0f4367544 100644 --- a/mevislab.github.io/content/tutorials/dataobjects/surfaces/surfaceexample5.md +++ b/mevislab.github.io/content/tutorials/dataobjects/surfaces/surfaceexample5.md @@ -58,7 +58,7 @@ To translate the LUT values from the PVLs into color, open the panel of `SoLUTEd Our goal is to colorize faces of the *Octasphere* in red if they are close to or even intersect the cubic WEM. And we like to colorize faces of the *Octasphere* in green if these faces are far away from the cubic WEM. -Open the tab *Editor* of the panel of `SoLUTEditor`. This tab allows to interactively select a color for each PVL value. Select the color point on the left side. Its *Position* value is supposed to be 0, so we like to select the *Color* *red* in order to color-code small distances between the WEMs in red. In addition to that, increase the *Opacity* of this color point. Next, select the right color point. Its *Position* is supposed to be 3 and thus equals the value of the field *New Range Max*. As these color points colorize large distances between WEMs, select the *Color* *green*. You can add new color points by clicking on the colorized bar in the panel. Select, for example, the *Color* *yellow* for a color point in the middle. Select and shift the color points to get the desired visualization. +Open the tab *Editor* of the panel of `SoLUTEditor`. This tab allows to interactively select a color for each PVL value. Select the color point on the left side. Its Position value is supposed to be *0*, so we like to set the *Color* to *red* in order to color-code small distances between the WEMs in red. In addition to that, increase the Opacity of this color point. Next, select the right color point. Its Position is supposed to be *3* and thus equals the value of the field New Range Max. As these color points colorize large distances between WEMs, set the Color to *green*. You can add new color points by clicking on the colorized bar in the panel. Select, for example, the Color *yellow* for a color point in the middle. Select and shift the color points to get the desired visualization. ![Changing the LUT](images/tutorials/dataobjects/surfaces/DO12_09.png "Changing the LUT") @@ -67,13 +67,13 @@ Add the module `WEMModify` to your workspace and connect the module as shown. If ![WEMModify](images/tutorials/dataobjects/surfaces/DO12_10.png "WEMModify") ### Interactive Shift of WEMs -As a next step, we like to implement the interactive shift of the WEM. Add the modules `SoTranslateDragger1` and `SyncVector`. Connect all translation vectors: Draw connections from the field *Translate* of `SoTranslateDragger1` to *Vector1* of `SyncVector`, from *Vector2* of `SyncVector` to *Translate* of `WEMModify`, and at last from *Translate* of `WEMModify` to *Translate* of `SoTranslateDragger1`. +As a next step, we like to implement the interactive shift of the WEM. Add the modules `SoTranslateDragger1` and `SyncVector`. Connect all translation vectors: Draw connections from the field Translate of `SoTranslateDragger1` to Vector1 of `SyncVector`, from Vector2 of `SyncVector` to Translate of `WEMModify`, and at last from Translate of `WEMModify` to Translate of `SoTranslateDragger1`. You can now interactively drag the WEM inside the viewer. ![Dragging the WEM](images/tutorials/dataobjects/surfaces/DO12_11.png "Dragging the WEM") -At last, exchange the `WEMInitialize` module showing the cube with `WEMLoad` and load *venus.off*. You can decrease the *Face Alpha* in the panel of `SoWEMRenderer1` to make that WEM transparent. +At last, exchange the `WEMInitialize` module showing the cube with `WEMLoad` and load *venus.off*. You can decrease the Face Alpha in the panel of `SoWEMRenderer1` to make that WEM transparent. ![WEM transparency](images/tutorials/dataobjects/surfaces/DO12_12.png "WEM transparency") diff --git a/mevislab.github.io/content/tutorials/image_processing/image_processing2.md b/mevislab.github.io/content/tutorials/image_processing/image_processing2.md index fac3d6432..9065d6a0d 100644 --- a/mevislab.github.io/content/tutorials/image_processing/image_processing2.md +++ b/mevislab.github.io/content/tutorials/image_processing/image_processing2.md @@ -31,7 +31,7 @@ Add a `LocalImage` and a `SynchroView2D` module to your network and connect the ![Example Network](images/tutorials/image_processing/network_example2a.png "Example Network") -Open the Automatic Panel of the `SynchroView2D` module via context menu {{< mousebutton "right" >}} and selecting {{< menuitem "Show Window" "Automatic Panel" >}}. Set the field *synchLUTs* to *TRUE*. +Open the Automatic Panel of the `SynchroView2D` module via context menu {{< mousebutton "right" >}} and selecting {{< menuitem "Show Window" "Automatic Panel" >}}. Set the field synchLUTs to *Yes*. ![Synchronize LUTs in SynchroView2D](images/tutorials/image_processing/synchLUTs.png "Synchronize LUTs in SynchroView2D") diff --git a/mevislab.github.io/content/tutorials/openinventor.md b/mevislab.github.io/content/tutorials/openinventor.md index 14bb301e5..0f3ff5b25 100644 --- a/mevislab.github.io/content/tutorials/openinventor.md +++ b/mevislab.github.io/content/tutorials/openinventor.md @@ -26,7 +26,7 @@ The names of Open Inventor modules start with the prefix `So\*` (for Scene Objec An exemplary Open Inventor scene will be implemented in the following paragraph. ## Open Inventor Scenes and Execution of Scene Graphs{#sceneGraphs} -Inventor scenes are organized in structures called scene graphs. A scene graph is made up of nodes, which represent 3D objects to be drawn, properties of the 3D objects, nodes that combine other nodes and are used for hierarchical grouping, and others (cameras, lights, etc.). These nodes are accordingly called shape nodes, property nodes, group nodes, and so on. Each node contains one or more pieces of information stored in fields. For example, the `SoSphere` node contains only its radius, stored in its *radius* field. Open Inventor modules function as Open Inventor nodes, so they may have input connectors to add Open Inventor child nodes (modules) and output connectors to link themselves to Open Inventor parent nodes (modules). +Inventor scenes are organized in structures called scene graphs. A scene graph is made up of nodes, which represent 3D objects to be drawn, properties of the 3D objects, nodes that combine other nodes and are used for hierarchical grouping, and others (cameras, lights, etc.). These nodes are accordingly called shape nodes, property nodes, group nodes, and so on. Each node contains one or more pieces of information stored in fields. For example, the `SoSphere` node contains only its radius, stored in its radius field. Open Inventor modules function as Open Inventor nodes, so they may have input connectors to add Open Inventor child nodes (modules) and output connectors to link themselves to Open Inventor parent nodes (modules). {{}} The model below depicts the order in which the modules are traversed. The red arrow indicates the traversal order: from top to bottom and from left to right. The modules are numbered accordingly from 1 to 8. Knowing about the traversal order can be crucial to achieve a certain ouput. diff --git a/mevislab.github.io/content/tutorials/openinventor/camerainteraction.md b/mevislab.github.io/content/tutorials/openinventor/camerainteraction.md index 4d93ff42c..29b7f01c0 100644 --- a/mevislab.github.io/content/tutorials/openinventor/camerainteraction.md +++ b/mevislab.github.io/content/tutorials/openinventor/camerainteraction.md @@ -27,7 +27,7 @@ Add a `SoBackground`, a `SoMaterial` and a `SoOrientationModel` module to your w ![SoRenderArea without camera and lights](images/tutorials/openinventor/Camera_1.png "SoRenderArea without camera and lights") -You cannot interact with your scene and the rendered content is very dark. Open the `SoOrientationModel` and change *Model* to *Skeleton* to see that a little bit better. You can also change the material by using the panel of the `SoMaterial` module. +You cannot interact with your scene and the rendered content is very dark. Open the `SoOrientationModel` and change Model to *Skeleton* to see that a little bit better. You can also change the material by using the panel of the `SoMaterial` module. Add a `SoCameraInteraction` module and connect it between the `SoGroup` and the `SoRenderArea`. @@ -41,7 +41,7 @@ The `SoCameraInteraction` can also be extended by a `SoPerspectiveCamera` or a ` ![SoPerspectiveCamera and SoOrthographicCamera](images/tutorials/openinventor/Camera_3.png "SoPerspectiveCamera and SoOrthographicCamera") -You can now switch between both cameras, but you cannot interact with them in the viewer. Select the `SoCameraInteraction` and toggle *detectCamera*. Now the default camera of the `SoCameraInteraction` is replaced by the camera selected in the `SoSwitch`. +You can now switch between both cameras, but you cannot interact with them in the viewer. Select the `SoCameraInteraction` and toggle detectCamera. Now the default camera of the `SoCameraInteraction` is replaced by the camera selected in the `SoSwitch`. Whenever you change the camera in the switch, you need to detect the new camera in the `SoCameraInteraction`. @@ -49,13 +49,13 @@ Whenever you change the camera in the switch, you need to detect the new camera A `SoPerspectiveCamera` camera defines a perspective projection from a viewpoint. -The viewing volume for a perspective camera is a truncated pyramid. By default, the camera is located at (0, 0, 1) and looks along the negative z-axis; the *Position* and *Orientation* fields can be used to change these values. The *Height Angle* field defines the total vertical angle of the viewing volume; this and the *Aspect Ratio* field determine the horizontal angle. +The viewing volume for a perspective camera is a truncated pyramid. By default, the camera is located at (0, 0, 1) and looks along the negative z-axis; the Position and Orientation fields can be used to change these values. The Height Angle field defines the total vertical angle of the viewing volume; this and the Aspect Ratio field determine the horizontal angle. A `SoOrthographicCamera` camera defines a parallel projection from a viewpoint. This camera does not diminish objects with distance as an SoPerspectiveCamera does. The viewing volume for an orthographic camera is a cuboid (a box). -By default, the camera is located at (0, 0, 1) and looks along the negative z-axis; the *Position* and *Orientation* fields can be used to change these values. The *Height* field defines the total height of the viewing volume; this and the *Aspect Ratio* field determine its width. +By default, the camera is located at *(0, 0, 1)* and looks along the negative z-axis; the Position and Orientation fields can be used to change these values. The Height field defines the total height of the viewing volume; this and the Aspect Ratio field determine its width. Add a `SoCameraWidget` and connect it to your `SoGroup`. @@ -74,7 +74,7 @@ Add a `SoExaminerViewer` to your workspace and connect it to the `SoBackground`, The difference to the `SoRenderArea` can be seen immediately. You can interact with your scene and a light is available initially. -The module also allows you to switch between perspective and orthographic camera by changing the field *cameraType*. +The module also allows you to switch between *perspective* and *orthographic* camera by changing the field cameraType. {{< imagegallery 2 "images/tutorials/openinventor" "SoExaminerViewer_Perspective" "SoExaminerViewer_Orthographic" >}} diff --git a/mevislab.github.io/content/tutorials/openinventor/mouseinteractions.md b/mevislab.github.io/content/tutorials/openinventor/mouseinteractions.md index 79d433f70..3a967f112 100644 --- a/mevislab.github.io/content/tutorials/openinventor/mouseinteractions.md +++ b/mevislab.github.io/content/tutorials/openinventor/mouseinteractions.md @@ -42,7 +42,7 @@ Make sure to configure `SoMouseGrabber` fields as seen below. ![SoMouseGrabber](images/tutorials/openinventor/V5_02.png "SoMouseGrabber") **You can see:** -1. *Button 3*, the right mouse button {{< mousebutton "right" >}}, is tagged as being pressed +1. Button 3, the right mouse button {{< mousebutton "right" >}}, is tagged as being pressed 2. Changes of the mouse coordinates are displayed in the box *Output* ![Mouse Interactions](images/tutorials/openinventor/V5_03.png "Mouse Interactions") diff --git a/mevislab.github.io/content/tutorials/summary/summary1.md b/mevislab.github.io/content/tutorials/summary/summary1.md index 95f4a3bc3..0356adff2 100644 --- a/mevislab.github.io/content/tutorials/summary/summary1.md +++ b/mevislab.github.io/content/tutorials/summary/summary1.md @@ -84,9 +84,9 @@ The result should be a three-dimensional rendering of your image. If the rendering is not immediately applied, click *Apply* in your `IsoSurface` module. {{}} -Define the field instanceName of your `IsoSurface` module as *IsoSurfaceImage* and add another `IsoSurface` module to your network. Set the instanceName to *IsoSurfaceSegmentation* and connect the module to the output of the `CloseGap` module from the image segmentation. Set *IsoValue* to *420*, *Resolution* to *1*, and check *Auto-Update* and *Auto-Apply*. +Define the field instanceName of your `IsoSurface` module as IsoSurfaceImage and add another `IsoSurface` module to your network. Set the instanceName to *IsoSurfaceSegmentation* and connect the module to the output of the `CloseGap` module from the image segmentation. Set IsoValue to *420*, Resolution to *1*, and check Auto-Update and Auto-Apply. -Set instanceName of the `SoWEMRenderer` module to *SoWEMRendererImage* and add another `SoWEMRenderer` module. Set this instanceName to *SoWEMRendererSegmentation* and connect it to the *IsoSurfaceSegmentation* module. Selecting the output of the new `SoWEMRenderer` shows the segmented parts as a 3D object in the output inspector. +Set instanceName of the `SoWEMRenderer` module to *SoWEMRendererImage* and add another `SoWEMRenderer` module. Set this instanceName to *SoWEMRendererSegmentation* and connect it to the `IsoSurfaceSegmentation` module. Selecting the output of the new `SoWEMRenderer` shows the segmented parts as a 3D object in the output inspector. ![Segmentation preview in output inspector](images/tutorials/summary/Example1_7.png "Segmentation preview in output inspector") @@ -103,7 +103,7 @@ Add a `SoSwitch` module to your network. Connect the switch to both of your `SoW ![SoSwitch](images/tutorials/summary/Example1_9.png "SoSwitch") -The default input of the switch is *None*. Your 3D viewer remains black. Using the arrows on the `SoSwitch` allows you to toggle between the segmentation and the image. Input 0 shows the segmented brain, input 1 shows the head. You are now able to toggle between them. A view with both objects is still missing. +The default input of the switch is *None*. Your 3D viewer remains black. Using the arrows on the `SoSwitch` allows you to toggle between the segmentation and the image. Input *0* shows the segmented brain, input *1* shows the head. You are now able to toggle between them. A view with both objects is still missing. {{< imagegallery 2 "images/tutorials/summary" "Example1_Segmentation" "Example1_Image" >}} @@ -111,14 +111,14 @@ Add a `SoGroup` module and connect both `SoWEMRenderer` modules as input. The ou ![SoGroup](images/tutorials/summary/Example1_10.png "SoGroup") -You can now also toggle input 2 of the switch showing both 3D objects. The only problem is: You cannot see the brain because it is located inside the head. Open the `SoWEMRendererImage` module panel and set *faceAlphaValue* to *0.5*. The viewer now shows the head in a semitransparent manner, so that you can see the brain. Certain levels of opacity are difficult to render. Add a `SoDepthPeelRenderer` module and connect it to the semitransparent `SoWEMRendererImage` module. Set *Layers* of the renderer to *1*. +You can now also toggle input *2* of the switch showing both 3D objects. The only problem is: You cannot see the brain because it is located inside the head. Open the `SoWEMRendererImage` module panel and set faceAlphaValue to *0.5*. The viewer now shows the head in a semitransparent manner, so that you can see the brain. Certain levels of opacity are difficult to render. Add a `SoDepthPeelRenderer` module and connect it to the semitransparent `SoWEMRendererImage` module. Set Layers of the renderer to *1*. ![SoDepthPeelRenderer](images/tutorials/summary/Example1_Both.png "SoDepthPeelRenderer") You have a 2D and a 3D viewer now. Let's define the colors of the overlay to be reused for the 3D segmentation. ### Parameter Connections for Visualization -Open the panels of the `SoView2DOverlay` and the `SoWEMRendererSegmentation` module. Draw a parameter connection from *SoView2DOverlay.baseColor* to *SoWEMRendererSegmentation.faceDiffuseColor*. +Open the panels of the `SoView2DOverlay` and the `SoWEMRendererSegmentation` module. Draw a parameter connection from SoView2DOverlay.baseColor to SoWEMRendererSegmentation.faceDiffuseColor. ![Synchronized segmentation colors](images/tutorials/summary/Example1_11.png "Synchronized segmentation colors") diff --git a/mevislab.github.io/content/tutorials/summary/summary3.md b/mevislab.github.io/content/tutorials/summary/summary3.md index 8d2175821..9fb19e5cb 100644 --- a/mevislab.github.io/content/tutorials/summary/summary3.md +++ b/mevislab.github.io/content/tutorials/summary/summary3.md @@ -85,9 +85,9 @@ An overview over the existing layout elements in MeVisLab Definition Language (M ##### Source The *Source Box* shall provide the possibility to select a file for loading into the viewers. You have many options to achieve that in MeVisLab and Python. The easiest way is to reuse the existing field of the `LocalImage` module in your internal network. -Add a field to the *Parameters* section of your *.script* file. Name the field *openFile* and set type to *String* and internalName to *LocalImage.name*. +Add a field to the *Parameters* section of your *.script* file. Name the field openFile and set type to *String* and internalName to LocalImage.name. -Then, add another field to your *Box* for the *Source* and use the field name from *Parameters* section, in this case *openFile*. Set *browseButton = Yes* and *browseMode = open* and save your script. +Then, add another field to your *Box* for the *Source* and use the field name from *Parameters* section, in this case openFile. Set browseButton = *Yes* and browseMode = *open* and save your script. {{< highlight filename=".script" >}} ```Stan @@ -139,9 +139,9 @@ Again, you can preview your user interface in MeVisLab directly. You can already ![Source Box](images/tutorials/summary/Example3_2.png "Source Box") ##### Viewing -Add the two viewer modules to the *Viewing* section of your *.script* file and define their field as *View2D.self* and *SoExaminerViewer.self*. Set *expandX = Yes* and *expandY = Yes* for both viewing modules. We want them to resize in the case the size of the Window changes. +Add the two viewer modules to the *Viewing* section of your *.script* file and define their field as View2D.self and SoExaminerViewer.self. Set expandX = *Yes* and expandY = *Yes for both viewing modules. We want them to resize in the case the size of the Window changes. -Set the 2D viewer's type to *SoRenderArea* and the 3D viewer's type to *SoExaminerViewer* and inspect your new user interface in MeVisLab. +Set the 2D viewer's type to *SoRenderArea* and the 3D viewer's type to *SoExaminerViewer* and inspect your new user interface in MeVisLab. {{< highlight filename=".script" >}} ```Stan @@ -182,9 +182,9 @@ The following shall be accessible as *Field* for our macro module: * Selection for 3D visualization (image, segmentation, or both) * Trigger to reset the application to its initial state -We already defined the filename as a field. Next we want to change the color of the overlay. Add another field to your *Parameters* section as *selectOverlayColor*. Define *internalName = SoView2DOverlay.baseColor* and *type = Color*. You may also define a title for the field, for example, *Color*. +We already defined the filename as a field. Next we want to change the color of the overlay. Add another field to your *Parameters* section as selectOverlayColor. Define internalName = SoView2DOverlay.baseColor and type = *Color*. You may also define a title for the field, for example, *Color*. -The *baseColor* field of the `SoView2DOverlay` already has a parameter connection to the color of the `SoWEMRendererSegmentation`. This has been done in the internal network. The defined color is used for 2D and 3D automatically. +The baseColor field of the `SoView2DOverlay` already has a parameter connection to the color of the `SoWEMRendererSegmentation`. This has been done in the internal network. The defined color is used for 2D and 3D automatically. {{< highlight filename=".script" >}} ```Stan @@ -216,17 +216,25 @@ Interface { The next elements follow the same rules; therefore, the final script will be available at the end for completeness. -In order to set the transparency of the 3D image, we need another field reusing the *SoWEMRendererImage.faceAlphaValue*. Add a field *imageAlpha* to the *Parameters* section. Define *internalName = SoWEMRendererImage.faceAlphaValue*, *type = Integer*, *min = 0*, and *max = 1*. +In order to set the transparency of the 3D image, we need another field reusing the SoWEMRendererImage.faceAlphaValue. Add a field imageAlpha to the *Parameters* section. Define internalName = SoWEMRendererImage.faceAlphaValue, type = *Integer*, min = *0*, and max = *1*. -Add the field to the *Settings Box* and set *step = 0.1* and *slider = Yes*. +{{}} +Setting min and max is not necessary, it is inherited already. +{{}} + +Add the field to the *Settings Box* and set step = *0.1* and slider = *Yes*. -For the `RegionGrowing` threshold, add the field *thresholdInterval* to *Parameters* section and set *type = Integer*, *min = 1*, *max = 100*, and *internalName = RegionGrowing.autoThresholdIntervalSizeInPercent*. +For the `RegionGrowing` threshold, add the field thresholdInterval to *Parameters* section and set type = *Integer*, min = *1*, max = *100*, and internalName = RegionGrowing.autoThresholdIntervalSizeInPercent. + +{{}} +Setting min and max is not necessary, it is inherited already. +{{}} -Add the field to the *Settings* UI, and define *step = 0.1* and *slider = Yes*. +Add the field to the *Settings* UI, and define step = *0.1* and slider = *Yes*. -Define a field *isoValueImage* in the *Parameters* section and set *internalName = IsoSurfaceImage.isoValue*, *type = Integer*, *min = 1*, and *max = 1000*. +Define a field isoValueImage in the *Parameters* section and set internalName = IsoSurfaceImage.isoValue, type = *Integer*, min = *1*, and max = *1000*. -In the *Settings* section of the UI, set *step = 2* and *slider = Yes*. +In the *Settings* section of the UI, set step = *2* and slider = *Yes*. {{< highlight filename=".script" >}} ```Stan @@ -337,13 +345,13 @@ Events can be raised by the user (e.g., by clicking a button) or by the applicat #### 3D Visualization Selection You will now add a selection possibility for the 3D viewer. This allows you to define the visibility of the 3D objects File, Segmented, or Both. -Add another field to your *Parameters* section. Define the field as *selected3DView* and set *type = Enum* and *values =Segmented,File,Both*. +Add another field to your *Parameters* section. Define the field as selected3DView and set type = *Enum* and values to *Segmented*, *File* and *Both*. -Add a *ComboBox* to your *Settings* and use the field name defined above. Set *alignX = Left* and *editable = False* and open the *Window* of the macro module in MeVisLab. +Add a *ComboBox* to your *Settings* and use the field name defined above. Set alignX = *Left* and editable = *No* and open the *Window* of the macro module in MeVisLab. -The values of the field can be selected, but nothing happens in our viewers. We need to implement a *FieldListener* in Python that reacts on any value changes of the field *selected3DView*. +The values of the field can be selected, but nothing happens in our viewers. We need to implement a *FieldListener* in Python that reacts on any value changes of the field selected3DView. -Open your script file and go to the *Commands* section. Add a *FieldListener* and reuse the name of our internal field *selected3DView*. Add a *Command* to the *FieldListener* calling a Python function *viewSelectionChanged*. +Open your script file and go to the *Commands* section. Add a *FieldListener* and reuse the name of our internal field selected3DView. Add a *Command* to the *FieldListener* calling a Python function *viewSelectionChanged*. {{< highlight filename=".script" >}} ```Stan @@ -376,9 +384,9 @@ def viewSelectionChanged(field): The function sets the `SoSwitch` to the child value depending on the selected field value from the *ComboBox* and you should now be able to switch the 3D rendering by selecting an entry in the user interface. #### Setting the Marker -The marker for the `RegionGrowing` is defined by the clicked position as Vector3. Add another field *markerPosition* to the *Parameters* section and define *type = Vector3*. +The marker for the `RegionGrowing` is defined by the clicked position as Vector3. Add another field markerPosition to the *Parameters* section and define type = *Vector3*. -Then, add a trigger field *applyMarker* to your *Parameters* section. Set *type = Trigger* and *title = Add*. +Then, add a trigger field applyMarker to your *Parameters* section. Set type = *Trigger* and title = *Add*. {{< highlight filename=".script" >}} ```Stan @@ -432,16 +440,16 @@ def applyPosition(): ``` {{}} -Whenever the field *markerPosition* changes its value, the value is automatically applied to the *SoView2DMarkerEditor.newPosXYZ*. Clicking *SoView2DMarkerEditor.add* adds the new position to the `SoView2DMarkerEditor` and the region growing starts. +Whenever the field markerPosition changes its value, the value is automatically applied to the SoView2DMarkerEditor.newPosXYZ. Clicking SoView2DMarkerEditor.add adds the new position to the `SoView2DMarkerEditor` and the region growing starts. {{}} -The *Field* *SoView2DMarkerEditor.useInsertTemplate* needs to be set to *True* in order to allow adding markers via Python. +The *Field* SoView2DMarkerEditor.useInsertTemplate needs to be set to *True* in order to allow adding markers via Python. {{}} #### Reset -Add a new field *resetApplication* to the *Parameters* section and set *type = Trigger* and *title = Reset*. +Add a new field resetApplication to the *Parameters* section and set type = *Trigger* and title = *Reset*. -Add another *FieldListener* to your *Commands* and define *command = resetApplication*. +Add another *FieldListener* to your *Commands* and define command = *resetApplication*. Add the field to your *Source* region. @@ -524,7 +532,7 @@ def resetApplication(): ### Information In the end, we want to provide some information about the volume of the segmented area (in ml). -Add one more field to your *Parameters* section and reuse the internal network fields *CalculateVolume.totalVolume*. Set field to *editable = False* +Add one more field to your *Parameters* section and reuse the internal network fields CalculateVolume.totalVolume. Set field to editable = *No*. Add the field to the *Info* section of your window. @@ -586,7 +594,7 @@ Interface { } Field totalVolume { internalName = CalculateVolume.totalVolume - editable = False + editable = No } Field resetApplication { type = Trigger @@ -670,7 +678,7 @@ Window { Field applyMarker {} ComboBox selected3DView { alignX = Left - editable = False + editable = No } } Box Info { diff --git a/mevislab.github.io/content/tutorials/summary/summary4.md b/mevislab.github.io/content/tutorials/summary/summary4.md index 1fdb4ccc3..7adff65ab 100644 --- a/mevislab.github.io/content/tutorials/summary/summary4.md +++ b/mevislab.github.io/content/tutorials/summary/summary4.md @@ -92,11 +92,11 @@ def loadImage(full_path): ``` {{}} -We define the path to a file to be loaded. The function *loadImage* sets the *openFile* field of the `TutorialSummary` module. +We define the path to a file to be loaded. The function *loadImage* sets the openFile field of the `TutorialSummary` module. The arrays for the marker location and color will be used later. -Next, we need a function to check if the loaded image available at the first output of our macro module (*out2D*) is valid. +Next, we need a function to check if the loaded image available at the first output of our macro module (out2D) is valid. {{< highlight filename=".py" >}} ```Python @@ -131,7 +131,7 @@ def setMarkerPosition(vector): ``` {{}} -The *setMarkerPosition* function gets a three-dimensional vector and sets the *markerPosition* field of our module. Then, the *applyMarker* trigger is touched. As the region growing algorithm might need some time to segment, we need to wait until the *outSegmentationMask* output field is valid, meaning that there is a valid segmentation mask at the segmentation mask output of our macro module. +The *setMarkerPosition* function gets a three-dimensional vector and sets the markerPosition field of our module. Then, the applyMarker trigger is touched. As the region growing algorithm might need some time to segment, we need to wait until the outSegmentationMask output field is valid, meaning that there is a valid segmentation mask at the segmentation mask output of our macro module. Finally, we need to reset the application to its initial state, so that each test case has the initial start conditions of the application. A test case should never depend on another test case so that they all can be executed exclusively. @@ -148,7 +148,7 @@ def reset(): ``` {{}} -For a reset, we just touch the *resetApplication* field of our macro module `TutorialSummary`. +For a reset, we just touch the resetApplication field of our macro module `TutorialSummary`. #### Requirement 1: The application shall be able to load DICOM data The first requirement we want to test is the possibility to load DICOM data. After setting the file to be loaded, the output provides a valid image. Resetting the application shall unload the image. @@ -291,7 +291,7 @@ Finally, an image comparison is done for the 3D rendering using the old and the The call *MLAB.processInventorQueue()* is sometimes necessary if an Open Inventor scene changed via Python scripting, because the viewers might not update immediately after changing the field. MeVisLab is now forced to process the queue in Open Inventor and to update the renderings. #### Requirement 8: The total volume of the segmented volume shall be calculated and shown (in ml) -For the correctness of the volume calculation, we added the `CalculateVolume` module to our test network. The volume given by our macro is compared to the volume of the segmentation from output *outSegmentationMask* calculated by the `CalculateVolume` module. +For the correctness of the volume calculation, we added the `CalculateVolume` module to our test network. The volume given by our macro is compared to the volume of the segmentation from output outSegmentationMask calculated by the `CalculateVolume` module. {{< highlight filename=".py" >}} ```Python diff --git a/mevislab.github.io/content/tutorials/summary/summary6.md b/mevislab.github.io/content/tutorials/summary/summary6.md index 376ad03d3..e737e162d 100644 --- a/mevislab.github.io/content/tutorials/summary/summary6.md +++ b/mevislab.github.io/content/tutorials/summary/summary6.md @@ -32,7 +32,7 @@ Use the module search to add your macro module to your workspace. We need an add Right-click {{< mousebutton "right" >}} your module and select {{< menuitem "Related Files" ".script" >}}. -In MATE, add another field to your *Parameters* section and reuse the field by setting the *internalName*. Add the field to the *Settings* section of your *Window*, maybe directly after the color selection. +In MATE, add another field to your *Parameters* section and reuse the field by setting the internalName. Add the field to the *Settings* section of your *Window*, maybe directly after the color selection. {{< highlight filename=".script" >}} ```Stan diff --git a/mevislab.github.io/content/tutorials/summary/summary8.md b/mevislab.github.io/content/tutorials/summary/summary8.md index 17724a19a..b2235d823 100644 --- a/mevislab.github.io/content/tutorials/summary/summary8.md +++ b/mevislab.github.io/content/tutorials/summary/summary8.md @@ -94,7 +94,7 @@ Web { ``` {{}} -Open the script file of the *TutorialSummary* module from [Step 3](tutorials/summary/summary3/). Copy the output section to your web macro and define *internalName* as the output of your `RemoteRendering` modules. +Open the script file of the *TutorialSummary* module from [Step 3](tutorials/summary/summary3/). Copy the output section to your web macro and define internalName as the output of your `RemoteRendering` modules. You can also copy all fields from *Parameters* section to your web macro module script. diff --git a/mevislab.github.io/content/tutorials/testing/testingexample1.md b/mevislab.github.io/content/tutorials/testing/testingexample1.md index 974a5879f..7f98eb2a6 100644 --- a/mevislab.github.io/content/tutorials/testing/testingexample1.md +++ b/mevislab.github.io/content/tutorials/testing/testingexample1.md @@ -87,21 +87,21 @@ def TEST_DicomImport(): ``` {{}} -The *filePath* variable defines the absolute path to the DICOM files that will be given to *source* field of the `DicomImport` module in the second step of the *OpenFiles* function. +The *filePath* variable defines the absolute path to the DICOM files that will be given to source field of the `DicomImport` module in the second step of the *OpenFiles* function. -The *OpenFiles* function first defines the `DicomImport` field *inputMode* to be a *Directory*. If you want to open single files, set this field's value to *Files*. Then, the *source* field is set to your previously defined *filePath*. After clicking *triggerImport*, the `DicomImport` module needs some time to load all images in the directory and process the DICOM tree. We have to wait until the field *ready* is *True*. While the import is not ready yet, we wait for 1 millisecond at a time and check again. *MLAB.processEvents()* lets MeVisLab continue execution while waiting for the `DicomImport` to be ready. +The *OpenFiles* function first defines the `DicomImport` field inputMode to be a *Directory*. If you want to open single files, set this field's value to *Files*. Then, the source field is set to your previously defined filePath. After clicking triggerImport, the `DicomImport` module needs some time to load all images in the directory and process the DICOM tree. We have to wait until the field ready is *True*. While the import is not ready yet, we wait for 1 millisecond at a time and check again. *MLAB.processEvents()* lets MeVisLab continue execution while waiting for the `DicomImport` to be ready. -When calling the function *TEST_DicomImport*, an expected value of *1.0* is defined. Then, the DICOM files are opened. +When calling the function *TEST_DicomImport*, an expected value of 1.0 is defined. Then, the DICOM files are opened. {{}} Call *Base.ignoreWarningAndError(MLAB.processEvents)* instead of *MLAB.processEvents()* if you receive error messages regarding invalid DICOM tags. {{}} -When *ready* is true, the test touches the *selectNextItem* trigger, so that the first images of the patient are selected and shown. The source directory will be written on the console as an additional log message for informative purposes. +When ready is true, the test touches the selectNextItem trigger, so that the first images of the patient are selected and shown. The source directory will be written on the console as an additional log message for informative purposes. -The value of our `DicomImport`s *progress* field is saved as the *currentValue* variable and compared to the *expectedValue* variable by calling *ASSERT_FLOAT_EQ(expectedValue,currentValue)* to determine if the DICOM import has finished (*currentValue* and *expectedValue* are equal) or not. +The value of our `DicomImport`s progress field is saved as the *currentValue* variable and compared to the *expectedValue* variable by calling *ASSERT_FLOAT_EQ(expectedValue,currentValue)* to determine if the DICOM import has finished (*currentValue* and *expectedValue* are equal) or not. -You can play around with the differences between **ASSERT_FLOAT_EQ()** and **EXPECT_FLOAT_EQ()** and le your test fail to see the differences. +You can play around with the differences between **ASSERT_FLOAT_EQ()** and **EXPECT_FLOAT_EQ()** and let your test fail to see the differences. ### Run Your Test Case Open the TestCase Manager und run your test by selecting your test case and clicking on the *Play* button in the bottom right corner. diff --git a/mevislab.github.io/content/tutorials/testing/testingexample3.md b/mevislab.github.io/content/tutorials/testing/testingexample3.md index 4035afae6..2c6801b7f 100644 --- a/mevislab.github.io/content/tutorials/testing/testingexample3.md +++ b/mevislab.github.io/content/tutorials/testing/testingexample3.md @@ -78,7 +78,7 @@ def testPatient(path, windowCenter): ``` {{}} -1. Initially, the path and filename for the module `LocalImage` are set. The data is loaded automatically, because the module has the *AutoLoad* flag enabled by default. +1. Initially, the path and filename for the module `LocalImage` are set. The data is loaded automatically, because the module has the AutoLoad flag enabled by default. ![LocalImage](images/tutorials/testing/LocalImage.png "LocalImage") 2. Then, the DICOM tree of the loaded file is used to get the *WindowCenter* value (*importValue*). 3. The previously defined value of the `DicomTagViewer` is set as *dicomValue*. diff --git a/mevislab.github.io/content/tutorials/thirdparty/MONAI/monaiexample2.md b/mevislab.github.io/content/tutorials/thirdparty/MONAI/monaiexample2.md index 9492104ba..84a4b0b02 100644 --- a/mevislab.github.io/content/tutorials/thirdparty/MONAI/monaiexample2.md +++ b/mevislab.github.io/content/tutorials/thirdparty/MONAI/monaiexample2.md @@ -155,7 +155,7 @@ Add a `SoView2DOverlay` and a `View2D` module and connect them to your local mac The **Spleen CT Segmentation** network expects images having a defined voxel size of 1.5 x 1.5 x 2. We want to define these values via fields in the Module Inspector. -Open the *.script* file and add the fields *start* and *voxelSize* to your local macro module `MonaiDemo`: +Open the *.script* file and add the fields start and voxelSize to your local macro module `MonaiDemo`: {{< highlight filename="MONAIDemo.script" >}} ```Stan @@ -199,9 +199,9 @@ Interface { {{}} Reload your macro module and enter the following values for your new fields: -* sizeX = 160 -* sizeY = 160 -* sizeZ = 160 +* sizeX = *160* +* sizeY = *160* +* sizeZ = *160* Next, we change the gray values of the image, because the algorithm has been trained on values between -57 and 164. Again, the values can be found in the *inference.json* file in your *configs* directory. @@ -223,8 +223,8 @@ Interface { {{}} As already done before, we can now defined the threshold values for our module via Module Inspector. Set the following: -* thresholdMin = -57 -* thresholdMax = 164 +* thresholdMin = *-57* +* thresholdMax = *164* As defined in the *inference.json* file in your *configs* directory, the gray values in the image must be between 0 and 1. @@ -246,8 +246,8 @@ Interface { {{}} Set the following: -* scaleMin = 0 -* scaleMax = 1 +* scaleMin = *0* +* scaleMax = *1* The algorithm expects NumPy images. NumPy uses the order Z, Y, X, other than MeVisLab. We are using X, Y, Z. The image needs to be transformed. @@ -297,7 +297,7 @@ Commands { ``` {{}} -If the user touches the trigger *start*, a Python function *onStart* will be executed. Whenever the size of our image is changed, we call a function called *_sizeChanged* and if the input image changes, we want to reset the module to its default values. +If the user touches the trigger start, a Python function *onStart* will be executed. Whenever the size of our image is changed, we call a function called *_sizeChanged* and if the input image changes, we want to reset the module to its default values. ### Python Scripting The next step is to write our Python code. diff --git a/mevislab.github.io/content/tutorials/thirdparty/assimp/assimpexample1.md b/mevislab.github.io/content/tutorials/thirdparty/assimp/assimpexample1.md index dd683adb8..097fe914c 100644 --- a/mevislab.github.io/content/tutorials/thirdparty/assimp/assimpexample1.md +++ b/mevislab.github.io/content/tutorials/thirdparty/assimp/assimpexample1.md @@ -31,7 +31,7 @@ Add the modules `SoSceneLoader`, `SoBackground`, and `SoExaminerViewer` to your Select the file *vtkCow.obj* from MeVisLab demo data directory. Open `SoExaminerViewer` and inspect the scene. You will see a 3D cow. {{}} -In the case you cannot see the cow, it might be located outside your current camera location. Trigger the field *rescanScene* in the case the cow is not visible. +In the case you cannot see the cow, it might be located outside your current camera location. Trigger the field rescanScene in the case the cow is not visible. {{}} ![Cow in SoExaminerViewer](images/tutorials/thirdparty/vtkCow.png "Cow in SoExaminerViewer") diff --git a/mevislab.github.io/content/tutorials/thirdparty/pytorch/pytorchexample2.md b/mevislab.github.io/content/tutorials/thirdparty/pytorch/pytorchexample2.md index 9ebe3fb25..0dedd9a8a 100644 --- a/mevislab.github.io/content/tutorials/thirdparty/pytorch/pytorchexample2.md +++ b/mevislab.github.io/content/tutorials/thirdparty/pytorch/pytorchexample2.md @@ -45,7 +45,7 @@ Our new module does not provide any input or output. ![DemoAI local macro](images/tutorials/thirdparty/pytorch_example2_4.png "DemoAI local macro"). ### Adding an Interface to the Local Macro -Right-click {{< mousebutton "right" >}} the local macro and select {{< menuitem "Related Files" "DemoAI.script">}}. MATE opens showing the *.script* file of our module. Add an input *Field* of type *Image*, an output *Field* using the *internalName* of the output of our `PythonImage`, and a *Trigger* to start the segmentation. +Right-click {{< mousebutton "right" >}} the local macro and select {{< menuitem "Related Files" "DemoAI.script">}}. MATE opens showing the *.script* file of our module. Add an input *Field* of type *Image*, an output *Field* using the internalName of the output of our `PythonImage`, and a *Trigger* to start the segmentation. You should also already add a Python file in the *Commands* section. diff --git a/mevislab.github.io/content/tutorials/thirdparty/pytorch/pytorchexample3.md b/mevislab.github.io/content/tutorials/thirdparty/pytorch/pytorchexample3.md index 95b20893c..28f1589d6 100644 --- a/mevislab.github.io/content/tutorials/thirdparty/pytorch/pytorchexample3.md +++ b/mevislab.github.io/content/tutorials/thirdparty/pytorch/pytorchexample3.md @@ -154,15 +154,15 @@ You should now have the complete functionality of the [Example 2: Face Detection ### Adapt the Network For *PyTorch*, we require some additional modules in our network. Open the internal network of your module and add another `PythonImage` module. Connect a `Resample3D` and an `ImagePropertyConvert` module. -In `Resample3D` module, define the *Image Size* 693, 520, 1. Change *VoxelSize* for all dimensions to 1. +In `Resample3D` module, define the Image Size as *693, 520, 1*. Change VoxelSize for all dimensions to *1*. ![Resample3D](images/tutorials/thirdparty/pytorch_example3_7.png "Resample3D") -Open the Panel of the `ImagePropertyConvert` module and check *World Matrix*. +Open the Panel of the `ImagePropertyConvert` module and check World Matrix. ![ImagePropertyConvert](images/tutorials/thirdparty/pytorch_example3_9.png "ImagePropertyConvert") -Then, add a `SoView2DOverlayMPR` module and connect it to the `ImagePropertyConvert` and the `View2D`. Change *Blend Mode* to *Blend*, *Alpha* to something between 0 and 1, and define a color for the overlay. +Then, add a `SoView2DOverlayMPR` module and connect it to the `ImagePropertyConvert` and the `View2D`. Change Blend Mode to *Blend*, Alpha to something between *0* and *1*, and define a color for the overlay. ![SoView2DOverlayMPR](images/tutorials/thirdparty/pytorch_example3_8.png "SoView2DOverlayMPR") diff --git a/mevislab.github.io/content/tutorials/visualization/pathtracer/pathtracerexample2.md b/mevislab.github.io/content/tutorials/visualization/pathtracer/pathtracerexample2.md index 0208395b8..837e593f9 100644 --- a/mevislab.github.io/content/tutorials/visualization/pathtracer/pathtracerexample2.md +++ b/mevislab.github.io/content/tutorials/visualization/pathtracer/pathtracerexample2.md @@ -80,7 +80,7 @@ As an alternative, you can replace the `SoLUTEditor` with a `LUTLoad` and load t Now, let's enhance your rendering further by using the `SoPathTracerMaterial` module. This module provides essential material properties for geometry and volumes within the `SoPathTracer` scene. -Add a `SoPathTracerMaterial` module to your `SoPathTracerVolume`. Open its panel and navigate to the tab *Surface Brdf*. Change the *Diffuse* color for altering the visual appearance of surfaces. The *Diffuse* color determines how light interacts with the surface, influencing its overall color and brightness. Set *Specular* to *0.5*, *Shininess* to *1.0*, and *Specular Intensity* to *0.5*. +Add a `SoPathTracerMaterial` module to your `SoPathTracerVolume`. Open its panel and navigate to the tab *Surface Brdf*. Change the Diffuse color for altering the visual appearance of surfaces. The Diffuse color determines how light interacts with the surface, influencing its overall color and brightness. Set Specular to *0.5*, Shininess to *1.0*, and Specular Intensity to *0.5*. ![SoPathTracerMaterial](images/tutorials/visualization/pathtracer/SoPathTracerMaterial_Knee.png "SoPathTracerMaterial") @@ -99,7 +99,7 @@ Load the [Bones mask](examples/visualization/example6/edited_Bones.mlimage) by u ![Bones mask](images/tutorials/visualization/pathtracer/View2D_Bones.png "Bones mask") -Start by disabling the visibility of your first volume by toggeling `SoPathTracerVolume` *Enabled* field to off. This helps to improve the rendering of the bones itself and makes it easier to define colors for your LUT. +Start by disabling the visibility of your first volume by toggeling `SoPathTracerVolume` Enabled field off. This helps to improve the rendering of the bones itself and makes it easier to define colors for your LUT. #### Load Example LUT from File Once again, you can decide to define the LUT yourself in `SoLUTEditor` module, or load a prepared XML File in a `LUTLoad` module as provided [here](examples/visualization/example6/LUT_Bones.xml). @@ -113,7 +113,7 @@ Open the panel of `SoLUTEditor1` for the bones and go to tab *Range* and set *Ne ![SoLUTEditor1](images/tutorials/visualization/pathtracer/V6.2_11_LUT_Bones.png "SoLUTEditor1") -You can increase the *Shininess* of the bones and change the *Diffuse* color in the *Surface Brdf* tab within the `SoPathTracerMaterial1`. Also set *Specular* to *0.5*, *Shininess* to *0.904*, and *Specular Intensity* to *0.466*. +You can increase the Shininess of the bones and change the Diffuse color in the *Surface Brdf* tab within the `SoPathTracerMaterial1`. Also set Specular to *0.5*, Shininess to *0.904*, and Specular Intensity to *0.466*. ![SoPathTracerMaterial1](images/tutorials/visualization/pathtracer/V6.2_SoPathTracerMaterial.png "SoPathTracerMaterial1") @@ -128,7 +128,7 @@ Load a prepared XML File in a `LUTLoad` module as provided [here](examples/visua #### Manually Define LUT Connect the `MinMaxScan` to your `LocalImage2`. -Access the `SoLUTEditor2` panel in the tab *Range* and set the *New Range Min* to *0* and the *New Range Max* to *255*. Additionally, modify the illustrated color settings within the *Editor* tab. +Access the `SoLUTEditor2` panel in the tab *Range* and set the New Range Min to *0* and the New Range Max to *255*. Additionally, modify the illustrated color settings within the *Editor* tab. ![Vessels](images/tutorials/visualization/pathtracer/MinMaxScan_Vessels.png "MinMaxScan of Vessels mask") diff --git a/mevislab.github.io/content/tutorials/visualization/visualizationexample2.md b/mevislab.github.io/content/tutorials/visualization/visualizationexample2.md index fb5448747..84e79d603 100644 --- a/mevislab.github.io/content/tutorials/visualization/visualizationexample2.md +++ b/mevislab.github.io/content/tutorials/visualization/visualizationexample2.md @@ -69,19 +69,19 @@ We rename the `DecomposeVector3` modules (press {{< keyboard "F2" >}} to do that In the panel of the module `Rectangle` in the box *Position*, you can see the position of the rectangle given in two 3D vectors. -We like to use the modules `DecomposeVector3` to extract the single x, y, and z values of the vector. For that, create a parameter connection from the field *Start Wold Pos* to the vector of the module we named `StartWorldPos_Rectangle` and create a connection from the field *End World Pos* to the vector of module `EndWorldPos_Rectangle`. The decomposed coordinates can be now used for further parameter connections. +We like to use the modules `DecomposeVector3` to extract the single x, y, and z values of the vector. For that, create a parameter connection from the field Start World Pos to the vector of the module we named `StartWorldPos_Rectangle` and create a connection from the field End World Pos to the vector of module `EndWorldPos_Rectangle`. The decomposed coordinates can be now used for further parameter connections. ![Parameter Connections](images/tutorials/visualization/V2_09.png "Parameter Connections") -Open the panel of the module `SubImage`. Select the *Mode World Start & End* (*Image Axis Aligned*). Enable the function *Auto apply*. +Open the panel of the module `SubImage`. Select the Mode *World Start & End (Image Axis Aligned)*. Toggle the field Auto apply *on*. {{}} -Make sure to also check *Auto-correct for negative subimage extents*, so that you can draw rectangles from left to right and from right to left. +Make sure to also check Auto-correct for negative subimage extents, so that you can draw rectangles from left to right and from right to left. {{}} ![World Coordinates](images/tutorials/visualization/V2_10.png "World Coordinates") -Now, create parameter connections from the fields *X*, *Y*, *Z* of the module `StartWorldPos_Rectangle` to the field *Start X*, *Start Y*, *Start Z* in the panel of the module `SubImage`. Similarly, connect the parameter fields *X*, *Y*, *Z* of the module `EndWorldPos_Rectangle` to the field *End X*, *End Y*, *End Z* in the panel of the module `SubImage`. +Now, create parameter connections from the fields X, Y, Z of the module `StartWorldPos_Rectangle` to the field Start X, Start Y, Start Z in the panel of the module `SubImage`. Similarly, connect the parameter fields X, Y, Z of the module `EndWorldPos_Rectangle` to the field End X, End Y, End Z in the panel of the module `SubImage`. ![Another Parameter Connection](images/tutorials/visualization/V2_11.png "Another Parameter Connection") diff --git a/mevislab.github.io/content/tutorials/visualization/visualizationexample7.md b/mevislab.github.io/content/tutorials/visualization/visualizationexample7.md index b161bdaad..1d3282a1a 100644 --- a/mevislab.github.io/content/tutorials/visualization/visualizationexample7.md +++ b/mevislab.github.io/content/tutorials/visualization/visualizationexample7.md @@ -31,7 +31,7 @@ The `OrthoView2D` module allows you to select multiple layouts. Select layout *C ![OrthoView2D Layouts](images/tutorials/image_processing/network_example7_2.png "OrthoView2D Layouts") -We now want to use a 3D rendering in the top left segment whenever the layout *Cube Equal* is chosen. Add a `View3D` and a `SoViewportRegion` module to your workspace. Connect the `LocalImage` with your `View3D`. The image is rendered in 3D. Hit {{< keyboard "SPACE" >}} on your keyboard to make the hidden output of the `View3D` module visible. Connect it with your `SoViewportRegion` and connect the `SoViewportRegion` with the *inInvPreLUT* input of the `OrthoView2D`. +We now want to use a 3D rendering in the top left segment whenever the layout *Cube Equal* is chosen. Add a `View3D` and a `SoViewportRegion` module to your workspace. Connect the `LocalImage` with your `View3D`. The image is rendered in 3D. Hit {{< keyboard "SPACE" >}} on your keyboard to make the hidden output of the `View3D` module visible. Connect it with your `SoViewportRegion` and connect the `SoViewportRegion` with the inInvPreLUT input of the `OrthoView2D`. ![Network with SoViewportRegion](images/tutorials/image_processing/network_example7_3.png "Network with SoViewportRegion") @@ -39,23 +39,23 @@ Open the `OrthoView2D` and inspect your layout. ![OrthoView2D with 3D](images/tutorials/image_processing/network_example7_4.png "OrthoView2D with 3D") -You can see your `View3D` being visible in the bottom right segment of the layout behind the coronal view of the image. Open the panel of the `SoViewportRegion` module. In section *X-Position and Width*, set *Left Border* to *0* and *Right Border* to *0.5*. In section *Y-Position and Height*, set *Lower Border* to *0* and *Upper Border* to *0.5*. Also check *Render delayed paths*. +You can see your `View3D` being visible in the bottom right segment of the layout behind the coronal view of the image. Open the panel of the `SoViewportRegion` module. In section *X-Position and Width*, set Left Border to *0* and Right Border to *0.5*. In section *Y-Position and Height*, set Lower Border to *0* and Upper Border to *0.5*. Also check Render delayed paths. ![Define viewport region](images/tutorials/image_processing/network_example7_5.png "Define viewport region") The `View3D` image is now rendered to the top left segment of the `OrthoView2D`, because the module `SoViewportRegion` renders a subgraph into a specified viewport region (VPR). The problem is: We cannot rotate and pan the 3D object, because there is no camera interaction available after adding the `SoViewportRegion`. The camera interaction is consumed by the `View3D` module before it can be used by the viewport. -Add a `SoCameraInteraction` module between the `View3D` and the `SoViewportRegion`. You can now interact with your 3D scene but the rotation is not executed on the center of the object. Trigger *ViewAll* on your `SoCameraInteraction` module. +Add a `SoCameraInteraction` module between the `View3D` and the `SoViewportRegion`. You can now interact with your 3D scene but the rotation is not executed on the center of the object. Trigger ViewAll on your `SoCameraInteraction` module. ![SoCameraInteraction](images/tutorials/image_processing/network_example7_6.png "SoCameraInteraction") You have now successfully added the `View3D` to the `OrthoView2D`, but there is still a problem remaining: If you change the layout to something different than *LAYOUT_CUBE_EQUAL*, the 3D content remains visible. -We can use a `StringUtils` module to resolve that. Set *Operation* to *Compare* and draw a parameter connection from the field *OrthoView2D.layout* to the field *StringUtils.string1*. The currently selected layout is displayed as *String A*. Enter *LAYOUT_CUBE_EQUAL* as *String B*. Now, draw a parameter connection from the field *StringUtils.boolResult* to the field *SoViewportRegion.on*. +We can use a `StringUtils` module to resolve that. Set Operation to *Compare* and draw a parameter connection from the field OrthoView2D.layout to the field StringUtils.string1. The currently selected layout is displayed as String A. Enter *LAYOUT_CUBE_EQUAL* as String B. Now, draw a parameter connection from the field StringUtils.boolResult to the field SoViewportRegion.on. ![StringUtils](images/tutorials/image_processing/network_example7_7.png "StringUtils") -If the selected layout in `OrthoView2D` now matches the string *LAYOUT_CUBE_EQUAL* (the field *boolResult* of the `StringUtils` module is *TRUE*), the `SoViewportRegion` is turned *on*. In any other case, the 3D segment is not visible. +If the selected layout in `OrthoView2D` now matches the string *LAYOUT_CUBE_EQUAL* (the field boolResult of the `StringUtils` module is *TRUE*), the `SoViewportRegion` is turned *on*. In any other case, the 3D segment is not visible. ![Final Network](images/tutorials/image_processing/network_example7_8.png "Final Network") diff --git a/mevislab.github.io/content/tutorials/visualization/visualizationexample8.md b/mevislab.github.io/content/tutorials/visualization/visualizationexample8.md index 8888ef04c..4ead740ea 100644 --- a/mevislab.github.io/content/tutorials/visualization/visualizationexample8.md +++ b/mevislab.github.io/content/tutorials/visualization/visualizationexample8.md @@ -138,10 +138,10 @@ Draw parameter connections from one `SoExaminerViewer` to the other. Use the fie ![ Camera positions](images/tutorials/visualization/V8_SyncFloat.png " Camera positions") -Connect the backwards direction of the two `SoExaminerViewer` by using multiple `SyncFloat` modules and two `SyncVector` modules for *position* and *orientation* fields. +Connect the backwards direction of the two `SoExaminerViewer` by using multiple `SyncFloat` modules and two `SyncVector` modules for position and orientation fields. {{}} -To establish connections between fields with the type *Float*, you can use the *SyncFloat* module. For fields containing vector, the appropriate connection can be achieved using the *SyncVector* module. +To establish connections between fields with the type *Float*, you can use the `SyncFloat` module. For fields containing vector, the appropriate connection can be achieved using the `SyncVector` module. {{}} ![ SyncFloat & SyncVector](images/tutorials/visualization/V8_SyncFloat_Network.png " SyncFloat & SyncVector") @@ -152,7 +152,7 @@ Now, you can notice the difference between the two modules. We use `SoVascularSy ![ SoVascularSystem & SoGVRVolumeRenderer](images/tutorials/visualization/V8_Difference1.png " SoVascularSystem & SoGVRVolumeRenderer") -The `SoVascularSystem` module has additional visualization examples unlike `SoGVRVolumeRenderer`. Open the panel of the `SoVascularSystem` module and select *Random Points* for *Display Mode* in the *Main* tab to see the difference. +The `SoVascularSystem` module has additional visualization examples unlike `SoGVRVolumeRenderer`. Open the panel of the `SoVascularSystem` module and select *Random Points* for Display Mode in the *Main* tab to see the difference. ![ Random Points](images/tutorials/visualization/V8_SoVasularSystem_DisplayMode1.png " Random Points") @@ -167,7 +167,7 @@ For volume calculations, use the original image mask instead of the result from ### Enhance Vessel Visualization Based on Distance Information Now that you've successfully obtained the vessel skeleton graph using `DtfSkeletonization`, let's take the next step to enhance the vessel visualization based on the radius information of the vessels. We will modify the existing code to use the minimum distance between centerline and surface of the vessels for defining the color. -The values for the provided vascular tree vary between 0mm and 10mm. Therefore, define the range of the `SoLUTEditor` to *New Range Min* as *1* and *New Range Max* as *10*. On *Editor* tab, define the following LUT: +The values for the provided vascular tree vary between 0mm and 10mm. Therefore, define the range of the `SoLUTEditor` to New Range Min as *1* and New Range Max as *10*. On *Editor* tab, define the following LUT: ![SoLUTEditor](images/tutorials/visualization/V8_SoLUTEditor2.png "SoLUTEditor") @@ -194,10 +194,10 @@ ctx.field("SoVascularSystem.apply").touch() {{}} -Be aware that the *MinDistance* and *MaxDistance* values are algorithm-specific and don't precisely represent vessel diameters. The result of `DTFSkeletonization` is a vascular graph with an idealized, circular profile while in reality, the vessels have more complicated profiles. It is an idealized graph where all vessels have a circular cross section. This cross section only has one radius, described by *MinDistance* and *MaxDistance*. Those are not the two radii of an elliptical cross section, but the results of two different algorithms to measure the one, idealized radius at Skeletons. +Be aware that the MinDistance and MaxDistance values are algorithm-specific and don't precisely represent vessel diameters. The result of `DTFSkeletonization` is a vascular graph with an idealized, circular profile while in reality, the vessels have more complicated profiles. It is an idealized graph where all vessels have a circular cross section. This cross section only has one radius, described by MinDistance and MaxDistance. Those are not the two radii of an elliptical cross section, but the results of two different algorithms to measure the one, idealized radius at Skeletons. {{}} -Instead of using the ID of each edge for the label property, we are now using the *MinDistance* property of the skeleton. The result is a color-coded 3D visualization depending on the radius of the vessels. Small vessels are red, large vessels are green. +Instead of using the ID of each edge for the label property, we are now using the MinDistance property of the skeleton. The result is a color-coded 3D visualization depending on the radius of the vessels. Small vessels are red, large vessels are green. ![Radius based Visualization](images/tutorials/visualization/V8_010new.png "Radius based Visualization") diff --git a/mevislab.github.io/content/tutorials/visualization/visualizationexample9.md b/mevislab.github.io/content/tutorials/visualization/visualizationexample9.md index 184d52212..01795f516 100644 --- a/mevislab.github.io/content/tutorials/visualization/visualizationexample9.md +++ b/mevislab.github.io/content/tutorials/visualization/visualizationexample9.md @@ -67,26 +67,26 @@ We want to show and hide the single segmentations during camera movements. Add t ![ LUTRescale](images/tutorials/visualization//pathtracer/V9_3.png " LUTRescale") ## Animate Bones and Vessels -Now, let's shift our focus to highlighting bones and vessels within the animation. Right-click on the `LUTRescale` module, navigate to *Show Window*, and select *Automatic Panel*. This will bring up the control window for the `LUTRescale` module. Search for the field named *targetMax*. You can either drag and drop it directly from the *Automatic Panel*, or alternatively, locate the *Max* field in the *Output Index Range* box within the module panel and then drag and drop it onto the fields section in the `AnimationRecorder` module, specifically under the *Perspective Camera* field. +Now, let's shift our focus to highlighting bones and vessels within the animation. Right-click on the `LUTRescale` module, navigate to *Show Window*, and select *Automatic Panel*. This will bring up the control window for the `LUTRescale` module. Search for the field named targetMax. You can either drag and drop it directly from the *Automatic Panel*, or alternatively, locate the Max field in the *Output Index Range* box within the module panel and then drag and drop it onto the fields section in the `AnimationRecorder` module, specifically under the *Perspective Camera* field. -By linking the *targetMax* field of the `LUTRescale` module to the `AnimationRecorder`, you establish a connection that allows you to define different values of the field for specific timepoints. The values between these timepoints can be interpolated as described above. +By linking the targetMax field of the `LUTRescale` module to the `AnimationRecorder`, you establish a connection that allows you to define different values of the field for specific timepoints. The values between these timepoints can be interpolated as described above. ![ LUTRescale & AnimationRecorder](images/tutorials/visualization//pathtracer/LUTRescale_AnimationRecorder2.png " LUTRescale & AnimationRecorder") -To initiate the animation sequence, start by adding a keyframe at position *0* for the *targetMax* field. Set the *Target Max* value in the *Edit Key Frame – [LUTRescale.targetMax]* window to *1*, and click on the *Store Current Field Value* button to save it. +To initiate the animation sequence, start by adding a keyframe at position *0* for the targetMax field. Set the Target Max value in the *Edit Key Frame – [LUTRescale.targetMax]* window to *1*, and click on the *Store Current Field Value* button to save it. -Next, proceed to add keyframes at the same timepoints as the desired keyframes of the *Perspective Camera* field's first sequence. For each selected keyframe, progressively set values for the *Target Max* field, gradually increasing to *10*. This ensures specific synchronization between the visibility adjustments controlled by the `LUTRescale` module and the camera movements in the animation, creating a seamless transition. This gradual shift visually reveals the bones and vessels while concealing the knee structures and muscles. +Next, proceed to add keyframes at the same timepoints as the desired keyframes of the *Perspective Camera's* first sequence. For each selected keyframe, progressively set values for the Target Max field, gradually increasing to *10*. This ensures specific synchronization between the visibility adjustments controlled by the `LUTRescale` module and the camera movements in the animation, creating a seamless transition. This gradual shift visually reveals the bones and vessels while concealing the knee structures and muscles. -To seamlessly incorporate the new keyframe at the same timepoints as the *Perspective Camera* field, you have two efficient options. Simply click on the keyframe of the first sequence, and the line will automatically appear in the middle of the keyframe. A double-click will effortlessly insert a keyframe at precisely the same position. If you prefer more accurate adjustments, you can also set your frame manually using the *Edit Key Frame - [LUTRescale.targetMax]* window. This flexibility allows for precise control over the animation timeline, ensuring keyframes align precisely with your intended moments. +To seamlessly incorporate the new keyframe at the same timepoints as the *Perspective Camera*, you have two efficient options. Simply click on the keyframe of the first sequence, and the line will automatically appear in the middle of the keyframe. A double-click will effortlessly insert a keyframe at precisely the same position. If you prefer more accurate adjustments, you can also set your frame manually using the *Edit Key Frame - LUTRescale.targetMax* window. This flexibility allows for precise control over the animation timeline, ensuring keyframes align precisely with your intended moments. ![ LUTRescale & AnimationRecorder](images/tutorials/visualization//pathtracer/V9_7.png " LUTRescale & AnimationRecorder") ## Showcasing Only Bones -To control the visibility of the vessels, right-click on the ` LUTRescale1` module connected to the vessels. Open the *Show Window* and select *Automatic Panel*. Drag and drop the *targetMax* field into the `AnimationRecorder` module's fields section. +To control the visibility of the vessels, right-click on the ` LUTRescale1` module connected to the vessels. Open the *Show Window* and select *Automatic Panel*. Drag and drop the targetMax field into the `AnimationRecorder` module's fields section. ![ LUTRescale1 & AnimationRecorder](images/tutorials/visualization//pathtracer/V9_8.png " LUTRescale1 & AnimationRecorder") -Add keyframes for both the *Perspective Camera* field and the *targetMax* in `LUTRescale1` at the same timepoints. Access the *Edit Camera Key Frame* window for the added keyframe in the *Perspective Camera* field and save the *current camera state*. To exclusively highlight only bones, adjust the *Target Max* values from *1* to *10000* in *Edit Key Frame - [LUTRescale1.targetMax]*. +Add keyframes for both the *Perspective Camera* and the targetMax in `LUTRescale1` at the same timepoints. Access the *Edit Camera Key Frame* window for the added keyframe in the Perspective Camera and save the *current camera state*. To exclusively highlight only bones, adjust the Target Max values from *1* to *10000* in *Edit Key Frame - LUTRescale1.targetMax*. ![ LUTRescale1 & AnimationRecorder](images/tutorials/visualization//pathtracer/V9_9.png " LUTRescale1 & AnimationRecorder") diff --git a/mevislab.github.io/themes/MeVisLab/assets/sass/styles.scss b/mevislab.github.io/themes/MeVisLab/assets/sass/styles.scss index 5f77102d8..b870094a8 100644 --- a/mevislab.github.io/themes/MeVisLab/assets/sass/styles.scss +++ b/mevislab.github.io/themes/MeVisLab/assets/sass/styles.scss @@ -87,6 +87,20 @@ body { background-color: #333131; } +field { + font-family: monospace; + font-size: .875em; + color: var(--bs-secondary); + word-wrap: break-word; +} + +attribute { + font-family: monospace; + font-size: .875em; + color: var(--bs-secondary); + word-wrap: break-word; +} + kbd { display: inline-block; border: 1px solid #ccc;