You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
223 lines
8.7 KiB
223 lines
8.7 KiB
#include "matmesh.h"
|
|
|
|
#include <igl/combine.h>
|
|
|
|
#include <map>
|
|
#include <set>
|
|
#include <vector>
|
|
|
|
#include <boost/range/adaptor/indexed.hpp>
|
|
|
|
namespace da {
|
|
namespace sha {
|
|
auto CreateMatMeshFromTetrahedralMesh(const TetrahedralMesh &mesh) -> TetrahedralMatMesh {
|
|
TetrahedralMatMesh mat_mesh;
|
|
mat_mesh.mat_coordinates.resize(mesh.n_vertices(), 3);
|
|
mat_mesh.mat_tetrahedrons.resize(mesh.n_cells(), 4);
|
|
for (auto vertex : mesh.vertices()) {
|
|
auto &point = mesh.vertex(vertex);
|
|
mat_mesh.mat_coordinates.row(vertex.idx()) << point[0], point[1], point[2];
|
|
}
|
|
for (auto &tetrahedron : mesh.cells()) {
|
|
for (auto &&[idx, vertex] : mesh.cell_vertices(tetrahedron) | boost::adaptors::indexed(0)) {
|
|
mat_mesh.mat_tetrahedrons(tetrahedron.idx(), idx) = vertex.idx();
|
|
}
|
|
}
|
|
return mat_mesh;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* 5-------6
|
|
* /| /|
|
|
* / | / |
|
|
* 3-------2 |
|
|
* | 4----|--7
|
|
* | / | /
|
|
* |/ |/
|
|
* 0-------1
|
|
*
|
|
*/
|
|
auto CreateMatMeshFromHexahedralMesh(const HexahedralMesh &mesh) -> HexahedralMatMesh {
|
|
std::map<index_t, index_t> map_openmesh_idx_to_vtk_idx = {{4, 0}, {0, 1}, {1, 2}, {7, 3},
|
|
{5, 4}, {3, 5}, {2, 6}, {6, 7}};
|
|
std::map<index_t, index_t> map_vtk_idx_to_openmesh_idx = {{0, 4}, {1, 0}, {2, 1}, {3, 7},
|
|
{4, 5}, {5, 3}, {6, 2}, {7, 6}};
|
|
std::array<index_t, 8> indices = {5, 6, 2, 1, 3, 7, 4, 0};
|
|
HexahedralMatMesh mat_mesh;
|
|
mat_mesh.mat_coordinates.resize(mesh.n_vertices(), 3);
|
|
mat_mesh.mat_hexahedrons.resize(mesh.n_cells(), 8);
|
|
for (auto vertex : mesh.vertices()) {
|
|
auto &point = mesh.vertex(vertex);
|
|
mat_mesh.mat_coordinates.row(vertex.idx()) << point[0], point[1], point[2];
|
|
}
|
|
for (auto &hexahedron : mesh.cells()) {
|
|
int cnt = 0;
|
|
for (auto he : mesh.cell_halfedges(hexahedron)) {
|
|
mat_mesh.mat_hexahedrons(hexahedron.idx(), indices[cnt]) = mesh.from_vertex_handle(he).idx();
|
|
if (++cnt == 8) break;
|
|
}
|
|
}
|
|
return mat_mesh;
|
|
}
|
|
|
|
auto CreateTetrahedralMeshFromMatMesh(const TetrahedralMatMesh &mat_mesh) -> TetrahedralMesh {
|
|
TetrahedralMesh mesh;
|
|
for (index_t vertex_idx = 0; vertex_idx < mat_mesh.NumVertices(); ++vertex_idx) {
|
|
mesh.add_vertex({mat_mesh.mat_coordinates(vertex_idx, 0),
|
|
mat_mesh.mat_coordinates(vertex_idx, 1),
|
|
mat_mesh.mat_coordinates(vertex_idx, 2)});
|
|
}
|
|
|
|
for (index_t cell_idx = 0; cell_idx < mat_mesh.NumTetrahedrons(); ++cell_idx) {
|
|
mesh.add_cell(OpenVolumeMesh::VertexHandle(mat_mesh.mat_tetrahedrons(cell_idx, 0)),
|
|
OpenVolumeMesh::VertexHandle(mat_mesh.mat_tetrahedrons(cell_idx, 1)),
|
|
OpenVolumeMesh::VertexHandle(mat_mesh.mat_tetrahedrons(cell_idx, 2)),
|
|
OpenVolumeMesh::VertexHandle(mat_mesh.mat_tetrahedrons(cell_idx, 3)));
|
|
}
|
|
return mesh;
|
|
}
|
|
|
|
auto CreateTetrahedralTopoMeshFromMatrix(size_t num_vertices,
|
|
const Eigen::MatrixXi &mat_tetrahedrons)
|
|
-> TetrahedralTopoMesh {
|
|
const size_t num_tetrahedrons = mat_tetrahedrons.rows();
|
|
TetrahedralTopoMesh tetrahedral_topomesh;
|
|
for (index_t vertex_idx = 0; vertex_idx < num_vertices; ++vertex_idx) {
|
|
tetrahedral_topomesh.add_vertex();
|
|
}
|
|
for (index_t cell_idx = 0; cell_idx < num_tetrahedrons; ++cell_idx) {
|
|
tetrahedral_topomesh.add_cell(OpenVolumeMesh::VertexHandle(mat_tetrahedrons(cell_idx, 0)),
|
|
OpenVolumeMesh::VertexHandle(mat_tetrahedrons(cell_idx, 1)),
|
|
OpenVolumeMesh::VertexHandle(mat_tetrahedrons(cell_idx, 2)),
|
|
OpenVolumeMesh::VertexHandle(mat_tetrahedrons(cell_idx, 3)));
|
|
}
|
|
return tetrahedral_topomesh;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* 5-------6
|
|
* /| /|
|
|
* / | / |
|
|
* 3-------2 |
|
|
* | 4----|--7
|
|
* | / | /
|
|
* |/ |/
|
|
* 0-------1
|
|
*
|
|
*/
|
|
auto CreateHexahedralMeshFromMatMesh(const HexahedralMatMesh &mat_mesh) -> HexahedralMesh {
|
|
const size_t num_vertices = mat_mesh.NumVertices();
|
|
const size_t num_hexahedrons = mat_mesh.NumHexahedrons();
|
|
static const std::map<index_t, index_t> map_openmesh_idx_to_vtk_idx = {
|
|
{4, 0}, {0, 1}, {1, 2}, {7, 3}, {5, 4}, {3, 5}, {2, 6}, {6, 7}};
|
|
|
|
HexahedralMesh mesh;
|
|
for (index_t vertex_idx = 0; vertex_idx < num_vertices; ++vertex_idx) {
|
|
mesh.add_vertex({mat_mesh.mat_coordinates(vertex_idx, 0),
|
|
mat_mesh.mat_coordinates(vertex_idx, 1),
|
|
mat_mesh.mat_coordinates(vertex_idx, 2)});
|
|
}
|
|
for (index_t cell_idx = 0; cell_idx < num_hexahedrons; ++cell_idx) {
|
|
std::vector<OpenVolumeMesh::VertexHandle> cell_vertices(8);
|
|
for (size_t idx = 0; idx < 8; idx++) {
|
|
cell_vertices[idx] = OpenVolumeMesh::VertexHandle(
|
|
mat_mesh.mat_hexahedrons(cell_idx, map_openmesh_idx_to_vtk_idx.at(idx)));
|
|
}
|
|
mesh.add_cell(cell_vertices);
|
|
}
|
|
return mesh;
|
|
}
|
|
auto CreateHexahedralTopoMeshFromMatrix(size_t num_vertices, const Eigen::MatrixXi &mat_hexahedrons)
|
|
-> HexahedralTopoMesh {
|
|
static const std::map<index_t, index_t> map_openmesh_idx_to_vtk_idx = {
|
|
{4, 0}, {0, 1}, {1, 2}, {7, 3}, {5, 4}, {3, 5}, {2, 6}, {6, 7}};
|
|
|
|
const size_t num_hexahedrons = mat_hexahedrons.rows();
|
|
|
|
HexahedralTopoMesh hexahedral_topomesh;
|
|
|
|
for (index_t vertex_idx = 0; vertex_idx < num_vertices; ++vertex_idx) {
|
|
hexahedral_topomesh.add_vertex();
|
|
}
|
|
for (index_t cell_idx = 0; cell_idx < num_hexahedrons; ++cell_idx) {
|
|
std::vector<OpenVolumeMesh::VertexHandle> cell_vertices(8);
|
|
for (size_t idx = 0; idx < 8; idx++) {
|
|
cell_vertices[idx] = OpenVolumeMesh::VertexHandle(
|
|
mat_hexahedrons(cell_idx, map_openmesh_idx_to_vtk_idx.at(idx)));
|
|
}
|
|
hexahedral_topomesh.add_cell(cell_vertices);
|
|
}
|
|
return hexahedral_topomesh;
|
|
}
|
|
|
|
auto CreateSurfaceMatrixFromTetrahedralTopoMesh(const TetrahedralTopoMesh &topomesh)
|
|
-> Eigen::MatrixXi {
|
|
Eigen::MatrixXi mat_surface_triangles;
|
|
std::vector<OpenVolumeMesh::FaceHandle> boundary_faces;
|
|
std::vector<OpenVolumeMesh::CellHandle> map_boundary_face_to_cell;
|
|
for (auto boundary_face = topomesh.bf_iter(); boundary_face.is_valid(); ++boundary_face) {
|
|
auto face = *boundary_face;
|
|
boundary_faces.push_back(face);
|
|
}
|
|
const size_t num_surface_faces = boundary_faces.size();
|
|
mat_surface_triangles.resize(num_surface_faces, 3);
|
|
|
|
for (index_t face_idx = 0; face_idx < num_surface_faces; ++face_idx) {
|
|
auto face = boundary_faces[face_idx];
|
|
|
|
for (auto &&[idx, face_vertex] : topomesh.face_vertices(face) | boost::adaptors::indexed(0)) {
|
|
mat_surface_triangles(face_idx, idx) = face_vertex.idx();
|
|
}
|
|
}
|
|
return mat_surface_triangles;
|
|
}
|
|
|
|
auto CreateSurfaceMatFromHexahedralTopoMesh(const HexahedralTopoMesh &topomesh) -> Eigen::MatrixXi {
|
|
Eigen::MatrixXi mat_surface_quadrangles;
|
|
std::vector<OpenVolumeMesh::FaceHandle> boundary_faces;
|
|
std::vector<OpenVolumeMesh::CellHandle> map_boundary_face_to_cell;
|
|
for (auto boundary_face = topomesh.bf_iter(); boundary_face.is_valid(); ++boundary_face) {
|
|
auto face = *boundary_face;
|
|
boundary_faces.push_back(face);
|
|
}
|
|
const size_t num_surface_faces = boundary_faces.size();
|
|
mat_surface_quadrangles.resize(num_surface_faces, 4);
|
|
|
|
for (index_t face_idx = 0; face_idx < num_surface_faces; ++face_idx) {
|
|
auto face = boundary_faces[face_idx];
|
|
|
|
for (auto &&[idx, face_vertex] : topomesh.face_vertices(face) | boost::adaptors::indexed(0)) {
|
|
mat_surface_quadrangles(face_idx, idx) = face_vertex.idx();
|
|
}
|
|
}
|
|
return mat_surface_quadrangles;
|
|
}
|
|
|
|
auto CombineTwoTetrahedralMatMeshes(const TetrahedralMatMesh &matmesh_1,
|
|
const TetrahedralMatMesh &matmesh_2) -> TetrahedralMatMesh {
|
|
if (matmesh_1.NumVertices() == 0) return matmesh_2;
|
|
if (matmesh_2.NumVertices() == 0) return matmesh_1;
|
|
TetrahedralMatMesh result_mesh;
|
|
igl::combine<Eigen::MatrixXd, Eigen::MatrixXi>(
|
|
{matmesh_1.mat_coordinates, matmesh_2.mat_coordinates},
|
|
{matmesh_1.mat_tetrahedrons, matmesh_2.mat_tetrahedrons}, result_mesh.mat_coordinates,
|
|
result_mesh.mat_tetrahedrons);
|
|
return result_mesh;
|
|
}
|
|
|
|
auto CombineTwoHexahedralMatMeshes(const HexahedralMatMesh &matmesh_1,
|
|
const HexahedralMatMesh &matmesh_2) -> HexahedralMatMesh {
|
|
if (matmesh_1.NumVertices() == 0) return matmesh_2;
|
|
if (matmesh_2.NumVertices() == 0) return matmesh_1;
|
|
HexahedralMatMesh result_mesh;
|
|
igl::combine<Eigen::MatrixXd, Eigen::MatrixXi>(
|
|
{matmesh_1.mat_coordinates, matmesh_2.mat_coordinates},
|
|
{matmesh_1.mat_hexahedrons, matmesh_2.mat_hexahedrons}, result_mesh.mat_coordinates,
|
|
result_mesh.mat_hexahedrons);
|
|
return result_mesh;
|
|
}
|
|
|
|
} // namespace sha
|
|
} // namespace da
|
|
|