Developer Documentation
ArrayKernel.hh
1 /* ========================================================================= *
2  * *
3  * OpenMesh *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openmesh.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenMesh. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39  * *
40  * ========================================================================= */
41 
42 
43 
44 
45 //=============================================================================
46 //
47 // CLASS ArrayKernel
48 //
49 //=============================================================================
50 
51 
52 #ifndef OPENMESH_ARRAY_KERNEL_HH
53 #define OPENMESH_ARRAY_KERNEL_HH
54 
55 
56 //== INCLUDES =================================================================
57 #include <vector>
58 
60 #include <OpenMesh/Core/Utils/GenProg.hh>
61 
62 #include <OpenMesh/Core/Mesh/ArrayItems.hh>
63 #include <OpenMesh/Core/Mesh/BaseKernel.hh>
64 #include <OpenMesh/Core/Mesh/Status.hh>
65 
66 //== NAMESPACES ===============================================================
67 namespace OpenMesh {
68 
69 
70 //== CLASS DEFINITION =========================================================
87 class OPENMESHDLLEXPORT ArrayKernel : public BaseKernel, public ArrayItems
88 {
89 public:
90 
91  // handles
101 
102 public:
103 
104  // --- constructor/destructor ---
105  ArrayKernel();
106  virtual ~ArrayKernel();
107 
114  void assign_connectivity(const ArrayKernel& _other);
115 
116  // --- handle -> item ---
117  VertexHandle handle(const Vertex& _v) const;
118 
119  HalfedgeHandle handle(const Halfedge& _he) const;
120 
121  EdgeHandle handle(const Edge& _e) const;
122 
123  FaceHandle handle(const Face& _f) const;
124 
125 
127  bool is_valid_handle(VertexHandle _vh) const;
128 
130  bool is_valid_handle(HalfedgeHandle _heh) const;
131 
133  bool is_valid_handle(EdgeHandle _eh) const;
134 
136  bool is_valid_handle(FaceHandle _fh) const;
137 
138 
139  // --- item -> handle ---
140  const Vertex& vertex(VertexHandle _vh) const
141  {
142  assert(is_valid_handle(_vh));
143  return vertices_[_vh.idx()];
144  }
145 
146  Vertex& vertex(VertexHandle _vh)
147  {
148  assert(is_valid_handle(_vh));
149  return vertices_[_vh.idx()];
150  }
151 
152  const Halfedge& halfedge(HalfedgeHandle _heh) const
153  {
154  assert(is_valid_handle(_heh));
155  return edges_[_heh.idx() >> 1].halfedges_[_heh.idx() & 1];
156  }
157 
158  Halfedge& halfedge(HalfedgeHandle _heh)
159  {
160  assert(is_valid_handle(_heh));
161  return edges_[_heh.idx() >> 1].halfedges_[_heh.idx() & 1];
162  }
163 
164  const Edge& edge(EdgeHandle _eh) const
165  {
166  assert(is_valid_handle(_eh));
167  return edges_[_eh.idx()];
168  }
169 
170  Edge& edge(EdgeHandle _eh)
171  {
172  assert(is_valid_handle(_eh));
173  return edges_[_eh.idx()];
174  }
175 
176  const Face& face(FaceHandle _fh) const
177  {
178  assert(is_valid_handle(_fh));
179  return faces_[_fh.idx()];
180  }
181 
182  Face& face(FaceHandle _fh)
183  {
184  assert(is_valid_handle(_fh));
185  return faces_[_fh.idx()];
186  }
187 
188  // --- get i'th items ---
189 
190  VertexHandle vertex_handle(unsigned int _i) const
191  { return (_i < n_vertices()) ? handle( vertices_[_i] ) : VertexHandle(); }
192 
193  HalfedgeHandle halfedge_handle(unsigned int _i) const
194  {
195  return (_i < n_halfedges()) ?
196  halfedge_handle(edge_handle(_i/2), _i%2) : HalfedgeHandle();
197  }
198 
199  EdgeHandle edge_handle(unsigned int _i) const
200  { return (_i < n_edges()) ? handle(edges_[_i]) : EdgeHandle(); }
201 
202  FaceHandle face_handle(unsigned int _i) const
203  { return (_i < n_faces()) ? handle(faces_[_i]) : FaceHandle(); }
204 
205 public:
206 
216  inline VertexHandle new_vertex()
217  {
218  vertices_.push_back(Vertex());
219  vprops_resize(n_vertices());//TODO:should it be push_back()?
220 
221  return handle(vertices_.back());
222  }
223 
234  inline VertexHandle new_vertex_dirty()
235  {
236  vertices_.push_back(Vertex());
237  vprops_resize_if_smaller(n_vertices());//TODO:should it be push_back()?
238 
239  return handle(vertices_.back());
240  }
241 
242  inline HalfedgeHandle new_edge(VertexHandle _start_vh, VertexHandle _end_vh)
243  {
244 // assert(_start_vh != _end_vh);
245  edges_.push_back(Edge());
246  eprops_resize(n_edges());//TODO:should it be push_back()?
247  hprops_resize(n_halfedges());//TODO:should it be push_back()?
248 
249  EdgeHandle eh(handle(edges_.back()));
250  HalfedgeHandle heh0(halfedge_handle(eh, 0));
251  HalfedgeHandle heh1(halfedge_handle(eh, 1));
252  set_vertex_handle(heh0, _end_vh);
253  set_vertex_handle(heh1, _start_vh);
254  return heh0;
255  }
256 
257  inline FaceHandle new_face()
258  {
259  faces_.push_back(Face());
260  fprops_resize(n_faces());
261  return handle(faces_.back());
262  }
263 
264  inline FaceHandle new_face(const Face& _f)
265  {
266  faces_.push_back(_f);
267  fprops_resize(n_faces());
268  return handle(faces_.back());
269  }
270 
271 public:
272  // --- resize/reserve ---
273  void resize( size_t _n_vertices, size_t _n_edges, size_t _n_faces );
274  void reserve(size_t _n_vertices, size_t _n_edges, size_t _n_faces );
275 
276  // --- deletion ---
292  void garbage_collection(bool _v=true, bool _e=true, bool _f=true);
293 
311  template<typename std_API_Container_VHandlePointer,
312  typename std_API_Container_HHandlePointer,
313  typename std_API_Container_FHandlePointer>
314  void garbage_collection(std_API_Container_VHandlePointer& vh_to_update,
315  std_API_Container_HHandlePointer& hh_to_update,
316  std_API_Container_FHandlePointer& fh_to_update,
317  bool _v=true, bool _e=true, bool _f=true);
318 
320  void clear();
321 
331  void clean();
332 
340  void clean_keep_reservation();
341 
342  // --- number of items ---
343  size_t n_vertices() const override { return vertices_.size(); }
344  size_t n_halfedges() const override { return 2*edges_.size(); }
345  size_t n_edges() const override { return edges_.size(); }
346  size_t n_faces() const override { return faces_.size(); }
347 
348  bool vertices_empty() const { return vertices_.empty(); }
349  bool halfedges_empty() const { return edges_.empty(); }
350  bool edges_empty() const { return edges_.empty(); }
351  bool faces_empty() const { return faces_.empty(); }
352 
353  // --- vertex connectivity ---
354 
355  HalfedgeHandle halfedge_handle(VertexHandle _vh) const
356  { return vertex(_vh).halfedge_handle_; }
357 
358  void set_halfedge_handle(VertexHandle _vh, HalfedgeHandle _heh)
359  {
360 // assert(is_valid_handle(_heh));
361  vertex(_vh).halfedge_handle_ = _heh;
362  }
363 
364  bool is_isolated(VertexHandle _vh) const
365  { return !halfedge_handle(_vh).is_valid(); }
366 
367  void set_isolated(VertexHandle _vh)
368  { vertex(_vh).halfedge_handle_.invalidate(); }
369 
370  unsigned int delete_isolated_vertices();
371 
372  // --- halfedge connectivity ---
373  VertexHandle to_vertex_handle(HalfedgeHandle _heh) const
374  { return halfedge(_heh).vertex_handle_; }
375 
376  VertexHandle from_vertex_handle(HalfedgeHandle _heh) const
377  { return to_vertex_handle(opposite_halfedge_handle(_heh)); }
378 
379  void set_vertex_handle(HalfedgeHandle _heh, VertexHandle _vh)
380  {
381 // assert(is_valid_handle(_vh));
382  halfedge(_heh).vertex_handle_ = _vh;
383  }
384 
385  FaceHandle face_handle(HalfedgeHandle _heh) const
386  { return halfedge(_heh).face_handle_; }
387 
388  void set_face_handle(HalfedgeHandle _heh, FaceHandle _fh)
389  {
390 // assert(is_valid_handle(_fh));
391  halfedge(_heh).face_handle_ = _fh;
392  }
393 
394  void set_boundary(HalfedgeHandle _heh)
395  { halfedge(_heh).face_handle_.invalidate(); }
396 
398  bool is_boundary(HalfedgeHandle _heh) const
399  { return !face_handle(_heh).is_valid(); }
400 
401  HalfedgeHandle next_halfedge_handle(HalfedgeHandle _heh) const
402  { return halfedge(_heh).next_halfedge_handle_; }
403 
404  void set_next_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _nheh)
405  {
406  assert(is_valid_handle(_nheh));
407 // assert(to_vertex_handle(_heh) == from_vertex_handle(_nheh));
408  halfedge(_heh).next_halfedge_handle_ = _nheh;
409  set_prev_halfedge_handle(_nheh, _heh);
410  }
411 
412 
413  void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh)
414  {
415  assert(is_valid_handle(_pheh));
416  set_prev_halfedge_handle(_heh, _pheh, HasPrevHalfedge());
417  }
418 
419  void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh,
420  GenProg::TrueType)
421  { halfedge(_heh).prev_halfedge_handle_ = _pheh; }
422 
423  void set_prev_halfedge_handle(HalfedgeHandle /* _heh */, HalfedgeHandle /* _pheh */,
424  GenProg::FalseType)
425  {}
426 
427  HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh) const
428  { return prev_halfedge_handle(_heh, HasPrevHalfedge() ); }
429 
430  HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::TrueType) const
431  { return halfedge(_heh).prev_halfedge_handle_; }
432 
433  HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::FalseType) const
434  {
435  if (is_boundary(_heh))
436  {//iterating around the vertex should be faster than iterating the boundary
437  HalfedgeHandle curr_heh(opposite_halfedge_handle(_heh));
438  HalfedgeHandle next_heh(next_halfedge_handle(curr_heh));
439  do
440  {
441  curr_heh = opposite_halfedge_handle(next_heh);
442  next_heh = next_halfedge_handle(curr_heh);
443  }
444  while (next_heh != _heh);
445  return curr_heh;
446  }
447  else
448  {
449  HalfedgeHandle heh(_heh);
450  HalfedgeHandle next_heh(next_halfedge_handle(heh));
451  while (next_heh != _heh) {
452  heh = next_heh;
453  next_heh = next_halfedge_handle(next_heh);
454  }
455  return heh;
456  }
457  }
458 
459 
460  HalfedgeHandle opposite_halfedge_handle(HalfedgeHandle _heh) const
461  { return HalfedgeHandle(_heh.idx() ^ 1); }
462 
463 
464  HalfedgeHandle ccw_rotated_halfedge_handle(HalfedgeHandle _heh) const
465  { return opposite_halfedge_handle(prev_halfedge_handle(_heh)); }
466 
467 
468  HalfedgeHandle cw_rotated_halfedge_handle(HalfedgeHandle _heh) const
469  { return next_halfedge_handle(opposite_halfedge_handle(_heh)); }
470 
471  // --- edge connectivity ---
472  static HalfedgeHandle s_halfedge_handle(EdgeHandle _eh, unsigned int _i)
473  {
474  assert(_i<=1);
475  return HalfedgeHandle((_eh.idx() << 1) + _i);
476  }
477 
478  static EdgeHandle s_edge_handle(HalfedgeHandle _heh)
479  { return EdgeHandle(_heh.idx() >> 1); }
480 
481  HalfedgeHandle halfedge_handle(EdgeHandle _eh, unsigned int _i) const
482  {
483  return s_halfedge_handle(_eh, _i);
484  }
485 
486  EdgeHandle edge_handle(HalfedgeHandle _heh) const
487  { return s_edge_handle(_heh); }
488 
489  // --- face connectivity ---
490  HalfedgeHandle halfedge_handle(FaceHandle _fh) const
491  { return face(_fh).halfedge_handle_; }
492 
493  void set_halfedge_handle(FaceHandle _fh, HalfedgeHandle _heh)
494  {
495 // assert(is_valid_handle(_heh));
496  face(_fh).halfedge_handle_ = _heh;
497  }
498 
500  //------------------------------------------------------------ vertex status
501  const StatusInfo& status(VertexHandle _vh) const
502  { return property(vertex_status_, _vh); }
503 
504  StatusInfo& status(VertexHandle _vh)
505  { return property(vertex_status_, _vh); }
506 
511  void reset_status() {
512  PropertyT<StatusInfo> &status_prop = property(vertex_status_);
513  PropertyT<StatusInfo>::vector_type &sprop_v = status_prop.data_vector();
514  std::fill(sprop_v.begin(), sprop_v.begin() + n_vertices(), StatusInfo());
515  }
516 
517  //----------------------------------------------------------- halfedge status
518  const StatusInfo& status(HalfedgeHandle _hh) const
519  { return property(halfedge_status_, _hh); }
520 
521  StatusInfo& status(HalfedgeHandle _hh)
522  { return property(halfedge_status_, _hh); }
523 
524  //--------------------------------------------------------------- edge status
525  const StatusInfo& status(EdgeHandle _eh) const
526  { return property(edge_status_, _eh); }
527 
528  StatusInfo& status(EdgeHandle _eh)
529  { return property(edge_status_, _eh); }
530 
531  //--------------------------------------------------------------- face status
532  const StatusInfo& status(FaceHandle _fh) const
533  { return property(face_status_, _fh); }
534 
535  StatusInfo& status(FaceHandle _fh)
536  { return property(face_status_, _fh); }
537 
538  inline bool has_vertex_status() const
539  { return vertex_status_.is_valid(); }
540 
541  inline bool has_halfedge_status() const
542  { return halfedge_status_.is_valid(); }
543 
544  inline bool has_edge_status() const
545  { return edge_status_.is_valid(); }
546 
547  inline bool has_face_status() const
548  { return face_status_.is_valid(); }
549 
550  inline VertexStatusPropertyHandle vertex_status_pph() const
551  { return vertex_status_; }
552 
553  inline HalfedgeStatusPropertyHandle halfedge_status_pph() const
554  { return halfedge_status_; }
555 
556  inline EdgeStatusPropertyHandle edge_status_pph() const
557  { return edge_status_; }
558 
559  inline FaceStatusPropertyHandle face_status_pph() const
560  { return face_status_; }
561 
563  inline VertexStatusPropertyHandle status_pph(VertexHandle /*_hnd*/) const
564  { return vertex_status_pph(); }
565 
566  inline HalfedgeStatusPropertyHandle status_pph(HalfedgeHandle /*_hnd*/) const
567  { return halfedge_status_pph(); }
568 
569  inline EdgeStatusPropertyHandle status_pph(EdgeHandle /*_hnd*/) const
570  { return edge_status_pph(); }
571 
572  inline FaceStatusPropertyHandle status_pph(FaceHandle /*_hnd*/) const
573  { return face_status_pph(); }
574 
577  {
578  if (!refcount_vstatus_++)
579  add_property( vertex_status_, "v:status" );
580  }
581 
582  void request_halfedge_status()
583  {
584  if (!refcount_hstatus_++)
585  add_property( halfedge_status_, "h:status" );
586  }
587 
588  void request_edge_status()
589  {
590  if (!refcount_estatus_++)
591  add_property( edge_status_, "e:status" );
592  }
593 
594  void request_face_status()
595  {
596  if (!refcount_fstatus_++)
597  add_property( face_status_, "f:status" );
598  }
599 
602  {
603  if ((refcount_vstatus_ > 0) && (! --refcount_vstatus_))
604  remove_property(vertex_status_);
605  }
606 
607  void release_halfedge_status()
608  {
609  if ((refcount_hstatus_ > 0) && (! --refcount_hstatus_))
610  remove_property(halfedge_status_);
611  }
612 
613  void release_edge_status()
614  {
615  if ((refcount_estatus_ > 0) && (! --refcount_estatus_))
616  remove_property(edge_status_);
617  }
618 
619  void release_face_status()
620  {
621  if ((refcount_fstatus_ > 0) && (! --refcount_fstatus_))
622  remove_property(face_status_);
623  }
624 
626 
634  template <class HandleT>
636  {
637  public:
638  typedef HandleT Handle;
639 
640  protected:
641  ArrayKernel& kernel_;
642 
643  public:
644  const unsigned int bit_mask_;
645 
646  public:
647  StatusSetT(ArrayKernel& _kernel, const unsigned int _bit_mask)
648  : kernel_(_kernel), bit_mask_(_bit_mask)
649  {}
650 
651  ~StatusSetT()
652  {}
653 
654  inline bool is_in(Handle _hnd) const
655  { return kernel_.status(_hnd).is_bit_set(bit_mask_); }
656 
657  inline void insert(Handle _hnd)
658  { kernel_.status(_hnd).set_bit(bit_mask_); }
659 
660  inline void erase(Handle _hnd)
661  { kernel_.status(_hnd).unset_bit(bit_mask_); }
662 
664  size_t size() const
665  {
666  const int n = kernel_.status_pph(Handle()).is_valid() ?
667  (int)kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
668 
669  size_t sz = 0;
670  for (int i = 0; i < n; ++i)
671  sz += (size_t)is_in(Handle(i));
672  return sz;
673  }
674 
676  void clear()
677  {
678  const int n = kernel_.status_pph(Handle()).is_valid() ?
679  (int)kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
680 
681  for (int i = 0; i < n; ++i)
682  erase(Handle(i));
683  }
684  };
685 
686  friend class StatusSetT<VertexHandle>;
687  friend class StatusSetT<EdgeHandle>;
688  friend class StatusSetT<FaceHandle>;
689  friend class StatusSetT<HalfedgeHandle>;
690 
692  template <class HandleT>
693  class AutoStatusSetT : public StatusSetT<HandleT>
694  {
695  private:
696  typedef HandleT Handle;
697  typedef StatusSetT<Handle> Base;
698 
699  public:
700  explicit AutoStatusSetT(ArrayKernel& _kernel)
701  : StatusSetT<Handle>(_kernel, _kernel.pop_bit_mask(Handle()))
702  { /*assert(size() == 0);*/ } //the set should be empty on creation
703 
704  ~AutoStatusSetT()
705  {
706  //assert(size() == 0);//the set should be empty on leave?
707  Base::kernel_.push_bit_mask(Handle(), Base::bit_mask_);
708  }
709  };
710 
711  friend class AutoStatusSetT<VertexHandle>;
712  friend class AutoStatusSetT<EdgeHandle>;
713  friend class AutoStatusSetT<FaceHandle>;
714  friend class AutoStatusSetT<HalfedgeHandle>;
715 
720 
722  template <class HandleT>
723  class ExtStatusSetT : public AutoStatusSetT<HandleT>
724  {
725  public:
726  typedef HandleT Handle;
728 
729  protected:
730  typedef std::vector<Handle> HandleContainer;
731  HandleContainer handles_;
732 
733  public:
734  typedef typename HandleContainer::iterator
735  iterator;
736  typedef typename HandleContainer::const_iterator
737  const_iterator;
738  public:
739  ExtStatusSetT(ArrayKernel& _kernel, size_t _capacity_hint = 0)
740  : Base(_kernel)
741  { handles_.reserve(_capacity_hint); }
742 
743  ~ExtStatusSetT()
744  { Base::clear(); }
745 
746  // Complexity: O(1)
747  inline void insert(Handle _hnd)
748  {
749  if (!Base::is_in(_hnd))
750  {
751  Base::insert(_hnd);
752  handles_.push_back(_hnd);
753  }
754  }
755 
757  inline void erase(Handle _hnd)
758  {
759  if (is_in(_hnd))
760  {
761  iterator it = std::find(begin(), end(), _hnd);
762  erase(it);
763  }
764  }
765 
767  inline void erase(iterator _it)
768  {
769  assert(_it != const_cast<const ExtStatusSetT*>(this)->end() &&
770  Base::is_in(*_it));
771  Base::erase(*_it);
772  *_it = handles_.back();
773  _it.pop_back();
774  }
775 
776  inline void clear()
777  {
778  for (iterator it = begin(); it != end(); ++it)
779  {
780  assert(Base::is_in(*it));
781  Base::erase(*it);
782  }
783  handles_.clear();
784  }
785 
787  inline unsigned int size() const
788  { return handles_.size(); }
789  inline bool empty() const
790  { return handles_.empty(); }
791 
792  //Vector API
793  inline iterator begin()
794  { return handles_.begin(); }
795  inline const_iterator begin() const
796  { return handles_.begin(); }
797 
798  inline iterator end()
799  { return handles_.end(); }
800  inline const_iterator end() const
801  { return handles_.end(); }
802 
803  inline Handle& front()
804  { return handles_.front(); }
805  inline const Handle& front() const
806  { return handles_.front(); }
807 
808  inline Handle& back()
809  { return handles_.back(); }
810  inline const Handle& back() const
811  { return handles_.back(); }
812  };
813 
818 
819 private:
820  // iterators
821  typedef std::vector<Vertex> VertexContainer;
822  typedef std::vector<Edge> EdgeContainer;
823  typedef std::vector<Face> FaceContainer;
824  typedef VertexContainer::iterator KernelVertexIter;
825  typedef VertexContainer::const_iterator KernelConstVertexIter;
826  typedef EdgeContainer::iterator KernelEdgeIter;
827  typedef EdgeContainer::const_iterator KernelConstEdgeIter;
828  typedef FaceContainer::iterator KernelFaceIter;
829  typedef FaceContainer::const_iterator KernelConstFaceIter;
830  typedef std::vector<unsigned int> BitMaskContainer;
831 
832 
833  KernelVertexIter vertices_begin() { return vertices_.begin(); }
834  KernelConstVertexIter vertices_begin() const { return vertices_.begin(); }
835  KernelVertexIter vertices_end() { return vertices_.end(); }
836  KernelConstVertexIter vertices_end() const { return vertices_.end(); }
837 
838  KernelEdgeIter edges_begin() { return edges_.begin(); }
839  KernelConstEdgeIter edges_begin() const { return edges_.begin(); }
840  KernelEdgeIter edges_end() { return edges_.end(); }
841  KernelConstEdgeIter edges_end() const { return edges_.end(); }
842 
843  KernelFaceIter faces_begin() { return faces_.begin(); }
844  KernelConstFaceIter faces_begin() const { return faces_.begin(); }
845  KernelFaceIter faces_end() { return faces_.end(); }
846  KernelConstFaceIter faces_end() const { return faces_.end(); }
847 
849  inline BitMaskContainer& bit_masks(VertexHandle /*_dummy_hnd*/)
850  { return vertex_bit_masks_; }
851  inline BitMaskContainer& bit_masks(EdgeHandle /*_dummy_hnd*/)
852  { return edge_bit_masks_; }
853  inline BitMaskContainer& bit_masks(FaceHandle /*_dummy_hnd*/)
854  { return face_bit_masks_; }
855  inline BitMaskContainer& bit_masks(HalfedgeHandle /*_dummy_hnd*/)
856  { return halfedge_bit_masks_; }
857 
858  template <class Handle>
859  unsigned int pop_bit_mask(Handle _hnd)
860  {
861  assert(!bit_masks(_hnd).empty());//check if the client request too many status sets
862  unsigned int bit_mask = bit_masks(_hnd).back();
863  bit_masks(_hnd).pop_back();
864  return bit_mask;
865  }
866 
867  template <class Handle>
868  void push_bit_mask(Handle _hnd, unsigned int _bit_mask)
869  {
870  assert(std::find(bit_masks(_hnd).begin(), bit_masks(_hnd).end(), _bit_mask) ==
871  bit_masks(_hnd).end());//this mask should be not already used
872  bit_masks(_hnd).push_back(_bit_mask);
873  }
874 
875  void init_bit_masks(BitMaskContainer& _bmc);
876  void init_bit_masks();
877 
878 protected:
879 
880  VertexStatusPropertyHandle vertex_status_;
881  HalfedgeStatusPropertyHandle halfedge_status_;
882  EdgeStatusPropertyHandle edge_status_;
883  FaceStatusPropertyHandle face_status_;
884 
885  unsigned int refcount_vstatus_;
886  unsigned int refcount_hstatus_;
887  unsigned int refcount_estatus_;
888  unsigned int refcount_fstatus_;
889 
890 private:
891  VertexContainer vertices_;
892  EdgeContainer edges_;
893  FaceContainer faces_;
894 
895  BitMaskContainer halfedge_bit_masks_;
896  BitMaskContainer edge_bit_masks_;
897  BitMaskContainer vertex_bit_masks_;
898  BitMaskContainer face_bit_masks_;
899 };
900 
901 
902 //=============================================================================
903 } // namespace OpenMesh
904 //=============================================================================
905 #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_ARRAY_KERNEL_C)
906 # define OPENMESH_ARRAY_KERNEL_TEMPLATES
907 # include "ArrayKernelT_impl.hh"
908 #endif
909 //=============================================================================
910 #endif // OPENMESH_ARRAY_KERNEL_HH defined
911 //=============================================================================
Handle for a edge entity.
Definition: Handles.hh:134
Handle for a face entity.
Definition: Handles.hh:141
Handle for a halfedge entity.
Definition: Handles.hh:127
int idx() const
Get the underlying index of this handle.
Definition: Handles.hh:69
size_t size() const
Note: 0(n) complexity.
Definition: ArrayKernel.hh:664
AutoStatusSetT: A status set that automatically picks a status bit.
Definition: ArrayKernel.hh:693
void unset_bit(unsigned int _s)
unset a certain bit
Definition: Status.hh:161
void request_vertex_status()
Status Request API.
Definition: ArrayKernel.hh:576
Handle for a vertex entity.
Definition: Handles.hh:120
BitMaskContainer & bit_masks(VertexHandle)
bit mask container by handle
Definition: ArrayKernel.hh:849
const StatusInfo & status(VertexHandle _vh) const
Status Query API.
Definition: ArrayKernel.hh:501
bool is_valid() const
The handle is valid iff the index is not negative.
Definition: Handles.hh:72
bool is_boundary(HalfedgeHandle _heh) const
Is halfedge _heh a boundary halfedge (is its face handle invalid) ?
Definition: ArrayKernel.hh:398
ExtStatusSet: A status set augmented with an array.
Definition: ArrayKernel.hh:723
Default property class for any type T.
Definition: Property.hh:89
bool is_bit_set(unsigned int _s) const
is a certain bit set ?
Definition: Status.hh:157
unsigned int size() const
Complexity: 0(1)
Definition: ArrayKernel.hh:787
void invalidate()
reset handle to be invalid
Definition: Handles.hh:77
VertexHandle new_vertex()
Add a new vertex.
Definition: ArrayKernel.hh:216
void release_vertex_status()
Status Release API.
Definition: ArrayKernel.hh:601
VertexStatusPropertyHandle status_pph(VertexHandle) const
status property by handle
Definition: ArrayKernel.hh:563
void clear()
Note: O(n) complexity.
Definition: ArrayKernel.hh:676
PropertyT< T > & property(VPropHandleT< T > _ph)
Definition: BaseKernel.hh:310
vector_type & data_vector()
Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!!!) ...
Definition: Property.hh:180
void set_bit(unsigned int _s)
set a certain bit
Definition: Status.hh:159
void erase(iterator _it)
Complexity: O(1)
Definition: ArrayKernel.hh:767
— StatusSet API —
Definition: ArrayKernel.hh:635
void erase(Handle _hnd)
Complexity: O(k), (k - number of the elements in the set)
Definition: ArrayKernel.hh:757
VertexHandle new_vertex_dirty()
Definition: ArrayKernel.hh:234