Utils/CloudView/Inc/CloudViewMainWindow.h

421 lines
10 KiB
C
Raw Normal View History

2026-02-19 00:45:00 +08:00
#ifndef CLOUD_VIEW_MAIN_WINDOW_H
#define CLOUD_VIEW_MAIN_WINDOW_H
#include <QMainWindow>
#include <QWidget>
#include <QPushButton>
#include <QToolButton>
2026-02-19 00:45:00 +08:00
#include <QLabel>
#include <QListWidget>
#include <QGroupBox>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QSplitter>
#include <QFileDialog>
#include <QMessageBox>
#include <QStatusBar>
#include <QLineEdit>
#include <QRadioButton>
#include <QCheckBox>
2026-07-11 18:33:31 +08:00
#include <QComboBox>
#include <QDialog>
#include <QStringList>
#include <memory>
2026-02-19 00:45:00 +08:00
2026-07-13 18:56:01 +08:00
#include "CloudView3D.h"
#include "PointCloudConverter.h"
2026-02-19 00:45:00 +08:00
2026-07-11 18:33:31 +08:00
class QTextEdit;
class QTableWidget;
class QCloseEvent;
2026-02-19 00:45:00 +08:00
/**
* @brief
*
*/
class CloudViewMainWindow : public QMainWindow
{
Q_OBJECT
2026-07-11 18:33:31 +08:00
public:
struct StartupFiles
{
QStringList displayFiles;
QStringList bboxFiles;
QStringList circleFiles;
QStringList rectangleFiles;
QStringList surfaceFiles;
QStringList triangleFiles;
bool sequential = false;
};
explicit CloudViewMainWindow(QWidget* parent = nullptr);
~CloudViewMainWindow() override;
bool loadStartupFiles(const StartupFiles& files);
bool loadDisplayFile(const QString& fileName);
bool loadCircleShapeFile(const QString& fileName);
bool loadRectangleShapeFile(const QString& fileName);
bool loadSurfaceShapeFile(const QString& fileName);
bool loadTriangleShapeFile(const QString& fileName);
void fitViewToContent();
protected:
bool eventFilter(QObject* obj, QEvent* event) override;
void closeEvent(QCloseEvent* event) override;
private:
enum class StartupFileType
{
Display,
BBox,
Circle,
Rectangle,
Surface,
Triangle
};
struct StartupItem
{
StartupFileType type;
QString fileName;
};
void buildStartupSequence(const StartupFiles& files);
bool loadStartupItem(const StartupItem& item);
bool loadCurrentStartupSequenceItem();
private slots:
2026-02-19 00:45:00 +08:00
/**
* @brief
*/
void onOpenFile();
/**
* @brief 姿
*/
void onOpenPoseFile();
/**
* @brief JSON文件
*/
void onOpenBBoxFile();
2026-02-19 00:45:00 +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-03-01 18:14:19 +08:00
/**
* @brief 1
*/
void onPoint1CoordChanged();
/**
* @brief 2
*/
void onPoint2CoordChanged();
2026-02-19 00:45:00 +08:00
/**
* @brief
*/
void onViewAnglesChanged(float rotX, float rotY, float rotZ);
/**
* @brief 线线
*/
void onSelectLineByNumber();
/**
* @brief 线/
*/
void onLineSelectModeChanged(bool checked);
/**
* @brief 线
*/
void onShowLinePoints();
/**
* @brief 线
*/
void onLinePointTableClicked(int row, int column);
/**
* @brief 1姿
*/
void onShowPose1();
/**
* @brief 2姿
*/
void onShowPose2();
/**
* @brief 线
*/
void onShowInputLine();
/**
* @brief 线
*/
void onClearInputLine();
/**
* @brief
*/
void onEulerOrderChanged(int index);
/**
* @brief
2026-02-19 00:45:00 +08:00
*/
void onEyeToHandTransform();
2026-02-19 00:45:00 +08:00
/**
* @brief + 姿
2026-02-19 00:45:00 +08:00
*/
void onEyeInHandTransform();
2026-02-19 00:45:00 +08:00
void onGeneratePointCloud();
void onRotateCloudByZ();
void onSavePointCloud(); // 保存 txt 点云
void onSavePlyPcdCloud(); // 保存 ply/pcd 点云
2026-07-03 12:46:19 +08:00
void onBatchConvertTxtToPly(); // 批量转换 txt -> ply
2026-07-11 18:33:31 +08:00
void onConvertEulerMatrix();
void onShowCircleShape();
void onShowRectangleShape();
void onShowSurfaceShape();
void onShowTriangleShape();
2026-02-19 00:45:00 +08:00
/**
* @brief 姿
*/
void onPoseCompensation();
2026-02-19 00:45:00 +08:00
private:
/**
* @brief
*/
void setupUI();
/**
* @brief
*/
QWidget* createViewerArea();
/**
* @brief
*/
QWidget* createControlPanel();
/**
* @brief
*/
QGroupBox* createFileGroup();
/**
* @brief 3D视图左侧
2026-02-19 00:45:00 +08:00
*/
QWidget* createViewToolbar();
2026-02-19 00:45:00 +08:00
/**
* @brief
*/
QGroupBox* createMeasureGroup();
/**
* @brief
*/
QWidget* createMeasurePage();
/**
* @brief 线
*/
QWidget* createLinePage();
/**
* @brief 线
*/
QGroupBox* createLineGroup();
/**
* @brief
*/
QGroupBox* createCloudListGroup();
/**
* @brief
*/
2026-07-13 18:56:01 +08:00
void updateSelectedPointsDisplay();
void clearMeasureResultDisplay();
void updateMeasureResultDisplay(const SelectedPointInfo& p1,
const SelectedPointInfo& p2,
float distance,
const QString& statusPrefix = QString());
/**
2026-02-19 00:45:00 +08:00
* @brief 线0,0,0
*/
QVector<QVector3D> getOriginalLinePoints(const SelectedLineInfo& lineInfo);
/**
* @brief 线
*/
void updateLinePointsDialog();
2026-02-22 16:54:45 +08:00
/**
* @brief
* @return
*/
bool loadPointCloudFile(const QString& fileName);
/**
* @brief 线Poly格式
* @return 线
*/
bool loadSegmentFile(const QString& fileName);
/**
* @brief JSON文件
* @return
*/
bool loadBoundingBoxFile(const QString& fileName);
2026-07-11 18:33:31 +08:00
void applyTransformToAllClouds(const QMatrix4x4& matrix);
void addGeneratedCloud(const PointCloudXYZ& cloud, const QString& name);
2026-07-13 18:56:01 +08:00
void showBasicShape(const QString& shapeName,
const QVector<LineSegment>& segments,
const QVector<BasicShapePoint>& points = QVector<BasicShapePoint>());
2026-07-11 18:33:31 +08:00
void showBasicSurface(const QString& shapeName, const QVector<SurfaceQuad>& surfaces, const QVector<LineSegment>& outlines);
2026-02-19 00:45:00 +08:00
// 点云显示控件
PointCloudGLWidget* m_glWidget;
// 点云转换器
std::unique_ptr<PointCloudConverter> m_converter;
// 文件操作控件
QPushButton* m_btnOpenFile;
QPushButton* m_btnOpenBBox;
2026-02-19 00:45:00 +08:00
QPushButton* m_btnClearAll;
// 视图角度输入控件
QLineEdit* m_editRotX;
QLineEdit* m_editRotY;
QLineEdit* m_editRotZ;
// 选点测距控件
QCheckBox* m_cbMeasureDistance;
QPushButton* m_btnClearPoints;
2026-07-13 18:56:01 +08:00
QLabel* m_lblPoint1;
QLabel* m_lblPoint2;
QLabel* m_lblDistance;
QLabel* m_lblDeltaXYZ;
2026-02-19 00:45:00 +08:00
2026-03-01 18:14:19 +08:00
// 点1坐标编辑控件
QLineEdit* m_editPoint1X;
QLineEdit* m_editPoint1Y;
QLineEdit* m_editPoint1Z;
// 点2坐标编辑控件
QLineEdit* m_editPoint2X;
QLineEdit* m_editPoint2Y;
QLineEdit* m_editPoint2Z;
2026-02-19 00:45:00 +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;
// 姿态坐标轴缩放
QLineEdit* m_editPoseScale;
2026-02-19 00:45:00 +08:00
// 欧拉角旋转顺序选择
QComboBox* m_comboEulerOrder;
// 选线拟合控件
QPushButton* m_btnClearLine;
QPushButton* m_btnShowLinePoints;
QLineEdit* m_lineNumberInput;
QPushButton* m_btnSelectByNumber;
QRadioButton* m_rbVertical;
QRadioButton* m_rbHorizontal;
QLabel* m_lblLineIndex;
QLabel* m_lblLinePointCount;
// 输入线段控件
QLineEdit* m_editLineX1;
QLineEdit* m_editLineY1;
QLineEdit* m_editLineZ1;
QLineEdit* m_editLineX2;
QLineEdit* m_editLineY2;
QLineEdit* m_editLineZ2;
QPushButton* m_btnShowLine;
QPushButton* m_btnClearLine2;
// 点云列表
QListWidget* m_cloudList;
// 已加载的点云数量
int m_cloudCount;
// 当前点云的线信息(用于旋转)
int m_currentLineNum;
int m_currentLinePtNum;
// 原始完整点云数据包含0,0,0点用于旋转
PointCloudXYZ m_originalCloud;
// 线上点对话框
QDialog* m_linePointsDialog;
QTableWidget* m_linePointsTable;
QVector<QVector3D> m_currentLinePoints; // 当前线的原始点坐标
2026-07-11 18:33:31 +08:00
// 悬浮缩放按钮
QToolButton* m_btnZoomIn;
QToolButton* m_btnZoomOut;
// 启动参数序列显示
QVector<StartupItem> m_startupSequence;
int m_startupSequenceIndex;
bool m_startupSequentialMode;
};
2026-02-19 00:45:00 +08:00
#endif // CLOUD_VIEW_MAIN_WINDOW_H