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.
 
 
 
 
 
 

355 lines
9.2 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkSampleFunction.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 "vtkSampleFunction.h"
#include "vtkDoubleArray.h"
#include "vtkFloatArray.h"
#include "vtkGarbageCollector.h"
#include "vtkImageData.h"
#include "vtkImplicitFunction.h"
#include "vtkMath.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkPointData.h"
vtkCxxRevisionMacro(vtkSampleFunction, "$Revision: 1.74 $");
vtkStandardNewMacro(vtkSampleFunction);
vtkCxxSetObjectMacro(vtkSampleFunction,ImplicitFunction,vtkImplicitFunction);
// Construct with ModelBounds=(-1,1,-1,1,-1,1), SampleDimensions=(50,50,50),
// Capping turned off, and normal generation on.
vtkSampleFunction::vtkSampleFunction()
{
this->ModelBounds[0] = -1.0;
this->ModelBounds[1] = 1.0;
this->ModelBounds[2] = -1.0;
this->ModelBounds[3] = 1.0;
this->ModelBounds[4] = -1.0;
this->ModelBounds[5] = 1.0;
this->SampleDimensions[0] = 50;
this->SampleDimensions[1] = 50;
this->SampleDimensions[2] = 50;
this->Capping = 0;
this->CapValue = VTK_LARGE_FLOAT;
this->ImplicitFunction = NULL;
this->ComputeNormals = 1;
this->OutputScalarType = VTK_DOUBLE;
this->SetNumberOfInputPorts(0);
}
vtkSampleFunction::~vtkSampleFunction()
{
this->SetImplicitFunction(NULL);
}
// Specify the dimensions of the data on which to sample.
void vtkSampleFunction::SetSampleDimensions(int i, int j, int k)
{
int dim[3];
dim[0] = i;
dim[1] = j;
dim[2] = k;
this->SetSampleDimensions(dim);
}
// Specify the dimensions of the data on which to sample.
void vtkSampleFunction::SetSampleDimensions(int dim[3])
{
vtkDebugMacro(<< " setting SampleDimensions to (" << dim[0] << "," << dim[1] << "," << dim[2] << ")");
if ( dim[0] != this->SampleDimensions[0] ||
dim[1] != this->SampleDimensions[1] ||
dim[2] != this->SampleDimensions[2] )
{
for ( int i=0; i<3; i++)
{
this->SampleDimensions[i] = (dim[i] > 0 ? dim[i] : 1);
}
this->Modified();
}
}
int vtkSampleFunction::RequestInformation (
vtkInformation * vtkNotUsed(request),
vtkInformationVector ** vtkNotUsed( inputVector ),
vtkInformationVector *outputVector)
{
// get the info objects
vtkInformation* outInfo = outputVector->GetInformationObject(0);
int i;
double ar[3], origin[3];
int wExt[6];
wExt[0] = 0; wExt[2] = 0; wExt[4] = 0;
wExt[1] = this->SampleDimensions[0]-1;
wExt[3] = this->SampleDimensions[1]-1;
wExt[5] = this->SampleDimensions[2]-1;
outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), wExt, 6);
for (i=0; i < 3; i++)
{
origin[i] = this->ModelBounds[2*i];
if ( this->SampleDimensions[i] <= 1 )
{
ar[i] = 1;
}
else
{
ar[i] = (this->ModelBounds[2*i+1] - this->ModelBounds[2*i])
/ (this->SampleDimensions[i] - 1);
}
}
outInfo->Set(vtkDataObject::ORIGIN(),origin,3);
outInfo->Set(vtkDataObject::SPACING(),ar,3);
vtkDataObject::SetPointDataActiveScalarInfo(outInfo, VTK_DOUBLE, 1);
return 1;
}
void vtkSampleFunction::ExecuteData(vtkDataObject *outp)
{
vtkIdType idx, i, j, k;
vtkFloatArray *newNormals=NULL;
vtkIdType numPts;
double p[3], s;
vtkImageData *output=this->GetOutput();
output->SetExtent(output->GetUpdateExtent());
output = this->AllocateOutputData(outp);
vtkDoubleArray *newScalars =
vtkDoubleArray::SafeDownCast(output->GetPointData()->GetScalars());
vtkDebugMacro(<< "Sampling implicit function");
// Initialize self; create output objects
//
if ( !this->ImplicitFunction )
{
vtkErrorMacro(<<"No implicit function specified");
return;
}
numPts = newScalars->GetNumberOfTuples();
// Traverse all points evaluating implicit function at each point
//
int extent[6];
output->GetUpdateExtent(extent);
double spacing[3];
output->GetSpacing(spacing);
for ( idx=0, k=extent[4]; k <= extent[5]; k++ )
{
p[2] = this->ModelBounds[4] + k*spacing[2];
for ( j=extent[2]; j <= extent[3]; j++ )
{
p[1] = this->ModelBounds[2] + j*spacing[1];
for ( i=extent[0]; i <= extent[1]; i++ )
{
p[0] = this->ModelBounds[0] + i*spacing[0];
s = this->ImplicitFunction->FunctionValue(p);
newScalars->SetTuple1(idx++,s);
}
}
}
// If normal computation turned on, compute them
//
if ( this->ComputeNormals )
{
double n[3];
newNormals = vtkFloatArray::New();
newNormals->SetNumberOfComponents(3);
newNormals->SetNumberOfTuples(numPts);
for ( idx=0, k=extent[4]; k <= extent[5]; k++ )
{
p[2] = this->ModelBounds[4] + k*spacing[2];
for ( j=extent[2]; j <= extent[3]; j++ )
{
p[1] = this->ModelBounds[2] + j*spacing[1];
for ( i=extent[0]; i <= extent[1]; i++ )
{
p[0] = this->ModelBounds[0] + i*spacing[0];
this->ImplicitFunction->FunctionGradient(p, n);
n[0] *= -1;
n[1] *= -1;
n[2] *= -1;
vtkMath::Normalize(n);
newNormals->SetTuple(idx++,n);
}
}
}
}
// If capping is turned on, set the distances of the outside of the volume
// to the CapValue.
//
if ( this->Capping )
{
this->Cap(newScalars);
}
// Update self
//
if (newNormals)
{
output->GetPointData()->SetNormals(newNormals);
newNormals->Delete();
}
}
unsigned long vtkSampleFunction::GetMTime()
{
unsigned long mTime=this->Superclass::GetMTime();
unsigned long impFuncMTime;
if ( this->ImplicitFunction != NULL )
{
impFuncMTime = this->ImplicitFunction->GetMTime();
mTime = ( impFuncMTime > mTime ? impFuncMTime : mTime );
}
return mTime;
}
void vtkSampleFunction::Cap(vtkDataArray *s)
{
int i,j,k,extent[6];
vtkIdType idx;
int d01=this->SampleDimensions[0]*this->SampleDimensions[1];
vtkImageData *output = this->GetOutput();
output->GetUpdateExtent(extent);
// i-j planes
//k = extent[4];
for (j=extent[2]; j<=extent[3]; j++)
{
for (i=extent[0]; i<=extent[1]; i++)
{
s->SetComponent(i+j*this->SampleDimensions[0], 0, this->CapValue);
}
}
k = extent[5];
idx = k*d01;
for (j=extent[2]; j<=extent[3]; j++)
{
for (i=extent[0]; i<=extent[1]; i++)
{
s->SetComponent(idx+i+j*this->SampleDimensions[0], 0, this->CapValue);
}
}
// j-k planes
//i = extent[0];
for (k=extent[4]; k<=extent[5]; k++)
{
for (j=extent[2]; j<=extent[3]; j++)
{
s->SetComponent(j*this->SampleDimensions[0]+k*d01, 0, this->CapValue);
}
}
i = extent[1];
for (k=extent[4]; k<=extent[5]; k++)
{
for (j=extent[2]; j<=extent[3]; j++)
{
s->SetComponent(i+j*this->SampleDimensions[0]+k*d01, 0, this->CapValue);
}
}
// i-k planes
//j = extent[2];
for (k=extent[4]; k<=extent[5]; k++)
{
for (i=extent[0]; i<=extent[1]; i++)
{
s->SetComponent(i+k*d01, 0, this->CapValue);
}
}
j = extent[3];
idx = j*this->SampleDimensions[0];
for (k=extent[4]; k<=extent[5]; k++)
{
for (i=extent[0]; i<=extent[1]; i++)
{
s->SetComponent(idx+i+k*d01, 0, this->CapValue);
}
}
}
void vtkSampleFunction::SetScalars(vtkDataArray *da)
{
if (da)
{
this->SetOutputScalarType(da->GetDataType());
}
}
void vtkSampleFunction::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "Sample Dimensions: (" << this->SampleDimensions[0] << ", "
<< this->SampleDimensions[1] << ", "
<< this->SampleDimensions[2] << ")\n";
os << indent << "ModelBounds: \n";
os << indent << " Xmin,Xmax: (" << this->ModelBounds[0]
<< ", " << this->ModelBounds[1] << ")\n";
os << indent << " Ymin,Ymax: (" << this->ModelBounds[2]
<< ", " << this->ModelBounds[3] << ")\n";
os << indent << " Zmin,Zmax: (" << this->ModelBounds[4]
<< ", " << this->ModelBounds[5] << ")\n";
os << indent << "OutputScalarType: " << this->OutputScalarType << "\n";
if ( this->ImplicitFunction )
{
os << indent << "Implicit Function: " << this->ImplicitFunction << "\n";
}
else
{
os << indent << "No Implicit function defined\n";
}
os << indent << "Capping: " << (this->Capping ? "On\n" : "Off\n");
os << indent << "Cap Value: " << this->CapValue << "\n";
os << indent << "Compute Normals: " << (this->ComputeNormals ? "On\n" : "Off\n");
}
//----------------------------------------------------------------------------
void vtkSampleFunction::ReportReferences(vtkGarbageCollector* collector)
{
this->Superclass::ReportReferences(collector);
vtkGarbageCollectorReport(collector, this->ImplicitFunction,
"ImplicitFunction");
}