Commit 944dbb4a authored by Max Lyon's avatar Max Lyon

Added Tetrahedral Mesh classes

parent 9de4e5ef
/*===========================================================================*\
* *
* OpenVolumeMesh *
* Copyright (C) 2011 by Computer Graphics Group, RWTH Aachen *
* www.openvolumemesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenVolumeMesh. *
* *
* OpenVolumeMesh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenVolumeMesh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenVolumeMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* $LastChangedBy$ *
* *
\*===========================================================================*/
#ifndef TETRAHEDRALGEOMETRYKERNEL_HH_
#define TETRAHEDRALGEOMETRYKERNEL_HH_
#include <cassert>
#include <iostream>
#include "../Geometry/VectorT.hh"
#include "../Core/GeometryKernel.hh"
#include "TetrahedralMeshTopologyKernel.hh"
namespace OpenVolumeMesh {
template <class VecT, class TopologyKernelT = TetrahedralMeshTopologyKernel>
class TetrahedralGeometryKernel : public GeometryKernel<VecT, TopologyKernelT> {
public:
typedef VecT PointT;
typedef TopologyKernelT KernelT;
typedef GeometryKernel<VecT, TopologyKernelT> ParentT;
/// Constructor
TetrahedralGeometryKernel() {}
/// Destructor
~TetrahedralGeometryKernel() {}
VertexHandle split_edge(HalfEdgeHandle heh, double alpha = 0.5)
{
OpenVolumeMeshEdge e = TopologyKernelT::halfedge(heh);
PointT newPos = alpha*ParentT::vertex(e.from_vertex()) + (1.0-alpha)*ParentT::vertex(e.to_vertex());
VertexHandle splitVertex = ParentT::add_vertex(newPos);
TopologyKernelT::split_edge(heh, splitVertex);
return splitVertex;
}
VertexHandle split_edge(EdgeHandle eh)
{
return split_edge(TopologyKernelT::halfedge_handle(eh,0));
}
VertexHandle split_face(FaceHandle fh, PointT pos)
{
VertexHandle splitVertex = ParentT::add_vertex(pos);
TopologyKernelT::split_face(fh, splitVertex);
return splitVertex;
}
VertexHandle split_face(FaceHandle fh)
{
VertexHandle splitVertex = ParentT::add_vertex(ParentT::barycenter(fh));
TopologyKernelT::split_face(fh, splitVertex);
return splitVertex;
}
protected:
};
} // Namespace OpenVolumeMesh
#endif /* TETRAHEDRALGEOMETRYKERNEL_HH_ */
/*===========================================================================*\
* *
* OpenVolumeMesh *
* Copyright (C) 2011 by Computer Graphics Group, RWTH Aachen *
* www.openvolumemesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenVolumeMesh. *
* *
* OpenVolumeMesh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenVolumeMesh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenVolumeMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* $LastChangedBy$ *
* *
\*===========================================================================*/
#ifndef TETRAHEDRALMESH_HH_
#define TETRAHEDRALMESH_HH_
#include "TetrahedralMeshTopologyKernel.hh"
#include "../Core/GeometryKernel.hh"
namespace OpenVolumeMesh {
/*
* Predefines for most common mesh types
*/
typedef GeometryKernel<Geometry::Vec2i, TetrahedralMeshTopologyKernel> GeometricTetrahedralMeshV2i;
typedef GeometryKernel<Geometry::Vec2ui, TetrahedralMeshTopologyKernel> GeometricTetrahedralMeshV2ui;
typedef GeometryKernel<Geometry::Vec2f, TetrahedralMeshTopologyKernel> GeometricTetrahedralMeshV2f;
typedef GeometryKernel<Geometry::Vec2d, TetrahedralMeshTopologyKernel> GeometricTetrahedralMeshV2d;
typedef GeometryKernel<Geometry::Vec2c, TetrahedralMeshTopologyKernel> GeometricTetrahedralMeshV2c;
typedef GeometryKernel<Geometry::Vec2uc, TetrahedralMeshTopologyKernel> GeometricTetrahedralMeshV2uc;
typedef GeometryKernel<Geometry::Vec3i, TetrahedralMeshTopologyKernel> GeometricTetrahedralMeshV3i;
typedef GeometryKernel<Geometry::Vec3ui, TetrahedralMeshTopologyKernel> GeometricTetrahedralMeshV3ui;
typedef GeometryKernel<Geometry::Vec3f, TetrahedralMeshTopologyKernel> GeometricTetrahedralMeshV3f;
typedef GeometryKernel<Geometry::Vec3d, TetrahedralMeshTopologyKernel> GeometricTetrahedralMeshV3d;
typedef GeometryKernel<Geometry::Vec3c, TetrahedralMeshTopologyKernel> GeometricTetrahedralMeshV3c;
typedef GeometryKernel<Geometry::Vec3uc, TetrahedralMeshTopologyKernel> GeometricTetrahedralMeshV3uc;
typedef GeometryKernel<Geometry::Vec4i, TetrahedralMeshTopologyKernel> GeometricTetrahedralMeshV4i;
typedef GeometryKernel<Geometry::Vec4ui, TetrahedralMeshTopologyKernel> GeometricTetrahedralMeshV4ui;
typedef GeometryKernel<Geometry::Vec4f, TetrahedralMeshTopologyKernel> GeometricTetrahedralMeshV4f;
typedef GeometryKernel<Geometry::Vec4d, TetrahedralMeshTopologyKernel> GeometricTetrahedralMeshV4d;
typedef GeometryKernel<Geometry::Vec4c, TetrahedralMeshTopologyKernel> GeometricTetrahedralMeshV4c;
typedef GeometryKernel<Geometry::Vec4uc, TetrahedralMeshTopologyKernel> GeometricTetrahedralMeshV4uc;
typedef TetrahedralMeshTopologyKernel TopologicTetrahedralMesh;
} // Namespace OpenVolumeMesh
#endif /* TETRAHEDRALMESH_HH_ */
/*===========================================================================*\
* *
* OpenVolumeMesh *
* Copyright (C) 2011 by Computer Graphics Group, RWTH Aachen *
* www.openvolumemesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenVolumeMesh. *
* *
* OpenVolumeMesh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenVolumeMesh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenVolumeMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* $LastChangedBy$ *
* *
\*===========================================================================*/
#include <set>
#include "TetrahedralMeshIterators.hh"
#include "TetrahedralMeshTopologyKernel.hh"
#include "../Core/Iterators.hh"
namespace OpenVolumeMesh {
//================================================================================================
// TetVertexIter
//================================================================================================
TetVertexIter::TetVertexIter(const CellHandle& _ref_h,
const TetrahedralMeshTopologyKernel* _mesh, int _max_laps) :
BaseIter(_mesh, _ref_h, _max_laps) {
assert(_ref_h.is_valid());
assert(_mesh->cell(_ref_h).halffaces().size() == 4);
// Get first half-face
HalfFaceHandle curHF = *_mesh->cell(_ref_h).halffaces().begin();
assert(curHF.is_valid());
// Get first half-edge
assert(_mesh->halfface(curHF).halfedges().size() == 3);
HalfEdgeHandle curHE = *_mesh->halfface(curHF).halfedges().begin();
assert(curHE.is_valid());
vertices_.push_back(_mesh->halfedge(curHE).to_vertex());
curHE = _mesh->next_halfedge_in_halfface(curHE, curHF);
vertices_.push_back(_mesh->halfedge(curHE).to_vertex());
curHE = _mesh->next_halfedge_in_halfface(curHE, curHF);
vertices_.push_back(_mesh->halfedge(curHE).to_vertex());
curHF = _mesh->adjacent_halfface_in_cell(curHF, curHE);
curHE = _mesh->opposite_halfedge_handle(curHE);
curHE = _mesh->next_halfedge_in_halfface(curHE, curHF);
vertices_.push_back(_mesh->halfedge(curHE).to_vertex());
cur_index_ = 0;
BaseIter::valid(vertices_.size() > 0);
if(BaseIter::valid()) {
BaseIter::cur_handle(vertices_[cur_index_]);
}
}
TetVertexIter& TetVertexIter::operator--() {
if (cur_index_ == 0) {
cur_index_ = vertices_.size() - 1;
--lap_;
if (lap_ < 0)
BaseIter::valid(false);
} else {
--cur_index_;
}
BaseIter::cur_handle(vertices_[cur_index_]);
return *this;
}
TetVertexIter& TetVertexIter::operator++() {
++cur_index_;
if(cur_index_ == vertices_.size()) {
cur_index_ = 0;
++lap_;
if (lap_ >= max_laps_)
BaseIter::valid(false);
}
BaseIter::cur_handle(vertices_[cur_index_]);
return *this;
}
} // Namespace OpenVolumeMesh
/*===========================================================================*\
* *
* OpenVolumeMesh *
* Copyright (C) 2011 by Computer Graphics Group, RWTH Aachen *
* www.openvolumemesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenVolumeMesh. *
* *
* OpenVolumeMesh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenVolumeMesh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenVolumeMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* $LastChangedBy$ *
* *
\*===========================================================================*/
#ifndef TETRAHEDRALMESHITERATORS_HH
#define TETRAHEDRALMESHITERATORS_HH
#include "../Core/Iterators.hh"
namespace OpenVolumeMesh {
class TetrahedralMeshTopologyKernel;
/** \brief Iterate over all vertices of a hexahedron in a specific order
*
* Vertices are addressed in the following order: vertices of one halfface in ccw order, then the remaining vertex
*
*/
class TetVertexIter : public BaseCirculator<CellHandle,
VertexHandle> {
private:
typedef BaseCirculator<CellHandle,
VertexHandle> BaseIter;
public:
TetVertexIter(const CellHandle& _ref_h,
const TetrahedralMeshTopologyKernel* _mesh,
int _max_laps = 1);
// Post increment/decrement operator
TetVertexIter operator++(int) {
TetVertexIter cpy = *this;
++(*this);
return cpy;
}
TetVertexIter operator--(int) {
TetVertexIter cpy = *this;
--(*this);
return cpy;
}
TetVertexIter operator+(int _n) {
TetVertexIter cpy = *this;
for(int i = 0; i < _n; ++i) {
++cpy;
}
return cpy;
}
TetVertexIter operator-(int _n) {
TetVertexIter cpy = *this;
for(int i = 0; i < _n; ++i) {
--cpy;
}
return cpy;
}
TetVertexIter& operator+=(int _n) {
for(int i = 0; i < _n; ++i) {
++(*this);
}
return *this;
}
TetVertexIter& operator-=(int _n) {
for(int i = 0; i < _n; ++i) {
--(*this);
}
return *this;
}
TetVertexIter& operator++();
TetVertexIter& operator--();
private:
std::vector<VertexHandle> vertices_;
size_t cur_index_;
};
} // Namespace OpenVolumeMesh
#endif /* TETRAHEDRALMESHITERATORS_HH */
/*===========================================================================*\
* *
* OpenVolumeMesh *
* Copyright (C) 2011 by Computer Graphics Group, RWTH Aachen *
* www.openvolumemesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenVolumeMesh. *
* *
* OpenVolumeMesh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenVolumeMesh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenVolumeMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* $LastChangedBy$ *
* *
\*===========================================================================*/
#include "TetrahedralMeshTopologyKernel.hh"
#include <iostream>
namespace OpenVolumeMesh {
TetrahedralMeshTopologyKernel::TetrahedralMeshTopologyKernel() {
}
//========================================================================================
TetrahedralMeshTopologyKernel::~TetrahedralMeshTopologyKernel() {
}
//========================================================================================
FaceHandle TetrahedralMeshTopologyKernel::add_face(const std::vector<HalfEdgeHandle>& _halfedges, bool _topologyCheck) {
if(_halfedges.size() != 3) {
#ifndef NDEBUG
std::cerr << "TetrahedralMeshTopologyKernel::add_face(): Face valence is not three! Returning" << std::endl;
std::cerr << "invalid handle." << std::endl;
#endif
return TopologyKernel::InvalidFaceHandle;
}
return TopologyKernel::add_face(_halfedges, _topologyCheck);
}
//========================================================================================
FaceHandle
TetrahedralMeshTopologyKernel::add_face(const std::vector<VertexHandle>& _vertices) {
if(_vertices.size() != 3) {
#ifndef NDEBUG
std::cerr << "TetrahedralMeshTopologyKernel::add_face(): Face valence is not three! Returning" << std::endl;
std::cerr << "invalid handle." << std::endl;
#endif
return TopologyKernel::InvalidFaceHandle;
}
return TopologyKernel::add_face(_vertices);
}
//========================================================================================
CellHandle
TetrahedralMeshTopologyKernel::add_cell(const std::vector<HalfFaceHandle>& _halffaces, bool _topologyCheck) {
if(_halffaces.size() != 4) {
// To make this consistent with add_face
#ifndef NDEBUG
std::cerr << "Cell valence is not four! Aborting." << std::endl;
#endif
return TopologyKernel::InvalidCellHandle;
}
for(std::vector<HalfFaceHandle>::const_iterator it = _halffaces.begin();
it != _halffaces.end(); ++it) {
if(TopologyKernel::halfface(*it).halfedges().size() != 3) {
#ifndef NDEBUG
std::cerr << "Incident face does not have valence three! Aborting." << std::endl;
#endif
return TopologyKernel::InvalidCellHandle;
}
}
return TopologyKernel::add_cell(_halffaces, _topologyCheck);
}
HalfEdgeHandle TetrahedralMeshTopologyKernel::add_halfedge(const VertexHandle& _fromVertex, const VertexHandle& _toVertex)
{
HalfEdgeHandle he = halfedge(_fromVertex, _toVertex);
if (he != InvalidHalfEdgeHandle)
return he;
else
return halfedge_handle(add_edge(_fromVertex, _toVertex), 0);
}
HalfFaceHandle TetrahedralMeshTopologyKernel::add_halfface(const std::vector<HalfEdgeHandle>& _halfedges, bool _topologyCheck)
{
HalfFaceHandle hf = halfface(_halfedges);
if (hf != InvalidHalfFaceHandle)
return hf;
else
return halfface_handle(add_face(_halfedges, _topologyCheck), 0);
}
HalfFaceHandle TetrahedralMeshTopologyKernel::add_halfface(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2, bool _topologyCheck)
{
std::vector<HalfEdgeHandle> halfedges;
halfedges.push_back(add_halfedge(_vh0, _vh1));
halfedges.push_back(add_halfedge(_vh1, _vh2));
halfedges.push_back(add_halfedge(_vh2, _vh0));
return add_halfface(halfedges, _topologyCheck);
}
/*void TetrahedralMeshTopologyKernel::replaceHalfFace(CellHandle ch, HalfFaceHandle hf_del, HalfFaceHandle hf_ins)
{
Cell& c = cells_[ch.idx()];
std::vector<HalfFaceHandle> hfs;
for (unsigned int i = 0; i < c.halffaces().size(); ++i)
if (c.halffaces()[i] != hf_del)
hfs.push_back(c.halffaces()[i]);
else
hfs.push_back(hf_ins);
c.set_halffaces(hfs);
}
void TetrahedralMeshTopologyKernel::replaceHalfEdge(HalfFaceHandle hfh, HalfEdgeHandle he_del, HalfEdgeHandle he_ins)
{
FaceHandle fh = face_handle(hfh);
unsigned char oppF = hfh.idx() - halfface_handle(fh, 0);
if (oppF == 1)
{
he_del = opposite_halfedge_handle(he_del);
he_ins = opposite_halfedge_handle(he_ins);
}
Face& f = faces_[fh.idx()];
std::vector<HalfEdgeHandle> hes;
for (unsigned int i = 0; i < f.halfedges().size(); ++i)
if (f.halfedges()[i] != he_del)
hes.push_back(f.halfedges()[i]);
else
hes.push_back(he_ins);
f.set_halfedges(hes);
}*/
/*
void TetrahedralMeshTopologyKernel::collapse_edge(HalfEdgeHandle _heh)
{
std::vector<bool> deleteTagFaces(faces_.size(), false);
std::vector<bool> deleteTagEdges(edges_.size(), false);
std::vector<bool> deleteTagCells(cells_.size(), false);
for (HalfEdgeHalfFaceIter hehf_it = hehf_iter(_heh); hehf_it.valid(); ++hehf_it)
{
CellHandle ch = incident_cell(*hehf_it);
if (ch.is_valid())
{
HalfFaceHandle hf134 = *hehf_it;
HalfFaceHandle hf143 = opposite_halfface_handle(hf143);
HalfEdgeHandle he13 = prev_halfedge_in_halfface(_heh, hf134);
HalfEdgeHandle he41 = next_halfedge_in_halfface(_heh, hf134);
HalfFaceHandle hf123 = adjacent_halfface_in_cell(hf134, he13);
HalfFaceHandle hf142 = adjacent_halfface_in_cell(hf134, he41);
HalfFaceHandle hf132 = opposite_halfface_handle(hf123);
CellHandle ch0123 = incident_cell(hf132);
HalfEdgeHandle he32 = next_halfedge_in_halfface(he13, hf132);
HalfEdgeHandle he23 = opposite_halfedge_handle(he32);
HalfEdgeHandle he14 = opposite_halfedge_handle(he41);
HalfEdgeHandle he31 = opposite_halfedge_handle(he13);
HalfEdgeHandle he42 = next_halfedge_in_halfface(he14, hf142);
HalfEdgeHandle he24 = opposite_halfedge_handle(he42);
HalfFaceHandle hf243 = adjacent_halfface_in_cell(hf134, he41);
HalfFaceHandle hf234 = opposite_halfface_handle(hf234);
HalfEdgeHandle he12 = next_halfedge_in_halfface(he42, hf142);
HalfEdgeHandle he21 = opposite_halfedge_handle(he12);
if (ch0123.is_valid())
{
HalfFaceHandle hf031 = adjacent_halfface_in_cell(hf132, he13);
HalfFaceHandle hf023 = adjacent_halfface_in_cell(hf132, he32);
replaceHalfEdge(hf031, he31, he41);
replaceHalfEdge(hf023, he23, he24);
replaceHalfFace(ch0123, hf132, hf142);
}
//copyHalfFaceAndHalfEdgeProperties(hf132, 142);
incident_cell_per_hf_[hf142.idx()] = ch0123;
deleteTagCells[ch.idx()] = true;
deleteTagFaces[face_handle(hf132).idx()] = true;
deleteTagFaces[face_handle(*hehf_it).idx()] = true;
deleteTagEdges[edge_handle(he13).idx()] = true;
deleteTagEdges[edge_handle(he32).idx()] = true;
std::set<HalfFaceHandle> excludeFaces;
excludeFaces.insert(hf134);
excludeFaces.insert(hf143);
excludeFaces.insert(hf123);
excludeFaces.insert(hf132);
excludeFaces.insert(hf243);
excludeFaces.insert(hf234);
std::vector<std::pair<HalfEdgeHandle, HalfEdgeHandle> > joinpartners;
joinpartners.push_back(std::make_pair(he41, he31));
joinpartners.push_back(std::make_pair(he14, he13));
joinpartners.push_back(std::make_pair(he42, he32));
joinpartners.push_back(std::make_pair(he24, he23));
for (unsigned int i = 0; i < joinpartners.size(); ++i)
{
HalfEdgeHandle target = joinpartners[i].first;
HalfEdgeHandle source = joinpartners[i].second;
std::vector<HalfFaceHandle> incidentHfs;
for (unsigned int j = 0; j < incident_hfs_per_he_[target.idx()].size(); ++j)
{
HalfFaceHandle cur_hf = incident_hfs_per_he_[target.idx()][j];
if ((excludeFaces.find(cur_hf) == excludeFaces.end()) && !deleteTagFaces[face_handle(cur_hf).idx()])
incidentHfs.push_back(cur_hf);
}
for (unsigned int i = 0; i < incident_hfs_per_he_[source.idx()].size(); ++i)
{
HalfFaceHandle cur_hf = incident_hfs_per_he_[source.idx()][i];
if ((excludeFaces.find(cur_hf) == excludeFaces.end()) && !deleteTagFaces[face_handle(cur_hf).idx()])
incidentHfs.push_back(cur_hf);
}
std::swap(incident_hfs_per_he_[target], incidentHfs);
}
std::vector<HalfFaceHandle>& vec = incident_hfs_per_he_[he21];
vec.erase(std::remove(vec.begin(), vec.end(), hf132), vec.end());
std::vector<HalfFaceHandle>& vec2 = incident_hfs_per_he_[he12];
vec2.erase(std::remove(vec2.begin(), vec2.end(), hf123), vec2.end());
}
else
{
deleteTagFaces[face_handle(*hehf_it).idx()] = true;
}
}
VertexHandle from_vh = halfedge(_heh).from_vertex();
VertexHandle to_vh = halfedge(_heh).to_vertex();
for (VertexOHalfEdgeIter voh_it = voh_iter(from_vh); voh_it.valid(); ++voh_it )
{
Edge he = halfedge(*voh_it);
if (he.to_vertex() == to_vh)
{