block requirements

This commit is contained in:
2026-09-28 19:58:29 +02:00
parent 26f7aaecc1
commit 3505efed8c
2 changed files with 50 additions and 7 deletions
+40 -2
View File
@@ -17,6 +17,7 @@ function harness() {
const events = new Map();
const previewEvents = new Map();
const timers = new Map();
const previewUpdates = [];
let sequence = 0;
class Group {
static all = [];
@@ -57,8 +58,20 @@ function harness() {
MenuBar: { menus: { tools: { addAction() {} } }, update() {} },
THREE: { MeshBasicMaterial: class { constructor(options) { Object.assign(this, options); } }, DoubleSide: 2 },
Canvas: {
updateAll() { for (const cube of Cube.all) previewEvents.get('update_faces')?.({ element: cube }); },
updateAll() {
for (const cube of Cube.all) {
cube.mesh.material = 'selected-shared-texture';
previewEvents.get('update_faces')?.({ element: cube });
}
},
updateAllFaces() { this.updateAll(); },
updateView(options) {
previewUpdates.push(options);
for (const cube of options.elements || []) {
cube.mesh.material = 'selected-shared-texture';
if (options.element_aspects?.faces) previewEvents.get('update_faces')?.({ element: cube });
}
},
},
Undo: {
initEdit(aspects) { edits.push({ before: project.animationdirector_block_requirements, aspects }); },
@@ -72,7 +85,7 @@ function harness() {
console,
};
vm.runInNewContext(source, context);
return { ...context.blockTest, context, project, dialogs, exports, errors, edits, events, previewEvents, timers, Group, Cube };
return { ...context.blockTest, context, project, dialogs, exports, errors, edits, events, previewEvents, timers, previewUpdates, Group, Cube };
}
function wallForm(overrides = {}) {
@@ -80,6 +93,31 @@ function wallForm(overrides = {}) {
facing: '', clearance_width: 1, clearance_height: 2, clearance_depth: 1, wall_thickness: 1, ...overrides };
}
test('building, editing, refreshing and removing guides never resets actor or folder texture overrides', () => {
const h = harness();
const actor = new h.Group({ name: 'actor1_body' });
actor.init(); actor.addTo('root');
const cubes = ['actor-texture', 'folder-override-texture'].map((material, index) => {
const cube = new h.Cube({ name: `actor1_cube${index}`, from: [0, 0, 0], to: [16, 16, 16] });
cube.init(); cube.addTo(actor);
cube.mesh.material = material;
for (const face of Object.values(cube.faces)) face.texture = material;
return cube;
});
const before = cubes.map((cube) => ({ material: cube.mesh.material, faces: JSON.stringify(cube.faces) }));
h.context.registration.onload();
h.rebuildBlockRequirementGuides('test', h.readBlockRequirementForm(wallForm()));
h.rebuildBlockRequirementGuides('test', h.readBlockRequirementForm(wallForm({ width_min: 3, clearance_depth: 2 })));
h.refreshBlockGuideFaces();
h.rebuildBlockRequirementGuides('test', null);
assert.deepEqual(cubes.map((cube) => ({ material: cube.mesh.material, faces: JSON.stringify(cube.faces) })), before);
for (const update of h.previewUpdates) {
assert.ok(update.elements.every((cube) => !cubes.includes(cube)));
assert.ok((update.groups || []).every((group) => group !== actor));
}
assert.equal(h.previewUpdates.length, 4);
});
test('guide cubes omit internal faces, preserve colored boundaries and restore newly exposed faces', () => {
const h = harness();
const make = (kind, from, to) => new h.Cube({ name: `__ad_block_requirement_${kind}_test`, from, to });