Merge pull request 'feature/0.12.0' (#121) from feature/0.12.0 into main

Reviewed-on: #121
This commit is contained in:
clawdie 2026-06-23 14:21:34 +02:00
commit 3adf4f2af8
2 changed files with 335 additions and 0 deletions

View 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.

View 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 |