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>
112 void assign_connectivity(
const ArrayKernel& _other);
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]) ?
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(
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 );
279 void garbage_collection(
bool _v=
true,
bool _e=
true,
bool _f=
true);
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);
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(); }
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(); }
332 {
return vertex(_vh).halfedge_handle_; }
337 vertex(_vh).halfedge_handle_ = _heh;
341 {
return !halfedge_handle(_vh).
is_valid(); }
344 { vertex(_vh).halfedge_handle_.invalidate(); }
346 unsigned int delete_isolated_vertices();
350 {
return halfedge(_heh).vertex_handle_; }
353 {
return to_vertex_handle(opposite_halfedge_handle(_heh)); }
358 halfedge(_heh).vertex_handle_ = _vh;
362 {
return halfedge(_heh).face_handle_; }
367 halfedge(_heh).face_handle_ = _fh;
375 {
return !face_handle(_heh).is_valid(); }
378 {
return halfedge(_heh).next_halfedge_handle_; }
380 void set_next_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _nheh)
382 assert(is_valid_handle(_nheh));
384 halfedge(_heh).next_halfedge_handle_ = _nheh;
385 set_prev_halfedge_handle(_nheh, _heh);
389 void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh)
391 assert(is_valid_handle(_pheh));
392 set_prev_halfedge_handle(_heh, _pheh, HasPrevHalfedge());
395 void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh,
397 { halfedge(_heh).prev_halfedge_handle_ = _pheh; }
399 void set_prev_halfedge_handle(HalfedgeHandle , HalfedgeHandle ,
403 HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh)
const
404 {
return prev_halfedge_handle(_heh, HasPrevHalfedge() ); }
406 HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::True)
const
407 {
return halfedge(_heh).prev_halfedge_handle_; }
409 HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::False)
const
411 if (is_boundary(_heh))
413 HalfedgeHandle curr_heh(opposite_halfedge_handle(_heh));
414 HalfedgeHandle next_heh(next_halfedge_handle(curr_heh));
417 curr_heh = opposite_halfedge_handle(next_heh);
418 next_heh = next_halfedge_handle(curr_heh);
420 while (next_heh != _heh);
425 HalfedgeHandle heh(_heh);
426 HalfedgeHandle next_heh(next_halfedge_handle(heh));
427 while (next_heh != _heh) {
429 next_heh = next_halfedge_handle(next_heh);
436 HalfedgeHandle opposite_halfedge_handle(HalfedgeHandle _heh)
const
437 {
return HalfedgeHandle((_heh.idx() & 1) ? _heh.idx()-1 : _heh.idx()+1); }
440 HalfedgeHandle ccw_rotated_halfedge_handle(HalfedgeHandle _heh)
const
441 {
return opposite_halfedge_handle(prev_halfedge_handle(_heh)); }
444 HalfedgeHandle cw_rotated_halfedge_handle(HalfedgeHandle _heh)
const
445 {
return next_halfedge_handle(opposite_halfedge_handle(_heh)); }
448 HalfedgeHandle halfedge_handle(EdgeHandle _eh,
unsigned int _i)
const
451 return HalfedgeHandle((_eh.idx() << 1) + _i);
454 EdgeHandle edge_handle(HalfedgeHandle _heh)
const
455 {
return EdgeHandle(_heh.idx() >> 1); }
458 HalfedgeHandle halfedge_handle(FaceHandle _fh)
const
459 {
return face(_fh).halfedge_handle_; }
461 void set_halfedge_handle(FaceHandle _fh, HalfedgeHandle _heh)
464 face(_fh).halfedge_handle_ = _heh;
470 {
return property(vertex_status_, _vh); }
473 {
return property(vertex_status_, _vh); }
476 const StatusInfo& status(HalfedgeHandle _hh)
const
477 {
return property(halfedge_status_, _hh); }
479 StatusInfo& status(HalfedgeHandle _hh)
480 {
return property(halfedge_status_, _hh); }
483 const StatusInfo& status(EdgeHandle _eh)
const
484 {
return property(edge_status_, _eh); }
486 StatusInfo& status(EdgeHandle _eh)
487 {
return property(edge_status_, _eh); }
490 const StatusInfo& status(FaceHandle _fh)
const
491 {
return property(face_status_, _fh); }
493 StatusInfo& status(FaceHandle _fh)
494 {
return property(face_status_, _fh); }
496 inline bool has_vertex_status()
const
497 {
return vertex_status_.is_valid(); }
499 inline bool has_halfedge_status()
const
500 {
return halfedge_status_.is_valid(); }
502 inline bool has_edge_status()
const
503 {
return edge_status_.is_valid(); }
505 inline bool has_face_status()
const
506 {
return face_status_.is_valid(); }
508 inline VertexStatusPropertyHandle vertex_status_pph()
const
509 {
return vertex_status_; }
511 inline HalfedgeStatusPropertyHandle halfedge_status_pph()
const
512 {
return halfedge_status_; }
514 inline EdgeStatusPropertyHandle edge_status_pph()
const
515 {
return edge_status_; }
517 inline FaceStatusPropertyHandle face_status_pph()
const
518 {
return face_status_; }
522 {
return vertex_status_pph(); }
524 inline HalfedgeStatusPropertyHandle status_pph(
HalfedgeHandle )
const
525 {
return halfedge_status_pph(); }
527 inline EdgeStatusPropertyHandle status_pph(EdgeHandle )
const
528 {
return edge_status_pph(); }
530 inline FaceStatusPropertyHandle status_pph(FaceHandle )
const
531 {
return face_status_pph(); }
534 void request_vertex_status()
536 if (!refcount_vstatus_++)
537 add_property( vertex_status_,
"v:status" );
540 void request_halfedge_status()
542 if (!refcount_hstatus_++)
543 add_property( halfedge_status_,
"h:status" );
546 void request_edge_status()
548 if (!refcount_estatus_++)
549 add_property( edge_status_,
"e:status" );
552 void request_face_status()
554 if (!refcount_fstatus_++)
555 add_property( face_status_,
"f:status" );
559 void release_vertex_status()
561 if ((refcount_vstatus_ > 0) && (! --refcount_vstatus_))
562 remove_property(vertex_status_);
565 void release_halfedge_status()
567 if ((refcount_hstatus_ > 0) && (! --refcount_hstatus_))
568 remove_property(halfedge_status_);
571 void release_edge_status()
573 if ((refcount_estatus_ > 0) && (! --refcount_estatus_))
574 remove_property(edge_status_);
577 void release_face_status()
579 if ((refcount_fstatus_ > 0) && (! --refcount_fstatus_))
580 remove_property(face_status_);
585 template <
class Handle>
592 const unsigned int bit_mask_;
596 : kernel_(_kernel), bit_mask_(_bit_mask)
602 inline bool is_in(Handle _hnd)
const
603 {
return kernel_.status(_hnd).is_bit_set(bit_mask_); }
605 inline void insert(Handle _hnd)
606 { kernel_.status(_hnd).set_bit(bit_mask_); }
608 inline void erase(Handle _hnd)
609 { kernel_.status(_hnd).unset_bit(bit_mask_); }
612 unsigned int size()
const
614 unsigned int n_elements = kernel_.status_pph(Handle()).is_valid() ?
615 kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
617 for (
unsigned int i = 0; i < n_elements; ++i)
619 sz += (
unsigned int)is_in(Handle(i));
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)
643 template <
class Handle>
656 Base::kernel_.push_bit_mask(Handle(), Base::bit_mask_);
672 template <
class Handle>
679 typedef std::vector<Handle> HandleContainer;
680 HandleContainer handles_;
683 typedef typename HandleContainer::iterator
685 typedef typename HandleContainer::const_iterator
690 { handles_.reserve(_capacity_hint); }
697 inline void insert(Handle _hnd)
702 handles_.push_back(_hnd);
707 inline void erase(Handle _hnd)
711 iterator it = std::find(begin(), end(), _hnd);
717 inline void erase(iterator _it)
719 assert(_it != end() && is_in(*_it));
721 *_it = handles_.back();
727 for (iterator it = begin(); it != end(); ++it)
736 inline unsigned int size()
const
737 {
return handles_.size(); }
738 inline bool empty()
const
739 {
return handles_.empty(); }
742 inline iterator begin()
743 {
return handles_.begin(); }
744 inline const_iterator begin()
const
745 {
return handles_.begin(); }
747 inline iterator end()
748 {
return handles_.end(); }
749 inline const_iterator end()
const
750 {
return handles_.end(); }
752 inline Handle& front()
753 {
return handles_.front(); }
754 inline const Handle& front()
const
755 {
return handles_.front(); }
757 inline Handle& back()
758 {
return handles_.back(); }
759 inline const Handle& back()
const
760 {
return handles_.back(); }
763 typedef ExtStatusSetT<FaceHandle> ExtFaceStatusSet;
764 typedef ExtStatusSetT<VertexHandle> ExtVertexStatusSet;
765 typedef ExtStatusSetT<EdgeHandle> ExtEdgeStatusSet;
766 typedef ExtStatusSetT<HalfedgeHandle> ExtHalfedgeStatusSet;
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;
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(); }
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(); }
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(); }
798 inline BitMaskContainer& bit_masks(VertexHandle )
799 {
return vertex_bit_masks_; }
800 inline BitMaskContainer& bit_masks(EdgeHandle )
801 {
return edge_bit_masks_; }
802 inline BitMaskContainer& bit_masks(FaceHandle )
803 {
return face_bit_masks_; }
804 inline BitMaskContainer& bit_masks(HalfedgeHandle )
805 {
return halfedge_bit_masks_; }
807 template <
class Handle>
808 unsigned int pop_bit_mask(Handle _hnd)
810 assert(!bit_masks(_hnd).empty());
811 unsigned int bit_mask = bit_masks(_hnd).back();
812 bit_masks(_hnd).pop_back();
816 template <
class Handle>
817 void push_bit_mask(Handle _hnd,
unsigned int _bit_mask)
819 assert(std::find(bit_masks(_hnd).begin(), bit_masks(_hnd).end(), _bit_mask) ==
820 bit_masks(_hnd).end());
821 bit_masks(_hnd).push_back(_bit_mask);
824 void init_bit_masks(BitMaskContainer& _bmc);
825 void init_bit_masks();
828 VertexContainer vertices_;
829 EdgeContainer edges_;
830 FaceContainer faces_;
832 VertexStatusPropertyHandle vertex_status_;
833 HalfedgeStatusPropertyHandle halfedge_status_;
834 EdgeStatusPropertyHandle edge_status_;
835 FaceStatusPropertyHandle face_status_;
837 unsigned int refcount_vstatus_;
838 unsigned int refcount_hstatus_;
839 unsigned int refcount_estatus_;
840 unsigned int refcount_fstatus_;
842 BitMaskContainer halfedge_bit_masks_;
843 BitMaskContainer edge_bit_masks_;
844 BitMaskContainer vertex_bit_masks_;
845 BitMaskContainer face_bit_masks_;
852 #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_ARRAY_KERNEL_C)
853 # define OPENMESH_ARRAY_KERNEL_TEMPLATES
854 # include "ArrayKernelT.cc"
857 #endif // OPENMESH_ARRAY_KERNEL_HH defined