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.
311 lines
9.3 KiB
311 lines
9.3 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkImageOpenClose3D.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 "vtkImageOpenClose3D.h"
|
|
|
|
#include "vtkGarbageCollector.h"
|
|
#include "vtkImageData.h"
|
|
#include "vtkImageDilateErode3D.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkCommand.h"
|
|
|
|
#include "vtkInformation.h"
|
|
#include "vtkInformationVector.h"
|
|
#include "vtkExecutive.h"
|
|
|
|
#include <math.h>
|
|
|
|
vtkCxxRevisionMacro(vtkImageOpenClose3D, "$Revision: 1.30.4.2 $");
|
|
vtkStandardNewMacro(vtkImageOpenClose3D);
|
|
|
|
//----------------------------------------------------------------------------
|
|
// functions to convert progress calls.
|
|
class vtkImageOpenClose3DProgress : public vtkCommand
|
|
{
|
|
public:
|
|
// generic new method
|
|
static vtkImageOpenClose3DProgress *New()
|
|
{ return new vtkImageOpenClose3DProgress; }
|
|
|
|
// the execute
|
|
virtual void Execute(vtkObject *caller,
|
|
unsigned long event, void* vtkNotUsed(v))
|
|
{
|
|
vtkAlgorithm *alg = vtkAlgorithm::SafeDownCast(caller);
|
|
if (event == vtkCommand::ProgressEvent && alg)
|
|
{
|
|
this->Self->UpdateProgress(this->Offset + 0.5 *
|
|
alg->GetProgress());
|
|
}
|
|
}
|
|
|
|
// some ivars that should be set
|
|
vtkImageOpenClose3D *Self;
|
|
double Offset;
|
|
};
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkImageOpenClose3D::vtkImageOpenClose3D()
|
|
{
|
|
// create the filter chain
|
|
this->Filter0 = vtkImageDilateErode3D::New();
|
|
vtkImageOpenClose3DProgress *cb = vtkImageOpenClose3DProgress::New();
|
|
cb->Self = this;
|
|
cb->Offset = 0;
|
|
this->Filter0->AddObserver(vtkCommand::ProgressEvent, cb);
|
|
cb->Delete();
|
|
|
|
this->Filter1 = vtkImageDilateErode3D::New();
|
|
cb = vtkImageOpenClose3DProgress::New();
|
|
cb->Self = this;
|
|
cb->Offset = 0.5;
|
|
this->Filter1->AddObserver(vtkCommand::ProgressEvent, cb);
|
|
cb->Delete();
|
|
this->SetOpenValue(0.0);
|
|
this->SetCloseValue(255.0);
|
|
|
|
// connect up the internal pipeline
|
|
this->Filter1->SetInputConnection(this->Filter0->GetOutputPort());
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Destructor: Delete the sub filters.
|
|
vtkImageOpenClose3D::~vtkImageOpenClose3D()
|
|
{
|
|
if (this->Filter0)
|
|
{
|
|
this->Filter0->Delete();
|
|
}
|
|
|
|
if (this->Filter1)
|
|
{
|
|
this->Filter1->Delete();
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageOpenClose3D::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os,indent);
|
|
os << indent << "Filter0: \n";
|
|
this->Filter0->PrintSelf(os, indent.GetNextIndent());
|
|
os << indent << "Filter1: \n";
|
|
this->Filter1->PrintSelf(os, indent.GetNextIndent());
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Turn debugging output on. (in sub filters also)
|
|
void vtkImageOpenClose3D::DebugOn()
|
|
{
|
|
this->vtkObject::DebugOn();
|
|
if (this->Filter0)
|
|
{
|
|
this->Filter0->DebugOn();
|
|
}
|
|
if (this->Filter1)
|
|
{
|
|
this->Filter1->DebugOn();
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageOpenClose3D::DebugOff()
|
|
{
|
|
this->vtkObject::DebugOff();
|
|
if (this->Filter0)
|
|
{
|
|
this->Filter0->DebugOff();
|
|
}
|
|
if (this->Filter1)
|
|
{
|
|
this->Filter1->DebugOff();
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Pass modified message to sub filters.
|
|
void vtkImageOpenClose3D::Modified()
|
|
{
|
|
this->vtkObject::Modified();
|
|
if (this->Filter0)
|
|
{
|
|
this->Filter0->Modified();
|
|
}
|
|
|
|
if (this->Filter1)
|
|
{
|
|
this->Filter1->Modified();
|
|
}
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// This method considers the sub filters MTimes when computing this objects
|
|
// MTime
|
|
unsigned long int vtkImageOpenClose3D::GetMTime()
|
|
{
|
|
unsigned long int t1, t2;
|
|
|
|
t1 = this->Superclass::GetMTime();
|
|
if (this->Filter0)
|
|
{
|
|
t2 = this->Filter0->GetMTime();
|
|
if (t2 > t1)
|
|
{
|
|
t1 = t2;
|
|
}
|
|
}
|
|
if (this->Filter1)
|
|
{
|
|
t2 = this->Filter1->GetMTime();
|
|
if (t2 > t1)
|
|
{
|
|
t1 = t2;
|
|
}
|
|
}
|
|
|
|
return t1;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
vtkImageOpenClose3D::ComputePipelineMTime(vtkInformation* request,
|
|
vtkInformationVector** inInfoVec,
|
|
vtkInformationVector* outInfoVec,
|
|
int requestFromOutputPort,
|
|
unsigned long* mtime)
|
|
{
|
|
// Process the request on the internal pipeline. Share our input
|
|
// information with the first filter and our output information with
|
|
// the last filter.
|
|
vtkExecutive* exec0 = this->Filter0->GetExecutive();
|
|
vtkExecutive* exec1 = this->Filter1->GetExecutive();
|
|
exec0->SetSharedInputInformation(inInfoVec);
|
|
exec1->SetSharedOutputInformation(outInfoVec);
|
|
unsigned long mtime1;
|
|
if(exec1->ComputePipelineMTime(request,
|
|
exec1->GetInputInformation(),
|
|
exec1->GetOutputInformation(),
|
|
requestFromOutputPort, &mtime1))
|
|
{
|
|
// Now run the request in this algorithm.
|
|
return this->Superclass::ComputePipelineMTime(request,
|
|
inInfoVec, outInfoVec,
|
|
requestFromOutputPort,
|
|
mtime);
|
|
}
|
|
else
|
|
{
|
|
// The internal pipeline failed to process the request.
|
|
vtkErrorMacro("Internal pipeline failed to process pipeline modified "
|
|
"time request.");
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkImageOpenClose3D::ProcessRequest(vtkInformation* request,
|
|
vtkInformationVector** inInfoVec,
|
|
vtkInformationVector* outInfoVec)
|
|
{
|
|
// Process the request on the internal pipeline. Share our input
|
|
// information with the first filter and our output information with
|
|
// the last filter.
|
|
vtkExecutive* exec0 = this->Filter0->GetExecutive();
|
|
vtkExecutive* exec1 = this->Filter1->GetExecutive();
|
|
exec0->SetSharedInputInformation(inInfoVec);
|
|
exec1->SetSharedOutputInformation(outInfoVec);
|
|
return exec1->ProcessRequest(request,
|
|
exec1->GetInputInformation(),
|
|
exec1->GetOutputInformation());
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Selects the size of gaps or objects removed.
|
|
void vtkImageOpenClose3D::SetKernelSize(int size0, int size1, int size2)
|
|
{
|
|
if ( ! this->Filter0 || ! this->Filter1)
|
|
{
|
|
vtkErrorMacro(<< "SetKernelSize: Sub filter not created yet.");
|
|
return;
|
|
}
|
|
|
|
this->Filter0->SetKernelSize(size0, size1, size2);
|
|
this->Filter1->SetKernelSize(size0, size1, size2);
|
|
// Sub filters take care of modified.
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Determines the value that will closed.
|
|
// Close value is first dilated, and then eroded
|
|
void vtkImageOpenClose3D::SetCloseValue(double value)
|
|
{
|
|
if ( ! this->Filter0 || ! this->Filter1)
|
|
{
|
|
vtkErrorMacro(<< "SetCloseValue: Sub filter not created yet.");
|
|
return;
|
|
}
|
|
|
|
this->Filter0->SetDilateValue(value);
|
|
this->Filter1->SetErodeValue(value);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
double vtkImageOpenClose3D::GetCloseValue()
|
|
{
|
|
if ( ! this->Filter0)
|
|
{
|
|
vtkErrorMacro(<< "GetCloseValue: Sub filter not created yet.");
|
|
return 0.0;
|
|
}
|
|
|
|
return this->Filter0->GetDilateValue();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Determines the value that will opened.
|
|
// Open value is first eroded, and then dilated.
|
|
void vtkImageOpenClose3D::SetOpenValue(double value)
|
|
{
|
|
if ( ! this->Filter0 || ! this->Filter1)
|
|
{
|
|
vtkErrorMacro(<< "SetOpenValue: Sub filter not created yet.");
|
|
return;
|
|
}
|
|
|
|
this->Filter0->SetErodeValue(value);
|
|
this->Filter1->SetDilateValue(value);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
double vtkImageOpenClose3D::GetOpenValue()
|
|
{
|
|
if ( ! this->Filter0)
|
|
{
|
|
vtkErrorMacro(<< "GetOpenValue: Sub filter not created yet.");
|
|
return 0.0;
|
|
}
|
|
|
|
return this->Filter0->GetErodeValue();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageOpenClose3D::ReportReferences(vtkGarbageCollector* collector)
|
|
{
|
|
this->Superclass::ReportReferences(collector);
|
|
// These filters share our input and are therefore involved in a
|
|
// reference loop.
|
|
vtkGarbageCollectorReport(collector, this->Filter0, "Filter0");
|
|
vtkGarbageCollectorReport(collector, this->Filter1, "Filter1");
|
|
}
|
|
|