fix(B06): 원지반 제약 끊음 — 다단 자동 자리 사면 1.0 m · 설계선 끝 수치 판정 · 전면 기울기 칸 아니면 성토 · 「지형에 막힘」 잔재 지움(91-3)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013rJwJMVL4EE31y77TB11AP
This commit is contained in:
2026-10-08 12:12:16 +09:00
co-authored by Claude Opus 5.5
parent 8c04d520f4
commit de93c7b248
14 changed files with 360 additions and 471 deletions
@@ -97,4 +97,34 @@ out.fordHandBedDown = fordFloor((s) => {
hand(s);
shiftGround(s, -2, -2, 2);
});
// ② 91-3 다단 자동 자리 — 관 180 유출 흙막이 + 2단 · 원지반을 옮겨도 단 자리 같음 · 사면 1.0 m
const { computeCulvertLayout } = loadTs(B06("B06_Section_UI_Cross_Culvert_Geom.ts"));
function tiers(dz) {
const s = clone(at(180));
shiftGround(s, dz);
s.culvert = {
type: "pipe",
chainage_m: 180,
pipe_kind: "흄관",
diameter_m: 1.0,
min_cover_m: 0.5,
inlet: { role: "inlet", structure: "기슭막이", revet_form: "돌쌓기(찰)" },
outlet: { role: "outlet", structure: "기슭막이", revet_form: "돌쌓기(찰)" },
};
s.design.inlet_structure = "revet";
const tier = { x: null, d: null, h: 2, m: null };
const layout = computeCulvertLayout(s, s.samples, { extras: [tier, tier] }, "revet");
return {
walls: layout.extraWalls.map((w) => [r3(w.bottomBack.offset), r3(w.bottomBack.elevation)]),
slopes: layout.outletFill.segments.slice(0, 2).map((g) => r3(g.lengthM)),
};
}
out.tiers = [tiers(0), tiers(0.5), tiers(-0.5)];
// ⑤ 91-3 전면 기울기 — 단면유형(원지반 자동판정)과 무관 · 성토/절토 칸만
const { leanOf } = loadTs(B06("B06_Section_UI_Cross_Lean.ts"));
out.lean = ["left_cut", "right_cut", "both_fill", "both_cut"].map((mode) => [
leanOf({ form: "돌쌓기(찰)", height_m: 1.5, section_mode: mode, side: "좌" }),
leanOf({ form: "돌쌓기(찰)", height_m: 1.5, section_mode: mode, side: "좌", face_role: "절토" }),
]);
process.stdout.write(JSON.stringify(out));
+39
View File
@@ -44,3 +44,42 @@ def test_세월교_바닥_손_값은_원지반을_바꿔도_그대로(fit: dict)
def test_세월교_박스_칸은_측벽_높이_줄을_받음() -> None:
dock = (ROOT / "B06_Section/B06_Section_UI_Adjust_Dock.ts").read_text(encoding="utf-8")
assert "sideSlots?.wingOutlet) return WALL_HEIGHT_ROW" in dock
def test_다단_자동_자리는_원지반과_무관_사면_1m(fit: dict) -> None:
base, up, down = fit["tiers"]
assert base["walls"] == up["walls"] == down["walls"]
assert base["slopes"] == [1.0, 1.0]
def test_전면_기울기는_단면유형과_무관_칸만(fit: dict) -> None:
# 단면유형 넷 모두 같은 값 · 비면 성토 표값(1.5 m 찰 = 0.25) · 절토 칸 = 0.2
assert all(pair == [0.25, 0.2] for pair in fit["lean"])
def test_B08_성토절토_판정도_칸_아니면_성토() -> None:
from common_util.common_util_structure_face_role import structure_face_role_of
for mode in ("left_cut", "right_cut", "both_cut", "both_fill"):
for side in ("좌", "우", "자동(성토 쪽)"):
assert structure_face_role_of(mode, {"side": side})[0] == "성토"
assert structure_face_role_of("both_fill", {"face_role": "절토"})[0] == "절토"
def test_설계선_끝은_화면_픽셀이_아니라_수치로() -> None:
line = (ROOT / "B06_Section/B06_Section_UI_Cross_Design_Line.ts").read_text(encoding="utf-8")
assert "OVERLAP_PX" not in line
assert line.count("Math.abs(point.elevation_m - g) <= OVERLAP_M") == 2
def test_지형에_막힘_잔재_없음() -> None:
for name in (
"B06_Section_UI_Cross_Culvert.ts",
"B06_Section_UI_Cross_Revetment.ts",
"B06_Section_UI_Cross_Culvert_Wire.ts",
"B06_Section_UI_Cross_Culvert_Types.ts",
"B06_Section_UI_Cross_Culvert_Extra.ts",
):
source = (ROOT / "B06_Section" / name).read_text(encoding="utf-8")
assert "shiftBlockedM" not in source and "지형에 막힘" not in source, name
assert "noticeExtraLimit" not in source and "noticeShortfall" not in source, name