QT6+CloudCompare显示3D点云

news2025/1/10 20:57:59

    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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/94971.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

文本转语音免费 微软Azure官网,在线就可以转语音。

使用跨 140 种语言和变体的 400 种神经网络语音吸引全球受众。使用极具表现力和类似人类的声音&#xff0c;使文本阅读器和已启用语音的助理等方案栩栩如生。神经网络文本转语音支持多种朗读风格&#xff0c;包括新闻广播、客户服务、呼喊、耳语以及高兴、悲伤等情感。 地址 文…

【Java寒假打卡】Java基础-数组学习笔记

【Java寒假打卡】Java基础-数组学习笔记一、定义二、定义格式三、数组动态初始化四、数组元素访问五、内存分配六、多个数组的不同内存图七、数组的静态初始化八、数组操作的两个小问题九、求数组的最大值十、查找数组的特定值一、定义 数组是一个容器&#xff0c;存储一种数组…

6 CPP之C风格字符串

CPP之C风格字符串 c中的string类&#xff0c;封装了C风格的字符串。 使用方便&#xff0c;能自动扩展&#xff0c;不用担心内存问题 在某些场景中&#xff0c;C风格字符串更方便&#xff0c;更高效 C标准库、Linux系统和开源库&#xff0c;大部分开源库一定有C语言版本&…

Vue前端浏览器链接/接口参数实现加密

场景 由于项目创建之前后端设计不合理&#xff0c;导致详情页链接参数id为顺序序数(例&#xff1a;1,2,3…等等)&#xff0c;安全系数非常低&#xff08;虽然我们前端做了菜单权限、按钮权限、Api权限等等&#xff09;&#xff0c;现在要前端解决下浏览器链接/接口参数实现加密…

《Linux运维总结:基于xtrabackup8工具全量物理备份Mysql8数据自动化工具(方案一)》

一、背景信息 说明&#xff1a;由于业务系统的特殊性&#xff0c;对数据的备份要求非常高&#xff0c;且数据量非常大&#xff0c;所以这里采用xtrabackup工具来对Mysql数据库进行全量物理备份。由于xtrabackup工具操作复杂&#xff0c;这里为了简便&#xff0c;基于xtrabackup…

张驰咨询:快速提高流程效率的5个关键精益生产工具

精益&#xff0c;又称“精益制造”或“精益生产”&#xff0c;注重通过消除浪费、消除缺陷&#xff0c;实现客户价值最大化。精益工具是关于理解过程&#xff0c;发现浪费&#xff0c;防止错误和记录你所做的事情。 让我们来看看流程改进中使用的五种精益工具&#xff0c;它们…

建立企业数据共享机制,打破数据壁垒

很多人可能也比较疑惑&#xff0c;为什么数据这么重要&#xff0c;能够有着数据治理、数据标准、数据管理以及我们接下来要讲的数据共享&#xff0c;各种针对数据的机制体系。一方面是因为数据在数字经济和数字化转型进程中发挥了巨大作用&#xff0c;甚至可以称得上是两者的核…

RCNN网络源码解读(Ⅰ) --- 获取数据并预处理数据

目录 1.RCNN是什么东西 2.处理数据集 2.1 code&#xff1a;下载VOC数据集&#xff08;pascal_voc.py&#xff09; 2.2 code&#xff1a; 数据集预处理&#xff08;pascal_voc_car.py&#xff09; 3.code区域候选建议&#xff08;selectivesearch.py&#xff09; 1.RCNN是什…

Web(十)JavaScript知识训练-JS函数

1、下列选项中&#xff0c;&#xff08; B&#xff09;可用于检查某个值是否为无穷大的数。 A、 isNaN&#xff08;&#xff09; B、 isFinite&#xff08;&#xff09; C、 parseInt&#xff08;&#xff09; D、 parseFloat&#xff08;&#xff09; 2、函数parseInt(15.36)…

燕东微在科创板上市:市值263亿元,北京电控、亦庄国投等为股东

