# 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 models use the maximum available space instead of the readable content width. The caption below the model always shows ` · · ` (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. ## Option C – Model embedded inline from a file note (recommended for blog posts) 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/)` (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-import-js (OpenCASCADE WASM, LGPL-2.1) in a **Web Worker** (non-blocking). > The first STEP view downloads the ~7.6 MB WASM once and then caches it in the browser. > STEP tessellation is set to `linearDeflection: 0.0002, angularDeflection: 0.1` > (dense meshes, typically a few hundred k to >1 M triangles for assemblies). ## 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__`, `__OCCT_WASM_ID__` (see the README installation for the note titles). - 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 `./` 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.