feat(640-2): implicit 점 수 = 지면점 비율 · 격자 칸 뽑기 · 설정 지문 바뀌면 다시 지음

- SURFACE_IMPLICIT_POINT_RATIO 0.175 · _MIN_POINTS 5 만 · _MAX_POINTS 200 만(옛 _MAX_POINTS_PER_TILE 걷음)
- TerrainContext.grid_sample — 칸 = √(외곽 넓이 / 점 수) · 씨앗 558 · 칸마다 하나 · 모자라면 무작위 채움(sample() 그대로)
- 짓기 캐시 흠 — manifest 항목 완료일 때만 재사용(지문 바뀐 뒤 implicit · nurbs · meshfree 옛 파일 재사용 막음)
- 지킴 시험 test_640_lidar_default 점 수 · 격자 뽑기 · 지문 다시 지음

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-01 21:25:08 +09:00
co-authored by Claude Opus 5.5
parent 366fd7a700
commit 437333c7af
5 changed files with 105 additions and 23 deletions
@@ -168,11 +168,19 @@ def build_nurbs(
)
def implicit_point_count(ground_count: int, config: dict[str, Any]) -> int:
"""implicit 중심점 수 = clip(지면점 × 비율, 하한, 상한) · 지면점이 하한보다 적으면 전부."""
minimum = int(config["implicit_min_points"])
if ground_count <= minimum:
return int(ground_count)
ratio = round(ground_count * float(config["implicit_point_ratio"]))
return int(min(max(ratio, minimum), int(config["implicit_max_points"])))
def build_implicit(
context: TerrainContext, output_dir: Path, stem: str, progress: ProgressCallback
) -> dict[str, Any]:
maximum = max(100, int(context.config["implicit_max_points_per_tile"]))
points = context.sample(maximum)
points = context.grid_sample(implicit_point_count(context.source_count, context.config))
unique_xy, unique_indices = np.unique(points[:, :2], axis=0, return_index=True)
points = points[unique_indices]
if len(points) < 4: