diff --git a/B04_PreProcess/B04_PreProcess_Engine_SheetSurface.py b/B04_PreProcess/B04_PreProcess_Engine_SheetSurface.py index 113b5527..c4cb0df1 100644 --- a/B04_PreProcess/B04_PreProcess_Engine_SheetSurface.py +++ b/B04_PreProcess/B04_PreProcess_Engine_SheetSurface.py @@ -27,8 +27,6 @@ from pyproj import Transformer from B04_PreProcess.B04_PreProcess_Engine_ModelContext import ( atomic_npz, clip_and_compact_mesh, - evaluate_nurbs_spline, - fit_nurbs_spline, grid_faces, grid_vertices, write_glb, @@ -43,9 +41,6 @@ from config.config_system import ( SHEET_SURFACE_MARGIN_M, SHEET_SURFACE_METHODS, SURFACE_MAX_PREVIEW_VERTICES, - SURFACE_NURBS_CONTROL_POINTS_PER_AXIS, - SURFACE_NURBS_DEGREE, - SURFACE_NURBS_PATCH_SIZE_M, SURFACE_SMOOTHING_DTM_PREVIEW_RESOLUTION_M, SURFACE_SMOOTHING_DTM_SIGMA_M, SURFACE_SMOOTHING_DTM_SPLINE_SMOOTH, @@ -106,45 +101,18 @@ def _load_features_metric( def _preview_mesh( x: np.ndarray, y: np.ndarray, z: np.ndarray, valid: np.ndarray ) -> tuple[np.ndarray, np.ndarray]: - """프리뷰용 정점·면 — 격자를 그대로 잇지 않고 **NURBS(B-spline) 곡면**으로 만든다. + """프리뷰용 정점·면 — 정점 수가 상한을 넘으면 격자를 성기게 딴다. - 격자 삼각형을 그대로 쓰면 1m 셀 경계가 계단처럼 보인다. LAS 파이프라인이 쓰는 - 것과 같은 곡면 적합(`fit_nurbs_spline`·`evaluate_nurbs_spline`)을 걸어 매끈한 - 면을 얻는다(2026-08-30 사용자 지시). **표고 정본(npz)은 격자 그대로**이고 여기서 - 바꾸는 것은 화면에 보이는 메시뿐이다 — 종·횡단은 격자를 샘플링한다. - - 적합에 쓰는 제어 간격은 LAS NURBS와 같은 config 값(패치 크기 ÷ 축당 제어점 수)이며, - 제어 격자가 격자보다 성기지 않도록 최소 1셀로 묶는다. + 격자를 그대로 잇는다. 한때 NURBS 곡면을 걸었으나(2026-08-30) DTM 스무딩이 + 들어오면서 곡면 적합이 이중으로 걸려 되돌렸다 — 스무딩은 표고 정본(npz)에서 + 한 번만 한다. """ stride = 1 while (len(x) // stride + 1) * (len(y) // stride + 1) > SURFACE_MAX_PREVIEW_VERTICES: stride += 1 px, py = x[::stride], y[::stride] - pv = valid[::stride, ::stride] - - cell_m = float(x[1] - x[0]) if len(x) > 1 else SHEET_SURFACE_GRID_M - control_m = max( - SURFACE_NURBS_PATCH_SIZE_M / max(SURFACE_NURBS_CONTROL_POINTS_PER_AXIS - 1, 1), cell_m - ) - control_step = max(1, int(round(control_m / max(cell_m, 1e-6)))) - # 곡면 적합은 결측을 못 받는다 — 무효 셀은 가장 가까운 유효 표고로 메우고, - # 메시를 자를 때 원래 유효 마스크로 다시 도려낸다. - filled = z.astype(np.float64) - if not valid.all(): - from scipy.ndimage import distance_transform_edt - - _, (rows, cols) = distance_transform_edt(~valid, return_indices=True) - filled = filled[rows, cols] - cx, cy = x[::control_step], y[::control_step] - cz = filled[::control_step, ::control_step] - try: - spline, z_range = fit_nurbs_spline(cx, cy, cz, SURFACE_NURBS_DEGREE) - pz = evaluate_nurbs_spline(spline, py, px, z_range, "도엽 서피스") - except Exception as exc: # noqa: BLE001 — 적합 실패 시 격자 메시로 되돌린다 - logger.warning("도엽 서피스: NURBS 곡면 적합 실패(%s) — 격자 메시를 씁니다.", exc) - pz = filled[::stride, ::stride] - - vertices = grid_vertices(px, py, np.asarray(pz, dtype=np.float64)) + pz, pv = z[::stride, ::stride], valid[::stride, ::stride] + vertices = grid_vertices(px, py, pz.astype(np.float64)) faces = grid_faces(len(py), len(px)) return clip_and_compact_mesh(vertices, faces, pv.reshape(-1))