HYUNJUNGLEE a33a879b41
Some checks failed
CI / Ruff + Test (Py3.11 + Py3.13) (3.11) (push) Failing after 10s
CI / Ruff + Test (Py3.11 + Py3.13) (3.13) (push) Failing after 10s
docs(CHANGELOG): consolidate 2026-05-08 #11 entries — wire 즉시 해소 narrative 정정
직전 커밋 be82843 의 \"scanvas_maker.py wire는 다음 세션\" 표현이 같은 세션 내
후속 커밋 c94b4a7 에서 무효화됐는데, CHANGELOG 본문이 정정되지 않아 같은 날짜에
모순된 두 섹션이 공존했음 (be82843 시점에서는 정확했지만 c94b4a7 이후 false).

본 커밋은 1) 두 개의 2026-05-08 섹션을 하나로 통합하고, 2) scaffold + wire 작업이
실제로는 하나의 의도된 단위(분리 사유는 prompt-injection 의심으로 인한 일시 차단)
임을 \"공정 노트\" 블록에서 명시한다. 코드는 변경 없음 (CHANGELOG.md만).

immutable git history 보존: be82843, c94b4a7 commit message 자체는 수정하지
않음 (force push 회피). narrative 정정은 본 changelog 가 권위 있는 출처가 됨.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 15:41:40 +09:00
2026-05-07 20:18:43 +09:00

S-CANVAS

Generative Design & Visualization Engine CAD 도면(DXF) · 공개 DEM · 위성영상 · Generative AI 를 결합해 건설/토목 프로젝트의 3D 조감도와 구조물 시각화를 자동 생성하는 데스크톱 엔진. Saman Corp. 자체 개발.

Python Platform GUI 3D


1. 프로그램 개요

S-CANVAS 는 토목·건설 도면(DXF)을 클릭 4번에 사실 기반 3D 조감도로 변환하는 자동 파이프라인입니다.

[DXF 도면]                                              [최종 결과물]
   │                                                         ▲
   ▼                                                         │
레이어 분류 → 등고선/구조물 분리                       AI 렌더링 (구조 보존)
   │                                                         ▲
   ▼                                                         │
TIN 생성 (Delaunay 삼각화)                     ← 제어맵 추출 (Depth + Texture)
   │                                                         ▲
   ▼                                                         │
DEM 자동 페치 (AWS Terrarium) → smoothstep blend             │
   │                                                         │
   ▼                                                         │
구조물 자동 빌드 (4단계):                                    │
  ① 위치 인식 (PCA frame)                                    │
  ② 굴착 pad + smoothstep 전이                                │
  ③ TIN 재-Delaunay (수정된 지형)                            │
  ④ 3D 메시 배치 (취수탑/옹벽/수문/제수변실)                 │
   │                                                         │
   ▼                                                         │
위성 타일 UV 매핑 (Seam-free 통합 메시) ────────────────────┘

1.1 핵심 진입점

  • scanvas_maker.py — 메인 GUI 엔트리 (~6,300 LOC, CustomTkinter 기반)
  • splash.py — 인트로 MP4 스플래시 (cv2 + Tk Toplevel)
  • 메인 클래스: SCanvasApp(ctk.CTk) — 사이드바 워크플로 + 메인 맵뷰
  • 상태 저장: %LOCALAPPDATA%\S-CANVAS\ (DB · 로그 · 캐시)

1.2 모듈 구성

모듈 역할
scanvas_maker.py 메인 GUI, Step 1~4 워크플로
dem_extender.py AWS Terrarium DEM 페치 + 도넛 링 메시
geo_referencing.py 4점 매칭 GeoReferencing
structure_placement.py 구조물 위치/방향 자동 인식 + TIN 굴착
structure_templates.py 구조물 유형 레지스트리 (Registry 패턴)
intake_tower_*.py 취수탑 파서 + 3D 빌더
retaining_wall_*.py 옹벽 파서 + 3D 빌더
gate_*.py 수문 파서 + 3D 빌더
valve_chamber_*.py 제수변실 파서 + 3D 빌더
detail_parser.py 상세도면 DXF 치수 파서 (TEXT/MTEXT/DIMENSION)
filename_classifier.py 파일명 → 구조물 유형 추정
dxf_geometry.py DXF 엔티티 → 좌표 추출
tile_downloader.py 위성 XYZ 타일 다운로드
gemini_renderer.py Gemini API/Vertex AI 렌더링 워커
structure_vlm_feedback.py Gemini Vision 기반 구조물 결과 검증
harness/ 품질·재현성·이력 서브시스템 (SQLite + structlog)

