floorplan-parser / README.md
rikhoffbauer2's picture
Update README with 3D reconstruction docs and Space link
1aa7462 verified
# ๐Ÿ  Floor Plan Parser + 3D Reconstruction
Parse floor plan images into structured data โ€” walls with thickness, doors, windows, and automatically detected rooms. Then generate interactive 3D models.
**๐ŸŽฎ Try it live:** [rikhoffbauer2/floorplan-3d](https://huggingface.co/spaces/rikhoffbauer2/floorplan-3d)
## Architecture
```
Floor Plan Image (raster or vector)
โ”‚
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ 1. INITIAL PARSE โ”‚ VLM extracts walls/doors/windows
โ”‚ (VLM or vector parser) โ”‚ into structured JSON schema
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ 2. COMPUTE TOPOLOGY โ”‚ Derive rooms from wall faces
โ”‚ (computational geometry) โ”‚ via planar subdivision (Shapely)
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ 3. RENDER OVERLAY โ”‚ Schema โ†’ SVG/PNG โ†’ alpha-composite
โ”‚ (PIL / SVG) โ”‚ on original image for verification
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ 4. VERIFY & CORRECT โ”‚ VLM sees overlay vs original,
โ”‚ (VLM or human) โ”‚ outputs field-level corrections
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ–ผ converged? โ”€โ”€noโ”€โ”€โ†’ back to step 2
yes
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ 5. 3D RECONSTRUCTION โ”‚ Extrude walls, cut openings,
โ”‚ (trimesh + manifold3d) โ”‚ add floors/ceilings โ†’ GLB
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
Interactive 3D model (GLB/glTF)
```
## Modules
| File | Purpose |
|------|---------|
| `floorplan/schema.py` | Pydantic data models โ€” `Wall`, `Opening`, `Room`, `FloorPlan`, `Correction` |
| `floorplan/geometry.py` | Computational geometry โ€” wall polygons, room detection, centerline ops |
| `floorplan/renderer.py` | SVG + PIL rendering for visual verification and overlay |
| `floorplan/parser.py` | VLM-based parsing with iterative correction loop |
| `floorplan/reconstruction.py` | **NEW** โ€” 3D mesh generation, boolean ops, GLB/OBJ export |
## The Schema
```json
{
"walls": [
{
"id": "w1",
"centerline": [{"x": 0, "y": 0}, {"x": 6, "y": 0}],
"thickness": 0.24,
"openings": [
{"id": "win1", "type": "window", "start": 1.5, "length": 1.5}
]
}
],
"rooms": [
{
"id": "r1", "label": "bedroom",
"boundary": [{"wall_id": "w1", "side": "right"}, {"wall_id": "w2", "side": "left"}],
"area": 16.0
}
]
}
```
## Quick Start
### Demo (no API key needed)
```python
from floorplan import *
# Build a floor plan
walls = [
Wall(id="w1", centerline=[Point2D(x=0, y=0), Point2D(x=5, y=0)], thickness=0.24,
openings=[Opening(id="d1", type=OpeningType.DOOR, start=1.0, length=0.9)]),
Wall(id="w2", centerline=[Point2D(x=5, y=0), Point2D(x=5, y=4)], thickness=0.24),
Wall(id="w3", centerline=[Point2D(x=5, y=4), Point2D(x=0, y=4)], thickness=0.24),
Wall(id="w4", centerline=[Point2D(x=0, y=4), Point2D(x=0, y=0)], thickness=0.24),
]
rooms, room_polygons = build_rooms(walls)
fp = FloorPlan(walls=walls, rooms=rooms)
# 2D render
img = render_to_image(fp, room_polygons=room_polygons)
img.save("output.png")
# 3D model
scene = generate_3d_model(fp, room_polygons=room_polygons)
export_glb(scene, "model.glb") # Open in any 3D viewer or Three.js
```
### Parse a real floor plan with VLM
```python
from floorplan import parse_floorplan, generate_3d_model, export_glb
# Parse image โ†’ structured data (uses HF Inference API)
fp, room_polygons, overlays = parse_floorplan(
image="floorplan.png",
api_key="hf_...",
base_url="https://router.huggingface.co/v1",
model="Qwen/Qwen2.5-VL-72B-Instruct",
max_iterations=3,
)
# Generate 3D
scene = generate_3d_model(fp, room_polygons=room_polygons, pixels_per_meter=100)
export_glb(scene, "model.glb")
```
## 3D Output
The 3D reconstruction generates:
- **Walls** โ€” extruded from 2D polygons, all walls boolean-unioned into a single watertight mesh
- **Door openings** โ€” cut through walls via boolean subtraction + door frame meshes
- **Window openings** โ€” cut at sill/head height + glass pane meshes
- **Floor slabs** โ€” per room, with wood material
- **Ceilings** โ€” per room, with white material
- **PBR materials** โ€” walls (warm white), floors (light wood), ceilings (white), glass (translucent blue)
Export formats: **GLB** (web/Three.js), **glTF**, **OBJ**
## Dependencies
**Core:**
- `pydantic` โ€” schema validation
- `shapely` โ€” computational geometry
- `numpy` โ€” array ops
- `pillow` โ€” image rendering
**3D reconstruction:**
- `trimesh[easy]` โ€” mesh generation, boolean ops, GLB export (includes manifold3d)
**VLM parsing (optional):**
- `openai` โ€” for VLM API calls
## License
MIT