Canvas → STL → G-code
Automated Mold Generation for Laser Engraving & FDM 3D Printing
I built this because I got bored of doing a simple repetitive task manually.
Turning a design into a usable mold should not require:
- opening CAD software
- manually extruding shapes
- fixing meshes
- exporting formats
- slicing again and again
It's slow, error-prone, and honestly unnecessary in 2026.
So I decided to build a system that does everything automatically.
⚠️ This project may look simple from the outside, but it actually requires a lot of engineering work: geometry processing, mesh generation, manufacturing constraints, G-code logic, and performance optimization.
A plug-and-play web application that converts any 2D input into machine-ready output:
Canvas / Image / SVG
↓
Heightmap
↓
3D Geometry
↓
Negative Mold
↓
STL + G-code
No CAD. No manual steps. No friction.
- Draw directly on canvas (brush + eraser)
- Upload images (PNG, JPG, WebP, BMP)
- Import SVG files
- Drag-and-drop support
- Grayscale → heightmap conversion
- Parametric depth control
- Grid-based mesh triangulation
- Watertight STL output guaranteed
- Automatic negative cavity creation via boolean subtraction
- Adjustable base thickness + wall margins
- Floor thickness control for structural integrity
- STL → binary export for both relief and mold
- G-code for:
- FDM printers (via CuraEngine CLI / fallback slicer)
- Laser engravers (raster scan with grayscale → power modulation)
- Real-time Three.js 3D viewer
- Orbit controls, wireframe mode, auto-rotate
- Heightmap 2D preview
- Mesh diagnostics (vertex count, face count, watertight status, volume)
Each pixel becomes a Z value:
Z(x,y) = depth × grayscale(x,y)
The image is converted to grayscale, normalized to [0, 1], optionally smoothed with a Gaussian filter, then scaled by the target depth.
- Grid-based triangulation over the heightmap
- Vertex displacement using Z values
- Side walls + bottom face sealing
- Result: watertight mesh every time
Z_mold = base_height − Z(x,y)
Boolean subtraction creates a negative cavity suitable for casting — with configurable wall thickness, floor thickness, and margins.
- STL → CuraEngine CLI → G-code
- Built-in fallback slicer if CuraEngine is not available
- Raster scan line by line
- Power modulation based on pixel intensity
- Configurable feed rate, max power, and resolution
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Next.js │ │ Node.js │ │ Python │
│ Frontend │────▶│ API Server │────▶│ Microservice │
│ :3000 │ │ :3001 │ │ :5001 │
│ │ │ │ │ │
│ • Canvas │ │ • REST Routes │ │ • Heightmap │
│ • Three.js │ │ • G-code Gen │ │ • Mesh Gen │
│ • Controls │ │ • File Upload │ │ • Boolean Ops │
│ • Export UI │ │ • Python Bridge │ │ • STL Export │
└─────────────────┘ └─────────────────┘ └─────────────────┘
- Node.js 18+ and npm
- Python 3.10+ with pip
git clone https://github.com/souheyell/Molding.git
cd Molding
./start.shThat's it. The script will:
- ✅ Check all requirements (Node.js, Python, npm, pip)
- ✅ Verify ports 3000, 3001, 5001 are available
- ✅ Create a Python virtual environment (if needed)
- ✅ Install all dependencies (Python + Node)
- ✅ Start all 3 services in the correct order
- ✅ Wait for health checks to confirm everything is running
- ✅ Open your browser automatically
Press Ctrl+C to stop all services cleanly.
💡 Windows users: Run the script in Git Bash or WSL.
Click to expand manual setup steps
git clone https://github.com/souheyell/Molding.git
cd Moldingcd python-service
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txt
python app.py # → http://localhost:5001cd backend
npm install
node server.js # → http://localhost:3001cd frontend
npm install
npm run dev # → http://localhost:3000Open http://localhost:3000 in your browser.
Molding/
├── start.sh # ⚡ One-click launcher
│
├── frontend/ # UI (canvas + preview)
│ └── src/
│ ├── app/
│ │ ├── page.js # Main application page
│ │ ├── layout.js # Root layout + metadata
│ │ └── globals.css # Design system + global styles
│ ├── components/
│ │ ├── Canvas/ # HTML5 drawing canvas
│ │ ├── Controls/ # Parameter sliders & toggles
│ │ ├── ExportPanel/ # STL & G-code download UI
│ │ ├── FileUpload/ # Drag-and-drop upload
│ │ └── Preview3D/ # Three.js 3D viewer
│ └── lib/
│ ├── api.js # Backend API client
│ └── constants.js # Default parameters
│
├── backend/ # API (Node.js)
│ ├── server.js # Entry point
│ ├── routes/
│ │ ├── process.js # Heightmap/mesh/mold endpoints
│ │ ├── export.js # STL download endpoints
│ │ └── gcode.js # G-code generation endpoints
│ └── services/
│ ├── pythonBridge.js # Python microservice HTTP client
│ └── gcodeGenerator.js # Laser & FDM G-code generator
│
├── python-service/ # Geometry engine (Python)
│ ├── app.py # Flask API server
│ ├── requirements.txt # Python dependencies
│ └── services/
│ ├── heightmap.py # Image → normalized grayscale
│ ├── mesh_generator.py # Grid triangulation
│ ├── mold_creator.py # Boolean subtraction
│ └── stl_exporter.py # Binary STL export
│
├── docs/screenshots/ # App screenshots
├── .gitignore
├── LICENSE
└── README.md
- Next.js 16 — React framework with Turbopack
- Three.js + @react-three/fiber — 3D rendering
- @react-three/drei — OrbitControls, Grid, helpers
- HTML5 Canvas API — Drawing input
- Express.js — REST API server
- Multer — File upload middleware
- node-fetch — HTTP client
- Flask — Python web framework
- NumPy — Heightmap computation
- Pillow — Image processing
- trimesh — Mesh generation & boolean operations
- SciPy — Gaussian blur filtering
- CuraEngine (FDM slicing)
- Custom raster → G-code generator (laser)
| Variable | Default | Description |
|---|---|---|
PYTHON_SERVICE_URL |
http://localhost:5001 |
Python microservice URL |
PORT (backend) |
3001 |
Node.js server port |
FRONTEND_URL |
http://localhost:3000 |
CORS origin for frontend |
NEXT_PUBLIC_API_URL |
http://localhost:3001 |
Backend API URL for frontend |
| Parameter | Range | Default | Unit |
|---|---|---|---|
| Resolution | 32 – 512 | 256 | px |
| Relief Depth | 1 – 50 | 10 | mm |
| Width | 10 – 300 | 100 | mm |
| Height | 10 – 300 | 100 | mm |
| Base Thickness | 0.5 – 10 | 2 | mm |
| Wall Thickness | 1 – 20 | 5 | mm |
| Floor Thickness | 1 – 10 | 3 | mm |
| Smoothing | 0 – 5 | 1.0 | σ |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/process |
Full pipeline (heightmap → mesh → mold) |
POST |
/api/process/heightmap |
Generate heightmap only |
POST |
/api/process/mesh |
Generate mesh from heightmap |
POST |
/api/process/mold |
Generate mold from mesh |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/export/stl/relief |
Download relief STL |
POST |
/api/export/stl/mold |
Download mold STL |
POST |
/api/export/heightmap |
Download heightmap image |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/gcode/laser |
Generate laser engraving G-code |
POST |
/api/gcode/fdm |
Generate FDM printing G-code |
This system enforces:
- Minimum feature size
- Mesh integrity (watertight guaranteed)
- Depth limits for printability
- Valid geometry for manufacturing
- Silicone keychain molds
- Embossed surfaces
- Engraved plates
- Custom stamps
- Rapid prototyping
- Diode lasers (5W – 40W+)
- CO₂ lasers
- Ender series
- Prusa
- Bambu Lab
- Multi-material mold support
- Resin printer optimization
- Advanced smoothing algorithms
- GPU acceleration (WebGL compute)
- Multi-part mold generation
Geometry should be generated, not designed.
If a machine can calculate it, you shouldn't have to model it.
This project is:
- Free to use
- Free to modify
- Free to build on
Anyone can take it, improve it, or adapt it to their workflow.
Contributions are welcome:
- Geometry improvements
- Performance optimization
- UI/UX enhancements
- Machine profiles
Feel free to fork, open a PR, or use the Request Feature button in the app to email suggestions directly.
MIT License — do whatever you want with it. See LICENSE for details.
This started as solving something trivial. It turned into building a full geometry pipeline.
If you use it, improve it, or break it — that's exactly the point.




