feature/0.12.0 #121
2 changed files with 335 additions and 0 deletions
68
docs/DOME-GEOMETRY-CAPABILITY.md
Normal file
68
docs/DOME-GEOMETRY-CAPABILITY.md
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
# Blender vs geodesic-dome-mcp — Capability Comparison
|
||||||
|
|
||||||
|
2026-06-23 | OSA (mother node) | FreeBSD 15.0
|
||||||
|
|
||||||
|
## The problem
|
||||||
|
|
||||||
|
Generate geodesic dome wireframes for architectural visualization and
|
||||||
|
bill-of-materials calculation. The obvious answer was Blender — it has
|
||||||
|
`bpy.ops.mesh.primitive_ico_sphere_add()` built in.
|
||||||
|
|
||||||
|
## Before: Blender
|
||||||
|
|
||||||
|
| Metric | Value |
|
||||||
|
|---|---|
|
||||||
|
| Packages installed | 53 |
|
||||||
|
| Download size | 323 MiB |
|
||||||
|
| Installed size | 1 GiB |
|
||||||
|
| Key dependencies | llvm19, ffmpeg, openimageio, opencolorio, openvdb, pulseaudio |
|
||||||
|
| Headless mode | `blender --background` (still pulls X11 deps) |
|
||||||
|
| Dome generation time | ~14s (Eevee render, 2000×2000) |
|
||||||
|
|
||||||
|
## After: geodesic-dome-mcp
|
||||||
|
|
||||||
|
| Metric | Value |
|
||||||
|
|---|---|
|
||||||
|
| File size | 6 KB (294 lines of Python) |
|
||||||
|
| Dependencies | numpy, Pillow (already installed on all nodes) |
|
||||||
|
| Dome generation time | <1s (wireframe), sub-second (BOM only) |
|
||||||
|
| Headless | Always — no X11, no GPU, no display server |
|
||||||
|
| Outputs | Wireframe PNG + structural BOM (JSON) |
|
||||||
|
|
||||||
|
## Capability impact
|
||||||
|
|
||||||
|
| Capability | Before (Blender) | After (geodesic-dome-mcp) |
|
||||||
|
|---|---|---|
|
||||||
|
| Can run on 32GB USB ISO? | ❌ (1 GiB, exceeds headroom) | ✅ (6 KB, negligible) |
|
||||||
|
| Can run on 12GB RAM VPS? | ❌ (would fit disk but overkill) | ✅ (already running) |
|
||||||
|
| Can run on bare-metal? | ✅ (if installed) | ✅ (always) |
|
||||||
|
| Structural BOM? | ❌ (needs separate script) | ✅ (built-in) |
|
||||||
|
| Half-sphere mode? | Manual mesh cut | ✅ (`half=true`) |
|
||||||
|
| Connector analysis? | ❌ | ✅ (3/4/5/6-way counts) |
|
||||||
|
| Strut length table? | ❌ | ✅ (grouped by size) |
|
||||||
|
| Material cost estimates? | ❌ | ✅ (glass/polycarbonate/insulated) |
|
||||||
|
|
||||||
|
## Registering capabilities
|
||||||
|
|
||||||
|
This comparison feeds into the mother node's PostgreSQL `usb_nodes` table.
|
||||||
|
When a node registers its hardware profile, the capability derivation trigger
|
||||||
|
marks nodes that can run `geodesic-dome-mcp` (all of them — numpy + Pillow
|
||||||
|
are universal). Nodes that have Blender installed get an additional
|
||||||
|
`has_blender: true` capability for 3D rendering workloads.
|
||||||
|
|
||||||
|
## OSA as example (registered 2026-06-23)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"hostname": "osa.smilepowered.org",
|
||||||
|
"ram_gb": 12,
|
||||||
|
"cpu_cores": 6,
|
||||||
|
"capabilities": {
|
||||||
|
"has_gpu": false,
|
||||||
|
"cpu_only": true,
|
||||||
|
"geodesic_dome_mcp": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
12GB RAM, no GPU, but `geodesic_dome_mcp` runs fine. No Blender needed.
|
||||||
267
docs/GIS-INTEGRATION-PLAN.md
Normal file
267
docs/GIS-INTEGRATION-PLAN.md
Normal file
|
|
@ -0,0 +1,267 @@
|
||||||
|
# GIS Integration — Step-by-Step Implementation Plan
|
||||||
|
|
||||||
|
2026-06-23 | Specification phase | No code yet
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Six standalone MCP tools, each one layer of the stack. Each tool is
|
||||||
|
independently testable, accepts JSON-RPC on stdin, returns JSON on stdout.
|
||||||
|
All tools run on the mother node (OSA) and are registered in
|
||||||
|
`/usr/local/etc/colibri/external-mcp.json`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 1: `gurs-address-lookup` — Address → Coordinates + Parcel ID
|
||||||
|
|
||||||
|
### Input
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"address": "Na vrtu 5",
|
||||||
|
"postal_code": "1000",
|
||||||
|
"municipality": "Ljubljana"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Implementation
|
||||||
|
1. WFS GetFeature to GURS Register naslovov
|
||||||
|
- Filter: `ULICA='Na vrtu' AND HISNA_STEVILKA='5' AND POSTNA_STEVILKA='1000'`
|
||||||
|
- EPSG 3794 → reproject to EPSG 4326
|
||||||
|
2. Parse: coordinates, parcel ID, land use code
|
||||||
|
3. Multiple results: return all, let caller pick
|
||||||
|
4. No results: partial match, suggest alternatives
|
||||||
|
|
||||||
|
### Output
|
||||||
|
Lat/lon + parcel ID + cadastral municipality + land use code.
|
||||||
|
|
||||||
|
### Diagram
|
||||||
|
```
|
||||||
|
User "Na vrtu 5, 1000 LJ"
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌──────────────────────────┐
|
||||||
|
│ GURS Register naslovov │
|
||||||
|
│ WFS GetFeature │
|
||||||
|
│ │
|
||||||
|
│ → 46.0514, 14.5060 │
|
||||||
|
│ → parcel 1724/3 │
|
||||||
|
│ → stavbno zemljišče │
|
||||||
|
└──────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 2: `gurs-parcel-boundary` — Parcel ID → Boundary + Metadata
|
||||||
|
|
||||||
|
### Implementation
|
||||||
|
1. WFS GetFeature to GURS Kataster nepremičnin (collection: `parcele`)
|
||||||
|
2. Compute: area, centroid, inscribed circle, setback compliance
|
||||||
|
3. Query GJI for road/utility access
|
||||||
|
4. Check OPSI orthophoto availability
|
||||||
|
|
||||||
|
### Output
|
||||||
|
Boundary GeoJSON + area + inscribed circle + infrastructure distances + setbacks.
|
||||||
|
|
||||||
|
### Diagram
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────┐
|
||||||
|
│ ┌───┐ │
|
||||||
|
│ │old│ existing building │
|
||||||
|
│ └───┘ │
|
||||||
|
│ · centroid │
|
||||||
|
│ ○ inscribed circle r=14.5m │
|
||||||
|
│ │
|
||||||
|
│ 850m², stavbno zemljišče │
|
||||||
|
│ road: 8m, power: 15m │
|
||||||
|
│ setback compliant for 5m dome │
|
||||||
|
└─────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 3: `dome-placement` — Optimal Dome Position
|
||||||
|
|
||||||
|
### Implementation
|
||||||
|
1. Inscribed circle search (binary search from centroid)
|
||||||
|
2. Orientation: entrance faces south, ramp fits within parcel
|
||||||
|
3. Ground slope from GURS DMR (optional)
|
||||||
|
4. Collision check against buildings/utilities
|
||||||
|
5. Sun path: winter solstice shadow analysis
|
||||||
|
|
||||||
|
### Output
|
||||||
|
Center coordinates + orientation + fit quality rating + conflicts + sun/shadow.
|
||||||
|
|
||||||
|
### Diagram
|
||||||
|
```
|
||||||
|
N
|
||||||
|
▲
|
||||||
|
┌──────────────────────────┐
|
||||||
|
│ · · · parcel · · · · · │
|
||||||
|
│ · ┌───┐ · │
|
||||||
|
│ · │old│ ╭──────╮ · │
|
||||||
|
│ · │bld│ │ DOME │ · │
|
||||||
|
│ · └───┘ │ r=5m │ · │
|
||||||
|
│ · │ ▸ │ · │
|
||||||
|
│ · ╰──────╯ · │
|
||||||
|
│ · entrance · │
|
||||||
|
│ · SOUTH · │
|
||||||
|
└──────────────────────────┘
|
||||||
|
setback 4m ✓, no conflicts ✓
|
||||||
|
winter shadow: 8.2m → NW (away from neighbor)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 4: `geodesic-dome-mcp` — Site-Context BOM
|
||||||
|
|
||||||
|
Already implemented: wireframes, BOM, strut constraint, construction layers.
|
||||||
|
New: site context from Steps 2-3.
|
||||||
|
|
||||||
|
### New output
|
||||||
|
- Foundation type based on frost depth + slope
|
||||||
|
- Access path length + gravel estimate
|
||||||
|
- Rebar updated with foundation starter bars
|
||||||
|
- Local Eurocode constants applied
|
||||||
|
|
||||||
|
### BOM Diagram
|
||||||
|
```
|
||||||
|
Item │ Qty │ Cost
|
||||||
|
──────────────────┼──────┼──────
|
||||||
|
FI12 rebar 6m │ 62 │ €372
|
||||||
|
Concrete C25/30 │ 3.1m³│ €310
|
||||||
|
Gravel 0-32mm │ 2.4t │ €48
|
||||||
|
Glass 4mm temper │196m² │€4910
|
||||||
|
5-way connectors │ 14 │ TBD
|
||||||
|
6-way connectors │ 44 │ TBD
|
||||||
|
──────────────────┼──────┼──────
|
||||||
|
Foundation depth: 0.9m (frost 0.8m)
|
||||||
|
Snow load: 1.5 kN/m² (zone A2)
|
||||||
|
Wind: 25 m/s (zone 2)
|
||||||
|
Seismic: 0.175g PGA
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 5: `dome-site-render` — Composite Visualization
|
||||||
|
|
||||||
|
### Three options
|
||||||
|
|
||||||
|
| Option | Cost | Quality | Effort |
|
||||||
|
|---|---|---|---|
|
||||||
|
| A: OPSI orthophoto overlay | Free | Good (2D site plan) | ~4h |
|
||||||
|
| B: Google 3D Tiles | Paid | Excellent (3D photoreal) | ~8h |
|
||||||
|
| C: Gemini AI-enhanced | ~$0.04 | Good (4K composite) | ~1h |
|
||||||
|
|
||||||
|
### Option C (quickest path)
|
||||||
|
1. Pass orthophoto + dome wireframe as Gemini reference images
|
||||||
|
2. Prompt: "Photorealistic vegetation matching Slovenian landscape..."
|
||||||
|
3. Output: 4K composite PNG
|
||||||
|
|
||||||
|
### Diagram
|
||||||
|
```
|
||||||
|
┌────────────────────────────────────┐
|
||||||
|
│ 3D Perspective — Dome on Site │
|
||||||
|
│ │
|
||||||
|
│ ╱▔▔▔╲ │
|
||||||
|
│ ╱ DOME ╲ │
|
||||||
|
│ ╱ r=5m ╲ │
|
||||||
|
│ ╱ ╱▔▔▔▔▔▔▔╲ ╲ │
|
||||||
|
│ ╱ ╱ wireframe ╲ ╲ │
|
||||||
|
│ ╱ ╱ subdivision ╲ ╲ │
|
||||||
|
│ ╱▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔╲ │
|
||||||
|
│ ▕ ░░░░░░░░░░░░░░░░░░ ▏ │
|
||||||
|
│ ▕ ░░ actual terrain ░ ▏ │
|
||||||
|
│ ───────────────────────── │
|
||||||
|
│ │
|
||||||
|
│ Background: OPSI orthophoto │
|
||||||
|
│ Overlay: geodesic-dome-mcp │
|
||||||
|
│ Enhance: Gemini AI │
|
||||||
|
└────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 6: `mother-blender-render` — Photorealistic 3D via Mother
|
||||||
|
|
||||||
|
Heavy nodes (USB) request renders from mother. Same MCP pattern as `build-colibri.sh`.
|
||||||
|
|
||||||
|
### Architecture
|
||||||
|
```
|
||||||
|
USB (light node) Mother (OSA, Blender 5.0)
|
||||||
|
│ │
|
||||||
|
│ MCP: blender_render({...}) │
|
||||||
|
├─────────────────────────────►│
|
||||||
|
│ ├─ blender --background --python dome_render.py
|
||||||
|
│ │ Cycles/EEVEE, 4K, materials, vegetation
|
||||||
|
│◄─────────────────────────────┤
|
||||||
|
│ image_path + metadata │
|
||||||
|
│ │
|
||||||
|
│ scp binary from mother │
|
||||||
|
└──────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### Capabilities
|
||||||
|
- Cycles path-traced rendering (photorealistic)
|
||||||
|
- EEVEE real-time rendering (fast previews)
|
||||||
|
- PBR materials (glass, steel, concrete, wood)
|
||||||
|
- Terrain + foundation extrusion
|
||||||
|
- Vegetation particle scattering
|
||||||
|
- Sun position + shadow study (any date/time)
|
||||||
|
- 360° turntable animation
|
||||||
|
- DXF/STL export (CNC-ready)
|
||||||
|
- 4K+ native resolution
|
||||||
|
|
||||||
|
### Render times (OSA, 6-core CPU, no GPU)
|
||||||
|
- Wireframe: ~5s (EEVEE)
|
||||||
|
- Materials + lighting: ~5min (Cycles 128)
|
||||||
|
- Full scene + vegetation: ~15-30min (Cycles 256, 4K)
|
||||||
|
|
||||||
|
### Blender render pipeline diagram
|
||||||
|
```
|
||||||
|
┌──────────────────────────────────────────┐
|
||||||
|
│ Mother Blender Render Pipeline │
|
||||||
|
│ │
|
||||||
|
│ Scene JSON ──► dome_render.py ──► PNG │
|
||||||
|
│ │ │
|
||||||
|
│ ▼ │
|
||||||
|
│ ┌──────────────┐ │
|
||||||
|
│ │ • icosphere │ │
|
||||||
|
│ │ • wireframe │ │
|
||||||
|
│ │ • materials │ │
|
||||||
|
│ │ • lighting │ │
|
||||||
|
│ │ • camera rig │ │
|
||||||
|
│ │ • terrain │ │
|
||||||
|
│ │ • vegetation │ │
|
||||||
|
│ └──────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ Queue: /var/db/geodesic/render-queue/ │
|
||||||
|
│ Cache: /var/db/geodesic/renders/ │
|
||||||
|
│ TTL: 7 days │
|
||||||
|
└──────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Implementation Priority
|
||||||
|
|
||||||
|
| Step | Effort | Priority |
|
||||||
|
|---|---|---|
|
||||||
|
| Step 1: address lookup | ~2h | 1 — unlocks everything |
|
||||||
|
| Step 2: parcel boundary | ~3h | 2 |
|
||||||
|
| Step 3: dome placement | ~4h | 3 |
|
||||||
|
| Step 4: site BOM | ~2h | 4 |
|
||||||
|
| Step 5: AI render | ~1h | 5 |
|
||||||
|
| Step 5: orthophoto | ~4h | 6 |
|
||||||
|
| Step 6: Blender render | ~6h | 7 |
|
||||||
|
| Step 5: Google 3D | ~8h | 8 |
|
||||||
|
|
||||||
|
Total: ~30h for complete pipeline.
|
||||||
|
|
||||||
|
## Slovenian building code (Eurocode)
|
||||||
|
|
||||||
|
| Parameter | Central Slovenia |
|
||||||
|
|---|---|
|
||||||
|
| Frost depth | 0.8m |
|
||||||
|
| Snow load | 1.5 kN/m² (≤500m) |
|
||||||
|
| Wind speed | 25 m/s |
|
||||||
|
| Seismic PGA | 0.175g |
|
||||||
|
| Setback | 4.0m |
|
||||||
Loading…
Add table
Reference in a new issue