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.
212 lines
8.2 KiB
212 lines
8.2 KiB
#include "mesh_io.h"
|
|
|
|
#include <CGAL/Surface_mesh/IO.h>
|
|
#include <igl/readOBJ.h>
|
|
#include <igl/readPLY.h>
|
|
#include <igl/readSTL.h>
|
|
#include <igl/writeOBJ.h>
|
|
|
|
#include <cstdio>
|
|
#include <fstream>
|
|
//#include "sha-base-framework/frame.h"
|
|
|
|
namespace da {
|
|
namespace sha {
|
|
SurfaceMesh3 ReadSurfaceMesh3FromOFF(const fs_path &file_path) {
|
|
SurfaceMesh3 mesh;
|
|
CGAL::IO::read_OFF(file_path.string(), mesh);
|
|
return mesh;
|
|
}
|
|
|
|
SurfaceMesh3 ReadSurfaceMesh3FromOBJ(const fs_path &file_path) {
|
|
SurfaceMesh3 mesh;
|
|
CGAL::IO::read_OBJ(file_path.string(), mesh);
|
|
return mesh;
|
|
}
|
|
|
|
MatMesh3 ReadMatMeshFromOBJ(const fs_path &file_path) {
|
|
MatMesh3 matmesh;
|
|
igl::readOBJ(file_path.string(), matmesh.mat_coordinates, matmesh.mat_faces);
|
|
return matmesh;
|
|
}
|
|
|
|
MatMesh3 ReadMatMeshFromSTL(const fs_path &file_path) {
|
|
MatMesh3 matmesh;
|
|
Eigen::MatrixXd mat_normals;
|
|
std::ifstream mesh_instream(file_path.string());
|
|
igl::readSTL(mesh_instream, matmesh.mat_coordinates, matmesh.mat_faces, mat_normals);
|
|
return matmesh;
|
|
}
|
|
|
|
MatMesh3 ReadMatMeshFromPLY(const fs_path &file_path) {
|
|
MatMesh3 matmesh;
|
|
std::ifstream mesh_instream(file_path.string());
|
|
Eigen::MatrixXd mat_normals;
|
|
|
|
Eigen::MatrixXd mat_uv, mat_vertex_data, mat_face_data, mesh_edge_data;
|
|
Eigen::MatrixXi mat_edges;
|
|
std::vector<std::string> vtx_data_headers, edge_data_headers, face_data_headers, comments;
|
|
|
|
igl::readPLY(mesh_instream, matmesh.mat_coordinates, matmesh.mat_faces, mat_edges, mat_normals,
|
|
mat_uv, mat_vertex_data, vtx_data_headers, mat_face_data, face_data_headers,
|
|
mesh_edge_data, edge_data_headers, comments);
|
|
|
|
return matmesh;
|
|
}
|
|
|
|
void WriteMatMesh3ToObj(const fs_path &file_path, const MatMesh3 &matmesh,
|
|
const Eigen::MatrixXd &mat_vtx_colors) {
|
|
if (mat_vtx_colors.rows() == 0) {
|
|
igl::writeOBJ(file_path.string(), matmesh.mat_coordinates, matmesh.mat_faces);
|
|
} else { // with colors
|
|
Assert(matmesh.NumVertices() == mat_vtx_colors.rows(),
|
|
"The number of colors and vertices should be equal");
|
|
Assert(mat_vtx_colors.cols() == 3, "Cols of colors must be 3");
|
|
std::ofstream obj_out_stream(file_path.string());
|
|
if (not obj_out_stream.is_open()) {
|
|
Terminate("File " + file_path.string() + " can not be opened.");
|
|
}
|
|
for (index_t vtx_idx = 0; vtx_idx < matmesh.NumVertices(); ++vtx_idx) {
|
|
obj_out_stream << "v " << matmesh.mat_coordinates(vtx_idx, 0) << " "
|
|
<< matmesh.mat_coordinates(vtx_idx, 1) << " "
|
|
<< matmesh.mat_coordinates(vtx_idx, 2) << " ";
|
|
obj_out_stream << mat_vtx_colors(vtx_idx, 0) << " " << mat_vtx_colors(vtx_idx, 1) << " "
|
|
<< mat_vtx_colors(vtx_idx, 2) << std::endl;
|
|
}
|
|
|
|
for (index_t face_idx = 0; face_idx < matmesh.NumFaces(); ++face_idx) {
|
|
obj_out_stream << "f " << matmesh.mat_faces(face_idx, 0) + 1 << " "
|
|
<< matmesh.mat_faces(face_idx, 1) + 1 << " "
|
|
<< matmesh.mat_faces(face_idx, 2) + 1 << std::endl;
|
|
}
|
|
obj_out_stream.close();
|
|
}
|
|
}
|
|
|
|
void WriteToVtk(const fs_path &file_path, const Eigen::MatrixXd &mat_coordinates,
|
|
const Eigen::MatrixXi &mat_cells, const std::vector<double> &point_data,
|
|
const std::vector<double> &cell_data, int cell_type) {
|
|
std::ofstream vtk_out_stream(file_path.string());
|
|
if (not vtk_out_stream.is_open()) {
|
|
Terminate("File " + file_path.string() + " can not be opened.");
|
|
}
|
|
vtk_out_stream << "# vtk DataFile Version 3.0\n"
|
|
"Volume Mesh\n"
|
|
"ASCII\n"
|
|
"DATASET UNSTRUCTURED_GRID"
|
|
<< std::endl;
|
|
vtk_out_stream << "POINTS " << mat_coordinates.rows() << " float" << std::endl;
|
|
for (index_t vertex_idx = 0; vertex_idx < mat_coordinates.rows(); ++vertex_idx) {
|
|
vtk_out_stream << mat_coordinates.row(vertex_idx).x() << " "
|
|
<< mat_coordinates.row(vertex_idx).y() << " "
|
|
<< mat_coordinates.row(vertex_idx).z() << std::endl;
|
|
}
|
|
vtk_out_stream << "CELLS " << mat_cells.rows() << " " << mat_cells.rows() * (mat_cells.cols() + 1)
|
|
<< std::endl;
|
|
for (index_t face_idx = 0; face_idx < mat_cells.rows(); ++face_idx) {
|
|
vtk_out_stream << mat_cells.cols();
|
|
for (index_t col_idx = 0; col_idx < mat_cells.cols(); ++col_idx) {
|
|
vtk_out_stream << " " << mat_cells(face_idx, col_idx);
|
|
}
|
|
vtk_out_stream << std::endl;
|
|
}
|
|
vtk_out_stream << "CELL_TYPES " << mat_cells.rows() << std::endl;
|
|
for (index_t face_idx = 0; face_idx < mat_cells.rows(); ++face_idx) {
|
|
vtk_out_stream << cell_type << std::endl;
|
|
}
|
|
|
|
if (!point_data.empty()) {
|
|
vtk_out_stream << "POINT_DATA " << point_data.size() << "\n"
|
|
<< "SCALARS point_scalars double 1\n"
|
|
<< "LOOKUP_TABLE default" << std::endl;
|
|
for (auto &data : point_data) {
|
|
vtk_out_stream << data << std::endl;
|
|
}
|
|
}
|
|
|
|
if (!cell_data.empty()) {
|
|
vtk_out_stream << "CELL_DATA " << cell_data.size() << "\n"
|
|
<< "SCALARS cell_scalars double 1\n"
|
|
<< "LOOKUP_TABLE default" << std::endl;
|
|
|
|
for (auto &data : cell_data) {
|
|
vtk_out_stream << data << std::endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
void ReadFromVtk(const fs_path &file_path, Eigen::MatrixXd &mat_coordinates,
|
|
Eigen::MatrixXi &mat_cells, const size_t cell_size) {
|
|
std::ifstream infile_stream(file_path.string());
|
|
std::string line;
|
|
std::string string_temp;
|
|
size_t num_vertices;
|
|
size_t num_cells;
|
|
int inttmp;
|
|
for (index_t line_idx = 0; line_idx < 4; ++line_idx) {
|
|
std::getline(infile_stream, line);
|
|
}
|
|
std::getline(infile_stream, line);
|
|
std::stringstream line_stream(line);
|
|
line_stream >> string_temp >> num_vertices >> string_temp;
|
|
mat_coordinates.resize(num_vertices, 3);
|
|
for (index_t vtx_idx = 0; vtx_idx < num_vertices; ++vtx_idx) {
|
|
std::getline(infile_stream, line);
|
|
std::stringstream ss(line);
|
|
ss >> mat_coordinates(vtx_idx, 0) >> mat_coordinates(vtx_idx, 1) >> mat_coordinates(vtx_idx, 2);
|
|
}
|
|
std::getline(infile_stream, line);
|
|
line_stream = std::stringstream(line);
|
|
line_stream >> string_temp >> num_cells >> string_temp;
|
|
mat_cells.resize(num_cells, cell_size);
|
|
for (int cell_idx = 0; cell_idx < num_cells; ++cell_idx) {
|
|
std::getline(infile_stream, line);
|
|
std::stringstream cell_stream(line);
|
|
cell_stream >> inttmp;
|
|
for (int j = 0; j < cell_size; j++) {
|
|
cell_stream >> mat_cells(cell_idx, j);
|
|
}
|
|
}
|
|
}
|
|
|
|
void WriteMatMesh3ToVtk(const fs_path &file_path, const MatMesh3 &matmesh,
|
|
const std::vector<double> &point_data,
|
|
const std::vector<double> &cell_data) {
|
|
WriteToVtk(file_path, matmesh.mat_coordinates, matmesh.mat_faces, point_data, cell_data, 5);
|
|
}
|
|
|
|
void WriteMatMesh2ToVtk(const fs_path &file_path, const MatMesh2 &matmesh,
|
|
const std::vector<double> &point_data,
|
|
const std::vector<double> &cell_data) {
|
|
WriteToVtk(file_path, matmesh.mat_coordinates, matmesh.mat_beams, point_data, cell_data, 3);
|
|
}
|
|
|
|
void WritePointsToVtk(const fs_path &file_path, const Eigen::MatrixXd &mat_points,
|
|
const std::vector<double> &point_data) {
|
|
const size_t num_points = mat_points.rows();
|
|
Eigen::MatrixXi mat_cells(num_points, 1);
|
|
mat_cells.col(0).setLinSpaced(0, num_points - 1);
|
|
WriteToVtk(file_path, mat_points, mat_cells, point_data, {}, 1);
|
|
}
|
|
|
|
void WriteTetrahedralMatmeshToVtk(const fs_path &file_path, const TetrahedralMatMesh &matmesh,
|
|
const std::vector<double> &point_data,
|
|
const std::vector<double> &cell_data) {
|
|
WriteToVtk(file_path, matmesh.mat_coordinates, matmesh.mat_tetrahedrons, point_data, cell_data,
|
|
10);
|
|
}
|
|
|
|
void WriteHexahedralMatmeshToVtk(const fs_path &file_path, const HexahedralMatMesh &matmesh,
|
|
const std::vector<double> &point_data,
|
|
const std::vector<double> &cell_data) {
|
|
WriteToVtk(file_path, matmesh.mat_coordinates, matmesh.mat_hexahedrons, point_data, cell_data,
|
|
12);
|
|
}
|
|
|
|
TetrahedralMatMesh ReadTetrahedralMatMeshFromVtk(const fs_path &file_path) {
|
|
TetrahedralMatMesh mesh;
|
|
ReadFromVtk(file_path, mesh.mat_coordinates, mesh.mat_tetrahedrons, 4);
|
|
return mesh;
|
|
}
|
|
} // namespace sha
|
|
} // namespace da
|
|
|