feat(rebar): 기둥 배근 입력 8개 (피복·띠철근 K3/K5/K4·K6·커플러·Δz·n_div), CL01·CL02 검사
- core/rebar/column-settings.ts: 입력 정의, 기본값(기둥철근 (1).md), 범위(제안), 검사 (CL01 범위, CL02 n_div 홀수) - 주철근 하단 갈고리는 고정 (입력 없음) - 기둥 탭 패널: 적용 버튼으로 반영, 계산 결과(K2 내측 r, 주철근·커플러 수량) 표시 - P1·P2 등분 수, P3·P5·P4·P6 간격, 커플러 간격·상승을 철근표 간격·비고와 근거(기본값/입력)에 연동 - 3D 주철근 개수도 n_div 입력을 사용 (COLUMN_P1 하드코딩 제거) Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
496e0ea4e5
commit
f619b9ea20
9 files changed
+215
-20
No files matched your search
+67
@@ -28,6 +28,8 @@ import { copingEndStation, copingFrontSvg, copingSectionSvg } from './view/copin
|
||||
import { BLOCK_REBAR_RANGES } from './core/rebar/block-check';
|
||||
import { DEFAULT_BLOCK_REBAR, type BlockRebarSettings } from './core/rebar/bearing-block';
|
||||
import { COPING_REBAR_RANGES, copingSettingsIssues, type CopingRebarSettings, DEFAULT_COPING_REBAR, DEFAULT_TOP_SPLICE, type TopSpliceSettings } from './core/rebar/coping-settings';
|
||||
import { COLUMN_REBAR_RANGES, type ColumnRebarSettings, columnSettingsIssues, DEFAULT_COLUMN_REBAR } from './core/rebar/column-settings';
|
||||
import { columnInputFor, columnRebar } from './core/rebar/column';
|
||||
import { groundSectionSvg } from './view/ground-svg';
|
||||
import { parseBearingElevationTable, parseSolplateTable, readDxfTexts } from './core/dxf-table';
|
||||
import { columnDiameterIssues } from './core/column-check';
|
||||
@@ -1183,6 +1185,70 @@ function renderCopingSettings(box: HTMLDivElement, pier: Pier): void {
|
||||
box.appendChild(wrap);
|
||||
}
|
||||
|
||||
/** 기둥 배근 입력 (승인 2026-10-26, 시안 ③ 기둥 삽도). The 주철근 하단 갈고리 is fixed. The 띠철근 간격 is three inputs (K3 · K5 · K4). */
|
||||
const COLUMN_REBAR_FIELDS: { key: keyof ColumnRebarSettings; label: string }[] = [
|
||||
{ key: 'c', label: 'K1 중심 피복 c (mm)' },
|
||||
{ key: 'ctcP3', label: '띠철근 간격 K3 (mm)' },
|
||||
{ key: 'ctcP5', label: '띠철근 간격 K5 (mm)' },
|
||||
{ key: 'ctcP4', label: '띠철근 간격 K4 (mm)' },
|
||||
{ key: 'ctcP6', label: '크로스타이 K6 간격 (mm)' },
|
||||
{ key: 'ctcCoupler', label: '커플러 간격 ctcOfcoupler (mm)' },
|
||||
{ key: 'dzCp2', label: 'P2 커플러 상승 Δz (mm)' },
|
||||
{ key: 'nDiv', label: '주철근 원주 등분 수 n_div' },
|
||||
];
|
||||
|
||||
/** 적용: the values go to the draft and the model is rebuilt only when every check passes (CL01·CL02). */
|
||||
function applyColumnRebar(name: string, next: ColumnRebarSettings): void {
|
||||
const p = state.piers.find((q) => q.input.name === name);
|
||||
if (!p) return;
|
||||
p.draft = { ...p.draft, columnRebar: next };
|
||||
regenerateOne(name);
|
||||
}
|
||||
|
||||
function renderColumnSettings(box: HTMLDivElement, pier: Pier): void {
|
||||
if (!pier.model) return;
|
||||
const wrap = el('div', undefined, 'bearing-ref');
|
||||
const current: ColumnRebarSettings = { ...DEFAULT_COLUMN_REBAR, ...pier.draft.columnRebar };
|
||||
wrap.appendChild(el('p', '기둥 배근 입력 (기본값 = 기둥철근 (1).md · 적용을 눌러야 반영)', 'lbl'));
|
||||
const grid = el('div', undefined, 'edit-fields');
|
||||
const inputs = new Map<keyof ColumnRebarSettings, HTMLInputElement>();
|
||||
for (const f of COLUMN_REBAR_FIELDS) {
|
||||
const row = el('div', undefined, 'edit-row');
|
||||
const label = el('label', f.label);
|
||||
const input = el('input');
|
||||
input.type = 'number';
|
||||
input.step = 'any';
|
||||
input.value = String(current[f.key]);
|
||||
input.id = `column-${f.key}`;
|
||||
label.htmlFor = input.id;
|
||||
inputs.set(f.key, input);
|
||||
const [lo, hi] = COLUMN_REBAR_RANGES[f.key];
|
||||
const changed = current[f.key] !== DEFAULT_COLUMN_REBAR[f.key] ? ' · 기본과 다름' : '';
|
||||
row.append(label, input, el('span', `범위 ${lo}–${hi} · 기본 ${DEFAULT_COLUMN_REBAR[f.key]}${changed}`, 'muted small'));
|
||||
grid.appendChild(row);
|
||||
}
|
||||
wrap.appendChild(grid);
|
||||
// Read-only results of the current model (계산 값).
|
||||
const col = columnRebar(columnInputFor(pier.model));
|
||||
wrap.appendChild(el('p', `K2 내측 r ${col.r2} mm · P1 ${col.mainP1}본 · P2 ${col.mainP2}본 · 주철근 커플러 ${col.couplers}개`, 'muted small'));
|
||||
const msg = el('p', undefined, 'muted small');
|
||||
const apply = el('button', '적용', 'btn small');
|
||||
apply.type = 'button';
|
||||
apply.addEventListener('click', () => {
|
||||
const next = { ...current };
|
||||
for (const f of COLUMN_REBAR_FIELDS) next[f.key] = Number(inputs.get(f.key)?.value);
|
||||
const issues = columnSettingsIssues(next);
|
||||
if (issues.length > 0) {
|
||||
msg.textContent = issues.map((i) => i.message).join(' · ');
|
||||
setError('기둥 배근 입력을 확인하세요. 값은 반영되지 않았습니다.');
|
||||
return;
|
||||
}
|
||||
applyColumnRebar(pier.input.name, next);
|
||||
});
|
||||
wrap.append(msg, apply);
|
||||
box.appendChild(wrap);
|
||||
}
|
||||
|
||||
function renderCopingDrawings(box: HTMLDivElement, pier: Pier): void {
|
||||
if (!pier.model || !rebar3d) return;
|
||||
const L = pier.model.copingL;
|
||||
@@ -1258,6 +1324,7 @@ function renderRebar(): void {
|
||||
if (state.rebarMember === 'bearing') renderBlockRebarSettings(box, pier);
|
||||
if (state.rebarMember === 'coping' && rebar3d) renderCopingDrawings(box, pier);
|
||||
if (state.rebarMember === 'coping') renderCopingSettings(box, pier);
|
||||
if (state.rebarMember === 'column') renderColumnSettings(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');
|
||||
|
||||
Reference in new issue
Block a user