Add load interruption handling, camera zoom controls, refreshed measurement UI, diagnostics/default-route coverage, and aligned docs for the Babylon-default renderer contract.
- Change .ai3d-btn-active from accent text to filled accent background + on-accent text.
- Keep the active highlight on hover with a slight brightness boost.
- Replace the dropdown menu with the original left/right inline expansion of secondary actions.
- Keep icon-only primary buttons and grouped toolbar layout.
- Move all secondary actions into a theme-styled dropdown menu triggered by the "more" button.
- Keep primary icon buttons on the toolbar: reset, wireframe, axes, bbox, focus, disassemble, measure, annotate, copy.
- Add menu sections with separators and full descriptive labels.
- Support Escape and outside-click to close the menu.
- Remove old inline .show-secondary expansion CSS.
- Promote reset, wireframe, axes, bounding box, focus, disassemble, measure, annotate, and copy snapshot to primary icon+text buttons.
- Collapse all secondary buttons behind a global "more" toggle by default.
- Add short-label i18n keys and tighten labeled-button CSS sizing.
- Update preview verification harness to expand the more menu for secondary actions.
- Make the measurement tool a primary inline toolbar button with a visible text label ("测距" / "Measure").
- Add .ai3d-inline-btn--labeled styles for icon+text layout and compact sizing.
- Verified with typecheck, lint, unit tests, preview harness, and Obsidian vault install.
- Remove the 5 icon buttons from the right sidebar (focus, disassembly,
reset, generate-note, open-index)
- Move knowledge controls (generate-note, open-note, open-index) to sidebar
- Move registered part matches to sidebar
- Bottom panel now only shows overview: backend, route, metrics
- Sidebar renders content vertically with full workbench card styling
- Mobile: sidebar content scrolls horizontally
This puts actionable information on the right and model status
on the bottom, reducing visual clutter in both areas.
Add a track-based workspace framework around the original workbench panel:
- Main preview area + right sidebar with action icons (focus, disassembly,
reset, generate-note, open-index)
- Draggable resize handles for sidebar width and bottom panel height
- Keep the original bottom workbench panel design: overview on the left,
knowledge actions and registered part matches on the right
- Mobile responsive: sidebar becomes a horizontal scrollable row
This keeps the familiar two-column workbench panel while adding
a proper resizable workspace frame so the preview area is no longer
squeezed by the panel.
- Replace the legacy bottom workbench panel with a track-based workspace layout
- Main preview area gets full remaining space without being squeezed by the panel
- Right sidebar with icon buttons for focus/disassembly/reset/annotation/generate-note/open-index
- Draggable resize handles for sidebar width and bottom panel height (like IDE split panes)
- Bottom panel organized into Overview/Matches/Knowledge tabs to reduce visual clutter
- Mobile responsive: sidebar becomes a horizontal row on narrow screens
- Add tab translation keys for Overview/Matches/Knowledge in both EN and ZH
- Clean up legacy workbench panel CSS and consolidate into workspace styles
The .ai3d-workbench CSS was redefined as display: grid with 2 columns,
overriding the original flex column layout and breaking the 3-column
studio-grid structure. Changed back to display: flex; flex-direction: column.
Obsidian's base CSS may set fill/stroke on SVG elements. CSS properties
have higher specificity than SVG presentation attributes (fill="none"
stroke="currentColor"), causing icons to render black.
Add explicit CSS rules with !important for fill/stroke on plugin SVG
icons to ensure currentColor is used for icon rendering.
activeDocument.createDiv/createEl throws HierarchyRequestError because
Obsidian's enhanced helpers try to appendChild on the Document node.
Previous createElement replacement fixed the error but lost Obsidian's
CSS variable inheritance, causing all UI to render black.
Fix by creating elements on parents already in the live DOM:
- helper-buttons: add parentEl param, create toolbar on live parent
- annotations: use this.hostEl (in DOM) for overlay/editor/pins
- app/workbench: create on container (in DOM)
- code-block: create canvas on host/gridHost (in DOM)
- loading-overlay: create on host (in DOM)
- live-preview/dom: keep staging pattern (elements attached later)
New src/utils/dom.ts provides createStagedDiv/createStagedEl for cases
where no live DOM parent is available at creation time.
- Replace all direct style.* assignments with CSS classes and CSS variables
(annotations.ts, code-block.ts, grid.ts, loading-overlay.ts, helper-buttons.ts, direct-view.ts)
- Replace node:fs/path/child_process/os imports with safe node-shim.ts wrapper
- Convert require() calls to static imports (stl-loader.ts, ply-loader.ts, picking.ts)
- Use sentence case for all UI text (en.ts, settings.ts, main.ts, etc.)
- Replace async methods with no await: onOpen, onClose, updateSettings, onunload, importModel
- Use setHeading() for settings section headings
- Replace activeLeaf with getActiveViewOfType(MarkdownView)
- Replace fetch() with dataUrlToBlob() for snapshot operations
- Replace navigator API with Platform.isMobile
- Replace TFile cast with instanceof check
- Replace console.log with console.debug
- Replace Function type with explicit ComponentFn type
- Add null guard for rootMesh assignment in scene.ts
Add bidirectional linking between annotation pins and note headings:
- Pin editor: heading autocomplete search across vault with dropdown,
keyboard navigation (arrows/Enter/Escape), content preview of
selected heading section, and binding tag indicator
- Pin hover: show note content popover when hovering over bound pins
- Heading badge: display 📌 badge on note headings linked to pins,
with click to pulse-highlight the pin and hover for pulse animation
- Heading text normalization: strip markdown formatting (bold, links,
wikilinks, highlights, code) for robust DOM-to-headingRef matching
- Memory optimization: pre-allocated scratch Vector3/Matrix/Ray for
updateProjections hot path, debounced MutationObserver for heading
scanning
- New shared utility: src/utils/note-reader.ts with readHeadingSection,
searchVaultHeadings, normalizeHeadingText
- Click-to-pin: click on 3D model to add labeled bookmarks with color
- Edit existing pins: click pin to edit label/color, or delete
- Camera focus: click pin label in panel to animate camera to pin position
- Depth occlusion: pins behind geometry show blurred/dimmed; fully hidden when camera idle
- Workbench integration: Annotations panel with toggle, pin list, edit/delete/focus actions
- DirectView integration: annotation toolbar button with pin count badge
- Code-block readonly: display saved annotations in inline previews
- ESC to exit annotation mode
- Semi-transparent mode overlay when annotation active
- Coordinate fix: engine render → CSS pixel scaling for accurate pin positioning
- Relative occlusion epsilon for large model compatibility
- orientation-gizmo: set viewport directly on camera instead of manual
engine.setViewport (which was overridden by scene.render)
- scene: include rootMesh in wireframe iteration for STL/PLY single-mesh models
- direct-view: remove height:100% that caused excessive blank space
- code-block: remove defaultCanvasHeight from min-height, use CSS only;
grid uses height instead of min-height so CSS max-height can cap it
- styles.css: reduce preview-host min-height, add grid-host max-height
New features:
- Add SLDPRT (SolidWorks) converter via FreeCAD + OpenCASCADE pipeline
- Add IGES/IGS and BREP format support via format-aware Python scripts
- Add 3MF and DAE format support via trimesh/Assimp converter
- Add loading overlay component with progress bar and phase text
- Enable STP files by default in format registry
Portability:
- Remove all hardcoded user paths, use process.env.LOCALAPPDATA for discovery
- Fix .split("/") path separator issues (scene.ts, app.ts, helper-buttons.ts)
- Add macOS Apple Silicon Homebrew paths (/opt/homebrew/bin/)
- Fix escapePyStr + raw string double-escaping (pyPath normalizes to forward slashes)
- Add maxBuffer to all execFileAsync calls (50MB)
Bug fixes:
- Fix OBJ load errors silently swallowed (now re-throw after logging)
- Fix explode position drift on repeated set/reset cycles (store original center)
- Fix explode uses world-space position (switch to local position)
- Fix picking highlight material leak when mesh disposed externally
- Fix grid layerMask collision in compose presets (one cell = one bit)
- Fix renderScale/quality inconsistency (track currentQuality)
- Fix stale loading flag drops model path changes (pendingPath mechanism)
- Fix persist() unhandled rejection on save failure
- Fix Python injection via double-quote in paths (reject quotes in pyPath)
- Fix PLY face indices parsed as floats (Math.round)
- Fix PLY face indices no bounds checking (skip out-of-range)
- Fix ASCII STL produces confusing error (detect and warn)
- Fix WebGL engine leak on live-preview load error
- Fix DirectView race condition on rapid file loads (generation counter)
- Fix MutationObserver not disconnected on code-block load error
- Fix auto-save timer fires after plugin unload (add dispose)
- Fix duplicate conversions on concurrent requests (in-flight dedup)
Other:
- Rewrite README with comprehensive usage, third-party setup, and demo page
- Add docs/demo.md with 11 feature walkthrough sections
- Remove dead code (freecad-stub.ts)
- Deduplicate generateNote() in main.ts, reuse app.ts version
- Remove unused formatFileSize() and escapeObsidianMarkup()
- Wire up isMobile() for automatic resolution scaling on mobile
- Replace hardcoded #1e1e22 with CSS variable for theme compat
Babylon.js-powered 3D viewer for Obsidian with support for
GLB, GLTF, STL, OBJ, and SPLAT formats. Features include
multi-model grid rendering, preset layouts, knowledge note
generation, and snapshot export.