52 #ifndef OPENMESH_ARRAY_KERNEL_HH 53 #define OPENMESH_ARRAY_KERNEL_HH 60 #include <OpenMesh/Core/Utils/GenProg.hh> 62 #include <OpenMesh/Core/Mesh/ArrayItems.hh> 63 #include <OpenMesh/Core/Mesh/BaseKernel.hh> 64 #include <OpenMesh/Core/Mesh/Status.hh> 114 void assign_connectivity(
const ArrayKernel& _other);
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;
127 bool is_valid_handle(VertexHandle _vh)
const;
130 bool is_valid_handle(HalfedgeHandle _heh)
const;
133 bool is_valid_handle(EdgeHandle _eh)
const;
136 bool is_valid_handle(FaceHandle _fh)
const;
140 const Vertex& vertex(VertexHandle _vh)
const 142 assert(is_valid_handle(_vh));
143 return vertices_[_vh.
idx()];
146 Vertex& vertex(VertexHandle _vh)
148 assert(is_valid_handle(_vh));
149 return vertices_[_vh.
idx()];
152 const Halfedge& halfedge(HalfedgeHandle _heh)
const 154 assert(is_valid_handle(_heh));
155 return edges_[_heh.
idx() >> 1].halfedges_[_heh.
idx() & 1];
158 Halfedge& halfedge(HalfedgeHandle _heh)
160 assert(is_valid_handle(_heh));
161 return edges_[_heh.
idx() >> 1].halfedges_[_heh.
idx() & 1];
164 const Edge& edge(EdgeHandle _eh)
const 166 assert(is_valid_handle(_eh));
167 return edges_[_eh.
idx()];
170 Edge& edge(EdgeHandle _eh)
172 assert(is_valid_handle(_eh));
173 return edges_[_eh.
idx()];
176 const Face& face(FaceHandle _fh)
const 178 assert(is_valid_handle(_fh));
179 return faces_[_fh.
idx()];
182 Face& face(FaceHandle _fh)
184 assert(is_valid_handle(_fh));
185 return faces_[_fh.
idx()];
190 VertexHandle vertex_handle(
unsigned int _i)
const 191 {
return (_i < n_vertices()) ? handle( vertices_[_i] ) : VertexHandle(); }
193 HalfedgeHandle halfedge_handle(
unsigned int _i)
const 195 return (_i < n_halfedges()) ?
196 halfedge_handle(edge_handle(_i/2), _i%2) : HalfedgeHandle();
199 EdgeHandle edge_handle(
unsigned int _i)
const 200 {
return (_i < n_edges()) ? handle(edges_[_i]) : EdgeHandle(); }
202 FaceHandle face_handle(
unsigned int _i)
const 203 {
return (_i < n_faces()) ? handle(faces_[_i]) : FaceHandle(); }
218 vertices_.push_back(Vertex());
219 vprops_resize(n_vertices());
221 return handle(vertices_.back());
236 vertices_.push_back(Vertex());
237 vprops_resize_if_smaller(n_vertices());
239 return handle(vertices_.back());
242 inline HalfedgeHandle new_edge(VertexHandle _start_vh, VertexHandle _end_vh)
245 edges_.push_back(Edge());
246 eprops_resize(n_edges());
247 hprops_resize(n_halfedges());
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);
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);
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);
340 void clean_keep_reservation();
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(); }
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(); }
355 HalfedgeHandle halfedge_handle(VertexHandle _vh)
const 356 {
return vertex(_vh).halfedge_handle_; }
358 void set_halfedge_handle(VertexHandle _vh, HalfedgeHandle _heh)
361 vertex(_vh).halfedge_handle_ = _heh;
364 bool is_isolated(VertexHandle _vh)
const 365 {
return !halfedge_handle(_vh).
is_valid(); }
367 void set_isolated(VertexHandle _vh)
368 { vertex(_vh).halfedge_handle_.invalidate(); }
370 unsigned int delete_isolated_vertices();
373 VertexHandle to_vertex_handle(HalfedgeHandle _heh)
const 374 {
return halfedge(_heh).vertex_handle_; }
376 VertexHandle from_vertex_handle(HalfedgeHandle _heh)
const 377 {
return to_vertex_handle(opposite_halfedge_handle(_heh)); }
379 void set_vertex_handle(HalfedgeHandle _heh, VertexHandle _vh)
382 halfedge(_heh).vertex_handle_ = _vh;
385 FaceHandle face_handle(HalfedgeHandle _heh)
const 386 {
return halfedge(_heh).face_handle_; }
388 void set_face_handle(HalfedgeHandle _heh, FaceHandle _fh)
391 halfedge(_heh).face_handle_ = _fh;
394 void set_boundary(HalfedgeHandle _heh)
399 {
return !face_handle(_heh).is_valid(); }
401 HalfedgeHandle next_halfedge_handle(HalfedgeHandle _heh)
const 402 {
return halfedge(_heh).next_halfedge_handle_; }
404 void set_next_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _nheh)
406 assert(is_valid_handle(_nheh));
408 halfedge(_heh).next_halfedge_handle_ = _nheh;
409 set_prev_halfedge_handle(_nheh, _heh);
413 void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh)
415 assert(is_valid_handle(_pheh));
416 set_prev_halfedge_handle(_heh, _pheh, HasPrevHalfedge());
419 void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh,
421 { halfedge(_heh).prev_halfedge_handle_ = _pheh; }
423 void set_prev_halfedge_handle(HalfedgeHandle , HalfedgeHandle ,
427 HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh)
const 428 {
return prev_halfedge_handle(_heh, HasPrevHalfedge() ); }
430 HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::TrueType)
const 431 {
return halfedge(_heh).prev_halfedge_handle_; }
433 HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::FalseType)
const 435 if (is_boundary(_heh))
437 HalfedgeHandle curr_heh(opposite_halfedge_handle(_heh));
438 HalfedgeHandle next_heh(next_halfedge_handle(curr_heh));
441 curr_heh = opposite_halfedge_handle(next_heh);
442 next_heh = next_halfedge_handle(curr_heh);
444 while (next_heh != _heh);
449 HalfedgeHandle heh(_heh);
450 HalfedgeHandle next_heh(next_halfedge_handle(heh));
451 while (next_heh != _heh) {
453 next_heh = next_halfedge_handle(next_heh);
460 HalfedgeHandle opposite_halfedge_handle(HalfedgeHandle _heh)
const 461 {
return HalfedgeHandle(_heh.
idx() ^ 1); }
464 HalfedgeHandle ccw_rotated_halfedge_handle(HalfedgeHandle _heh)
const 465 {
return opposite_halfedge_handle(prev_halfedge_handle(_heh)); }
468 HalfedgeHandle cw_rotated_halfedge_handle(HalfedgeHandle _heh)
const 469 {
return next_halfedge_handle(opposite_halfedge_handle(_heh)); }
472 static HalfedgeHandle s_halfedge_handle(EdgeHandle _eh,
unsigned int _i)
475 return HalfedgeHandle((_eh.
idx() << 1) + _i);
478 static EdgeHandle s_edge_handle(HalfedgeHandle _heh)
479 {
return EdgeHandle(_heh.
idx() >> 1); }
481 HalfedgeHandle halfedge_handle(EdgeHandle _eh,
unsigned int _i)
const 483 return s_halfedge_handle(_eh, _i);
486 EdgeHandle edge_handle(HalfedgeHandle _heh)
const 487 {
return s_edge_handle(_heh); }
490 HalfedgeHandle halfedge_handle(FaceHandle _fh)
const 491 {
return face(_fh).halfedge_handle_; }
493 void set_halfedge_handle(FaceHandle _fh, HalfedgeHandle _heh)
496 face(_fh).halfedge_handle_ = _heh;
501 const StatusInfo&
status(VertexHandle _vh)
const 502 {
return property(vertex_status_, _vh); }
504 StatusInfo& status(VertexHandle _vh)
505 {
return property(vertex_status_, _vh); }
513 PropertyT<StatusInfo>::vector_type &sprop_v = status_prop.
data_vector();
514 std::fill(sprop_v.begin(), sprop_v.begin() + n_vertices(), StatusInfo());
518 const StatusInfo& status(HalfedgeHandle _hh)
const 519 {
return property(halfedge_status_, _hh); }
521 StatusInfo& status(HalfedgeHandle _hh)
522 {
return property(halfedge_status_, _hh); }
525 const StatusInfo& status(EdgeHandle _eh)
const 526 {
return property(edge_status_, _eh); }
528 StatusInfo& status(EdgeHandle _eh)
529 {
return property(edge_status_, _eh); }
532 const StatusInfo& status(FaceHandle _fh)
const 533 {
return property(face_status_, _fh); }
535 StatusInfo& status(FaceHandle _fh)
536 {
return property(face_status_, _fh); }
538 inline bool has_vertex_status()
const 539 {
return vertex_status_.is_valid(); }
541 inline bool has_halfedge_status()
const 542 {
return halfedge_status_.is_valid(); }
544 inline bool has_edge_status()
const 545 {
return edge_status_.is_valid(); }
547 inline bool has_face_status()
const 548 {
return face_status_.is_valid(); }
550 inline VertexStatusPropertyHandle vertex_status_pph()
const 551 {
return vertex_status_; }
553 inline HalfedgeStatusPropertyHandle halfedge_status_pph()
const 554 {
return halfedge_status_; }
556 inline EdgeStatusPropertyHandle edge_status_pph()
const 557 {
return edge_status_; }
559 inline FaceStatusPropertyHandle face_status_pph()
const 560 {
return face_status_; }
563 inline VertexStatusPropertyHandle
status_pph(VertexHandle )
const 564 {
return vertex_status_pph(); }
566 inline HalfedgeStatusPropertyHandle status_pph(HalfedgeHandle )
const 567 {
return halfedge_status_pph(); }
569 inline EdgeStatusPropertyHandle status_pph(EdgeHandle )
const 570 {
return edge_status_pph(); }
572 inline FaceStatusPropertyHandle status_pph(FaceHandle )
const 573 {
return face_status_pph(); }
578 if (!refcount_vstatus_++)
579 add_property( vertex_status_,
"v:status" );
582 void request_halfedge_status()
584 if (!refcount_hstatus_++)
585 add_property( halfedge_status_,
"h:status" );
588 void request_edge_status()
590 if (!refcount_estatus_++)
591 add_property( edge_status_,
"e:status" );
594 void request_face_status()
596 if (!refcount_fstatus_++)
597 add_property( face_status_,
"f:status" );
603 if ((refcount_vstatus_ > 0) && (! --refcount_vstatus_))
604 remove_property(vertex_status_);
607 void release_halfedge_status()
609 if ((refcount_hstatus_ > 0) && (! --refcount_hstatus_))
610 remove_property(halfedge_status_);
613 void release_edge_status()
615 if ((refcount_estatus_ > 0) && (! --refcount_estatus_))
616 remove_property(edge_status_);
619 void release_face_status()
621 if ((refcount_fstatus_ > 0) && (! --refcount_fstatus_))
622 remove_property(face_status_);
634 template <
class HandleT>
638 typedef HandleT Handle;
644 const unsigned int bit_mask_;
648 : kernel_(_kernel), bit_mask_(_bit_mask)
654 inline bool is_in(Handle _hnd)
const 657 inline void insert(Handle _hnd)
660 inline void erase(Handle _hnd)
670 for (
int i = 0; i < n; ++i)
671 sz += (
size_t)is_in(Handle(i));
681 for (
int i = 0; i < n; ++i)
692 template <
class HandleT>
696 typedef HandleT Handle;
707 Base::kernel_.push_bit_mask(Handle(), Base::bit_mask_);
722 template <
class HandleT>
726 typedef HandleT Handle;
730 typedef std::vector<Handle> HandleContainer;
731 HandleContainer handles_;
734 typedef typename HandleContainer::iterator
736 typedef typename HandleContainer::const_iterator
741 { handles_.reserve(_capacity_hint); }
747 inline void insert(Handle _hnd)
749 if (!Base::is_in(_hnd))
752 handles_.push_back(_hnd);
761 iterator it = std::find(begin(), end(), _hnd);
769 assert(_it != const_cast<const ExtStatusSetT*>(
this)->end() &&
772 *_it = handles_.back();
778 for (iterator it = begin(); it != end(); ++it)
780 assert(Base::is_in(*it));
787 inline unsigned int size()
const 788 {
return handles_.size(); }
789 inline bool empty()
const 790 {
return handles_.empty(); }
793 inline iterator begin()
794 {
return handles_.begin(); }
795 inline const_iterator begin()
const 796 {
return handles_.begin(); }
798 inline iterator end()
799 {
return handles_.end(); }
800 inline const_iterator end()
const 801 {
return handles_.end(); }
803 inline Handle& front()
804 {
return handles_.front(); }
805 inline const Handle& front()
const 806 {
return handles_.front(); }
808 inline Handle& back()
809 {
return handles_.back(); }
810 inline const Handle& back()
const 811 {
return handles_.back(); }
821 typedef std::vector<Vertex> VertexContainer;
822 typedef std::vector<Edge> EdgeContainer;
823 typedef std::vector<Face> FaceContainer;
824 typedef VertexContainer::iterator KernelVertexIter;
825 typedef VertexContainer::const_iterator KernelConstVertexIter;
826 typedef EdgeContainer::iterator KernelEdgeIter;
827 typedef EdgeContainer::const_iterator KernelConstEdgeIter;
828 typedef FaceContainer::iterator KernelFaceIter;
829 typedef FaceContainer::const_iterator KernelConstFaceIter;
830 typedef std::vector<unsigned int> BitMaskContainer;
833 KernelVertexIter vertices_begin() {
return vertices_.begin(); }
834 KernelConstVertexIter vertices_begin()
const {
return vertices_.begin(); }
835 KernelVertexIter vertices_end() {
return vertices_.end(); }
836 KernelConstVertexIter vertices_end()
const {
return vertices_.end(); }
838 KernelEdgeIter edges_begin() {
return edges_.begin(); }
839 KernelConstEdgeIter edges_begin()
const {
return edges_.begin(); }
840 KernelEdgeIter edges_end() {
return edges_.end(); }
841 KernelConstEdgeIter edges_end()
const {
return edges_.end(); }
843 KernelFaceIter faces_begin() {
return faces_.begin(); }
844 KernelConstFaceIter faces_begin()
const {
return faces_.begin(); }
845 KernelFaceIter faces_end() {
return faces_.end(); }
846 KernelConstFaceIter faces_end()
const {
return faces_.end(); }
850 {
return vertex_bit_masks_; }
851 inline BitMaskContainer& bit_masks(EdgeHandle )
852 {
return edge_bit_masks_; }
853 inline BitMaskContainer& bit_masks(FaceHandle )
854 {
return face_bit_masks_; }
855 inline BitMaskContainer& bit_masks(HalfedgeHandle )
856 {
return halfedge_bit_masks_; }
858 template <
class Handle>
859 unsigned int pop_bit_mask(Handle _hnd)
861 assert(!bit_masks(_hnd).empty());
862 unsigned int bit_mask = bit_masks(_hnd).back();
863 bit_masks(_hnd).pop_back();
867 template <
class Handle>
868 void push_bit_mask(Handle _hnd,
unsigned int _bit_mask)
870 assert(std::find(bit_masks(_hnd).begin(), bit_masks(_hnd).end(), _bit_mask) ==
871 bit_masks(_hnd).end());
872 bit_masks(_hnd).push_back(_bit_mask);
875 void init_bit_masks(BitMaskContainer& _bmc);
876 void init_bit_masks();
880 VertexStatusPropertyHandle vertex_status_;
881 HalfedgeStatusPropertyHandle halfedge_status_;
882 EdgeStatusPropertyHandle edge_status_;
883 FaceStatusPropertyHandle face_status_;
885 unsigned int refcount_vstatus_;
886 unsigned int refcount_hstatus_;
887 unsigned int refcount_estatus_;
888 unsigned int refcount_fstatus_;
891 VertexContainer vertices_;
892 EdgeContainer edges_;
893 FaceContainer faces_;
895 BitMaskContainer halfedge_bit_masks_;
896 BitMaskContainer edge_bit_masks_;
897 BitMaskContainer vertex_bit_masks_;
898 BitMaskContainer face_bit_masks_;
905 #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_ARRAY_KERNEL_C) 906 # define OPENMESH_ARRAY_KERNEL_TEMPLATES 907 # include "ArrayKernelT_impl.hh" 910 #endif // OPENMESH_ARRAY_KERNEL_HH defined Handle for a edge entity.
Handle for a face entity.
Handle for a halfedge entity.
int idx() const
Get the underlying index of this handle.
size_t size() const
Note: 0(n) complexity.
AutoStatusSetT: A status set that automatically picks a status bit.
void unset_bit(unsigned int _s)
unset a certain bit
void request_vertex_status()
Status Request API.
Handle for a vertex entity.
BitMaskContainer & bit_masks(VertexHandle)
bit mask container by handle
const StatusInfo & status(VertexHandle _vh) const
Status Query API.
bool is_valid() const
The handle is valid iff the index is not negative.
bool is_boundary(HalfedgeHandle _heh) const
Is halfedge _heh a boundary halfedge (is its face handle invalid) ?
ExtStatusSet: A status set augmented with an array.
Default property class for any type T.
bool is_bit_set(unsigned int _s) const
is a certain bit set ?
unsigned int size() const
Complexity: 0(1)
void invalidate()
reset handle to be invalid
VertexHandle new_vertex()
Add a new vertex.
void release_vertex_status()
Status Release API.
VertexStatusPropertyHandle status_pph(VertexHandle) const
status property by handle
void clear()
Note: O(n) complexity.
PropertyT< T > & property(VPropHandleT< T > _ph)
vector_type & data_vector()
Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!!!) ...
void set_bit(unsigned int _s)
set a certain bit
void erase(iterator _it)
Complexity: O(1)
void erase(Handle _hnd)
Complexity: O(k), (k - number of the elements in the set)
VertexHandle new_vertex_dirty()