feat(rebar): block rebar settings card and C–C section on the ③ bearing tab

- Six inputs with their ranges and P1 defaults; a change regenerates the pier.
- The 적용 블럭 line shows the blocks (분리 n개 or 일체 n쌍, 전체).
- view/block-rebar-svg.ts: the section C–C along the 교축 with the S2 dots, the
  S1 lines and legs, and the dimensions (block widths, the S2 layout).
- 받침블럭 철근 설정 is tracked for changes (defaults vs the current draft).

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
ypshimandClaude Haiku 5.5 committed 2026-10-26 14:12:36 +09:00
1 parent a6f362df56
commit 38bb26eda5
4 files changed
+130 -1

No files matched your search

+55
View File
@@ -22,6 +22,9 @@ import { bearingEdgeDistances, integratedCheck, PAIR_ECCENTRICITY_LIMIT_MM, pair
import { bearingPlanSvg, type BearingPlanOverlay, PAIR_CHIP_LABELS } from './view/bearing-plan-svg';
import { bearingSectionSvg, type BearingDrawingRef } from './view/bearing-section-svg';
import { solplateDetailSvg, type SolplateDrawingRef } from './view/solplate-svg';
import { blockRebarSectionSvg } from './view/block-rebar-svg';
import { BLOCK_REBAR_RANGES } from './core/rebar/block-check';
import { DEFAULT_BLOCK_REBAR, type BlockRebarSettings } from './core/rebar/bearing-block';
import { groundSectionSvg } from './view/ground-svg';
import { parseBearingElevationTable, parseSolplateTable, readDxfTexts } from './core/dxf-table';
import { columnDiameterIssues } from './core/column-check';
@@ -987,6 +990,56 @@ for (const b of document.querySelectorAll<HTMLButtonElement>('#rebar-color butto
});
}
/** 받침블럭 배근 설정 (승인 2026-10-26, 시안 ③): the six inputs (ranges shown), the 적용 블럭, and the C–C section. */
const BLOCK_REBAR_FIELDS: { key: keyof BlockRebarSettings; label: string }[] = [
{ key: 'coverTop', label: '상면 피복 (철근 중심, mm)' },
{ key: 'coverSide', label: '측면 피복 (mm)' },
{ key: 'firstGap', label: '첫 철근 최소 여유 (mm)' },
{ key: 'spacingS1', label: '간격 S1 (mm)' },
{ key: 'spacingS2', label: '간격 S2 (mm)' },
{ key: 'legLength', label: '다리 길이 (mm)' },
];
function setBlockRebar(name: string, key: keyof BlockRebarSettings, value: number): void {
const p = state.piers.find((q) => q.input.name === name);
if (!p) return;
if (!Number.isFinite(value)) {
setError('받침블럭 철근 값은 숫자로 입력하세요. 값을 되돌렸습니다.');
renderAll();
return;
}
p.draft = { ...p.draft, blockRebar: { ...p.draft.blockRebar, [key]: value } };
regenerateOne(name);
}
function renderBlockRebarSettings(box: HTMLDivElement, pier: Pier): void {
if (!pier.model) return;
const wrap = el('div', undefined, 'bearing-ref');
const current: BlockRebarSettings = { ...DEFAULT_BLOCK_REBAR, ...pier.draft.blockRebar };
wrap.appendChild(el('p', '받침블럭 배근 설정 (기본값 = P1 · 범위는 칸 옆에 표시)', 'lbl'));
const grid = el('div', undefined, 'edit-fields');
for (const f of BLOCK_REBAR_FIELDS) {
const row = el('div', undefined, 'edit-row');
const label = el('label', f.label);
const input = el('input');
input.type = 'number';
input.step = '1';
input.value = String(current[f.key]);
input.addEventListener('change', () => setBlockRebar(pier.input.name, f.key, Number(input.value)));
const [lo, hi] = BLOCK_REBAR_RANGES[f.key];
row.append(label, input, el('span', `범위 ${lo}–${hi} · 기본 ${DEFAULT_BLOCK_REBAR[f.key]}`, 'muted small'));
grid.appendChild(row);
}
wrap.appendChild(grid);
const n = pier.model.integratedBlocks.length;
wrap.appendChild(el('p', `적용 블럭: ${n > 0 ? `일체 ${n}쌍` : `분리 ${pier.model.blocks.length}개`} (전체)`, 'muted small'));
const fig = el('figure', undefined, 'ground-fig');
fig.innerHTML = blockRebarSectionSvg(pier.model);
fig.appendChild(el('figcaption', '단면 C–C · 교축 방향 · S2 점(상면), S1 선과 다리(⊓) · 치수 mm', 'muted small'));
wrap.appendChild(fig);
box.appendChild(wrap);
}
function renderRebar(): void {
const pier = activePier();
// 교각 목록 with the 배근 status (시안 ③). The checks are the same as in ① and ②.
@@ -1020,6 +1073,7 @@ function renderRebar(): void {
}
const { rows, warnings } = rebarSummary(pier.model, state.material, state.fckByMember);
$('rebar-note').textContent = `${pier.input.name} · 형상 기준 계산 · 값은 기본값 기준 문서 규칙`;
if (state.rebarMember === 'bearing') renderBlockRebarSettings(box, pier);
const shown = rows.filter((r) => r.member === state.rebarMember);
box.appendChild(rebarSelectBar(shown.map((r) => r.name)));
const table = el('table', undefined, 'grid-table rebar-table');
@@ -1632,6 +1686,7 @@ function valueText(key: EditableKey, v: unknown): string {
return rows.length ? rows.map((r) => `${r.name} ${r.bottomEl}`).join(' / ') : '없음';
}
if (typeof v === 'boolean') return v ? '예' : '아니오';
if (typeof v === 'object') return JSON.stringify(v);
return String(v);
}