OpenMesh

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

- File List
- File Members

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
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 {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>
586 class StatusSetT
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
665 typedef AutoStatusSetT<VertexHandle> VertexStatusSet;
666 typedef AutoStatusSetT<EdgeHandle> EdgeStatusSet;
667 typedef AutoStatusSetT<FaceHandle> FaceStatusSet;
668 typedef AutoStatusSetT<HalfedgeHandle> HalfedgeStatusSet;
669
671
672 template <class Handle>
673 class ExtStatusSetT : public AutoStatusSetT<Handle>
674 {
675 public:
676 typedef AutoStatusSetT<Handle> Base;
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 //=============================================================================