/
klischa
/
AstraScanner2
Обзор
Документация
Войти
/
klischa
/
AstraScanner2
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/gui/MainWindow.h
334 строки
13 KB
k k
refactor: remove MainWindow dead code + fix VoxelGrid warnings
14 июл 2026, 23:40
14 июл 2026, 23:40
1459aca
Код
Авторство
О чём код?
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <Eigen/Dense> #include <Eigen/Geometry> #include <QLabel> #include <QProgressBar> #include <QElapsedTimer> #include <QTimer> #include <QTextEdit> #include <QMutex> #include <QSharedPointer> #include <atomic> #include <memory> #include <pcl/point_cloud.h> #include <pcl/point_types.h> #include <pcl/filters/voxel_grid.h> #include <pcl/PolygonMesh.h> #include <QProcess> #include <QEventLoop> #include <QPolygonF> #include <opencv2/opencv.hpp> #include <deque> #include "../filters/PointCloudFilters.h" #include "../controllers/ProcessingController.h" #include "../tracking/SurfelCoverageTracker.h" QT_BEGIN_NAMESPACE class QTabWidget; class QPushButton; class QVTKOpenGLNativeWidget; class QCheckBox; class QSpinBox; class QDoubleSpinBox; class QComboBox; QT_END_NAMESPACE class CameraCalibrator; class HelpDialog; class PointCloudFilters; class ProjectManager; class ExportManager; class HomeTabBinder; class StatusBarBinder; class MenuBarBinder; class ViewerCoordinator; class ProjectUiController; class ProjectTabBinder; class ScanTabBinder; class CalibrationTabBinder; class LogTabBinder; class ProcessingTabBinder; class TurntableController; class CaptureSessionController; class ScanWorkflow; class ProcessingWorkflow; class ProjectWorkflow; QT_BEGIN_NAMESPACE class QListWidget; class QListWidgetItem; QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); Q_INVOKABLE void appendLog(const QString &text); // <-- добавлено Q_INVOKABLE signals: void cloudSizeChanged(int size); void distanceChanged(int distance); private slots: void onPreviewClicked(); void onScanClicked(); void onPauseClicked(); void onStopClicked(); void onClearClicked(); void onNewFrame(QSharedPointer<cv::Mat> color, QSharedPointer<cv::Mat> depth); void onPointCloudReady(pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud); void onCaptureError(const QString &msg); void onCaptureWarning(const QString &msg); void onFrameProcessed(int totalFrames); void updateViewer(); void checkScanTimeout(); void onMarkersDetected(QSharedPointer<cv::Mat> markersImage); void onCalibPreviewClicked(); void onCalibCaptureClicked(); void onCalibCalibrateClicked(); void onCalibResetClicked(); void onCalibrationStatus(const QString &msg); // --- Проект / экспорт --- void onNewProject(); void onOpenProject(); void onSaveProject(); void onSaveProjectAs(); void onAddCurrentCloudToProject(); void onExportCurrentCloud(); void onExportMesh(); void onScansListContextMenu(const QPoint &pos); void onScansListDoubleClicked(QListWidgetItem *item); void refreshScansList(); // --- Poisson-реконструкция --- void onReconstructMeshClicked(const PointCloudFilters::PoissonParams ¶ms); void onReconstructLightweightClicked(); void onShowCloudClicked(); // --- ICP-регистрация --- void onMergeScansClicked(const PointCloudFilters::MergeParams ¶ms); void onSaveMergedToProject(); // --- Настройки (единый диалог) --- void onShowSettingsDialog(); void onShowHelpDialog(); // --- Поворотный стол / авто-сохранение по таймеру --- void onTurntableToggled(bool enabled); void onTurntableTick(); private: void setupUI(); void setupVisualizer(); void startCapture(bool enableCloudProcessing); bool stopCapture(); void updateProjectStatusUi(); void syncTrackingModeComboFromProject(); bool confirmDiscardDirtyProject(const QString &title, const QString &question); QString chooseProjectDirectory(const QString &title, bool existingOnly); bool ensureProjectOpenForSave(); pcl::PointCloud<pcl::PointXYZRGB>::Ptr currentCloudSnapshot(); bool loadProjectScanIntoCurrentCloud(int index); QString chooseExportFilename(const QString &title, const QStringList &filters); void rememberExportDirectory(const QString &filename); bool tryExportPointCloud(const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr &cloud, const QString &dialogTitle); void updateScannerPoseLabel(const Eigen::Affine3f &pose, bool showEuler = false); void updateScannerPoseLabelFromProject(bool showEuler = false); void setTurntableStatusText(const QString &text); void stopTurntableMode(bool uncheckCheckbox = false); void setupStatusBarWidgets(); void applyProcessedCloudResult(const pcl::PointCloud<pcl::PointXYZRGB>::Ptr &filtered, bool usesProcessingProgress); void applyProcessedMeshResult(const pcl::PolygonMesh &mesh); void handleCloudProcessingCanceled(const QString &logMessage, bool usesProcessingProgress); void handleMeshProcessingCanceled(const QString &logMessage); void runCloudProcessingAction(const pcl::PointCloud<pcl::PointXYZRGB>::Ptr &snapshot, const ProcessingController::CloudOperation &operation, const QString &cancelMessage, bool usesProcessingProgress); bool currentMeshSnapshot(pcl::PolygonMesh &meshCopy); void runMeshProcessingAction(const pcl::PolygonMesh &meshCopy, const ProcessingController::MeshOperation &operation, const QString &cancelMessage); void handlePoissonResult(const pcl::PolygonMesh &mesh); void handlePoissonCanceled(); void handleMergeResult(const pcl::PointCloud<pcl::PointXYZRGB>::Ptr &merged); void handleMergeCanceled(); void showHelpSection(const QString &anchor); void updateScanQualityPanel(const QString &trackingText, int trackingLevel, const QString &alignmentText, int alignmentLevel, const QString &depthText, int depthLevel, const QString &driftText, int driftLevel); void updateCoverageSummary(); void resetScanQualityPanel(); void resetConfidenceCoverage(); QTabWidget *m_tabWidget = nullptr; QPushButton *m_previewBtn = nullptr; QPushButton *m_scanBtn = nullptr; QPushButton *m_pauseBtn = nullptr; QPushButton *m_stopBtn = nullptr; QPushButton *m_clearBtn = nullptr; QLabel *m_rgbLabel = nullptr; QLabel *m_depthLabel = nullptr; QProgressBar *m_distanceIndicator = nullptr; QLabel *m_trackingQualityLabel = nullptr; QLabel *m_alignmentQualityLabel = nullptr; QLabel *m_depthQualityLabel = nullptr; QLabel *m_driftQualityLabel = nullptr; QLabel *m_coverageSummaryLabel = nullptr; QLabel *m_fpsLabel = nullptr; QLabel *m_frameCountLabel = nullptr; QLabel *m_timeLabel = nullptr; QVTKOpenGLNativeWidget *m_vtkWidget = nullptr; enum class ScanViewColorMode { Rgb = 0, Quality = 1 }; pcl::PointCloud<pcl::PointXYZRGB>::Ptr m_accumulatedCloud; QMutex m_cloudMutex; std::unique_ptr<SurfelCoverageTracker> m_surfelCoverageTracker; ScanViewColorMode m_scanViewColorMode = ScanViewColorMode::Rgb; int m_lastTrackingQualityLevel = 1; int m_lastAlignmentQualityLevel = 1; int m_lastDepthQualityLevel = 1; int m_lastDriftQualityLevel = 1; bool m_scanning = false; bool m_cloudProcessing = false; QTimer *m_viewerUpdateTimer = nullptr; QTimer *m_scanTimeoutTimer = nullptr; QElapsedTimer m_scanTimer; cv::Mat m_lastColorFrame; int m_depthColormap = cv::COLORMAP_JET; CameraCalibrator *m_calibrator = nullptr; QLabel *m_calibStatusLabel = nullptr; QLabel *m_calibFrameCountLabel = nullptr; QPushButton *m_calibPreviewBtn = nullptr; QPushButton *m_calibCaptureBtn = nullptr; QPushButton *m_calibCalibrateBtn = nullptr; QPushButton *m_calibResetBtn = nullptr; QLabel *m_calibRgbLabel = nullptr; QLabel *m_homeProjectStatusLabel = nullptr; QLabel *m_homeCalibStatusLabel = nullptr; QLabel *m_homeCalibFrameCountLabel = nullptr; QPushButton *m_homeCalibCalibrateBtn = nullptr; QLabel *m_homeCalibRgbLabel = nullptr; HelpDialog *m_helpDialog = nullptr; PointCloudFilters *m_filters = nullptr; ProcessingController *m_processingController = nullptr; QTextEdit *m_logTextEdit = nullptr; // --- Проект / экспорт --- ProjectManager *m_project = nullptr; ExportManager *m_exporter = nullptr; HomeTabBinder *m_homeTabBinder = nullptr; StatusBarBinder *m_statusBarBinder = nullptr; MenuBarBinder *m_menuBarBinder = nullptr; ViewerCoordinator *m_viewerCoordinator = nullptr; ProjectUiController *m_projectUiController = nullptr; ProjectTabBinder *m_projectTabBinder = nullptr; ScanTabBinder *m_scanTabBinder = nullptr; CalibrationTabBinder *m_calibrationTabBinder = nullptr; LogTabBinder *m_logTabBinder = nullptr; ProcessingTabBinder *m_processingTabBinder = nullptr; TurntableController *m_turntableController = nullptr; CaptureSessionController *m_captureSessionController = nullptr; ScanWorkflow *m_scanWorkflow = nullptr; ProcessingWorkflow *m_processingWorkflow = nullptr; ProjectWorkflow *m_projectWorkflow = nullptr; QListWidget *m_scansList = nullptr; QLabel *m_projectStatusLabel = nullptr; // Последний реконструированный меш (Poisson). Пустой, пока не нажата // кнопка «Построить меш» в вкладке «Обработка» или до первой успешной // реконструкции. pcl::PolygonMesh m_lastMesh; QProgressBar *m_poissonProgress = nullptr; QProgressBar *m_icpProgress = nullptr; QProgressBar *m_processingProgress = nullptr; QProgressBar *m_activeProgressBar = nullptr; QLabel *m_meshStatusLabel = nullptr; // Флаг наличия валидного меша для операций постобработки bool m_meshSaved = false; QMutex m_meshMutex; // ICP-регистрация QPushButton *m_mergeBtn = nullptr; QPushButton *m_addMergedBtn = nullptr; QLabel *m_icpStatusLabel = nullptr; // Последний результат ICP-мержа, готовый к записи в проект как новый // скан. Null — результата ещё нет. pcl::PointCloud<pcl::PointXYZRGB>::Ptr m_lastMerged; // Ручная переориентация нормалей для Poisson. Живут прямо в UI // группы «Реконструкция поверхности», чтобы значения читались в момент // нажатия «Построить меш». QCheckBox *m_poissonFlipNormalsChk = nullptr; QCheckBox *m_poissonCustomVpChk = nullptr; QDoubleSpinBox *m_poissonVpX = nullptr; QDoubleSpinBox *m_poissonVpY = nullptr; QDoubleSpinBox *m_poissonVpZ = nullptr; QCheckBox *m_poissonConsistentOrientChk = nullptr; // Label для отображения позы сканера QLabel *m_scannerPoseLabel = nullptr; // Поворотный стол / авто-сохранение QTimer *m_turntableTimer = nullptr; QCheckBox *m_turntableEnableChk = nullptr; QSpinBox *m_turntableIntervalSpin = nullptr; QSpinBox *m_turntableCountSpin = nullptr; QComboBox *m_turntableModeCombo = nullptr; QLabel *m_turntableStatusLabel = nullptr; QComboBox *m_trackingModeCombo = nullptr; // Кнопки фильтров (SOR, ROR, Voxel, MagicWand) — хранятся как члены, // чтобы блокировать все одновременно при запуске любого фильтра. QPushButton *m_sorBtn = nullptr; QPushButton *m_rorBtn = nullptr; QPushButton *m_voxelBtn = nullptr; QPushButton *m_magicWandBtn = nullptr; void setFilterButtonsEnabled(bool enabled); void setMeshFilterButtonsEnabled(bool enabled); void updateProcViewer(); // Кнопки постобработки (PR #1, PR #2) QPushButton *m_bgBtn = nullptr; QPushButton *m_segBtn = nullptr; QPushButton *m_smoothBtn = nullptr; QPushButton *m_simplBtn = nullptr; QPushButton *m_holeBtn = nullptr; // Визуализатор облака на вкладке «Обработка» QVTKOpenGLNativeWidget *m_procVtkWidget = nullptr; }; // Глобальный указатель на главное окно, используется обработчиком сообщений // Qt (fileMessageHandler) для форвардинга логов в GUI. Доступ атомарный, // потому что сообщения могут приходить из любого потока. extern std::atomic<MainWindow *> g_mainWindow; #endif // MAINWINDOW_H