35 #ifndef TOPOLOGYKERNEL_HH_ 36 #define TOPOLOGYKERNEL_HH_ 42 #include "BaseEntities.hh" 43 #include "OpenVolumeMeshHandle.hh" 44 #include "ResourceManager.hh" 45 #include "Iterators.hh" 46 #include "OpenVolumeMesh/Config/Export.hh" 59 assert(other !=
nullptr);
109 template <
class Circulator>
110 static Circulator make_end_circulator(
const Circulator& _circ)
112 Circulator end = _circ;
114 end.lap(_circ.max_laps());
126 std::pair<VertexVertexIter, VertexVertexIter> vertex_vertices(
const VertexHandle& _h,
int _max_laps = 1)
const {
128 return std::make_pair(begin, make_end_circulator(begin));
135 std::pair<VertexOHalfEdgeIter, VertexOHalfEdgeIter> outgoing_halfedges(
const VertexHandle& _h,
int _max_laps = 1)
const {
137 return std::make_pair(begin, make_end_circulator(begin));
144 std::pair<VertexIHalfEdgeIter, VertexIHalfEdgeIter> incoming_halfedges(
const VertexHandle& _h,
int _max_laps = 1)
const {
146 return std::make_pair(begin, make_end_circulator(begin));
153 std::pair<VertexEdgeIter, VertexEdgeIter> vertex_edges(
const VertexHandle& _h,
int _max_laps = 1)
const {
155 return std::make_pair(begin, make_end_circulator(begin));
162 std::pair<VertexHalfFaceIter, VertexHalfFaceIter> vertex_halffaces(
const VertexHandle& _h,
int _max_laps = 1)
const {
164 return std::make_pair(begin, make_end_circulator(begin));
171 std::pair<VertexFaceIter, VertexFaceIter> vertex_faces(
const VertexHandle& _h,
int _max_laps = 1)
const {
173 return std::make_pair(begin, make_end_circulator(begin));
180 std::pair<VertexCellIter, VertexCellIter> vertex_cells(
const VertexHandle& _h,
int _max_laps = 1)
const {
182 return std::make_pair(begin, make_end_circulator(begin));
189 std::pair<HalfEdgeHalfFaceIter, HalfEdgeHalfFaceIter> halfedge_halffaces(
const HalfEdgeHandle& _h,
int _max_laps = 1)
const {
191 return std::make_pair(begin, make_end_circulator(begin));
198 std::pair<HalfEdgeFaceIter, HalfEdgeFaceIter> halfedge_faces(
const HalfEdgeHandle& _h,
int _max_laps = 1)
const {
200 return std::make_pair(begin, make_end_circulator(begin));
207 std::pair<HalfEdgeCellIter, HalfEdgeCellIter> halfedge_cells(
const HalfEdgeHandle& _h,
int _max_laps = 1)
const {
209 return std::make_pair(begin, make_end_circulator(begin));
216 std::pair<EdgeHalfFaceIter, EdgeHalfFaceIter> edge_halffaces(
const EdgeHandle& _h,
int _max_laps = 1)
const {
218 return std::make_pair(begin, make_end_circulator(begin));
225 std::pair<EdgeFaceIter, EdgeFaceIter> edge_faces(
const EdgeHandle& _h,
int _max_laps = 1)
const {
227 return std::make_pair(begin, make_end_circulator(begin));
234 std::pair<EdgeCellIter, EdgeCellIter> edge_cells(
const EdgeHandle& _h,
int _max_laps = 1)
const {
236 return std::make_pair(begin, make_end_circulator(begin));
243 std::pair<HalfFaceHalfEdgeIter, HalfFaceHalfEdgeIter> halfface_halfedges(
const HalfFaceHandle& _h,
int _max_laps = 1)
const {
245 return std::make_pair(begin, make_end_circulator(begin));
252 std::pair<HalfFaceEdgeIter, HalfFaceEdgeIter> halfface_edges(
const HalfFaceHandle& _h,
int _max_laps = 1)
const {
254 return std::make_pair(begin, make_end_circulator(begin));
261 std::pair<FaceVertexIter, FaceVertexIter> face_vertices(
const FaceHandle& _h,
int _max_laps = 1)
const {
263 return std::make_pair(begin, make_end_circulator(begin));
270 std::pair<FaceHalfEdgeIter, FaceHalfEdgeIter> face_halfedges(
const FaceHandle& _h,
int _max_laps = 1)
const {
272 return std::make_pair(begin, make_end_circulator(begin));
279 std::pair<FaceEdgeIter, FaceEdgeIter> face_edges(
const FaceHandle& _h,
int _max_laps = 1)
const {
281 return std::make_pair(begin, make_end_circulator(begin));
288 std::pair<CellVertexIter, CellVertexIter> cell_vertices(
const CellHandle& _h,
int _max_laps = 1)
const {
290 return std::make_pair(begin, make_end_circulator(begin));
297 std::pair<CellHalfEdgeIter, CellHalfEdgeIter> cell_halfedges(
const CellHandle& _h,
int _max_laps = 1)
const {
299 return std::make_pair(begin, make_end_circulator(begin));
306 std::pair<CellEdgeIter, CellEdgeIter> cell_edges(
const CellHandle& _h,
int _max_laps = 1)
const {
308 return std::make_pair(begin, make_end_circulator(begin));
315 std::pair<CellHalfFaceIter, CellHalfFaceIter> cell_halffaces(
const CellHandle& _h,
int _max_laps = 1)
const {
317 return std::make_pair(begin, make_end_circulator(begin));
324 std::pair<CellFaceIter, CellFaceIter> cell_faces(
const CellHandle& _h,
int _max_laps = 1)
const {
326 return std::make_pair(begin, make_end_circulator(begin));
333 std::pair<CellCellIter, CellCellIter> cell_cells(
const CellHandle& _h,
int _max_laps = 1)
const {
335 return std::make_pair(begin, make_end_circulator(begin));
342 std::pair<HalfFaceVertexIter, HalfFaceVertexIter> halfface_vertices(
const HalfFaceHandle& _h,
int _max_laps = 1)
const {
344 return std::make_pair(begin, make_end_circulator(begin));
351 std::pair<BoundaryHalfFaceHalfFaceIter, BoundaryHalfFaceHalfFaceIter> boundary_halfface_halffaces(
const HalfFaceHandle& _h,
int _max_laps = 1)
const {
353 return std::make_pair(begin, make_end_circulator(begin));
396 std::pair<VertexIter, VertexIter> vertices()
const {
397 return std::make_pair(vertices_begin(), vertices_end());
412 std::pair<EdgeIter, EdgeIter> edges()
const {
413 return std::make_pair(edges_begin(), edges_end());
428 std::pair<HalfEdgeIter, HalfEdgeIter> halfedges()
const {
429 return std::make_pair(halfedges_begin(), halfedges_end());
444 std::pair<FaceIter, FaceIter> faces()
const {
445 return std::make_pair(faces_begin(), faces_end());
460 std::pair<HalfFaceIter, HalfFaceIter> halffaces()
const {
461 return std::make_pair(halffaces_begin(), halffaces_end());
476 std::pair<CellIter, CellIter> cells()
const {
477 return std::make_pair(cells_begin(), cells_end());
484 std::vector<VertexHandle> halfedge_vertices(
const HalfEdgeHandle& _h)
const {
485 std::vector<VertexHandle> res(2);
486 res[0] = from_vertex_handle(_h);
487 res[1] = to_vertex_handle(_h);
491 std::vector<VertexHandle> edge_vertices(
const EdgeHandle& _h)
const {
492 return halfedge_vertices(halfedge_handle(_h, 0));
495 std::vector<HalfEdgeHandle> edge_halfedges(
const EdgeHandle& _h)
const {
496 std::vector<HalfEdgeHandle> res(2);
497 res[0] = halfedge_handle(_h, 0);
498 res[1] = halfedge_handle(_h, 1);
502 std::vector<HalfFaceHandle> face_halffaces(
const FaceHandle& _h)
const {
503 std::vector<HalfFaceHandle> res(2);
504 res[0] = halfface_handle(_h, 0);
505 res[1] = halfface_handle(_h, 1);
509 std::vector<CellHandle> face_cells(
const FaceHandle& _h)
const {
510 std::vector<CellHandle> res(2);
511 res[0] = incident_cell(halfface_handle(_h, 0));
512 res[1] = incident_cell(halfface_handle(_h, 1));
523 size_t n_edges()
const override {
return edges_.size(); }
525 size_t n_halfedges()
const override {
return edges_.size() * 2u; }
527 size_t n_faces()
const override {
return faces_.size(); }
529 size_t n_halffaces()
const override {
return faces_.size() * 2u; }
531 size_t n_cells()
const override {
return cells_.size(); }
548 int g = (1 - (int)(n_vertices() -
553 if(g % 2 == 0)
return (g / 2);
563 size_t n_vertices_ = 0u;
582 virtual FaceHandle add_face(
const std::vector<HalfEdgeHandle>& _halfedges,
bool _topologyCheck =
false);
585 virtual FaceHandle add_face(
const std::vector<VertexHandle>& _vertices);
594 virtual CellHandle add_cell(
const std::vector<HalfFaceHandle>& _halffaces,
bool _topologyCheck =
false);
600 void set_face(
const FaceHandle& _fh,
const std::vector<HalfEdgeHandle>& _hes);
603 void set_cell(
const CellHandle& _ch,
const std::vector<HalfFaceHandle>& _hfs);
610 const Edge& edge(
const EdgeHandle& _edgeHandle)
const;
613 const Face& face(
const FaceHandle& _faceHandle)
const;
616 const Cell& cell(
const CellHandle& _cellHandle)
const;
634 Edge opposite_halfedge(
const HalfEdgeHandle& _halfEdgeHandle)
const;
637 Face opposite_halfface(
const HalfFaceHandle& _halfFaceHandle)
const;
645 HalfFaceHandle halfface(
const std::vector<VertexHandle>& _vs)
const;
650 HalfFaceHandle halfface_extensive(
const std::vector<VertexHandle>& _vs)
const;
655 HalfFaceHandle halfface(
const std::vector<HalfEdgeHandle>& _hes)
const;
665 return halfedge(_h).from_vertex();
670 return halfedge(_h).to_vertex();
675 assert(has_vertex_bottom_up_incidences());
676 assert(_vh.is_valid() && _vh.
uidx() < outgoing_hes_per_vertex_.size());
678 return outgoing_hes_per_vertex_[_vh.
uidx()].size();
683 assert(has_edge_bottom_up_incidences());
684 assert(_eh.is_valid() && _eh.
uidx() < edges_.size());
685 assert(halfedge_handle(_eh, 0).uidx() < incident_hfs_per_he_.size());
687 return incident_hfs_per_he_[halfedge_handle(_eh, 0).uidx()].size();
692 assert(_fh.is_valid() && _fh.
uidx() < faces_.size());
694 return face(_fh).halfedges().size();
699 assert(_ch.is_valid() && _ch.
uidx() < cells_.size());
701 return cell(_ch).halffaces().size();
718 virtual void collect_garbage();
721 virtual bool is_deleted(
const VertexHandle& _h)
const {
return vertex_deleted_[_h.
uidx()]; }
722 virtual bool is_deleted(
const EdgeHandle& _h)
const {
return edge_deleted_[_h.
uidx()]; }
723 virtual bool is_deleted(
const HalfEdgeHandle& _h)
const {
return edge_deleted_[_h.
uidx()/2]; }
724 virtual bool is_deleted(
const FaceHandle& _h)
const {
return face_deleted_[_h.
uidx()]; }
725 virtual bool is_deleted(
const HalfFaceHandle& _h)
const {
return face_deleted_[_h.
uidx()/2]; }
726 virtual bool is_deleted(
const CellHandle& _h)
const {
return cell_deleted_[_h.
uidx()]; }
730 template <
class ContainerT>
731 void get_incident_edges(
const ContainerT& _vs, std::set<EdgeHandle>& _es)
const;
733 template <
class ContainerT>
734 void get_incident_faces(
const ContainerT& _es, std::set<FaceHandle>& _fs)
const;
736 template <
class ContainerT>
737 void get_incident_cells(
const ContainerT& _fs, std::set<CellHandle>& _cs)
const;
763 virtual void delete_multiple_vertices(
const std::vector<bool>& _tag);
765 virtual void delete_multiple_edges(
const std::vector<bool>& _tag);
767 virtual void delete_multiple_faces(
const std::vector<bool>& _tag);
769 virtual void delete_multiple_cells(
const std::vector<bool>& _tag);
773 explicit EdgeCorrector(
const std::vector<int>& _newIndices) :
774 newIndices_(_newIndices) {}
776 void operator()(Edge& _edge) {
777 _edge.set_from_vertex(
VertexHandle(newIndices_[_edge.from_vertex().
uidx()]));
781 const std::vector<int>& newIndices_;
786 explicit FaceCorrector(
const std::vector<int>& _newIndices) :
787 newIndices_(_newIndices) {}
789 void operator()(Face& _face) {
790 std::vector<HalfEdgeHandle> hes = _face.halfedges();
791 for(std::vector<HalfEdgeHandle>::iterator he_it = hes.begin(),
792 he_end = hes.end(); he_it != he_end; ++he_it) {
795 unsigned char opp = he_it->idx() == halfedge_handle(eh, 1).idx();
796 *he_it = halfedge_handle(
EdgeHandle(newIndices_[eh.
uidx()]), opp);
798 _face.set_halfedges(hes);
801 const std::vector<int>& newIndices_;
806 explicit CellCorrector(
const std::vector<int>& _newIndices) :
807 newIndices_(_newIndices) {}
809 void operator()(Cell& _cell) {
810 std::vector<HalfFaceHandle> hfs = _cell.halffaces();
811 for(std::vector<HalfFaceHandle>::iterator hf_it = hfs.begin(),
812 hf_end = hfs.end(); hf_it != hf_end; ++hf_it) {
815 unsigned char opp = hf_it->idx() == halfface_handle(fh, 1).idx();
816 *hf_it = halfface_handle(
FaceHandle(newIndices_[fh.
uidx()]), opp);
818 _cell.set_halffaces(hfs);
821 const std::vector<int>& newIndices_;
839 virtual void clear(
bool _clearProps =
true) {
844 vertex_deleted_.clear();
845 edge_deleted_.clear();
846 face_deleted_.clear();
847 cell_deleted_.clear();
848 n_deleted_vertices_ = 0;
849 n_deleted_edges_ = 0;
850 n_deleted_faces_ = 0;
851 n_deleted_cells_ = 0;
852 outgoing_hes_per_vertex_.clear();
853 incident_hfs_per_he_.clear();
854 incident_cell_per_hf_.clear();
860 clear_vertex_props();
862 clear_halfedge_props();
864 clear_halfface_props();
883 void enable_bottom_up_incidences(
bool _enable =
true) {
885 enable_vertex_bottom_up_incidences(_enable);
886 enable_edge_bottom_up_incidences(_enable);
887 enable_face_bottom_up_incidences(_enable);
890 void enable_vertex_bottom_up_incidences(
bool _enable =
true) {
892 if(_enable && !v_bottom_up_) {
895 compute_vertex_bottom_up_incidences();
899 outgoing_hes_per_vertex_.clear();
902 v_bottom_up_ = _enable;
905 void enable_edge_bottom_up_incidences(
bool _enable =
true) {
907 if(_enable && !e_bottom_up_) {
910 compute_edge_bottom_up_incidences();
913 #if defined(__clang_major__) && (__clang_major__ >= 5) 914 for(
EdgeIter e_it = edges_begin(), e_end = edges_end();
915 e_it != e_end; ++e_it) {
916 reorder_incident_halffaces(*e_it);
919 std::for_each(edges_begin(), edges_end(),
920 fun::bind(&TopologyKernel::reorder_incident_halffaces,
this, fun::placeholders::_1));
926 incident_hfs_per_he_.clear();
929 e_bottom_up_ = _enable;
932 void enable_face_bottom_up_incidences(
bool _enable =
true) {
934 bool updateOrder =
false;
935 if(_enable && !f_bottom_up_) {
938 compute_face_bottom_up_incidences();
944 incident_cell_per_hf_.clear();
947 f_bottom_up_ = _enable;
951 #if defined(__clang_major__) && (__clang_major__ >= 5) 952 for(
EdgeIter e_it = edges_begin(), e_end = edges_end();
953 e_it != e_end; ++e_it) {
954 reorder_incident_halffaces(*e_it);
957 std::for_each(edges_begin(), edges_end(),
958 fun::bind(&TopologyKernel::reorder_incident_halffaces,
this, fun::placeholders::_1));
964 bool has_full_bottom_up_incidences()
const {
965 return (has_vertex_bottom_up_incidences() &&
966 has_edge_bottom_up_incidences() &&
967 has_face_bottom_up_incidences());
970 bool has_vertex_bottom_up_incidences()
const {
return v_bottom_up_; }
972 bool has_edge_bottom_up_incidences()
const {
return e_bottom_up_; }
974 bool has_face_bottom_up_incidences()
const {
return f_bottom_up_; }
977 void enable_deferred_deletion(
bool _enable =
true);
978 bool deferred_deletion_enabled()
const {
return deferred_deletion; }
981 void enable_fast_deletion(
bool _enable =
true) { fast_deletion = _enable; }
982 bool fast_deletion_enabled()
const {
return fast_deletion; }
987 void compute_vertex_bottom_up_incidences();
989 void compute_edge_bottom_up_incidences();
991 void compute_face_bottom_up_incidences();
993 void reorder_incident_halffaces(
const EdgeHandle& _eh);
996 std::vector<std::vector<HalfEdgeHandle> > outgoing_hes_per_vertex_;
999 std::vector<std::vector<HalfFaceHandle> > incident_hfs_per_he_;
1002 std::vector<CellHandle> incident_cell_per_hf_;
1005 bool v_bottom_up_ =
true;
1007 bool e_bottom_up_ =
true;
1009 bool f_bottom_up_ =
true;
1011 bool deferred_deletion =
true;
1013 bool fast_deletion =
true;
1034 assert(_halfFaceHandle.is_valid() && _halfFaceHandle.
uidx() < faces_.size() * 2u);
1035 assert(has_face_bottom_up_incidences());
1036 assert(_halfFaceHandle.
uidx() < incident_cell_per_hf_.size());
1037 return incident_cell_per_hf_[_halfFaceHandle.
uidx()] == InvalidCellHandle;
1040 bool is_boundary(
const FaceHandle& _faceHandle)
const {
1041 assert(_faceHandle.is_valid() && _faceHandle.
uidx() < faces_.size());
1042 assert(has_face_bottom_up_incidences());
1043 return is_boundary(halfface_handle(_faceHandle, 0)) ||
1044 is_boundary(halfface_handle(_faceHandle, 1));
1047 bool is_boundary(
const EdgeHandle& _edgeHandle)
const {
1048 assert(has_edge_bottom_up_incidences());
1049 assert(_edgeHandle.is_valid() && _edgeHandle.
uidx() < edges_.size());
1052 hehf_it.valid(); ++hehf_it) {
1053 if(is_boundary(face_handle(*hehf_it))) {
1061 assert(has_edge_bottom_up_incidences());
1062 assert(_halfedgeHandle.is_valid() && _halfedgeHandle.
uidx() < edges_.size() * 2u);
1065 hehf_it.valid(); ++hehf_it) {
1066 if(is_boundary(face_handle(*hehf_it))) {
1073 bool is_boundary(
const VertexHandle& _vertexHandle)
const {
1074 assert(has_vertex_bottom_up_incidences());
1075 assert(_vertexHandle.is_valid() && _vertexHandle.
uidx() < n_vertices());
1078 if(is_boundary(*voh_it))
return true;
1083 bool is_boundary(
const CellHandle& _cellHandle)
const {
1084 assert(_cellHandle.is_valid() && (size_t)_cellHandle.idx() < n_cells());
1086 for(
CellFaceIter cf_it = cf_iter(_cellHandle); cf_it.valid(); ++cf_it) {
1087 if(is_boundary(*cf_it))
return true;
1092 size_t n_vertices_in_cell(
const CellHandle& _ch)
const {
1093 assert(_ch.is_valid() && _ch.
uidx() < cells_.size());
1095 std::set<VertexHandle> vhs;
1096 std::vector<HalfFaceHandle> hfs = cell(_ch).halffaces();
1097 for(std::vector<HalfFaceHandle>::const_iterator hf_it = hfs.begin();
1098 hf_it != hfs.end(); ++hf_it) {
1099 std::vector<HalfEdgeHandle> hes = halfface(*hf_it).halfedges();
1100 for(std::vector<HalfEdgeHandle>::const_iterator he_it = hes.begin();
1101 he_it != hes.end(); ++he_it) {
1102 vhs.insert(halfedge(*he_it).to_vertex());
1114 Edge opposite_halfedge(
const Edge& _edge)
const {
1115 return Edge(_edge.to_vertex(), _edge.from_vertex());
1118 Face opposite_halfface(
const Face& _face)
const {
1119 std::vector<HalfEdgeHandle> opp_halfedges;
1120 for(std::vector<HalfEdgeHandle>::const_iterator it = _face.halfedges().begin(); it
1121 != _face.halfedges().end(); ++it) {
1122 opp_halfedges.insert(opp_halfedges.begin(), opposite_halfedge_handle(*it));
1125 return Face(opp_halfedges);
1135 assert(_h.is_valid());
1136 assert(_subIdx < 2);
1144 assert(_h.is_valid());
1145 assert(_subIdx < 2);
1153 assert(_h.is_valid());
1160 assert(_h.is_valid());
1167 assert(_h.is_valid());
1171 if(_h.idx() % 2 == 0) {
1179 assert(_h.is_valid());
1183 if(_h.idx() % 2 == 0) {
1189 bool inline needs_garbage_collection()
const {
1190 return n_deleted_vertices_ > 0 || n_deleted_edges_ > 0 || n_deleted_faces_ > 0 || n_deleted_cells_ > 0;
1196 std::vector<Edge> edges_;
1199 std::vector<Face> faces_;
1202 std::vector<Cell> cells_;
1204 std::vector<bool> vertex_deleted_;
1205 std::vector<bool> edge_deleted_;
1206 std::vector<bool> face_deleted_;
1207 std::vector<bool> cell_deleted_;
1210 size_t n_deleted_vertices_ = 0;
1211 size_t n_deleted_edges_ = 0;
1212 size_t n_deleted_faces_ = 0;
1213 size_t n_deleted_cells_ = 0;
size_t n_edges() const override
Get number of edges in mesh.
size_t valence(const VertexHandle &_vh) const
Get valence of vertex (number of incident edges)
virtual void clear(bool _clearProps=true)
Clear whole mesh.
size_t n_logical_halffaces() const
Get number of undeleted halffaces in mesh.
size_t n_cells() const override
Get number of cells in mesh.
size_t n_logical_cells() const
Get number of undeleted cells in mesh.
size_t uidx() const
return unsigned idx - handle must be valid
VertexHandle to_vertex_handle(const HalfEdgeHandle &_h) const
Get the vertex the halfedge points to.
size_t n_logical_vertices() const
Get number of undeleted vertices in mesh.
static EdgeHandle edge_handle(const HalfEdgeHandle &_h)
Handle conversion.
size_t valence(const EdgeHandle &_eh) const
Get valence of edge (number of incident faces)
static HalfFaceHandle halfface_handle(const FaceHandle &_h, const unsigned char _subIdx)
Conversion function.
size_t n_faces() const override
Get number of faces in mesh.
size_t n_vertices() const override
Get number of vertices in mesh.
size_t valence(const CellHandle &_ch) const
Get valence of cell (number of incident faces)
size_t valence(const FaceHandle &_fh) const
Get valence of face (number of incident edges)
bool bind(osg::GeometryPtr &_geo, Mesh &_mesh)
VertexHandle from_vertex_handle(const HalfEdgeHandle &_h) const
Get the vertex the halfedge starts from.
size_t n_logical_faces() const
Get number of undeleted faces in mesh.
size_t n_halffaces() const override
Get number of halffaces in mesh.
size_t n_logical_edges() const
Get number of undeleted edges in mesh.
size_t n_logical_halfedges() const
Get number of undeleted halfedges in mesh.
static HalfEdgeHandle halfedge_handle(const EdgeHandle &_h, const unsigned char _subIdx)
Conversion function.
size_t n_halfedges() const override
Get number of halfedges in mesh.