Scaffold Vite + TypeScript + Three.js (scène vide : sol + boîte, marqueur de build), store et encodage de l'état dans l'URL (5 tests), lint de frontières entre modules, pipeline d'extraction Rhino (graine du 26/09) et première géométrie v0, deploy.sh statique (releases + lien symbolique + smoke), AGENTS.md, RUNBOOK, licences MIT + CC BY-SA 4.0. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
35 lines
1.8 KiB
Python
35 lines
1.8 KiB
Python
import sys, json, math, rhino3dm
|
|
from shapely.geometry import Polygon
|
|
p = sys.argv[1]; m = rhino3dm.File3dm.Read(p)
|
|
L = {i: l.Name for i, l in enumerate(m.Layers)}
|
|
def pts(c):
|
|
n = 64 if not isinstance(c,(rhino3dm.PolylineCurve,)) else c.PointCount
|
|
if isinstance(c, rhino3dm.PolylineCurve):
|
|
return [(c.Point(i).X/100, c.Point(i).Y/100) for i in range(c.PointCount)]
|
|
pl = c.ToPolyline(0.0,0.0,0.1,5.0,0.0,0.0,0.0,0.0,True) if hasattr(c,'ToPolyline') else None
|
|
if pl is None:
|
|
d=c.Domain; return [(c.PointAt(d.T0+(d.T1-d.T0)*i/n).X/100, c.PointAt(d.T0+(d.T1-d.T0)*i/n).Y/100) for i in range(n+1)]
|
|
return [(pl[i].X/100, pl[i].Y/100) for i in range(pl.Count)]
|
|
out = {"parcelles":[], "noues":[], "sentiers":[], "topo":[], "plante":[], "maisons_candidates":[], "autres_fermes":[]}
|
|
for o in m.Objects:
|
|
g=o.Geometry; ln=L.get(o.Attributes.LayerIndex,"")
|
|
if not isinstance(g, rhino3dm.Curve): continue
|
|
try: P=pts(g)
|
|
except Exception: continue
|
|
if len(P)<2: continue
|
|
if ln=="7_TOPO": out["topo"].append(P); continue
|
|
if not g.IsClosed: continue
|
|
try: poly=Polygon(P); a=poly.area
|
|
except Exception: continue
|
|
if ln=="PARCELLES": out["parcelles"].append(P)
|
|
elif ln=="B_EAU noues": out["noues"].append(P)
|
|
elif ln=="C_SENTIER": out["sentiers"].append(P)
|
|
elif ln=="planté": out["plante"].append(P)
|
|
elif ln in ("0","caché","3_ TRAITS VUS","4_ TRAITS VUS FIINS","traits cachés","Défaut","ombres portées") and 40<=a<=400:
|
|
# maison candidate : quadrilatère-ish compact
|
|
mrr=poly.minimum_rotated_rectangle;
|
|
if mrr.area>0 and a/mrr.area>0.7: out["maisons_candidates"].append({"layer":ln,"area":round(a,1),"pts":P})
|
|
json.dump(out, open(sys.argv[2],"w"))
|
|
print({k:len(v) for k,v in out.items()})
|
|
import collections; print(collections.Counter(c["layer"] for c in out["maisons_candidates"]))
|