12月16日&#xff0c;北京燕东微电子股份有限公司&#xff08;下称“燕东微”&#xff0c;SH:688172&#xff09;在上海证券交易所科创板上市。本次在上市&#xff0c;燕东微的发行价为21.98元/股&#xff0c;募资总额约为39.53亿元&#xff0c;募资净额约为37.57亿元&#xff…

【Java寒假打卡】Java基础-方法

【Java寒假打卡】Java基础-方法一、定义二、方法的定义和调用三、方法调用过程四、带参数的方法和调用五、debug查看方法参数传递六、带返回值的方法的调用七、方法重载八、方法传递数据九、返回一个数组的最大值和最小值一、定义 方法就是一段具有独立功能的代码块&#xff0…

Java中的Set系列集合

Set系列集合Set系列集合Set系列集合概述HashSet元素的底层原理&#xff1a;哈希表HashSet元素去重复的底层原理实现类&#xff1a;LinkedHashSet实现类&#xff1a;TreeSetCollection体系的特点、使用场景终结补充知识&#xff1a;可变参数集合工具类CollectionsCollection体系…

Unity PolyNav2D(2D寻路) 插件

下载地址 https://download.csdn.net/download/qq_27461747/87300286 组件 PolyNav2D 寻路地图&#xff0c;一般来说 有且只有一个&#xff0c; 寻路的主要接口就在这个组件里PolyNavObstacle 障碍物PolyNavAgent 导航代理, 带有移动功能。这个可有可无&#xff0c;可以自己…

重点| 系统集成项目管理工程师考前50个知识点(6)

本文章总结了系统集成项目管理工程师考试背记50个知识点&#xff01;&#xff01;&#xff01; 帮助大家更好的复习&#xff0c;希望能对大家有所帮助 比较长&#xff0c;放了部分&#xff0c;需要可私信&#xff01;&#xff01; 40、冲突的下列特点&#xff1a; &#xff…

css知识复习点

四种css使用方式&#xff1a;内嵌式、外链式、行内式、导入式 复合选择器 后代选择器 选择器之间需要用空格隔开&#xff0c;后代不一定是儿子 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>复合…

渗透测试-crlf注入原理

目录 概念 HTTP报文结构与漏洞原理 漏洞检测 Bottle之CRLF漏洞 nginx配置错误之CRLF漏洞 漏洞危害 会话固定 修复建议 漏洞检测POC 概念 这个漏洞一般很少出现。 CRLF是CR和LF两个字符的拼接&#xff0c;它们分别代表”回车换行”&#xff08;\r\n&#xff09;。十六…

[附源码]Nodejs计算机毕业设计基于的学生事务管理系统Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分…

Java+mysql基于SSM的网上出差审批与费用报销系统 开题 毕业设计

本课题是一个基于SSM的管理系统,本网上出差审批与费用报销系统是在Windows7系统的环境下,利用Eclipse和Mysql工具开发的。在网上出差审批与费用报销系统中分为管理员和普通用户2个模块。其中网上出差审批与费用报销系统中的管理人员在登陆之后可以管理本系统内的部门信息管理,员…

性能测试场景:如何进行场景设计?

我们在前面屡次强调了场景的重要性,今天终于到了要把实际场景拿出来解析的时候了。 在本篇文章中,为了保证数据的连续性,我用之前的项目资料来作明确地说明。同时为了模糊关键业务信息,以及让场景的描述更通用性,我会把所有的业务名隐去。 根据之前我们所说的,基准性能…

【DevOps实战系列】第六章:详解Docker私服Nexus3篇

个人亲自录制全套DevOps系列实战教程 &#xff1a;手把手教你玩转DevOps全栈技术 概述/目标 私服我们很熟悉了&#xff0c;比如docker hub就是官方私服&#xff0c;而有些情况比如我们自建的镜像&#xff0c;不想往外传&#xff0c;就需要考虑内部搭建一个私有服务器来存放私有…