You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
187 lines
5.0 KiB
187 lines
5.0 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkImageConnector.cxx,v $
|
|
|
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
|
All rights reserved.
|
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the above copyright notice for more information.
|
|
|
|
=========================================================================*/
|
|
#include "vtkImageConnector.h"
|
|
|
|
#include "vtkImageData.h"
|
|
#include "vtkObjectFactory.h"
|
|
|
|
vtkCxxRevisionMacro(vtkImageConnector, "$Revision: 1.20 $");
|
|
vtkStandardNewMacro(vtkImageConnector);
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkImageConnector::vtkImageConnector()
|
|
{
|
|
this->Seeds = NULL;
|
|
this->LastSeed = NULL;
|
|
this->ConnectedValue = 255;
|
|
this->UnconnectedValue = 128;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkImageConnector::~vtkImageConnector()
|
|
{
|
|
this->RemoveAllSeeds();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageConnector::RemoveAllSeeds()
|
|
{
|
|
vtkImageConnectorSeed *temp;
|
|
|
|
while (this->Seeds)
|
|
{
|
|
temp = this->Seeds;
|
|
this->Seeds = temp->Next;
|
|
delete temp;
|
|
}
|
|
this->LastSeed = NULL;
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkImageConnectorSeed *vtkImageConnector::NewSeed(int index[3], void *ptr)
|
|
{
|
|
vtkImageConnectorSeed *seed = vtkImageConnectorSeed::New();
|
|
int idx;
|
|
|
|
for (idx = 0; idx < 3; ++idx)
|
|
{
|
|
seed->Index[idx] = index[idx];
|
|
}
|
|
seed->Pointer = ptr;
|
|
seed->Next = NULL;
|
|
|
|
return seed;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Add a new seed to the end of the seed list.
|
|
void vtkImageConnector::AddSeedToEnd(vtkImageConnectorSeed *seed)
|
|
{
|
|
// Add the seed to the end of the list
|
|
if (this->LastSeed == NULL)
|
|
{ // no seeds yet
|
|
this->LastSeed = this->Seeds = seed;
|
|
}
|
|
else
|
|
{
|
|
this->LastSeed->Next = seed;
|
|
this->LastSeed = seed;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Add a new seed to the start of the seed list.
|
|
void vtkImageConnector::AddSeed(vtkImageConnectorSeed *seed)
|
|
{
|
|
seed->Next = this->Seeds;
|
|
this->Seeds = seed;
|
|
if ( ! this->LastSeed)
|
|
{
|
|
this->LastSeed = seed;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Removes a seed from the start of the seed list, and returns the seed.
|
|
vtkImageConnectorSeed *vtkImageConnector::PopSeed()
|
|
{
|
|
vtkImageConnectorSeed *seed;
|
|
|
|
seed = this->Seeds;
|
|
this->Seeds = seed->Next;
|
|
if (this->Seeds == NULL)
|
|
{
|
|
this->LastSeed = NULL;
|
|
}
|
|
return seed;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Input a data of 0's and "UnconnectedValue"s. Seeds of this object are
|
|
// used to find connected pixels.
|
|
// All pixels connected to seeds are set to ConnectedValue.
|
|
// The data has to be unsigned char.
|
|
void vtkImageConnector::MarkData(vtkImageData *data, int numberOfAxes, int extent[6])
|
|
{
|
|
vtkIdType *incs, *pIncs;
|
|
int *pExtent;
|
|
vtkImageConnectorSeed *seed;
|
|
unsigned char *ptr;
|
|
int newIndex[3], *pIndex, idx;
|
|
long count = 0;
|
|
|
|
incs = data->GetIncrements();
|
|
while (this->Seeds)
|
|
{
|
|
++count;
|
|
seed = this->PopSeed();
|
|
// just in case the seed has not been marked visited.
|
|
*((unsigned char *)(seed->Pointer)) = this->ConnectedValue;
|
|
// Add neighbors
|
|
newIndex[0] = seed->Index[0];
|
|
newIndex[1] = seed->Index[1];
|
|
newIndex[2] = seed->Index[2];
|
|
pExtent = extent;
|
|
pIncs = incs;
|
|
pIndex = newIndex;
|
|
for (idx = 0; idx < numberOfAxes; ++idx)
|
|
{
|
|
// check pixel below
|
|
if (*pExtent < *pIndex)
|
|
{
|
|
ptr = (unsigned char *)(seed->Pointer) - *pIncs;
|
|
if (*ptr == this->UnconnectedValue)
|
|
{ // add a new seed
|
|
--(*pIndex);
|
|
*ptr = this->ConnectedValue;
|
|
this->AddSeedToEnd(this->NewSeed(newIndex, ptr));
|
|
++(*pIndex);
|
|
}
|
|
}
|
|
++pExtent;
|
|
// check above pixel
|
|
if (*pExtent > *pIndex)
|
|
{
|
|
ptr = (unsigned char *)(seed->Pointer) + *pIncs;
|
|
if (*ptr == this->UnconnectedValue)
|
|
{ // add a new seed
|
|
++(*pIndex);
|
|
*ptr = this->ConnectedValue;
|
|
this->AddSeedToEnd(this->NewSeed(newIndex, ptr));
|
|
--(*pIndex);
|
|
}
|
|
}
|
|
++pExtent;
|
|
// move to next axis
|
|
++pIncs;
|
|
++pIndex;
|
|
}
|
|
|
|
// Delete seed
|
|
delete seed;
|
|
}
|
|
vtkDebugMacro("Marked " << count << " pixels");
|
|
}
|
|
|
|
void vtkImageConnector::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os,indent);
|
|
|
|
os << indent << "ConnectedValue: " << this->ConnectedValue << "\n";
|
|
os << indent << "UnconnectedValue: " << this->UnconnectedValue << "\n";
|
|
|
|
}
|
|
|
|
|