当然可以,我们一起来分析 ccPointPickingGenericInterface
这个接口类,它是 CloudCompare 中用于点选操作相关交互工具的通用基类,代码结构清晰、职责单一,适合作为各种需要鼠标选点功能工具的基类。
ccPointPickingGenericInterface
ccPointPickingGenericInterface.h
ccPointPickingGenericInterface.cpp
class ccPointPickingGenericInterface : public ccOverlayDialog, public ccPickingListener
ccOverlayDialog
:CloudCompare 中所有工具浮窗的基类,提供对话框与渲染窗口的绑定、开始/停止的接口。ccPickingListener
:CloudCompare 的拾取回调接口,专门用来监听鼠标选中的点等拾取信息。该类是一个抽象基类(接口类),用于实现所有基于鼠标点选操作的工具。例如:点距离测量工具、基准点选取、投影工具等。
它为这些工具提供了统一的拾取点逻辑框架,具体点选处理逻辑由子类实现。
explicit ccPointPickingGenericInterface(ccPickingHub* pickingHub, QWidget* parent = nullptr);
ccPickingHub*
对象,用于注册监听点选事件。ccPickingHub
是点选事件调度中心,可以同时支持多个监听器。bool ccPointPickingGenericInterface::linkWith(ccGLWindowInterface* win)
ccGLWindowInterface
(渲染窗口)。ccOverlayDialog::linkWith(win)
是基类实现的绑定逻辑,必须调用。bool ccPointPickingGenericInterface::start()
m_pickingHub->addListener(this, true, true, POINT_PICKING)
注册本对象到 ccPickingHub
。ccOverlayDialog::start()
调用后进入浮窗显示状态。void ccPointPickingGenericInterface::stop(bool state)
ccOverlayDialog::stop(state)
通知父类退出浮窗状态。void ccPointPickingGenericInterface::onItemPicked(const PickedItem& pi)
ccPickingListener
,当用户通过鼠标在窗口中拾取了一个点,会调用此函数。processPickedPoint(pi)
,由子类进一步处理。ccPickingHub* m_pickingHub;
功能 | 实现方式 |
---|---|
绑定渲染窗口 | linkWith() |
注册监听点拾取 | start() |
处理拾取结果 | onItemPicked() 调用 processPickedPoint() |
停止拾取并解绑 | stop() |
留给子类扩展逻辑 | processPickedPoint() (纯虚函数) |
你可以看到该类作为如下功能的基础类:
子类继承这个接口后只需实现 processPickedPoint()
,即可实现各种响应逻辑,避免重复构建点选管理逻辑。
你目前提供的两个基类是:
ccOverlayDialog
:是一个基于 QDialog
的界面类,用于作为叠加式的工具对话框;ccPickingListener
:是一个抽象接口类,用于响应 3D 视图中的点/面拾取事件。下面对这两个类进行详细分析,并结合它们在 CloudCompare 中可能的继承用途进行总结。
ccOverlayDialog
分析(继承自 QDialog
)该类是 CloudCompare 中所有工具对话框(如测量、剪裁、绘图等)的通用基类,它:
FramelessWindowHint | Tool
设置);ccGLWindowInterface
;start()
/ stop()
流程控制接口;窗口与渲染窗口联动:通过 linkWith(ccGLWindowInterface* win)
绑定到具体的渲染视图;
生命周期管理:start()
和 stop(bool accepted)
管理工具的运行状态;
快捷键支持:可通过 addOverriddenShortcut(Qt::Key key)
添加快捷键;
自动监听 Esc
退出;
事件过滤器:过滤并响应窗口事件、快捷键事件、Show
事件;
信号:
processFinished(bool)
:工具流程结束时发出;shortcutTriggered(int)
:自定义快捷键被触发;shown()
:窗口展示时发出;ccPickingListener
分析(接口类)该类是 CloudCompare 中与鼠标拾取(pick)相关的功能接口,用于响应:
纯虚函数:
virtual void onItemPicked(const PickedItem& pi) = 0;
子类必须实现该函数,响应用户拾取行为。
数据结构 PickedItem
:
提供了拾取位置、目标实体、点索引、3D 坐标、barycentric 坐标等详细信息。
一个继承了 ccOverlayDialog
和 ccPickingListener
的类将:
这种多重继承设计非常适合构建 “带界面的拾取工具”,例如:
class MyPickingDialog : public ccOverlayDialog, public ccPickingListener
{
Q_OBJECT
public:
MyPickingDialog(QWidget* parent = nullptr);
//实现拾取处理逻辑
void onItemPicked(const PickedItem& pi) override;
//界面初始化和开始逻辑
void startPicking();
private:
//内部状态,比如拾取的点集合、选中实体等
};
基类 | 功能类型 | 特点说明 |
---|---|---|
ccOverlayDialog |
UI框架 | QDialog 弹窗形式工具,能绑定视图、接收快捷键等 |
ccPickingListener |
拾取接口 | 响应用户在三维视图中点击选择点、面、中心的事件 |
多继承配合 | 工具设计模板 | 能设计“带界面的交互工具”,响应鼠标点选并处理对应逻辑 |
如你正在设计测量工具或交互工具界面,这两个类正是 CloudCompare 插件或内部功能的标准模式,可以直接扩展复用。需要帮助实现具体类或功能时可继续提供具体需求。
CloudCompare 中继承自 ccPointPickingGenericInterface
的两个类之一 —— ccPointPropertiesDlg
,它主要是一个用于点拾取和属性显示的对话框类。现在我们来详细分析这个类以及其在项目中的作用:
ccPointPropertiesDlg
的职责该类继承自 ccPointPickingGenericInterface
,用于管理如下几种拾取/测量模式:
模式名 | 功能说明 |
---|---|
POINT_INFO |
显示单个点的属性信息(如坐标、标量值等) |
POINT_POINT_DISTANCE |
计算两个点之间的距离 |
POINTS_ANGLE |
计算三个点所构成夹角 |
RECT_ZONE |
矩形区域选择(2D 区域) |
Mode m_pickingMode; // 当前拾取模式
cc2DLabel* m_label; // 用于显示点、距离、角度的2D标签
cc2DViewportLabel* m_rect2DLabel; // 用于绘制矩形区域的2D标签
bool start() override; // 开始拾取,默认启用点信息模式
void stop(bool state) override; // 停止拾取,清除状态
bool linkWith(ccGLWindowInterface* win) override; // 绑定窗口,注册事件
void processPickedPoint(const PickedItem&) override; // 处理拾取点
void activatePointPropertiesDisplay();
void activateDistanceDisplay();
void activateAngleDisplay();
void activate2DZonePicking();
void exportCurrentLabel(); // 导出当前标签为实体(可用于保存或进一步操作)
void initializeState(); // 重置当前状态
void update2DZone(int x, int y, Qt::MouseButtons buttons); // 鼠标拖动区域时调用
void processClickedPoint(int x, int y); // 处理2D区域点击
void close2DZone(); // 鼠标释放时结束矩形选择
processPickedPoint
工作流程详解这是该类最核心的处理逻辑,它会根据当前模式执行如下动作:
processClickedPoint
)并且在每次点选后,会输出点信息至控制台日志(ccLog::Print()
)。
linkWith
功能说明此函数将标签与 ccGLWindowInterface
绑定,注册信号槽响应(如鼠标移动、点击等)。它还负责在不同窗口切换时的清理/注册逻辑,确保标签显示不混乱。
ccPointPropertiesDlg
的核心价值该类提供了直观、可视化的点拾取交互工具,具备以下特性:
ccPointPickingGenericInterface
)它是 CloudCompare 交互式测量功能中的核心组件之一。
你贴出的 ccPointListPickingDlg
类是 CloudCompare 中 点列表拾取功能的完整交互对话框类,是一个核心 UI 类,继承自 ccPointPickingGenericInterface
,并结合 Qt Designer 的 UI 界面类(Ui::PointListPickingDlg
)。这个类的主要功能是让用户通过图形界面 依次拾取点并管理点列表、导出数据或生成新对象(如 polyline、点云等)。
功能 | 描述 |
---|---|
拾取点 | 支持交互方式拾取多个点,显示在列表中 |
导出点列表 | 支持导出为 ASCII 文件(多种格式)、点云或 polyline |
撤销拾取 | 可撤销最近点或全部点(通过 UI 按钮) |
支持取消还原 | 用户取消拾取时恢复原始状态 |
交互性强 | 拾取过程中标记点、重绘窗口、修改标注尺寸和索引等 |
class ccPointListPickingDlg
: public ccPointPickingGenericInterface, // 拾取点通用接口(虚函数 processPickedPoint)
, public Ui::PointListPickingDlg // Qt UI 界面(控件等)
ccPointPickingGenericInterface
:抽象接口类,提供通用的点拾取机制(定义了 processPickedPoint()
虚函数)。Ui::PointListPickingDlg
:由 Qt Designer 生成的界面类,包含按钮、表格等控件。ccPointListPickingDlg(ccPickingHub* pickingHub, QWidget* parent);
ccPickingHub
(CloudCompare 的中心拾取系统)。void processPickedPoint(const PickedItem& picked) override;
m_toBeAdded
等待后续处理。void linkWithEntity(ccHObject* entity);
void exportToNewCloud();
void exportToNewPolyline();
void exportToASCII(ExportFormat format); // 支持多种导出格式
exportToNewCloud()
:将拾取的点生成一个新的 ccPointCloud
。
exportToNewPolyline()
:按拾取顺序连接成 polyline。
exportToASCII(format)
:
XYZ
:基本坐标IXYZ
:带点索引GXYZ
:带全局索引LXYZ
:带标签或注释等void removeLastEntry(); // 撤销最近一个
void cancelAndExit(); // 取消所有新建标注
void applyAndExit(); // 确认当前拾取
m_toBeDeleted
, m_toBeAdded
管理新增/待删除对象,支持撤销。void markerSizeChanged(int);
void startIndexChanged(int);
void updateList();
updateList()
会更新 Qt 表格显示当前所有拾取的点及其属性。成员变量 | 含义 |
---|---|
ccHObject* m_associatedEntity |
当前操作的点云或网格 |
ccHObject* m_orderedLabelsContainer |
顺序存储生成的 cc2DLabel 对象 |
ccHObject::Container m_toBeDeleted |
记录在取消时应删除的对象 |
ccHObject::Container m_toBeAdded |
记录在取消时应恢复的新增对象 |
unsigned m_lastPreviousID |
启动前已有标注的最大 ID(用于防止 ID 冲突) |
ccPointListPickingDlg
对话框)。linkWithEntity()
绑定点云或网格。processPickedPoint()
被调用,生成 2D label,记录坐标。m_toBeDeleted
/ m_toBeAdded
管理撤销。ccPointPickingGenericInterface
的区别?类名 | 作用 |
---|---|
ccPointPickingGenericInterface |
抽象接口类,定义拾取流程中的通用行为 |
ccPointListPickingDlg |
UI 层封装类,真正实现交互功能、管理拾取逻辑、绑定实体、导出 |
CloudCompare 中不同拾取功能(如三点测角、线段测距)都可能继承 ccPointPickingGenericInterface
,但使用不同 UI 封装类。
你提供的这份 ccPointListPickingDlg
类实现是 CloudCompare 中负责“点列表拾取与导出”的 UI 类之一。它允许用户在 3D 视图中交互式选择点、查看坐标、导出为点云或折线、保存为 ASCII 文本等。以下是对这段代码关键模块的结构性分析与说明:
功能 | 实现方式 |
---|---|
拾取点列表管理 | cc2DLabel 组合在 m_orderedLabelsContainer 中管理 |
拾取点的导出(ASCII/Cloud/Polyline) | exportToASCII_* ,exportToNewCloud() ,exportToNewPolyline() |
操作撤销(移除最后拾取点) | removeLastEntry() |
拾取序号设置与更新 | startIndexSpinBox 与 startIndexChanged() |
坐标系选择(局部/全局) | showGlobalCoordsCheckBox 与 updateList() |
UI 按钮与菜单构建 | 构造函数中创建 QMenu 并绑定 QAction |
持久化用户选项(文件路径等) | 使用 QSettings |
updateList()
:刷新当前点列表显示(表格视图)unsigned ccPointListPickingDlg::getPickedPoints(std::vector<cc2DLabel*>& pickedPoints)
m_orderedLabelsContainer
中所有可见的 cc2DLabel
(注意:排除 cc2DViewportLabel
)void ccPointListPickingDlg::linkWithEntity(ccHObject* entity)
exportToNewCloud()
:将拾取点导出为新的 ccPointCloud
,可用于保存/后续处理exportToNewPolyline()
:生成 ccPolyline
,常用于测量路径等用途exportToASCII_xyz()
等:将点导出为指定格式文本(X,Y,Z、标签、局部/全局索引)removeLastEntry()
:根据唯一 ID 判断是否是旧点,从添加或删除列表中更新状态cancelAndExit()
:恢复之前的标签状态(还原不可见等)applyAndExit()
:确认拾取点后从数据库中删除旧标签,清除临时缓存static const char s_defaultLabelBaseName[] = "Point #";
可用于后续自动命名拾取点,例如 “Point #0”, “Point #1” 等。
m_toBeDeleted
: 存储用户在当前会话中删除的旧点(在取消时恢复)m_toBeAdded
: 当前会话中新增的点(在撤销时删除)拓展项 | 建议实现 |
---|---|
支持多维数据导出 | 在 exportToASCII_* 中加入强度、颜色、法线等字段 |
导入功能 | 支持从 ASCII 导入点列表并创建 label |
支持区域选择添加标签 | 批量在选区中拾取点作为 label |
兼容多实体 | 当前 m_associatedEntity 是单一对象,未来可以扩展为多个实体支持 |
此类一般配合:
ccPickingHub
:处理鼠标点击拾取事件(点击点)cc2DLabel
:显示每个拾取点的2D标签信息MainWindow::TheInstance()->addToDB()
:统一添加/管理对象ccGLWindowInterface
:响应标注大小调整、重绘等 UI 操作