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);
115 VertexHandle handle(
const Vertex& _v)
const;
117 HalfedgeHandle handle(
const Halfedge& _he)
const;
119 EdgeHandle handle(
const Edge& _e)
const;
121 FaceHandle handle(
const Face& _f)
const;
125 bool is_valid_handle(VertexHandle _vh)
const;
128 bool is_valid_handle(HalfedgeHandle _heh)
const;
131 bool is_valid_handle(EdgeHandle _eh)
const;
134 bool is_valid_handle(FaceHandle _fh)
const;
138 const Vertex& vertex(VertexHandle _vh)
const
140 assert(is_valid_handle(_vh));
141 return vertices_[_vh.
idx()];
144 Vertex& vertex(VertexHandle _vh)
146 assert(is_valid_handle(_vh));
147 return vertices_[_vh.
idx()];
150 const Halfedge& halfedge(HalfedgeHandle _heh)
const
152 assert(is_valid_handle(_heh));
153 return edges_[_heh.
idx() >> 1].halfedges_[_heh.
idx() & 1];
156 Halfedge& halfedge(HalfedgeHandle _heh)
158 assert(is_valid_handle(_heh));
159 return edges_[_heh.
idx() >> 1].halfedges_[_heh.
idx() & 1];
162 const Edge& edge(EdgeHandle _eh)
const
164 assert(is_valid_handle(_eh));
165 return edges_[_eh.
idx()];
168 Edge& edge(EdgeHandle _eh)
170 assert(is_valid_handle(_eh));
171 return edges_[_eh.
idx()];
174 const Face& face(FaceHandle _fh)
const
176 assert(is_valid_handle(_fh));
177 return faces_[_fh.
idx()];
180 Face& face(FaceHandle _fh)
182 assert(is_valid_handle(_fh));
183 return faces_[_fh.
idx()];
188 VertexHandle vertex_handle(
unsigned int _i)
const
189 {
return (_i < n_vertices()) ? handle( vertices_[_i] ) : VertexHandle(); }
191 HalfedgeHandle halfedge_handle(
unsigned int _i)
const
193 return (_i < n_halfedges()) ?
194 halfedge_handle(edge_handle(_i/2), _i%2) : HalfedgeHandle();
197 EdgeHandle edge_handle(
unsigned int _i)
const
198 {
return (_i < n_edges()) ? handle(edges_[_i]) : EdgeHandle(); }
200 FaceHandle face_handle(
unsigned int _i)
const
201 {
return (_i < n_faces()) ? handle(faces_[_i]) : FaceHandle(); }
205 inline VertexHandle new_vertex()
207 vertices_.push_back(Vertex());
208 vprops_resize(n_vertices());
210 return handle(vertices_.back());
213 inline HalfedgeHandle new_edge(VertexHandle _start_vh, VertexHandle _end_vh)
216 edges_.push_back(Edge());
217 eprops_resize(n_edges());
218 hprops_resize(n_halfedges());
220 EdgeHandle eh(handle(edges_.back()));
221 HalfedgeHandle heh0(halfedge_handle(eh, 0));
222 HalfedgeHandle heh1(halfedge_handle(eh, 1));
223 set_vertex_handle(heh0, _end_vh);
224 set_vertex_handle(heh1, _start_vh);
228 inline FaceHandle new_face()
230 faces_.push_back(Face());
231 fprops_resize(n_faces());
232 return handle(faces_.back());
235 inline FaceHandle new_face(
const Face& _f)
237 faces_.push_back(_f);
238 fprops_resize(n_faces());
239 return handle(faces_.back());
244 void resize(
size_t _n_vertices,
size_t _n_edges,
size_t _n_faces );
245 void reserve(
size_t _n_vertices,
size_t _n_edges,
size_t _n_faces );
263 void garbage_collection(
bool _v=
true,
bool _e=
true,
bool _f=
true);
282 template<
typename std_API_Container_VHandlePointer,
283 typename std_API_Container_HHandlePointer,
284 typename std_API_Container_FHandlePointer>
285 void garbage_collection(std_API_Container_VHandlePointer& vh_to_update,
286 std_API_Container_HHandlePointer& hh_to_update,
287 std_API_Container_FHandlePointer& fh_to_update,
288 bool _v=
true,
bool _e=
true,
bool _f=
true);
303 size_t n_vertices()
const {
return vertices_.size(); }
304 size_t n_halfedges()
const {
return 2*edges_.size(); }
305 size_t n_edges()
const {
return edges_.size(); }
306 size_t n_faces()
const {
return faces_.size(); }
308 bool vertices_empty()
const {
return vertices_.empty(); }
309 bool halfedges_empty()
const {
return edges_.empty(); }
310 bool edges_empty()
const {
return edges_.empty(); }
311 bool faces_empty()
const {
return faces_.empty(); }
315 HalfedgeHandle halfedge_handle(VertexHandle _vh)
const
316 {
return vertex(_vh).halfedge_handle_; }
318 void set_halfedge_handle(VertexHandle _vh, HalfedgeHandle _heh)
321 vertex(_vh).halfedge_handle_ = _heh;
324 bool is_isolated(VertexHandle _vh)
const
325 {
return !halfedge_handle(_vh).
is_valid(); }
327 void set_isolated(VertexHandle _vh)
328 { vertex(_vh).halfedge_handle_.invalidate(); }
330 unsigned int delete_isolated_vertices();
333 VertexHandle to_vertex_handle(HalfedgeHandle _heh)
const
334 {
return halfedge(_heh).vertex_handle_; }
336 VertexHandle from_vertex_handle(HalfedgeHandle _heh)
const
337 {
return to_vertex_handle(opposite_halfedge_handle(_heh)); }
339 void set_vertex_handle(HalfedgeHandle _heh, VertexHandle _vh)
342 halfedge(_heh).vertex_handle_ = _vh;
345 FaceHandle face_handle(HalfedgeHandle _heh)
const
346 {
return halfedge(_heh).face_handle_; }
348 void set_face_handle(HalfedgeHandle _heh, FaceHandle _fh)
351 halfedge(_heh).face_handle_ = _fh;
354 void set_boundary(HalfedgeHandle _heh)
359 {
return !face_handle(_heh).is_valid(); }
361 HalfedgeHandle next_halfedge_handle(HalfedgeHandle _heh)
const
362 {
return halfedge(_heh).next_halfedge_handle_; }
364 void set_next_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _nheh)
366 assert(is_valid_handle(_nheh));
368 halfedge(_heh).next_halfedge_handle_ = _nheh;
369 set_prev_halfedge_handle(_nheh, _heh);
373 void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh)
375 assert(is_valid_handle(_pheh));
376 set_prev_halfedge_handle(_heh, _pheh, HasPrevHalfedge());
379 void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh,
381 { halfedge(_heh).prev_halfedge_handle_ = _pheh; }
383 void set_prev_halfedge_handle(HalfedgeHandle , HalfedgeHandle ,
387 HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh)
const
388 {
return prev_halfedge_handle(_heh, HasPrevHalfedge() ); }
390 HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::TrueType)
const
391 {
return halfedge(_heh).prev_halfedge_handle_; }
393 HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::FalseType)
const
395 if (is_boundary(_heh))
397 HalfedgeHandle curr_heh(opposite_halfedge_handle(_heh));
398 HalfedgeHandle next_heh(next_halfedge_handle(curr_heh));
401 curr_heh = opposite_halfedge_handle(next_heh);
402 next_heh = next_halfedge_handle(curr_heh);
404 while (next_heh != _heh);
409 HalfedgeHandle heh(_heh);
410 HalfedgeHandle next_heh(next_halfedge_handle(heh));
411 while (next_heh != _heh) {
413 next_heh = next_halfedge_handle(next_heh);
420 HalfedgeHandle opposite_halfedge_handle(HalfedgeHandle _heh)
const
421 {
return HalfedgeHandle((_heh.idx() & 1) ? _heh.idx()-1 : _heh.idx()+1); }
424 HalfedgeHandle ccw_rotated_halfedge_handle(HalfedgeHandle _heh)
const
425 {
return opposite_halfedge_handle(prev_halfedge_handle(_heh)); }
428 HalfedgeHandle cw_rotated_halfedge_handle(HalfedgeHandle _heh)
const
429 {
return next_halfedge_handle(opposite_halfedge_handle(_heh)); }
432 HalfedgeHandle halfedge_handle(EdgeHandle _eh,
unsigned int _i)
const
435 return HalfedgeHandle((_eh.idx() << 1) + _i);
438 EdgeHandle edge_handle(HalfedgeHandle _heh)
const
439 {
return EdgeHandle(_heh.idx() >> 1); }
442 HalfedgeHandle halfedge_handle(FaceHandle _fh)
const
443 {
return face(_fh).halfedge_handle_; }
445 void set_halfedge_handle(FaceHandle _fh, HalfedgeHandle _heh)
448 face(_fh).halfedge_handle_ = _heh;
453 const StatusInfo&
status(VertexHandle _vh)
const
454 {
return property(vertex_status_, _vh); }
456 StatusInfo& status(VertexHandle _vh)
457 {
return property(vertex_status_, _vh); }
460 const StatusInfo& status(HalfedgeHandle _hh)
const
461 {
return property(halfedge_status_, _hh); }
463 StatusInfo& status(HalfedgeHandle _hh)
464 {
return property(halfedge_status_, _hh); }
467 const StatusInfo& status(EdgeHandle _eh)
const
468 {
return property(edge_status_, _eh); }
470 StatusInfo& status(EdgeHandle _eh)
471 {
return property(edge_status_, _eh); }
474 const StatusInfo& status(FaceHandle _fh)
const
475 {
return property(face_status_, _fh); }
477 StatusInfo& status(FaceHandle _fh)
478 {
return property(face_status_, _fh); }
480 inline bool has_vertex_status()
const
481 {
return vertex_status_.is_valid(); }
483 inline bool has_halfedge_status()
const
484 {
return halfedge_status_.is_valid(); }
486 inline bool has_edge_status()
const
487 {
return edge_status_.is_valid(); }
489 inline bool has_face_status()
const
490 {
return face_status_.is_valid(); }
492 inline VertexStatusPropertyHandle vertex_status_pph()
const
493 {
return vertex_status_; }
495 inline HalfedgeStatusPropertyHandle halfedge_status_pph()
const
496 {
return halfedge_status_; }
498 inline EdgeStatusPropertyHandle edge_status_pph()
const
499 {
return edge_status_; }
501 inline FaceStatusPropertyHandle face_status_pph()
const
502 {
return face_status_; }
505 inline VertexStatusPropertyHandle
status_pph(VertexHandle )
const
506 {
return vertex_status_pph(); }
508 inline HalfedgeStatusPropertyHandle status_pph(HalfedgeHandle )
const
509 {
return halfedge_status_pph(); }
511 inline EdgeStatusPropertyHandle status_pph(EdgeHandle )
const
512 {
return edge_status_pph(); }
514 inline FaceStatusPropertyHandle status_pph(FaceHandle )
const
515 {
return face_status_pph(); }
520 if (!refcount_vstatus_++)
521 add_property( vertex_status_,
"v:status" );
524 void request_halfedge_status()
526 if (!refcount_hstatus_++)
527 add_property( halfedge_status_,
"h:status" );
530 void request_edge_status()
532 if (!refcount_estatus_++)
533 add_property( edge_status_,
"e:status" );
536 void request_face_status()
538 if (!refcount_fstatus_++)
539 add_property( face_status_,
"f:status" );
545 if ((refcount_vstatus_ > 0) && (! --refcount_vstatus_))
546 remove_property(vertex_status_);
549 void release_halfedge_status()
551 if ((refcount_hstatus_ > 0) && (! --refcount_hstatus_))
552 remove_property(halfedge_status_);
555 void release_edge_status()
557 if ((refcount_estatus_ > 0) && (! --refcount_estatus_))
558 remove_property(edge_status_);
561 void release_face_status()
563 if ((refcount_fstatus_ > 0) && (! --refcount_fstatus_))
564 remove_property(face_status_);
569 template <
class Handle>
576 const unsigned int bit_mask_;
580 : kernel_(_kernel), bit_mask_(_bit_mask)
586 inline bool is_in(Handle _hnd)
const
589 inline void insert(Handle _hnd)
592 inline void erase(Handle _hnd)
601 for (
unsigned int i = 0; i < n_elements; ++i)
603 sz += (
unsigned int)is_in(Handle(i));
613 for (
unsigned int i = 0; i < n_elements; ++i)
620 friend class StatusSetT<VertexHandle>;
621 friend class StatusSetT<EdgeHandle>;
622 friend class StatusSetT<FaceHandle>;
623 friend class StatusSetT<HalfedgeHandle>;
627 template <
class Handle>
640 Base::kernel_.push_bit_mask(Handle(), Base::bit_mask_);
656 template <
class Handle>
663 typedef std::vector<Handle> HandleContainer;
664 HandleContainer handles_;
667 typedef typename HandleContainer::iterator
669 typedef typename HandleContainer::const_iterator
674 { handles_.reserve(_capacity_hint); }
681 inline void insert(Handle _hnd)
686 handles_.push_back(_hnd);
691 inline void erase(Handle _hnd)
695 iterator it = std::find(begin(), end(), _hnd);
701 inline void erase(iterator _it)
703 assert(_it != end() && is_in(*_it));
705 *_it = handles_.back();
711 for (iterator it = begin(); it != end(); ++it)
720 inline unsigned int size()
const
721 {
return handles_.size(); }
722 inline bool empty()
const
723 {
return handles_.empty(); }
726 inline iterator begin()
727 {
return handles_.begin(); }
728 inline const_iterator begin()
const
729 {
return handles_.begin(); }
731 inline iterator end()
732 {
return handles_.end(); }
733 inline const_iterator end()
const
734 {
return handles_.end(); }
736 inline Handle& front()
737 {
return handles_.front(); }
738 inline const Handle& front()
const
739 {
return handles_.front(); }
741 inline Handle& back()
742 {
return handles_.back(); }
743 inline const Handle& back()
const
744 {
return handles_.back(); }
747 typedef ExtStatusSetT<FaceHandle> ExtFaceStatusSet;
748 typedef ExtStatusSetT<VertexHandle> ExtVertexStatusSet;
749 typedef ExtStatusSetT<EdgeHandle> ExtEdgeStatusSet;
750 typedef ExtStatusSetT<HalfedgeHandle> ExtHalfedgeStatusSet;
754 typedef std::vector<Vertex> VertexContainer;
755 typedef std::vector<Edge> EdgeContainer;
756 typedef std::vector<Face> FaceContainer;
757 typedef VertexContainer::iterator KernelVertexIter;
758 typedef VertexContainer::const_iterator KernelConstVertexIter;
759 typedef EdgeContainer::iterator KernelEdgeIter;
760 typedef EdgeContainer::const_iterator KernelConstEdgeIter;
761 typedef FaceContainer::iterator KernelFaceIter;
762 typedef FaceContainer::const_iterator KernelConstFaceIter;
763 typedef std::vector<unsigned int> BitMaskContainer;
766 KernelVertexIter vertices_begin() {
return vertices_.begin(); }
767 KernelConstVertexIter vertices_begin()
const {
return vertices_.begin(); }
768 KernelVertexIter vertices_end() {
return vertices_.end(); }
769 KernelConstVertexIter vertices_end()
const {
return vertices_.end(); }
771 KernelEdgeIter edges_begin() {
return edges_.begin(); }
772 KernelConstEdgeIter edges_begin()
const {
return edges_.begin(); }
773 KernelEdgeIter edges_end() {
return edges_.end(); }
774 KernelConstEdgeIter edges_end()
const {
return edges_.end(); }
776 KernelFaceIter faces_begin() {
return faces_.begin(); }
777 KernelConstFaceIter faces_begin()
const {
return faces_.begin(); }
778 KernelFaceIter faces_end() {
return faces_.end(); }
779 KernelConstFaceIter faces_end()
const {
return faces_.end(); }
782 inline BitMaskContainer& bit_masks(VertexHandle )
783 {
return vertex_bit_masks_; }
784 inline BitMaskContainer& bit_masks(EdgeHandle )
785 {
return edge_bit_masks_; }
786 inline BitMaskContainer& bit_masks(FaceHandle )
787 {
return face_bit_masks_; }
788 inline BitMaskContainer& bit_masks(HalfedgeHandle )
789 {
return halfedge_bit_masks_; }
791 template <
class Handle>
792 unsigned int pop_bit_mask(Handle _hnd)
794 assert(!bit_masks(_hnd).empty());
795 unsigned int bit_mask = bit_masks(_hnd).back();
796 bit_masks(_hnd).pop_back();
800 template <
class Handle>
801 void push_bit_mask(Handle _hnd,
unsigned int _bit_mask)
803 assert(std::find(bit_masks(_hnd).begin(), bit_masks(_hnd).end(), _bit_mask) ==
804 bit_masks(_hnd).end());
805 bit_masks(_hnd).push_back(_bit_mask);
808 void init_bit_masks(BitMaskContainer& _bmc);
809 void init_bit_masks();
812 VertexContainer vertices_;
813 EdgeContainer edges_;
814 FaceContainer faces_;
816 VertexStatusPropertyHandle vertex_status_;
817 HalfedgeStatusPropertyHandle halfedge_status_;
818 EdgeStatusPropertyHandle edge_status_;
819 FaceStatusPropertyHandle face_status_;
821 unsigned int refcount_vstatus_;
822 unsigned int refcount_hstatus_;
823 unsigned int refcount_estatus_;
824 unsigned int refcount_fstatus_;
826 BitMaskContainer halfedge_bit_masks_;
827 BitMaskContainer edge_bit_masks_;
828 BitMaskContainer vertex_bit_masks_;
829 BitMaskContainer face_bit_masks_;
836 #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_ARRAY_KERNEL_C)
837 # define OPENMESH_ARRAY_KERNEL_TEMPLATES
838 # include "ArrayKernelT.cc"
841 #endif // OPENMESH_ARRAY_KERNEL_HH defined
void release_vertex_status()
Status Release API.
Definition: ArrayKernel.hh:543
bool is_bit_set(unsigned int _s) const
is a certain bit set ?
Definition: Status.hh:155
This class provides the basic property management like adding/removing properties and access to prope...
Definition: BaseKernel.hh:91
— ExtStatusSet API — (hybrid between a set and an array)
Definition: ArrayKernel.hh:657
PropertyT< T > & property(VPropHandleT< T > _ph)
Access a property.
Definition: BaseKernel.hh:286
void unset_bit(unsigned int _s)
unset a certain bit
Definition: Status.hh:159
int idx() const
Get the underlying index of this handle.
Definition: Handles.hh:67
void clear()
Note: O(n) complexity.
Definition: ArrayKernel.hh:609
Mesh kernel using arrays for mesh item storage.
Definition: ArrayKernel.hh:85
VertexStatusPropertyHandle status_pph(VertexHandle) const
status property by handle
Definition: ArrayKernel.hh:505
— AutoStatusSet API —
Definition: ArrayKernel.hh:628
const StatusInfo & status(VertexHandle _vh) const
Status Query API.
Definition: ArrayKernel.hh:453
Handle for a vertex entity.
Definition: Handles.hh:114
— StatusSet API —
Definition: ArrayKernel.hh:570
unsigned int size() const
Note: 0(n) complexity.
Definition: ArrayKernel.hh:596
void request_vertex_status()
Status Request API.
Definition: ArrayKernel.hh:518
Add status information to a base class.
Definition: Status.hh:92
void invalidate()
reset handle to be invalid
Definition: Handles.hh:75
Handle for a face entity.
Definition: Handles.hh:135
void set_bit(unsigned int _s)
set a certain bit
Definition: Status.hh:157
Handle for a halfedge entity.
Definition: Handles.hh:121
Handle for a edge entity.
Definition: Handles.hh:128
bool is_boundary(HalfedgeHandle _heh) const
Is halfedge _heh a boundary halfedge (is its face handle invalid) ?
Definition: ArrayKernel.hh:358
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:56
unsigned int size() const
Complexity: 0(1)
Definition: ArrayKernel.hh:720
bool is_valid() const
The handle is valid iff the index is not equal to -1.
Definition: Handles.hh:70