Search code examples
c++renderingvtk

VTK Camera Clipping with 2 Renderers


Current Setup:

  • I have 2 renderers, gridRenderer and geoRenderer, within 2 layers of a render window:
gridRenderer->SetLayer(0);
geoRenderer->SetLayer(1);
RenderWindow()->SetNumberOfLayers(2);
RenderWindow()->AddRenderer(geoRenderer);
RenderWindow()->AddRenderer(geoRenderer);
  • I then connect their interactor by setting both of their active cameras to the same one:
 gridRenderer->SetActiveCamera(geoRenderer->GetActiveCamera());

This successfully allows me to have a grid in the background, with a geometry in the foreground.

Problem:

  • The camera's clipping planes only focused on the geoRenderer, causing the much larger gridRenderer's actor to be clipped out.

enter image description here

Similar Issue:

  • https://gitlab.kitware.com/vtk/vtk/issues/17107

  • The difference between my issue and this one is that I am updating both the gridRender's and geoRenderer's actors, sometimes removing all of the actors within a renderer entirely (empty renderer could mess up the clipping planes, not rendering anything, if the camera chooses it as the active renderer).

  • My assumption is that VTK is confused as to which renderer to use in order to set the shared camera's clipping planes. I tried using vtkRenderer::ResetCameraClippingRange() on both of the renderer's but cannot get the clipping planes to form properly

  • Is there someway I can tell VTK which renderer to look at when resetting the clipping planes/camera?

Update:

  • I have begun to manually set the clipping range using a sum of ComputeVisiblePropBounds calls, along with disabling vtkInteractorStyle::AutoAdjustCameraClippingRange as such:
double geoCB[6];
double gridCB[6];
geoRenderer->ComputeVisiblePropBounds(geoCB);
gridRenderer->ComputeVisiblePropBounds(gridCB);
double finalCB[6];
for (int i = 0; i < 6; i++) {
  if (i % 2 == 0) {
    // Even Index is Min
    if (geoCB[i] < gridCB[i]) {
      finalCB[i] = geoCB[i];
    } else {
      finalCB[i] = gridCB[i];
    }
  } else {
    // Odd Index is Max
    if (geoCB[i] > gridCB[i]) {
      finalCB[i] = geoCB[i];
    } else {
      finalCB[i] = gridCB[i];
    }
  }
}
geoRenderer->ResetCameraClippingRange(finalCB);

Unfortunately this still does not work properly at all...


Solution

  • Important Update:

    • The above code is correct, you just need to call it every single time before RenderWindow->Render().
    • After creating my own implmementation of vtkRenderWindow, I simply needed to overrride Render(), putting the above code inside, and then finisihing the ovveride with a call to the default Render()
    • If you simply set the min clipping planes to a very small value, and the max to a very large one, it might work but can destroy the depth filter, messing the whole render up completely.