mirror of
https://github.com/OpenFOAM/ThirdParty-6.git
synced 2025-12-08 06:57:43 +00:00
ParaView-5.0.1: Added the source-tree to ThirdParty-dev and patched as described in the README file
Resolves bug-report http://bugs.openfoam.org/view.php?id=2098
This commit is contained in:
@ -0,0 +1,319 @@
|
||||
/*=========================================================================
|
||||
|
||||
Program: Visualization Toolkit
|
||||
Module: vtkFastMarchingGeodesicPath.cxx
|
||||
|
||||
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.
|
||||
|
||||
=========================================================================*/
|
||||
/*=========================================================================
|
||||
|
||||
Copyright (c) 2013 Karthik Krishnan.
|
||||
Contributed to the VisualizationToolkit by the author under the terms
|
||||
of the Visualization Toolkit copyright
|
||||
|
||||
=========================================================================*/
|
||||
#include "vtkFastMarchingGeodesicPath.h"
|
||||
|
||||
#include "vtkFastMarchingGeodesicDistance.h"
|
||||
#include "vtkInformation.h"
|
||||
#include "vtkInformationVector.h"
|
||||
#include "vtkObjectFactory.h"
|
||||
#include "vtkExecutive.h"
|
||||
#include "vtkIdList.h"
|
||||
#include "vtkMath.h"
|
||||
#include "vtkSmartPointer.h"
|
||||
#include "vtkCellArray.h"
|
||||
#include "vtkNew.h"
|
||||
|
||||
#include "gw_geodesic/GW_GeodesicMesh.h"
|
||||
#include "gw_geodesic/GW_GeodesicPath.h"
|
||||
#include "gw_core/GW_Vertex.h"
|
||||
#include "gw_core/GW_Face.h"
|
||||
#include "gw_core/GW_Config.h"
|
||||
#include <assert.h>
|
||||
#include <set>
|
||||
|
||||
#ifdef _WIN32
|
||||
// new is being defined to a new method that takes in 4 parameters within
|
||||
// one of the GeodesicMesh headers. Go back to what its supposed to be or
|
||||
// this can wreck havoc.
|
||||
#ifdef new
|
||||
#undef new
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
vtkStandardNewMacro(vtkFastMarchingGeodesicPath);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
vtkFastMarchingGeodesicPath::vtkFastMarchingGeodesicPath()
|
||||
{
|
||||
this->MaximumPathPoints = GW_INFINITE; // no limit
|
||||
this->InterpolationOrder = 1; // linear by default
|
||||
this->BeginPointId = -1; // undefined
|
||||
this->Geodesic = vtkFastMarchingGeodesicDistance::New();
|
||||
this->ZerothOrderPathPointIds = vtkIdList::New();
|
||||
this->FirstOrderPathPointIds = vtkIdList::New();
|
||||
this->GeodesicLength = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
vtkFastMarchingGeodesicPath::~vtkFastMarchingGeodesicPath()
|
||||
{
|
||||
this->ZerothOrderPathPointIds->Delete();
|
||||
this->FirstOrderPathPointIds->Delete();
|
||||
this->Geodesic->Delete();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int vtkFastMarchingGeodesicPath::RequestData(
|
||||
vtkInformation * vtkNotUsed( request ),
|
||||
vtkInformationVector ** inputVector,
|
||||
vtkInformationVector * outputVector)
|
||||
{
|
||||
vtkInformation * inInfo = inputVector[0]->GetInformationObject(0);
|
||||
vtkInformation *outInfo = outputVector->GetInformationObject(0);
|
||||
|
||||
vtkPolyData *input = vtkPolyData::SafeDownCast(
|
||||
inInfo->Get(vtkDataObject::DATA_OBJECT()));
|
||||
vtkPolyData *output = vtkPolyData::SafeDownCast(
|
||||
outInfo->Get(vtkDataObject::DATA_OBJECT()));
|
||||
|
||||
if (!output || !input)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
this->Geodesic->SetInputData(input);
|
||||
|
||||
// Setup the termination criteria such that we stop marching when we reach
|
||||
// the destination.
|
||||
vtkNew< vtkIdList > terminationIds;
|
||||
terminationIds->InsertNextId(this->BeginPointId);
|
||||
this->Geodesic->SetDestinationVertexStopCriterion(
|
||||
terminationIds.GetPointer());
|
||||
|
||||
// This will re-run fast marching and compute the distance field from the
|
||||
// seeded points, if necessary (if the mesh or seeds have changed)
|
||||
this->Geodesic->Update();
|
||||
|
||||
// - Compute the path by gradient backtracking of the distance field.
|
||||
// - Also copy the path from the GW datastructures into a vtkPolyData. The
|
||||
// result is a polydata containing an open polyline with a single cell.
|
||||
// - Also copy the point ids of the closest and the bounding vertices of
|
||||
// the path.
|
||||
this->ComputePath(output);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void vtkFastMarchingGeodesicPath::SetSeeds( vtkIdList *seeds )
|
||||
{
|
||||
this->Geodesic->SetSeeds(seeds);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
vtkIdList *vtkFastMarchingGeodesicPath::GetSeeds()
|
||||
{
|
||||
return this->Geodesic->GetSeeds();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void vtkFastMarchingGeodesicPath::ComputePath(vtkPolyData *pd)
|
||||
{
|
||||
// clear the length and the path point ids
|
||||
this->GeodesicLength = 0;
|
||||
this->ZerothOrderPathPointIds->Initialize();
|
||||
this->FirstOrderPathPointIds->Initialize();
|
||||
|
||||
// The points defining the path
|
||||
vtkSmartPointer< vtkPoints > pathPoints =
|
||||
vtkSmartPointer< vtkPoints >::New();
|
||||
pathPoints->Initialize();
|
||||
|
||||
GW::GW_GeodesicMesh *mesh = (GW::GW_GeodesicMesh *)(
|
||||
this->Geodesic->GetGeodesicMesh());
|
||||
GW::GW_GeodesicVertex* begin =
|
||||
(GW::GW_GeodesicVertex*)(mesh->GetVertex((GW::GW_U32)this->BeginPointId));
|
||||
|
||||
// Sanity check to ensure that the start point for the gradient tracing
|
||||
// does indeed lie on the mesh.
|
||||
if (!begin)
|
||||
{
|
||||
vtkErrorMacro( << "BeginPointId was not found to lie on the mesh." );
|
||||
return;
|
||||
}
|
||||
|
||||
// Do a gradient tracing from a point
|
||||
GW::GW_GeodesicPath track;
|
||||
track.ComputePath(*begin, this->MaximumPathPoints);
|
||||
|
||||
// Get the track
|
||||
GW::T_GeodesicPointList ptList = track.GetPointList();
|
||||
|
||||
GW::GW_GeodesicPoint* pt;
|
||||
float parametricPos;
|
||||
GW::GW_GeodesicVertex *endVert1, *endVert2;
|
||||
GW::GW_Vector3D endPt1, endPt2;
|
||||
double pathPt[3] = {0.0, 0.0, 0.0};
|
||||
double lastPathPt[3] = {0.0, 0.0, 0.0};
|
||||
vtkIdType endPtId1, endPtId2, lastInsertedPtId = -1;
|
||||
vtkIdType i = 0, i0 = 0;
|
||||
|
||||
const size_t nPts = ptList.size();
|
||||
pathPoints->SetNumberOfPoints(nPts);
|
||||
|
||||
// the closet path points on the mesh
|
||||
this->ZerothOrderPathPointIds->SetNumberOfIds( nPts );
|
||||
|
||||
// With linear interpolation we return a pair of point ids (corresponding to
|
||||
// the triangle edge end points) for each path point.
|
||||
if (this->InterpolationOrder == 1)
|
||||
{
|
||||
this->FirstOrderPathPointIds->SetNumberOfIds( nPts * 2 );
|
||||
}
|
||||
|
||||
// Loop through points on the track
|
||||
for ( GW::CIT_GeodesicPointList cit = ptList.begin(), citEnd = ptList.end();
|
||||
cit != citEnd;
|
||||
++cit, ++i,
|
||||
lastPathPt[0] = pathPt[0],
|
||||
lastPathPt[1] = pathPt[1],
|
||||
lastPathPt[2] = pathPt[2])
|
||||
{
|
||||
// This is a point on the track
|
||||
pt = *cit;
|
||||
|
||||
// The parametric position of the vertex on the edge
|
||||
parametricPos = pt->GetCoord();
|
||||
|
||||
// Get the end points of the edge on which the path lies.
|
||||
endVert1 = pt->GetVertex1();
|
||||
endVert2 = pt->GetVertex2();
|
||||
endPt1 = endVert1->GetPosition();
|
||||
endPt2 = endVert2->GetPosition();
|
||||
endPtId1 = endVert1->GetID();
|
||||
endPtId2 = endVert2->GetID();
|
||||
|
||||
// Store the edge point ids. The ZerothOrderPointIds contain the closest
|
||||
// one. The FirstOrderPointIds contains the other one.
|
||||
|
||||
if (parametricPos > 0.5) // pt is closer to endPtId1
|
||||
{
|
||||
|
||||
if (lastInsertedPtId != endPtId1)
|
||||
{
|
||||
// avoid repeats
|
||||
lastInsertedPtId = endPtId1;
|
||||
this->ZerothOrderPathPointIds->SetId(i0, endPtId1);
|
||||
pathPt[0] = endPt1[0];
|
||||
pathPt[1] = endPt1[1];
|
||||
pathPt[2] = endPt1[2];
|
||||
if (this->InterpolationOrder == 0)
|
||||
{
|
||||
pathPoints->SetPoint(i0, pathPt[0], pathPt[1], pathPt[2]);
|
||||
}
|
||||
++i0;
|
||||
}
|
||||
|
||||
// Store both end points of the path in FirstOrderPathPointIds
|
||||
if (this->InterpolationOrder == 1)
|
||||
{
|
||||
this->FirstOrderPathPointIds->SetId(2*i, endPtId1);
|
||||
this->FirstOrderPathPointIds->SetId(2*i+1, endPtId2);
|
||||
}
|
||||
}
|
||||
else // pt is closer to endPtId2
|
||||
{
|
||||
if (lastInsertedPtId != endPtId2)
|
||||
{
|
||||
// avoid repeats
|
||||
lastInsertedPtId = endPtId2;
|
||||
this->ZerothOrderPathPointIds->SetId(i0, endPtId2);
|
||||
pathPt[0] = endPt2[0];
|
||||
pathPt[1] = endPt2[1];
|
||||
pathPt[2] = endPt2[2];
|
||||
if (this->InterpolationOrder == 0)
|
||||
{
|
||||
pathPoints->SetPoint(i0, pathPt[0], pathPt[1], pathPt[2]);
|
||||
}
|
||||
++i0;
|
||||
}
|
||||
|
||||
// Store both end points of the path in FirstOrderPathPointIds
|
||||
if (this->InterpolationOrder == 1)
|
||||
{
|
||||
this->FirstOrderPathPointIds->SetId(2*i, endPtId2);
|
||||
this->FirstOrderPathPointIds->SetId(2*i+1, endPtId1);
|
||||
}
|
||||
}
|
||||
|
||||
if (this->InterpolationOrder == 1)
|
||||
{
|
||||
// Linearly interpolate the edge vertices based on the parametric
|
||||
// position on the edge
|
||||
pathPt[0] = parametricPos * endPt1[0] + (1-parametricPos) * endPt2[0];
|
||||
pathPt[1] = parametricPos * endPt1[1] + (1-parametricPos) * endPt2[1];
|
||||
pathPt[2] = parametricPos * endPt1[2] + (1-parametricPos) * endPt2[2];
|
||||
|
||||
pathPoints->SetPoint(i, pathPt[0], pathPt[1], pathPt[2]);
|
||||
}
|
||||
|
||||
// Compute the curve length
|
||||
if (i)
|
||||
{
|
||||
this->GeodesicLength += sqrt(
|
||||
vtkMath::Distance2BetweenPoints(lastPathPt, pathPt));
|
||||
}
|
||||
|
||||
} // end loop over vertices in the gradient trace
|
||||
|
||||
|
||||
// Set the size to the actual size, which may be less than the track.npts
|
||||
// because we avoid repeats.
|
||||
this->ZerothOrderPathPointIds->SetNumberOfIds( i0 );
|
||||
if (this->InterpolationOrder == 0)
|
||||
{
|
||||
pathPoints->SetNumberOfPoints(i0);
|
||||
}
|
||||
|
||||
// Set this path on the output. Its an open polyline with a single cell.
|
||||
|
||||
vtkIdType nUniquePoints = pathPoints->GetNumberOfPoints();
|
||||
pd->SetPoints(pathPoints);
|
||||
vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
|
||||
lines->InsertNextCell(nUniquePoints);
|
||||
for (i = 0; i < nUniquePoints; i++)
|
||||
{
|
||||
lines->InsertCellPoint(i);
|
||||
}
|
||||
pd->SetLines(lines);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void vtkFastMarchingGeodesicPath::PrintSelf(ostream& os, vtkIndent indent)
|
||||
{
|
||||
this->Superclass::PrintSelf(os,indent);
|
||||
|
||||
os << indent << this->Geodesic << "\n";
|
||||
if (this->Geodesic)
|
||||
{
|
||||
this->Geodesic->PrintSelf(os, indent.GetNextIndent());
|
||||
}
|
||||
os << indent << "BeginPointId: " << this->BeginPointId << "\n";
|
||||
os << indent << "InterpolationOrder: " << this->InterpolationOrder << "\n";
|
||||
os << indent << "GeodesicLength: " << this->GeodesicLength << "\n";
|
||||
os << indent << "MaximumPathPoints: " << this->MaximumPathPoints << "\n";
|
||||
os << indent << "ZerothOrderPathPointIds: "
|
||||
<< this->ZerothOrderPathPointIds << "\n";
|
||||
os << indent << "FirstOrderPathPointIds: "
|
||||
<< this->FirstOrderPathPointIds << "\n";
|
||||
}
|
||||
Reference in New Issue
Block a user