[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