AI Model Workbench

approved

by flash555588

This plugin has not been manually reviewed by Obsidian staff. Turn 3D models into linked knowledge assets.

6 stars21 downloadsUpdated 10d agoMIT

AI Model Workbench

A local-first Obsidian 3D viewer focused on knowledge workflows. It renders common 3D assets in a Babylon.js viewport, lets you annotate key parts, and turns models into linked notes. Common mesh formats load directly, while CAD, FBX, and interchange formats can be converted to GLB through local tools.

English | 简体中文

preview

Table of Contents


Features

  • Direct mesh preview for GLB/GLTF, STL, OBJ, and PLY
  • Optional conversion for CAD, FBX, 3MF, and DAE assets
  • Babylon.js 9.6 engine with WebGL 2 rendering
  • Three embedding methods: Live Preview, code blocks, direct file view
  • Grid system: render multiple models in a single viewport with presets
  • 3D annotations: click-to-pin bookmarks with labels, colors, and depth-aware occlusion
  • Knowledge notes: generate structured Markdown from loaded models
  • Snapshots: copy, save, or download rendered previews as PNG
  • i18n: English and Simplified Chinese with auto-detect system locale
  • Desktop support: Obsidian Desktop on Windows, macOS, and Linux
  • Mobile support: iOS, iPadOS, and Android support direct formats and a simplified workbench layout

Platform Support Matrix

CapabilityWindows / macOS / LinuxiOS / iPadOS / Android
Direct formats (GLB, GLTF, OBJ, STL, PLY)YesYes
Direct file viewYesYes
Inline embed / Live Preview for direct formatsYesYes
Workbench layoutFull desktop layoutSimplified single-column mobile layout
Local conversion (CAD, FBX, 3MF, DAE, SLDPRT)YesNo
Converter diagnostics and local CLI checksYesNo
Already converted .ai3d-converted.glb assetsYesYes

Quick Start

  1. Build the plugin:
npm install
npm run build
  1. Open your local Obsidian vault folder on your computer.

  2. Create this folder inside the vault:

<your-vault>/.obsidian/plugins/ai-model-workbench/
  1. Copy main.js, manifest.json, and styles.css into that folder.

  2. In Obsidian, open Settings > Community Plugins and enable AI Model Workbench.

  3. Put a supported model file into the same vault, for example model.glb.

  4. In any note inside that vault, embed it like this:

![[model.glb]]
![[model.glb|400x300]]

Installation

Use Quick Start if you only want the fastest setup.

Requirements

  • Obsidian 1.5.0 or later
  • Obsidian Desktop on Windows, macOS, or Linux for local tool-based conversion
  • A local Obsidian vault folder on your computer
  • This plugin folder inside the vault:
<vault>/.obsidian/plugins/ai-model-workbench/

All install methods place the same three files in that folder:

FileSizeDescription
main.js~1.7 MBPlugin runtime (Babylon.js core)
manifest.json~1 KBObsidian plugin manifest
styles.css~10 KBPlugin styles

Direct rendering works on desktop and mobile. Local converter tools for CAD, FBX, 3MF, and DAE require desktop OS access.

Option A: Build from Source

  1. Clone the repository and build the plugin:
git clone https://github.com/flash555588/ai-model-workbench.git
cd ai-model-workbench
npm install
npm run build
  1. Create <vault>/.obsidian/plugins/ai-model-workbench/ if it does not exist.
  2. Copy main.js, manifest.json, and styles.css into that folder.
  3. In Obsidian, enable AI Model Workbench in Settings > Community Plugins.

Option B: Download a Release

  1. Download main.js, manifest.json, and styles.css from Releases.
  2. Create <vault>/.obsidian/plugins/ai-model-workbench/ if it does not exist.
  3. Put the three files in that folder.
  4. In Obsidian, enable AI Model Workbench in Settings > Community Plugins.

Option C: Symlink for Development

  1. Make sure <vault>/.obsidian/plugins/ already exists.
  2. Create a symlink named ai-model-workbench that points to this repository.

Windows (PowerShell):

New-Item -ItemType SymbolicLink `
  -Path "C:\path\to\your-vault\.obsidian\plugins\ai-model-workbench" `
  -Target "C:\path\to\ai-model-workbench"

macOS / Linux:

