Advance N-015 through N-018 bounded workflows
This commit is contained in:
@@ -44,6 +44,17 @@ function command(engine, handle, payload) {
|
||||
finally { engine._free(pointer); }
|
||||
}
|
||||
|
||||
function reject(engine, handle, payload, code) {
|
||||
const bytes = new TextEncoder().encode(JSON.stringify(payload));
|
||||
const pointer = engine._malloc(bytes.byteLength);
|
||||
try {
|
||||
engine.HEAPU8.set(bytes, pointer);
|
||||
assert.notEqual(engine._web_engine_apply_command(handle, pointer, bytes.byteLength), 0, `${payload.type} unexpectedly succeeded`);
|
||||
assert.match(engine.UTF8ToString(engine._web_engine_last_error_message()), new RegExp(code));
|
||||
}
|
||||
finally { engine._free(pointer); }
|
||||
}
|
||||
|
||||
function snapshot(engine, handle) {
|
||||
return JSON.parse(new TextDecoder().decode(output(engine, handle, engine._web_engine_get_scene_snapshot)));
|
||||
}
|
||||
@@ -198,7 +209,8 @@ const curveCyclic = curve.cyclicU.map((value, index) => index === 0 ? !value : v
|
||||
const curveHandlePoints = curve.handlePoints.slice();
|
||||
curveHandlePoints[0] += 0.25;
|
||||
curveHandlePoints[15] -= 0.2;
|
||||
command(engine, handle, { type: "setCurveTopology", dataId: curveId, splineTypes: curve.splineTypes, cyclicU: curveCyclic, cyclicV: curve.cyclicV, handleTypes: curve.handleTypes, handlePoints: curveHandlePoints });
|
||||
reject(engine, handle, { type: "setCurveTopology", baseRevision: snapshot(engine, handle).revision - 1, dataId: curveId, splineTypes: curve.splineTypes, cyclicU: curveCyclic, cyclicV: curve.cyclicV, handleTypes: curve.handleTypes, handlePoints: curveHandlePoints }, "REVISION_CONFLICT");
|
||||
command(engine, handle, { type: "setCurveTopology", baseRevision: snapshot(engine, handle).revision, dataId: curveId, splineTypes: curve.splineTypes, cyclicU: curveCyclic, cyclicV: curve.cyclicV, handleTypes: curve.handleTypes, handlePoints: curveHandlePoints });
|
||||
const preciseHandlePosition = curveHandlePoints.slice(12, 15);
|
||||
preciseHandlePosition[2] += 0.125;
|
||||
command(engine, handle, { type: "setCurveHandle", dataId: curveId, pointIndex: curve.handlePointIndices[2], side: "LEFT", position: preciseHandlePosition });
|
||||
|
||||
69
tools/web/check-physics-main-reader.mjs
Normal file
69
tools/web/check-physics-main-reader.mjs
Normal file
@@ -0,0 +1,69 @@
|
||||
import assert from "node:assert/strict";
|
||||
import crypto from "node:crypto";
|
||||
import fs from "node:fs";
|
||||
import factory from "../../web/app/src/vendor/blender/web_engine.js";
|
||||
|
||||
const root = new URL("../../", import.meta.url);
|
||||
const wasmBinary = fs.readFileSync(new URL("web/app/src/vendor/blender/web_engine.wasm", root));
|
||||
const fixture = fs.readFileSync(new URL("tests/files/web/modifier_physics_scene.blend", root));
|
||||
|
||||
function open(engine, handle, bytes) {
|
||||
const pointer = engine._malloc(bytes.byteLength);
|
||||
try {
|
||||
engine.HEAPU8.set(bytes, pointer);
|
||||
assert.equal(engine._web_engine_open_blend(handle, pointer, bytes.byteLength), 0,
|
||||
engine.UTF8ToString(engine._web_engine_last_error_message()));
|
||||
}
|
||||
finally { engine._free(pointer); }
|
||||
}
|
||||
|
||||
function output(engine, handle, fn, owned = false) {
|
||||
const dataOut = engine._malloc(4);
|
||||
const lengthOut = engine._malloc(4);
|
||||
try {
|
||||
assert.equal(fn(handle, dataOut, lengthOut), 0, engine.UTF8ToString(engine._web_engine_last_error_message()));
|
||||
const pointer = engine.HEAPU32[dataOut >>> 2];
|
||||
const length = engine.HEAPU32[lengthOut >>> 2];
|
||||
const bytes = engine.HEAPU8.slice(pointer, pointer + length);
|
||||
if (owned) engine._web_engine_free_buffer(pointer);
|
||||
return bytes;
|
||||
}
|
||||
finally { engine._free(dataOut); engine._free(lengthOut); }
|
||||
}
|
||||
|
||||
function snapshot(engine, handle) {
|
||||
return JSON.parse(new TextDecoder().decode(output(engine, handle, engine._web_engine_get_scene_snapshot)));
|
||||
}
|
||||
|
||||
function assertManifest(scene) {
|
||||
const manifest = scene.physicsSimulation;
|
||||
assert.equal(manifest?.schemaVersion, 1);
|
||||
assert.deepEqual(manifest.systems.map((system) => system.family).sort(), ["CLOTH", "SOFT_BODY"]);
|
||||
for (const system of manifest.systems) {
|
||||
assert.match(system.id, /^physics:/);
|
||||
assert.match(system.ownerObjectId, /^object:/);
|
||||
assert.deepEqual(system.settingsHash, crypto.createHash("sha256").update(JSON.stringify(system.settings)).digest("hex"));
|
||||
assert.equal(system.cache, undefined);
|
||||
}
|
||||
const collisionId = "object:PhysicsCollisionDisabled";
|
||||
assert.ok(manifest.systems.every((system) => system.dependencyIds.includes(collisionId)));
|
||||
const cloth = manifest.systems.find((system) => system.family === "CLOTH");
|
||||
const soft = manifest.systems.find((system) => system.family === "SOFT_BODY");
|
||||
assert.equal(cloth.settings.name, "Cloth Disabled");
|
||||
assert.equal(cloth.settings.enabled, false);
|
||||
assert.equal(soft.ownerObjectId, "object:PhysicsSoftBodyDisabled");
|
||||
assert.equal(typeof soft.settings.nodeMass, "number");
|
||||
}
|
||||
|
||||
const engine = await factory({ wasmBinary: wasmBinary.slice() });
|
||||
const handle = engine._web_engine_create();
|
||||
open(engine, handle, fixture);
|
||||
assertManifest(snapshot(engine, handle));
|
||||
const saved = output(engine, handle, engine._web_engine_save_blend, true);
|
||||
engine._web_engine_destroy(handle);
|
||||
|
||||
const reopened = engine._web_engine_create();
|
||||
open(engine, reopened, saved);
|
||||
assertManifest(snapshot(engine, reopened));
|
||||
engine._web_engine_destroy(reopened);
|
||||
process.stdout.write("physics-main-reader-ok families=CLOTH,SOFT_BODY dependencies=COLLISION settings-sha256=passed save-reopen=passed playback=BLOCKED solver=BLOCKED\n");
|
||||
23
tools/web/check-vdb-availability.mjs
Normal file
23
tools/web/check-vdb-availability.mjs
Normal file
@@ -0,0 +1,23 @@
|
||||
import assert from "node:assert/strict";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
const root = path.resolve(new URL("../..", import.meta.url).pathname);
|
||||
const cachePath = path.join(root, "build_web_blender6", "CMakeCache.txt");
|
||||
const cache = fs.readFileSync(cachePath, "utf8");
|
||||
assert.match(cache, /^WITH_OPENVDB:BOOL=OFF$/m, "OpenVDB must remain disabled until a WASM decoder is linked");
|
||||
assert.match(cache, /^WITH_NANOVDB:BOOL=ON$/m, "NanoVDB metadata support is expected");
|
||||
|
||||
const roots = [path.join(root, "resource-library"), path.join(root, "tests"), "/home/mes123456/resource-library"];
|
||||
const vdbFiles = [];
|
||||
function scan(directory) {
|
||||
if (!fs.existsSync(directory)) return;
|
||||
for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
|
||||
const fullPath = path.join(directory, entry.name);
|
||||
if (entry.isDirectory()) scan(fullPath);
|
||||
else if (/\.vdb(?:\.gz)?$/i.test(entry.name)) vdbFiles.push(fullPath);
|
||||
}
|
||||
}
|
||||
for (const directory of roots) scan(directory);
|
||||
assert.equal(vdbFiles.length, 0, `unexpected local VDB resource(s): ${vdbFiles.join(", ")}`);
|
||||
process.stdout.write("vdb-availability-ok status=BLOCKED openvdb=disabled nanovdb=metadata-only local-vdb=0 renderer=blocked decoder=blocked\n");
|
||||
Reference in New Issue
Block a user