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>
33 lines
1.4 KiB
Python
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]))
|