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.
351 lines
11 KiB
351 lines
11 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkProbeFilter.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 "vtkProbeFilter.h"
|
|
|
|
#include "vtkCell.h"
|
|
#include "vtkIdTypeArray.h"
|
|
#include "vtkImageData.h"
|
|
#include "vtkInformation.h"
|
|
#include "vtkInformationVector.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkPointData.h"
|
|
#include "vtkStreamingDemandDrivenPipeline.h"
|
|
|
|
vtkCxxRevisionMacro(vtkProbeFilter, "$Revision: 1.82.12.2 $");
|
|
vtkStandardNewMacro(vtkProbeFilter);
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkProbeFilter::vtkProbeFilter()
|
|
{
|
|
this->SpatialMatch = 0;
|
|
this->ValidPoints = vtkIdTypeArray::New();
|
|
this->SetNumberOfInputPorts(2);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkProbeFilter::~vtkProbeFilter()
|
|
{
|
|
this->ValidPoints->Delete();
|
|
this->ValidPoints = NULL;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkProbeFilter::SetSourceConnection(vtkAlgorithmOutput* algOutput)
|
|
{
|
|
this->SetInputConnection(1, algOutput);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkProbeFilter::SetSource(vtkDataObject *input)
|
|
{
|
|
this->SetInput(1, input);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkDataObject *vtkProbeFilter::GetSource()
|
|
{
|
|
if (this->GetNumberOfInputConnections(1) < 1)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
return this->GetExecutive()->GetInputData(1, 0);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkProbeFilter::RequestData(
|
|
vtkInformation *vtkNotUsed(request),
|
|
vtkInformationVector **inputVector,
|
|
vtkInformationVector *outputVector)
|
|
{
|
|
// get the info objects
|
|
vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
|
|
vtkInformation *sourceInfo = inputVector[1]->GetInformationObject(0);
|
|
vtkInformation *outInfo = outputVector->GetInformationObject(0);
|
|
|
|
// get the input and ouptut
|
|
vtkDataSet *input = vtkDataSet::SafeDownCast(
|
|
inInfo->Get(vtkDataObject::DATA_OBJECT()));
|
|
vtkDataSet *source = vtkDataSet::SafeDownCast(
|
|
sourceInfo->Get(vtkDataObject::DATA_OBJECT()));
|
|
vtkDataSet *output = vtkDataSet::SafeDownCast(
|
|
outInfo->Get(vtkDataObject::DATA_OBJECT()));
|
|
|
|
if (!source)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
this->Probe(input, source, output);
|
|
return 1;
|
|
}
|
|
|
|
void vtkProbeFilter::Probe(vtkDataSet *input, vtkDataSet *source,
|
|
vtkDataSet *output)
|
|
{
|
|
vtkIdType ptId, numPts;
|
|
double x[3], tol2;
|
|
vtkCell *cell;
|
|
vtkPointData *pd, *outPD;
|
|
int subId;
|
|
double pcoords[3], *weights;
|
|
double fastweights[256];
|
|
|
|
vtkDebugMacro(<<"Probing data");
|
|
|
|
pd = source->GetPointData();
|
|
int size = input->GetNumberOfPoints();
|
|
|
|
// lets use a stack allocated array if possible for performance reasons
|
|
int mcs = source->GetMaxCellSize();
|
|
if (mcs<=256)
|
|
{
|
|
weights = fastweights;
|
|
}
|
|
else
|
|
{
|
|
weights = new double[mcs];
|
|
}
|
|
|
|
// First, copy the input to the output as a starting point
|
|
output->CopyStructure( input );
|
|
|
|
numPts = input->GetNumberOfPoints();
|
|
this->ValidPoints->Allocate(numPts);
|
|
|
|
// Allocate storage for output PointData
|
|
//
|
|
outPD = output->GetPointData();
|
|
outPD->InterpolateAllocate(pd, size, size);
|
|
|
|
// Use tolerance as a function of size of source data
|
|
//
|
|
tol2 = source->GetLength();
|
|
tol2 = tol2 ? tol2*tol2 / 1000.0 : 0.001;
|
|
|
|
// Loop over all input points, interpolating source data
|
|
//
|
|
int abort=0;
|
|
vtkIdType progressInterval=numPts/20 + 1;
|
|
for (ptId=0; ptId < numPts && !abort; ptId++)
|
|
{
|
|
if ( !(ptId % progressInterval) )
|
|
{
|
|
this->UpdateProgress((double)ptId/numPts);
|
|
abort = GetAbortExecute();
|
|
}
|
|
|
|
// Get the xyz coordinate of the point in the input dataset
|
|
input->GetPoint(ptId, x);
|
|
|
|
// Find the cell that contains xyz and get it
|
|
cell = source->FindAndGetCell(x,NULL,-1,tol2,subId,pcoords,weights);
|
|
if (cell)
|
|
{
|
|
// Interpolate the point data
|
|
outPD->InterpolatePoint(pd,ptId,cell->PointIds,weights);
|
|
this->ValidPoints->InsertNextValue(ptId);
|
|
}
|
|
else
|
|
{
|
|
outPD->NullPoint(ptId);
|
|
}
|
|
}
|
|
// BUG FIX: JB.
|
|
// Output gets setup from input, but when output is imagedata, scalartype
|
|
// depends on source scalartype not input scalartype
|
|
if (output->IsA("vtkImageData"))
|
|
{
|
|
vtkImageData *out = (vtkImageData*)output;
|
|
vtkDataArray *s = outPD->GetScalars();
|
|
out->SetScalarType(s->GetDataType());
|
|
out->SetNumberOfScalarComponents(s->GetNumberOfComponents());
|
|
}
|
|
if (mcs>256)
|
|
{
|
|
delete [] weights;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkProbeFilter::RequestInformation(
|
|
vtkInformation *vtkNotUsed(request),
|
|
vtkInformationVector **inputVector,
|
|
vtkInformationVector *outputVector)
|
|
{
|
|
// get the info objects
|
|
vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
|
|
vtkInformation *sourceInfo = inputVector[1]->GetInformationObject(0);
|
|
vtkInformation *outInfo = outputVector->GetInformationObject(0);
|
|
|
|
outInfo->CopyEntry(sourceInfo,
|
|
vtkStreamingDemandDrivenPipeline::TIME_STEPS());
|
|
|
|
outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),
|
|
inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT()),
|
|
6);
|
|
outInfo->Set(vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(),
|
|
inInfo->Get(
|
|
vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES()));
|
|
|
|
// Special case for ParaView.
|
|
if (this->SpatialMatch == 2)
|
|
{
|
|
outInfo->Set(
|
|
vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(),
|
|
sourceInfo->Get(
|
|
vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES()));
|
|
}
|
|
|
|
if (this->SpatialMatch == 1)
|
|
{
|
|
int m1 =
|
|
inInfo->Get(vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES());
|
|
int m2 =
|
|
sourceInfo->Get(
|
|
vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES());
|
|
if (m1 < 0 && m2 < 0)
|
|
{
|
|
outInfo->Set(vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(),
|
|
-1);
|
|
}
|
|
else
|
|
{
|
|
if (m1 < -1)
|
|
{
|
|
m1 = VTK_LARGE_INTEGER;
|
|
}
|
|
if (m2 < -1)
|
|
{
|
|
m2 = VTK_LARGE_INTEGER;
|
|
}
|
|
if (m2 < m1)
|
|
{
|
|
m1 = m2;
|
|
}
|
|
outInfo->Set(vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(),
|
|
m1);
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkProbeFilter::RequestUpdateExtent(
|
|
vtkInformation *vtkNotUsed(request),
|
|
vtkInformationVector **inputVector,
|
|
vtkInformationVector *outputVector)
|
|
{
|
|
// get the info objects
|
|
vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
|
|
vtkInformation *sourceInfo = inputVector[1]->GetInformationObject(0);
|
|
vtkInformation *outInfo = outputVector->GetInformationObject(0);
|
|
|
|
int usePiece = 0;
|
|
|
|
// What ever happend to CopyUpdateExtent in vtkDataObject?
|
|
// Copying both piece and extent could be bad. Setting the piece
|
|
// of a structured data set will affect the extent.
|
|
vtkDataObject* output = outInfo->Get(vtkDataObject::DATA_OBJECT());
|
|
if (output &&
|
|
(!strcmp(output->GetClassName(), "vtkUnstructuredGrid") ||
|
|
!strcmp(output->GetClassName(), "vtkPolyData")))
|
|
{
|
|
usePiece = 1;
|
|
}
|
|
|
|
inInfo->Set(vtkStreamingDemandDrivenPipeline::EXACT_EXTENT(), 1);
|
|
|
|
if ( ! this->SpatialMatch)
|
|
{
|
|
sourceInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(), 0);
|
|
sourceInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(),
|
|
1);
|
|
sourceInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(),
|
|
0);
|
|
}
|
|
else if (this->SpatialMatch == 1)
|
|
{
|
|
if (usePiece)
|
|
{
|
|
// Request an extra ghost level because the probe
|
|
// gets external values with computation prescision problems.
|
|
// I think the probe should be changed to have an epsilon ...
|
|
sourceInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(),
|
|
outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()));
|
|
sourceInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(),
|
|
outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES()));
|
|
sourceInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(),
|
|
outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS())+1);
|
|
}
|
|
else
|
|
{
|
|
sourceInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(),
|
|
outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT()),
|
|
6);
|
|
}
|
|
}
|
|
|
|
if (usePiece)
|
|
{
|
|
inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(),
|
|
outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()));
|
|
inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(),
|
|
outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES()));
|
|
inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(),
|
|
outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS()));
|
|
}
|
|
else
|
|
{
|
|
inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(),
|
|
outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT()),
|
|
6);
|
|
}
|
|
|
|
// Use the whole input in all processes, and use the requested update
|
|
// extent of the output to divide up the source.
|
|
if (this->SpatialMatch == 2)
|
|
{
|
|
inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(), 0);
|
|
inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(), 1);
|
|
inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(), 0);
|
|
sourceInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(),
|
|
outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()));
|
|
sourceInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(),
|
|
outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES()));
|
|
sourceInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(),
|
|
outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS()));
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkProbeFilter::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
vtkDataObject *source = this->GetSource();
|
|
|
|
this->Superclass::PrintSelf(os,indent);
|
|
os << indent << "Source: " << source << "\n";
|
|
if (this->SpatialMatch)
|
|
{
|
|
os << indent << "SpatialMatchOn\n";
|
|
}
|
|
else
|
|
{
|
|
os << indent << "SpatialMatchOff\n";
|
|
}
|
|
os << indent << "ValidPoints: " << this->ValidPoints << "\n";
|
|
}
|
|
|