fix(B05): 기슭막이 상단 성토면을 되메움 리본 배열에 담는다
배수관 세트(기슭막이) 구간에서 노견 → 벽 이음선 상단 성토 사면이 3D에서 통째로
비어 있었다. 포켓(FILL_CUT_APPLY)은 노견까지 파는데, 되메움 배열(fillRuns,
4a5a98fe)에는 벽 아래 다단 성토선·집수정 성토선만 담겨 그 위가 안 메워졌다.
culvertSilhouettes가 designTrim 사면선을 push(실루엣)만 하고 addRun(리본)은 하지
않은 게 원인 — 세월교·BOX암거는 각각 fillSegments·fillLine으로 담고 있어 무관하다.
새 면을 만들지 않는다. 실루엣이 이미 쓰던 designTrim.min/maxSlope 점 배열을 리본
배열에도 등록할 뿐이다.
- Station_Structure: pushTopSlope() 추가 — push + addRun을 함께 하되 측당 한 번만.
벽 루프와 집수정 분기가 같은 designTrim 사면선을 각각 담으므로 표시가 없으면
리본이 두 장 겹친다. 호출 3곳(벽 루프, 집수정 slope, 집수정 2점 폴백).
- Corridor: BUILD_VERSION 79 -> 80.
실측(공용 브라우저 A/B, git stash로 코드만 교체):
- 패치 리본 6 -> 10장. 늘어난 4장 전부 기슭막이 세트(측점 84.3·275.71).
- 275.71 좌측: 기존 z 531.11~535.93 바로 위에 536.85~539.92가 새로 앉았다.
사이 0.92m는 벽 전면 — 구조물 솔리드 몫이라 원래 비는 자리.
- 84.3은 수정 전 양측 0장 — 포켓만 파고 되메움이 통째로 없었다.
- 날개형 구조물(149.73·200.92) 리본 수·z 범위 소수점까지 불변 = 무회귀.
- tsc --noEmit 0.
화면 검증은 사용자가 직접 수행(2026-08-27 사용자 지시).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -157,7 +157,12 @@ function fnv1a(text: string): string {
|
||||
// 지우고 걸친 셀은 안쪽 조각만 남긴다(`patchClip`). 행 단위 바깥선 트림은 폐기 —
|
||||
// 비스듬한 사다리꼴 경계를 행 끝 하나로는 못 맞춰 74셀이 삐져나왔다(실측).
|
||||
// 지우는 면과 채우는 면이 같은 경계를 공유한다(2026-08-27 사용자).
|
||||
const BUILD_VERSION = 79;
|
||||
// 80 = 배수관 세트(기슭막이) **노견 → 벽 이음선 상단 성토 사면**을 되메움 리본 배열
|
||||
// (`fillRuns`)에도 담는다 — 78/79의 포켓은 노견까지 파는데 79까지의 배열에는
|
||||
// 벽 아래 다단·집수정 성토선만 있어 **기슭막이 상단부가 통째로 비었다**
|
||||
// (2026-08-27 사용자). 새 면이 아니라 실루엣이 이미 쓰던 `designTrim` 사면선
|
||||
// 그대로다. 벽 루프·집수정 분기가 같은 선을 담으므로 측당 한 번만 등록한다.
|
||||
const BUILD_VERSION = 80;
|
||||
|
||||
/** 종횡단 정본에서 코리도에 영향을 주는 입력만 요약해 해시 — 갱신 감지 기준. */
|
||||
export function corridorHash(detail: SectionDetailResponse, routePoints: RoutePoint[]): string {
|
||||
|
||||
@@ -258,11 +258,31 @@ export function culvertSilhouettes(section: CrossSection): StructureSilhouette[]
|
||||
};
|
||||
const trimSlopeOf = (side: "left" | "right") =>
|
||||
side === "left" ? layout.designTrim?.maxSlope : layout.designTrim?.minSlope;
|
||||
/**
|
||||
* 노견 → 구조물 상단 성토 사면선을 이미 담은 측. 벽 루프와 집수정 분기가 **같은**
|
||||
* `designTrim` 사면선을 각각 담으므로 표시가 없으면 리본이 두 장 겹친다.
|
||||
*/
|
||||
const topSlopeSides = new Set<"left" | "right">();
|
||||
/**
|
||||
* 노견 → 구조물 상단 성토 사면 — 실루엣과 **되메움 리본에 함께** 담는다
|
||||
* (2026-08-27 사용자: "기슭막이 상단부 성토면이 비어 있다"). `fillRuns` 도입
|
||||
* (`4a5a98fe`) 때 이 줄만 `addRun`에서 빠져 포켓이 그 자리만 안 메워졌다.
|
||||
* 벽 전면과 달리 구조물 솔리드가 덮지 않는 자리라 리본이 있어야 한다.
|
||||
*/
|
||||
const pushTopSlope = (
|
||||
side: "left" | "right",
|
||||
points: ReadonlyArray<{ offset: number; elevation: number }>,
|
||||
): void => {
|
||||
push(side, points);
|
||||
if (topSlopeSides.has(side)) return;
|
||||
topSlopeSides.add(side);
|
||||
addRun(side, points);
|
||||
};
|
||||
|
||||
for (const wall of layout.walls) {
|
||||
const side: "left" | "right" = wall.outward > 0 ? "left" : "right";
|
||||
const slope = trimSlopeOf(side);
|
||||
if (slope) push(side, slope.points);
|
||||
if (slope) pushTopSlope(side, slope.points);
|
||||
// 구조물 전면 실루엣 — 이음선 상단에서 전면 발끝까지 내려온다.
|
||||
push(side, [wall.topJoint, wall.bottomFront]);
|
||||
spans[side] = wallSpanOf(section, wall.role === "inlet" ? "inlet" : "outlet");
|
||||
@@ -292,10 +312,10 @@ export function culvertSilhouettes(section: CrossSection): StructureSilhouette[]
|
||||
const trimElevation =
|
||||
inletSide === "left" ? layout.designTrim?.maxElevation : layout.designTrim?.minElevation;
|
||||
if (slope) {
|
||||
push(inletSide, slope.points);
|
||||
pushTopSlope(inletSide, slope.points);
|
||||
} else if (trimOffset != null && trimElevation != null && Number.isFinite(trimOffset)) {
|
||||
const edge = inletSide === "left" ? edges.left : edges.right;
|
||||
push(inletSide, [
|
||||
pushTopSlope(inletSide, [
|
||||
{ offset: edge.offset_m, elevation: edge.elevation_m },
|
||||
{ offset: trimOffset, elevation: trimElevation },
|
||||
]);
|
||||
|
||||
Reference in New Issue
Block a user