1.3 주요 기능

  • TIN 자동 생성: DXF 등고선 → Delaunay 삼각화 → zero-basing
  • DEM 자동 확장: 도면 범위 밖을 AWS 글로벌 DEM 으로 자동 채움 (3-Zone smoothstep 블렌드)
  • 구조물 자동 빌드: 도면 → 4단계 (위치인식 → 굴착 → TIN수정 → 3D배치). 취수탑·옹벽·수문·제수변실
  • Seam-free 통합 메시: merge_points=True + compute_normals(feature_angle=180) 로 도면-DEM 경계 쉐이딩 불연속 제거
  • 위성 타일 UV 매핑: Google / ArcGIS / Bing / Vworld 등 9종 지원
  • AI 조감도 렌더링: Gemini (Vertex / API Key) + Stability AI 3단계 폴백
  • VLM 피드백 루프: Gemini Vision 으로 빌더 결과 ↔ 원본 도면 자동 검증
  • 결정론적 재현성 (Harness): DXF 해시 → seed → 같은 입력 → 같은 출력
  • 자동 품질 검증: OpenCV 기반 해상도/선명도/채도 게이트

1.4 구조물 자동 빌드 워크플로 (핵심 차별화)

위성지도 결합 이전 에 실행되어 TIN 자체를 수정합니다. 구조물이 자연스럽게 지형에 묻히도록 4단계로 처리:

단계 내용 핵심 모듈
① 위치 인식 DXF 폴리곤 추출 → PCA 로 frame 방향 결정 structure_placement.py (compute_orientation_from_points)
② 굴착 (Excavation) 폴리곤 평탄 pad + smoothstep 전이 — 구조물 발자국 영역만 매끈하게 structure_placement.py (apply_placement)
③ TIN 수정 굴착된 영역으로 Delaunay 재계산 → 메시 재구성 scanvas_maker.py 내부
④ 3D 메시 배치 4개 quad 코너에 fit + embed_offset 으로 TIN 관통 방지 structure_placement.py (fit_meshes_to_quad)

지원 구조물 4종 (structure_types/structure_v1.yaml 정의):

유형 빌더 입력
취수탑 (Intake Tower) intake_tower_3d_builder.py DXF 평면도 → 외곽 폴리곤 + 높이
옹벽 (Retaining Wall) retaining_wall_3d_builder.py DXF 단면도 → 단면 형상 + 길이
수문 (Gate) gate_3d_builder.py DXF 정면도 → 게이트 + 슬라브
제수변실 (Valve Chamber) valve_chamber_3d_builder.py DXF 평면도 → 박스 + 슬래브 + 점검구

자동 분류: filename_classifier.py 가 파일명 (예: "신설 취수탑.dxf") 으로 1차 후보 제시 → 사용자가 GUI 다이얼로그에서 최종 확정 → structure_templates.REGISTRY 가 적절한 빌더로 라우팅.

치수 자동 추출: detail_parser.py 가 DXF TEXT/MTEXT/DIMENSION 엔티티에서 치수값 파싱 → 빌더 파라미터로 변환 (수동 입력 불필요).

메시 방향 보정 (디버깅에서 얻은 교훈):

  • CW(시계방향) picks + Y-flip + detail/TIN 상대회전 + PCA frame_angle
  • → 앞뒤 뒤집힘 / 좌우 반전 문제 자동 해결

VLM 검증 루프: 빌드 완료 후 structure_vlm_feedback.py 가 렌더 결과와 원본 DXF 평면도를 Gemini Vision 에 동시 전송 → 차이점 자연어 응답 → 사용자가 재시도 결정.


2. 필수 Package

2.1 시스템 요구사항

  • Python: 3.9+ (권장 3.11+, 빌드 머신 검증 = 3.9.13)
  • Platform: Windows 10/11 (Linux/macOS 는 GUI 일부 제한)
  • 메모리: 8GB+ (PyVista + VTK + 위성 타일 캐시)
  • 디스크: 1GB+ 여유 (DEM/타일 캐시 포함)

2.2 설치

pip install -r requirements.txt

2.3 카테고리별 패키지

