diff --git a/B06_Section/B06_Section_Engine_Revetment.py b/B06_Section/B06_Section_Engine_Revetment.py index b1147d36..3c0133a5 100644 --- a/B06_Section/B06_Section_Engine_Revetment.py +++ b/B06_Section/B06_Section_Engine_Revetment.py @@ -42,8 +42,15 @@ def load_revetments(project_root: Path) -> list[dict[str, Any]]: "start_m": float(min(start, end)), "end_m": float(max(start, end)), "anchor_m": float(structure.anchor_m()), - "form": options.get("form"), - "height_m": options.get("height_m"), + # 형태·높이는 **배관 유출 키 한 벌**이 정본이다(B05 폼 2026-08-28 + # 이관). 옛 전용 키(form·height_m)는 읽을 때만 폴백으로 본다 — + # 이걸 안 보면 형태가 비어 도형이 늘 메쌓기로 그려졌다(2026-08-30). + "form": options.get("outlet_revet_form") or options.get("form"), + "height_m": ( + options.get("outlet_revet_height_m") + if options.get("outlet_revet_height_m") is not None + else options.get("height_m") + ), "side": options.get("side"), # 다단 — 1이면 단일 벽. 전개 규칙은 화면·3D가 같은 산식으로 푼다. "tiers": options.get("tiers"), diff --git a/B06_Section/B06_Section_UI_Adjust_Dock.ts b/B06_Section/B06_Section_UI_Adjust_Dock.ts index a169a526..e4d0c4fc 100644 --- a/B06_Section/B06_Section_UI_Adjust_Dock.ts +++ b/B06_Section/B06_Section_UI_Adjust_Dock.ts @@ -53,6 +53,15 @@ function slotUsable(target: HTMLElement | undefined): target is HTMLElement { * 나오지 않는다(2026-08-29 사용자 보고: 단 수·옵션이 사라짐). */ const movedRows: Array<{ row: HTMLElement; anchor: Comment }> = []; +/** 그룹 이름표 — 원래 문구를 한 번만 적어 두고, 선택에 따라 괄호 표기를 붙였다 뗀다. */ +function setGroupLabel(group: HTMLElement, suffix: string): void { + const legend = group.querySelector("legend"); + if (!legend) return; + legend.dataset.baseLabel ??= legend.textContent ?? ""; + const base = legend.dataset.baseLabel; + legend.textContent = suffix ? `${base} (${suffix})` : base; +} + /** 옮겨 온 행을 **원래 자리로 되돌리고** 슬롯을 비운다. 그룹 강조도 끈다. */ function clearSideSlots(): void { while (movedRows.length) { @@ -62,9 +71,11 @@ function clearSideSlots(): void { for (const target of [sideSlots?.inlet, sideSlots?.outlet, sideSlots?.extra]) { target?.replaceChildren(); const group = target?.closest("fieldset"); - group?.classList.remove("is-active"); + if (!group) continue; + group.classList.remove("is-active"); + setGroupLabel(group, ""); // 추가 기슭막이 칸은 고른 다단 벽이 있을 때만 서 있는다 — 비면 그룹째 내린다. - if (group && target === sideSlots?.extra) group.hidden = true; + if (target === sideSlots?.extra) group.hidden = true; } } @@ -79,11 +90,9 @@ function relocateSideRows(panelRoot: HTMLElement): void { const target = sideSlots[side]; // 추가 기슭막이 칸은 평소 숨어 있다 — 고른 벽이 다단이면 여기서 세운다. if (side === "extra") { - const group = target.closest("fieldset"); + const group = target.closest("fieldset"); if (!group) return; group.hidden = false; - const legend = group.querySelector("legend"); - if (legend) legend.textContent = panelRoot.dataset.extraTitle || "추가 기슭막이"; } else if (!slotUsable(target)) return; const rows = panelRoot.querySelectorAll(side === "extra" ? EXTRA_ROWS : SIDE_ROWS); rows.forEach((row) => { @@ -95,7 +104,14 @@ function relocateSideRows(panelRoot: HTMLElement): void { target.append(row); }); // 고른 구조물이 어느 쪽인지 그룹 테두리로 알린다(2026-08-29 사용자 지시 3). - target.closest("fieldset")?.classList.add("is-active"); + const group = target.closest("fieldset"); + if (!group) return; + group.classList.add("is-active"); + // 이름표에 지금 만지는 구조물을 적는다 — "유입구 (기슭막이)", "유출구 (기슭막이(독립))". + // 추가 기슭막이 칸은 이름 자체가 그 단이라 괄호 안에 단 번호가 온다(2026-08-30 지시 1). + setGroupLabel(group, panelRoot.dataset.panelTitle ?? ""); + // 다단은 칸이 새로 서는 것이라 화면 밖일 수 있다 — 그 자리로 스크롤한다(지시 2). + if (side === "extra") group.scrollIntoView({ block: "nearest", behavior: "smooth" }); } function ensureDock(): void { diff --git a/B06_Section/B06_Section_UI_Cross_Revetment.ts b/B06_Section/B06_Section_UI_Cross_Revetment.ts index e860207c..0985c12d 100644 --- a/B06_Section/B06_Section_UI_Cross_Revetment.ts +++ b/B06_Section/B06_Section_UI_Cross_Revetment.ts @@ -241,6 +241,9 @@ export function computeRevetmentLayout( groundAt, limitOffset: limit, adjusts: Array.from({ length: requestedTiers - 1 }, () => ({ ...ZERO_ADJUST })), + // 단들도 1단과 같은 형태로 선다 — 안 넘기면 형태가 비어 늘 메쌓기로 + // 그려졌다(2026-08-30 사용자: 형태별 모양이 누락되는 경우). + ownerForm: spec.form, equalize: false, }) : { walls: [], segments: [], appliedAdjusts: [], addable: false }; diff --git a/B06_Section/B06_Section_UI_Cross_Structure_Panel.ts b/B06_Section/B06_Section_UI_Cross_Structure_Panel.ts index dd2445b3..51a13fdb 100644 --- a/B06_Section/B06_Section_UI_Cross_Structure_Panel.ts +++ b/B06_Section/B06_Section_UI_Cross_Structure_Panel.ts @@ -582,7 +582,10 @@ export function buildStructurePanel( : tierChannel === "basin" ? "inlet" : ""; - root.dataset.extraTitle = isExtra ? (title.textContent ?? "") : ""; + // 옮겨 갈 그룹의 이름표에 쓴다 — 유입구·유출구는 괄호 안에, 추가 기슭막이는 + // 이름 자체로(2026-08-30 사용자 지시 1). 어느 구조물을 만지는지 폼에서 읽힌다. + // 다단은 칸 이름이 이미 "추가 기슭막이"라 단 번호만 붙인다 — "추가 기슭막이 (2단)". + root.dataset.panelTitle = isExtra ? `${extraIndex + 1}단` : (title.textContent ?? ""); const tiers = tierChannel === "outlet" ? deps.extraState()