Commit a238d32f authored by Cory Quammen's avatar Cory Quammen Committed by Kitware Robot
Browse files

Merge topic 'vtkImplicitPolyDataDistanceWithClosestPoint'

d2554b4c

 Improvements to vtkImplicitPolyData
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Acked-by: Cory Quammen's avatarCory Quammen <cory.quammen@kitware.com>
Acked-by: Bill Lorensen's avatarBill Lorensen <bill.lorensen@gmail.com>
Merge-request: !723
parents fb6f4f0f d2554b4c
......@@ -54,8 +54,18 @@ int TestImplicitPolyDataDistance(int argc, char* argv[])
vtkNew<vtkImplicitPolyDataDistance> implicitDistance;
implicitDistance->SetInput(reader->GetOutput());
// Test SetNoClosestPoint() and GetNoClosestPoint()
double noClosestPoint[3] = {1.0, 1.0, 1.0};
implicitDistance->SetNoClosestPoint(noClosestPoint);
implicitDistance->GetNoClosestPoint(noClosestPoint);
if(noClosestPoint[0] != 1.0 && noClosestPoint[1] != 1.0 && noClosestPoint[2] != 1.0)
{
return EXIT_FAILURE;
}
// Compute distances to test points, saving those within the cuspy surface for display
vtkNew<vtkPoints> points;
vtkNew<vtkPoints> insidePoints;
vtkNew<vtkPoints> surfacePoints;
double xRange[2] = {-47.6, 46.9};
double yRange[2] = {-18.2, 82.1};
double zRange[2] = {1.63, 102};
......@@ -66,34 +76,55 @@ int TestImplicitPolyDataDistance(int argc, char* argv[])
{
for (double x = xRange[0]; x < xRange[1]; x += spacing)
{
double pt[3] = {x, y, z};
double distance = implicitDistance->EvaluateFunction(pt);
double point[3] = {x, y, z};
double surfacePoint[3];
double distance = implicitDistance->EvaluateFunctionAndGetClosestPoint(point, surfacePoint);
if (distance <= 0.0)
{
points->InsertNextPoint(pt);
insidePoints->InsertNextPoint(point);
surfacePoints->InsertNextPoint(surfacePoint);
}
}
}
}
// Set up the point data structure
vtkNew<vtkPolyData> insidePoints;
insidePoints->SetPoints(points.GetPointer());
// Set up inside points data structure
vtkNew<vtkPolyData> insidePointsPolyData;
insidePointsPolyData->SetPoints(insidePoints.GetPointer());
// Glyph the points
vtkNew<vtkSphereSource> insidePointSphere;
insidePointSphere->SetRadius(3);
vtkNew<vtkGlyph3D> insidePointsGlypher;
insidePointsGlypher->SetInputData(insidePointsPolyData.GetPointer());
insidePointsGlypher->SetSourceConnection(insidePointSphere->GetOutputPort());
// Display the glyphs
vtkNew<vtkPolyDataMapper> insidePointMapper;
insidePointMapper->SetInputConnection(insidePointsGlypher->GetOutputPort());
vtkNew<vtkActor> insidePointActor;
insidePointActor->SetMapper(insidePointMapper.GetPointer());
insidePointActor->GetProperty()->SetColor(1.0, 0.0, 0.0);
// Set up surface points data structure
vtkNew<vtkPolyData> surfacePointsPolyData;
surfacePointsPolyData->SetPoints(surfacePoints.GetPointer());
// Glyph the points
vtkNew<vtkSphereSource> sphere;
sphere->SetRadius(3);
vtkNew<vtkGlyph3D> glypher;
glypher->SetInputData(insidePoints.GetPointer());
glypher->SetSourceConnection(sphere->GetOutputPort());
vtkNew<vtkSphereSource> surfacePointSphere;
surfacePointSphere->SetRadius(3);
vtkNew<vtkGlyph3D> surfacePointsGlypher;
surfacePointsGlypher->SetInputData(surfacePointsPolyData.GetPointer());
surfacePointsGlypher->SetSourceConnection(surfacePointSphere->GetOutputPort());
// Display the glyphs
vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputConnection(glypher->GetOutputPort());
vtkNew<vtkPolyDataMapper> surfacePointMapper;
surfacePointMapper->SetInputConnection(surfacePointsGlypher->GetOutputPort());
vtkNew<vtkActor> actor;
actor->SetMapper(mapper.GetPointer());
actor->GetProperty()->SetColor(1.0, 0.0, 0.0);
vtkNew<vtkActor> surfacePointActor;
surfacePointActor->SetMapper(surfacePointMapper.GetPointer());
surfacePointActor->GetProperty()->SetColor(0.0, 0.0, 1.0);
// Display the bounding surface
vtkNew<vtkPolyDataMapper> surfaceMapper;
......@@ -114,7 +145,8 @@ int TestImplicitPolyDataDistance(int argc, char* argv[])
vtkSmartPointer<vtkRenderWindowInteractor>::New();
iren->SetRenderWindow(renWin);
renderer->AddActor(actor.GetPointer());
renderer->AddActor(insidePointActor.GetPointer());
renderer->AddActor(surfacePointActor.GetPointer());
renderer->AddActor(surfaceActor.GetPointer());
// Standard testing code.
......
9ec794488c7500c9255d341d9364cc31
b70529ed226107310733b25ab9859293
......@@ -29,12 +29,16 @@ vtkStandardNewMacro(vtkImplicitPolyDataDistance);
//-----------------------------------------------------------------------------
vtkImplicitPolyDataDistance::vtkImplicitPolyDataDistance()
{
this->NoValue = 0.0;
this->NoClosestPoint[0] = 0.0;
this->NoClosestPoint[1] = 0.0;
this->NoClosestPoint[2] = 0.0;
this->NoGradient[0] = 0.0;
this->NoGradient[1] = 0.0;
this->NoGradient[2] = 1.0;
this->NoValue = 0.0;
this->Input = NULL;
this->Locator = NULL;
this->Tolerance = 1e-12;
......@@ -61,11 +65,7 @@ void vtkImplicitPolyDataDistance::SetInput(vtkPolyData* input)
this->Input->BuildLinks();
this->NoValue = this->Input->GetLength();
if (this->Locator != NULL)
{
this->Locator->Delete();
}
this->Locator = vtkCellLocator::New();
this->CreateDefaultLocator();
this->Locator->SetDataSet(this->Input);
this->Locator->SetTolerance(this->Tolerance);
this->Locator->SetNumberOfCellsPerBucket(10);
......@@ -93,32 +93,58 @@ unsigned long vtkImplicitPolyDataDistance::GetMTime()
//-----------------------------------------------------------------------------
vtkImplicitPolyDataDistance::~vtkImplicitPolyDataDistance()
{
if (this->Locator != NULL)
if ( this->Locator )
{
this->Locator->Delete();
this->Locator->UnRegister(this);
this->Locator = NULL;
}
}
//----------------------------------------------------------------------------
void vtkImplicitPolyDataDistance::CreateDefaultLocator()
{
if ( this->Locator == NULL)
{
this->Locator = vtkCellLocator::New();
}
}
//-----------------------------------------------------------------------------
double vtkImplicitPolyDataDistance::EvaluateFunction(double x[3])
{
double n[3];
return this->SharedEvaluate(x, n); // get distance value returned, normal not used
double g[3];
double p[3];
return this->SharedEvaluate(x, g, p); // get distance value returned, normal and closest point not used
}
//-----------------------------------------------------------------------------
double vtkImplicitPolyDataDistance::EvaluateFunctionAndGetClosestPoint(double x[3], double closestPoint[3])
{
double g[3];
return this->SharedEvaluate(x, g, closestPoint); // distance value returned and point on vtkPolyData stored in p (normal not used).
}
//-----------------------------------------------------------------------------
void vtkImplicitPolyDataDistance::EvaluateGradient(double x[3], double n[3])
void vtkImplicitPolyDataDistance::EvaluateGradient(double x[3], double g[3])
{
this->SharedEvaluate(x, n); // get normal, returned distance value not used
double p[3];
this->SharedEvaluate(x, g, p); // get normal, returned distance value not used and closest point not used
}
//-----------------------------------------------------------------------------
double vtkImplicitPolyDataDistance::SharedEvaluate(double x[3], double n[3])
double vtkImplicitPolyDataDistance::SharedEvaluate(double x[3], double g[3], double closestPoint[3])
{
// Set defaults
double ret = this->NoValue;
for( int i=0; i < 3; i++ )
{
g[i] = this->NoGradient[i];
}
for( int i=0; i < 3; i++ )
{
n[i] = this->NoGradient[i];
closestPoint[i] = this->NoClosestPoint[i];
}
// See if data set with polygons has been specified
......@@ -151,11 +177,10 @@ double vtkImplicitPolyDataDistance::SharedEvaluate(double x[3], double n[3])
// grad = (point - x) / dist
for (int i = 0; i < 3; i++)
{
n[i] = (p[i] - x[i]) / (ret == 0. ? 1. : ret);
g[i] = (p[i] - x[i]) / (ret == 0. ? 1. : ret);
}
double dist2, weights[3], pcoords[3], awnorm[3] = {0, 0, 0};
double closestPoint[3];
cell->EvaluatePosition(p, closestPoint, subId, pcoords, dist2, weights);
vtkIdList* idList = vtkIdList::New();
......@@ -287,16 +312,16 @@ double vtkImplicitPolyDataDistance::SharedEvaluate(double x[3], double n[3])
{
for (int i = 0; i < 3; i++)
{
n[i] = awnorm[i];
g[i] = awnorm[i];
}
}
ret *= (vtkMath::Dot(n, awnorm) < 0.) ? 1. : -1.;
ret *= (vtkMath::Dot(g, awnorm) < 0.) ? 1. : -1.;
if (ret > 0.)
{
for (int i = 0; i < 3; i++)
{
n[i] = -n[i];
g[i] = -g[i];
}
}
}
......
......@@ -62,6 +62,10 @@ public:
// Evaluate function gradient of nearest triangle to point x[3].
void EvaluateGradient(double x[3], double g[3]);
// Description:
// Evaluate plane equation of nearest triangle to point x[3] and provides closest point on an input vtkPolyData.
double EvaluateFunctionAndGetClosestPoint (double x[3], double closestPoint[3]);
// Description:
// Set the input vtkPolyData used for the implicit function
// evaluation. Passes input through an internal instance of
......@@ -81,6 +85,12 @@ public:
vtkSetVector3Macro(NoGradient, double);
vtkGetVector3Macro(NoGradient, double);
// Description:
// Set/get the closest point to use if no input vtkPolyData
// specified.
vtkSetVector3Macro(NoClosestPoint, double);
vtkGetVector3Macro(NoClosestPoint, double);
// Description:
// Set/get the tolerance usued for the locator.
vtkGetMacro(Tolerance, double);
......@@ -90,19 +100,23 @@ protected:
vtkImplicitPolyDataDistance();
~vtkImplicitPolyDataDistance();
double SharedEvaluate( double x[3], double n[3] );
// Description:
// Create default locator. Used to create one when none is specified.
void CreateDefaultLocator(void);
private:
vtkImplicitPolyDataDistance(const vtkImplicitPolyDataDistance&); // Not implemented.
void operator=(const vtkImplicitPolyDataDistance&); // Not implemented.
double SharedEvaluate(double x[3], double g[3], double p[3]);
double NoValue;
double NoGradient[3];
double NoClosestPoint[3];
double NoValue;
double Tolerance;
vtkPolyData *Input;
vtkCellLocator *Locator;
vtkPolyData *Input;
vtkCellLocator *Locator;
private:
vtkImplicitPolyDataDistance(const vtkImplicitPolyDataDistance&); // Not implemented.
void operator=(const vtkImplicitPolyDataDistance&); // Not implemented.
};
#endif
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment