Commit f332da82 authored by David Gobbi's avatar David Gobbi
Browse files

BUG: Picker getting incorrect matrix from vtkImageStack members.

When the picker picks a vtkImageStack, it gets the mapper from the
currently active image on the stack.  Unfortunately, though, instead
of getting the matrix from the image, it was getting the matrix of the
stack itself (usually identity), This is now fixed, through the use
of a simple assembly path for the stack that contains only the active
image.  This also fixes the Bounds computation, which required a new
regression test image for TestImageStack.
parent 74c75b4e
......@@ -18,6 +18,8 @@
#include "vtkImageProperty.h"
#include "vtkImageMapper3D.h"
#include "vtkMatrix4x4.h"
#include "vtkAssemblyPath.h"
#include "vtkAssemblyPaths.h"
#include "vtkObjectFactory.h"
vtkStandardNewMacro(vtkImageStack);
......@@ -52,6 +54,26 @@ vtkImageStack::~vtkImageStack()
}
}
//----------------------------------------------------------------------------
vtkImageSlice *vtkImageStack::GetActiveImage()
{
vtkImageSlice *activeImage = 0;
vtkCollectionSimpleIterator pit;
this->Images->InitTraversal(pit);
vtkImageSlice *image = 0;
while ( (image = this->Images->GetNextImage(pit)) != 0)
{
vtkImageProperty *p = image->GetProperty();
if (p->GetLayerNumber() == this->ActiveLayer)
{
activeImage = image;
}
}
return activeImage;
}
//----------------------------------------------------------------------------
void vtkImageStack::AddImage(vtkImageSlice *prop)
{
......@@ -123,16 +145,10 @@ void vtkImageStack::SetProperty(vtkImageProperty *)
vtkImageProperty *vtkImageStack::GetProperty()
{
// Get the property with the active layer number
vtkCollectionSimpleIterator pit;
this->Images->InitTraversal(pit);
vtkImageSlice *image = 0;
while ( (image = this->Images->GetNextImage(pit)) != 0)
vtkImageSlice *image = this->GetActiveImage();
if (image)
{
vtkImageProperty *p = image->GetProperty();
if (p->GetLayerNumber() == this->ActiveLayer)
{
return p;
}
return image->GetProperty();
}
// Return a dummy property, can't return NULL.
......@@ -155,16 +171,10 @@ void vtkImageStack::SetMapper(vtkImageMapper3D *)
vtkImageMapper3D *vtkImageStack::GetMapper()
{
// Get the mapper with the active layer number
vtkCollectionSimpleIterator pit;
this->Images->InitTraversal(pit);
vtkImageSlice *image = 0;
while ( (image = this->Images->GetNextImage(pit)) != 0)
vtkImageSlice *image = this->GetActiveImage();
if (image)
{
vtkImageProperty *p = image->GetProperty();
if (p->GetLayerNumber() == this->ActiveLayer)
{
return image->GetMapper();
}
return image->GetMapper();
}
return NULL;
......@@ -173,6 +183,8 @@ vtkImageMapper3D *vtkImageStack::GetMapper()
//----------------------------------------------------------------------------
double *vtkImageStack::GetBounds()
{
this->UpdatePaths();
double bounds[6];
bool nobounds = true;
......@@ -183,6 +195,11 @@ double *vtkImageStack::GetBounds()
bounds[4] = VTK_DOUBLE_MAX;
bounds[5] = VTK_DOUBLE_MIN;
if (!this->IsIdentity)
{
this->PokeMatrices(this->GetMatrix());
}
vtkCollectionSimpleIterator pit;
this->Images->InitTraversal(pit);
vtkImageSlice *image = 0;
......@@ -201,6 +218,11 @@ double *vtkImageStack::GetBounds()
}
}
if (!this->IsIdentity)
{
this->PokeMatrices(NULL);
}
if (nobounds)
{
return 0;
......@@ -277,6 +299,7 @@ int vtkImageStack::RenderOpaqueGeometry(vtkViewport* viewport)
// Opaque render is always called first, so sort here
this->Images->Sort();
this->UpdatePaths();
if (!this->IsIdentity)
{
......@@ -459,10 +482,83 @@ unsigned long int vtkImageStack::GetRedrawMTime()
return mTime;
}
//----------------------------------------------------------------------------
void vtkImageStack::InitPathTraversal()
{
this->UpdatePaths();
this->Paths->InitTraversal();
}
//----------------------------------------------------------------------------
vtkAssemblyPath *vtkImageStack::GetNextPath()
{
if (this->Paths)
{
return this->Paths->GetNextItem();
}
return NULL;
}
//----------------------------------------------------------------------------
int vtkImageStack::GetNumberOfPaths()
{
this->UpdatePaths();
return this->Paths->GetNumberOfItems();
}
//----------------------------------------------------------------------------
void vtkImageStack::UpdatePaths()
{
if (this->GetMTime() > this->PathTime ||
(this->Paths && this->Paths->GetMTime() > this->PathTime))
{
if (this->Paths)
{
this->Paths->Delete();
}
// Create the list to hold all the paths
this->Paths = vtkAssemblyPaths::New();
vtkAssemblyPath *path = vtkAssemblyPath::New();
// Add ourselves to the path to start things off
path->AddNode(this, this->GetMatrix());
// Add the active image
vtkImageSlice *image = this->GetActiveImage();
if (image)
{
path->AddNode(image, image->GetMatrix());
image->BuildPaths(this->Paths, path);
path->DeleteLastNode();
}
path->Delete();
this->PathTime.Modified();
}
}
//----------------------------------------------------------------------------
void vtkImageStack::BuildPaths(vtkAssemblyPaths *paths, vtkAssemblyPath *path)
{
// the path consists only of the active image
vtkImageSlice *image = this->GetActiveImage();
if (image)
{
path->AddNode(image, image->GetMatrix());
image->BuildPaths(paths, path);
path->DeleteLastNode();
}
}
//----------------------------------------------------------------------------
void vtkImageStack::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "Images: " << this->Images << "\n";
os << indent << "ActiveLayer: " << this->ActiveLayer << "\n";
os << indent << "ActiveImage: " << this->GetActiveImage() << "\n";
}
......@@ -67,6 +67,12 @@ public:
vtkSetMacro(ActiveLayer, int);
int GetActiveLayer() { return this->ActiveLayer; }
// Description:
// Get the active image. This will be the topmost image whose
// LayerNumber is the ActiveLayer. If no image matches, then NULL
// will be returned.
vtkImageSlice *GetActiveImage();
// Description:
// Get the mapper for the currently active image.
vtkImageMapper3D *GetMapper();
......@@ -115,6 +121,19 @@ public:
// Release any resources held by this prop.
void ReleaseGraphicsResources(vtkWindow *win);
// Description:
// Methods for traversing the stack as if it was an assembly.
// The traversal only gives the view prop for the active layer.
void InitPathTraversal();
vtkAssemblyPath *GetNextPath();
int GetNumberOfPaths();
// Description:
// WARNING: INTERNAL METHOD - NOT INTENDED FOR GENERAL USE
// DO NOT USE THIS METHOD OUTSIDE OF THE RENDERING PROCESS
// Used to construct assembly paths and perform part traversal.
void BuildPaths(vtkAssemblyPaths *paths, vtkAssemblyPath *path);
protected:
vtkImageStack();
~vtkImageStack();
......@@ -123,7 +142,9 @@ protected:
void SetProperty(vtkImageProperty *property);
void PokeMatrices(vtkMatrix4x4 *matrix);
void UpdatePaths();
vtkTimeStamp PathTime;
vtkCollection *ImageMatrices;
vtkImageSliceCollection *Images;
int ActiveLayer;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment