[vtkusers] Visualizing multiple isosurfaces using vtkContourFilter

Christian Lackas lackas at invicro.com
Wed Mar 2 03:37:20 EST 2011


* Thommen Korah <thkorah at hotmail.com> [110302 03:59]:

Hi Thommen,

I am rather new to VTK, still, so please take my suggestions with a
grain of salt:

> void addMultiColorRois( short* sampleGrid, int numContours,
>                               int dimX, int dimY, int dimZ,
>                               double voxX, double voxY, double voxZ,
>                               int minX, int minY, int minZ)
> {
>   // Use existing array of samples, such that vtk does not free memory.
>   vtkShortArray* sampleData = vtkShortArray::New();
>   int numSamples = dimX * dimY * dimZ;
>   sampleData->SetArray( sampleGrid, numSamples, 1 );

OK, so sampleData is supposed to leave sampleGrid alone when you remove
it.

>   // Create isosurface
>   vtkDiscreteMarchingCubes* dmc = vtkDiscreteMarchingCubes::New();
>   dmc->SetInput(sampledSpace);

In VTK 5, you should consider using SetInputConnection() and
GetOutputPort().

>   vtkLookupTable* lut = vtkLookupTable::New();
>   lut->SetNumberOfColors (numContours);
>   //lut->SetTableRange(0,numContours-1);

You definitely want to set the table range. In my case, I have 0 for
background and then e.g. 1-7 for actual contours, so I use

    SetTableRange(1, numContours);

>   lut->SetHueRange(0,0.667);

If you set the table values manually, you don't need this.

>   lut->Build();
>   for (int c = 0; c < numContours-1; c++)

This should be 'c<numContours' if you want to set all colors (and not
skip the last one at 'numContours-1').

>   // Create mapper and actor, and add to renderer
>   vtkPolyDataMapper* contourMapper = vtkPolyDataMapper::New();
>   contourMapper->SetInput( dmc->GetOutput() );
>   contourMapper->SetLookupTable(lut);
>   contourMapper->SetScalarModeToUseCellData();
>   contourMapper->SetScalarRange (0,numContours-1);

To avoid defining the range twice, I found it useful to write:

    contourMapper->SetScalarRange( lut->GetTableRange() );

>   vtkActor* impGeoActor = vtkActor::New();
>   impGeoActor->SetMapper( contourMapper );
> 
>   int pos = addActor( impGeoActor );
> 
>   contourMapper->Delete();
>   dmc->Delete();
>   sampledSpace->Delete();
>   sampleData->Delete();
>   lut->Delete();

This is the part I am not 100% sure about, however, I don't think you
can delete components of an active pipeline. When you use Render() later
on the RenderWindow, it will query the contourMapper for its data (could
have been changed in the meantime) which then could go further back in
the pipeline.
I would remove these lines and see if your program still crashes, then
think about how to clean up later (e.g. use an object that goes out of
scope when you are done, which takes care of this in its destructor).

>   return pos;

Your function is defined to return void, no integer.

> }

Hope this helps you.

Christian

-- 
Dr. Christian Lackas, Managing Partner
inviCRO, LLC -- In Imaging Yours
P: +49 2203 9034723, F: +49 2203 9034722, E: lackas at invicro.com
http://www.invicro.com/  http://www.spect-ct.com/



More information about the vtkusers mailing list