"""Pipeline chain insights (mirrors MainWindow::recomputeInsights).""" from __future__ import annotations from typing import Any def compute_insights( preprocess_plugins: list[str], reconstruction_plugin: str, ) -> dict[str, Any]: warnings: list[str] = [] risk_state = False stages = [s for s in preprocess_plugins if s] voxel_idx = stages.index("pcl_voxel_grid") if "pcl_voxel_grid" in stages else -1 remove_nan_idx = stages.index("pcl_remove_nan") if "pcl_remove_nan" in stages else -1 remove_nan_normals_idx = ( stages.index("pcl_remove_nan_normals") if "pcl_remove_nan_normals" in stages else -1 ) outlier_indexes = [] for stage_id in ( "pcl_statistical_outlier", "pcl_radius_outlier", "pcl_model_outlier", "pcl_shadow_points", ): if stage_id in stages: outlier_indexes.append(stages.index(stage_id)) first_outlier_idx = min(outlier_indexes) if outlier_indexes else -1 if not stages: risk_state = True warnings.append("Добавьте хотя бы один этап препроцессинга перед реконструкцией.") else: if first_outlier_idx < 0: warnings.append("Добавьте outlier removal для стабилизации триангуляции.") if first_outlier_idx >= 0: nan_idxs = [i for i in (remove_nan_idx, remove_nan_normals_idx) if i >= 0] first_nan_preclean_idx = min(nan_idxs) if nan_idxs else -1 if first_nan_preclean_idx < 0 or first_nan_preclean_idx > first_outlier_idx: warnings.append( "Удалите NaN сразу после загрузки/обрезки: иначе статистические фильтры работают нестабильно." ) if voxel_idx >= 0 and first_outlier_idx >= 0 and first_outlier_idx > voxel_idx: warnings.append( "OutlierRemoval стоит после VoxelGrid: лучше сначала очистить шум, затем прореживать." ) if reconstruction_plugin == "pcl_greedy_triangulation" and voxel_idx < 0: warnings.append("Greedy triangulation обычно работает лучше после voxel downsampling.") if risk_state: chain_health = "Risk" recommendation = warnings[0] if warnings else "Проверьте порядок этапов пайплайна." elif warnings: chain_health = "Warning" recommendation = warnings[0] else: chain_health = "OK" recommendation = "Пайплайн сбалансирован. Используйте «Сохр. конф.» для A/B-сравнения." return { "chainHealth": chain_health, "warningsList": warnings, "recommendation": recommendation, }