fix: [fire-shutter] 스크린 가이드레일 flange 30mm 수정 (슬롯 10mm)
- flange:8→30 (양쪽 30mm씩 → 슬롯 개구부 10mm) - lip=10mm는 슬랫이 통과하는 홈 폭 (width-2*flange=10mm) - 평면도 클립을 채널 내부 사이드월 면으로 재배치 - 3D 클립을 사이드월 내면 L형 브라켓으로 수정 - 슬롯 갭 치수 표시 추가
This commit is contained in:
@@ -401,7 +401,7 @@
|
||||
openHeight: 3000,
|
||||
quantity: 1,
|
||||
// Guide Rail
|
||||
gr: { width:70, depth:120, thickness:1.55, lip:10, flange:8, sideWall:80, backWall:67, trimThick:1.2, sealThick:0.8, sealDepth:40, slatThick:0.8, anchorSpacing:500, viewMode:'cross', showDim:true, showSeal:true },
|
||||
gr: { width:70, depth:120, thickness:1.55, lip:10, flange:30, sideWall:80, backWall:67, trimThick:1.2, sealThick:0.8, sealDepth:40, slatThick:0.8, anchorSpacing:500, viewMode:'cross', showDim:true, showSeal:true },
|
||||
// Shutter Box
|
||||
sb: { width:2280, height:380, depth:500, thickness:1.6, shaftDia:80, bracketW:10, motorSide:'right', viewMode:'front', showShaft:true, showSlatRoll:true, showMotor:true, showBrake:true, showSpring:true },
|
||||
// 3D
|
||||
@@ -420,7 +420,7 @@
|
||||
sb:{height:550, depth:650, frontH:410, bottomOpen:75, shaftDia:120},
|
||||
bk:{nmH:320, nmD:320, mtH:320, mtD:530, thick:18, sprocketR:215, motorSpR:40, motorOffset:160} },
|
||||
screen: { marginW:140, marginH:350, weightFactor:2,
|
||||
gr:{width:70, depth:120, thickness:1.55, lip:10, flange:8, sideWall:80, backWall:67, trimThick:1.2},
|
||||
gr:{width:70, depth:120, thickness:1.55, lip:10, flange:30, sideWall:80, backWall:67, trimThick:1.2},
|
||||
slatThick:0.8,
|
||||
sb:{height:380, depth:500, frontH:240, bottomOpen:75, shaftDia:80},
|
||||
bk:{nmH:180, nmD:180, mtH:180, mtD:380, thick:18, sprocketR:70, motorSpR:30, motorOffset:0} },
|
||||
@@ -734,7 +734,7 @@ function renderGrCross() {
|
||||
const sw = (g.sideWall || 80) * sc; // 80mm 사이드월
|
||||
const t = g.thickness * sc; // 1.55mm
|
||||
const bodyD = sw + t; // ~82mm 본체 깊이 (가로)
|
||||
const fl = (g.flange || 8) * sc; // 8mm 플랜지
|
||||
const fl = (g.flange || 30) * sc; // 30mm 플랜지 (슬롯=width-2*fl=10mm)
|
||||
const lp = g.lip * sc; // 10mm 립
|
||||
const sealT = g.sealThick * sc;
|
||||
const sealD = g.sealDepth * sc;
|
||||
@@ -807,13 +807,17 @@ function renderGrCross() {
|
||||
const slatX1 = bx + t + 2;
|
||||
const slatX2 = bx + bodyD - lp - t - 2;
|
||||
|
||||
// ① 클립 (개구부쪽, 플랜지 내면에서 안쪽으로)
|
||||
const clipLen = Math.min(15 * sc, (fw - 2*fl) * 0.15);
|
||||
const clipW = Math.max(t, 3);
|
||||
// ① 클립 (채널 내부, 사이드월 내면에 부착 — 참조 도면 기준)
|
||||
// 클립은 개구부 근처 채널 넓은 공간에 L형 브라켓으로 위치
|
||||
const clipSize = 15 * sc; // 15mm 클립 크기
|
||||
const clipT = Math.max(t, 3); // 클립 두께
|
||||
const clipX = bx + bodyD - lp - t - clipSize - 4; // 개구부 근처 (립 안쪽)
|
||||
const clipY1 = by + t + 4; // 상단 사이드월 내면
|
||||
const clipY2 = by + fw - t - clipSize - 4; // 하단 사이드월 내면
|
||||
const clipSvg = `
|
||||
<rect x="${bx+bodyD-lp-t-clipLen}" y="${by+fl+t}" width="${clipLen}" height="${clipW}" fill="#8b5cf6" opacity="0.5" rx="1"/>
|
||||
<rect x="${bx+bodyD-lp-t-clipLen}" y="${by+fw-fl-t-clipW}" width="${clipLen}" height="${clipW}" fill="#8b5cf6" opacity="0.5" rx="1"/>
|
||||
${g.showDim ? `<text x="${bx+bodyD-lp-t-clipLen-2}" y="${by+fl+t+clipW+10}" fill="#8b5cf6" font-size="7" font-weight="700" text-anchor="end" font-family="Pretendard">①</text>` : ''}`;
|
||||
<rect x="${clipX}" y="${clipY1}" width="${clipSize}" height="${clipSize}" fill="none" stroke="#8b5cf6" stroke-width="${clipT}" opacity="0.5" rx="1"/>
|
||||
<rect x="${clipX}" y="${clipY2}" width="${clipSize}" height="${clipSize}" fill="none" stroke="#8b5cf6" stroke-width="${clipT}" opacity="0.5" rx="1"/>
|
||||
${g.showDim ? `<text x="${clipX+clipSize+4}" y="${clipY1+clipSize/2+3}" fill="#8b5cf6" font-size="7" font-weight="700" text-anchor="start" font-family="Pretendard">①</text>` : ''}`;
|
||||
|
||||
// 치수선
|
||||
let dimLines = '';
|
||||
@@ -833,9 +837,13 @@ function renderGrCross() {
|
||||
// 플랜지 (우측 상단)
|
||||
dimLines += `<line x1="${bx+bodyD+3}" y1="${by}" x2="${bx+bodyD+3}" y2="${by+fl}" stroke="#94a3b8" stroke-width="0.8"/>`;
|
||||
dimLines += `<text x="${bx+bodyD+8}" y="${by+fl/2+3}" fill="#94a3b8" font-size="9" font-weight="700" text-anchor="start" font-family="Pretendard">FL ${g.flange}</text>`;
|
||||
// 립 길이 (우측 플랜지 아래)
|
||||
// 슬롯 개구부 (우측 플랜지 사이)
|
||||
const slotGap = g.width - 2 * g.flange;
|
||||
dimLines += `<line x1="${bx+bodyD}" y1="${by+fl+3}" x2="${bx+bodyD}" y2="${by+fw-fl-3}" stroke="#22c55e" stroke-width="0.8"/>`;
|
||||
dimLines += `<text x="${bx+bodyD+6}" y="${by+fw/2+3}" fill="#22c55e" font-size="8" font-weight="700" text-anchor="start" font-family="Pretendard">슬롯 ${slotGap}</text>`;
|
||||
// 립 깊이 (개구부→채널 방향)
|
||||
dimLines += `<line x1="${bx+bodyD-lp}" y1="${by+fl+3}" x2="${bx+bodyD}" y2="${by+fl+3}" stroke="#94a3b8" stroke-width="0.8"/>`;
|
||||
dimLines += `<text x="${bx+bodyD-lp/2}" y="${by+fl+14}" fill="#94a3b8" font-size="9" font-weight="700" text-anchor="middle" font-family="Pretendard">립 ${g.lip}</text>`;
|
||||
dimLines += `<text x="${bx+bodyD-lp/2}" y="${by+fl+14}" fill="#94a3b8" font-size="9" font-weight="700" text-anchor="middle" font-family="Pretendard">립깊이 ${g.lip}</text>`;
|
||||
// 두께
|
||||
dimLines += `<text x="${bx+t}" y="${by+fw+55}" fill="#94a3b8" font-size="9" font-weight="700" font-family="Pretendard">t=${g.thickness}</text>`;
|
||||
}
|
||||
@@ -1645,13 +1653,13 @@ function createRailGroup() {
|
||||
if (isScreen) {
|
||||
// ====== 스크린형 가이드레일 (실제 조립 구조) ======
|
||||
// 단면 좌표계: X=폭(0→70), Y=깊이(0=개구부/실내측, +=벽쪽)
|
||||
const fl = g.flange; // 8mm (플랜지)
|
||||
const fl = g.flange; // 30mm (플랜지, 슬롯=width-2*fl=10mm)
|
||||
const lp = g.lip; // 10mm (립)
|
||||
const sw = g.sideWall; // 80mm (사이드월)
|
||||
const bw = g.backWall; // 67mm (백월)
|
||||
|
||||
// --- ② 본체 (EGI 1.55T): 10-26-80-67-80-26-10 ---
|
||||
// C채널: 사이드월 80mm, 백월 67mm, 플랜지 26mm, 립 10mm
|
||||
// --- ② 본체 (EGI 1.55T): 슬롯10-플랜지30-사이드월80-백월t-사이드월80-플랜지30-슬롯 ---
|
||||
// C채널: 사이드월 80mm, 플랜지 30mm, 슬롯 개구부 10mm (=width-2*fl)
|
||||
const bodyShape = new THREE.Shape();
|
||||
// 외곽 (시계방향)
|
||||
bodyShape.moveTo(0, 0); // 하단-전면 모서리
|
||||
@@ -1747,22 +1755,22 @@ function createRailGroup() {
|
||||
tt.lineTo(rw + trimT, -9);
|
||||
grp.add(new THREE.Mesh(new THREE.ExtrudeGeometry(tt, railExtrude), railSusMat));
|
||||
|
||||
// --- ① 마감재 (EGI 1.55T): 10-11-110-30-15-15-15 × 2개 ---
|
||||
// 슬랫 가이드 클립: 채널 내부에서 슬랫을 잡아주는 ㄱ자 클립
|
||||
const clipSeg = [10, 11, 110, 30, 15, 15, 15];
|
||||
// 상단/하단 각 1개씩 — 플랜지 내면에 부착
|
||||
[fl + rt, rw - fl - rt].forEach((clipX, idx) => {
|
||||
const clipDir = idx === 0 ? 1 : -1; // 채널 중심 방향
|
||||
// --- ① 마감재 (EGI 1.55T) × 2개 ---
|
||||
// 슬랫 가이드 클립: 사이드월 내면에 부착된 L형 브라켓
|
||||
// 참조 도면 기준: 채널 내부 사이드월에서 안쪽으로 돌출
|
||||
[{ x: rt, dir: 1 }, { x: rw - rt, dir: -1 }].forEach(({ x, dir }) => {
|
||||
const clipShape = new THREE.Shape();
|
||||
// 간략화: 주요 가이드 돌출부만 표현 (30mm×15mm ㄱ자)
|
||||
const cy = lp + rt + 5; // 립 내면에서 약간 안쪽
|
||||
clipShape.moveTo(clipX, cy);
|
||||
clipShape.lineTo(clipX + clipDir * 15, cy);
|
||||
clipShape.lineTo(clipX + clipDir * 15, cy + 30);
|
||||
clipShape.lineTo(clipX + clipDir * 15 - clipDir * rt, cy + 30);
|
||||
clipShape.lineTo(clipX + clipDir * 15 - clipDir * rt, cy + rt);
|
||||
clipShape.lineTo(clipX, cy + rt);
|
||||
clipShape.lineTo(clipX, cy);
|
||||
const cy = lp + rt + 3; // 립 내면에서 약간 안쪽
|
||||
const armLen = 12; // 사이드월에서 안쪽으로 돌출 길이
|
||||
const legLen = 20; // 사이드월 따라 길이
|
||||
// L형 브라켓 (사이드월 내면 → 채널 안쪽으로)
|
||||
clipShape.moveTo(x, cy);
|
||||
clipShape.lineTo(x + dir * armLen, cy);
|
||||
clipShape.lineTo(x + dir * armLen, cy + rt);
|
||||
clipShape.lineTo(x + dir * rt, cy + rt);
|
||||
clipShape.lineTo(x + dir * rt, cy + legLen);
|
||||
clipShape.lineTo(x, cy + legLen);
|
||||
clipShape.lineTo(x, cy);
|
||||
const clipGeo = new THREE.ExtrudeGeometry(clipShape, railExtrude);
|
||||
grp.add(new THREE.Mesh(clipGeo, railMat));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user