ln -s /path/to/ai-model-workbench \
  /path/to/your-vault/.obsidian/plugins/ai-model-workbench
  1. In this repository, run npm install once if needed.
  2. Run npm run dev while developing.
  3. In Obsidian, enable AI Model Workbench in Settings > Community Plugins.

After Install

  1. Put a supported model file into the same vault, for example model.glb.
  2. In any note inside that vault, embed it like this:
![[model.glb]]
![[model.glb|400x300]]

Security & Privacy

AI Model Workbench does not collect telemetry, phone home, or run background network sync. Model previews are loaded from files already present in the Obsidian vault, and OBJ material/texture references are resolved from the vault instead of being fetched from the network.

The bundled Babylon.js runtime contains generic loader utilities that are capable of loading URLs for web applications. This plugin passes vault file bytes to Babylon as data URLs, overrides OBJ MTL loading to avoid remote fetches, and installs a runtime guard that rejects explicit http(s) / ws(s) asset or script URLs while disabling Babylon retry hooks for those requests. Optional converter diagnostics and conversions run only after a user action and execute local tools on desktop platforms.

Release assets are limited to the three files Obsidian downloads: main.js, manifest.json, and styles.css. GitHub Actions builds these files from source and publishes artifact attestations for provenance verification.


Funding

AI Model Workbench does not include donation prompts, payment flows, or cryptocurrency wallet addresses in the plugin bundle.


Format Support

Direct Rendering (No External Tools)

FormatExtensionFeatures
GLB / GLTF.glb .gltfPBR materials, animations, textures, scene hierarchy
STL.stlBinary format, per-face colors (VisCAM/SolidView)
OBJ.objMTL materials, vault-relative texture resolution
PLY.plyASCII/binary, vertex colors, point cloud support

SPLAT preview is temporarily disabled in packaged builds while its loader is replaced with a local-only implementation.

SPLAT Status and Roadmap

  • Current status: SPLAT preview is temporarily disabled in community release builds. GLB, GLTF, STL, OBJ, PLY, and the current local conversion routes are unaffected.
  • Why: the current Babylon SPLAT/SPZ loader still carries dynamic script and remote module fallback paths. The plugin runtime already rejects remote requests, but the packaged release also aims to remove those paths from the shipped bundle to reduce review and static-scan risk.
  • Roadmap: first restore local-only .splat loading; then reopen it after idle-render stability is improved for Windows and large scenes; finally evaluate .spz separately, and only re-enable it if the decoder dependencies can be bundled locally and reviewed as local assets.

Conversion (Requires External Tools)

FormatExtensionConverterOutput
STEP.step .stpPython + CadQuery/OCCTGLB
IGES.iges .igsPython + CadQuery/OCCTGLB
BREP.brepPython + CadQuery/OCCTGLB
SLDPRT.sldprtFreeCADGLB
3MF.3mfPython + trimeshGLB
DAE.daePython + trimeshGLB
FBX.fbxFBX2glTFGLB

Format Feature Matrix

FeatureGLB/GLTFSTLOBJPLYFBX (converted)CAD
MeshYesYesYesYesYesYes
Point CloudNoNoNoYesNoNo
MaterialsPBRBasicMTLBasicBasicNo
TexturesEmbeddedNoExternalNoNoNo
ColorsVertexFaceNoVertexNoFace (STEP)
AnimationYesNoNoNoYesNo

Usage

Syntax Guide

1. Inline Embed

Write a wikilink anywhere in your note. Works in Reading and Live Preview.

![[model.glb]]
![[model.glb|400x300]]

2. 3d Code Block

Quick — file path only:

```3d model.glb
```

Full config — camera, lights, scene, multi-model:

```3d
{
  "models": [
    { "path": "model.glb" },
    { "path": "part.stl", "color": "#ff0000", "wireframe": true }
  ],
  "camera": { "fov": 30, "position": [5, 5, 5] },
  "lights": [
    { "type": "hemisphere", "color": "#fff", "intensity": 1 },
    { "type": "directional", "position": [10, 20, 10] }
  ],
  "scene": { "autoRotate": true, "grid": true },
  "width": "100%",
  "height": 500
}
```
SectionKey fields
models[]path (required), color, wireframe
camerafov, position, lookAt, mode ("perspective" / "orthographic")
lights[]type ("hemisphere" "directional" "point" "spot" "ambient" "attachToCam"), color, intensity, position
scenebackground, autoRotate, autoRotateSpeed, grid, axis, groundShadow, transparent
stlcolor, wireframe (defaults for STL files)
top-levelwidth, height

