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"]))