OpenMesh
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ArrayKernel.hh
1 /*===========================================================================*\
2  * *
3  * OpenMesh *
4  * Copyright (C) 2001-2015 by Computer Graphics Group, RWTH Aachen *
5  * www.openmesh.org *
6  * *
7  *---------------------------------------------------------------------------*
8  * This file is part of OpenMesh. *
9  * *
10  * OpenMesh is free software: you can redistribute it and/or modify *
11  * it under the terms of the GNU Lesser General Public License as *
12  * published by the Free Software Foundation, either version 3 of *
13  * the License, or (at your option) any later version with the *
14  * following exceptions: *
15  * *
16  * If other files instantiate templates or use macros *
17  * or inline functions from this file, or you compile this file and *
18  * link it with other files to produce an executable, this file does *
19  * not by itself cause the resulting executable to be covered by the *
20  * GNU Lesser General Public License. This exception does not however *
21  * invalidate any other reasons why the executable file might be *
22  * covered by the GNU Lesser General Public License. *
23  * *
24  * OpenMesh is distributed in the hope that it will be useful, *
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
27  * GNU Lesser General Public License for more details. *
28  * *
29  * You should have received a copy of the GNU LesserGeneral Public *
30  * License along with OpenMesh. If not, *
31  * see <http://www.gnu.org/licenses/>. *
32  * *
33 \*===========================================================================*/
34 
35 /*===========================================================================*\
36  * *
37  * $Revision: 1188 $ *
38  * $Date: 2015-01-05 16:34:10 +0100 (Mo, 05 Jan 2015) $ *
39  * *
40 \*===========================================================================*/
41 
42 
43 //=============================================================================
44 //
45 // CLASS ArrayKernel
46 //
47 //=============================================================================
48 
49 
50 #ifndef OPENMESH_ARRAY_KERNEL_HH
51 #define OPENMESH_ARRAY_KERNEL_HH
52 
53 
54 //== INCLUDES =================================================================
55 #include <vector>
56 
57 #include <OpenMesh/Core/System/config.h>
58 #include <OpenMesh/Core/Utils/GenProg.hh>
59 
60 #include <OpenMesh/Core/Mesh/ArrayItems.hh>
61 #include <OpenMesh/Core/Mesh/BaseKernel.hh>
62 #include <OpenMesh/Core/Mesh/Status.hh>
63 
64 //== NAMESPACES ===============================================================
65 namespace OpenMesh {
66 
67 
68 //== CLASS DEFINITION =========================================================
85 class OPENMESHDLLEXPORT ArrayKernel : public BaseKernel, public ArrayItems
86 {
87 public:
88 
89  // handles
99 
100 public:
101 
102  // --- constructor/destructor ---
103  ArrayKernel();
104  virtual ~ArrayKernel();
105 
112  void assign_connectivity(const ArrayKernel& _other);
113 
114  // --- handle -> item ---
115  VertexHandle handle(const Vertex& _v) const;
116 
117  HalfedgeHandle handle(const Halfedge& _he) const;
118 
119  EdgeHandle handle(const Edge& _e) const;
120 
121  FaceHandle handle(const Face& _f) const;
122 
123 
125  bool is_valid_handle(VertexHandle _vh) const;
126 
128  bool is_valid_handle(HalfedgeHandle _heh) const;
129 
131  bool is_valid_handle(EdgeHandle _eh) const;
132 
134  bool is_valid_handle(FaceHandle _fh) const;
135 
136 
137  // --- item -> handle ---
138  const Vertex& vertex(VertexHandle _vh) const
139  {
140  assert(is_valid_handle(_vh));
141  return vertices_[_vh.idx()];
142  }
143 
144  Vertex& vertex(VertexHandle _vh)
145  {
146  assert(is_valid_handle(_vh));
147  return vertices_[_vh.idx()];
148  }
149 
150  const Halfedge& halfedge(HalfedgeHandle _heh) const
151  {
152  assert(is_valid_handle(_heh));
153  return edges_[_heh.idx() >> 1].halfedges_[_heh.idx() & 1];
154  }
155 
156  Halfedge& halfedge(HalfedgeHandle _heh)
157  {
158  assert(is_valid_handle(_heh));
159  return edges_[_heh.idx() >> 1].halfedges_[_heh.idx() & 1];
160  }
161 
162  const Edge& edge(EdgeHandle _eh) const
163  {
164  assert(is_valid_handle(_eh));
165  return edges_[_eh.idx()];
166  }
167 
168  Edge& edge(EdgeHandle _eh)
169  {
170  assert(is_valid_handle(_eh));
171  return edges_[_eh.idx()];
172  }
173 
174  const Face& face(FaceHandle _fh) const
175  {
176  assert(is_valid_handle(_fh));
177  return faces_[_fh.idx()];
178  }
179 
180  Face& face(FaceHandle _fh)
181  {
182  assert(is_valid_handle(_fh));
183  return faces_[_fh.idx()];
184  }
185 
186  // --- get i'th items ---
187 
188  VertexHandle vertex_handle(unsigned int _i) const
189  { return (_i < n_vertices()) ? handle( vertices_[_i] ) : VertexHandle(); }
190 
191  HalfedgeHandle halfedge_handle(unsigned int _i) const
192  {
193  return (_i < n_halfedges()) ?
194  halfedge_handle(edge_handle(_i/2), _i%2) : HalfedgeHandle();
195  }
196 
197  EdgeHandle edge_handle(unsigned int _i) const
198  { return (_i < n_edges()) ? handle(edges_[_i]) : EdgeHandle(); }
199 
200  FaceHandle face_handle(unsigned int _i) const
201  { return (_i < n_faces()) ? handle(faces_[_i]) : FaceHandle(); }
202 
203 public:
204 
205  inline VertexHandle new_vertex()
206  {
207  vertices_.push_back(Vertex());
208  vprops_resize(n_vertices());//TODO:should it be push_back()?
209 
210  return handle(vertices_.back());
211  }
212 
213  inline HalfedgeHandle new_edge(VertexHandle _start_vh, VertexHandle _end_vh)
214  {
215 // assert(_start_vh != _end_vh);
216  edges_.push_back(Edge());
217  eprops_resize(n_edges());//TODO:should it be push_back()?
218  hprops_resize(n_halfedges());//TODO:should it be push_back()?
219 
220  EdgeHandle eh(handle(edges_.back()));
221  HalfedgeHandle heh0(halfedge_handle(eh, 0));
222  HalfedgeHandle heh1(halfedge_handle(eh, 1));
223  set_vertex_handle(heh0, _end_vh);
224  set_vertex_handle(heh1, _start_vh);
225  return heh0;
226  }
227 
228  inline FaceHandle new_face()
229  {
230  faces_.push_back(Face());
231  fprops_resize(n_faces());
232  return handle(faces_.back());
233  }
234 
235  inline FaceHandle new_face(const Face& _f)
236  {
237  faces_.push_back(_f);
238  fprops_resize(n_faces());
239  return handle(faces_.back());
240  }
241 
242 public:
243  // --- resize/reserve ---
244  void resize( size_t _n_vertices, size_t _n_edges, size_t _n_faces );
245  void reserve(size_t _n_vertices, size_t _n_edges, size_t _n_faces );
246 
247  // --- deletion ---
263  void garbage_collection(bool _v=true, bool _e=true, bool _f=true);
264 
282  template<typename std_API_Container_VHandlePointer,
283  typename std_API_Container_HHandlePointer,
284  typename std_API_Container_FHandlePointer>
285  void garbage_collection(std_API_Container_VHandlePointer& vh_to_update,
286  std_API_Container_HHandlePointer& hh_to_update,
287  std_API_Container_FHandlePointer& fh_to_update,
288  bool _v=true, bool _e=true, bool _f=true);
289 
294  void clear();
295 
300  void clean();
301 
302  // --- number of items ---
303  size_t n_vertices() const { return vertices_.size(); }
304  size_t n_halfedges() const { return 2*edges_.size(); }
305  size_t n_edges() const { return edges_.size(); }
306  size_t n_faces() const { return faces_.size(); }
307 
308  bool vertices_empty() const { return vertices_.empty(); }
309  bool halfedges_empty() const { return edges_.empty(); }
310  bool edges_empty() const { return edges_.empty(); }
311  bool faces_empty() const { return faces_.empty(); }
312 
313  // --- vertex connectivity ---
314 
315  HalfedgeHandle halfedge_handle(VertexHandle _vh) const
316  { return vertex(_vh).halfedge_handle_; }
317 
318  void set_halfedge_handle(VertexHandle _vh, HalfedgeHandle _heh)
319  {
320 // assert(is_valid_handle(_heh));
321  vertex(_vh).halfedge_handle_ = _heh;
322  }
323 
324  bool is_isolated(VertexHandle _vh) const
325  { return !halfedge_handle(_vh).is_valid(); }
326 
327  void set_isolated(VertexHandle _vh)
328  { vertex(_vh).halfedge_handle_.invalidate(); }
329 
330  unsigned int delete_isolated_vertices();
331 
332  // --- halfedge connectivity ---
333  VertexHandle to_vertex_handle(HalfedgeHandle _heh) const
334  { return halfedge(_heh).vertex_handle_; }
335 
336  VertexHandle from_vertex_handle(HalfedgeHandle _heh) const
337  { return to_vertex_handle(opposite_halfedge_handle(_heh)); }
338 
339  void set_vertex_handle(HalfedgeHandle _heh, VertexHandle _vh)
340  {
341 // assert(is_valid_handle(_vh));
342  halfedge(_heh).vertex_handle_ = _vh;
343  }
344 
345  FaceHandle face_handle(HalfedgeHandle _heh) const
346  { return halfedge(_heh).face_handle_; }
347 
348  void set_face_handle(HalfedgeHandle _heh, FaceHandle _fh)
349  {
350 // assert(is_valid_handle(_fh));
351  halfedge(_heh).face_handle_ = _fh;
352  }
353 
354  void set_boundary(HalfedgeHandle _heh)
355  { halfedge(_heh).face_handle_.invalidate(); }
356 
358  bool is_boundary(HalfedgeHandle _heh) const
359  { return !face_handle(_heh).is_valid(); }
360 
361  HalfedgeHandle next_halfedge_handle(HalfedgeHandle _heh) const
362  { return halfedge(_heh).next_halfedge_handle_; }
363 
364  void set_next_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _nheh)
365  {
366  assert(is_valid_handle(_nheh));
367 // assert(to_vertex_handle(_heh) == from_vertex_handle(_nheh));
368  halfedge(_heh).next_halfedge_handle_ = _nheh;
369  set_prev_halfedge_handle(_nheh, _heh);
370  }
371 
372 
373  void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh)
374  {
375  assert(is_valid_handle(_pheh));
376  set_prev_halfedge_handle(_heh, _pheh, HasPrevHalfedge());
377  }
378 
379  void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh,
380  GenProg::TrueType)
381  { halfedge(_heh).prev_halfedge_handle_ = _pheh; }
382 
383  void set_prev_halfedge_handle(HalfedgeHandle /* _heh */, HalfedgeHandle /* _pheh */,
384  GenProg::FalseType)
385  {}
386 
387  HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh) const
388  { return prev_halfedge_handle(_heh, HasPrevHalfedge() ); }
389 
390  HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::TrueType) const
391  { return halfedge(_heh).prev_halfedge_handle_; }
392 
393  HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::FalseType) const
394  {
395  if (is_boundary(_heh))
396  {//iterating around the vertex should be faster than iterating the boundary
397  HalfedgeHandle curr_heh(opposite_halfedge_handle(_heh));
398  HalfedgeHandle next_heh(next_halfedge_handle(curr_heh));
399  do
400  {
401  curr_heh = opposite_halfedge_handle(next_heh);
402  next_heh = next_halfedge_handle(curr_heh);
403  }
404  while (next_heh != _heh);
405  return curr_heh;
406  }
407  else
408  {
409  HalfedgeHandle heh(_heh);
410  HalfedgeHandle next_heh(next_halfedge_handle(heh));
411  while (next_heh != _heh) {
412  heh = next_heh;
413  next_heh = next_halfedge_handle(next_heh);
414  }
415  return heh;
416  }
417  }
418 
419 
420  HalfedgeHandle opposite_halfedge_handle(HalfedgeHandle _heh) const
421  { return HalfedgeHandle((_heh.idx() & 1) ? _heh.idx()-1 : _heh.idx()+1); }
422 
423 
424  HalfedgeHandle ccw_rotated_halfedge_handle(HalfedgeHandle _heh) const
425  { return opposite_halfedge_handle(prev_halfedge_handle(_heh)); }
426 
427 
428  HalfedgeHandle cw_rotated_halfedge_handle(HalfedgeHandle _heh) const
429  { return next_halfedge_handle(opposite_halfedge_handle(_heh)); }
430 
431  // --- edge connectivity ---
432  HalfedgeHandle halfedge_handle(EdgeHandle _eh, unsigned int _i) const
433  {
434  assert(_i<=1);
435  return HalfedgeHandle((_eh.idx() << 1) + _i);
436  }
437 
438  EdgeHandle edge_handle(HalfedgeHandle _heh) const
439  { return EdgeHandle(_heh.idx() >> 1); }
440 
441  // --- face connectivity ---
442  HalfedgeHandle halfedge_handle(FaceHandle _fh) const
443  { return face(_fh).halfedge_handle_; }
444 
445  void set_halfedge_handle(FaceHandle _fh, HalfedgeHandle _heh)
446  {
447 // assert(is_valid_handle(_heh));
448  face(_fh).halfedge_handle_ = _heh;
449  }
450 
452  //------------------------------------------------------------ vertex status
453  const StatusInfo& status(VertexHandle _vh) const
454  { return property(vertex_status_, _vh); }
455 
456  StatusInfo& status(VertexHandle _vh)
457  { return property(vertex_status_, _vh); }
458 
459  //----------------------------------------------------------- halfedge status
460  const StatusInfo& status(HalfedgeHandle _hh) const
461  { return property(halfedge_status_, _hh); }
462 
463  StatusInfo& status(HalfedgeHandle _hh)
464  { return property(halfedge_status_, _hh); }
465 
466  //--------------------------------------------------------------- edge status
467  const StatusInfo& status(EdgeHandle _eh) const
468  { return property(edge_status_, _eh); }
469 
470  StatusInfo& status(EdgeHandle _eh)
471  { return property(edge_status_, _eh); }
472 
473  //--------------------------------------------------------------- face status
474  const StatusInfo& status(FaceHandle _fh) const
475  { return property(face_status_, _fh); }
476 
477  StatusInfo& status(FaceHandle _fh)
478  { return property(face_status_, _fh); }
479 
480  inline bool has_vertex_status() const
481  { return vertex_status_.is_valid(); }
482 
483  inline bool has_halfedge_status() const
484  { return halfedge_status_.is_valid(); }
485 
486  inline bool has_edge_status() const
487  { return edge_status_.is_valid(); }
488 
489  inline bool has_face_status() const
490  { return face_status_.is_valid(); }
491 
492  inline VertexStatusPropertyHandle vertex_status_pph() const
493  { return vertex_status_; }
494 
495  inline HalfedgeStatusPropertyHandle halfedge_status_pph() const
496  { return halfedge_status_; }
497 
498  inline EdgeStatusPropertyHandle edge_status_pph() const
499  { return edge_status_; }
500 
501  inline FaceStatusPropertyHandle face_status_pph() const
502  { return face_status_; }
503 
505  inline VertexStatusPropertyHandle status_pph(VertexHandle /*_hnd*/) const
506  { return vertex_status_pph(); }
507 
508  inline HalfedgeStatusPropertyHandle status_pph(HalfedgeHandle /*_hnd*/) const
509  { return halfedge_status_pph(); }
510 
511  inline EdgeStatusPropertyHandle status_pph(EdgeHandle /*_hnd*/) const
512  { return edge_status_pph(); }
513 
514  inline FaceStatusPropertyHandle status_pph(FaceHandle /*_hnd*/) const
515  { return face_status_pph(); }
516 
519  {
520  if (!refcount_vstatus_++)
521  add_property( vertex_status_, "v:status" );
522  }
523 
524  void request_halfedge_status()
525  {
526  if (!refcount_hstatus_++)
527  add_property( halfedge_status_, "h:status" );
528  }
529 
530  void request_edge_status()
531  {
532  if (!refcount_estatus_++)
533  add_property( edge_status_, "e:status" );
534  }
535 
536  void request_face_status()
537  {
538  if (!refcount_fstatus_++)
539  add_property( face_status_, "f:status" );
540  }
541 
544  {
545  if ((refcount_vstatus_ > 0) && (! --refcount_vstatus_))
546  remove_property(vertex_status_);
547  }
548 
549  void release_halfedge_status()
550  {
551  if ((refcount_hstatus_ > 0) && (! --refcount_hstatus_))
552  remove_property(halfedge_status_);
553  }
554 
555  void release_edge_status()
556  {
557  if ((refcount_estatus_ > 0) && (! --refcount_estatus_))
558  remove_property(edge_status_);
559  }
560 
561  void release_face_status()
562  {
563  if ((refcount_fstatus_ > 0) && (! --refcount_fstatus_))
564  remove_property(face_status_);
565  }
566 
568 
569  template <class Handle>
571  {
572  protected:
573  ArrayKernel& kernel_;
574 
575  public:
576  const unsigned int bit_mask_;
577 
578  public:
579  StatusSetT(ArrayKernel& _kernel, unsigned int _bit_mask)
580  : kernel_(_kernel), bit_mask_(_bit_mask)
581  {}
582 
583  ~StatusSetT()
584  {}
585 
586  inline bool is_in(Handle _hnd) const
587  { return kernel_.status(_hnd).is_bit_set(bit_mask_); }
588 
589  inline void insert(Handle _hnd)
590  { kernel_.status(_hnd).set_bit(bit_mask_); }
591 
592  inline void erase(Handle _hnd)
593  { kernel_.status(_hnd).unset_bit(bit_mask_); }
594 
596  unsigned int size() const
597  {
598  unsigned int n_elements = kernel_.status_pph(Handle()).is_valid() ?
599  kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
600  unsigned int sz = 0;
601  for (unsigned int i = 0; i < n_elements; ++i)
602  {
603  sz += (unsigned int)is_in(Handle(i));
604  }
605  return sz;
606  }
607 
609  void clear()
610  {
611  unsigned int n_elements = kernel_.status_pph(Handle()).is_valid() ?
612  kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
613  for (unsigned int i = 0; i < n_elements; ++i)
614  {
615  erase(Handle(i));
616  }
617  }
618  };
619 
620  friend class StatusSetT<VertexHandle>;
621  friend class StatusSetT<EdgeHandle>;
622  friend class StatusSetT<FaceHandle>;
623  friend class StatusSetT<HalfedgeHandle>;
624 
626 
627  template <class Handle>
628  class AutoStatusSetT : public StatusSetT<Handle>
629  {
630  private:
631  typedef StatusSetT<Handle> Base;
632  public:
633  AutoStatusSetT(ArrayKernel& _kernel)
634  : StatusSetT<Handle>(_kernel, _kernel.pop_bit_mask(Handle()))
635  { /*assert(size() == 0);*/ } //the set should be empty on creation
636 
637  ~AutoStatusSetT()
638  {
639  //assert(size() == 0);//the set should be empty on leave?
640  Base::kernel_.push_bit_mask(Handle(), Base::bit_mask_);
641  }
642  };
643 
644  friend class AutoStatusSetT<VertexHandle>;
645  friend class AutoStatusSetT<EdgeHandle>;
646  friend class AutoStatusSetT<FaceHandle>;
647  friend class AutoStatusSetT<HalfedgeHandle>;
648 
653 
655 
656  template <class Handle>
657  class ExtStatusSetT : public AutoStatusSetT<Handle>
658  {
659  public:
661 
662  protected:
663  typedef std::vector<Handle> HandleContainer;
664  HandleContainer handles_;
665 
666  public:
667  typedef typename HandleContainer::iterator
668  iterator;
669  typedef typename HandleContainer::const_iterator
670  const_iterator;
671  public:
672  ExtStatusSetT(ArrayKernel& _kernel, size_t _capacity_hint = 0)
673  : Base(_kernel)
674  { handles_.reserve(_capacity_hint); }
675 
676  ~ExtStatusSetT()
677  { clear(); }
678 
679  //set API
680  // Complexity: O(1)
681  inline void insert(Handle _hnd)
682  {
683  if (!is_in(_hnd))
684  {
685  Base::insert(_hnd);
686  handles_.push_back(_hnd);
687  }
688  }
689 
690  // Complexity: O(k), (k - number of the elements in the set)
691  inline void erase(Handle _hnd)
692  {
693  if (is_in(_hnd))
694  {
695  iterator it = std::find(begin(), end(), _hnd);
696  erase(it);
697  }
698  }
699 
700  // Complexity: O(1)
701  inline void erase(iterator _it)
702  {
703  assert(_it != end() && is_in(*_it));
704  clear(*_it);
705  *_it = handles_.back();
706  _it.pop_back();
707  }
708 
709  inline void clear()
710  {
711  for (iterator it = begin(); it != end(); ++it)
712  {
713  assert(is_in(*it));
714  Base::erase(*it);
715  }
716  handles_.clear();
717  }
718 
720  inline unsigned int size() const
721  { return handles_.size(); }
722  inline bool empty() const
723  { return handles_.empty(); }
724 
725  //Vector API
726  inline iterator begin()
727  { return handles_.begin(); }
728  inline const_iterator begin() const
729  { return handles_.begin(); }
730 
731  inline iterator end()
732  { return handles_.end(); }
733  inline const_iterator end() const
734  { return handles_.end(); }
735 
736  inline Handle& front()
737  { return handles_.front(); }
738  inline const Handle& front() const
739  { return handles_.front(); }
740 
741  inline Handle& back()
742  { return handles_.back(); }
743  inline const Handle& back() const
744  { return handles_.back(); }
745  };
746 
747  typedef ExtStatusSetT<FaceHandle> ExtFaceStatusSet;
748  typedef ExtStatusSetT<VertexHandle> ExtVertexStatusSet;
749  typedef ExtStatusSetT<EdgeHandle> ExtEdgeStatusSet;
750  typedef ExtStatusSetT<HalfedgeHandle> ExtHalfedgeStatusSet;
751 
752 private:
753  // iterators
754  typedef std::vector<Vertex> VertexContainer;
755  typedef std::vector<Edge> EdgeContainer;
756  typedef std::vector<Face> FaceContainer;
757  typedef VertexContainer::iterator KernelVertexIter;
758  typedef VertexContainer::const_iterator KernelConstVertexIter;
759  typedef EdgeContainer::iterator KernelEdgeIter;
760  typedef EdgeContainer::const_iterator KernelConstEdgeIter;
761  typedef FaceContainer::iterator KernelFaceIter;
762  typedef FaceContainer::const_iterator KernelConstFaceIter;
763  typedef std::vector<unsigned int> BitMaskContainer;
764 
765 
766  KernelVertexIter vertices_begin() { return vertices_.begin(); }
767  KernelConstVertexIter vertices_begin() const { return vertices_.begin(); }
768  KernelVertexIter vertices_end() { return vertices_.end(); }
769  KernelConstVertexIter vertices_end() const { return vertices_.end(); }
770 
771  KernelEdgeIter edges_begin() { return edges_.begin(); }
772  KernelConstEdgeIter edges_begin() const { return edges_.begin(); }
773  KernelEdgeIter edges_end() { return edges_.end(); }
774  KernelConstEdgeIter edges_end() const { return edges_.end(); }
775 
776  KernelFaceIter faces_begin() { return faces_.begin(); }
777  KernelConstFaceIter faces_begin() const { return faces_.begin(); }
778  KernelFaceIter faces_end() { return faces_.end(); }
779  KernelConstFaceIter faces_end() const { return faces_.end(); }
780 
782  inline BitMaskContainer& bit_masks(VertexHandle /*_dummy_hnd*/)
783  { return vertex_bit_masks_; }
784  inline BitMaskContainer& bit_masks(EdgeHandle /*_dummy_hnd*/)
785  { return edge_bit_masks_; }
786  inline BitMaskContainer& bit_masks(FaceHandle /*_dummy_hnd*/)
787  { return face_bit_masks_; }
788  inline BitMaskContainer& bit_masks(HalfedgeHandle /*_dummy_hnd*/)
789  { return halfedge_bit_masks_; }
790 
791  template <class Handle>
792  unsigned int pop_bit_mask(Handle _hnd)
793  {
794  assert(!bit_masks(_hnd).empty());//check if the client request too many status sets
795  unsigned int bit_mask = bit_masks(_hnd).back();
796  bit_masks(_hnd).pop_back();
797  return bit_mask;
798  }
799 
800  template <class Handle>
801  void push_bit_mask(Handle _hnd, unsigned int _bit_mask)
802  {
803  assert(std::find(bit_masks(_hnd).begin(), bit_masks(_hnd).end(), _bit_mask) ==
804  bit_masks(_hnd).end());//this mask should be not already used
805  bit_masks(_hnd).push_back(_bit_mask);
806  }
807 
808  void init_bit_masks(BitMaskContainer& _bmc);
809  void init_bit_masks();
810 
811 private:
812  VertexContainer vertices_;
813  EdgeContainer edges_;
814  FaceContainer faces_;
815 
816  VertexStatusPropertyHandle vertex_status_;
817  HalfedgeStatusPropertyHandle halfedge_status_;
818  EdgeStatusPropertyHandle edge_status_;
819  FaceStatusPropertyHandle face_status_;
820 
821  unsigned int refcount_vstatus_;
822  unsigned int refcount_hstatus_;
823  unsigned int refcount_estatus_;
824  unsigned int refcount_fstatus_;
825 
826  BitMaskContainer halfedge_bit_masks_;
827  BitMaskContainer edge_bit_masks_;
828  BitMaskContainer vertex_bit_masks_;
829  BitMaskContainer face_bit_masks_;
830 };
831 
832 
833 //=============================================================================
834 } // namespace OpenMesh
835 //=============================================================================
836 #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_ARRAY_KERNEL_C)
837 # define OPENMESH_ARRAY_KERNEL_TEMPLATES
838 # include "ArrayKernelT.cc"
839 #endif
840 //=============================================================================
841 #endif // OPENMESH_ARRAY_KERNEL_HH defined
842 //=============================================================================
void release_vertex_status()
Status Release API.
Definition: ArrayKernel.hh:543
bool is_bit_set(unsigned int _s) const
is a certain bit set ?
Definition: Status.hh:155
This class provides the basic property management like adding/removing properties and access to prope...
Definition: BaseKernel.hh:91
— ExtStatusSet API — (hybrid between a set and an array)
Definition: ArrayKernel.hh:657
PropertyT< T > & property(VPropHandleT< T > _ph)
Access a property.
Definition: BaseKernel.hh:286
void unset_bit(unsigned int _s)
unset a certain bit
Definition: Status.hh:159
int idx() const
Get the underlying index of this handle.
Definition: Handles.hh:67
void clear()
Note: O(n) complexity.
Definition: ArrayKernel.hh:609
Mesh kernel using arrays for mesh item storage.
Definition: ArrayKernel.hh:85
VertexStatusPropertyHandle status_pph(VertexHandle) const
status property by handle
Definition: ArrayKernel.hh:505
— AutoStatusSet API —
Definition: ArrayKernel.hh:628
const StatusInfo & status(VertexHandle _vh) const
Status Query API.
Definition: ArrayKernel.hh:453
Handle for a vertex entity.
Definition: Handles.hh:114
— StatusSet API —
Definition: ArrayKernel.hh:570
unsigned int size() const
Note: 0(n) complexity.
Definition: ArrayKernel.hh:596
void request_vertex_status()
Status Request API.
Definition: ArrayKernel.hh:518
Add status information to a base class.
Definition: Status.hh:92
void invalidate()
reset handle to be invalid
Definition: Handles.hh:75
Handle for a face entity.
Definition: Handles.hh:135
void set_bit(unsigned int _s)
set a certain bit
Definition: Status.hh:157
Handle for a halfedge entity.
Definition: Handles.hh:121
Handle for a edge entity.
Definition: Handles.hh:128
bool is_boundary(HalfedgeHandle _heh) const
Is halfedge _heh a boundary halfedge (is its face handle invalid) ?
Definition: ArrayKernel.hh:358
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:56
unsigned int size() const
Complexity: 0(1)
Definition: ArrayKernel.hh:720
bool is_valid() const
The handle is valid iff the index is not equal to -1.
Definition: Handles.hh:70

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