How to Implement Scissors tool?

Hello All, I am using VTK for a long time, and there’s this feature that I couldn’t implement in any version (C++/JS) which is the scissors tool where you can draw a 2D contour, then it automatically hides/shows the projection of this contour, any help on how I can start this?? what steps to follow?

You might want to look at 3D Slicer (C++/Python) that has scissor tool in the Segmentation Editor module.

1 Like

Here’s the link to the relevant file: https://github.com/Slicer/Slicer/blob/04d69cd0749ce72b44113535fa2c4da20386142c/Modules/Loadable/Segmentations/EditorEffects/qSlicerSegmentEditorScissorsEffect.cxx

This could be implemented in vtk.js, but no effort has been made towards that yet.

1 Like

Thanks for the link, but I am still confused.
What are the steps to follow if I want to implement in vtk.js, I assume:

  1. draw a 2d contour on the screen
  2. map it to world position
  3. compute the projection of this contour
  4. compute the intersection between the projection and the volume
  5. hide these voxels
    Is this correct? and is there any tools for each step inside vtk.js? as I can see in the slicer code it has some classes that are missing in vtk.js, so I want like a pipeline to follow inisde vtk.js
  1. Drawing a 2D contour on the screen could be done using something like vtkShapeWidget.
  2. Mapping display space points to world positions can be done using renderWindow.displayToWorld(coord)
  3. 3 and 4 are more involved. Here is one thought: you could take your 2d contour as polydata line, and extrude surfaces from the near clipping plane to the far clipping plane. Take the camera direction, and compute the transform such that the camera looks down on Z, then transform your polydata similarly. This way, you can go down Z and rasterize each “layer” of your contour.
  4. take the rasterized polydata from step 3, and do a 3D stencil operation/filter, where you leave voxels on if it’s in the rasterized volume, and vice-versa. This can be implemented as a filter, at the cost of duplicating the volume memory.
  5. render the new volume

Step 3 and 4 are the most complicated steps of this pipeline, and vtk.js doesn’t have built-in support for certain tasks. I think the key feature that is needed is rasterizing contours in order to determine which voxels are inside and outside.

1 Like

Thanks @Forrest
How does the spacing value of ImageData affect when I crop freehand?. For example: (0.703125, 0.703125, 1.25)

Freehand cropping generates world coordinates. How you handle non-integral image index coordinates after transforming is up to you (rounding, floor, etc.).