VTK planes not clipping volume using react-vtk-viewport

Hello,

I have been working on this for over a month, and I’m pulling my hair over it.

Basically i’m using the example from this page: https://github.com/OHIF/react-vtkjs-viewport/blob/master/examples/VTKVolumeRenderingExample.js to pull images and create a volume and render it as a base for a part of my project. I’m trying to implement VTK clipping planes from the VTK example page: https://kitware.github.io/vtk-js/examples/VolumeClipPlane.html. I have set my mapper as global. i can interact with the planes and set their normal and original, but they don’t appear to be clipping the volume.

I have literally tried everything, I checked that the planes do intersect the volume using imageData.getBounds(), i created a range input to manually move the planes, changed the order in which the code applied the planes, when the mapper is set to the actor (in which function). Added mapper.update() which didn’t do anything. I even check that the View3d component handles everything correctly. Am I missing something? My last guess was that View3d uses vtkGenericRenderWindow instead of vtkFullScreenRenderWindow, which shouldn’t be an issue. Any help is appreciated.

Here is is snip of my function:

function createActorMapper(imageData) {
  const mapper = vtkVolumeMapper.newInstance();
  const clipPlane1 = vtkPlane.newInstance();
  const clipPlane2 = vtkPlane.newInstance();

  const clipPlane1Normal = [-1, 1, 0];
  const clipPlane2Normal = [0, 0, 1];
  const extent = imageData.getExtent();
  const spacing = imageData.getSpacing();
  const sizeX = extent[1] * spacing[0];
  const sizeY = extent[3] * spacing[1];

  let clipPlane1Position = sizeX / 4;
  let clipPlane2Position = sizeY / 2;
  const clipPlane1Origin = [
    clipPlane1Position * clipPlane1Normal[0],
    clipPlane1Position * clipPlane1Normal[1],
    clipPlane1Position * clipPlane1Normal[2],
  ];
  const clipPlane2Origin = [
    clipPlane2Position * clipPlane2Normal[0],
    clipPlane2Position * clipPlane2Normal[1],
    clipPlane2Position * clipPlane2Normal[2],
  ];

  clipPlane1.setNormal(clipPlane1Normal);
  clipPlane1.setOrigin(clipPlane1Origin);
  clipPlane2.setNormal(clipPlane2Normal);
  clipPlane2.setOrigin(clipPlane2Origin);

  const rotationNormal = [0, 1, 0];
  const clipPlane1RotationAngle = 5; 
  const clipPlane2RotationAngle = 5; 
  vtkMatrixBuilder
    .buildFromDegree()
    .rotate(clipPlane1RotationAngle, rotationNormal)
    .apply(clipPlane1Normal);
  clipPlane1.setNormal(clipPlane1Normal);
  vtkMatrixBuilder
    .buildFromDegree()
    .rotate(clipPlane2RotationAngle, rotationNormal)
    .apply(clipPlane2Normal);
  clipPlane2.setNormal(clipPlane2Normal);

  mapper.addClippingPlane(clipPlane1);
  mapper.addClippingPlane(clipPlane2);
  mapper.setInputData(imageData);
  mapper.update();
  const actor = vtkVolume.newInstance();
  actor.setMapper(mapper);
 
  global.mapper = mapper;
  return {
    actor,
    mapper,
  };
}

In calculating the size of the imageData, the origin is getting neglected. You’d have to add the origin like so

const clipPlane1Origin = [
  imageOrigin[0] + clipPlane1Position * clipPlane1Normal[0],
  imageOrigin[1] + clipPlane1Position * clipPlane1Normal[1],
  imageOrigin[2] + clipPlane1Position * clipPlane1Normal[2],
];

I have already tried that , I’ve even tried imageData.setOrigin(0,0,0) and still can’t get it to work, did work for camera setClippinPlane() though, but not for VTK Planes.

Does the volume clipping plane example work for you?

One way to “see” the plane you’re using is to use the vtkImplicitPlaneWidget. Take a look at the ImageResliceMapper example for an idea on how to use the plane widget.