[vtkusers] Re-using a vtkRenderer with a different image
Charlotte Curtis
cfcurtis at ucalgary.ca
Wed Sep 2 18:32:08 EDT 2009
Hi all,
I've got what's grown to be a rather complicated program based on
ITK/VTK and wxWidgets (using the wxVTKRenderWindowInteractor). If I
just load an image (3D dicom dataset), all is well and it seems to
display more or less correctly (in both axial and coronal views).
However, if I then try to load a *different* image, it seems as though
the renderer, or the image actor, or something is "remembering" values
from the first image, and it doesn't display correctly - the coronal
viewport is messed up due to anisotropic voxels, and the image appears
"zoomed in" if it is larger than the first one.
I've tried a number of things, like deleting and recreating both the
imageactor and the renderer each time I load a new image, but that
doesn't even seem to work. Any ideas on what needs to be "reset" so
that I can load a different image?
The relevant portion of my code is as follows (where "image" is the
new image, and m_image is the member variable holding the image in
memory. Similarly, m_actor, m_renderer, etc, are hopefully
self-explanatory member variables).
m_windowleveler->RemoveAllInputs();
m_renderer->RemoveAllViewProps();
if (m_image)
m_image->PrepareForNewData();
else
m_image = vtkImageData::New();
m_image->DeepCopy(image);
m_image->SetUpdateExtentToWholeExtent();
m_windowleveler->SetInput(m_image);
if (image->GetDataDimension() == 3)
{
switch (dim)
{
case AXIAL:
m_slices = image->GetDimensions()[2];
break;
case CORONAL:
m_slices = image->GetDimensions()[1];
break;
case SAGITTAL:
m_slices = image->GetDimensions()[0];
break;
default:
return false;
}
}
else
{
int *extent = image->GetWholeExtent();
m_actor->SetDisplayExtent(extent[0], extent[1], extent[2], extent[3], 0, 0);
m_slices = 1;
}
m_range = image->GetScalarRange();
m_windowleveler->GetOutput()->UpdateInformation();
m_windowleveler->GetOutput()->SetUpdateExtentToWholeExtent();
m_windowleveler->Update();
m_actor->SetInput(m_windowleveler->GetOutput());
m_renderer->AddActor(m_actor);
vtkCamera *cam = m_renderer->GetActiveCamera();
switch (dim)
{
case CORONAL:
cam->SetFocalPoint(0,0,0);
cam->SetPosition(0,-1,0); // 1 if medical ?
cam->SetViewUp(0,0,1);
break;
case SAGITTAL:
cam->SetFocalPoint(0,0,0);
cam->SetPosition(1,0,0); // -1 if medical ?
cam->SetViewUp(0,0,1);
break;
// Axial and single slice
default:
cam->SetFocalPoint(0,0,0);
cam->SetPosition(0,0,1); // -1 if medical ?
cam->SetViewUp(0,1,0);
break;
}
double *spacing = image->GetSpacing();
int *extents = image->GetExtent();
cam->SetParallelScale((double)(extents[3]-extents[2])*spacing[1]/2.0);
m_renderer->ResetCameraClippingRange();
double scale = m_renderer->GetActiveCamera()->GetParallelScale();
m_renderer->ResetCamera();
m_renderer->GetActiveCamera()->SetParallelScale(scale);
m_iren->Render();
More information about the vtkusers
mailing list