点云处理,有一个出名的处理软件,cloud compare,简称 cc,将自己实现的功能以插件形式集成到 CC 里,方便使用

前提

环境:cc 2.13,qt 5.15,cmake 3.18,vs2019【其他组合也可,本文基于此展开】

能力要求:能够使用 cmake 成功编译 cc 并安装

有问题,欢迎留言、进群讨论或私聊:【群号:392784757】

CC 插件概述

CC 提供了一种插件化的二次开发方式,以插件的形式,避免了核心代码的修改,利用提供的接口,完成我们需要功能的二次开发

组织结构

cc 中的插件全都放在 源码 plugins 文件夹下

core 是 cc 已经实现的插件功能

example 是 cc 提供给我们的示例,本文也基于其中的示例进行开发我们的插件

其中 core 文件夹下,又对插件进行了划分

  • GL,基于 gl 可视化插件
  • IO ,涉及 IO 处理的插件
  • Standard ,大部分插件都属于这种

example 文件夹下也对应提供了 相应的示例插件

  • ExampleGLPlugin
  • ExampleIOPlugin
  • ExamplePlugin

本文基于其中的 ExamplePlugin 插件,也就是标准插件类型,实现一个 PCA 功能,并可视化

ExamplePlugin

images 中放置的是 icon.png

include 涉及的头文件,自己的功能头文件和用到的其他第三方的头文件

src 功能代码

ExamplePlugin.qrc,qt 组织资源的方式,提供资源的路径给代码使用

info. json,插件的描述,涉及的相关资源路径,以及开发者信息、相关资料

{
"type": "Standard",
"name": "MyTest (Standard Plugin)",
"icon": ":/CC/plugin/MyTestPlugin/images/icon.png",
"description": "This is a description of the marvelous Example plugin. It does nothing.",
"authors": [
{
"name": "xxx",
"email": "xxx"
}
],
"maintainers": [
{
"name": "yyy,
"email": "yyy@gmail.com"
},
{
"name": "zzz"
}
],
"references": [
{
"text": "xx references",
"url": "http://www.bmj.com/content/333/7582/1285"
},
{
"text": "a test plugin"
}
]
}

cmake 组织

基础的结构讲完,cc 是如何通过某种方式将插件组织起来的,答案就是 cmake

从高到低涉及的 cmakelists.txt 完成了这一任务【下面或区分两条不同路径情况,一个是放在 core\standard ,另一个是放在 example】

D:\06-source_code\CloudCompare-2.13\CMakeLists.txt

# ...

# Plugins
add_subdirectory( plugins ) # ...

D:\06-source_code\CloudCompare-2.13\plugins\CMakeLists.txt

# ...

add_subdirectory( core )
add_subdirectory( example ) # ...

D:\06-source_code\CloudCompare-2.13\plugins\core\CMakeLists.txt 【D:\06-source_code\CloudCompare-2.13\plugins\example\CMakeLists.txt】

add_subdirectory( GL )
add_subdirectory( IO )
add_subdirectory( Standard )

add_subdirectory( ${CMAKE_CURRENT_SOURCE_DIR}/ExampleGLPlugin )
add_subdirectory( ${CMAKE_CURRENT_SOURCE_DIR}/ExampleIOPlugin )
add_subdirectory( ${CMAKE_CURRENT_SOURCE_DIR}/ExamplePlugin )

D:\06-source_code\CloudCompare-2.13\plugins\core\Standard\CMakeLists.txt

add_subdirectory( qAnimation )
add_subdirectory( qBroom )
add_subdirectory( qCanupo )
add_subdirectory( qCloudLayers )
add_subdirectory( qCompass )
add_subdirectory( qCork )
add_subdirectory( qCSF )
add_subdirectory( qFacets )
add_subdirectory( qHoughNormals )
add_subdirectory( qHPR )
add_subdirectory( qM3C2 )
add_subdirectory( qPCL )
add_subdirectory( qPCV )
add_subdirectory( qPoissonRecon )
add_subdirectory( qRANSAC_SD )
add_subdirectory( qSRA )
add_subdirectory( qMeshBoolean ) #plugins integrated as submodules
set( submod_plugins
${CMAKE_CURRENT_SOURCE_DIR}/qColorimetricSegmenter
${CMAKE_CURRENT_SOURCE_DIR}/qMasonry
${CMAKE_CURRENT_SOURCE_DIR}/qMPlane
${CMAKE_CURRENT_SOURCE_DIR}/qJSonRPCPlugin
${CMAKE_CURRENT_SOURCE_DIR}/qTreeIso
${CMAKE_CURRENT_SOURCE_DIR}/q3DMASC
) foreach( dir ${submod_plugins} )
if( IS_DIRECTORY ${dir} AND EXISTS ${dir}/CMakeLists.txt )
message( STATUS "Found submodule plugin: " ${dir} )
add_subdirectory( ${dir} )
endif()
endforeach()

