Performance degrade for more than 10000 actor

Hello Team,

I tried to support large actor count with individual interaction. Performance degrade when actor count goes beyond 1000 actor. Please support me on this. I need to move individual sphere with mouse as same time actor count goes beyond 10000.

#define vtkSP(instance, type)
vtkSmartPointer instance = vtkSmartPointer::New();
int main()
{
vtkSP(colors, vtkNamedColors);

std::array<unsigned char, 4> bkg{ {26, 51, 102, 255} };
colors->SetColor("BkgColor", bkg.data());

vtkSP(renderer, vtkRenderer);
vtkSP(append, vtkAppendPolyData);
for (int j = 1; j <= 20; j++)
{
	for (int i = 1; i <= 20; i++)
	{
		vtkSP(sphere, vtkSphereSource);
		sphere->SetRadius(1.0);
		sphere->SetCenter(2 * i, 2 * j, 0);
		sphere->SetThetaResolution(16);
		sphere->SetPhiResolution(16);

		sphere->Update();
		append->AddInputConnection(sphere->GetOutputPort());
	}
}

vtkSP(sphereMapper, vtkPolyDataMapper);
sphereMapper->SetInputConnection(append->GetOutputPort());
vtkSP(sphereActor, vtkActor);
sphereActor->SetMapper(sphereMapper);
sphereMapper->ScalarVisibilityOff();
//sphereMapper->Update();
//sphereMapper->StaticOn();
renderer->AddActor(sphereActor);

vtkSP(renderWindow, vtkRenderWindow);
renderWindow->SetSize(500, 500);
renderWindow->AddRenderer(renderer);
renderWindow->SetWindowName("Approach3: Single Actor and Renderer");

for (int i = 0; i <= 15; i++)
{
	renderWindow->Render();
	renderer->GetActiveCamera()->Roll(24);
}

vtkSP(renderWindowInteractor, vtkRenderWindowInteractor);
renderWindowInteractor->SetRenderWindow(renderWindow);

renderWindow->Render();
const char* info = renderWindow->ReportCapabilities();
renderWindowInteractor->Start();

return EXIT_SUCCESS;

}

Your example does not seem related as there is a single actor with the geometry of all the 400 spheres.

Yes Joachim, you are correct there is 1 actor only. Previously I tried to create 400 actor and 1 renderer screen, it will degrade the performance, so i tried to group all actor in one and then render. I able to got 40 FPS, which is good but when I tried to increase the sphere count to 2000 or more my performance degrade drastically. Also I loose the individual interaction of each sphere.

Please find my previously code containing 400 actor.

int Approach1()
{
	vtkSP(colors, vtkNamedColors);

	std::array<unsigned char, 4> bkg{ {26, 51, 102, 255} };
	colors->SetColor("BkgColor", bkg.data());

	vtkSP(renderer, vtkRenderer);
	vtkSP(append, vtkAppendPolyData);
	for (int j = 1; j <= 20; j++)
	{
		for (int i = 1; i <= 20; i++)
		{
			vtkSP(sphere, vtkSphereSource);
			sphere->SetRadius(1.0);
			sphere->SetCenter(2 * i, 2 * j, 0);
			sphere->SetThetaResolution(16);
			sphere->SetPhiResolution(16);

			sphere->Update();
			append->AddInputConnection(sphere->GetOutputPort());

			vtkSP(sphereMapper, vtkPolyDataMapper);
			sphereMapper->SetInputConnection(append->GetOutputPort());
			vtkSP(sphereActor, vtkActor);
			sphereActor->SetMapper(sphereMapper);
			sphereMapper->ScalarVisibilityOff();
			//sphereMapper->Update();
			//sphereMapper->StaticOn();
			renderer->AddActor(sphereActor);
		}
	}

	vtkSP(renderWindow, vtkRenderWindow);
	renderWindow->SetSize(500, 500);
	renderWindow->AddRenderer(renderer);
	renderWindow->SetWindowName("Approach1: Multiple Actor and Renderer");

	for (int i = 0; i <= 15; i++)
	{
		renderWindow->Render();
		renderer->GetActiveCamera()->Roll(24);
	}

	vtkSP(renderWindowInteractor, vtkRenderWindowInteractor);
	renderWindowInteractor->SetRenderWindow(renderWindow);

	renderWindow->Render();
	const char* info = renderWindow->ReportCapabilities();
	renderWindowInteractor->Start();

	return EXIT_SUCCESS;
}

Problem Statement:

  1. Need to render more than 10000 actor of different geometry types such as Sphere, Cone, Cylinder etc
  2. Need to interact individual entity by mouse control without any lag.

It would be great help if you provide some help on this.

Thanks in advance

Hello,

Can you move the defintion of the vtkSP() macro into a code section? There are parts of it missing due to markdown formatting.

thanks,

Paulo

Please find vtkSP definition.

#define vtkSP(instance, type)
vtkSmartPointer instance = vtkSmartPointer::New();

Hello,

For you case, first, I’d use a single source (vtkSphereSource) for all actors and set the position of each actor (vtkProp3D::SetPosition(double pos[3])) so they are rendered in different positions. Second, I’d use a single mapper for all actors.

regards,

Paulo

You should keep the number of actors preferably below a few hundred. If you want to display thousands of small spheres then you can use a glyph filter (such as vtkGlyph3D) and render it using a single actor; or for even better performance, use a glyph mapper.

I’m not sure if there is a widget that you can use for individual picking and moving of individual spheres. In 3D Slicer, we had to implement our own widget for this, and the performance is good with a few 10k points. If you need to interact with many point glyphs from a C++ or Python application with Qt GUI then you may consider using 3D Slicer as a platform, especially if you work in the medical imaging domain.

You may find this and related topics relevant:

2 Likes

You are appending the spheres. You could also use a composite data set like vtkMultiBlockDataSet.
And pass it to a composite mapper like vtkCompositePolyDataMapper2.

The composite data set allows control over color, opacity of each block (sphere) and performance should be improved.