OpenMesh

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends 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: 847 $ *
38 * $Date: 2013-07-23 16:23:12 +0200 (Di, 23. Jul 2013) $ *
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
90 typedef OpenMesh::VertexHandle VertexHandle;
91 typedef OpenMesh::HalfedgeHandle HalfedgeHandle;
92 typedef OpenMesh::EdgeHandle EdgeHandle;
93 typedef OpenMesh::FaceHandle FaceHandle;
94 typedef Attributes::StatusInfo StatusInfo;
95 typedef VPropHandleT<StatusInfo> VertexStatusPropertyHandle;
96 typedef HPropHandleT<StatusInfo> HalfedgeStatusPropertyHandle;
97 typedef EPropHandleT<StatusInfo> EdgeStatusPropertyHandle;
98 typedef FPropHandleT<StatusInfo> FaceStatusPropertyHandle;
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::True)
381 { halfedge(_heh).prev_halfedge_handle_ = _pheh; }
382
383 void set_prev_halfedge_handle(HalfedgeHandle /* _heh */, HalfedgeHandle /* _pheh */,
384 GenProg::False)
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::True) const
391 { return halfedge(_heh).prev_halfedge_handle_; }
392
393 HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::False) 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
518 void request_vertex_status()
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
543 void release_vertex_status()
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>
570 class StatusSetT
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
649 typedef AutoStatusSetT<VertexHandle> VertexStatusSet;
650 typedef AutoStatusSetT<EdgeHandle> EdgeStatusSet;
651 typedef AutoStatusSetT<FaceHandle> FaceStatusSet;
652 typedef AutoStatusSetT<HalfedgeHandle> HalfedgeStatusSet;
653
655
656 template <class Handle>
657 class ExtStatusSetT : public AutoStatusSetT<Handle>
658 {
659 public:
660 typedef AutoStatusSetT<Handle> Base;
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 //=============================================================================