Point Cloud Library (PCL)  1.9.1-dev
mesh_circulators.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2009-2012, Willow Garage, Inc.
6  * Copyright (c) 2012-, Open Perception, Inc.
7  *
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * * Redistributions of source code must retain the above copyright
15  * notice, this list of conditions and the following disclaimer.
16  * * Redistributions in binary form must reproduce the above
17  * copyright notice, this list of conditions and the following
18  * disclaimer in the documentation and/or other materials provided
19  * with the distribution.
20  * * Neither the name of the copyright holder(s) nor the names of its
21  * contributors may be used to endorse or promote products derived
22  * from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  *
37  * $Id$
38  *
39  */
40 
41 // NOTE: This file has been created with 'pcl_src/geometry/include/pcl/geometry/mesh_circulators.py'
42 
43 #pragma once
44 
45 #include <pcl/geometry/boost.h>
46 #include <pcl/geometry/mesh_indices.h>
47 
48 ////////////////////////////////////////////////////////////////////////////////
49 // VertexAroundVertexCirculator
50 ////////////////////////////////////////////////////////////////////////////////
51 
52 namespace pcl
53 {
54  namespace geometry
55  {
56  /** \brief Circulates counter-clockwise around a vertex and returns an index to the terminating vertex of the outgoing half-edge (the target). The best way to declare the circulator is to use the method pcl::geometry::MeshBase::getVertexAroundVertexCirculator ().
57  * \tparam MeshT Mesh to which this circulator belongs to.
58  * \note The circulator can't be used to change the connectivity in the mesh (only const circulators are valid).
59  * \author Martin Saelzle
60  * \ingroup geometry
61  */
62  template <class MeshT>
64  : boost::equality_comparable <pcl::geometry::VertexAroundVertexCirculator <MeshT>
65  , boost::unit_steppable <pcl::geometry::VertexAroundVertexCirculator <MeshT>
66  > >
67  {
68  public:
69 
70  typedef boost::equality_comparable <pcl::geometry::VertexAroundVertexCirculator <MeshT>
71  , boost::unit_steppable <pcl::geometry::VertexAroundVertexCirculator <MeshT> > > Base;
73 
74  typedef MeshT Mesh;
75  typedef typename Mesh::VertexIndex VertexIndex;
76  typedef typename Mesh::HalfEdgeIndex HalfEdgeIndex;
77 
78  /** \brief Constructor resulting in an invalid circulator. */
80  : mesh_ (nullptr),
82  {
83  }
84 
85  /** \brief Construct from the vertex around which we want to circulate. */
86  VertexAroundVertexCirculator (const VertexIndex& idx_vertex,
87  Mesh*const mesh)
88  : mesh_ (mesh),
89  idx_outgoing_half_edge_ (mesh->getOutgoingHalfEdgeIndex (idx_vertex))
90  {
91  }
92 
93  /** \brief Construct directly from the outgoing half-edge. */
94  VertexAroundVertexCirculator (const HalfEdgeIndex& idx_outgoing_half_edge,
95  Mesh*const mesh)
96  : mesh_ (mesh),
97  idx_outgoing_half_edge_ (idx_outgoing_half_edge)
98  {
99  }
100 
101  /** \brief Check if the circulator is valid.
102  * \warning Does NOT check if the stored mesh pointer is valid. You have to ensure this yourself when constructing the circulator. */
103  inline bool
104  isValid () const
105  {
106  return (idx_outgoing_half_edge_.isValid ());
107  }
108 
109  /** \brief Comparison operators (with boost::operators): == !=
110  * \warning Does NOT check if the circulators belong to the same mesh. Please check this yourself. */
111  inline bool
112  operator == (const Self& other) const
113  {
115  }
116 
117  /** \brief Increment operators (with boost::operators): ++ (pre and post) */
118  inline Self&
120  {
121  idx_outgoing_half_edge_ = mesh_->getNextHalfEdgeIndex (mesh_->getOppositeHalfEdgeIndex (idx_outgoing_half_edge_));
122  return (*this);
123  }
124 
125  /** \brief Decrement operators (with boost::operators): -- (pre and post) */
126  inline Self&
128  {
129  idx_outgoing_half_edge_ = mesh_->getOppositeHalfEdgeIndex (mesh_->getPrevHalfEdgeIndex (idx_outgoing_half_edge_));
130  return (*this);
131  }
132 
133  /** \brief Get the index to the target vertex. */
134  inline VertexIndex
135  getTargetIndex () const
136  {
137  return (mesh_->getTerminatingVertexIndex (idx_outgoing_half_edge_));
138  }
139 
140  /** \brief Get the half-edge that is currently stored in the circulator. */
141  inline HalfEdgeIndex
143  {
144  return (idx_outgoing_half_edge_);
145  }
146 
147  /** \brief The mesh to which this circulator belongs to. */
148  Mesh* mesh_;
149 
150  /** \brief The outgoing half-edge of the vertex around which we want to circulate. */
151  HalfEdgeIndex idx_outgoing_half_edge_;
152  };
153  } // End namespace geometry
154 } // End namespace pcl
155 
156 ////////////////////////////////////////////////////////////////////////////////
157 // OutgoingHalfEdgeAroundVertexCirculator
158 ////////////////////////////////////////////////////////////////////////////////
159 
160 namespace pcl
161 {
162  namespace geometry
163  {
164  /** \brief Circulates counter-clockwise around a vertex and returns an index to the outgoing half-edge (the target). The best way to declare the circulator is to use the method pcl::geometry::MeshBase::getOutgoingHalfEdgeAroundVertexCirculator ().
165  * \tparam MeshT Mesh to which this circulator belongs to.
166  * \note The circulator can't be used to change the connectivity in the mesh (only const circulators are valid).
167  * \author Martin Saelzle
168  * \ingroup geometry
169  */
170  template <class MeshT>
172  : boost::equality_comparable <pcl::geometry::OutgoingHalfEdgeAroundVertexCirculator <MeshT>
173  , boost::unit_steppable <pcl::geometry::OutgoingHalfEdgeAroundVertexCirculator <MeshT>
174  > >
175  {
176  public:
177 
178  typedef boost::equality_comparable <pcl::geometry::OutgoingHalfEdgeAroundVertexCirculator <MeshT>
179  , boost::unit_steppable <pcl::geometry::OutgoingHalfEdgeAroundVertexCirculator <MeshT> > > Base;
181 
182  typedef MeshT Mesh;
183  typedef typename Mesh::VertexIndex VertexIndex;
184  typedef typename Mesh::HalfEdgeIndex HalfEdgeIndex;
185 
186  /** \brief Constructor resulting in an invalid circulator. */
188  : mesh_ (nullptr),
190  {
191  }
192 
193  /** \brief Construct from the vertex around which we want to circulate. */
194  OutgoingHalfEdgeAroundVertexCirculator (const VertexIndex& idx_vertex,
195  Mesh*const mesh)
196  : mesh_ (mesh),
197  idx_outgoing_half_edge_ (mesh->getOutgoingHalfEdgeIndex (idx_vertex))
198  {
199  }
200 
201  /** \brief Construct directly from the outgoing half-edge. */
202  OutgoingHalfEdgeAroundVertexCirculator (const HalfEdgeIndex& idx_outgoing_half_edge,
203  Mesh*const mesh)
204  : mesh_ (mesh),
205  idx_outgoing_half_edge_ (idx_outgoing_half_edge)
206  {
207  }
208 
209  /** \brief Check if the circulator is valid.
210  * \warning Does NOT check if the stored mesh pointer is valid. You have to ensure this yourself when constructing the circulator. */
211  inline bool
212  isValid () const
213  {
214  return (idx_outgoing_half_edge_.isValid ());
215  }
216 
217  /** \brief Comparison operators (with boost::operators): == !=
218  * \warning Does NOT check if the circulators belong to the same mesh. Please check this yourself. */
219  inline bool
220  operator == (const Self& other) const
221  {
223  }
224 
225  /** \brief Increment operators (with boost::operators): ++ (pre and post) */
226  inline Self&
228  {
229  idx_outgoing_half_edge_ = mesh_->getNextHalfEdgeIndex (mesh_->getOppositeHalfEdgeIndex (idx_outgoing_half_edge_));
230  return (*this);
231  }
232 
233  /** \brief Decrement operators (with boost::operators): -- (pre and post) */
234  inline Self&
236  {
237  idx_outgoing_half_edge_ = mesh_->getOppositeHalfEdgeIndex (mesh_->getPrevHalfEdgeIndex (idx_outgoing_half_edge_));
238  return (*this);
239  }
240 
241  /** \brief Get the index to the outgoing half-edge. */
242  inline HalfEdgeIndex
243  getTargetIndex () const
244  {
245  return (idx_outgoing_half_edge_);
246  }
247 
248  /** \brief Get the half-edge that is currently stored in the circulator. */
249  inline HalfEdgeIndex
251  {
252  return (idx_outgoing_half_edge_);
253  }
254 
255  /** \brief The mesh to which this circulator belongs to. */
256  Mesh* mesh_;
257 
258  /** \brief The outgoing half-edge of the vertex around which we want to circulate. */
259  HalfEdgeIndex idx_outgoing_half_edge_;
260  };
261  } // End namespace geometry
262 } // End namespace pcl
263 
264 ////////////////////////////////////////////////////////////////////////////////
265 // IncomingHalfEdgeAroundVertexCirculator
266 ////////////////////////////////////////////////////////////////////////////////
267 
268 namespace pcl
269 {
270  namespace geometry
271  {
272  /** \brief Circulates counter-clockwise around a vertex and returns an index to the incoming half-edge (the target). The best way to declare the circulator is to use the method pcl::geometry::MeshBase::getIncomingHalfEdgeAroundVertexCirculator ().
273  * \tparam MeshT Mesh to which this circulator belongs to.
274  * \note The circulator can't be used to change the connectivity in the mesh (only const circulators are valid).
275  * \author Martin Saelzle
276  * \ingroup geometry
277  */
278  template <class MeshT>
280  : boost::equality_comparable <pcl::geometry::IncomingHalfEdgeAroundVertexCirculator <MeshT>
281  , boost::unit_steppable <pcl::geometry::IncomingHalfEdgeAroundVertexCirculator <MeshT>
282  > >
283  {
284  public:
285 
286  typedef boost::equality_comparable <pcl::geometry::IncomingHalfEdgeAroundVertexCirculator <MeshT>
287  , boost::unit_steppable <pcl::geometry::IncomingHalfEdgeAroundVertexCirculator <MeshT> > > Base;
289 
290  typedef MeshT Mesh;
291  typedef typename Mesh::VertexIndex VertexIndex;
292  typedef typename Mesh::HalfEdgeIndex HalfEdgeIndex;
293 
294  /** \brief Constructor resulting in an invalid circulator. */
296  : mesh_ (nullptr),
297  idx_incoming_half_edge_ ()
298  {
299  }
300 
301  /** \brief Construct from the vertex around which we want to circulate. */
302  IncomingHalfEdgeAroundVertexCirculator (const VertexIndex& idx_vertex,
303  Mesh*const mesh)
304  : mesh_ (mesh),
305  idx_incoming_half_edge_ (mesh->getIncomingHalfEdgeIndex (idx_vertex))
306  {
307  }
308 
309  /** \brief Construct directly from the incoming half-edge. */
310  IncomingHalfEdgeAroundVertexCirculator (const HalfEdgeIndex& idx_incoming_half_edge,
311  Mesh*const mesh)
312  : mesh_ (mesh),
313  idx_incoming_half_edge_ (idx_incoming_half_edge)
314  {
315  }
316 
317  /** \brief Check if the circulator is valid.
318  * \warning Does NOT check if the stored mesh pointer is valid. You have to ensure this yourself when constructing the circulator. */
319  inline bool
320  isValid () const
321  {
322  return (idx_incoming_half_edge_.isValid ());
323  }
324 
325  /** \brief Comparison operators (with boost::operators): == !=
326  * \warning Does NOT check if the circulators belong to the same mesh. Please check this yourself. */
327  inline bool
328  operator == (const Self& other) const
329  {
330  return (idx_incoming_half_edge_ == other.idx_incoming_half_edge_);
331  }
332 
333  /** \brief Increment operators (with boost::operators): ++ (pre and post) */
334  inline Self&
336  {
337  idx_incoming_half_edge_ = mesh_->getOppositeHalfEdgeIndex (mesh_->getNextHalfEdgeIndex (idx_incoming_half_edge_));
338  return (*this);
339  }
340 
341  /** \brief Decrement operators (with boost::operators): -- (pre and post) */
342  inline Self&
344  {
345  idx_incoming_half_edge_ = mesh_->getPrevHalfEdgeIndex (mesh_->getOppositeHalfEdgeIndex (idx_incoming_half_edge_));
346  return (*this);
347  }
348 
349  /** \brief Get the index to the incoming half-edge. */
350  inline HalfEdgeIndex
351  getTargetIndex () const
352  {
353  return (idx_incoming_half_edge_);
354  }
355 
356  /** \brief Get the half-edge that is currently stored in the circulator. */
357  inline HalfEdgeIndex
359  {
360  return (idx_incoming_half_edge_);
361  }
362 
363  /** \brief The mesh to which this circulator belongs to. */
364  Mesh* mesh_;
365 
366  /** \brief The incoming half-edge of the vertex around which we want to circulate. */
367  HalfEdgeIndex idx_incoming_half_edge_;
368  };
369  } // End namespace geometry
370 } // End namespace pcl
371 
372 ////////////////////////////////////////////////////////////////////////////////
373 // FaceAroundVertexCirculator
374 ////////////////////////////////////////////////////////////////////////////////
375 
376 namespace pcl
377 {
378  namespace geometry
379  {
380  /** \brief Circulates counter-clockwise around a vertex and returns an index to the face of the outgoing half-edge (the target). The best way to declare the circulator is to use the method pcl::geometry::MeshBase::getFaceAroundVertexCirculator ().
381  * \tparam MeshT Mesh to which this circulator belongs to.
382  * \note The circulator can't be used to change the connectivity in the mesh (only const circulators are valid).
383  * \author Martin Saelzle
384  * \ingroup geometry
385  */
386  template <class MeshT>
388  : boost::equality_comparable <pcl::geometry::FaceAroundVertexCirculator <MeshT>
389  , boost::unit_steppable <pcl::geometry::FaceAroundVertexCirculator <MeshT>
390  > >
391  {
392  public:
393 
394  typedef boost::equality_comparable <pcl::geometry::FaceAroundVertexCirculator <MeshT>
395  , boost::unit_steppable <pcl::geometry::FaceAroundVertexCirculator <MeshT> > > Base;
397 
398  typedef MeshT Mesh;
399  typedef typename Mesh::FaceIndex FaceIndex;
400  typedef typename Mesh::VertexIndex VertexIndex;
401  typedef typename Mesh::HalfEdgeIndex HalfEdgeIndex;
402 
403  /** \brief Constructor resulting in an invalid circulator. */
405  : mesh_ (nullptr),
407  {
408  }
409 
410  /** \brief Construct from the vertex around which we want to circulate. */
411  FaceAroundVertexCirculator (const VertexIndex& idx_vertex,
412  Mesh*const mesh)
413  : mesh_ (mesh),
414  idx_outgoing_half_edge_ (mesh->getOutgoingHalfEdgeIndex (idx_vertex))
415  {
416  }
417 
418  /** \brief Construct directly from the outgoing half-edge. */
419  FaceAroundVertexCirculator (const HalfEdgeIndex& idx_outgoing_half_edge,
420  Mesh*const mesh)
421  : mesh_ (mesh),
422  idx_outgoing_half_edge_ (idx_outgoing_half_edge)
423  {
424  }
425 
426  /** \brief Check if the circulator is valid.
427  * \warning Does NOT check if the stored mesh pointer is valid. You have to ensure this yourself when constructing the circulator. */
428  inline bool
429  isValid () const
430  {
431  return (idx_outgoing_half_edge_.isValid ());
432  }
433 
434  /** \brief Comparison operators (with boost::operators): == !=
435  * \warning Does NOT check if the circulators belong to the same mesh. Please check this yourself. */
436  inline bool
437  operator == (const Self& other) const
438  {
440  }
441 
442  /** \brief Increment operators (with boost::operators): ++ (pre and post) */
443  inline Self&
445  {
446  idx_outgoing_half_edge_ = mesh_->getNextHalfEdgeIndex (mesh_->getOppositeHalfEdgeIndex (idx_outgoing_half_edge_));
447  return (*this);
448  }
449 
450  /** \brief Decrement operators (with boost::operators): -- (pre and post) */
451  inline Self&
453  {
454  idx_outgoing_half_edge_ = mesh_->getOppositeHalfEdgeIndex (mesh_->getPrevHalfEdgeIndex (idx_outgoing_half_edge_));
455  return (*this);
456  }
457 
458  /** \brief Get the index to the target face. */
459  inline FaceIndex
460  getTargetIndex () const
461  {
462  return (mesh_->getFaceIndex (idx_outgoing_half_edge_));
463  }
464 
465  /** \brief Get the half-edge that is currently stored in the circulator. */
466  inline HalfEdgeIndex
468  {
469  return (idx_outgoing_half_edge_);
470  }
471 
472  /** \brief The mesh to which this circulator belongs to. */
473  Mesh* mesh_;
474 
475  /** \brief The outgoing half-edge of the vertex around which we want to circulate. */
476  HalfEdgeIndex idx_outgoing_half_edge_;
477  };
478  } // End namespace geometry
479 } // End namespace pcl
480 
481 ////////////////////////////////////////////////////////////////////////////////
482 // VertexAroundFaceCirculator
483 ////////////////////////////////////////////////////////////////////////////////
484 
485 namespace pcl
486 {
487  namespace geometry
488  {
489  /** \brief Circulates clockwise around a face and returns an index to the terminating vertex of the inner half-edge (the target). The best way to declare the circulator is to use the method pcl::geometry::MeshBase::getVertexAroundFaceCirculator ().
490  * \tparam MeshT Mesh to which this circulator belongs to.
491  * \note The circulator can't be used to change the connectivity in the mesh (only const circulators are valid).
492  * \author Martin Saelzle
493  * \ingroup geometry
494  */
495  template <class MeshT>
497  : boost::equality_comparable <pcl::geometry::VertexAroundFaceCirculator <MeshT>
498  , boost::unit_steppable <pcl::geometry::VertexAroundFaceCirculator <MeshT>
499  > >
500  {
501  public:
502 
503  typedef boost::equality_comparable <pcl::geometry::VertexAroundFaceCirculator <MeshT>
504  , boost::unit_steppable <pcl::geometry::VertexAroundFaceCirculator <MeshT> > > Base;
506 
507  typedef MeshT Mesh;
508  typedef typename Mesh::VertexIndex VertexIndex;
509  typedef typename Mesh::FaceIndex FaceIndex;
510  typedef typename Mesh::HalfEdgeIndex HalfEdgeIndex;
511 
512  /** \brief Constructor resulting in an invalid circulator. */
514  : mesh_ (nullptr),
515  idx_inner_half_edge_ ()
516  {
517  }
518 
519  /** \brief Construct from the face around which we want to circulate. */
520  VertexAroundFaceCirculator (const FaceIndex& idx_face,
521  Mesh*const mesh)
522  : mesh_ (mesh),
523  idx_inner_half_edge_ (mesh->getInnerHalfEdgeIndex (idx_face))
524  {
525  }
526 
527  /** \brief Construct directly from the inner half-edge. */
528  VertexAroundFaceCirculator (const HalfEdgeIndex& idx_inner_half_edge,
529  Mesh*const mesh)
530  : mesh_ (mesh),
531  idx_inner_half_edge_ (idx_inner_half_edge)
532  {
533  }
534 
535  /** \brief Check if the circulator is valid.
536  * \warning Does NOT check if the stored mesh pointer is valid. You have to ensure this yourself when constructing the circulator. */
537  inline bool
538  isValid () const
539  {
540  return (idx_inner_half_edge_.isValid ());
541  }
542 
543  /** \brief Comparison operators (with boost::operators): == !=
544  * \warning Does NOT check if the circulators belong to the same mesh. Please check this yourself. */
545  inline bool
546  operator == (const Self& other) const
547  {
548  return (idx_inner_half_edge_ == other.idx_inner_half_edge_);
549  }
550 
551  /** \brief Increment operators (with boost::operators): ++ (pre and post) */
552  inline Self&
554  {
555  idx_inner_half_edge_ = mesh_->getNextHalfEdgeIndex (idx_inner_half_edge_);
556  return (*this);
557  }
558 
559  /** \brief Decrement operators (with boost::operators): -- (pre and post) */
560  inline Self&
562  {
563  idx_inner_half_edge_ = mesh_->getPrevHalfEdgeIndex (idx_inner_half_edge_);
564  return (*this);
565  }
566 
567  /** \brief Get the index to the target vertex. */
568  inline VertexIndex
569  getTargetIndex () const
570  {
571  return (mesh_->getTerminatingVertexIndex (idx_inner_half_edge_));
572  }
573 
574  /** \brief Get the half-edge that is currently stored in the circulator. */
575  inline HalfEdgeIndex
577  {
578  return (idx_inner_half_edge_);
579  }
580 
581  /** \brief The mesh to which this circulator belongs to. */
582  Mesh* mesh_;
583 
584  /** \brief The inner half-edge of the face around which we want to circulate. */
585  HalfEdgeIndex idx_inner_half_edge_;
586  };
587  } // End namespace geometry
588 } // End namespace pcl
589 
590 ////////////////////////////////////////////////////////////////////////////////
591 // InnerHalfEdgeAroundFaceCirculator
592 ////////////////////////////////////////////////////////////////////////////////
593 
594 namespace pcl
595 {
596  namespace geometry
597  {
598  /** \brief Circulates clockwise around a face and returns an index to the inner half-edge (the target). The best way to declare the circulator is to use the method pcl::geometry::MeshBase::getInnerHalfEdgeAroundFaceCirculator ().
599  * \tparam MeshT Mesh to which this circulator belongs to.
600  * \note The circulator can't be used to change the connectivity in the mesh (only const circulators are valid).
601  * \author Martin Saelzle
602  * \ingroup geometry
603  */
604  template <class MeshT>
606  : boost::equality_comparable <pcl::geometry::InnerHalfEdgeAroundFaceCirculator <MeshT>
607  , boost::unit_steppable <pcl::geometry::InnerHalfEdgeAroundFaceCirculator <MeshT>
608  > >
609  {
610  public:
611 
612  typedef boost::equality_comparable <pcl::geometry::InnerHalfEdgeAroundFaceCirculator <MeshT>
613  , boost::unit_steppable <pcl::geometry::InnerHalfEdgeAroundFaceCirculator <MeshT> > > Base;
615 
616  typedef MeshT Mesh;
617  typedef typename Mesh::FaceIndex FaceIndex;
618  typedef typename Mesh::HalfEdgeIndex HalfEdgeIndex;
619 
620  /** \brief Constructor resulting in an invalid circulator. */
622  : mesh_ (nullptr),
623  idx_inner_half_edge_ ()
624  {
625  }
626 
627  /** \brief Construct from the face around which we want to circulate. */
628  InnerHalfEdgeAroundFaceCirculator (const FaceIndex& idx_face,
629  Mesh*const mesh)
630  : mesh_ (mesh),
631  idx_inner_half_edge_ (mesh->getInnerHalfEdgeIndex (idx_face))
632  {
633  }
634 
635  /** \brief Construct directly from the inner half-edge. */
636  InnerHalfEdgeAroundFaceCirculator (const HalfEdgeIndex& idx_inner_half_edge,
637  Mesh*const mesh)
638  : mesh_ (mesh),
639  idx_inner_half_edge_ (idx_inner_half_edge)
640  {
641  }
642 
643  /** \brief Check if the circulator is valid.
644  * \warning Does NOT check if the stored mesh pointer is valid. You have to ensure this yourself when constructing the circulator. */
645  inline bool
646  isValid () const
647  {
648  return (idx_inner_half_edge_.isValid ());
649  }
650 
651  /** \brief Comparison operators (with boost::operators): == !=
652  * \warning Does NOT check if the circulators belong to the same mesh. Please check this yourself. */
653  inline bool
654  operator == (const Self& other) const
655  {
656  return (idx_inner_half_edge_ == other.idx_inner_half_edge_);
657  }
658 
659  /** \brief Increment operators (with boost::operators): ++ (pre and post) */
660  inline Self&
662  {
663  idx_inner_half_edge_ = mesh_->getNextHalfEdgeIndex (idx_inner_half_edge_);
664  return (*this);
665  }
666 
667  /** \brief Decrement operators (with boost::operators): -- (pre and post) */
668  inline Self&
670  {
671  idx_inner_half_edge_ = mesh_->getPrevHalfEdgeIndex (idx_inner_half_edge_);
672  return (*this);
673  }
674 
675  /** \brief Get the index to the inner half-edge. */
676  inline HalfEdgeIndex
677  getTargetIndex () const
678  {
679  return (idx_inner_half_edge_);
680  }
681 
682  /** \brief Get the half-edge that is currently stored in the circulator. */
683  inline HalfEdgeIndex
685  {
686  return (idx_inner_half_edge_);
687  }
688 
689  /** \brief The mesh to which this circulator belongs to. */
690  Mesh* mesh_;
691 
692  /** \brief The inner half-edge of the face around which we want to circulate. */
693  HalfEdgeIndex idx_inner_half_edge_;
694  };
695  } // End namespace geometry
696 } // End namespace pcl
697 
698 ////////////////////////////////////////////////////////////////////////////////
699 // OuterHalfEdgeAroundFaceCirculator
700 ////////////////////////////////////////////////////////////////////////////////
701 
702 namespace pcl
703 {
704  namespace geometry
705  {
706  /** \brief Circulates clockwise around a face and returns an index to the outer half-edge (the target). The best way to declare the circulator is to use the method pcl::geometry::MeshBase::getOuterHalfEdgeAroundFaceCirculator ().
707  * \tparam MeshT Mesh to which this circulator belongs to.
708  * \note The circulator can't be used to change the connectivity in the mesh (only const circulators are valid).
709  * \author Martin Saelzle
710  * \ingroup geometry
711  */
712  template <class MeshT>
714  : boost::equality_comparable <pcl::geometry::OuterHalfEdgeAroundFaceCirculator <MeshT>
715  , boost::unit_steppable <pcl::geometry::OuterHalfEdgeAroundFaceCirculator <MeshT>
716  > >
717  {
718  public:
719 
720  typedef boost::equality_comparable <pcl::geometry::OuterHalfEdgeAroundFaceCirculator <MeshT>
721  , boost::unit_steppable <pcl::geometry::OuterHalfEdgeAroundFaceCirculator <MeshT> > > Base;
723 
724  typedef MeshT Mesh;
725  typedef typename Mesh::FaceIndex FaceIndex;
726  typedef typename Mesh::HalfEdgeIndex HalfEdgeIndex;
727 
728  /** \brief Constructor resulting in an invalid circulator. */
730  : mesh_ (nullptr),
731  idx_inner_half_edge_ ()
732  {
733  }
734 
735  /** \brief Construct from the face around which we want to circulate. */
736  OuterHalfEdgeAroundFaceCirculator (const FaceIndex& idx_face,
737  Mesh*const mesh)
738  : mesh_ (mesh),
739  idx_inner_half_edge_ (mesh->getInnerHalfEdgeIndex (idx_face))
740  {
741  }
742 
743  /** \brief Construct directly from the inner half-edge. */
744  OuterHalfEdgeAroundFaceCirculator (const HalfEdgeIndex& idx_inner_half_edge,
745  Mesh*const mesh)
746  : mesh_ (mesh),
747  idx_inner_half_edge_ (idx_inner_half_edge)
748  {
749  }
750 
751  /** \brief Check if the circulator is valid.
752  * \warning Does NOT check if the stored mesh pointer is valid. You have to ensure this yourself when constructing the circulator. */
753  inline bool
754  isValid () const
755  {
756  return (idx_inner_half_edge_.isValid ());
757  }
758 
759  /** \brief Comparison operators (with boost::operators): == !=
760  * \warning Does NOT check if the circulators belong to the same mesh. Please check this yourself. */
761  inline bool
762  operator == (const Self& other) const
763  {
764  return (idx_inner_half_edge_ == other.idx_inner_half_edge_);
765  }
766 
767  /** \brief Increment operators (with boost::operators): ++ (pre and post) */
768  inline Self&
770  {
771  idx_inner_half_edge_ = mesh_->getNextHalfEdgeIndex (idx_inner_half_edge_);
772  return (*this);
773  }
774 
775  /** \brief Decrement operators (with boost::operators): -- (pre and post) */
776  inline Self&
778  {
779  idx_inner_half_edge_ = mesh_->getPrevHalfEdgeIndex (idx_inner_half_edge_);
780  return (*this);
781  }
782 
783  /** \brief Get the index to the outer half-edge. */
784  inline HalfEdgeIndex
785  getTargetIndex () const
786  {
787  return (mesh_->getOppositeHalfEdgeIndex (idx_inner_half_edge_));
788  }
789 
790  /** \brief Get the half-edge that is currently stored in the circulator. */
791  inline HalfEdgeIndex
793  {
794  return (idx_inner_half_edge_);
795  }
796 
797  /** \brief The mesh to which this circulator belongs to. */
798  Mesh* mesh_;
799 
800  /** \brief The inner half-edge of the face around which we want to circulate. */
801  HalfEdgeIndex idx_inner_half_edge_;
802  };
803  } // End namespace geometry
804 } // End namespace pcl
805 
806 ////////////////////////////////////////////////////////////////////////////////
807 // FaceAroundFaceCirculator
808 ////////////////////////////////////////////////////////////////////////////////
809 
810 namespace pcl
811 {
812  namespace geometry
813  {
814  /** \brief Circulates clockwise around a face and returns an index to the face of the outer half-edge (the target). The best way to declare the circulator is to use the method pcl::geometry::MeshBase::getFaceAroundFaceCirculator ().
815  * \tparam MeshT Mesh to which this circulator belongs to.
816  * \note The circulator can't be used to change the connectivity in the mesh (only const circulators are valid).
817  * \author Martin Saelzle
818  * \ingroup geometry
819  */
820  template <class MeshT>
822  : boost::equality_comparable <pcl::geometry::FaceAroundFaceCirculator <MeshT>
823  , boost::unit_steppable <pcl::geometry::FaceAroundFaceCirculator <MeshT>
824  > >
825  {
826  public:
827 
828  typedef boost::equality_comparable <pcl::geometry::FaceAroundFaceCirculator <MeshT>
829  , boost::unit_steppable <pcl::geometry::FaceAroundFaceCirculator <MeshT> > > Base;
831 
832  typedef MeshT Mesh;
833  typedef typename Mesh::FaceIndex FaceIndex;
834  typedef typename Mesh::HalfEdgeIndex HalfEdgeIndex;
835 
836  /** \brief Constructor resulting in an invalid circulator. */
838  : mesh_ (nullptr),
839  idx_inner_half_edge_ ()
840  {
841  }
842 
843  /** \brief Construct from the face around which we want to circulate. */
844  FaceAroundFaceCirculator (const FaceIndex& idx_face,
845  Mesh*const mesh)
846  : mesh_ (mesh),
847  idx_inner_half_edge_ (mesh->getInnerHalfEdgeIndex (idx_face))
848  {
849  }
850 
851  /** \brief Construct directly from the inner half-edge. */
852  FaceAroundFaceCirculator (const HalfEdgeIndex& idx_inner_half_edge,
853  Mesh*const mesh)
854  : mesh_ (mesh),
855  idx_inner_half_edge_ (idx_inner_half_edge)
856  {
857  }
858 
859  /** \brief Check if the circulator is valid.
860  * \warning Does NOT check if the stored mesh pointer is valid. You have to ensure this yourself when constructing the circulator. */
861  inline bool
862  isValid () const
863  {
864  return (idx_inner_half_edge_.isValid ());
865  }
866 
867  /** \brief Comparison operators (with boost::operators): == !=
868  * \warning Does NOT check if the circulators belong to the same mesh. Please check this yourself. */
869  inline bool
870  operator == (const Self& other) const
871  {
872  return (idx_inner_half_edge_ == other.idx_inner_half_edge_);
873  }
874 
875  /** \brief Increment operators (with boost::operators): ++ (pre and post) */
876  inline Self&
878  {
879  idx_inner_half_edge_ = mesh_->getNextHalfEdgeIndex (idx_inner_half_edge_);
880  return (*this);
881  }
882 
883  /** \brief Decrement operators (with boost::operators): -- (pre and post) */
884  inline Self&
886  {
887  idx_inner_half_edge_ = mesh_->getPrevHalfEdgeIndex (idx_inner_half_edge_);
888  return (*this);
889  }
890 
891  /** \brief Get the index to the target face. */
892  inline FaceIndex
893  getTargetIndex () const
894  {
895  return (mesh_->getOppositeFaceIndex (idx_inner_half_edge_));
896  }
897 
898  /** \brief Get the half-edge that is currently stored in the circulator. */
899  inline HalfEdgeIndex
901  {
902  return (idx_inner_half_edge_);
903  }
904 
905  /** \brief The mesh to which this circulator belongs to. */
906  Mesh* mesh_;
907 
908  /** \brief The inner half-edge of the face around which we want to circulate. */
909  HalfEdgeIndex idx_inner_half_edge_;
910  };
911  } // End namespace geometry
912 } // End namespace pcl
boost::equality_comparable< pcl::geometry::OutgoingHalfEdgeAroundVertexCirculator< MeshT >, boost::unit_steppable< pcl::geometry::OutgoingHalfEdgeAroundVertexCirculator< MeshT > > > Base
bool isValid() const
Check if the circulator is valid.
HalfEdgeIndex getCurrentHalfEdgeIndex() const
Get the half-edge that is currently stored in the circulator.
HalfEdgeIndex idx_inner_half_edge_
The inner half-edge of the face around which we want to circulate.
FaceAroundVertexCirculator(const VertexIndex &idx_vertex, Mesh *const mesh)
Construct from the vertex around which we want to circulate.
Self & operator--()
Decrement operators (with boost::operators): – (pre and post)
boost::equality_comparable< pcl::geometry::FaceAroundFaceCirculator< MeshT >, boost::unit_steppable< pcl::geometry::FaceAroundFaceCirculator< MeshT > > > Base
This file defines compatibility wrappers for low level I/O functions.
Definition: convolution.h:44
HalfEdgeIndex idx_incoming_half_edge_
The incoming half-edge of the vertex around which we want to circulate.
HalfEdgeIndex idx_inner_half_edge_
The inner half-edge of the face around which we want to circulate.
bool isValid() const
Check if the circulator is valid.
Circulates clockwise around a face and returns an index to the face of the outer half-edge (the targe...
Circulates counter-clockwise around a vertex and returns an index to the incoming half-edge (the targ...
OutgoingHalfEdgeAroundVertexCirculator(const VertexIndex &idx_vertex, Mesh *const mesh)
Construct from the vertex around which we want to circulate.
HalfEdgeIndex getCurrentHalfEdgeIndex() const
Get the half-edge that is currently stored in the circulator.
FaceIndex getTargetIndex() const
Get the index to the target face.
VertexIndex getTargetIndex() const
Get the index to the target vertex.
HalfEdgeIndex getCurrentHalfEdgeIndex() const
Get the half-edge that is currently stored in the circulator.
Mesh * mesh_
The mesh to which this circulator belongs to.
FaceIndex getTargetIndex() const
Get the index to the target face.
Mesh * mesh_
The mesh to which this circulator belongs to.
IncomingHalfEdgeAroundVertexCirculator(const HalfEdgeIndex &idx_incoming_half_edge, Mesh *const mesh)
Construct directly from the incoming half-edge.
pcl::geometry::VertexAroundFaceCirculator< MeshT > Self
bool isValid() const
Check if the circulator is valid.
VertexAroundFaceCirculator(const HalfEdgeIndex &idx_inner_half_edge, Mesh *const mesh)
Construct directly from the inner half-edge.
Mesh * mesh_
The mesh to which this circulator belongs to.
VertexAroundVertexCirculator(const VertexIndex &idx_vertex, Mesh *const mesh)
Construct from the vertex around which we want to circulate.
OutgoingHalfEdgeAroundVertexCirculator(const HalfEdgeIndex &idx_outgoing_half_edge, Mesh *const mesh)
Construct directly from the outgoing half-edge.
OuterHalfEdgeAroundFaceCirculator(const FaceIndex &idx_face, Mesh *const mesh)
Construct from the face around which we want to circulate.
Mesh * mesh_
The mesh to which this circulator belongs to.
InnerHalfEdgeAroundFaceCirculator(const HalfEdgeIndex &idx_inner_half_edge, Mesh *const mesh)
Construct directly from the inner half-edge.
HalfEdgeIndex idx_inner_half_edge_
The inner half-edge of the face around which we want to circulate.
FaceAroundFaceCirculator()
Constructor resulting in an invalid circulator.
Circulates counter-clockwise around a vertex and returns an index to the terminating vertex of the ou...
HalfEdgeIndex getCurrentHalfEdgeIndex() const
Get the half-edge that is currently stored in the circulator.
Mesh * mesh_
The mesh to which this circulator belongs to.
VertexIndex getTargetIndex() const
Get the index to the target vertex.
boost::equality_comparable< pcl::geometry::OuterHalfEdgeAroundFaceCirculator< MeshT >, boost::unit_steppable< pcl::geometry::OuterHalfEdgeAroundFaceCirculator< MeshT > > > Base
Circulates clockwise around a face and returns an index to the terminating vertex of the inner half-e...
pcl::geometry::FaceAroundVertexCirculator< MeshT > Self
boost::equality_comparable< pcl::geometry::VertexAroundFaceCirculator< MeshT >, boost::unit_steppable< pcl::geometry::VertexAroundFaceCirculator< MeshT > > > Base
HalfEdgeIndex idx_outgoing_half_edge_
The outgoing half-edge of the vertex around which we want to circulate.
Mesh * mesh_
The mesh to which this circulator belongs to.
HalfEdgeIndex idx_inner_half_edge_
The inner half-edge of the face around which we want to circulate.
pcl::geometry::FaceAroundFaceCirculator< MeshT > Self
Self & operator++()
Increment operators (with boost::operators): ++ (pre and post)
boost::equality_comparable< pcl::geometry::FaceAroundVertexCirculator< MeshT >, boost::unit_steppable< pcl::geometry::FaceAroundVertexCirculator< MeshT > > > Base
Circulates counter-clockwise around a vertex and returns an index to the outgoing half-edge (the targ...
pcl::geometry::VertexAroundVertexCirculator< MeshT > Self
bool isValid() const
Check if the circulator is valid.
HalfEdgeIndex getCurrentHalfEdgeIndex() const
Get the half-edge that is currently stored in the circulator.
boost::equality_comparable< pcl::geometry::VertexAroundVertexCirculator< MeshT >, boost::unit_steppable< pcl::geometry::VertexAroundVertexCirculator< MeshT > > > Base
pcl::geometry::InnerHalfEdgeAroundFaceCirculator< MeshT > Self
VertexAroundFaceCirculator(const FaceIndex &idx_face, Mesh *const mesh)
Construct from the face around which we want to circulate.
bool isValid() const
Check if the circulator is valid.
HalfEdgeIndex getTargetIndex() const
Get the index to the inner half-edge.
boost::equality_comparable< pcl::geometry::InnerHalfEdgeAroundFaceCirculator< MeshT >, boost::unit_steppable< pcl::geometry::InnerHalfEdgeAroundFaceCirculator< MeshT > > > Base
HalfEdgeIndex getCurrentHalfEdgeIndex() const
Get the half-edge that is currently stored in the circulator.
OuterHalfEdgeAroundFaceCirculator()
Constructor resulting in an invalid circulator.
HalfEdgeIndex getTargetIndex() const
Get the index to the outer half-edge.
InnerHalfEdgeAroundFaceCirculator(const FaceIndex &idx_face, Mesh *const mesh)
Construct from the face around which we want to circulate.
VertexAroundVertexCirculator()
Constructor resulting in an invalid circulator.
pcl::geometry::OuterHalfEdgeAroundFaceCirculator< MeshT > Self
InnerHalfEdgeAroundFaceCirculator()
Constructor resulting in an invalid circulator.
HalfEdgeIndex getCurrentHalfEdgeIndex() const
Get the half-edge that is currently stored in the circulator.
FaceAroundFaceCirculator(const HalfEdgeIndex &idx_inner_half_edge, Mesh *const mesh)
Construct directly from the inner half-edge.
Mesh * mesh_
The mesh to which this circulator belongs to.
bool isValid() const
Check if the circulator is valid.
pcl::geometry::OutgoingHalfEdgeAroundVertexCirculator< MeshT > Self
Mesh * mesh_
The mesh to which this circulator belongs to.
Circulates clockwise around a face and returns an index to the inner half-edge (the target)...
bool isValid() const
Check if the circulator is valid.
VertexAroundFaceCirculator()
Constructor resulting in an invalid circulator.
HalfEdgeIndex idx_outgoing_half_edge_
The outgoing half-edge of the vertex around which we want to circulate.
Circulates clockwise around a face and returns an index to the outer half-edge (the target)...
Circulates counter-clockwise around a vertex and returns an index to the face of the outgoing half-ed...
FaceAroundFaceCirculator(const FaceIndex &idx_face, Mesh *const mesh)
Construct from the face around which we want to circulate.
boost::equality_comparable< pcl::geometry::IncomingHalfEdgeAroundVertexCirculator< MeshT >, boost::unit_steppable< pcl::geometry::IncomingHalfEdgeAroundVertexCirculator< MeshT > > > Base
FaceAroundVertexCirculator(const HalfEdgeIndex &idx_outgoing_half_edge, Mesh *const mesh)
Construct directly from the outgoing half-edge.
IncomingHalfEdgeAroundVertexCirculator(const VertexIndex &idx_vertex, Mesh *const mesh)
Construct from the vertex around which we want to circulate.
HalfEdgeIndex getCurrentHalfEdgeIndex() const
Get the half-edge that is currently stored in the circulator.
IncomingHalfEdgeAroundVertexCirculator()
Constructor resulting in an invalid circulator.
OuterHalfEdgeAroundFaceCirculator(const HalfEdgeIndex &idx_inner_half_edge, Mesh *const mesh)
Construct directly from the inner half-edge.
bool operator==(const Self &other) const
Comparison operators (with boost::operators): == !=.
pcl::geometry::IncomingHalfEdgeAroundVertexCirculator< MeshT > Self
HalfEdgeIndex idx_outgoing_half_edge_
The outgoing half-edge of the vertex around which we want to circulate.
HalfEdgeIndex getTargetIndex() const
Get the index to the incoming half-edge.
OutgoingHalfEdgeAroundVertexCirculator()
Constructor resulting in an invalid circulator.
HalfEdgeIndex getTargetIndex() const
Get the index to the outgoing half-edge.
FaceAroundVertexCirculator()
Constructor resulting in an invalid circulator.
VertexAroundVertexCirculator(const HalfEdgeIndex &idx_outgoing_half_edge, Mesh *const mesh)
Construct directly from the outgoing half-edge.
bool isValid() const
Check if the circulator is valid.