Speed problems

Will Schroeder will.schroeder at kitware.com
Tue Oct 19 08:21:14 EDT 1999


Hi Nils-

>At 05:25 PM 10/14/99 +0200, Nils Holger Busch wrote:
>Hello,
>
>I am encountering severe speed problems using vtk . In my app code I
>read in a 160^2*200 volume and try to render three orthogonal slices
>like in the medical example. However, vtk takes a lot of time to even
>display(several minutes) the slices and it is almost impossible to
>interact (transform the viewpoint) with the data. Can anyone explain
>that behaviour? Is this normal?

I believe that you are running graphics/medical3.cxx. If so, here's the problem:

vtkStructuredPointsGeometryFilter is used to extract slices. This filter converts the slice into
polygons, one per "pixel" on the slice plane (in your case that's a fair number of polygons).
Plus, the filter vtkStructuredPointsGeometryFilter takes some time to pump out all the polygons.
(The example should be changed, I'll look into that.)

A better approach is to extract the slices as images, and then texture these images on one 
quadrilateral polygon per slice (the polygon needs texture coordinates). You'll see a huge increase in performance. (Extract the images with vtkExtractVOI, use a plane source to position the plane on which to texture map.)

The example code will look like this. (Note you'll need later versions of vtk because the textures,
if not powers of two, was a problem for OpenGL. Since (version 2.3?) we rewrote the texture class
to automatically resample textures to power of two.) Note the tricks you have to play with the texture
maps: make sure the color table receives a Build(); turn apColorScalarsThroughLookupTableOn(),
and assign the texture to the actor. Also, you have to make sure you position the plane right, taking 
into account the spacing of the voxels. (I'm going to look into adding another output to vtkExtractVOI which will be a plane properly positioned and with texture coordinates, it would greatly simplify plane
positioning.)

A modified medical3.cxx follows:

#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkVolume16Reader.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkOutlineFilter.h"
#include "vtkCamera.h"
#include "vtkStripper.h"
#include "vtkLookupTable.h"
#include "vtkExtractVOI.h"
#include "vtkPlaneSource.h"
#include "vtkContourFilter.h"

#include "SaveImage.h"

void main( int argc, char *argv[] )
{
   // create the renderer stuff
   vtkRenderer *aRenderer = vtkRenderer::New();
   vtkRenderWindow *renWin = vtkRenderWindow::New();
     renWin->AddRenderer(aRenderer);
   vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
     iren->SetRenderWindow(renWin);

   // read the volume
   vtkVolume16Reader *v16 = vtkVolume16Reader::New();
     v16->SetDataDimensions(64,64);
     v16->SetDataByteOrderToLittleEndian();
     v16->SetFilePrefix ("../../../vtkdata/headsq/quarter");
     v16->SetImageRange(1, 93);
     v16->SetDataSpacing (3.2, 3.2, 1.5);

   // extract the skin
   vtkContourFilter *skinExtractor = vtkContourFilter::New();
     skinExtractor->SetInput(v16->GetOutput());
     skinExtractor->SetValue(0, 500);
   vtkStripper *skinStripper = vtkStripper::New();
     skinStripper->SetInput(skinExtractor->GetOutput());
   vtkPolyDataMapper *skinMapper = vtkPolyDataMapper::New();
     skinMapper->SetInput(skinStripper->GetOutput());
     skinMapper->ScalarVisibilityOff();
   vtkActor *skin = vtkActor::New();
     skin->SetMapper(skinMapper);
     skin->GetProperty()->SetDiffuseColor(1, .49, .25);
     skin->GetProperty()->SetSpecular(.3);
     skin->GetProperty()->SetSpecularPower(20);

   // extract the bone
   vtkContourFilter *boneExtractor = vtkContourFilter::New();
     boneExtractor->SetInput(v16->GetOutput());
     boneExtractor->SetValue(0, 1150);
   vtkStripper *boneStripper = vtkStripper::New();
     boneStripper->SetInput(boneExtractor->GetOutput());
   vtkPolyDataMapper *boneMapper = vtkPolyDataMapper::New();
     boneMapper->SetInput(boneStripper->GetOutput());
     boneMapper->ScalarVisibilityOff();
   vtkActor *bone = vtkActor::New();
     bone->SetMapper(boneMapper);
     bone->GetProperty()->SetDiffuseColor(1, 1, .9412);

   // get an outline
   vtkOutlineFilter *outlineData = vtkOutlineFilter::New();
     outlineData->SetInput(v16->GetOutput());
   vtkPolyDataMapper *mapOutline = vtkPolyDataMapper::New();
     mapOutline->SetInput(outlineData->GetOutput());
   vtkActor *outline = vtkActor::New();
     outline->SetMapper(mapOutline);
     outline->GetProperty()->SetColor(0,0,0);

   // create a b/w lookup table
   vtkLookupTable *bwLut = vtkLookupTable::New();
     bwLut->SetTableRange (0, 2000);
     bwLut->SetSaturationRange (0, 0);
     bwLut->SetHueRange (0, 0);
     bwLut->SetValueRange (0, 1);
     bwLut->Build ();

   // create a hue lookup table
   vtkLookupTable *hueLut = vtkLookupTable::New();
     hueLut->SetTableRange (0, 2000);
     hueLut->SetHueRange (0, 1);
     hueLut->SetSaturationRange (1, 1);
     hueLut->SetValueRange (1, 1);
         hueLut->Build();

   // create a saturation lookup table
   vtkLookupTable *satLut = vtkLookupTable::New();
     satLut->SetTableRange (0, 2000);
     satLut->SetHueRange (.6, .6);
     satLut->SetSaturationRange (0, 1);
     satLut->SetValueRange (1, 1);
         satLut->Build();

   // sagittal
   vtkExtractVOI *saggitalSection = vtkExtractVOI::New();
     saggitalSection->SetVOI (32,32, 0,63, 0, 93);
     saggitalSection->SetInput (v16->GetOutput());
   vtkTexture *saggitalTexture = vtkTexture::New();
     saggitalTexture->SetInput(saggitalSection->GetOutput());
     saggitalTexture->InterpolateOn();
     saggitalTexture->SetLookupTable (bwLut);
     saggitalTexture->MapColorScalarsThroughLookupTableOn();
   vtkPlaneSource *saggitalPlane = vtkPlaneSource::New();
     saggitalPlane->SetXResolution(1);
     saggitalPlane->SetYResolution(1);
     saggitalPlane->SetOrigin(3.2*32.0, 0.0, 0.0);
     saggitalPlane->SetPoint1(3.2*32.0, 3.2*63.0, 0.0);
     saggitalPlane->SetPoint2(3.2*32.0, 0.0, 1.5*93.0);
   vtkPolyDataMapper *saggitalMapper = vtkPolyDataMapper::New();
     saggitalMapper->SetInput(saggitalPlane->GetOutput());
     saggitalMapper->ImmediateModeRenderingOn();
   vtkActor *sagittal = vtkActor::New();
     sagittal->SetMapper(saggitalMapper);
     sagittal->SetTexture(saggitalTexture);

   // axial
   vtkExtractVOI *axialSection = vtkExtractVOI::New();
     axialSection->SetVOI (0,63, 0,63, 46,46);
     axialSection->SetInput (v16->GetOutput());
   vtkTexture *axialTexture = vtkTexture::New();
     axialTexture->SetInput(axialSection->GetOutput());
     axialTexture->InterpolateOn();
     axialTexture->SetLookupTable (hueLut);
     axialTexture->MapColorScalarsThroughLookupTableOn();
   vtkPlaneSource *axialPlane = vtkPlaneSource::New();
     axialPlane->SetXResolution(1);
     axialPlane->SetYResolution(1);
     axialPlane->SetOrigin(0.0, 0.0, 1.5*46);
     axialPlane->SetPoint1(3.2*63, 0.0, 1.5*46);
     axialPlane->SetPoint2(0.0, 3.2*63, 1.5*46.0);
   vtkPolyDataMapper *axialMapper = vtkPolyDataMapper::New();
     axialMapper->SetInput(axialPlane->GetOutput());
     axialMapper->ImmediateModeRenderingOn();
   vtkActor *axial = vtkActor::New();
     axial->SetMapper(axialMapper);
     axial->SetTexture(axialTexture);

   // coronal
   vtkExtractVOI *coronalSection = vtkExtractVOI::New();
     coronalSection->SetVOI (0,63, 32,32, 0,92);
     coronalSection->SetInput (v16->GetOutput());
   vtkTexture *coronalTexture = vtkTexture::New();
     coronalTexture->SetInput(coronalSection->GetOutput());
     coronalTexture->InterpolateOn();
     coronalTexture->SetLookupTable (hueLut);
     coronalTexture->MapColorScalarsThroughLookupTableOn();
   vtkPlaneSource *coronalPlane = vtkPlaneSource::New();
     coronalPlane->SetXResolution(1);
     coronalPlane->SetYResolution(1);
     coronalPlane->SetOrigin(0.0, 3.2*32, 0.0);
     coronalPlane->SetPoint1(3.2*63, 3.2*32, 0.0);
     coronalPlane->SetPoint2(0.0, 3.2*32, 1.5*92.0);
   vtkPolyDataMapper *coronalMapper = vtkPolyDataMapper::New();
     coronalMapper->SetInput(coronalPlane->GetOutput());
     coronalMapper->ImmediateModeRenderingOn();
   vtkActor *coronal = vtkActor::New();
     coronal->SetMapper(coronalMapper);
     coronal->SetTexture(coronalTexture);

   // create a camera with the correct view up
   vtkCamera *aCamera = vtkCamera::New();
     aCamera->SetViewUp (0, 0, -1);
     aCamera->SetPosition (0, 1, 0);
     aCamera->SetFocalPoint (0, 0, 0);
     aCamera->ComputeViewPlaneNormal();

   // now, tell the renderer our actors
   aRenderer->AddActor(outline);
   aRenderer->AddActor(sagittal);
   aRenderer->AddActor(axial);
   aRenderer->AddActor(coronal);
   aRenderer->AddActor(skin);
   aRenderer->AddActor(bone);

   // turn off bone for this examples
   bone->VisibilityOff();

   // set skin to semi-transparent
   skin->GetProperty()->SetOpacity(0.5);

   aRenderer->SetActiveCamera(aCamera);
   aRenderer->ResetCamera ();
   aCamera->Dolly(1.5);
   aRenderer->SetBackground(1,1,1);
   aRenderer->ResetCameraClippingRange();
   
   // interact with data
   renWin->SetSize(300, 300);
   renWin->Render();

   SAVEIMAGE( renWin );

   iren->Start(); 
}

Will

--------------------------------
Dr. William J. Schroeder
Kitware Visualization Solutions / vtk Commercial Support
469 Clifton Corporate Parkway
Clifton Park, NY 12065
will.schroeder at kitware.com
1-518-371-3971 (Phone & Fax)


-----------------------------------------------------------------------------
This is the private VTK discussion list.  Please keep messages on-topic.
Check the FAQ at: <http://www.automatrix.com/cgi-bin/vtkfaq>
To UNSUBSCRIBE, send message body containing "unsubscribe vtkusers" to
<majordomo at gsao.med.ge.com>.  For help, send message body containing
"info vtkusers" to the same address.     Live long and prosper.
-----------------------------------------------------------------------------




More information about the vtkusers mailing list