# DotsToSurface (Qt 5.11) ## Структура репозитория | Слой | Папка | Назначение | |------|-------|------------| | **Engine** | `src/engine/` | C++ пайплайн, PCL, CLI `--cli` | | **Backend** | `backend/` | FastAPI — HTTP-обёртка над CLI | | **Frontend (Web)** | `frontend/web/` | Vue 3 dashboard + Three.js | | **Frontend (Desktop)** | `src/desktop/` | Qt QML dashboard | Подробнее: [ARCHITECTURE.md](ARCHITECTURE.md) Сборка Web-версии полностью воспроизводится в Docker (`docker compose up --build`). В git — исходники; артефакты (`build/`, `frontend/web/dist/`) не коммитятся. --- Демонстрационная программа на Qt 5.11 C++, которая: - принимает массив 3D-точек `QVector`; - выполняет stage-based pipeline (preprocess -> transform -> registration -> reconstruction); - визуализирует точки и полученную треугольную поверхность. ## Вход/выход API `src/engine/algorithms/reconstruction/surface_reconstruction.h`: - `struct Point3f { float x, y, z; };` - `struct Triangle { int i0, i1, i2; };` - `QVector buildSurfaceTriangles(const QVector& points);` `Triangle` хранит индексы вершин в исходном массиве `points`. ## Как это работает Реализация использует инкрементальный `Convex Hull 3D`: - удаление дубликатов точек (epsilon-сравнение); - поиск стартового тетраэдра; - поочередное добавление точек с пересчетом видимых граней и горизонта; - поддержание ориентированных наружу треугольников. ## Ограничения Текущая реализация строит **выпуклую оболочку** облака точек. Для невыпуклых объектов и детальной реконструкции произвольной поверхности нужны более сложные алгоритмы (например, alpha-shapes, Poisson reconstruction и т.п.). ## Архитектурный каркас под robotics pipeline - `core`: контракты (`PointCloudFrame`, `PipelineContext`, `PipelineStats`, stage-интерфейсы, plugin registry). - `adapters`: мосты к источникам и внешним транспортам (`FilePointCloudSource`, `Ros2PointCloudSource`, `PointCloud2`/`tf2` adapters). - `strategies`: конкретные стадии пайплайна (preprocess, transform, registration, reconstruction). - `factories`: сборка `PipelineExecutor` из plugin-id и профиля. ## Этап 1 (backend-first, без CLI) - Парсинг и применение `defaults` параметров стадий вынесены из UI в `core`: `src/engine/core/pipeline_stage_defaults.h` и `src/engine/core/pipeline_stage_defaults.cpp`. - `MainWindow` больше не содержит backend-логику разбора параметров, а вызывает `core::applyStageDefaultsToConfig(...)`. - Это позволяет использовать один и тот же backend API из GUI сейчас и из будущего CLI на этапе 2 без дублирования логики. ## Pipeline Dashboard: UX и анализ цепочки В dashboard реализованы инструменты для пошаговой настройки всей pipeline-цепочки (preprocess + reconstruction): - **Категориальная палитра этапов**: фильтры сгруппированы по логике обработки (`Обрезка -> NaN (предочистка) -> Условия/Индексы -> Шум -> Морфология -> Прореживание -> Сглаживание -> Нормали -> Реконструкция`), для каждого фильтра доступны краткие подсказки. - **Проверка порядка этапов**: при рискованной последовательности (например, когда `OutlierRemoval` идет после `VoxelGrid`) показываются предупреждения и рекомендация. - **Стартовые пресеты**: доступны шаблоны для типичных источников (`LiDAR_scan`, `RGBD_camera`, `Synthetic_clean`) как отправная точка с возможностью ручной донастройки. - **Метрики между шагами**: показывается вклад каждого preprocess-этапа: входные точки, выходные точки, сколько удалено и время шага в миллисекундах. - **Единый редактор параметров**: и preprocess-стадии, и реконструкторы поверхности настраиваются через одинаковые карточки и один диалог параметров. Пер-шаговые метрики собираются на уровне `core::PipelineExecutor` и возвращаются через `PipelineStats::preprocessStepMetrics`, чтобы данные были едиными для GUI и тестов. ### Профили выполнения - `desktop_debug`: дефолтный профиль для GUI/отладки. - `rpi4_runtime`: профиль для Raspberry Pi 4 (жестче downsampling, лимит точек, reconstruction реже, async-friendly настройки). Выбор профиля: - `factories::pipeline::createPipelineExecutorForProfile("desktop_debug")` - `factories::pipeline::createPipelineExecutorForProfile("rpi4_runtime")` ## Сборка и запуск в WSL Рабочий поток для этого проекта на Windows: собирать и запускать через WSL. ```bash cd /mnt/d/yakupov/Projects/DotsToSurface/build-wsl qmake ../DotsToSurface.pro 'DEFINES+=PCL_ENABLED' make -j4 LIBGL_ALWAYS_SOFTWARE=1 QT_QPA_PLATFORM=xcb ./DotsToSurface ``` Примечания: - `DEFINES+=PCL_ENABLED` включает PCL-стадии пайплайна. - `LIBGL_ALWAYS_SOFTWARE=1` снижает риски графических артефактов в WSLg. - `QT_QPA_PLATFORM=xcb` используется как стабильный backend для Qt в WSL. Перезапуск после правок: ```bash pkill -f '^./DotsToSurface$' || true cd /mnt/d/yakupov/Projects/DotsToSurface/build-wsl qmake ../DotsToSurface.pro 'DEFINES+=PCL_ENABLED' make -j4 LIBGL_ALWAYS_SOFTWARE=1 QT_QPA_PLATFORM=xcb ./DotsToSurface ``` ## Smoke tests (отдельный runner) Для быстрой проверки пайплайна без GUI добавлен отдельный консольный таргет: `DotsToSurfaceTests.pro`. ```bash qmake DotsToSurfaceTests.pro make ./release/DotsToSurfaceTests.exe ``` При успешном запуске runner печатает `Smoke tests passed.` и завершаетcя с кодом `0`. ## CLI режим (этап 2) Для headless-прогона без GUI добавлен CLI-режим в основном бинарнике через `--cli`. Пример: ```bash cd /mnt/d/yakupov/Projects/DotsToSurface/build-wsl qmake ../DotsToSurface.pro 'DEFINES+=PCL_ENABLED' make -j4 ./DotsToSurface --cli \ --input /mnt/d/path/to/cloud.xyz \ --profile desktop_debug \ --preprocess pcl_remove_nan,pcl_voxel_grid,pcl_statistical_outlier \ --reconstruction pcl_greedy_triangulation \ --stage-default pcl_voxel_grid:leaf=0.03 \ --stage-default pcl_greedy_triangulation:searchRadius=0.08,mu=2.5,maxNearest=100,maxSurfaceAngle=0.8 \ --output-json /mnt/d/path/to/result.json ``` CLI печатает краткую сводку по метрикам (`input`, `after preprocess`, `triangles`, `reconstruction ms`). ### JSON-конфиг для CLI (этап 2.1) Чтобы не передавать длинную команду, можно задать пайплайн через `--config-json`. Пример `pipeline_config.json`: ```json { "profile": "desktop_debug", "preprocessPlugins": ["pcl_remove_nan", "pcl_voxel_grid", "pcl_statistical_outlier"], "reconstructionPlugin": "pcl_greedy_triangulation", "stageDefaults": { "pcl_voxel_grid": "leaf=0.03", "pcl_greedy_triangulation": "searchRadius=0.08,mu=2.5,maxNearest=100,maxSurfaceAngle=0.8" } } ``` Запуск: ```bash ./DotsToSurface --cli --input /mnt/d/path/to/cloud.xyz --config-json /mnt/d/path/to/pipeline_config.json ``` Если одновременно переданы `--config-json` и обычные CLI-флаги (`--preprocess`, `--reconstruction`, `--stage-default`), флаги командной строки имеют приоритет. ### Autotune Grid Search (этап 3) Для подбора параметров с целью уменьшения дыр на поверхности добавлен режим: `--autotune-config`. Пример `autotune_config.json`: ```json { "baseConfigJson": "/mnt/d/path/to/pipeline_config.json", "searchSpace": { "pclVoxelLeafSize": [0.02, 0.03, 0.04], "pclGreedySearchRadius": [0.06, 0.08, 0.10], "neighborRadiusScale": [2.5, 3.0] }, "objective": { "connectivityWeight": 0.45, "coverageWeight": 0.45, "speedPenaltyWeight": 0.10 }, "limits": { "maxCandidates": 20, "topK": 5 }, "output": { "resultJsonPath": "/mnt/d/path/to/autotune_result.json" } } ``` Запуск: ```bash ./DotsToSurface --cli \ --input /mnt/d/path/to/cloud.xyz \ --autotune-config /mnt/d/path/to/autotune_config.json ``` Опционально можно переопределить путь результата через `--output-json`. Файл `autotune_result.json` теперь содержит поля `title` и `stages` в формате GUI-пресета, поэтому его можно загрузить напрямую кнопкой `Загрузить пресет`. Дополнительно рядом сохраняется `*_best_preset.json` (чистый preset-JSON). ## Docker + Web UI (CLI + PCL) Для запуска пайплайна с PCL в изолированной среде (без конфликтов с `libpq` на хосте) добавлены: - `docker/Dockerfile` — сборка `DotsToSurface` с `PCL_ENABLED` + Vue 3 dashboard; - `docker/docker-compose.yml`; - `backend/main.py` — HTTP API (`/api/run`, `/api/presets`, `/api/validate-config`, …); - `frontend/web/` — Vue 3 + Pinia + Three.js (полный dashboard, паритет с Qt); **Qt desktop (`./DotsToSurface`) сохраняется** как локальный fallback без Docker. ### Быстрый старт ```bash cd docker docker compose up --build ``` Откройте в браузере: [http://localhost:8080](http://localhost:8080) ### Локальная разработка frontend ```bash cd frontend/web npm install npm run dev ``` API проксируется на `http://localhost:8080` (см. `vite.config.js`). ### API (основное) - `GET /api/health` — статус сервиса - `GET /api/catalog` — метаданные стадий - `GET /api/builtin-presets` — LiDAR / RGBD / Synthetic / Fast / Robust - `GET /api/presets` — встроенные + файловые + user presets - `POST /api/validate-config` — warnings / chainHealth без запуска - `POST /api/wizard` — suggested chain - `GET /api/demo` — демо-облако точек - `POST /api/user-presets` — сохранение пользовательских пресетов - `POST /api/run` — multipart: `file` или `demo_surface` + `config_json` - `GET /api/geometry/{workId}` — бинарная геометрия для больших облаков CLI `--output-json` включает `points`, `triangleIndices`, `preprocessStepMetrics`. ## Демо При запуске приложение: - генерирует тестовое облако точек (приближенная сфера с небольшим шумом); - строит триангуляцию; - показывает статистику: количество точек, количество треугольников и время построения; - отображает сцену в `QOpenGLWidget` (ЛКМ - вращение, колесо - зум).