3. 3dgrid Code Block

Render multiple models in one viewport using layout presets.

```3dgrid
{
  "models": [
    { "path": "v1.step" },
    { "path": "v2.step" },
    { "path": "v3.step" }
  ],
  "preset": "compare"
}
```
PresetLayout
compareSide-by-side A/B
showcaseMulti-angle single model
explodeRing arrangement
timelineHorizontal strip
galleryAll in one scene (default)
composeCustom sections

3dgrid accepts the same camera, lights, scene fields as 3d, plus: preset, params, columns, rowHeight, gapX, gapY, sections, direction.

4. Direct File View

Click any .glb/.gltf/.stl/.obj/.ply file in the file explorer.

Supported Extensions

TypeFormats
Direct.glb .gltf .stl .obj .ply
Conversion.step .stp .iges .igs .brep .sldprt .3mf .dae .fbx

Keyboard Shortcuts (in preview)

KeyAction
RReset view
WToggle wireframe
GToggle orientation gizmo
BToggle bounding box
SpacePlay/pause animation
EscExit annotation mode

3D Annotations

Add labeled bookmarks directly on model surfaces. Annotations persist per model file.

Direct View & Workbench (edit mode):

  1. Click the tag icon in the toolbar (or "Annotate" button in the workbench panel)
  2. A blue overlay indicates annotation mode is active
  3. Click anywhere on the model surface to place a pin
  4. Enter a label and pick a color in the popup editor
  5. Click an existing pin to edit its label/color or delete it
  6. Click a pin label in the workbench panel to animate the camera to that position
  7. Press Esc to exit annotation mode

Depth-aware occlusion: Pins behind geometry display blurred and dimmed. When the camera stops moving for ~250ms, fully occluded pins are automatically hidden, leaving only visible bookmarks.

Code blocks & Live Preview: Saved annotations display as read-only overlays with the same occlusion behavior.


Settings

SettingDefaultDescription
LanguageautoUI language (English / Simplified Chinese / auto-detect)
Canvas height400Preview height in pixels
Auto-rotateoffStart with turntable animation
Auto-rotate speed0.5Rotation speed (0.1-2.0)
Render qualityhighQuality preset (low/medium/high)
Render scale1.0Resolution multiplier (0.25-2.0)
Snapshot folderMedia/3D PreviewsExport folder
Snapshot namingmodel-nameFile naming mode for exported PNG snapshots
Report folderAnalysis/3D ReportsKnowledge notes folder
Log levelwarnConsole log verbosity

Converter Settings

SettingDescription
Enable CAD converterEnable STEP/IGES/BREP via CadQuery
Enable SLDPRT converterEnable SolidWorks via FreeCAD
Enable mesh converterEnable 3MF/DAE via trimesh
Enable OBJ2GLTF converterOptional OBJ normalization through obj2gltf
Enable FBX2glTF converterEnable FBX conversion through FBX2glTF
Python command path (for CAD conversion)Override the Python executable used for STEP/IGES/BREP conversion
FreeCADCmd path (for SLDPRT conversion)Override the FreeCAD executable used for .sldprt conversion
obj2gltf command pathOverride the obj2gltf CLI path
FBX2glTF command pathOverride the FBX2glTF CLI path
Python command path (for 3MF/DAE conversion)Override the Python executable used for 3MF/DAE conversion
Converter command diagnosticsShow which executable path the plugin will actually use and run lightweight self-checks for Python environments and converter CLIs

Portability and diagnostics

The rendering layer is cross-platform: direct formats like GLB, OBJ, STL, PLY, and already-converted .ai3d-converted.glb assets can render anywhere Obsidian Desktop can provide WebGL.

On iOS, iPadOS, and Android, the plugin now supports direct formats such as GLB, GLTF, OBJ, STL, and PLY. Local conversion routes for CAD, FBX, 3MF, DAE, and SLDPRT remain desktop-only because they depend on external CLI tools and Python environments.

