[vtkusers] create multiple cubes with different colors

stone85 Stein_85 at web.de
Tue Jun 7 13:02:14 EDT 2011


Hey David,

thanks for the hint. It works fine now.
If anyone else has the same problem, here is my solution:
I added the bold lines to my initial function drawCubesViaHexahedron():

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();

    

    // Create the color array
    vtkSmartPointer<vtkUnsignedCharArray> cubeColors = 
    vtkSmartPointer<vtkUnsignedCharArray>::New();
    cubeColors->SetNumberOfComponents(3);
    cubeColors->SetName("color");
    

    // Step through all map cells
    for (ushort n=0;n&lt;map.GetMapInfo().cellsNorth; n++)
    {
        for (ushort e=0;e&lt;map.GetMapInfo().cellsEast; e++)
        {
            vector&lt;mapData&gt; mapElement = map.getElement(n,e);
            for (uint i=0; i&lt;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-&gt;InsertNextPoint(P0);
                points->InsertNextPoint(P1);
                points->InsertNextPoint(P2);
                points->InsertNextPoint(P3);
                points->InsertNextPoint(P4);
                points->InsertNextPoint(P5);
                points->InsertNextPoint(P6);
                points->InsertNextPoint(P7);
               
                

                unsigned char color[3] = {mapElement[i].color[0],
mapElement[i].color[1], mapElement[i].color[2]};
		cubeColors->InsertNextTupleValue(color);


                }
            }
            mapElement.clear();
        }
    }
 
               
    //create the hexahedron
    vtkHexahedron * *theHex;
    theHex = new vtkHexahedron*[map.getNumberOfFilledCells()];

    for(int i=0;i&lt;map.getNumberOfFilledCells();i++)
    {
        theHex[i] = vtkHexahedron::New();
        theHex[i]-&gt;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&lt;map.getNumberOfFilledCells();i++)
    {
        theGrid-&gt;InsertNextCell(theHex[i]->GetCellType(),
        theHex[i]->GetPointIds());
    }
    theGrid->SetPoints(points);
    

    theGrid->GetCellData()->AddArray(cubeColors);
    theGrid->GetCellData()->SetActiveScalars("color");


    //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();
}


Thanks a lot, David.

Greetings,
stone





David E DeMarle wrote:
> 
> 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 &lt;Stein_85 at web.de&gt;
> 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&lt;map.GetMapInfo().cellsNorth; n++)
> &gt;     {
>>         for (ushort e=0;e&lt;map.GetMapInfo().cellsEast; e++)
> &gt;         {
>>             vector<mapData> mapElement = map.getElement(n,e);
>>             for (uint i=0; i&lt;mapElement.size(); i++)
> &gt;             {
>>                 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&lt;map.GetMapInfo().cellsNorth; n++)
> &gt;     {
>>         for (ushort e=0;e&lt;map.GetMapInfo().cellsEast; e++)
> &gt;         {
>>             vector<mapData> mapElement = map.getElement(n,e);
>>             for (uint i=0; i&lt;mapElement.size(); i++)
> &gt;             {
>>                 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&lt;map.getNumberOfFilledCells();i++)
> &gt;     {
>>         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&lt;map.getNumberOfFilledCells();i++)
> &gt;     {
>>         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*&lt;http://produkte.web.de/go/toolbar&gt;
>>
>> _______________________________________________
>> 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
>>
>>
> 
> _______________________________________________
> 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
> 


--
View this message in context: http://vtk.1045678.n5.nabble.com/create-multiple-cubes-with-different-colors-tp4461833p4462312.html
Sent from the VTK - Users mailing list archive at Nabble.com.



More information about the vtkusers mailing list