feat(view): bearing 공통 규칙 inputs (mortar h2, bearing h3, solplate T, margin) and recalculated E, L, W, T1, T2

On the bearing card, four inputs drive E = h1 + h2 + h3 + h4, L = A + margin, W = B + margin and T1/T2 = T ± L·|S|/2. The
defaults are the drawing values, so every row gives back the drawing values; changed rows are marked. The values are screen
state for now and do not change the model or the project file (Q16 stays open).

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
ypshimandClaude Haiku 5.5 committed 2026-10-23 14:12:36 +09:00
1 parent 64795e0a19
commit 553c696638
4 files changed
+97 -1

No files matched your search

+51 -1
View File
@@ -16,7 +16,10 @@ import { buildRebar3D, type RebarColorMode, type RebarScene } from './view/rebar
import { DEFAULT_MATERIAL, FCK_MEMBERS, fyOf, GRADE_CHOICES, isAssumedMaterial, materialFrom, type BendFactors, type FckByMember, type FckMember, type GradeKey, type Material } from './core/rebar/common';
import { buildQuantity, quantityRows, type Quantity, type QuantityLine } from './core/rebar/quantity';
import { P1_COPING_GEOM } from './core/coping-geom';
import { BEARING_ELEVATION_REF, SOLPLATE_REF, SOLPLATE_T_RULE, solplateTs } from './core/bearing-ref';
import { applyBearingRules, BEARING_ELEVATION_REF, BEARING_RULES_DEFAULT, type BearingRules, SOLPLATE_REF, SOLPLATE_T_RULE, solplateTs } from './core/bearing-ref';
/** 공통 규칙 of the bearing card (2단계). Screen state for now; not yet saved to the project file. */
let bearingRules: BearingRules = { ...BEARING_RULES_DEFAULT };
import { allVisibleChecked, setVisibleChecked, type TypeFilter } from './core/selection';
import { choose, defaultSummary, isSelectable, SHAPE_GROUPS, UNDEFINED_REASON, type MemberId } from './core/shape-options';
import { parseProject, SCHEMA_VERSION, serializeProject, type ProjectFile, type ProjectInfo } from './core/project';
@@ -1251,6 +1254,53 @@ function setMaterial(key: 'fck' | GradeKey, raw: string): void {
function renderBearingRef(box: HTMLDivElement, pier: Pier): void {
const m = pier.model;
const wrap = el('div', undefined, 'bearing-ref');
wrap.appendChild(el('p', '공통 규칙 (입력 · 기본값 = 도면값)', 'lbl'));
const rules: [keyof BearingRules, string][] = [['h2', '모르타르 h2 (mm)'], ['h3', '받침 높이 h3 (mm)'], ['T', '솔플레이트 중심 T (mm)'], ['margin', '솔플 여유 (mm)']];
const grid = el('div', undefined, 'edit-row');
for (const [key, label] of rules) {
const id = `bear-${key}`;
const lab = el('label', label);
lab.htmlFor = id;
const input = el('input');
input.id = id;
input.type = 'number';
input.step = 'any';
input.value = String(bearingRules[key]);
const changed = bearingRules[key] !== BEARING_RULES_DEFAULT[key];
if (changed) input.classList.add('changed-input');
input.addEventListener('change', () => {
const v = Number(input.value);
const min = key === 'margin' ? 0 : 0.0001;
if (!Number.isFinite(v) || v < min) {
setError(`${label}은(는) ${key === 'margin' ? '0 이상' : '0보다 큰'} 숫자여야 합니다.`);
renderAll();
return;
}
bearingRules = { ...bearingRules, [key]: v };
renderAll();
});
grid.append(lab, input, el('span', `기본 ${BEARING_RULES_DEFAULT[key]}`, 'muted small'));
}
wrap.appendChild(grid);
wrap.appendChild(el('p', '규칙 적용 값 (E = h1 + h2 + h3 + h4, L = A + 여유, W = B + 여유, T1·T2 = T ± L·|S|/2)', 'lbl'));
const ct = el('table', undefined, 'grid-table rebar-table');
const ch = el('thead');
const chr = el('tr');
for (const h of ['No', '열', 'E', 'L', 'W', 'T1 (−측)', 'T2 (+측)', '도면 대비']) chr.appendChild(el('th', h));
ch.appendChild(chr);
ct.appendChild(ch);
const cb = el('tbody');
for (const r of BEARING_ELEVATION_REF) {
const v = applyBearingRules(r, bearingRules);
const d = applyBearingRules(r, BEARING_RULES_DEFAULT);
const same = v.E === d.E && v.L === d.L && v.W === d.W && v.T1 === d.T1 && v.T2 === d.T2;
cb.appendChild(el('tr')).append(
el('td', String(r.no)), el('td', r.row), el('td', String(v.E)), el('td', String(v.L)), el('td', String(v.W)),
el('td', String(v.T1)), el('td', String(v.T2)), el('td', same ? '같음' : '규칙 변경'),
);
}
ct.appendChild(cb);
wrap.appendChild(el('div', undefined, 'table-scroll')).appendChild(ct);
wrap.appendChild(el('p', '교량받침 ELEVATION TABLE (도면값 · 읽기 전용, mm · EL m)', 'lbl'));
wrap.appendChild(el('p', '도면값은 모델에 쓰지 않습니다(Q16). 아래 "차이"는 도면과 모델의 코핑 상면 차이입니다.', 'muted small'));
const front = m?.segments ?? [];