- Code\rebar_pipeline, review_pipeline, pier-program을 정션에서 실제 폴더로 전환 - Code\rhino_mcp 및 CLAUDE_rhino배경.md 추가, .mcp.json은 PYTHONPATH로 새 위치 사용 - pier-program 내부 .git 제거(이력은 backup\pier-program_20261028.bundle에 보관) - worktree 가이드 반영(CLAUDE.local.md, HANDOFF.md) - D:\Rhino-MCP 경로 참조를 새 위치로 치환 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
123 lines
7.4 KiB
Python
123 lines
7.4 KiB
Python
"""One-off (2026-10-19): write the values read from the Ungok P3 drawing (see prompt log Task_도면도형직접판독시험) into data/운곡교P3/params.json.
|
|
params.json only; expected.json is left alone (independent evidence, P7). Backs up params/expected/confirm first. Prints what changed and what was NOT read.
|
|
usage: python tools/apply_p3_read_values.py [--dry]"""
|
|
import copy
|
|
import json
|
|
import shutil
|
|
import sys
|
|
import time
|
|
from pathlib import Path
|
|
|
|
APP = Path(__file__).resolve().parents[1]
|
|
sys.path.insert(0, str(APP / "web"))
|
|
sys.path.insert(0, str(APP))
|
|
import store # noqa: E402
|
|
from tools import infer_footing_rebar as inf # noqa: E402
|
|
|
|
p3 = store.Pier("운곡교P3")
|
|
P = p3.load("params")
|
|
Q = copy.deepcopy(P)
|
|
P1 = json.loads((APP / "data" / "운곡교P1" / "params.json").read_text(encoding="utf-8"))
|
|
SH = -1909 # coping heights P1 -> P3 (D1 EL labels)
|
|
changes = []
|
|
|
|
|
|
def put(obj, path, val, why):
|
|
keys = path.split(".")
|
|
x = obj
|
|
for k in keys[:-1]:
|
|
x = x[int(k)] if isinstance(x, list) else x[k]
|
|
last = int(keys[-1]) if isinstance(x, list) else keys[-1]
|
|
old = x[last]
|
|
if old != val:
|
|
x[last] = val
|
|
changes.append((path, old if not isinstance(old, (list, dict)) else f"{type(old).__name__}[{len(old)}]",
|
|
val if not isinstance(val, (list, dict)) else f"{type(val).__name__}[{len(val)}]", why))
|
|
|
|
|
|
# ---- footing, piles, column (D1 dimension texts, cross-checked by section-view line lengths and the pile layout sums)
|
|
put(Q, "footing.size_y", 8800.0, "D1 8.800, 800+4@1800+800")
|
|
put(Q, "footing.z_bottom", 25175, "D1 EL. 25.175")
|
|
put(Q, "lean_concrete.size_y", 9000.0, "footing + 200 (section lines 9000)")
|
|
put(Q, "lean_concrete.z_bottom", 25075, "footing bottom - 100")
|
|
put(Q, "lean_concrete.z_top", 25175, "= footing bottom")
|
|
put(Q, "piles.pitch_y", 1800.0, "D1 4@1.800=7.200")
|
|
put(Q, "piles.length", 25300, "D1 L=25.3M")
|
|
put(Q, "column.height", 11127, "D1 11.127 = 38502 - (25175 + 2200)")
|
|
# ---- coping (geometry of D1 front view, tools/extract_coping_outline.py)
|
|
steps = [(-6000, -3764, 41502), (-3764, -1263, 41576), (-1263, 1237, 41650), (1237, 3738, 41724), (3738, 6000, 41798)]
|
|
for i, (a, b, z) in enumerate(steps):
|
|
put(Q, f"coping.top_steps.{i}.x0", float(a), "D1 coping top outline")
|
|
put(Q, f"coping.top_steps.{i}.x1", float(b), "D1 coping top outline")
|
|
put(Q, f"coping.top_steps.{i}.z", z, "D1 coping top outline + EL. 41.798")
|
|
put(Q, "coping.z_bottom_flat", 38502, "D1 coping soffit flat")
|
|
# ---- coping rebar (D1 front view rebar lines)
|
|
for t, z in (("1", 41402), ("2", 41302), ("3", 41202)):
|
|
put(Q, f"coping_rebar.top.tiers.{t}.z", z, "D1 rebar lines")
|
|
put(Q, "coping_rebar.bottom.z_flat", 38602, "soffit flat + 100 (as P1)")
|
|
put(Q, "coping_rebar.loops.levels", [v + SH for v in P1["coping_rebar"]["loops"]["levels"]], "P1 levels shifted by the coping drop; lines at 40102..40852 seen")
|
|
put(Q, "coping_rebar.c15.z", 41698, "D1 rebar line")
|
|
put(Q, "coping_rebar.c15.x0", 3838, "D1 rebar line; schedule C15 a 2.062 = 5900 - 3838")
|
|
put(Q, "coping_rebar.c16.z", 41550, "D1 rebar line")
|
|
put(Q, "coping_rebar.c16.x0", -1163, "schedule C16 a 5.251 = 4088 + 1163")
|
|
put(Q, "coping_rebar.c16.x1", 4088, "D1 rebar line")
|
|
# ---- bearings (D1 plan view LWPOLYLINEs, datum = coping plan centre as in P1)
|
|
bs = Q["bearing_seats"]
|
|
pitch = 2500.5
|
|
put(Q, "bearing_seats.pitch_x", pitch, "plan pedestals 2487.4 -> 4987.9; text 3@2.501=7.502")
|
|
put(Q, "bearing_seats.pedestal_girder5.front_half", [[4369.3, -1280.7], [4408.7, -31.3], [5608.1, -69.1], [5568.7, -1318.5]], "D1 plan outline")
|
|
put(Q, "bearing_seats.pedestal_girder5.rear_half", [[4408.7, -31.3], [4448.0, 1218.1], [5647.4, 1180.3], [5608.1, -69.1]], "D1 plan outline")
|
|
put(Q, "bearing_seats.pedestal_girder5.rotation_deg", 1.81, "outline angle 178.19")
|
|
put(Q, "bearing_seats.pad_rows.front.centre_rel_girder5", [4987.9, -699.9], "D1 plan pad polyline")
|
|
put(Q, "bearing_seats.pad_rows.front.rotation_deg", 1.81, "pad polyline angle")
|
|
put(Q, "bearing_seats.pad_rows.rear.centre_rel_girder5", [5014.1, 599.6], "D1 plan pad polyline")
|
|
put(Q, "bearing_seats.pad_rows.rear.rotation_deg", 0.5, "pad polyline angle")
|
|
for i, b in enumerate(bs["bearings"]):
|
|
g = b["girder_line"]
|
|
front = b["row"] == "front"
|
|
x = (4987.9 if front else 5014.1) - (5 - g) * pitch
|
|
put(Q, f"bearing_seats.bearings.{i}.centre", [round(x, 1), -699.9 if front else 599.6], "g4/g5 drawn, g1-g3 by pitch")
|
|
put(Q, f"bearing_seats.bearings.{i}.rotation_deg", 1.81 if front else 0.5, "pad angle")
|
|
# ---- footing rebar (rules of tools/infer_footing_rebar.py + D1 rebar points)
|
|
r = inf.infer(10350, 8800)
|
|
put(Q, "footing_rebar.a_x", r["a_x"], "footing - 200")
|
|
put(Q, "footing_rebar.a_y", r["a_y"], "footing - 200")
|
|
for k in ("bottom_Y1", "bottom_X2", "bottom_Y3", "bottom_X4", "top_Y", "top_X"):
|
|
put(Q, f"footing_rebar.layers.{k}.pos", [float(v) for v in r[k]], "layer rule; counts equal the schedule")
|
|
mid_x = {"550.0": [-2750, -1750, -750, 750, 1750, 2750], "950.0": [-3750, -3250, -2250, -1250, -250, 250, 1250, 2250, 3250, 3750]}
|
|
mid_x["1350.0"], mid_x["1750.0"] = mid_x["550.0"], mid_x["950.0"]
|
|
mid_y = {"550.0": [-3875, -2875, -1875, 1875, 2875, 3875], "950.0": [-4375, -3375, -2375, -1375, -375, 375, 1375, 2375, 3375, 4375]}
|
|
mid_y["1350.0"], mid_y["1750.0"] = mid_y["550.0"], mid_y["950.0"]
|
|
put(Q, "footing_rebar.layers.mid_X.levels", {k: [float(v) for v in vs] for k, vs in mid_x.items()}, "D1 section dots (B11), 32 bars")
|
|
put(Q, "footing_rebar.layers.mid_Y.levels", {k: [float(v) for v in vs] for k, vs in mid_y.items()}, "D1 front dots (B12), 32 bars (schedule 38, as P1: drawn 28 / schedule 34)")
|
|
put(Q, "footing_rebar.b9.grid_x", [-4625 + 250 * i for i in range(38)], "38 x 33 grid, checkerboard = 627 = schedule")
|
|
put(Q, "footing_rebar.b9.grid_y", [-4000 + 250 * i for i in range(33)], "38 x 33 grid")
|
|
put(Q, "footing_rebar.b9.count", 627, "schedule 627 = 1351.185 / 2.155")
|
|
put(Q, "footing_rebar.b10.size_y", 8644.0, "schedule B10 b 8.644")
|
|
# ---- column rebar (schedule + D1 hoop dots)
|
|
put(Q, "column_rebar.main_bars.p1.hook_leg_z", 25475, "footing bottom + 300 (as P1)")
|
|
put(Q, "column_rebar.main_bars.p1.straight_from", 25815, "+ bend R340")
|
|
put(Q, "column_rebar.main_bars.p1.straight_len", 15337, "schedule P1 A 15.337")
|
|
put(Q, "column_rebar.main_bars.p2.z0", 25475, "as above")
|
|
put(Q, "column_rebar.main_bars.p2.length", 15677, "schedule P2 15.677")
|
|
levels = [26355 + 120 * i for i in range(31)]
|
|
levels += [levels[-1] + 300 * (i + 1) for i in range(33)]
|
|
put(Q, "column_rebar.hoops.levels", levels, "first level 26355 seen in D1 dots; 31 @120 + 33 @300 (schedule 9+22+33)")
|
|
put(Q, "column_rebar.hoops.marks", ["P4"] * 9 + ["P5"] * 22 + ["P3"] * 33, "schedule counts")
|
|
put(Q, "column_rebar.hoops.radius", 902, "schedule P4/P5 R 902 (2*pi*902 = 5667)")
|
|
put(Q, "column_rebar.ties.levels", [26355 + 1800 * i for i in range(8)], "ASSUMED start; chain 7@1.800 = 8 levels (schedule P6 32 = 8 x 4)")
|
|
|
|
print(f"{len(changes)} changes")
|
|
for c in changes:
|
|
print(f" {c[0]:58s} {str(c[1])[:22]:>22} -> {str(c[2])[:28]:<28} | {c[3]}")
|
|
print("NOT read / not changed: coping_rebar c14 points, stirrups, bottom curve, top_right, x_c9..x_c11; schedule tables; column ties start/end (assumed); main-bar bottom z (assumed)")
|
|
if "--dry" in sys.argv:
|
|
sys.exit(0)
|
|
bk = p3.dir / "backup" / f"before_read_values_{time.strftime('%Y%m%d_%H%M%S')}"
|
|
bk.mkdir(parents=True)
|
|
for f in ("params.json", "expected.json", "confirm.json"):
|
|
if (p3.dir / f).exists():
|
|
shutil.copy2(p3.dir / f, bk / f)
|
|
p3.save("params", Q)
|
|
print("saved; backup:", bk)
|