This commit is contained in:
张壹 2025-02-19 10:22:01 +08:00
parent 5a00846fa8
commit 0f4a1090d9
4 changed files with 176 additions and 955446 deletions

View File

@ -34,14 +34,9 @@ int main(int argc, char const *argv[]) try
{
array<vertex3dc> nodes;
array<triangle> tris;
read_stl_ascii("tmp/Stanford_Bunny", nodes, tris);
mesh_io mshio;
mshio.import_from(tris, nodes);
mshio.save_gmsh_v2_ascii("tmp");
mshio.info();
save_stl_ascii("tmp", nodes, tris, "Stanford_Bunny");
read_stl_binary("tmp/Stanford_Bunny_Binary", nodes, tris);
save_stl_ascii("tmp", tris, "Stanford_Bunny");
save_stl_binary("tmp_binary", tris, "Stanford_Bunny");
return 0;
}
catch(std::exception &e)

View File

@ -35,6 +35,17 @@
namespace gctl
{
/**
* @brief Read stl file ascii format
*
* @tparam E vertex attribute type
* @tparam A element attribute type
* @param filename File name
* @param nodes return nodes
* @param facets return facets
* @param solid solid name ('null' will read the first solid)
* @param eps epsilon for node comparison
*/
template <typename E, typename A>
void read_stl_ascii(std::string filename, array<vertex<point3dc, E>> &nodes,
array<type_triangle<A>> &facets, std::string solid = "null", double eps = 1e-8)
@ -74,7 +85,7 @@ namespace gctl
{
std::getline(infile, line);
line.erase(0, line.find_first_not_of(" \t"));
line.erase(line.find_last_not_of(" \t") + 1);
line.erase(line.find_last_not_of(" \t") + 1);
sscanf(line.c_str(), "vertex %lf %lf %lf", &vt[i].x, &vt[i].y, &vt[i].z);
}
std::getline(infile, line); // endloop
@ -129,9 +140,18 @@ namespace gctl
return;
}
template <typename E, typename A>
void save_stl_ascii(std::string filename, const array<vertex<point3dc, E>> &nodes,
const array<type_triangle<A>> &facets, std::string solid)
/**
* @brief Save stl file ascii format
*
* @tparam E Vertex attribute type
* @tparam A Element attribute type
* @param filename File name
* @param facets Input facets
* @param solid Solid name
*/
template <typename A>
void save_stl_ascii(std::string filename, const array<type_triangle<A>> &facets,
std::string solid = "STL generated by GCTL")
{
std::ofstream outfile;
open_outfile(outfile, filename, ".stl");
@ -153,6 +173,155 @@ namespace gctl
outfile.close();
return;
}
/**
* @brief Read stl file binary format
*
* @tparam E vertex attribute type
* @tparam A element attribute type
* @param filename File name
* @param nodes return nodes
* @param facets return facets
* @param eps epsilon for node comparison
*
* @return solid name
*/
template <typename E, typename A>
std::string read_stl_binary(std::string filename, array<vertex<point3dc, E>> &nodes,
array<type_triangle<A>> &facets, double eps = 1e-8)
{
std::ifstream infile;
open_infile(infile, filename, ".stl", std::ios::binary);
char blank[2], header[80];
infile.read(header, 80);
int n_facets;
infile.read((char*)&n_facets, 4);
vertex3dc tmp_node;
std::vector<vertex3dc> tmp_nodes;
_1i_vector one_tri(3);
_2i_vector tmp_tris;
tmp_tris.reserve(n_facets);
bool new_node;
point3fc nor, vt[3];
for (size_t i = 0; i < n_facets; i++)
{
infile.read((char*)&nor.x, 4);
infile.read((char*)&nor.y, 4);
infile.read((char*)&nor.z, 4);
for (size_t j = 0; j < 3; j++)
{
infile.read((char*)&vt[j].x, 4);
infile.read((char*)&vt[j].y, 4);
infile.read((char*)&vt[j].z, 4);
}
infile.read((char*)&blank, 2);
for (size_t j = 0; j < 3; j++)
{
tmp_node.id = tmp_nodes.size();
tmp_node.x = vt[j].x;
tmp_node.y = vt[j].y;
tmp_node.z = vt[j].z;
new_node = true;
for (size_t v = 0; v < tmp_nodes.size(); v++)
{
if (isequal(tmp_nodes[v], tmp_node, eps))
{
tmp_node.id = tmp_nodes[v].id;
new_node = false;
break;
}
}
if (new_node) tmp_nodes.push_back(tmp_node);
one_tri[j] = tmp_node.id;
}
tmp_tris.push_back(one_tri);
}
infile.close();
nodes.resize(tmp_nodes.size());
for (size_t i = 0; i < tmp_nodes.size(); i++)
{
nodes[i].id = tmp_nodes[i].id;
nodes[i].x = tmp_nodes[i].x;
nodes[i].y = tmp_nodes[i].y;
nodes[i].z = tmp_nodes[i].z;
}
facets.resize(tmp_tris.size());
for (size_t i = 0; i < tmp_tris.size(); i++)
{
facets[i].set(nodes[tmp_tris[i][0]], nodes[tmp_tris[i][1]], nodes[tmp_tris[i][2]], i);
}
destroy_vector(tmp_nodes);
destroy_vector(tmp_tris);
destroy_vector(one_tri);
std::string solid_name(header);
return solid_name;
}
/**
* @brief Save stl file binary format
*
* @tparam E vertex attribute type
* @tparam A element attribute type
* @param filename File name
* @param facets return facets
* @param solid solid name
*/
template <typename A>
void save_stl_binary(std::string filename, const array<type_triangle<A>> &facets,
std::string solid = "STL generated by GCTL")
{
std::ofstream outfile;
open_outfile(outfile, filename, ".stl", std::ios::binary);
char blank[2] = {'\0', '\0'};
char header[80];
for (size_t i = 0; i < 80; i++) header[i] = '\0';
for (size_t i = 0; i < solid.size(); i++) header[i] = solid[i];
outfile.write(header, 80);
int n_facets = facets.size();
outfile.write((char*)&n_facets, 4);
point3dc nor;
point3fc nor_fl;
point3fc vt[3];
for (size_t i = 0; i < facets.size(); i++)
{
nor = cross(*facets[i].vert[1] - *facets[i].vert[0], *facets[i].vert[2] - *facets[i].vert[0]).normal();
// convert from double to float
nor_fl.x = nor.x;
nor_fl.y = nor.y;
nor_fl.z = nor.z;
for (size_t j = 0; j < 3; j++)
{
vt[j].x = facets[i].vert[j]->x;
vt[j].y = facets[i].vert[j]->y;
vt[j].z = facets[i].vert[j]->z;
}
outfile.write((char*)&nor_fl.x, 4);
outfile.write((char*)&nor_fl.y, 4);
outfile.write((char*)&nor_fl.z, 4);
for (size_t j = 0; j < 3; j++)
{
outfile.write((char*)&vt[j].x, 4);
outfile.write((char*)&vt[j].y, 4);
outfile.write((char*)&vt[j].z, 4);
}
outfile.write(blank, 2);
}
outfile.close();
}
};
#endif // _GCTL_STL_IO_H

168618
tmp.msh

File diff suppressed because it is too large Load Diff

786816
tmp.stl

File diff suppressed because it is too large Load Diff