설계툴 검토
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
|
||||
import { AcApDocManager } from "@mlightcad/cad-simple-viewer";
|
||||
import {
|
||||
acdbHostApplicationServices,
|
||||
AcCmColor,
|
||||
AcDbLayerTableRecord,
|
||||
AcDbLine,
|
||||
@@ -113,7 +114,14 @@ export function mountPocCadViewer(host: HTMLElement, drawing: CadDrawingJson): n
|
||||
if (!drawingLoaded) {
|
||||
appended = loadDrawingIntoDatabase(manager, drawing);
|
||||
drawingLoaded = true;
|
||||
|
||||
// 파일 오픈 흐름이 아니므로 layoutSwitched 이벤트를 직접 발화해야
|
||||
// 뷰가 레이아웃 뷰 생성·가시화·초기 줌을 수행한다 (미발화 시 빈 화면).
|
||||
const db = manager.curDocument.database;
|
||||
const modelSpaceBtrId = db.tables.blockTable.modelSpace.objectId;
|
||||
manager.setActiveLayout();
|
||||
acdbHostApplicationServices().layoutManager.setCurrentLayoutBtrId(modelSpaceBtrId, db);
|
||||
manager.curView.zoomToFitDrawing();
|
||||
}
|
||||
manager.curView.zoomToFitDrawing();
|
||||
return appended;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
/* =============================================================================
|
||||
* B07_wf4_DesignDetail_UI_Page.ts
|
||||
* 로그인 후 07: 4차 워크플로우 (상세 설계) — WebCAD PoC
|
||||
* 로그인 후 07: 4차 워크플로우 (상세 설계) — WebCAD 전체 앱 임베드
|
||||
*
|
||||
* 레이아웃 (PLAN.md WebCAD 사용자 지시):
|
||||
* - 사이드 패널: 빈 상태 유지 (B06→B07 전달 데이터 스펙 미확정)
|
||||
* - 상세 페이지 영역: CAD 뷰어 (서버 기하 JSON 렌더링, DXF 파싱 없음)
|
||||
* 방향 전환 (PLAN.md 2026-07-19): 코어 조립이 아니라 완성된 오픈소스 CAD 앱
|
||||
* (external_program/cad-viewer-example, GPL 워커 제외 빌드)을 /cadviewer 정적
|
||||
* 경로로 서빙하고 iframe으로 임베드한다. 데이터 연동은 후속 단계.
|
||||
*
|
||||
* 레이아웃 (사용자 지시): 사이드 패널 빈 상태 유지 + 상세 영역 CAD 화면.
|
||||
* 제약 준수 (frontend.md §2 3단 레이아웃): createWorkflowLayout 재사용.
|
||||
* ========================================================================== */
|
||||
|
||||
@@ -19,8 +21,9 @@ import {
|
||||
WORKFLOW_STEP_ROUTES,
|
||||
type WorkflowState,
|
||||
} from "../A00_Common/b_workflow_nav";
|
||||
import { fetchPocSampleDrawing } from "./B07_wf4_DesignDetail_Api_Fetch";
|
||||
import { mountPocCadViewer } from "./B07_wf4_DesignDetail_UI_CadViewer";
|
||||
|
||||
/** WebCAD 전체 앱 정적 경로 (main.py /cadviewer 마운트, dev는 vite proxy 위임) */
|
||||
const CAD_VIEWER_APP_URL = "/cadviewer/index.html";
|
||||
|
||||
/** locale 헬퍼 */
|
||||
function L(key: keyof typeof ui_locales): string {
|
||||
@@ -57,10 +60,11 @@ export async function renderB07DesignDetail(root: HTMLElement): Promise<void> {
|
||||
|
||||
const cadHost = document.createElement("div");
|
||||
cadHost.className = "b07-cad-host";
|
||||
const status = document.createElement("div");
|
||||
status.className = "b07-cad-status";
|
||||
status.textContent = L("B07_Cad_Loading");
|
||||
cadHost.append(status);
|
||||
const frame = document.createElement("iframe");
|
||||
frame.className = "b07-cad-frame";
|
||||
frame.src = CAD_VIEWER_APP_URL;
|
||||
frame.title = L("B07_Design_Title");
|
||||
cadHost.append(frame);
|
||||
|
||||
const layout = createWorkflowLayout({
|
||||
title: L("B07_Design_Title"),
|
||||
@@ -77,14 +81,4 @@ export async function renderB07DesignDetail(root: HTMLElement): Promise<void> {
|
||||
});
|
||||
layout.root.classList.add("b07-design-layout");
|
||||
root.replaceChildren(layout.root);
|
||||
|
||||
try {
|
||||
const drawing = await fetchPocSampleDrawing();
|
||||
mountPocCadViewer(cadHost, drawing);
|
||||
status.remove();
|
||||
} catch (error) {
|
||||
status.textContent = `${L("B07_Cad_Load_Failed")} ${
|
||||
error instanceof Error ? error.message : ""
|
||||
}`.trim();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,15 @@
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* WebCAD 전체 앱 임베드 (iframe) */
|
||||
.b07-cad-frame {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* 로딩·오류 상태 메시지 */
|
||||
.b07-cad-status {
|
||||
position: absolute;
|
||||
|
||||
Submodule
+1
Submodule external_program/cad-viewer added at 7b9a8084d7
Submodule
+1
Submodule external_program/cad-viewer-example added at 482a061c44
@@ -223,6 +223,15 @@ app.mount(
|
||||
)
|
||||
logger.info(f"✓ 정적 파일 서빙 경로 등록: {STATIC_URL} → {STATIC_DIR}")
|
||||
|
||||
# WebCAD 전체 앱 (external_program/cad-viewer-example 빌드본, GPL 워커 제외) — B07 iframe용
|
||||
CADVIEWER_DIST_DIR = str(Path(__file__).parent / "external_program" / "cad-viewer-example" / "dist")
|
||||
app.mount(
|
||||
"/cadviewer",
|
||||
StaticFiles(directory=CADVIEWER_DIST_DIR, html=True, check_dir=False),
|
||||
name="cadviewer",
|
||||
)
|
||||
logger.info(f"✓ WebCAD 정적 서빙 경로 등록: /cadviewer → {CADVIEWER_DIST_DIR}")
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────
|
||||
# 기본 엔드포인트
|
||||
# ─────────────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
import sys
|
||||
import traceback
|
||||
from pathlib import Path
|
||||
import numpy as np
|
||||
|
||||
# Add project root to sys.path
|
||||
PROJECT_ROOT = Path(__file__).resolve().parent.parent
|
||||
sys.path.insert(0, str(PROJECT_ROOT))
|
||||
|
||||
from B04_wf1_Surface.B04_wf1_Surface_Engine_VWorld import download_vworld_satellite_map
|
||||
from B04_wf1_Surface.B04_wf1_Surface_Engine_GisVector import download_all_gis_vectors
|
||||
|
||||
PRJ_PATH = PROJECT_ROOT / "storage/1/3/acb9170b-9ac8-49b3-82a0-51cfa32bb42d/B03_FileInput/input/prj/result.prj"
|
||||
NPZ_PATH = PROJECT_ROOT / "storage/1/3/acb9170b-9ac8-49b3-82a0-51cfa32bb42d/B04_wf1_Surface/processed/ground_points_csf.npz"
|
||||
OUTPUT_DIR = PROJECT_ROOT / "storage/1/3/acb9170b-9ac8-49b3-82a0-51cfa32bb42d/B04_wf1_Surface/processed"
|
||||
|
||||
def main():
|
||||
print("Loading NPZ to get bounds...")
|
||||
with np.load(NPZ_PATH) as data:
|
||||
bounds = data["bounds"]
|
||||
print("Raw bounds:", bounds)
|
||||
|
||||
bounds_dict = {
|
||||
"x": [float(bounds[0, 0]), float(bounds[0, 1])],
|
||||
"y": [float(bounds[1, 0]), float(bounds[1, 1])],
|
||||
"z": [float(bounds[2, 0]), float(bounds[2, 1])],
|
||||
}
|
||||
|
||||
print("\n--- Test 1: VWorld Satellite Map Download ---")
|
||||
try:
|
||||
res = download_vworld_satellite_map(
|
||||
prj_path=PRJ_PATH,
|
||||
bounds=bounds_dict,
|
||||
output_dir=OUTPUT_DIR,
|
||||
layer_name="Satellite",
|
||||
ext="jpeg"
|
||||
)
|
||||
print("Download Result:", res)
|
||||
except Exception as e:
|
||||
print("VWorld Download Failed:")
|
||||
traceback.print_exc()
|
||||
|
||||
print("\n--- Test 2: GIS Vector Download ---")
|
||||
try:
|
||||
download_all_gis_vectors(
|
||||
prj_path=PRJ_PATH,
|
||||
bounds_meter=bounds_dict,
|
||||
output_dir=OUTPUT_DIR
|
||||
)
|
||||
print("GIS Vector Download completed.")
|
||||
except Exception as e:
|
||||
print("GIS Download Failed:")
|
||||
traceback.print_exc()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -170,6 +170,12 @@
|
||||
--card-padding: 24px;
|
||||
--element-gap: 8px;
|
||||
|
||||
/* Scrollbar */
|
||||
--color-scrollbar-track: color-mix(in srgb, var(--color-text) 9%, transparent);
|
||||
--color-scrollbar-thumb: color-mix(in srgb, var(--color-text) 38%, transparent);
|
||||
--color-scrollbar-thumb-hover: color-mix(in srgb, var(--color-text) 56%, transparent);
|
||||
--color-scrollbar-thumb-active: color-mix(in srgb, var(--color-text) 72%, transparent);
|
||||
|
||||
/* 워크플로우 3단 레이아웃 (frontend.md §2) */
|
||||
--wf-header-height: 56px; /* 상단: 타이틀 + 진행 단계 */
|
||||
--wf-left-panel-width: 320px; /* 좌측: 입력 폼 (너비 고정) */
|
||||
@@ -271,6 +277,44 @@
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Keep the platform scrollbar footprint while giving every scroll container a
|
||||
* consistent translucent treatment. Width/height are intentionally untouched. */
|
||||
* {
|
||||
scrollbar-color: var(--color-scrollbar-thumb) var(--color-scrollbar-track);
|
||||
scrollbar-width: auto;
|
||||
}
|
||||
|
||||
@supports selector(::-webkit-scrollbar) {
|
||||
* {
|
||||
scrollbar-color: auto;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-track {
|
||||
background-color: var(--color-scrollbar-track);
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-thumb {
|
||||
border: 3px solid transparent;
|
||||
border-radius: var(--radius-pills);
|
||||
background-color: var(--color-scrollbar-thumb);
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-thumb:hover {
|
||||
background-color: var(--color-scrollbar-thumb-hover);
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-thumb:active {
|
||||
background-color: var(--color-scrollbar-thumb-active);
|
||||
}
|
||||
}
|
||||
|
||||
@media (forced-colors: active) {
|
||||
* {
|
||||
scrollbar-color: auto;
|
||||
}
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
|
||||
@@ -41,6 +41,11 @@ export default {
|
||||
target: "http://localhost:8000",
|
||||
changeOrigin: true,
|
||||
},
|
||||
// WebCAD 전체 앱 (B07 iframe) — FastAPI 정적 마운트로 위임
|
||||
"/cadviewer": {
|
||||
target: "http://localhost:8000",
|
||||
changeOrigin: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
build: {
|
||||
|
||||
Reference in New Issue
Block a user