OpenMesh: OpenMesh/Core/Mesh/ArrayKernel.hh Source File

| OpenMesh

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
97 typedef OpenMesh::VertexHandle VertexHandle;
98 typedef OpenMesh::HalfedgeHandle HalfedgeHandle;
99 typedef OpenMesh::EdgeHandle EdgeHandle;
100 typedef OpenMesh::FaceHandle FaceHandle;
101 typedef Attributes::StatusInfo StatusInfo;
102 typedef VPropHandleT<StatusInfo> VertexStatusPropertyHandle;
103 typedef HPropHandleT<StatusInfo> HalfedgeStatusPropertyHandle;
104 typedef EPropHandleT<StatusInfo> EdgeStatusPropertyHandle;
105 typedef FPropHandleT<StatusInfo> FaceStatusPropertyHandle;
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
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
239 inline VertexHandle new_vertex_dirty()
240 {
241 vertices_.push_back(Vertex());
242 vprops_resize_if_smaller(n_vertices());//TODO:should it be push_back()?
243
244 return handle(vertices_.back());
245 }
246
247 inline HalfedgeHandle new_edge(VertexHandle _start_vh, VertexHandle _end_vh)
248 {
249 // assert(_start_vh != _end_vh);
250 edges_.push_back(Edge());
251 eprops_resize(n_edges());//TODO:should it be push_back()?
252 hprops_resize(n_halfedges());//TODO:should it be push_back()?
253
254 EdgeHandle eh(handle(edges_.back()));
255 HalfedgeHandle heh0(halfedge_handle(eh, 0));
256 HalfedgeHandle heh1(halfedge_handle(eh, 1));
257 set_vertex_handle(heh0, _end_vh);
258 set_vertex_handle(heh1, _start_vh);
259 return heh0;
260 }
261
262 inline FaceHandle new_face()
263 {
264 faces_.push_back(Face());
265 fprops_resize(n_faces());
266 return handle(faces_.back());
267 }
268
269 inline FaceHandle new_face(const Face& _f)
270 {
271 faces_.push_back(_f);
272 fprops_resize(n_faces());
273 return handle(faces_.back());
274 }
275
276 public:
277 // --- resize/reserve ---
278 void resize( size_t _n_vertices, size_t _n_edges, size_t _n_faces );
279 void reserve(size_t _n_vertices, size_t _n_edges, size_t _n_faces );
280
281 // --- deletion ---
297 void garbage_collection(bool _v=true, bool _e=true, bool _f=true);
298
316 template<typename std_API_Container_VHandlePointer,
317 typename std_API_Container_HHandlePointer,
318 typename std_API_Container_FHandlePointer>
319 void garbage_collection(std_API_Container_VHandlePointer& vh_to_update,
320 std_API_Container_HHandlePointer& hh_to_update,
321 std_API_Container_FHandlePointer& fh_to_update,
322 bool _v=true, bool _e=true, bool _f=true);
323
325 void clear();
326
336 void clean();
337
345 void clean_keep_reservation();
346
347 // --- number of items ---
348 size_t n_vertices() const { return vertices_.size(); }
349 size_t n_halfedges() const { return 2*edges_.size(); }
350 size_t n_edges() const { return edges_.size(); }
351 size_t n_faces() const { return faces_.size(); }
352
353 bool vertices_empty() const { return vertices_.empty(); }
354 bool halfedges_empty() const { return edges_.empty(); }
355 bool edges_empty() const { return edges_.empty(); }
356 bool faces_empty() const { return faces_.empty(); }
357
358 // --- vertex connectivity ---
359
360 HalfedgeHandle halfedge_handle(VertexHandle _vh) const
361 { return vertex(_vh).halfedge_handle_; }
362
363 void set_halfedge_handle(VertexHandle _vh, HalfedgeHandle _heh)
364 {
365 // assert(is_valid_handle(_heh));
366 vertex(_vh).halfedge_handle_ = _heh;
367 }
368
369 bool is_isolated(VertexHandle _vh) const
370 { return !halfedge_handle(_vh).is_valid(); }
371
372 void set_isolated(VertexHandle _vh)
373 { vertex(_vh).halfedge_handle_.invalidate(); }
374
375 unsigned int delete_isolated_vertices();
376
377 // --- halfedge connectivity ---
378 VertexHandle to_vertex_handle(HalfedgeHandle _heh) const
379 { return halfedge(_heh).vertex_handle_; }
380
381 VertexHandle from_vertex_handle(HalfedgeHandle _heh) const
382 { return to_vertex_handle(opposite_halfedge_handle(_heh)); }
383
384 void set_vertex_handle(HalfedgeHandle _heh, VertexHandle _vh)
385 {
386 // assert(is_valid_handle(_vh));
387 halfedge(_heh).vertex_handle_ = _vh;
388 }
389
390 FaceHandle face_handle(HalfedgeHandle _heh) const
391 { return halfedge(_heh).face_handle_; }
392
393 void set_face_handle(HalfedgeHandle _heh, FaceHandle _fh)
394 {
395 // assert(is_valid_handle(_fh));
396 halfedge(_heh).face_handle_ = _fh;
397 }
398
399 void set_boundary(HalfedgeHandle _heh)
400 { halfedge(_heh).face_handle_.invalidate(); }
401
403 bool is_boundary(HalfedgeHandle _heh) const
404 { return !face_handle(_heh).is_valid(); }
405
406 HalfedgeHandle next_halfedge_handle(HalfedgeHandle _heh) const
407 { return halfedge(_heh).next_halfedge_handle_; }
408
409 void set_next_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _nheh)
410 {
411 assert(is_valid_handle(_nheh));
412 // assert(to_vertex_handle(_heh) == from_vertex_handle(_nheh));
413 halfedge(_heh).next_halfedge_handle_ = _nheh;
414 set_prev_halfedge_handle(_nheh, _heh);
415 }
416
417
418 void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh)
419 {
420 assert(is_valid_handle(_pheh));
421 set_prev_halfedge_handle(_heh, _pheh, HasPrevHalfedge());
422 }
423
424 void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh,
425 GenProg::TrueType)
426 { halfedge(_heh).prev_halfedge_handle_ = _pheh; }
427
428 void set_prev_halfedge_handle(HalfedgeHandle /* _heh */, HalfedgeHandle /* _pheh */,
429 GenProg::FalseType)
430 {}
431
432 HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh) const
433 { return prev_halfedge_handle(_heh, HasPrevHalfedge() ); }
434
435 HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::TrueType) const
436 { return halfedge(_heh).prev_halfedge_handle_; }
437
438 HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::FalseType) const
439 {
440 if (is_boundary(_heh))
441 {//iterating around the vertex should be faster than iterating the boundary
442 HalfedgeHandle curr_heh(opposite_halfedge_handle(_heh));
443 HalfedgeHandle next_heh(next_halfedge_handle(curr_heh));
444 do
445 {
446 curr_heh = opposite_halfedge_handle(next_heh);
447 next_heh = next_halfedge_handle(curr_heh);
448 }
449 while (next_heh != _heh);
450 return curr_heh;
451 }
452 else
453 {
454 HalfedgeHandle heh(_heh);
455 HalfedgeHandle next_heh(next_halfedge_handle(heh));
456 while (next_heh != _heh) {
457 heh = next_heh;
458 next_heh = next_halfedge_handle(next_heh);
459 }
460 return heh;
461 }
462 }
463
464
465 HalfedgeHandle opposite_halfedge_handle(HalfedgeHandle _heh) const
466 { return HalfedgeHandle(_heh.idx() ^ 1); }
467
468
469 HalfedgeHandle ccw_rotated_halfedge_handle(HalfedgeHandle _heh) const
470 { return opposite_halfedge_handle(prev_halfedge_handle(_heh)); }
471
472
473 HalfedgeHandle cw_rotated_halfedge_handle(HalfedgeHandle _heh) const
474 { return next_halfedge_handle(opposite_halfedge_handle(_heh)); }
475
476 // --- edge connectivity ---
477 static HalfedgeHandle s_halfedge_handle(EdgeHandle _eh, unsigned int _i)
478 {
479 assert(_i<=1);
480 return HalfedgeHandle((_eh.idx() << 1) + _i);
481 }
482
483 static EdgeHandle s_edge_handle(HalfedgeHandle _heh)
484 { return EdgeHandle(_heh.idx() >> 1); }
485
486 HalfedgeHandle halfedge_handle(EdgeHandle _eh, unsigned int _i) const
487 {
488 return s_halfedge_handle(_eh, _i);
489 }
490
491 EdgeHandle edge_handle(HalfedgeHandle _heh) const
492 { return s_edge_handle(_heh); }
493
494 // --- face connectivity ---
495 HalfedgeHandle halfedge_handle(FaceHandle _fh) const
496 { return face(_fh).halfedge_handle_; }
497
498 void set_halfedge_handle(FaceHandle _fh, HalfedgeHandle _heh)
499 {
500 // assert(is_valid_handle(_heh));
501 face(_fh).halfedge_handle_ = _heh;
502 }
503
505 //------------------------------------------------------------ vertex status
506 const StatusInfo& status(VertexHandle _vh) const
507 { return property(vertex_status_, _vh); }
508
509 StatusInfo& status(VertexHandle _vh)
510 { return property(vertex_status_, _vh); }
511
516 void reset_status() {
517 PropertyT<StatusInfo> &status_prop = property(vertex_status_);
518 PropertyT<StatusInfo>::vector_type &sprop_v = status_prop.data_vector();
519 std::fill(sprop_v.begin(), sprop_v.begin() + n_vertices(), StatusInfo());
520 }
521
522 //----------------------------------------------------------- halfedge status
523 const StatusInfo& status(HalfedgeHandle _hh) const
524 { return property(halfedge_status_, _hh); }
525
526 StatusInfo& status(HalfedgeHandle _hh)
527 { return property(halfedge_status_, _hh); }
528
529 //--------------------------------------------------------------- edge status
530 const StatusInfo& status(EdgeHandle _eh) const
531 { return property(edge_status_, _eh); }
532
533 StatusInfo& status(EdgeHandle _eh)
534 { return property(edge_status_, _eh); }
535
536 //--------------------------------------------------------------- face status
537 const StatusInfo& status(FaceHandle _fh) const
538 { return property(face_status_, _fh); }
539
540 StatusInfo& status(FaceHandle _fh)
541 { return property(face_status_, _fh); }
542
543 inline bool has_vertex_status() const
544 { return vertex_status_.is_valid(); }
545
546 inline bool has_halfedge_status() const
547 { return halfedge_status_.is_valid(); }
548
549 inline bool has_edge_status() const
550 { return edge_status_.is_valid(); }
551
552 inline bool has_face_status() const
553 { return face_status_.is_valid(); }
554
555 inline VertexStatusPropertyHandle vertex_status_pph() const
556 { return vertex_status_; }
557
558 inline HalfedgeStatusPropertyHandle halfedge_status_pph() const
559 { return halfedge_status_; }
560
561 inline EdgeStatusPropertyHandle edge_status_pph() const
562 { return edge_status_; }
563
564 inline FaceStatusPropertyHandle face_status_pph() const
565 { return face_status_; }
566
568 inline VertexStatusPropertyHandle status_pph(VertexHandle /*_hnd*/) const
569 { return vertex_status_pph(); }
570
571 inline HalfedgeStatusPropertyHandle status_pph(HalfedgeHandle /*_hnd*/) const
572 { return halfedge_status_pph(); }
573
574 inline EdgeStatusPropertyHandle status_pph(EdgeHandle /*_hnd*/) const
575 { return edge_status_pph(); }
576
577 inline FaceStatusPropertyHandle status_pph(FaceHandle /*_hnd*/) const
578 { return face_status_pph(); }
579
581 void request_vertex_status()
582 {
583 if (!refcount_vstatus_++)
584 add_property( vertex_status_, "v:status" );
585 }
586
587 void request_halfedge_status()
588 {
589 if (!refcount_hstatus_++)
590 add_property( halfedge_status_, "h:status" );
591 }
592
593 void request_edge_status()
594 {
595 if (!refcount_estatus_++)
596 add_property( edge_status_, "e:status" );
597 }
598
599 void request_face_status()
600 {
601 if (!refcount_fstatus_++)
602 add_property( face_status_, "f:status" );
603 }
604
606 void release_vertex_status()
607 {
608 if ((refcount_vstatus_ > 0) && (! --refcount_vstatus_))
609 remove_property(vertex_status_);
610 }
611
612 void release_halfedge_status()
613 {
614 if ((refcount_hstatus_ > 0) && (! --refcount_hstatus_))
615 remove_property(halfedge_status_);
616 }
617
618 void release_edge_status()
619 {
620 if ((refcount_estatus_ > 0) && (! --refcount_estatus_))
621 remove_property(edge_status_);
622 }
623
624 void release_face_status()
625 {
626 if ((refcount_fstatus_ > 0) && (! --refcount_fstatus_))
627 remove_property(face_status_);
628 }
629
631
639 template <class HandleT>
640 class StatusSetT
641 {
642 public:
643 typedef HandleT Handle;
644
645 protected:
646 ArrayKernel& kernel_;
647
648 public:
649 const unsigned int bit_mask_;
650
651 public:
652 StatusSetT(ArrayKernel& _kernel, const unsigned int _bit_mask)
653 : kernel_(_kernel), bit_mask_(_bit_mask)
654 {}
655
656 ~StatusSetT()
657 {}
658
659 inline bool is_in(Handle _hnd) const
660 { return kernel_.status(_hnd).is_bit_set(bit_mask_); }
661
662 inline void insert(Handle _hnd)
663 { kernel_.status(_hnd).set_bit(bit_mask_); }
664
665 inline void erase(Handle _hnd)
666 { kernel_.status(_hnd).unset_bit(bit_mask_); }
667
669 size_t size() const
670 {
671 const int n = kernel_.status_pph(Handle()).is_valid() ?
672 (int)kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
673
674 size_t sz = 0;
675 for (int i = 0; i < n; ++i)
676 sz += (size_t)is_in(Handle(i));
677 return sz;
678 }
679
681 void clear()
682 {
683 const int n = kernel_.status_pph(Handle()).is_valid() ?
684 (int)kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
685
686 for (int i = 0; i < n; ++i)
687 erase(Handle(i));
688 }
689 };
690
691 friend class StatusSetT<VertexHandle>;
692 friend class StatusSetT<EdgeHandle>;
693 friend class StatusSetT<FaceHandle>;
694 friend class StatusSetT<HalfedgeHandle>;
695
697 template <class HandleT>
698 class AutoStatusSetT : public StatusSetT<HandleT>
699 {
700 private:
701 typedef HandleT Handle;
702 typedef StatusSetT<Handle> Base;
703
704 public:
705 AutoStatusSetT(ArrayKernel& _kernel)
706 : StatusSetT<Handle>(_kernel, _kernel.pop_bit_mask(Handle()))
707 { /*assert(size() == 0);*/ } //the set should be empty on creation
708
709 ~AutoStatusSetT()
710 {
711 //assert(size() == 0);//the set should be empty on leave?
712 Base::kernel_.push_bit_mask(Handle(), Base::bit_mask_);
713 }
714 };
715
716 friend class AutoStatusSetT<VertexHandle>;
717 friend class AutoStatusSetT<EdgeHandle>;
718 friend class AutoStatusSetT<FaceHandle>;
719 friend class AutoStatusSetT<HalfedgeHandle>;
720
721 typedef AutoStatusSetT<VertexHandle> VertexStatusSet;
722 typedef AutoStatusSetT<EdgeHandle> EdgeStatusSet;
723 typedef AutoStatusSetT<FaceHandle> FaceStatusSet;
724 typedef AutoStatusSetT<HalfedgeHandle> HalfedgeStatusSet;
725
727 template <class HandleT>
728 class ExtStatusSetT : public AutoStatusSetT<HandleT>
729 {
730 public:
731 typedef HandleT Handle;
732 typedef AutoStatusSetT<Handle> Base;
733
734 protected:
735 typedef std::vector<Handle> HandleContainer;
736 HandleContainer handles_;
737
738 public:
739 typedef typename HandleContainer::iterator
740 iterator;
741 typedef typename HandleContainer::const_iterator
742 const_iterator;
743 public:
744 ExtStatusSetT(ArrayKernel& _kernel, size_t _capacity_hint = 0)
745 : Base(_kernel)
746 { handles_.reserve(_capacity_hint); }
747
748 ~ExtStatusSetT()
749 { clear(); }
750
751 // Complexity: O(1)
752 inline void insert(Handle _hnd)
753 {
754 if (!is_in(_hnd))
755 {
756 Base::insert(_hnd);
757 handles_.push_back(_hnd);
758 }
759 }
760
762 inline void erase(Handle _hnd)
763 {
764 if (is_in(_hnd))
765 {
766 iterator it = std::find(begin(), end(), _hnd);
767 erase(it);
768 }
769 }
770
772 inline void erase(iterator _it)
773 {
774 assert(_it != end() && is_in(*_it));
775 Base::erase(*_it);
776 *_it = handles_.back();
777 _it.pop_back();
778 }
779
780 inline void clear()
781 {
782 for (iterator it = begin(); it != end(); ++it)
783 {
784 assert(is_in(*it));
785 Base::erase(*it);
786 }
787 handles_.clear();
788 }
789
791 inline unsigned int size() const
792 { return handles_.size(); }
793 inline bool empty() const
794 { return handles_.empty(); }
795
796 //Vector API
797 inline iterator begin()
798 { return handles_.begin(); }
799 inline const_iterator begin() const
800 { return handles_.begin(); }
801
802 inline iterator end()
803 { return handles_.end(); }
804 inline const_iterator end() const
805 { return handles_.end(); }
806
807 inline Handle& front()
808 { return handles_.front(); }
809 inline const Handle& front() const
810 { return handles_.front(); }
811
812 inline Handle& back()
813 { return handles_.back(); }
814 inline const Handle& back() const
815 { return handles_.back(); }
816 };
817
818 typedef ExtStatusSetT<FaceHandle> ExtFaceStatusSet;
819 typedef ExtStatusSetT<VertexHandle> ExtVertexStatusSet;
820 typedef ExtStatusSetT<EdgeHandle> ExtEdgeStatusSet;
821 typedef ExtStatusSetT<HalfedgeHandle> ExtHalfedgeStatusSet;
822
823 private:
824 // iterators
825 typedef std::vector<Vertex> VertexContainer;
826 typedef std::vector<Edge> EdgeContainer;
827 typedef std::vector<Face> FaceContainer;
828 typedef VertexContainer::iterator KernelVertexIter;
829 typedef VertexContainer::const_iterator KernelConstVertexIter;
830 typedef EdgeContainer::iterator KernelEdgeIter;
831 typedef EdgeContainer::const_iterator KernelConstEdgeIter;
832 typedef FaceContainer::iterator KernelFaceIter;
833 typedef FaceContainer::const_iterator KernelConstFaceIter;
834 typedef std::vector<unsigned int> BitMaskContainer;
835
836
837 KernelVertexIter vertices_begin() { return vertices_.begin(); }
838 KernelConstVertexIter vertices_begin() const { return vertices_.begin(); }
839 KernelVertexIter vertices_end() { return vertices_.end(); }
840 KernelConstVertexIter vertices_end() const { return vertices_.end(); }
841
842 KernelEdgeIter edges_begin() { return edges_.begin(); }
843 KernelConstEdgeIter edges_begin() const { return edges_.begin(); }
844 KernelEdgeIter edges_end() { return edges_.end(); }
845 KernelConstEdgeIter edges_end() const { return edges_.end(); }
846
847 KernelFaceIter faces_begin() { return faces_.begin(); }
848 KernelConstFaceIter faces_begin() const { return faces_.begin(); }
849 KernelFaceIter faces_end() { return faces_.end(); }
850 KernelConstFaceIter faces_end() const { return faces_.end(); }
851
853 inline BitMaskContainer& bit_masks(VertexHandle /*_dummy_hnd*/)
854 { return vertex_bit_masks_; }
855 inline BitMaskContainer& bit_masks(EdgeHandle /*_dummy_hnd*/)
856 { return edge_bit_masks_; }
857 inline BitMaskContainer& bit_masks(FaceHandle /*_dummy_hnd*/)
858 { return face_bit_masks_; }
859 inline BitMaskContainer& bit_masks(HalfedgeHandle /*_dummy_hnd*/)
860 { return halfedge_bit_masks_; }
861
862 template <class Handle>
863 unsigned int pop_bit_mask(Handle _hnd)
864 {
865 assert(!bit_masks(_hnd).empty());//check if the client request too many status sets
866 unsigned int bit_mask = bit_masks(_hnd).back();
867 bit_masks(_hnd).pop_back();
868 return bit_mask;
869 }
870
871 template <class Handle>
872 void push_bit_mask(Handle _hnd, unsigned int _bit_mask)
873 {
874 assert(std::find(bit_masks(_hnd).begin(), bit_masks(_hnd).end(), _bit_mask) ==
875 bit_masks(_hnd).end());//this mask should be not already used
876 bit_masks(_hnd).push_back(_bit_mask);
877 }
878
879 void init_bit_masks(BitMaskContainer& _bmc);
880 void init_bit_masks();
881
882 protected:
883
884 VertexStatusPropertyHandle vertex_status_;
885 HalfedgeStatusPropertyHandle halfedge_status_;
886 EdgeStatusPropertyHandle edge_status_;
887 FaceStatusPropertyHandle face_status_;
888
889 unsigned int refcount_vstatus_;
890 unsigned int refcount_hstatus_;
891 unsigned int refcount_estatus_;
892 unsigned int refcount_fstatus_;
893
894 private:
895 VertexContainer vertices_;
896 EdgeContainer edges_;
897 FaceContainer faces_;
898
899 BitMaskContainer halfedge_bit_masks_;
900 BitMaskContainer edge_bit_masks_;
901 BitMaskContainer vertex_bit_masks_;
902 BitMaskContainer face_bit_masks_;
903 };
904
905
906 //=============================================================================
907 } // namespace OpenMesh
908 //=============================================================================
909 #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_ARRAY_KERNEL_C)
910 # define OPENMESH_ARRAY_KERNEL_TEMPLATES
911 # include "ArrayKernelT.cc"
912 #endif
913 //=============================================================================
914 #endif // OPENMESH_ARRAY_KERNEL_HH defined
915 //=============================================================================
OpenMesh::HalfedgeHandle
Handle for a halfedge entity.
Definition: Handles.hh:132
OpenMesh::BaseKernel
This class provides low-level property management like adding/removing properties and access to prope...
Definition: BaseKernel.hh:102
OpenMesh::Attributes::StatusInfo
Add status information to a base class.
Definition: Status.hh:99
OpenMesh::ArrayKernel::status_pph
VertexStatusPropertyHandle status_pph(VertexHandle) const
status property by handle
Definition: ArrayKernel.hh:568
OpenMesh::Attributes::StatusInfo::set_bit
void set_bit(unsigned int _s)
set a certain bit
Definition: Status.hh:164
OpenMesh::FaceHandle
Handle for a face entity.
Definition: Handles.hh:146
OpenMesh::ArrayKernel::StatusSetT::clear
void clear()
Note: O(n) complexity.
Definition: ArrayKernel.hh:681
OpenMesh::ArrayKernel::status
const StatusInfo & status(VertexHandle _vh) const
Status Query API.
Definition: ArrayKernel.hh:506
OpenMesh::PropertyT
Default property class for any type T.
Definition: Property.hh:94
OpenMesh::PropertyT::data_vector
vector_type & data_vector()
Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!!!) ...
Definition: Property.hh:183
OpenMesh::ArrayKernel::reset_status
void reset_status()
Reinitializes the status of all vertices using the StatusInfo default constructor, i.e.
Definition: ArrayKernel.hh:516
OpenMesh::BaseHandle::is_valid
bool is_valid() const
The handle is valid iff the index is not negative.
Definition: Handles.hh:77
OpenMesh
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:64
OpenMesh::ArrayKernel::is_boundary
bool is_boundary(HalfedgeHandle _heh) const
Is halfedge _heh a boundary halfedge (is its face handle invalid) ?
Definition: ArrayKernel.hh:403
OpenMesh::FPropHandleT< StatusInfo >
OpenMesh::BaseHandle::idx
int idx() const
Get the underlying index of this handle.
Definition: Handles.hh:74
OpenMesh::ArrayKernel::request_vertex_status
void request_vertex_status()
Status Request API.
Definition: ArrayKernel.hh:581
OpenMesh::ArrayKernel::AutoStatusSetT
AutoStatusSetT: A status set that automatically picks a status bit.
Definition: ArrayKernel.hh:698
OpenMesh::Attributes::StatusInfo::is_bit_set
bool is_bit_set(unsigned int _s) const
is a certain bit set ?
Definition: Status.hh:162
OpenMesh::VPropHandleT< StatusInfo >
OpenMesh::ArrayKernel::ExtStatusSetT::erase
void erase(Handle _hnd)
Complexity: O(k), (k - number of the elements in the set)
Definition: ArrayKernel.hh:762
OpenMesh::VertexHandle
Handle for a vertex entity.
Definition: Handles.hh:125
OpenMesh::BaseKernel::property
PropertyT< T > & property(VPropHandleT< T > _ph)
In most cases you should use the convenient PropertyManager wrapper and use of this function should n...
Definition: BaseKernel.hh:315
OpenMesh::BaseHandle::invalidate
void invalidate()
reset handle to be invalid
Definition: Handles.hh:82
OpenMesh::EPropHandleT< StatusInfo >
OpenMesh::ArrayKernel::StatusSetT
— StatusSet API —
Definition: ArrayKernel.hh:640
OpenMesh::ArrayKernel::new_vertex
VertexHandle new_vertex()
Add a new vertex.
Definition: ArrayKernel.hh:221
OpenMesh::ArrayKernel::new_vertex_dirty
VertexHandle new_vertex_dirty()
Same as new_vertex() but uses PropertyContainer::resize_if_smaller() to resize the vertex property co...
Definition: ArrayKernel.hh:239
OpenMesh::ArrayKernel::release_vertex_status
void release_vertex_status()
Status Release API.
Definition: ArrayKernel.hh:606
OpenMesh::ArrayKernel::StatusSetT::size
size_t size() const
Note: 0(n) complexity.
Definition: ArrayKernel.hh:669
OpenMesh::HPropHandleT< StatusInfo >
OpenMesh::ArrayKernel::ExtStatusSetT::erase
void erase(iterator _it)
Complexity: O(1)
Definition: ArrayKernel.hh:772
OpenMesh::EdgeHandle
Handle for a edge entity.
Definition: Handles.hh:139
OpenMesh::Attributes::StatusInfo::unset_bit
void unset_bit(unsigned int _s)
unset a certain bit
Definition: Status.hh:166
OpenMesh::ArrayKernel::ExtStatusSetT
ExtStatusSet: A status set augmented with an array.
Definition: ArrayKernel.hh:728
OpenMesh::ArrayKernel
Mesh kernel using arrays for mesh item storage.
Definition: ArrayKernel.hh:92
OpenMesh::ArrayKernel::ExtStatusSetT::size
unsigned int size() const
Complexity: 0(1)
Definition: ArrayKernel.hh:791