OpenMesh
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ArrayKernel.hh
1 /*===========================================================================*\
2  * *
3  * OpenMesh *
4  * Copyright (C) 2001-2011 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: 543 $ *
38  * $Date: 2012-02-29 14:21:06 +0100 (Mi, 29 Feb 2012) $ *
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 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  {return VertexHandle(&_v - &vertices_.front()); }
117 
118  HalfedgeHandle handle(const Halfedge& _he) const
119  {
120  // Calculate edge belonging to given halfedge
121  // There are two halfedges stored per edge
122  // Get memory position inside edge vector and devide by size of an edge
123  // to get the corresponding edge for the requested halfedge
124  uint eh = ( (char*)&_he - (char*)&edges_.front() ) / sizeof(Edge) ;
125  assert((&_he == &edges_[eh].halfedges_[0]) ||
126  (&_he == &edges_[eh].halfedges_[1]));
127  return ((&_he == &edges_[eh].halfedges_[0]) ?
128  HalfedgeHandle(eh<<1) : HalfedgeHandle((eh<<1)+1));
129  }
130 
131  EdgeHandle handle(const Edge& _e) const
132  { return EdgeHandle(&_e - &edges_.front()); }
133 
134  FaceHandle handle(const Face& _f) const
135  { return FaceHandle(&_f - &faces_.front()); }
136 
137 #define SIGNED(x) signed( (x) )
138  //checks handle validity - useful for debugging
139  bool is_valid_handle(VertexHandle _vh) const
140  { return 0 <= _vh.idx() && _vh.idx() < SIGNED(n_vertices()); }
141 
142  bool is_valid_handle(HalfedgeHandle _heh) const
143  { return 0 <= _heh.idx() && _heh.idx() < SIGNED(n_edges()*2); }
144 
145  bool is_valid_handle(EdgeHandle _eh) const
146  { return 0 <= _eh.idx() && _eh.idx() < SIGNED(n_edges()); }
147 
148  bool is_valid_handle(FaceHandle _fh) const
149  { return 0 <= _fh.idx() && _fh.idx() < SIGNED(n_faces()); }
150 
151  // --- item -> handle ---
152  const Vertex& vertex(VertexHandle _vh) const
153  {
154  assert(is_valid_handle(_vh));
155  return vertices_[_vh.idx()];
156  }
157 
158  Vertex& vertex(VertexHandle _vh)
159  {
160  assert(is_valid_handle(_vh));
161  return vertices_[_vh.idx()];
162  }
163 
164  const Halfedge& halfedge(HalfedgeHandle _heh) const
165  {
166  assert(is_valid_handle(_heh));
167  return edges_[_heh.idx() >> 1].halfedges_[_heh.idx() & 1];
168  }
169 
170  Halfedge& halfedge(HalfedgeHandle _heh)
171  {
172  assert(is_valid_handle(_heh));
173  return edges_[_heh.idx() >> 1].halfedges_[_heh.idx() & 1];
174  }
175 
176  const Edge& edge(EdgeHandle _eh) const
177  {
178  assert(is_valid_handle(_eh));
179  return edges_[_eh.idx()];
180  }
181 
182  Edge& edge(EdgeHandle _eh)
183  {
184  assert(is_valid_handle(_eh));
185  return edges_[_eh.idx()];
186  }
187 
188  const Face& face(FaceHandle _fh) const
189  {
190  assert(is_valid_handle(_fh));
191  return faces_[_fh.idx()];
192  }
193 
194  Face& face(FaceHandle _fh)
195  {
196  assert(is_valid_handle(_fh));
197  return faces_[_fh.idx()];
198  }
199 
200 #undef SIGNED
201 
202  // --- get i'th items ---
203 
204  VertexHandle vertex_handle(uint _i) const
205  { return (_i < n_vertices()) ? handle( vertices_[_i] ) : VertexHandle(); }
206 
207  HalfedgeHandle halfedge_handle(uint _i) const
208  {
209  return (_i < n_halfedges()) ?
210  halfedge_handle(edge_handle(_i/2), _i%2) : HalfedgeHandle();
211  }
212 
213  EdgeHandle edge_handle(uint _i) const
214  { return (_i < n_edges()) ? handle(edges_[_i]) : EdgeHandle(); }
215 
216  FaceHandle face_handle(uint _i) const
217  { return (_i < n_faces()) ? handle(faces_[_i]) : FaceHandle(); }
218 
219 public:
220 
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 
229  inline HalfedgeHandle new_edge(VertexHandle _start_vh, VertexHandle _end_vh)
230  {
231 // assert(_start_vh != _end_vh);
232  edges_.push_back(Edge());
233  eprops_resize(n_edges());//TODO:should it be push_back()?
234  hprops_resize(n_halfedges());//TODO:should it be push_back()?
235 
236  EdgeHandle eh(handle(edges_.back()));
237  HalfedgeHandle heh0(halfedge_handle(eh, 0));
238  HalfedgeHandle heh1(halfedge_handle(eh, 1));
239  set_vertex_handle(heh0, _end_vh);
240  set_vertex_handle(heh1, _start_vh);
241  return heh0;
242  }
243 
244  inline FaceHandle new_face()
245  {
246  faces_.push_back(Face());
247  fprops_resize(n_faces());
248  return handle(faces_.back());
249  }
250 
251  inline FaceHandle new_face(const Face& _f)
252  {
253  faces_.push_back(_f);
254  fprops_resize(n_faces());
255  return handle(faces_.back());
256  }
257 
258 public:
259  // --- resize/reserve ---
260  void resize( uint _n_vertices, uint _n_edges, uint _n_faces );
261  void reserve(uint _n_vertices, uint _n_edges, uint _n_faces );
262 
263  // --- deletion ---
264  void garbage_collection(bool _v=true, bool _e=true, bool _f=true);
265  void clear();
266 
267  // --- number of items ---
268  uint n_vertices() const { return vertices_.size(); }
269  uint n_halfedges() const { return 2*edges_.size(); }
270  uint n_edges() const { return edges_.size(); }
271  uint n_faces() const { return faces_.size(); }
272 
273  bool vertices_empty() const { return vertices_.empty(); }
274  bool halfedges_empty() const { return edges_.empty(); }
275  bool edges_empty() const { return edges_.empty(); }
276  bool faces_empty() const { return faces_.empty(); }
277 
278  // --- vertex connectivity ---
279 
280  HalfedgeHandle halfedge_handle(VertexHandle _vh) const
281  { return vertex(_vh).halfedge_handle_; }
282 
283  void set_halfedge_handle(VertexHandle _vh, HalfedgeHandle _heh)
284  {
285 // assert(is_valid_handle(_heh));
286  vertex(_vh).halfedge_handle_ = _heh;
287  }
288 
289  bool is_isolated(VertexHandle _vh) const
290  { return !halfedge_handle(_vh).is_valid(); }
291 
292  void set_isolated(VertexHandle _vh)
293  { vertex(_vh).halfedge_handle_.invalidate(); }
294 
295  uint delete_isolated_vertices();
296 
297  // --- halfedge connectivity ---
298  VertexHandle to_vertex_handle(HalfedgeHandle _heh) const
299  { return halfedge(_heh).vertex_handle_; }
300 
301  VertexHandle from_vertex_handle(HalfedgeHandle _heh) const
302  { return to_vertex_handle(opposite_halfedge_handle(_heh)); }
303 
304  void set_vertex_handle(HalfedgeHandle _heh, VertexHandle _vh)
305  {
306 // assert(is_valid_handle(_vh));
307  halfedge(_heh).vertex_handle_ = _vh;
308  }
309 
310  FaceHandle face_handle(HalfedgeHandle _heh) const
311  { return halfedge(_heh).face_handle_; }
312 
313  void set_face_handle(HalfedgeHandle _heh, FaceHandle _fh)
314  {
315 // assert(is_valid_handle(_fh));
316  halfedge(_heh).face_handle_ = _fh;
317  }
318 
319  void set_boundary(HalfedgeHandle _heh)
320  { halfedge(_heh).face_handle_.invalidate(); }
321 
323  bool is_boundary(HalfedgeHandle _heh) const
324  { return !face_handle(_heh).is_valid(); }
325 
326  HalfedgeHandle next_halfedge_handle(HalfedgeHandle _heh) const
327  { return halfedge(_heh).next_halfedge_handle_; }
328 
329  void set_next_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _nheh)
330  {
331  assert(is_valid_handle(_nheh));
332 // assert(to_vertex_handle(_heh) == from_vertex_handle(_nheh));
333  halfedge(_heh).next_halfedge_handle_ = _nheh;
334  set_prev_halfedge_handle(_nheh, _heh);
335  }
336 
337 
338  void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh)
339  {
340  assert(is_valid_handle(_pheh));
341  set_prev_halfedge_handle(_heh, _pheh, HasPrevHalfedge());
342  }
343 
344  void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh,
346  { halfedge(_heh).prev_halfedge_handle_ = _pheh; }
347 
348  void set_prev_halfedge_handle(HalfedgeHandle /* _heh */, HalfedgeHandle /* _pheh */,
350  {}
351 
352  HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh) const
353  { return prev_halfedge_handle(_heh, HasPrevHalfedge() ); }
354 
355  HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::True) const
356  { return halfedge(_heh).prev_halfedge_handle_; }
357 
358  HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::False) const
359  {
360  if (is_boundary(_heh))
361  {//iterating around the vertex should be faster than iterating the boundary
362  HalfedgeHandle curr_heh(opposite_halfedge_handle(_heh));
363  HalfedgeHandle next_heh(next_halfedge_handle(curr_heh));
364  do
365  {
366  curr_heh = opposite_halfedge_handle(next_heh);
367  next_heh = next_halfedge_handle(curr_heh);
368  }
369  while (next_heh != _heh);
370  return curr_heh;
371  }
372  else
373  {
374  HalfedgeHandle heh(_heh);
375  HalfedgeHandle next_heh(next_halfedge_handle(heh));
376  while (next_heh != _heh) {
377  heh = next_heh;
378  next_heh = next_halfedge_handle(next_heh);
379  }
380  return heh;
381  }
382  }
383 
384 
385  HalfedgeHandle opposite_halfedge_handle(HalfedgeHandle _heh) const
386  { return HalfedgeHandle((_heh.idx() & 1) ? _heh.idx()-1 : _heh.idx()+1); }
387 
388 
389  HalfedgeHandle ccw_rotated_halfedge_handle(HalfedgeHandle _heh) const
390  { return opposite_halfedge_handle(prev_halfedge_handle(_heh)); }
391 
392 
393  HalfedgeHandle cw_rotated_halfedge_handle(HalfedgeHandle _heh) const
394  { return next_halfedge_handle(opposite_halfedge_handle(_heh)); }
395 
396  // --- edge connectivity ---
397  HalfedgeHandle halfedge_handle(EdgeHandle _eh, uint _i) const
398  {
399  assert(_i<=1);
400  return HalfedgeHandle((_eh.idx() << 1) + _i);
401  }
402 
403  EdgeHandle edge_handle(HalfedgeHandle _heh) const
404  { return EdgeHandle(_heh.idx() >> 1); }
405 
406  // --- face connectivity ---
407  HalfedgeHandle halfedge_handle(FaceHandle _fh) const
408  { return face(_fh).halfedge_handle_; }
409 
410  void set_halfedge_handle(FaceHandle _fh, HalfedgeHandle _heh)
411  {
412 // assert(is_valid_handle(_heh));
413  face(_fh).halfedge_handle_ = _heh;
414  }
415 
417  //------------------------------------------------------------ vertex status
418  const StatusInfo& status(VertexHandle _vh) const
419  { return property(vertex_status_, _vh); }
420 
421  StatusInfo& status(VertexHandle _vh)
422  { return property(vertex_status_, _vh); }
423 
424  //----------------------------------------------------------- halfedge status
425  const StatusInfo& status(HalfedgeHandle _hh) const
426  { return property(halfedge_status_, _hh); }
427 
428  StatusInfo& status(HalfedgeHandle _hh)
429  { return property(halfedge_status_, _hh); }
430 
431  //--------------------------------------------------------------- edge status
432  const StatusInfo& status(EdgeHandle _eh) const
433  { return property(edge_status_, _eh); }
434 
435  StatusInfo& status(EdgeHandle _eh)
436  { return property(edge_status_, _eh); }
437 
438  //--------------------------------------------------------------- face status
439  const StatusInfo& status(FaceHandle _fh) const
440  { return property(face_status_, _fh); }
441 
442  StatusInfo& status(FaceHandle _fh)
443  { return property(face_status_, _fh); }
444 
445  inline bool has_vertex_status() const
446  { return vertex_status_.is_valid(); }
447 
448  inline bool has_halfedge_status() const
449  { return halfedge_status_.is_valid(); }
450 
451  inline bool has_edge_status() const
452  { return edge_status_.is_valid(); }
453 
454  inline bool has_face_status() const
455  { return face_status_.is_valid(); }
456 
457  inline VertexStatusPropertyHandle vertex_status_pph() const
458  { return vertex_status_; }
459 
460  inline HalfedgeStatusPropertyHandle halfedge_status_pph() const
461  { return halfedge_status_; }
462 
463  inline EdgeStatusPropertyHandle edge_status_pph() const
464  { return edge_status_; }
465 
466  inline FaceStatusPropertyHandle face_status_pph() const
467  { return face_status_; }
468 
471  { return vertex_status_pph(); }
472 
473  inline HalfedgeStatusPropertyHandle status_pph(HalfedgeHandle /*_hnd*/) const
474  { return halfedge_status_pph(); }
475 
476  inline EdgeStatusPropertyHandle status_pph(EdgeHandle /*_hnd*/) const
477  { return edge_status_pph(); }
478 
479  inline FaceStatusPropertyHandle status_pph(FaceHandle /*_hnd*/) const
480  { return face_status_pph(); }
481 
484  {
485  if (!refcount_vstatus_++)
486  add_property( vertex_status_, "v:status" );
487  }
488 
489  void request_halfedge_status()
490  {
491  if (!refcount_hstatus_++)
492  add_property( halfedge_status_, "h:status" );
493  }
494 
495  void request_edge_status()
496  {
497  if (!refcount_estatus_++)
498  add_property( edge_status_, "e:status" );
499  }
500 
501  void request_face_status()
502  {
503  if (!refcount_fstatus_++)
504  add_property( face_status_, "f:status" );
505  }
506 
509  {
510  if ((refcount_vstatus_ > 0) && (! --refcount_vstatus_))
511  remove_property(vertex_status_);
512  }
513 
514  void release_halfedge_status()
515  {
516  if ((refcount_hstatus_ > 0) && (! --refcount_hstatus_))
517  remove_property(halfedge_status_);
518  }
519 
520  void release_edge_status()
521  {
522  if ((refcount_estatus_ > 0) && (! --refcount_estatus_))
523  remove_property(edge_status_);
524  }
525 
526  void release_face_status()
527  {
528  if ((refcount_fstatus_ > 0) && (! --refcount_fstatus_))
529  remove_property(face_status_);
530  }
531 
533 
534  template <class Handle>
536  {
537  protected:
538  ArrayKernel& kernel_;
539 
540  public:
541  const uint bit_mask_;
542 
543  public:
544  StatusSetT(ArrayKernel& _kernel, uint _bit_mask)
545  : kernel_(_kernel), bit_mask_(_bit_mask)
546  {}
547 
548  ~StatusSetT()
549  {}
550 
551  inline bool is_in(Handle _hnd) const
552  { return kernel_.status(_hnd).is_bit_set(bit_mask_); }
553 
554  inline void insert(Handle _hnd)
555  { return kernel_.status(_hnd).set_bit(bit_mask_); }
556 
557  inline void erase(Handle _hnd)
558  { return kernel_.status(_hnd).unset_bit(bit_mask_); }
559 
561  uint size() const
562  {
563  uint n_elements = kernel_.status_pph(Handle()).is_valid() ?
564  kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
565  uint sz = 0;
566  for (uint i = 0; i < n_elements; ++i)
567  {
568  sz += (uint)is_in(Handle(i));
569  }
570  return sz;
571  }
572 
574  void clear()
575  {
576  uint n_elements = kernel_.status_pph(Handle()).is_valid() ?
577  kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
578  for (uint i = 0; i < n_elements; ++i)
579  {
580  erase(Handle(i));
581  }
582  }
583  };
584 
585  friend class StatusSetT<VertexHandle>;
586  friend class StatusSetT<EdgeHandle>;
587  friend class StatusSetT<FaceHandle>;
588  friend class StatusSetT<HalfedgeHandle>;
589 
591 
592  template <class Handle>
593  class AutoStatusSetT : public StatusSetT<Handle>
594  {
595  private:
596  typedef StatusSetT<Handle> Base;
597  public:
598  AutoStatusSetT(ArrayKernel& _kernel)
599  : StatusSetT<Handle>(_kernel, _kernel.pop_bit_mask(Handle()))
600  { /*assert(size() == 0);*/ } //the set should be empty on creation
601 
602  ~AutoStatusSetT()
603  {
604  //assert(size() == 0);//the set should be empty on leave?
605  Base::kernel_.push_bit_mask(Handle(), Base::bit_mask_);
606  }
607  };
608 
609  friend class AutoStatusSetT<VertexHandle>;
610  friend class AutoStatusSetT<EdgeHandle>;
611  friend class AutoStatusSetT<FaceHandle>;
612  friend class AutoStatusSetT<HalfedgeHandle>;
613 
618 
620 
621  template <class Handle>
622  class ExtStatusSetT : public AutoStatusSetT<Handle>
623  {
624  public:
626 
627  protected:
628  typedef std::vector<Handle> HandleContainer;
629  HandleContainer handles_;
630 
631  public:
632  typedef typename HandleContainer::iterator
633  iterator;
634  typedef typename HandleContainer::const_iterator
635  const_iterator;
636  public:
637  ExtStatusSetT(ArrayKernel& _kernel, uint _capacity_hint = 0)
638  : Base(_kernel)
639  { handles_.reserve(_capacity_hint); }
640 
641  ~ExtStatusSetT()
642  { clear(); }
643 
644  //set API
645  // Complexity: O(1)
646  inline void insert(Handle _hnd)
647  {
648  if (!is_in(_hnd))
649  {
650  Base::insert(_hnd);
651  handles_.push_back(_hnd);
652  }
653  }
654 
655  // Complexity: O(k), (k - number of the elements in the set)
656  inline void erase(Handle _hnd)
657  {
658  if (is_in(_hnd))
659  {
660  iterator it = std::find(begin(), end(), _hnd);
661  erase(it);
662  }
663  }
664 
665  // Complexity: O(1)
666  inline void erase(iterator _it)
667  {
668  assert(_it != end() && is_in(*_it));
669  clear(*_it);
670  *_it = handles_.back();
671  *_it.pop_back();
672  }
673 
674  inline void clear()
675  {
676  for (iterator it = begin(); it != end(); ++it)
677  {
678  assert(is_in(*it));
679  Base::erase(*it);
680  }
681  handles_.clear();
682  }
683 
685  inline uint size() const
686  { return handles_.size(); }
687  inline bool empty() const
688  { return handles_.empty(); }
689 
690  //Vector API
691  inline iterator begin()
692  { return handles_.begin(); }
693  inline const_iterator begin() const
694  { return handles_.begin(); }
695 
696  inline iterator end()
697  { return handles_.end(); }
698  inline const_iterator end() const
699  { return handles_.end(); }
700 
701  inline Handle& front()
702  { return handles_.front(); }
703  inline const Handle& front() const
704  { return handles_.front(); }
705 
706  inline Handle& back()
707  { return handles_.back(); }
708  inline const Handle& back() const
709  { return handles_.back(); }
710  };
711 
712  typedef ExtStatusSetT<FaceHandle> ExtFaceStatusSet;
713  typedef ExtStatusSetT<VertexHandle> ExtVertexStatusSet;
714  typedef ExtStatusSetT<EdgeHandle> ExtEdgeStatusSet;
715  typedef ExtStatusSetT<HalfedgeHandle> ExtHalfedgeStatusSet;
716 
717 private:
718  // iterators
719  typedef std::vector<Vertex> VertexContainer;
720  typedef std::vector<Edge> EdgeContainer;
721  typedef std::vector<Face> FaceContainer;
722  typedef VertexContainer::iterator KernelVertexIter;
723  typedef VertexContainer::const_iterator KernelConstVertexIter;
724  typedef EdgeContainer::iterator KernelEdgeIter;
725  typedef EdgeContainer::const_iterator KernelConstEdgeIter;
726  typedef FaceContainer::iterator KernelFaceIter;
727  typedef FaceContainer::const_iterator KernelConstFaceIter;
728  typedef std::vector<uint> BitMaskContainer;
729 
730 
731  KernelVertexIter vertices_begin() { return vertices_.begin(); }
732  KernelConstVertexIter vertices_begin() const { return vertices_.begin(); }
733  KernelVertexIter vertices_end() { return vertices_.end(); }
734  KernelConstVertexIter vertices_end() const { return vertices_.end(); }
735 
736  KernelEdgeIter edges_begin() { return edges_.begin(); }
737  KernelConstEdgeIter edges_begin() const { return edges_.begin(); }
738  KernelEdgeIter edges_end() { return edges_.end(); }
739  KernelConstEdgeIter edges_end() const { return edges_.end(); }
740 
741  KernelFaceIter faces_begin() { return faces_.begin(); }
742  KernelConstFaceIter faces_begin() const { return faces_.begin(); }
743  KernelFaceIter faces_end() { return faces_.end(); }
744  KernelConstFaceIter faces_end() const { return faces_.end(); }
745 
747  inline BitMaskContainer& bit_masks(VertexHandle /*_dummy_hnd*/)
748  { return vertex_bit_masks_; }
749  inline BitMaskContainer& bit_masks(EdgeHandle /*_dummy_hnd*/)
750  { return edge_bit_masks_; }
751  inline BitMaskContainer& bit_masks(FaceHandle /*_dummy_hnd*/)
752  { return face_bit_masks_; }
753  inline BitMaskContainer& bit_masks(HalfedgeHandle /*_dummy_hnd*/)
754  { return halfedge_bit_masks_; }
755 
756  template <class Handle>
757  uint pop_bit_mask(Handle _hnd)
758  {
759  assert(!bit_masks(_hnd).empty());//check if the client request too many status sets
760  uint bit_mask = bit_masks(_hnd).back();
761  bit_masks(_hnd).pop_back();
762  return bit_mask;
763  }
764 
765  template <class Handle>
766  void push_bit_mask(Handle _hnd, uint _bit_mask)
767  {
768  assert(std::find(bit_masks(_hnd).begin(), bit_masks(_hnd).end(), _bit_mask) ==
769  bit_masks(_hnd).end());//this mask should be not already used
770  bit_masks(_hnd).push_back(_bit_mask);
771  }
772 
773  void init_bit_masks(BitMaskContainer& _bmc);
774  void init_bit_masks();
775 
776 private:
777  VertexContainer vertices_;
778  EdgeContainer edges_;
779  FaceContainer faces_;
780 
781  VertexStatusPropertyHandle vertex_status_;
782  HalfedgeStatusPropertyHandle halfedge_status_;
783  EdgeStatusPropertyHandle edge_status_;
784  FaceStatusPropertyHandle face_status_;
785 
786  uint refcount_vstatus_;
787  uint refcount_hstatus_;
788  uint refcount_estatus_;
789  uint refcount_fstatus_;
790 
791  BitMaskContainer halfedge_bit_masks_;
792  BitMaskContainer edge_bit_masks_;
793  BitMaskContainer vertex_bit_masks_;
794  BitMaskContainer face_bit_masks_;
795 };
796 
797 //=============================================================================
798 } // namespace OpenMesh
799 //=============================================================================
800 #endif // OPENMESH_ARRAY_KERNEL_HH defined
801 //=============================================================================

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