New module: Dynamic Modeler - parametric surface editing for biomedical applications

We have added a new module called “Dynamic Modeler” to the latest Slicer preview releases (4.11). This module provides an extensible framework for automatic processing of mesh nodes by executing “Tools” on the input to generate output mesh.

Output of a tool can be used as input in another tool, which allows specification of complex editing operations. This is similar to “parametric editing” in engineering CAD software, but this module is specifically developed to work well on complex meshes used in biomedical applications (while most engineering CAD software does not directly support parametric editing of complex polygonal meshes).

Current tools:

  • Plane cut: Cut a plane into two separate meshes using any number of markup planes or slice views. The planes can be combined using union, intersection and difference boolean operations.
  • Mirror: Reflect the points in a model across the input plane. Useful in conjunction with the plane cut tool to cut a model in half and then mirror the selected half accross the cutting plane.
  • Curve cut: Extract a region from the surface that is enclosed by a markup curve.
  • Boundary cut: Extract a region from the surface that is enclosed by many markup curves and planes. In instances where there is ambiguity about which region should be extracted, a markup fiducial can be used to specify the region of interest.
  • Append: Combine multiple models into a single output model.

Notes:

  • To enable automatic update (so that outputs are automatically recomputed whenever inputs change), check the checkbox on the Apply button.
  • Tools cannot be run continuously if one of the input nodes is present in the output. The tool can still be run on demand by clicking the apply button.

Any suggestions and feature requests are welcome. Based on feedback we get, we may add more tools, such as: rotate around axis, shell, extrude, intersect, parametric shapes (cube, cylinder, etc.).

Parcellating white matter surface with curves and planes:

Skull mirroring for facial deformity reconstruction:

For developers:

  • New tools can be added by any module by subclassing the vtkSlicerDynamicModelerTool class and registering the new tool with the vtkSlicerDynamicModelerToolFactory.
  • Tools can be added to models in the scene by adding a vtkMRMLDynamicModelerNode to the scene, specifying the tool name, setting the parameters, and setting the input/output node references as defined by the tool.

Development was funded in part by CANARIE’s Research Software Program, OpenAnatomy, and Brigham and Women’s Hospital through NIH grant R01MH112748.

8 Likes

@Sunderlandkyl @lassoan
I am trying the curveCut implementation, and getting “Can’t follow edge. No input data” error. Are these implemented or they are place holders?

This is what I am trying to cut:

It is fully implemented and should work well. Can you share your scene with us so that we can investigate?

Sure. here it is:
https://app.box.com/s/x5y85fzrcxwueefox7i53eep6whhqqiv

I am using the resampled curve to cut.

There are two issues:

  • the mesh has has very large, unevenly sized, ill-shaped cells, so methods that rely on path searching between points run into trouble (similarly to how some image processing algorithms cannot operate on very low-resolution images)
  • the mesh has multiple disconnected regions (internal cavities), so when the surface cut is completed and the curve cut tool finds the largest mesh piece, it finds and extracts an already disconnected region (because that is larger than the small extracted patch) - @sunderlandkyl, do you have an idea if we could fix this?

You can solve these issues using Surface toolbox:

  • Enable “Decimation”, set reduction to 0.5% (to force resampling, and remove very small cells, but still keep enough points), this uses the recently introduced Quadric decimation method, which provides much higher quality mesh than the previously used DecimatePro
  • Enable “Connectivity” (this keeps only the largest connected region)
  • Optional: Enable “Normals” (just to improve appearance)

Full scene: https://1drv.ms/u/s!Arm_AFxB9yqHw70xlDR_uOifvDbc-Q?e=ljUnrm

I would recommend to re-create the simplified gorilla head mesh from the original high-resolution mesh using the new quadric decimation method. You will get much higher quality mesh with the same number of points.

Thanks Andras.

I do not have the original high-res mesh anymore, but I do have the volume it came from:
https://raw.githubusercontent.com/muratmaga/Hominoid_Skulls/master/Gorilla_gorilla/gor_template0_cleaned.nrrd

After segmentation via threshold (10.15-Max), I am trying what you suggested and whenever I enable the Connectivity and/or Normal, output is blank. Decimation by itself works. Here is the log file, if there is anything helpful:

"Model" Reader has successfully read the file "C:/Users/murat/Desktop/Gorilla_Skull_original_segmentation.obj" "[14.24s]"
Found CommandLine Module, target is  C:/Users/murat/AppData/Local/NA-MIC/Slicer 4.11.0-2020-08-04/bin/../lib/Slicer-4.11/cli-modules/Decimation.exe
ModuleType: CommandLineModule
Decimation command line: 

