128 template <
class Circulator>
129 static Circulator make_end_circulator(
const Circulator& _circ)
131 Circulator end = _circ;
133 end.lap(_circ.max_laps());
145 std::pair<VertexVertexIter, VertexVertexIter> vertex_vertices(
VertexHandle _h,
int _max_laps = 1)
const {
147 return std::make_pair(begin, make_end_circulator(begin));
154 std::pair<VertexOHalfEdgeIter, VertexOHalfEdgeIter> outgoing_halfedges(
VertexHandle _h,
int _max_laps = 1)
const {
156 return std::make_pair(begin, make_end_circulator(begin));
163 std::pair<VertexIHalfEdgeIter, VertexIHalfEdgeIter> incoming_halfedges(
VertexHandle _h,
int _max_laps = 1)
const {
165 return std::make_pair(begin, make_end_circulator(begin));
172 std::pair<VertexEdgeIter, VertexEdgeIter> vertex_edges(
VertexHandle _h,
int _max_laps = 1)
const {
174 return std::make_pair(begin, make_end_circulator(begin));
181 std::pair<VertexHalfFaceIter, VertexHalfFaceIter> vertex_halffaces(
VertexHandle _h,
int _max_laps = 1)
const {
183 return std::make_pair(begin, make_end_circulator(begin));
190 std::pair<VertexFaceIter, VertexFaceIter> vertex_faces(
VertexHandle _h,
int _max_laps = 1)
const {
192 return std::make_pair(begin, make_end_circulator(begin));
199 std::pair<VertexCellIter, VertexCellIter> vertex_cells(
VertexHandle _h,
int _max_laps = 1)
const {
201 return std::make_pair(begin, make_end_circulator(begin));
208 std::pair<HalfEdgeHalfFaceIter, HalfEdgeHalfFaceIter> halfedge_halffaces(
HalfEdgeHandle _h,
int _max_laps = 1)
const {
210 return std::make_pair(begin, make_end_circulator(begin));
217 std::pair<HalfEdgeFaceIter, HalfEdgeFaceIter> halfedge_faces(
HalfEdgeHandle _h,
int _max_laps = 1)
const {
219 return std::make_pair(begin, make_end_circulator(begin));
226 std::pair<HalfEdgeCellIter, HalfEdgeCellIter> halfedge_cells(
HalfEdgeHandle _h,
int _max_laps = 1)
const {
228 return std::make_pair(begin, make_end_circulator(begin));
235 std::pair<EdgeHalfFaceIter, EdgeHalfFaceIter> edge_halffaces(
EdgeHandle _h,
int _max_laps = 1)
const {
237 return std::make_pair(begin, make_end_circulator(begin));
244 std::pair<EdgeFaceIter, EdgeFaceIter> edge_faces(
EdgeHandle _h,
int _max_laps = 1)
const {
246 return std::make_pair(begin, make_end_circulator(begin));
253 std::pair<EdgeCellIter, EdgeCellIter> edge_cells(
EdgeHandle _h,
int _max_laps = 1)
const {
255 return std::make_pair(begin, make_end_circulator(begin));
262 std::pair<HalfFaceHalfEdgeIter, HalfFaceHalfEdgeIter> halfface_halfedges(
HalfFaceHandle _h,
int _max_laps = 1)
const {
264 return std::make_pair(begin, make_end_circulator(begin));
271 std::pair<HalfFaceEdgeIter, HalfFaceEdgeIter> halfface_edges(
HalfFaceHandle _h,
int _max_laps = 1)
const {
273 return std::make_pair(begin, make_end_circulator(begin));
280 std::pair<FaceVertexIter, FaceVertexIter> face_vertices(
FaceHandle _h,
int _max_laps = 1)
const {
282 return std::make_pair(begin, make_end_circulator(begin));
289 std::pair<FaceHalfEdgeIter, FaceHalfEdgeIter> face_halfedges(
FaceHandle _h,
int _max_laps = 1)
const {
291 return std::make_pair(begin, make_end_circulator(begin));
298 std::pair<FaceEdgeIter, FaceEdgeIter> face_edges(
FaceHandle _h,
int _max_laps = 1)
const {
300 return std::make_pair(begin, make_end_circulator(begin));
307 std::pair<CellVertexIter, CellVertexIter> cell_vertices(
CellHandle _h,
int _max_laps = 1)
const {
309 return std::make_pair(begin, make_end_circulator(begin));
316 std::pair<CellHalfEdgeIter, CellHalfEdgeIter> cell_halfedges(
CellHandle _h,
int _max_laps = 1)
const {
318 return std::make_pair(begin, make_end_circulator(begin));
325 std::pair<CellEdgeIter, CellEdgeIter> cell_edges(
CellHandle _h,
int _max_laps = 1)
const {
327 return std::make_pair(begin, make_end_circulator(begin));
334 std::pair<CellHalfFaceIter, CellHalfFaceIter> cell_halffaces(
CellHandle _h,
int _max_laps = 1)
const {
336 return std::make_pair(begin, make_end_circulator(begin));
343 std::pair<CellFaceIter, CellFaceIter> cell_faces(
CellHandle _h,
int _max_laps = 1)
const {
345 return std::make_pair(begin, make_end_circulator(begin));
352 std::pair<CellCellIter, CellCellIter> cell_cells(
CellHandle _h,
int _max_laps = 1)
const {
354 return std::make_pair(begin, make_end_circulator(begin));
361 std::pair<HalfFaceVertexIter, HalfFaceVertexIter> halfface_vertices(
HalfFaceHandle _h,
int _max_laps = 1)
const {
363 return std::make_pair(begin, make_end_circulator(begin));
370 std::pair<BoundaryHalfFaceHalfFaceIter, BoundaryHalfFaceHalfFaceIter> boundary_halfface_halffaces(
HalfFaceHandle _h,
int _max_laps = 1)
const {
372 return std::make_pair(begin, make_end_circulator(begin));
415 std::pair<VertexIter, VertexIter> vertices()
const {
416 return std::make_pair(vertices_begin(), vertices_end());
431 std::pair<EdgeIter, EdgeIter> edges()
const {
432 return std::make_pair(edges_begin(), edges_end());
447 std::pair<HalfEdgeIter, HalfEdgeIter> halfedges()
const {
448 return std::make_pair(halfedges_begin(), halfedges_end());
463 std::pair<FaceIter, FaceIter> faces()
const {
464 return std::make_pair(faces_begin(), faces_end());
479 std::pair<HalfFaceIter, HalfFaceIter> halffaces()
const {
480 return std::make_pair(halffaces_begin(), halffaces_end());
495 std::pair<CellIter, CellIter> cells()
const {
496 return std::make_pair(cells_begin(), cells_end());
503 std::array<VertexHandle, 2> halfedge_vertices(
HalfEdgeHandle _h)
const {
504 return {from_vertex_handle(_h), to_vertex_handle(_h)};
507 std::array<VertexHandle, 2> edge_vertices(
EdgeHandle _h)
const {
508 return halfedge_vertices(halfedge_handle(_h, 0));
511 std::array<HalfEdgeHandle, 2> edge_halfedges(
EdgeHandle _h)
const {
513 halfedge_handle(_h, 0),
514 halfedge_handle(_h, 1)};
517 std::array<HalfFaceHandle,2> face_halffaces(
FaceHandle _h)
const {
519 halfface_handle(_h, 0),
520 halfface_handle(_h, 1)};
523 std::array<CellHandle, 2> face_cells(
FaceHandle _h)
const {
525 incident_cell(halfface_handle(_h, 0)),
526 incident_cell(halfface_handle(_h, 1))};
536 size_t n_edges()
const override {
return edges_.size(); }
538 size_t n_halfedges()
const override {
return edges_.size() * 2u; }
540 size_t n_faces()
const override {
return faces_.size(); }
542 size_t n_halffaces()
const override {
return faces_.size() * 2u; }
544 size_t n_cells()
const override {
return cells_.size(); }
561 int g = (1 - (int)(n_logical_vertices() -
566 if(g % 2 == 0)
return (g / 2);
576 size_t n_vertices_ = 0u;
579 void add_n_vertices(
size_t n);
580 void reserve_vertices(
size_t n);
581 void reserve_edges(
size_t n);
582 void reserve_faces(
size_t n);
583 void reserve_cells(
size_t n);
586 virtual VertexHandle add_vertex();
591 virtual EdgeHandle add_edge(VertexHandle _fromVertex, VertexHandle _toHandle,
bool _allowDuplicates =
false);
600 virtual FaceHandle add_face(std::vector<HalfEdgeHandle> _halfedges,
bool _topologyCheck =
false);
603 virtual FaceHandle add_face(
const std::vector<VertexHandle>& _vertices);
612 virtual CellHandle add_cell(std::vector<HalfFaceHandle> _halffaces,
bool _topologyCheck =
false);
615 void set_edge(EdgeHandle _eh, VertexHandle _fromVertex, VertexHandle _toVertex);
618 void set_face(FaceHandle _fh,
const std::vector<HalfEdgeHandle>& _hes);
621 void set_cell(CellHandle _ch,
const std::vector<HalfFaceHandle>& _hfs);
624 void reorder_incident_halffaces(EdgeHandle _eh);
631 const Edge& edge(EdgeHandle _edgeHandle)
const;
634 const Face& face(FaceHandle _faceHandle)
const;
637 const Cell& cell(CellHandle _cellHandle)
const;
640 Edge& edge(EdgeHandle _edgeHandle);
643 Face& face(FaceHandle _faceHandle);
646 Cell& cell(CellHandle _cellHandle);
649 Edge halfedge(HalfEdgeHandle _halfEdgeHandle)
const;
652 Face halfface(HalfFaceHandle _halfFaceHandle)
const;
655 Edge opposite_halfedge(HalfEdgeHandle _halfEdgeHandle)
const;
658 Face opposite_halfface(HalfFaceHandle _halfFaceHandle)
const;
661 HalfEdgeHandle find_halfedge(VertexHandle _vh1, VertexHandle _vh2)
const;
662 [[deprecated(
"please use find_halfedge instead")]]
663 HalfEdgeHandle halfedge (VertexHandle _vh1, VertexHandle _vh2)
const;
666 HalfEdgeHandle find_halfedge_in_cell(VertexHandle _vh1, VertexHandle _vh2, CellHandle _ch)
const;
671 HalfFaceHandle find_halfface(
const std::vector<VertexHandle>& _vs)
const;
672 [[deprecated(
"please use find_halfface instead")]]
673 HalfFaceHandle halfface (
const std::vector<VertexHandle>& _vs)
const;
678 HalfFaceHandle find_halfface_in_cell(
const std::vector<VertexHandle>& _vs, CellHandle _ch)
const;
683 HalfFaceHandle find_halfface_extensive(
const std::vector<VertexHandle>& _vs)
const;
684 [[deprecated(
"please use find_halfface_extensive instead")]]
685 HalfFaceHandle halfface_extensive (
const std::vector<VertexHandle>& _vs)
const;
690 HalfFaceHandle find_halfface(
const std::vector<HalfEdgeHandle>& _hes)
const;
691 [[deprecated(
"please use find_halfface instead")]]
692 HalfFaceHandle halfface (
const std::vector<HalfEdgeHandle>& _hes)
const;
695 HalfEdgeHandle next_halfedge_in_halfface(HalfEdgeHandle _heh, HalfFaceHandle _hfh)
const;
698 HalfEdgeHandle prev_halfedge_in_halfface(HalfEdgeHandle _heh, HalfFaceHandle _hfh)
const;
702 return halfedge(_h).from_vertex();
707 return halfedge(_h).to_vertex();
712 assert(is_valid(_vh));
713 assert(has_vertex_bottom_up_incidences());
715 return outgoing_hes_per_vertex_[_vh].size();
720 assert(is_valid(_eh));
721 assert(has_edge_bottom_up_incidences());
723 return incident_hfs_per_he_[halfedge_handle(_eh, 0)].size();
728 assert(is_valid(_fh));
730 return face(_fh).halfedges().size();
735 assert(is_valid(_ch));
737 return cell(_ch).halffaces().size();
741 std::vector<VertexHandle> get_halfface_vertices(
HalfFaceHandle hfh)
const;
764 virtual void collect_garbage();
767 virtual bool is_deleted(
VertexHandle _h)
const {
return vertex_deleted_[_h]; }
768 virtual bool is_deleted(EdgeHandle _h)
const {
return edge_deleted_[_h]; }
769 virtual bool is_deleted(HalfEdgeHandle _h)
const {
return edge_deleted_[_h.edge_handle()]; }
770 virtual bool is_deleted(FaceHandle _h)
const {
return face_deleted_[_h]; }
771 virtual bool is_deleted(HalfFaceHandle _h)
const {
return face_deleted_[_h.face_handle()]; }
772 virtual bool is_deleted(CellHandle _h)
const {
return cell_deleted_[_h]; }
776 template <
class ContainerT>
777 void get_incident_edges(
const ContainerT& _vs, std::set<EdgeHandle>& _es)
const;
779 template <
class ContainerT>
780 void get_incident_faces(
const ContainerT& _es, std::set<FaceHandle>& _fs)
const;
782 template <
class ContainerT>
783 void get_incident_cells(
const ContainerT& _fs, std::set<CellHandle>& _cs)
const;
785 VertexIter delete_vertex_core(VertexHandle _h);
787 EdgeIter delete_edge_core(EdgeHandle _h);
789 FaceIter delete_face_core(FaceHandle _h);
791 CellIter delete_cell_core(CellHandle _h);
796 virtual void swap_cell_indices(CellHandle _h1, CellHandle _h2);
799 virtual void swap_face_indices(FaceHandle _h1, FaceHandle _h2);
802 virtual void swap_edge_indices(EdgeHandle _h1, EdgeHandle _h2);
805 virtual void swap_vertex_indices(VertexHandle _h1, VertexHandle _h2);
811 explicit EdgeCorrector(
const std::vector<int>& _newIndices) :
812 newIndices_(_newIndices) {}
814 void operator()(
Edge& _edge) {
815 _edge.set_from_vertex(
VertexHandle(newIndices_[_edge.from_vertex().
uidx()]));
819 const std::vector<int>& newIndices_;
824 explicit FaceCorrector(
const std::vector<int>& _newIndices) :
825 newIndices_(_newIndices) {}
827 void operator()(
Face& _face) {
828 std::vector<HalfEdgeHandle> hes = _face.halfedges();
829 for(std::vector<HalfEdgeHandle>::iterator he_it = hes.begin(),
830 he_end = hes.end(); he_it != he_end; ++he_it) {
833 unsigned char opp = he_it->idx() == halfedge_handle(eh, 1).idx();
834 *he_it = halfedge_handle(
EdgeHandle(newIndices_[eh.
uidx()]), opp);
836 _face.set_halfedges(hes);
839 const std::vector<int>& newIndices_;
844 explicit CellCorrector(
const std::vector<int>& _newIndices) :
845 newIndices_(_newIndices) {}
847 void operator()(
Cell& _cell) {
848 std::vector<HalfFaceHandle> hfs = _cell.halffaces();
849 for(std::vector<HalfFaceHandle>::iterator hf_it = hfs.begin(),
850 hf_end = hfs.end(); hf_it != hf_end; ++hf_it) {
853 unsigned char opp = hf_it->idx() == halfface_handle(fh, 1).idx();
854 *hf_it = halfface_handle(
FaceHandle(newIndices_[fh.
uidx()]), opp);
856 _cell.set_halffaces(hfs);
859 const std::vector<int>& newIndices_;
865 virtual void clear(
bool _clearProps =
true) {
870 vertex_deleted_.clear();
871 edge_deleted_.clear();
872 face_deleted_.clear();
873 cell_deleted_.clear();
874 n_deleted_vertices_ = 0;
875 n_deleted_edges_ = 0;
876 n_deleted_faces_ = 0;
877 n_deleted_cells_ = 0;
878 outgoing_hes_per_vertex_.clear();
879 incident_hfs_per_he_.clear();
880 incident_cell_per_hf_.clear();
900 void enable_bottom_up_incidences(
bool _enable =
true)
902 enable_vertex_bottom_up_incidences(_enable);
903 enable_edge_bottom_up_incidences(_enable);
904 enable_face_bottom_up_incidences(_enable);
907 void enable_vertex_bottom_up_incidences(
bool _enable =
true) {
909 if(_enable && !v_bottom_up_) {
912 compute_vertex_bottom_up_incidences();
916 outgoing_hes_per_vertex_.clear();
919 v_bottom_up_ = _enable;
922 void enable_edge_bottom_up_incidences(
bool _enable =
true) {
924 if(_enable && !e_bottom_up_) {
927 compute_edge_bottom_up_incidences();
930 for (
const auto &eh: edges()) {
931 reorder_incident_halffaces(eh);
937 incident_hfs_per_he_.clear();
940 e_bottom_up_ = _enable;
943 void enable_face_bottom_up_incidences(
bool _enable =
true) {
945 bool updateOrder =
false;
946 if(_enable && !f_bottom_up_) {
949 compute_face_bottom_up_incidences();
955 incident_cell_per_hf_.clear();
958 f_bottom_up_ = _enable;
962 for (
const auto &eh: edges()) {
963 reorder_incident_halffaces(eh);
969 bool has_full_bottom_up_incidences()
const {
970 return (has_vertex_bottom_up_incidences() &&
971 has_edge_bottom_up_incidences() &&
972 has_face_bottom_up_incidences());
975 bool has_vertex_bottom_up_incidences()
const {
return v_bottom_up_; }
977 bool has_edge_bottom_up_incidences()
const {
return e_bottom_up_; }
979 bool has_face_bottom_up_incidences()
const {
return f_bottom_up_; }
982 void enable_deferred_deletion(
bool _enable =
true);
983 bool deferred_deletion_enabled()
const {
return deferred_deletion_; }
986 void enable_fast_deletion(
bool _enable =
true) { fast_deletion_ = _enable; }
987 bool fast_deletion_enabled()
const {
return fast_deletion_; }
992 void compute_vertex_bottom_up_incidences();
994 void compute_edge_bottom_up_incidences();
996 void compute_face_bottom_up_incidences();
999 VertexVector<std::vector<HalfEdgeHandle> > outgoing_hes_per_vertex_;
1002 HalfEdgeVector<std::vector<HalfFaceHandle> > incident_hfs_per_he_;
1005 HalfFaceVector<CellHandle> incident_cell_per_hf_;
1008 bool v_bottom_up_ =
true;
1010 bool e_bottom_up_ =
true;
1012 bool f_bottom_up_ =
true;
1014 bool deferred_deletion_ =
true;
1016 bool fast_deletion_ =
true;
1034 HalfFaceHandle adjacent_halfface_in_cell(HalfFaceHandle _halfFaceHandle, HalfEdgeHandle _halfEdgeHandle)
const;
1037 CellHandle incident_cell(HalfFaceHandle _halfFaceHandle)
const;
1039 bool is_boundary(HalfFaceHandle _halfFaceHandle)
const
1041 assert(is_valid(_halfFaceHandle));
1042 assert(has_face_bottom_up_incidences());
1043 return incident_cell_per_hf_[_halfFaceHandle] == InvalidCellHandle;
1046 bool is_boundary(FaceHandle _faceHandle)
const {
1047 assert(is_valid(_faceHandle));
1048 assert(has_face_bottom_up_incidences());
1049 return is_boundary(halfface_handle(_faceHandle, 0)) ||
1050 is_boundary(halfface_handle(_faceHandle, 1));
1053 bool is_boundary(EdgeHandle _edgeHandle)
const {
1054 assert(is_valid(_edgeHandle));
1055 assert(has_edge_bottom_up_incidences());
1057 for(HalfEdgeHalfFaceIter hehf_it = hehf_iter(halfedge_handle(_edgeHandle, 0));
1058 hehf_it.valid(); ++hehf_it) {
1059 if(is_boundary(face_handle(*hehf_it))) {
1066 bool is_boundary(HalfEdgeHandle _halfedgeHandle)
const {
1067 assert(is_valid(_halfedgeHandle));
1068 assert(has_edge_bottom_up_incidences());
1070 for(HalfEdgeHalfFaceIter hehf_it = hehf_iter(_halfedgeHandle);
1071 hehf_it.valid(); ++hehf_it) {
1072 if(is_boundary(face_handle(*hehf_it))) {
1079 bool is_boundary(VertexHandle _vertexHandle)
const {
1080 assert(is_valid(_vertexHandle));
1081 assert(has_vertex_bottom_up_incidences());
1083 for(VertexOHalfEdgeIter voh_it = voh_iter(_vertexHandle); voh_it.valid(); ++voh_it) {
1084 if(is_boundary(*voh_it))
return true;
1089 bool is_boundary(CellHandle _cellHandle)
const {
1090 assert(is_valid(_cellHandle));
1092 for(CellFaceIter cf_it = cf_iter(_cellHandle); cf_it.valid(); ++cf_it) {
1093 if(is_boundary(*cf_it))
return true;
1098 size_t n_vertices_in_cell(CellHandle _ch)
const {
1099 assert(is_valid(_ch));
1101 std::set<VertexHandle> vhs;
1102 for(
const auto hfh: cell_halffaces(_ch)) {
1103 for(
const auto heh: halfface_halfedges(hfh)) {
1104 vhs.insert(to_vertex_handle(heh));
1117 return Edge(_edge.to_vertex(), _edge.from_vertex());
1120 Face opposite_halfface(
const Face& _face)
const {
1121 std::vector<HalfEdgeHandle> opp_halfedges;
1122 opp_halfedges.resize(_face.halfedges().size());
1123 std::transform(_face.halfedges().rbegin(),
1124 _face.halfedges().rend(),
1125 opp_halfedges.begin(),
1126 opposite_halfedge_handle);
1127 return Face(opp_halfedges);
1137 assert(_h.is_valid());
1138 assert(_subIdx < 2);
1146 assert(_h.is_valid());
1147 assert(_subIdx < 2);
1154 assert(_h.is_valid());
1159 assert(_h.is_valid());
1163 static inline HalfEdgeHandle opposite_halfedge_handle(HalfEdgeHandle _h) {
1164 assert(_h.is_valid());
1165 return HalfEdgeHandle(_h.idx() ^ 1);
1168 static inline HalfFaceHandle opposite_halfface_handle(HalfFaceHandle _h) {
1169 assert(_h.is_valid());
1170 return HalfFaceHandle(_h.idx() ^ 1);
1173 bool inline needs_garbage_collection()
const {
1174 return n_deleted_vertices_ > 0 || n_deleted_edges_ > 0 || n_deleted_faces_ > 0 || n_deleted_cells_ > 0;
1178 template<
typename Handle>
1180 static_assert(is_handle_v<Handle>);
1181 return _h.is_valid() && _h.uidx() < n<typename Handle::EntityTag>();
1198 size_t n_deleted_vertices_ = 0;
1199 size_t n_deleted_edges_ = 0;
1200 size_t n_deleted_faces_ = 0;
1201 size_t n_deleted_cells_ = 0;