[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<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);
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<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);
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 <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
>>
>>
>
> _______________________________________________
> 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