Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkPointLocator.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include "mitkPointLocator.h"
18 #include <ANN/ANN.h>
19 #include <vtkPointSet.h>
20 
22  : m_SearchTreeInitialized(false),
23  m_VtkPoints(nullptr),
24  m_MitkPoints(nullptr),
25  m_ItkPoints(nullptr),
26  m_ANNK(1),
27  m_ANNDimension(3),
28  m_ANNEpsilon(0),
29  m_ANNDataPoints(nullptr),
30  m_ANNQueryPoint(nullptr),
31  m_ANNPointIndexes(nullptr),
32  m_ANNDistances(nullptr),
33  m_ANNTree(nullptr)
34 {
35 }
36 
38 {
39  if (m_SearchTreeInitialized)
40  DestroyANN();
41 }
42 
43 void mitk::PointLocator::SetPoints(vtkPointSet *pointSet)
44 {
45  if (pointSet == nullptr)
46  {
47  itkWarningMacro("Points are NULL!");
48  return;
49  }
50  vtkPoints *points = pointSet->GetPoints();
51 
52  if (m_VtkPoints)
53  {
54  if ((m_VtkPoints == points) && (m_VtkPoints->GetMTime() == points->GetMTime()))
55  {
56  return; // no need to recalculate search tree
57  }
58  }
59  m_VtkPoints = points;
60 
61  size_t size = points->GetNumberOfPoints();
62  if (m_ANNDataPoints != nullptr)
63  delete[] m_ANNDataPoints;
64  m_ANNDataPoints = annAllocPts(size, m_ANNDimension);
65  m_IndexToPointIdContainer.clear();
66  m_IndexToPointIdContainer.resize(size);
67  for (vtkIdType i = 0; (unsigned)i < size; ++i)
68  {
69  double *currentPoint = points->GetPoint(i);
70  (m_ANNDataPoints[i])[0] = currentPoint[0];
71  (m_ANNDataPoints[i])[1] = currentPoint[1];
72  (m_ANNDataPoints[i])[2] = currentPoint[2];
73  m_IndexToPointIdContainer[i] = i;
74  }
75  InitANN();
76 }
77 
79 {
80  if (points == nullptr)
81  {
82  itkWarningMacro("Points are NULL!");
83  return;
84  }
85 
86  if (m_MitkPoints)
87  {
88  if ((m_MitkPoints == points) && (m_MitkPoints->GetMTime() == points->GetMTime()))
89  {
90  return; // no need to recalculate search tree
91  }
92  }
93  m_MitkPoints = points;
94 
95  size_t size = points->GetSize();
96  if (m_ANNDataPoints != nullptr)
97  delete[] m_ANNDataPoints;
98  m_ANNDataPoints = annAllocPts(size, m_ANNDimension);
99  m_IndexToPointIdContainer.clear();
100  m_IndexToPointIdContainer.resize(size);
101  size_t counter = 0;
102  mitk::PointSet::PointsContainer *pointsContainer = points->GetPointSet()->GetPoints();
103  mitk::PointSet::PointsContainer::Iterator it;
104  mitk::PointSet::PointType currentPoint;
105  mitk::PointSet::PointsContainer::ElementIdentifier currentId;
106  for (it = pointsContainer->Begin(); it != pointsContainer->End(); ++it, ++counter)
107  {
108  currentPoint = it->Value();
109  currentId = it->Index();
110  (m_ANNDataPoints[counter])[0] = currentPoint[0];
111  (m_ANNDataPoints[counter])[1] = currentPoint[1];
112  (m_ANNDataPoints[counter])[2] = currentPoint[2];
113  m_IndexToPointIdContainer[counter] = currentId;
114  }
115  InitANN();
116 }
117 
119 {
120  if (pointSet == nullptr)
121  {
122  itkWarningMacro("Points are NULL!");
123  return;
124  }
125 
126  if (m_ItkPoints)
127  {
128  if ((m_ItkPoints == pointSet) && (m_ItkPoints->GetMTime() == pointSet->GetMTime()))
129  {
130  return; // no need to recalculate search tree
131  }
132  }
133  m_ItkPoints = pointSet;
134 
135  size_t size = pointSet->GetNumberOfPoints();
136  if (m_ANNDataPoints != nullptr)
137  delete[] m_ANNDataPoints;
138  m_ANNDataPoints = annAllocPts(size, m_ANNDimension);
139  m_IndexToPointIdContainer.clear();
140  m_IndexToPointIdContainer.resize(size);
141  size_t counter = 0;
142  ITKPointSet::PointsContainerConstPointer pointsContainer = pointSet->GetPoints();
143  ITKPointSet::PointsContainer::ConstIterator it;
144  ITKPointSet::PointType currentPoint;
145  ITKPointSet::PointsContainer::ElementIdentifier currentId;
146  for (it = pointsContainer->Begin(); it != pointsContainer->End(); ++it, ++counter)
147  {
148  currentPoint = it->Value();
149  currentId = it->Index();
150  (m_ANNDataPoints[counter])[0] = currentPoint[0];
151  (m_ANNDataPoints[counter])[1] = currentPoint[1];
152  (m_ANNDataPoints[counter])[2] = currentPoint[2];
153  m_IndexToPointIdContainer[counter] = currentId;
154  }
155  InitANN();
156 }
157 
159 {
160  m_ANNQueryPoint[0] = point[0];
161  m_ANNQueryPoint[1] = point[1];
162  m_ANNQueryPoint[2] = point[2];
163  return FindClosestANNPoint(m_ANNQueryPoint);
164 }
165 
167 {
168  m_ANNQueryPoint[0] = x;
169  m_ANNQueryPoint[1] = y;
170  m_ANNQueryPoint[2] = z;
171  return FindClosestANNPoint(m_ANNQueryPoint);
172 }
173 
175 {
176  m_ANNQueryPoint[0] = point[0];
177  m_ANNQueryPoint[1] = point[1];
178  m_ANNQueryPoint[2] = point[2];
179  return FindClosestANNPoint(m_ANNQueryPoint);
180 }
181 
183 {
184  if (!m_SearchTreeInitialized)
185  return -1;
186  m_ANNTree->annkSearch(point, m_ANNK, m_ANNPointIndexes, m_ANNDistances);
187  return m_IndexToPointIdContainer[m_ANNPointIndexes[0]];
188 }
189 
191 {
192  m_ANNQueryPoint[0] = point[0];
193  m_ANNQueryPoint[1] = point[1];
194  m_ANNQueryPoint[2] = point[2];
195  return GetMinimalDistance(m_ANNQueryPoint);
196 }
197 
199 {
200  if (!m_SearchTreeInitialized)
201  return -1;
202  m_ANNTree->annkSearch(point, m_ANNK, m_ANNPointIndexes, m_ANNDistances);
203  return m_ANNDistances[0];
204 }
205 
207 {
208  if (m_SearchTreeInitialized)
209  DestroyANN();
210 
211  m_ANNQueryPoint = annAllocPt(m_ANNDimension);
212  m_ANNPointIndexes = new ANNidx[m_ANNK];
213  m_ANNDistances = new ANNdist[m_ANNK];
214  m_ANNTree = new ANNkd_tree(m_ANNDataPoints, m_IndexToPointIdContainer.size(), m_ANNDimension);
215 
216  m_SearchTreeInitialized = true;
217 }
218 
220 {
221  m_SearchTreeInitialized = false;
222  if (m_ANNQueryPoint != nullptr)
223  annDeallocPt(m_ANNQueryPoint);
224  if (m_ANNDataPoints != nullptr)
225  annDeallocPts(m_ANNDataPoints);
226  if (m_ANNPointIndexes != nullptr)
227  delete[] m_ANNPointIndexes;
228  if (m_ANNDistances != nullptr)
229  delete[] m_ANNDistances;
230  if (m_ANNTree != nullptr)
231  delete m_ANNTree;
232 }
233 
235 {
236  m_ANNQueryPoint[0] = point[0];
237  m_ANNQueryPoint[1] = point[1];
238  m_ANNQueryPoint[2] = point[2];
239 
240  m_ANNTree->annkSearch(m_ANNQueryPoint, m_ANNK, m_ANNPointIndexes, m_ANNDistances);
241 
242  *id = m_IndexToPointIdContainer[m_ANNPointIndexes[0]];
243  *dist = m_ANNDistances[0];
244  return true;
245 }
mitk::Point3D PointType
virtual int GetSize(unsigned int t=0) const
returns the current size of the point-list
DistanceType GetMinimalDistance(mitk::PointSet::PointType point)
void SetPoints(vtkPointSet *points)
bool FindClosestPointAndDistance(mitk::PointSet::PointType point, IdType *id, DistanceType *dist)
Data structure which stores a set of points. Superclass of mitk::Mesh.
Definition: mitkPointSet.h:79
virtual DataType::Pointer GetPointSet(int t=0) const
returns the pointset
virtual unsigned long GetMTime() const override
Get the modified time of the last change of the contents this data object or its geometry.
DataType::PointsContainer PointsContainer
Definition: mitkPointSet.h:136
itk::PointSet< PixelType, 3, MeshTraits > ITKPointSet
IdType FindClosestANNPoint(const MyANNpoint &point)
IdType FindClosestPoint(const double point[3])