#! python3 # reconcile the two protrusion measurements: list the concrete solids and test the same P3-1 bars point by point import sys, os, json, math, collections, traceback sys.path.insert(0, r"C:\Users\User\AppData\Local\PierApp\jobs\c1_work") import Rhino import Rhino.Geometry as rg from c1_core import BASE P = os.path.join(BASE, "Ramp-A교P1", "ramp-A G5_수정5_20261026.3dm") OUT = r"C:\Users\User\AppData\Local\PierApp\jobs\c1_work\c1_protrude_diag.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} conc = [] allsolid = [] bars = [] for o in doc.Objects.GetObjectList(st): g = o.Geometry L = lay.get(o.Attributes.LayerIndex, "") if isinstance(g, rg.Brep): if g.IsSolid and "철근" not in L: bb = g.GetBoundingBox(True) allsolid.append({"layer": L, "name": o.Attributes.Name, "bbox": [round(x) for x in (bb.Min.X, bb.Min.Y, bb.Min.Z, bb.Max.X, bb.Max.Y, bb.Max.Z)], "vol": round(g.GetVolume() / 1e9, 2)}) if "기둥" in L or "코핑" in L or "기초" in L: conc.append((L, g)) if isinstance(g, rg.Curve) and "중심선" in L and o.Attributes.GetUserString("mark") == "P3-1": bars.append(o) res["concrete_solids"] = allsolid bars.sort(key=lambda o: o.Attributes.Name) out = [] for o in bars[:48]: c = o.Geometry n = 60 ts = c.DivideByCount(n, True) flags = [] for t in ts: pt = c.PointAt(t) flags.append(1 if any(b.IsPointInside(pt, 0.01, True) for _, b in conc) else 0) bb = c.GetBoundingBox(True) out.append([o.Attributes.Name, round(bb.Min.X), round(bb.Max.X), round(bb.Min.Z), sum(flags), len(flags)]) res["bars"] = out # radial position of the column surface at the z of the first few bars col = [b for L, b in conc if "기둥" in L] if col: b0 = col[0] info = [] for o in bars[:6]: c = o.Geometry z = c.GetBoundingBox(True).Min.Z + 100 for ang in (0, 90): import math as _m d = rg.Vector3d(_m.cos(_m.radians(ang)), _m.sin(_m.radians(ang)), 0) ln = rg.Line(rg.Point3d(0, 0, z), rg.Point3d(0, 0, z) + d * 4000.0) ok = rg.Intersect.Intersection.CurveBrep(ln.ToNurbsCurve(), b0, 0.01) hits = [] try: cr = ok[1] if isinstance(ok, tuple) else None for pt in (cr or []): hits.append(round(pt.DistanceTo(rg.Point3d(0, 0, z)))) except Exception: pass info.append([o.Attributes.Name, round(z), ang, hits]) res["column_surface_radius_probe"] = info 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)