.pragma library function inferParamType(valueText) { var v = (valueText === undefined || valueText === null) ? "" : String(valueText).trim() if (v === "true" || v === "false") return "bool" if (/^-?\d+$/.test(v)) return "int" if (/^-?(?:\d+\.\d*|\d*\.\d+)$/.test(v)) return "float" return "string" } function parseDefaults(defaultsText) { var out = [] if (!defaultsText) return out var chunks = String(defaultsText).split(",") for (var i = 0; i < chunks.length; ++i) { var chunk = chunks[i].trim() if (!chunk) continue var eq = chunk.indexOf("=") var key = eq >= 0 ? chunk.slice(0, eq).trim() : chunk var value = eq >= 0 ? chunk.slice(eq + 1).trim() : "" out.push({ key: key, value: value, kind: inferParamType(value) }) } return out } function serializeParams(items) { var parts = [] for (var i = 0; i < items.length; ++i) { var p = items[i] parts.push(p.key + "=" + p.value) } return parts.join(",") } function paramDescription(key) { if (key === "minCluster") return "Минимальный размер кластера в точках." if (key === "targetPoints") return "Целевое количество точек после прореживания." if (key === "leaf") return "Размер вокселя для Voxel Grid." if (key === "meanK") return "Число соседей для статистической оценки." if (key === "stddev") return "Порог отклонения для удаления выбросов." if (key === "radius") return "Радиус поиска соседей." if (key === "minNeighbors") return "Минимум соседей, чтобы точка считалась валидной." if (key === "threshold") return "Порог отклонения точки от геометрической модели." if (key === "shadowThreshold") return "Порог для удаления теневых точек по нормалям." if (key === "resolution") return "Размер ячейки 2D-сетки для фильтра GridMinimum." if (key === "sample") return "Количество точек, которое нужно оставить после выборки." if (key === "axis") return "Ось фильтрации: x, y или z." if (key === "min" || key === "max") return "Граница диапазона для фильтра PassThrough." if (key === "minX" || key === "minY" || key === "minZ" || key === "maxX" || key === "maxY" || key === "maxZ") return "Границы CropBox/CropHull по соответствующим осям." if (key === "near" || key === "far") return "Ближняя/дальняя граница фрустума." if (key === "hfov" || key === "vfov") return "Горизонтальный/вертикальный угол обзора (в градусах)." if (key === "a" || key === "b" || key === "c" || key === "d") return "Коэффициенты плоскости ax+by+cz+d=0." if (key === "keepPositive") return "Оставлять ли точки на положительной стороне плоскости." if (key === "zMin" || key === "zMax") return "Допустимый диапазон координаты Z для conditional-фильтра." if (key === "nth") return "Оставлять каждую N-ю точку." if (key === "radiusMax") return "Максимальный радиус точки от начала координат." if (key === "sigmaS" || key === "sigmaR") return "Параметры bilateral-фильтра (пространство/интенсивность)." if (key === "sigma" || key === "kernel") return "Параметры гауссова ядра свертки." if (key === "iterations") return "Число итераций уточнения." if (key === "minHits") return "Минимальная заполненность вокселя для прохождения фильтра." if (key === "neighborRadiusScale") return "Масштаб радиуса поиска соседей для fallback-реконструкции." if (key === "runEveryNthFrame") return "Запуск реконструкции на каждом N-м кадре." if (key === "searchRadius") return "Радиус поиска соседей для greedy triangulation." if (key === "mu") return "Коэффициент плотности соседей для greedy triangulation." if (key === "maxNearest") return "Максимум соседей для greedy triangulation." if (key === "maxSurfaceAngle") return "Максимальный угол поверхности в радианах." if (key === "poissonDepth") return "Глубина октодерева для Poisson реконструкции." if (key === "samplesPerNode") return "Число выборок на узел для сглаживания Poisson." return "Параметр этапа обработки." } function reconstructionTitle(id) { if (id === "surface_fallback") return "Fallback Surface" if (id === "pcl_greedy_triangulation") return "PCL Greedy Triangulation" if (id === "pcl_poisson_reconstruction") return "PCL Poisson Reconstruction" return id } function phaseModel() { return [ { id: "crop", title: "Обрезка", hint: "Ограничение области интереса и удаление лишних фрагментов.", accent: "#88d1ff", filterBg: "#263e55", filterBorder: "#4b7598" }, { id: "nan_preclean", title: "NaN (предочистка)", hint: "Удаление NaN сразу после загрузки/обрезки, иначе статистические фильтры работают нестабильно.", accent: "#8fe8ff", filterBg: "#1f4450", filterBorder: "#3f8394" }, { id: "conditions_indexes", title: "Условия/Индексы", hint: "Отбор точек по полям, диапазонам и индексным маскам.", accent: "#9fd7ff", filterBg: "#24405a", filterBorder: "#4f7aa1" }, { id: "noise", title: "Шум", hint: "Удаление выбросов и нестабильных точек перед геометрией.", accent: "#a4f4b9", filterBg: "#244534", filterBorder: "#4b8f68" }, { id: "morphology", title: "Морфология", hint: "Геометрические операции локальной структуры облака.", accent: "#9cf5d1", filterBg: "#1f4a3e", filterBorder: "#4b8f7d" }, { id: "downsample", title: "Прореживание", hint: "Снижение плотности облака для скорости и устойчивости.", accent: "#ffcb8a", filterBg: "#4a3724", filterBorder: "#8e6f47" }, { id: "smoothing", title: "Сглаживание", hint: "Снижение локального шума перед расчетом нормалей и реконструкцией.", accent: "#ffd892", filterBg: "#4e3a22", filterBorder: "#917349" }, { id: "normals", title: "Нормали", hint: "Подготовка нормалей для продвинутой реконструкции (этап зарезервирован).", accent: "#d2b7ff", filterBg: "#3e3155", filterBorder: "#6f5a95" }, { id: "reconstruction", title: "Реконструкция", hint: "Построение поверхности по подготовленному облаку точек.", accent: "#ff9dc4", filterBg: "#4b2f40", filterBorder: "#8d5a75" } ] } function filterDefinitions() { return [ { title: "Крупнейший кластер", idValue: "keep_largest_cluster", phaseId: "crop", hint: "Оставляет основной объект и отбрасывает изолированные фрагменты." }, { title: "Remove NaN Points", idValue: "pcl_remove_nan", phaseId: "nan_preclean", family: "preprocess", hint: "Удаляет NaN/Inf после загрузки и обрезки, до статистических фильтров." }, { title: "Remove NaN Normals", idValue: "pcl_remove_nan_normals", phaseId: "nan_preclean", family: "preprocess", hint: "Удаляет невалидные нормали (в текущем формате — невалидную геометрию)." }, { title: "PassThrough", idValue: "pcl_pass_through", phaseId: "crop", hint: "Фильтрует точки по диапазону выбранной оси." }, { title: "CropBox", idValue: "pcl_crop_box", phaseId: "crop", hint: "Ограничивает облако заданным 3D-параллелепипедом." }, { title: "CropHull", idValue: "pcl_crop_hull", phaseId: "crop", hint: "Обрезка по области интереса (в текущей версии через box-границы)." }, { title: "Frustum Culling", idValue: "pcl_frustum_culling", phaseId: "crop", hint: "Оставляет точки в пирамиде видимости камеры." }, { title: "PlaneClipper3D", idValue: "pcl_plane_clipper_3d", phaseId: "crop", hint: "Отсекает точки по уравнению плоскости." }, { title: "Conditional Removal", idValue: "pcl_conditional_removal", phaseId: "conditions_indexes", hint: "Удаляет точки по логическому условию (диапазон Z)." }, { title: "Extract Indices", idValue: "pcl_extract_indices", phaseId: "conditions_indexes", hint: "Извлекает точки по индексной маске (каждая N-я)." }, { title: "Functor Filter", idValue: "pcl_functor_filter", phaseId: "conditions_indexes", hint: "Пользовательский предикат (радиус + проверка валидности)." }, { title: "ProjectInliers", idValue: "pcl_project_inliers", phaseId: "normals", hint: "Проецирует точки на геометрическую модель (плоскость)." }, { title: "Normal Refinement", idValue: "pcl_normal_refinement", phaseId: "normals", hint: "Уточняет локальную геометрию по соседям." }, { title: "Статистическая фильтрация", idValue: "pcl_statistical_outlier", phaseId: "noise", hint: "Удаляет выбросы на основе распределения расстояний до соседей." }, { title: "Радиусная фильтрация", idValue: "pcl_radius_outlier", phaseId: "noise", hint: "Удаляет точки с недостаточным числом соседей в заданном радиусе." }, { title: "Model Outlier Removal", idValue: "pcl_model_outlier", phaseId: "noise", hint: "Удаляет точки, отклоняющиеся от геометрической модели." }, { title: "Shadow Points Removal", idValue: "pcl_shadow_points", phaseId: "noise", hint: "Удаляет теневые точки на основе нормалей поверхности." }, { title: "Approximate Voxel Grid", idValue: "pcl_approximate_voxel_grid", phaseId: "downsample", hint: "Ускоренное воксельное прореживание для больших облаков." }, { title: "Voxel Grid Label", idValue: "pcl_voxel_grid_label", phaseId: "downsample", hint: "Воксельное прореживание с поддержкой меток." }, { title: "Voxel Grid Covariance", idValue: "pcl_voxel_grid_covariance", phaseId: "downsample", hint: "Воксельная сетка с ковариациями (для NDT-пайплайнов)." }, { title: "Grid Minimum", idValue: "pcl_grid_minimum", phaseId: "downsample", hint: "Оставляет точку с минимальным Z в каждой ячейке." }, { title: "Farthest Point Sampling", idValue: "pcl_farthest_point_sampling", phaseId: "downsample", hint: "Выбирает наиболее удаленные друг от друга точки." }, { title: "Normal Space Sampling", idValue: "pcl_normal_space_sampling", phaseId: "downsample", hint: "Равномерная выборка в пространстве нормалей." }, { title: "Sampling Surface Normal", idValue: "pcl_sampling_surface_normal", phaseId: "downsample", hint: "Выборка точек на основе нормалей поверхности." }, { title: "Bilateral Filter", idValue: "pcl_bilateral_filter", phaseId: "smoothing", hint: "Двустороннее сглаживание с сохранением границ." }, { title: "Fast Bilateral Filter", idValue: "pcl_fast_bilateral_filter", phaseId: "smoothing", hint: "Быстрое двустороннее сглаживание." }, { title: "Fast Bilateral Filter OMP", idValue: "pcl_fast_bilateral_filter_omp", phaseId: "smoothing", hint: "Параллельная версия bilateral-фильтра." }, { title: "Convolution", idValue: "pcl_convolution", phaseId: "smoothing", hint: "Свертка облака точек с ядром." }, { title: "Gaussian Kernel", idValue: "pcl_gaussian_kernel", phaseId: "smoothing", hint: "Гауссово ядро свертки." }, { title: "Gaussian Kernel RGB", idValue: "pcl_gaussian_kernel_rgb", phaseId: "smoothing", hint: "Гауссово ядро с RGB-ориентированной семантикой." }, { title: "VoxelGrid Occlusion Estimation", idValue: "pcl_voxel_grid_occlusion", phaseId: "morphology", hint: "Оценка окклюзии через заполненность вокселей." }, { title: "Fallback Surface", idValue: "surface_fallback", phaseId: "reconstruction", family: "reconstruction", hint: "Базовая реконструкция поверхности по облаку точек." }, { title: "PCL Greedy Triangulation", idValue: "pcl_greedy_triangulation", phaseId: "reconstruction", family: "reconstruction", hint: "Жадная триангуляция с параметрами радиуса и углов." }, { title: "PCL Poisson Reconstruction", idValue: "pcl_poisson_reconstruction", phaseId: "reconstruction", family: "reconstruction", hint: "Реконструкция поверхности методом Poisson из libpcl_surface." }, { title: "Прореживание плотности", idValue: "downsample_dense", phaseId: "downsample", hint: "Снижает число точек для ускорения пайплайна на плотных облаках." }, { title: "PCL Voxel Grid", idValue: "pcl_voxel_grid", phaseId: "downsample", hint: "Равномерно прореживает облако с помощью воксельной сетки." } ] } function filterPaletteModel() { return filterDefinitions() } function filterPaletteGroupedModel() { var phases = phaseModel() var filters = filterDefinitions() var grouped = [] for (var p = 0; p < phases.length; ++p) { var phase = phases[p] var items = [] for (var i = 0; i < filters.length; ++i) { if (filters[i].phaseId === phase.id) items.push(filters[i]) } grouped.push({ phaseId: phase.id, phaseTitle: phase.title, phaseHint: phase.hint, phaseAccent: phase.accent, phaseFilterBg: phase.filterBg, phaseFilterBorder: phase.filterBorder, items: items }) } return grouped } function reconstructionPaletteModel() { return [ { title: "Fallback Surface", idValue: "surface_fallback" }, { title: "PCL Greedy Triangulation", idValue: "pcl_greedy_triangulation" }, { title: "PCL Poisson Reconstruction", idValue: "pcl_poisson_reconstruction" } ] }