2026-01-16 01:04:43 +08:00
|
|
|
|
#ifndef CLOUD_VIEW_MAIN_WINDOW_H
|
|
|
|
|
|
#define CLOUD_VIEW_MAIN_WINDOW_H
|
|
|
|
|
|
|
|
|
|
|
|
#include <QMainWindow>
|
|
|
|
|
|
#include <QWidget>
|
|
|
|
|
|
#include <QPushButton>
|
|
|
|
|
|
#include <QLabel>
|
|
|
|
|
|
#include <QListWidget>
|
|
|
|
|
|
#include <QGroupBox>
|
|
|
|
|
|
#include <QVBoxLayout>
|
|
|
|
|
|
#include <QHBoxLayout>
|
|
|
|
|
|
#include <QSplitter>
|
|
|
|
|
|
#include <QFileDialog>
|
|
|
|
|
|
#include <QMessageBox>
|
|
|
|
|
|
#include <QStatusBar>
|
|
|
|
|
|
#include <QLineEdit>
|
|
|
|
|
|
#include <QRadioButton>
|
2026-01-17 12:29:57 +08:00
|
|
|
|
#include <QCheckBox>
|
2026-02-11 00:53:51 +08:00
|
|
|
|
#include <QComboBox>
|
2026-01-17 12:29:57 +08:00
|
|
|
|
#include <QDialog>
|
2026-01-16 01:04:43 +08:00
|
|
|
|
#include <memory>
|
|
|
|
|
|
|
|
|
|
|
|
#include "PointCloudGLWidget.h"
|
|
|
|
|
|
#include "PointCloudConverter.h"
|
|
|
|
|
|
|
2026-01-17 12:29:57 +08:00
|
|
|
|
class QTextEdit;
|
|
|
|
|
|
class QTableWidget;
|
|
|
|
|
|
|
2026-01-16 01:04:43 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 点云查看器主窗口
|
|
|
|
|
|
* 左侧显示点云,右侧为操作区域
|
|
|
|
|
|
*/
|
|
|
|
|
|
class CloudViewMainWindow : public QMainWindow
|
|
|
|
|
|
{
|
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
explicit CloudViewMainWindow(QWidget* parent = nullptr);
|
|
|
|
|
|
~CloudViewMainWindow() override;
|
|
|
|
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 打开文件
|
|
|
|
|
|
*/
|
|
|
|
|
|
void onOpenFile();
|
|
|
|
|
|
|
2026-02-07 23:46:44 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 打开线段文件
|
|
|
|
|
|
*/
|
|
|
|
|
|
void onOpenSegmentFile();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 打开姿态点文件
|
|
|
|
|
|
*/
|
|
|
|
|
|
void onOpenPoseFile();
|
|
|
|
|
|
|
2026-01-16 01:04:43 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 清除所有点云
|
|
|
|
|
|
*/
|
|
|
|
|
|
void onClearAll();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 重置视图
|
|
|
|
|
|
*/
|
|
|
|
|
|
void onResetView();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 清除选中的点
|
|
|
|
|
|
*/
|
|
|
|
|
|
void onClearSelectedPoints();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 清除选线
|
|
|
|
|
|
*/
|
|
|
|
|
|
void onClearLinePoints();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 处理点选中事件
|
|
|
|
|
|
*/
|
|
|
|
|
|
void onPointSelected(const SelectedPointInfo& point);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 处理两点选中事件(测距)
|
|
|
|
|
|
*/
|
|
|
|
|
|
void onTwoPointsSelected(const SelectedPointInfo& p1, const SelectedPointInfo& p2, float distance);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 处理线选中事件
|
|
|
|
|
|
*/
|
|
|
|
|
|
void onLineSelected(const SelectedLineInfo& line);
|
|
|
|
|
|
|
2026-02-11 00:53:51 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 处理视角旋转角度改变事件
|
|
|
|
|
|
*/
|
|
|
|
|
|
void onViewAnglesChanged(float rotX, float rotY, float rotZ);
|
|
|
|
|
|
|
2026-01-16 01:04:43 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 通过输入线号选择线
|
|
|
|
|
|
*/
|
|
|
|
|
|
void onSelectLineByNumber();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 选线模式切换(纵向/横向)
|
|
|
|
|
|
*/
|
|
|
|
|
|
void onLineSelectModeChanged(bool checked);
|
|
|
|
|
|
|
2026-01-17 12:29:57 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 显示选中线上的所有点坐标
|
|
|
|
|
|
*/
|
|
|
|
|
|
void onShowLinePoints();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 线上点列表项被点击
|
|
|
|
|
|
*/
|
|
|
|
|
|
void onLinePointTableClicked(int row, int column);
|
|
|
|
|
|
|
2026-02-07 23:46:44 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 显示点1的姿态
|
|
|
|
|
|
*/
|
|
|
|
|
|
void onShowPose1();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 显示点2的姿态
|
|
|
|
|
|
*/
|
|
|
|
|
|
void onShowPose2();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 显示输入的线段
|
|
|
|
|
|
*/
|
|
|
|
|
|
void onShowInputLine();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 清除输入的线段
|
|
|
|
|
|
*/
|
|
|
|
|
|
void onClearInputLine();
|
|
|
|
|
|
|
2026-02-11 00:53:51 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 欧拉角旋转顺序改变
|
|
|
|
|
|
*/
|
|
|
|
|
|
void onEulerOrderChanged(int index);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 从文件加载变换矩阵
|
|
|
|
|
|
*/
|
|
|
|
|
|
void onLoadMatrix();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 应用矩阵变换到所有点云
|
|
|
|
|
|
*/
|
|
|
|
|
|
void onApplyMatrix();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 重置矩阵为单位矩阵
|
|
|
|
|
|
*/
|
|
|
|
|
|
void onResetMatrix();
|
|
|
|
|
|
|
2026-01-16 01:04:43 +08:00
|
|
|
|
private:
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 初始化界面
|
|
|
|
|
|
*/
|
|
|
|
|
|
void setupUI();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 创建左侧点云显示区域
|
|
|
|
|
|
*/
|
|
|
|
|
|
QWidget* createViewerArea();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 创建右侧操作区域
|
|
|
|
|
|
*/
|
|
|
|
|
|
QWidget* createControlPanel();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 创建文件操作组
|
|
|
|
|
|
*/
|
|
|
|
|
|
QGroupBox* createFileGroup();
|
|
|
|
|
|
|
2026-02-11 00:53:51 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 创建视图方向组
|
|
|
|
|
|
*/
|
|
|
|
|
|
QGroupBox* createViewGroup();
|
|
|
|
|
|
|
2026-01-16 01:04:43 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 创建选点测距组
|
|
|
|
|
|
*/
|
|
|
|
|
|
QGroupBox* createMeasureGroup();
|
|
|
|
|
|
|
2026-02-07 23:46:44 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 创建选点测距页面
|
|
|
|
|
|
*/
|
|
|
|
|
|
QWidget* createMeasurePage();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 创建选线页面
|
|
|
|
|
|
*/
|
|
|
|
|
|
QWidget* createLinePage();
|
|
|
|
|
|
|
2026-02-11 00:53:51 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 创建矩阵变换页面
|
|
|
|
|
|
*/
|
|
|
|
|
|
QWidget* createTransformPage();
|
|
|
|
|
|
|
2026-01-16 01:04:43 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 创建选线拟合组
|
|
|
|
|
|
*/
|
|
|
|
|
|
QGroupBox* createLineGroup();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 创建点云列表组
|
|
|
|
|
|
*/
|
|
|
|
|
|
QGroupBox* createCloudListGroup();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 更新选点信息显示
|
|
|
|
|
|
*/
|
|
|
|
|
|
void updateSelectedPointsDisplay();
|
|
|
|
|
|
|
2026-01-17 12:29:57 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 从原始数据获取线上点(包含0,0,0)
|
|
|
|
|
|
*/
|
|
|
|
|
|
QVector<QVector3D> getOriginalLinePoints(const SelectedLineInfo& lineInfo);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 更新线上点对话框内容
|
|
|
|
|
|
*/
|
|
|
|
|
|
void updateLinePointsDialog();
|
|
|
|
|
|
|
2026-01-16 01:04:43 +08:00
|
|
|
|
// 点云显示控件
|
|
|
|
|
|
PointCloudGLWidget* m_glWidget;
|
|
|
|
|
|
|
|
|
|
|
|
// 点云转换器
|
|
|
|
|
|
std::unique_ptr<PointCloudConverter> m_converter;
|
|
|
|
|
|
|
|
|
|
|
|
// 文件操作控件
|
|
|
|
|
|
QPushButton* m_btnOpenFile;
|
2026-02-07 23:46:44 +08:00
|
|
|
|
QPushButton* m_btnOpenSegment;
|
|
|
|
|
|
QPushButton* m_btnOpenPose;
|
2026-01-16 01:04:43 +08:00
|
|
|
|
QPushButton* m_btnClearAll;
|
2026-02-11 00:53:51 +08:00
|
|
|
|
|
|
|
|
|
|
// 视图角度输入控件
|
|
|
|
|
|
QLineEdit* m_editRotX;
|
|
|
|
|
|
QLineEdit* m_editRotY;
|
|
|
|
|
|
QLineEdit* m_editRotZ;
|
2026-01-16 01:04:43 +08:00
|
|
|
|
|
|
|
|
|
|
// 选点测距控件
|
2026-01-17 12:29:57 +08:00
|
|
|
|
QCheckBox* m_cbMeasureDistance;
|
2026-01-16 01:04:43 +08:00
|
|
|
|
QPushButton* m_btnClearPoints;
|
|
|
|
|
|
QLabel* m_lblPoint1;
|
|
|
|
|
|
QLabel* m_lblPoint2;
|
|
|
|
|
|
QLabel* m_lblDistance;
|
|
|
|
|
|
|
2026-02-07 23:46:44 +08:00
|
|
|
|
// 点1姿态输入控件
|
|
|
|
|
|
QLineEdit* m_editRx1;
|
|
|
|
|
|
QLineEdit* m_editRy1;
|
|
|
|
|
|
QLineEdit* m_editRz1;
|
|
|
|
|
|
QPushButton* m_btnShowPose1;
|
|
|
|
|
|
|
|
|
|
|
|
// 点2姿态输入控件
|
|
|
|
|
|
QLineEdit* m_editRx2;
|
|
|
|
|
|
QLineEdit* m_editRy2;
|
|
|
|
|
|
QLineEdit* m_editRz2;
|
|
|
|
|
|
QPushButton* m_btnShowPose2;
|
|
|
|
|
|
|
2026-02-11 00:53:51 +08:00
|
|
|
|
// 欧拉角旋转顺序选择
|
|
|
|
|
|
QComboBox* m_comboEulerOrder;
|
|
|
|
|
|
|
2026-01-16 01:04:43 +08:00
|
|
|
|
// 选线拟合控件
|
|
|
|
|
|
QPushButton* m_btnClearLine;
|
2026-01-17 12:29:57 +08:00
|
|
|
|
QPushButton* m_btnShowLinePoints;
|
2026-01-16 01:04:43 +08:00
|
|
|
|
QLineEdit* m_lineNumberInput;
|
|
|
|
|
|
QPushButton* m_btnSelectByNumber;
|
|
|
|
|
|
QRadioButton* m_rbVertical;
|
|
|
|
|
|
QRadioButton* m_rbHorizontal;
|
|
|
|
|
|
QLabel* m_lblLineIndex;
|
|
|
|
|
|
QLabel* m_lblLinePointCount;
|
|
|
|
|
|
|
2026-02-07 23:46:44 +08:00
|
|
|
|
// 输入线段控件
|
|
|
|
|
|
QLineEdit* m_editLineX1;
|
|
|
|
|
|
QLineEdit* m_editLineY1;
|
|
|
|
|
|
QLineEdit* m_editLineZ1;
|
|
|
|
|
|
QLineEdit* m_editLineX2;
|
|
|
|
|
|
QLineEdit* m_editLineY2;
|
|
|
|
|
|
QLineEdit* m_editLineZ2;
|
|
|
|
|
|
QPushButton* m_btnShowLine;
|
|
|
|
|
|
QPushButton* m_btnClearLine2;
|
|
|
|
|
|
|
2026-01-16 01:04:43 +08:00
|
|
|
|
// 点云列表
|
|
|
|
|
|
QListWidget* m_cloudList;
|
|
|
|
|
|
|
|
|
|
|
|
// 已加载的点云数量
|
|
|
|
|
|
int m_cloudCount;
|
|
|
|
|
|
|
|
|
|
|
|
// 当前点云的线信息(用于旋转)
|
|
|
|
|
|
int m_currentLineNum;
|
|
|
|
|
|
int m_currentLinePtNum;
|
|
|
|
|
|
|
|
|
|
|
|
// 原始完整点云数据(包含0,0,0点,用于旋转)
|
|
|
|
|
|
PointCloudXYZ m_originalCloud;
|
2026-01-17 12:29:57 +08:00
|
|
|
|
|
|
|
|
|
|
// 线上点对话框
|
|
|
|
|
|
QDialog* m_linePointsDialog;
|
|
|
|
|
|
QTableWidget* m_linePointsTable;
|
|
|
|
|
|
QVector<QVector3D> m_currentLinePoints; // 当前线的原始点坐标
|
2026-02-11 00:53:51 +08:00
|
|
|
|
|
|
|
|
|
|
// 矩阵变换控件
|
|
|
|
|
|
QTextEdit* m_matrixEdit;
|
|
|
|
|
|
QPushButton* m_btnLoadMatrix;
|
|
|
|
|
|
QPushButton* m_btnApplyMatrix;
|
|
|
|
|
|
QPushButton* m_btnResetMatrix;
|
2026-01-16 01:04:43 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#endif // CLOUD_VIEW_MAIN_WINDOW_H
|