Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "mitkPointLocator.h"
00019 #include <vtkPointSet.h>
00020 #include <ANN/ANN.h>
00021
00022
00023 mitk::PointLocator::PointLocator() :
00024 m_SearchTreeInitialized(false),
00025 m_VtkPoints(NULL), m_MitkPoints(NULL),
00026 m_ItkPoints(NULL),
00027 m_ANNK(1), m_ANNDimension(3),
00028 m_ANNEpsilon(0), m_ANNDataPoints(NULL),
00029 m_ANNQueryPoint(NULL), m_ANNPointIndexes(NULL),
00030 m_ANNDistances(NULL), m_ANNTree(NULL)
00031 {
00032
00033 }
00034
00035
00036
00037 mitk::PointLocator::~PointLocator()
00038 {
00039 if ( m_SearchTreeInitialized )
00040 DestroyANN();
00041 }
00042
00043
00044
00045 void mitk::PointLocator::SetPoints( vtkPointSet* pointSet )
00046 {
00047 if ( pointSet == NULL )
00048 {
00049 itkWarningMacro("Points are NULL!");
00050 return;
00051 }
00052 vtkPoints* points = pointSet->GetPoints();
00053
00054 if(m_VtkPoints)
00055 {
00056 if ( (m_VtkPoints == points) && (m_VtkPoints->GetMTime() == points->GetMTime()) )
00057 {
00058 return;
00059 }
00060 }
00061 m_VtkPoints = points;
00062
00063 size_t size = points->GetNumberOfPoints();
00064 if ( m_ANNDataPoints != NULL )
00065 delete[] m_ANNDataPoints;
00066 m_ANNDataPoints = annAllocPts( size, m_ANNDimension );
00067 m_IndexToPointIdContainer.clear();
00068 m_IndexToPointIdContainer.resize( size );
00069 for( vtkIdType i = 0; (unsigned)i < size; ++i )
00070 {
00071 vtkFloatingPointType* currentPoint = points->GetPoint( i );
00072 (m_ANNDataPoints[i])[0] = currentPoint[0];
00073 (m_ANNDataPoints[i])[1] = currentPoint[1];
00074 (m_ANNDataPoints[i])[2] = currentPoint[2];
00075 m_IndexToPointIdContainer[i] = i;
00076 }
00077 InitANN();
00078 }
00079
00080
00081
00082 void mitk::PointLocator::SetPoints( mitk::PointSet* points )
00083 {
00084 if ( points == NULL )
00085 {
00086 itkWarningMacro("Points are NULL!");
00087 return;
00088 }
00089
00090 if(m_MitkPoints)
00091 {
00092 if ( (m_MitkPoints == points) && (m_MitkPoints->GetMTime() == points->GetMTime()) )
00093 {
00094 return;
00095 }
00096 }
00097 m_MitkPoints = points;
00098
00099 size_t size = points->GetSize();
00100 if ( m_ANNDataPoints != NULL )
00101 delete[] m_ANNDataPoints;
00102 m_ANNDataPoints = annAllocPts( size, m_ANNDimension );
00103 m_IndexToPointIdContainer.clear();
00104 m_IndexToPointIdContainer.resize( size );
00105 size_t counter = 0;
00106 mitk::PointSet::PointsContainer* pointsContainer = points->GetPointSet()->GetPoints();
00107 mitk::PointSet::PointsContainer::Iterator it;
00108 mitk::PointSet::PointType currentPoint;
00109 mitk::PointSet::PointsContainer::ElementIdentifier currentId;
00110 for( it = pointsContainer->Begin(); it != pointsContainer->End(); ++it, ++counter )
00111 {
00112 currentPoint = it->Value();
00113 currentId = it->Index();
00114 (m_ANNDataPoints[counter])[0] = currentPoint[0];
00115 (m_ANNDataPoints[counter])[1] = currentPoint[1];
00116 (m_ANNDataPoints[counter])[2] = currentPoint[2];
00117 m_IndexToPointIdContainer[counter] = currentId;
00118 }
00119 InitANN();
00120 }
00121
00122
00123 void mitk::PointLocator::SetPoints( ITKPointSet* pointSet )
00124 {
00125 if ( pointSet == NULL )
00126 {
00127 itkWarningMacro("Points are NULL!");
00128 return;
00129 }
00130
00131 if(m_ItkPoints)
00132 {
00133 if ( (m_ItkPoints == pointSet) && (m_ItkPoints->GetMTime() == pointSet->GetMTime()) )
00134 {
00135 return;
00136 }
00137 }
00138 m_ItkPoints = pointSet;
00139
00140 size_t size = pointSet->GetNumberOfPoints();
00141 if ( m_ANNDataPoints != NULL )
00142 delete[] m_ANNDataPoints;
00143 m_ANNDataPoints = annAllocPts( size, m_ANNDimension );
00144 m_IndexToPointIdContainer.clear();
00145 m_IndexToPointIdContainer.resize( size );
00146 size_t counter = 0;
00147 ITKPointSet::PointsContainerConstPointer pointsContainer = pointSet->GetPoints();
00148 ITKPointSet::PointsContainer::ConstIterator it;
00149 ITKPointSet::PointType currentPoint;
00150 ITKPointSet::PointsContainer::ElementIdentifier currentId;
00151 for( it = pointsContainer->Begin(); it != pointsContainer->End(); ++it, ++counter )
00152 {
00153 currentPoint = it->Value();
00154 currentId = it->Index();
00155 (m_ANNDataPoints[counter])[0] = currentPoint[0];
00156 (m_ANNDataPoints[counter])[1] = currentPoint[1];
00157 (m_ANNDataPoints[counter])[2] = currentPoint[2];
00158 m_IndexToPointIdContainer[counter] = currentId;
00159 }
00160 InitANN();
00161 }
00162
00163
00164
00165 mitk::PointLocator::IdType mitk::PointLocator::FindClosestPoint( const vtkFloatingPointType point[3] )
00166 {
00167 m_ANNQueryPoint[0] = point[0];
00168 m_ANNQueryPoint[1] = point[1];
00169 m_ANNQueryPoint[2] = point[2];
00170 return FindClosestPoint( m_ANNQueryPoint );
00171 }
00172
00173
00174
00175 mitk::PointLocator::IdType mitk::PointLocator::FindClosestPoint( vtkFloatingPointType x, vtkFloatingPointType y, vtkFloatingPointType z )
00176 {
00177 m_ANNQueryPoint[0] = x;
00178 m_ANNQueryPoint[1] = y;
00179 m_ANNQueryPoint[2] = z;
00180 return FindClosestPoint( m_ANNQueryPoint );
00181 }
00182
00183
00184
00185 mitk::PointLocator::IdType mitk::PointLocator::FindClosestPoint( mitk::PointSet::PointType point )
00186 {
00187 m_ANNQueryPoint[0] = point[0];
00188 m_ANNQueryPoint[1] = point[1];
00189 m_ANNQueryPoint[2] = point[2];
00190 return FindClosestPoint( m_ANNQueryPoint );
00191 }
00192
00193 mitk::PointLocator::IdType mitk::PointLocator::FindClosestPoint( const ANNpoint& point)
00194 {
00195 if ( ! m_SearchTreeInitialized )
00196 return -1;
00197 m_ANNTree->annkSearch(point, m_ANNK, m_ANNPointIndexes, m_ANNDistances);
00198 return m_IndexToPointIdContainer[m_ANNPointIndexes[0]];
00199 }
00200
00201 mitk::PointLocator::DistanceType mitk::PointLocator::GetMinimalDistance( mitk::PointSet::PointType point )
00202 {
00203 m_ANNQueryPoint[0] = point[0];
00204 m_ANNQueryPoint[1] = point[1];
00205 m_ANNQueryPoint[2] = point[2];
00206 return GetMinimalDistance( m_ANNQueryPoint );
00207 }
00208
00209 mitk::PointLocator::DistanceType mitk::PointLocator::GetMinimalDistance( const ANNpoint& point)
00210 {
00211 if ( ! m_SearchTreeInitialized )
00212 return -1;
00213 m_ANNTree->annkSearch(point, m_ANNK, m_ANNPointIndexes, m_ANNDistances);
00214 return m_ANNDistances[0];
00215 }
00216
00217
00218 void mitk::PointLocator::InitANN()
00219 {
00220 if ( m_SearchTreeInitialized )
00221 DestroyANN();
00222
00223 m_ANNQueryPoint = annAllocPt( m_ANNDimension );
00224 m_ANNPointIndexes = new ANNidx[m_ANNK];
00225 m_ANNDistances = new ANNdist[m_ANNK];
00226 m_ANNTree = new ANNkd_tree( m_ANNDataPoints, m_IndexToPointIdContainer.size(), m_ANNDimension );
00227
00228 m_SearchTreeInitialized = true;
00229 }
00230
00231
00232
00233 void mitk::PointLocator::DestroyANN()
00234 {
00235 m_SearchTreeInitialized = false;
00236 if ( m_ANNQueryPoint != NULL )
00237 annDeallocPt( m_ANNQueryPoint );
00238 if ( m_ANNDataPoints != NULL )
00239 annDeallocPts( m_ANNDataPoints );
00240 if ( m_ANNPointIndexes != NULL )
00241 delete[] m_ANNPointIndexes;
00242 if ( m_ANNDistances != NULL )
00243 delete[] m_ANNDistances;
00244 if ( m_ANNTree != NULL )
00245 delete m_ANNTree;
00246 }
00247
00248 bool mitk::PointLocator::FindClosestPointAndDistance( mitk::PointSet::PointType point, IdType* id, DistanceType* dist )
00249 {
00250 m_ANNQueryPoint[0] = point[0];
00251 m_ANNQueryPoint[1] = point[1];
00252 m_ANNQueryPoint[2] = point[2];
00253
00254 m_ANNTree->annkSearch( m_ANNQueryPoint, m_ANNK, m_ANNPointIndexes, m_ANNDistances);
00255
00256 *id = m_IndexToPointIdContainer[m_ANNPointIndexes[0]];
00257 *dist = m_ANNDistances[0];
00258 return true;
00259 }
00260