#! python3 # read-only: layout of Okseong B9 (H19 C-ties) in the latest model: plane, position, extent, tail direction, overlaps import os, json, math, collections, traceback import Rhino P = r"D:\★Pier 자료\프로그램\Pier_T\검토파일\검토_옥성교P1\옥성교P1_G5_수정2_20261026.3dm" OUT = r"C:\Users\User\AppData\Local\PierApp\jobs\c1_work\c1_okb9_layout.json" res = {} try: doc = Rhino.RhinoDoc.OpenHeadless(P) st = Rhino.DocObjects.ObjectEnumeratorSettings() st.HiddenObjects = True; st.LockedObjects = True; st.NormalObjects = True lay = {l.Index: l.FullPath for l in doc.Layers} fb = [o for o in doc.Objects.GetObjectList(st) if o.Attributes.Name == "P1-FT"][0].Geometry.GetBoundingBox(True) bars = [] for o in doc.Objects.GetObjectList(st): g = o.Geometry if not (isinstance(g, Rhino.Geometry.PolyCurve) and "중심선" in lay.get(o.Attributes.LayerIndex, "")): continue if o.Attributes.GetUserString("mark") != "B9": continue s0, sN = g.SegmentCurve(0), g.SegmentCurve(g.SegmentCount - 1) pts = [g.SegmentCurve(i).PointAtStart for i in range(g.SegmentCount)] + [sN.PointAtEnd] xs = [p.X for p in pts]; ys = [p.Y for p in pts] planeX = (max(xs) - min(xs)) < 1.0 # all points share x -> bar lies in the YZ plane planeY = (max(ys) - min(ys)) < 1.0 if planeX: c, lo, hi = xs[0], min(ys), max(ys) tail_dir = "tails toward %s" % ("+Y" if s0.PointAtEnd.Y > s0.PointAtStart.Y else "-Y") plane = "YZ(x=const)" elif planeY: c, lo, hi = ys[0], min(xs), max(xs) tail_dir = "tails toward %s" % ("+X" if s0.PointAtEnd.X > s0.PointAtStart.X else "-X") plane = "XZ(y=const)" else: plane, c, lo, hi, tail_dir = "other", None, None, None, "" bars.append({"name": o.Attributes.Name, "plane": plane, "c": c, "lo": lo, "hi": hi, "tail": tail_dir, "zmin": g.GetBoundingBox(True).Min.Z - fb.Min.Z, "zmax": g.GetBoundingBox(True).Max.Z - fb.Min.Z}) cnt = collections.Counter((b["plane"]) for b in bars) lines = collections.defaultdict(list) for b in bars: lines[(b["plane"], round(b["c"], 1) if b["c"] is not None else None)].append((round(b["lo"], 1), round(b["hi"], 1), b["tail"])) summary = [] for (pl, c), iv in sorted(lines.items(), key=lambda x: (x[0][0], x[0][1] if x[0][1] is not None else 0)): iv.sort() overlaps = sum(1 for a, b2 in zip(iv, iv[1:]) if b2[0] < a[1]) summary.append({"plane": pl, "const": c, "n": len(iv), "first": iv[:3], "overlapping_neighbours": overlaps}) res = {"n": len(bars), "planes": dict(cnt), "footing_half": [round(fb.Max.X, 1), round(fb.Max.Y, 1)], "lines": summary[:60], "n_lines": len(summary), "tail_dirs": dict(collections.Counter(b["tail"] for b in bars)), "z": [round(min(b["zmin"] for b in bars), 1), round(max(b["zmax"] for b in bars), 1)]} doc.Dispose() except Exception: res["error"] = traceback.format_exc() res["done"] = True json.dump(res, open(OUT, "w", encoding="utf-8"), ensure_ascii=False, indent=1)