mesh-avatar-studio
Turn one illustration into an animated 2D mesh avatar with a coding agent and a local editor
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证AI chat-to-STL portal: describe an object, DeepSeek V4.1 Flash designs it, an exact Manifold geometry kernel builds a watertight 3D-printable STL plus a Blender script. Next.js 16, PostgreSQL, 3D viewer, gallery with likes and sharing, credit-based plans, Coolify-ready.
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗
Describe an object in the chat, get back a watertight, printable STL plus a Blender Python script that rebuilds it with native primitives and booleans. Preview it in 3D, refine it in conversation, publish it to a gallery with likes and social sharing, and download it. Credit‑based plans: Free (10 credits), Starter (100/month), Pro (1000/month); a new model costs 5 credits, each edit 1 (Free = one model plus five edits, text only).
Inspired by Meshy AI and Tripo AI, built for Blender users and FDM printers.
https://3dblend.tertiaryinfotech.com — hosted on Hostinger via Coolify. Every push to main is deployed automatically through a GitHub webhook.
{op:"mesh"} in the agent's spec: a watertight base solid (via Manifold) the agent can cut, extend, scale or move; upload a 3DBlend Blender script and its embedded spec is restored for further editing.src/agent/) — DeepSeek V4.1 Flash emits a tiny JSON CSG language; a deterministic kernel builds it; printability checks feed errors back for automatic repair. Runs from the CLI too..3mf (units, indexed mesh, metadata) for Bambu Studio, PrusaSlicer and Cura, and .obj (millimetres, Z‑up, same frame as the STL) for Blender, Fusion and game engines; both derived from the stored STL and cached..blender.py per model that recreates the design with bmesh primitives, EXACT booleans, arrays and mirrors, in millimetres, sitting on the build plate.M400 U1), PrusaSlicer (M600/M601) and Cura/Marlin (M0/M600), plus material‑pairing tips.src/lib/site.ts.remixOfId) and a "Title by Author" snapshot that every later version inherits; shown on the share page, in the studio, on gallery cards and inside the 3MF metadata (CC BY 4.0).defaultVisibility / canMakePrivate in src/lib/plans.ts)./admin (users flagged isAdmin): overview KPIs, all users with search and pagination (plan, credit top‑ups, grant/revoke admin), every subscription and invoice (sync, cancel, PDF), gallery moderation (feature, hide, delete), and an Integrations tab: DeepSeek API, HitPay keys, SMTP, each with a test button, plus editable transactional email templates (welcome, subscription activated, invoice with PDF, cancellation). Settings saved there override the environment and secrets are encrypted at rest.┌────────────┐ SSE ┌──────────────────────┐ OpenAI-compatible ┌───────────────────┐
│ Next.js │ ◄──────► │ /api/chat (harness) │ ──────────────────────► │ DeepSeek V4.1 │
│ App Router│ │ validate → build → │ ◄────── JSON spec ───── │ Flash │
│ R3F viewer│ │ check → repair loop │ └───────────────────┘
└─────┬──────┘ └──────────┬───────────┘
│ Prisma │ Manifold (WASM) → binary STL + Blender .py
▼ ▼
┌────────────┐ ┌──────────────────────┐
│ PostgreSQL │ │ STORAGE_DIR volume │
└────────────┘ └──────────────────────┘
user idea (+ image / PDF, printer, nozzle, material)
│
▼
LLM ─► { message, spec } ─► zod validation ─► Manifold build ─► DFM checks ─► OK? ──► optimise pass ─► STL / 3MF / .py
▲ │ │ │ (kept only if the
└──────── repair prompt with the exact errors ◄─────┴──────────────┘ print score improves)
(max 4 attempts)
The model never touches geometry directly. It writes a declarative spec in a ~20‑op CSG DSL (cube, cylinder, sphere, cone, torus, roundedBox, extrude, revolve, union, difference, intersection, hull, translate, rotate, scale, mirror, repeat, radial, ref/parts). The harness owns every side effect, which keeps generation deterministic, cheap (one LLM call per attempt, ~3 s), replayable, and safe to expose publicly.
Key files:
| File | Purpose |
|---|---|
src/agent/spec.ts | DSL schema (zod) and semantic validation (refs, cycles, size limits) |
src/agent/kernel.ts | Manifold builder → positions/indices, volume, bbox, genus, shells |
src/agent/checks.ts | DFM analysis: fit, overhangs, bridges, thin walls, layer height, material tips |
src/agent/thickness.ts | Local wall‑thickness map via BVH ray casting (three-mesh-bvh) |
src/lib/printers.ts | Printer / nozzle / material presets |
src/components/PrintSetup.tsx | Printer / nozzle / material selector (persisted per browser) |
src/app/api/messages/[id]/image | Serves a message's reference image (owner only) |
src/agent/stl.ts | Binary STL writer + parser |
src/agent/threemf.ts | 3MF (zip + XML) writer |
src/agent/obj.ts | Wavefront OBJ writer |
src/components/ModelStage.tsx | Viewer wrapper with the 3D ⇄ Render toggle, finish/colour picker and PNG export |
src/lib/colour-swap.ts / src/components/TwoColourGuide.tsx | Swap‑height suggestions and the per‑slicer two‑colour guide |
src/agent/blender.ts | Spec → self‑contained bpy script |
src/agent/llm.ts | DeepSeek client (OpenAI SDK, non‑thinking mode, JSON output; TruncatedOutputError on token‑cap hits) |
src/agent/harness.ts | The generate → validate → build → check → repair → optimise loop (text + image input) |
src/lib/editor.ts / src/components/ShapeEditor.tsx | Manual shape editor model and the 3D edit‑mode UI (TransformControls gizmos) |
src/lib/security.ts | Turnstile verification, honeypot, in‑memory rate limiter |
src/lib/verification.ts | Email verification tokens and sending |
src/lib/settings.ts |
Why non‑thinking mode? DeepSeek V4.x in thinking mode spends its entire token budget reasoning about geometry and returns empty content for anything non‑trivial. The harness supplies the verification loop instead, and direct mode answers in ~3 s. Set
DEEPSEEK_THINKING=1to opt back in.
Runaway replies. Flash occasionally loops, re‑emitting the same few nodes until it hits the output cap. Spec calls are capped at 8k tokens (real specs are ~2k); a cut‑off reply counts as one attempt and the harness retries with a "be compact — use
repeat/radial/parts" nudge instead of failing the request. Only if every attempt runs away does the request fail (and the credit is refunded).
git clone https://github.com/alfredang/3dblend.git && cd 3dblend
npm install
cp .env.example .env # fill DEEPSEEK_API_KEY, DATABASE_URL, AUTH_SECRET
docker run -d --name 3dblend-pg -e POSTGRES_USER=blend -e POSTGRES_PASSWORD=blend -e POSTGRES_DB=blend -p 5544:5432 postgres:16-alpine
npm run db:push # create tables
npm run db:seed # demo users + 6 featured models (optional; also happens on first page view)
npm run dev # http://localhost:3000
Demo login: [email protected] / demo1234 (Pro plan, 1000 credits). With SEED_ADMIN_PASSWORD / SEED_TEST_PASSWORD set, [email protected] and [email protected] are also available (passwords from the env).
Move models between instances (for example local → production); the target rebuilds each model from its spec and skips ones it already has:
TARGET_URL=https://3dblend.tertiaryinfotech.com ADMIN_PASSWORD=... npm run push-models
Try the harness without the web app:
npm run agent -- "a desk phone stand for a 75mm wide phone, angled 65 degrees, with a cable slot"
# → out/phone-stand.stl, out/phone-stand.blender.py, out/phone-stand.spec.json
| Variable | Required | Notes |
|---|---|---|
DEEPSEEK_API_KEY | ✅ | DeepSeek API key |
DEEPSEEK_BASE_URL | default https://api.deepseek.com | |
DEEPSEEK_MODEL | default deepseek-flash (= DeepSeek‑V4.1‑Flash) | |
DATABASE_URL | ✅ | PostgreSQL connection string |
AUTH_SECRET | ✅ | openssl rand -base64 32 |
NEXT_PUBLIC_APP_URL / NEXTAUTH_URL | ✅ | public URL (share links, HitPay redirect and webhook URLs, email links) |
STORAGE_DIR | where STL / .py files live (/data/storage in Docker, mount a volume) | |
HITPAY_API_KEY, HITPAY_SALT, HITPAY_WEBHOOK_SALT, HITPAY_SANDBOX, HITPAY_CURRENCY | enable paid upgrades via HitPay recurring billing (sandbox with HITPAY_SANDBOX=1); without a key the UI shows “Coming soon” | |
CRON_SECRET | protects GET /api/cron/reset-credits (monthly top‑ups) | |
SEED_ON_BOOT | 0 disables auto‑seeding of sample models | |
TURNSTILE_SITE_KEY, TURNSTILE_SECRET_KEY, REQUIRE_EMAIL_VERIFICATION | sign‑up bot protection and verification toggle (also editable in Admin → Integrations) | |
SMTP_HOST, SMTP_PORT, SMTP_SECURE, SMTP_USER, SMTP_PASS, SMTP_FROM_NAME, SMTP_FROM_EMAIL, SMTP_REPLY_TO | transactional email; all of these (and the AI / HitPay keys) can instead be set in Admin → Integrations | |
SEED_ADMIN_PASSWORD, SEED_TEST_PASSWORD | when set, [email protected] (admin, Pro) and [email protected] (Free) are created/updated on boot |
The production instance was created through the Coolify API; the same steps work from the UI:
https://github.com/alfredang/3dblend, branch main, build pack Docker Compose, compose file /docker-compose.yml. Coolify builds the multi‑stage Dockerfile (Next.js standalone output) and brings up the bundled PostgreSQL 16 service with persistent pgdata and storage volumes.POSTGRES_PASSWORD, DEEPSEEK_API_KEY, AUTH_SECRET, NEXT_PUBLIC_APP_URL, CRON_SECRET). Coolify pre‑creates the keys from the compose file.web service: https://3dblend.tertiaryinfotech.com:3000 (the :3000 tells the Traefik proxy which container port to route to; the service is not published on the host). Coolify provisions TLS.https://<coolify-host>/webhooks/source/github/events/manual, content type application/json, secret = the application's Manual webhook secret (Coolify → app → Webhooks), event push. With Auto Deploy enabled, every push to main redeploys. Manual trigger: POST /api/v1/deploy?uuid=<app-uuid> with a Coolify API token.prisma db push so the schema is always in sync; sample models are seeded on the first page view.curl -fsS -H "x-cron-secret: $CRON_SECRET" https://3dblend.tertiaryinfotech.com/api/cron/reset-creditsSMTP_* variables); use the test buttons there to verify DeepSeek, HitPay and SMTP after deploying.Local run of the same stack: docker compose -f docker-compose.yml -f docker-compose.local.yml up --build (the override publishes port 3000).
Health check: GET /api/health.
| Route | Method | Description |
|---|---|---|
/api/register | POST | create account (10 free credits); Turnstile + honeypot + rate limit; sends the verification email |
/api/auth/verify, /api/auth/resend | GET / POST | consume a verification link / resend it |
/api/auth/* | Auth.js credentials provider | |
/api/projects | GET / POST | list / create chat projects |
/api/chat | POST (SSE) | run the agent for a project with { message, setup, attachment? }; events status, message, model, credits, error |
/api/messages/:id/image, /api/messages/:id/attachment | GET | reference image / original upload for a chat message (owner only) |
/api/models/:id/stl | GET | binary STL (?download=1 counts a download) |
/api/models/:id/3mf | GET | 3MF package (?download=1 counts a download) |
/api/models/:id/blender | GET | Blender Python script |
/api/models/:id/like | POST | toggle thumbs‑up |
/api/models/:id/publish | POST | toggle gallery visibility, edit title/description |
/api/models/:id/remix | POST | copy a public model into a new project of yours |
/api/models/:id/edit | POST | manual shape edit: merge { shapes[] } into the spec, rebuild, save as a new version |
/api/billing/checkout | POST | create a HitPay recurring billing for STARTER / PRO, returns the hosted checkout URL |
/api/billing/return | GET | HitPay redirect target; re-verifies the subscription with HitPay's API |
User (plan, credits, isAdmin) → Subscription (HitPay recurring billing, status lifecycle) → Invoice (numbered, one per charge); User → Project → Message (role, content, optional modelId, optional reference imagePath / attachmentPath / extracted attachmentText) and Model (spec JSON, stats JSON, stlPath, blenderPath, isPublic, featured, counters) with Like (user × model) and CreditTransaction (audit log).
Next.js 16 (App Router, standalone output) · React 19 · TypeScript · Tailwind CSS 4 · Prisma 6 + PostgreSQL 16 · Auth.js v5 · OpenAI SDK → DeepSeek V4.1 Flash (text + vision) · manifold‑3d (WASM) · three.js / @react‑three/fiber / drei · three‑mesh‑bvh · pdfjs‑dist + @napi‑rs/canvas · pdf‑lib · fflate · HitPay · Docker / Coolify.
.blender.py exporter targets Blender 3.6+.MIT © Alfred Ang. Gallery models are shared by their authors under CC BY 4.0 unless stated otherwise.
| DB‑backed integration settings with env fallback and AES‑GCM‑encrypted secrets |
src/lib/email.ts | SMTP sending (nodemailer) and editable {{variable}} templates |
src/lib/attachments.ts | Attachments: images, PDF text + first‑page render, STL/3MF import, Blender‑script spec recovery |
src/agent/meshio.ts | STL (ASCII/binary) and 3MF parsers, spec extraction from exported Blender scripts |
src/agent/prompts.ts | System prompt with the DSL reference and FDM design rules |
scripts/push-models.ts | Sync local models to another instance through the admin import API |
scripts/agent-cli.ts | npm run agent -- "a hex pencil cup" → out/*.stl, *.blender.py, *.spec.json |
/api/billing/webhook| POST |
HitPay callbacks (event webhooks with Hitpay-Signature, or legacy hmac form callbacks) |
/api/billing/cancel, /api/billing/sync | POST | cancel at HitPay / re-check status |
/api/invoices/:id/pdf | GET | invoice PDF (owner or admin) |
/api/admin/users, /api/admin/models, /api/admin/subscriptions | PATCH/DELETE | admin actions |
/api/admin/models/import | POST | admin bulk import: rebuild models from specs (used by npm run push-models) |
/api/admin/settings, /api/admin/settings/test, /api/admin/email-templates, /api/admin/email-templates/test | GET/PUT/POST | integrations and email templates |
/api/cron/reset-credits | GET | monthly credit top‑up (secret header) |
/api/health | GET | DB connectivity |