| 1234567891011121314151617181920212223242526 |
- """Compare Blender's cap triangulation to active GIS outlines without exporting assets."""
- import json
- from pathlib import Path
- from mathutils import Vector
- from mathutils.geometry import tessellate_polygon
- root = Path(__file__).parent / 'city/cad-bim'
- area = lambda ring: 0.5 * sum(p[0] * ring[(i + 1) % len(ring)][1] - ring[(i + 1) % len(ring)][0] * p[1]
- for i, p in enumerate(ring))
- plan = json.loads((root / 'seated-batch-urban8000c.json').read_text(encoding='utf-8'))
- manifest = json.loads((root / 'lod-batch-urban8000c-aligned/manifest.json').read_text(encoding='utf-8'))
- ids = {id for cell in manifest['cells'] for id in cell['buildingIds']}
- for building in plan['buildings']:
- if building['id'] not in ids:
- continue
- ring = building['footprintENU']
- if area(ring) < 0:
- ring = list(reversed(ring))
- ax, ay, _ = building['positionENU']
- points = [Vector((x - ax, y - ay, 0)) for x, y in ring]
- triangles = tessellate_polygon([points])
- actual = sum(abs(area([ring[i] for i in triangle])) for triangle in triangles)
- wanted = area(ring)
- if abs(actual - wanted) > max(0.001, actual * 1e-6):
- print(json.dumps({'id': building['id'], 'actual': actual, 'wanted': wanted,
- 'difference': actual - wanted, 'ring': ring, 'triangles': triangles}), flush=True)
|