Files
DOSSIER-STANDALONE/scripts/probe-ambientcg.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

107 lines
4.1 KiB
JavaScript

// Probe (ambientCG Live-Browse): öffnet den Material-Picker, wechselt in den
// Modus „Bibliothek durchsuchen", sucht „wood", zeigt die Live-Treffer mit
// Thumbnails, wählt ein Material (lädt die Maps über den Proxy + entpackt), und
// beweist die texturierte Wand im 3D-Modus „Texturiert".
//
// Aufruf: PROBE_URL=http://localhost:5187/ node scripts/probe-ambientcg.mjs
import puppeteer from "puppeteer";
const URL = process.env.PROBE_URL || "http://localhost:5187/";
const OUT = "scripts";
const browser = await puppeteer.launch({
headless: "new",
args: ["--no-sandbox", "--use-gl=swiftshader", "--enable-unsafe-swiftshader"],
});
const page = await browser.newPage();
await page.setViewport({ width: 1360, height: 900, deviceScaleFactor: 2 });
const logs = [];
page.on("console", (m) => logs.push(`[${m.type()}] ${m.text()}`));
page.on("pageerror", (e) => logs.push(`[PAGEERROR] ${e.message}`));
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const shot = (n) => page.screenshot({ path: `${OUT}/${n}` });
async function clickByText(selector, text) {
const handle = await page.evaluateHandle(
(sel, t) =>
[...document.querySelectorAll(sel)].find((el) => el.textContent.includes(t)),
selector,
text,
);
const el = handle.asElement();
if (!el) throw new Error(`nicht gefunden: ${selector} ~ "${text}"`);
await el.click();
}
await page.goto(URL, { waitUntil: "domcontentloaded", timeout: 20000 });
await page.waitForSelector(".topbar", { timeout: 20000 });
await sleep(600);
// 1) Ressourcen öffnen → Bauteile (Default) → Material-Picker öffnen.
const resBtn = await page.$('button[aria-label="Ressourcen"]');
if (!resBtn) throw new Error("Ressourcen-Button nicht gefunden");
await resBtn.click();
await sleep(400);
await page.waitForSelector(".res-material-btn", { timeout: 8000 });
const matBtns = await page.$$(".res-material-btn");
await matBtns[0].click();
await page.waitForSelector(".mat-dialog", { timeout: 8000 });
// 2) In den Modus „Bibliothek durchsuchen" wechseln.
await clickByText(".mat-mode-btn", "Bibliothek durchsuchen");
await page.waitForSelector(".mat-browse", { timeout: 8000 });
await sleep(500);
// 3) Nach „wood" suchen.
await page.type(".mat-search", "wood");
await clickByText(".mat-browse-bar .res-add", "Suchen");
// Auf Live-Treffer warten (Kacheln im Browse-Grid).
await page.waitForSelector(".mat-browse-grid .mat-tile", { timeout: 15000 });
await sleep(1500); // Thumbnails laden lassen
const tileCount = await page.$$eval(".mat-browse-grid .mat-tile", (els) => els.length);
console.log("Live-Treffer (wood):", tileCount);
await shot("probe-ambientcg-1-browse.png");
// 4) Erstes Ergebnis wählen → lädt Maps über Proxy + entpackt + weist zu.
const firstTile = await page.$(".mat-browse-grid .mat-tile");
await firstTile.click();
// Warten, bis Dialog schließt (Download fertig → onAssign → onClose).
await page.waitForSelector(".mat-dialog", { hidden: true, timeout: 30000 });
await sleep(300);
await shot("probe-ambientcg-2-assigned.png");
// 5) Ressourcen schließen, in die Perspektive wechseln, „Texturiert".
async function closeResources() {
const closeBtn = await page.$(".res-drawer .res-close");
if (closeBtn) {
await closeBtn.click();
await page.waitForSelector(".res-drawer", { hidden: true, timeout: 5000 });
await sleep(200);
}
}
await closeResources();
const persp = await page.$('button[aria-label="Perspektive"]');
if (persp) await persp.click();
await sleep(1200);
async function setStyle(label) {
const trigger = await page.$('button.tb-dd-trigger[title*="Darstellungsart der"]');
if (!trigger) throw new Error("Darstellung-Dropdown nicht gefunden");
await trigger.click();
await page.waitForSelector("button.tb-dd-item", { timeout: 4000 });
await sleep(150);
await clickByText("button.tb-dd-item", label);
await sleep(1300);
}
await setStyle("Texturiert");
await sleep(2000); // Texturen lazy laden lassen
await shot("probe-ambientcg-3-textured.png");
console.log("--- console (letzte 30) ---");
for (const l of logs.slice(-30)) console.log(l);
await browser.close();
console.log("done");