- B9 (확대기초철근 (1).md §9): H16 with the 135° stirrup hook, on the odd grid (i_W = 1, 5, …), 16 rows, 20 per row (even rows start at i_L 1, odd at 3), 320 bars, length l_v 1750 + 2 × 189 ≈ 2128. - The rebar summary now lists B9; the alert about B9 is gone. Positions and hooks are the document's proposed rules (Q-B18, Q-B19), noted on the row. - Tests: the document's B9 values; P1 summary has 320 and only the splice alert. - Not verified in a browser. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
99 lines
6.4 KiB
TypeScript
99 lines
6.4 KiB
TypeScript
import type { PierModel } from '../geometry';
|
||
import { bearingBlockRebar, totals } from './bearing-block';
|
||
import { bottomPiece, topBarLength, widthLayout } from './coping-main';
|
||
import { shearBars, sideRows, C14_COUNTS, c14Total, STEP_BAR_COUNTS } from './coping';
|
||
import { columnRebar, COLUMN_P1 } from './column';
|
||
import { bottomBars, crossBars, sideBars, assemblyBars, shearB9 } from './footing';
|
||
|
||
/** One line of a 철근표. length is null where the document gives no length yet. */
|
||
export interface RebarRow {
|
||
member: 'bearing' | 'coping' | 'column' | 'footing';
|
||
name: string;
|
||
size: string;
|
||
count: number;
|
||
length: number | null;
|
||
note: string;
|
||
}
|
||
|
||
export interface RebarWarning {
|
||
code: string;
|
||
message: string;
|
||
}
|
||
|
||
/** 정척 L_bar (mm) from 확대기초철근.md §1.2. Bars longer than this need a splice. */
|
||
export const STANDARD_BAR = 12000;
|
||
|
||
/**
|
||
* 철근표 for one pier (③ screen v1): bearing blocks, coping, column, footing. Built from the generated model.
|
||
* Values come from the document rules in src/core/rebar/*. B9 (전단철근) is not computed yet.
|
||
*/
|
||
export function rebarSummary(model: PierModel): { rows: RebarRow[]; warnings: RebarWarning[] } {
|
||
const rows: RebarRow[] = [];
|
||
const warnings: RebarWarning[] = [];
|
||
const L = model.copingL * 1000;
|
||
const B = model.copingB * 1000;
|
||
|
||
// Bearing blocks (§6.3 · plan C2)
|
||
const blk = totals(bearingBlockRebar(model));
|
||
rows.push({ member: 'bearing', name: 'S1', size: 'H19', count: blk.S1, length: 2500, note: '블럭 배치 분리, 블럭당 8본' });
|
||
rows.push({ member: 'bearing', name: 'S2', size: 'H19', count: blk.S2, length: 2500, note: '블럭 배치 분리, 블럭당 8본' });
|
||
|
||
// Coping (코핑철근.md §5–§8)
|
||
const width = widthLayout(B);
|
||
const perRow = width.count / 2; // cycle split, 12 per row
|
||
// C1–C3 and C4–C6 are the same three top rows (row 1, 2, 3), one set per cycle.
|
||
for (const [name, k] of [['C1', 1], ['C2', 2], ['C3', 3], ['C4', 1], ['C5', 2], ['C6', 3]] as const) {
|
||
rows.push({ member: 'coping', name, size: 'H29', count: perRow, length: topBarLength(L, k), note: '상면, 이음 무시' });
|
||
}
|
||
const bottom = bottomPiece();
|
||
rows.push({ member: 'coping', name: 'C7', size: 'H29', count: perRow, length: bottom.piece, note: '하면, 2조각 겹침이음' });
|
||
rows.push({ member: 'coping', name: 'C8', size: 'H29', count: perRow, length: bottom.piece, note: '하면, 2조각 겹침이음' });
|
||
const shear = shearBars(L);
|
||
rows.push({ member: 'coping', name: 'C9', size: 'H25', count: shear.c9.length, length: null, note: '전단 좌 @250' });
|
||
rows.push({ member: 'coping', name: 'C10', size: 'H25', count: shear.c10.length, length: null, note: '전단 Level @300' });
|
||
rows.push({ member: 'coping', name: 'C11', size: 'H25', count: shear.c11.length, length: null, note: '전단 우 @250' });
|
||
const side = sideRows(41.288, 42.538);
|
||
rows.push({ member: 'coping', name: 'C12', size: 'H25', count: side.c12.length, length: null, note: '측면, 경사 하면에서 끊김' });
|
||
rows.push({ member: 'coping', name: 'C13', size: 'H25', count: side.c13.length, length: null, note: '측면, 끝면까지' });
|
||
rows.push({ member: 'coping', name: 'C14', size: 'H19', count: c14Total(), length: null, note: `직각 수평 ${C14_COUNTS.upperLines * C14_COUNTS.upperPerLine}+${C14_COUNTS.lower.join('+')}` });
|
||
rows.push({ member: 'coping', name: 'C15', size: 'H19', count: STEP_BAR_COUNTS.C15, length: null, note: '계단부, 가장 높은 구간' });
|
||
rows.push({ member: 'coping', name: 'C16', size: 'H19', count: STEP_BAR_COUNTS.C16, length: null, note: '계단부, 3·4구간' });
|
||
|
||
// Column (기둥철근.md · plan C4), P1 defaults
|
||
const col = columnRebar(COLUMN_P1);
|
||
rows.push({ member: 'column', name: 'P1', size: 'S32', count: col.mainP1, length: null, note: '외측 r 875, 커플러로 이음' });
|
||
rows.push({ member: 'column', name: 'P2', size: 'S32', count: col.mainP2, length: null, note: '내측 r 843.2, 커플러로 이음' });
|
||
rows.push({ member: 'column', name: '커플러', size: 'L150 Ø60', count: col.couplers, length: 150, note: '@3000, P2 +150' });
|
||
rows.push({ member: 'column', name: 'P3', size: 'H19', count: col.p3Count, length: null, note: '일반 구간 띠철근 @300' });
|
||
rows.push({ member: 'column', name: 'P5', size: 'H19', count: col.p5Count, length: null, note: '단부 띠철근 @120' });
|
||
rows.push({ member: 'column', name: 'P4', size: 'H19', count: col.p4Count, length: col.p4SemicircleLength * 2, note: '확대기초 안, 반원 2개 (길이는 반원 2개 합) · B11 간섭 무시' });
|
||
rows.push({ member: 'column', name: 'P6', size: 'H16', count: col.p6Count, length: col.p6Length, note: '크로스타이, 8단 × 4' });
|
||
|
||
// Footing (확대기초철근 (1).md · plan C5). Only when the footing exists (not 현장타설말뚝).
|
||
const f = model.footings[0];
|
||
if (f) {
|
||
const Lf = f.length * 1000;
|
||
const Wf = f.width * 1000;
|
||
const Hf = (f.top - f.bottom) * 1000;
|
||
for (const b of bottomBars(Lf, Wf, Hf)) {
|
||
rows.push({ member: 'footing', name: b.name, size: b.size, count: b.count, length: b.length, note: '교각축' });
|
||
if (b.length > STANDARD_BAR) {
|
||
warnings.push({ code: 'RB-F08', message: `${b.name} 길이 ${Math.round(b.length)} mm가 정척 ${STANDARD_BAR} mm를 넘어 이음이 필요합니다 (Q-B6).` });
|
||
}
|
||
}
|
||
for (const b of crossBars(Lf, Wf, Hf)) {
|
||
rows.push({ member: 'footing', name: b.name, size: b.size, count: b.count, length: b.length, note: '교각축 직각' });
|
||
if (b.length > STANDARD_BAR) {
|
||
warnings.push({ code: 'RB-F08', message: `${b.name} 길이 ${Math.round(b.length)} mm가 정척 ${STANDARD_BAR} mm를 넘어 이음이 필요합니다 (Q-B6).` });
|
||
}
|
||
}
|
||
for (const b of sideBars(Lf, Wf)) rows.push({ member: 'footing', name: b.name, size: b.size, count: b.count, length: b.length, note: '측면 수평' });
|
||
for (const b of assemblyBars(Lf, Wf)) rows.push({ member: 'footing', name: b.name, size: b.size, count: b.count, length: b.length, note: '조립 수평' });
|
||
const b9 = shearB9(Lf, Wf, Hf);
|
||
rows.push({ member: 'footing', name: 'B9', size: 'H16', count: b9.count, length: b9.length, note: `전단 @500 엇갈림, ${b9.rows}행 (위치·갈고리는 Q-B18·B19 제안)` });
|
||
} else {
|
||
warnings.push({ code: 'RB-F00', message: '현장타설말뚝은 확대기초가 없어 확대기초 철근을 만들지 않습니다.' });
|
||
}
|
||
return { rows, warnings };
|
||
}
|