# -*- coding: utf-8 -*- # Rhino(IronPython, execute_code)에서 실행. 운곡교 기초 뚜껑 ㄷ철근(B5, B11)의 다리 길이를 이음장 J로 바꾼다. # 중심선(P1-RC-*)을 다시 만들고 같은 반지름의 파이프(P1-R-*)로 교체한다. 속성·이름·레이어는 그대로 둔다. # 주의: execute_code는 모듈 변수가 함수에서 보이지 않으므로 함수 하나에 모두 넣고, 중첩 def·컴프리헨션을 쓰지 않는다. # 호출: res = run({"B5": 1050, "B11": 580}, True) # True=시험(문서 변경 없음), False=적용 def run(J_BY_MARK, DRY): import math import Rhino import Rhino.Geometry as rg d = Rhino.RhinoDoc.ActiveDoc tol = d.ModelAbsoluteTolerance atol = d.ModelAngleToleranceRadians out = [] curves = {} breps = {} for o in d.Objects: n = o.Name or "" if n.startswith("P1-RC-B5-") or n.startswith("P1-RC-B11-"): curves[n] = o elif n.startswith("P1-R-B5-") or n.startswith("P1-R-B11-"): breps[n] = o done = 0 for name in sorted(curves.keys()): cobj = curves[name] mark = name.split("-")[2] if mark not in J_BY_MARK: continue jlen = J_BY_MARK[mark] bobj = breps.get(name.replace("P1-RC-", "P1-R-", 1)) if bobj is None: out.append("no brep " + name) continue crv = cobj.Geometry oldlen = crv.GetLength() vol = rg.VolumeMassProperties.Compute(bobj.Geometry).Volume rr = math.sqrt(vol / (math.pi * oldlen)) segs = crv.DuplicateSegments() lines = [] arcs = [] for s in segs: if isinstance(s, rg.LineCurve): lines.append(s) else: arcs.append(s) if len(lines) != 3 or len(arcs) != 2: out.append("FAIL segs %s %d/%d" % (name, len(lines), len(arcs))) continue ok, arc = arcs[0].TryGetArc() r = arc.Radius leg1 = lines[0] mid = lines[1] leg2 = lines[2] ok1, ta, tb = rg.Intersect.Intersection.LineLine(leg1.Line, mid.Line) ok2, tc, te = rg.Intersect.Intersection.LineLine(mid.Line, leg2.Line) p1 = mid.Line.PointAt(tb) p2 = mid.Line.PointAt(tc) if leg1.PointAtStart.DistanceTo(p1) > leg1.PointAtEnd.DistanceTo(p1): s1 = leg1.PointAtStart else: s1 = leg1.PointAtEnd if leg2.PointAtStart.DistanceTo(p2) > leg2.PointAtEnd.DistanceTo(p2): s2 = leg2.PointAtStart else: s2 = leg2.PointAtEnd u1 = s1 - p1 u1.Unitize() u2 = s2 - p2 u2.Unitize() old1 = s1.DistanceTo(p1) old2 = s2.DistanceTo(p2) q1 = p1 + u1 * jlen q2 = p2 + u2 * jlen if crv.PointAtStart.DistanceTo(q1) <= crv.PointAtStart.DistanceTo(q2): pts = [q1, p1, p2, q2] else: pts = [q2, p2, p1, q1] pl = rg.PolylineCurve(pts) nc = rg.Curve.CreateFilletCornersCurve(pl, r, tol, atol) if nc is None: out.append("FILLET FAIL " + name) continue pipes = rg.Brep.CreatePipe(nc, rr, False, rg.PipeCapMode.Flat, True, tol, atol) if not pipes or len(pipes) == 0: out.append("PIPE FAIL " + name) continue if DRY: out.append(str((name, round(oldlen, 1), round(nc.GetLength(), 1), round(rr, 2), round(r, 1), round(old1, 1), round(old2, 1)))) return out d.Objects.Replace(cobj.Id, nc) d.Objects.Replace(bobj.Id, pipes[0]) o2 = d.Objects.FindId(cobj.Id) a = o2.Attributes a.SetUserString("design_length", "%.3f" % (2.0 * 0 + pl.GetLength())) a.SetUserString("leg_resize", "J=%d (50%% lap, fck27 fy500) 2026-10-28" % jlen) o2.CommitChanges() done += 1 out.append("replaced %d" % done) return out