Easy3D 2.6.1
Loading...
Searching...
No Matches
surface_mesh.h
1/********************************************************************
2 * Copyright (C) 2015-2021 by Liangliang Nan <liangliang.nan@gmail.com>
3 * Copyright (C) 2011-2013 by Graphics & Geometry Group, Bielefeld University
4 * Copyright (C) 2001-2005 by Computer Graphics Group, RWTH Aachen
5 *
6 * The code in this file is partly from Surface_mesh (v1.1) with
7 * modifications and enhancement:
8 * https://opensource.cit-ec.de/projects/surface_mesh
9 * The original code was distributed under the GNU GPL License.
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Library General Public License
13 * as published by the Free Software Foundation, version 2.
14 *
15 * This library is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU Library General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 ********************************************************************/
24
25#ifndef EASY3D_CORE_SURFACE_MESH_H
26#define EASY3D_CORE_SURFACE_MESH_H
27
28#include <easy3d/core/model.h>
29#include <easy3d/core/types.h>
30#include <easy3d/core/property.h>
31
32namespace easy3d {
33
50 class SurfaceMesh : public Model
51 {
52
53 public: //------------------------------------------------------ topology types
54
60 {
61 public:
66 explicit BaseHandle(int _idx=-1) : idx_(_idx) {}
67
72 int idx() const { return idx_; }
73
77 void reset() { idx_=-1; }
78
83 bool is_valid() const { return idx_ != -1; }
84
90 bool operator==(const BaseHandle& _rhs) const {
91 return idx_ == _rhs.idx_;
92 }
93
99 bool operator!=(const BaseHandle& _rhs) const {
100 return idx_ != _rhs.idx_;
101 }
102
108 bool operator<(const BaseHandle& _rhs) const {
109 return idx_ < _rhs.idx_;
110 }
111
115 struct Hash {
121 std::size_t operator()(const BaseHandle& h) const { return h.idx(); }
122 };
123
124 private:
125 friend class SurfaceMesh;
126 int idx_;
127 };
128
129
135 {
140 explicit Vertex(int _idx=-1) : BaseHandle(_idx) {}
146 std::ostream& operator<<(std::ostream& os) const { return os << 'v' << idx(); }
147 };
148
149
155 {
160 explicit Halfedge(int _idx=-1) : BaseHandle(_idx) {}
166 std::ostream& operator<<(std::ostream& os) const { return os << 'h' << idx(); }
167 };
168
169
173 {
178 explicit Edge(int _idx=-1) : BaseHandle(_idx) {}
184 std::ostream& operator<<(std::ostream& os) const { return os << 'e' << idx(); }
185 };
186
187
191 {
196 explicit Face(int _idx=-1) : BaseHandle(_idx) {}
202 std::ostream& operator<<(std::ostream& os) const { return os << 'f' << idx(); }
203 };
204
205
206 public: //-------------------------------------------------- connectivity types
207
217
218
234
235
245
246
247
248 public: //------------------------------------------------------ property types
249
254 template <class T> class VertexProperty : public Property<T>
255 {
256 public:
257
259 VertexProperty() = default;
264 explicit VertexProperty(Property<T> p) : Property<T>(p) {}
265
274
283 };
284
285
290 template <class T> class HalfedgeProperty : public Property<T>
291 {
292 public:
293
295 HalfedgeProperty() = default;
300 explicit HalfedgeProperty(Property<T> p) : Property<T>(p) {}
301
310
319 };
320
321
326 template <class T> class EdgeProperty : public Property<T>
327 {
328 public:
329
331 EdgeProperty() = default;
336 explicit EdgeProperty(Property<T> p) : Property<T>(p) {}
337
346
353 return Property<T>::operator[](e.idx());
354 }
355 };
356
357
362 template <class T> class FaceProperty : public Property<T>
363 {
364 public:
365
367 FaceProperty() = default;
372 explicit FaceProperty(Property<T> p) : Property<T>(p) {}
373
382
389 return Property<T>::operator[](f.idx());
390 }
391 };
392
393
398 template <class T> class ModelProperty : public Property<T>
399 {
400 public:
401
403 ModelProperty() = default;
408 explicit ModelProperty(Property<T> p) : Property<T>(p) {}
409
415 typename Property<T>::reference operator[](size_t idx) {
416 return Property<T>::operator[](idx);
417 }
418
424 typename Property<T>::const_reference operator[](size_t idx) const {
425 return Property<T>::operator[](idx);
426 }
427 };
428
429
430
431 public: //------------------------------------------------------ iterator types
432
439 {
440 public:
446 explicit VertexIterator(Vertex v=Vertex(), const SurfaceMesh* m=nullptr) : hnd_(v), mesh_(m) {
447 if (mesh_ && mesh_->has_garbage()) while (mesh_->is_valid(hnd_) && mesh_->is_deleted(hnd_)) ++hnd_.idx_;
448 }
449
454 Vertex operator*() const { return hnd_; }
455
461 bool operator==(const VertexIterator& rhs) const {
462 return (hnd_==rhs.hnd_);
463 }
464
470 bool operator!=(const VertexIterator& rhs) const {
471 return !operator==(rhs);
472 }
473
479 ++hnd_.idx_;
480 assert(mesh_);
481 while (mesh_->has_garbage() && mesh_->is_valid(hnd_) && mesh_->is_deleted(hnd_)) ++hnd_.idx_;
482 return *this;
483 }
484
490 --hnd_.idx_;
491 assert(mesh_);
492 while (mesh_->has_garbage() && mesh_->is_valid(hnd_) && mesh_->is_deleted(hnd_)) --hnd_.idx_;
493 return *this;
494 }
495
496 private:
497 Vertex hnd_;
498 const SurfaceMesh* mesh_;
499 };
500
501
508 {
509 public:
515 explicit HalfedgeIterator(Halfedge h=Halfedge(), const SurfaceMesh* m=nullptr) : hnd_(h), mesh_(m) {
516 if (mesh_ && mesh_->has_garbage()) while (mesh_->is_valid(hnd_) && mesh_->is_deleted(hnd_)) ++hnd_.idx_;
517 }
518
523 Halfedge operator*() const { return hnd_; }
524
530 bool operator==(const HalfedgeIterator& rhs) const {
531 return (hnd_==rhs.hnd_);
532 }
533
539 bool operator!=(const HalfedgeIterator& rhs) const {
540 return !operator==(rhs);
541 }
542
548 ++hnd_.idx_;
549 assert(mesh_);
550 while (mesh_->has_garbage() && mesh_->is_valid(hnd_) && mesh_->is_deleted(hnd_)) ++hnd_.idx_;
551 return *this;
552 }
553
559 --hnd_.idx_;
560 assert(mesh_);
561 while (mesh_->has_garbage() && mesh_->is_valid(hnd_) && mesh_->is_deleted(hnd_)) --hnd_.idx_;
562 return *this;
563 }
564
565 private:
566 Halfedge hnd_;
567 const SurfaceMesh* mesh_;
568 };
569
570
577 {
578 public:
584 explicit EdgeIterator(Edge e=Edge(), const SurfaceMesh* m=nullptr) : hnd_(e), mesh_(m) {
585 if (mesh_ && mesh_->has_garbage()) while (mesh_->is_valid(hnd_) && mesh_->is_deleted(hnd_)) ++hnd_.idx_;
586 }
587
592 Edge operator*() const { return hnd_; }
593
599 bool operator==(const EdgeIterator& rhs) const {
600 return (hnd_==rhs.hnd_);
601 }
602
608 bool operator!=(const EdgeIterator& rhs) const {
609 return !operator==(rhs);
610 }
611
617 ++hnd_.idx_;
618 assert(mesh_);
619 while (mesh_->has_garbage() && mesh_->is_valid(hnd_) && mesh_->is_deleted(hnd_)) ++hnd_.idx_;
620 return *this;
621 }
622
628 --hnd_.idx_;
629 assert(mesh_);
630 while (mesh_->has_garbage() && mesh_->is_valid(hnd_) && mesh_->is_deleted(hnd_)) --hnd_.idx_;
631 return *this;
632 }
633
634 private:
635 Edge hnd_;
636 const SurfaceMesh* mesh_;
637 };
638
639
646 {
647 public:
653 explicit FaceIterator(Face f=Face(), const SurfaceMesh* m=nullptr) : hnd_(f), mesh_(m) {
654 if (mesh_ && mesh_->has_garbage()) while (mesh_->is_valid(hnd_) && mesh_->is_deleted(hnd_)) ++hnd_.idx_;
655 }
656
661 Face operator*() const { return hnd_; }
662
668 bool operator==(const FaceIterator& rhs) const {
669 return (hnd_==rhs.hnd_);
670 }
671
677 bool operator!=(const FaceIterator& rhs) const {
678 return !operator==(rhs);
679 }
680
686 ++hnd_.idx_;
687 assert(mesh_);
688 while (mesh_->has_garbage() && mesh_->is_valid(hnd_) && mesh_->is_deleted(hnd_)) ++hnd_.idx_;
689 return *this;
690 }
691
697 --hnd_.idx_;
698 assert(mesh_);
699 while (mesh_->has_garbage() && mesh_->is_valid(hnd_) && mesh_->is_deleted(hnd_)) --hnd_.idx_;
700 return *this;
701 }
702
703 private:
704 Face hnd_;
705 const SurfaceMesh* mesh_;
706 };
707
708
709
710 public: //-------------------------- containers for C++11 range-based for loops
711
717 {
718 public:
724 VertexContainer(VertexIterator _begin, VertexIterator _end) : begin_(_begin), end_(_end) {}
729 VertexIterator begin() const { return begin_; }
734 VertexIterator end() const { return end_; }
735 private:
736 VertexIterator begin_, end_;
737 };
738
739
745 {
746 public:
752 HalfedgeContainer(HalfedgeIterator _begin, HalfedgeIterator _end) : begin_(_begin), end_(_end) {}
757 HalfedgeIterator begin() const { return begin_; }
762 HalfedgeIterator end() const { return end_; }
763 private:
764 HalfedgeIterator begin_, end_;
765 };
766
767
773 {
774 public:
780 EdgeContainer(EdgeIterator _begin, EdgeIterator _end) : begin_(_begin), end_(_end) {}
785 EdgeIterator begin() const { return begin_; }
790 EdgeIterator end() const { return end_; }
791 private:
792 EdgeIterator begin_, end_;
793 };
794
795
801 {
802 public:
808 FaceContainer(FaceIterator _begin, FaceIterator _end) : begin_(_begin), end_(_end) {}
813 FaceIterator begin() const { return begin_; }
818 FaceIterator end() const { return end_; }
819 private:
820 FaceIterator begin_, end_;
821 };
822
823
824
825 public: //---------------------------------------------------- circulator types
826
844 {
845 public:
851 explicit VertexAroundVertexCirculator(const SurfaceMesh* m = nullptr, Vertex v = Vertex())
852 : mesh_(m), active_(true)
853 {
854 if (mesh_) halfedge_ = mesh_->out_halfedge(v);
855 }
856
863 assert(mesh_);
864 return (active_ && (mesh_==rhs.mesh_) && (halfedge_==rhs.halfedge_));
865 }
866
873 return !operator==(rhs);
874 }
875
881 assert(mesh_);
882 halfedge_ = mesh_->prev_around_source(halfedge_);
883 active_ = true;
884 return *this;
885 }
886
892 assert(mesh_);
893 halfedge_ = mesh_->next_around_source(halfedge_);
894 return *this;
895 }
896
902 assert(mesh_);
903 return mesh_->target(halfedge_);
904 }
905
910 operator bool() const { return halfedge_.is_valid(); }
911
916 Halfedge halfedge() const { return halfedge_; }
917
922 VertexAroundVertexCirculator& begin() { active_=!halfedge_.is_valid(); return *this; }
927 VertexAroundVertexCirculator& end() { active_=true; return *this; }
928
929 private:
930 const SurfaceMesh* mesh_;
931 Halfedge halfedge_;
932 // helper for C++11 range-based for-loops
933 bool active_;
934 };
935
936
954 {
955 public:
962 : mesh_(m), active_(true)
963 {
964 if (mesh_) halfedge_ = mesh_->out_halfedge(v);
965 }
966
973 assert(mesh_);
974 return (active_ && (mesh_==rhs.mesh_) && (halfedge_==rhs.halfedge_));
975 }
976
983 return !operator==(rhs);
984 }
985
991 assert(mesh_);
992 halfedge_ = mesh_->prev_around_source(halfedge_);
993 active_ = true;
994 return *this;
995 }
996
1002 assert(mesh_);
1003 halfedge_ = mesh_->next_around_source(halfedge_);
1004 return *this;
1005 }
1006
1011 Halfedge operator*() const { return halfedge_; }
1012
1017 operator bool() const { return halfedge_.is_valid(); }
1018
1023 HalfedgeAroundVertexCirculator& begin() { active_=!halfedge_.is_valid(); return *this; }
1028 HalfedgeAroundVertexCirculator& end() { active_=true; return *this; }
1029
1030 private:
1031 const SurfaceMesh* mesh_;
1032 Halfedge halfedge_;
1033 // helper for C++11 range-based for-loops
1034 bool active_;
1035 };
1036
1037
1055 {
1056 public:
1062 explicit FaceAroundVertexCirculator(const SurfaceMesh* m=nullptr, Vertex v=Vertex())
1063 : mesh_(m), active_(true)
1064 {
1065 if (mesh_) {
1066 halfedge_ = mesh_->out_halfedge(v);
1067 if (halfedge_.is_valid() && mesh_->is_border(halfedge_))
1068 operator++();
1069 }
1070 }
1071
1078 assert(mesh_);
1079 return (active_ && (mesh_==rhs.mesh_) && (halfedge_==rhs.halfedge_));
1080 }
1081
1088 return !operator==(rhs);
1089 }
1090
1096 assert(mesh_ && halfedge_.is_valid());
1097 do {
1098 halfedge_ = mesh_->prev_around_source(halfedge_);
1099 } while (mesh_->is_border(halfedge_));
1100 active_ = true;
1101 return *this;
1102 }
1103
1109 assert(mesh_ && halfedge_.is_valid());
1110 do
1111 halfedge_ = mesh_->next_around_source(halfedge_);
1112 while (mesh_->is_border(halfedge_));
1113 return *this;
1114 }
1115
1120 Face operator*() const {
1121 assert(mesh_ && halfedge_.is_valid());
1122 return mesh_->face(halfedge_);
1123 }
1124
1129 operator bool() const { return halfedge_.is_valid(); }
1130
1135 FaceAroundVertexCirculator& begin() { active_=!halfedge_.is_valid(); return *this; }
1140 FaceAroundVertexCirculator& end() { active_=true; return *this; }
1141
1142 private:
1143 const SurfaceMesh* mesh_;
1144 Halfedge halfedge_;
1145 // helper for C++11 range-based for-loops
1146 bool active_;
1147 };
1148
1149
1167 {
1168 public:
1174 explicit VertexAroundFaceCirculator(const SurfaceMesh* m=nullptr, Face f=Face())
1175 : mesh_(m), active_(true)
1176 {
1177 if (mesh_) halfedge_ = mesh_->halfedge(f);
1178 }
1179
1186 assert(mesh_);
1187 return (active_ && (mesh_==rhs.mesh_) && (halfedge_==rhs.halfedge_));
1188 }
1189
1196 return !operator==(rhs);
1197 }
1198
1204 assert(mesh_ && halfedge_.is_valid());
1205 halfedge_ = mesh_->next(halfedge_);
1206 active_ = true;
1207 return *this;
1208 }
1209
1215 assert(mesh_ && halfedge_.is_valid());
1216 halfedge_ = mesh_->prev(halfedge_);
1217 return *this;
1218 }
1219
1225 assert(mesh_ && halfedge_.is_valid());
1226 return mesh_->target(halfedge_);
1227 }
1228
1233 VertexAroundFaceCirculator& begin() { active_=false; return *this; }
1238 VertexAroundFaceCirculator& end() { active_=true; return *this; }
1239
1240 private:
1241 const SurfaceMesh* mesh_;
1242 Halfedge halfedge_;
1243 // helper for C++11 range-based for-loops
1244 bool active_;
1245 };
1246
1247
1265 {
1266 public:
1272 explicit HalfedgeAroundFaceCirculator(const SurfaceMesh* m=nullptr, Face f=Face())
1273 : mesh_(m), active_(true)
1274 {
1275 if (mesh_) halfedge_ = mesh_->halfedge(f);
1276 }
1277
1284 assert(mesh_);
1285 return (active_ && (mesh_==rhs.mesh_) && (halfedge_==rhs.halfedge_));
1286 }
1287
1294 return !operator==(rhs);
1295 }
1296
1302 assert(mesh_ && halfedge_.is_valid());
1303 halfedge_ = mesh_->next(halfedge_);
1304 active_ = true;
1305 return *this;
1306 }
1307
1313 assert(mesh_ && halfedge_.is_valid());
1314 halfedge_ = mesh_->prev(halfedge_);
1315 return *this;
1316 }
1317
1322 Halfedge operator*() const { return halfedge_; }
1323
1328 HalfedgeAroundFaceCirculator& begin() { active_=false; return *this; }
1333 HalfedgeAroundFaceCirculator& end() { active_=true; return *this; }
1334
1335 private:
1336 const SurfaceMesh* mesh_;
1337 Halfedge halfedge_;
1338 // helper for C++11 range-based for-loops
1339 bool active_;
1340 };
1341
1342
1343
1344 public: //-------------------------------------------- constructor / destructor
1345
1347
1348
1352 SurfaceMesh();
1353
1355 ~SurfaceMesh() override = default;
1356
1358 SurfaceMesh(const SurfaceMesh& rhs) { operator=(rhs); }
1359
1361 SurfaceMesh& operator=(const SurfaceMesh& rhs);
1362
1369 SurfaceMesh& operator+=(const SurfaceMesh& other) { join(other); return *this; }
1370
1377 SurfaceMesh& join(const SurfaceMesh& other);
1378
1380 SurfaceMesh& assign(const SurfaceMesh& rhs);
1382
1385
1389 bool read(const std::string& filename);
1390
1394 bool write(const std::string& filename) const;
1396
1397 public: //----------------------------------------------- add new vertex / face
1398
1400
1401
1407 Vertex add_vertex(const vec3& p) { Vertex v = new_vertex(); vpoint_[v] = p; return v; }
1408
1415 Face add_face(const std::vector<Vertex>& vertices);
1416
1420 Face add_triangle(Vertex v1, Vertex v2, Vertex v3);
1421
1425 Face add_quad(Vertex v1, Vertex v2, Vertex v3, Vertex v4);
1426
1428
1429
1430 public: //--------------------------------------------------- memory management
1431
1433
1434
1436 unsigned int vertices_size() const { return (unsigned int) vprops_.size(); }
1438 unsigned int halfedges_size() const { return (unsigned int) hprops_.size(); }
1440 unsigned int edges_size() const { return (unsigned int) eprops_.size(); }
1442 unsigned int faces_size() const { return (unsigned int) fprops_.size(); }
1443
1444
1446 unsigned int n_vertices() const { return vertices_size() - deleted_vertices_; }
1448 unsigned int n_halfedges() const { return halfedges_size() - 2*deleted_edges_; }
1450 unsigned int n_edges() const { return edges_size() - deleted_edges_; }
1452 unsigned int n_faces() const { return faces_size() - deleted_faces_; }
1453
1459 void clear();
1460
1467 void reserve(unsigned int n_vertices, unsigned int n_edges, unsigned int n_faces);
1468
1472 void resize(unsigned int nv, unsigned int ne, unsigned int nf) {
1473 vprops_.resize(nv);
1474 hprops_.resize(2 * ne);
1475 eprops_.resize(ne);
1476 fprops_.resize(nf);
1477 }
1478
1480 bool has_garbage() const { return garbage_; }
1481
1483 void collect_garbage();
1484
1485
1488 bool is_deleted(Vertex v) const {
1489 return vdeleted_[v];
1490 }
1491
1493 bool is_deleted(Halfedge h) const {
1494 return edeleted_[edge(h)];
1495 }
1496
1498 bool is_deleted(Edge e) const {
1499 return edeleted_[e];
1500 }
1501
1503 bool is_deleted(Face f) const {
1504 return fdeleted_[f];
1505 }
1506
1507
1509 bool is_valid(Vertex v) const {
1510 return (0 <= v.idx()) && (v.idx() < (int)vertices_size());
1511 }
1512
1513 bool is_valid(Halfedge h) const {
1514 return (0 <= h.idx()) && (h.idx() < (int)halfedges_size());
1515 }
1516
1517 bool is_valid(Edge e) const {
1518 return (0 <= e.idx()) && (e.idx() < (int)edges_size());
1519 }
1520
1521 bool is_valid(Face f) const {
1522 return (0 <= f.idx()) && (f.idx() < (int)faces_size());
1523 }
1524
1526
1527
1528
1529 public: //---------------------------------------------- low-level connectivity
1530
1532
1533
1537 return vconn_[v].halfedge_;
1538 }
1539
1542 vconn_[v].halfedge_ = h;
1543 }
1544
1546 bool is_border(Vertex v) const {
1547 Halfedge h(out_halfedge(v));
1548 return (!(h.is_valid() && face(h).is_valid()));
1549 }
1550
1552 bool is_isolated(Vertex v) const {
1553 return !out_halfedge(v).is_valid();
1554 }
1555
1557 bool is_manifold(Vertex v) const
1558 {
1559 // [Liangliang: I doubt. It should also check if more than 1 cones meet at the same vertex.
1560 // See the "resolve_non_manifold_vertices()" in manifold_builder.cpp
1561
1562 // The vertex is non-manifold if more than one gap exists, i.e.
1563 // more than one outgoing boundary halfedge.
1564 int n(0);
1565 HalfedgeAroundVertexCirculator hit = halfedges(v), hend=hit;
1566 if (hit) do
1567 {
1568 if (is_border(*hit))
1569 ++n;
1570 }
1571 while (++hit!=hend);
1572 return n<2;
1573 }
1574
1576 bool is_degenerate(Face f) const;
1577
1580 return hconn_[h].vertex_;
1581 }
1582
1585 return target(opposite(h));
1586 }
1587
1590 hconn_[h].vertex_ = v;
1591 }
1592
1594 Face face(Halfedge h) const {
1595 return hconn_[h].face_;
1596 }
1597
1600 hconn_[h].face_ = f;
1601 }
1602
1605 return hconn_[h].next_;
1606 }
1607
1610 hconn_[h].next_ = nh;
1611 hconn_[nh].prev_ = h;
1612 }
1613
1616 return hconn_[h].prev_;
1617 }
1618
1621 return Halfedge((h.idx() & 1) ? h.idx()-1 : h.idx()+1);
1622 }
1623
1627 return opposite(prev(h));
1628 }
1629
1633 return next(opposite(h));
1634 }
1635
1639 return prev(opposite(h));
1640 }
1641
1645 return opposite(next(h));
1646 }
1647
1649 Edge edge(Halfedge h) const {
1650 return Edge(h.idx() >> 1);
1651 }
1652
1654 bool is_border(Halfedge h) const {
1655 return !face(h).is_valid();
1656 }
1657
1658
1660 Halfedge halfedge(Edge e, unsigned int i) const {
1661 assert(i<=1);
1662 return Halfedge(static_cast<int>((e.idx() << 1) + i));
1663 }
1664
1666 Vertex vertex(Edge e, unsigned int i) const {
1667 assert(i<=1);
1668 return target(halfedge(e, i));
1669 }
1670
1672 Face face(Edge e, unsigned int i) const {
1673 assert(i<=1);
1674 return face(halfedge(e, i));
1675 }
1676
1679 bool is_border(Edge e) const {
1680 return (is_border(halfedge(e, 0)) || is_border(halfedge(e, 1)));
1681 }
1682
1685 return fconn_[f].halfedge_;
1686 }
1687
1690 fconn_[f].halfedge_ = h;
1691 }
1692
1694 bool is_border(Face f) const
1695 {
1696 Halfedge h = halfedge(f);
1697 Halfedge hh = h;
1698 do
1699 {
1700 if (is_border(opposite(h)))
1701 return true;
1702 h = next(h);
1703 }
1704 while (h != hh);
1705 return false;
1706 }
1707
1709
1710
1711
1712 public: //--------------------------------------------------- property handling
1713
1715
1716
1725 template <class T> VertexProperty<T> add_vertex_property(const std::string& name, const T t=T()) {
1726 return VertexProperty<T>(vprops_.add<T>(name, t));
1727 }
1728
1736 template <class T> HalfedgeProperty<T> add_halfedge_property(const std::string& name, const T t=T()) {
1737 return HalfedgeProperty<T>(hprops_.add<T>(name, t));
1738 }
1739
1747 template <class T> EdgeProperty<T> add_edge_property(const std::string& name, const T t=T()) {
1748 return EdgeProperty<T>(eprops_.add<T>(name, t));
1749 }
1750
1758 template <class T> FaceProperty<T> add_face_property(const std::string& name, const T t=T()) {
1759 return FaceProperty<T>(fprops_.add<T>(name, t));
1760 }
1761
1773 template <class T> ModelProperty<T> add_model_property(const std::string& name, const T t=T()) {
1774 return ModelProperty<T>(mprops_.add<T>(name, t));
1775 }
1776
1777
1784 template <class T> VertexProperty<T> get_vertex_property(const std::string& name) const {
1785 return VertexProperty<T>(vprops_.get<T>(name));
1786 }
1787
1793 template <class T> HalfedgeProperty<T> get_halfedge_property(const std::string& name) const {
1794 return HalfedgeProperty<T>(hprops_.get<T>(name));
1795 }
1796
1802 template <class T> EdgeProperty<T> get_edge_property(const std::string& name) const {
1803 return EdgeProperty<T>(eprops_.get<T>(name));
1804 }
1805
1811 template <class T> FaceProperty<T> get_face_property(const std::string& name) const {
1812 return FaceProperty<T>(fprops_.get<T>(name));
1813 }
1814
1825 template <class T> ModelProperty<T> get_model_property(const std::string& name) const {
1826 return ModelProperty<T>(mprops_.get<T>(name));
1827 }
1828
1837 template <class T> VertexProperty<T> vertex_property(const std::string& name, const T t=T()) {
1838 return VertexProperty<T>(vprops_.get_or_add<T>(name, t));
1839 }
1840
1848 template <class T> HalfedgeProperty<T> halfedge_property(const std::string& name, const T t=T()) {
1849 return HalfedgeProperty<T>(hprops_.get_or_add<T>(name, t));
1850 }
1851
1859 template <class T> EdgeProperty<T> edge_property(const std::string& name, const T t=T()) {
1860 return EdgeProperty<T>(eprops_.get_or_add<T>(name, t));
1861 }
1862
1870 template <class T> FaceProperty<T> face_property(const std::string& name, const T t=T()) {
1871 return FaceProperty<T>(fprops_.get_or_add<T>(name, t));
1872 }
1873
1882 template <class T> ModelProperty<T> model_property(const std::string& name, const T t=T()) {
1883 return ModelProperty<T>(mprops_.get_or_add<T>(name, t));
1884 }
1885
1886
1892 template<class T>
1893 bool remove_vertex_property(VertexProperty<T> &p) { return vprops_.remove(p); }
1894
1900 bool remove_vertex_property(const std::string &n) { return vprops_.remove(n); }
1901
1907 template<class T>
1908 bool remove_halfedge_property(HalfedgeProperty<T> &p) { return hprops_.remove(p); }
1909
1915 bool remove_halfedge_property(const std::string &n) { return hprops_.remove(n); }
1916
1922 template<class T>
1923 bool remove_edge_property(EdgeProperty<T> &p) { return eprops_.remove(p); }
1924
1930 bool remove_edge_property(const std::string &n) { return eprops_.remove(n); }
1931
1937 template<class T>
1938 bool remove_face_property(FaceProperty<T> &p) { return fprops_.remove(p); }
1939
1945 bool remove_face_property(const std::string &n) { return fprops_.remove(n); }
1946
1952 template<class T>
1953 bool remove_model_property(ModelProperty<T> &p) { return mprops_.remove(p); }
1954
1960 bool remove_model_property(const std::string &n) { return mprops_.remove(n); }
1961
1968 bool rename_vertex_property(const std::string &old_name, const std::string &new_name) {
1969 return vprops_.rename(old_name, new_name);
1970 }
1971
1978 bool rename_face_property(const std::string &old_name, const std::string &new_name) {
1979 return fprops_.rename(old_name, new_name);
1980 }
1981
1988 bool rename_edge_property(const std::string &old_name, const std::string &new_name) {
1989 return eprops_.rename(old_name, new_name);
1990 }
1991
1998 bool rename_halfedge_property(const std::string &old_name, const std::string &new_name) {
1999 return hprops_.rename(old_name, new_name);
2000 }
2001
2008 bool rename_model_property(const std::string &old_name, const std::string &new_name) {
2009 return mprops_.rename(old_name, new_name);
2010 }
2011
2012
2018 const std::type_info& get_vertex_property_type(const std::string& name) const {
2019 return vprops_.get_type(name);
2020 }
2021
2026 const std::type_info& get_halfedge_property_type(const std::string& name) const {
2027 return hprops_.get_type(name);
2028 }
2029
2034 const std::type_info& get_edge_property_type(const std::string& name) const {
2035 return eprops_.get_type(name);
2036 }
2037
2042 const std::type_info& get_face_property_type(const std::string& name) const {
2043 return fprops_.get_type(name);
2044 }
2045
2050 const std::type_info& get_model_property_type(const std::string& name) const {
2051 return mprops_.get_type(name);
2052 }
2053
2054
2059 std::vector<std::string> vertex_properties() const {
2060 return vprops_.properties();
2061 }
2062
2066 std::vector<std::string> halfedge_properties() const {
2067 return hprops_.properties();
2068 }
2069
2073 std::vector<std::string> edge_properties() const {
2074 return eprops_.properties();
2075 }
2076
2080 std::vector<std::string> face_properties() const {
2081 return fprops_.properties();
2082 }
2083
2087 std::vector<std::string> model_properties() const {
2088 return mprops_.properties();
2089 }
2090
2095 void property_stats(std::ostream &output) const override;
2096
2098
2099
2100 public: //--------------------------------------------- iterators & circulators
2101
2103
2104
2110 return VertexIterator(Vertex(0), this);
2111 }
2112
2118 return VertexIterator(Vertex(static_cast<int>(vertices_size())), this);
2119 }
2120
2128
2134 return HalfedgeIterator(Halfedge(0), this);
2135 }
2136
2142 return HalfedgeIterator(Halfedge(static_cast<int>(halfedges_size())), this);
2143 }
2144
2152
2158 return EdgeIterator(Edge(0), this);
2159 }
2160
2166 return EdgeIterator(Edge(static_cast<int>(edges_size())), this);
2167 }
2168
2174 return EdgeContainer(edges_begin(), edges_end());
2175 }
2176
2182 return FaceIterator(Face(0), this);
2183 }
2184
2190 return FaceIterator(Face(static_cast<int>(faces_size())), this);
2191 }
2192
2198 return FaceContainer(faces_begin(), faces_end());
2199 }
2200
2209
2218
2227
2236
2245
2247
2248
2249 public: //--------------------------------------------- higher-level operations
2250
2252
2253
2255 bool is_closed() const;
2256
2260 bool is_triangle_mesh() const;
2261
2264 bool is_quad_mesh() const;
2265
2268 void triangulate();
2269
2272 void triangulate(Face f);
2273
2277 void reverse_orientation();
2278
2281 bool is_collapse_ok(Halfedge h) const;
2282
2293 void collapse(Halfedge h);
2294
2295
2301 Vertex split(Face f, const vec3& p) { Vertex v=add_vertex(p); split(f,v); return v; }
2302
2307 void split(Face f, Vertex v);
2308
2309
2318 Halfedge split(Edge e, const vec3& p) { return split(e, add_vertex(p)); }
2319
2320
2329 Halfedge split(Edge e, Vertex v);
2330
2331
2341 {
2342 return insert_vertex(halfedge(e,0), add_vertex(p));
2343 }
2344
2353 {
2354 return insert_vertex(halfedge(e,0), v);
2355 }
2356
2364 Halfedge insert_vertex(Halfedge h, Vertex v);
2365
2373 bool join_edges(Vertex v);
2378 bool can_join_edges(Vertex v) const;
2379
2380
2384 Halfedge insert_edge(Halfedge h0, Halfedge h1);
2385
2386
2392 bool is_flip_ok(Edge e) const;
2393
2399 void flip(Edge e);
2400
2401
2406 bool is_stitch_ok(Halfedge h0, Halfedge h1);
2407
2414 void stitch(Halfedge h0, Halfedge h1);
2415
2416
2419 unsigned int valence(Vertex v) const;
2420
2422 unsigned int valence(Face f) const;
2423
2425 Halfedge find_halfedge(Vertex start, Vertex end) const;
2426
2428 Edge find_edge(Vertex a, Vertex b) const;
2429
2433 void delete_vertex(Vertex v);
2434
2438 void delete_edge(Edge e);
2439
2443 void delete_face(Face f);
2444
2446
2447
2448 public: //------------------------------------------ geometry-related functions
2449
2451
2452
2458 const vec3& position(Vertex v) const { return vpoint_[v]; }
2459
2465 vec3& position(Vertex v) { return vpoint_[v]; }
2466
2471 const std::vector<vec3>& points() const override { return vpoint_.vector(); }
2472
2477 std::vector<vec3>& points() override { return vpoint_.vector(); }
2478
2480 void update_face_normals();
2481
2487 vec3 compute_face_normal(Face f) const;
2488
2490 void update_vertex_normals();
2491
2494 vec3 compute_vertex_normal(Vertex v) const;
2495
2497 float edge_length(Edge e) const;
2499 float edge_length(Halfedge h) const;
2500
2502
2503
2504 private: //---------------------------------------------- allocate new elements
2505
2507 Vertex new_vertex()
2508 {
2509 vprops_.push_back();
2510 return Vertex(static_cast<int>(vertices_size()-1));
2511 }
2512
2514 Halfedge new_edge(Vertex start, Vertex end)
2515 {
2516 assert(start != end);
2517
2518 eprops_.push_back();
2519 hprops_.push_back();
2520 hprops_.push_back();
2521
2522 Halfedge h0(static_cast<int>(halfedges_size()-2));
2523 Halfedge h1(static_cast<int>(halfedges_size()-1));
2524
2525 set_target(h0, end);
2526 set_target(h1, start);
2527
2528 return h0;
2529 }
2530
2532 Face new_face()
2533 {
2534 fprops_.push_back();
2535 return Face(static_cast<int>(faces_size()-1));
2536 }
2537
2538
2539 private: //--------------------------------------------------- helper functions
2540
2547 void adjust_outgoing_halfedges();
2548
2551 void adjust_outgoing_halfedge(Vertex v);
2552
2554 void remove_edge(Halfedge h);
2555
2557 void remove_loop(Halfedge h);
2558
2561 bool can_merge_vertices(Halfedge h0, Halfedge h1) const;
2562
2563 private: //------------------------------------------------------- private data
2564
2565 PropertyContainer vprops_;
2566 PropertyContainer hprops_;
2567 PropertyContainer eprops_;
2568 PropertyContainer fprops_;
2569 PropertyContainer mprops_;
2570
2574
2575 VertexProperty<bool> vdeleted_;
2576 EdgeProperty<bool> edeleted_;
2577 FaceProperty<bool> fdeleted_;
2578
2579 VertexProperty<vec3> vpoint_;
2580 VertexProperty<vec3> vnormal_;
2581 FaceProperty<vec3> fnormal_;
2582
2583 unsigned int deleted_vertices_;
2584 unsigned int deleted_edges_;
2585 unsigned int deleted_faces_;
2586 bool garbage_;
2587
2588 // helper data for add_face()
2589 typedef std::pair<Halfedge, Halfedge> NextCacheEntry;
2590 typedef std::vector<NextCacheEntry> NextCache;
2591 std::vector<Vertex> add_face_vertices_;
2592 std::vector<Halfedge> add_face_halfedges_;
2593 std::vector<bool> add_face_is_new_;
2594 std::vector<bool> add_face_needs_adjust_;
2595 NextCache add_face_next_cache_;
2596
2597 friend class SurfaceMeshBuilder;
2598 };
2599
2600
2601 //------------------------------------------------------------ output operators
2602
2604 inline std::ostream& operator<<(std::ostream& os, SurfaceMesh::Vertex v)
2605 {
2606 return (os << 'v' << v.idx());
2607 }
2608
2610 inline std::ostream& operator<<(std::ostream& os, SurfaceMesh::Halfedge h)
2611 {
2612 return (os << 'h' << h.idx());
2613 }
2614
2616 inline std::ostream& operator<<(std::ostream& os, SurfaceMesh::Edge e)
2617 {
2618 return (os << 'e' << e.idx());
2619 }
2620
2622 inline std::ostream& operator<<(std::ostream& os, SurfaceMesh::Face f)
2623 {
2624 return (os << 'f' << f.idx());
2625 }
2626
2627} // namespace easy3d
2628
2629#endif // EASY3D_CORE_SURFACE_MESH_H
const std::string & name() const
The name of a model.
Definition model.h:61
Model(const std::string &name="unknown")
Default constructor. The parameter name is optional, but it is useful for handling multiple models wi...
Definition model.cpp:33
void push_back()
Adds a new element to each vector.
Definition property.h:771
PropertyArray< T >::const_reference const_reference
The const reference type of the property.
Definition property.h:329
virtual reference operator[](size_t i)
Accesses the i-th element.
Definition property.h:365
Property(PropertyArray< T > *p=nullptr)
Constructor.
Definition property.h:338
PropertyArray< T >::reference reference
The reference type of the property.
Definition property.h:328
bool operator!=(const BaseHandle &_rhs) const
Inequality operator.
Definition surface_mesh.h:99
bool is_valid() const
Return whether the handle is valid, i.e., the index is not equal to -1.
Definition surface_mesh.h:83
int idx() const
Get the underlying index of this handle.
Definition surface_mesh.h:72
bool operator<(const BaseHandle &_rhs) const
Compare operator useful for sorting handles.
Definition surface_mesh.h:108
bool operator==(const BaseHandle &_rhs) const
Equality operator.
Definition surface_mesh.h:90
void reset()
Reset handle to be invalid (index=-1).
Definition surface_mesh.h:77
BaseHandle(int _idx=-1)
Constructor.
Definition surface_mesh.h:66
This helper class is a container for iterating through all edges using C++11 range-based for-loops.
Definition surface_mesh.h:773
EdgeIterator begin() const
Get the beginning iterator.
Definition surface_mesh.h:785
EdgeIterator end() const
Get the ending iterator.
Definition surface_mesh.h:790
EdgeContainer(EdgeIterator _begin, EdgeIterator _end)
Constructor.
Definition surface_mesh.h:780
This class iterates linearly over all edges.
Definition surface_mesh.h:577
bool operator!=(const EdgeIterator &rhs) const
Inequality operator.
Definition surface_mesh.h:608
EdgeIterator & operator++()
Pre-increment iterator.
Definition surface_mesh.h:616
Edge operator*() const
Get the edge the iterator refers to.
Definition surface_mesh.h:592
bool operator==(const EdgeIterator &rhs) const
Equality operator.
Definition surface_mesh.h:599
EdgeIterator(Edge e=Edge(), const SurfaceMesh *m=nullptr)
Default constructor.
Definition surface_mesh.h:584
EdgeIterator & operator--()
Pre-decrement iterator.
Definition surface_mesh.h:627
Edge property of type T.
Definition surface_mesh.h:327
EdgeProperty()=default
default constructor
Property< T >::reference operator[](Edge e)
Access the data stored for edge e.
Definition surface_mesh.h:343
Property< T >::const_reference operator[](Edge e) const
Access the data stored for edge e.
Definition surface_mesh.h:352
EdgeProperty(Property< T > p)
Constructor with property.
Definition surface_mesh.h:336
bool operator!=(const FaceAroundVertexCirculator &rhs) const
Inequality operator.
Definition surface_mesh.h:1087
bool operator==(const FaceAroundVertexCirculator &rhs) const
Equality operator.
Definition surface_mesh.h:1077
FaceAroundVertexCirculator & operator++()
Pre-increment operator (rotate counter-clockwise).
Definition surface_mesh.h:1095
FaceAroundVertexCirculator & begin()
Helper for C++11 range-based for-loops.
Definition surface_mesh.h:1135
Face operator*() const
Get the face the circulator refers to.
Definition surface_mesh.h:1120
FaceAroundVertexCirculator & end()
Helper for C++11 range-based for-loops.
Definition surface_mesh.h:1140
FaceAroundVertexCirculator(const SurfaceMesh *m=nullptr, Vertex v=Vertex())
Default constructor.
Definition surface_mesh.h:1062
FaceAroundVertexCirculator & operator--()
Pre-decrement operator (rotate clockwise).
Definition surface_mesh.h:1108
This helper class is a container for iterating through all faces using C++11 range-based for-loops.
Definition surface_mesh.h:801
FaceContainer(FaceIterator _begin, FaceIterator _end)
Constructor.
Definition surface_mesh.h:808
FaceIterator begin() const
Get the beginning iterator.
Definition surface_mesh.h:813
FaceIterator end() const
Get the ending iterator.
Definition surface_mesh.h:818
This class iterates linearly over all faces.
Definition surface_mesh.h:646
bool operator!=(const FaceIterator &rhs) const
Inequality operator.
Definition surface_mesh.h:677
bool operator==(const FaceIterator &rhs) const
Equality operator.
Definition surface_mesh.h:668
FaceIterator & operator--()
Pre-decrement iterator.
Definition surface_mesh.h:696
FaceIterator(Face f=Face(), const SurfaceMesh *m=nullptr)
Default constructor.
Definition surface_mesh.h:653
Face operator*() const
Get the face the iterator refers to.
Definition surface_mesh.h:661
FaceIterator & operator++()
Pre-increment iterator.
Definition surface_mesh.h:685
Face property of type T.
Definition surface_mesh.h:363
Property< T >::reference operator[](Face f)
Access the data stored for face f.
Definition surface_mesh.h:379
FaceProperty(Property< T > p)
Constructor with property.
Definition surface_mesh.h:372
FaceProperty()=default
default constructor
Property< T >::const_reference operator[](Face f) const
Access the data stored for face f.
Definition surface_mesh.h:388
Halfedge operator*() const
Get the halfedge the circulator refers to.
Definition surface_mesh.h:1322
HalfedgeAroundFaceCirculator & operator--()
Pre-decrement operator (rotate clockwise).
Definition surface_mesh.h:1312
bool operator==(const HalfedgeAroundFaceCirculator &rhs) const
Equality operator.
Definition surface_mesh.h:1283
bool operator!=(const HalfedgeAroundFaceCirculator &rhs) const
Inequality operator.
Definition surface_mesh.h:1293
HalfedgeAroundFaceCirculator & end()
Helper for C++11 range-based for-loops.
Definition surface_mesh.h:1333
HalfedgeAroundFaceCirculator(const SurfaceMesh *m=nullptr, Face f=Face())
Default constructor.
Definition surface_mesh.h:1272
HalfedgeAroundFaceCirculator & begin()
Helper for C++11 range-based for-loops.
Definition surface_mesh.h:1328
HalfedgeAroundFaceCirculator & operator++()
Pre-increment operator (rotate counter-clockwise).
Definition surface_mesh.h:1301
HalfedgeAroundVertexCirculator & end()
Helper for C++11 range-based for-loops.
Definition surface_mesh.h:1028
bool operator==(const HalfedgeAroundVertexCirculator &rhs) const
Equality operator.
Definition surface_mesh.h:972
Halfedge operator*() const
Get the halfedge the circulator refers to.
Definition surface_mesh.h:1011
HalfedgeAroundVertexCirculator & begin()
Helper for C++11 range-based for-loops.
Definition surface_mesh.h:1023
HalfedgeAroundVertexCirculator & operator++()
Pre-increment operator (rotate counter-clockwise).
Definition surface_mesh.h:990
bool operator!=(const HalfedgeAroundVertexCirculator &rhs) const
Inequality operator.
Definition surface_mesh.h:982
HalfedgeAroundVertexCirculator & operator--()
Pre-decrement operator (rotate clockwise).
Definition surface_mesh.h:1001
HalfedgeAroundVertexCirculator(const SurfaceMesh *m=nullptr, Vertex v=Vertex())
Default constructor.
Definition surface_mesh.h:961
This helper class is a container for iterating through all halfedges using C++11 range-based for-loop...
Definition surface_mesh.h:745
HalfedgeIterator begin() const
Get the beginning iterator.
Definition surface_mesh.h:757
HalfedgeContainer(HalfedgeIterator _begin, HalfedgeIterator _end)
Constructor.
Definition surface_mesh.h:752
HalfedgeIterator end() const
Get the beginning iterator.
Definition surface_mesh.h:762
This class iterates linearly over all halfedges.
Definition surface_mesh.h:508
HalfedgeIterator & operator--()
Pre-decrement iterator.
Definition surface_mesh.h:558
Halfedge operator*() const
Get the halfedge the iterator refers to.
Definition surface_mesh.h:523
HalfedgeIterator(Halfedge h=Halfedge(), const SurfaceMesh *m=nullptr)
Default constructor.
Definition surface_mesh.h:515
HalfedgeIterator & operator++()
Pre-increment iterator.
Definition surface_mesh.h:547
bool operator==(const HalfedgeIterator &rhs) const
Equality operator.
Definition surface_mesh.h:530
bool operator!=(const HalfedgeIterator &rhs) const
Inequality operator.
Definition surface_mesh.h:539
Halfedge property of type T.
Definition surface_mesh.h:291
HalfedgeProperty(Property< T > p)
Constructor with property.
Definition surface_mesh.h:300
Property< T >::reference operator[](Halfedge h)
Access the data stored for halfedge h.
Definition surface_mesh.h:307
Property< T >::const_reference operator[](Halfedge h) const
Access the data stored for halfedge h.
Definition surface_mesh.h:316
HalfedgeProperty()=default
default constructor
Mesh property of type T.
Definition surface_mesh.h:399
ModelProperty()=default
default constructor
ModelProperty(Property< T > p)
Constructor with property.
Definition surface_mesh.h:408
Property< T >::const_reference operator[](size_t idx) const
Access the data stored for the mesh.
Definition surface_mesh.h:424
Property< T >::reference operator[](size_t idx)
Access the data stored for the mesh.
Definition surface_mesh.h:415
VertexAroundFaceCirculator & end()
Helper for C++11 range-based for-loops.
Definition surface_mesh.h:1238
VertexAroundFaceCirculator(const SurfaceMesh *m=nullptr, Face f=Face())
Default constructor.
Definition surface_mesh.h:1174
bool operator!=(const VertexAroundFaceCirculator &rhs) const
Inequality operator.
Definition surface_mesh.h:1195
Vertex operator*() const
Get the vertex the circulator refers to.
Definition surface_mesh.h:1224
bool operator==(const VertexAroundFaceCirculator &rhs) const
Equality operator.
Definition surface_mesh.h:1185
VertexAroundFaceCirculator & operator--()
Pre-decrement operator (rotate clockwise).
Definition surface_mesh.h:1214
VertexAroundFaceCirculator & begin()
Helper for C++11 range-based for-loops.
Definition surface_mesh.h:1233
VertexAroundFaceCirculator & operator++()
Pre-increment operator (rotate counter-clockwise).
Definition surface_mesh.h:1203
bool operator!=(const VertexAroundVertexCirculator &rhs) const
Inequality operator.
Definition surface_mesh.h:872
VertexAroundVertexCirculator & operator++()
Pre-increment operator (rotate counter-clockwise).
Definition surface_mesh.h:880
VertexAroundVertexCirculator & begin()
Helper for C++11 range-based for-loops.
Definition surface_mesh.h:922
Vertex operator*() const
Get the vertex the circulator refers to.
Definition surface_mesh.h:901
VertexAroundVertexCirculator(const SurfaceMesh *m=nullptr, Vertex v=Vertex())
Default constructor.
Definition surface_mesh.h:851
bool operator==(const VertexAroundVertexCirculator &rhs) const
Equality operator.
Definition surface_mesh.h:862
VertexAroundVertexCirculator & operator--()
Pre-decrement operator (rotate clockwise).
Definition surface_mesh.h:891
VertexAroundVertexCirculator & end()
Helper for C++11 range-based for-loops.
Definition surface_mesh.h:927
Halfedge halfedge() const
Get the current halfedge.
Definition surface_mesh.h:916
This helper class is a container for iterating through all vertices using C++11 range-based for-loops...
Definition surface_mesh.h:717
VertexContainer(VertexIterator _begin, VertexIterator _end)
Constructor.
Definition surface_mesh.h:724
VertexIterator begin() const
Get the beginning iterator.
Definition surface_mesh.h:729
VertexIterator end() const
Get the ending iterator.
Definition surface_mesh.h:734
This class iterates linearly over all vertices.
Definition surface_mesh.h:439
Vertex operator*() const
Get the vertex the iterator refers to.
Definition surface_mesh.h:454
bool operator==(const VertexIterator &rhs) const
Equality operator.
Definition surface_mesh.h:461
VertexIterator & operator--()
Pre-decrement iterator.
Definition surface_mesh.h:489
bool operator!=(const VertexIterator &rhs) const
Inequality operator.
Definition surface_mesh.h:470
VertexIterator(Vertex v=Vertex(), const SurfaceMesh *m=nullptr)
Default constructor.
Definition surface_mesh.h:446
VertexIterator & operator++()
Pre-increment iterator.
Definition surface_mesh.h:478
Vertex property of type T.
Definition surface_mesh.h:255
VertexProperty(Property< T > p)
Constructor with property.
Definition surface_mesh.h:264
Property< T >::const_reference operator[](Vertex v) const
Access the data stored for vertex v.
Definition surface_mesh.h:280
Property< T >::reference operator[](Vertex v)
Access the data stored for vertex v.
Definition surface_mesh.h:271
VertexProperty()=default
default constructor
A halfedge data structure for polygonal meshes of 2-manifold.
Definition surface_mesh.h:51
const vec3 & position(Vertex v) const
Returns the position of a vertex.
Definition surface_mesh.h:2458
bool is_border(Vertex v) const
returns whether v is a boundary vertex
Definition surface_mesh.h:1546
bool is_quad_mesh() const
Definition surface_mesh.cpp:896
EdgeContainer edges() const
Returns a container for range-based iteration over edges.
Definition surface_mesh.h:2173
const std::type_info & get_vertex_property_type(const std::string &name) const
Get the type information of the vertex property name.
Definition surface_mesh.h:2018
Vertex source(Halfedge h) const
returns the vertex the halfedge h emanates from
Definition surface_mesh.h:1584
unsigned int n_faces() const
returns number of faces in the mesh
Definition surface_mesh.h:1452
bool remove_vertex_property(const std::string &n)
Remove the vertex property named n.
Definition surface_mesh.h:1900
EdgeIterator edges_end() const
Returns an iterator to the end of the edges.
Definition surface_mesh.h:2165
unsigned int n_halfedges() const
returns number of halfedge in the mesh
Definition surface_mesh.h:1448
unsigned int halfedges_size() const
returns number of (deleted and valid)halfedge in the mesh
Definition surface_mesh.h:1438
void set_next(Halfedge h, Halfedge nh)
sets the next halfedge of h within the face to nh
Definition surface_mesh.h:1609
VertexAroundVertexCirculator vertices(Vertex v) const
Returns circulator for the vertices around vertex v.
Definition surface_mesh.h:2206
bool is_valid(Halfedge h) const
return whether halfedge h is valid, i.e. the index is stores it within the array bounds.
Definition surface_mesh.h:1513
HalfedgeAroundFaceCirculator halfedges(Face f) const
Returns circulator for halfedges of face f.
Definition surface_mesh.h:2242
unsigned int n_edges() const
returns number of edges in the mesh
Definition surface_mesh.h:1450
bool is_valid(Edge e) const
return whether edge e is valid, i.e. the index is stores it within the array bounds.
Definition surface_mesh.h:1517
void triangulate()
Definition surface_mesh.cpp:908
bool rename_vertex_property(const std::string &old_name, const std::string &new_name)
Rename a vertex property given its name.
Definition surface_mesh.h:1968
unsigned int valence(Vertex v) const
Definition surface_mesh.cpp:834
HalfedgeProperty< T > add_halfedge_property(const std::string &name, const T t=T())
Add a halfedge property of type T with name name and default value t.
Definition surface_mesh.h:1736
Face add_face(const std::vector< Vertex > &vertices)
Adds a new face to the mesh.
Definition surface_mesh.cpp:518
bool remove_halfedge_property(HalfedgeProperty< T > &p)
Remove the halfedge property p.
Definition surface_mesh.h:1908
VertexContainer vertices() const
Returns a container for range-based iteration over vertices.
Definition surface_mesh.h:2125
void stitch(Halfedge h0, Halfedge h1)
Stitch two halfedges h0 and h1. Precondition: h0 and h1 are both on the border and point in reversed ...
Definition surface_mesh.cpp:1598
Halfedge opposite(Halfedge h) const
returns the opposite halfedge of h
Definition surface_mesh.h:1620
FaceProperty< T > get_face_property(const std::string &name) const
Get the face property with name name of type T.
Definition surface_mesh.h:1811
const std::type_info & get_edge_property_type(const std::string &name) const
Get the type information of the edge property name.
Definition surface_mesh.h:2034
bool is_collapse_ok(Halfedge h) const
Definition surface_mesh.cpp:1706
const std::type_info & get_halfedge_property_type(const std::string &name) const
Get the type information of the halfedge property name.
Definition surface_mesh.h:2026
void delete_face(Face f)
Definition surface_mesh.cpp:1946
bool has_garbage() const
are there deleted vertices, edges or faces?
Definition surface_mesh.h:1480
Halfedge halfedge(Edge e, unsigned int i) const
returns the i'th halfedge of edge e. i has to be 0 or 1.
Definition surface_mesh.h:1660
Halfedge insert_vertex(Edge e, Vertex v)
Definition surface_mesh.h:2352
bool rename_face_property(const std::string &old_name, const std::string &new_name)
Rename a face property given its name.
Definition surface_mesh.h:1978
Edge find_edge(Vertex a, Vertex b) const
find the edge (a, b)
Definition surface_mesh.cpp:436
void reserve(unsigned int n_vertices, unsigned int n_edges, unsigned int n_faces)
Reserves memory for the given number of vertices, edges, and faces.
Definition surface_mesh.cpp:339
VertexProperty< T > vertex_property(const std::string &name, const T t=T())
If a vertex property of type T with name name exists, it is returned. Otherwise, this property is add...
Definition surface_mesh.h:1837
unsigned int edges_size() const
returns number of (deleted and valid)edges in the mesh
Definition surface_mesh.h:1440
std::vector< std::string > face_properties() const
Get the names of all face properties.
Definition surface_mesh.h:2080
bool is_flip_ok(Edge e) const
Definition surface_mesh.cpp:1435
FaceContainer faces() const
Returns a container for range-based iteration over faces.
Definition surface_mesh.h:2197
ModelProperty< T > get_model_property(const std::string &name) const
Gets the model property named name of type T.
Definition surface_mesh.h:1825
~SurfaceMesh() override=default
destructor (is virtual, since we inherit from Geometry_representation)
std::vector< std::string > vertex_properties() const
Get the names of all vertex properties.
Definition surface_mesh.h:2059
void update_face_normals()
compute face normals by calling compute_face_normal(Face) for each face.
Definition surface_mesh.cpp:1011
vec3 compute_face_normal(Face f) const
Computes the normal vector of face f. This method is robust for concave and general polygonal faces.
Definition surface_mesh.cpp:1035
SurfaceMesh(const SurfaceMesh &rhs)
copy constructor: copies rhs to *this. performs a deep copy of all properties.
Definition surface_mesh.h:1358
Halfedge insert_vertex(Edge e, const vec3 &p)
Definition surface_mesh.h:2340
EdgeProperty< T > get_edge_property(const std::string &name) const
Get the edge property with name name of type T.
Definition surface_mesh.h:1802
void set_halfedge(Face f, Halfedge h)
sets the halfedge of face f to h
Definition surface_mesh.h:1689
const std::type_info & get_face_property_type(const std::string &name) const
Get the type information of the face property name.
Definition surface_mesh.h:2042
EdgeIterator edges_begin() const
Returns an iterator to the beginning of the edges.
Definition surface_mesh.h:2157
VertexAroundFaceCirculator vertices(Face f) const
Returns circulator for vertices of face f.
Definition surface_mesh.h:2233
FaceIterator faces_begin() const
Returns an iterator to the beginning of the faces.
Definition surface_mesh.h:2181
Halfedge find_halfedge(Vertex start, Vertex end) const
find the halfedge from start to end
Definition surface_mesh.cpp:411
VertexProperty< T > get_vertex_property(const std::string &name) const
Get the vertex property with name name of type T.
Definition surface_mesh.h:1784
bool remove_face_property(const std::string &n)
Remove the face property named n.
Definition surface_mesh.h:1945
bool is_stitch_ok(Halfedge h0, Halfedge h1)
Definition surface_mesh.cpp:1556
Vertex split(Face f, const vec3 &p)
Definition surface_mesh.h:2301
void reverse_orientation()
Reverses the orientation of the entire mesh.
Definition surface_mesh.cpp:923
std::vector< std::string > edge_properties() const
Get the names of all edge properties.
Definition surface_mesh.h:2073
bool read(const std::string &filename)
Read mesh from a SM file filename. Mainly for quick debug purposes. Client code should use SurfaceMes...
Definition surface_mesh.cpp:203
bool is_deleted(Vertex v) const
Definition surface_mesh.h:1488
void set_face(Halfedge h, Face f)
sets the incident face to halfedge h to f
Definition surface_mesh.h:1599
SurfaceMesh()
Default constructor. Initializes an empty surface mesh.
Definition surface_mesh.cpp:33
std::vector< std::string > model_properties() const
Get the names of all model properties.
Definition surface_mesh.h:2087
Vertex target(Halfedge h) const
returns the vertex the halfedge h points to
Definition surface_mesh.h:1579
Halfedge halfedge(Face f) const
returns a halfedge of face f
Definition surface_mesh.h:1684
bool is_deleted(Face f) const
Definition surface_mesh.h:1503
HalfedgeContainer halfedges() const
Returns a container for range-based iteration over halfedges.
Definition surface_mesh.h:2149
void collect_garbage()
remove deleted vertices/edges/faces
Definition surface_mesh.cpp:2060
SurfaceMesh & operator=(const SurfaceMesh &rhs)
assign rhs to *this. performs a deep copy of all properties.
Definition surface_mesh.cpp:55
bool rename_edge_property(const std::string &old_name, const std::string &new_name)
Rename an edge property given its name.
Definition surface_mesh.h:1988
void resize(unsigned int nv, unsigned int ne, unsigned int nf)
Definition surface_mesh.h:1472
bool is_deleted(Edge e) const
Definition surface_mesh.h:1498
Halfedge split(Edge e, const vec3 &p)
Definition surface_mesh.h:2318
Halfedge prev_around_source(Halfedge h) const
Definition surface_mesh.h:1626
Halfedge insert_edge(Halfedge h0, Halfedge h1)
Definition surface_mesh.cpp:1394
const std::type_info & get_model_property_type(const std::string &name) const
Get the type information of the model property name.
Definition surface_mesh.h:2050
Halfedge prev(Halfedge h) const
returns the previous halfedge within the incident face
Definition surface_mesh.h:1615
void set_target(Halfedge h, Vertex v)
sets the vertex the halfedge h points to to v
Definition surface_mesh.h:1589
Halfedge next_around_target(Halfedge h) const
Definition surface_mesh.h:1644
std::vector< vec3 > & points() override
Returns a modifiable vector of all vertex positions.
Definition surface_mesh.h:2477
SurfaceMesh & join(const SurfaceMesh &other)
Merges another surface mesh into the current one. Shifts the indices of vertices of the other mesh by...
Definition surface_mesh.cpp:93
bool is_closed() const
returns whether the mesh closed (i.e., no boundary edges)
Definition surface_mesh.cpp:869
bool remove_face_property(FaceProperty< T > &p)
Remove the face property p.
Definition surface_mesh.h:1938
bool remove_edge_property(const std::string &n)
Remove the edge property named n.
Definition surface_mesh.h:1930
ModelProperty< T > model_property(const std::string &name, const T t=T())
If a model property of type T with name name exists, it is returned. Otherwise, this property is adde...
Definition surface_mesh.h:1882
Face add_quad(Vertex v1, Vertex v2, Vertex v3, Vertex v4)
Definition surface_mesh.cpp:504
VertexProperty< T > add_vertex_property(const std::string &name, const T t=T())
Add a vertex property of type T with name name and default value t.
Definition surface_mesh.h:1725
bool remove_model_property(ModelProperty< T > &p)
Remove the model property p.
Definition surface_mesh.h:1953
FaceProperty< T > face_property(const std::string &name, const T t=T())
If a face property of type T with name name exists, it is returned. Otherwise, this property is added...
Definition surface_mesh.h:1870
FaceProperty< T > add_face_property(const std::string &name, const T t=T())
Add a face property of type T with name name and default value t.
Definition surface_mesh.h:1758
FaceAroundVertexCirculator faces(Vertex v) const
Returns circulator for faces around vertex v.
Definition surface_mesh.h:2224
std::vector< std::string > halfedge_properties() const
Get the names of all halfedge properties.
Definition surface_mesh.h:2066
Face add_triangle(Vertex v1, Vertex v2, Vertex v3)
Definition surface_mesh.cpp:491
bool rename_model_property(const std::string &old_name, const std::string &new_name)
Rename a model property given its name.
Definition surface_mesh.h:2008
bool is_triangle_mesh() const
Definition surface_mesh.cpp:882
ModelProperty< T > add_model_property(const std::string &name, const T t=T())
Adds a model property of type T with name name and default value t.
Definition surface_mesh.h:1773
bool can_join_edges(Vertex v) const
Definition surface_mesh.cpp:2271
HalfedgeIterator halfedges_begin() const
Returns an iterator to the beginning of the halfedges.
Definition surface_mesh.h:2133
vec3 compute_vertex_normal(Vertex v) const
Definition surface_mesh.cpp:1112
HalfedgeProperty< T > get_halfedge_property(const std::string &name) const
Get the halfedge property with name name of type T.
Definition surface_mesh.h:1793
bool write(const std::string &filename) const
Write mesh to a SM file filename. Mainly for quick debug purposes. Client code should use SurfaceMesh...
Definition surface_mesh.cpp:250
SurfaceMesh & operator+=(const SurfaceMesh &other)
Merges another surface mesh into the current one. Shifts the indices of vertices of the other mesh by...
Definition surface_mesh.h:1369
Vertex add_vertex(const vec3 &p)
Adds a new vertex to the mesh.
Definition surface_mesh.h:1407
bool is_valid(Face f) const
return whether face f is valid, i.e. the index is stores it within the array bounds.
Definition surface_mesh.h:1521
bool is_border(Face f) const
returns whether f is a boundary face, i.e., it one of its edges is a boundary edge.
Definition surface_mesh.h:1694
EdgeProperty< T > edge_property(const std::string &name, const T t=T())
If an edge property of type T with name name exists, it is returned. Otherwise, this property is adde...
Definition surface_mesh.h:1859
Halfedge prev_around_target(Halfedge h) const
Definition surface_mesh.h:1638
Face face(Halfedge h) const
returns the face incident to halfedge h
Definition surface_mesh.h:1594
bool remove_edge_property(EdgeProperty< T > &p)
Remove the edge property p.
Definition surface_mesh.h:1923
void property_stats(std::ostream &output) const override
Prints the names of all properties to an output stream (e.g., std::cout).
Definition surface_mesh.cpp:354
void delete_edge(Edge e)
Definition surface_mesh.cpp:1932
void update_vertex_normals()
compute vertex normals by calling compute_vertex_normal(Vertex) for each vertex.
Definition surface_mesh.cpp:1093
FaceIterator faces_end() const
Returns an iterator to the end of the faces.
Definition surface_mesh.h:2189
SurfaceMesh & assign(const SurfaceMesh &rhs)
assign rhs to *this. does not copy custom properties.
Definition surface_mesh.cpp:149
void collapse(Halfedge h)
Definition surface_mesh.cpp:1768
void flip(Edge e)
Definition surface_mesh.cpp:1461
HalfedgeProperty< T > halfedge_property(const std::string &name, const T t=T())
If a halfedge property of type T with name name exists, it is returned. Otherwise,...
Definition surface_mesh.h:1848
bool is_manifold(Vertex v) const
returns whether v is a manifold vertex (not incident to several patches)
Definition surface_mesh.h:1557
void clear()
Clears the mesh, removing all vertices, edges, faces, and properties (and resets garbage state).
Definition surface_mesh.cpp:302
Halfedge next_around_source(Halfedge h) const
Definition surface_mesh.h:1632
bool rename_halfedge_property(const std::string &old_name, const std::string &new_name)
Rename a halfedge property given its name.
Definition surface_mesh.h:1998
bool remove_halfedge_property(const std::string &n)
Remove the halfedge property named n.
Definition surface_mesh.h:1915
bool is_isolated(Vertex v) const
returns whether v is isolated, i.e., not incident to any face
Definition surface_mesh.h:1552
vec3 & position(Vertex v)
Returns the position of a vertex.
Definition surface_mesh.h:2465
bool is_deleted(Halfedge h) const
Definition surface_mesh.h:1493
HalfedgeAroundVertexCirculator halfedges(Vertex v) const
Returns circulator for outgoing halfedges around vertex v.
Definition surface_mesh.h:2215
unsigned int vertices_size() const
returns number of (deleted and valid) vertices in the mesh
Definition surface_mesh.h:1436
Edge edge(Halfedge h) const
return the edge that contains halfedge h as one of its two halfedges.
Definition surface_mesh.h:1649
bool remove_model_property(const std::string &n)
Remove the model property named n.
Definition surface_mesh.h:1960
float edge_length(Edge e) const
compute the length of edge e.
Definition surface_mesh.cpp:1175
EdgeProperty< T > add_edge_property(const std::string &name, const T t=T())
Add an edge property of type T with name name and default value t.
Definition surface_mesh.h:1747
unsigned int faces_size() const
returns number of (deleted and valid)faces in the mesh
Definition surface_mesh.h:1442
Halfedge next(Halfedge h) const
returns the next halfedge within the incident face
Definition surface_mesh.h:1604
Face face(Edge e, unsigned int i) const
returns the face incident to the i'th halfedge of edge e. i has to be 0 or 1.
Definition surface_mesh.h:1672
Halfedge out_halfedge(Vertex v) const
Definition surface_mesh.h:1536
void delete_vertex(Vertex v)
Definition surface_mesh.cpp:1898
bool is_border(Edge e) const
Definition surface_mesh.h:1679
VertexIterator vertices_begin() const
Returns an iterator to the beginning of the vertices.
Definition surface_mesh.h:2109
HalfedgeIterator halfedges_end() const
Returns an iterator to the end of the halfedges.
Definition surface_mesh.h:2141
bool remove_vertex_property(VertexProperty< T > &p)
Remove the vertex property p.
Definition surface_mesh.h:1893
bool is_degenerate(Face f) const
returns whether f is degenerate
Definition surface_mesh.cpp:2207
VertexIterator vertices_end() const
Returns an iterator to the end of the vertices.
Definition surface_mesh.h:2117
bool is_valid(Vertex v) const
return whether vertex v is valid, i.e. the index is stores it within the array bounds.
Definition surface_mesh.h:1509
Vertex vertex(Edge e, unsigned int i) const
returns the i'th vertex of edge e. i has to be 0 or 1.
Definition surface_mesh.h:1666
bool is_border(Halfedge h) const
returns whether h is a boundary halfedge, i.e., if its face does not exist.
Definition surface_mesh.h:1654
bool join_edges(Vertex v)
Definition surface_mesh.cpp:2287
const std::vector< vec3 > & points() const override
Returns a read-only vector of all vertex positions.
Definition surface_mesh.h:2471
unsigned int n_vertices() const
returns number of vertices in the mesh
Definition surface_mesh.h:1446
void set_out_halfedge(Vertex v, Halfedge h)
set the outgoing halfedge of vertex v to h
Definition surface_mesh.h:1541
Definition collider.cpp:182
Vec< 3, float > vec3
A 3D point/vector of float type.
Definition types.h:44
std::ostream & operator<<(std::ostream &os, Graph::Vertex v)
Output stream support for Graph::Vertex.
Definition graph.h:1300
Helper structure to be able to use std::unordered_map.
Definition surface_mesh.h:115
std::size_t operator()(const BaseHandle &h) const
Hash function for BaseHandle.
Definition surface_mesh.h:121
Definition surface_mesh.h:173
std::ostream & operator<<(std::ostream &os) const
Output stream support for Edge.
Definition surface_mesh.h:184
Edge(int _idx=-1)
Default constructor (with invalid index).
Definition surface_mesh.h:178
This type stores the face connectivity.
Definition surface_mesh.h:241
Halfedge halfedge_
a halfedge that is part of the face
Definition surface_mesh.h:243
Definition surface_mesh.h:191
Face(int _idx=-1)
Default constructor (with invalid index).
Definition surface_mesh.h:196
std::ostream & operator<<(std::ostream &os) const
Output stream support for Face.
Definition surface_mesh.h:202
This type stores the halfedge connectivity.
Definition surface_mesh.h:224
Vertex vertex_
vertex the halfedge points to
Definition surface_mesh.h:228
Halfedge next_
next halfedge within a face (or along a boundary)
Definition surface_mesh.h:230
Face face_
face incident to halfedge
Definition surface_mesh.h:226
Halfedge prev_
previous halfedge within a face (or along a boundary)
Definition surface_mesh.h:232
This type represents a halfedge (internally it is basically an index).
Definition surface_mesh.h:155
std::ostream & operator<<(std::ostream &os) const
Output stream support for Halfedge.
Definition surface_mesh.h:166
Halfedge(int _idx=-1)
Default constructor (with invalid index).
Definition surface_mesh.h:160
This type stores the vertex connectivity.
Definition surface_mesh.h:213
Halfedge halfedge_
an outgoing halfedge per vertex (it will be a boundary halfedge for boundary vertices)
Definition surface_mesh.h:215
This type represents a vertex (internally it is basically an index).
Definition surface_mesh.h:135
std::ostream & operator<<(std::ostream &os) const
Output stream support for Vertex.
Definition surface_mesh.h:146
Vertex(int _idx=-1)
Default constructor (with invalid index).
Definition surface_mesh.h:140