import numpy as np import tempfile from pathlib import Path import pytest def _make_tiny_ply(path: Path) -> None: import open3d as o3d pcd = o3d.geometry.PointCloud() pts = np.random.rand(1000, 3).astype(np.float64) pcd.points = o3d.utility.Vector3dVector(pts) o3d.io.write_point_cloud(str(path), pcd) def test_decimate_reduces_points(): from scripts.pre_decimate import decimate_ply with tempfile.TemporaryDirectory() as tmp: src = Path(tmp) / "model.ply" dst = Path(tmp) / "model_decimated.ply" _make_tiny_ply(src) decimate_ply(str(src), str(dst), max_pts=100) import open3d as o3d pcd = o3d.io.read_point_cloud(str(dst)) # voxel downsampling is approximate — assert significantly fewer than original 1000 assert len(pcd.points) < 500 def test_decimate_small_cloud_unchanged(): from scripts.pre_decimate import decimate_ply with tempfile.TemporaryDirectory() as tmp: src = Path(tmp) / "small.ply" dst = Path(tmp) / "small_decimated.ply" _make_tiny_ply(src) decimate_ply(str(src), str(dst), max_pts=5000) import open3d as o3d pcd = o3d.io.read_point_cloud(str(dst)) assert len(pcd.points) == 1000 def test_decimate_missing_src_raises(): from scripts.pre_decimate import decimate_ply with tempfile.TemporaryDirectory() as tmp: with pytest.raises(FileNotFoundError): decimate_ply("/nonexistent.ply", str(Path(tmp) / "out.ply")) def test_find_ply_candidates(): from scripts.pre_decimate import find_ply with tempfile.TemporaryDirectory() as tmp: d = Path(tmp) assert find_ply(d) is None (d / "model.ply").touch() assert find_ply(d) == d / "model.ply"