56 lines
2.7 KiB
JavaScript
56 lines
2.7 KiB
JavaScript
import fs from "node:fs";
|
|
import factory from "../../web/app/src/vendor/blender/web_engine.js";
|
|
|
|
const ratio = Number(process.argv[2]);
|
|
if (!Number.isFinite(ratio) || ratio <= 0 || ratio > 1) throw new Error("usage: probe-collapse-ratio.mjs RATIO");
|
|
const wasmBinary = fs.readFileSync(new URL("../../web/app/src/vendor/blender/web_engine.wasm", import.meta.url));
|
|
const blend = fs.readFileSync(new URL("../../tests/files/web/basic_scene.blend", import.meta.url));
|
|
const engine = await factory({ wasmBinary });
|
|
const handle = engine._web_engine_create();
|
|
const text = new TextEncoder();
|
|
function open() {
|
|
const pointer = engine._malloc(blend.byteLength);
|
|
engine.HEAPU8.set(blend, pointer);
|
|
const result = engine._web_engine_open_blend(handle, pointer, blend.byteLength);
|
|
engine._free(pointer);
|
|
return result;
|
|
}
|
|
function snapshot() {
|
|
const dataOut = engine._malloc(4);
|
|
const lengthOut = engine._malloc(4);
|
|
try {
|
|
const result = engine._web_engine_get_scene_snapshot(handle, dataOut, lengthOut);
|
|
if (result !== 0) throw new Error("snapshot failed");
|
|
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);
|
|
}
|
|
}
|
|
function apply(meshId, revision) {
|
|
const command = text.encode(JSON.stringify({
|
|
type: "decimateMesh",
|
|
meshId,
|
|
profile: { schemaVersion: 1, sourceMeshRevision: revision, attributePolicy: "PRESERVE", mode: "COLLAPSE", ratio, triangulate: false, useSymmetry: false },
|
|
}));
|
|
const pointer = engine._malloc(command.byteLength);
|
|
engine.HEAPU8.set(command, pointer);
|
|
const result = engine._web_engine_apply_command(handle, pointer, command.byteLength);
|
|
engine._free(pointer);
|
|
return result;
|
|
}
|
|
const opened = open();
|
|
if (opened !== 0) throw new Error(`open failed code=${opened} message=${engine.UTF8ToString(engine._web_engine_last_error_message())}`);
|
|
const source = snapshot();
|
|
const mesh = source.meshes.find((candidate) => candidate.id === "mesh:Cube.001") ?? source.meshes.find((candidate) => candidate.geometryStatus === "available");
|
|
if (!mesh) throw new Error("cube mesh not found");
|
|
const result = apply(mesh.id, source.revision);
|
|
const message = engine.UTF8ToString(engine._web_engine_last_error_message());
|
|
let output = null;
|
|
if (result === 0) output = snapshot().meshes.find((candidate) => candidate.id === mesh.id);
|
|
console.log(JSON.stringify({ ratio, result, message, allocatedBytes: engine._web_engine_get_allocated_bytes(), output: output && { vertexCount: output.vertexCount, triangleCount: output.triangleCount, faceCount: output.faceCount } }));
|
|
engine._web_engine_destroy(handle);
|