diff --git a/public/analysis/도면분석.md b/public/analysis/도면분석.md new file mode 100644 index 0000000..6a898a8 --- /dev/null +++ b/public/analysis/도면분석.md @@ -0,0 +1,48 @@ +# BLOCK8 도면 분석 기록 + +## 사용 자료 + +| 자료 | 파일 | 확인 범위 | +|---|---|---| +| 전체 일반도 DXF | `public/drawings/광터지하차도_BLOCK8.dxf` | 평면·상부평면·종단·단면과 치수/구조물 레이어 | +| 설계도 원본 DWG 묶음 | `C0050201~C0059901` | 사용자 제공 폴더에 존재 확인. 이 환경에서 직접 열람/대조는 미완료 | + +DXF 내부 표제 및 주석에서 `평면도`, `상부평면도`, `종단면도`, `(BLOCK8)`, `U-Type 구간`을 확인했다. 입력 도면은 여러 구간/도면을 포함하므로 BLOCK8 경계 표기로 자료를 선별했다. + +## 도면 연결 및 기준값 + +| 항목 | 읽은 값 | 근거/위치 | 상태 | +|---|---:|---|---| +| BLOCK8 시점 측점 | STA. 0K+319.010 | 일반도 DXF, BLOCK8 경계 주석 | 도면 명시값 | +| BLOCK8 종점 측점 | STA. 0K+338.990 | 일반도 DXF, BLOCK8 경계 주석 | 도면 명시값 | +| 측점 차이 | 19.980 m | 위 두 측점 차 계산 | 계산으로 도출한 값 | +| 인접 표기 측점 | STA. 0K+319.000, 0K+339.000 | 평면/구조 배치 주변 주석 | 도면 명시값; 경계 측점과 각각 0.010m 차이 | +| 단면 기준 EL 후보(시점) | 101.777~107.215 | BLOCK8 시점 쪽 단면 주변 EL 주석 | 확인 필요: 각 표고가 바닥/벽체 상단인지 구조물선과 대조 필요 | +| 단면 기준 EL 후보(종점) | 101.292~107.857 | BLOCK8 종점 쪽 단면 주변 EL 주석 | 확인 필요: 각 표고가 바닥/벽체 상단인지 구조물선과 대조 필요 | +| 상부/평면 치수 후보 | 19.5, 20.099, 20.3, 8.75, 1.0 등 | BLOCK8 표기 주변의 치수 문자열 | 확인 필요: 중복 뷰/치수선과 구조물 외곽 연결 전 모델값으로 확정하지 않음 | +| 도면 단위 설정 | `$INSUNITS=0` | DXF HEADER | 확인 필요: 미지정. 치수 표기와 좌표 변환으로 단위 검증 필요 | + +## 레이어 및 형상 해석 + +- DXF 모델 공간에는 `CS-CONC-MAJR` 510개, `CS-CONC-MINR` 57개 엔티티가 있다. `CS-DIMT`/`CS-DIML`은 치수, `CS-TEXT`/`CS-NOTE`는 문자·주석으로 구분했다. +- 구조 윤곽 추출은 `CS-CONC-MAJR`, `CS-CONC-MINR`만 대상으로 해야 한다. 단순히 도면 전체 선을 모델링하면 치수선과 보조선이 섞인다. +- 주요 형상 중 일부가 INSERT 블록으로 저장되어 있어 블록 내부 변환(삽입점·축척·회전)을 풀어 원 좌표로 검증해야 한다. 현재 레이어별 원시 개수는 확인했으나, 모든 블록 내부 윤곽의 완전 추출은 아직 끝나지 않았다. +- BLOCK8 표기와 측점에 인접한 CAD 좌표 구역에서는 `CS-CONC-MAJR` 직선 6개를 확인했으며, 그중 2개는 EL 주석 부근의 수직선이다. 같은 2D 창에서 `CS-CONC-MINR` 구조선은 확인되지 않았다. 따라서 이 구역만으로 단면 윤곽 전체를 구성할 근거가 부족하다. +- 평면 중심선과 종단면, 시점·종점 단면, 측구 상세의 동일 부재 대응은 원본 DWG/블록 도형과의 위치 검토가 더 필요하다. + +## 축척 + +DXF HEADER의 `$INSUNITS=0`으로 파일 단위는 지정되지 않았다. 도면 축척 문구를 모든 뷰에서 확인하고, 표기 치수(예: 19.980m)와 CAD 좌표 차이를 비교해 좌표 단위를 확정해야 한다. 이 확인 전에는 화면상 축척 측정값을 도면 명시 치수로 취급하지 않는다. + +## 오류·누락·확인 항목 + +1. 319.000/339.000 표기와 BLOCK8 경계 319.010/338.990 사이에 각각 0.010m 차이가 있다. 어떤 경계를 모델 끝으로 쓸지 구조 이음/상세에서 확인한다. +2. 종단/단면 EL 후보를 벽체 상단 및 중심 기준 EL로 확정하려면 각 주석의 지시선과 CS-CONC 구조선을 연결해야 한다. +3. 단면 전체 윤곽, 두께, 측구/공동구 상세 치수 및 부재 개수는 INSERT 내부 요소까지 추출해 확인해야 한다. +4. 원본 DWG의 제원·특기사항 및 구조도와 교차 대조가 미완료다. + +따라서 현재 확정 가능한 모델 기준은 BLOCK8 경계 측점과 19.980m 길이뿐이다. 미확정 단면 윤곽과 높이는 임의로 만들어 넣지 않는다. + +## 모델 생성 진행 상태 + +현재는 도면 원본 보존과 1차 분석까지 완료했다. 실제 3D 형상 생성은 보류 상태다. 이유는 BLOCK8 단면의 구조물선 전체와 A-A/B-B 대응을 확인하지 못했고, DXF 단위도 미지정이기 때문이다. 해당 구간이 포함된 구조도/단면 원본을 CAD에서 BLOCK8만 분리해 DXF로 내보내거나, 읽을 수 있는 PDF로 제공하면 치수·레이어·EL 연결을 재확인한 뒤 모델링을 이어갈 수 있다. diff --git a/public/작업기록.txt b/public/작업기록.txt new file mode 100644 index 0000000..a537b74 --- /dev/null +++ b/public/작업기록.txt @@ -0,0 +1,24 @@ +광터지하차도 BLOCK8 작업기록 + +※ 초기화 커밋 이전의 이력은 제외하고, 초기화 이후 작업만 기록합니다. +※ 날짜: 2026-10-20 + +1. 작업지침 저장 + - 도면 기반 3D 모델 분석·기록·검증 지침을 AGENTS.md에 저장 + - 커밋: 0adb717 도면 기반 모델 작업지침 추가 + +2. 도면 등록 및 1차 분석 + - BLOCK8 DXF 원본을 프로젝트에 등록 + - 시점 STA. 0K+319.010, 종점 STA. 0K+338.990, 계산 길이 19.980m 기록 + - DXF 단위 미지정, 단면 윤곽 및 EL 연결 확인 필요 사항 기록 + - 커밋: 1783d1f BLOCK8 도면 자료와 1차 분석 기록 추가 + +3. 구조 윤곽 분석 상태 보완 + - BLOCK8 인접 좌표 구역의 구조선 추출 한계와 추가 도면 자료 필요 사항 기록 + - 커밋: 62c7395 BLOCK8 윤곽 추출 한계와 추가 자료 기록 + +4. 모델/자료 보기 화면 추가 + - 확인된 측점 구간을 기준선으로 표시 + - 단면 형상이 미확정임을 웹 화면에 표시 + - 분석 파일과 작업 로그를 웹 화면에서 열 수 있도록 연결 + - 초기화 이후 커밋 이력만 이 파일에 정리 diff --git a/src/App.jsx b/src/App.jsx index 7d00fcf..3967394 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,14 +1,100 @@ -export default function App() { +import { useState } from 'react' + +const views = { + 전체: { transform: 'rotate(-8 450 180) skewY(-2deg)' }, + 평면: { transform: 'rotate(0 450 180)' }, + 정면: { transform: 'rotate(-90 450 180)' }, + 측면: { transform: 'rotate(90 450 180)' }, +} + +function StationModel({ view }) { return ( -
-
- -