具体插件的 CMakeLists.txt

【D:\06-source_code\CloudCompare-2.13\plugins\core\Standard\qPCA\CMakeLists.txt】或【D:\06-source_code\CloudCompare-2.13\plugins\example\ExamplePlugin\CMakeLists.txt】

# ...

# CloudCompare example for standard plugins

# REPLACE ALL 'ExamplePlugin' OCCURENCES BY YOUR PLUGIN NAME
# AND ADAPT THE CODE BELOW TO YOUR OWN NEEDS! # Add an option to CMake to control whether we build this plugin or not
option( PLUGIN_EXAMPLE_STANDARD "Install example plugin" OFF ) if ( PLUGIN_EXAMPLE_STANDARD )
project( ExamplePlugin ) AddPlugin( NAME ${PROJECT_NAME} ) add_subdirectory( include )
add_subdirectory( src ) # set dependencies to necessary libraries
# target_link_libraries( ${PROJECT_NAME} LIB1 )
endif()

具体开发前修改

info.json

{
"type": "Standard",
"name": "PCA (Standard Plugin)",
"icon": ":/CC/plugin/qPCA/images/icon.png",
"description": "This is a description of the PCA plugin. It does nothing.",
"authors": [
{
"name": "xxx",
"email": "xxx"
}
],
"maintainers": [
{
"name": "yyy,
"email": "yyy@gmail.com"
},
{
"name": "zzz"
}
],
"references": [
{
"text": "xx references",
"url": "http://www.bmj.com/content/333/7582/1285"
},
{
"text": "a PCA plugin"
}
]
}

具体插件上一级的 CMakeLists.txt,这里是 Standard\CMakeLists.txt

add_subdirectory( qAnimation )
add_subdirectory( qBroom )
add_subdirectory( qCanupo )
add_subdirectory( qCloudLayers )
add_subdirectory( qCompass )
add_subdirectory( qCork )
add_subdirectory( qCSF )
add_subdirectory( qFacets )
add_subdirectory( qHoughNormals )
add_subdirectory( qHPR )
add_subdirectory( qM3C2 )
add_subdirectory( qPCL )
add_subdirectory( qPCV )
add_subdirectory( qPoissonRecon )
add_subdirectory( qRANSAC_SD )
add_subdirectory( qSRA )
add_subdirectory( qMeshBoolean ) # --------------------
add_subdirectory( qPCA )
# -------------------- #plugins integrated as submodules
set( submod_plugins
${CMAKE_CURRENT_SOURCE_DIR}/qColorimetricSegmenter
${CMAKE_CURRENT_SOURCE_DIR}/qMasonry
${CMAKE_CURRENT_SOURCE_DIR}/qMPlane
${CMAKE_CURRENT_SOURCE_DIR}/qJSonRPCPlugin
${CMAKE_CURRENT_SOURCE_DIR}/qTreeIso
${CMAKE_CURRENT_SOURCE_DIR}/q3DMASC
) foreach( dir ${submod_plugins} )
if( IS_DIRECTORY ${dir} AND EXISTS ${dir}/CMakeLists.txt )
message( STATUS "Found submodule plugin: " ${dir} )
add_subdirectory( ${dir} )
endif()
endforeach()

具体插件的 CMakeLists.txt, qPCA/CMakeLists.txt

# CloudCompare example for standard plugins

