Upload a static 3D mesh. Get an animation-ready rigged model in seconds.
Features • Architecture • Pipeline • Tech Stack • Getting Started • Project Structure • API • License
ZamaRig is a full-stack web application that automatically rigs 3D models using a combination of machine learning classification and procedural bone fitting. Users upload a static .obj or .fbx mesh through a modern web interface, and the system:
- Renders the model from multiple camera angles
- Classifies it as humanoid or quadruped using a trained CNN
- Generates and fits a skeleton template based on the model's anatomy
- Applies automatic weight painting (skinning)
- Returns the rigged model ready for animation
No manual bone placement. No weight painting by hand. Just upload and download.
- AI Classification — EfficientNetB0-based CNN automatically determines model type (humanoid / quadruped)
- Automatic Skeleton Generation — Procedural bone placement using bounding box analysis and anatomical proportions
- Pose Detection — Detects whether humanoid models are in A-pose or T-pose for accurate fitting
- Geodesic Skinning — Advanced weight painting using geodesic distance calculations for natural deformation
- Interactive 3D Landing Page — Scroll-driven animations with dissolve effects, model transitions, and skeleton visualization using Three.js
- Real-time 3D Preview — Preview uploaded and rigged models directly in the browser with React Three Fiber
- Dark / Light Theme — Full theme support across UI and 3D viewport
- Responsive Design — Optimized layouts for desktop, tablet, and mobile
┌─────────────────────────────────────────────────────────────────┐
│ CLIENT │
│ React + TypeScript + Three.js/R3F + GSAP + Tailwind CSS │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ Landing │ │ Rig │ │ 3D View │ │ Theme System │ │
│ │ Page │ │ Page │ │ (R3F) │ │ (Context) │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────────┘ │
└────────────────────────┬────────────────────────────────────────┘
│ REST API (multipart/form-data)
▼
┌─────────────────────────────────────────────────────────────────┐
│ BACKEND │
│ FastAPI + Uvicorn (Async Python) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ API Router │ │ ML Service │ │ Blender Service │ │
│ │ /api/v1/* │ │ (TF/Keras) │ │ (subprocess → bpy) │ │
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
└────────────────────────┬────────────────────────────────────────┘
│ subprocess call
▼
┌─────────────────────────────────────────────────────────────────┐
│ BLENDER (Headless) │
│ Python bpy scripts — runs without GUI │
│ ┌────────────┐ ┌──────────────┐ ┌────────────────────────┐ │
│ │ Renderer │ │ Humanoid │ │ Quadruped │ │
│ │ (renders) │ │ Rigging │ │ Rigging │ │
│ └────────────┘ └──────────────┘ └────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
The auto-rigging pipeline follows 6 sequential stages:
The user uploads a .obj or .fbx file. The backend saves it temporarily and validates the format.
Blender runs headlessly to import the model, center it, and render silhouette images from 4–6 camera angles (front, back, left, right, top). These renders serve as input to the classifier.
The rendered images are fed into a pre-trained EfficientNetB0 model (transfer learning on ImageNet). The CNN outputs a category with a confidence score:
humanoid— bipedal characters (humans, robots, etc.)quadruped— four-legged animals (dogs, horses, etc.)
Based on the classification result, the corresponding skeleton template is loaded. The system:
- Computes the mesh's bounding box dimensions
- For humanoids: detects A-pose vs T-pose via arm angle analysis
- Scales and positions each bone proportionally using anatomical heuristics
- Handles special cases like finger joints, spine curvature, and tail bones
Vertices are assigned bone influence weights using:
- Blender's built-in Auto Weights as a baseline
- Geodesic distance-based skinning for improved deformation quality around joints
The fully rigged model is exported as .glb (glTF Binary) and served to the frontend for preview and download.
📖 For an in-depth technical deep-dive with mathematical foundations, bone hierarchies, and code-level explanations, see RIGGING_PIPELINE.md.
| Technology | Purpose |
|---|---|
| React 19 | UI framework with hooks & context |
| TypeScript | Type-safe development |
| Vite | Build tool & dev server |
| React Three Fiber | Declarative Three.js for 3D rendering |
| Three.js | WebGL-based 3D engine |
| GSAP + ScrollTrigger | Scroll-driven animations & transitions |
| Lenis | Smooth scroll behavior |
| Tailwind CSS 4 | Utility-first styling |
| React Router 7 | Client-side routing |
| Technology | Purpose |
|---|---|
| FastAPI | Async Python API framework |
| Uvicorn | ASGI server |
| TensorFlow / Keras | ML model inference (EfficientNetB0) |
| Pillow | Image preprocessing |
| NumPy | Numerical operations |
| Pydantic | Request/response validation |
| Technology | Purpose |
|---|---|
| Blender 5.x (bpy) | Headless 3D processing, rendering, rigging |
| EfficientNetB0 | Image classification (transfer learning) |
| Geodesic Skinning | Distance-based vertex weight calculation |
| Technology | Purpose |
|---|---|
| Vercel | Frontend hosting (SPA with rewrites) |
| Bun | JavaScript runtime & package manager |
- Node.js 18+ or Bun (recommended)
- Python 3.10+
- Blender 5.x (must be accessible from command line)
cd frontend
bun install # or npm install
bun dev # starts dev server at http://localhost:5173cd backend
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
python main.py # starts API at http://localhost:8000Create frontend/.env:
VITE_API_URL=http://localhost:8000cd frontend
bun run build # outputs to dist/auto-rigging/
├── frontend/ # React + TypeScript SPA
│ ├── public/ # Static assets (3D models, icons)
│ ├── src/
│ │ ├── components/
│ │ │ ├── landing/ # Landing page components
│ │ │ │ ├── landing-canvas.tsx # Three.js canvas wrapper
│ │ │ │ ├── landing-model.tsx # 3D model with scroll animations
│ │ │ │ ├── dissolve-material.ts # Custom dissolve shader
│ │ │ │ ├── smooth-scroll.tsx # Lenis smooth scroll + progress bar
│ │ │ │ ├── loading-screen.tsx # Loading overlay
│ │ │ │ ├── footer.tsx # Site footer
│ │ │ │ └── sections/ # Individual scroll sections
│ │ │ ├── layout/ # Header, layout wrapper
│ │ │ └── ui/ # Reusable UI components
│ │ ├── config/
│ │ │ └── scroll-anim-config.ts # Responsive scroll animation values
│ │ ├── hooks/ # Custom React hooks (theme, etc.)
│ │ ├── pages/ # Route pages (Home, Rig)
│ │ ├── services/ # API client services
│ │ └── types/ # TypeScript type definitions
│ ├── vercel.json # Vercel SPA routing config
│ └── package.json
│
├── backend/ # FastAPI Python server
│ ├── main.py # App entry point
│ ├── requirements.txt
│ ├── app/
│ │ ├── api/v1/
│ │ │ └── endpoints/
│ │ │ └── rigging.py # POST /api/v1/rigging/process
│ │ ├── core/ # Settings, configuration
│ │ └── services/
│ │ ├── ml_service.py # TensorFlow model inference
│ │ └── blender_service.py # Blender subprocess orchestration
│ ├── blender_scripts/
│ │ ├── common/ # Shared utilities
│ │ │ ├── blender_utils.py
│ │ │ ├── fitting_utils.py
│ │ │ ├── mesh_processing.py
│ │ │ ├── mesh_utils.py
│ │ │ └── profile_analysis.py
│ │ ├── humanoid/
│ │ │ ├── analyzer.py # Pose detection, proportion analysis
│ │ │ └── rigging.py # Humanoid skeleton generation & fitting
│ │ ├── quadruped/
│ │ │ ├── analyzer.py # Body segment analysis
│ │ │ └── rigging.py # Quadruped skeleton generation & fitting
│ │ └── tools/
│ │ ├── take_renders.py # Multi-angle rendering script
│ │ ├── run_rigging.py # Rigging orchestrator
│ │ ├── geodesic_skinning.py # Advanced weight painting
│ │ └── inspect_rig.py # Debug/inspection utility
│ └── public/ # Served static files (processed models)
│
├── blender/ # Standalone Blender utilities
│ ├── scripts/
│ │ ├── render_dataset.py # Batch render script for dataset creation
│ │ └── export_all.py # Batch export utility
│ └── add-ons/ # Custom Blender add-ons
│
├── ml_pipeline/ # Machine learning training
│ ├── notebooks/
│ │ ├── model_train.ipynb # EfficientNetB0 training notebook
│ │ └── test.ipynb # Model evaluation & testing
│ └── saved_models/ # Exported .keras model files
│
├── dataset/ # Training data
│ ├── models/ # Raw 3D models (organized by class)
│ ├── renders/ # Multi-angle renders for training
│ └── test_renders/ # Test set renders
│
├── RIGGING_PIPELINE.md # In-depth technical documentation
├── TODOS.md # Development roadmap & progress
└── README.md # ← You are here
Accepts a 3D model file and returns a rigged version.
Request:
Content-Type: multipart/form-data
file: <.obj or .fbx file>
Response:
{
"status": "success",
"classification": "humanoid",
"confidence": 0.97,
"output_file": "/public/results/<id>/rigged_model.glb"
}Pipeline Steps (server-side):
- Save uploaded file →
public/uploads/ - Render silhouettes via Blender subprocess
- Classify renders via TensorFlow
- Run appropriate rigging script via Blender subprocess
- Return rigged
.glbpath
Redirects to Swagger UI documentation at /docs.
The landing page features an interactive 3D experience built with React Three Fiber and GSAP:
- Scroll-driven model animation — The 3D model moves, rotates, and scales based on scroll position with configurable breakpoint-specific values
- Dissolve effect — Custom shader-based morph transition between humanoid and quadruped models in the Classification section
- Skeleton visualization — 3D bone meshes rendered on top of the model in the Download section with emissive cyan material
- Smooth scrolling — Lenis-powered buttery smooth scroll with GSAP ScrollTrigger integration
- Responsive configs — Separate animation values for desktop (>1024px), tablet (768–1024px), and mobile (<768px)
- Loading screen — Animated overlay that displays while 3D assets are loading
This project is open source under the MIT License.
Built with ❤️ by zamazincode