import { join } from 'path' import { existsSync } from 'fs' import { execFile } from 'child_process' import { promisify } from 'util' const execFileAsync = promisify(execFile) /** * Compress a GLTF/GLB model using Blender's Draco compression. * Returns { success: true } on success, or { success: false, error } on failure. * Callers should fall back to the original file on failure. */ export async function compressWithBlender( inputPath: string, outputPath: string, ): Promise<{ success: boolean; error?: string }> { const blenderPath = process.env.BLENDER_PATH || 'blender' const scriptPath = join(process.cwd(), 'scripts', 'compress.py') if (!existsSync(scriptPath)) { return { success: false, error: 'scripts/compress.py introuvable' } } try { await execFileAsync( blenderPath, [ '--background', '--python', scriptPath, '--', '-i', inputPath, '-o', outputPath, '--draco-level', '7', '--texture-size', '512', '-q', ], { timeout: 120_000 }, ) if (!existsSync(outputPath)) { return { success: false, error: "Blender n'a pas produit de fichier compresse" } } return { success: true } } catch (err) { const message = err instanceof Error ? err.message : String(err) return { success: false, error: `Compression Blender echouee: ${message}` } } }