- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# Core/Mesh/Kernels/ArrayKernel/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.7 $
    00027 //   $Date: 2005-12-21 13:51:54 $
    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 //=============================================================================