QT cmake CouldCompare 点操作功能移植记录3

目录

一、源起

二、CouldCompare的相关源码分析

三、最终效果

四、CC的实列流程源码分析

 五、修改的效果测试


一、源起

项目更新迭代以及新功能的需求,

本来就是点云的处理,需要对基于点的一些基本功能的处理支持(点的拾取,距离测量等)。

所以就有了这一次的功能增加。

环境等前置,参考前面:

QT cmake cc级联pcl 魔改项目-CSDN博客

主要还是记录,谨防遗忘,因为本身就是CouldCompare的功能移植进自己的项目而已。

二、CouldCompare的相关源码分析

CC的大概逻辑流程也是相对比较简单,都在猜测之内,所以整个移植和修改也相对简单,

毕竟也是有了前面的魔改基础了,就相对更容易把握。

class ccPickingHub : public QObject{

ccPickingHub::ccPickingHub{

    //修改部分,为了去除MDI的激活来选定此变量,直接固定即可
    m_activeGLWindow =app->getActiveGLWindow();
    connect(m_activeGLWindow, &ccGLWindow::itemPicked, this, &ccPickingHub::processPickedItem, Qt::UniqueConnection);
    connect(m_activeGLWindow, &QObject::destroyed, this, &ccPickingHub::onActiveWindowDeleted);
	//---以上修改-为增加内容---

}




bool addListener(....){}


public slots:
	void onActiveWindowChanged(QMdiSubWindow*)
	{
		.....
		....

		if (glWindow)
		{
			//重要,对于MDI 来说存在切换问题,每一次第一次进来的时候要与对应的信号绑定
			//对于我们的实列来说不存在这个问题,直接注释掉也可以,需要提升到构造函数中做一次操作即可
			connect(glWindow, &ccGLWindow::itemPicked, this, &ccPickingHub::processPickedItem, Qt::UniqueConnection);
			connect(glWindow, &QObject::destroyed, this, &ccPickingHub::onActiveWindowDeleted);
			m_activeGLWindow = glWindow;

			if (m_autoEnableOnActivatedWindow && !m_listeners.empty())
			{
				togglePickingMode(true);
			}
		}
	}
	
	
	void onActiveWindowDeleted(QObject*);

	void processPickedItem(ccHObject*, unsigned, int, int, const CCVector3&, const CCVector3d&){
	
	
		//核心 分配到关联的对应实列上
		std::set< ccPickingListener* > listeners = m_listeners;//由本类中对应的方法进行切换操作
		for (ccPickingListener* l : listeners)
		{
			if (l)
			{
				l->onItemPicked(item);
			}
		}	
	
	}


}


MainWindow : public QMainWindow, public ccMainAppInterface, public ccPickingListener {


	//picking hub
	{
		m_pickingHub = new ccPickingHub(this, this);
        //对于本列不是MDI 直接注释即可,别忘了需要修改下 m_pickingHub 内部
		//connect(m_mdiArea, &QMdiArea::subWindowActivated, m_pickingHub, &ccPickingHub::onActiveWindowChanged);
	}
connect(m_UI->actionPointPicking,&QAction::triggered, this, &MainWindow::activatePointPickingMode);

void onItemPicked(const PickedItem& pi) override;

    ccPointPropertiesDlg* m_ppDlg;
	
	//核心变量,相关变换的变量及信号发射到槽的实列变化都在此处完成,整个交换中枢,
    ccPickingHub* m_pickingHub;

//common
#include <ccPickingHub.h>


void MainWindow::activatePointPickingMode(){

/*----对应的相关依赖项----
pointPropertiesDlg.ui
ccPointPropertiesDlg.h
ccPointPropertiesDlg.cpp
ccPointPickingGenericInterface.h
ccPointPickingGenericInterface.cpp

*/


	if (!m_ppDlg)
	{
		m_ppDlg = new ccPointPropertiesDlg(m_pickingHub, this);
		connect(m_ppDlg, &ccOverlayDialog::processFinished,this, &MainWindow::deactivatePointPickingMode);
		connect(m_ppDlg, &ccPointPropertiesDlg::newLabel,this, &MainWindow::handleNewLabel);

		registerOverlayDialog(m_ppDlg, Qt::TopRightCorner);
	}

}

void MainWindow::cancelPreviousPickingOperation(bool aborted){
}

void MainWindow::onItemPicked(const PickedItem& pi){
}

}


