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, 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 
212  inline VertexHandle new_vertex()
213  {
214  vertices_.push_back(Vertex());
215  vprops_resize(n_vertices());//TODO:should it be push_back()?
216 
217  return handle(vertices_.back());
218  }
219 
220  inline HalfedgeHandle new_edge(VertexHandle _start_vh, VertexHandle _end_vh)
221  {
222 // assert(_start_vh != _end_vh);
223  edges_.push_back(Edge());
224  eprops_resize(n_edges());//TODO:should it be push_back()?
225  hprops_resize(n_halfedges());//TODO:should it be push_back()?
226 
227  EdgeHandle eh(handle(edges_.back()));
228  HalfedgeHandle heh0(halfedge_handle(eh, 0));
229  HalfedgeHandle heh1(halfedge_handle(eh, 1));
230  set_vertex_handle(heh0, _end_vh);
231  set_vertex_handle(heh1, _start_vh);
232  return heh0;
233  }
234 
235  inline FaceHandle new_face()
236  {
237  faces_.push_back(Face());
238  fprops_resize(n_faces());
239  return handle(faces_.back());
240  }
241 
242  inline FaceHandle new_face(const Face& _f)
243  {
244  faces_.push_back(_f);
245  fprops_resize(n_faces());
246  return handle(faces_.back());
247  }
248 
249 public:
250  // --- resize/reserve ---
251  void resize( size_t _n_vertices, size_t _n_edges, size_t _n_faces );
252  void reserve(size_t _n_vertices, size_t _n_edges, size_t _n_faces );
253 
254  // --- deletion ---
270  void garbage_collection(bool _v=true, bool _e=true, bool _f=true);
271 
289  template<typename std_API_Container_VHandlePointer,
290  typename std_API_Container_HHandlePointer,
291  typename std_API_Container_FHandlePointer>
292  void garbage_collection(std_API_Container_VHandlePointer& vh_to_update,
293  std_API_Container_HHandlePointer& hh_to_update,
294  std_API_Container_FHandlePointer& fh_to_update,
295  bool _v=true, bool _e=true, bool _f=true);
296 
301  void clear();
302 
307  void clean();
308 
315  void clean_keep_reservation();
316 
317  // --- number of items ---
318  size_t n_vertices() const { return vertices_.size(); }
319  size_t n_halfedges() const { return 2*edges_.size(); }
320  size_t n_edges() const { return edges_.size(); }
321  size_t n_faces() const { return faces_.size(); }
322 
323  bool vertices_empty() const { return vertices_.empty(); }
324  bool halfedges_empty() const { return edges_.empty(); }
325  bool edges_empty() const { return edges_.empty(); }
326  bool faces_empty() const { return faces_.empty(); }
327 
328  // --- vertex connectivity ---
329 
330  HalfedgeHandle halfedge_handle(VertexHandle _vh) const
331  { return vertex(_vh).halfedge_handle_; }
332 
333  void set_halfedge_handle(VertexHandle _vh, HalfedgeHandle _heh)
334  {
335 // assert(is_valid_handle(_heh));
336  vertex(_vh).halfedge_handle_ = _heh;
337  }
338 
339  bool is_isolated(VertexHandle _vh) const
340  { return !halfedge_handle(_vh).is_valid(); }
341 
342  void set_isolated(VertexHandle _vh)
343  { vertex(_vh).halfedge_handle_.invalidate(); }
344 
345  unsigned int delete_isolated_vertices();
346 
347  // --- halfedge connectivity ---
348  VertexHandle to_vertex_handle(HalfedgeHandle _heh) const
349  { return halfedge(_heh).vertex_handle_; }
350 
351  VertexHandle from_vertex_handle(HalfedgeHandle _heh) const
352  { return to_vertex_handle(opposite_halfedge_handle(_heh)); }
353 
354  void set_vertex_handle(HalfedgeHandle _heh, VertexHandle _vh)
355  {
356 // assert(is_valid_handle(_vh));
357  halfedge(_heh).vertex_handle_ = _vh;
358  }
359 
360  FaceHandle face_handle(HalfedgeHandle _heh) const
361  { return halfedge(_heh).face_handle_; }
362 
363  void set_face_handle(HalfedgeHandle _heh, FaceHandle _fh)
364  {
365 // assert(is_valid_handle(_fh));
366  halfedge(_heh).face_handle_ = _fh;
367  }
368 
369  void set_boundary(HalfedgeHandle _heh)
370  { halfedge(_heh).face_handle_.invalidate(); }
371 
373  bool is_boundary(HalfedgeHandle _heh) const
374  { return !face_handle(_heh).is_valid(); }
375 
376  HalfedgeHandle next_halfedge_handle(HalfedgeHandle _heh) const
377  { return halfedge(_heh).next_halfedge_handle_; }
378 
379  void set_next_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _nheh)
380  {
381  assert(is_valid_handle(_nheh));
382 // assert(to_vertex_handle(_heh) == from_vertex_handle(_nheh));
383  halfedge(_heh).next_halfedge_handle_ = _nheh;
384  set_prev_halfedge_handle(_nheh, _heh);
385  }
386 
387 
388  void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh)
389  {
390  assert(is_valid_handle(_pheh));
391  set_prev_halfedge_handle(_heh, _pheh, HasPrevHalfedge());
392  }
393 
394  void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh,
395  GenProg::TrueType)
396  { halfedge(_heh).prev_halfedge_handle_ = _pheh; }
397 
398  void set_prev_halfedge_handle(HalfedgeHandle /* _heh */, HalfedgeHandle /* _pheh */,
399  GenProg::FalseType)
400  {}
401 
402  HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh) const
403  { return prev_halfedge_handle(_heh, HasPrevHalfedge() ); }
404 
405  HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::TrueType) const
406  { return halfedge(_heh).prev_halfedge_handle_; }
407 
408  HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::FalseType) const
409  {
410  if (is_boundary(_heh))
411  {//iterating around the vertex should be faster than iterating the boundary
412  HalfedgeHandle curr_heh(opposite_halfedge_handle(_heh));
413  HalfedgeHandle next_heh(next_halfedge_handle(curr_heh));
414  do
415  {
416  curr_heh = opposite_halfedge_handle(next_heh);
417  next_heh = next_halfedge_handle(curr_heh);
418  }
419  while (next_heh != _heh);
420  return curr_heh;
421  }
422  else
423  {
424  HalfedgeHandle heh(_heh);
425  HalfedgeHandle next_heh(next_halfedge_handle(heh));
426  while (next_heh != _heh) {
427  heh = next_heh;
428  next_heh = next_halfedge_handle(next_heh);
429  }
430  return heh;
431  }
432  }
433 
434 
435  HalfedgeHandle opposite_halfedge_handle(HalfedgeHandle _heh) const
436  { return HalfedgeHandle(_heh.idx() ^ 1); }
437 
438 
439  HalfedgeHandle ccw_rotated_halfedge_handle(HalfedgeHandle _heh) const
440  { return opposite_halfedge_handle(prev_halfedge_handle(_heh)); }
441 
442 
443  HalfedgeHandle cw_rotated_halfedge_handle(HalfedgeHandle _heh) const
444  { return next_halfedge_handle(opposite_halfedge_handle(_heh)); }
445 
446  // --- edge connectivity ---
447  static HalfedgeHandle s_halfedge_handle(EdgeHandle _eh, unsigned int _i)
448  {
449  assert(_i<=1);
450  return HalfedgeHandle((_eh.idx() << 1) + _i);
451  }
452 
453  static EdgeHandle s_edge_handle(HalfedgeHandle _heh)
454  { return EdgeHandle(_heh.idx() >> 1); }
455 
456  HalfedgeHandle halfedge_handle(EdgeHandle _eh, unsigned int _i) const
457  {
458  return s_halfedge_handle(_eh, _i);
459  }
460 
461  EdgeHandle edge_handle(HalfedgeHandle _heh) const
462  { return s_edge_handle(_heh); }
463 
464  // --- face connectivity ---
465  HalfedgeHandle halfedge_handle(FaceHandle _fh) const
466  { return face(_fh).halfedge_handle_; }
467 
468  void set_halfedge_handle(FaceHandle _fh, HalfedgeHandle _heh)
469  {
470 // assert(is_valid_handle(_heh));
471  face(_fh).halfedge_handle_ = _heh;
472  }
473 
475  //------------------------------------------------------------ vertex status
476  const StatusInfo& status(VertexHandle _vh) const
477  { return property(vertex_status_, _vh); }
478 
479  StatusInfo& status(VertexHandle _vh)
480  { return property(vertex_status_, _vh); }
481 
482  //----------------------------------------------------------- halfedge status
483  const StatusInfo& status(HalfedgeHandle _hh) const
484  { return property(halfedge_status_, _hh); }
485 
486  StatusInfo& status(HalfedgeHandle _hh)
487  { return property(halfedge_status_, _hh); }
488 
489  //--------------------------------------------------------------- edge status
490  const StatusInfo& status(EdgeHandle _eh) const
491  { return property(edge_status_, _eh); }
492 
493  StatusInfo& status(EdgeHandle _eh)
494  { return property(edge_status_, _eh); }
495 
496  //--------------------------------------------------------------- face status
497  const StatusInfo& status(FaceHandle _fh) const
498  { return property(face_status_, _fh); }
499 
500  StatusInfo& status(FaceHandle _fh)
501  { return property(face_status_, _fh); }
502 
503  inline bool has_vertex_status() const
504  { return vertex_status_.is_valid(); }
505 
506  inline bool has_halfedge_status() const
507  { return halfedge_status_.is_valid(); }
508 
509  inline bool has_edge_status() const
510  { return edge_status_.is_valid(); }
511 
512  inline bool has_face_status() const
513  { return face_status_.is_valid(); }
514 
515  inline VertexStatusPropertyHandle vertex_status_pph() const
516  { return vertex_status_; }
517 
518  inline HalfedgeStatusPropertyHandle halfedge_status_pph() const
519  { return halfedge_status_; }
520 
521  inline EdgeStatusPropertyHandle edge_status_pph() const
522  { return edge_status_; }
523 
524  inline FaceStatusPropertyHandle face_status_pph() const
525  { return face_status_; }
526 
528  inline VertexStatusPropertyHandle status_pph(VertexHandle /*_hnd*/) const
529  { return vertex_status_pph(); }
530 
531  inline HalfedgeStatusPropertyHandle status_pph(HalfedgeHandle /*_hnd*/) const
532  { return halfedge_status_pph(); }
533 
534  inline EdgeStatusPropertyHandle status_pph(EdgeHandle /*_hnd*/) const
535  { return edge_status_pph(); }
536 
537  inline FaceStatusPropertyHandle status_pph(FaceHandle /*_hnd*/) const
538  { return face_status_pph(); }
539 
542  {
543  if (!refcount_vstatus_++)
544  add_property( vertex_status_, "v:status" );
545  }
546 
547  void request_halfedge_status()
548  {
549  if (!refcount_hstatus_++)
550  add_property( halfedge_status_, "h:status" );
551  }
552 
553  void request_edge_status()
554  {
555  if (!refcount_estatus_++)
556  add_property( edge_status_, "e:status" );
557  }
558 
559  void request_face_status()
560  {
561  if (!refcount_fstatus_++)
562  add_property( face_status_, "f:status" );
563  }
564 
567  {
568  if ((refcount_vstatus_ > 0) && (! --refcount_vstatus_))
569  remove_property(vertex_status_);
570  }
571 
572  void release_halfedge_status()
573  {
574  if ((refcount_hstatus_ > 0) && (! --refcount_hstatus_))
575  remove_property(halfedge_status_);
576  }
577 
578  void release_edge_status()
579  {
580  if ((refcount_estatus_ > 0) && (! --refcount_estatus_))
581  remove_property(edge_status_);
582  }
583 
584  void release_face_status()
585  {
586  if ((refcount_fstatus_ > 0) && (! --refcount_fstatus_))
587  remove_property(face_status_);
588  }
589 
591 
599  template <class HandleT>
601  {
602  public:
603  typedef HandleT Handle;
604 
605  protected:
606  ArrayKernel& kernel_;
607 
608  public:
609  const unsigned int bit_mask_;
610 
611  public:
612  StatusSetT(ArrayKernel& _kernel, const unsigned int _bit_mask)
613  : kernel_(_kernel), bit_mask_(_bit_mask)
614  {}
615 
616  ~StatusSetT()
617  {}
618 
619  inline bool is_in(Handle _hnd) const
620  { return kernel_.status(_hnd).is_bit_set(bit_mask_); }
621 
622  inline void insert(Handle _hnd)
623  { kernel_.status(_hnd).set_bit(bit_mask_); }
624 
625  inline void erase(Handle _hnd)
626  { kernel_.status(_hnd).unset_bit(bit_mask_); }
627 
629  size_t size() const
630  {
631  const int n = kernel_.status_pph(Handle()).is_valid() ?
632  (int)kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
633 
634  size_t sz = 0;
635  for (int i = 0; i < n; ++i)
636  sz += (size_t)is_in(Handle(i));
637  return sz;
638  }
639 
641  void clear()
642  {
643  const int n = kernel_.status_pph(Handle()).is_valid() ?
644  (int)kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
645 
646  for (int i = 0; i < n; ++i)
647  erase(Handle(i));
648  }
649  };
650 
651  friend class StatusSetT<VertexHandle>;
652  friend class StatusSetT<EdgeHandle>;
653  friend class StatusSetT<FaceHandle>;
654  friend class StatusSetT<HalfedgeHandle>;
655 
657  template <class HandleT>
658  class AutoStatusSetT : public StatusSetT<HandleT>
659  {
660  private:
661  typedef HandleT Handle;
662  typedef StatusSetT<Handle> Base;
663 
664  public:
665  AutoStatusSetT(ArrayKernel& _kernel)
666  : StatusSetT<Handle>(_kernel, _kernel.pop_bit_mask(Handle()))
667  { /*assert(size() == 0);*/ } //the set should be empty on creation
668 
669  ~AutoStatusSetT()
670  {
671  //assert(size() == 0);//the set should be empty on leave?
672  Base::kernel_.push_bit_mask(Handle(), Base::bit_mask_);
673  }
674  };
675 
676  friend class AutoStatusSetT<VertexHandle>;
677  friend class AutoStatusSetT<EdgeHandle>;
678  friend class AutoStatusSetT<FaceHandle>;
679  friend class AutoStatusSetT<HalfedgeHandle>;
680 
685 
687  template <class HandleT>
688  class ExtStatusSetT : public AutoStatusSetT<HandleT>
689  {
690  public:
691  typedef HandleT Handle;
693 
694  protected:
695  typedef std::vector<Handle> HandleContainer;
696  HandleContainer handles_;
697 
698  public:
699  typedef typename HandleContainer::iterator
700  iterator;
701  typedef typename HandleContainer::const_iterator
702  const_iterator;
703  public:
704  ExtStatusSetT(ArrayKernel& _kernel, size_t _capacity_hint = 0)
705  : Base(_kernel)
706  { handles_.reserve(_capacity_hint); }
707 
708  ~ExtStatusSetT()
709  { clear(); }
710 
711  // Complexity: O(1)
712  inline void insert(Handle _hnd)
713  {
714  if (!is_in(_hnd))
715  {
716  Base::insert(_hnd);
717  handles_.push_back(_hnd);
718  }
719  }
720 
722  inline void erase(Handle _hnd)
723  {
724  if (is_in(_hnd))
725  {
726  iterator it = std::find(begin(), end(), _hnd);
727  erase(it);
728  }
729  }
730 
732  inline void erase(iterator _it)
733  {
734  assert(_it != end() && is_in(*_it));
735  Base::erase(*_it);
736  *_it = handles_.back();
737  _it.pop_back();
738  }
739 
740  inline void clear()
741  {
742  for (iterator it = begin(); it != end(); ++it)
743  {
744  assert(is_in(*it));
745  Base::erase(*it);
746  }
747  handles_.clear();
748  }
749 
751  inline unsigned int size() const
752  { return handles_.size(); }
753  inline bool empty() const
754  { return handles_.empty(); }
755 
756  //Vector API
757  inline iterator begin()
758  { return handles_.begin(); }
759  inline const_iterator begin() const
760  { return handles_.begin(); }
761 
762  inline iterator end()
763  { return handles_.end(); }
764  inline const_iterator end() const
765  { return handles_.end(); }
766 
767  inline Handle& front()
768  { return handles_.front(); }
769  inline const Handle& front() const
770  { return handles_.front(); }
771 
772  inline Handle& back()
773  { return handles_.back(); }
774  inline const Handle& back() const
775  { return handles_.back(); }
776  };
777 
778  typedef ExtStatusSetT<FaceHandle> ExtFaceStatusSet;
779  typedef ExtStatusSetT<VertexHandle> ExtVertexStatusSet;
780  typedef ExtStatusSetT<EdgeHandle> ExtEdgeStatusSet;
781  typedef ExtStatusSetT<HalfedgeHandle> ExtHalfedgeStatusSet;
782 
783 private:
784  // iterators
785  typedef std::vector<Vertex> VertexContainer;
786  typedef std::vector<Edge> EdgeContainer;
787  typedef std::vector<Face> FaceContainer;
788  typedef VertexContainer::iterator KernelVertexIter;
789  typedef VertexContainer::const_iterator KernelConstVertexIter;
790  typedef EdgeContainer::iterator KernelEdgeIter;
791  typedef EdgeContainer::const_iterator KernelConstEdgeIter;
792  typedef FaceContainer::iterator KernelFaceIter;
793  typedef FaceContainer::const_iterator KernelConstFaceIter;
794  typedef std::vector<unsigned int> BitMaskContainer;
795 
796 
797  KernelVertexIter vertices_begin() { return vertices_.begin(); }
798  KernelConstVertexIter vertices_begin() const { return vertices_.begin(); }
799  KernelVertexIter vertices_end() { return vertices_.end(); }
800  KernelConstVertexIter vertices_end() const { return vertices_.end(); }
801 
802  KernelEdgeIter edges_begin() { return edges_.begin(); }
803  KernelConstEdgeIter edges_begin() const { return edges_.begin(); }
804  KernelEdgeIter edges_end() { return edges_.end(); }
805  KernelConstEdgeIter edges_end() const { return edges_.end(); }
806 
807  KernelFaceIter faces_begin() { return faces_.begin(); }
808  KernelConstFaceIter faces_begin() const { return faces_.begin(); }
809  KernelFaceIter faces_end() { return faces_.end(); }
810  KernelConstFaceIter faces_end() const { return faces_.end(); }
811 
813  inline BitMaskContainer& bit_masks(VertexHandle /*_dummy_hnd*/)
814  { return vertex_bit_masks_; }
815  inline BitMaskContainer& bit_masks(EdgeHandle /*_dummy_hnd*/)
816  { return edge_bit_masks_; }
817  inline BitMaskContainer& bit_masks(FaceHandle /*_dummy_hnd*/)
818  { return face_bit_masks_; }
819  inline BitMaskContainer& bit_masks(HalfedgeHandle /*_dummy_hnd*/)
820  { return halfedge_bit_masks_; }
821 
822  template <class Handle>
823  unsigned int pop_bit_mask(Handle _hnd)
824  {
825  assert(!bit_masks(_hnd).empty());//check if the client request too many status sets
826  unsigned int bit_mask = bit_masks(_hnd).back();
827  bit_masks(_hnd).pop_back();
828  return bit_mask;
829  }
830 
831  template <class Handle>
832  void push_bit_mask(Handle _hnd, unsigned int _bit_mask)
833  {
834  assert(std::find(bit_masks(_hnd).begin(), bit_masks(_hnd).end(), _bit_mask) ==
835  bit_masks(_hnd).end());//this mask should be not already used
836  bit_masks(_hnd).push_back(_bit_mask);
837  }
838 
839  void init_bit_masks(BitMaskContainer& _bmc);
840  void init_bit_masks();
841 
842 private:
843  VertexContainer vertices_;
844  EdgeContainer edges_;
845  FaceContainer faces_;
846 
847  VertexStatusPropertyHandle vertex_status_;
848  HalfedgeStatusPropertyHandle halfedge_status_;
849  EdgeStatusPropertyHandle edge_status_;
850  FaceStatusPropertyHandle face_status_;
851 
852  unsigned int refcount_vstatus_;
853  unsigned int refcount_hstatus_;
854  unsigned int refcount_estatus_;
855  unsigned int refcount_fstatus_;
856 
857  BitMaskContainer halfedge_bit_masks_;
858  BitMaskContainer edge_bit_masks_;
859  BitMaskContainer vertex_bit_masks_;
860  BitMaskContainer face_bit_masks_;
861 };
862 
863 
864 //=============================================================================
865 } // namespace OpenMesh
866 //=============================================================================
867 #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_ARRAY_KERNEL_C)
868 # define OPENMESH_ARRAY_KERNEL_TEMPLATES
869 # include "ArrayKernelT.cc"
870 #endif
871 //=============================================================================
872 #endif // OPENMESH_ARRAY_KERNEL_HH defined
873 //=============================================================================
void erase(Handle _hnd)
Complexity: O(k), (k - number of the elements in the set)
Definition: ArrayKernel.hh:722
size_t size() const
Note: 0(n) complexity.
Definition: ArrayKernel.hh:629
void request_vertex_status()
Status Request API.
Definition: ArrayKernel.hh:541
int idx() const
Get the underlying index of this handle.
Definition: Handles.hh:74
ExtStatusSet: A status set augmented with an array.
Definition: ArrayKernel.hh:688
bool is_bit_set(unsigned int _s) const
is a certain bit set ?
Definition: Status.hh:162
Mesh kernel using arrays for mesh item storage.
Definition: ArrayKernel.hh:92
unsigned int size() const
Complexity: 0(1)
Definition: ArrayKernel.hh:751
Add status information to a base class.
Definition: Status.hh:99
void set_bit(unsigned int _s)
set a certain bit
Definition: Status.hh:164
void erase(iterator _it)
Complexity: O(1)
Definition: ArrayKernel.hh:732
void release_vertex_status()
Status Release API.
Definition: ArrayKernel.hh:566
This class provides the basic property management like adding/removing properties and access to prope...
Definition: BaseKernel.hh:99
bool is_valid() const
The handle is valid iff the index is not equal to -1.
Definition: Handles.hh:77
VertexStatusPropertyHandle status_pph(VertexHandle) const
status property by handle
Definition: ArrayKernel.hh:528
Handle for a edge entity.
Definition: Handles.hh:137
void clear()
Note: O(n) complexity.
Definition: ArrayKernel.hh:641
Handle for a vertex entity.
Definition: Handles.hh:123
AutoStatusSetT: A status set that automatically picks a status bit.
Definition: ArrayKernel.hh:658
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:64
void invalidate()
reset handle to be invalid
Definition: Handles.hh:82
const StatusInfo & status(VertexHandle _vh) const
Status Query API.
Definition: ArrayKernel.hh:476
Handle for a halfedge entity.
Definition: Handles.hh:130
PropertyT< T > & property(VPropHandleT< T > _ph)
Access a property.
Definition: BaseKernel.hh:294
Handle for a face entity.
Definition: Handles.hh:144
void unset_bit(unsigned int _s)
unset a certain bit
Definition: Status.hh:166
bool is_boundary(HalfedgeHandle _heh) const
Is halfedge _heh a boundary halfedge (is its face handle invalid) ?
Definition: ArrayKernel.hh:373
— StatusSet API —
Definition: ArrayKernel.hh:600

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