diff --git a/B06_Section/B06_Section_UI_Cross_Culvert_Wire.ts b/B06_Section/B06_Section_UI_Cross_Culvert_Wire.ts index 7f54b88b..35d1b2bb 100644 --- a/B06_Section/B06_Section_UI_Cross_Culvert_Wire.ts +++ b/B06_Section/B06_Section_UI_Cross_Culvert_Wire.ts @@ -7,7 +7,7 @@ import type { CrossSection, SectionSample } from "./B06_Section_Api_Fetch"; import { computeCulvertLayout } from "./B06_Section_UI_Cross_Culvert"; import type { CulvertLayout, InletStructureChoice, RevetKey } from "./B06_Section_UI_Cross_Culvert"; -import type { BasinAdjust } from "./B06_Section_UI_Cross_Culvert_Types"; +import type { BasinAdjust, CulvertDesignTrim } from "./B06_Section_UI_Cross_Culvert_Types"; import { basinSpanOfSpec, materialLabel, @@ -201,10 +201,36 @@ function spanCovers(span: StructureSpan, deltaM: number): boolean { return deltaM < 0 ? -deltaM <= span.beforeM + 1e-9 : deltaM <= span.afterM + 1e-9; } +/** + * 지운 구조물이 남긴 **설계선 트림**을 쪽별로 되돌린다(2026-08-26 사용자 지적 — + * 4·14 측점 성토선 삭제). 구조물은 안 그리는데 트림만 남으면 그 측점 설계선이 + * 노견 밖에서 통째로 끊긴다 — 집수정은 대체 사면선(`minSlope`/`maxSlope`)도 조작량이 + * 0이면 없어서 아무것도 안 남는다. `-/+Infinity` = 트림 없음(기하가 쓰는 초기값). + */ +function keepTrimSides( + trim: CulvertDesignTrim | null, + keepMin: boolean, + keepMax: boolean, +): CulvertDesignTrim | null { + if (!trim || (!keepMin && !keepMax)) return null; + if (keepMin && keepMax) return trim; + return { + minOffset: keepMin ? trim.minOffset : Number.NEGATIVE_INFINITY, + maxOffset: keepMax ? trim.maxOffset : Number.POSITIVE_INFINITY, + ...(keepMin && trim.minElevation != null ? { minElevation: trim.minElevation } : {}), + ...(keepMax && trim.maxElevation != null ? { maxElevation: trim.maxElevation } : {}), + ...(keepMin && trim.minSlope ? { minSlope: trim.minSlope } : {}), + ...(keepMax && trim.maxSlope ? { maxSlope: trim.maxSlope } : {}), + }; +} + /** * 링크 카드에서 **연장이 여기까지 오지 않는 요소**를 지운다(요소별 판정). * 유입·유출 기슭막이는 각자 길이·전/후를 갖고, 집수정은 자기 연장(기본 2m·1/1) * 만큼만 이어진다. 관은 한 측점 전용이라 그리기 단계에서 숨긴다(`hidePipe`). + * + * 도형뿐 아니라 그 구조물이 만든 **설계선 트림·성토부선까지 함께** 지운다 — 도형만 + * 지우면 없는 구조물이 설계선을 끊는다(2026-08-26). */ function trimLinkedLayout(layout: CulvertLayout, link: CulvertLink): CulvertLayout { const spec = layout.culvert; @@ -212,16 +238,29 @@ function trimLinkedLayout(layout: CulvertLayout, link: CulvertLink): CulvertLayo spec[side]?.structure === "집수정" ? basinSpanOfSpec(spec[side]) : revetSpanOfSpec(spec[side]); const inletIn = spanCovers(spanOf("inlet"), link.deltaM); const outletIn = spanCovers(spanOf("outlet"), link.deltaM); + // 집수정은 링크 측점에 서지 않으므로(아래 `basin: null`) 그 트림은 언제나 지운다. + const keepInlet = inletIn && !layout.basin; + // 좌표 규약 +offset = 좌측, outward=+1(좌) = trimMax — 유입이 어느 쪽 트림인지는 + // 관 양 끝 offset 대소로 가른다(관은 노선을 가로지르므로 좌우가 갈린다). + const inletIsMax = layout.pipe.inlet.offset > layout.pipe.outlet.offset; + const empty = { segments: [], addable: false }; return { ...layout, walls: layout.walls.filter((wall) => (wall.role === "inlet" ? inletIn : outletIn)), // 다단(성토부)은 유출 벽에 딸린다. extraWalls: outletIn ? layout.extraWalls : [], + outletFill: outletIn ? layout.outletFill : empty, // 집수정은 **소유 측점 횡단도 하나에만** 선다(2026-08-24 사용자 확정) — 기슭막이와 - // 달리 옆 측점으로 이어지는 구조물이 아니다. 계류측 다단도 집수정에 딸린 것이라 - // 함께 뺀다. 3D에서는 소유 측점 하나가 자기 길이(기본 2m)만큼 스윕한다. + // 달리 옆 측점으로 이어지는 구조물이 아니다. 계류측 다단·성토부선도 집수정에 딸린 + // 것이라 함께 뺀다. 3D에서는 소유 측점 하나가 자기 길이(기본 2m)만큼 스윕한다. basinExtras: [], + basinFill: empty, basin: null, + designTrim: keepTrimSides( + layout.designTrim, + inletIsMax ? outletIn : keepInlet, + inletIsMax ? keepInlet : outletIn, + ), }; }