File size: 5,518 Bytes
1aa7462 39bf1f4 1aa7462 39bf1f4 1aa7462 39bf1f4 1aa7462 39bf1f4 1aa7462 39bf1f4 1aa7462 39bf1f4 1aa7462 39bf1f4 1aa7462 39bf1f4 1aa7462 39bf1f4 1aa7462 39bf1f4 1aa7462 39bf1f4 1aa7462 39bf1f4 1aa7462 39bf1f4 1aa7462 39bf1f4 1aa7462 39bf1f4 1aa7462 39bf1f4 1aa7462 39bf1f4 1aa7462 39bf1f4 1aa7462 39bf1f4 1aa7462 39bf1f4 1aa7462 39bf1f4 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | # ๐ 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
|