scimesh 0.3.2
Headless CPU-only 3D software renderer for scientific mesh visualization
Loading...
Searching...
No Matches
stl_io.h
Go to the documentation of this file.
1
8
9#pragma once
10
11#include <scimesh/mesh.h>
12#include "stl_reader.h"
13#include <fstream>
14#include <cstring>
15#include <stdexcept>
16#include <string>
17
18namespace scimesh {
20namespace stl_io {
21
45inline Mesh read_stl(const std::string &path) {
46 std::vector<float> coords, normals;
47 std::vector<unsigned int> tris, solids;
48
49 try {
50 stl_reader::ReadStlFile(path.c_str(), coords, normals, tris, solids);
51 } catch (const std::exception &e) {
52 throw std::runtime_error(std::string("Failed to read STL file '") +
53 path + "': " + e.what());
54 }
55
56 Mesh mesh;
57
58 int nv = static_cast<int>(coords.size()) / 3;
59 for (int i = 0; i < nv; i++) {
60 mesh.vertices.push_back(Vec3(
61 coords[i * 3 + 0], coords[i * 3 + 1], coords[i * 3 + 2]));
62 }
63
64 int nt = static_cast<int>(tris.size()) / 3;
65 for (int i = 0; i < nt; i++) {
66 mesh.triangles.push_back(Triangle{
67 tris[i * 3 + 0], tris[i * 3 + 1], tris[i * 3 + 2]});
68 }
69
70 int nn = static_cast<int>(normals.size()) / 3;
71 for (int i = 0; i < nn; i++) {
72 mesh.normals.push_back(Vec3(
73 normals[i * 3 + 0], normals[i * 3 + 1], normals[i * 3 + 2]));
74 }
75
76 return mesh;
77}
78
90inline void write_stl_binary(const std::string &path, const Mesh &mesh) {
91 std::ofstream out(path, std::ios::binary);
92 if (!out) {
93 throw std::runtime_error("Failed to open file for writing: " + path);
94 }
95
96 char header[80] = {};
97 std::memcpy(header, "scimesh STL export", 18);
98 out.write(header, 80);
99
100 uint32_t ntri = static_cast<uint32_t>(mesh.triangles.size());
101 out.write(reinterpret_cast<const char *>(&ntri), 4);
102
103 for (const auto &tri : mesh.triangles) {
104 Vec3 v0 = mesh.vertices[tri.v0];
105 Vec3 v1 = mesh.vertices[tri.v1];
106 Vec3 v2 = mesh.vertices[tri.v2];
107
108 float nx = 0.0f, ny = 0.0f, nz = 1.0f;
109 if (mesh.has_normals() && tri.v0 < mesh.normals.size()) {
110 nx = mesh.normals[tri.v0].x;
111 ny = mesh.normals[tri.v0].y;
112 nz = mesh.normals[tri.v0].z;
113 }
114
115 float normal[3] = {nx, ny, nz};
116 out.write(reinterpret_cast<const char *>(normal), 12);
117
118 float vert_data[9] = {
119 v0.x, v0.y, v0.z,
120 v1.x, v1.y, v1.z,
121 v2.x, v2.y, v2.z};
122 out.write(reinterpret_cast<const char *>(vert_data), 36);
123
124 uint16_t attr = 0;
125 out.write(reinterpret_cast<const char *>(&attr), 2);
126 }
127}
128
140inline void write_stl_ascii(const std::string &path, const Mesh &mesh) {
141 std::ofstream out(path);
142 if (!out) {
143 throw std::runtime_error("Failed to open file for writing: " + path);
144 }
145
146 out << "solid scimesh\n";
147 for (const auto &tri : mesh.triangles) {
148 Vec3 v0 = mesh.vertices[tri.v0];
149 Vec3 v1 = mesh.vertices[tri.v1];
150 Vec3 v2 = mesh.vertices[tri.v2];
151
152 out << " facet normal 0 0 1\n";
153 out << " outer loop\n";
154 out << " vertex " << v0.x << ' ' << v0.y << ' ' << v0.z << '\n';
155 out << " vertex " << v1.x << ' ' << v1.y << ' ' << v1.z << '\n';
156 out << " vertex " << v2.x << ' ' << v2.y << ' ' << v2.z << '\n';
157 out << " endloop\n";
158 out << " endfacet\n";
159 }
160 out << "endsolid scimesh\n";
161}
162
179inline void write_stl(const std::string &path, const Mesh &mesh,
180 const std::string &format) {
181 if (format == "binary") {
182 write_stl_binary(path, mesh);
183 } else {
184 write_stl_ascii(path, mesh);
185 }
186}
187
188} // namespace stl_io
189} // namespace scimesh
The Mesh — the central data structure for 3D geometry in scimesh.
void write_stl(const std::string &path, const Mesh &mesh, const std::string &format)
Write a mesh to an STL file, choosing the format.
Definition stl_io.h:179
void write_stl_binary(const std::string &path, const Mesh &mesh)
Write a mesh to a binary STL file.
Definition stl_io.h:90
Mesh read_stl(const std::string &path)
Load a mesh from an STL file (ASCII or binary).
Definition stl_io.h:45
void write_stl_ascii(const std::string &path, const Mesh &mesh)
Write a mesh to an ASCII STL file.
Definition stl_io.h:140
glm::vec3 Vec3
3-component floating-point vector (xyz).
Definition types.h:46
A 3D triangle mesh using an indexed face set representation.
Definition mesh.h:76
std::vector< Vec3 > normals
Per-vertex surface normals (unit-length direction vectors).
Definition mesh.h:125
bool has_normals() const
Does the mesh have per-vertex normals?
Definition mesh.h:187
std::vector< Vec3 > vertices
3D vertex positions.
Definition mesh.h:86
std::vector< Triangle > triangles
Triangle index triplets.
Definition mesh.h:94
A triangle defined by three vertex indices.
Definition types.h:127