50 #ifndef OPENMESH_ARRAY_KERNEL_HH
51 #define OPENMESH_ARRAY_KERNEL_HH
57 #include <OpenMesh/Core/System/config.h>
58 #include <OpenMesh/Core/Utils/GenProg.hh>
60 #include <OpenMesh/Core/Mesh/ArrayItems.hh>
61 #include <OpenMesh/Core/Mesh/BaseKernel.hh>
62 #include <OpenMesh/Core/Mesh/Status.hh>
124 uint 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]) ?
137 #define SIGNED(x) signed( (x) )
140 {
return 0 <= _vh.
idx() && _vh.
idx() < SIGNED(n_vertices()); }
143 {
return 0 <= _heh.
idx() && _heh.
idx() < SIGNED(n_edges()*2); }
146 {
return 0 <= _eh.
idx() && _eh.
idx() < SIGNED(n_edges()); }
149 {
return 0 <= _fh.
idx() && _fh.
idx() < SIGNED(n_faces()); }
154 assert(is_valid_handle(_vh));
155 return vertices_[_vh.
idx()];
160 assert(is_valid_handle(_vh));
161 return vertices_[_vh.
idx()];
166 assert(is_valid_handle(_heh));
167 return edges_[_heh.
idx() >> 1].halfedges_[_heh.
idx() & 1];
172 assert(is_valid_handle(_heh));
173 return edges_[_heh.
idx() >> 1].halfedges_[_heh.
idx() & 1];
178 assert(is_valid_handle(_eh));
179 return edges_[_eh.
idx()];
184 assert(is_valid_handle(_eh));
185 return edges_[_eh.
idx()];
190 assert(is_valid_handle(_fh));
191 return faces_[_fh.
idx()];
196 assert(is_valid_handle(_fh));
197 return faces_[_fh.
idx()];
205 {
return (_i < n_vertices()) ? handle( vertices_[_i] ) :
VertexHandle(); }
209 return (_i < n_halfedges()) ?
214 {
return (_i < n_edges()) ? handle(edges_[_i]) :
EdgeHandle(); }
217 {
return (_i < n_faces()) ? handle(faces_[_i]) :
FaceHandle(); }
223 vertices_.push_back(Vertex());
224 vprops_resize(n_vertices());
226 return handle(vertices_.back());
232 edges_.push_back(
Edge());
233 eprops_resize(n_edges());
234 hprops_resize(n_halfedges());
239 set_vertex_handle(heh0, _end_vh);
240 set_vertex_handle(heh1, _start_vh);
246 faces_.push_back(Face());
247 fprops_resize(n_faces());
248 return handle(faces_.back());
253 faces_.push_back(_f);
254 fprops_resize(n_faces());
255 return handle(faces_.back());
260 void resize( uint _n_vertices, uint _n_edges, uint _n_faces );
261 void reserve(uint _n_vertices, uint _n_edges, uint _n_faces );
264 void garbage_collection(
bool _v=
true,
bool _e=
true,
bool _f=
true);
268 uint n_vertices()
const {
return vertices_.size(); }
269 uint n_halfedges()
const {
return 2*edges_.size(); }
270 uint n_edges()
const {
return edges_.size(); }
271 uint n_faces()
const {
return faces_.size(); }
273 bool vertices_empty()
const {
return vertices_.empty(); }
274 bool halfedges_empty()
const {
return edges_.empty(); }
275 bool edges_empty()
const {
return edges_.empty(); }
276 bool faces_empty()
const {
return faces_.empty(); }
281 {
return vertex(_vh).halfedge_handle_; }
286 vertex(_vh).halfedge_handle_ = _heh;
290 {
return !halfedge_handle(_vh).
is_valid(); }
293 { vertex(_vh).halfedge_handle_.
invalidate(); }
295 uint delete_isolated_vertices();
299 {
return halfedge(_heh).vertex_handle_; }
302 {
return to_vertex_handle(opposite_halfedge_handle(_heh)); }
307 halfedge(_heh).vertex_handle_ = _vh;
311 {
return halfedge(_heh).face_handle_; }
316 halfedge(_heh).face_handle_ = _fh;
320 { halfedge(_heh).face_handle_.invalidate(); }
324 {
return !face_handle(_heh).
is_valid(); }
327 {
return halfedge(_heh).next_halfedge_handle_; }
329 void set_next_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _nheh)
331 assert(is_valid_handle(_nheh));
333 halfedge(_heh).next_halfedge_handle_ = _nheh;
334 set_prev_halfedge_handle(_nheh, _heh);
338 void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh)
340 assert(is_valid_handle(_pheh));
341 set_prev_halfedge_handle(_heh, _pheh, HasPrevHalfedge());
344 void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh,
346 { halfedge(_heh).prev_halfedge_handle_ = _pheh; }
348 void set_prev_halfedge_handle(HalfedgeHandle , HalfedgeHandle ,
352 HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh)
const
353 {
return prev_halfedge_handle(_heh, HasPrevHalfedge() ); }
355 HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh,
GenProg::True)
const
356 {
return halfedge(_heh).prev_halfedge_handle_; }
358 HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh,
GenProg::False)
const
362 HalfedgeHandle curr_heh(opposite_halfedge_handle(_heh));
363 HalfedgeHandle next_heh(next_halfedge_handle(curr_heh));
366 curr_heh = opposite_halfedge_handle(next_heh);
367 next_heh = next_halfedge_handle(curr_heh);
369 while (next_heh != _heh);
374 HalfedgeHandle heh(_heh);
375 HalfedgeHandle next_heh(next_halfedge_handle(heh));
376 while (next_heh != _heh) {
378 next_heh = next_halfedge_handle(next_heh);
385 HalfedgeHandle opposite_halfedge_handle(HalfedgeHandle _heh)
const
386 {
return HalfedgeHandle((_heh.idx() & 1) ? _heh.idx()-1 : _heh.idx()+1); }
389 HalfedgeHandle ccw_rotated_halfedge_handle(HalfedgeHandle _heh)
const
390 {
return opposite_halfedge_handle(prev_halfedge_handle(_heh)); }
393 HalfedgeHandle cw_rotated_halfedge_handle(HalfedgeHandle _heh)
const
394 {
return next_halfedge_handle(opposite_halfedge_handle(_heh)); }
397 HalfedgeHandle halfedge_handle(EdgeHandle _eh, uint _i)
const
400 return HalfedgeHandle((_eh.idx() << 1) + _i);
403 EdgeHandle edge_handle(HalfedgeHandle _heh)
const
404 {
return EdgeHandle(_heh.idx() >> 1); }
407 HalfedgeHandle halfedge_handle(FaceHandle _fh)
const
408 {
return face(_fh).halfedge_handle_; }
410 void set_halfedge_handle(FaceHandle _fh, HalfedgeHandle _heh)
413 face(_fh).halfedge_handle_ = _heh;
419 {
return property(vertex_status_, _vh); }
422 {
return property(vertex_status_, _vh); }
425 const StatusInfo&
status(HalfedgeHandle _hh)
const
426 {
return property(halfedge_status_, _hh); }
428 StatusInfo&
status(HalfedgeHandle _hh)
429 {
return property(halfedge_status_, _hh); }
432 const StatusInfo&
status(EdgeHandle _eh)
const
433 {
return property(edge_status_, _eh); }
435 StatusInfo&
status(EdgeHandle _eh)
436 {
return property(edge_status_, _eh); }
439 const StatusInfo&
status(FaceHandle _fh)
const
440 {
return property(face_status_, _fh); }
442 StatusInfo&
status(FaceHandle _fh)
443 {
return property(face_status_, _fh); }
445 inline bool has_vertex_status()
const
446 {
return vertex_status_.
is_valid(); }
448 inline bool has_halfedge_status()
const
449 {
return halfedge_status_.
is_valid(); }
451 inline bool has_edge_status()
const
454 inline bool has_face_status()
const
457 inline VertexStatusPropertyHandle vertex_status_pph()
const
458 {
return vertex_status_; }
460 inline HalfedgeStatusPropertyHandle halfedge_status_pph()
const
461 {
return halfedge_status_; }
463 inline EdgeStatusPropertyHandle edge_status_pph()
const
464 {
return edge_status_; }
466 inline FaceStatusPropertyHandle face_status_pph()
const
467 {
return face_status_; }
471 {
return vertex_status_pph(); }
474 {
return halfedge_status_pph(); }
476 inline EdgeStatusPropertyHandle
status_pph(EdgeHandle )
const
477 {
return edge_status_pph(); }
479 inline FaceStatusPropertyHandle
status_pph(FaceHandle )
const
480 {
return face_status_pph(); }
485 if (!refcount_vstatus_++)
489 void request_halfedge_status()
491 if (!refcount_hstatus_++)
495 void request_edge_status()
497 if (!refcount_estatus_++)
501 void request_face_status()
503 if (!refcount_fstatus_++)
510 if ((refcount_vstatus_ > 0) && (! --refcount_vstatus_))
514 void release_halfedge_status()
516 if ((refcount_hstatus_ > 0) && (! --refcount_hstatus_))
520 void release_edge_status()
522 if ((refcount_estatus_ > 0) && (! --refcount_estatus_))
526 void release_face_status()
528 if ((refcount_fstatus_ > 0) && (! --refcount_fstatus_))
534 template <
class Handle>
541 const uint bit_mask_;
545 : kernel_(_kernel), bit_mask_(_bit_mask)
551 inline bool is_in(Handle _hnd)
const
554 inline void insert(Handle _hnd)
557 inline void erase(Handle _hnd)
566 for (uint i = 0; i < n_elements; ++i)
568 sz += (uint)is_in(Handle(i));
578 for (uint i = 0; i < n_elements; ++i)
592 template <
class Handle>
605 Base::kernel_.push_bit_mask(Handle(), Base::bit_mask_);
621 template <
class Handle>
628 typedef std::vector<Handle> HandleContainer;
629 HandleContainer handles_;
632 typedef typename HandleContainer::iterator
634 typedef typename HandleContainer::const_iterator
639 { handles_.reserve(_capacity_hint); }
646 inline void insert(Handle _hnd)
651 handles_.push_back(_hnd);
656 inline void erase(Handle _hnd)
660 iterator it = std::find(begin(), end(), _hnd);
666 inline void erase(iterator _it)
668 assert(_it != end() && is_in(*_it));
670 *_it = handles_.back();
676 for (iterator it = begin(); it != end(); ++it)
686 {
return handles_.size(); }
687 inline bool empty()
const
688 {
return handles_.empty(); }
691 inline iterator begin()
692 {
return handles_.begin(); }
693 inline const_iterator begin()
const
694 {
return handles_.begin(); }
696 inline iterator end()
697 {
return handles_.end(); }
698 inline const_iterator end()
const
699 {
return handles_.end(); }
701 inline Handle& front()
702 {
return handles_.front(); }
703 inline const Handle& front()
const
704 {
return handles_.front(); }
706 inline Handle& back()
707 {
return handles_.back(); }
708 inline const Handle& back()
const
709 {
return handles_.back(); }
712 typedef ExtStatusSetT<FaceHandle> ExtFaceStatusSet;
713 typedef ExtStatusSetT<VertexHandle> ExtVertexStatusSet;
714 typedef ExtStatusSetT<EdgeHandle> ExtEdgeStatusSet;
715 typedef ExtStatusSetT<HalfedgeHandle> ExtHalfedgeStatusSet;
719 typedef std::vector<Vertex> VertexContainer;
720 typedef std::vector<Edge> EdgeContainer;
721 typedef std::vector<Face> FaceContainer;
722 typedef VertexContainer::iterator KernelVertexIter;
723 typedef VertexContainer::const_iterator KernelConstVertexIter;
724 typedef EdgeContainer::iterator KernelEdgeIter;
725 typedef EdgeContainer::const_iterator KernelConstEdgeIter;
726 typedef FaceContainer::iterator KernelFaceIter;
727 typedef FaceContainer::const_iterator KernelConstFaceIter;
728 typedef std::vector<uint> BitMaskContainer;
731 KernelVertexIter vertices_begin() {
return vertices_.begin(); }
732 KernelConstVertexIter vertices_begin()
const {
return vertices_.begin(); }
733 KernelVertexIter vertices_end() {
return vertices_.end(); }
734 KernelConstVertexIter vertices_end()
const {
return vertices_.end(); }
736 KernelEdgeIter edges_begin() {
return edges_.begin(); }
737 KernelConstEdgeIter edges_begin()
const {
return edges_.begin(); }
738 KernelEdgeIter edges_end() {
return edges_.end(); }
739 KernelConstEdgeIter edges_end()
const {
return edges_.end(); }
741 KernelFaceIter faces_begin() {
return faces_.begin(); }
742 KernelConstFaceIter faces_begin()
const {
return faces_.begin(); }
743 KernelFaceIter faces_end() {
return faces_.end(); }
744 KernelConstFaceIter faces_end()
const {
return faces_.end(); }
747 inline BitMaskContainer& bit_masks(VertexHandle )
748 {
return vertex_bit_masks_; }
749 inline BitMaskContainer& bit_masks(EdgeHandle )
750 {
return edge_bit_masks_; }
751 inline BitMaskContainer& bit_masks(FaceHandle )
752 {
return face_bit_masks_; }
753 inline BitMaskContainer& bit_masks(HalfedgeHandle )
754 {
return halfedge_bit_masks_; }
756 template <
class Handle>
757 uint pop_bit_mask(Handle _hnd)
759 assert(!bit_masks(_hnd).empty());
760 uint bit_mask = bit_masks(_hnd).back();
761 bit_masks(_hnd).pop_back();
765 template <
class Handle>
766 void push_bit_mask(Handle _hnd, uint _bit_mask)
768 assert(std::find(bit_masks(_hnd).begin(), bit_masks(_hnd).end(), _bit_mask) ==
769 bit_masks(_hnd).end());
770 bit_masks(_hnd).push_back(_bit_mask);
773 void init_bit_masks(BitMaskContainer& _bmc);
774 void init_bit_masks();
777 VertexContainer vertices_;
778 EdgeContainer edges_;
779 FaceContainer faces_;
781 VertexStatusPropertyHandle vertex_status_;
782 HalfedgeStatusPropertyHandle halfedge_status_;
783 EdgeStatusPropertyHandle edge_status_;
784 FaceStatusPropertyHandle face_status_;
786 uint refcount_vstatus_;
787 uint refcount_hstatus_;
788 uint refcount_estatus_;
789 uint refcount_fstatus_;
791 BitMaskContainer halfedge_bit_masks_;
792 BitMaskContainer edge_bit_masks_;
793 BitMaskContainer vertex_bit_masks_;
794 BitMaskContainer face_bit_masks_;
800 #endif // OPENMESH_ARRAY_KERNEL_HH defined