QT cmake cc级联pcl 魔改项目

目录

一、缘起:

二、qt 的cmake编译

1.最终目录如下:

2.相关cmakelist修改

3.qpcl的启用

三、实际代码的魔改

1.cc的插件及ui的改造

2.MainWindow.cpp

3.点云文件的显示

4.最终集成进自己的项目

四、总结:

1.QT 64位报错 0xc000007b,这个报错不是 缺DLL 就是 64 与 32位混掉了的缘故。

2.CDB process terminated unexpectedly (exit code : -2)


一、缘起:

还是公司的项目需求,不过原本CC的UI层相关中内容太多,而且和项目需求差异也比较大,所以准备魔改CC (couldCompare )的界面层相关qcc,核心cclib是不准备做任何改动的。

因为有之前的准备相关cmake 构建和准备,同时 qt 也选择了cmake构建工程,就是为了能方便集成进入自己项目中魔改的,所以这次相对顺利很多。

前置环境  以及  cmake 构建 CC 级联 编译pcl 参考笔者上篇内容:

《CMAKE构建 QT5 CC PCL 点云相关》

二、qt 的cmake编译

因为git 上涉及跨平台的项目都是需要cmake构建,所以在搭建QT项目的时候就选择了cmake构建。所以基本上在有了cmake 基本语法和基础知识和了解后,了解下与QT cmake的区别和qt 专有的相关内容即可。

原本想着这两个是同一个东西,而且都是cmake编译,而且已经确定是qt构建的所以直接都没改,用qt cmake编译直接各种报错:

so,一看还是要做工程改动,主要几个问题:目录重构,资源的重新载入。反正都是路径的问题

1.最终目录如下:

自己的项目是确定了qt 环境的所有直接通过qt 生成的,剩下的就是直接将CC需要的功能搬入集成并剔除不要的界面层qcc目录,画圈的是直接从原本qcc中提取的,可以自己根据需求使用,然后修改CMakeLists.txt即可。

2.相关cmakelist修改

主要是icones.qrc资源文件集成,和需要用的一些功能代码的集成(有的直接从qcc中拷贝来的)

打马赛克的地方为一些本项目使用的公司需求相关内容不展示了。

主要和CC相关的魔改cmake部分如上。

3.qpcl的启用

plugins/core/standard/qPCL/CMakeLists.txt

option( PLUGIN_STANDARD_QPCL "Check to install qPCL plugin" OFF ) --->OFF改成ON开启

include( ../../../CMakePluginTpl.cmake )  ==========》 plugins/CMakePluginTpl.cmake

也可以在qt cmake 项目构建配置中找对应选项直接勾选:

然后一路编译居然一次即过,真是惊呆了,意外的顺利:

不过一次即过才应该是常态,毕竟都是cmake的。

说明上面基本上的目录和cmakelist的修改应该是正确的。

在概要信息中是直接可以查看编译信息的,不需要像cmake一样手动去开启调试信息。

而且此处原本cmake构建时候侦测成32位的,在这个qt 的cmake是直接可以侦测出来是64位的,不知道是不是和之前改过有关系,也懒的再去看了。

一切编译成功后,

工程项目的结构的一栏中cmakemodel中也会正确的出现相关cmake的相关配置文件

三、实际代码的魔改

1.cc的插件及ui的改造

如果只使用 CC的相关文件格式 bin txt ply 等格式实际上是很简单的不需要插件模块的,

但是笔者还需要使用pcd 等一些第三方的格式,需要加入插件相关内容,

CC的插件分为三种类型:CC_STD_PLUGIN,CC_GL_FILTER_PLUGIN,CC_IO_FILTER_PLUGIN

标准型,第三方型(分两个子类好像是IO 和 Core),还有一种没仔细注意,

所以相关不用的可全部注释掉。

-------以下---2023---10----07----补充----

CC_STD_PLUGIN   标准型
CC_GL_FILTER_PLUGIN:
    --》Core型
    --》thirdParty型
CC_IO_FILTER_PLUGIN: io型比如文件格式解析/保存,不具备滤波等功能操作
-------以上---2023---10----07----补充----

//插件管理类,QT 原生
class ccPluginUIManager : public QObject
{
	//其他都是主界面控件相关的一些关联管理,可全部注释掉
    ........
	//关键变量
	QList<ccPluginInterface *> m_plugins;

    ......

}

同时一些宏条件编译直接剔除了,不过命令行运行还是保留了,不知道会不会和UI有共享使用的东西,main.cpp代码精简后如下:

int main(int argc, char *argv[])
{
    bool commandLine = (argc > 1) && (argv[1][0] == '-');
    if ( !commandLine )
    {
        ccApplication::initOpenGL();
    }


    ccApplication app(argc, argv, commandLine);

    //store the log message until a valid logging instance is registered
    ccLog::EnableMessageBackup(true);

    //restore some global parameters
    {
        QSettings settings;
        settings.beginGroup(ccPS::GlobalShift());
        double maxAbsCoord = settings.value(ccPS::MaxAbsCoord(), ccGlobalShiftManager::MaxCoordinateAbsValue()).toDouble();
        double maxAbsDiag = settings.value(ccPS::MaxAbsDiag(), ccGlobalShiftManager::MaxBoundgBoxDiagonal()).toDouble();
        settings.endGroup();

        ccLog::Print(QString("[Global Shift] Max abs. coord = %1 / max abs. diag = %2").arg(maxAbsCoord, 0, 'e', 0).arg(maxAbsDiag, 0, 'e', 0));

        ccGlobalShiftManager::SetMaxCoordinateAbsValue(maxAbsCoord);
        ccGlobalShiftManager::SetMaxBoundgBoxDiagonal(maxAbsDiag);
    }
    //global structures initialization
    FileIOFilter::InitInternalFilters(); //load all known I/O filters (plugins will come later!)
    ccNormalVectors::GetUniqueInstance(); //force pre-computed normals array initialization
    ccColorScalesManager::GetUniqueInstance(); //force pre-computed color tables initialization

    ccPluginManager::get().loadPlugins();

    int result = 0;

    QTranslator translator;
    const QStringList uiLanguages = QLocale::system().uiLanguages();
    for (const QString &locale : uiLanguages) {
        const QString baseName = "xxxxTester_" + QLocale(locale).name();
        if (translator.load(":/i18n/" + baseName)) {
            app.installTranslator(&translator);
            break;
        }
    }

    MainWindow w;
    w.setWindowFlags(Qt::WindowCloseButtonHint | Qt::WindowMinimizeButtonHint|Qt::MSWindowsFixedSizeDialogHint);
    w.showMaximized();
    //w.setFixedSize(w.width(), w.height());
    QApplication::processEvents();


    QDir  workingDir = QCoreApplication::applicationDirPath();
    QDir::setCurrent(workingDir.absolutePath());

    result = app.exec();

    //release global structures
    FileIOFilter::UnregisterAll();

    return result;
}
2.MainWindow.cpp

主要窗体结构的更改,如果不用插件系统,则不需要继承 ccMainAppInterface

ccMainAppInterface这是个接口类,在使用插件中提供给各第三方插件使用的各种方法接口来对本界面上相关的内容操作的,所以如果不需要使用插件可以直接不继承此接口。

同时除了ccMainAppInterface接口的override函数外,还有一些和 DB树视图和属性页视图相关的回显,如果不使用相关的CC定义的控件显示,

或者准备和笔者一样完全魔改的,完全可以注释重改流程。

这样的话整个MainWindow.cpp 会更加精简,可读性更高。

class MainWindow : public QMainWindow,public ccMainAppInterface
{


dbTreeView//自定义显示的控件变量,不用可注释掉,视图模型关联到 ccDBRoot

//-----构造初始化的时候:

//非常重要信号函数,由m_ccRoot->changeSelection内部发射回来 不用显示就注释掉
connect(m_ccRoot, &ccDBRoot::selectionChanged,    this,&MainWindow::updateUIWithSelection);

//不用显示就注释掉,同上
connect(m_ccRoot, &ccDBRoot::dbIsEmpty, [&]() { updateUIWithSelection(); updateMenus(); }); //we don't call updateUI because there's no need to update the properties dialog

//不用显示就注释掉,同上
connect(m_ccRoot, &ccDBRoot::dbIsNotEmptyAnymore, [&]() { updateUIWithSelection(); updateMenus(); }); 
//we don't call updateUI because there's no need to update the properties dialog
   


}
3.点云文件的显示

MainWindow主窗体中显示点云模型是通过MDI的多文档窗体中子窗口显示的,但在本项目中实际不需要MDI,原本想SDI也可以,后来看QT 的界面控件关联 比MFC的简单太多,没什么panel 之类的这种区分,widget 中嵌widget 直接可以,所以就直接使用一个widget 显示就可以了。

qcc原本的核心显示原理是

1.doActionLoadFile()函数执行打开文件选择对话框(会更具CC插件的内容确认一些额外的格式信息选择),

2.addToDB()解析对应的格式存储在 CC核心的数据格式:ccHObject 中,里面包含了点云数据和属性解析等。

3.new3DView()中对视图窗口的场景设置为 ccHObject* 对象指针。这样只要指针实列一变串口模型就可以更着变化了。

相关显示模型的核心代码的分析整理如下:

class Q_CORE_EXPORT QAbstractItemModel : public QObject;

//QT 的原生结构,提DB视图 及对应读取文件的属性视图的管理和相关操作
class ccDBRoot : public QAbstractItemModel
{
	ccHObject* m_treeRoot;//树视图模型--- CC的主要结构
	
	QTreeView* m_dbTreeWidget;//QT窗体显示部件视图,可不用注释

    //如果涉及其他qCC中相关的界面控件元素使用需要回去刷新,这是一个接口继承的函数重写
	MainWindow::RefreshAllGLWindow(false);

