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.
170 lines
4.4 KiB
170 lines
4.4 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkImplicitVolume.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 "vtkImplicitVolume.h"
|
|
|
|
#include "vtkDoubleArray.h"
|
|
#include "vtkImageData.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkPointData.h"
|
|
#include "vtkVoxel.h"
|
|
|
|
vtkCxxRevisionMacro(vtkImplicitVolume, "$Revision: 1.31 $");
|
|
vtkStandardNewMacro(vtkImplicitVolume);
|
|
vtkCxxSetObjectMacro(vtkImplicitVolume,Volume,vtkImageData);
|
|
|
|
// Construct an vtkImplicitVolume with no initial volume; the OutValue
|
|
// set to a large negative number; and the OutGradient set to (0,0,1).
|
|
vtkImplicitVolume::vtkImplicitVolume()
|
|
{
|
|
this->Volume = NULL;
|
|
this->OutValue = -VTK_FLOAT_MAX;
|
|
|
|
this->OutGradient[0] = 0.0;
|
|
this->OutGradient[1] = 0.0;
|
|
this->OutGradient[2] = 1.0;
|
|
|
|
this->PointIds = vtkIdList::New();
|
|
this->PointIds->Allocate(8);
|
|
}
|
|
|
|
vtkImplicitVolume::~vtkImplicitVolume()
|
|
{
|
|
if (this->Volume)
|
|
{
|
|
this->Volume->Delete();
|
|
this->Volume = NULL;
|
|
}
|
|
this->PointIds->Delete();
|
|
}
|
|
|
|
// Evaluate the ImplicitVolume. This returns the interpolated scalar value
|
|
// at x[3].
|
|
double vtkImplicitVolume::EvaluateFunction(double x[3])
|
|
{
|
|
vtkDataArray *scalars;
|
|
int ijk[3];
|
|
vtkIdType numPts, i;
|
|
double pcoords[3], weights[8], s;
|
|
|
|
// See if a volume is defined
|
|
if ( !this->Volume ||
|
|
!(scalars = this->Volume->GetPointData()->GetScalars()) )
|
|
{
|
|
vtkErrorMacro(<<"Can't evaluate volume!");
|
|
return this->OutValue;
|
|
}
|
|
|
|
// Find the cell that contains xyz and get it
|
|
if ( this->Volume->ComputeStructuredCoordinates(x,ijk,pcoords) )
|
|
{
|
|
this->Volume->GetCellPoints(this->Volume->ComputeCellId(ijk),this->PointIds);
|
|
vtkVoxel::InterpolationFunctions(pcoords,weights);
|
|
|
|
numPts = this->PointIds->GetNumberOfIds ();
|
|
for (s=0.0, i=0; i < numPts; i++)
|
|
{
|
|
s += scalars->GetComponent(this->PointIds->GetId(i),0) * weights[i];
|
|
}
|
|
return s;
|
|
}
|
|
|
|
else
|
|
{
|
|
return this->OutValue;
|
|
}
|
|
}
|
|
|
|
unsigned long vtkImplicitVolume::GetMTime()
|
|
{
|
|
unsigned long mTime=this->vtkImplicitFunction::GetMTime();
|
|
unsigned long volumeMTime;
|
|
|
|
if ( this->Volume != NULL )
|
|
{
|
|
this->Volume->RequestExactExtentOn();
|
|
this->Volume->UpdateInformation();
|
|
this->Volume->SetUpdateExtentToWholeExtent();
|
|
this->Volume->Update();
|
|
volumeMTime = this->Volume->GetMTime();
|
|
mTime = ( volumeMTime > mTime ? volumeMTime : mTime );
|
|
}
|
|
|
|
return mTime;
|
|
}
|
|
|
|
|
|
// Evaluate ImplicitVolume gradient.
|
|
void vtkImplicitVolume::EvaluateGradient(double x[3], double n[3])
|
|
{
|
|
vtkDataArray *scalars;
|
|
int i, ijk[3];
|
|
double pcoords[3], weights[8], *v;
|
|
vtkDoubleArray *gradient;
|
|
|
|
gradient = vtkDoubleArray::New();
|
|
gradient->SetNumberOfComponents(3);
|
|
gradient->SetNumberOfTuples(8);
|
|
|
|
// See if a volume is defined
|
|
if ( !this->Volume ||
|
|
!(scalars = this->Volume->GetPointData()->GetScalars()) )
|
|
{
|
|
vtkErrorMacro(<<"Can't evaluate volume!");
|
|
return;
|
|
}
|
|
|
|
// Find the cell that contains xyz and get it
|
|
if ( this->Volume->ComputeStructuredCoordinates(x,ijk,pcoords) )
|
|
{
|
|
vtkVoxel::InterpolationFunctions(pcoords,weights);
|
|
this->Volume->GetVoxelGradient(ijk[0], ijk[1], ijk[2], scalars, gradient);
|
|
|
|
n[0] = n[1] = n[2] = 0.0;
|
|
for (i=0; i < 8; i++)
|
|
{
|
|
v = gradient->GetTuple(i);
|
|
n[0] += v[0] * weights[i];
|
|
n[1] += v[1] * weights[i];
|
|
n[2] += v[2] * weights[i];
|
|
}
|
|
}
|
|
|
|
else
|
|
{ // use outside value
|
|
for ( i=0; i < 3; i++ )
|
|
{
|
|
n[i] = this->OutGradient[i];
|
|
}
|
|
}
|
|
gradient->Delete();
|
|
}
|
|
|
|
void vtkImplicitVolume::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os,indent);
|
|
|
|
os << indent << "Out Value: " << this->OutValue << "\n";
|
|
os << indent << "Out Gradient: (" << this->OutGradient[0] << ", "
|
|
<< this->OutGradient[1] << ", " << this->OutGradient[2] << ")\n";
|
|
|
|
if ( this->Volume )
|
|
{
|
|
os << indent << "Volume: " << this->Volume << "\n";
|
|
}
|
|
else
|
|
{
|
|
os << indent << "Volume: (none)\n";
|
|
}
|
|
}
|
|
|