# REPLACE ALL 'ExamplePlugin' OCCURENCES BY YOUR PLUGIN NAME
# AND ADAPT THE CODE BELOW TO YOUR OWN NEEDS! # Add an option to CMake to control whether we build this plugin or not
# option( PLUGIN_EXAMPLE_STANDARD "Install example plugin" OFF )
option( PLUGIN_qPCA "Install example plugin" OFF ) # if ( PLUGIN_EXAMPLE_STANDARD )
if ( PLUGIN_qPCA )
# project( ExamplePlugin )
project( QPCA_PLUGIN ) # 全部大写 AddPlugin( NAME ${PROJECT_NAME} ) add_subdirectory( include )
add_subdirectory( src ) # 添加其他需要的库 set dependencies to necessary libraries
# target_link_libraries( ${PROJECT_NAME} LIB1 )
endif()

更新 ExamplePlugin 中的文件名为新插件对应的名称

ExamplePlugin.qrc ---> qPCA.qrc

ExamplePlugin.h ---> qPCA.h

ExamplePlugin.cpp ---> qPCA.cpp

src include 下的 CMakeLists.txt 更新文件名

src/CMakeLists.txt

target_sources( ${PROJECT_NAME}
PRIVATE
${CMAKE_CURRENT_LIST_DIR}/ActionA.cpp
# ${CMAKE_CURRENT_LIST_DIR}/ExamplePlugin.cpp
${CMAKE_CURRENT_LIST_DIR}/qPCA.cpp
# 其他新加文件
)

include/CMakeLists.txt

target_sources( ${PROJECT_NAME}
PRIVATE
${CMAKE_CURRENT_LIST_DIR}/ActionA.h
# ${CMAKE_CURRENT_LIST_DIR}/ExamplePlugin.h
${CMAKE_CURRENT_LIST_DIR}/qPCA.h
# 候选其他头文件也要在这添加
) target_include_directories( ${PROJECT_NAME}
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
)

更新 ExamplePlugin.qrc,更新资源路径

直接用 vscode 打开 修改

<RCC>
<qresource prefix="/CC/plugin/ExamplePlugin">
<file>images/icon.png</file>
<file>info.json</file>
</qresource>
</RCC>

修改后

此图片为后面生成 project 后在 vs 中修改

主文件修改

修改 qPCA.cpp

# #include "ExamplePlugin.h" 改为
#include "qPCA.h" # ,ccStdPluginInterface( ":/CC/plugin/ExamplePlugin/info.json" ) ,ccStdPluginInterface( ":/CC/plugin/qPCA/info.json" )

修改 qPCA.h

# Q_PLUGIN_METADATA( IID "cccorp.cloudcompare.plugin.Example" FILE "../info.json" )
Q_PLUGIN_METADATA( IID "cccorp.cloudcompare.plugin.qPCA" FILE "../info.json" )

cmake 构建

可以看到我们的 qPCA 插件选项,选中

然后生成 project

运行

下一篇,我们来实现具体的 PCA 逻辑和可视化效果

有问题,欢迎留言、进群讨论或私聊:【群号:392784757】

cloud compare二次插件化功能开发详细步骤(一)的更多相关文章

  1. 使用Android-studio开发移动app与weex结合开发详细步骤

    详细步骤如下:   首先,确保机器已经安装了node.js,并且把npm更新到最新版本 下载完毕后,我们可以看到全局目录下的node_modules下面多出一个weex-toolkit 同时,我们留意 ...

  2. Java支付宝PC网站支付功能开发(详细教程)

    一.前言 本案例使用的是Java实现的.使用支付宝的沙盒环境示例.发布需要换成正式环境.这里就不作详细说明了 本代码适合用来做参考,不要直接复制去使用. 没有账号的需要去平台注册一个: 登录支付宝开发 ...

  3. 微信公众平台开发详细步骤与java代码

    1.微信公众平台设置 首先在https://mp.weixin.qq.com/注册一个公众平台账号(服务号.订阅号.企业号的区别) 微信公众平台地址:https://mp.weixin.qq.com ...

  4. 用grunt搭建自动化的web前端开发环境实战教程(详细步骤)

    用grunt搭建自动化的web前端开发环境实战教程(详细步骤) jQuery在使用grunt,bootstrap在使用grunt,百度UEditor在使用grunt,你没有理由不学.不用!前端自动化, ...

  5. 安装SVN并进行汉化的详细步骤

    安装SVN并进行汉化的详细步骤 SAE提供了不同的代码部署方式,可以分为两类:一是通过SVN客户端部署,这是SAE推荐的代码部署方法.另一个是通过非SVN客户端部署,即在线代码在线编辑器和推荐应用安装 ...

  6. unity3d开发的android应用中增加AD系统的详细步骤

    unity3d开发的android应用中增加AD系统的详细步骤 博客分类: Unity3d unity3d  Unity3d已经支持android,怎样在程序里增加admob?  试了一下,确实能够, ...

  7. Delphi 编写ActiveForm窗体工程知识和样例(开发浏览器客户端应用程序)(有详细步骤)

    一.基础知识介绍: 1.ActiveForm的基础知识介绍: 在Delphi中,ActiveForm是封装了Delphi Form的一种ActiveX控件.ActiveForm其实是一种标准的Delp ...

  8. 组件化网页开发 / 步骤一 · 4-4 匹配HTML标签

    组件化网页开发 / 步骤一 · 4-4 匹配HTML标签

  9. 【Linux开发】【Qt开发】ARM QT移植详细步骤教程

    ARM QT移植详细步骤教程 米尔SAM9X5和A5D3X上默认的Qt版本是4.5.3,当这个版本的Qt库不能满足实际开发需求时,可通过此方法制定Qt开发.运行环境. 移植的步骤如下: 1.下载新版q ...

  10. [转帖]龙芯服务器部署WEB服务的体验和详细步骤

    龙芯服务器部署WEB服务的体验和详细步骤 2019年01月02日 18:40:34 weixin_40065369 阅读数 1733   版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权 ...

