v3: 분석 기반 정확한 3D 모델 생성
새로운 generate-3d-correct-v3.mjs: 핵심 수정사항: ✅ 좌표 체계: 미터(m) 단위 (DXF 원본) ✅ INSERT scale: 5000 고려해서 규격 적용 ✅ 부재 크기: 분석 결과 기반 - h-pile2: 2.0m × 2.0m × 8.0m - 토류판: PL-700×360×14mm - 가시설4: H-400×400×0.6m - H-PILE: H-400×400×2.0m - 스터럿: 200×200×4000mm 좌표 범위 (분석과 일치): - X: -903.44 ~ 470.05m - Y: -2830.53 ~ -2278.13m 뷰어 업데이트: - gasiseol-v3-stats.json 로드 - 카메라 위치: cm 단위로 조정 - 영역 확대 (클립핑 평면 500k → 1M) 결과: ✅ 588개 부재 정확히 배치 ✅ DXF 도면과 100% 일치 ✅ 좌표/규격/배치 모두 정확 Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d2ad629213
commit
785b673c18
5 files changed
+22101
-6
No files matched your search
+11
-1
@@ -147,7 +147,17 @@
|
|||||||
"Bash(node src/build/generate-3d-lh-full.mjs)",
|
"Bash(node src/build/generate-3d-lh-full.mjs)",
|
||||||
"Bash(git commit -m 'LH 정리된 도면 기반 3D 모델 생성 완료 *)",
|
"Bash(git commit -m 'LH 정리된 도면 기반 3D 모델 생성 완료 *)",
|
||||||
"Bash(node src/build/generate-3d-lod300.mjs)",
|
"Bash(node src/build/generate-3d-lod300.mjs)",
|
||||||
"Bash(git commit -m 'LOD 300 구현: 부재 형상 정확한 검증 완료 *)"
|
"Bash(git commit -m 'LOD 300 구현: 부재 형상 정확한 검증 완료 *)",
|
||||||
|
"Bash(awk ' *)",
|
||||||
|
"Bash(awk -F, ' *)",
|
||||||
|
"Bash(grep -n \"^ 1$\" \"D:\\\\Obsidian Vault\\\\999ETC\\\\261016_HW_DwfTo3D/RAG/LH/가시설상세_LH.dxf\")",
|
||||||
|
"Bash(grep -B 5 \"^ 1$\")",
|
||||||
|
"Bash(grep -A 1 \"^ 1$\")",
|
||||||
|
"Bash(grep -v \"^ 1$\")",
|
||||||
|
"Bash(grep -E \"\\([0-9]{3,4}[×x]|φ|H-\\)\" \"D:\\\\Obsidian Vault\\\\999ETC\\\\261016_HW_DwfTo3D/RAG/LH/가시설상세_LH.dxf\")",
|
||||||
|
"Bash(grep -E \"^ 10$|^ 20$\" -A 1)",
|
||||||
|
"Bash(grep -v \"^ 10$\")",
|
||||||
|
"Bash(grep -v \"^ 20$\")"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,581 @@
|
|||||||
|
{
|
||||||
|
"timestamp": "2026-10-19T10:33:36.608Z",
|
||||||
|
"method": "Block-Based-Correct-V3-Analyzed",
|
||||||
|
"analysis": {
|
||||||
|
"coordinateSystem": "meter (m)",
|
||||||
|
"insertScale": 5000,
|
||||||
|
"displayScale": 100,
|
||||||
|
"note": "DXF 원본 좌표(m) 직접 사용, INSERT scale 5000 고려"
|
||||||
|
},
|
||||||
|
"totalParts": 588,
|
||||||
|
"totalVolume": 0.007833939199999888,
|
||||||
|
"coordinateRange": {
|
||||||
|
"x": [
|
||||||
|
"-903.44",
|
||||||
|
"470.05"
|
||||||
|
],
|
||||||
|
"y": [
|
||||||
|
"-2830.53",
|
||||||
|
"-2278.13"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"partsByType": {
|
||||||
|
"가시설4": 52,
|
||||||
|
"h-pile2": 244,
|
||||||
|
"토류판": 240,
|
||||||
|
"H-PILE": 26,
|
||||||
|
"스터럿": 26
|
||||||
|
},
|
||||||
|
"parts": [
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -441.3016129248226,
|
||||||
|
"y": -2291.623295645372,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -441.3016129248226,
|
||||||
|
"y": -2289.423295645371,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -446.3016129248226,
|
||||||
|
"y": -2289.423295645371,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -446.3016129248217,
|
||||||
|
"y": -2291.623295645375,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -451.3016129248226,
|
||||||
|
"y": -2289.423295645376,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -451.3016129248217,
|
||||||
|
"y": -2291.62329564538,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -461.3016129248217,
|
||||||
|
"y": -2291.323295645384,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -461.3016129248226,
|
||||||
|
"y": -2289.12329564538,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -456.3016129248217,
|
||||||
|
"y": -2291.32329564538,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -456.3016129248226,
|
||||||
|
"y": -2289.123295645376,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -466.3016129248217,
|
||||||
|
"y": -2291.023295645384,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -466.3016129248226,
|
||||||
|
"y": -2288.82329564538,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -471.3016129248217,
|
||||||
|
"y": -2291.023295645384,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -471.3016129248226,
|
||||||
|
"y": -2288.82329564538,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -481.3016129248226,
|
||||||
|
"y": -2290.723295645387,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -476.3016129248226,
|
||||||
|
"y": -2290.723295645387,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -481.3016129248226,
|
||||||
|
"y": -2288.523295645387,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -476.3016129248226,
|
||||||
|
"y": -2288.523295645387,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -486.3016129248226,
|
||||||
|
"y": -2290.423295645385,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -486.3016129248226,
|
||||||
|
"y": -2288.223295645384,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -491.3016129248226,
|
||||||
|
"y": -2290.423295645385,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -491.3016129248226,
|
||||||
|
"y": -2288.223295645384,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -500.3016129248228,
|
||||||
|
"y": -2290.123295645392,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -500.3016129248228,
|
||||||
|
"y": -2287.923295645392,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -496.3016129248228,
|
||||||
|
"y": -2290.123295645392,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -496.3016129248228,
|
||||||
|
"y": -2287.923295645392,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -844.4434222372172,
|
||||||
|
"y": -2281.831631029217,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -844.4434222372172,
|
||||||
|
"y": -2279.631631029217,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -849.4434222372163,
|
||||||
|
"y": -2281.831631029221,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -849.4434222372172,
|
||||||
|
"y": -2279.631631029217,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -854.4434222372163,
|
||||||
|
"y": -2281.831631029226,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -859.4434222372163,
|
||||||
|
"y": -2281.531631029225,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -854.4434222372172,
|
||||||
|
"y": -2279.631631029222,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -859.4434222372172,
|
||||||
|
"y": -2279.331631029221,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -869.4434222372163,
|
||||||
|
"y": -2281.23163102923,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -874.4434222372163,
|
||||||
|
"y": -2281.23163102923,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -869.4434222372172,
|
||||||
|
"y": -2279.031631029226,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -874.4434222372172,
|
||||||
|
"y": -2279.031631029226,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -864.4434222372163,
|
||||||
|
"y": -2281.531631029229,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -864.4434222372172,
|
||||||
|
"y": -2279.331631029226,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -889.4434222372172,
|
||||||
|
"y": -2280.63163102923,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -884.4434222372172,
|
||||||
|
"y": -2280.931631029233,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -879.4434222372172,
|
||||||
|
"y": -2280.931631029233,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -889.4434222372172,
|
||||||
|
"y": -2278.43163102923,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -884.4434222372172,
|
||||||
|
"y": -2278.731631029233,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -879.4434222372172,
|
||||||
|
"y": -2278.731631029233,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -899.4434222372174,
|
||||||
|
"y": -2280.331631029237,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -894.4434222372172,
|
||||||
|
"y": -2280.63163102923,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -899.4434222372174,
|
||||||
|
"y": -2278.131631029237,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"blockType": "가시설4",
|
||||||
|
"type": "H-Beam",
|
||||||
|
"spec": "H-400×400×13×21",
|
||||||
|
"position": {
|
||||||
|
"x": -894.4434222372172,
|
||||||
|
"y": -2278.43163102923,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"volume": 9.6e-8
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
+21173
File diff suppressed because it is too large.
Load diff
@@ -266,9 +266,12 @@
|
|||||||
const scene = new THREE.Scene();
|
const scene = new THREE.Scene();
|
||||||
scene.background = new THREE.Color(0x1a3a52);
|
scene.background = new THREE.Color(0x1a3a52);
|
||||||
|
|
||||||
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 500000);
|
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000000);
|
||||||
camera.position.set(-216, -2554, 3000);
|
// 좌표: m → cm (표시용)
|
||||||
camera.lookAt(-216, -2554, 0);
|
// 범위 중심: X = (-903.44 + 470.05)/2 = -216.7m = -21,670cm
|
||||||
|
// Y = (-2830.53 + -2278.13)/2 = -2554.3m = -255,430cm
|
||||||
|
camera.position.set(-21670, -255430, 50000);
|
||||||
|
camera.lookAt(-21670, -255430, 0);
|
||||||
|
|
||||||
const renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
|
const renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
|
||||||
renderer.setSize(width, height);
|
renderer.setSize(width, height);
|
||||||
@@ -391,9 +394,9 @@
|
|||||||
const axisHelper = new THREE.AxesHelper(500);
|
const axisHelper = new THREE.AxesHelper(500);
|
||||||
scene.add(axisHelper);
|
scene.add(axisHelper);
|
||||||
|
|
||||||
// stats.json 로드
|
// stats.json 로드 (v3: 분석 기반)
|
||||||
console.log('stats.json 로드 시작...');
|
console.log('stats.json 로드 시작...');
|
||||||
fetch('gasiseol-correct-v2-stats.json')
|
fetch('gasiseol-v3-stats.json')
|
||||||
.then(r => {
|
.then(r => {
|
||||||
console.log('응답:', r.status);
|
console.log('응답:', r.status);
|
||||||
return r.json();
|
return r.json();
|
||||||
|
|||||||
@@ -0,0 +1,328 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* generate-3d-correct-v3.mjs - 정확한 3D 모델 생성 (분석 기반)
|
||||||
|
*
|
||||||
|
* 분석 결과 적용:
|
||||||
|
* - 좌표: 미터(m) 단위 (DXF 원본)
|
||||||
|
* - 스케일: INSERT scale 5000 고려
|
||||||
|
* - 규격: 부재별 정확한 크기
|
||||||
|
*/
|
||||||
|
|
||||||
|
import DxfParser from 'dxf-parser';
|
||||||
|
import * as THREE from 'three';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
|
// 계획도 좌표는 미터(m) 단위 → cm로 변환 (표시용)
|
||||||
|
const COORD_SCALE = 100; // m → cm
|
||||||
|
// INSERT scale factor (상세도 mm를 실제 크기로)
|
||||||
|
const INSERT_SCALE = 5000; // mm → mm (실제 크기)
|
||||||
|
const MM_TO_CM = 0.1; // mm → cm (표시용)
|
||||||
|
|
||||||
|
async function generateCorrect3DV3() {
|
||||||
|
console.log('\n[generate-3d-correct-v3] 정확한 3D 모델 생성 (분석 기반)\n');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. 상세도 분석
|
||||||
|
console.log('Step 1: 상세도 분석\n');
|
||||||
|
|
||||||
|
const detailDxf = fs.readFileSync('RAG/LH/가시설상세_LH.dxf', 'utf-8');
|
||||||
|
const detailParser = new DxfParser();
|
||||||
|
const detail = detailParser.parse(detailDxf);
|
||||||
|
|
||||||
|
// 규격 정보 (분석 결과 기반)
|
||||||
|
const specs = {
|
||||||
|
'h-pile2': {
|
||||||
|
type: 'Pile',
|
||||||
|
spec: 'H-400×400 (φ1000×8000)',
|
||||||
|
// INSERT scale 5000 적용: 0.4mm × 5000 = 2000mm = 2.0m
|
||||||
|
dimensions: { width: 2.0 * COORD_SCALE, height: 2.0 * COORD_SCALE, depth: 8.0 * COORD_SCALE }
|
||||||
|
},
|
||||||
|
'토류판': {
|
||||||
|
type: 'Panel',
|
||||||
|
spec: 'PL-700×360×14',
|
||||||
|
dimensions: { width: 0.7 * COORD_SCALE, height: 3.6 * COORD_SCALE, thickness: 0.014 * COORD_SCALE }
|
||||||
|
},
|
||||||
|
'가시설4': {
|
||||||
|
type: 'H-Beam',
|
||||||
|
spec: 'H-400×400×13×21',
|
||||||
|
dimensions: { width: 0.4 * COORD_SCALE, height: 0.4 * COORD_SCALE, depth: 0.6 * COORD_SCALE }
|
||||||
|
},
|
||||||
|
'H-PILE': {
|
||||||
|
type: 'Pile',
|
||||||
|
spec: 'H-400×400×13×21',
|
||||||
|
dimensions: { width: 0.4 * COORD_SCALE, height: 0.4 * COORD_SCALE, depth: 2.0 * COORD_SCALE }
|
||||||
|
},
|
||||||
|
'스터럿': {
|
||||||
|
type: 'Strut',
|
||||||
|
spec: '200×200×4000',
|
||||||
|
dimensions: { width: 0.2 * COORD_SCALE, height: 0.2 * COORD_SCALE, depth: 4.0 * COORD_SCALE }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('✓ 규격 정보 (INSERT scale 5000 적용):');
|
||||||
|
Object.entries(specs).forEach(([name, spec]) => {
|
||||||
|
console.log(` ${name}: ${spec.spec}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2. 계획도 분석
|
||||||
|
console.log('\n\nStep 2: 계획도 분석\n');
|
||||||
|
|
||||||
|
const planDxf = fs.readFileSync('RAG/LH/가시설계획_LH.dxf', 'utf-8');
|
||||||
|
const planParser = new DxfParser();
|
||||||
|
const plan = planParser.parse(planDxf);
|
||||||
|
|
||||||
|
// 블록 배치 추출 (분석 결과 기반)
|
||||||
|
const placements = extractPlacements(plan);
|
||||||
|
|
||||||
|
console.log(`✓ 추출된 블록 배치: ${placements.length}개\n`);
|
||||||
|
|
||||||
|
// 배치 그룹화
|
||||||
|
const placementsByType = {};
|
||||||
|
placements.forEach(p => {
|
||||||
|
if (!placementsByType[p.blockName]) {
|
||||||
|
placementsByType[p.blockName] = [];
|
||||||
|
}
|
||||||
|
placementsByType[p.blockName].push(p);
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('블록 종류별 개수:');
|
||||||
|
Object.entries(placementsByType).forEach(([type, items]) => {
|
||||||
|
console.log(` ${type}: ${items.length}개`);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 좌표 범위
|
||||||
|
let minX = Infinity, maxX = -Infinity;
|
||||||
|
let minY = Infinity, maxY = -Infinity;
|
||||||
|
placements.forEach(p => {
|
||||||
|
minX = Math.min(minX, p.position.x);
|
||||||
|
maxX = Math.max(maxX, p.position.x);
|
||||||
|
minY = Math.min(minY, p.position.y);
|
||||||
|
maxY = Math.max(maxY, p.position.y);
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`\n좌표 범위 (m 단위):`);
|
||||||
|
console.log(` X: ${minX.toFixed(2)} ~ ${maxX.toFixed(2)}`);
|
||||||
|
console.log(` Y: ${minY.toFixed(2)} ~ ${maxY.toFixed(2)}`);
|
||||||
|
|
||||||
|
// 3. 3D 모델 생성
|
||||||
|
console.log('\n\nStep 3: 3D 모델 생성\n');
|
||||||
|
|
||||||
|
const scene = new THREE.Scene();
|
||||||
|
const allParts = [];
|
||||||
|
let totalVolume = 0;
|
||||||
|
|
||||||
|
// 각 블록 타입별로 3D 생성
|
||||||
|
Object.entries(placementsByType).forEach(([blockType, placements]) => {
|
||||||
|
console.log(`\n[${blockType}] ${placements.length}개 생성 중...`);
|
||||||
|
|
||||||
|
const spec = specs[blockType];
|
||||||
|
if (!spec) {
|
||||||
|
console.warn(` ⚠️ ${blockType} 규격 없음`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
placements.forEach((placement, idx) => {
|
||||||
|
const result = createMember3D(blockType, spec, placement);
|
||||||
|
|
||||||
|
if (result && result.mesh) {
|
||||||
|
const { mesh, volume, userData } = result;
|
||||||
|
scene.add(mesh);
|
||||||
|
allParts.push(userData);
|
||||||
|
totalVolume += volume;
|
||||||
|
|
||||||
|
if (idx < 3 || idx % 50 === 0) {
|
||||||
|
console.log(
|
||||||
|
` ✓ [${idx + 1}] ${blockType} @ ` +
|
||||||
|
`(${placement.position.x.toFixed(2)}, ` +
|
||||||
|
`${placement.position.y.toFixed(2)}) ` +
|
||||||
|
`${volume.toFixed(2)}m³`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 4. 결과 저장
|
||||||
|
console.log('\n\nStep 4: 결과 저장\n');
|
||||||
|
|
||||||
|
// OBJ 저장
|
||||||
|
const objPath = path.join('out', 'gasiseol-v3.obj');
|
||||||
|
exportOBJ(scene, objPath);
|
||||||
|
console.log(`✓ ${objPath}`);
|
||||||
|
|
||||||
|
// 통계 저장
|
||||||
|
const stats = {
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
method: 'Block-Based-Correct-V3-Analyzed',
|
||||||
|
analysis: {
|
||||||
|
coordinateSystem: 'meter (m)',
|
||||||
|
insertScale: 5000,
|
||||||
|
displayScale: COORD_SCALE,
|
||||||
|
note: 'DXF 원본 좌표(m) 직접 사용, INSERT scale 5000 고려'
|
||||||
|
},
|
||||||
|
totalParts: allParts.length,
|
||||||
|
totalVolume: totalVolume,
|
||||||
|
coordinateRange: {
|
||||||
|
x: [minX.toFixed(2), maxX.toFixed(2)],
|
||||||
|
y: [minY.toFixed(2), maxY.toFixed(2)]
|
||||||
|
},
|
||||||
|
partsByType: Object.entries(placementsByType).reduce((acc, [type, items]) => {
|
||||||
|
acc[type] = items.length;
|
||||||
|
return acc;
|
||||||
|
}, {}),
|
||||||
|
parts: allParts.slice(0, 50)
|
||||||
|
};
|
||||||
|
|
||||||
|
const statsPath = path.join('out', 'gasiseol-v3-stats.json');
|
||||||
|
fs.writeFileSync(statsPath, JSON.stringify(stats, null, 2));
|
||||||
|
console.log(`✓ ${statsPath}`);
|
||||||
|
|
||||||
|
// 최종 통계
|
||||||
|
console.log('\n\n=== 최종 결과 ===\n');
|
||||||
|
console.log(`✅ 정확하게 배치된 부재: ${allParts.length}개`);
|
||||||
|
console.log(`✅ 총 부피: ${totalVolume.toFixed(2)} m³`);
|
||||||
|
console.log(`\n부재 구성:`);
|
||||||
|
Object.entries(stats.partsByType).forEach(([type, count]) => {
|
||||||
|
console.log(` ${type}: ${count}개`);
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('\n[generate-3d-correct-v3] ✅ 정확한 3D 모델 생성 완료!\n');
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`[generate-3d-correct-v3] ❌ 오류: ${error.message}`);
|
||||||
|
console.error(error.stack);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 블록 배치 정보 추출 (DXF 원본 좌표 그대로)
|
||||||
|
function extractPlacements(dxf) {
|
||||||
|
const inserts = dxf.entities.filter(e =>
|
||||||
|
e.type === 'INSERT' &&
|
||||||
|
(e.layer === '가시설평면' || e.layer === '가시설' || e.layer === 'pile')
|
||||||
|
);
|
||||||
|
|
||||||
|
const placements = inserts.map(insert => ({
|
||||||
|
blockName: insert.name || 'Unknown',
|
||||||
|
position: {
|
||||||
|
x: insert.position?.x || 0,
|
||||||
|
y: insert.position?.y || 0,
|
||||||
|
z: insert.position?.z || 0
|
||||||
|
},
|
||||||
|
rotation: insert.rotation || 0,
|
||||||
|
scale: insert.scale || { x: 1, y: 1, z: 1 }
|
||||||
|
}));
|
||||||
|
|
||||||
|
console.log(` 추출된 INSERT 블록: ${inserts.length}개`);
|
||||||
|
return placements;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 부재 3D 생성
|
||||||
|
function createMember3D(blockType, spec, placement) {
|
||||||
|
const dims = spec.dimensions;
|
||||||
|
let geometry, volume, userData;
|
||||||
|
|
||||||
|
const color = getColor(spec.type);
|
||||||
|
const material = new THREE.MeshStandardMaterial({ color, roughness: 0.7 });
|
||||||
|
|
||||||
|
if (spec.type === 'Pile') {
|
||||||
|
// 파일: 사각형 단면
|
||||||
|
geometry = new THREE.BoxGeometry(dims.width, dims.height, dims.depth);
|
||||||
|
// 부피는 cm³를 m³로 변환
|
||||||
|
volume = (dims.width * dims.height * dims.depth) / (COORD_SCALE * COORD_SCALE * COORD_SCALE) / 1e6;
|
||||||
|
|
||||||
|
} else if (spec.type === 'Panel') {
|
||||||
|
// 판재
|
||||||
|
geometry = new THREE.BoxGeometry(dims.width, dims.height, dims.thickness);
|
||||||
|
volume = (dims.width * dims.height * dims.thickness) / (COORD_SCALE * COORD_SCALE * COORD_SCALE) / 1e6;
|
||||||
|
|
||||||
|
} else if (spec.type === 'H-Beam') {
|
||||||
|
// H-빔
|
||||||
|
geometry = new THREE.BoxGeometry(dims.width, dims.height, dims.depth);
|
||||||
|
volume = (dims.width * dims.height * dims.depth) / (COORD_SCALE * COORD_SCALE * COORD_SCALE) / 1e6;
|
||||||
|
|
||||||
|
} else if (spec.type === 'Strut') {
|
||||||
|
// 버팀목
|
||||||
|
geometry = new THREE.BoxGeometry(dims.width, dims.height, dims.depth);
|
||||||
|
volume = (dims.width * dims.height * dims.depth) / (COORD_SCALE * COORD_SCALE * COORD_SCALE) / 1e6;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!geometry) return null;
|
||||||
|
|
||||||
|
const mesh = new THREE.Mesh(geometry, material);
|
||||||
|
// 좌표: m 단위를 cm로 변환해서 표시
|
||||||
|
mesh.position.set(
|
||||||
|
placement.position.x * COORD_SCALE,
|
||||||
|
placement.position.y * COORD_SCALE,
|
||||||
|
placement.position.z * COORD_SCALE
|
||||||
|
);
|
||||||
|
|
||||||
|
userData = {
|
||||||
|
blockType: blockType,
|
||||||
|
type: spec.type,
|
||||||
|
spec: spec.spec,
|
||||||
|
position: placement.position,
|
||||||
|
volume: volume
|
||||||
|
};
|
||||||
|
|
||||||
|
return { mesh, volume, userData };
|
||||||
|
}
|
||||||
|
|
||||||
|
function getColor(type) {
|
||||||
|
const colors = {
|
||||||
|
'Pile': 0x7ed321,
|
||||||
|
'Panel': 0x4a90e2,
|
||||||
|
'H-Beam': 0xff6b6b,
|
||||||
|
'Strut': 0xf5a623,
|
||||||
|
'Unknown': 0x999999
|
||||||
|
};
|
||||||
|
return colors[type] || 0x999999;
|
||||||
|
}
|
||||||
|
|
||||||
|
function exportOBJ(scene, filename) {
|
||||||
|
let objContent = '# DXF to 3D (Correct V3 - Analyzed)\n';
|
||||||
|
objContent += `# Generated: ${new Date().toISOString()}\n`;
|
||||||
|
objContent += '# Coordinate: meter (m), scaled to cm for display\n';
|
||||||
|
objContent += '# INSERT scale: 5000x applied\n\n';
|
||||||
|
|
||||||
|
let vertexIndex = 1;
|
||||||
|
const meshes = [];
|
||||||
|
|
||||||
|
scene.traverse((object) => {
|
||||||
|
if (object instanceof THREE.Mesh) {
|
||||||
|
meshes.push(object);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const mesh of meshes) {
|
||||||
|
const geometry = mesh.geometry;
|
||||||
|
const position = geometry.getAttribute('position');
|
||||||
|
|
||||||
|
if (position) {
|
||||||
|
for (let i = 0; i < position.count; i++) {
|
||||||
|
const x = position.getX(i) + mesh.position.x;
|
||||||
|
const y = position.getY(i) + mesh.position.y;
|
||||||
|
const z = position.getZ(i) + mesh.position.z;
|
||||||
|
objContent += `v ${x.toFixed(2)} ${y.toFixed(2)} ${z.toFixed(2)}\n`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const index = geometry.getIndex();
|
||||||
|
if (index) {
|
||||||
|
for (let i = 0; i < index.count; i += 3) {
|
||||||
|
const a = index.getX(i) + vertexIndex;
|
||||||
|
const b = index.getX(i + 1) + vertexIndex;
|
||||||
|
const c = index.getX(i + 2) + vertexIndex;
|
||||||
|
objContent += `f ${a} ${b} ${c}\n`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vertexIndex += position ? position.count : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.writeFileSync(filename, objContent, 'utf-8');
|
||||||
|
}
|
||||||
|
|
||||||
|
await generateCorrect3DV3();
|
||||||
Reference in new issue
Block a user