Files

31 lines
2.2 KiB
TypeScript

import test from 'node:test';
import assert from 'node:assert/strict';
import {promisify} from 'node:util';
import {execFile} from 'node:child_process';
import {mkdtemp,readFile,rm} from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
import {inspectModel,modelDocument} from '../engine/model.ts';
const exec=promisify(execFile), binary=process.env.FORMA_BLENDER;
test('Blender exports shape keys, curves, cameras, lights and driver-baked animated textures', {skip:!binary,timeout:180000}, async()=>{
const dir=await mkdtemp(path.join(os.tmpdir(),'forma-blender-'));
try{
const input=path.join(dir,'input.blend'),output=path.join(dir,'output.glb');
await exec(binary!,['--background','--factory-startup','--disable-autoexec','--python-exit-code','1','--python',path.resolve('tests/blender-fixture.py'),'--',input],{maxBuffer:4*1024*1024});
const original=await readFile(input);
await exec(process.execPath,['scripts/export-blender.mjs',input,'--output',output,'--bake-materials','--resolution','16','--samples','1'],{maxBuffer:4*1024*1024});
assert.deepEqual(await readFile(input),original,'the source .blend is never saved or modified');
const bytes=new Uint8Array(await readFile(output)),doc=modelDocument(bytes,'output.glb'),meta=inspectModel(bytes,'output.glb');
assert.equal(doc.scenes.length,1);assert.equal(meta.cameras.length,1);assert.equal(meta.lights,1);assert.equal(meta.morphTargets,1);
assert.equal(meta.activeCamera,'ActiveCameraData');
assert.ok(Math.abs(doc.extensions.KHR_lights_punctual.lights[0].intensity-100/(4*Math.PI))<.001,'Forma-compatible light units avoid overexposure');
assert.ok(doc.nodes.some((n:any)=>n.name==='ConvertedCurve'&&n.mesh!==undefined));
assert.ok(!doc.nodes.some((n:any)=>n.name==='UnrelatedObject'));
assert.ok(meta.animatedProperties.some(p=>p.endsWith('KHR_texture_transform/offset')));
const report=JSON.parse(await readFile(output.replace('.glb','.report.json'),'utf8'));
assert.equal(report.bakedMaterials[0].frames,3);
const material=doc.materials.find((m:any)=>m.name.startsWith('FormaBake_'));
assert.ok(material.pbrMetallicRoughness.baseColorTexture.extensions.KHR_texture_transform);
}finally{await rm(dir,{recursive:true,force:true});}
});