printhive/lib/converter.js
dlawler489 a37db15a3f Initial commit: Printhive 3D-print file library
Self-hosted Express + Postgres app for organizing STL/3MF/OBJ/etc. with:
- Model/file library, tags, collections, print settings
- URL import: Thingiverse (API), Printables (GraphQL), MakerWorld
  (FlareSolverr + token), cubee3d/other (metadata + manual files)
- In-browser 3D viewer; 3MF rendered via Python/trimesh GLB conversion
- Auto thumbnails, license/commercial-use tracking, in-app editing
- Settings (API tokens / FlareSolverr) stored in DB with .env fallback

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 13:15:17 +10:00

32 lines
1.1 KiB
JavaScript

// Converts 3MF files to GLB via the Python/trimesh sidecar, so the browser can
// render Bambu/MakerWorld production-extension 3MFs (which the JS 3MFLoader can't).
const path = require('path');
const { execFile } = require('child_process');
const PYTHON = path.join(__dirname, '..', 'tools', 'venv', 'bin', 'python');
const SCRIPT = path.join(__dirname, '..', 'tools', 'convert_3mf.py');
// Returns { glb, volume_cm3, bbox, faces } or throws.
function convert3mfToGlb(inputPath, outputPath) {
return new Promise((resolve, reject) => {
execFile(
PYTHON,
[SCRIPT, inputPath, outputPath],
{ maxBuffer: 16 * 1024 * 1024, timeout: 120000 },
(err, stdout, stderr) => {
if (err) return reject(new Error(stderr ? stderr.split('\n').slice(-3).join(' ') : err.message));
let result;
try {
result = JSON.parse(stdout.trim().split('\n').pop());
} catch {
return reject(new Error('Converter returned unparseable output.'));
}
if (result.error) return reject(new Error(result.error));
resolve(result);
}
);
});
}
module.exports = { convert3mfToGlb };