About ImplictPlaneWidget2.cxx

Hi,
I am using the example of ImplicitPlaneWidget2.
I want to be able to manipulate this by inputting a 3D image (.raw).

Data entry has been corrected as follows.
vtkSmartPointer reader = vtkSmartPointer::New();
reader->SetFileName(argv[1]);
reader->SetDataExtent(0, 511, 0, 511, 0, 511);
reader->SetFileDimensionality(3);
reader->SetDataScalarTypeToUnsignedChar();

I think that it is necessary to correct the part of “Setup a visualization pipeline”.
However, I do not know how to correct it.
Please let me know if you know.

https://lorensen.github.io/VTKExamples/site/Cxx/Widgets/ImplicitPlaneWidget2

@dgobbi

Hi Tomonari,

That example is for polydata, so it needs to be changed to work with image data.

“reader” must be “vtkImageReader2” (you have already done this part)
“mapper” must be “vtkImageResliceMapper”
“actor” must be “vtkImageSlice” (this is the actor type for images)

The code will look something like this:

vtkSmartPointer<vtkImageReader2> reader =
  vtkSmartPointer<vtkImageReader2>::New();
reader->SetFileName(argv[1]);
reader->SetDataExtent(0, 511, 0, 511, 0, 511);
reader->SetOrigin(-0.5*511, -0.5*511, -0.5*511);
reader->SetFileDimensionality(3);
reader->SetDataScalarTypeToUnsignedChar();

// Setup a visualization pipeline
vtkSmartPointer<vtkPlane> plane =
  vtkSmartPointer<vtkPlane>::New();

vtkSmartPointer<vtkImageResliceMapper> mapper =
  vtkSmartPointer<vtkImageResliceMapper>::New();
mapper->SetInputConnection(reader->GetOutputPort());
mapper->SetSlicePlane(plane);

vtkSmartPointer<vtkImageSlice> actor =
  vtkSmartPointer<vtkImageSlice>::New();
actor->SetMapper(mapper);

vtkImageProperty *property = actor->GetProperty();
property->SetColorWindow(255.0);
property->SetColorLevel(127.5);

// A renderer and render window
vtkSmartPointer<vtkRenderer> renderer =
  vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow =
  vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
renderer->AddViewProp(actor);

// An interactor
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
  vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);

// Render to update the actor (so that we can get its bounds)
renderWindow->Render();

// The callback will do the work
vtkSmartPointer<vtkIPWCallback> myCallback =
  vtkSmartPointer<vtkIPWCallback>::New();
myCallback->Plane = plane;

vtkSmartPointer<vtkImplicitPlaneRepresentation> rep =
  vtkSmartPointer<vtkImplicitPlaneRepresentation>::New();
rep->SetPlaceFactor(1.00); // This must be set prior to placing the widget
rep->DrawPlaneOff(); // Don't draw the plane if we are showing an image!
rep->PlaceWidget(actor->GetBounds());
rep->SetNormal(plane->GetNormal());

vtkSmartPointer<vtkImplicitPlaneWidget2> planeWidget =
  vtkSmartPointer<vtkImplicitPlaneWidget2>::New();
planeWidget->SetInteractor(renderWindowInteractor);
planeWidget->SetRepresentation(rep);
planeWidget->AddObserver(vtkCommand::InteractionEvent,myCallback);

// Render
renderWindowInteractor->Initialize();
renderWindow->Render();
planeWidget->On();

// Begin mouse interaction
renderWindowInteractor->Start();
1 Like

Hi Davidm,
Thanks for your reply.
The detailed explanation enabled the program to work properly.

As the next step, I would like to slice in the plane for 3D data such as volume rendering as in the example.
Is it technically possible?

Where should I correct?
Please let me know if you know.

@dgobbi

For volume rendering, the “mapper” must be vtkGPUVolumeRayCastMapper, and the “actor” must be vtkVolume. So the code would be like this:

// Setup a visualization pipeline
vtkSmartPointer<vtkPlane> plane =
  vtkSmartPointer<vtkPlane>::New();

vtkSmartPointer<vtkGPUVolumeRayCastMapper> mapper =
  vtkSmartPointer<vtkGPUVolumeRayCastMapper>::New();
mapper->SetInputConnection(reader->GetOutputPort());
mapper->AddClippingPlane(plane);

vtkSmartPointer<vtkColorTransferFunction> color =
  vtkSmartPointer<vtkColorTransferFunction>::New();
color->AddRGBPoint(0,   0.0, 0.0, 0.0);
color->AddRGBPoint(255, 1.0, 1.0, 1.0);

vtkSmartPointer<vtkPiecewiseFunction> opacity =
  vtkSmartPointer<vtkPiecewiseFunction>::New();
opacity->AddPoint(0,   0.00);
opacity->AddPoint(255, 1.00);

vtkSmartPointer<vtkVolumeProperty> property =
  vtkSmartPointer<vtkVolumeProperty>::New();
property->SetColor(color);
property->SetScalarOpacity(opacity);
property->SetInterpolationTypeToLinear();
property->ShadeOff();

vtkSmartPointer<vtkVolume> actor =
  vtkSmartPointer<vtkVolume>::New();
actor->SetMapper(mapper);
actor->SetProperty(property);

Thank you for your reply.
Thanks to you, I was able to realize what I was thinking.

@dgobbi