Model Undercuts Removal by Label Map Addition

Operating system: Win 10 64 Bit
Slicer version: 4.7 Nightly

Background: Undercuts are important in dental CAD because for two rigidly mating objects (for example teeth and an appliance), a path of insertion is necessary or else the parts will bind. This is also useful in many other applications outside of dentistry

Goal: I would like to create a Module which takes as input a closed STL or other model surface, and outputs a closed surface which has all undercuts from a given direction removed.

Overall Plan: Create a label map from the model, and add layers above to all layers below it, ensuring that the model is always monotonically widening wrt to the desired insertion axis.
-Import the model
-Transform the model so that Z axis is aligned with desired insertion axis
-Create volume based on desired slice thickness
-Create label map from the model
-Modify the label map by adding the layers “downward” across the volume
-Recompute surface representation
-Export

I’ll report back here as progress continues. Any tips appreciated!

1 Like

This sounds like a good approach. You may use Crop Volume module (even from your own module, programmatically) to create a reference volume with any size, axis directions (you can rotate the ROI by applying a transform to it), and any resolution.

You may use Segmentations module to convert between labelmap and closed surface representations: you can import your model, Segmentations can automatically create a labelmap representation; make it the master representation; process it; and at the end you can export the segment back to a model.

1 Like

Progress Update 1 (Should I edit original post or keep adding replies?)

-A simple UI with a model select node, and a push button (More parameters to be added later)

On Push Button Code:

  • The model bounding box is calculated
  • Slice thickness, and number of slices are calculated
  • A new volume is added to the MRML Scene
  • A transform node is added that translates volume to fit the model

I verify this by going to the crop volume Module after I run my script and creating a new annotation ROI and fit ROI to volume.

Thanks for the update. Nice progress. A couple of suggestions:

  • It seems that you use some very old template for your extension. Download the latest nightly build of Slicer (it works well and there are many bugfixes and improvements compared to the latest stable version) and use its Extension Wizard module to generate an up-to-date module template.
  • Create a new project on github and keep updating that instead of sharing code in some temporary gists (make sure to include all the files that Extension Wizard generated - it will allow you to submit your module to the Slicer appstore when it’s ready)
  • As a next step, I would recommend to have a look at Segmentations, as it allows seamless conversion between labelmaps and models. See self-test of Segment Statistics module for an example of how to create segments from models.
  • You don’t need to create a linear transform to position your volume: a volume can be fully positioned, scaled, and rotated by setting its IJK to RAS transform. Once you have your volume, set it as reference geometry in your segmentation node (segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(…))
  • To update your segment with undercut:

Re: Extension Wizard. I have been following tutorial from Sonia Pujol and Steve Pieper for my Module Template. I will use the wizard and re-package once I get the initial workflow

Re Git: Absolutely. Most of my projects are github repos. In fact I just used Gist to get a quick show and tell :slight_smile:

Re: Segmentation self test:
I get an error with this line. First I used inputModel.GetPolyData() using my own input model, then I tried using a vtk.vtkSphereSource() from the example to see if it was my model. I’m using nightly from 6/11/2017 so I will download todays and try again but perhaps there is an error in that line?

Traceback (most recent call last):
File “C:/Dev/slicer_scripts/ModelUndercutRemoval.py”, line 173, in onHelloWorldButtonClicked
segmentationNode.AddSegmentFromClosedSurfaceRepresentation (sphereSource.GetOutput(), segmentationNode.GetSegmentation().GenerateUniqueSegmentID(“Test”))
AttributeError: ‘vtkCommonCorePython.vtkObject’ object has no attribute ‘GenerateUniqueSegmentID’

Things are moving along nicely! Thanks for you help and pointers.

-P

To avoid this error, you need to import vtkSegmentationCore:

import vtkSegmentationCorePython as vtkSegmentationCore

Soon this import will be done automatically - see Import vtkSegmentationCorePython and vtkAddonPython by default ¡ Issue #4385 ¡ Slicer/Slicer ¡ GitHub.

1 Like
  1. I used the Extension Wizard to generate cmakelists.txt, a png file.

  2. I have uploaded project to a github directory. It is up to date with current code as seen in the video below.
    https://github.com/patmo141/SlicerModelUndercuts

  3. Initial workflow is very close! I seem to have a problem with the final step of generating a surface from the Label Map. It’s like it uses the old surface and ignores the new lablel map? Perhaps I need to delete the old surface model? See video.

  1. After this, i will do code cleanup, start to tweak parameters, and add adjustable direction, add adjustable resolutions, then create a pull request for inclusion with Slicer Modules

So far a good time!

It looks really nice! I think the only step you miss is calling modelLabelMap.Modified() after you’ve modified the modelLabelMap voxels using numpy (around line 175).

Another small suggestion: instead of switching between Segmentations and Models modules to show/hide segments and models and export segment to model - you can use the Data module for all this. Click on the eye icon to show/hide a node. Right-click on a segmentation node to export to model.

Use the Extension wizard to create a complete skeleton for your extension and your module (adding just a CMakeListst.txt is not enough; you’ll need a separate subdirectory for your module, within that a Resources, Testing, etc. directory). Add a new module with identical name as your existing module and copy-paste content from your existing module.

yes this fixed it! The output model now reflects the label map changes

1 Like

A post was split to a new topic: How to install extensions?

Hello Patrick,

I know it has been a while, but did you get the chance to finish your extension. The github repo does not seem to work as shown in the video. And I wasn’t able to find the option to choose the insertion axis.

Regardless thank you for the work, we are trying to create a module to produce dental surgical guide and this would be a key component.