C:/Users/murat/AppData/Local/NA-MIC/Slicer 4.11.0-2020-08-04/bin/../lib/Slicer-4.11/cli-modules/Decimation.exe --reductionFactor 0.5 --method FastQuadric --deleteBoundary --aggressiveness 7.0 C:/Users/murat/AppData/Local/Temp/Slicer/DFCHC_vtkMRMLModelNodeF.obj C:/Users/murat/AppData/Local/Temp/Slicer/DFCHC_vtkMRMLModelNodeF.obj 

Decimation standard output:

Input: 2388660 vertices,4779192 triangles (target 2389596)
Output: 1192449 vertices,2389596 triangles (0.5 reduction)
vtkDebugLeaks has found no leaks.

Decimation completed without errors

ReadDataInternal (vtkMRMLModelStorageNode2): File C:/Users/murat/AppData/Local/Temp/Slicer/DFCHC_vtkMRMLModelNodeF.obj does not contain coordinate system information. Assuming LPS.


Found CommandLine Module, target is  C:/Users/murat/AppData/Local/NA-MIC/Slicer 4.11.0-2020-08-04/bin/../lib/Slicer-4.11/cli-modules/Normals.exe
ModuleType: CommandLineModule
Normals command line: 

C:/Users/murat/AppData/Local/NA-MIC/Slicer 4.11.0-2020-08-04/bin/../lib/Slicer-4.11/cli-modules/Normals.exe --angle 30 C:/Users/murat/AppData/Local/Temp/Slicer/DFCHC_vtkMRMLModelNodeF.vtp C:/Users/murat/AppData/Local/Temp/Slicer/DFCHC_vtkMRMLModelNodeF.vtp 

Normals standard output:

vtkDebugLeaks has found no leaks.

Normals completed without errors

ReadDataInternal (vtkMRMLModelStorageNode2): File C:/Users/murat/AppData/Local/Temp/Slicer/DFCHC_vtkMRMLModelNodeF.vtp does not contain coordinate system information. Assuming LPS.


Found CommandLine Module, target is  C:/Users/murat/AppData/Local/NA-MIC/Slicer 4.11.0-2020-08-04/bin/../lib/Slicer-4.11/cli-modules/Connectivity.exe
ModuleType: CommandLineModule
Connectivity command line: 

C:/Users/murat/AppData/Local/NA-MIC/Slicer 4.11.0-2020-08-04/bin/../lib/Slicer-4.11/cli-modules/Connectivity.exe C:/Users/murat/AppData/Local/Temp/Slicer/DFCHC_vtkMRMLModelNodeF.vtp C:/Users/murat/AppData/Local/Temp/Slicer/DFCHC_vtkMRMLModelNodeF.vtp 

Connectivity standard output:

vtkDebugLeaks has found no leaks.

Connectivity completed without errors

ReadDataInternal (vtkMRMLModelStorageNode2): File C:/Users/murat/AppData/Local/Temp/Slicer/DFCHC_vtkMRMLModelNodeF.vtp does not contain coordinate system information. Assuming LPS.

I segmented using Threshold and Smoothing (Fill holes), exported to surface, and then used Surface Toolbox successfully:

Complete scene: https://1drv.ms/u/s!Arm_AFxB9yqHw71U9_FPmLMQrx0PPw?e=OmQnvK

With 95% decimation, curve cut is quite usable but it sometimes requires some adjustment of the curve to find path between points. Probably the underlying VTK filters could be made more robust.

1 Like

These settings worked for me too! Thanks.

1 Like

Currently the curve cut tool finds the smallest region as the “inside”, and the largest region as the outside. I think there are a couple of ways that it can be improved, including adding an optional seed fiducial to select the “inside” (similar to boundary cut).

An optional seed would be great.

Instead of smallest/largest region, we should return the inside and “inverse of inside” (I don’t remember which filter we use, but there should be either an option to return both inside and outside surface or a flag to invert the selection).

1 Like

I’ve implemented multiple fixes in the VTK filter that the Curve cut tool uses. As a result, cuts are now always successful (Can’t follow edge never occurs) and also more accurate (previously the cuts sometimes did not go all the way to the boundaries). I’ve also added an additional option for straight cut (switches between following the input curve more accurately / preserving the original cells) and a fiducial point input to select what region is considered as being “inside”.

2 Likes
3 Likes