[GUI]
customtkinter==5.2.2       모던 Tk 기반 GUI 프레임워크
tkintermapview==1.29       위성 지도 인터랙티브 뷰
Pillow==11.3.0             이미지 처리 (PIL)

[3D / Mesh]
pyvista==0.46.5            메시 처리 + 렌더링 (VTK 자동 설치, ~150MB)

[Geospatial / DXF]
ezdxf==1.4.2               DXF 파싱 (R12~R2024)
pyproj==3.6.1              좌표계 변환 (EPSG)
rasterio==1.4.3            (선택) 로컬 GeoTIFF DEM (NGII 5m 등)

[Numerical]
numpy==2.0.2
scipy==1.13.1              Delaunay 삼각화, KDTree
matplotlib==3.9.4          signed-distance polygon paths

[Image / Video]
opencv-python==4.13.0.92   인트로 MP4 + Harness QualityValidator

[Network]
requests==2.32.5           HTTP 타일/DEM/AI 페치

[AI Rendering]
google-genai==1.47.0       Gemini SDK (Vertex AI / API Key 통합)
google-auth==2.49.2

[Persistence / Logging]
SQLAlchemy==2.0.49         JobRecord ORM
structlog==25.5.0          구조화 로깅
PyYAML==6.0.3              prompt_v*.yaml / structure_v*.yaml

[Build (선택)]
pyinstaller==6.18.0        Windows .exe 빌드

3. 간단 사용법

3.1 실행

python scanvas_maker.py

실행 흐름:

  1. splash.pyDesign/logo_intro.mp4 8초 인트로 재생 (페이드 인/아웃)
  2. SCanvasApp 메인 창 기동 (1200×900)
  3. 사이드바에서 워크플로 진행

3.2 사이드바 워크플로

SETTINGS
  ├─ Satellite Source         (Google / ArcGIS / Vworld 등 선택)
  ├─ Vworld API Key           (Vworld 사용 시)
  ├─ AI Engine                (Gemini Vertex / Gemini API / Stability)
  ├─ GCP / API Key            (선택한 엔진의 인증 정보)
  └─ Project CRS              (EPSG:5187 / 5186 / 5185 / 5181 / 3857)

WORKFLOW
  1.   TIN 생성 (DXF)            ← DXF 파일 선택 + Delaunay 삼각화
  🎯  TIN 이용 범위               ← (선택) 정밀 보존 영역 지정
  1.5  DEM 으로 TIN 확장          ← AWS Terrarium 도넛 링 메시 추가
  ──  구조물 상세 3D 빌드          ← 위치인식 → 굴착 → TIN수정 → 3D배치
                                    (취수탑·옹벽·수문·제수변실)
  2.   위성지도 결합              ← 위성 타일 다운로드 + UV 매핑
                                    (구조물 굴착 반영된 TIN 위에 매핑)
  3.   제어맵 추출                ← Depth / Texture 캡처 (PyVista offscreen)
  4.   AI 렌더링                 ← 최종 조감도 생성 (Gemini / Stability)

OPTIONS
  ├─ □ 와이어프레임 보기
  ├─ 뷰 버퍼 (%)              (Step 2/3 외곽 여유)
  ├─ □ 지형 확장 (DEM)
  └─ Light / Dark 테마 토글

3.3 결과 파일

파일 의미
rendered_birdseye.png 최종 AI 렌더 결과
capture_textured.png Step 3 위성+DEM 합성 control map
depth_map.png Step 3 깊이 맵
lineart_map.png Step 3 라인아트
guide_composite.png 합성 가이드 이미지
scanvas_jobs.db SQLite 작업 이력 (Harness)
scanvas_harness.log structlog 출력

3.4 인증 / API 키 설정

모든 키는 코드에 하드코딩되지 않습니다. 환경변수 또는 사이드바 입력란을 사용하세요.

환경변수 발급처 용도
GCP Service Account (파일) gcp-key.json GCP Console → IAM Gemini Vertex AI
GCP Project ID GCP_PROJECT_ID (gcp-key.json 자동 추출) Vertex AI 라우팅
GCP Location GCP_LOCATION Vertex AI 리전 (기본 global)
Gemini API Key (UI 입력) aistudio.google.com Gemini API 직접 호출
Stability API Key (UI 입력) platform.stability.ai Stability AI 폴백
Vworld API Key VWORLD_API_KEY vworld.kr/dev 한국 위성 타일 (선택)
Google API Key (VLM) GOOGLE_API_KEY 또는 GEMINI_API_KEY aistudio.google.com structure_vlm_feedback

