Remove viewer debug line/state colours; app widget parity (chunking, near/far, occt-wasm)

This commit is contained in:
trilium-share-gruvbox
2026-08-28 20:06:56 +02:00
parent 18f8afaf69
commit 6b9b458e97
5 changed files with 5 additions and 38 deletions
+2 -3
View File
@@ -95,9 +95,8 @@ set the other labels, and set `publish=true` **last**.
- **3D models** (`scripts/3d_model_viewer.js`): renders `.step`/`.stp`/`.stl` as file notes - **3D models** (`scripts/3d_model_viewer.js`): renders `.step`/`.stp`/`.stl` as file notes
(title ends in the extension), inline attachment links, or links to published model file (title ends in the extension), inline attachment links, or links to published model file
notes from text notes (resolved via `window.blogData`). The viewer is **full-bleed** notes from text notes (resolved via `window.blogData`). The viewer is **full-bleed**
(`~100vw`, `height: min(70vh, 900px)`, ResizeObserver), with a loading progress bar, a (`~100vw`, `height: min(70vh, 900px)`, ResizeObserver), with a loading progress bar and a
caption that shows `name · size · triangle count`, and a **debug line** under the box that caption that shows `name · size · triangle count`. STEP is parsed
logs the step (`loading`/`parsing`/`done`/`error`) for on-device diagnosis. STEP is parsed
by **occt-wasm** (OpenCASCADE **V8**, MIT/Apache-2.0) in a **module worker** by **occt-wasm** (OpenCASCADE **V8**, MIT/Apache-2.0) in a **module worker**
(`new Worker(url, {type:"module"})`, non-blocking) with (`new Worker(url, {type:"module"})`, non-blocking) with
`linearDeflection: 0.4, angularDeflection: 0.2`. Libraries hosted as local notes via `linearDeflection: 0.4, angularDeflection: 0.2`. Libraries hosted as local notes via
+2 -2
View File
@@ -48,8 +48,8 @@ no external dependencies (except `highlight.js`, vendored in `lib/`).
- **3D models**: `.step` / `.stp` / `.stl` files (as file notes, as inline attachments, or linked - **3D models**: `.step` / `.stp` / `.stl` files (as file notes, as inline attachments, or linked
from text notes) render in an interactive three.js viewer (STEP via **occt-wasm**, OpenCASCADE from text notes) render in an interactive three.js viewer (STEP via **occt-wasm**, OpenCASCADE
V8, parsed in a non-blocking **module worker**). The viewer is **full-bleed** (~`100vw`) with a V8, parsed in a non-blocking **module worker**). The viewer is **full-bleed** (~`100vw`) with a
viewport-based height, drag to rotate / scroll to zoom, rounded 8px box, a loading progress bar, viewport-based height, drag to rotate / scroll to zoom, rounded 8px box, a loading progress bar
a caption showing `name · size · triangle count`, and a small debug line. Large meshes are and a caption showing `name · size · triangle count`. Large meshes are
split into `Uint16` chunks so mobile GPUs render them too (≈480k triangles for the demo split into `Uint16` chunks so mobile GPUs render them too (≈480k triangles for the demo
battery module). See [docs/embed-3d-model.md](docs/embed-3d-model.md). battery module). See [docs/embed-3d-model.md](docs/embed-3d-model.md).
- **3D viewer inside Trilium (app widget)**: the same viewer runs in the Trilium app itself - **3D viewer inside Trilium (app widget)**: the same viewer runs in the Trilium app itself
+1 -2
View File
@@ -59,8 +59,7 @@ exists as its own (published) file note — the model stays in one place.
- **Mobile compatibility**: the mesh is split into chunks of ≤65000 vertices - **Mobile compatibility**: the mesh is split into chunks of ≤65000 vertices
(`chunkGeometry`, `Uint16` indices) so it renders on GPUs without (`chunkGeometry`, `Uint16` indices) so it renders on GPUs without
`OES_element_index_uint`; the camera near/far is tightened after `fit()` for 16-bit `OES_element_index_uint`; the camera near/far is tightened after `fit()` for 16-bit
depth buffers. The caption always shows a small **debug line** with the current step depth buffers.
(`loading` / `parsing` / `done` / `error`) useful while diagnosing.
- For **inline embedding from a file note (Option C)** the `blog_data` note must be - For **inline embedding from a file note (Option C)** the `blog_data` note must be
present and the target model must be a published article (the viewer resolves present and the target model must be a published article (the viewer resolves
`./<alias>` links against `window.blogData`). `./<alias>` links against `window.blogData`).
-16
View File
@@ -132,9 +132,6 @@
cap.textContent = name; cap.textContent = name;
box.appendChild(cap); box.appendChild(cap);
} }
var dbg = document.createElement("div");
dbg.className = "model-viewer-debug";
box.appendChild(dbg);
return box; return box;
} }
@@ -178,11 +175,6 @@
var s = el.querySelector(".model-viewer-status"); var s = el.querySelector(".model-viewer-status");
if (s) s.textContent = text; if (s) s.textContent = text;
} }
function setStep(state, msg) {
el.className = "model-viewer model-" + state;
var dbg = el.querySelector(".model-viewer-debug");
if (dbg) dbg.textContent = new Date().toLocaleTimeString() + " [" + state + "] " + msg;
}
function setProgress(percent) { function setProgress(percent) {
var bar = el.querySelector(".model-viewer-progress-fill"); var bar = el.querySelector(".model-viewer-progress-fill");
if (!bar) return; if (!bar) return;
@@ -198,7 +190,6 @@
var s = el.querySelector(".model-viewer-status"); var s = el.querySelector(".model-viewer-status");
if (s) { s.textContent = msg || "Could not load 3D model."; s.classList.add("error"); } if (s) { s.textContent = msg || "Could not load 3D model."; s.classList.add("error"); }
setProgress(0); setProgress(0);
setStep("error", msg || "Could not load 3D model.");
} }
function showData(extra) { function showData(extra) {
var d = el.querySelector(".model-viewer-data"); var d = el.querySelector(".model-viewer-data");
@@ -232,7 +223,6 @@
setProgress(null); setProgress(null);
setStatus("Loading 3D libraries\u2026"); setStatus("Loading 3D libraries\u2026");
setStep("loading", "Loading 3D libraries");
loadThree(function () { loadThree(function () {
var wrap = el.querySelector(".model-viewer-canvas") || el; var wrap = el.querySelector(".model-viewer-canvas") || el;
@@ -293,7 +283,6 @@
fetchProgress(url, function (p) { setProgress(p); }).then(function (buf) { fetchProgress(url, function (p) { setProgress(p); }).then(function (buf) {
fileSize = buf.byteLength; fileSize = buf.byteLength;
showData(); showData();
setStep("loading", "Downloaded model " + formatBytes(fileSize));
var data = new Uint8Array(buf); var data = new Uint8Array(buf);
if (isStep) { if (isStep) {
setStatus("Downloading STEP parser\u2026"); setStatus("Downloading STEP parser\u2026");
@@ -301,12 +290,10 @@
fetchProgress(OCCT_WASM_ABS, function () {}).then(function (wasmBuf) { fetchProgress(OCCT_WASM_ABS, function () {}).then(function (wasmBuf) {
setStatus("Parsing STEP\u2026"); setStatus("Parsing STEP\u2026");
setProgress(null); setProgress(null);
setStep("parsing", "STEP parser ready, parsing");
var t0 = Date.now(); var t0 = Date.now();
var parseTimer = setInterval(function () { var parseTimer = setInterval(function () {
var el2 = Date.now() - t0; var el2 = Date.now() - t0;
setStatus("Parsing STEP\u2026 (" + Math.round(el2 / 1000) + "s)"); setStatus("Parsing STEP\u2026 (" + Math.round(el2 / 1000) + "s)");
setStep("parsing", "Parsing STEP " + Math.round(el2 / 1000) + "s");
if (el2 > 240000 && !settled) { worker.terminate(); URL.revokeObjectURL(wurl); clearInterval(parseTimer); onError("STEP parse timed out."); } if (el2 > 240000 && !settled) { worker.terminate(); URL.revokeObjectURL(wurl); clearInterval(parseTimer); onError("STEP parse timed out."); }
}, 1000); }, 1000);
var blob = new Blob([WORKER_SRC], { type: "application/javascript" }); var blob = new Blob([WORKER_SRC], { type: "application/javascript" });
@@ -320,7 +307,6 @@
var geo = new THREE.BufferGeometry(); var geo = new THREE.BufferGeometry();
geo.setAttribute("position", new THREE.Float32BufferAttribute(e.data.positions, 3)); geo.setAttribute("position", new THREE.Float32BufferAttribute(e.data.positions, 3));
if (e.data.indices) geo.setIndex(new THREE.BufferAttribute(e.data.indices, 1)); if (e.data.indices) geo.setIndex(new THREE.BufferAttribute(e.data.indices, 1));
var geoStats = "posV=" + geo.attributes.position.count + " idx=" + (geo.index ? geo.index.count : 0);
fixWinding(geo); fixWinding(geo);
var mat = new THREE.MeshStandardMaterial({ color: 0xb8bb26, metalness: 0.2, roughness: 0.6, side: THREE.DoubleSide, flatShading: false }); var mat = new THREE.MeshStandardMaterial({ color: 0xb8bb26, metalness: 0.2, roughness: 0.6, side: THREE.DoubleSide, flatShading: false });
chunkGeometry(geo, group, mat); chunkGeometry(geo, group, mat);
@@ -328,8 +314,6 @@
fit(); fit();
showCanvas(); showCanvas();
showData(formatCount(tris) + " triangles"); showData(formatCount(tris) + " triangles");
var capGL = renderer.capabilities ? (renderer.capabilities.isWebGL2 ? "WebGL2" : "WebGL1") : "?";
setStep("done", "Rendered " + formatCount(tris) + " tris; meshes=" + group.children.length + " gl=" + capGL + " " + geoStats);
} catch (err) { } catch (err) {
onError("build: " + (err && err.message || err)); onError("build: " + (err && err.message || err));
} }
-15
View File
@@ -918,21 +918,6 @@ html.theme-light #content code {
height: 100%; height: 100%;
} }
.model-viewer.model-loading { background: #282828; }
.model-viewer.model-parsing { background: #504945; }
.model-viewer.model-done { background: #1d2021; }
.model-viewer.model-error { background: #3c3836; }
.model-viewer-debug {
font-family: "JetBrains Mono", Consolas, monospace;
font-size: 0.72em;
color: #928374;
text-align: center;
padding: 4px 12px;
background: #1d2021;
border-top: 1px solid var(--background-highlight);
}
/* ---------- Bildunterschriften (Gruvbox) ---------- */ /* ---------- Bildunterschriften (Gruvbox) ---------- */
#content figcaption { #content figcaption {
font-size: 0.85em; font-size: 0.85em;