From 145c14842a6be90e81e2f8d03d76e7664ccfd5e2 Mon Sep 17 00:00:00 2001 From: chk <79915315+ChKendel@users.noreply.github.com> Date: Wed, 10 Jun 2026 18:40:57 +0200 Subject: [PATCH] x-axis justierung: lines --- public/boardViewer.html | 76 +++++++++++++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 10 deletions(-) diff --git a/public/boardViewer.html b/public/boardViewer.html index 2996e0c..3483277 100644 --- a/public/boardViewer.html +++ b/public/boardViewer.html @@ -213,8 +213,13 @@ const gPaper = new THREE.Group(); // weißes A0-Papier const gMarkers = new THREE.Group(); // Modell-Rechtecke const gMeasured = new THREE.Group(); // gemessene Positionen (3b) const gCameras = new THREE.Group(); // Kamera-Frusta -const gCompare = new THREE.Group(); // Vergleichs-Punkte (anderer Timestamp, nur fremd) -scene.add(gPaper, gMarkers, gMeasured, gCameras, gCompare); +const gCompare = new THREE.Group(); // Vergleichs-Punkte (anderer Timestamp, nur fremd) +const gCompareLines = new THREE.Group(); // Verbindungslinien Basis↔Vergleich +scene.add(gPaper, gMarkers, gMeasured, gCameras, gCompare, gCompareLines); + +// ── Zustand für Vergleichs-Linien ───────────────────────────────────────────── +let _primaryFremdMarkers = []; // [{marker_id, position_mm, num_cameras}] +let _compareFremdMarkers = []; // [{marker_id, position_mm, num_cameras}] function clearGroup(g) { while (g.children.length) { @@ -573,6 +578,48 @@ function buildTable(data) { wrap.innerHTML = html; } +// ── Vergleichs-Overlay: Transparenz + Linien ───────────────────────────────── + +/** + * Setzt Board-Marker und Papier-Ebene auf geringere Deckkraft, wenn der + * Vergleichs-Modus aktiv ist (compareActive=true → 10 % Deckkraft). + * Ursprüngliche Deckkraft wird pro Material einmalig gespeichert. + */ +function setSceneOpacity(compareActive) { + for (const obj of [...gPaper.children, ...gMarkers.children]) { + const mats = obj.material + ? (Array.isArray(obj.material) ? obj.material : [obj.material]) + : []; + for (const mat of mats) { + if (!mat) continue; + if (mat._origOpacity === undefined) mat._origOpacity = mat.opacity ?? 1.0; + if (mat._origTransparent === undefined) mat._origTransparent = mat.transparent ?? false; + mat.transparent = compareActive || mat._origTransparent; + mat.opacity = compareActive ? mat._origOpacity * 0.10 : mat._origOpacity; + mat.needsUpdate = true; + } + } +} + +/** + * Zeichnet Verbindungslinien von Basis-fremd-Markern zu gleich-ID-Vergleichs-Markern. + * Aktualisiert gleichzeitig die Board-Transparenz. + */ +function buildCompareLines() { + clearGroup(gCompareLines); + const compareActive = _compareFremdMarkers.length > 0; + setSceneOpacity(compareActive); + if (!compareActive || !_primaryFremdMarkers.length) return; + + const primaryMap = new Map(_primaryFremdMarkers.map(m => [m.marker_id, m])); + for (const cm of _compareFremdMarkers) { + const pm = primaryMap.get(cm.marker_id); + if (!pm) continue; + // Linie: Basis-Position (blau) → Vergleichs-Position (orange) + gCompareLines.add(makeLine(r2vArr(pm.position_mm), r2vArr(cm.position_mm), 0xfb923c, 0.85)); + } +} + // ── Daten laden ─────────────────────────────────────────────────────────────── /** Haupt-Run laden (Basis-Dropdown). Ohne Selektion → neuester Run. */ @@ -595,6 +642,10 @@ async function loadData() { } buildScene(data); buildTable(data); + // Fremd-Marker für Verbindungslinien merken (Marker, die nicht in Board-Link stehen) + const bIds = new Set((data.robot?.links?.Board?.markers ?? []).map(m => m.id)); + _primaryFremdMarkers = (data.measuredMarkers?.markers ?? []).filter(m => !bIds.has(m.marker_id)); + buildCompareLines(); const robotLabel = data.robotFile ? ` • Robot: ${data.robotFile}` : ''; statusEl.textContent = `Run: ${data.runDir}${robotLabel} • ${new Date().toLocaleTimeString('de-CH')}`; } catch (err) { @@ -602,26 +653,31 @@ async function loadData() { } } -/** Vergleichs-Run laden (Compare-Dropdown) – zeigt nur fremd-triangulierte Marker als orange Kugeln. */ +/** + * Vergleichs-Run laden (Compare-Dropdown). + * Zeigt nur fremd-triangulierte Marker (nicht im Board-Link) als orange Kugeln. + * Zieht außerdem Verbindungslinien zu gleich-ID-Markern im Basis-Run. + */ async function loadCompareData() { clearGroup(gCompare); + _compareFremdMarkers = []; const selRun = document.getElementById('sel-run-compare')?.value ?? ''; - if (!selRun) return; + if (!selRun) { buildCompareLines(); return; } try { const r = await fetch(`/api/board/latest?run=${encodeURIComponent(selRun)}`); - if (!r.ok) return; - const data = await r.json(); + if (!r.ok) { buildCompareLines(); return; } + const data = await r.json(); const markers = data.measuredMarkers?.markers ?? []; - if (!markers.length) return; - // Board-Marker-IDs aus Robot.json (für diesen Run) + // Board-Marker-IDs aus Robot.json dieses Runs const boardIds = new Set((data.robot?.links?.Board?.markers ?? []).map(m => m.id)); for (const m of markers) { if (!boardIds.has(m.marker_id)) { - // Nicht zugeordnet → orange Kugel (Vergleich) - gCompare.add(makeSphere(r2vArr(m.position_mm), 0.006, 0xf97316)); + _compareFremdMarkers.push(m); // für Linien + gCompare.add(makeSphere(r2vArr(m.position_mm), 0.006, 0xf97316)); // orange Kugel } } } catch { /* kein 3b-Output für diesen Run */ } + buildCompareLines(); // Linien + Transparenz aktualisieren } /** Run-Listen laden und beide Dropdowns befüllen. */