Polyhedron.h
1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2013-2015 Imperial College London
5  * Copyright 2013-2015 Andreas Schuh
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifndef MIRTK_Polyhedron_H
21 #define MIRTK_Polyhedron_H
22 
23 #include "mirtk/Object.h"
24 #include "mirtk/Point.h"
25 
26 #include "vtkSmartPointer.h"
27 #include "vtkPolyData.h"
28 
29 
30 namespace mirtk {
31 
32 
33 /**
34  * Utility functions for dealing with VTK polydata representing a polyhedron.
35  *
36  * \note The point-in-polyhedron test based on the winding number method and
37  * the polyhedron volume computation are a C++ implementation of the excellent
38  * polyhedron.py Python module of Mark Dickinson found on GitHub at
39  * https://github.com/mdickinson/polyhedron/blob/cd7361bcee8cbd9ef2e0aac58a7ce59bf9a52c4f/polyhedron.py
40  */
41 class Polyhedron : public Object
42 {
43  mirtkObjectMacro(Polyhedron);
44 
45  // ---------------------------------------------------------------------------
46  // Attributes
47 
48  /// Dataset defining the geometry and topology of this polyhedron
49  mirtkPublicAttributeMacro(vtkSmartPointer<vtkPolyData>, DataSet);
50 
51 public:
52 
53  // ---------------------------------------------------------------------------
54  // Construction/destruction
55 
56  /// Constructor
57  Polyhedron(vtkPolyData * = NULL);
58 
59  /// Copy constructor
60  Polyhedron(const Polyhedron &);
61 
62  /// Assignment operator
64 
65  /// Destructor
66  virtual ~Polyhedron();
67 
68  // ---------------------------------------------------------------------------
69  // Geometry / Topology
70 
71  /// Number of vertices
72  int NumberOfPoints() const;
73 
74  /// Get vertex position
75  void GetPoint(int, double &, double &, double &) const;
76 
77  /// Get vertex position
78  void GetPoint(int, double [3]) const;
79 
80  /// Get vertex position
81  Point GetPoint(int) const;
82 
83  // ---------------------------------------------------------------------------
84  // Properties
85 
86  /// Calculate volume enclosed by polyhedron
87  double Volume() const;
88 
89  /// Calculate volume enclosed by polyhedron
90  static double Volume(vtkPolyData *);
91 
92  /// Compute winding number of polyhedron around given point
93  int WindingNumber(double, double, double) const;
94 
95  /// Compute winding number of polyhedron around given point
96  int WindingNumber(double [3]) const;
97 
98  /// Compute winding number of polyhedron around given point
99  int WindingNumber(const Point &) const;
100 
101  /// Compute winding number of polyhedron around given point
102  static int WindingNumber(vtkPolyData *, double, double, double);
103 
104  /// Compute winding number of polyhedron around given point
105  static int WindingNumber(vtkPolyData *, double [3]);
106 
107  /// Compute winding number of polyhedron around given point
108  static int WindingNumber(vtkPolyData *, const Point &);
109 
110  // ---------------------------------------------------------------------------
111  // Point-in-polyhedron test
112 
113  /// Test whether point is inside the polyhedron
114  bool IsInside(double, double, double) const;
115 
116  /// Test whether point is inside the polyhedron
117  bool IsInside(double [3]) const;
118 
119  /// Test whether point is inside the polyhedron
120  bool IsInside(const Point &) const;
121 
122  /// Test whether point is inside the polyhedron
123  static bool IsInside(vtkPolyData *, double, double, double);
124 
125  /// Test whether point is inside the polyhedron
126  static bool IsInside(vtkPolyData *, double [3]);
127 
128  /// Test whether point is inside the polyhedron
129  static bool IsInside(vtkPolyData *, const Point &);
130 
131 };
132 
133 ////////////////////////////////////////////////////////////////////////////////
134 // Inline definitions
135 ////////////////////////////////////////////////////////////////////////////////
136 
137 // =============================================================================
138 // Geometry / Topology
139 // =============================================================================
140 
141 // -----------------------------------------------------------------------------
142 inline int Polyhedron::NumberOfPoints() const
143 {
144  return static_cast<int>(_DataSet->GetNumberOfPoints());
145 }
146 
147 // -----------------------------------------------------------------------------
148 inline void Polyhedron::GetPoint(int i, double p[3]) const
149 {
150  _DataSet->GetPoint(i, p);
151 }
152 
153 // -----------------------------------------------------------------------------
154 inline void Polyhedron::GetPoint(int i, double &x, double &y, double &z) const
155 {
156  double p[3];
157  _DataSet->GetPoint(i, p);
158  x = p[0], y = p[1], z = p[2];
159 }
160 
161 // -----------------------------------------------------------------------------
162 inline Point Polyhedron::GetPoint(int i) const
163 {
164  Point p;
165  GetPoint(i, p._x, p._y, p._z);
166  return p;
167 }
168 
169 // =============================================================================
170 // Properties
171 // =============================================================================
172 
173 // -----------------------------------------------------------------------------
174 inline double Polyhedron::Volume() const
175 {
176  return Volume(_DataSet);
177 }
178 
179 // -----------------------------------------------------------------------------
180 inline int Polyhedron::WindingNumber(double x, double y, double z) const
181 {
182  return WindingNumber(_DataSet, x, y, z);
183 }
184 
185 // -----------------------------------------------------------------------------
186 inline int Polyhedron::WindingNumber(double p[3]) const
187 {
188  return WindingNumber(p[0], p[1], p[2]);
189 }
190 
191 // -----------------------------------------------------------------------------
192 inline int Polyhedron::WindingNumber(const Point &p) const
193 {
194  return WindingNumber(p._x, p._y, p._z);
195 }
196 
197 // -----------------------------------------------------------------------------
198 inline int Polyhedron::WindingNumber(vtkPolyData *polydata, double p[3])
199 {
200  return WindingNumber(polydata, p[0], p[1], p[2]);
201 }
202 
203 // -----------------------------------------------------------------------------
204 inline int Polyhedron::WindingNumber(vtkPolyData *polydata, const Point &p)
205 {
206  return WindingNumber(polydata, p._x, p._y, p._z);
207 }
208 
209 // =============================================================================
210 // Point-in-polyhedron test
211 // =============================================================================
212 
213 // -----------------------------------------------------------------------------
214 inline bool Polyhedron::IsInside(vtkPolyData *polydata, double x, double y, double z)
215 {
216  return WindingNumber(polydata, x, y, z) != 0;
217 }
218 
219 // -----------------------------------------------------------------------------
220 inline bool Polyhedron::IsInside(double x, double y, double z) const
221 {
222  return IsInside(_DataSet, x, y, z);
223 }
224 
225 // -----------------------------------------------------------------------------
226 inline bool Polyhedron::IsInside(double p[3]) const
227 {
228  return IsInside(p[0], p[1], p[2]);
229 }
230 
231 // -----------------------------------------------------------------------------
232 inline bool Polyhedron::IsInside(const Point &p) const
233 {
234  return IsInside(p._x, p._y, p._z);
235 }
236 
237 // -----------------------------------------------------------------------------
238 inline bool Polyhedron::IsInside(vtkPolyData *polydata, double p[3])
239 {
240  return IsInside(polydata, p[0], p[1], p[2]);
241 }
242 
243 // -----------------------------------------------------------------------------
244 inline bool Polyhedron::IsInside(vtkPolyData *polydata, const Point &p)
245 {
246  return IsInside(polydata, p._x, p._y, p._z);
247 }
248 
249 
250 } // namespace mirtk
251 
252 #endif // MIRTK_Polyhedron_H
void GetPoint(int, double &, double &, double &) const
Get vertex position.
Definition: Polyhedron.h:154
double Volume() const
Calculate volume enclosed by polyhedron.
Definition: Polyhedron.h:174
double _x
x coordinate of Point
Definition: Point.h:46
virtual ~Polyhedron()
Destructor.
Definition: IOConfig.h:41
int WindingNumber(double, double, double) const
Compute winding number of polyhedron around given point.
Definition: Polyhedron.h:180
Polyhedron(vtkPolyData *=NULL)
Constructor.
bool IsInside(double, double, double) const
Test whether point is inside the polyhedron.
Definition: Polyhedron.h:220
double _z
z coordinate of Point
Definition: Point.h:48
int NumberOfPoints() const
Number of vertices.
Definition: Polyhedron.h:142
double _y
y coordinate of Point
Definition: Point.h:47
Polyhedron & operator=(const Polyhedron &)
Assignment operator.