| 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
45 //=============================================================================
46 //
47 // CLASS ArrayKernel
48 //
49 //=============================================================================
50
51
52 #ifndef OPENMESH_ARRAY_KERNEL_HH
53 #define OPENMESH_ARRAY_KERNEL_HH
54
55
56 //== INCLUDES =================================================================
57 #include <vector>
58
59 #include <OpenMesh/Core/System/config.h>
60 #include <OpenMesh/Core/Utils/GenProg.hh>
61
62 #include <OpenMesh/Core/Mesh/ArrayItems.hh>
63 #include <OpenMesh/Core/Mesh/BaseKernel.hh>
64 #include <OpenMesh/Core/Mesh/Status.hh>
65
66 //== NAMESPACES ===============================================================
67 namespace OpenMesh {
68
69
70 //== CLASS DEFINITION =========================================================
87 class OPENMESHDLLEXPORT ArrayKernel : public BaseKernel, public ArrayItems
88 {
89 public:
90
91 // handles
92 typedef OpenMesh::VertexHandle VertexHandle;
93 typedef OpenMesh::HalfedgeHandle HalfedgeHandle;
94 typedef OpenMesh::EdgeHandle EdgeHandle;
95 typedef OpenMesh::FaceHandle FaceHandle;
96 typedef Attributes::StatusInfo StatusInfo;
97 typedef VPropHandleT<StatusInfo> VertexStatusPropertyHandle;
98 typedef HPropHandleT<StatusInfo> HalfedgeStatusPropertyHandle;
99 typedef EPropHandleT<StatusInfo> EdgeStatusPropertyHandle;
100 typedef FPropHandleT<StatusInfo> FaceStatusPropertyHandle;
101
102 public:
103
104 // --- constructor/destructor ---
105 ArrayKernel();
106 virtual ~ArrayKernel();
107
114 void assign_connectivity(const ArrayKernel& _other);
115
116 // --- handle -> item ---
117 VertexHandle handle(const Vertex& _v) const;
118
119 HalfedgeHandle handle(const Halfedge& _he) const;
120
121 EdgeHandle handle(const Edge& _e) const;
122
123 FaceHandle handle(const Face& _f) const;
124
125
127 bool is_valid_handle(VertexHandle _vh) const;
128
130 bool is_valid_handle(HalfedgeHandle _heh) const;
131
133 bool is_valid_handle(EdgeHandle _eh) const;
134
136 bool is_valid_handle(FaceHandle _fh) const;
137
138
139 // --- item -> handle ---
140 const Vertex& vertex(VertexHandle _vh) const
141 {
142 assert(is_valid_handle(_vh));
143 return vertices_[_vh.idx()];
144 }
145
146 Vertex& vertex(VertexHandle _vh)
147 {
148 assert(is_valid_handle(_vh));
149 return vertices_[_vh.idx()];
150 }
151
152 const Halfedge& halfedge(HalfedgeHandle _heh) const
153 {
154 assert(is_valid_handle(_heh));
155 return edges_[_heh.idx() >> 1].halfedges_[_heh.idx() & 1];
156 }
157
158 Halfedge& halfedge(HalfedgeHandle _heh)
159 {
160 assert(is_valid_handle(_heh));
161 return edges_[_heh.idx() >> 1].halfedges_[_heh.idx() & 1];
162 }
163
164 const Edge& edge(EdgeHandle _eh) const
165 {
166 assert(is_valid_handle(_eh));
167 return edges_[_eh.idx()];
168 }
169
170 Edge& edge(EdgeHandle _eh)
171 {
172 assert(is_valid_handle(_eh));
173 return edges_[_eh.idx()];
174 }
175
176 const Face& face(FaceHandle _fh) const
177 {
178 assert(is_valid_handle(_fh));
179 return faces_[_fh.idx()];
180 }
181
182 Face& face(FaceHandle _fh)
183 {
184 assert(is_valid_handle(_fh));
185 return faces_[_fh.idx()];
186 }
187
188 // --- get i'th items ---
189
190 VertexHandle vertex_handle(unsigned int _i) const
191 { return (_i < n_vertices()) ? handle( vertices_[_i] ) : VertexHandle(); }
192
193 HalfedgeHandle halfedge_handle(unsigned int _i) const
194 {
195 return (_i < n_halfedges()) ?
196 halfedge_handle(edge_handle(_i/2), _i%2) : HalfedgeHandle();
197 }
198
199 EdgeHandle edge_handle(unsigned int _i) const
200 { return (_i < n_edges()) ? handle(edges_[_i]) : EdgeHandle(); }
201
202 FaceHandle face_handle(unsigned int _i) const
203 { return (_i < n_faces()) ? handle(faces_[_i]) : FaceHandle(); }
204
205 public:
206
216 inline VertexHandle new_vertex()
217 {
218 vertices_.push_back(Vertex());
219 vprops_resize(n_vertices());//TODO:should it be push_back()?
220
221 return handle(vertices_.back());
222 }
223
234 inline VertexHandle new_vertex_dirty()
235 {
236 vertices_.push_back(Vertex());
237 vprops_resize_if_smaller(n_vertices());//TODO:should it be push_back()?
238
239 return handle(vertices_.back());
240 }
241
242 inline HalfedgeHandle new_edge(VertexHandle _start_vh, VertexHandle _end_vh)
243 {
244 // assert(_start_vh != _end_vh);
245 edges_.push_back(Edge());
246 eprops_resize(n_edges());//TODO:should it be push_back()?
247 hprops_resize(n_halfedges());//TODO:should it be push_back()?
248
249 EdgeHandle eh(handle(edges_.back()));
250 HalfedgeHandle heh0(halfedge_handle(eh, 0));
251 HalfedgeHandle heh1(halfedge_handle(eh, 1));
252 set_vertex_handle(heh0, _end_vh);
253 set_vertex_handle(heh1, _start_vh);
254 return heh0;
255 }
256
257 inline FaceHandle new_face()
258 {
259 faces_.push_back(Face());
260 fprops_resize(n_faces());
261 return handle(faces_.back());
262 }
263
264 inline FaceHandle new_face(const Face& _f)
265 {
266 faces_.push_back(_f);
267 fprops_resize(n_faces());
268 return handle(faces_.back());
269 }
270
271 public:
272 // --- resize/reserve ---
273 void resize( size_t _n_vertices, size_t _n_edges, size_t _n_faces );
274 void reserve(size_t _n_vertices, size_t _n_edges, size_t _n_faces );
275
276 // --- deletion ---
292 void garbage_collection(bool _v=true, bool _e=true, bool _f=true);
293
311 template<typename std_API_Container_VHandlePointer,
312 typename std_API_Container_HHandlePointer,
313 typename std_API_Container_FHandlePointer>
314 void garbage_collection(std_API_Container_VHandlePointer& vh_to_update,
315 std_API_Container_HHandlePointer& hh_to_update,
316 std_API_Container_FHandlePointer& fh_to_update,
317 bool _v=true, bool _e=true, bool _f=true);
318
320 void clear();
321
331 void clean();
332
340 void clean_keep_reservation();
341
342 // --- number of items ---
343 size_t n_vertices() const override { return vertices_.size(); }
344 size_t n_halfedges() const override { return 2*edges_.size(); }
345 size_t n_edges() const override { return edges_.size(); }
346 size_t n_faces() const override { return faces_.size(); }
347
348 bool vertices_empty() const { return vertices_.empty(); }
349 bool halfedges_empty() const { return edges_.empty(); }
350 bool edges_empty() const { return edges_.empty(); }
351 bool faces_empty() const { return faces_.empty(); }
352
353 // --- vertex connectivity ---
354
355 HalfedgeHandle halfedge_handle(VertexHandle _vh) const
356 { return vertex(_vh).halfedge_handle_; }
357
358 void set_halfedge_handle(VertexHandle _vh, HalfedgeHandle _heh)
359 {
360 // assert(is_valid_handle(_heh));
361 vertex(_vh).halfedge_handle_ = _heh;
362 }
363
364 bool is_isolated(VertexHandle _vh) const
365 { return !halfedge_handle(_vh).is_valid(); }
366
367 void set_isolated(VertexHandle _vh)
368 { vertex(_vh).halfedge_handle_.invalidate(); }
369
370 unsigned int delete_isolated_vertices();
371
372 // --- halfedge connectivity ---
373 VertexHandle to_vertex_handle(HalfedgeHandle _heh) const
374 { return halfedge(_heh).vertex_handle_; }
375
376 VertexHandle from_vertex_handle(HalfedgeHandle _heh) const
377 { return to_vertex_handle(opposite_halfedge_handle(_heh)); }
378
379 void set_vertex_handle(HalfedgeHandle _heh, VertexHandle _vh)
380 {
381 // assert(is_valid_handle(_vh));
382 halfedge(_heh).vertex_handle_ = _vh;
383 }
384
385 FaceHandle face_handle(HalfedgeHandle _heh) const
386 { return halfedge(_heh).face_handle_; }
387
388 void set_face_handle(HalfedgeHandle _heh, FaceHandle _fh)
389 {
390 // assert(is_valid_handle(_fh));
391 halfedge(_heh).face_handle_ = _fh;
392 }
393
394 void set_boundary(HalfedgeHandle _heh)
395 { halfedge(_heh).face_handle_.invalidate(); }
396
398 bool is_boundary(HalfedgeHandle _heh) const
399 { return !face_handle(_heh).is_valid(); }
400
401 HalfedgeHandle next_halfedge_handle(HalfedgeHandle _heh) const
402 { return halfedge(_heh).next_halfedge_handle_; }
403
404 void set_next_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _nheh)
405 {
406 assert(is_valid_handle(_nheh));
407 // assert(to_vertex_handle(_heh) == from_vertex_handle(_nheh));
408 halfedge(_heh).next_halfedge_handle_ = _nheh;
409 set_prev_halfedge_handle(_nheh, _heh);
410 }
411
412
413 void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh)
414 {
415 assert(is_valid_handle(_pheh));
416 set_prev_halfedge_handle(_heh, _pheh, HasPrevHalfedge());
417 }
418
419 void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh,
420 GenProg::TrueType)
421 { halfedge(_heh).prev_halfedge_handle_ = _pheh; }
422
423 void set_prev_halfedge_handle(HalfedgeHandle /* _heh */, HalfedgeHandle /* _pheh */,
424 GenProg::FalseType)
425 {}
426
427 HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh) const
428 { return prev_halfedge_handle(_heh, HasPrevHalfedge() ); }
429
430 HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::TrueType) const
431 { return halfedge(_heh).prev_halfedge_handle_; }
432
433 HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::FalseType) const
434 {
435 if (is_boundary(_heh))
436 {//iterating around the vertex should be faster than iterating the boundary
437 HalfedgeHandle curr_heh(opposite_halfedge_handle(_heh));
438 HalfedgeHandle next_heh(next_halfedge_handle(curr_heh));
439 do
440 {
441 curr_heh = opposite_halfedge_handle(next_heh);
442 next_heh = next_halfedge_handle(curr_heh);
443 }
444 while (next_heh != _heh);
445 return curr_heh;
446 }
447 else
448 {
449 HalfedgeHandle heh(_heh);
450 HalfedgeHandle next_heh(next_halfedge_handle(heh));
451 while (next_heh != _heh) {
452 heh = next_heh;
453 next_heh = next_halfedge_handle(next_heh);
454 }
455 return heh;
456 }
457 }
458
459
460 HalfedgeHandle opposite_halfedge_handle(HalfedgeHandle _heh) const
461 { return HalfedgeHandle(_heh.idx() ^ 1); }
462
463
464 HalfedgeHandle ccw_rotated_halfedge_handle(HalfedgeHandle _heh) const
465 { return opposite_halfedge_handle(prev_halfedge_handle(_heh)); }
466
467
468 HalfedgeHandle cw_rotated_halfedge_handle(HalfedgeHandle _heh) const
469 { return next_halfedge_handle(opposite_halfedge_handle(_heh)); }
470
471 // --- edge connectivity ---
472 static HalfedgeHandle s_halfedge_handle(EdgeHandle _eh, unsigned int _i)
473 {
474 assert(_i<=1);
475 return HalfedgeHandle((_eh.idx() << 1) + _i);
476 }
477
478 static EdgeHandle s_edge_handle(HalfedgeHandle _heh)
479 { return EdgeHandle(_heh.idx() >> 1); }
480
481 HalfedgeHandle halfedge_handle(EdgeHandle _eh, unsigned int _i) const
482 {
483 return s_halfedge_handle(_eh, _i);
484 }
485
486 EdgeHandle edge_handle(HalfedgeHandle _heh) const
487 { return s_edge_handle(_heh); }
488
489 // --- face connectivity ---
490 HalfedgeHandle halfedge_handle(FaceHandle _fh) const
491 { return face(_fh).halfedge_handle_; }
492
493 void set_halfedge_handle(FaceHandle _fh, HalfedgeHandle _heh)
494 {
495 // assert(is_valid_handle(_heh));
496 face(_fh).halfedge_handle_ = _heh;
497 }
498
500 //------------------------------------------------------------ vertex status
501 const StatusInfo& status(VertexHandle _vh) const
502 { return property(vertex_status_, _vh); }
503
504 StatusInfo& status(VertexHandle _vh)
505 { return property(vertex_status_, _vh); }
506
511 void reset_status() {
512 PropertyT<StatusInfo> &status_prop = property(vertex_status_);
513 PropertyT<StatusInfo>::vector_type &sprop_v = status_prop.data_vector();
514 std::fill(sprop_v.begin(), sprop_v.begin() + n_vertices(), StatusInfo());
515 }
516
517 //----------------------------------------------------------- halfedge status
518 const StatusInfo& status(HalfedgeHandle _hh) const
519 { return property(halfedge_status_, _hh); }
520
521 StatusInfo& status(HalfedgeHandle _hh)
522 { return property(halfedge_status_, _hh); }
523
524 //--------------------------------------------------------------- edge status
525 const StatusInfo& status(EdgeHandle _eh) const
526 { return property(edge_status_, _eh); }
527
528 StatusInfo& status(EdgeHandle _eh)
529 { return property(edge_status_, _eh); }
530
531 //--------------------------------------------------------------- face status
532 const StatusInfo& status(FaceHandle _fh) const
533 { return property(face_status_, _fh); }
534
535 StatusInfo& status(FaceHandle _fh)
536 { return property(face_status_, _fh); }
537
538 inline bool has_vertex_status() const
539 { return vertex_status_.is_valid(); }
540
541 inline bool has_halfedge_status() const
542 { return halfedge_status_.is_valid(); }
543
544 inline bool has_edge_status() const
545 { return edge_status_.is_valid(); }
546
547 inline bool has_face_status() const
548 { return face_status_.is_valid(); }
549
550 inline VertexStatusPropertyHandle vertex_status_pph() const
551 { return vertex_status_; }
552
553 inline HalfedgeStatusPropertyHandle halfedge_status_pph() const
554 { return halfedge_status_; }
555
556 inline EdgeStatusPropertyHandle edge_status_pph() const
557 { return edge_status_; }
558
559 inline FaceStatusPropertyHandle face_status_pph() const
560 { return face_status_; }
561
563 inline VertexStatusPropertyHandle status_pph(VertexHandle /*_hnd*/) const
564 { return vertex_status_pph(); }
565
566 inline HalfedgeStatusPropertyHandle status_pph(HalfedgeHandle /*_hnd*/) const
567 { return halfedge_status_pph(); }
568
569 inline EdgeStatusPropertyHandle status_pph(EdgeHandle /*_hnd*/) const
570 { return edge_status_pph(); }
571
572 inline FaceStatusPropertyHandle status_pph(FaceHandle /*_hnd*/) const
573 { return face_status_pph(); }
574
576 void request_vertex_status()
577 {
578 if (!refcount_vstatus_++)
579 add_property( vertex_status_, "v:status" );
580 }
581
582 void request_halfedge_status()
583 {
584 if (!refcount_hstatus_++)
585 add_property( halfedge_status_, "h:status" );
586 }
587
588 void request_edge_status()
589 {
590 if (!refcount_estatus_++)
591 add_property( edge_status_, "e:status" );
592 }
593
594 void request_face_status()
595 {
596 if (!refcount_fstatus_++)
597 add_property( face_status_, "f:status" );
598 }
599
601 void release_vertex_status()
602 {
603 if ((refcount_vstatus_ > 0) && (! --refcount_vstatus_))
604 remove_property(vertex_status_);
605 }
606
607 void release_halfedge_status()
608 {
609 if ((refcount_hstatus_ > 0) && (! --refcount_hstatus_))
610 remove_property(halfedge_status_);
611 }
612
613 void release_edge_status()
614 {
615 if ((refcount_estatus_ > 0) && (! --refcount_estatus_))
616 remove_property(edge_status_);
617 }
618
619 void release_face_status()
620 {
621 if ((refcount_fstatus_ > 0) && (! --refcount_fstatus_))
622 remove_property(face_status_);
623 }
624
626
634 template <class HandleT>
635 class StatusSetT
636 {
637 public:
638 typedef HandleT Handle;
639
640 protected:
641 ArrayKernel& kernel_;
642
643 public:
644 const unsigned int bit_mask_;
645
646 public:
647 StatusSetT(ArrayKernel& _kernel, const unsigned int _bit_mask)
648 : kernel_(_kernel), bit_mask_(_bit_mask)
649 {}
650
651 ~StatusSetT()
652 {}
653
654 inline bool is_in(Handle _hnd) const
655 { return kernel_.status(_hnd).is_bit_set(bit_mask_); }
656
657 inline void insert(Handle _hnd)
658 { kernel_.status(_hnd).set_bit(bit_mask_); }
659
660 inline void erase(Handle _hnd)
661 { kernel_.status(_hnd).unset_bit(bit_mask_); }
662
664 size_t size() const
665 {
666 const int n = kernel_.status_pph(Handle()).is_valid() ?
667 (int)kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
668
669 size_t sz = 0;
670 for (int i = 0; i < n; ++i)
671 sz += (size_t)is_in(Handle(i));
672 return sz;
673 }
674
676 void clear()
677 {
678 const int n = kernel_.status_pph(Handle()).is_valid() ?
679 (int)kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
680
681 for (int i = 0; i < n; ++i)
682 erase(Handle(i));
683 }
684 };
685
686 friend class StatusSetT<VertexHandle>;
687 friend class StatusSetT<EdgeHandle>;
688 friend class StatusSetT<FaceHandle>;
689 friend class StatusSetT<HalfedgeHandle>;
690
692 template <class HandleT>
693 class AutoStatusSetT : public StatusSetT<HandleT>
694 {
695 private:
696 typedef HandleT Handle;
697 typedef StatusSetT<Handle> Base;
698
699 public:
700 explicit AutoStatusSetT(ArrayKernel& _kernel)
701 : StatusSetT<Handle>(_kernel, _kernel.pop_bit_mask(Handle()))
702 { /*assert(size() == 0);*/ } //the set should be empty on creation
703
704 ~AutoStatusSetT()
705 {
706 //assert(size() == 0);//the set should be empty on leave?
707 Base::kernel_.push_bit_mask(Handle(), Base::bit_mask_);
708 }
709 };
710
711 friend class AutoStatusSetT<VertexHandle>;
712 friend class AutoStatusSetT<EdgeHandle>;
713 friend class AutoStatusSetT<FaceHandle>;
714 friend class AutoStatusSetT<HalfedgeHandle>;
715
716 typedef AutoStatusSetT<VertexHandle> VertexStatusSet;
717 typedef AutoStatusSetT<EdgeHandle> EdgeStatusSet;
718 typedef AutoStatusSetT<FaceHandle> FaceStatusSet;
719 typedef AutoStatusSetT<HalfedgeHandle> HalfedgeStatusSet;
720
722 template <class HandleT>
723 class ExtStatusSetT : public AutoStatusSetT<HandleT>
724 {
725 public:
726 typedef HandleT Handle;
727 typedef AutoStatusSetT<Handle> Base;
728
729 protected:
730 typedef std::vector<Handle> HandleContainer;
731 HandleContainer handles_;
732
733 public:
734 typedef typename HandleContainer::iterator
735 iterator;
736 typedef typename HandleContainer::const_iterator
737 const_iterator;
738 public:
739 ExtStatusSetT(ArrayKernel& _kernel, size_t _capacity_hint = 0)
740 : Base(_kernel)
741 { handles_.reserve(_capacity_hint); }
742
743 ~ExtStatusSetT()
744 { clear(); }
745
746 // Complexity: O(1)
747 inline void insert(Handle _hnd)
748 {
749 if (!is_in(_hnd))
750 {
751 Base::insert(_hnd);
752 handles_.push_back(_hnd);
753 }
754 }
755
757 inline void erase(Handle _hnd)
758 {
759 if (is_in(_hnd))
760 {
761 iterator it = std::find(begin(), end(), _hnd);
762 erase(it);
763 }
764 }
765
767 inline void erase(iterator _it)
768 {
769 assert(_it != const_cast<const ExtStatusSetT*>(this)->end() && is_in(*_it));
770 Base::erase(*_it);
771 *_it = handles_.back();
772 _it.pop_back();
773 }
774
775 inline void clear()
776 {
777 for (iterator it = begin(); it != end(); ++it)
778 {
779 assert(is_in(*it));
780 Base::erase(*it);
781 }
782 handles_.clear();
783 }
784
786 inline unsigned int size() const
787 { return handles_.size(); }
788 inline bool empty() const
789 { return handles_.empty(); }
790
791 //Vector API
792 inline iterator begin()
793 { return handles_.begin(); }
794 inline const_iterator begin() const
795 { return handles_.begin(); }
796
797 inline iterator end()
798 { return handles_.end(); }
799 inline const_iterator end() const
800 { return handles_.end(); }
801
802 inline Handle& front()
803 { return handles_.front(); }
804 inline const Handle& front() const
805 { return handles_.front(); }
806
807 inline Handle& back()
808 { return handles_.back(); }
809 inline const Handle& back() const
810 { return handles_.back(); }
811 };
812
813 typedef ExtStatusSetT<FaceHandle> ExtFaceStatusSet;
814 typedef ExtStatusSetT<VertexHandle> ExtVertexStatusSet;
815 typedef ExtStatusSetT<EdgeHandle> ExtEdgeStatusSet;
816 typedef ExtStatusSetT<HalfedgeHandle> ExtHalfedgeStatusSet;
817
818 private:
819 // iterators
820 typedef std::vector<Vertex> VertexContainer;
821 typedef std::vector<Edge> EdgeContainer;
822 typedef std::vector<Face> FaceContainer;
823 typedef VertexContainer::iterator KernelVertexIter;
824 typedef VertexContainer::const_iterator KernelConstVertexIter;
825 typedef EdgeContainer::iterator KernelEdgeIter;
826 typedef EdgeContainer::const_iterator KernelConstEdgeIter;
827 typedef FaceContainer::iterator KernelFaceIter;
828 typedef FaceContainer::const_iterator KernelConstFaceIter;
829 typedef std::vector<unsigned int> BitMaskContainer;
830
831
832 KernelVertexIter vertices_begin() { return vertices_.begin(); }
833 KernelConstVertexIter vertices_begin() const { return vertices_.begin(); }
834 KernelVertexIter vertices_end() { return vertices_.end(); }
835 KernelConstVertexIter vertices_end() const { return vertices_.end(); }
836
837 KernelEdgeIter edges_begin() { return edges_.begin(); }
838 KernelConstEdgeIter edges_begin() const { return edges_.begin(); }
839 KernelEdgeIter edges_end() { return edges_.end(); }
840 KernelConstEdgeIter edges_end() const { return edges_.end(); }
841
842 KernelFaceIter faces_begin() { return faces_.begin(); }
843 KernelConstFaceIter faces_begin() const { return faces_.begin(); }
844 KernelFaceIter faces_end() { return faces_.end(); }
845 KernelConstFaceIter faces_end() const { return faces_.end(); }
846
848 inline BitMaskContainer& bit_masks(VertexHandle /*_dummy_hnd*/)
849 { return vertex_bit_masks_; }
850 inline BitMaskContainer& bit_masks(EdgeHandle /*_dummy_hnd*/)
851 { return edge_bit_masks_; }
852 inline BitMaskContainer& bit_masks(FaceHandle /*_dummy_hnd*/)
853 { return face_bit_masks_; }
854 inline BitMaskContainer& bit_masks(HalfedgeHandle /*_dummy_hnd*/)
855 { return halfedge_bit_masks_; }
856
857 template <class Handle>
858 unsigned int pop_bit_mask(Handle _hnd)
859 {
860 assert(!bit_masks(_hnd).empty());//check if the client request too many status sets
861 unsigned int bit_mask = bit_masks(_hnd).back();
862 bit_masks(_hnd).pop_back();
863 return bit_mask;
864 }
865
866 template <class Handle>
867 void push_bit_mask(Handle _hnd, unsigned int _bit_mask)
868 {
869 assert(std::find(bit_masks(_hnd).begin(), bit_masks(_hnd).end(), _bit_mask) ==
870 bit_masks(_hnd).end());//this mask should be not already used
871 bit_masks(_hnd).push_back(_bit_mask);
872 }
873
874 void init_bit_masks(BitMaskContainer& _bmc);
875 void init_bit_masks();
876
877 protected:
878
879 VertexStatusPropertyHandle vertex_status_;
880 HalfedgeStatusPropertyHandle halfedge_status_;
881 EdgeStatusPropertyHandle edge_status_;
882 FaceStatusPropertyHandle face_status_;
883
884 unsigned int refcount_vstatus_;
885 unsigned int refcount_hstatus_;
886 unsigned int refcount_estatus_;
887 unsigned int refcount_fstatus_;
888
889 private:
890 VertexContainer vertices_;
891 EdgeContainer edges_;
892 FaceContainer faces_;
893
894 BitMaskContainer halfedge_bit_masks_;
895 BitMaskContainer edge_bit_masks_;
896 BitMaskContainer vertex_bit_masks_;
897 BitMaskContainer face_bit_masks_;
898 };
899
900
901 //=============================================================================
902 } // namespace OpenMesh
903 //=============================================================================
904 #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_ARRAY_KERNEL_C)
905 # define OPENMESH_ARRAY_KERNEL_TEMPLATES
906 # include "ArrayKernelT_impl.hh"
907 #endif
908 //=============================================================================
909 #endif // OPENMESH_ARRAY_KERNEL_HH defined
910 //=============================================================================
OpenMesh::FPropHandleT< StatusInfo >
OpenMesh::FaceHandle
Handle for a face entity.
Definition: Handles.hh:141
OpenMesh::VPropHandleT< StatusInfo >
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:180
OpenMesh::Attributes::StatusInfo::unset_bit
void unset_bit(unsigned int _s)
unset a certain bit
Definition: Status.hh:161
OpenMesh::ArrayKernel::release_vertex_status
void release_vertex_status()
Status Release API.
Definition: ArrayKernel.hh:601
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:234
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:310
OpenMesh::Attributes::StatusInfo::is_bit_set
bool is_bit_set(unsigned int _s) const
is a certain bit set ?
Definition: Status.hh:157
OpenMesh::BaseHandle::invalidate
void invalidate()
reset handle to be invalid
Definition: Handles.hh:77
OpenMesh::ArrayKernel::AutoStatusSetT
AutoStatusSetT: A status set that automatically picks a status bit.
Definition: ArrayKernel.hh:693
OpenMesh::BaseHandle::is_valid
bool is_valid() const
The handle is valid iff the index is not negative.
Definition: Handles.hh:72
OpenMesh::ArrayKernel::status
const StatusInfo & status(VertexHandle _vh) const
Status Query API.
Definition: ArrayKernel.hh:501
OpenMesh::VertexHandle
Handle for a vertex entity.
Definition: Handles.hh:120
OpenMesh::ArrayKernel::ExtStatusSetT::size
unsigned int size() const
Complexity: 0(1)
Definition: ArrayKernel.hh:786
OpenMesh::ArrayKernel::is_boundary
bool is_boundary(HalfedgeHandle _heh) const
Is halfedge _heh a boundary halfedge (is its face handle invalid) ?
Definition: ArrayKernel.hh:398
OpenMesh::EPropHandleT< StatusInfo >
OpenMesh::BaseHandle::idx
int idx() const
Get the underlying index of this handle.
Definition: Handles.hh:69
OpenMesh::ArrayKernel::StatusSetT::clear
void clear()
Note: O(n) complexity.
Definition: ArrayKernel.hh:676
OpenMesh::ArrayKernel::StatusSetT
— StatusSet API —
Definition: ArrayKernel.hh:635
OpenMesh::ArrayKernel::request_vertex_status
void request_vertex_status()
Status Request API.
Definition: ArrayKernel.hh:576
OpenMesh::EdgeHandle
Handle for a edge entity.
Definition: Handles.hh:134
OpenMesh::ArrayKernel::reset_status
void reset_status()
Reinitializes the status of all vertices using the StatusInfo default constructor, i.e.
Definition: ArrayKernel.hh:511
OpenMesh::PropertyT
Default property class for any type T.
Definition: Property.hh:89
OpenMesh::ArrayKernel::ExtStatusSetT
ExtStatusSet: A status set augmented with an array.
Definition: ArrayKernel.hh:723
OpenMesh::ArrayKernel::ExtStatusSetT::erase
void erase(iterator _it)
Complexity: O(1)
Definition: ArrayKernel.hh:767
OpenMesh::ArrayKernel
Mesh kernel using arrays for mesh item storage.
Definition: ArrayKernel.hh:87
OpenMesh::ArrayKernel::status_pph
VertexStatusPropertyHandle status_pph(VertexHandle) const
status property by handle
Definition: ArrayKernel.hh:563
OpenMesh::Attributes::StatusInfo
Add status information to a base class.
Definition: Status.hh:94
OpenMesh::HPropHandleT< StatusInfo >
OpenMesh
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:59
OpenMesh::Attributes::StatusInfo::set_bit
void set_bit(unsigned int _s)
set a certain bit
Definition: Status.hh:159
OpenMesh::HalfedgeHandle
Handle for a halfedge entity.
Definition: Handles.hh:127
OpenMesh::BaseKernel
This class provides low-level property management like adding/removing properties and access to prope...
Definition: BaseKernel.hh:97
OpenMesh::ArrayKernel::new_vertex
VertexHandle new_vertex()
Add a new vertex.
Definition: ArrayKernel.hh:216
OpenMesh::ArrayKernel::ExtStatusSetT::erase
void erase(Handle _hnd)
Complexity: O(k), (k - number of the elements in the set)
Definition: ArrayKernel.hh:757
OpenMesh::ArrayKernel::StatusSetT::size
size_t size() const
Note: 0(n) complexity.
Definition: ArrayKernel.hh:664