feat: initial commit - massive-cloud point cloud processing system
This commit is contained in:
104
alg/point_porj/config_loader.py
Normal file
104
alg/point_porj/config_loader.py
Normal file
@@ -0,0 +1,104 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from copy import deepcopy
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
import yaml
|
||||
|
||||
|
||||
DEFAULT_CONFIG: dict[str, Any] = {
|
||||
"paths": {
|
||||
"cad": "CAD/11.step",
|
||||
"mesh": "Mesh/11.stl",
|
||||
"pointcloud": "PointCloud/11.ply",
|
||||
"noisy_pointcloud": "Noise_PointCloud/11_noisy.ply",
|
||||
"output_mesh": "Mesh/11.stl",
|
||||
"curvature_output": None,
|
||||
},
|
||||
"cad": {
|
||||
"precision": 1.0,
|
||||
"enabled": False,
|
||||
},
|
||||
"noise": {
|
||||
"enabled": True,
|
||||
"std": 4.0,
|
||||
"seed": None,
|
||||
},
|
||||
"filters": {
|
||||
"enabled": True,
|
||||
"methods": ["SOR"],
|
||||
"sor_neighbors": 20,
|
||||
"sor_std_ratio": 2.0,
|
||||
"ror_points": 5,
|
||||
"ror_radius": 20.0,
|
||||
"voxel_size": 0.05,
|
||||
"pass_axis": "z",
|
||||
"pass_min": None,
|
||||
"pass_max": None,
|
||||
"bf_sigma_s": 0.01,
|
||||
"bf_sigma_r": 0.1,
|
||||
},
|
||||
"registration": {
|
||||
"voxel_size": 10.0,
|
||||
"roll": 10.0,
|
||||
"pitch": 10.0,
|
||||
"yaw": 10.0,
|
||||
"trans_range": 0.0,
|
||||
"random_seed": None,
|
||||
},
|
||||
"evaluation": {
|
||||
"chunk_size": 2048,
|
||||
"triangle_chunk_size": 4096,
|
||||
"cad_mesh_deflection": 0.1,
|
||||
},
|
||||
"curvature": {
|
||||
"radius": 2.0,
|
||||
"max_nn": 30,
|
||||
"color_scale": 3.0,
|
||||
},
|
||||
"plane": {
|
||||
"size_mm": 1000.0,
|
||||
"noise_std_mm": 0.5,
|
||||
"num_points": 10000,
|
||||
"threshold_mm": 0.5,
|
||||
"max_iterations": 2000,
|
||||
},
|
||||
"visualization": {
|
||||
"enabled": True,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def deep_update(base: dict[str, Any], updates: dict[str, Any]) -> dict[str, Any]:
|
||||
result = deepcopy(base)
|
||||
for key, value in updates.items():
|
||||
if isinstance(value, dict) and isinstance(result.get(key), dict):
|
||||
result[key] = deep_update(result[key], value)
|
||||
else:
|
||||
result[key] = value
|
||||
return result
|
||||
|
||||
|
||||
class ConfigLoader:
|
||||
"""Load YAML config and merge it with project defaults."""
|
||||
|
||||
def __init__(self, default_config: dict[str, Any] | None = None) -> None:
|
||||
self.default_config = default_config or DEFAULT_CONFIG
|
||||
|
||||
def load(self, config_path: str | None = None) -> dict[str, Any]:
|
||||
config = deepcopy(self.default_config)
|
||||
if not config_path:
|
||||
return config
|
||||
|
||||
path = Path(config_path)
|
||||
if not path.exists():
|
||||
raise FileNotFoundError(f"Config file not found: {path}")
|
||||
|
||||
with path.open("r", encoding="utf-8") as f:
|
||||
user_config = yaml.safe_load(f) or {}
|
||||
|
||||
if not isinstance(user_config, dict):
|
||||
raise ValueError("Config file must contain a YAML mapping at the top level.")
|
||||
|
||||
return deep_update(config, user_config)
|
||||
Reference in New Issue
Block a user