class ccGLWindow{

ccGLWindow::startPicking(....){

	.....
	
	//在debug 下 拾取3D点 会走CPU这个方法  CPU-based point picking
	startCPUBasedPointPicking(params){
		//最终也是进入这个方法
		processPickingResult();
	
	};	

	startOpenGLPicking(params);
}

//关键,内部处理完成后发送信号到具体的实列上处理
ccGLWindow::processPickingResult(......){

	emit entitySelectionChanged(pickedEntity);

	emit itemPicked();

	emit itemPickedFast(.....)//信号发射

}


void ccGLWindow::onItemPickedFast(ccHObject* pickedEntity, int pickedItemIndex, int x, int y){
	.......
	.....
	...

	emit fastPickingFinished();//拾取 完成 信号发射 
}

}


//最终实列中做的处理,后期这整个对话框也可以优化掉。先功能移植过来。
class ccPointPropertiesDlg : public ccPointPickingGenericInterface,
{




void ccPointPropertiesDlg::processPickedPoint(const PickedItem& picked){

}

}

主要核心下面两个类和一个接口类:

ccPickingListener 主要接口类,

ccPickingHub 拾取处理,

ccGLWindow 所有视图显示相关的都在里面。

整个处理流程逻辑参考上面的源码分析。

三、最终效果

移植修改完毕后就是加入自己的处理流程了。

-----以下----编辑自2023-12-05---新增-----

四、CC的实列流程源码分析

通过上面的源码分析已经确定CC提供了设计上的实列扩展,

主要在:ccPointPropertiesDlg这个界面对话框类中,

因为后准备后期直接优化掉这个对话框所以也先做个简单的分析。

分析代码如下:

//注意 cc2DLabel 是继承自 ccHObject对象的
class QCC_DB_LIB_API cc2DLabel : public ccHObject, public ccInteractor{

}

class ccPointPropertiesDlg : public ccPointPickingGenericInterface, public Ui::PointPropertiesDlg
{


ccPointPropertiesDlg(){

	//标签对象,关键临时标签
	m_label = new cc2DLabel();
	m_label->setSelected(true);
	
	//2D 视图区域标签,关键临时标签
	m_rect2DLabel = new cc2DViewportLabel();
	m_rect2DLabel->setVisible(false);	//=invalid
	m_rect2DLabel->setSelected(true);	//=closed
	connect(saveLabelButton,&QToolButton::clicked, this, &ccPointPropertiesDlg::exportCurrentLabel);
}

void exportCurrentLabel(){

	ccHObject* newLabelObject = nullptr;
	if (m_pickingMode == RECT_ZONE)
	{
		newLabelObject = m_rect2DLabel = new cc2DViewportLabel();
		m_rect2DLabel->setVisible(false);	//=invalid
		m_rect2DLabel->setSelected(true);	//=closed
	}
	else
	{
		m_label->getPickedPoint(0).entity()->addChild(labelObject);
		newLabelObject = m_label = new cc2DLabel();
		m_label->setSelected(true);
	}
	
	//关键信号发射,并将标签对象传递过去
	//实列在 MainWindow.cpp 主页中
	//connect(view3D,	&ccGLWindow::newLabel, this, &MainWindow::handleNewLabel);
	emit newLabel(labelObject);	
}

void ccPointPropertiesDlg::processPickedPoint(const PickedItem& picked){
	.....
	//此处2D标签的对象的一些操作,后期魔改可用。
	m_label->addPickedPoint(static_cast<ccGenericPointCloud*>(picked.entity), picked.itemIndex, picked.entityCenter);
	m_label->setVisible(true);
	m_label->displayPointLegend(m_label->size() == 3); //we need to display 'A', 'B' and 'C' for 3-points labels
	if (m_label->size() == 1 && m_associatedWin)
	{
		m_label->setPosition(static_cast<float>(picked.clickPoint.x() + 20) / m_associatedWin->glWidth(), static_cast<float>(picked.clickPoint.y() + 20) / m_associatedWin->glHeight());
	}
	...
}

}




void MainWindow::handleNewLabel(ccHObject* entity)
{
    if (entity)
    {
        addToDB(entity);
        //需要做个分支判断,拾取的是点才做下面的处理
        //此处将对应的标签保存到自己的文件格式中
        cc2DLabel *label = (cc2DLabel *)entity;
        ccLog::Print(QString::fromLocal8Bit("[点域加入]\t- ")+label->getName());
    }
    else
    {
        assert(false);
    }
}

 五、修改的效果测试

上面仅是在控制日志 加入了一个打印 【点域加入】效果测试,如下图:

具体可根据实际需求在ccPointPropertiesDlg 中做一些更有必要的修改,

或者如笔者后期准备的直接魔改优化掉整个ccPointPropertiesDlg 对话框。

有了上面的这些分析,可以轻松搞定这些问题了。

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值