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