OpenMesh
|
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: 362 $ * 00038 * $Date: 2011-01-26 10:21:12 +0100 (Mi, 26 Jan 2011) $ * 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 //=============================================================================