Main Page | Modules | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

ArrayKernelT.hh

00001 //=============================================================================
00002 //
00003 //                               OpenMesh
00004 //      Copyright (C) 2001-2005 by Computer Graphics Group, RWTH Aachen
00005 //                           www.openmesh.org
00006 //
00007 //-----------------------------------------------------------------------------
00008 //
00009 //                                License
00010 //
00011 //   This library is free software; you can redistribute it and/or modify it
00012 //   under the terms of the GNU Library General Public License as published
00013 //   by the Free Software Foundation, version 2.
00014 //
00015 //   This library is distributed in the hope that it will be useful, but
00016 //   WITHOUT ANY WARRANTY; without even the implied warranty of
00017 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 //   Library General Public License for more details.
00019 //
00020 //   You should have received a copy of the GNU Library General Public
00021 //   License along with this library; if not, write to the Free Software
00022 //   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00023 //
00024 //-----------------------------------------------------------------------------
00025 //
00026 //   $Revision: 1.6 $
00027 //   $Date: 2005/08/11 09:40:06 $
00028 //
00029 //=============================================================================
00030 
00031 
00032 //=============================================================================
00033 //
00034 //  CLASS ArrayKernelT
00035 //
00036 //=============================================================================
00037 
00038 
00039 #ifndef OPENMESH_ARRAY_KERNEL_HH
00040 #define OPENMESH_ARRAY_KERNEL_HH
00041 
00042 
00043 //== INCLUDES =================================================================
00044 
00045 
00046 #include <OpenMesh/Core/System/config.hh>
00047 #include <OpenMesh/Core/Mesh/Kernels/Common/AttribKernelT.hh>
00048 #include <OpenMesh/Core/Utils/GenProg.hh>
00049 #include <vector>
00050 
00051 
00052 
00053 //== NAMESPACES ===============================================================
00054 
00055 
00056 namespace OpenMesh {
00057 
00058 
00059 //== CLASS DEFINITION =========================================================
00060 
00061 
00078 template <class AttribKernel, class FinalMeshItems>
00079 class ArrayKernelT : public AttribKernel
00080 {
00081 public:
00082 
00083   typedef ArrayKernelT<AttribKernel, FinalMeshItems>  This;
00084   typedef AttribKernel                                Base;
00085 
00086   // attributes
00087   typedef typename Base::HasPrevHalfedge              HasPrevHalfedge;
00088 
00089   // item types
00090   typedef typename FinalMeshItems::Vertex             Vertex;
00091   typedef typename FinalMeshItems::Halfedge           Halfedge;
00092   typedef typename FinalMeshItems::Edge               Edge;
00093   typedef typename FinalMeshItems::Face               Face;
00094   typedef typename FinalMeshItems::Point              Point;
00095   typedef typename FinalMeshItems::Scalar             Scalar;
00096 
00097   // handles
00098   typedef OpenMesh::VertexHandle       VertexHandle;
00099   typedef OpenMesh::HalfedgeHandle     HalfedgeHandle;
00100   typedef OpenMesh::EdgeHandle         EdgeHandle;
00101   typedef OpenMesh::FaceHandle         FaceHandle;
00102 
00103 
00104 
00105   // --- constructor/destructor ---
00106 
00107 
00108   ArrayKernelT() {}
00109   ~ArrayKernelT() { clear(); }
00110 
00111 
00112   void copy_topology_from(const ArrayKernelT& _other)
00113   {
00114     // copy raw data
00115     vertices_ = _other.vertices_;
00116     edges_    = _other.edges_;
00117     faces_    = _other.faces_;
00118 
00119     // resize properties
00120     resize(n_vertices(), n_edges(), n_faces());
00121   }
00122 
00123 
00124   // --- handle -> item ---
00125 
00126   VertexHandle handle(const Vertex& _v) const  {
00127     return VertexHandle(&_v - &vertices_.front());
00128   }
00129 
00130   HalfedgeHandle handle(const Halfedge& _he) const {
00131     unsigned int eh = ((char*)&_he - (char*)&edges_.front()) / sizeof(Edge);
00132     assert((&_he == &edges_[eh].halfedges_[0]) ||
00133            (&_he == &edges_[eh].halfedges_[1]));
00134     return ((&_he == &edges_[eh].halfedges_[0]) ?
00135             HalfedgeHandle(eh<<1) : HalfedgeHandle((eh<<1)+1));
00136   }
00137 
00138   EdgeHandle handle(const Edge& _e) const {
00139     return EdgeHandle(&_e - &edges_.front());
00140   }
00141 
00142   FaceHandle handle(const Face& _f) const {
00143     return FaceHandle(&_f - &faces_.front());
00144   }
00145 
00146 
00147 
00148 #define SIGNED(x) signed( (x) )
00149   //checks handle validity - useful for debugging
00150   bool is_valid_handle(VertexHandle _vh) const
00151   {
00152     return 0 <= _vh.idx() && _vh.idx() < SIGNED(n_vertices());
00153   }
00154 
00155   bool is_valid_handle(HalfedgeHandle _heh) const
00156   {
00157     return 0 <= _heh.idx() && _heh.idx() < SIGNED(n_edges()*2);
00158   }
00159 
00160   bool is_valid_handle(EdgeHandle _eh) const
00161   {
00162     return 0 <= _eh.idx() && _eh.idx() < SIGNED(n_edges());
00163   }
00164 
00165   bool is_valid_handle(FaceHandle _fh) const
00166   {
00167     return 0 <= _fh.idx() && _fh.idx() < SIGNED(n_faces());
00168   }
00169 
00170   // --- item -> handle ---
00171 
00172   const Vertex& vertex(VertexHandle _vh) const
00173   {
00174     assert(is_valid_handle(_vh));
00175     return vertices_[_vh.idx()];
00176   }
00177 
00178   Vertex& vertex(VertexHandle _vh)
00179   {
00180     assert(is_valid_handle(_vh));
00181     return vertices_[_vh.idx()];
00182   }
00183 
00184   const Halfedge& halfedge(HalfedgeHandle _heh) const
00185   {
00186     assert(is_valid_handle(_heh));
00187     return edges_[_heh.idx() >> 1].halfedges_[_heh.idx() & 1];
00188   }
00189 
00190   Halfedge& halfedge(HalfedgeHandle _heh)
00191   {
00192     assert(is_valid_handle(_heh));
00193     return edges_[_heh.idx() >> 1].halfedges_[_heh.idx() & 1];
00194   }
00195 
00196   const Edge& edge(EdgeHandle _eh) const
00197   {
00198     assert(is_valid_handle(_eh));
00199     return edges_[_eh.idx()];
00200   }
00201 
00202   Edge& edge(EdgeHandle _eh) {
00203     assert(is_valid_handle(_eh));
00204     return edges_[_eh.idx()];
00205   }
00206 
00207   const Face& face(FaceHandle _fh) const {
00208     assert(is_valid_handle(_fh));
00209     return faces_[_fh.idx()];
00210   }
00211 
00212   Face& face(FaceHandle _fh) {
00213     assert(is_valid_handle(_fh));
00214     return faces_[_fh.idx()];
00215   }
00216 
00217 #undef SIGNED
00218 
00219 
00220 
00221   // --- get i'th items ---
00222 
00223   VertexHandle vertex_handle(unsigned int _i) const {
00224     return (_i < n_vertices()) ? handle( vertices_[_i] ) : VertexHandle();
00225   }
00226 
00227   HalfedgeHandle halfedge_handle(unsigned int _i) const {
00228     return (_i < n_halfedges()) ? halfedge_handle(edge_handle(_i/2), _i%2) : HalfedgeHandle();
00229   }
00230 
00231   EdgeHandle edge_handle(unsigned int _i) const {
00232     return (_i < n_edges()) ? handle(edges_[_i]) : EdgeHandle();
00233   }
00234 
00235   FaceHandle face_handle(unsigned int _i) const {
00236     return (_i < n_faces()) ? handle(faces_[_i]) : FaceHandle();
00237   }
00238 
00239 
00240   // --- add new items ---
00241 
00242   void reserve( unsigned int _n_vertices,
00243                 unsigned int _n_edges,
00244                 unsigned int _n_faces )
00245   {
00246     vertices_.reserve(_n_vertices);
00247     edges_.reserve(_n_edges);
00248     faces_.reserve(_n_faces);
00249 
00250     AttribKernel::vprops_reserve(_n_vertices);
00251     AttribKernel::hprops_reserve(_n_edges*2);
00252     AttribKernel::eprops_reserve(_n_edges);
00253     AttribKernel::fprops_reserve(_n_faces);
00254   }
00255 
00256 
00257 public:
00258 
00259   VertexHandle new_vertex()
00260   {
00261     vertices_.push_back(Vertex());
00262     vprops_resize(n_vertices());
00263 
00264     return handle(vertices_.back());
00265   }
00266 
00267 
00268   VertexHandle new_vertex(const Point& _p)
00269   {
00270     vertices_.push_back(Vertex());
00271     vprops_resize(n_vertices());
00272 
00273     VertexHandle vh(handle(vertices_.back()));
00274     set_point(vh, _p);
00275     return vh;
00276   }
00277 
00278 
00279   HalfedgeHandle new_edge(VertexHandle _start_vertex_handle,
00280                           VertexHandle _end_vertex_handle)
00281   {
00282     assert(_start_vertex_handle != _end_vertex_handle);
00283     edges_.push_back(Edge());
00284     eprops_resize(n_edges());
00285     hprops_resize(n_halfedges());
00286 
00287     EdgeHandle eh(handle(edges_.back()));
00288     HalfedgeHandle heh0(halfedge_handle(eh, 0));
00289     HalfedgeHandle heh1(halfedge_handle(eh, 1));
00290     set_vertex_handle(heh0, _end_vertex_handle);
00291     set_vertex_handle(heh1, _start_vertex_handle);
00292     return heh0;
00293   }
00294 
00295 
00296   FaceHandle new_face()
00297   {
00298     faces_.push_back(Face());
00299     fprops_resize(n_faces());
00300     return handle(faces_.back());
00301   }
00302 
00303   FaceHandle new_face(const Face& _f)
00304   {
00305     faces_.push_back(_f);
00306     fprops_resize(n_faces());
00307     return handle(faces_.back());
00308   }
00309 
00310 public:
00311 
00312 
00313 
00314   // --- deletion ---
00315 
00316   void garbage_collection(bool _v=true, bool _e=true, bool _f=true);
00317 
00318   void clear() 
00319   {
00320     vertices_.clear();
00321     edges_.clear();
00322     faces_.clear();
00323 
00324     AttribKernel::vprops_resize(0);
00325     AttribKernel::eprops_resize(0);
00326     AttribKernel::hprops_resize(0);
00327     AttribKernel::fprops_resize(0);
00328   }
00329 
00330   void free_mem()
00331   {
00332     VertexContainer(vertices_).swap(vertices_);
00333     EdgeContainer(edges_).swap(edges_);
00334     FaceContainer(faces_).swap(faces_);
00335 
00336     Base::vprops_free_mem();
00337     Base::eprops_free_mem();
00338     Base::hprops_free_mem();
00339     Base::fprops_free_mem();
00340   }
00341 
00342   void resize( unsigned int _n_vertices,
00343                unsigned int _n_edges,
00344                unsigned int _n_faces )
00345   {
00346     vertices_.resize(_n_vertices);
00347     edges_.resize(_n_edges);
00348     faces_.resize(_n_faces);
00349 
00350     vprops_resize(n_vertices());
00351     hprops_resize(n_halfedges());
00352     eprops_resize(n_edges());
00353     fprops_resize(n_faces());
00354   }
00355 
00356 
00357 
00358 
00359   // --- number of items ---
00360 
00361   unsigned int n_vertices()  const { return vertices_.size(); }
00362   unsigned int n_halfedges() const { return 2*edges_.size(); }
00363   unsigned int n_edges()     const { return edges_.size(); }
00364   unsigned int n_faces()     const { return faces_.size(); }
00365 
00366   bool empty()           const { return vertices_.empty(); }
00367   bool vertices_empty()  const { return vertices_.empty(); }
00368   bool halfedges_empty() const { return edges_.empty(); }
00369   bool edges_empty()     const { return edges_.empty(); }
00370   bool faces_empty()     const { return faces_.empty(); }
00371 
00372 
00373 
00374 
00375 
00376   // --- vertex connectivity ---
00377 
00378   HalfedgeHandle halfedge_handle(VertexHandle _vh) const {
00379     return vertex(_vh).halfedge_handle_;
00380   }
00381 
00382   void set_halfedge_handle(VertexHandle _vh, HalfedgeHandle _heh)
00383   {
00384 //     assert(is_valid_handle(_heh));
00385     vertex(_vh).halfedge_handle_ = _heh;
00386   }
00387 
00388   bool is_isolated(VertexHandle _vh) const
00389   {
00390     return !halfedge_handle(_vh).is_valid();
00391   }
00392 
00393   void set_isolated(VertexHandle _vh)
00394   {
00395     vertex(_vh).halfedge_handle_.invalidate();
00396   }
00397 
00398 
00399   // --- halfedge connectivity ---
00400 
00401 
00402   VertexHandle to_vertex_handle(HalfedgeHandle _heh) const {
00403     return halfedge(_heh).vertex_handle_;
00404   }
00405 
00406   VertexHandle from_vertex_handle(HalfedgeHandle _heh) const {
00407     return to_vertex_handle(opposite_halfedge_handle(_heh));
00408   }
00409 
00410   void set_vertex_handle(HalfedgeHandle _heh, VertexHandle _vh)
00411   {
00412     assert(is_valid_handle(_vh));
00413     halfedge(_heh).vertex_handle_ = _vh;
00414   }
00415 
00416 
00417   FaceHandle face_handle(HalfedgeHandle _heh) const {
00418     return halfedge(_heh).face_handle_;
00419   }
00420 
00421   void set_face_handle(HalfedgeHandle _heh, FaceHandle _fh)
00422   {
00423 //     assert(is_valid_handle(_fh));
00424     halfedge(_heh).face_handle_ = _fh;
00425   }
00426 
00427   void set_boundary(HalfedgeHandle _heh)
00428   {
00429     halfedge(_heh).face_handle_.invalidate();
00430   }
00431 
00433   bool is_boundary(HalfedgeHandle _heh) const
00434   {
00435     return !face_handle(_heh).is_valid();
00436   }
00437 
00438   HalfedgeHandle next_halfedge_handle(HalfedgeHandle _heh) const {
00439     return halfedge(_heh).next_halfedge_handle_;
00440   }
00441 
00442   void set_next_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _nheh)
00443   {
00444     assert(is_valid_handle(_nheh));
00445 //     assert(to_vertex_handle(_heh) == from_vertex_handle(_nheh));
00446     halfedge(_heh).next_halfedge_handle_ = _nheh;
00447     set_prev_halfedge_handle(_nheh, _heh);
00448   }
00449 
00450 
00451   void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh)
00452   {
00453     assert(is_valid_handle(_pheh));
00454     set_prev_halfedge_handle(_heh, _pheh, HasPrevHalfedge());
00455   }
00456 
00457   void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh,
00458         GenProg::True) {
00459     halfedge(_heh).prev_halfedge_handle_ = _pheh;
00460   }
00461   void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh,
00462         GenProg::False) {}
00463 
00464 
00465   HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh) const {
00466     return prev_halfedge_handle(_heh, HasPrevHalfedge() );
00467   }
00468 
00469   HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh,
00470               GenProg::True) const {
00471     return halfedge(_heh).prev_halfedge_handle_;
00472   }
00473 
00474   HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh,
00475               GenProg::False) const
00476   {
00477     if (is_boundary(_heh))
00478     {//iterating around the vertex should be faster than iterating the boundary
00479       HalfedgeHandle curr_heh(opposite_halfedge_handle(_heh));
00480       HalfedgeHandle next_heh(This::next_halfedge_handle(curr_heh));
00481       do
00482       {
00483         curr_heh = opposite_halfedge_handle(next_heh);
00484         next_heh = This::next_halfedge_handle(curr_heh);
00485       }
00486       while (next_heh != _heh);
00487       return curr_heh;
00488     }
00489     else
00490     {
00491       HalfedgeHandle  heh(_heh);
00492       HalfedgeHandle  next_heh(This::next_halfedge_handle(heh));
00493       while (next_heh != _heh) {
00494         heh = next_heh;
00495         next_heh = This::next_halfedge_handle(next_heh);
00496       }
00497       return heh;
00498     }
00499   }
00500 
00501 
00502   HalfedgeHandle opposite_halfedge_handle(HalfedgeHandle _heh) const {
00503     return HalfedgeHandle((_heh.idx() & 1) ? _heh.idx()-1 : _heh.idx()+1);
00504   }
00505 
00506 
00507   HalfedgeHandle ccw_rotated_halfedge_handle(HalfedgeHandle _heh) const {
00508     return opposite_halfedge_handle(prev_halfedge_handle(_heh));
00509   }
00510 
00511 
00512   HalfedgeHandle cw_rotated_halfedge_handle(HalfedgeHandle _heh) const {
00513     return next_halfedge_handle(opposite_halfedge_handle(_heh));
00514   }
00515 
00516 
00517 
00518   // --- edge connectivity ---
00519 
00520 
00521   HalfedgeHandle halfedge_handle(EdgeHandle _eh, unsigned int _i) const {
00522     assert(_i<=1);
00523     return HalfedgeHandle((_eh.idx() << 1) + _i);
00524   }
00525 
00526 
00527   EdgeHandle edge_handle(HalfedgeHandle _heh) const {
00528     return EdgeHandle(_heh.idx() >> 1);
00529   }
00530 
00531 
00532 
00533   // --- face connectivity ---
00534 
00535 
00536   HalfedgeHandle halfedge_handle(FaceHandle _fh) const {
00537     return face(_fh).halfedge_handle_;
00538   }
00539 
00540   void set_halfedge_handle(FaceHandle _fh, HalfedgeHandle _heh)
00541   {
00542 //     assert(is_valid_handle(_heh));
00543     face(_fh).halfedge_handle_ = _heh;
00544   }
00545 
00546 private:
00547 
00548   // iterators
00549   typedef std::vector<Vertex>                         VertexContainer;
00550   typedef std::vector<Edge>                           EdgeContainer;
00551   typedef std::vector<Face>                           FaceContainer;
00552   typedef typename VertexContainer::iterator          KernelVertexIter;
00553   typedef typename VertexContainer::const_iterator    KernelConstVertexIter;
00554   typedef typename EdgeContainer::iterator            KernelEdgeIter;
00555   typedef typename EdgeContainer::const_iterator      KernelConstEdgeIter;
00556   typedef typename FaceContainer::iterator            KernelFaceIter;
00557   typedef typename FaceContainer::const_iterator      KernelConstFaceIter;
00558 
00559 
00560   KernelVertexIter vertices_begin()             { return vertices_.begin(); }
00561   KernelConstVertexIter vertices_begin() const  { return vertices_.begin(); }
00562   KernelVertexIter vertices_end()               { return vertices_.end(); }
00563   KernelConstVertexIter vertices_end() const    { return vertices_.end(); }
00564 
00565   KernelEdgeIter edges_begin()                  { return edges_.begin(); }
00566   KernelConstEdgeIter edges_begin() const       { return edges_.begin(); }
00567   KernelEdgeIter edges_end()                    { return edges_.end(); }
00568   KernelConstEdgeIter edges_end() const         { return edges_.end(); }
00569 
00570   KernelFaceIter faces_begin()                  { return faces_.begin(); }
00571   KernelConstFaceIter faces_begin() const       { return faces_.begin(); }
00572   KernelFaceIter faces_end()                    { return faces_.end(); }
00573   KernelConstFaceIter faces_end() const         { return faces_.end(); }
00574 
00575 
00576 private:
00577 
00578   VertexContainer    vertices_;
00579   EdgeContainer      edges_;
00580   FaceContainer      faces_;
00581 };
00582 
00583 
00584 //-----------------------------------------------------------------------------
00585 
00586 
00587 template <class AttribKernel, class FinalMeshItems>
00588 void
00589 ArrayKernelT<AttribKernel, FinalMeshItems>::
00590 garbage_collection(bool _v, bool _e, bool _f)
00591 {
00592   int            i, i0, i1,
00593                  nV(n_vertices()),
00594                  nE(n_edges()),
00595                  nH(2*n_edges()),
00596                  nF(n_faces());
00597 
00598   std::vector<VertexHandle>    vh_map;
00599   std::vector<HalfedgeHandle>  hh_map;
00600   std::vector<FaceHandle>      fh_map;
00601 
00602   // setup handle mapping:
00603   vh_map.reserve(nV);
00604   for (i=0; i<nV; ++i) vh_map.push_back(VertexHandle(i));
00605 
00606   hh_map.reserve(nH);
00607   for (i=0; i<nH; ++i) hh_map.push_back(HalfedgeHandle(i));
00608 
00609   fh_map.reserve(nF);
00610   for (i=0; i<nF; ++i) fh_map.push_back(FaceHandle(i));
00611 
00612 
00613   // remove deleted vertices
00614   if (_v && n_vertices() > 0)
00615   {
00616     i0=0;  i1=nV-1;
00617 
00618     while (1)
00619     {
00620       // find 1st deleted and last un-deleted
00621       while (!AttribKernel::status(VertexHandle(i0)).deleted() && i0 < i1)  ++i0;
00622       while ( AttribKernel::status(VertexHandle(i1)).deleted() && i0 < i1)  --i1;
00623       if (i0 >= i1) break;
00624 
00625       // swap
00626       std::swap(vertices_[i0], vertices_[i1]);
00627       std::swap(vh_map[i0],  vh_map[i1]);
00628       AttribKernel::vprops_swap(i0, i1);
00629     };
00630 
00631     vertices_.resize(AttribKernel::status(VertexHandle(i0)).deleted() ? i0 : i0+1);
00632     vprops_resize(n_vertices());
00633   }
00634 
00635 
00636   // remove deleted edges
00637   if (_e && n_edges() > 0)
00638   {
00639     i0=0;  i1=nE-1;
00640 
00641     while (1)
00642     {
00643       // find 1st deleted and last un-deleted
00644       while (!AttribKernel::status(EdgeHandle(i0)).deleted() && i0 < i1)  ++i0;
00645       while ( AttribKernel::status(EdgeHandle(i1)).deleted() && i0 < i1)  --i1;
00646       if (i0 >= i1) break;
00647 
00648       // swap
00649       std::swap(edges_[i0], edges_[i1]);
00650       std::swap(hh_map[2*i0], hh_map[2*i1]);
00651       std::swap(hh_map[2*i0+1], hh_map[2*i1+1]);
00652       AttribKernel::eprops_swap(i0, i1);
00653       AttribKernel::hprops_swap(2*i0,   2*i1);
00654       AttribKernel::hprops_swap(2*i0+1, 2*i1+1);
00655     };
00656 
00657     edges_.resize(AttribKernel::status(EdgeHandle(i0)).deleted() ? i0 : i0+1);
00658     eprops_resize(n_edges());
00659     hprops_resize(n_halfedges());
00660   }
00661 
00662 
00663   // remove deleted faces
00664   if (_f && n_faces() > 0)
00665   {
00666     i0=0;  i1=nF-1;
00667 
00668     while (1)
00669     {
00670       // find 1st deleted and last un-deleted
00671       while (!AttribKernel::status(FaceHandle(i0)).deleted() && i0 < i1)  ++i0;
00672       while ( AttribKernel::status(FaceHandle(i1)).deleted() && i0 < i1)  --i1;
00673       if (i0 >= i1) break;
00674 
00675       // swap
00676       std::swap(faces_[i0], faces_[i1]);
00677       std::swap(fh_map[i0], fh_map[i1]);
00678       AttribKernel::fprops_swap(i0, i1);
00679     };
00680 
00681     faces_.resize(AttribKernel::status(FaceHandle(i0)).deleted() ? i0 : i0+1);
00682     fprops_resize(n_faces());
00683   }
00684 
00685 
00686   // update handles of vertices
00687   if (_e)
00688   {
00689     KernelVertexIter v_it(vertices_begin()), v_end(vertices_end());
00690     VertexHandle     vh;
00691 
00692     for (; v_it!=v_end; ++v_it)
00693     {
00694       vh = handle(*v_it);
00695       if (!AttribKernel::status(vh).deleted() && !is_isolated(vh))
00696         set_halfedge_handle(vh, hh_map[halfedge_handle(vh).idx()]);
00697     }
00698   }
00699 
00700   HalfedgeHandle hh;
00701   // update handles of halfedges
00702   for (KernelEdgeIter e_it(edges_begin()); e_it != edges_end(); ++e_it)
00703   {//in the first pass update the (half)edges vertices
00704     hh = halfedge_handle(handle(*e_it), 0);
00705     set_vertex_handle(hh, vh_map[to_vertex_handle(hh).idx()]);
00706     hh = halfedge_handle(handle(*e_it), 1);
00707     set_vertex_handle(hh, vh_map[to_vertex_handle(hh).idx()]);
00708   }
00709   for (KernelEdgeIter e_it(edges_begin()); e_it != edges_end(); ++e_it)
00710   {//in the second pass update the connectivity of the (half)edges
00711     hh = halfedge_handle(handle(*e_it), 0);
00712     set_next_halfedge_handle(hh, hh_map[next_halfedge_handle(hh).idx()]);
00713     if (!is_boundary(hh))
00714     {
00715       set_face_handle(hh, fh_map[face_handle(hh).idx()]);
00716     }
00717     hh = halfedge_handle(handle(*e_it), 1);
00718     set_next_halfedge_handle(hh, hh_map[next_halfedge_handle(hh).idx()]);
00719     if (!is_boundary(hh))
00720     {
00721       set_face_handle(hh, fh_map[face_handle(hh).idx()]);
00722     }
00723   }
00724 
00725 
00726   // update handles of faces
00727   if (_e)
00728   {
00729     KernelFaceIter  f_it(faces_begin()), f_end(faces_end());
00730     FaceHandle      fh;
00731 
00732     for (; f_it!=f_end; ++f_it)
00733     {
00734       fh = handle(*f_it);
00735       set_halfedge_handle(fh, hh_map[halfedge_handle(fh).idx()]);
00736     }
00737   }
00738 
00739 }
00740 
00741 
00742 //=============================================================================
00743 } // namespace OpenMesh
00744 //=============================================================================
00745 #endif // OPENMESH_ARRAY_KERNEL_HH defined
00746 //=============================================================================

acg pic Project OpenMesh, ©  Computer Graphics Group, RWTH Aachen. Documentation generated using doxygen .