87class OPENMESHDLLEXPORT ArrayKernel :
public BaseKernel,
public ArrayItems
106 virtual ~ArrayKernel();
117 VertexHandle handle(
const Vertex& _v)
const;
119 HalfedgeHandle handle(
const Halfedge& _he)
const;
121 EdgeHandle handle(
const Edge& _e)
const;
123 FaceHandle handle(
const Face& _f)
const;
140 const Vertex& vertex(VertexHandle _vh)
const
143 return vertices_[_vh.
idx()];
146 Vertex& vertex(VertexHandle _vh)
149 return vertices_[_vh.
idx()];
152 const Halfedge& halfedge(HalfedgeHandle _heh)
const
155 return edges_[_heh.
idx() >> 1].halfedges_[_heh.
idx() & 1];
158 Halfedge& halfedge(HalfedgeHandle _heh)
161 return edges_[_heh.
idx() >> 1].halfedges_[_heh.
idx() & 1];
164 const Edge& edge(EdgeHandle _eh)
const
167 return edges_[_eh.
idx()];
170 Edge& edge(EdgeHandle _eh)
173 return edges_[_eh.
idx()];
176 const Face& face(FaceHandle _fh)
const
179 return faces_[_fh.
idx()];
182 Face& face(FaceHandle _fh)
185 return faces_[_fh.
idx()];
190 VertexHandle vertex_handle(
unsigned int _i)
const
191 {
return (_i <
n_vertices()) ? handle( vertices_[_i] ) : VertexHandle(); }
200 {
return (_i <
n_edges()) ? handle(edges_[_i]) : EdgeHandle(); }
203 {
return (_i <
n_faces()) ? handle(faces_[_i]) : FaceHandle(); }
218 vertices_.push_back(Vertex());
221 return handle(vertices_.back());
236 vertices_.push_back(Vertex());
239 return handle(vertices_.back());
245 edges_.push_back(Edge());
246 eprops_resize(n_edges());
247 hprops_resize(n_halfedges());
252 set_vertex_handle(heh0, _end_vh);
253 set_vertex_handle(heh1, _start_vh);
257 inline FaceHandle new_face()
259 faces_.push_back(Face());
260 fprops_resize(n_faces());
261 return handle(faces_.back());
264 inline FaceHandle new_face(
const Face& _f)
266 faces_.push_back(_f);
267 fprops_resize(n_faces());
268 return handle(faces_.back());
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 );
292 void garbage_collection(
bool _v=
true,
bool _e=
true,
bool _f=
true);
313 template<
typename std_API_Container_VHandlePointer,
314 typename std_API_Container_HHandlePointer,
315 typename std_API_Container_FHandlePointer>
316 void garbage_collection(std_API_Container_VHandlePointer& vh_to_update,
317 std_API_Container_HHandlePointer& hh_to_update,
318 std_API_Container_FHandlePointer& fh_to_update,
319 bool _v=
true,
bool _e=
true,
bool _f=
true);
342 void clean_keep_reservation();
345 size_t n_vertices()
const override {
return vertices_.size(); }
347 size_t n_edges()
const override {
return edges_.size(); }
348 size_t n_faces()
const override {
return faces_.size(); }
350 bool vertices_empty()
const {
return vertices_.empty(); }
351 bool halfedges_empty()
const {
return edges_.empty(); }
352 bool edges_empty()
const {
return edges_.empty(); }
353 bool faces_empty()
const {
return faces_.empty(); }
358 {
return vertex(_vh).halfedge_handle_; }
363 vertex(_vh).halfedge_handle_ = _heh;
366 bool is_isolated(VertexHandle _vh)
const
367 {
return !halfedge_handle(_vh).
is_valid(); }
369 void set_isolated(VertexHandle _vh)
370 { vertex(_vh).halfedge_handle_.invalidate(); }
372 unsigned int delete_isolated_vertices();
375 VertexHandle to_vertex_handle(HalfedgeHandle _heh)
const
376 {
return halfedge(_heh).vertex_handle_; }
378 VertexHandle from_vertex_handle(HalfedgeHandle _heh)
const
379 {
return to_vertex_handle(opposite_halfedge_handle(_heh)); }
381 void set_vertex_handle(HalfedgeHandle _heh, VertexHandle _vh)
384 halfedge(_heh).vertex_handle_ = _vh;
388 {
return halfedge(_heh).face_handle_; }
393 halfedge(_heh).face_handle_ = _fh;
396 void set_boundary(HalfedgeHandle _heh)
401 {
return !face_handle(_heh).is_valid(); }
404 {
return halfedge(_heh).next_halfedge_handle_; }
408 assert(is_valid_handle(_nheh));
410 halfedge(_heh).next_halfedge_handle_ = _nheh;
411 set_prev_halfedge_handle(_nheh, _heh);
415 void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh)
417 assert(is_valid_handle(_pheh));
418 set_prev_halfedge_handle(_heh, _pheh, HasPrevHalfedge());
421 void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh,
423 { halfedge(_heh).prev_halfedge_handle_ = _pheh; }
425 void set_prev_halfedge_handle(HalfedgeHandle , HalfedgeHandle ,
433 {
return halfedge(_heh).prev_halfedge_handle_; }
446 while (next_heh != _heh);
451 HalfedgeHandle heh(_heh);
453 while (next_heh != _heh) {
463 {
return HalfedgeHandle(_heh.
idx() ^ 1); }
477 return HalfedgeHandle((_eh.
idx() << 1) + _i);
481 {
return EdgeHandle(_heh.
idx() >> 1); }
493 {
return face(_fh).halfedge_handle_; }
498 face(_fh).halfedge_handle_ = _heh;
503 const StatusInfo&
status(VertexHandle _vh)
const
504 {
return property(vertex_status_, _vh); }
507 {
return property(vertex_status_, _vh); }
515 PropertyT<StatusInfo>::vector_type &sprop_v = status_prop.
data_vector();
516 std::fill(sprop_v.begin(), sprop_v.begin() +
n_vertices(), StatusInfo());
521 {
return property(halfedge_status_, _hh); }
523 StatusInfo& status(HalfedgeHandle _hh)
524 {
return property(halfedge_status_, _hh); }
527 const StatusInfo& status(EdgeHandle _eh)
const
528 {
return property(edge_status_, _eh); }
530 StatusInfo& status(EdgeHandle _eh)
531 {
return property(edge_status_, _eh); }
534 const StatusInfo& status(FaceHandle _fh)
const
535 {
return property(face_status_, _fh); }
537 StatusInfo& status(FaceHandle _fh)
538 {
return property(face_status_, _fh); }
540 inline bool has_vertex_status()
const
541 {
return vertex_status_.is_valid(); }
543 inline bool has_halfedge_status()
const
544 {
return halfedge_status_.is_valid(); }
546 inline bool has_edge_status()
const
547 {
return edge_status_.is_valid(); }
549 inline bool has_face_status()
const
550 {
return face_status_.is_valid(); }
552 inline VertexStatusPropertyHandle vertex_status_pph()
const
553 {
return vertex_status_; }
555 inline HalfedgeStatusPropertyHandle halfedge_status_pph()
const
556 {
return halfedge_status_; }
558 inline EdgeStatusPropertyHandle edge_status_pph()
const
559 {
return edge_status_; }
561 inline FaceStatusPropertyHandle face_status_pph()
const
562 {
return face_status_; }
565 inline VertexStatusPropertyHandle
status_pph(VertexHandle )
const
566 {
return vertex_status_pph(); }
568 inline HalfedgeStatusPropertyHandle status_pph(
HalfedgeHandle )
const
569 {
return halfedge_status_pph(); }
571 inline EdgeStatusPropertyHandle status_pph(EdgeHandle )
const
572 {
return edge_status_pph(); }
574 inline FaceStatusPropertyHandle status_pph(FaceHandle )
const
575 {
return face_status_pph(); }
580 if (!refcount_vstatus_++)
584 void request_halfedge_status()
586 if (!refcount_hstatus_++)
587 add_property( halfedge_status_,
"h:status" );
590 void request_edge_status()
592 if (!refcount_estatus_++)
593 add_property( edge_status_,
"e:status" );
596 void request_face_status()
598 if (!refcount_fstatus_++)
599 add_property( face_status_,
"f:status" );
605 if ((refcount_vstatus_ > 0) && (! --refcount_vstatus_))
609 void release_halfedge_status()
611 if ((refcount_hstatus_ > 0) && (! --refcount_hstatus_))
612 remove_property(halfedge_status_);
615 void release_edge_status()
617 if ((refcount_estatus_ > 0) && (! --refcount_estatus_))
618 remove_property(edge_status_);
621 void release_face_status()
623 if ((refcount_fstatus_ > 0) && (! --refcount_fstatus_))
624 remove_property(face_status_);
636 template <
class HandleT>
640 typedef HandleT Handle;
643 ArrayKernel& kernel_;
646 const unsigned int bit_mask_;
649 StatusSetT(ArrayKernel& _kernel,
const unsigned int _bit_mask)
650 : kernel_(_kernel), bit_mask_(_bit_mask)
656 inline bool is_in(Handle _hnd)
const
657 {
return kernel_.status(_hnd).is_bit_set(bit_mask_); }
659 inline void insert(Handle _hnd)
660 { kernel_.status(_hnd).set_bit(bit_mask_); }
662 inline void erase(Handle _hnd)
663 { kernel_.status(_hnd).unset_bit(bit_mask_); }
668 const int n = kernel_.status_pph(Handle()).is_valid() ?
669 (int)kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
672 for (
int i = 0; i < n; ++i)
673 sz += (
size_t)is_in(Handle(i));
680 const int n = kernel_.status_pph(Handle()).is_valid() ?
681 (int)kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
683 for (
int i = 0; i < n; ++i)
694 template <
class HandleT>
695 class AutoStatusSetT :
public StatusSetT<HandleT>
698 typedef HandleT Handle;
699 typedef StatusSetT<Handle> Base;
702 explicit AutoStatusSetT(ArrayKernel& _kernel)
703 : StatusSetT<Handle>(_kernel, _kernel.pop_bit_mask(Handle()))
709 Base::kernel_.push_bit_mask(Handle(), Base::bit_mask_);
724 template <
class HandleT>
725 class ExtStatusSetT :
public AutoStatusSetT<HandleT>
728 typedef HandleT Handle;
729 typedef AutoStatusSetT<Handle> Base;
732 typedef std::vector<Handle> HandleContainer;
733 HandleContainer handles_;
736 typedef typename HandleContainer::iterator
738 typedef typename HandleContainer::const_iterator
741 explicit ExtStatusSetT(ArrayKernel& _kernel,
size_t _capacity_hint = 0)
743 { handles_.reserve(_capacity_hint); }
749 inline void insert(Handle _hnd)
751 if (!Base::is_in(_hnd))
754 handles_.push_back(_hnd);
763 iterator it = std::find(begin(), end(), _hnd);
771 assert(_it !=
const_cast<const ExtStatusSetT*
>(
this)->end() &&
774 *_it = handles_.back();
780 for (iterator it = begin(); it != end(); ++it)
782 assert(Base::is_in(*it));
789 inline unsigned int size()
const
790 {
return handles_.size(); }
791 inline bool empty()
const
792 {
return handles_.empty(); }
795 inline iterator begin()
796 {
return handles_.begin(); }
797 inline const_iterator begin()
const
798 {
return handles_.begin(); }
800 inline iterator end()
801 {
return handles_.end(); }
802 inline const_iterator end()
const
803 {
return handles_.end(); }
805 inline Handle& front()
806 {
return handles_.front(); }
807 inline const Handle& front()
const
808 {
return handles_.front(); }
810 inline Handle& back()
811 {
return handles_.back(); }
812 inline const Handle& back()
const
813 {
return handles_.back(); }
816 typedef ExtStatusSetT<FaceHandle> ExtFaceStatusSet;
817 typedef ExtStatusSetT<VertexHandle> ExtVertexStatusSet;
818 typedef ExtStatusSetT<EdgeHandle> ExtEdgeStatusSet;
819 typedef ExtStatusSetT<HalfedgeHandle> ExtHalfedgeStatusSet;
823 typedef std::vector<Vertex> VertexContainer;
824 typedef std::vector<Edge> EdgeContainer;
825 typedef std::vector<Face> FaceContainer;
826 typedef VertexContainer::iterator KernelVertexIter;
827 typedef VertexContainer::const_iterator KernelConstVertexIter;
828 typedef EdgeContainer::iterator KernelEdgeIter;
829 typedef EdgeContainer::const_iterator KernelConstEdgeIter;
830 typedef FaceContainer::iterator KernelFaceIter;
831 typedef FaceContainer::const_iterator KernelConstFaceIter;
832 typedef std::vector<unsigned int> BitMaskContainer;
835 KernelVertexIter vertices_begin() {
return vertices_.begin(); }
836 KernelConstVertexIter vertices_begin()
const {
return vertices_.begin(); }
837 KernelVertexIter vertices_end() {
return vertices_.end(); }
838 KernelConstVertexIter vertices_end()
const {
return vertices_.end(); }
840 KernelEdgeIter edges_begin() {
return edges_.begin(); }
841 KernelConstEdgeIter edges_begin()
const {
return edges_.begin(); }
842 KernelEdgeIter edges_end() {
return edges_.end(); }
843 KernelConstEdgeIter edges_end()
const {
return edges_.end(); }
845 KernelFaceIter faces_begin() {
return faces_.begin(); }
846 KernelConstFaceIter faces_begin()
const {
return faces_.begin(); }
847 KernelFaceIter faces_end() {
return faces_.end(); }
848 KernelConstFaceIter faces_end()
const {
return faces_.end(); }
851 inline BitMaskContainer& bit_masks(VertexHandle )
852 {
return vertex_bit_masks_; }
853 inline BitMaskContainer& bit_masks(EdgeHandle )
854 {
return edge_bit_masks_; }
855 inline BitMaskContainer& bit_masks(FaceHandle )
856 {
return face_bit_masks_; }
857 inline BitMaskContainer& bit_masks(HalfedgeHandle )
858 {
return halfedge_bit_masks_; }
860 template <
class Handle>
861 unsigned int pop_bit_mask(Handle _hnd)
863 assert(!bit_masks(_hnd).empty());
864 unsigned int bit_mask = bit_masks(_hnd).back();
865 bit_masks(_hnd).pop_back();
869 template <
class Handle>
870 void push_bit_mask(Handle _hnd,
unsigned int _bit_mask)
872 assert(std::find(bit_masks(_hnd).begin(), bit_masks(_hnd).end(), _bit_mask) ==
873 bit_masks(_hnd).end());
874 bit_masks(_hnd).push_back(_bit_mask);
877 void init_bit_masks(BitMaskContainer& _bmc);
878 void init_bit_masks();
882 VertexStatusPropertyHandle vertex_status_;
883 HalfedgeStatusPropertyHandle halfedge_status_;
884 EdgeStatusPropertyHandle edge_status_;
885 FaceStatusPropertyHandle face_status_;
887 unsigned int refcount_vstatus_;
888 unsigned int refcount_hstatus_;
889 unsigned int refcount_estatus_;
890 unsigned int refcount_fstatus_;
893 VertexContainer vertices_;
894 EdgeContainer edges_;
895 FaceContainer faces_;
897 BitMaskContainer halfedge_bit_masks_;
898 BitMaskContainer edge_bit_masks_;
899 BitMaskContainer vertex_bit_masks_;
900 BitMaskContainer face_bit_masks_;