Questions about layer of vtkRenderer

Hello,
I have a question about the layer of the vtkRenderer. I set two layers/renders for vtkRenderWindow, when the two renders/layers display extent are different, the display is annormal. as shown here.

The white box is layer 1, other is layer 0. My goal is to make the white box display at the front. but the upper left corner is obviously abnormal.

Could you please advise for me?

Thank you :slightly_smiling_face:

Hi,

My two cents: I believe there’s something clipping the mentioned corner. Maybe you should check any clipping planes defined or the clipping distances configured for your scene.

best,

Paulo

Hi,
I recorded a video, I’m sure I haven’t set any clipping configuration.The image and the box are on different layers.I guess it may have something to do with camera settings

Hello,

Thanks for the video. Like I said before, please, check the clipping distances: VTK: vtkCamera Class Reference

take care,

Paulo

Hello,
Thanks for you reply. I read the link you sent and made sure that it was not set in my program. Default clipping distances used in my program. I also tried to set the clipping distances range to 0.01-2000, but the same problem still occurred.

In addition, i think how to use vtkRenderer::ResetCameraClippingRange in moving is important to solve this problem, because I found that when I move the box and call this method, this problem will not occur again. This phenomenon occurs when I move other places and this method is not called.

That confirms the problem is caused by clipping planes. Per the docs: VTK: vtkRenderer Class Reference :

Reset the camera clipping range based on the bounds of the visible actors.

This ensures that no props are cut off

So you’re likely rotating the actors instead of the camera, then parts of them may fall out of the clipping range when you move them about. That’s quite the expected behavior. Maybe you can avoid calling that method repeatedly by positioning the actors a bit far ahead (e.g. around Z=1000) or adjusting the range accordingly as suggested.

Hello @Paulo_Carvalho,
There’s good news, although I don’t know why, when I correctly calculated the camera clipping range, I solved this problem. I found that the camera clipping range always uses the second prop as the basis for calculation, so my solution is to calculate all the props together, so that the camera clipping range can cover all the props.

Finally, thank for your suggestion, which has been very helpful to me.

Hi,

So can you please share your solution? Others with the same issue as yours may benefit from it.

regards,

PC

As shown in the following code, calculate the bounds of all props and call vtkRenderer::ResetCameraClippingRange.This method will correctly calculate the clipping range.

class MyCamerCallback : public vtkCommand
{
public:

	KtOpenGLNativeWidget* m_widget = nullptr;

	static MyCamerCallback *New()
	{
		return new MyCamerCallback;
	}

	virtual void Execute(vtkObject *caller,
		unsigned long, void*)
	{
		// set one camera;
		vtkCamera *camera = static_cast<vtkCamera*>(caller);

		auto renders = m_widget->renderWindow()->GetRenderers();
		int n = renders->GetNumberOfItems();
		auto render = renders->GetFirstRenderer();
		double allBounds[6] = { 0 };
		allBounds[0] = allBounds[2] = allBounds[4] = VTK_DOUBLE_MAX;
		allBounds[1] = allBounds[3] = allBounds[5] = -VTK_DOUBLE_MAX;
		bool enabled = false;
		for (int i = 0; i < n; i++)
		{
			auto render = static_cast<vtkRenderer*>(renders->GetItemAsObject(i));
			double bounds[6] = { 0 };
			render->ComputeVisiblePropBounds(bounds);
			if (vtkMath::AreBoundsInitialized(bounds))
			{
				enabled = true;

				if (bounds[0] < allBounds[0])
				{
					allBounds[0] = bounds[0];
				}
				if (bounds[1] > allBounds[1])
				{
					allBounds[1] = bounds[1];
				}
				if (bounds[2] < allBounds[2])
				{
					allBounds[2] = bounds[2];
				}
				if (bounds[3] > allBounds[3])
				{
					allBounds[3] = bounds[3];
				}
				if (bounds[4] < allBounds[4])
				{
					allBounds[4] = bounds[4];
				}
				if (bounds[5] > allBounds[5])
				{
					allBounds[5] = bounds[5];
				}
			}
		}
		if (camera && render && enabled)
		{
			render->ResetCameraClippingRange(allBounds);
		}

		//double rg[2] = { };
		//camera->GetClippingRange(rg);
		//LOG_DEBUG("GetClippingRange [{0}] [{1}]", rg[0], rg[1]);
	}
};

KtOpenGLNativeWidget::KtOpenGLNativeWidget(QWidget* parent, Qt::WindowFlags f)
	:QVTKOpenGLNativeWidget(parent, f)
{
	m_render = vtkSmartPointer<vtkRenderer>::New();

	vtkSmartPointer<MyCamerCallback> cameraCallback = vtkSmartPointer<MyCamerCallback>::New();
	cameraCallback->m_widget = this;
	m_render->GetActiveCamera()->AddObserver(vtkCommand::ModifiedEvent, cameraCallback);
    renderWindow()->AddRenderer(m_render);
	renderWindow()->Render();
}
1 Like