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.
342 lines
9.2 KiB
342 lines
9.2 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkMarchingContourFilter.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 "vtkMarchingContourFilter.h"
|
|
|
|
#include "vtkCell.h"
|
|
#include "vtkContourFilter.h"
|
|
#include "vtkContourValues.h"
|
|
#include "vtkImageMarchingCubes.h"
|
|
#include "vtkInformation.h"
|
|
#include "vtkInformationVector.h"
|
|
#include "vtkMarchingCubes.h"
|
|
#include "vtkMarchingSquares.h"
|
|
#include "vtkMergePoints.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkPointData.h"
|
|
#include "vtkPolyData.h"
|
|
#include "vtkScalarTree.h"
|
|
#include "vtkStreamingDemandDrivenPipeline.h"
|
|
#include "vtkStructuredPoints.h"
|
|
|
|
#include <math.h>
|
|
|
|
vtkCxxRevisionMacro(vtkMarchingContourFilter, "$Revision: 1.1 $");
|
|
vtkStandardNewMacro(vtkMarchingContourFilter);
|
|
|
|
// Construct object with initial range (0,1) and single contour value
|
|
// of 0.0.
|
|
vtkMarchingContourFilter::vtkMarchingContourFilter()
|
|
{
|
|
this->ContourValues = vtkContourValues::New();
|
|
|
|
this->ComputeNormals = 1;
|
|
this->ComputeGradients = 0;
|
|
this->ComputeScalars = 1;
|
|
|
|
this->Locator = NULL;
|
|
|
|
this->UseScalarTree = 0;
|
|
this->ScalarTree = NULL;
|
|
}
|
|
|
|
vtkMarchingContourFilter::~vtkMarchingContourFilter()
|
|
{
|
|
this->ContourValues->Delete();
|
|
if ( this->Locator )
|
|
{
|
|
this->Locator->UnRegister(this);
|
|
this->Locator = NULL;
|
|
}
|
|
if ( this->ScalarTree )
|
|
{
|
|
this->ScalarTree->Delete();
|
|
}
|
|
}
|
|
|
|
// Overload standard modified time function. If contour values are modified,
|
|
// then this object is modified as well.
|
|
unsigned long vtkMarchingContourFilter::GetMTime()
|
|
{
|
|
unsigned long mTime=this->Superclass::GetMTime();
|
|
unsigned long time;
|
|
|
|
if (this->ContourValues)
|
|
{
|
|
time = this->ContourValues->GetMTime();
|
|
mTime = ( time > mTime ? time : mTime );
|
|
}
|
|
if (this->Locator)
|
|
{
|
|
time = this->Locator->GetMTime();
|
|
mTime = ( time > mTime ? time : mTime );
|
|
}
|
|
|
|
return mTime;
|
|
}
|
|
|
|
//
|
|
// General contouring filter. Handles arbitrary input.
|
|
//
|
|
int vtkMarchingContourFilter::RequestData(
|
|
vtkInformation *vtkNotUsed(request),
|
|
vtkInformationVector **inputVector,
|
|
vtkInformationVector *outputVector)
|
|
{
|
|
// get the info objects
|
|
vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
|
|
vtkInformation *outInfo = outputVector->GetInformationObject(0);
|
|
|
|
// get the input and ouptut
|
|
vtkDataSet *input = vtkDataSet::SafeDownCast(
|
|
inInfo->Get(vtkDataObject::DATA_OBJECT()));
|
|
vtkPolyData *output = vtkPolyData::SafeDownCast(
|
|
outInfo->Get(vtkDataObject::DATA_OBJECT()));
|
|
|
|
vtkDataArray *inScalars;
|
|
vtkIdType numCells;
|
|
|
|
vtkDebugMacro(<< "Executing marching contour filter");
|
|
|
|
numCells = input->GetNumberOfCells();
|
|
inScalars = input->GetPointData()->GetScalars();
|
|
if ( ! inScalars || numCells < 1 )
|
|
{
|
|
vtkErrorMacro(<<"No data to contour");
|
|
return 1;
|
|
}
|
|
|
|
// If structured points, use more efficient algorithms
|
|
if ( (input->GetDataObjectType() == VTK_STRUCTURED_POINTS))
|
|
{
|
|
if (inScalars->GetDataType() != VTK_BIT)
|
|
{
|
|
int dim = input->GetCell(0)->GetCellDimension();
|
|
|
|
if ( input->GetCell(0)->GetCellDimension() >= 2 )
|
|
{
|
|
vtkDebugMacro(<< "Structured Points");
|
|
this->StructuredPointsContour(dim, input, output);
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( (input->GetDataObjectType() == VTK_IMAGE_DATA))
|
|
{
|
|
if (inScalars->GetDataType() != VTK_BIT)
|
|
{
|
|
int dim = input->GetCell(0)->GetCellDimension();
|
|
|
|
if ( input->GetCell(0)->GetCellDimension() >= 2 )
|
|
{
|
|
vtkDebugMacro(<< "Image");
|
|
this->ImageContour(dim, input, output);
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
vtkDebugMacro(<< "Unoptimized");
|
|
this->DataSetContour(input, output);
|
|
|
|
return 1;
|
|
}
|
|
|
|
void vtkMarchingContourFilter::StructuredPointsContour(int dim,
|
|
vtkDataSet *input,
|
|
vtkPolyData *thisOutput)
|
|
{
|
|
vtkPolyData *output;
|
|
int numContours=this->ContourValues->GetNumberOfContours();
|
|
double *values=this->ContourValues->GetValues();
|
|
|
|
if ( dim == 2 ) //marching squares
|
|
{
|
|
vtkMarchingSquares *msquares;
|
|
int i;
|
|
|
|
msquares = vtkMarchingSquares::New();
|
|
msquares->SetInput((vtkImageData *)input);
|
|
msquares->SetDebug(this->Debug);
|
|
msquares->SetNumberOfContours(numContours);
|
|
for (i=0; i < numContours; i++)
|
|
{
|
|
msquares->SetValue(i,values[i]);
|
|
}
|
|
|
|
msquares->Update();
|
|
output = msquares->GetOutput();
|
|
output->Register(this);
|
|
msquares->Delete();
|
|
}
|
|
|
|
else //marching cubes
|
|
{
|
|
vtkMarchingCubes *mcubes;
|
|
int i;
|
|
|
|
mcubes = vtkMarchingCubes::New();
|
|
mcubes->SetInput((vtkImageData *)input);
|
|
mcubes->SetComputeNormals (this->ComputeNormals);
|
|
mcubes->SetComputeGradients (this->ComputeGradients);
|
|
mcubes->SetComputeScalars (this->ComputeScalars);
|
|
mcubes->SetDebug(this->Debug);
|
|
mcubes->SetNumberOfContours(numContours);
|
|
for (i=0; i < numContours; i++)
|
|
{
|
|
mcubes->SetValue(i,values[i]);
|
|
}
|
|
|
|
mcubes->Update();
|
|
output = mcubes->GetOutput();
|
|
output->Register(this);
|
|
mcubes->Delete();
|
|
}
|
|
|
|
thisOutput->CopyStructure(output);
|
|
thisOutput->GetPointData()->ShallowCopy(output->GetPointData());
|
|
output->UnRegister(this);
|
|
}
|
|
|
|
void vtkMarchingContourFilter::DataSetContour(vtkDataSet *input,
|
|
vtkPolyData *output)
|
|
{
|
|
int numContours=this->ContourValues->GetNumberOfContours();
|
|
double *values=this->ContourValues->GetValues();
|
|
|
|
vtkContourFilter *contour = vtkContourFilter::New();
|
|
contour->SetInput((vtkImageData *)input);
|
|
contour->SetComputeNormals (this->ComputeNormals);
|
|
contour->SetComputeGradients (this->ComputeGradients);
|
|
contour->SetComputeScalars (this->ComputeScalars);
|
|
contour->SetDebug(this->Debug);
|
|
contour->SetNumberOfContours(numContours);
|
|
for (int i=0; i < numContours; i++)
|
|
{
|
|
contour->SetValue(i,values[i]);
|
|
}
|
|
|
|
contour->Update();
|
|
output->ShallowCopy(contour->GetOutput());
|
|
this->SetOutput(output);
|
|
contour->Delete();
|
|
}
|
|
|
|
void vtkMarchingContourFilter::ImageContour(int dim, vtkDataSet *input,
|
|
vtkPolyData *output)
|
|
{
|
|
int numContours=this->ContourValues->GetNumberOfContours();
|
|
double *values=this->ContourValues->GetValues();
|
|
vtkPolyData *contourOutput;
|
|
|
|
if ( dim == 2 ) //marching squares
|
|
{
|
|
vtkMarchingSquares *msquares;
|
|
int i;
|
|
|
|
msquares = vtkMarchingSquares::New();
|
|
msquares->SetInput((vtkImageData *)input);
|
|
msquares->SetDebug(this->Debug);
|
|
msquares->SetNumberOfContours(numContours);
|
|
for (i=0; i < numContours; i++)
|
|
{
|
|
msquares->SetValue(i,values[i]);
|
|
}
|
|
|
|
contourOutput = msquares->GetOutput();
|
|
msquares->Update();
|
|
output->ShallowCopy(contourOutput);
|
|
msquares->Delete();
|
|
}
|
|
|
|
else //image marching cubes
|
|
{
|
|
vtkImageMarchingCubes *mcubes;
|
|
int i;
|
|
|
|
mcubes = vtkImageMarchingCubes::New();
|
|
mcubes->SetInput((vtkImageData *)input);
|
|
mcubes->SetComputeNormals (this->ComputeNormals);
|
|
mcubes->SetComputeGradients (this->ComputeGradients);
|
|
mcubes->SetComputeScalars (this->ComputeScalars);
|
|
mcubes->SetDebug(this->Debug);
|
|
mcubes->SetNumberOfContours(numContours);
|
|
for (i=0; i < numContours; i++)
|
|
{
|
|
mcubes->SetValue(i,values[i]);
|
|
}
|
|
|
|
contourOutput = mcubes->GetOutput();
|
|
mcubes->Update();
|
|
output->ShallowCopy(contourOutput);
|
|
mcubes->Delete();
|
|
}
|
|
}
|
|
|
|
// Specify a spatial locator for merging points. By default,
|
|
// an instance of vtkMergePoints is used.
|
|
void vtkMarchingContourFilter::SetLocator(vtkPointLocator *locator)
|
|
{
|
|
if ( this->Locator == locator )
|
|
{
|
|
return;
|
|
}
|
|
if ( this->Locator )
|
|
{
|
|
this->Locator->UnRegister(this);
|
|
this->Locator = NULL;
|
|
}
|
|
if ( locator )
|
|
{
|
|
locator->Register(this);
|
|
}
|
|
this->Locator = locator;
|
|
this->Modified();
|
|
}
|
|
|
|
void vtkMarchingContourFilter::CreateDefaultLocator()
|
|
{
|
|
if ( this->Locator == NULL )
|
|
{
|
|
this->Locator = vtkMergePoints::New();
|
|
}
|
|
}
|
|
|
|
int vtkMarchingContourFilter::FillInputPortInformation(int, vtkInformation *info)
|
|
{
|
|
info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
|
|
return 1;
|
|
}
|
|
|
|
void vtkMarchingContourFilter::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os,indent);
|
|
|
|
os << indent << "Compute Gradients: " << (this->ComputeGradients ? "On\n" : "Off\n");
|
|
os << indent << "Compute Normals: " << (this->ComputeNormals ? "On\n" : "Off\n");
|
|
os << indent << "Compute Scalars: " << (this->ComputeScalars ? "On\n" : "Off\n");
|
|
os << indent << "Use Scalar Tree: " << (this->UseScalarTree ? "On\n" : "Off\n");
|
|
|
|
this->ContourValues->PrintSelf(os,indent.GetNextIndent());
|
|
|
|
if ( this->Locator )
|
|
{
|
|
os << indent << "Locator: " << this->Locator << "\n";
|
|
}
|
|
else
|
|
{
|
|
os << indent << "Locator: (none)\n";
|
|
}
|
|
}
|
|
|