[vtkusers] create multiple cubes with different colors

David E DeMarle dave.demarle at kitware.com
Tue Jun 7 10:15:24 EDT 2011


You are right to use the second approach. Each actor has enough overhead
that you can not use more than a few hundreds of them in an interactive
application.

To give each cell a distinct color, avoid color mapping. Make a 3 component
unsigned char array with one entry per cell and insert that into the
UnstructuredGrid's cell data array set. Unless you tell it otherwise, VTK
will recognize this as an RGB attribute array and render those colors
directly rather than trying to map those values through a lookup table.

David E DeMarle
Kitware, Inc.
R&D Engineer
28 Corporate Drive
Clifton Park, NY 12065-8662
Phone: 518-371-3971 x109


On Tue, Jun 7, 2011 at 9:39 AM, Andreas Stein <Stein_85 at web.de> wrote:

> Hey,
>
> I am new to this list and looking for the answer to my current problem.
> Unfortunately, I could not find a corresponding topic in the wiki.
>
> What I want to do, is drawing multiple cubes (several thousands) with
> different colors.
>
> First, I tried to solve the problem by using the vtkCubeSource class.
> Here is the C++ function:
>
> void mapViewer::drawCubesViaCubeSource(gridMap map)
> {
>     // Create renderer and render window
>     vtkRenderer *m_ren = vtkRenderer::New();
>     vtkRenderWindow *renWin = vtkRenderWindow::New();
>     renWin->AddRenderer(m_ren);
>
>     // Create interactor
>     vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
>     iren->SetRenderWindow(renWin);
>
>     // Step through all map cells
>     for (ushort n=0;n<map.GetMapInfo().cellsNorth; n++)
>     {
>         for (ushort e=0;e<map.GetMapInfo().cellsEast; e++)
>         {
>             vector<mapData> mapElement = map.getElement(n,e);
>             for (uint i=0; i<mapElement.size(); i++)
>             {
>                 if (mapElement[i].isValid())
>                     drawCube(n, e,
> (-mapElement[i].height/map.GetMapInfo().cubeHeight),
> map.GetMapInfo().cellSize, map.GetMapInfo().cubeHeight,
> mapElement[i].color[0], mapElement[i].color[1], mapElement[i].color[2]);
>             }
>             mapElement.clear();
>         }
>     }
>
>     // Set window background color
>     m_ren->SetBackground(0,0,0);
>
>     // Render an image (lights and cameras are created automatically)
>     renWin->Render();
>
>     // Begin mouse interaction
>     iren->Start();
> }
>
> This is the corresponding function "drawCube" which is called
>
> void mapViewer::drawCube(double n, double e, double d, float cellSize,
> float cubeHeight, unsigned char r, unsigned char g, unsigned char b)
> {
>     // Create a cube
>     vtkCubeSource* cube = vtkCubeSource::New();
>     cube->SetCenter(e*cellSize,-d*cubeHeight,-n*cellSize);
>     cube->SetXLength(cellSize);
>     cube->SetYLength(cubeHeight);
>     cube->SetZLength(cellSize);
>
>     // Create a mapper and actor
>     vtkPolyDataMapper* mapper = vtkPolyDataMapper::New();
>     mapper->SetInputConnection(cube->GetOutputPort());
>
>     vtkActor* cubeActor = vtkActor::New();
>
>  cubeActor->GetProperty()->SetColor(floor(float(r))/255,floor(float(g))/255,floor(float(b))/255);
>     cubeActor->SetMapper(mapper);
>
>     m_ren->AddActor(cubeActor);
>
>     // Clean-up
>     cubeActor->Delete();
>     cube->Delete();
>     mapper->Delete();
> }
>
> The problem was that after rendering a lot of cubes, the mouse interaction
> did not work very well. When you try to move the displayed data in the vtk
> window, everything is very slow.
> This may be the case because the visualization blocks a lot of system
> memory (about 700MB).
> In the next approach, I tried to use the vtkHexahedron class to fulfill the
> task.
> You can see the function here:
>
> void mapViewer::drawCubesViaHexahedron(gridMap map)
> {
>     // Create renderer and render window
>     m_ren = vtkRenderer::New();
>     vtkRenderWindow *renWin = vtkRenderWindow::New();
>     renWin->AddRenderer(m_ren);
>
>     // Create interactor
>     vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
>     iren->SetRenderWindow(renWin);
>
>     // Create the point structure
>     vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
>
>     // Step through all map cells
>     for (ushort n=0;n<map.GetMapInfo().cellsNorth; n++)
>     {
>         for (ushort e=0;e<map.GetMapInfo().cellsEast; e++)
>         {
>             vector<mapData> mapElement = map.getElement(n,e);
>             for (uint i=0; i<mapElement.size(); i++)
>             {
>                 if (mapElement[i].isValid())
>                 {
>
>                 // Setup the coordinates of eight points
>                 // (the two faces must be in counter clockwise order as
> viewd from the outside)
>                 double P0[3] =
> {float(e)*map.GetMapInfo().cellSize-map.GetMapInfo().cellSize/2,
> mapElement[i].height-map.GetMapInfo().cubeHeight/2,
> -(float(n)*map.GetMapInfo().cellSize-map.GetMapInfo().cellSize/2)};
>                 double P1[3] =
> {float(e)*map.GetMapInfo().cellSize+map.GetMapInfo().cellSize/2,
> mapElement[i].height-map.GetMapInfo().cubeHeight/2,
> -(float(n)*map.GetMapInfo().cellSize-map.GetMapInfo().cellSize/2)};
>                 double P2[3] =
> {float(e)*map.GetMapInfo().cellSize+map.GetMapInfo().cellSize/2,
> mapElement[i].height+map.GetMapInfo().cubeHeight/2,
> -(float(n)*map.GetMapInfo().cellSize-map.GetMapInfo().cellSize/2)};
>                 double P3[3] =
> {float(e)*map.GetMapInfo().cellSize-map.GetMapInfo().cellSize/2,
> mapElement[i].height+map.GetMapInfo().cubeHeight/2,
> -(float(n)*map.GetMapInfo().cellSize-map.GetMapInfo().cellSize/2)};
>                 double P4[3] =
> {float(e)*map.GetMapInfo().cellSize-map.GetMapInfo().cellSize/2,
> mapElement[i].height-map.GetMapInfo().cubeHeight/2,
> -(float(n)*map.GetMapInfo().cellSize+map.GetMapInfo().cellSize/2)};
>                 double P5[3] =
> {float(e)*map.GetMapInfo().cellSize+map.GetMapInfo().cellSize/2,
> mapElement[i].height-map.GetMapInfo().cubeHeight/2,
> -(float(n)*map.GetMapInfo().cellSize+map.GetMapInfo().cellSize/2)};
>                 double P6[3] =
> {float(e)*map.GetMapInfo().cellSize+map.GetMapInfo().cellSize/2,
> mapElement[i].height+map.GetMapInfo().cubeHeight/2,
> -(float(n)*map.GetMapInfo().cellSize+map.GetMapInfo().cellSize/2)};
>                 double P7[3] =
> {float(e)*map.GetMapInfo().cellSize-map.GetMapInfo().cellSize/2,
> mapElement[i].height+map.GetMapInfo().cubeHeight/2,
> -(float(n)*map.GetMapInfo().cellSize+map.GetMapInfo().cellSize/2)};
>
>                 // Create the points
>                 points->InsertNextPoint(P0);
>                 points->InsertNextPoint(P1);
>                 points->InsertNextPoint(P2);
>                 points->InsertNextPoint(P3);
>                 points->InsertNextPoint(P4);
>                 points->InsertNextPoint(P5);
>                 points->InsertNextPoint(P6);
>                 points->InsertNextPoint(P7);
>
>                 }
>             }
>             mapElement.clear();
>         }
>     }
>
>
>     //create the hexahedron
>     vtkHexahedron * *theHex;
>     theHex = new vtkHexahedron*[map.getNumberOfFilledCells()];
>
>     for(int i=0;i<map.getNumberOfFilledCells();i++)
>     {
>         theHex[i] = vtkHexahedron::New();
>         theHex[i]->GetPointIds()->SetNumberOfIds(8);
>         for (int j = 0; j <8; j++)
>         {
>             theHex[i]->GetPointIds()->SetId(j,j+(i*8));  //this maps
> internal id 0-7 to global point Id
>         }
>     }
>
>     //create an unstructured grid for the hexahedron
>     vtkUnstructuredGrid* theGrid = vtkUnstructuredGrid::New();
>     theGrid->Allocate(map.getNumberOfFilledCells());
>     for(int i =0;i<map.getNumberOfFilledCells();i++)
>     {
>         theGrid->InsertNextCell(theHex[i]->GetCellType(),
>         theHex[i]->GetPointIds());
>     }
>     theGrid->SetPoints(points);
>
>     //create a mapper for the hexahedron
>     vtkDataSetMapper *theHexMapper;
>     theHexMapper = vtkDataSetMapper::New();
>     theHexMapper->SetInput(theGrid);
>
>     //create an actor
>     vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
>     actor->SetMapper(theHexMapper);
>
>     m_ren->AddActor(actor);
>
>     // Set window background color
>     m_ren->SetBackground(0,0,0);
>
>     // Render an image (lights and cameras are created automatically)
>     renWin->Render();
>
>     // Begin mouse interaction
>     iren->Start();
> }
>
> Using the second approach led to very good results.
> Furthermore it reduced the blocked system memory to about 100MB.
> My problem is now:
> By now, there are no colors in the second approach.
> How can I color the cubes. It is important to know that every cube has to
> get a different color.
> I have no clue how to solve this problem.
>
> Any ideas?
>
> I would appreciate any help.
> Thanks in advance.
>
> Greetings,
> stone
>
>
>
>
> Schon gehört? WEB.DE hat einen genialen Phishing-Filter in die
> Toolbar eingebaut! *http://produkte.web.de/go/toolbar*<http://produkte.web.de/go/toolbar>
>
> _______________________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Please keep messages on-topic and check the VTK FAQ at:
> http://www.vtk.org/Wiki/VTK_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.vtk.org/mailman/listinfo/vtkusers
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20110607/91ca3571/attachment.htm>


More information about the vtkusers mailing list