Files
DOSSIER-STANDALONE/scripts/probe-wall-cmd.mjs
T
karim 3d2d4d6321 2D-Plan-Renderer auf WebGL2 (GPU) + akkumulierter Funktionsstand
Neuer GPU-Renderer fuer den Grundriss (src/plan/glPlan/): Earcut-Tessellierung
(konkav-faehig), gehrte Linienzuege (Miter), echte Papier-mm-Strichbreiten im
Massstab (repliziert den SVG-printStrokeVb-Pfad), Hybrid mit scharfem SVG-Text-
Overlay. GPU ist der Standardpfad; der SVG-Renderer bleibt automatischer Fallback,
falls WebGL2/Shader nicht verfuegbar sind. Imperativer Pan (rAF + CSS-transform)
fuer fluessige Interaktion ohne React-Re-Render je Frame.

Enthaelt zudem den bisher nicht committeten Arbeitsstand des Browser-BIM
(Oeffnungen, Treppen, Raeume, Decken, DXF-Export, Materialbibliothek, Kontext-
Import, Tauri-Compute-Boundary-PoC).
2026-07-02 00:12:39 +02:00

102 lines
4.6 KiB
JavaScript

// Verifikation: „Wand" als echter Engine-Befehl.
// 1) GUI-„Wand" klicken → Befehlsfeld aktiv (Wand-Prompt, Feld fokussiert).
// 2) Mehrere Punkte im Plan klicken → Wände entstehen (Plan-Primitive wachsen),
// Rechtsklick beendet den (chainenden) Zug.
// 3) In 3D (Isometrie) schalten → die Wände sind dort sichtbar (Screenshot).
// 4) Getipptes „wand" startet DENSELBEN Befehl (Prompt = Wand-Prompt).
// Temporäres Verifikations-Gerüst (nicht eingecheckt).
import puppeteer from "puppeteer";
const URL = process.env.PROBE_URL || "http://localhost:5188/";
const b = await puppeteer.launch({
headless: "new",
args: ["--no-sandbox", "--use-gl=swiftshader", "--enable-unsafe-swiftshader"],
});
const p = await b.newPage();
await p.setViewport({ width: 1400, height: 900, deviceScaleFactor: 1.25 });
const errs = [];
p.on("pageerror", (e) => errs.push(e.message));
await p.goto(URL, { waitUntil: "networkidle0", timeout: 20000 }).catch(() => {});
const wait = (ms) => new Promise((r) => setTimeout(r, ms));
await wait(900);
const clickTool = (label) =>
p.evaluate((l) => [...document.querySelectorAll("button.tool-row")]
.find((x) => x.textContent.trim() === l)?.click(), label);
const clickView = (aria) =>
p.evaluate((a) => [...document.querySelectorAll("button")]
.find((x) => x.getAttribute("aria-label") === a)?.click(), aria);
const planBox = () => p.evaluate(() => {
const r = document.querySelector(".plan-svg").getBoundingClientRect();
return { x: r.x, y: r.y, w: r.width, h: r.height };
});
const click = async (x, y, opts) => { await p.mouse.move(x, y); await p.mouse.click(x, y, opts); await wait(110); };
const cmdState = () => p.evaluate(() => {
const prompt = document.querySelector(".cmdline-prompt")?.textContent?.trim() ?? "";
const input = document.querySelector(".cmdline-input");
const focused = document.activeElement === input;
const placeholder = input?.getAttribute("placeholder") ?? "";
return { prompt, focused, active: placeholder === "" };
});
// Grobes Mass für „Wand-Geometrie im Plan": Anzahl Pfad-/Polygon-Primitive.
// Wände rendern als gefüllte Schicht-Polygone + Umriss-Pfade; jede neue Wand
// erhöht diese Zahl deutlich.
const primCount = () => p.evaluate(() =>
document.querySelectorAll(".plan-svg path, .plan-svg polygon").length);
const typeInCmd = async (text) => {
await p.evaluate(() => document.querySelector(".cmdline-input")?.focus());
await p.keyboard.type(text);
await p.keyboard.press("Enter");
await wait(200);
};
const box = await planBox();
const cx = box.x + box.w / 2, cy = box.y + box.h / 2;
// ── 1) „Wand" anklicken → Befehlsfeld aktiv, Wand-Prompt ─────────────────────
const primStart = await primCount();
await clickTool("Wand");
await wait(300);
const afterToolClick = await cmdState();
console.log("after Wand-tool click → cmdline:", afterToolClick);
await p.screenshot({ path: "scripts/probe-wall-cmd-1-active.png" });
// ── 2) Mehrere Punkte → chainende Wände, dann Rechtsklick zum Beenden ────────
const P = [
[cx - 220, cy - 120],
[cx + 40, cy - 160],
[cx + 200, cy + 10],
[cx + 60, cy + 150],
];
for (const pt of P) await click(...pt);
await p.mouse.click(P[P.length - 1][0], P[P.length - 1][1], { button: "right" }); // Zug beenden
await wait(300);
const primAfter = await primCount();
console.log("plan primitives start / after walls:", primStart, primAfter, "→ delta", primAfter - primStart);
await p.screenshot({ path: "scripts/probe-wall-cmd-2-plan.png" });
// ── 3) In 3D (Isometrie) → Wände sichtbar ───────────────────────────────────
await clickView("Isometrie");
await wait(1500);
await p.screenshot({ path: "scripts/probe-wall-cmd-3-3d.png" });
// Zurück in den Grundriss.
await clickView("Grundriss");
await wait(600);
// ── 4) Getipptes „wand" startet DENSELBEN Befehl ────────────────────────────
await clickTool("Auswahl");
await wait(200);
const before = await cmdState();
await typeInCmd("wand");
const afterTyped = await cmdState();
console.log("after typing 'wand' → cmdline:", afterTyped, "(was:", before, ")");
// Einen Punkt setzen + Rechtsklick (Abbruch ohne 2. Punkt) — nur Prompt-Beleg.
await p.screenshot({ path: "scripts/probe-wall-cmd-4-typed.png" });
await p.keyboard.press("Escape");
console.log("errs:", errs.slice(0, 6));
console.log("RESULT activePrompt:", afterToolClick.active, afterToolClick.prompt,
"| primDelta:", primAfter - primStart,
"| typedPrompt:", afterTyped.active, afterTyped.prompt);
await b.close();