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 a structured result so callers can decide whether to fall back or stop. */ export async function compressWithBlender( inputPath: string, outputPath: string, ): Promise<{ success: boolean; error?: string }> { const blenderPath = process.env.BLENDER_PATH || 'blender' const timeout = Number(process.env.BLENDER_TIMEOUT_MS || 600_000) 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 }, ) 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}` } } }