Cloned library of VTK-5.0.0 with extra build files for internal package management.
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.
 
 
 
 
 
 

304 lines
8.3 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkImageSeedConnectivity.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 "vtkImageSeedConnectivity.h"
#include "vtkImageConnector.h"
#include "vtkImageData.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkStreamingDemandDrivenPipeline.h"
vtkCxxRevisionMacro(vtkImageSeedConnectivity, "$Revision: 1.32 $");
vtkStandardNewMacro(vtkImageSeedConnectivity);
//----------------------------------------------------------------------------
vtkImageSeedConnectivity::vtkImageSeedConnectivity()
{
this->InputConnectValue = 255;
this->OutputConnectedValue = 255;
this->OutputUnconnectedValue = 0;
this->Seeds = NULL;
this->Connector = vtkImageConnector::New();
this->Dimensionality = 3;
}
//----------------------------------------------------------------------------
vtkImageSeedConnectivity::~vtkImageSeedConnectivity()
{
this->Connector->Delete();
this->RemoveAllSeeds();
}
//----------------------------------------------------------------------------
void vtkImageSeedConnectivity::RemoveAllSeeds()
{
vtkImageConnectorSeed *temp;
while (this->Seeds)
{
temp = this->Seeds;
this->Seeds = temp->Next;
delete temp;
}
}
//----------------------------------------------------------------------------
void vtkImageSeedConnectivity::AddSeed(int num, int *index)
{
int idx, newIndex[3];
vtkImageConnectorSeed *seed;
if (num > 3)
{
num = 3;
}
for (idx = 0; idx < num; ++idx)
{
newIndex[idx] = index[idx];
}
for (idx = num; idx < 3; ++idx)
{
newIndex[idx] = 0;
}
seed = this->Connector->NewSeed(newIndex, NULL);
seed->Next = this->Seeds;
this->Seeds = seed;
this->Modified();
}
//----------------------------------------------------------------------------
void vtkImageSeedConnectivity::AddSeed(int i0, int i1, int i2)
{
int index[3];
index[0] = i0;
index[1] = i1;
index[2] = i2;
this->AddSeed(3, index);
}
//----------------------------------------------------------------------------
void vtkImageSeedConnectivity::AddSeed(int i0, int i1)
{
int index[2];
index[0] = i0;
index[1] = i1;
this->AddSeed(2, index);
}
//----------------------------------------------------------------------------
int vtkImageSeedConnectivity::RequestUpdateExtent(
vtkInformation *vtkNotUsed(request),
vtkInformationVector **inputVector,
vtkInformationVector *vtkNotUsed(outputVector))
{
vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(),
inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT()),
6);
return 1;
}
//----------------------------------------------------------------------------
int vtkImageSeedConnectivity::RequestData(
vtkInformation *vtkNotUsed(request),
vtkInformationVector **inputVector,
vtkInformationVector *outputVector)
{
vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
vtkInformation *outInfo = outputVector->GetInformationObject(0);
vtkImageData *inData = vtkImageData::SafeDownCast(
inInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkImageData *outData = vtkImageData::SafeDownCast(
outInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkImageConnectorSeed *seed;
int idx0, idx1, idx2;
vtkIdType inInc0, inInc1, inInc2;
vtkIdType outInc0, outInc1, outInc2;
int min0, max0, min1, max1, min2, max2;
unsigned char *inPtr0, *inPtr1, *inPtr2;
unsigned char *outPtr0, *outPtr1, *outPtr2;
unsigned char temp1, temp2;
int temp;
outData->SetExtent(
outInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT()));
outData->AllocateScalars();
if (inData->GetScalarType() != VTK_UNSIGNED_CHAR ||
outData->GetScalarType() != VTK_UNSIGNED_CHAR)
{
vtkErrorMacro("Execute: Both input and output must have scalar type UnsignedChar");
return 1;
}
// Pick an intermediate value (In some cases, we could eliminate the last threshold.)
temp1 = 1;
while (temp1 == this->InputConnectValue ||
temp1 == this->OutputUnconnectedValue ||
temp1 == this->OutputConnectedValue)
{
++temp1;
}
temp2 = temp1 + 1;
while (temp2 == this->InputConnectValue ||
temp2 == this->OutputUnconnectedValue ||
temp2 == this->OutputConnectedValue)
{
++temp2;
}
//-------
// threshold to eliminate unknown values ( only intermediate and 0)
inData->GetIncrements(inInc0, inInc1, inInc2);
this->GetOutput()->GetExtent(min0, max0, min1, max1, min2, max2);
outData->GetIncrements(outInc0, outInc1, outInc2);
inPtr2 = (unsigned char *)(inData->GetScalarPointer(min0,min1,min2));
outPtr2 = (unsigned char *)(outData->GetScalarPointer(min0,min1,min2));
for (idx2 = min2; idx2 <= max2; ++idx2)
{
inPtr1 = inPtr2;
outPtr1 = outPtr2;
for (idx1 = min1; idx1 <= max1; ++idx1)
{
inPtr0 = inPtr1;
outPtr0 = outPtr1;
for (idx0 = min0; idx0 <= max0; ++idx0)
{
if (*inPtr0 == this->InputConnectValue)
{
*outPtr0 = temp1;
}
else
{
*outPtr0 = 0;
}
inPtr0 += inInc0;
outPtr0 += outInc0;
}
inPtr1 += inInc1;
outPtr1 += outInc1;
}
inPtr2 += inInc2;
outPtr2 += outInc2;
}
this->UpdateProgress(0.2);
if (this->AbortExecute)
{
return 1;
}
//-------
// find actual seeds in this image. (only scan along the first axis for now)
this->Connector->RemoveAllSeeds();
seed = this->Seeds;
while (seed)
{
temp = seed->Index[0];
// make sure z value of seed is acceptable
if (seed->Index[2] < min2)
{
seed->Index[2] = min2;
}
if (seed->Index[2] > max2)
{
seed->Index[2] = max2;
}
outPtr0 = (unsigned char *)(outData->GetScalarPointer(seed->Index));
for (idx0 = temp; idx0 <= max0; ++idx0)
{
if (*outPtr0 == temp1)
{ // we found our seed
seed->Index[0] = idx0;
this->Connector->AddSeed(this->Connector->NewSeed(seed->Index, outPtr0));
seed->Index[0] = temp;
break;
}
outPtr0 += outInc0;
}
seed = seed->Next;
}
this->UpdateProgress(0.5);
if (this->AbortExecute)
{
return 1;
}
//-------
// connect
this->Connector->SetUnconnectedValue(temp1);
this->Connector->SetConnectedValue(temp2);
this->Connector->MarkData(outData, this->Dimensionality,
this->GetOutput()->GetExtent());
this->UpdateProgress(0.9);
if (this->AbortExecute)
{
return 1;
}
//-------
// Threshold to convert intermediate values into OutputUnconnectedValues
outPtr2 = (unsigned char *)(outData->GetScalarPointer(min0,min1,min2));
for (idx2 = min2; idx2 <= max2; ++idx2)
{
outPtr1 = outPtr2;
for (idx1 = min1; idx1 <= max1; ++idx1)
{
outPtr0 = outPtr1;
for (idx0 = min0; idx0 <= max0; ++idx0)
{
if (*outPtr0 == temp2)
{
*outPtr0 = this->OutputConnectedValue;
}
else
{
*outPtr0 = this->OutputUnconnectedValue;
}
outPtr0 += outInc0;
}
outPtr1 += outInc1;
}
outPtr2 += outInc2;
}
return 1;
}
void vtkImageSeedConnectivity::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
if ( this->Connector )
{
os << indent << "Connector: " << this->Connector << "\n";
}
else
{
os << indent << "Connector: (none)\n";
}
os << indent << "Dimensionality: " << this->Dimensionality << "\n";
os << indent << "InputConnectValue: " << this->InputConnectValue << "\n";
os << indent << "OutputConnectedValue: " << this->OutputConnectedValue << "\n";
os << indent << "OutputUnconnectedValue: " << this->OutputUnconnectedValue << "\n";
}