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>
44 lines
2.1 KiB
Python
44 lines
2.1 KiB
Python
# Extrait toute la géométrie utile du plan Rhino TRANSFO en mètres (JSON), une fois pour toutes.
|
|
import sys, json, rhino3dm, math
|
|
m = rhino3dm.File3dm.Read(sys.argv[1])
|
|
L = {i: l.Name for i, l in enumerate(m.Layers)}
|
|
def pts(c, n=48):
|
|
if isinstance(c, rhino3dm.PolylineCurve):
|
|
return [(c.Point(i).X/100, c.Point(i).Y/100) for i in range(c.PointCount)]
|
|
if isinstance(c, rhino3dm.LineCurve):
|
|
return [(c.PointAtStart.X/100, c.PointAtStart.Y/100), (c.PointAtEnd.X/100, c.PointAtEnd.Y/100)]
|
|
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)]
|
|
courbes = []
|
|
instances = []
|
|
defs = {str(d.Id): d.Name for d in m.InstanceDefinitions}
|
|
for o in m.Objects:
|
|
g = o.Geometry; ln = L.get(o.Attributes.LayerIndex, "")
|
|
if isinstance(g, rhino3dm.InstanceReference):
|
|
x = g.Xform
|
|
px, py = x.M03/100, x.M13/100
|
|
sx = math.hypot(x.M00, x.M10);
|
|
instances.append({"l": ln, "d": defs.get(str(g.ParentIdefId), "?"), "x": round(px, 3), "y": round(py, 3), "s": round(sx, 4)})
|
|
continue
|
|
if not isinstance(g, rhino3dm.Curve): continue
|
|
try: P = pts(g)
|
|
except Exception: continue
|
|
if len(P) < 2: continue
|
|
courbes.append({"l": ln, "f": bool(g.IsClosed), "p": [[round(a, 3), round(b, 3)] for a, b in P]})
|
|
# boîte englobante de chaque définition de bloc (pour le rayon des arbres)
|
|
bb = {}
|
|
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: bb[d.Name] = [round((max(xs)-min(xs))/100, 3), round((max(ys)-min(ys))/100, 3)]
|
|
json.dump({"courbes": courbes, "instances": instances, "defs_bbox": bb}, open(sys.argv[2], "w"))
|
|
import collections
|
|
print("courbes", len(courbes), "instances", len(instances))
|
|
print(collections.Counter(i["l"] for i in instances).most_common(12))
|
|
print("defs bbox (échantillon)", list(bb.items())[:8])
|