Files

4.3 KiB
Raw Permalink Blame History

Embedding a 3D model (STEP / STL) in a note

The share can render .step / .stp / .stl models interactively (three.js + occt-import-js, hosted locally). The viewer fills the available screen width (full-bleed, ~100vw) with a height based on the viewport (min(70vh, 900px)), so standalone model pages use the maximum available space instead of the readable content width. Inline viewers embedded in text articles (Options B and C) are limited to the content width (model-viewer-inline). The caption below the model always shows <file name> · <size> · <triangle count> (e.g. Wrench.stl · 711 KB · 14.6k triangles).

There are three ways to embed a model, depending on how you store the file.

Option A Model as its own note (file note)

  1. Create (or upload) a file note and make sure its title ends in .step, .stp or .stl, e.g. bracket.step or rear_housing.stp.
  2. Put it under a category in the blog and set publish=true.
  3. The note's share page then shows the interactive 3D viewer automatically: drag to rotate, scroll to zoom.

Option B Model embedded inline in a text note (attachment)

  1. Upload the STEP/STL file as an attachment of the note: drag & drop it onto the note, or use the attachment dialog (paperclip icon).
  2. Rename the attachment so its title ends in .step, .stp or .stl (the viewer detects a model by the file name). Example: flange.step.
  3. Insert the attachment link into the note body: right-click the attachment → "Insert link", or drag the attachment into the text.
  4. On the share, that link is automatically replaced by the embedded 3D viewer.

This lets you write blog posts that contain models inline, referencing a model that also exists as its own (published) file note — the model stays in one place.

  1. Create the model as a file note (title ends in .step / .stp / .stl), publish it (see Option A). The viewer needs it in blog_data, i.e. it must be a published article reachable in the blog tree.
  2. In your text note, add a link to that file note, e.g. [Wrench.stl](#root/<noteId>) (markdown) or drag the note reference into the editor.
  3. On the share, the link to a model file note is replaced by the inline viewer. You can embed several models per post this way.

Tip: STL (plain triangle meshes) is rendered with three.js only; STEP (CAD B-rep) is parsed by occt-wasm (OpenCASCADE V8, WASM, MIT/Apache-2.0) in a Web Worker (module worker, non-blocking). The first STEP view downloads the ~22 MB WASM once and then caches it in the browser. STEP tessellation is set to linearDeflection: 0.4, angularDeflection: 0.2 (≈480k triangles for the ignis battery module; tuned for mobile).

Requirements

  • The 3d model viewer script must be wired: ~shareHtml → 3d model viewer (inheritable) on the blog root, shareHtmlLocation=body:end.
  • The five libraries must exist as notes and be referenced by the script via the placeholder tokens in scripts/3d_model_viewer.js: __THREE_ID__, __THREE_ORBIT_ID__, __THREE_STL_ID__, __OCCT_JS_ID__ (the occt-wasm bundle), __OCCT_WASM_ID__ (occt-wasm.wasm) see the README installation for the note titles. The STEP worker is a module worker (type: "module"), so the browser must support ES modules in workers (all modern browsers).
  • Mobile compatibility: the mesh is split into chunks of ≤65000 vertices (chunkGeometry, Uint16 indices) so it renders on GPUs without OES_element_index_uint; the camera near/far is tightened after fit() for 16-bit depth buffers.
  • 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 ./<alias> links against window.blogData).

Trilium app widget (independent of the share)

The same viewer is also available inside Trilium itself (independent of the blog): a note-detail-pane widget (app/3d-model-viewer-app.jsx + app/3d-worker.js) renders the viewer whenever you open a file note whose title ends in .step / .stp / .stl. The worker is loaded from a code note (not a Blob) so it works under the app's CSP. Wire it by giving the JSX note the label #widget=3dModelViewer and reload the app.