101 lines
3.9 KiB
Python
101 lines
3.9 KiB
Python
# -*- 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
|