82 lines
4.1 KiB
JavaScript
82 lines
4.1 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import fs from "node:fs";
|
|
import factory from "../../web/app/src/vendor/blender/web_engine.js";
|
|
|
|
const root = new URL("../../", import.meta.url);
|
|
const repeat = Math.max(1, Number.parseInt(process.env.DEPSGRAPH_REPEAT ?? "100", 10) || 100);
|
|
const fixtures = ["empty.blend", "basic_scene.blend", "rigged_shape_scene.blend"];
|
|
const deformationGolden = JSON.parse(fs.readFileSync(new URL("tests/golden/W-079/blender-deformation.json", root), "utf8"));
|
|
|
|
function evaluateFixture(engine, bytes) {
|
|
const handle = engine._web_engine_create();
|
|
assert.ok(handle > 0, "WebEngine handle creation failed");
|
|
try {
|
|
const input = engine._malloc(bytes.byteLength);
|
|
try {
|
|
engine.HEAPU8.set(bytes, input);
|
|
assert.equal(engine._web_engine_open_blend(handle, input, bytes.byteLength), 0, "blend open failed");
|
|
}
|
|
finally {
|
|
engine._free(input);
|
|
}
|
|
|
|
const dataOut = engine._malloc(4);
|
|
const lengthOut = engine._malloc(4);
|
|
try {
|
|
assert.equal(engine._web_engine_evaluate_depsgraph(handle, dataOut, lengthOut), 0, "depsgraph evaluation failed");
|
|
const pointer = engine.HEAPU32[dataOut >>> 2];
|
|
const length = engine.HEAPU32[lengthOut >>> 2];
|
|
assert.ok(pointer && length, "depsgraph returned an empty report");
|
|
return JSON.parse(new TextDecoder().decode(engine.HEAPU8.slice(pointer, pointer + length)));
|
|
}
|
|
finally {
|
|
engine._free(dataOut);
|
|
engine._free(lengthOut);
|
|
}
|
|
}
|
|
finally {
|
|
engine._web_engine_destroy(handle);
|
|
}
|
|
}
|
|
|
|
for (let iteration = 0; iteration < repeat; iteration++) {
|
|
for (const fixture of fixtures) {
|
|
const bytes = fs.readFileSync(new URL(`tests/files/web/${fixture}`, root));
|
|
const engine = await factory({
|
|
wasmBinary: fs.readFileSync(new URL("web/app/src/vendor/blender/web_engine.wasm", root)),
|
|
});
|
|
const report = evaluateFixture(engine, bytes);
|
|
assert.equal(report.engine, "BlenderDepsgraph");
|
|
assert.equal(report.status, "EVALUATED");
|
|
assert.ok(report.objectCount >= report.meshObjectCount);
|
|
for (const mesh of report.meshes) {
|
|
assert.equal(mesh.positions.length, mesh.vertexCount * 3);
|
|
assert.equal(mesh.indices.length, mesh.triangleCount * 3);
|
|
assert.ok(mesh.indices.every((index) => index >= 0 && index < mesh.vertexCount));
|
|
assert.equal(mesh.modifiers.length, mesh.modifierCount);
|
|
assert.deepEqual(mesh.modifiers.map((modifier) => modifier.index), mesh.modifiers.map((_, index) => index));
|
|
assert.ok(mesh.modifiers.every((modifier) => modifier.uuid.startsWith(`modifier:${mesh.objectId}:`)));
|
|
}
|
|
if (fixture === "rigged_shape_scene.blend") {
|
|
const mesh = report.meshes.find((candidate) => candidate.sourceMeshId === `mesh:${deformationGolden.mesh}`);
|
|
assert.ok(mesh, "rigged mesh missing from depsgraph report");
|
|
assert.deepEqual(mesh.modifiers.map((modifier) => modifier.type), ["Armature", "Decimate"]);
|
|
assert.deepEqual(mesh.modifiers.map((modifier) => modifier.status), ["EVALUATED", "BLOCKED"]);
|
|
assert.equal(mesh.modifiers[1].showViewport, true);
|
|
assert.match(mesh.modifiers[1].error, /more than 3 input faces/);
|
|
assert.equal(mesh.modifiers[1].errorCode, "BLENDER_MODIFIER_ERROR");
|
|
assert.match(mesh.modifiers[1].suggestion, /disable/);
|
|
assert.deepEqual(mesh.modifiers[0].targetObjectIds, ["object:RiggedArmatureObject"]);
|
|
assert.ok(mesh.modifiers[0].dependsOn.includes("object:RiggedArmatureObject"));
|
|
assert.deepEqual(mesh.modifiers[1].dependsOn, [mesh.modifiers[0].uuid]);
|
|
const errors = mesh.positions.map((value, index) => value - deformationGolden.positions[index]);
|
|
const maxError = Math.max(...errors.map((value) => Math.abs(value)));
|
|
const rmsError = Math.sqrt(errors.reduce((sum, value) => sum + value * value, 0) / errors.length);
|
|
assert.ok(maxError <= deformationGolden.tolerance.maxPositionError, `max error ${maxError}`);
|
|
assert.ok(rmsError <= deformationGolden.tolerance.rmsPositionError, `RMS error ${rmsError}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
process.stdout.write(`depsgraph-ok repeat=${repeat} fixtures=${fixtures.join(",")}\n`);
|