43 #ifndef TOPOLOGYKERNEL_HH_
44 #define TOPOLOGYKERNEL_HH_
51 #include "BaseEntities.hh"
52 #include "OpenVolumeMeshHandle.hh"
53 #include "ResourceManager.hh"
54 #include "Iterators.hh"
56 namespace OpenVolumeMesh {
217 virtual unsigned int n_vertices()
const {
return n_vertices_; }
219 virtual unsigned int n_edges()
const {
return edges_.size(); }
221 virtual unsigned int n_halfedges()
const {
return edges_.size() * 2u; }
223 virtual unsigned int n_faces()
const {
return faces_.size(); }
225 virtual unsigned int n_halffaces()
const {
return faces_.size() * 2u; }
227 virtual unsigned int n_cells()
const {
return cells_.size(); }
232 unsigned int n_vertices_;
245 virtual FaceHandle add_face(
const std::vector<HalfEdgeHandle>& _halfedges,
bool _topologyCheck =
false);
251 virtual CellHandle add_cell(
const std::vector<HalfFaceHandle>& _halffaces,
bool _topologyCheck =
false);
316 std::cerr <<
"Could not get vertex valence: No bottom-up incidences for vertices available!" << std::endl;
319 assert((
unsigned int)_vh.idx() < outgoing_hes_per_vertex_.size());
320 return outgoing_hes_per_vertex_[_vh.idx()].size();
326 std::cerr <<
"Could not get edge valence: No bottom-up incidences for edges available!" << std::endl;
329 assert((
unsigned int)
halfedge_handle(_eh, 0).idx() < incident_hfs_per_he_.size());
336 assert((
unsigned int)_fh.idx() < faces_.size());
337 return face(_fh).halfedges().size();
343 assert((
unsigned int)_ch.idx() < cells_.size());
344 return cell(_ch).halffaces().size();
363 virtual void delete_multiple_vertices(
const std::vector<bool>& _tag);
365 virtual void delete_multiple_edges(
const std::vector<bool>& _tag);
367 virtual void delete_multiple_faces(
const std::vector<bool>& _tag);
369 virtual void delete_multiple_cells(
const std::vector<bool>& _tag);
374 newIndices_(_newIndices) {}
376 void operator()(
Edge& _edge) {
377 _edge.set_from_vertex(
VertexHandle(newIndices_[_edge.from_vertex().idx()]));
378 _edge.set_to_vertex(
VertexHandle(newIndices_[_edge.to_vertex().idx()]));
381 const std::vector<int>& newIndices_;
387 newIndices_(_newIndices) {}
389 void operator()(
Face& _face) {
390 std::vector<HalfEdgeHandle> hes = _face.halfedges();
391 for(std::vector<HalfEdgeHandle>::iterator he_it = hes.begin(),
392 he_end = hes.end(); he_it != he_end; ++he_it) {
398 _face.set_halfedges(hes);
401 const std::vector<int>& newIndices_;
407 newIndices_(_newIndices) {}
409 void operator()(
Cell& _cell) {
410 std::vector<HalfFaceHandle> hfs = _cell.halffaces();
411 for(std::vector<HalfFaceHandle>::iterator hf_it = hfs.begin(),
412 hf_end = hfs.end(); hf_it != hf_end; ++hf_it) {
418 _cell.set_halffaces(hfs);
421 const std::vector<int>& newIndices_;
439 virtual void clear(
bool _clearProps =
true) {
444 outgoing_hes_per_vertex_.clear();
445 incident_hfs_per_he_.clear();
446 incident_cell_per_hf_.clear();
452 clear_vertex_props();
454 clear_halfedge_props();
456 clear_halfface_props();
475 void enable_bottom_up_incidences(
bool _enable =
true) {
477 enable_vertex_bottom_up_incidences(_enable);
478 enable_edge_bottom_up_incidences(_enable);
479 enable_face_bottom_up_incidences(_enable);
482 void enable_vertex_bottom_up_incidences(
bool _enable =
true) {
484 if(_enable && !v_bottom_up_) {
487 compute_vertex_bottom_up_incidences();
491 outgoing_hes_per_vertex_.clear();
494 v_bottom_up_ = _enable;
497 void enable_edge_bottom_up_incidences(
bool _enable =
true) {
499 if(_enable && !e_bottom_up_) {
502 compute_edge_bottom_up_incidences();
505 std::for_each(edges_begin(), edges_end(),
506 fun::bind(&TopologyKernel::reorder_incident_halffaces,
this, fun::placeholders::_1));
511 incident_hfs_per_he_.clear();
514 e_bottom_up_ = _enable;
517 void enable_face_bottom_up_incidences(
bool _enable =
true) {
519 bool updateOrder =
false;
520 if(_enable && !f_bottom_up_) {
523 compute_face_bottom_up_incidences();
529 incident_cell_per_hf_.clear();
532 f_bottom_up_ = _enable;
536 std::for_each(edges_begin(), edges_end(),
537 fun::bind(&TopologyKernel::reorder_incident_halffaces,
this, fun::placeholders::_1));
542 bool has_full_bottom_up_incidences()
const {
543 return (has_vertex_bottom_up_incidences() &&
544 has_edge_bottom_up_incidences() &&
545 has_face_bottom_up_incidences());
548 bool has_vertex_bottom_up_incidences()
const {
return v_bottom_up_; }
550 bool has_edge_bottom_up_incidences()
const {
return e_bottom_up_; }
552 bool has_face_bottom_up_incidences()
const {
return f_bottom_up_; }
556 void compute_vertex_bottom_up_incidences();
558 void compute_edge_bottom_up_incidences();
560 void compute_face_bottom_up_incidences();
562 void reorder_incident_halffaces(
const EdgeHandle& _eh);
565 std::vector<std::vector<HalfEdgeHandle> > outgoing_hes_per_vertex_;
568 std::vector<std::vector<HalfFaceHandle> > incident_hfs_per_he_;
571 std::vector<CellHandle> incident_cell_per_hf_;
586 HalfFaceHandle
adjacent_halfface_in_cell(
const HalfFaceHandle& _halfFaceHandle,
const HalfEdgeHandle& _halfEdgeHandle)
const;
589 CellHandle
incident_cell(
const HalfFaceHandle& _halfFaceHandle)
const;
591 bool is_boundary(
const HalfFaceHandle& _halfFaceHandle)
const {
592 return _halfFaceHandle.idx() >= 0 && (
unsigned int)_halfFaceHandle.idx() < incident_cell_per_hf_.size() &&
593 incident_cell_per_hf_[_halfFaceHandle.idx()] == InvalidCellHandle;
596 bool is_boundary(
const FaceHandle& _faceHandle)
const {
601 bool is_boundary(
const EdgeHandle& _edgeHandle)
const {
603 std::cerr <<
"Error: Function is_boundary() needs bottom-up incidences for edges!" << std::endl;
606 for(HalfEdgeHalfFaceIter hehf_it = hehf_iter(
halfedge_handle(_edgeHandle, 0));
607 hehf_it.valid(); ++hehf_it) {
608 if(is_boundary(face_handle(*hehf_it))) {
615 bool is_boundary(
const HalfEdgeHandle& _halfedgeHandle)
const {
617 std::cerr <<
"Error: Function is_boundary() needs bottom-up incidences for edges!" << std::endl;
620 for(HalfEdgeHalfFaceIter hehf_it = hehf_iter(_halfedgeHandle);
621 hehf_it.valid(); ++hehf_it) {
622 if(is_boundary(face_handle(*hehf_it))) {
629 bool is_boundary(
const VertexHandle& _vertexHandle)
const {
631 std::cerr <<
"Error: Function is_boundary() needs bottom-up incidences for vertices!" << std::endl;
634 for(VertexOHalfEdgeIter voh_it = voh_iter(_vertexHandle); voh_it.valid(); ++voh_it) {
635 if(is_boundary(*voh_it))
return true;
640 unsigned int n_vertices_in_cell(
const CellHandle& _ch)
const {
642 std::set<VertexHandle> vertices;
643 std::vector<HalfFaceHandle> hfs =
cell(_ch).halffaces();
644 for(std::vector<HalfFaceHandle>::const_iterator hf_it = hfs.begin();
645 hf_it != hfs.end(); ++hf_it) {
646 std::vector<HalfEdgeHandle> hes =
halfface(*hf_it).halfedges();
647 for(std::vector<HalfEdgeHandle>::const_iterator he_it = hes.begin();
648 he_it != hes.end(); ++he_it) {
649 vertices.insert(
halfedge(*he_it).to_vertex());
652 return vertices.size();
662 return Edge(_edge.to_vertex(), _edge.from_vertex());
667 std::vector<HalfEdgeHandle> opp_halfedges;
668 for(std::vector<HalfEdgeHandle>::const_iterator it = _face.halfedges().begin(); it
669 != _face.halfedges().end(); ++it) {
670 opp_halfedges.insert(opp_halfedges.begin(), opposite_halfedge_handle(*it));
673 return Face(opp_halfedges);
683 if(_h.idx() < 0 || _subIdx > 1)
return InvalidHalfEdgeHandle;
690 if(_h.idx() < 0 || _subIdx > 1)
return InvalidHalfFaceHandle;
697 if(_h.idx() < 0)
return InvalidEdgeHandle;
703 if(_h.idx() < 0)
return InvalidFaceHandle;
707 static inline HalfEdgeHandle opposite_halfedge_handle(
const HalfEdgeHandle& _h) {
709 if(_h.idx() < 0)
return InvalidHalfEdgeHandle;
712 if(_h.idx() % 2 == 0) {
713 return HalfEdgeHandle(_h.idx() + 1);
715 return HalfEdgeHandle(_h.idx() - 1);
718 static inline HalfFaceHandle opposite_halfface_handle(
const HalfFaceHandle& _h) {
720 if(_h.idx() < 0)
return InvalidHalfFaceHandle;
723 if(_h.idx() % 2 == 0) {
724 return HalfFaceHandle(_h.idx() + 1);
726 return HalfFaceHandle(_h.idx() - 1);
732 std::vector<Edge> edges_;
735 std::vector<Face> faces_;
738 std::vector<Cell> cells_;