Materializr
Open-source parametric 3D CAD for makers — constraint sketches, solid modeling, threads, SVG & text engraving, STL/STEP export. Android, iPad, Linux, Mac, Windows. Vibe coded.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Personal Fully Offline Assistant (Powered by OLLAMA)
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
Dānā — an agentic CAD engineer that turns sketches into FreeCAD models Dānā is an open-source, multi-step LLM agent that designs mechanical parts. You describe a part, or hand it a drawing. It plans the build, drives a real FreeCAD kernel through ~90 typed tools, checks its own geometry, and exports a standalone FreeCAD macro that rebuilds the part without the agent. It began as a commercial product and is now published as an engineering portfolio piece. The README focuses on the four engineering problems that took the most work, with links to the code that solves each one.查看完整 README ↗
Dānā is an open-source, multi-step LLM agent that designs mechanical parts. You describe a part, or hand it a drawing. It plans the build, drives a real FreeCAD kernel through ~90 typed tools, checks its own geometry, and exports a standalone FreeCAD macro that rebuilds the part without the agent.
It began as a commercial product and is now published as an engineering portfolio piece. The README focuses on the four engineering problems that took the most work, with links to the code that solves each one.
| Stack | Python 3.11 · FastAPI + WebSockets · React/TypeScript (Tauri desktop shell) · FreeCAD (headless FreeCADCmd) · Ollama · Jinja2 |
| Models | Cloud: DeepSeek (primary), Gemini, OpenRouter, Groq · Local: qwen2.5-coder:14b (tools), qwen2.5vl:7b (vision) |
| Tests | 1,479 pytest cases, blocking in CI, no live model or GPU needed · Playwright UI tests against a mock backend |
Problem. A multi-step CAD session mixes very different turns. Some make precise geometry calls, where a wrong argument corrupts the model. Others are cheap bookkeeping, such as a catalog lookup. Letting "whatever model is configured" handle every turn wasted money and let small local models slip wrong parameters into the geometry.
Solution. Each turn's model chain is a pure function of config plus turn state, with no randomness and no LLM-judged routing:
routing_config.yaml, parsed by dana/core/llm_router.py). Each entry is a provider, model, priority, context window and cost. API keys are referenced by env-var name and never stored in the file.context_window × safety_margin fits the turn's estimated token count. Eligible entries are tried in priority order, with a configured terminal fallback (local Qwen) always last.allow_cloud: false) returns only Ollama entries, with no silent escape to the cloud.dana/core/react_dispatch.py pins Turn 0 (create_plan) to a cloud model.report_fleet_entry_failure) and the chain falls through to the next one. The whole router can be removed: without the YAML file, the legacy .env resolution runs unchanged.In practice, DeepSeek handles planning and geometry, local Qwen handles bookkeeping and full-offline mode, and every routing decision can be reproduced from config.
Problem. Vision models are good at recognizing what is in a drawing and bad at how big it is. A 7B VLM returns JSON that is structurally valid but numerically wrong: all-zero boxes, invented part IDs.
Solution. A staged pipeline where every step that touches numbers is deterministic:
dana/plugins/vision/ocr_grounding.py). EasyOCR reads the printed dimensions from each orthographic view. They are passed to the VLM as hard constraints, and they alone determine the bounding box.dana/plugins/vision/image_analysis.py). Pass 1 extracts primitives (box, cylinder, sphere and their dimensions). Pass 2 extracts relationships and joints given pass 1's output. Each pass tries a local model first and falls back to the cloud, and a JSON decode failure moves on to the next provider instead of aborting.parent_id/child_id references fail loudly. A fabricated blueprint never reaches the CAD kernel as ok: true.dana/plugins/freecad/ir.py). One step-dict schema (box, cylinder, boolean, edge ops, …) is shared by three consumers that used to generate FreeCAD script text separately: live tool execution, session replay, and the composite-skill compiler.dana/plugins/freecad/py_export.py + templates/macro_export.py.jinja2). The session's call log, including boolean cut/union/intersect steps, is rendered into one standalone .py macro that rebuilds the part in stock FreeCAD.dana/tools/cad_vision.py). After every mutating CAD call, the viewport is captured headlessly and a VLM reads it back, so the agent checks what it actually built.No GPU? Set DANA_VISION_MOCK_FALLBACK=1. When no vision model is reachable, the pipeline then continues on a clearly flagged placeholder blueprint ("mocked": true) instead of stopping. It is off by default because it is fabricated geometry.
What a chat session gives you besides the conversation:
dana/plugins/freecad/rebuild.py). Every CAD call is recorded and replayed through the same Universal CAD IR the macro export uses. The Parameters tab lists the model's dimensions; change one and Apply & Rebuild re-runs the recorded steps with no LLM call. On FreeCAD the steps render into a scratch document that replaces the live one only on success; on the mock engine (CI, the hosted demo) the call log is replayed through the mock driver..py, with a provenance header listing the editable parameters and how many LLM calls vs. free rebuilds built it), STEP/STL, the 2D blueprint and a costed BOM with tip-over stability — none of them cost tokens.dana/api/session_state.py). The plan, object registry, topology, call log and token/cost totals are saved with the chat, and the FreeCAD document is snapshotted with its SHA-256; resuming restores both. Approvals, auto-approve and API keys are never written to disk.Problem. An earlier deploy broke even though CI was green, because CI only imported a single module. The fix was to make CI run the real code in the same kind of environment it ships to.
Solution (.github/workflows/build.yml):
xvfb, with --strict-markers and a per-test timeout. Failures are parsed out of the JUnit XML into GitHub ::error annotations, so they show on the PR without opening the log.app.py from the exact payload deploy/stage_space.sh ships, with the pinned Gradio version.tsc && vite build that Vercel runs.workflow_run only after Build succeeds.tests/conftest.py). Every module-level path into freecad_output/, exports/ or agent_workspace/ is redirected to the test's tmp_path (found by sweeping the loaded modules, so a new one is covered automatically), every per-session registry is cleared before and after each test, and the run fails if the real workspace changed at all. TTS/audio hardware calls go to fakes. They block mid-test .env reloads (a real leak that once overrode test env vars) and force auto-approve and context distillation off. DANA_HEADLESS=true and DANA_OS_DRY_RUN=1 keep FreeCAD's GUI and physical input out of CI.tests/e2e/). Playwright drives the real UI against the real server with the mock CAD engine, a scripted model and a throwaway workspace (tests/e2e/mock_backend.py): streaming, the cost bar, macro export, the BOM popover and a parametric rebuild. Run with cd frontend && npx playwright test.Problem. The agent keeps a persistent "core memory" of user preferences, project constraints and learned workflows. It is injected into every system prompt and survives restarts. Nothing limited its size, so over weeks of use it would grow without limit into every turn's context.
Solution (dana/plugins/memory/core_memory.py):
React/Tauri UI ──WebSocket /ws/chat──▶ FastAPI (dana/api/server.py)
│
ReAct loop (dana/core/react_dispatch.py)
plan → tool call → observe → verify
│
┌──────────────────────────────┼──────────────────────────────┐
▼ ▼ ▼
LLM router (llm_router.py) Tool registry (~90 tools) Core memory (2k, FIFO)
DeepSeek / Gemini / OpenRouter CAD · vision · web · OS · skills + session call log
/ Groq → local Qwen fallback │
▼
FreeCAD plugin (dana/plugins/freecad/)
Universal IR → FreeCADCmd (headless)
→ .FCStd session doc · STEP/STL/URDF · .py macro
Requires Python 3.11, FreeCAD 1.0+, Ollama, and Node 20+ for the UI.
git clone https://github.com/Cascade-Router/Dana.git && cd Dana
python -m venv .venv && source .venv/bin/activate # Windows: .\.venv\Scripts\activate
pip install -r requirements.txt -r requirements-dev.txt
cp .env.example .env # OLLAMA_URL defaults to http://localhost:11434
cp routing_config.yaml.example routing_config.yaml # optional: enables the deterministic router
ollama pull qwen2.5-coder:14b # local tool-calling fallback
ollama pull qwen2.5vl:7b # local vision (or set DANA_VISION_MOCK_FALLBACK=1)
(cd frontend && npm install)
./launch_dana.sh # Windows: powershell -File launch_dana.ps1
With no cloud keys set, Dānā runs fully locally on Ollama. Add DEEPSEEK_API_KEY (or another provider's key) to .env to enable cloud routing.
Run the test suite (no GPU, model server or API key needed):
DANA_HEADLESS=true DANA_OS_DRY_RUN=1 python -m pytest
cd frontend && npx playwright install chromium && npx playwright test # UI tests, no FreeCAD or API key
A two-minute walkthrough of the pipeline is scripted in DEMO_SCRIPT.md.
| Path | What lives there |
|---|---|
dana/api/ | FastAPI server, WebSocket chat protocol, sessions, model registry |
dana/core/ | ReAct loop, LLM router, model providers, context management |
dana/plugins/freecad/ | FreeCAD engine, universal IR, Jinja2 templates, macro/TechDraw export |
dana/plugins/vision/ | OCR grounding and two-pass blueprint extraction |
dana/plugins/memory/ | Persistent core memory |
frontend/ | React + TypeScript UI (Tauri desktop shell) |
tests/ | pytest suite (mirrors the dana/ layout) |
docs/ | Architecture notes and design write-ups (ARCHITECTURE.md) |
AGPL-3.0. See CONTRIBUTING.md and SECURITY.md.