4-bit
4-bit

Reputation: 274

VTK camera update issue in vtkImageResliceMapper

I am trying to show an image using vtkImageResliceMapper.

The problem is that I want to position the camera so that the image fills the whole height of the viewport. I have found some camera parameters that would do the job, but when I start the application, no image is shown until I drag/scroll with the mouse inside the window. I guess that the vtkInteractorStyleTrackballCamera events are doing something that updates the state of one of the components, but I can't figure out what it is. As soon as I do interaction with the mouse, the image appears and everything works as expected.

If I replace the camera settings with a simple imageRenderer->ResetCamera(), the image will be shown, but it will not fill the screen.

(I have googled for hours and reading posts in this mailing list and even searched in the source code without any success).

Any help would be appreciated, here is the code:

int main(int, char *[])
{
    auto imageReader = vtkSmartPointer<vtkPNGReader>::New();
    imageReader->SetFileName("image.png");

    auto imageResliceMapper = vtkSmartPointer<vtkImageResliceMapper>::New();
    imageResliceMapper->SetInputConnection(imageReader->GetOutputPort());

    auto imageSlice = vtkSmartPointer<vtkImageSlice>::New();
    imageSlice->SetMapper(imageResliceMapper);

    auto imageRenderer = vtkSmartPointer<vtkRenderer>::New();
    imageRenderer->SetBackground(0, 0, 0); // Background color black
    imageRenderer->SetViewport(0.0, 0.0, 1.0, 1.0);
    imageRenderer->AddViewProp(imageSlice);

    // Set the camera so that the image fills the viewport.
    imageRenderer->GetActiveCamera()->SetPosition(729.5, 539.5, 1977.83);
    imageRenderer->GetActiveCamera()->SetViewUp(0, 1, 0);
    imageRenderer->GetActiveCamera()->SetFocalPoint(729.5, 539.5, 1976.83);

    auto renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->SetPosition(500, 200);
    renderWindow->SetSize(1024, 768);
    renderWindow->AddRenderer(imageRenderer);

    auto renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    renderWindowInteractor->SetRenderWindow(renderWindow);

    auto style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
    style->setCamera(imageRenderer->GetActiveCamera());
    renderWindowInteractor->SetInteractorStyle(style);
    renderWindowInteractor->Render();
    renderWindowInteractor->Initialize();

    renderWindow->Render();
    renderWindowInteractor->Start();

    return EXIT_SUCCESS;
}

Upvotes: 2

Views: 739

Answers (2)

TurtleIzzy
TurtleIzzy

Reputation: 1047

I had a similar issue but ResetCameraClippingRange worked only for the first time. If I set another group of parameters, the viewport just won't update before I make any movement by mouse.

I googled and found many people (#1, #2, #3) encountered similar issue as mine but none of them had a valid solution. I have also tried setting a new vtkCamera object instead of modifying the one returned by GetActiveCamera, but nothing worked.

So I ended up reading source code of vtkInteractorStyleTrackballCamera.cxx.

I found that you have to explicitly call Render method of renderWindowInteractor after you make any change to camera parameters to make the viewport update according to https://github.com/Kitware/VTK/blob/master/Interaction/Style/vtkInteractorStyleTrackballCamera.cxx#L272

These three steps solved this issue perfectly.

        self.viewport.renderer.ResetCameraClippingRange()
        self.viewport.renderer.UpdateLightsGeometryToFollowCamera()
        self.viewport._Iren.Render()
  1. https://www.mail-archive.com/[email protected]/msg07176.html
  2. Setting camera and frustum parameters in VTK
  3. https://public.kitware.com/pipermail/vtkusers/2010-October/063594.html

Upvotes: 0

4-bit
4-bit

Reputation: 274

Finally I found the solution! (And I know lots of people are having this problem so I post the answer here).

In order to get the graphics to show correctly after changing the camera parameters, you have to call:

imageRenderer->ResetCameraClippingRange();

Upvotes: 4

Related Questions