diff --git a/resources/views/juil/bim-viewer.blade.php b/resources/views/juil/bim-viewer.blade.php index d5f69764..d56a5fba 100644 --- a/resources/views/juil/bim-viewer.blade.php +++ b/resources/views/juil/bim-viewer.blade.php @@ -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;