#! python3 # C-1 dry run: plan new centrelines + pipes for the 4 review models, no document edits. import sys, os, json, math, collections, traceback sys.path.insert(0, r"C:\Users\User\AppData\Local\PierApp\jobs\c1_work") import importlib import c1_core importlib.reload(c1_core) import Rhino from c1_core import BASE, plan_curve, make_pipe, required_rc MODELS = { "ungok": os.path.join(BASE, "철근 모델랑 운곡교P1_바이브코딩", "운곡교p1.3dm"), "sanoe": os.path.join(BASE, "검토_산외교P1", "산외교P1 G5.3dm"), "okseong": os.path.join(BASE, "검토_옥성교P1", "옥성교P1_G5.3dm"), "rampa": os.path.join(BASE, "Ramp-A교P1", "ramp-A G5.3dm"), } OUT = r"C:\Users\User\AppData\Local\PierApp\jobs\c1_work\c1_dry.json" res = {} try: for key, path in MODELS.items(): doc = Rhino.RhinoDoc.OpenHeadless(path) tol = doc.ModelAbsoluteTolerance st = Rhino.DocObjects.ObjectEnumeratorSettings() st.HiddenObjects = True st.LockedObjects = True st.NormalObjects = True lay = {l.Index: l.FullPath for l in doc.Layers} breps = {} curves = [] for o in doc.Objects.GetObjectList(st): g = o.Geometry if isinstance(g, Rhino.Geometry.Brep) and "철근" in lay.get(o.Attributes.LayerIndex, ""): breps.setdefault(o.Attributes.Name, []).append(o) elif isinstance(g, Rhino.Geometry.Curve) and "중심선" in lay.get(o.Attributes.LayerIndex, ""): curves.append(o) per = collections.OrderedDict() for o in curves: a = o.Attributes mark = a.GetUserString("mark") dia = a.GetUserString("dia") m = per.setdefault((mark, dia), collections.Counter()) m["bars"] += 1 c = o.Geometry if not isinstance(c, Rhino.Geometry.PolyCurve): m["not_poly"] += 1 continue pc, info = plan_curve(c, dia) if info["status"] == "unchanged": continue m["short_bars"] += 1 m["short_arcs"] += info["short"] if info["status"] != "ok": m["complex"] += 1 continue req, d = required_rc(dia) nb = breps.get(a.Name.replace("-RC-", "-R-"), []) if len(nb) != 1: m["brep_match_" + str(len(nb))] += 1 continue pipes = make_pipe(pc, d, tol) if not pipes or len(pipes) != 1 or not pipes[0].IsSolid: m["pipe_fail"] += 1 continue v_new = Rhino.Geometry.VolumeMassProperties.Compute(pipes[0]).Volume v_exp = math.pi * (d / 2.0) ** 2 * pc.GetLength() if abs(v_new / v_exp - 1.0) > 0.002: m["vol_off"] += 1 dl = pc.GetLength() - c.GetLength() m["ok"] += 1 m["sum_dlen_x1000"] += int(round(dl * 1000)) if abs(dl) > m["max_dlen_x1000"]: m["max_dlen_x1000"] = int(round(abs(dl) * 1000)) if pc.PointAtStart.DistanceTo(c.PointAtStart) > 1e-6 or pc.PointAtEnd.DistanceTo(c.PointAtEnd) > 1e-6: m["end_moved"] += 1 res[key] = {"objects": doc.Objects.Count, "marks": [{"mark": k[0], "dia": k[1], "req": required_rc(k[1])[0], **dict(v)} for k, v in per.items() if v.get("short_bars")]} doc.Dispose() except Exception: res["error"] = traceback.format_exc() json.dump(res, open(OUT, "w", encoding="utf-8"), ensure_ascii=False, indent=1)