The conversion layer is less portable because it depends on local tools and Python environments that vary by machine. Use the converter diagnostics panel in plugin settings as the first check when a CAD or mesh format fails. It verifies both the executable path the plugin resolved and whether the selected Python environment can import the required packages or the native converter CLI can launch.

For repository-level implementation rules, see docs/cross-platform-development.md.

On macOS in particular, the system Python at /usr/bin/python3 often exists but does not include CAD packages. If diagnostics show that path and the self-check fails, install a separate Python environment and point the plugin setting to that interpreter explicitly.


External Dependencies

Only needed for CAD, FBX, and mesh conversion. Direct formats work without any external tools.

Python + CadQuery (STEP, IGES, BREP)

# Install
pip install cadquery trimesh

Verify with the Python command your OS uses:

  • Windows: py -c "import cadquery; print('OK')"
  • macOS / Linux: python3 -c "import cadquery; print('OK')"

If diagnostics resolve to /usr/bin/python3 on macOS and the import check fails, install a separate Python (for example Homebrew Python), install cadquery and trimesh there, then set that interpreter path in plugin settings.

FreeCAD (SLDPRT)

Install FreeCAD for your platform:

  • Windows: install from freecad.org/downloads
  • macOS: install the app bundle or use brew install --cask freecad
  • Linux: install your distro's FreeCAD package and make sure freecadcmd is available

The plugin prefers the explicit setting and environment variable first, then checks common user-managed install locations, then PATH, and finally system fallback hints such as:

  • Windows: %LOCALAPPDATA%\Programs\FreeCAD*\bin\FreeCADCmd.exe
  • macOS: /Applications/FreeCAD.app/Contents/MacOS/FreeCADCmd, /usr/local/bin/FreeCADCmd, /opt/homebrew/bin/FreeCADCmd
  • Linux: /usr/bin/freecadcmd

Python + trimesh (3MF, DAE)

pip install trimesh numpy networkx pycollada

Auto-discovery: Same Python as CadQuery (see above).

Override: Environment variable AI3D_ASSIMP_CMD.

obj2gltf (OBJ, optional)

The plugin already has a built-in OBJ loader. obj2gltf is an optional alternative that can produce higher-fidelity GLB output.

Install:

npm install -g obj2gltf

Resolution order: The plugin prefers the explicit setting and environment variable first, then checks common user-managed install locations, then PATH, and finally system fallback hints such as obj2gltf.cmd on Windows and obj2gltf in standard macOS/Linux locations like /usr/local/bin/obj2gltf and /opt/homebrew/bin/obj2gltf.

Enable: Settings > Enable OBJ2GLTF converter, or set "obj2gltf path".

FBX2glTF (FBX)

FBX files are converted to GLB through the local FBX2glTF binary. The older community FBX loader is not bundled because its current release targets Babylon.js 8, while this plugin uses Babylon.js 9.

Install:

Download or build FBX2glTF for your platform and place the binary in a known location.

Resolution order: The plugin prefers the explicit setting and environment variable first, then checks common user-managed install locations, then PATH, and finally system fallback hints such as:

C:\Program Files\FBX2glTF\FBX2glTF-windows-x64.exe
C:\Program Files\FBX2glTF\FBX2glTF.exe
/usr/local/bin/FBX2glTF
/opt/homebrew/bin/FBX2glTF
/usr/local/bin/fbx2gltf

Enable: Settings > Enable FBX2glTF converter, or set "FBX2glTF path".

Environment Variables

VariablePurpose
AI3D_FREECAD_CMDPython command for CadQuery
AI3D_FREECADCMDFreeCADCmd path
AI3D_ASSIMP_CMDPython command for trimesh
AI3D_OBJ2GLTF_CMDobj2gltf command path
AI3D_FBX2GLTF_CMDFBX2glTF command path

The legacy alias AI3D_FREECMDCMD is still accepted for compatibility, but new setups should use AI3D_FREECADCMD.


Technical Details

Architecture

