From 02eb05bda48387e867ca64143b5ef25e044b4eea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=A7=80=EC=98=81?= <본인 이메일m17208.tdc.hanmacgroup@gmail.com> Date: Tue, 20 Oct 2026 10:57:56 +0900 Subject: [PATCH] =?UTF-8?q?=EB=8B=A8=EB=A9=B4=20=EC=9C=A4=EA=B3=BD?= =?UTF-8?q?=EC=9D=98=20OBJ=20=ED=8C=8C=EC=9D=BC=20=EB=B0=8F=20=EA=B7=BC?= =?UTF-8?q?=EA=B1=B0=20JSON=20=EB=82=B4=EB=B3=B4=EB=82=B4=EA=B8=B0=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.jsx | 7 ++++--- src/model/geometry.js | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 5f39102..4766ecd 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,6 +1,6 @@ import { useMemo, useState } from 'react' import Viewer from './Viewer' -import { model, groups, palette, partDimensions, exportModel } from './model/geometry' +import { model, groups, palette, partDimensions, exportModel, exportOBJ } from './model/geometry' function download(data, filename, type = 'application/json') { const url = URL.createObjectURL(new Blob([data], { type })) @@ -21,7 +21,7 @@ export default function App() { G도면 모델 작업실 구조 검토 / 일반도 13 · 14 원본 DXF ↓ - +
도면에서 읽은 구조, 근거가 보이는 모델

광터지하차도 BLOCK7

원본 단면 윤곽을 보존한 3D 검토 모델

@@ -49,7 +49,7 @@ export default function App() { if (!ps.length) return null const allHidden = ps.every(p => hidden.has(p.id)) return
{g}{ps.length}
{ps.map(p =>
toggle([p.id])} />
)}
- })}{!filtered.length &&

검색 결과가 없습니다.

}

선 개수는 실제 부재 개수와 다릅니다. 반복선은 기본적으로 숨겨져 있습니다.

} + })}{!filtered.length &&

검색 결과가 없습니다.

}

선 개수는 실제 부재 개수와 다릅니다. 반복선은 기본적으로 숨겨져 있습니다.

} {tab === '도면' && <>

원본 좌표 검토

주요 LINE·TEXT와 공동구 선을 발췌한 검토 자료입니다. 전체 도면은 원본 DXF를 확인하세요.

{['단면A', '단면B', '평면검토', '종단검토', '측구상세'].map(s => )}
{`${source}크게 보기 ↗
그림 읽는 법

녹색은 두 콘크리트 레이어, 황토색은 공동구 삽입 블록, 회색은 보조선입니다. 도면 기호·일부 블록은 생략되어 있습니다.

} {tab === '검증' && <>

확인한 것과 남은 것

현재 표현 범위

두 단면의 구조선과 공동구 윤곽을 공간에 배치했습니다. 표면·그림자를 적용한 렌더링은 연결 형상 확인 후 추가할 항목입니다. 현재 윤곽 명암은 실사 렌더링이 아닙니다.

} @@ -57,3 +57,4 @@ export default function App() { } + diff --git a/src/model/geometry.js b/src/model/geometry.js index 5309e55..bd00946 100644 --- a/src/model/geometry.js +++ b/src/model/geometry.js @@ -17,3 +17,18 @@ export function exportModel(hidden) { const visibleParts = data.parts.filter(p => !hidden.has(p.id)) return { ...data, parts: visibleParts, description: '단면 윤곽 3D 배치. 평면 위치·단면간 연결 미확정. 부재 체적 아님.', coordinateSystem: 'X=단면 횡방향(m), Y=EL(m), Z=단면 STA 차(m); 실제 평면 좌표 미확정' } } + +export function exportOBJ(hidden = new Set()) { + const rows = ['# 광터지하차도 BLOCK7 단면 윤곽 모델', '# 단위 m. X 횡방향 / Y EL / Z 단면 STA 차. 평면 배치와 연결 표면 미확정.'] + let index = 1 + for (const part of data.parts.filter(p => !hidden.has(p.id))) { + for (const section of [0, 1]) { + rows.push(`# ${part.name} / ${part.source}`, `o ${part.id.replace(/[^a-zA-Z0-9-]/g, '_')}-${section ? 'B' : 'A'}`) + const points = profileVertices(part, section) + points.forEach(([x, y, z]) => rows.push(`v ${x} ${y + 100} ${z + 10}`)) + rows.push(`l ${points.map((_, i) => index + i).join(' ')}`) + index += points.length + } + } + return rows.join('\n') + '\n' +}