/******************************************************** * ██████╗ ██████╗████████╗██╗ * ██╔════╝ ██╔════╝╚══██╔══╝██║ * ██║ ███╗██║ ██║ ██║ * ██║ ██║██║ ██║ ██║ * ╚██████╔╝╚██████╗ ██║ ███████╗ * ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝ * Geophysical Computational Tools & Library (GCTL) * * Copyright (c) 2023 Yi Zhang (yizhang-geo@zju.edu.cn) * * GCTL is distributed under a dual licensing scheme. 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 2 * of the License, or (at your option) any later version. You should have * received a copy of the GNU Lesser General Public License along with this * program. If not, see . * * If the terms and conditions of the LGPL v.2. would prevent you from using * the GCTL, please consider the option to obtain a commercial license for a * fee. These licenses are offered by the GCTL's original author. As a rule, * licenses are provided "as-is", unlimited in time for a one time fee. Please * send corresponding requests to: yizhang-geo@zju.edu.cn. Please do not forget * to include some description of your company and the realm of its activities. * Also add information on how to contact you by electronic and paper mail. ******************************************************/ #ifndef _GCTL_STL_IO_H #define _GCTL_STL_IO_H // library's head file #include "../core.h" #include "../utility.h" #include "../geometry.h" namespace gctl { template void read_stl_ascii(std::string filename, array> &nodes, array> &facets, std::string solid = "null", double eps = 1e-8) { std::ifstream infile; open_infile(infile, filename, ".stl"); vertex3dc tmp_node; std::vector tmp_nodes; _1i_vector one_tri(3); _2i_vector tmp_tris; bool inside_solid, new_node; point3dc nor, vt[3]; char solid_name[256], solid_endname[256]; std::string line; while (std::getline(infile, line)) { if (sscanf(line.c_str(), "solid %s", solid_name) == 1 && (!strcmp(solid_name, solid.c_str()) || solid == "null")) { inside_solid = true; while (inside_solid) { std::getline(infile, line); if (sscanf(line.c_str(), "endsolid %s", solid_endname) == 1) { if (strcmp(solid_endname, solid_name)) throw std::runtime_error("[gctl::read_stl_ascii] Invalid solid names."); inside_solid = false; } else { sscanf(line.c_str(), "facet normal %lf %lf %lf", &nor.x, &nor.y, &nor.z); std::getline(infile, line); // outer loop for (int i = 0; i < 3; i++) { std::getline(infile, line); line.erase(0, line.find_first_not_of(" \t")); 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 std::getline(infile, line); // endfacet for (size_t i = 0; i < 3; i++) { tmp_node.id = tmp_nodes.size(); tmp_node.x = vt[i].x; tmp_node.y = vt[i].y; tmp_node.z = vt[i].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[i] = 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); return; } template void save_stl_ascii(std::string filename, const array> &nodes, const array> &facets, std::string solid) { std::ofstream outfile; open_outfile(outfile, filename, ".stl"); point3dc nor; outfile << "solid " << solid << "\n"; 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(); outfile << "facet normal " << nor.x << " " << nor.y << " " << nor.z << "\n"; outfile << " outer loop\n"; outfile << " vertex " << facets[i].vert[0]->x << " " << facets[i].vert[0]->y << " " << facets[i].vert[0]->z << "\n"; outfile << " vertex " << facets[i].vert[1]->x << " " << facets[i].vert[1]->y << " " << facets[i].vert[1]->z << "\n"; outfile << " vertex " << facets[i].vert[2]->x << " " << facets[i].vert[2]->y << " " << facets[i].vert[2]->z << "\n"; outfile << " endloop\n"; outfile << "endfacet\n"; } outfile << "endsolid " << solid << "\n"; outfile.close(); return; } }; #endif // _GCTL_STL_IO_H