QT6+CloudCompare显示3D点云
Posted QtHalcon
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QT6+CloudCompare显示3D点云相关的知识,希望对你有一定的参考价值。
CloudCompare是一个三维点云(网格)编辑和处理软件。最初,它被设计用来对稠密的三维点云进行直接比较。它依赖于一种特定的八叉树结构,在进行点云对比这类任务时具有出色的性能。此外,由于大多数点云都是由地面激光扫描仪采集的,CloudCompare的目的是在一台标准笔记本电脑上处理大规模的点云——通常超过1000万个点云。在2005年后,cloudcompare就实现了点云和三角形网格之间的比较。随后,许多其他点云处理算法(配准、重采样、颜色/法线向量/尺度、统计计算、传感器管理、交互式或自动分割等)以及显示增强工具(自定义颜色渐变、颜色和法向量处理,校准图像处理、OpenGL着色器、插件等)
1 下载和安装
CloudCompare软件的下载地址如下:
http://www.cloudcompare.org/
源码地址如下:
https://github.com/cloudcompare/cloudcompare
2 构建Qt工程
CloudCompare源码是基于Qt5的,如果你要编译Qt5版本,就直接用cmake编译就行。
先构建如下的文件:
CloudCompare.pro文件改为如下设置。
TEMPLATE = subdirs
SUBDIRS += \\
CC \\
contrib \\
libs \\
plugins \\
ccViewer
# qCC \\
至于每个子项目的.pro怎么设置,可以参考如下代码:
TEMPLATE = lib
TARGET = CC_CORE_LIB
CONFIG += c++17
DEFINES += QT_DEPRECATED_WARNINGS
DEFINES += CC_CORE_LIB_EXPORTS
##################################################################
#指定生成的文件存放位置
##################################################################
MOC_DIR = $$PWD/temp/moc
RCC_DIR = $$PWD/temp/rcc
UI_DIR = $$PWD/temp/ui
OBJECTS_DIR = $$PWD/temp/obj
DESTDIR = $$PWD/temp/bin
INCLUDEPATH += . \\
./include \\
./src
HEADERS += \\
include/AutoSegmentationTools.h \\
include/BoundingBox.h \\
include/CCConst.h \\
include/CCCoreLib.h \\
include/CCCoreLibExport.h \\
include/CCGeom.h \\
include/CCMiscTools.h \\
include/CCPlatform.h \\
include/CCShareable.h \\
include/CCToolbox.h \\
include/CCTypes.h \\
include/ChamferDistanceTransform.h \\
include/CloudSamplingTools.h \\
include/ConjugateGradient.h \\
include/Delaunay2dMesh.h \\
include/DgmOctree.h \\
include/DgmOctreeReferenceCloud.h \\
include/DistanceComputationTools.h \\
include/ErrorFunction.h \\
include/FastMarching.h \\
include/FastMarchingForPropagation.h \\
include/Garbage.h \\
include/GenericCloud.h \\
include/GenericDistribution.h \\
include/GenericIndexedCloud.h \\
include/GenericIndexedCloudPersist.h \\
include/GenericIndexedMesh.h \\
include/GenericMesh.h \\
include/GenericOctree.h \\
include/GenericProgressCallback.h \\
include/GenericTriangle.h \\
include/GeometricalAnalysisTools.h \\
include/Grid3D.h \\
include/Jacobi.h \\
include/KdTree.h \\
include/LocalModel.h \\
include/ManualSegmentationTools.h \\
include/MathTools.h \\
include/MeshSamplingTools.h \\
include/Neighbourhood.h \\
include/NormalDistribution.h \\
include/ParallelSort.h \\
include/PointCloud.h \\
include/PointCloudTpl.h \\
include/PointProjectionTools.h \\
include/Polyline.h \\
include/RayAndBox.h \\
include/ReferenceCloud.h \\
include/RegistrationTools.h \\
include/SaitoSquaredDistanceTransform.h \\
include/ScalarField.h \\
include/ScalarFieldTools.h \\
include/SimpleMesh.h \\
include/SimpleTriangle.h \\
include/SquareMatrix.h \\
include/StatisticalTestingTools.h \\
include/TrueKdTree.h \\
include/WeibullDistribution.h \\
src/Chi2Helper.h
SOURCES += \\
src/AutoSegmentationTools.cpp \\
src/BoundingBox.cpp \\
src/CCMiscTools.cpp \\
src/CCShareable.cpp \\
src/ChamferDistanceTransform.cpp \\
src/CloudSamplingTools.cpp \\
src/Delaunay2dMesh.cpp \\
src/DgmOctree.cpp \\
src/DgmOctreeReferenceCloud.cpp \\
src/DistanceComputationTools.cpp \\
src/ErrorFunction.cpp \\
src/FastMarching.cpp \\
src/FastMarchingForPropagation.cpp \\
src/GeometricalAnalysisTools.cpp \\
src/KdTree.cpp \\
src/LocalModel.cpp \\
src/ManualSegmentationTools.cpp \\
src/MeshSamplingTools.cpp \\
src/Neighbourhood.cpp \\
src/NormalDistribution.cpp \\
src/NormalizedProgress.cpp \\
src/PointProjectionTools.cpp \\
src/Polyline.cpp \\
src/ReferenceCloud.cpp \\
src/RegistrationTools.cpp \\
src/SaitoSquaredDistanceTransform.cpp \\
src/ScalarField.cpp \\
src/ScalarFieldTools.cpp \\
src/SimpleMesh.cpp \\
src/StatisticalTestingTools.cpp \\
src/TrueKdTree.cpp \\
src/WeibullDistribution.cpp
然后将CloudCompare源码中对应的源文件,拷贝到自己对应的工程目录下。
最后构建完后的工程如下图所示:
3 修改源码
由于CloudCompare源码是基于Qt5的,换成Qt6后要修改部分源码。下面是我记录的要修改的内容:
//修改内容1:
inline ccQOpenGLFunctions* functions() const return context() ? context()->versionFunctions<ccQOpenGLFunctions>() : nullptr; //源码
inline ccQOpenGLFunctions* functions() const return context() ? (ccQOpenGLFunctions*)context()->functions () : nullptr; //修改后
//修改内容2:
<<endl;//源码
<<Qt::endl;//修改后
//修改内容3:
stream.readNextStartElement();
QString itemName = stream.name().toString();
QString itemValue = stream.readElementText();
ccLog::Print(QString("[XML] Item '%1': '%2'").arg(itemName,itemValue));
// QStringRef itemName = stream.name();
// QString itemValue = stream.readElementText();
// ccLog::Print(QString("[XML] Item '%1': '%2'").arg(itemName.toString(),itemValue));
//修改内容4:
QOpenGLFunctions_2_1* glFunc = (QOpenGLFunctions_2_1*)context->functions();//修改后
// QOpenGLFunctions_2_1* glFunc = context->versionFunctions<QOpenGLFunctions_2_1>();
//修改内容5:
// QStringList tokens = currentLine.simplified().split(QChar(' '), QString::SkipEmptyParts);
QStringList tokens = currentLine.simplified().split(QChar(' '), Qt::SkipEmptyParts);
//修改内容6:
//#include <QGLBuffer>
#include <QOpenGLBuffer>
//修改内容7:
// xShift = tab.colWidth[c] - QFontMetrics(bodyFont).width(str);
xShift = tab.colWidth[c] - QFontMetrics(bodyFont).horizontalAdvance(str);
//修改内容8:
// float sizeModifier = (event->delta() < 0 ? -1.0f : 1.0f);
float sizeModifier = (event->angleDelta().y() < 0 ? -1.0f : 1.0f);
//修改内容9:
// return QStringLiteral( "Created %1" ).arg( QDateTime::currentDateTime().toString( Qt::SystemLocaleShortDate ) );
return QStringLiteral( "Created %1" ).arg( QDateTime::currentDateTime().toString("yyyy/MM/dd hh:mm") );
//修改内容10:
// QSize screenSize = QApplication::desktop()->screenGeometry().size();
QSize screenSize = QGuiApplication::primaryScreen()->availableSize();
//修改内容11:
// if (sep == 4) //comma
if (sep == QChar(44)) //comma
// if (lsfDlg.listWidget->isItemSelected(lsfDlg.listWidget->item(i)))
if (lsfDlg.listWidget->item(i)->isSelected())
//修改内容12:
// foreach (QCPItemPosition *child, mChildrenX.toList())
foreach (QCPItemPosition *child, mChildrenX.values())
//修改内容13:
// painter.setRenderHint(QPainter::HighQualityAntialiasing);
painter.setRenderHint(QPainter::Antialiasing); // to make Antialiasing look good if using the OpenGL graphicssystem
//修改内容14:
// if (QCPLayoutElement *el = layoutElementAt(event->pos()))
if (QCPLayoutElement *el = layoutElementAt(event->position()))
//修改内容15:
// mColorBuffer[i] = (it-1).value().rgb();
--it;
mColorBuffer[i] = it.value().rgb();
//修改内容16:
// mAxisRect.data()->setRangeDrag(0);
mAxisRect.data()->setRangeDrag(QCPAxis::orientation(QCPAxis::AxisType(0)));
//修改内容17:
// QCPDataMap::const_iterator upperEnd = upper+1;
QCPDataMap::const_iterator upperEnd = ++upper;--upper;
//修改内容18:
// newData.t = (mData->constEnd()-1).key()+1;
QCPCurveDataMap::const_iterator upperEnd = mData->constEnd();--upperEnd;
if (!mData->isEmpty())
newData.t = upperEnd.key()+1;
//修改内容19:
if (command == PDMS_LAST)
if (s_elementsStack.size() < 2)
return false;
// ElementsStack::iterator it = s_elementsStack.end(); --it;
ElementsStack::iterator i = s_elementsStack.begin();
ElementsStack::iterator j = s_elementsStack.begin();
for (; i != s_elementsStack.end(); j=i,++i)
ElementsStack::iterator it = j;
if (isSet() == 1)
// while (true)
//
// if (isNameReference() && strcmp(refname, (*it)->name) == 0)
// break;
// if (isTokenReference() && (*it)->getType() == token)
// break;
// if (it == s_elementsStack.begin())
// return false;
// --it;
//
for (ElementsStack::iterator tmp = s_elementsStack.begin(); tmp != j; ++tmp)
it = tmp;
if (isNameReference() && strcmp(refname, (*it)->name) == 0)
break;
if (isTokenReference() && (*it)->getType() == token)
break;
if (it == s_elementsStack.begin())
return false;
item = *it;
return true;
//修改内容20:
// ccViewer(QWidget *parent = 0, Qt::WindowFlags flags = 0);
ccViewer(QWidget *parent = 0, Qt::WindowFlags flags = Qt::Widget);
4 编译源码
编译成功后,拷贝对应的库到程序目录,运行程序后效果如下:
我以将测试源码放到CSDN上面,有需要可以下载。
https://download.csdn.net/download/qq_40732350/85230547
以上是关于QT6+CloudCompare显示3D点云的主要内容,如果未能解决你的问题,请参考以下文章