OpenMesh
OpenMesh/Core/Mesh/ArrayKernel.hh
00001 /*===========================================================================*\
00002  *                                                                           *
00003  *                               OpenMesh                                    *
00004  *      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen      *
00005  *                           www.openmesh.org                                *
00006  *                                                                           *
00007  *---------------------------------------------------------------------------* 
00008  *  This file is part of OpenMesh.                                           *
00009  *                                                                           *
00010  *  OpenMesh is free software: you can redistribute it and/or modify         * 
00011  *  it under the terms of the GNU Lesser General Public License as           *
00012  *  published by the Free Software Foundation, either version 3 of           *
00013  *  the License, or (at your option) any later version with the              *
00014  *  following exceptions:                                                    *
00015  *                                                                           *
00016  *  If other files instantiate templates or use macros                       *
00017  *  or inline functions from this file, or you compile this file and         *
00018  *  link it with other files to produce an executable, this file does        *
00019  *  not by itself cause the resulting executable to be covered by the        *
00020  *  GNU Lesser General Public License. This exception does not however       *
00021  *  invalidate any other reasons why the executable file might be            *
00022  *  covered by the GNU Lesser General Public License.                        *
00023  *                                                                           *
00024  *  OpenMesh is distributed in the hope that it will be useful,              *
00025  *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
00026  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
00027  *  GNU Lesser General Public License for more details.                      *
00028  *                                                                           *
00029  *  You should have received a copy of the GNU LesserGeneral Public          *
00030  *  License along with OpenMesh.  If not,                                    *
00031  *  see <http://www.gnu.org/licenses/>.                                      *
00032  *                                                                           *
00033 \*===========================================================================*/ 
00034 
00035 /*===========================================================================*\
00036  *                                                                           *             
00037  *   $Revision: 543 $                                                         *
00038  *   $Date: 2012-02-29 14:21:06 +0100 (Mi, 29 Feb 2012) $                   *
00039  *                                                                           *
00040 \*===========================================================================*/
00041 
00042 
00043 //=============================================================================
00044 //
00045 //  CLASS ArrayKernel
00046 //
00047 //=============================================================================
00048 
00049 
00050 #ifndef OPENMESH_ARRAY_KERNEL_HH
00051 #define OPENMESH_ARRAY_KERNEL_HH
00052 
00053 
00054 //== INCLUDES =================================================================
00055 #include <vector>
00056 
00057 #include <OpenMesh/Core/System/config.h>
00058 #include <OpenMesh/Core/Utils/GenProg.hh>
00059 
00060 #include <OpenMesh/Core/Mesh/ArrayItems.hh>
00061 #include <OpenMesh/Core/Mesh/BaseKernel.hh>
00062 #include <OpenMesh/Core/Mesh/Status.hh>
00063 
00064 //== NAMESPACES ===============================================================
00065 namespace OpenMesh {
00066 
00067 
00068 //== CLASS DEFINITION =========================================================
00085 class ArrayKernel : public BaseKernel, public ArrayItems
00086 {
00087 public:
00088 
00089   // handles
00090   typedef OpenMesh::VertexHandle            VertexHandle;
00091   typedef OpenMesh::HalfedgeHandle          HalfedgeHandle;
00092   typedef OpenMesh::EdgeHandle              EdgeHandle;
00093   typedef OpenMesh::FaceHandle              FaceHandle;
00094   typedef Attributes::StatusInfo            StatusInfo;
00095   typedef VPropHandleT<StatusInfo>          VertexStatusPropertyHandle;
00096   typedef HPropHandleT<StatusInfo>          HalfedgeStatusPropertyHandle;
00097   typedef EPropHandleT<StatusInfo>          EdgeStatusPropertyHandle;
00098   typedef FPropHandleT<StatusInfo>          FaceStatusPropertyHandle;
00099 
00100 public:
00101 
00102   // --- constructor/destructor ---
00103   ArrayKernel();
00104   virtual ~ArrayKernel();
00105 
00112   void                                      assign_connectivity(const ArrayKernel& _other);
00113   
00114   // --- handle -> item ---
00115   VertexHandle handle(const Vertex& _v) const
00116   {return VertexHandle(&_v - &vertices_.front()); }
00117 
00118   HalfedgeHandle handle(const Halfedge& _he) const
00119   {
00120     // Calculate edge belonging to given halfedge
00121     // There are two halfedges stored per edge
00122     // Get memory position inside edge vector and devide by size of an edge
00123     // to get the corresponding edge for the requested halfedge
00124     uint eh = ( (char*)&_he - (char*)&edges_.front() ) /  sizeof(Edge)  ;
00125     assert((&_he == &edges_[eh].halfedges_[0]) ||
00126            (&_he == &edges_[eh].halfedges_[1]));
00127     return ((&_he == &edges_[eh].halfedges_[0]) ?
00128                       HalfedgeHandle(eh<<1) : HalfedgeHandle((eh<<1)+1));
00129   }
00130 
00131   EdgeHandle handle(const Edge& _e) const 
00132   { return EdgeHandle(&_e - &edges_.front()); }
00133 
00134   FaceHandle handle(const Face& _f) const 
00135   { return FaceHandle(&_f - &faces_.front()); }
00136 
00137 #define SIGNED(x) signed( (x) )
00138   //checks handle validity - useful for debugging
00139   bool is_valid_handle(VertexHandle _vh) const
00140   { return 0 <= _vh.idx() && _vh.idx() < SIGNED(n_vertices()); }
00141 
00142   bool is_valid_handle(HalfedgeHandle _heh) const
00143   { return 0 <= _heh.idx() && _heh.idx() < SIGNED(n_edges()*2); }
00144 
00145   bool is_valid_handle(EdgeHandle _eh) const
00146   { return 0 <= _eh.idx() && _eh.idx() < SIGNED(n_edges()); }
00147 
00148   bool is_valid_handle(FaceHandle _fh) const
00149   { return 0 <= _fh.idx() && _fh.idx() < SIGNED(n_faces()); }
00150 
00151   // --- item -> handle ---
00152   const Vertex& vertex(VertexHandle _vh) const
00153   {
00154     assert(is_valid_handle(_vh));
00155     return vertices_[_vh.idx()];
00156   }
00157 
00158   Vertex& vertex(VertexHandle _vh)
00159   {
00160     assert(is_valid_handle(_vh));
00161     return vertices_[_vh.idx()];
00162   }
00163 
00164   const Halfedge& halfedge(HalfedgeHandle _heh) const
00165   {
00166     assert(is_valid_handle(_heh));
00167     return edges_[_heh.idx() >> 1].halfedges_[_heh.idx() & 1];
00168   }
00169 
00170   Halfedge& halfedge(HalfedgeHandle _heh)
00171   {
00172     assert(is_valid_handle(_heh));
00173     return edges_[_heh.idx() >> 1].halfedges_[_heh.idx() & 1];
00174   }
00175 
00176   const Edge& edge(EdgeHandle _eh) const
00177   {
00178     assert(is_valid_handle(_eh));
00179     return edges_[_eh.idx()];
00180   }
00181 
00182   Edge& edge(EdgeHandle _eh)
00183   {
00184     assert(is_valid_handle(_eh));
00185     return edges_[_eh.idx()];
00186   }
00187 
00188   const Face& face(FaceHandle _fh) const
00189   {
00190     assert(is_valid_handle(_fh));
00191     return faces_[_fh.idx()];
00192   }
00193 
00194   Face& face(FaceHandle _fh)
00195   {
00196     assert(is_valid_handle(_fh));
00197     return faces_[_fh.idx()];
00198   }
00199 
00200 #undef SIGNED
00201 
00202   // --- get i'th items ---
00203 
00204   VertexHandle vertex_handle(uint _i) const
00205   { return (_i < n_vertices()) ? handle( vertices_[_i] ) : VertexHandle(); }
00206 
00207   HalfedgeHandle halfedge_handle(uint _i) const
00208   {
00209     return (_i < n_halfedges()) ?
00210       halfedge_handle(edge_handle(_i/2), _i%2) : HalfedgeHandle();
00211   }
00212 
00213   EdgeHandle edge_handle(uint _i) const
00214   { return (_i < n_edges()) ? handle(edges_[_i]) : EdgeHandle(); }
00215 
00216   FaceHandle face_handle(uint _i) const
00217   { return (_i < n_faces()) ? handle(faces_[_i]) : FaceHandle(); }
00218 
00219 public:
00220 
00221   inline VertexHandle new_vertex()
00222   {
00223     vertices_.push_back(Vertex());
00224     vprops_resize(n_vertices());//TODO:should it be push_back()?
00225 
00226     return handle(vertices_.back());
00227   }
00228 
00229   inline HalfedgeHandle new_edge(VertexHandle _start_vh, VertexHandle _end_vh)
00230   {
00231 //     assert(_start_vh != _end_vh);
00232     edges_.push_back(Edge());
00233     eprops_resize(n_edges());//TODO:should it be push_back()?
00234     hprops_resize(n_halfedges());//TODO:should it be push_back()?
00235 
00236     EdgeHandle eh(handle(edges_.back()));
00237     HalfedgeHandle heh0(halfedge_handle(eh, 0));
00238     HalfedgeHandle heh1(halfedge_handle(eh, 1));
00239     set_vertex_handle(heh0, _end_vh);
00240     set_vertex_handle(heh1, _start_vh);
00241     return heh0;
00242   }
00243 
00244   inline FaceHandle new_face()
00245   {
00246     faces_.push_back(Face());
00247     fprops_resize(n_faces());
00248     return handle(faces_.back());
00249   }
00250 
00251   inline FaceHandle new_face(const Face& _f)
00252   {
00253     faces_.push_back(_f);
00254     fprops_resize(n_faces());
00255     return handle(faces_.back());
00256   }
00257 
00258 public:
00259   // --- resize/reserve ---
00260   void resize( uint _n_vertices, uint _n_edges, uint _n_faces );
00261   void reserve(uint _n_vertices, uint _n_edges, uint _n_faces );
00262 
00263   // --- deletion ---
00264   void garbage_collection(bool _v=true, bool _e=true, bool _f=true);
00265   void clear();
00266 
00267   // --- number of items ---
00268   uint n_vertices()  const { return vertices_.size(); }
00269   uint n_halfedges() const { return 2*edges_.size(); }
00270   uint n_edges()     const { return edges_.size(); }
00271   uint n_faces()     const { return faces_.size(); }
00272 
00273   bool vertices_empty()  const { return vertices_.empty(); }
00274   bool halfedges_empty() const { return edges_.empty(); }
00275   bool edges_empty()     const { return edges_.empty(); }
00276   bool faces_empty()     const { return faces_.empty(); }
00277 
00278   // --- vertex connectivity ---
00279 
00280   HalfedgeHandle halfedge_handle(VertexHandle _vh) const
00281   { return vertex(_vh).halfedge_handle_; }
00282 
00283   void set_halfedge_handle(VertexHandle _vh, HalfedgeHandle _heh)
00284   {
00285 //     assert(is_valid_handle(_heh));
00286     vertex(_vh).halfedge_handle_ = _heh;
00287   }
00288 
00289   bool is_isolated(VertexHandle _vh) const
00290   { return !halfedge_handle(_vh).is_valid(); }
00291 
00292   void set_isolated(VertexHandle _vh)
00293   { vertex(_vh).halfedge_handle_.invalidate(); }
00294 
00295   uint delete_isolated_vertices();
00296 
00297   // --- halfedge connectivity ---
00298   VertexHandle to_vertex_handle(HalfedgeHandle _heh) const
00299   { return halfedge(_heh).vertex_handle_; }
00300 
00301   VertexHandle from_vertex_handle(HalfedgeHandle _heh) const
00302   { return to_vertex_handle(opposite_halfedge_handle(_heh)); }
00303 
00304   void set_vertex_handle(HalfedgeHandle _heh, VertexHandle _vh)
00305   {
00306 //     assert(is_valid_handle(_vh));
00307     halfedge(_heh).vertex_handle_ = _vh;
00308   }
00309 
00310   FaceHandle face_handle(HalfedgeHandle _heh) const
00311   { return halfedge(_heh).face_handle_; }
00312 
00313   void set_face_handle(HalfedgeHandle _heh, FaceHandle _fh)
00314   {
00315 //     assert(is_valid_handle(_fh));
00316     halfedge(_heh).face_handle_ = _fh;
00317   }
00318 
00319   void set_boundary(HalfedgeHandle _heh)
00320   { halfedge(_heh).face_handle_.invalidate(); }
00321 
00323   bool is_boundary(HalfedgeHandle _heh) const
00324   { return !face_handle(_heh).is_valid(); }
00325 
00326   HalfedgeHandle next_halfedge_handle(HalfedgeHandle _heh) const
00327   { return halfedge(_heh).next_halfedge_handle_; }
00328 
00329   void set_next_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _nheh)
00330   {
00331     assert(is_valid_handle(_nheh));
00332 //     assert(to_vertex_handle(_heh) == from_vertex_handle(_nheh));
00333     halfedge(_heh).next_halfedge_handle_ = _nheh;
00334     set_prev_halfedge_handle(_nheh, _heh);
00335   }
00336 
00337 
00338   void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh)
00339   {
00340     assert(is_valid_handle(_pheh));
00341     set_prev_halfedge_handle(_heh, _pheh, HasPrevHalfedge());
00342   }
00343 
00344   void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh,
00345                                 GenProg::True)
00346   { halfedge(_heh).prev_halfedge_handle_ = _pheh; }
00347 
00348   void set_prev_halfedge_handle(HalfedgeHandle /* _heh */, HalfedgeHandle /* _pheh */,
00349                                 GenProg::False)
00350   {}
00351 
00352   HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh) const
00353   { return prev_halfedge_handle(_heh, HasPrevHalfedge() ); }
00354 
00355   HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::True) const
00356   { return halfedge(_heh).prev_halfedge_handle_; }
00357 
00358   HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::False) const
00359   {
00360     if (is_boundary(_heh))
00361     {//iterating around the vertex should be faster than iterating the boundary
00362       HalfedgeHandle curr_heh(opposite_halfedge_handle(_heh));
00363       HalfedgeHandle next_heh(next_halfedge_handle(curr_heh));
00364       do
00365       {
00366         curr_heh = opposite_halfedge_handle(next_heh);
00367         next_heh = next_halfedge_handle(curr_heh);
00368       }
00369       while (next_heh != _heh);
00370       return curr_heh;
00371     }
00372     else
00373     {
00374       HalfedgeHandle  heh(_heh);
00375       HalfedgeHandle  next_heh(next_halfedge_handle(heh));
00376       while (next_heh != _heh) {
00377         heh = next_heh;
00378         next_heh = next_halfedge_handle(next_heh);
00379       }
00380       return heh;
00381     }
00382   }
00383 
00384 
00385   HalfedgeHandle opposite_halfedge_handle(HalfedgeHandle _heh) const
00386   { return HalfedgeHandle((_heh.idx() & 1) ? _heh.idx()-1 : _heh.idx()+1); }
00387 
00388 
00389   HalfedgeHandle ccw_rotated_halfedge_handle(HalfedgeHandle _heh) const
00390   { return opposite_halfedge_handle(prev_halfedge_handle(_heh)); }
00391 
00392 
00393   HalfedgeHandle cw_rotated_halfedge_handle(HalfedgeHandle _heh) const
00394   { return next_halfedge_handle(opposite_halfedge_handle(_heh)); }
00395 
00396   // --- edge connectivity ---
00397   HalfedgeHandle halfedge_handle(EdgeHandle _eh, uint _i) const
00398   {
00399     assert(_i<=1);
00400     return HalfedgeHandle((_eh.idx() << 1) + _i);
00401   }
00402 
00403   EdgeHandle edge_handle(HalfedgeHandle _heh) const
00404   { return EdgeHandle(_heh.idx() >> 1); }
00405 
00406   // --- face connectivity ---
00407   HalfedgeHandle halfedge_handle(FaceHandle _fh) const
00408   { return face(_fh).halfedge_handle_; }
00409 
00410   void set_halfedge_handle(FaceHandle _fh, HalfedgeHandle _heh)
00411   {
00412 //     assert(is_valid_handle(_heh));
00413     face(_fh).halfedge_handle_ = _heh;
00414   }
00415 
00417   //------------------------------------------------------------ vertex status
00418   const StatusInfo&                         status(VertexHandle _vh) const
00419   { return property(vertex_status_, _vh); }
00420 
00421   StatusInfo&                               status(VertexHandle _vh)
00422   { return property(vertex_status_, _vh); }
00423 
00424   //----------------------------------------------------------- halfedge status
00425   const StatusInfo&                         status(HalfedgeHandle _hh) const
00426   { return property(halfedge_status_, _hh);  }
00427 
00428   StatusInfo&                               status(HalfedgeHandle _hh)
00429   { return property(halfedge_status_, _hh); }
00430 
00431   //--------------------------------------------------------------- edge status
00432   const StatusInfo&                         status(EdgeHandle _eh) const
00433   { return property(edge_status_, _eh); }
00434 
00435   StatusInfo&                               status(EdgeHandle _eh)
00436   { return property(edge_status_, _eh); }
00437 
00438   //--------------------------------------------------------------- face status
00439   const StatusInfo&                         status(FaceHandle _fh) const
00440   { return property(face_status_, _fh); }
00441 
00442   StatusInfo&                               status(FaceHandle _fh)
00443   { return property(face_status_, _fh); }
00444 
00445   inline bool                               has_vertex_status() const
00446   { return vertex_status_.is_valid();    }
00447 
00448   inline bool                               has_halfedge_status() const
00449   { return halfedge_status_.is_valid();  }
00450 
00451   inline bool                               has_edge_status() const
00452   { return edge_status_.is_valid(); }
00453 
00454   inline bool                               has_face_status() const
00455   { return face_status_.is_valid(); }
00456 
00457   inline VertexStatusPropertyHandle         vertex_status_pph() const
00458   { return vertex_status_;  }
00459 
00460   inline HalfedgeStatusPropertyHandle       halfedge_status_pph() const
00461   { return halfedge_status_; }
00462 
00463   inline EdgeStatusPropertyHandle           edge_status_pph() const
00464   { return edge_status_;  }
00465 
00466   inline FaceStatusPropertyHandle           face_status_pph() const
00467   { return face_status_; }
00468 
00470   inline VertexStatusPropertyHandle         status_pph(VertexHandle /*_hnd*/) const
00471   { return vertex_status_pph(); }
00472 
00473   inline HalfedgeStatusPropertyHandle       status_pph(HalfedgeHandle /*_hnd*/) const
00474   { return halfedge_status_pph(); }
00475 
00476   inline EdgeStatusPropertyHandle           status_pph(EdgeHandle /*_hnd*/) const
00477   { return edge_status_pph();  }
00478 
00479   inline FaceStatusPropertyHandle           status_pph(FaceHandle /*_hnd*/) const
00480   { return face_status_pph();  }
00481 
00483   void request_vertex_status()
00484   {
00485     if (!refcount_vstatus_++)
00486       add_property( vertex_status_, "v:status" );
00487   }
00488 
00489   void request_halfedge_status()
00490   {
00491     if (!refcount_hstatus_++)
00492       add_property( halfedge_status_, "h:status" );
00493   }
00494 
00495   void request_edge_status()
00496   {
00497     if (!refcount_estatus_++)
00498       add_property( edge_status_, "e:status" );
00499   }
00500 
00501   void request_face_status()
00502   {
00503     if (!refcount_fstatus_++)
00504       add_property( face_status_, "f:status" );
00505   }
00506 
00508   void release_vertex_status()
00509   {
00510     if ((refcount_vstatus_ > 0) && (! --refcount_vstatus_))
00511       remove_property(vertex_status_);
00512   }
00513 
00514   void release_halfedge_status()
00515   {
00516     if ((refcount_hstatus_ > 0) && (! --refcount_hstatus_))
00517       remove_property(halfedge_status_);
00518   }
00519 
00520   void release_edge_status()
00521   {
00522     if ((refcount_estatus_ > 0) && (! --refcount_estatus_))
00523       remove_property(edge_status_);
00524   }
00525 
00526   void release_face_status()
00527   {
00528     if ((refcount_fstatus_ > 0) && (! --refcount_fstatus_))
00529       remove_property(face_status_);
00530   }
00531 
00533 
00534   template <class Handle>
00535   class StatusSetT
00536   {
00537   protected:
00538     ArrayKernel&                            kernel_;
00539 
00540   public:
00541     const uint                              bit_mask_;
00542 
00543   public:
00544     StatusSetT(ArrayKernel& _kernel, uint _bit_mask)
00545     : kernel_(_kernel), bit_mask_(_bit_mask)
00546     {}
00547 
00548     ~StatusSetT()
00549     {}
00550 
00551     inline bool                             is_in(Handle _hnd) const
00552     { return kernel_.status(_hnd).is_bit_set(bit_mask_); }
00553 
00554     inline void                             insert(Handle _hnd)
00555     { return kernel_.status(_hnd).set_bit(bit_mask_); }
00556 
00557     inline void                             erase(Handle _hnd)
00558     { return kernel_.status(_hnd).unset_bit(bit_mask_); }
00559 
00561     uint                                    size() const
00562     {
00563       uint n_elements = kernel_.status_pph(Handle()).is_valid() ?
00564                           kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
00565       uint sz = 0;
00566       for (uint i = 0; i < n_elements; ++i)
00567       {
00568         sz += (uint)is_in(Handle(i));
00569       }
00570       return sz;
00571     }
00572     
00574     void                                    clear()
00575     {
00576       uint n_elements = kernel_.status_pph(Handle()).is_valid() ?
00577                           kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
00578       for (uint i = 0; i < n_elements; ++i)
00579       {
00580         erase(Handle(i));
00581       }
00582     }
00583   };
00584 
00585   friend class StatusSetT<VertexHandle>;
00586   friend class StatusSetT<EdgeHandle>;
00587   friend class StatusSetT<FaceHandle>;
00588   friend class StatusSetT<HalfedgeHandle>;
00589 
00591   
00592   template <class Handle>
00593   class AutoStatusSetT : public StatusSetT<Handle>
00594   {
00595   private:
00596     typedef StatusSetT<Handle>              Base;
00597   public:
00598     AutoStatusSetT(ArrayKernel& _kernel)
00599     : StatusSetT<Handle>(_kernel, _kernel.pop_bit_mask(Handle()))
00600     { /*assert(size() == 0);*/ } //the set should be empty on creation
00601 
00602     ~AutoStatusSetT()
00603     {
00604       //assert(size() == 0);//the set should be empty on leave?
00605       Base::kernel_.push_bit_mask(Handle(), Base::bit_mask_);
00606     }
00607   };
00608 
00609   friend class AutoStatusSetT<VertexHandle>;
00610   friend class AutoStatusSetT<EdgeHandle>;
00611   friend class AutoStatusSetT<FaceHandle>;
00612   friend class AutoStatusSetT<HalfedgeHandle>;
00613 
00614   typedef AutoStatusSetT<VertexHandle>      VertexStatusSet;
00615   typedef AutoStatusSetT<EdgeHandle>        EdgeStatusSet;
00616   typedef AutoStatusSetT<FaceHandle>        FaceStatusSet;
00617   typedef AutoStatusSetT<HalfedgeHandle>    HalfedgeStatusSet;
00618 
00620   
00621   template <class Handle>
00622   class ExtStatusSetT : public AutoStatusSetT<Handle>
00623   {
00624   public:
00625     typedef AutoStatusSetT<Handle>          Base;
00626 
00627   protected:
00628     typedef std::vector<Handle>             HandleContainer;
00629     HandleContainer                         handles_;
00630 
00631   public:
00632     typedef typename HandleContainer::iterator
00633                                             iterator;
00634     typedef typename HandleContainer::const_iterator
00635                                             const_iterator;
00636   public:
00637     ExtStatusSetT(ArrayKernel& _kernel, uint _capacity_hint = 0)
00638     : Base(_kernel)
00639     { handles_.reserve(_capacity_hint); }
00640 
00641     ~ExtStatusSetT()
00642     { clear(); }
00643 
00644     //set API
00645     // Complexity: O(1)
00646     inline void                             insert(Handle _hnd)
00647     {
00648       if (!is_in(_hnd))
00649       {
00650         Base::insert(_hnd);
00651         handles_.push_back(_hnd);
00652       }
00653     }
00654 
00655     // Complexity: O(k), (k - number of the elements in the set)
00656     inline void                             erase(Handle _hnd)
00657     {
00658       if (is_in(_hnd))
00659       {
00660         iterator it = std::find(begin(), end(), _hnd);
00661         erase(it);
00662       }
00663     }
00664 
00665     // Complexity: O(1)
00666     inline void                             erase(iterator _it)
00667     {
00668       assert(_it != end() && is_in(*_it));
00669       clear(*_it);
00670       *_it = handles_.back();
00671       *_it.pop_back();
00672     }
00673 
00674     inline void                             clear()
00675     {
00676       for (iterator it = begin(); it != end(); ++it)
00677       {
00678         assert(is_in(*it));
00679         Base::erase(*it);
00680       }
00681       handles_.clear();
00682     }
00683 
00685     inline uint                             size() const
00686     { return handles_.size(); }
00687     inline bool                             empty() const
00688     { return handles_.empty(); }
00689 
00690     //Vector API
00691     inline iterator                         begin()
00692     { return handles_.begin(); }
00693     inline const_iterator                   begin() const
00694     { return handles_.begin(); }
00695 
00696     inline iterator                         end()
00697     { return handles_.end(); }
00698     inline const_iterator                   end() const
00699     { return handles_.end(); }
00700 
00701     inline Handle&                          front()
00702     { return handles_.front(); }
00703     inline const Handle&                    front() const
00704     { return handles_.front(); }
00705 
00706     inline Handle&                          back()
00707     { return handles_.back(); }
00708     inline const Handle&                    back() const
00709     { return handles_.back(); }
00710   };
00711 
00712   typedef ExtStatusSetT<FaceHandle>         ExtFaceStatusSet;
00713   typedef ExtStatusSetT<VertexHandle>       ExtVertexStatusSet;
00714   typedef ExtStatusSetT<EdgeHandle>         ExtEdgeStatusSet;
00715   typedef ExtStatusSetT<HalfedgeHandle>     ExtHalfedgeStatusSet;
00716   
00717 private:
00718   // iterators
00719   typedef std::vector<Vertex>                VertexContainer;
00720   typedef std::vector<Edge>                  EdgeContainer;
00721   typedef std::vector<Face>                  FaceContainer;
00722   typedef VertexContainer::iterator          KernelVertexIter;
00723   typedef VertexContainer::const_iterator    KernelConstVertexIter;
00724   typedef EdgeContainer::iterator            KernelEdgeIter;
00725   typedef EdgeContainer::const_iterator      KernelConstEdgeIter;
00726   typedef FaceContainer::iterator            KernelFaceIter;
00727   typedef FaceContainer::const_iterator      KernelConstFaceIter;
00728   typedef std::vector<uint>                  BitMaskContainer;
00729 
00730 
00731   KernelVertexIter      vertices_begin()        { return vertices_.begin(); }
00732   KernelConstVertexIter vertices_begin() const  { return vertices_.begin(); }
00733   KernelVertexIter      vertices_end()          { return vertices_.end(); }
00734   KernelConstVertexIter vertices_end() const    { return vertices_.end(); }
00735 
00736   KernelEdgeIter        edges_begin()           { return edges_.begin(); }
00737   KernelConstEdgeIter   edges_begin() const     { return edges_.begin(); }
00738   KernelEdgeIter        edges_end()             { return edges_.end(); }
00739   KernelConstEdgeIter   edges_end() const       { return edges_.end(); }
00740 
00741   KernelFaceIter        faces_begin()           { return faces_.begin(); }
00742   KernelConstFaceIter   faces_begin() const     { return faces_.begin(); }
00743   KernelFaceIter        faces_end()             { return faces_.end(); }
00744   KernelConstFaceIter   faces_end() const       { return faces_.end(); }
00745 
00747   inline BitMaskContainer&                  bit_masks(VertexHandle /*_dummy_hnd*/)
00748   { return vertex_bit_masks_; }
00749   inline BitMaskContainer&                  bit_masks(EdgeHandle /*_dummy_hnd*/)
00750   { return edge_bit_masks_; }
00751   inline BitMaskContainer&                  bit_masks(FaceHandle /*_dummy_hnd*/)
00752   { return face_bit_masks_; }
00753   inline BitMaskContainer&                  bit_masks(HalfedgeHandle /*_dummy_hnd*/)
00754   { return halfedge_bit_masks_; }
00755 
00756   template <class Handle>
00757   uint                                      pop_bit_mask(Handle _hnd)
00758   {
00759     assert(!bit_masks(_hnd).empty());//check if the client request too many status sets
00760     uint bit_mask = bit_masks(_hnd).back();
00761     bit_masks(_hnd).pop_back();
00762     return bit_mask;
00763   }
00764 
00765   template <class Handle>
00766   void                                      push_bit_mask(Handle _hnd, uint _bit_mask)
00767   {
00768     assert(std::find(bit_masks(_hnd).begin(), bit_masks(_hnd).end(), _bit_mask) ==
00769            bit_masks(_hnd).end());//this mask should be not already used
00770     bit_masks(_hnd).push_back(_bit_mask);
00771   }
00772 
00773   void                                      init_bit_masks(BitMaskContainer& _bmc);
00774   void                                      init_bit_masks();
00775   
00776 private:
00777   VertexContainer                           vertices_;
00778   EdgeContainer                             edges_;
00779   FaceContainer                             faces_;
00780 
00781   VertexStatusPropertyHandle                vertex_status_;
00782   HalfedgeStatusPropertyHandle              halfedge_status_;
00783   EdgeStatusPropertyHandle                  edge_status_;
00784   FaceStatusPropertyHandle                  face_status_;
00785 
00786   uint                                      refcount_vstatus_;
00787   uint                                      refcount_hstatus_;
00788   uint                                      refcount_estatus_;
00789   uint                                      refcount_fstatus_;
00790 
00791   BitMaskContainer                          halfedge_bit_masks_;
00792   BitMaskContainer                          edge_bit_masks_;
00793   BitMaskContainer                          vertex_bit_masks_;
00794   BitMaskContainer                          face_bit_masks_;
00795 };
00796 
00797 //=============================================================================
00798 } // namespace OpenMesh
00799 //=============================================================================
00800 #endif // OPENMESH_ARRAY_KERNEL_HH defined
00801 //=============================================================================
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines