OpenMesh
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  * $Revision$ *
45  * $Date$ *
46  * *
47 \*===========================================================================*/
48 
49 
50 //=============================================================================
51 //
52 // CLASS ArrayKernel
53 //
54 //=============================================================================
55 
56 
57 #ifndef OPENMESH_ARRAY_KERNEL_HH
58 #define OPENMESH_ARRAY_KERNEL_HH
59 
60 
61 //== INCLUDES =================================================================
62 #include <vector>
63 
64 #include <OpenMesh/Core/System/config.h>
65 #include <OpenMesh/Core/Utils/GenProg.hh>
66 
67 #include <OpenMesh/Core/Mesh/ArrayItems.hh>
68 #include <OpenMesh/Core/Mesh/BaseKernel.hh>
69 #include <OpenMesh/Core/Mesh/Status.hh>
70 
71 //== NAMESPACES ===============================================================
72 namespace OpenMesh {
73 
74 
75 //== CLASS DEFINITION =========================================================
92 class OPENMESHDLLEXPORT ArrayKernel : public BaseKernel, public ArrayItems
93 {
94 public:
95 
96  // handles
106 
107 public:
108 
109  // --- constructor/destructor ---
110  ArrayKernel();
111  virtual ~ArrayKernel();
112 
119  void assign_connectivity(const ArrayKernel& _other);
120 
121  // --- handle -> item ---
122  VertexHandle handle(const Vertex& _v) const;
123 
124  HalfedgeHandle handle(const Halfedge& _he) const;
125 
126  EdgeHandle handle(const Edge& _e) const;
127 
128  FaceHandle handle(const Face& _f) const;
129 
130 
132  bool is_valid_handle(VertexHandle _vh) const;
133 
135  bool is_valid_handle(HalfedgeHandle _heh) const;
136 
138  bool is_valid_handle(EdgeHandle _eh) const;
139 
141  bool is_valid_handle(FaceHandle _fh) const;
142 
143 
144  // --- item -> handle ---
145  const Vertex& vertex(VertexHandle _vh) const
146  {
147  assert(is_valid_handle(_vh));
148  return vertices_[_vh.idx()];
149  }
150 
151  Vertex& vertex(VertexHandle _vh)
152  {
153  assert(is_valid_handle(_vh));
154  return vertices_[_vh.idx()];
155  }
156 
157  const Halfedge& halfedge(HalfedgeHandle _heh) const
158  {
159  assert(is_valid_handle(_heh));
160  return edges_[_heh.idx() >> 1].halfedges_[_heh.idx() & 1];
161  }
162 
163  Halfedge& halfedge(HalfedgeHandle _heh)
164  {
165  assert(is_valid_handle(_heh));
166  return edges_[_heh.idx() >> 1].halfedges_[_heh.idx() & 1];
167  }
168 
169  const Edge& edge(EdgeHandle _eh) const
170  {
171  assert(is_valid_handle(_eh));
172  return edges_[_eh.idx()];
173  }
174 
175  Edge& edge(EdgeHandle _eh)
176  {
177  assert(is_valid_handle(_eh));
178  return edges_[_eh.idx()];
179  }
180 
181  const Face& face(FaceHandle _fh) const
182  {
183  assert(is_valid_handle(_fh));
184  return faces_[_fh.idx()];
185  }
186 
187  Face& face(FaceHandle _fh)
188  {
189  assert(is_valid_handle(_fh));
190  return faces_[_fh.idx()];
191  }
192 
193  // --- get i'th items ---
194 
195  VertexHandle vertex_handle(unsigned int _i) const
196  { return (_i < n_vertices()) ? handle( vertices_[_i] ) : VertexHandle(); }
197 
198  HalfedgeHandle halfedge_handle(unsigned int _i) const
199  {
200  return (_i < n_halfedges()) ?
201  halfedge_handle(edge_handle(_i/2), _i%2) : HalfedgeHandle();
202  }
203 
204  EdgeHandle edge_handle(unsigned int _i) const
205  { return (_i < n_edges()) ? handle(edges_[_i]) : EdgeHandle(); }
206 
207  FaceHandle face_handle(unsigned int _i) const
208  { return (_i < n_faces()) ? handle(faces_[_i]) : FaceHandle(); }
209 
210 public:
211 
221  inline VertexHandle new_vertex()
222  {
223  vertices_.push_back(Vertex());
224  vprops_resize(n_vertices());//TODO:should it be push_back()?
225 
226  return handle(vertices_.back());
227  }
228 
239  inline VertexHandle new_vertex_dirty()
240  {
241  vertices_.push_back(Vertex());
242  vprops_resize_if_smaller(n_vertices());//TODO:should it be push_back()?
243 
244  return handle(vertices_.back());
245  }
246 
247  inline HalfedgeHandle new_edge(VertexHandle _start_vh, VertexHandle _end_vh)
248  {
249 // assert(_start_vh != _end_vh);
250  edges_.push_back(Edge());
251  eprops_resize(n_edges());//TODO:should it be push_back()?
252  hprops_resize(n_halfedges());//TODO:should it be push_back()?
253 
254  EdgeHandle eh(handle(edges_.back()));
255  HalfedgeHandle heh0(halfedge_handle(eh, 0));
256  HalfedgeHandle heh1(halfedge_handle(eh, 1));
257  set_vertex_handle(heh0, _end_vh);
258  set_vertex_handle(heh1, _start_vh);
259  return heh0;
260  }
261 
262  inline FaceHandle new_face()
263  {
264  faces_.push_back(Face());
265  fprops_resize(n_faces());
266  return handle(faces_.back());
267  }
268 
269  inline FaceHandle new_face(const Face& _f)
270  {
271  faces_.push_back(_f);
272  fprops_resize(n_faces());
273  return handle(faces_.back());
274  }
275 
276 public:
277  // --- resize/reserve ---
278  void resize( size_t _n_vertices, size_t _n_edges, size_t _n_faces );
279  void reserve(size_t _n_vertices, size_t _n_edges, size_t _n_faces );
280 
281  // --- deletion ---
297  void garbage_collection(bool _v=true, bool _e=true, bool _f=true);
298 
316  template<typename std_API_Container_VHandlePointer,
317  typename std_API_Container_HHandlePointer,
318  typename std_API_Container_FHandlePointer>
319  void garbage_collection(std_API_Container_VHandlePointer& vh_to_update,
320  std_API_Container_HHandlePointer& hh_to_update,
321  std_API_Container_FHandlePointer& fh_to_update,
322  bool _v=true, bool _e=true, bool _f=true);
323 
325  void clear();
326 
336  void clean();
337 
345  void clean_keep_reservation();
346 
347  // --- number of items ---
348  size_t n_vertices() const { return vertices_.size(); }
349  size_t n_halfedges() const { return 2*edges_.size(); }
350  size_t n_edges() const { return edges_.size(); }
351  size_t n_faces() const { return faces_.size(); }
352 
353  bool vertices_empty() const { return vertices_.empty(); }
354  bool halfedges_empty() const { return edges_.empty(); }
355  bool edges_empty() const { return edges_.empty(); }
356  bool faces_empty() const { return faces_.empty(); }
357 
358  // --- vertex connectivity ---
359 
360  HalfedgeHandle halfedge_handle(VertexHandle _vh) const
361  { return vertex(_vh).halfedge_handle_; }
362 
363  void set_halfedge_handle(VertexHandle _vh, HalfedgeHandle _heh)
364  {
365 // assert(is_valid_handle(_heh));
366  vertex(_vh).halfedge_handle_ = _heh;
367  }
368 
369  bool is_isolated(VertexHandle _vh) const
370  { return !halfedge_handle(_vh).is_valid(); }
371 
372  void set_isolated(VertexHandle _vh)
373  { vertex(_vh).halfedge_handle_.invalidate(); }
374 
375  unsigned int delete_isolated_vertices();
376 
377  // --- halfedge connectivity ---
378  VertexHandle to_vertex_handle(HalfedgeHandle _heh) const
379  { return halfedge(_heh).vertex_handle_; }
380 
381  VertexHandle from_vertex_handle(HalfedgeHandle _heh) const
382  { return to_vertex_handle(opposite_halfedge_handle(_heh)); }
383 
384  void set_vertex_handle(HalfedgeHandle _heh, VertexHandle _vh)
385  {
386 // assert(is_valid_handle(_vh));
387  halfedge(_heh).vertex_handle_ = _vh;
388  }
389 
390  FaceHandle face_handle(HalfedgeHandle _heh) const
391  { return halfedge(_heh).face_handle_; }
392 
393  void set_face_handle(HalfedgeHandle _heh, FaceHandle _fh)
394  {
395 // assert(is_valid_handle(_fh));
396  halfedge(_heh).face_handle_ = _fh;
397  }
398 
399  void set_boundary(HalfedgeHandle _heh)
400  { halfedge(_heh).face_handle_.invalidate(); }
401 
403  bool is_boundary(HalfedgeHandle _heh) const
404  { return !face_handle(_heh).is_valid(); }
405 
406  HalfedgeHandle next_halfedge_handle(HalfedgeHandle _heh) const
407  { return halfedge(_heh).next_halfedge_handle_; }
408 
409  void set_next_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _nheh)
410  {
411  assert(is_valid_handle(_nheh));
412 // assert(to_vertex_handle(_heh) == from_vertex_handle(_nheh));
413  halfedge(_heh).next_halfedge_handle_ = _nheh;
414  set_prev_halfedge_handle(_nheh, _heh);
415  }
416 
417 
418  void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh)
419  {
420  assert(is_valid_handle(_pheh));
421  set_prev_halfedge_handle(_heh, _pheh, HasPrevHalfedge());
422  }
423 
424  void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh,
425  GenProg::TrueType)
426  { halfedge(_heh).prev_halfedge_handle_ = _pheh; }
427 
428  void set_prev_halfedge_handle(HalfedgeHandle /* _heh */, HalfedgeHandle /* _pheh */,
429  GenProg::FalseType)
430  {}
431 
432  HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh) const
433  { return prev_halfedge_handle(_heh, HasPrevHalfedge() ); }
434 
435  HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::TrueType) const
436  { return halfedge(_heh).prev_halfedge_handle_; }
437 
438  HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::FalseType) const
439  {
440  if (is_boundary(_heh))
441  {//iterating around the vertex should be faster than iterating the boundary
442  HalfedgeHandle curr_heh(opposite_halfedge_handle(_heh));
443  HalfedgeHandle next_heh(next_halfedge_handle(curr_heh));
444  do
445  {
446  curr_heh = opposite_halfedge_handle(next_heh);
447  next_heh = next_halfedge_handle(curr_heh);
448  }
449  while (next_heh != _heh);
450  return curr_heh;
451  }
452  else
453  {
454  HalfedgeHandle heh(_heh);
455  HalfedgeHandle next_heh(next_halfedge_handle(heh));
456  while (next_heh != _heh) {
457  heh = next_heh;
458  next_heh = next_halfedge_handle(next_heh);
459  }
460  return heh;
461  }
462  }
463 
464 
465  HalfedgeHandle opposite_halfedge_handle(HalfedgeHandle _heh) const
466  { return HalfedgeHandle(_heh.idx() ^ 1); }
467 
468 
469  HalfedgeHandle ccw_rotated_halfedge_handle(HalfedgeHandle _heh) const
470  { return opposite_halfedge_handle(prev_halfedge_handle(_heh)); }
471 
472 
473  HalfedgeHandle cw_rotated_halfedge_handle(HalfedgeHandle _heh) const
474  { return next_halfedge_handle(opposite_halfedge_handle(_heh)); }
475 
476  // --- edge connectivity ---
477  static HalfedgeHandle s_halfedge_handle(EdgeHandle _eh, unsigned int _i)
478  {
479  assert(_i<=1);
480  return HalfedgeHandle((_eh.idx() << 1) + _i);
481  }
482 
483  static EdgeHandle s_edge_handle(HalfedgeHandle _heh)
484  { return EdgeHandle(_heh.idx() >> 1); }
485 
486  HalfedgeHandle halfedge_handle(EdgeHandle _eh, unsigned int _i) const
487  {
488  return s_halfedge_handle(_eh, _i);
489  }
490 
491  EdgeHandle edge_handle(HalfedgeHandle _heh) const
492  { return s_edge_handle(_heh); }
493 
494  // --- face connectivity ---
495  HalfedgeHandle halfedge_handle(FaceHandle _fh) const
496  { return face(_fh).halfedge_handle_; }
497 
498  void set_halfedge_handle(FaceHandle _fh, HalfedgeHandle _heh)
499  {
500 // assert(is_valid_handle(_heh));
501  face(_fh).halfedge_handle_ = _heh;
502  }
503 
505  //------------------------------------------------------------ vertex status
506  const StatusInfo& status(VertexHandle _vh) const
507  { return property(vertex_status_, _vh); }
508 
509  StatusInfo& status(VertexHandle _vh)
510  { return property(vertex_status_, _vh); }
511 
516  void reset_status() {
517  PropertyT<StatusInfo> &status_prop = property(vertex_status_);
518  PropertyT<StatusInfo>::vector_type &sprop_v = status_prop.data_vector();
519  std::fill(sprop_v.begin(), sprop_v.begin() + n_vertices(), StatusInfo());
520  }
521 
522  //----------------------------------------------------------- halfedge status
523  const StatusInfo& status(HalfedgeHandle _hh) const
524  { return property(halfedge_status_, _hh); }
525 
526  StatusInfo& status(HalfedgeHandle _hh)
527  { return property(halfedge_status_, _hh); }
528 
529  //--------------------------------------------------------------- edge status
530  const StatusInfo& status(EdgeHandle _eh) const
531  { return property(edge_status_, _eh); }
532 
533  StatusInfo& status(EdgeHandle _eh)
534  { return property(edge_status_, _eh); }
535 
536  //--------------------------------------------------------------- face status
537  const StatusInfo& status(FaceHandle _fh) const
538  { return property(face_status_, _fh); }
539 
540  StatusInfo& status(FaceHandle _fh)
541  { return property(face_status_, _fh); }
542 
543  inline bool has_vertex_status() const
544  { return vertex_status_.is_valid(); }
545 
546  inline bool has_halfedge_status() const
547  { return halfedge_status_.is_valid(); }
548 
549  inline bool has_edge_status() const
550  { return edge_status_.is_valid(); }
551 
552  inline bool has_face_status() const
553  { return face_status_.is_valid(); }
554 
555  inline VertexStatusPropertyHandle vertex_status_pph() const
556  { return vertex_status_; }
557 
558  inline HalfedgeStatusPropertyHandle halfedge_status_pph() const
559  { return halfedge_status_; }
560 
561  inline EdgeStatusPropertyHandle edge_status_pph() const
562  { return edge_status_; }
563 
564  inline FaceStatusPropertyHandle face_status_pph() const
565  { return face_status_; }
566 
568  inline VertexStatusPropertyHandle status_pph(VertexHandle /*_hnd*/) const
569  { return vertex_status_pph(); }
570 
571  inline HalfedgeStatusPropertyHandle status_pph(HalfedgeHandle /*_hnd*/) const
572  { return halfedge_status_pph(); }
573 
574  inline EdgeStatusPropertyHandle status_pph(EdgeHandle /*_hnd*/) const
575  { return edge_status_pph(); }
576 
577  inline FaceStatusPropertyHandle status_pph(FaceHandle /*_hnd*/) const
578  { return face_status_pph(); }
579 
582  {
583  if (!refcount_vstatus_++)
584  add_property( vertex_status_, "v:status" );
585  }
586 
587  void request_halfedge_status()
588  {
589  if (!refcount_hstatus_++)
590  add_property( halfedge_status_, "h:status" );
591  }
592 
593  void request_edge_status()
594  {
595  if (!refcount_estatus_++)
596  add_property( edge_status_, "e:status" );
597  }
598 
599  void request_face_status()
600  {
601  if (!refcount_fstatus_++)
602  add_property( face_status_, "f:status" );
603  }
604 
607  {
608  if ((refcount_vstatus_ > 0) && (! --refcount_vstatus_))
609  remove_property(vertex_status_);
610  }
611 
612  void release_halfedge_status()
613  {
614  if ((refcount_hstatus_ > 0) && (! --refcount_hstatus_))
615  remove_property(halfedge_status_);
616  }
617 
618  void release_edge_status()
619  {
620  if ((refcount_estatus_ > 0) && (! --refcount_estatus_))
621  remove_property(edge_status_);
622  }
623 
624  void release_face_status()
625  {
626  if ((refcount_fstatus_ > 0) && (! --refcount_fstatus_))
627  remove_property(face_status_);
628  }
629 
631 
639  template <class HandleT>
641  {
642  public:
643  typedef HandleT Handle;
644 
645  protected:
646  ArrayKernel& kernel_;
647 
648  public:
649  const unsigned int bit_mask_;
650 
651  public:
652  StatusSetT(ArrayKernel& _kernel, const unsigned int _bit_mask)
653  : kernel_(_kernel), bit_mask_(_bit_mask)
654  {}
655 
656  ~StatusSetT()
657  {}
658 
659  inline bool is_in(Handle _hnd) const
660  { return kernel_.status(_hnd).is_bit_set(bit_mask_); }
661 
662  inline void insert(Handle _hnd)
663  { kernel_.status(_hnd).set_bit(bit_mask_); }
664 
665  inline void erase(Handle _hnd)
666  { kernel_.status(_hnd).unset_bit(bit_mask_); }
667 
669  size_t size() const
670  {
671  const int n = kernel_.status_pph(Handle()).is_valid() ?
672  (int)kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
673 
674  size_t sz = 0;
675  for (int i = 0; i < n; ++i)
676  sz += (size_t)is_in(Handle(i));
677  return sz;
678  }
679 
681  void clear()
682  {
683  const int n = kernel_.status_pph(Handle()).is_valid() ?
684  (int)kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
685 
686  for (int i = 0; i < n; ++i)
687  erase(Handle(i));
688  }
689  };
690 
691  friend class StatusSetT<VertexHandle>;
692  friend class StatusSetT<EdgeHandle>;
693  friend class StatusSetT<FaceHandle>;
694  friend class StatusSetT<HalfedgeHandle>;
695 
697  template <class HandleT>
698  class AutoStatusSetT : public StatusSetT<HandleT>
699  {
700  private:
701  typedef HandleT Handle;
702  typedef StatusSetT<Handle> Base;
703 
704  public:
705  AutoStatusSetT(ArrayKernel& _kernel)
706  : StatusSetT<Handle>(_kernel, _kernel.pop_bit_mask(Handle()))
707  { /*assert(size() == 0);*/ } //the set should be empty on creation
708 
709  ~AutoStatusSetT()
710  {
711  //assert(size() == 0);//the set should be empty on leave?
712  Base::kernel_.push_bit_mask(Handle(), Base::bit_mask_);
713  }
714  };
715 
716  friend class AutoStatusSetT<VertexHandle>;
717  friend class AutoStatusSetT<EdgeHandle>;
718  friend class AutoStatusSetT<FaceHandle>;
719  friend class AutoStatusSetT<HalfedgeHandle>;
720 
725 
727  template <class HandleT>
728  class ExtStatusSetT : public AutoStatusSetT<HandleT>
729  {
730  public:
731  typedef HandleT Handle;
733 
734  protected:
735  typedef std::vector<Handle> HandleContainer;
736  HandleContainer handles_;
737 
738  public:
739  typedef typename HandleContainer::iterator
740  iterator;
741  typedef typename HandleContainer::const_iterator
742  const_iterator;
743  public:
744  ExtStatusSetT(ArrayKernel& _kernel, size_t _capacity_hint = 0)
745  : Base(_kernel)
746  { handles_.reserve(_capacity_hint); }
747 
748  ~ExtStatusSetT()
749  { clear(); }
750 
751  // Complexity: O(1)
752  inline void insert(Handle _hnd)
753  {
754  if (!is_in(_hnd))
755  {
756  Base::insert(_hnd);
757  handles_.push_back(_hnd);
758  }
759  }
760 
762  inline void erase(Handle _hnd)
763  {
764  if (is_in(_hnd))
765  {
766  iterator it = std::find(begin(), end(), _hnd);
767  erase(it);
768  }
769  }
770 
772  inline void erase(iterator _it)
773  {
774  assert(_it != end() && is_in(*_it));
775  Base::erase(*_it);
776  *_it = handles_.back();
777  _it.pop_back();
778  }
779 
780  inline void clear()
781  {
782  for (iterator it = begin(); it != end(); ++it)
783  {
784  assert(is_in(*it));
785  Base::erase(*it);
786  }
787  handles_.clear();
788  }
789 
791  inline unsigned int size() const
792  { return handles_.size(); }
793  inline bool empty() const
794  { return handles_.empty(); }
795 
796  //Vector API
797  inline iterator begin()
798  { return handles_.begin(); }
799  inline const_iterator begin() const
800  { return handles_.begin(); }
801 
802  inline iterator end()
803  { return handles_.end(); }
804  inline const_iterator end() const
805  { return handles_.end(); }
806 
807  inline Handle& front()
808  { return handles_.front(); }
809  inline const Handle& front() const
810  { return handles_.front(); }
811 
812  inline Handle& back()
813  { return handles_.back(); }
814  inline const Handle& back() const
815  { return handles_.back(); }
816  };
817 
822 
823 private:
824  // iterators
825  typedef std::vector<Vertex> VertexContainer;
826  typedef std::vector<Edge> EdgeContainer;
827  typedef std::vector<Face> FaceContainer;
828  typedef VertexContainer::iterator KernelVertexIter;
829  typedef VertexContainer::const_iterator KernelConstVertexIter;
830  typedef EdgeContainer::iterator KernelEdgeIter;
831  typedef EdgeContainer::const_iterator KernelConstEdgeIter;
832  typedef FaceContainer::iterator KernelFaceIter;
833  typedef FaceContainer::const_iterator KernelConstFaceIter;
834  typedef std::vector<unsigned int> BitMaskContainer;
835 
836 
837  KernelVertexIter vertices_begin() { return vertices_.begin(); }
838  KernelConstVertexIter vertices_begin() const { return vertices_.begin(); }
839  KernelVertexIter vertices_end() { return vertices_.end(); }
840  KernelConstVertexIter vertices_end() const { return vertices_.end(); }
841 
842  KernelEdgeIter edges_begin() { return edges_.begin(); }
843  KernelConstEdgeIter edges_begin() const { return edges_.begin(); }
844  KernelEdgeIter edges_end() { return edges_.end(); }
845  KernelConstEdgeIter edges_end() const { return edges_.end(); }
846 
847  KernelFaceIter faces_begin() { return faces_.begin(); }
848  KernelConstFaceIter faces_begin() const { return faces_.begin(); }
849  KernelFaceIter faces_end() { return faces_.end(); }
850  KernelConstFaceIter faces_end() const { return faces_.end(); }
851 
853  inline BitMaskContainer& bit_masks(VertexHandle /*_dummy_hnd*/)
854  { return vertex_bit_masks_; }
855  inline BitMaskContainer& bit_masks(EdgeHandle /*_dummy_hnd*/)
856  { return edge_bit_masks_; }
857  inline BitMaskContainer& bit_masks(FaceHandle /*_dummy_hnd*/)
858  { return face_bit_masks_; }
859  inline BitMaskContainer& bit_masks(HalfedgeHandle /*_dummy_hnd*/)
860  { return halfedge_bit_masks_; }
861 
862  template <class Handle>
863  unsigned int pop_bit_mask(Handle _hnd)
864  {
865  assert(!bit_masks(_hnd).empty());//check if the client request too many status sets
866  unsigned int bit_mask = bit_masks(_hnd).back();
867  bit_masks(_hnd).pop_back();
868  return bit_mask;
869  }
870 
871  template <class Handle>
872  void push_bit_mask(Handle _hnd, unsigned int _bit_mask)
873  {
874  assert(std::find(bit_masks(_hnd).begin(), bit_masks(_hnd).end(), _bit_mask) ==
875  bit_masks(_hnd).end());//this mask should be not already used
876  bit_masks(_hnd).push_back(_bit_mask);
877  }
878 
879  void init_bit_masks(BitMaskContainer& _bmc);
880  void init_bit_masks();
881 
882 protected:
883 
884  VertexStatusPropertyHandle vertex_status_;
885  HalfedgeStatusPropertyHandle halfedge_status_;
886  EdgeStatusPropertyHandle edge_status_;
887  FaceStatusPropertyHandle face_status_;
888 
889  unsigned int refcount_vstatus_;
890  unsigned int refcount_hstatus_;
891  unsigned int refcount_estatus_;
892  unsigned int refcount_fstatus_;
893 
894 private:
895  VertexContainer vertices_;
896  EdgeContainer edges_;
897  FaceContainer faces_;
898 
899  BitMaskContainer halfedge_bit_masks_;
900  BitMaskContainer edge_bit_masks_;
901  BitMaskContainer vertex_bit_masks_;
902  BitMaskContainer face_bit_masks_;
903 };
904 
905 
906 //=============================================================================
907 } // namespace OpenMesh
908 //=============================================================================
909 #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_ARRAY_KERNEL_C)
910 # define OPENMESH_ARRAY_KERNEL_TEMPLATES
911 # include "ArrayKernelT.cc"
912 #endif
913 //=============================================================================
914 #endif // OPENMESH_ARRAY_KERNEL_HH defined
915 //=============================================================================
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:64
VertexHandle new_vertex_dirty()
Same as new_vertex() but uses PropertyContainer::resize_if_smaller() to resize the vertex property co...
Definition: ArrayKernel.hh:239
int idx() const
Get the underlying index of this handle.
Definition: Handles.hh:74
void invalidate()
reset handle to be invalid
Definition: Handles.hh:82
ExtStatusSet: A status set augmented with an array.
Definition: ArrayKernel.hh:728
void clear()
Note: O(n) complexity.
Definition: ArrayKernel.hh:681
VertexHandle new_vertex()
Add a new vertex.
Definition: ArrayKernel.hh:221
Mesh kernel using arrays for mesh item storage.
Definition: ArrayKernel.hh:92
void request_vertex_status()
Status Request API.
Definition: ArrayKernel.hh:581
bool is_boundary(HalfedgeHandle _heh) const
Is halfedge _heh a boundary halfedge (is its face handle invalid) ?
Definition: ArrayKernel.hh:403
bool is_bit_set(unsigned int _s) const
is a certain bit set ?
Definition: Status.hh:162
Handle for a halfedge entity.
Definition: Handles.hh:132
This class provides low-level property management like adding/removing properties and access to prope...
Definition: BaseKernel.hh:102
Add status information to a base class.
Definition: Status.hh:99
Handle for a face entity.
Definition: Handles.hh:146
size_t size() const
Note: 0(n) complexity.
Definition: ArrayKernel.hh:669
void unset_bit(unsigned int _s)
unset a certain bit
Definition: Status.hh:166
unsigned int size() const
Complexity: 0(1)
Definition: ArrayKernel.hh:791
AutoStatusSetT: A status set that automatically picks a status bit.
Definition: ArrayKernel.hh:698
Default property class for any type T.
Definition: Property.hh:94
PropertyT< T > & property(VPropHandleT< T > _ph)
In most cases you should use the convenient PropertyManager wrapper and use of this function should n...
Definition: BaseKernel.hh:315
Handle for a vertex entity.
Definition: Handles.hh:125
— StatusSet API —
Definition: ArrayKernel.hh:640
const StatusInfo & status(VertexHandle _vh) const
Status Query API.
Definition: ArrayKernel.hh:506
bool is_valid() const
The handle is valid iff the index is not negative.
Definition: Handles.hh:77
vector_type & data_vector()
Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!!!) ...
Definition: Property.hh:183
void erase(Handle _hnd)
Complexity: O(k), (k - number of the elements in the set)
Definition: ArrayKernel.hh:762
void erase(iterator _it)
Complexity: O(1)
Definition: ArrayKernel.hh:772
Handle for a edge entity.
Definition: Handles.hh:139
void release_vertex_status()
Status Release API.
Definition: ArrayKernel.hh:606
void reset_status()
Reinitializes the status of all vertices using the StatusInfo default constructor, i.e.
Definition: ArrayKernel.hh:516
void set_bit(unsigned int _s)
set a certain bit
Definition: Status.hh:164
VertexStatusPropertyHandle status_pph(VertexHandle) const
status property by handle
Definition: ArrayKernel.hh:568

Project OpenMesh, ©  Computer Graphics Group, RWTH Aachen. Documentation generated using doxygen .