    //显示模型使用,非常重要,由加载文件后变更此内容,引起3D视窗中模型变化
	ccHObject* ccDBRoot::getRootEntity()
	{
		return m_treeRoot;
	}
	
	//CCDBRoot.cpp	line 357
	void ccDBRoot::addElement(ccHObject* object, bool autoExpand/*=true*/)
	{
	
	}
	
	//本类中非槽函数,在提供给主页面树形部件 信号链接的槽函数,调用本函数
    //CCDBRoot.cpp	line 964
	void ccDBRoot::selectEntities(std::unordered_set<int> entIDs);

}



//一些文件选择对话框相关的设置操作,主要是 是文件过滤相关内容
doActionLoadFile()
------>addToDB(....);
		{
			//主要的核心调用--CC的从文件加载内容的解析及结构化
			ccHObject* newGroup = FileIoFilter::LoadFormFile(...);
		
				if (destWin)
				{
					newGroup->setDisplay_recursive(destWin);
				}
				addToDB(newGroup, true, true, false)--》 {
							//add object to DB root
							if (m_ccRoot)
							{
									//force a 'global zoom' if the DB was emtpy!
									if (!m_ccRoot->getRootEntity() || m_ccRoot->getRootEntity()->getChildrenNumber() == 0)
									{
										updateZoom = true;
									}
									m_ccRoot->addElement(obj, autoExpandDBTree);//obj = newGroup
							}
				
				
				
					}
		
		}



	//初始化 生成视窗窗口,重要
	new3DView(true);
	
	//槽链接函数,提供给 新曾视图窗口按钮使用
	connect(m_UI->actionNew3DView,					&QAction::triggered, this, &MainWindow::new3DView);

//主窗体结构接口 继承 的 函数
void MainWindow::activateRegisterPointPairTool(){...new3DView()...}

//主窗体结构接口 继承 的 函数
void MainWindow::activateSectionExtractionMode(){...new3DView()...};


//主窗体结构接口 继承 的 函数,非常重要
new3DView(){

void ccDBRoot::selectEntities(std::unordered_set<int> entIDs);

view3D->setSceneDB(m_ccRoot->getRootEntity());


}


//#include "ccPropertiesTreeDelegate.h"
//#include "ccSelectChildrenDlg.h"
/*
不是必须的头文件,一旦引入会引入一堆 和点云值和模型属性显示相关的界面
相关内容可都注释掉
ccDBRoot <-------   sfEditDlg	<----   ccHistogramWindow.h
ccDBRoot <-------   ccColorScaleEditorDlg.h
ccSelectChildrenDlg.h
*/



//视口上 线宽和点大小尺寸的 + -号  不显示问题
ccGLWindow.cpp

void ccGLWindow::renderText(......);

void ccGLWindow::drawClickableItems(.....){




    //+ -号的相关资源图片调用
	//line 1398:
	static const QImage c_minusPix = QImage(":/CC/images/ccMinus.png").mirrored();
	static const QImage c_plusPix = QImage(":/CC/images/ccPlus.png").mirrored();



	line 1414 call  ccGLUtils::DisplayTexture2DPosition


}


ccGLUtils.cpp
void ccGLUtils::DisplayTexture2DPosition(...)	//line 24
4.最终集成进自己的项目

内容魔改效果图如下:(以下是魔改过程中遇到的一些小问题的图片记录及以上的解决过程)

同时主界面采用的是QT 的dockWidget处理,所有可以进行浮动拖拽,

四、总结:

本次的魔改主要对QT的界面开发及QT cmake构建开发项目收获比较巨大,

但是QT 的IDE 调试器真的是太不友好了,总之没VS 的好用。

过程中稍微遇到一些异常就奔溃了或者不能继续调试,只能重启了在重新调试这种问题比比皆是。

1.QT 64位报错 0xc000007b,这个报错不是 缺DLL 就是 64 与 32位混掉了的缘故。

具体可参考:QT出现应用程序无法正常启动0xc000007b的错误_qt应用程序无法正常启动0xc000007b_水军总督的博客-CSDN博客


ACLUI.DLL
ACTIVEDS.DLL
ADSLDPC.DLL
ADVAPI32.DLL
ADVPACK.DLL
AEPIC.DLL

2.CDB process terminated unexpectedly (exit code : -2)

这个比较坑,

网上有差不多的问题:解决QT无法调试问题-----the cdb process terminated unexpectedly (exit code -805306296)_qt不能调试_lizhengl的博客-CSDN博客
 

QT运行出现The CDB process terminated解决办法(亲测有效)_bloomerOAO的博客-CSDN博客

但是我的错误代码是 -2的,不过看这两个的问题处理都是和IDE相关的,所以大概猜测了一下,

因为公司电脑由加密所以,把IDE中相关的一些文件全部加密了,导致运行可以,但是只要一调试调用CDB就报这个错。

后来解密下,就可以了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值