feat(abut): ② 날개벽 카드를 시안대로 작성 (좌우 같게 · 측별 치수 · 삽도 3개)
- 선택 줄 (타일): 좌우 같게(기본) / 따로 정하기, 편집할 측 (좌 · ① 쪽 / 우 · ⑤ 쪽), 형식 일반형(기본) / 단축형 / 없음 - 측별 치수 입력 (WingDims, 교대 기록 wingDims): 길이 6500, 두께 450, 끝 높이 1500(일반형), 헌치 300. 단축형 길이 기본 = 뒷굽 끝(1.807 m). 좌우 같게이면 양쪽에 함께 적용, 켤 때 좌측 값을 우측에 복사 - 연동: 두께 → 날개벽 3D · 접속슬래브 폭(geometry slabWidthMm) · 슬래브 평면, 헌치 → 연직 헌치 · 저판 상면 헌치 (0이면 없음) - 자동 값: 경사 (A1 = −i), 등단면 · 변화단면 경계(뒷굽 끝), 끝 EL 상단 / 하단 (가정), 단축형 하단 = 확대기초 상면 (뒷굽 밖은 AI02 안내) - 삽도 3개 (src/view/abut-wing-svg.ts): 평면(좌우 날개벽 · 접속슬래브, abutPlanOutline 공유), 측면(수평 단 · 뒷굽 끝), 날개벽–흉벽 모서리 모식도(헌치 · 브라켓 · 슬래브 모따기 · 간격) - "생성되는 날개벽" 줄과 시안 메모. 프로젝트 파일 검사에 wingDims · wingsLinked 추가 - 테스트 7건 추가 · 갱신. 전체 669건 통과, 타입 검사 · 빌드 통과. 브라우저 시각 확인은 미실시 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a025a61209
commit
80e5302192
12 files changed
+610
-53
No files matched your search
@@ -4,6 +4,7 @@
|
||||
*/
|
||||
import type { AbutRecord } from './parse';
|
||||
import type { WingForm } from './geometry';
|
||||
import { WING_DIMS_DEFAULT, wingDimsIssues, type WingDims } from './wings';
|
||||
import { shapeIssues, type AbutShape } from './shape';
|
||||
import { abutBearingRuleIssues, resolveBearingRule, type AbutBearingRule } from './bearing-table';
|
||||
|
||||
@@ -32,11 +33,45 @@ export function applyAbutEdit(rec: AbutRecord, key: AbutEditKey, value: number):
|
||||
return next;
|
||||
}
|
||||
|
||||
/** 좌우 같게 (기본): the form and dims apply to both sides. Off: each side keeps its own. */
|
||||
export function wingsLinked(rec: AbutRecord): boolean {
|
||||
return rec.wingsLinked !== false;
|
||||
}
|
||||
|
||||
export function setWingForm(rec: AbutRecord, side: 'left' | 'right', form: WingForm): AbutRecord {
|
||||
const current = rec.wings ?? { left: 'general' as WingForm, right: 'general' as WingForm };
|
||||
if (wingsLinked(rec)) return { ...rec, wings: { left: form, right: form } };
|
||||
return { ...rec, wings: { ...current, [side]: form } };
|
||||
}
|
||||
|
||||
/** Turns 좌우 같게 on or off. Turning it on copies the left side (form and dims) to the right. */
|
||||
export function setWingsLinked(rec: AbutRecord, linked: boolean): AbutRecord {
|
||||
if (!linked) return { ...rec, wingsLinked: false };
|
||||
const left = rec.wings?.left ?? 'general';
|
||||
const dims = rec.wingDims?.left;
|
||||
return { ...rec, wingsLinked: true, wings: { left, right: left }, wingDims: dims ? { left: { ...dims }, right: { ...dims } } : undefined };
|
||||
}
|
||||
|
||||
/** 날개벽 치수 입력 칸 (② 날개벽 카드, 시안 순서). 단축형에는 끝 높이가 없다. */
|
||||
export const WING_DIM_FIELDS: { key: keyof WingDims; label: string; general: boolean; short: boolean }[] = [
|
||||
{ key: 'lengthMm', label: '길이 (mm)', general: true, short: true },
|
||||
{ key: 'thicknessMm', label: '두께 (mm)', general: true, short: true },
|
||||
{ key: 'endHeightMm', label: '끝 높이 (mm)', general: true, short: false },
|
||||
{ key: 'haunchMm', label: '헌치 (mm, 300 × 300의 한 변)', general: true, short: true },
|
||||
];
|
||||
|
||||
/** Changes one wing dim of a side (both sides when 좌우 같게). Length, thickness and end height must be > 0, the haunch ≥ 0. */
|
||||
export function applyWingDim(rec: AbutRecord, side: 'left' | 'right', key: keyof WingDims, value: number): AbutRecord {
|
||||
if (!Number.isFinite(value)) throw new Error('숫자를 입력하세요.');
|
||||
const probe = { ...WING_DIMS_DEFAULT, [key]: value };
|
||||
const issues = wingDimsIssues(probe);
|
||||
if (issues.length > 0) throw new Error(issues[0]);
|
||||
const sides: ('left' | 'right')[] = wingsLinked(rec) ? ['left', 'right'] : [side];
|
||||
const next = { left: { ...(rec.wingDims?.left ?? {}) }, right: { ...(rec.wingDims?.right ?? {}) } };
|
||||
for (const s of sides) next[s] = { ...next[s], [key]: value };
|
||||
return { ...rec, wingDims: next };
|
||||
}
|
||||
|
||||
/** 받침 값 편집 (2026-11-03): z (패드 상면, m) or 교좌면 override (m, undefined = 자동 — 블럭 높이 규칙을 따른다). */
|
||||
export function applyBearingEdit(rec: AbutRecord, no: number, key: 'z' | 'seatEl', value: number | undefined): AbutRecord {
|
||||
const target = rec.bearings.find((b) => b.no === no);
|
||||
|
||||
Reference in new issue
Block a user