export type RunMode = 'const_height' | 'cloud_compare'; export type CloudRole = 'unique' | 'top' | 'bottom'; /** Mirroir des strategies de remplissage de cellules vides de CloudCompare (-EMPTY_FILL). */ export type EmptyCellStrategy = 'leave_empty' | 'min_height' | 'max_height' | 'custom_height' | 'interpolate' | 'kriging'; /** Mirroir de -PROJ (type de projection par cellule). INV_VAR omis (necessite un champ scalaire dedie, non applicable ici). */ export type ProjectionType = 'avg' | 'min' | 'max' | 'med'; /** Mirroir de -VERT_DIR : 0=X, 1=Y, 2=Z. */ export type VertDir = 0 | 1 | 2; export interface LevelCloudInfo { role: CloudRole; spatialStep: number | null; // null pour le niveau 0 (nuage complet, non decime) pointCount: number; pointRatio: number; // vs le niveau 0 du meme role binFile: string | null; // chemin relatif au dossier du run (nuage brut, non rempli) } export interface LevelResult { level: number; gridStep: number | null; // grille de calcul du volume a CE niveau (adaptee dynamiquement, voir CLAUDE.md) maxEdgeLength: number | null; // limite de remplissage des trous (Delaunay) a CE niveau, si strategie = interpolate clouds: LevelCloudInfo[]; // 1 element en mode const_height, 2 (top puis bottom) en mode cloud_compare volume: number | null; surface: number | null; addedVolume: number | null; removedVolume: number | null; matchingCellsPct: number | null; groundNonMatchingPct: number | null; ceilNonMatchingPct: number | null; diffMapImage: string | null; // chemin relatif au dossier du run : carte de comparaison unique (bleu->rouge) warn: boolean; status: 'ok' | 'skipped' | 'error'; message?: string; computeTimeMs: number; } export interface RunParamsInput { mode: RunMode; zrefOverride?: number; // mode const_height uniquement initialStepOverride?: number; gridStepMultiplierOverride?: number; maxEdgeLengthOverride?: number; emptyCellStrategy?: EmptyCellStrategy; // defaut 'interpolate' customHeightValue?: number; // requis si emptyCellStrategy = 'custom_height' krigingKnn?: number; // requis si emptyCellStrategy = 'kriging' projectionType?: ProjectionType; // defaut 'avg' vertDir?: VertDir; // defaut 2 (Z) } export interface RunReport { runId: string; mode: RunMode; originalFilename: string; // fichier unique (const_height) ou nom du nuage du haut (cloud_compare) originalFilenameBottom: string | null; // mode cloud_compare uniquement createdAt: string; params: { zref: number | null; // mode const_height uniquement zrefSource: 'override' | 'auto' | null; initialStep: number; initialStepSource: 'override' | 'auto'; gridStepMultiplier: number; gridStepMultiplierSource: 'override' | 'auto'; maxEdgeLengthMultiplier: number; maxEdgeLengthSource: 'override' | 'auto'; emptyCellStrategy: EmptyCellStrategy; customHeightValue: number | null; krigingKnn: number | null; projectionType: ProjectionType; vertDir: VertDir; factor: number; steps: number; densityMatch: { topSpacing: number; bottomSpacing: number; matchedSpacing: number; preDecimatedRole: 'top' | 'bottom' | 'none'; } | null; // mode cloud_compare uniquement sampleStats: { sampleCount: number; meanNn: number; medianNn: number; bboxApprox: { xmin: number; xmax: number; ymin: number; ymax: number; zmin: number; zmax: number }; }; }; levels: LevelResult[]; mergedBinFile: string | null; }