Windows 환경변수 설정 예:

# 영구 (사용자 환경)
[Environment]::SetEnvironmentVariable("VWORLD_API_KEY", "your-key-here", "User")
[Environment]::SetEnvironmentVariable("GCP_PROJECT_ID", "your-project-id", "User")

# 현재 세션만
$env:VWORLD_API_KEY = "your-key-here"

Gemini Vertex AI (서비스 어카운트):

  1. GCP 프로젝트에서 서비스 어카운트 키 (JSON) 발급
  2. gcp-key.json 을 프로젝트 루트 또는 %LOCALAPPDATA%\S-CANVAS\ 에 배치
  3. 자동으로 GOOGLE_APPLICATION_CREDENTIALS 설정 + project_id 추출
  4. gcp-key.json.gitignore 차단됨 — 절대 커밋 금지

4. URL 기반 외부 데이터 소스

S-CANVAS 가 사용하는 모든 외부 URL 엔드포인트입니다. 인터넷 연결 필요.

4.1 DEM (지형 고도) — 인증 불필요

소스 URL 패턴 비고
AWS Open Terrain Tiles https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png 글로벌, ~30m 정확도, API 키 없음. terrarium PNG 디코딩: elev_m = (R*256 + G + B/256) - 32768. SHA1(bbox+zoom) 캐시 → 재실행 시 네트워크 0

dem_extender.py:48 에 정의 → cache/dem/ 에 PNG 캐시. 로컬 GeoTIFF (cache/dem/local.tif) 가 있으면 우선 사용 (rasterio 필요).

4.2 위성 타일 (Texture)

scanvas_maker.py:248-258 — UI 에서 사용자 선택.

서버 URL 패턴 인증
Google Satellite https://mt{s}.google.com/vt/lyrs=s&x={x}&y={y}&z={z} 불필요
Google Hybrid https://mt{s}.google.com/vt/lyrs=y&x={x}&y={y}&z={z} 불필요
ArcGIS World Imagery https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x} 불필요
ArcGIS Hybrid https://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer/tile/{z}/{y}/{x} 불필요
Bing Aerial https://ecn.t{s}.tiles.virtualearth.net/tiles/a{q}.jpeg?g=1 불필요
OpenStreetMap https://tile.openstreetmap.org/{z}/{x}/{y}.png 불필요
OpenTopo https://tile.opentopomap.org/{z}/{x}/{y}.png 불필요
Vworld 위성 https://api.vworld.kr/req/wmts/1.0.0/{vworld_key}/Satellite/{z}/{y}/{x}.jpeg Vworld 키 필요
Vworld 기본 https://api.vworld.kr/req/wmts/1.0.0/{vworld_key}/Base/{z}/{y}/{x}.png Vworld 키 필요
Vworld 하이브리드 https://api.vworld.kr/req/wmts/1.0.0/{vworld_key}/Hybrid/{z}/{y}/{x}.png Vworld 키 필요

tile_downloader.py:11 에서 tile.openstreetmap.org 폴백 처리.

4.3 AI 렌더링 — 인증 필수

엔진 엔드포인트 인증 방식
Gemini (Vertex AI) google-genai SDK 내부 호출 GCP Service Account (gcp-key.json) — GOOGLE_APPLICATION_CREDENTIALS 자동 설정
Gemini (API Key) google-genai SDK 내부 호출 aistudio.google.com 키
Stability Conservative Upscale https://api.stability.ai/v2beta/stable-image/upscale/conservative Bearer API Key
Stability Creative Upscale https://api.stability.ai/v2beta/stable-image/upscale/creative Bearer API Key
Stability img2img (sd3.5-large) https://api.stability.ai/v2beta/stable-image/generate/sd3 Bearer API Key

scanvas_maker.py:6432 (Conservative/Creative) · scanvas_maker.py:6477 (img2img) · gemini_renderer.py (Gemini 워커).

Stability 는 3단계 자동 폴백 (Conservative → Creative → img2img).

4.4 위성 지도 미리보기 (GUI)

scanvas_maker.py:572tkintermapview 의 기본 타일 서버:

  • https://mt0.google.com/vt/lyrs=s&x={x}&y={y}&z={z}

