feat(abut): 교대 형상·입력 패널과 교각 받침·솔플레이트 개편

- 교대 형상(src/core/abut, 3D 장면, 목록·카메라·맞춤)과 교대 입력 패널 추가
- 교각 받침 기준 카드 제거, 솔플레이트 규칙을 교각별 입력으로 변경
- 받침 ELEVATION·솔플레이트 TABLE을 모델값으로 연결
- 교대 입력값 카드: 형식 행에 시점·종점 표시, 제목을 "A1 입력값 [입력]"으로 변경
- 테스트 614건 통과, 타입 검사 통과

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
ypshimandClaude Haiku 5.5 committed 2026-11-03 14:51:34 +09:00
1 parent b1b2ad1ddb
commit 1d31d2f3a9
44 files changed
+2571 -120

No files matched your search

+14
View File
@@ -38,6 +38,20 @@ export function validateInput(input: PierInput, issues: Issue[]): boolean {
/** Geometry-level checks (spec §10 W01–W05, W07, I01) on a built model. */
export function validatePier(input: PierInput, model: PierModel, issues: Issue[]): void {
// W10 (2026-11-03): the input 교좌면 EL should match the 두부보 상면 slope within 5 mm; the input wins.
for (const b of model.blocks) {
const seat = input.bearings.find((r) => r.no === b.no)?.seatEl;
if (seat === undefined) continue;
const diffMm = (seat - b.seatCalc) * 1000;
if (Math.abs(diffMm) > 5) {
issues.push({
code: 'W10',
level: 'W',
pier: input.name,
message: `${b.row} 받침 ${b.no}번 교좌면 EL ${seat.toFixed(3)}은(는) 두부보 상면 계산값 ${b.seatCalc.toFixed(3)}과 ${diffMm.toFixed(1)} mm 차이가 납니다 (허용 5 mm). 입력값을 씁니다.`,
});
}
}
const ip2Gap = Math.hypot(model.ip2Input.e - model.ip2Calc.e, model.ip2Input.n - model.ip2Calc.n);
if (ip2Gap > 0.001) {
issues.push({