src/
├── main.ts                    # Plugin lifecycle, commands
├── domain/
│   ├── models.ts              # Shared interfaces
│   └── constants.ts           # Default settings, extensions
├── store/
│   ├── create-store.ts        # Custom store primitive
│   └── plugin-store.ts        # Obsidian saveData bridge
├── render/babylon/
│   ├── scene.ts               # BabylonModelPreview class
│   ├── grid.ts                # GridRenderer class
│   ├── annotations.ts         # AnnotationManager (pin overlay + occlusion)
│   ├── picking.ts             # Click-to-pick with highlight
│   ├── loaders/
│   │   ├── stl-loader.ts      # Custom binary STL parser
│   │   ├── ply-loader.ts      # Custom ASCII/binary PLY parser
│   │   └── register.ts        # Babylon SceneLoader plugins
│   └── presets/               # Grid layout presets
├── io/
│   ├── formats/
│   │   └── registry.ts        # Format capability registry
│   ├── conversion/
│   │   ├── manager.ts         # Conversion orchestration
│   │   └── adapters/          # Converter implementations
│   └── model-pipeline.ts      # Format routing logic
└── view/
    ├── workbench/             # Main workbench UI
    ├── inline/                # Code blocks, live preview
    └── direct-view.ts         # Direct file opening

Model Import Pipeline

┌─────────────────────────────────────────────────────────────┐
│  1. Format Detection                                        │
│     └─ getFormatCapability(ext) → { family, strategy }      │
│                                                             │
│  2. Route Decision                                          │
│     ├─ strategy: "direct" → prepareDirectLoad()             │
│     └─ strategy: "convert" → convertForPreview()            │
│                                                             │
│  3. Data Loading                                            │
│     ├─ readBinaryPath() → ArrayBuffer                       │
│     └─ [if converted] → read converted .glb                 │
│                                                             │
│  4. Babylon Rendering                                       │
│     ├─ GLB/GLTF/OBJ → SceneLoader.ImportMeshAsync()        │
│     ├─ STL → loadSTLBuffer() (direct parse)                 │
│     └─ PLY → loadPLYBuffer() (direct parse)                 │
└─────────────────────────────────────────────────────────────┘

Why Direct Buffer Loading for STL/PLY

Babylon.js v9 SceneLoader has a bug where custom plugins receive data URL strings instead of ArrayBuffer when loading via SceneLoader.ImportMeshAsync(). Built-in loaders (GLTF and OBJ) are unaffected.

Workaround: STL and PLY parsers are called directly with the raw ArrayBuffer, bypassing SceneLoader entirely.

Conversion Caching

  • Location: Same directory as source file
  • Format: {filename}.ai3d-converted.glb
  • Validation: Checks converter identity, cache key, file existence
  • Invalidation: Automatic when converter settings change
  • Manual clear: Command palette > "Clear Conversion Cache"

Known Limitations

IssueAffected FormatsWorkaround
External converter requiredFBXInstall and enable FBX2glTF
Binary-only STLSTLConvert ASCII STL to binary
External tools requiredSTEP/IGES/BREP/SLDPRTInstall Python + CadQuery or FreeCAD
Texture path resolutionOBJPlace textures in same directory as OBJ
Conversion timeoutSLDPRT10-minute timeout for complex assemblies

Deployment

Prerequisites

  • Node.js >= 18
  • npm >= 9
  • Obsidian >= 1.5.0

Build Commands

npm install           # Install dependencies
npm run dev           # Development build with watch
npm run build         # Production build
npm run typecheck     # TypeScript type check

Build Output

ai-model-workbench/
├── main.js           # 1.7 MB (minified, Babylon.js core)
├── manifest.json     # Plugin manifest
├── styles.css        # Plugin styles
└── src/              # Source code

Release Publishing

Releases are published by the GitHub Actions Release workflow. Push a tag that matches manifest.json, for example v0.1.7, or run the workflow manually. The workflow uploads only main.js, manifest.json, and styles.css, removes unsupported release assets, and generates GitHub artifact attestations for the published files.

Platform Support

PlatformStatus
WindowsFull support
macOSFull support
LinuxFull support
Obsidian MobileSupported (reduced resolution)

Bundle Size Optimization

Babylon.js core is ~98% of the bundle size. The project uses:

  • Subpath imports (@babylonjs/core/Engines/engine.js) instead of barrel imports
  • Tree-shaking to remove unused features
  • esbuild for fast, optimized bundling

Without subpath imports, the bundle would be ~7 MB instead of 1.7 MB.


License

MIT

For plugin developers

Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.