GeoReferencing 4점 매칭 시 사용자가 위성 위에 클릭하는 인터랙티브 맵.

4.5 캐시 정책

캐시 위치 내용 무효화 키
cache/dem/ AWS Terrarium PNG 타일 SHA1(bbox + zoom)
cache/tiles/ 위성 타일 PNG URL 해시
scanvas_jobs.db SQLite Job 이력 (재현성) dxf_hash + seed + prompt_hash

오프라인 동작: 캐시 hit 시 네트워크 호출 0회. 첫 실행 후 동일 영역은 오프라인 가능.


5. 좌표계 / 단위

지원 EPSG (사이드바 선택):

EPSG 이름 영역
5187 Korea 2000 / Central Belt 2010 한국 중부 (서울·경기·충청) — 기본값
5186 Korea 2000 / Central Belt 한국 중부 (구)
5185 Korea 2000 / West Belt 2010 한국 서부
5181 Korea 2000 / Unified CS 통합 좌표계
3857 Web Mercator 글로벌 (위성 타일 호환)

단위 강제: DXF $INSUNITS 헤더가 부정확한 경우가 많아 항상 m 로 강제 (unit_override="m"). KATEC 류 대형 좌표값을 mm 로 오판하는 사고 차단.

Zero-Basing: 큰 절대좌표(EPSG:5187 의 200,000m+) 의 float32 정밀도 손실 방지 → bbox 좌하단을 origin 으로 평행이동.


6. 디렉토리 구조

.
├── scanvas_maker.py              # 메인 진입점
├── splash.py                     # 인트로 스플래시
├── requirements.txt              # 의존성
├── S-CANVAS_brief.md             # 상세 기술 문서 (NotebookLM 소스)
├── CHANGELOG.md                  # 수정 이력 (역순)
│
├── dem_extender.py               # DEM 페치/링 메시
├── geo_referencing.py            # 4점 매칭
├── structure_placement.py        # 구조물 배치/굴착
├── structure_templates.py        # 구조물 레지스트리
├── intake_tower_parser.py + _3d_builder.py
├── retaining_wall_parser.py + _3d_builder.py
├── gate_parser.py + _3d_builder.py
├── valve_chamber_parser.py + _3d_builder.py
├── detail_parser.py
├── filename_classifier.py
├── polygon_reconstructor.py
├── dxf_geometry.py
├── tile_downloader.py
├── view_detector.py
├── view_reconstructor.py
├── optional_detector.py
├── gemini_renderer.py
├── structure_vlm_feedback.py
├── resource_paths.py             # PyInstaller 번들/소스 경로 분기
│
├── harness/                      # 품질·재현성 서브시스템
│   ├── seed_manager.py           # DXF 해시 → seed
│   ├── quality_validator.py      # OpenCV 자동 QA
│   ├── prompt_registry.py        # YAML 버전 관리
│   └── logger.py                 # SQLite ORM + structlog
│
├── prompt_templates/
│   └── prompt_v1.yaml            # 시간대/앙각/구조보존 프롬프트
│
├── structure_types/
│   └── structure_v1.yaml         # 구조물 유형 정의
│
├── Design/                       # 브랜딩 자산
│   ├── logo_V2.png
│   ├── SAMAN_CI.gif
│   └── logo_intro.mp4            # 8s, 24fps, 1280×720
│
├── SAMPLE_CAD/                   # 테스트용 DXF 샘플
└── cache/dem/                    # 런타임 DEM 캐시 (gitignore)

7. 추가 문서

  • S-CANVAS_brief.md — 시스템 아키텍처/혁신 포인트/메모리화된 결정 사항 (개발자/리뷰어용 심층 자료)
  • CHANGELOG.md — 모든 수정 이력 (역순, 날짜/파일/사유/diff 요지)
  • Build_log.txt — 사용자 원본 요청 이력

8. 라이선스 / 저작권

© 2026 Saman Corp. All rights reserved.

본 프로그램은 Saman Corp. 자체 개발 자산이며, 외부 라이선스가 부여된 패키지는 각 패키지의 라이선스를 따릅니다.

문의: 프로젝트 관리자에게 직접 연락

Description
No description provided
Readme 62 MiB
Languages
Python 98.8%
Batchfile 0.7%
Shell 0.5%