Files
quartier/pipeline/axo/04_instances_monde.py
T
Jules NényandClaude Opus 5.5 731531dbe2 Test axonométrique du 27/09 : pipeline de fabrication et prototype
pipeline/axo : extraction du Rhino, recalage sur la planche (1:640), maisons,
arbres (positions réelles des blocs, couleurs de la planche), scène en mètres,
sols depuis le PDF Illustrator vectoriel (calques pilotés), bulles de la page 15,
planche de l'eau nettoyée. prototypes/axo-test : la page de test et son assembleur.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 16:46:14 +02:00

33 lines
1.4 KiB
Python

import sys, json, rhino3dm, math
m = rhino3dm.File3dm.Read(sys.argv[1])
L = {i: l.Name for i, l in enumerate(m.Layers)}
centre = {}
for d in m.InstanceDefinitions:
xs, ys = [], []
for oid in d.GetObjectIds():
ob = m.Objects.FindId(oid)
if ob is None: continue
try:
b = ob.Geometry.GetBoundingBox(); xs += [b.Min.X, b.Max.X]; ys += [b.Min.Y, b.Max.Y]
except Exception: pass
if xs: centre[str(d.Id)] = ((min(xs) + max(xs)) / 2, (min(ys) + max(ys)) / 2, (max(xs) - min(xs)), (max(ys) - min(ys)))
out = []
for o in m.Objects:
g = o.Geometry
if not isinstance(g, rhino3dm.InstanceReference): continue
ln = L.get(o.Attributes.LayerIndex, "")
c = centre.get(str(g.ParentIdefId))
if not c: continue
x = g.Xform
wx = x.M00 * c[0] + x.M01 * c[1] + x.M03
wy = x.M10 * c[0] + x.M11 * c[1] + x.M13
sc = math.hypot(x.M00, x.M10)
out.append({"l": ln, "x": round(wx / 100, 3), "y": round(wy / 100, 3), "r": round(max(c[2], c[3]) * sc / 200, 3)})
json.dump(out, open(sys.argv[2], "w"))
import collections
print(len(out), collections.Counter(o["l"] for o in out).most_common(8))
for l in ["Ishigami's fruit tree's 1", "ishigami foret", "PERSOS"]:
a = [o for o in out if o["l"] == l]
xs = [o["x"] for o in a]; ys = [o["y"] for o in a]; rs = sorted(o["r"] for o in a)
print(l, "x %.0f..%.0f y %.0f..%.0f rayon médian %.2f m" % (min(xs), max(xs), min(ys), max(ys), rs[len(rs)//2]))