build123d
build123d copied to clipboard
add BytesIO support to all export functions (STL, STEP, etc)
Currently export_brep supports BytesIO export, consider adding to other export functions. It may make upcoming wasm in-browser usage easier.
ref: https://github.com/yeicor/OCP.wasm/issues/4
BytesIO support for gltf would be a big help for me as well
+1 for gltf in particular as it is the preferred format for threejs. stl would also be useful to me.
OK I have done further research and testing, and here is the current state of this proposal (has not been put into build123d yet, just local work). I am particularly disappointed that we don't have an OCCT-native solution for GLTF. It appears that OCCT simply does not support std::ostream for many of the exporter file formats.
| file format | ability to export to BytesIO |
|---|---|
| BREP | ✅ already implemented |
| SVG | ✅ tested and working |
| DXF | ✅ tested and working |
| STEP | ✅ tested and working |
| STL | ❌ not possible with OCCT |
| GLTF/GLB | ❌ not possible with OCCT |
| STL | ✅ tested and working using lib3mf / Mesher |
| 3MF | ✅ tested and working using lib3mf / Mesher |
After consulting with ChatGPT on this the following seems like it might be an acceptable solution the the STL and GLTF/GLB case:
import io
import os
import tempfile
import sys
from OCP.StlAPI import StlAPI_Writer
def write_stl_to_memory(shape, binary=True) -> io.BytesIO:
"""Write shape to STL entirely in memory (best-effort cross-platform)."""
writer = StlAPI_Writer()
writer.ASCIIMode(not binary)
# --- Linux fast path ---
if hasattr(os, "memfd_create"):
fd = os.memfd_create("stl_buffer")
tmp_path = f"/proc/self/fd/{fd}"
writer.Write(shape, tmp_path)
os.lseek(fd, 0, os.SEEK_SET)
data = os.read(fd, 1 << 24) # read up to 16 MB; adjust as needed
os.close(fd)
return io.BytesIO(data)
# --- macOS / Windows fallback ---
with tempfile.SpooledTemporaryFile(max_size=64 * 1024 * 1024) as tmp:
tmp_name = tmp.name if tmp.name else "tmp.stl"
writer.Write(shape, tmp_name)
tmp.seek(0)
data = tmp.read()
return io.BytesIO(data)
OK as of the above merged PR, here is the current status:
| file format | ability to export to BytesIO |
|---|---|
| BREP | ✅ already released |
| SVG | ✅ merged in PR #1141 |
| DXF | ✅ merged in PR #1141 |
| STEP | ✅ merged in PR #1141 |
| STL | ❌ not possible with OCCT |
| GLTF/GLB | ❌ not possible with OCCT |
| STL | ✅ merged in PR #1141 using lib3mf / Mesher.write_stream |
| 3MF | ✅ merged in PR #1141 using lib3mf / Mesher.write_stream |
As such, I have decided to keep this issue open (with an updated title). The major missing piece is GLTF/GLB, per the linked issue at OCCT it sounds like they have added this (and STL, maybe others) to their roadmap.