Files
workinf_Blender_Wasm/tools/web/diagnose-depsgraph.mjs
2026-08-12 04:47:48 -04:00

93 lines
3.7 KiB
JavaScript

import fs from "node:fs";
import factory from "../../web/app/src/vendor/blender/web_engine.js";
const fixtures = process.argv.slice(2);
const fixtureNames = fixtures.length > 0 ? fixtures : [
"empty.blend",
"basic_scene.blend",
"rigged_shape_scene.blend",
];
function readFixture(name) {
if (name.includes("/")) return fs.readFileSync(name);
return fs.readFileSync(new URL(`../../tests/files/web/${name}`, import.meta.url));
}
function openBlend(engine, handle, bytes) {
const pointer = engine._malloc(bytes.byteLength);
try {
engine.HEAPU8.set(bytes, pointer);
return engine._web_engine_open_blend(handle, pointer, bytes.byteLength);
}
finally {
engine._free(pointer);
}
}
function evaluate(engine, handle) {
const dataOut = engine._malloc(4);
const lengthOut = engine._malloc(4);
try {
const result = engine._web_engine_evaluate_depsgraph(handle, dataOut, lengthOut);
const messagePointer = engine._web_engine_last_error_message();
const message = messagePointer ? engine.UTF8ToString(messagePointer) : "";
if (result !== 0) return { result, message };
const pointer = engine.HEAPU32[dataOut >>> 2];
const length = engine.HEAPU32[lengthOut >>> 2];
return { result, report: JSON.parse(new TextDecoder().decode(engine.HEAPU8.slice(pointer, pointer + length))) };
}
finally {
engine._free(dataOut);
engine._free(lengthOut);
}
}
function snapshot(engine, handle) {
const dataOut = engine._malloc(4);
const lengthOut = engine._malloc(4);
try {
if (engine._web_engine_get_scene_snapshot(handle, dataOut, lengthOut) !== 0) return null;
const pointer = engine.HEAPU32[dataOut >>> 2];
const length = engine.HEAPU32[lengthOut >>> 2];
return JSON.parse(new TextDecoder().decode(engine.HEAPU8.slice(pointer, pointer + length)));
}
finally {
engine._free(dataOut);
engine._free(lengthOut);
}
}
for (const fixtureName of fixtureNames) {
process.stdout.write(`depsgraph-diagnostic fixture=${fixtureName} stage=create\n`);
try {
const engine = await factory({ wasmBinary: fs.readFileSync(new URL("../../web/app/src/vendor/blender/web_engine.wasm", import.meta.url)) });
const handle = engine._web_engine_create();
process.stdout.write(`depsgraph-diagnostic fixture=${fixtureName} stage=open\n`);
const openResult = openBlend(engine, handle, readFixture(fixtureName));
if (openResult !== 0) {
process.stdout.write(`depsgraph-diagnostic fixture=${fixtureName} open=${openResult} message=${engine.UTF8ToString(engine._web_engine_last_error_message())}\n`);
engine._web_engine_destroy(handle);
continue;
}
if (process.env.DIAGNOSE_SNAPSHOT === "1") {
const scene = snapshot(engine, handle);
process.stdout.write(`depsgraph-diagnostic fixture=${fixtureName} snapshot=${JSON.stringify(scene?.meshes?.map((mesh) => ({ id: mesh.id, modifiers: mesh.modifierStack })) ?? [])}\n`);
}
process.stdout.write(`depsgraph-diagnostic fixture=${fixtureName} stage=evaluate\n`);
const evaluation = evaluate(engine, handle);
process.stdout.write(`depsgraph-diagnostic fixture=${fixtureName} result=${JSON.stringify(evaluation)}\n`);
engine._web_engine_destroy(handle);
}
catch (error) {
const message = error instanceof Error ? error.message : String(error);
process.stdout.write(`depsgraph-diagnostic fixture=${fixtureName} exception=${message}\n`);
if (error instanceof Error && error.stack) {
const wasmFrames = error.stack.split("\n")
.filter((line) => line.includes("wasm-function") || line.trimStart().startsWith("at "))
.filter((line) => !line.includes("web_engine.js:9"))
.slice(0, 16);
for (const frame of wasmFrames) process.stdout.write(`depsgraph-diagnostic stack=${frame.trim()}\n`);
}
}
}