00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef OPENMESH_ARRAY_KERNEL_HH
00040 #define OPENMESH_ARRAY_KERNEL_HH
00041
00042
00043
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
00054
00055
00056 namespace OpenMesh {
00057
00058
00059
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
00087 typedef typename Base::HasPrevHalfedge HasPrevHalfedge;
00088
00089
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
00098 typedef OpenMesh::VertexHandle VertexHandle;
00099 typedef OpenMesh::HalfedgeHandle HalfedgeHandle;
00100 typedef OpenMesh::EdgeHandle EdgeHandle;
00101 typedef OpenMesh::FaceHandle FaceHandle;
00102
00103
00104
00105
00106
00107
00108 ArrayKernelT() {}
00109 ~ArrayKernelT() { clear(); }
00110
00111
00112 void copy_topology_from(const ArrayKernelT& _other)
00113 {
00114
00115 vertices_ = _other.vertices_;
00116 edges_ = _other.edges_;
00117 faces_ = _other.faces_;
00118
00119
00120 resize(n_vertices(), n_edges(), n_faces());
00121 }
00122
00123
00124
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
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
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
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
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
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
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
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
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
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
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
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 {
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
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
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
00543 face(_fh).halfedge_handle_ = _heh;
00544 }
00545
00546 private:
00547
00548
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
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
00614 if (_v && n_vertices() > 0)
00615 {
00616 i0=0; i1=nV-1;
00617
00618 while (1)
00619 {
00620
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
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
00637 if (_e && n_edges() > 0)
00638 {
00639 i0=0; i1=nE-1;
00640
00641 while (1)
00642 {
00643
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
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
00664 if (_f && n_faces() > 0)
00665 {
00666 i0=0; i1=nF-1;
00667
00668 while (1)
00669 {
00670
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
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
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 (!is_isolated(vh))
00696 {
00697 set_halfedge_handle(vh, hh_map[halfedge_handle(vh).idx()]);
00698 }
00699 }
00700 }
00701
00702 HalfedgeHandle hh;
00703
00704 for (KernelEdgeIter e_it(edges_begin()); e_it != edges_end(); ++e_it)
00705 {
00706 hh = halfedge_handle(handle(*e_it), 0);
00707 set_vertex_handle(hh, vh_map[to_vertex_handle(hh).idx()]);
00708 hh = halfedge_handle(handle(*e_it), 1);
00709 set_vertex_handle(hh, vh_map[to_vertex_handle(hh).idx()]);
00710 }
00711 for (KernelEdgeIter e_it(edges_begin()); e_it != edges_end(); ++e_it)
00712 {
00713 hh = halfedge_handle(handle(*e_it), 0);
00714 set_next_halfedge_handle(hh, hh_map[next_halfedge_handle(hh).idx()]);
00715 if (!is_boundary(hh))
00716 {
00717 set_face_handle(hh, fh_map[face_handle(hh).idx()]);
00718 }
00719 hh = halfedge_handle(handle(*e_it), 1);
00720 set_next_halfedge_handle(hh, hh_map[next_halfedge_handle(hh).idx()]);
00721 if (!is_boundary(hh))
00722 {
00723 set_face_handle(hh, fh_map[face_handle(hh).idx()]);
00724 }
00725 }
00726
00727
00728
00729 if (_e)
00730 {
00731 KernelFaceIter f_it(faces_begin()), f_end(faces_end());
00732 FaceHandle fh;
00733
00734 for (; f_it!=f_end; ++f_it)
00735 {
00736 fh = handle(*f_it);
00737 set_halfedge_handle(fh, hh_map[halfedge_handle(fh).idx()]);
00738 }
00739 }
00740
00741 }
00742
00743
00744
00745 }
00746
00747 #endif // OPENMESH_ARRAY_KERNEL_HH defined
00748