Is there any way to draw hundreds of balls with different colors?

Is there any way to draw hundreds of balls with different colors more efficiently?
I had obtained the position information from the sensor and hope to illustrate the data using the ball in 3D View. There is hundreds of balls should be illustrated with different color! How to achieve this in a more efficient way?
Thanks very much!

Create a vtkPolyData (using vtkGlyph3D filter), set that into a Model node, and choose a colormap to color it (based on point data stored in the vtkPolyData). Let us know if you stuck at any point.

1 Like

You can check my gist, which includes a minimal example of vtkGlyph3D: https://gist.github.com/fepegar/bb18198c9dae273e083521db422ec5c0

1 Like

If you want to visualize positions then I think fiducials could be a good way to do that. You can add fiducials from the toolbar and handle them in the Markups module. They are visualized in 3D as balls by default. The different colors can be set to each fiducial set node.

I think it would be hard for Slicer to handle “hundreds” of fiducials, as discussed in this issue.

1 Like

Hi Lasso,

I had created a vtkPolyData which store the point data and scalars (color), and set it into a Model node. How can I choose the scalars stored in vtkPolyData as the colormap?
Thanks very much!

vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
for(iter=path->begin();iter!=path->end();iter++)
	points->InsertNextPoint(iter->pos.x,iter->pos.y,iter->pos.z);

vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
polyData->SetPoints(points);

vtkSmartPointer<vtkVertexGlyphFilter> vertexFilter = vtkSmartPointer<vtkVertexGlyphFilter>::New();
vertexFilter->SetInputData(polyData);
vertexFilter->Update();

vtkSmartPointer<vtkUnsignedCharArray> Colors=vtkSmartPointer<vtkUnsignedCharArray>::New();
Colors->SetName("Color");
Colors->SetNumberOfComponents(3);
std::vector<Point3f>::iterator it1;
for(it1=color->begin();it1!=color->end();it1++)
	Colors->InsertNextTuple3(it1->x,it1->y,it1->z);	

vtkSmartPointer<vtkPolyData> polyData1 = vtkSmartPointer<vtkPolyData>::New();
polyData1->ShallowCopy(vertexFilter->GetOutput());
polyData1->GetPointData()->SetScalars(Colors);


//create model node
m_PtsModelNode[which] = vtkSmartPointer<vtkMRMLModelNode>::New();
m_PtsModelNode[which].Take(vtkMRMLModelNode::SafeDownCast(m_scene->CreateNodeByClass("vtkMRMLModelNode")));
m_PtsModelNode[which]->SetName(m_scene->GetUniqueNameByString(m_strModelName[which].c_str()));
m_PtsModelNode[which]->SetAndObservePolyData(polyData1);

Best,
Wenpeng

Example:

modelNode.GetDisplayNode().SetActiveScalarName('Distance')
modelNode.GetDisplayNode().SetAndObserveColorNodeID('vtkMRMLFreeSurferProceduralColorNodeBlueRed')
modelNode.GetDisplayNode().ScalarVisibilityOn()
#modelNode.GetDisplayNode().AutoScalarRangeOn()
modelNode.GetDisplayNode().SetScalarRangeFlag(slicer.vtkMRMLDisplayNode.UseColorNodeScalarRange) 

See API description here: http://apidocs.slicer.org/master/classvtkMRMLModelDisplayNode.html

1 Like

Hi Fernando,

Thanks for your reply. It works!

Best,
Wenpeng

1 Like

Hi Lasso,

Thanks for your reply. It works!

Best,
Wenpeng