A simple STL serializer and deserializer
Project description
OpenSTL
The fastest and most intuitive library to manipulate STL files (stereolithography) for C++ and Python, header-only.
🌟 Please consider starring the GitHub repo to show your support! 🌟
Performances benchmark
Discover the staggering performance of OpenSTL in comparison to numpy-stl, meshio and stl-reader, thanks to its powerful C++ backend. See benchmark.py. Benchmark performed on an Intel i5-9600KF CPU @ 3.70GHz.
Performance gains over numpy-stl, meshio and stl-reader
Write: 1.3 to 4+ X faster
Read: 1 to 2.3+ X faster
Rotate: 1 to 12+ X faster
Note: meshio has no straightfoward way of rotating vertices, so it was not benchmarked.
Python Usage
Install
pip install openstl
or pip install -U git+https://github.com/Innoptech/OpenSTL@main
Read and write from a STL file
import openstl
import numpy as np
# Define an array of triangles
# Following the STL standard, each triangle is defined with : normal, v0, v1, v2
quad = np.array([
# normal, vertices 0, vertices 1, vertices 2
[[0.0, 0.0, 1.0], [0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [1.0, 1.0, 0.0]], # Triangle 1
[[0.0, 0.0, 1.0], [0.0, 0.0, 0.0], [0.0, 1.0, 0.0], [1.0, 1.0, 0.0]], # Triangle 2
])
# Serialize the triangles to a file
success = openstl.write("quad.stl", quad, openstl.format.binary) # Or openstl.format.ascii (slower but human readable)
if not success:
raise Exception("Error: Failed to write to the specified file.")
# Deserialize triangles from a file
deserialized_quad = openstl.read("quad.stl")
# Print the deserialized triangles
print("Deserialized Triangles:", deserialized_quad)
Rotate, translate and scale a mesh
import openstl
import numpy as np
quad = openstl.read("quad.stl")
# Rotating
rotation_matrix = np.array([
[0,-1, 0],
[1, 0, 0],
[0, 0, 1]
])
rotated_quad = np.matmul(rotation_matrix, quad.reshape(-1,3).T).T.reshape(-1,4,3)
# Translating
translation_vector = np.array([1,1,1])
quad[:,1:4,:] += translation_vector # Avoid translating normals
# Scaling
scale = 1000.0
quad[:,1:4,:] *= scale # Avoid scaling normals
C++ Usage
Read STL from file
std::ifstream file(filename, std::ios::binary);
if (!file.is_open()) {
std::cerr << "Error: Unable to open file '" << filename << "'" << std::endl;
}
// Deserialize the triangles in either binary or ASCII format
std::vector<openstl::Triangle> triangles = openstl::deserializeStl(file);
file.close();
Write STL to a file
std::ofstream file(filename, std::ios::binary);
if (!file.is_open()) {
std::cerr << "Error: Unable to open file '" << filename << "'" << std::endl;
}
std::vector<openstl::Triangle> originalTriangles{}; // User triangles
openstl::serialize(originalTriangles, file, openstl::StlFormat::Binary); // Or StlFormat::ASCII
if (file.fail()) {
std::cerr << "Error: Failed to write to file " << filename << std::endl;
} else {
std::cout << "File " << filename << " has been successfully written." << std::endl;
}
file.close();
Serialize STL to a stream
std::stringstream ss;
std::vector<openstl::Triangle> originalTriangles{}; // User triangles
openstl::serialize(originalTriangles, ss, openstl::StlFormat::Binary); // Or StlFormat::ASCII
Integrate to your codebase
Smart method
Include this repository with CMAKE Fetchcontent and link your executable/library to openstl::core
library.
Choose weither you want to fetch a specific branch or tag using GIT_TAG
. Use the main
branch to keep updated with the latest improvements.
include(FetchContent)
FetchContent_Declare(
openstl
GIT_REPOSITORY https://github.com/Innoptech/OpenSTL.git
GIT_TAG main
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE
)
FetchContent_MakeAvailable(openstl)
Naïve method
Simply add stl.h to your codebase.
Test
git clone https://github.com/Innoptech/OpenSTL
mkdir OpenSTL/build && cd OpenSTL/build
cmake -DOPENSTL_BUILD_TESTS=ON .. && cmake --build .
ctest .
Requirements
C++11 or higher.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Hashes for openstl-1.0.3-pp310-pypy310_pp73-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 668c7ae52d81728849ebea4cd43ad8b781bf315894f1790ff58d01d645514cf0 |
|
MD5 | 2e46d72c7c9ac4d25b0eaf30182d1728 |
|
BLAKE2b-256 | c890a7c493fed368a4c2d214346ac0c072183996e30c1c5c5257a41cb58bf43b |
Hashes for openstl-1.0.3-pp39-pypy39_pp73-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 93b229c284ab88fad3efb265fcefae2ab9a7472aebaa7ed5b7ad27540428c0b9 |
|
MD5 | 7531ad17591bbe151428e445fbcb0ee5 |
|
BLAKE2b-256 | 772b67dbc8b259dc3eb38369236688ce0626d52e845c0f21eb5ef02ade33f968 |
Hashes for openstl-1.0.3-pp38-pypy38_pp73-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | eb5548ed2bc939fd9a43cb70aba42855eaface5b5eb2bc3cf33962ede1429034 |
|
MD5 | cc0104941b420f8d58eb590b7f6f7828 |
|
BLAKE2b-256 | 5f271f056bbc3e224c3fd811d5e68d6ccf97a327535579f301a158932ee25265 |
Hashes for openstl-1.0.3-pp37-pypy37_pp73-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 8930be3fc6f781cf1f0e6581214d356be6426ae17a8c13ab2641230bd5385f0b |
|
MD5 | a552b6c2a132fdfc21ee23b1c8e95cbe |
|
BLAKE2b-256 | 0f906bbaf3829316036368cafc9ab7c19be780a617c7bb5d875f6aa0ca2d03a0 |
Hashes for openstl-1.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 413c2e774340a601fc19c7f65bac33b5566b1e402399445ec24173c3bebee1a3 |
|
MD5 | 6f3ec4eec4b725abbf73ed9b8c15d0ec |
|
BLAKE2b-256 | fc6d6e502379922fc64d47fe95890395c173672173dde3552b6fa05e7de17315 |
Hashes for openstl-1.0.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 4c99fd113f125887c4166c47bd6e3040a8d0423ea20ab49e72b61818a25350ec |
|
MD5 | a9fc53306a6bc079db2ce4f12c8b84fe |
|
BLAKE2b-256 | 333b735b2427aafa8b2195861a8077a0136684fa1fde46347638ab4f75c11425 |
Hashes for openstl-1.0.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | fe750aa69217270e2d5b210642cd07cff61bb7911131b9e31f0d93d33805aeb2 |
|
MD5 | 3f1f6eeb8b4325da64c6ec400a81659b |
|
BLAKE2b-256 | 84ff9f3adf1c0eac6c7d1f11632388eedde1172b30dec10ad606252b8eedec9d |
Hashes for openstl-1.0.3-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | db4a95db5f2248597b1588a399d62bc6bcc712ec81a64ebdeb003ceda61eaa83 |
|
MD5 | 99e08721c6c5cd857fc95650473eb31e |
|
BLAKE2b-256 | 298a8524e94f19c0f79be5fde94b48f6223d9876139c30bb783cb1a3b5a50841 |
Hashes for openstl-1.0.3-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0b295f839ad3f808e2a9e862d084b6d9fdc4a34b33499f1807fab57a2054b85f |
|
MD5 | bd48b189497d389d8a40bb3d472592d3 |
|
BLAKE2b-256 | 3a389771c8a1d79f1051591adb5ce7e46c7c826d033f38f2bd25dfd8135ecebe |
Hashes for openstl-1.0.3-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 53af7c9198d03469936e4e2b1bc9952eab959f3bc8a30d8e00d345d44fede69a |
|
MD5 | 112caae6d13273820123ad90cc1b8890 |
|
BLAKE2b-256 | 7ff37d5d917a2b9f00e34f4aae31c252952b580d149b29ba53321e03d50d8849 |
Hashes for openstl-1.0.3-cp36-cp36m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0282405e1131160c4fa9cfcd8ff9cbb622888416504fee3d57b6300eaab637ab |
|
MD5 | 861b922a5b340e543ed2b5b5efca0a38 |
|
BLAKE2b-256 | 78ab96a66d114ce95eabff72f80369fa18b214bf4da37d621f3a24613daddf56 |