새 프로젝트

-

작업을 시작할 준비가 되었습니다

-

- 이 공간은 비어 있습니다. 도면과 작업 내용을 추가해 새 모델을 만들어 보세요. -

+ + BLOCK8 확인된 종단 기준선 + 측점 319.010에서 338.990까지 19.980미터의 기준 구간입니다. 단면 형상은 미확정입니다. + + + + + + + + + + + + + + + + + + 19.980 m · 측점 차이 + STA. 0K+319.010 + STA. 0K+338.990 + + + + 종단 기준EL 기준 미연결 + + + ) +} + +export default function App() { + const [view, setView] = useState('전체') + return ( +
+
+ B8도면 모델 작업실 + 광터지하차도 · BLOCK8 + +
+ +
+
+ 도면 근거가 확인된 범위부터 표시합니다 +

BLOCK8 모델 보기

+

현재 도면에서 확인된 종단 구간 기준선입니다. 구조물 단면은 추가 확인이 필요합니다.

+
+ 단면 윤곽 확인 필요
+ +
+
시점0K+319.010도면 명시값
+
종점0K+338.990도면 명시값
+
구간 길이19.980 m측점 차이로 계산
+
단면 폭 · 높이확인 필요구조선과 EL 연결 전
+
+ +
+
+
3D 기준 보기 · 형상 검토 중

확인된 종단 구간

+
+ {Object.keys(views).map(name => )} +
+
+
선은 측점 범위를 나타냅니다 · 구조물 단면/폭/높이를 표현한 형상이 아닙니다
+
도면 명시 측점으로 계산한 기준선단면 윤곽 · 배치 · EL 연결: 확인 필요
+
+ +
+
+ 진행 상태

분석은 완료, 구조 형상은 미확정

+

도면에서 측점과 구간 길이를 읽었습니다. DXF 단위가 지정되지 않았고 BLOCK8의 전체 구조물 윤곽을 확인하지 못해, 임의의 폭·높이를 넣은 구조물 모델은 표시하지 않습니다.

+ 도면 분석 내용 보기 ↗ +
+
+ 작업 기록

분석 자료와 변경 이력

+

초기화 이후 도면 등록과 분석 기록을 날짜·커밋 단위로 정리했습니다.

+ 작업 로그 파일 열기 ↗ +
+
+
단위 m · 도면 명시값과 계산값을 구분해 표시합니다.
) } diff --git a/src/index.css b/src/index.css index dc5a3b7..6710f55 100644 --- a/src/index.css +++ b/src/index.css @@ -8,9 +8,87 @@ * { box-sizing: border-box; } body { min-width: 320px; min-height: 100vh; margin: 0; } -.welcome { display: grid; min-height: 100vh; place-items: center; padding: 24px; } -.welcome-card { width: min(100%, 560px); padding: 48px 32px; text-align: center; background: #fafcf8; border: 1px solid #dbe4d7; border-radius: 16px; } -.welcome-mark { display: grid; width: 52px; height: 52px; margin: 0 auto 24px; place-items: center; border-radius: 15px; background: #446b58; color: white; font-size: 17px; font-weight: 700; } -.welcome-kicker { margin: 0 0 10px; color: #71877a; font-size: 12px; font-weight: 700; letter-spacing: .08em; } -h1 { margin: 0; font-size: clamp(22px, 5vw, 30px); letter-spacing: -.05em; } -.welcome-description { margin: 16px 0 0; color: #77857b; font-size: 14px; line-height: 1.8; } +a { color: inherit; text-decoration: none; } +button { font: inherit; cursor: pointer; } +.page-shell { width: min(100% - 64px, 1380px); margin: 0 auto; padding-bottom: 25px; } +.topbar { min-height: 72px; display: flex; align-items: center; gap: 20px; border-bottom: 1px solid #d8e0d6; } +.brand { display: inline-flex; align-items: center; gap: 10px; font-size: 14px; font-weight: 700; white-space: nowrap; } +.brand-mark { display: grid; width: 34px; height: 34px; place-items: center; border-radius: 10px; background: #446b58; color: #fff; font-size: 12px; } +.project-chip { color: #819087; font-size: 11px; } +.file-links { display: flex; gap: 8px; margin-left: auto; } +.file-links a { padding: 9px 11px; border: 1px solid #d7dfd4; border-radius: 7px; background: #fafcf8; color: #536d5b; font-size: 11px; white-space: nowrap; } +.file-links a:hover,.text-link:hover { border-color: #89a28d; color: #2d6045; } +.intro { display: flex; align-items: center; justify-content: space-between; gap: 18px; padding: 36px 0 25px; } +.kicker,.eyebrow { display: block; color: #788a7d; font-size: 10px; font-weight: 700; letter-spacing: .08em; } +h1 { margin: 8px 0; font-size: clamp(27px, 4vw, 34px); letter-spacing: -.06em; } +h1 em { margin-left: 7px; color: #778b7d; font-size: .8em; font-style: normal; font-weight: 400; } +.intro p,.info-card p { margin: 0; color: #79877c; font-size: 12px; line-height: 1.8; } +.status-pill { display: inline-flex; align-items: center; gap: 8px; padding: 10px 14px; border: 1px solid #e5dbc2; border-radius: 30px; background: #faf5e9; color: #967641; font-size: 11px; white-space: nowrap; } +.status-pill i { width: 7px; height: 7px; border-radius: 50%; background: #b98f48; } +.summary-grid { display: grid; grid-template-columns: repeat(4, 1fr); margin-bottom: 18px; overflow: hidden; border: 1px solid #dce4d9; border-radius: 11px; background: #fafcf8; } +.summary-grid article { min-height: 112px; padding: 18px 22px; border-right: 1px solid #e3e9e1; } +.summary-grid article:last-child { border: 0; } +.summary-grid span,.summary-grid small { display: block; color: #839084; font-size: 10px; } +.summary-grid strong { display: block; margin: 10px 0 6px; font-family: Georgia,serif; font-size: clamp(19px, 2.5vw, 26px); font-weight: 400; white-space: nowrap; } +.summary-grid strong i { color: #78877c; font-family: sans-serif; font-size: 12px; font-style: normal; } +.summary-grid .unknown strong { color: #a38048; font-family: inherit; font-size: 18px; } +.model-card,.info-card { overflow: hidden; border: 1px solid #dbe4d7; border-radius: 12px; background: #fafcf8; } +.card-heading { display: flex; align-items: center; justify-content: space-between; gap: 15px; padding: 19px 22px 12px; } +h2 { margin: 5px 0 0; font-size: 17px; letter-spacing: -.04em; } +.view-controls { display: flex; gap: 4px; padding: 3px; border-radius: 7px; background: #edf1ea; } +.view-controls button { padding: 7px 11px; border: 0; border-radius: 5px; background: transparent; color: #768579; font-size: 10px; } +.view-controls button.active { background: white; color: #426a50; box-shadow: 0 1px 4px #233c2912; } +.model-stage { position: relative; display: grid; min-height: 330px; place-items: center; overflow: hidden; border-top: 1px solid #e0e7dd; border-bottom: 1px solid #e0e7dd; background: linear-gradient(180deg,#f6f9f5,#edf2ec); } +.model-svg { width: min(100%, 940px); height: auto; min-height: 270px; overflow: visible; } +.model-grid path { fill: none; stroke: #dbe4dc; stroke-width: 1; } +.station-line { transform-box: view-box; transform-origin: center; transition: transform .35s ease; } +.station-shadow { fill: none; stroke: #d2ddd2; stroke-width: 15; stroke-linecap: round; } +.station-main { fill: none; stroke: #547d62; stroke-width: 5; stroke-linecap: round; } +.station-cap { fill: none; stroke: #819782; stroke-width: 2; } +.station-line circle { fill: #fafcf8; stroke: #52785d; stroke-width: 4; } +.dimension { fill: none; stroke: #718b78; stroke-width: 1.5; } +.dimension-tick { fill: none; stroke: #a5b5a5; stroke-width: 1; } +.length-label { fill: #49694f; font-size: 16px; font-weight: 700; } +.endpoint-label { fill: #566e5c; font-size: 12px; } +.axis-labels path { stroke: #758e79; stroke-width: 2; } +.axis-labels text { fill: #809083; font-size: 10px; } +.stage-note { position: absolute; right: 15px; bottom: 12px; color: #9a835b; font-size: 9px; text-align: right; } +.model-caption { display: flex; justify-content: space-between; gap: 14px; padding: 13px 20px; color: #839084; font-size: 10px; } +.model-caption>span:first-child { display: inline-flex; align-items: center; gap: 8px; } +.legend-line { width: 19px; height: 3px; border-radius: 2px; background: #547d62; } +.bottom-grid { display: grid; grid-template-columns: 1.25fr 1fr; gap: 16px; margin-top: 17px; } +.info-card { min-height: 172px; padding: 19px 21px; } +.info-card h2 { margin-bottom: 10px; } +.info-card p { max-width: 720px; } +.text-link { display: inline-flex; align-items: center; gap: 9px; margin-top: 14px; padding: 8px 10px; border: 1px solid #d8e1d6; border-radius: 6px; color: #4b6b52; font-size: 10px; } +.text-link span { font-size: 13px; } +footer { padding-top: 18px; color: #89958a; font-size: 9px; } + +@media (max-width: 760px) { + .page-shell { width: min(100% - 32px, 620px); } + .topbar { flex-wrap: wrap; gap: 10px; padding: 13px 0; } + .project-chip { margin-left: auto; } + .file-links { width: 100%; margin: 0; } + .file-links a { flex: 1; text-align: center; } + .intro { align-items: flex-start; flex-direction: column; padding: 27px 0 19px; } + .summary-grid { grid-template-columns: 1fr 1fr; } + .summary-grid article { min-height: 98px; padding: 15px; border-bottom: 1px solid #e3e9e1; } + .summary-grid article:nth-child(2) { border-right: 0; } + .summary-grid article:nth-child(n+3) { border-bottom: 0; } + .card-heading { align-items: flex-start; flex-direction: column; padding: 17px 15px 12px; } + .model-stage { min-height: 260px; } + .model-svg { min-height: 220px; } + .endpoint-label { font-size: 11px; } + .stage-note { max-width: 260px; line-height: 1.5; } + .model-caption { flex-direction: column; padding: 12px 15px; } + .bottom-grid { grid-template-columns: 1fr; gap: 11px; } + .info-card { min-height: 0; padding: 17px; } +} + +@media (max-width: 400px) { + .file-links { gap: 5px; } + .file-links a { padding: 8px 5px; font-size: 10px; } + .view-controls button { padding: 7px 9px; } + .model-stage { min-height: 220px; } + .length-label { font-size: 13px; } +}