Перенесены backend/frontend/desktop/engine, добавлены вкладки конструктора сцен и генератора датасета с параметрами лучей и длины сетки рельефа, обновлены API и Docker-сборка. Co-authored-by: Cursor <cursoragent@cursor.com>
274 lines
13 KiB
Markdown
274 lines
13 KiB
Markdown
# 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<Point3f>`;
|
||
- выполняет 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<Triangle> buildSurfaceTriangles(const QVector<Point3f>& 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` (ЛКМ - вращение, колесо - зум).
|