ITK  5.0.0
Insight Segmentation and Registration Toolkit
itkQuadEdge.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkQuadEdge_h
19 #define itkQuadEdge_h
20 
22 #include "ITKQuadEdgeMeshExport.h"
23 
24 #include "itkMacro.h"
25 
26 // Debugging macros for classes that do not derive from the itkObject.
27 // FIXME: Maybe variations of these macros should be moved into
28 // itkMacro.h
29 //
30 #define itkQEDebugMacro(x) \
31  { \
32  std::ostringstream itkmsg; \
33  itkmsg << "Debug: In " __FILE__ ", line " << __LINE__ << "\n" \
34  << " (" << this << "): " x \
35  << "\n\n"; \
36  OutputWindowDisplayDebugText( itkmsg.str().c_str() ); \
37  }
38 #define itkQEWarningMacro(x) \
39  { \
40  std::ostringstream itkmsg; \
41  itkmsg << "WARNING: In " __FILE__ ", line " << __LINE__ << "\n" \
42  << " (" << this << "): " x \
43  << "\n\n"; \
44  OutputWindowDisplayWarningText( itkmsg.str().c_str() ); \
45  }
46 
47 // -------------------------------------------------------------------------
57 #define itkQEAccessorsMacro(st, pt, dt) \
58  pt * GetOnext() \
59  { \
60  return ( dynamic_cast< pt * >( this->st::GetOnext() ) ); \
61  } \
62  \
63  dt *GetRot() \
64  { \
65  return ( dynamic_cast< dt * >( this->st::GetRot() ) ); \
66  } \
67  \
68  pt *GetSym() \
69  { \
70  return ( dynamic_cast< pt * >( this->st::GetSym() ) ); \
71  } \
72  \
73  pt *GetLnext() \
74  { \
75  return ( dynamic_cast< pt * >( this->st::GetLnext() ) ); \
76  } \
77  \
78  pt *GetRnext() \
79  { \
80  return ( dynamic_cast< pt * >( this->st::GetRnext() ) ); \
81  } \
82  \
83  pt *GetDnext() \
84  { \
85  return ( dynamic_cast< pt * >( this->st::GetDnext() ) ); \
86  } \
87  \
88  pt *GetOprev() \
89  { \
90  return ( dynamic_cast< pt * >( this->st::GetOprev() ) ); \
91  } \
92  \
93  pt *GetLprev() \
94  { \
95  return ( dynamic_cast< pt * >( this->st::GetLprev() ) ); \
96  } \
97  \
98  pt *GetRprev() \
99  { \
100  return ( dynamic_cast< pt * >( this->st::GetRprev() ) ); \
101  } \
102  \
103  pt *GetDprev() \
104  { \
105  return ( dynamic_cast< pt * >( this->st::GetDprev() ) ); \
106  } \
107  \
108  dt *GetInvRot() \
109  { \
110  return ( dynamic_cast< dt * >( this->st::GetInvRot() ) ); \
111  } \
112  \
113  pt *GetInvOnext() \
114  { \
115  return ( dynamic_cast< pt * >( this->st::GetInvOnext() ) ); \
116  } \
117  \
118  pt *GetInvLnext() \
119  { \
120  return ( dynamic_cast< pt * >( this->st::GetInvLnext() ) ); \
121  } \
122  \
123  pt *GetInvRnext() \
124  { \
125  return ( dynamic_cast< pt * >( this->st::GetInvRnext() ) ); \
126  } \
127  \
128  pt *GetInvDnext() \
129  { \
130  return ( dynamic_cast< pt * >( this->st::GetInvDnext() ) ); \
131  } \
132  const pt *GetOnext() const \
133  { \
134  return ( dynamic_cast< const pt * >( this->st::GetOnext() ) ); \
135  } \
136  \
137  const dt *GetRot() const \
138  { \
139  return ( dynamic_cast< const dt * >( this->st::GetRot() ) ); \
140  } \
141  \
142  const pt *GetSym() const \
143  { \
144  return ( dynamic_cast< const pt * >( this->st::GetSym() ) ); \
145  } \
146  \
147  const pt *GetLnext() const \
148  { \
149  return ( dynamic_cast< const pt * >( this->st::GetLnext() ) ); \
150  } \
151  \
152  const pt *GetRnext() const \
153  { \
154  return ( dynamic_cast< const pt * >( this->st::GetRnext() ) ); \
155  } \
156  \
157  const pt *GetDnext() const \
158  { \
159  return ( dynamic_cast< const pt * >( this->st::GetDnext() ) ); \
160  } \
161  \
162  const pt *GetOprev() const \
163  { \
164  return ( dynamic_cast< const pt * >( this->st::GetOprev() ) ); \
165  } \
166  \
167  const pt *GetLprev() const \
168  { \
169  return ( dynamic_cast< const pt * >( this->st::GetLprev() ) ); \
170  } \
171  \
172  const pt *GetRprev() const \
173  { \
174  return ( dynamic_cast< const pt * >( this->st::GetRprev() ) ); \
175  } \
176  \
177  const pt *GetDprev() const \
178  { \
179  return ( dynamic_cast< const pt * >( this->st::GetDprev() ) ); \
180  } \
181  \
182  const dt *GetInvRot() const \
183  { \
184  return ( dynamic_cast< const dt * >( this->st::GetInvRot() ) ); \
185  } \
186  \
187  const pt *GetInvOnext() const \
188  { \
189  return ( dynamic_cast< const pt * >( this->st::GetInvOnext() ) ); \
190  } \
191  \
192  const pt *GetInvLnext() const \
193  { \
194  return ( dynamic_cast< const pt * >( this->st::GetInvLnext() ) ); \
195  } \
196  \
197  const pt *GetInvRnext() const \
198  { \
199  return ( dynamic_cast< const pt * >( this->st::GetInvRnext() ) ); \
200  } \
201  \
202  const pt *GetInvDnext() const \
203  { \
204  return ( dynamic_cast< const pt * >( this->st::GetInvDnext() ) ); \
205  }
206 
207 
208 namespace itk
209 {
225 class ITKQuadEdgeMesh_EXPORT QuadEdge
226 {
227 public:
229  using Self = QuadEdge;
230 
234 
236  inline itkQEDefineIteratorMethodsMacro(Onext);
237  // itkQEDefineIteratorMethodsMacro( Sym );
238  // itkQEDefineIteratorMethodsMacro( Lnext );
239  // itkQEDefineIteratorMethodsMacro( Rnext );
240  // itkQEDefineIteratorMethodsMacro( Dnext );
241  // itkQEDefineIteratorMethodsMacro( Oprev );
242  // itkQEDefineIteratorMethodsMacro( Lprev );
243  // itkQEDefineIteratorMethodsMacro( Rprev );
244  // itkQEDefineIteratorMethodsMacro( Dprev );
245  // itkQEDefineIteratorMethodsMacro( InvOnext );
246  // itkQEDefineIteratorMethodsMacro( InvLnext );
247  // itkQEDefineIteratorMethodsMacro( InvRnext );
248  // itkQEDefineIteratorMethodsMacro( InvDnext );
250 
252  QuadEdge();
253  QuadEdge(const QuadEdge &) = default;
254  QuadEdge(QuadEdge &&) = default;
255  QuadEdge & operator=(const QuadEdge &) = default;
256  QuadEdge & operator=(QuadEdge &&) = default;
257  virtual ~QuadEdge();
259 
261  inline void SetOnext(Self *onext) { this->m_Onext = onext; }
262  inline void SetRot(Self *rot) { this->m_Rot = rot; }
264 
268  inline Self * GetOnext() { return this->m_Onext; }
269  inline Self * GetRot() { return this->m_Rot; }
270  inline const Self * GetOnext() const { return this->m_Onext; }
271  inline const Self * GetRot() const { return this->m_Rot; }
273 
290 // TODO fix this ref
291 // * \sa \ref DoxySurgeryConnectivity
292  inline void Splice(Self *b)
293  {
294  Self *aNext = this->GetOnext();
295  Self *bNext = b->GetOnext();
296  Self *alpha = aNext->GetRot();
297  Self *beta = bNext->GetRot();
298  Self *alphaNext = alpha->GetOnext();
299  Self *betaNext = beta->GetOnext();
301 
302  this->SetOnext(bNext);
303  b->SetOnext(aNext);
304  alpha->SetOnext(betaNext);
305  beta->SetOnext(alphaNext);
306  }
307 
308  // Second order accessors.
309 
312  inline Self * GetSym()
313  {
314  if ( this->m_Rot )
315  {
316  return ( this->m_Rot->m_Rot );
317  }
318  return ( this->m_Rot );
319  }
321 
322  inline const Self * GetSym() const
323  {
324  if ( this->m_Rot )
325  {
326  return ( this->m_Rot->m_Rot );
327  }
328  return ( this->m_Rot );
329  }
330 
333  Self * GetLnext();
334 
335  const Self * GetLnext() const;
336 
340  Self * GetRnext();
341 
342  const Self * GetRnext() const;
343 
347  Self * GetDnext();
348 
349  const Self * GetDnext() const;
350 
353  Self * GetOprev();
354 
355  const Self * GetOprev() const;
356 
360  Self * GetLprev();
361 
362  const Self * GetLprev() const;
363 
367  Self * GetRprev();
368 
369  const Self * GetRprev() const;
370 
374  Self * GetDprev();
375 
376  const Self * GetDprev() const;
377 
379  inline Self * GetInvRot()
380  {
381 #ifdef NDEBUG
382  return ( this->GetRot()->GetRot()->GetRot() );
383 #else
384  Self *p1 = this->GetRot();
385  if ( !p1 ) { return nullptr; }
386  Self *p2 = p1->GetRot();
387  if ( !p2 ) { return nullptr; }
388  Self *p3 = p2->GetRot();
389  if ( !p3 ) { return nullptr; }
390  return p3;
391 #endif
392  }
394 
395  inline Self * GetInvOnext() { return this->GetOprev(); }
396  inline Self * GetInvLnext() { return this->GetLprev(); }
397  inline Self * GetInvRnext() { return this->GetRprev(); }
398  inline Self * GetInvDnext() { return this->GetDprev(); }
399  inline const Self * GetInvRot() const
400  {
401 #ifdef NDEBUG
402  return ( this->GetRot()->GetRot()->GetRot() );
403 #else
404  const Self *p1 = this->GetRot();
405  if ( !p1 ) { return nullptr; }
406  const Self *p2 = p1->GetRot();
407  if ( !p2 ) { return nullptr; }
408  const Self *p3 = p2->GetRot();
409  if ( !p3 ) { return nullptr; }
410  return p3;
411 #endif
412  }
413 
414  inline const Self * GetInvOnext() const { return this->GetOprev(); }
415  inline const Self * GetInvLnext() const { return this->GetLprev(); }
416  inline const Self * GetInvRnext() const { return this->GetRprev(); }
417  inline const Self * GetInvDnext() const { return this->GetDprev(); }
418 
420  inline bool IsHalfEdge() const { return ( ( m_Onext == this ) || ( m_Rot == nullptr ) ); }
421  inline bool IsIsolated() const { return ( this == this->GetOnext() ); }
422  bool IsEdgeInOnextRing(Self *testEdge) const;
424 
425  bool IsLnextGivenSizeCyclic(const int size) const;
426 
427  unsigned int GetOrder() const;
428 
429 private:
433 };
434 }
435 
436 #endif
Self * GetInvRot()
Definition: itkQuadEdge.h:379
bool IsHalfEdge() const
Definition: itkQuadEdge.h:420
const Self * GetInvOnext() const
Definition: itkQuadEdge.h:414
const Self * GetSym() const
Definition: itkQuadEdge.h:322
Self * GetSym()
Definition: itkQuadEdge.h:312
void SetRot(Self *rot)
Definition: itkQuadEdge.h:262
const Self * GetOnext() const
Definition: itkQuadEdge.h:270
Base class for the implementation of a quad-edge data structure as proposed in &quot;Guibas and Stolfi 198...
Definition: itkQuadEdge.h:225
Self * GetInvOnext()
Definition: itkQuadEdge.h:395
const Self * GetInvRnext() const
Definition: itkQuadEdge.h:416
Self * GetOnext()
Definition: itkQuadEdge.h:268
void SetOnext(Self *onext)
Definition: itkQuadEdge.h:261
Non const iterator for QuadMesh.
Self * GetInvRnext()
Definition: itkQuadEdge.h:397
#define itkQEDefineIteratorMethodsMacro(Op)
const Self * GetRot() const
Definition: itkQuadEdge.h:271
const Self * GetInvRot() const
Definition: itkQuadEdge.h:399
const Self * GetInvLnext() const
Definition: itkQuadEdge.h:415
Self * GetRot()
Definition: itkQuadEdge.h:269
Self * GetInvDnext()
Definition: itkQuadEdge.h:398
Const iterator for QuadEdgeMesh.
Self * GetInvLnext()
Definition: itkQuadEdge.h:396
bool IsIsolated() const
Definition: itkQuadEdge.h:421
void Splice(Self *b)
Basic quad-edge topological method.
Definition: itkQuadEdge.h:292
const Self * GetInvDnext() const
Definition: itkQuadEdge.h:417