43 #include "TetrahedralMeshTopologyKernel.hh"
50 TetrahedralMeshTopologyKernel::TetrahedralMeshTopologyKernel() {
57 TetrahedralMeshTopologyKernel::~TetrahedralMeshTopologyKernel() {
66 if(_halfedges.size() != 3) {
68 std::cerr <<
"TetrahedralMeshTopologyKernel::add_face(): Face valence is not three! Returning" << std::endl;
69 std::cerr <<
"invalid handle." << std::endl;
71 return TopologyKernel::InvalidFaceHandle;
83 if(_vertices.size() != 3) {
85 std::cerr <<
"TetrahedralMeshTopologyKernel::add_face(): Face valence is not three! Returning" << std::endl;
86 std::cerr <<
"invalid handle." << std::endl;
88 return TopologyKernel::InvalidFaceHandle;
100 if(_halffaces.size() != 4) {
103 std::cerr <<
"Cell valence is not four! Aborting." << std::endl;
105 return TopologyKernel::InvalidCellHandle;
107 for(std::vector<HalfFaceHandle>::const_iterator it = _halffaces.begin();
108 it != _halffaces.end(); ++it) {
111 std::cerr <<
"Incident face does not have valence three! Aborting." << std::endl;
113 return TopologyKernel::InvalidCellHandle;
124 if (he != InvalidHalfEdgeHandle)
130 HalfFaceHandle TetrahedralMeshTopologyKernel::add_halfface(
const std::vector<HalfEdgeHandle>& _halfedges,
bool _topologyCheck)
132 HalfFaceHandle hf =
halfface(_halfedges);
133 if (hf != InvalidHalfFaceHandle)
139 HalfFaceHandle TetrahedralMeshTopologyKernel::add_halfface(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2,
bool _topologyCheck)
141 std::vector<HalfEdgeHandle> halfedges;
142 halfedges.push_back(add_halfedge(_vh0, _vh1));
143 halfedges.push_back(add_halfedge(_vh1, _vh2));
144 halfedges.push_back(add_halfedge(_vh2, _vh0));
145 return add_halfface(halfedges, _topologyCheck);
333 VertexHandle TetrahedralMeshTopologyKernel::collapse_edge(HalfEdgeHandle _heh)
335 bool deferred_deletion_tmp = deferred_deletion_enabled();
337 if (!deferred_deletion_tmp)
338 enable_deferred_deletion(
true);
340 VertexHandle from_vh =
halfedge(_heh).from_vertex();
341 VertexHandle to_vh =
halfedge(_heh).to_vertex();
345 std::set<CellHandle> collapsingCells;
346 for (HalfEdgeHalfFaceIter hehf_it = hehf_iter(_heh); hehf_it.valid(); ++hehf_it)
348 HalfFaceHandle hfh = *hehf_it;
351 collapsingCells.insert(ch);
354 std::vector<CellHandle> incidentCells;
355 for (VertexCellIter vc_it = vc_iter(from_vh); vc_it.valid(); ++vc_it)
356 incidentCells.push_back(*vc_it);
358 for (
unsigned int i = 0; i < incidentCells.size(); ++i)
360 CellHandle ch = incidentCells[i];
362 if (collapsingCells.find(ch) != collapsingCells.end())
367 std::vector<HalfFaceHandle> newHalffaces;
369 for (
unsigned int i = 0; i < 4; ++i)
371 Face hf =
halfface(c.halffaces()[i]);
372 std::vector<HalfEdgeHandle> newHalfedges;
374 for (
unsigned int j = 0; j < 3; ++j)
376 Edge e =
halfedge(hf.halfedges()[j]);
377 VertexHandle newStart = (e.from_vertex() == from_vh) ? to_vh: e.from_vertex();
378 VertexHandle newEnd = (e.to_vertex() == from_vh) ? to_vh : e.to_vertex();
380 HalfEdgeHandle heh = add_halfedge(newStart, newEnd);
381 newHalfedges.push_back(heh);
382 swap_halfedge_properties(hf.halfedges()[j], heh);
385 HalfFaceHandle hfh = add_halfface(newHalfedges);
386 newHalffaces.push_back(hfh);
387 swap_halfface_properties(c.halffaces()[i], hfh);
392 CellHandle newCell =
add_cell(newHalffaces);
394 swap_cell_properties(ch, newCell);
399 VertexHandle survivingVertex = to_vh;
401 if (!deferred_deletion_tmp)
403 if (fast_deletion_enabled())
407 survivingVertex = from_vh;
412 if (from_vh.idx() < to_vh.idx())
413 survivingVertex = VertexHandle(to_vh.idx() - 1);
419 enable_deferred_deletion(deferred_deletion_tmp);
421 return survivingVertex;
425 void TetrahedralMeshTopologyKernel::split_edge(HalfEdgeHandle _heh, VertexHandle _vh)
427 bool deferred_deletion_tmp = deferred_deletion_enabled();
429 if (!deferred_deletion_tmp)
430 enable_deferred_deletion(
true);
432 for (HalfEdgeHalfFaceIter hehf_it = hehf_iter(_heh); hehf_it.valid(); ++hehf_it)
437 std::vector<VertexHandle> vertices = get_cell_vertices(*hehf_it, _heh);
441 add_cell(vertices[0], _vh, vertices[2], vertices[3]);
442 add_cell(_vh, vertices[1], vertices[2], vertices[3]);
449 enable_deferred_deletion(deferred_deletion_tmp);
453 void TetrahedralMeshTopologyKernel::split_face(FaceHandle _fh, VertexHandle _vh)
455 bool deferred_deletion_tmp = deferred_deletion_enabled();
457 if (!deferred_deletion_tmp)
458 enable_deferred_deletion(
true);
460 for (
unsigned int i = 0; i < 2; ++i)
466 std::vector<VertexHandle> vertices = get_cell_vertices(hfh);
470 add_cell(vertices[0], vertices[1], _vh, vertices[3]);
471 add_cell(vertices[0], _vh, vertices[2], vertices[3]);
472 add_cell(_vh, vertices[1], vertices[2], vertices[3]);
478 enable_deferred_deletion(deferred_deletion_tmp);
483 std::vector<VertexHandle> TetrahedralMeshTopologyKernel::get_cell_vertices(CellHandle ch)
const
485 return get_cell_vertices(
cell(ch).halffaces().front());
488 std::vector<VertexHandle> TetrahedralMeshTopologyKernel::get_cell_vertices(CellHandle ch, VertexHandle vh)
const
490 HalfFaceHandle hfh =
cell(ch).halffaces()[0];
493 for (
unsigned int i = 0; i < 3; ++i)
495 Edge e =
halfedge(f.halfedges()[i]);
496 if (e.from_vertex() == vh)
498 heh = f.halfedges()[i];
508 return get_cell_vertices(hfh,heh);
512 std::vector<VertexHandle> TetrahedralMeshTopologyKernel::get_cell_vertices(HalfFaceHandle hfh)
const
514 return get_cell_vertices(hfh,
halfface(hfh).halfedges().front());
517 std::vector<VertexHandle> TetrahedralMeshTopologyKernel::get_cell_vertices(HalfFaceHandle hfh, HalfEdgeHandle heh)
const
519 std::vector<VertexHandle> vertices;
522 for (
unsigned int i = 0; i < 3; ++i)
525 vertices.push_back(e.from_vertex());
530 HalfFaceHandle otherHfh = c.halffaces()[0];
532 otherHfh = c.halffaces()[1];
536 for (
unsigned int i = 0; i < otherF.halfedges().size(); ++i)
538 HalfEdgeHandle he = otherF.halfedges()[i];
540 if (std::find(vertices.begin(), vertices.end(), e.to_vertex()) == vertices.end())
542 vertices.push_back(e.to_vertex());
550 std::vector<VertexHandle> TetrahedralMeshTopologyKernel::get_halfface_vertices(HalfFaceHandle hfh)
const
552 return get_halfface_vertices(hfh,
halfface(hfh).halfedges().front());
555 std::vector<VertexHandle> TetrahedralMeshTopologyKernel::get_halfface_vertices(HalfFaceHandle hfh, VertexHandle vh)
const
558 for (
unsigned int i = 0; i < 3; ++i)
559 if (
halfedge(hf.halfedges()[i]).from_vertex() == vh)
560 return get_halfface_vertices(hfh, hf.halfedges()[i]);
562 return std::vector<VertexHandle>();
565 std::vector<VertexHandle> TetrahedralMeshTopologyKernel::get_halfface_vertices(HalfFaceHandle hfh, HalfEdgeHandle heh)
const
567 std::vector<VertexHandle> vertices;
570 for (
unsigned int i = 0; i < 3; ++i)
573 vertices.push_back(e.from_vertex());
587 assert(TopologyKernel::has_full_bottom_up_incidences());
588 assert(_vertices.size() == 4);
591 if(!TopologyKernel::has_full_bottom_up_incidences()) {
592 return CellHandle(-1);
595 if(_vertices.size() != 4) {
596 return CellHandle(-1);
599 HalfFaceHandle hf0, hf1, hf2, hf3;
601 std::vector<VertexHandle> vs;
603 vs.push_back(_vertices[0]);
604 vs.push_back(_vertices[1]);
605 vs.push_back(_vertices[2]);
607 if(!hf0.is_valid()) {
613 vs.push_back(_vertices[0]);
614 vs.push_back(_vertices[2]);
615 vs.push_back(_vertices[3]);
617 if(!hf1.is_valid()) {
623 vs.push_back(_vertices[0]);
624 vs.push_back(_vertices[3]);
625 vs.push_back(_vertices[1]);
627 if(!hf2.is_valid()) {
633 vs.push_back(_vertices[1]);
634 vs.push_back(_vertices[3]);
635 vs.push_back(_vertices[2]);
637 if(!hf3.is_valid()) {
643 assert(hf0.is_valid());
644 assert(hf1.is_valid());
645 assert(hf2.is_valid());
646 assert(hf3.is_valid());
649 std::vector<HalfFaceHandle> hfs;
655 if (_topologyCheck) {
664 std::set<HalfEdgeHandle> incidentHalfedges;
665 std::set<EdgeHandle> incidentEdges;
667 for(std::vector<HalfFaceHandle>::const_iterator it = hfs.begin(),
668 end = hfs.end(); it != end; ++it) {
670 OpenVolumeMeshFace hface =
halfface(*it);
671 for(std::vector<HalfEdgeHandle>::const_iterator he_it = hface.halfedges().begin(),
672 he_end = hface.halfedges().end(); he_it != he_end; ++he_it) {
673 incidentHalfedges.insert(*he_it);
678 if(incidentHalfedges.size() != (incidentEdges.size() * 2u)) {
680 std::cerr <<
"The specified halffaces are not connected!" << std::endl;
682 return InvalidCellHandle;
686 if(has_face_bottom_up_incidences()) {
688 for(std::vector<HalfFaceHandle>::const_iterator it = hfs.begin(),
689 end = hfs.end(); it != end; ++it) {
692 std::cerr <<
"Warning: One of the specified half-faces is already incident to another cell!" << std::endl;
694 return InvalidCellHandle;
707 std::vector<HalfFaceHandle> halffaces;
708 halffaces.push_back(add_halfface(_vh0, _vh1, _vh2));
709 halffaces.push_back(add_halfface(_vh0, _vh2, _vh3));
710 halffaces.push_back(add_halfface(_vh0, _vh3, _vh1));
711 halffaces.push_back(add_halfface(_vh1, _vh3, _vh2));
712 return add_cell(halffaces, _topologyCheck);
HalfFaceHandle adjacent_halfface_in_cell(const HalfFaceHandle &_halfFaceHandle, const HalfEdgeHandle &_halfEdgeHandle) const
Get halfface that is adjacent (w.r.t. a common halfedge) within the same cell.
Edge halfedge(const HalfEdgeHandle &_halfEdgeHandle) const
Get edge that corresponds to halfedge with handle _halfEdgeHandle.
virtual size_t n_vertices() const
Get number of vertices in mesh.
virtual EdgeHandle add_edge(const VertexHandle &_fromVertex, const VertexHandle &_toHandle, bool _allowDuplicates=false)
Add edge.
virtual CellIter delete_cell(const CellHandle &_h)
Delete cell from mesh.
CellHandle incident_cell(const HalfFaceHandle &_halfFaceHandle) const
Get cell that is incident to the given halfface.
virtual FaceHandle add_face(const std::vector< HalfEdgeHandle > &_halfedges, bool _topologyCheck=false)
Add face via incident edges.
virtual CellHandle add_cell(const std::vector< HalfFaceHandle > &_halffaces, bool _topologyCheck=false)
Add cell via incident halffaces.
const Cell & cell(const CellHandle &_cellHandle) const
Get cell with handle _cellHandle.
Face halfface(const HalfFaceHandle &_halfFaceHandle) const
Get face that corresponds to halfface with handle _halfFaceHandle.
virtual CellHandle add_cell(const std::vector< HalfFaceHandle > &_halffaces, bool _topologyCheck=false)
Add cell via incident halffaces.
virtual EdgeIter delete_edge(const EdgeHandle &_h)
Delete edge from mesh.
static HalfEdgeHandle halfedge_handle(const EdgeHandle &_h, const unsigned char _subIdx)
Conversion function.
HalfEdgeHandle prev_halfedge_in_halfface(const HalfEdgeHandle &_heh, const HalfFaceHandle &_hfh) const
Get previous halfedge within a halfface.
static HalfFaceHandle halfface_handle(const FaceHandle &_h, const unsigned char _subIdx)
Conversion function.
static EdgeHandle edge_handle(const HalfEdgeHandle &_h)
Handle conversion.
virtual FaceHandle add_face(const std::vector< HalfEdgeHandle > &_halfedges, bool _topologyCheck=false)
Add face via incident edges.
virtual FaceIter delete_face(const FaceHandle &_h)
Delete face from mesh.
HalfEdgeHandle next_halfedge_in_halfface(const HalfEdgeHandle &_heh, const HalfFaceHandle &_hfh) const
Get next halfedge within a halfface.
virtual VertexIter delete_vertex(const VertexHandle &_h)
Delete vertex from mesh.