35 #include "TetrahedralMeshTopologyKernel.hh" 43 if(_halfedges.size() != 3) {
45 std::cerr <<
"TetrahedralMeshTopologyKernel::add_face(): Face valence is not three! Returning" << std::endl;
46 std::cerr <<
"invalid handle." << std::endl;
48 return TopologyKernel::InvalidFaceHandle;
60 if(_vertices.size() != 3) {
62 std::cerr <<
"TetrahedralMeshTopologyKernel::add_face(): Face valence is not three! Returning" << std::endl;
63 std::cerr <<
"invalid handle." << std::endl;
65 return TopologyKernel::InvalidFaceHandle;
77 if(_halffaces.size() != 4) {
80 std::cerr <<
"Cell valence is not four! Aborting." << std::endl;
82 return TopologyKernel::InvalidCellHandle;
84 for(std::vector<HalfFaceHandle>::const_iterator it = _halffaces.begin();
85 it != _halffaces.end(); ++it) {
88 std::cerr <<
"Incident face does not have valence three! Aborting." << std::endl;
90 return TopologyKernel::InvalidCellHandle;
101 if (he != InvalidHalfEdgeHandle)
107 HalfFaceHandle TetrahedralMeshTopologyKernel::add_halfface(
const std::vector<HalfEdgeHandle>& _halfedges,
bool _topologyCheck)
110 if (hf != InvalidHalfFaceHandle)
118 std::vector<HalfEdgeHandle> halfedges;
119 halfedges.push_back(add_halfedge(_vh0, _vh1));
120 halfedges.push_back(add_halfedge(_vh1, _vh2));
121 halfedges.push_back(add_halfedge(_vh2, _vh0));
122 return add_halfface(halfedges, _topologyCheck);
313 bool deferred_deletion_tmp = deferred_deletion_enabled();
315 if (!deferred_deletion_tmp)
316 enable_deferred_deletion(
true);
323 std::set<CellHandle> collapsingCells;
329 collapsingCells.insert(ch);
332 std::vector<CellHandle> incidentCells;
333 for (
VertexCellIter vc_it = vc_iter(from_vh); vc_it.valid(); ++vc_it)
334 incidentCells.push_back(*vc_it);
338 if (collapsingCells.find(ch) != collapsingCells.end())
343 std::vector<HalfFaceHandle> newHalffaces;
345 for (
unsigned int hf_idx = 0; hf_idx < 4; ++hf_idx)
348 std::vector<HalfEdgeHandle> newHalfedges;
350 for (
unsigned int j = 0; j < 3; ++j)
353 VertexHandle newStart = (e.from_vertex() == from_vh) ? to_vh: e.from_vertex();
354 VertexHandle newEnd = (e.to_vertex() == from_vh) ? to_vh : e.to_vertex();
357 newHalfedges.push_back(heh);
358 swap_halfedge_properties(hf.halfedges()[j], heh);
362 newHalffaces.push_back(hfh);
363 swap_halfface_properties(c.halffaces()[hf_idx], hfh);
370 swap_cell_properties(ch, newCell);
377 if (!deferred_deletion_tmp)
379 if (fast_deletion_enabled())
383 survivingVertex = from_vh;
388 if (from_vh.idx() < to_vh.idx())
395 enable_deferred_deletion(deferred_deletion_tmp);
397 return survivingVertex;
404 bool deferred_deletion_tmp = deferred_deletion_enabled();
406 if (!deferred_deletion_tmp)
407 enable_deferred_deletion(
true);
409 std::vector<HalfFaceHandle> incident_halffaces_with_cells;
414 incident_halffaces_with_cells.push_back(*hehf_it);
417 for (
auto hfh : incident_halffaces_with_cells)
421 std::vector<VertexHandle> vertices = get_cell_vertices(hfh, _heh);
425 add_cell(vertices[0], _vh, vertices[2], vertices[3]);
426 add_cell(_vh, vertices[1], vertices[2], vertices[3]);
431 enable_deferred_deletion(deferred_deletion_tmp);
438 bool deferred_deletion_tmp = deferred_deletion_enabled();
440 if (!deferred_deletion_tmp)
441 enable_deferred_deletion(
true);
443 for (
char i = 0; i < 2; ++i)
449 std::vector<VertexHandle> vertices = get_cell_vertices(hfh);
453 add_cell(vertices[0], vertices[1], _vh, vertices[3]);
454 add_cell(vertices[0], _vh, vertices[2], vertices[3]);
455 add_cell(_vh, vertices[1], vertices[2], vertices[3]);
461 enable_deferred_deletion(deferred_deletion_tmp);
466 std::vector<VertexHandle> TetrahedralMeshTopologyKernel::get_cell_vertices(
CellHandle ch)
const 468 return get_cell_vertices(
cell(ch).halffaces().front());
471 std::vector<VertexHandle> TetrahedralMeshTopologyKernel::get_cell_vertices(
CellHandle ch,
VertexHandle vh)
const 476 for (
unsigned int i = 0; i < 3; ++i)
479 if (e.from_vertex() == vh)
481 heh = f.halfedges()[i];
491 return get_cell_vertices(hfh,heh);
495 std::vector<VertexHandle> TetrahedralMeshTopologyKernel::get_cell_vertices(
HalfFaceHandle hfh)
const 497 return get_cell_vertices(hfh,
halfface(hfh).halfedges().front());
502 std::vector<VertexHandle> vertices;
505 for (
unsigned int i = 0; i < 3; ++i)
508 vertices.push_back(e.from_vertex());
515 otherHfh = c.halffaces()[1];
519 for (
unsigned int i = 0; i < otherF.halfedges().size(); ++i)
523 if (std::find(vertices.begin(), vertices.end(), e.to_vertex()) == vertices.end())
525 vertices.push_back(e.to_vertex());
533 std::vector<VertexHandle> TetrahedralMeshTopologyKernel::get_halfface_vertices(
HalfFaceHandle hfh)
const 535 return get_halfface_vertices(hfh,
halfface(hfh).halfedges().front());
541 for (
unsigned int i = 0; i < 3; ++i)
542 if (
halfedge(hf.halfedges()[i]).from_vertex() == vh)
543 return get_halfface_vertices(hfh, hf.halfedges()[i]);
545 return std::vector<VertexHandle>();
551 std::vector<VertexHandle> vertices;
554 for (
unsigned int i = 0; i < 3; ++i)
557 vertices.push_back(e.from_vertex());
566 if (is_boundary(hfh)) {
567 return InvalidVertexHandle;
570 const std::vector<VertexHandle> base = get_halfface_vertices(hfh);
573 if (vh != base[0] && vh != base[1] && vh != base[2]) {
578 return InvalidVertexHandle;
588 assert(TopologyKernel::has_full_bottom_up_incidences());
589 assert(_vertices.size() == 4);
592 if(!TopologyKernel::has_full_bottom_up_incidences()) {
596 if(_vertices.size() != 4) {
602 std::vector<VertexHandle> vs;
604 vs.push_back(_vertices[0]);
605 vs.push_back(_vertices[1]);
606 vs.push_back(_vertices[2]);
608 if(!hf0.is_valid()) {
614 vs.push_back(_vertices[0]);
615 vs.push_back(_vertices[2]);
616 vs.push_back(_vertices[3]);
618 if(!hf1.is_valid()) {
624 vs.push_back(_vertices[0]);
625 vs.push_back(_vertices[3]);
626 vs.push_back(_vertices[1]);
628 if(!hf2.is_valid()) {
634 vs.push_back(_vertices[1]);
635 vs.push_back(_vertices[3]);
636 vs.push_back(_vertices[2]);
638 if(!hf3.is_valid()) {
644 assert(hf0.is_valid());
645 assert(hf1.is_valid());
646 assert(hf2.is_valid());
647 assert(hf3.is_valid());
650 std::vector<HalfFaceHandle> hfs;
656 if (_topologyCheck) {
665 std::set<HalfEdgeHandle> incidentHalfedges;
666 std::set<EdgeHandle> incidentEdges;
668 for(std::vector<HalfFaceHandle>::const_iterator it = hfs.begin(),
669 end = hfs.end(); it != end; ++it) {
672 for(std::vector<HalfEdgeHandle>::const_iterator he_it = hface.halfedges().begin(),
673 he_end = hface.halfedges().end(); he_it != he_end; ++he_it) {
674 incidentHalfedges.insert(*he_it);
679 if(incidentHalfedges.size() != (incidentEdges.size() * 2u)) {
681 std::cerr <<
"The specified halffaces are not connected!" << std::endl;
683 return InvalidCellHandle;
687 if(has_face_bottom_up_incidences()) {
689 for(std::vector<HalfFaceHandle>::const_iterator it = hfs.begin(),
690 end = hfs.end(); it != end; ++it) {
693 std::cerr <<
"Warning: One of the specified half-faces is already incident to another cell!" << std::endl;
695 return InvalidCellHandle;
708 std::vector<HalfFaceHandle> halffaces;
709 halffaces.push_back(add_halfface(_vh0, _vh1, _vh2));
710 halffaces.push_back(add_halfface(_vh0, _vh2, _vh3));
711 halffaces.push_back(add_halfface(_vh0, _vh3, _vh1));
712 halffaces.push_back(add_halfface(_vh1, _vh3, _vh2));
713 return add_cell(halffaces, _topologyCheck);
virtual FaceHandle add_face(const std::vector< HalfEdgeHandle > &_halfedges, bool _topologyCheck=false)
Add face via incident edges.
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 EdgeHandle add_edge(const VertexHandle &_fromVertex, const VertexHandle &_toHandle, bool _allowDuplicates=false)
Add edge.
virtual EdgeIter delete_edge(const EdgeHandle &_h)
Delete edge from mesh.
static EdgeHandle edge_handle(const HalfEdgeHandle &_h)
Handle conversion.
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.
static HalfFaceHandle halfface_handle(const FaceHandle &_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.
HalfEdgeHandle next_halfedge_in_halfface(const HalfEdgeHandle &_heh, const HalfFaceHandle &_hfh) const
Get next halfedge within a halfface.
size_t n_vertices() const override
Get number of vertices in mesh.
Face halfface(const HalfFaceHandle &_halfFaceHandle) const
Get face that corresponds to halfface with handle _halfFaceHandle.
virtual VertexIter delete_vertex(const VertexHandle &_h)
Delete vertex from mesh.
virtual CellHandle add_cell(const std::vector< HalfFaceHandle > &_halffaces, bool _topologyCheck=false)
Add cell via incident halffaces.
Edge halfedge(const HalfEdgeHandle &_halfEdgeHandle) const
Get edge that corresponds to halfedge with handle _halfEdgeHandle.
virtual FaceIter delete_face(const FaceHandle &_h)
Delete face from mesh.
FaceHandle add_face(const std::vector< HalfEdgeHandle > &_halfedges, bool _topologyCheck=false) override
Add face via incident edges.
const Cell & cell(const CellHandle &_cellHandle) const
Get cell with handle _cellHandle.
CellHandle add_cell(const std::vector< HalfFaceHandle > &_halffaces, bool _topologyCheck=false) override
Add cell via incident halffaces.
static HalfEdgeHandle halfedge_handle(const EdgeHandle &_h, const unsigned char _subIdx)
Conversion function.