feat: [pmis] BIM 뷰어 기둥/보를 H형강 단면으로 개선

- hbeam() 메서드 추가 (상/하 플랜지 + 웹 3파트 구성)
- X방향/Z방향/수직(Y) 3축 지원
- 보: H500×300, H450×300 H형강 단면 적용
- 기둥: H400×400 H형강 단면 적용
- 요소 통계에서 플랜지 부품 카운트 제외 (본체만)
This commit is contained in:
김보곤
2026-03-12 23:02:25 +09:00
parent 824ea6f494
commit 48ff96d203

View File

@@ -340,6 +340,27 @@ class BimScene {
return mesh;
}
// H형강 — 상/하 플랜지 + 웹 3파트 구성
// axis: 'x'=X방향, 'z'=Z방향, 'y'=수직(기둥)
// h=단면 높이, w=플랜지 폭, tw=웹 두께, tf=플랜지 두께
hbeam(length, h, w, tw, tf, pos, axis, userData, group) {
const fl = { ...userData, part: 'flange' };
const webH = h - 2 * tf;
if (axis === 'x') {
this.box(length, tf, w, [pos[0], pos[1] + h / 2 - tf / 2, pos[2]], fl, group);
this.box(length, tf, w, [pos[0], pos[1] - h / 2 + tf / 2, pos[2]], fl, group);
this.box(length, webH, tw, pos, userData, group);
} else if (axis === 'z') {
this.box(w, tf, length, [pos[0], pos[1] + h / 2 - tf / 2, pos[2]], fl, group);
this.box(w, tf, length, [pos[0], pos[1] - h / 2 + tf / 2, pos[2]], fl, group);
this.box(tw, webH, length, pos, userData, group);
} else { // 'y' — 기둥 (수직, H단면은 X-Z 평면)
this.box(w, length, tf, [pos[0], pos[1], pos[2] + h / 2 - tf / 2], fl, group);
this.box(w, length, tf, [pos[0], pos[1], pos[2] - h / 2 + tf / 2], fl, group);
this.box(tw, length, webH, pos, userData, group);
}
}
createDemoBuilding() {
const W = 60, D = 30, FH = 4, NF = 3, CX = 7, CZ = 4, SX = 10, SZ = 10;
for (let f = 0; f <= NF; f++) {
@@ -347,18 +368,22 @@ class BimScene {
this.box(W + 0.6, th, D + 0.6, [W / 2, f * FH, D / 2],
{ type: isR ? 'roof' : 'floor', name: label, material: '철근콘크리트 (24MPa)', floor: isR ? 'RF' : (f === 0 ? 'GL' : f + 'F'), dimensions: `${W}m × ${D}m × ${th * 1000}mm` }, isR ? 'roof' : 'floor');
}
// H형강 기둥 — CTW: 웹 두께, CTF: 플랜지 두께
const CTW = 0.04, CTF = 0.05;
let cn = 0;
for (let f = 0; f < NF; f++) for (let ix = 0; ix < CX; ix++) for (let iz = 0; iz < CZ; iz++) {
cn++; const ch = FH - 0.3;
this.box(0.45, ch, 0.45, [ix * SX, f * FH + 0.15 + ch / 2, iz * SZ],
{ type: 'column', name: `C-${String(cn).padStart(3, '0')}`, material: 'H형강 (SS400)', floor: `${f + 1}F`, dimensions: '400×400×3,700mm', grid: `(${ix + 1},${iz + 1})` }, 'column');
this.hbeam(ch, 0.45, 0.45, CTW, CTF, [ix * SX, f * FH + 0.15 + ch / 2, iz * SZ], 'y',
{ type: 'column', name: `C-${String(cn).padStart(3, '0')}`, material: 'H형강 H400×400 (SS400)', floor: `${f + 1}F`, dimensions: 'H400×400×40×50 L=3,700mm', grid: `(${ix + 1},${iz + 1})` }, 'column');
}
// H형강 보 — tw: 웹 두께, tf: 플랜지 두께 (시각적 가시성 위해 확대)
const BTW = 0.05, BTF = 0.06;
for (let f = 1; f <= NF; f++) {
const by = f * FH - 0.25;
for (let iz = 0; iz < CZ; iz++) this.box(W, 0.5, 0.3, [W / 2, by, iz * SZ],
{ type: 'beam', name: `GB-X${iz + 1}-${f}F`, material: 'H형강 (SS400)', floor: `${f}F`, dimensions: `${W}m × 300×500mm` }, 'beam');
for (let ix = 0; ix < CX; ix++) this.box(0.3, 0.45, D, [ix * SX, by, D / 2],
{ type: 'beam', name: `GB-Z${ix + 1}-${f}F`, material: 'H형강 (SS400)', floor: `${f}F`, dimensions: `${D}m × 300×450mm` }, 'beam');
for (let iz = 0; iz < CZ; iz++) this.hbeam(W, 0.5, 0.3, BTW, BTF, [W / 2, by, iz * SZ], 'x',
{ type: 'beam', name: `GB-X${iz + 1}-${f}F`, material: 'H형강 H500×300 (SS400)', floor: `${f}F`, dimensions: `${W}m × H500×300×50×60` }, 'beam');
for (let ix = 0; ix < CX; ix++) this.hbeam(D, 0.45, 0.3, BTW, BTF, [ix * SX, by, D / 2], 'z',
{ type: 'beam', name: `GB-Z${ix + 1}-${f}F`, material: 'H형강 H450×300 (SS400)', floor: `${f}F`, dimensions: `${D}m × H450×300×50×60` }, 'beam');
}
const segW = SX - 1;
for (let f = 0; f < NF; f++) {
@@ -589,7 +614,7 @@ class BimScene {
const c = {};
this.meshes.forEach(m => {
const t = m.userData.type; if (!t) return;
if (t === 'fireShutter' && m.userData.part) return; // Jamb/Housing 제외, 패널만 카운트
if (m.userData.part) return; // 부품(플랜지, Jamb, 하우징) 제외 — 본체만 카운트
c[t] = (c[t] || 0) + 1;
});
return c;