Files

42 lines
2.3 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
import { spawn } from 'node:child_process';
import { access } from 'node:fs/promises';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const args = process.argv.slice(2);
if (!args.length || args.includes('--help')) {
console.log(`Usage: npm run blender:export -- INPUT.blend --output OUTPUT.glb [options]
--blender PATH Blender binary (or FORMA_BLENDER; default: blender)
--scene NAME Scene to export
--objects GLOB Export matching objects; repeat for several patterns
--bake-materials Bake procedural/animated surface inputs to UV atlases
--resolution 128 Pixels per baked frame, 161024
--samples 8 Cycles samples per bake, 1256
--lighting compat Unitless lights for Forma; spec preserves physical units
--start-frame N --end-frame N --frame-step N
--allow-lossy Accept approximations listed in OUTPUT.report.json
See docs/BLENDER.md for supported features and limitations.`);
process.exit(args.length ? 0 : 1);
}
const input = path.resolve(args.shift());
if (!/\.blend$/i.test(input)) throw Error('Input must be a .blend file');
await access(input);
const binaryFlag = args.indexOf('--blender');
let binary = process.env.FORMA_BLENDER || 'blender';
if (binaryFlag >= 0) {
if (!args[binaryFlag + 1]) throw Error('--blender requires a path');
binary = args[binaryFlag + 1]; args.splice(binaryFlag, 2);
}
const outputFlag = args.indexOf('--output');
if (outputFlag < 0 || !args[outputFlag + 1] || !/\.glb$/i.test(args[outputFlag + 1])) throw Error('--output OUTPUT.glb is required');
const output = path.resolve(args[outputFlag + 1]);
if (output === input) throw Error('Output must differ from input');
args[outputFlag + 1] = output;
const script = fileURLToPath(new URL('../blender/export_forma.py', import.meta.url));
const child = spawn(binary, ['--background', '--factory-startup', '--disable-autoexec', input, '--python-exit-code', '1', '--python', script, '--', ...args], { stdio: 'inherit', shell: false });
child.on('error', error => { console.error(`Cannot start Blender: ${error.message}. Set FORMA_BLENDER or --blender.`); process.exitCode = 1; });
child.on('exit', (code, signal) => { process.exitCode = code ?? (signal ? 1 : 0); });
process.once('SIGINT', () => child.kill('SIGINT'));
process.once('SIGTERM', () => child.kill('SIGTERM'));