Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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])