printhive/lib/converter.js
dlawler489 aabc0dd870 Add Docker packaging (Dockerfile, compose, sidecar deps)
- Dockerfile: node:22-bookworm-slim + Python venv with trimesh for the
  3MF->GLB sidecar (PYTHON_BIN env points the converter at it)
- docker-compose.yml: app + postgres 16 with healthcheck/depends_on,
  named volumes for pgdata/uploads/thumbnails/glb, token env passthrough
- .dockerignore, tools/requirements.txt
- converter.js honours PYTHON_BIN (defaults to local venv)

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

32 lines
1.2 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 = process.env.PYTHON_BIN || 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 };