OpenMesh
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ArrayKernel.hh
1 /*===========================================================================*\
2  * *
3  * OpenMesh *
4  * Copyright (C) 2001-2012 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: 736 $ *
38  * $Date: 2012-10-08 09:30:49 +0200 (Mo, 08 Okt 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 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  {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  unsigned int 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(unsigned int _i) const
205  { return (_i < n_vertices()) ? handle( vertices_[_i] ) : VertexHandle(); }
206 
207  HalfedgeHandle halfedge_handle(unsigned int _i) const
208  {
209  return (_i < n_halfedges()) ?
210  halfedge_handle(edge_handle(_i/2), _i%2) : HalfedgeHandle();
211  }
212 
213  EdgeHandle edge_handle(unsigned int _i) const
214  { return (_i < n_edges()) ? handle(edges_[_i]) : EdgeHandle(); }
215 
216  FaceHandle face_handle(unsigned int _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( unsigned int _n_vertices, unsigned int _n_edges, unsigned int _n_faces );
261  void reserve(unsigned int _n_vertices, unsigned int _n_edges, unsigned int _n_faces );
262 
263  // --- deletion ---
279  void garbage_collection(bool _v=true, bool _e=true, bool _f=true);
280 
298  template<typename std_API_Container_VHandlePointer,
299  typename std_API_Container_HHandlePointer,
300  typename std_API_Container_FHandlePointer>
301  void garbage_collection(std_API_Container_VHandlePointer& vh_to_update,
302  std_API_Container_HHandlePointer& hh_to_update,
303  std_API_Container_FHandlePointer& fh_to_update,
304  bool _v=true, bool _e=true, bool _f=true);
305 
310  void clear();
311 
316  void clean();
317 
318  // --- number of items ---
319  unsigned int n_vertices() const { return vertices_.size(); }
320  unsigned int n_halfedges() const { return 2*edges_.size(); }
321  unsigned int n_edges() const { return edges_.size(); }
322  unsigned int n_faces() const { return faces_.size(); }
323 
324  bool vertices_empty() const { return vertices_.empty(); }
325  bool halfedges_empty() const { return edges_.empty(); }
326  bool edges_empty() const { return edges_.empty(); }
327  bool faces_empty() const { return faces_.empty(); }
328 
329  // --- vertex connectivity ---
330 
331  HalfedgeHandle halfedge_handle(VertexHandle _vh) const
332  { return vertex(_vh).halfedge_handle_; }
333 
334  void set_halfedge_handle(VertexHandle _vh, HalfedgeHandle _heh)
335  {
336 // assert(is_valid_handle(_heh));
337  vertex(_vh).halfedge_handle_ = _heh;
338  }
339 
340  bool is_isolated(VertexHandle _vh) const
341  { return !halfedge_handle(_vh).is_valid(); }
342 
343  void set_isolated(VertexHandle _vh)
344  { vertex(_vh).halfedge_handle_.invalidate(); }
345 
346  unsigned int delete_isolated_vertices();
347 
348  // --- halfedge connectivity ---
349  VertexHandle to_vertex_handle(HalfedgeHandle _heh) const
350  { return halfedge(_heh).vertex_handle_; }
351 
352  VertexHandle from_vertex_handle(HalfedgeHandle _heh) const
353  { return to_vertex_handle(opposite_halfedge_handle(_heh)); }
354 
355  void set_vertex_handle(HalfedgeHandle _heh, VertexHandle _vh)
356  {
357 // assert(is_valid_handle(_vh));
358  halfedge(_heh).vertex_handle_ = _vh;
359  }
360 
361  FaceHandle face_handle(HalfedgeHandle _heh) const
362  { return halfedge(_heh).face_handle_; }
363 
364  void set_face_handle(HalfedgeHandle _heh, FaceHandle _fh)
365  {
366 // assert(is_valid_handle(_fh));
367  halfedge(_heh).face_handle_ = _fh;
368  }
369 
370  void set_boundary(HalfedgeHandle _heh)
371  { halfedge(_heh).face_handle_.invalidate(); }
372 
374  bool is_boundary(HalfedgeHandle _heh) const
375  { return !face_handle(_heh).is_valid(); }
376 
377  HalfedgeHandle next_halfedge_handle(HalfedgeHandle _heh) const
378  { return halfedge(_heh).next_halfedge_handle_; }
379 
380  void set_next_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _nheh)
381  {
382  assert(is_valid_handle(_nheh));
383 // assert(to_vertex_handle(_heh) == from_vertex_handle(_nheh));
384  halfedge(_heh).next_halfedge_handle_ = _nheh;
385  set_prev_halfedge_handle(_nheh, _heh);
386  }
387 
388 
389  void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh)
390  {
391  assert(is_valid_handle(_pheh));
392  set_prev_halfedge_handle(_heh, _pheh, HasPrevHalfedge());
393  }
394 
395  void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh,
396  GenProg::True)
397  { halfedge(_heh).prev_halfedge_handle_ = _pheh; }
398 
399  void set_prev_halfedge_handle(HalfedgeHandle /* _heh */, HalfedgeHandle /* _pheh */,
400  GenProg::False)
401  {}
402 
403  HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh) const
404  { return prev_halfedge_handle(_heh, HasPrevHalfedge() ); }
405 
406  HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::True) const
407  { return halfedge(_heh).prev_halfedge_handle_; }
408 
409  HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::False) const
410  {
411  if (is_boundary(_heh))
412  {//iterating around the vertex should be faster than iterating the boundary
413  HalfedgeHandle curr_heh(opposite_halfedge_handle(_heh));
414  HalfedgeHandle next_heh(next_halfedge_handle(curr_heh));
415  do
416  {
417  curr_heh = opposite_halfedge_handle(next_heh);
418  next_heh = next_halfedge_handle(curr_heh);
419  }
420  while (next_heh != _heh);
421  return curr_heh;
422  }
423  else
424  {
425  HalfedgeHandle heh(_heh);
426  HalfedgeHandle next_heh(next_halfedge_handle(heh));
427  while (next_heh != _heh) {
428  heh = next_heh;
429  next_heh = next_halfedge_handle(next_heh);
430  }
431  return heh;
432  }
433  }
434 
435 
436  HalfedgeHandle opposite_halfedge_handle(HalfedgeHandle _heh) const
437  { return HalfedgeHandle((_heh.idx() & 1) ? _heh.idx()-1 : _heh.idx()+1); }
438 
439 
440  HalfedgeHandle ccw_rotated_halfedge_handle(HalfedgeHandle _heh) const
441  { return opposite_halfedge_handle(prev_halfedge_handle(_heh)); }
442 
443 
444  HalfedgeHandle cw_rotated_halfedge_handle(HalfedgeHandle _heh) const
445  { return next_halfedge_handle(opposite_halfedge_handle(_heh)); }
446 
447  // --- edge connectivity ---
448  HalfedgeHandle halfedge_handle(EdgeHandle _eh, unsigned int _i) const
449  {
450  assert(_i<=1);
451  return HalfedgeHandle((_eh.idx() << 1) + _i);
452  }
453 
454  EdgeHandle edge_handle(HalfedgeHandle _heh) const
455  { return EdgeHandle(_heh.idx() >> 1); }
456 
457  // --- face connectivity ---
458  HalfedgeHandle halfedge_handle(FaceHandle _fh) const
459  { return face(_fh).halfedge_handle_; }
460 
461  void set_halfedge_handle(FaceHandle _fh, HalfedgeHandle _heh)
462  {
463 // assert(is_valid_handle(_heh));
464  face(_fh).halfedge_handle_ = _heh;
465  }
466 
468  //------------------------------------------------------------ vertex status
469  const StatusInfo& status(VertexHandle _vh) const
470  { return property(vertex_status_, _vh); }
471 
472  StatusInfo& status(VertexHandle _vh)
473  { return property(vertex_status_, _vh); }
474 
475  //----------------------------------------------------------- halfedge status
476  const StatusInfo& status(HalfedgeHandle _hh) const
477  { return property(halfedge_status_, _hh); }
478 
479  StatusInfo& status(HalfedgeHandle _hh)
480  { return property(halfedge_status_, _hh); }
481 
482  //--------------------------------------------------------------- edge status
483  const StatusInfo& status(EdgeHandle _eh) const
484  { return property(edge_status_, _eh); }
485 
486  StatusInfo& status(EdgeHandle _eh)
487  { return property(edge_status_, _eh); }
488 
489  //--------------------------------------------------------------- face status
490  const StatusInfo& status(FaceHandle _fh) const
491  { return property(face_status_, _fh); }
492 
493  StatusInfo& status(FaceHandle _fh)
494  { return property(face_status_, _fh); }
495 
496  inline bool has_vertex_status() const
497  { return vertex_status_.is_valid(); }
498 
499  inline bool has_halfedge_status() const
500  { return halfedge_status_.is_valid(); }
501 
502  inline bool has_edge_status() const
503  { return edge_status_.is_valid(); }
504 
505  inline bool has_face_status() const
506  { return face_status_.is_valid(); }
507 
508  inline VertexStatusPropertyHandle vertex_status_pph() const
509  { return vertex_status_; }
510 
511  inline HalfedgeStatusPropertyHandle halfedge_status_pph() const
512  { return halfedge_status_; }
513 
514  inline EdgeStatusPropertyHandle edge_status_pph() const
515  { return edge_status_; }
516 
517  inline FaceStatusPropertyHandle face_status_pph() const
518  { return face_status_; }
519 
521  inline VertexStatusPropertyHandle status_pph(VertexHandle /*_hnd*/) const
522  { return vertex_status_pph(); }
523 
524  inline HalfedgeStatusPropertyHandle status_pph(HalfedgeHandle /*_hnd*/) const
525  { return halfedge_status_pph(); }
526 
527  inline EdgeStatusPropertyHandle status_pph(EdgeHandle /*_hnd*/) const
528  { return edge_status_pph(); }
529 
530  inline FaceStatusPropertyHandle status_pph(FaceHandle /*_hnd*/) const
531  { return face_status_pph(); }
532 
534  void request_vertex_status()
535  {
536  if (!refcount_vstatus_++)
537  add_property( vertex_status_, "v:status" );
538  }
539 
540  void request_halfedge_status()
541  {
542  if (!refcount_hstatus_++)
543  add_property( halfedge_status_, "h:status" );
544  }
545 
546  void request_edge_status()
547  {
548  if (!refcount_estatus_++)
549  add_property( edge_status_, "e:status" );
550  }
551 
552  void request_face_status()
553  {
554  if (!refcount_fstatus_++)
555  add_property( face_status_, "f:status" );
556  }
557 
559  void release_vertex_status()
560  {
561  if ((refcount_vstatus_ > 0) && (! --refcount_vstatus_))
562  remove_property(vertex_status_);
563  }
564 
565  void release_halfedge_status()
566  {
567  if ((refcount_hstatus_ > 0) && (! --refcount_hstatus_))
568  remove_property(halfedge_status_);
569  }
570 
571  void release_edge_status()
572  {
573  if ((refcount_estatus_ > 0) && (! --refcount_estatus_))
574  remove_property(edge_status_);
575  }
576 
577  void release_face_status()
578  {
579  if ((refcount_fstatus_ > 0) && (! --refcount_fstatus_))
580  remove_property(face_status_);
581  }
582 
584 
585  template <class Handle>
587  {
588  protected:
589  ArrayKernel& kernel_;
590 
591  public:
592  const unsigned int bit_mask_;
593 
594  public:
595  StatusSetT(ArrayKernel& _kernel, unsigned int _bit_mask)
596  : kernel_(_kernel), bit_mask_(_bit_mask)
597  {}
598 
599  ~StatusSetT()
600  {}
601 
602  inline bool is_in(Handle _hnd) const
603  { return kernel_.status(_hnd).is_bit_set(bit_mask_); }
604 
605  inline void insert(Handle _hnd)
606  { kernel_.status(_hnd).set_bit(bit_mask_); }
607 
608  inline void erase(Handle _hnd)
609  { kernel_.status(_hnd).unset_bit(bit_mask_); }
610 
612  unsigned int size() const
613  {
614  unsigned int n_elements = kernel_.status_pph(Handle()).is_valid() ?
615  kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
616  unsigned int sz = 0;
617  for (unsigned int i = 0; i < n_elements; ++i)
618  {
619  sz += (unsigned int)is_in(Handle(i));
620  }
621  return sz;
622  }
623 
625  void clear()
626  {
627  unsigned int n_elements = kernel_.status_pph(Handle()).is_valid() ?
628  kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
629  for (unsigned int i = 0; i < n_elements; ++i)
630  {
631  erase(Handle(i));
632  }
633  }
634  };
635 
636  friend class StatusSetT<VertexHandle>;
637  friend class StatusSetT<EdgeHandle>;
638  friend class StatusSetT<FaceHandle>;
639  friend class StatusSetT<HalfedgeHandle>;
640 
642 
643  template <class Handle>
644  class AutoStatusSetT : public StatusSetT<Handle>
645  {
646  private:
647  typedef StatusSetT<Handle> Base;
648  public:
649  AutoStatusSetT(ArrayKernel& _kernel)
650  : StatusSetT<Handle>(_kernel, _kernel.pop_bit_mask(Handle()))
651  { /*assert(size() == 0);*/ } //the set should be empty on creation
652 
653  ~AutoStatusSetT()
654  {
655  //assert(size() == 0);//the set should be empty on leave?
656  Base::kernel_.push_bit_mask(Handle(), Base::bit_mask_);
657  }
658  };
659 
660  friend class AutoStatusSetT<VertexHandle>;
661  friend class AutoStatusSetT<EdgeHandle>;
662  friend class AutoStatusSetT<FaceHandle>;
663  friend class AutoStatusSetT<HalfedgeHandle>;
664 
669 
671 
672  template <class Handle>
673  class ExtStatusSetT : public AutoStatusSetT<Handle>
674  {
675  public:
677 
678  protected:
679  typedef std::vector<Handle> HandleContainer;
680  HandleContainer handles_;
681 
682  public:
683  typedef typename HandleContainer::iterator
684  iterator;
685  typedef typename HandleContainer::const_iterator
686  const_iterator;
687  public:
688  ExtStatusSetT(ArrayKernel& _kernel, unsigned int _capacity_hint = 0)
689  : Base(_kernel)
690  { handles_.reserve(_capacity_hint); }
691 
692  ~ExtStatusSetT()
693  { clear(); }
694 
695  //set API
696  // Complexity: O(1)
697  inline void insert(Handle _hnd)
698  {
699  if (!is_in(_hnd))
700  {
701  Base::insert(_hnd);
702  handles_.push_back(_hnd);
703  }
704  }
705 
706  // Complexity: O(k), (k - number of the elements in the set)
707  inline void erase(Handle _hnd)
708  {
709  if (is_in(_hnd))
710  {
711  iterator it = std::find(begin(), end(), _hnd);
712  erase(it);
713  }
714  }
715 
716  // Complexity: O(1)
717  inline void erase(iterator _it)
718  {
719  assert(_it != end() && is_in(*_it));
720  clear(*_it);
721  *_it = handles_.back();
722  *_it.pop_back();
723  }
724 
725  inline void clear()
726  {
727  for (iterator it = begin(); it != end(); ++it)
728  {
729  assert(is_in(*it));
730  Base::erase(*it);
731  }
732  handles_.clear();
733  }
734 
736  inline unsigned int size() const
737  { return handles_.size(); }
738  inline bool empty() const
739  { return handles_.empty(); }
740 
741  //Vector API
742  inline iterator begin()
743  { return handles_.begin(); }
744  inline const_iterator begin() const
745  { return handles_.begin(); }
746 
747  inline iterator end()
748  { return handles_.end(); }
749  inline const_iterator end() const
750  { return handles_.end(); }
751 
752  inline Handle& front()
753  { return handles_.front(); }
754  inline const Handle& front() const
755  { return handles_.front(); }
756 
757  inline Handle& back()
758  { return handles_.back(); }
759  inline const Handle& back() const
760  { return handles_.back(); }
761  };
762 
763  typedef ExtStatusSetT<FaceHandle> ExtFaceStatusSet;
764  typedef ExtStatusSetT<VertexHandle> ExtVertexStatusSet;
765  typedef ExtStatusSetT<EdgeHandle> ExtEdgeStatusSet;
766  typedef ExtStatusSetT<HalfedgeHandle> ExtHalfedgeStatusSet;
767 
768 private:
769  // iterators
770  typedef std::vector<Vertex> VertexContainer;
771  typedef std::vector<Edge> EdgeContainer;
772  typedef std::vector<Face> FaceContainer;
773  typedef VertexContainer::iterator KernelVertexIter;
774  typedef VertexContainer::const_iterator KernelConstVertexIter;
775  typedef EdgeContainer::iterator KernelEdgeIter;
776  typedef EdgeContainer::const_iterator KernelConstEdgeIter;
777  typedef FaceContainer::iterator KernelFaceIter;
778  typedef FaceContainer::const_iterator KernelConstFaceIter;
779  typedef std::vector<unsigned int> BitMaskContainer;
780 
781 
782  KernelVertexIter vertices_begin() { return vertices_.begin(); }
783  KernelConstVertexIter vertices_begin() const { return vertices_.begin(); }
784  KernelVertexIter vertices_end() { return vertices_.end(); }
785  KernelConstVertexIter vertices_end() const { return vertices_.end(); }
786 
787  KernelEdgeIter edges_begin() { return edges_.begin(); }
788  KernelConstEdgeIter edges_begin() const { return edges_.begin(); }
789  KernelEdgeIter edges_end() { return edges_.end(); }
790  KernelConstEdgeIter edges_end() const { return edges_.end(); }
791 
792  KernelFaceIter faces_begin() { return faces_.begin(); }
793  KernelConstFaceIter faces_begin() const { return faces_.begin(); }
794  KernelFaceIter faces_end() { return faces_.end(); }
795  KernelConstFaceIter faces_end() const { return faces_.end(); }
796 
798  inline BitMaskContainer& bit_masks(VertexHandle /*_dummy_hnd*/)
799  { return vertex_bit_masks_; }
800  inline BitMaskContainer& bit_masks(EdgeHandle /*_dummy_hnd*/)
801  { return edge_bit_masks_; }
802  inline BitMaskContainer& bit_masks(FaceHandle /*_dummy_hnd*/)
803  { return face_bit_masks_; }
804  inline BitMaskContainer& bit_masks(HalfedgeHandle /*_dummy_hnd*/)
805  { return halfedge_bit_masks_; }
806 
807  template <class Handle>
808  unsigned int pop_bit_mask(Handle _hnd)
809  {
810  assert(!bit_masks(_hnd).empty());//check if the client request too many status sets
811  unsigned int bit_mask = bit_masks(_hnd).back();
812  bit_masks(_hnd).pop_back();
813  return bit_mask;
814  }
815 
816  template <class Handle>
817  void push_bit_mask(Handle _hnd, unsigned int _bit_mask)
818  {
819  assert(std::find(bit_masks(_hnd).begin(), bit_masks(_hnd).end(), _bit_mask) ==
820  bit_masks(_hnd).end());//this mask should be not already used
821  bit_masks(_hnd).push_back(_bit_mask);
822  }
823 
824  void init_bit_masks(BitMaskContainer& _bmc);
825  void init_bit_masks();
826 
827 private:
828  VertexContainer vertices_;
829  EdgeContainer edges_;
830  FaceContainer faces_;
831 
832  VertexStatusPropertyHandle vertex_status_;
833  HalfedgeStatusPropertyHandle halfedge_status_;
834  EdgeStatusPropertyHandle edge_status_;
835  FaceStatusPropertyHandle face_status_;
836 
837  unsigned int refcount_vstatus_;
838  unsigned int refcount_hstatus_;
839  unsigned int refcount_estatus_;
840  unsigned int refcount_fstatus_;
841 
842  BitMaskContainer halfedge_bit_masks_;
843  BitMaskContainer edge_bit_masks_;
844  BitMaskContainer vertex_bit_masks_;
845  BitMaskContainer face_bit_masks_;
846 };
847 
848 
849 //=============================================================================
850 } // namespace OpenMesh
851 //=============================================================================
852 #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_ARRAY_KERNEL_C)
853 # define OPENMESH_ARRAY_KERNEL_TEMPLATES
854 # include "ArrayKernelT.cc"
855 #endif
856 //=============================================================================
857 #endif // OPENMESH_ARRAY_KERNEL_HH defined
858 //=============================================================================

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