随机推荐

  1. 安装PHP5.6.20

    安装php的前提是安装了数据库和httpd!!!!!!!! 1 因为yum缺省安装的是PHP5.4,所以先要添加yum库 [root@svnhost ~]# rpm -Uvh https://mirr ...

  2. Prometheus监控系统(二)Prometheus部署与使用

    1. Prometheus安装 官网:https://prometheus.io/ 下载地址:https://prometheus.io/download/ Prometheus基于Golang编写, ...

  3. IEC61850方案分享,基于全志、瑞芯微国产平台实现!

    什么是IEC61850协议? IEC61850是一种用于在电力自动化系统中进行数据交换和控制的通信协议.它定义了一种标准化的通信和数据模型,以支持设备和系统之间的数据交换和互操作性. IEC61850 ...

  4. 请查收“国产化率认证报告”(100%)——RK3568J工业核心板

    创龙科技RK3568J核心板获得"100%国产化"认证日前,创龙科技"国产化率100%认证"的核心板再添一员!RK3568J工业核心板(SOM-TL3568)获 ...

  5. React Router 6

    路由的概念,可以想像一下路由器,当来了一个请求时,路由器做了什么事情?它会把请求的IP地址和路由表进行匹配,匹配成功后,进行转发,直到目标主机.可以看到路由有三部分组成,一个是请求,一个是路由表,一个 ...

  6. 做一个单纯的react-image显示组件

    最近项目上有一个需求,在显示图片的时候,需要传递自定义的头部就行认证.google了一番之后,发现没有现成的组件库可以使用[也可能是我没找到],所以请求图片只能采用xhr方式来异步加载.下面就是在做这 ...

  7. LSTM实现文本情感分类demo

    import torch import torch.optim as optim import torch.nn as nn import numpy as np import torch.nn.fu ...

  8. 2022 开源之夏 | Curve 邀你与中国存储软件共成长,赢万元奖金

    Curve 社区携手开源之夏,邀你开展有趣而精彩的开源之旅,直面社区大咖,积累项目经历,摘取丰厚奖金,共同推进我国基础软件自主创新 2022 年,Curve 社区再次加入系列高校开源活动 -- 开源之 ...

  9. 全网最适合入门的面向对象编程教程:17 类和对象的Python实现-鸭子类型与“file-like object“

    全网最适合入门的面向对象编程教程:17 类和对象的 Python 实现-鸭子类型与"file-like object" 摘要: 本文主要介绍了 Python 中创建自定义类时鸭子类 ...

  10. [项目自荐] 交叉编译njs并使用Nginx搭建自由的个人网盘:vList5

    这个博客好久没有打理了,最近才想起来 这篇文章是以下 5 篇文章的组合,希望这个免费的项目能实现他的初衷吧 vList5:部署指南 vList5.3 全面加密,从我做起 njs 从入门(交叉编译)到入 ...