cloud compare二次插件化功能开发详细步骤(一)

news2024/11/15 12:05:33

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

前提

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

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

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

CC插件概述

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

组织结构

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

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

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

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

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

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

  • ExampleGLPlugin
  • ExampleIOPlugin
  • ExamplePlugin

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

ExamplePlugin

image-20240814170233699
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>

修改后
image-20240814190146241

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

主文件修改

修改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

运行

image-20240814202916848

image-20240814203105623

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

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

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

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

相关文章

二、AI工作流(低代码)的趋势崛起在即。带你轻松玩转输入-文本组件

对工作流感兴趣的小伙伴可以去试一试。&#x1f525;偷偷的告诉你&#xff0c;它的GPTo4.0不要&#x1f4b0;。传送门&#xff1a;https://www.nyai.chat/chat?invitenyai_1141439 一、能用AI工作流介绍 能用AI-工作流是一个“低代码”工具、它也是个人或者中小企业的提效工…

8G显存玩转书生大模型

基础任务 使用 Cli Demo 完成 InternLM2-Chat-1.8B 模型的部署&#xff0c;并生成 300 字小故事&#xff0c;记录复现过程并截图。 尝试很多方法无解后在网页端重新输入&#xff1a; import torch from transformers import AutoTokenizer, AutoModelForCausalLM使用了Tran…

sql注入(判断字符型/数字型)

目录 字符型 数字型 字符型闭合方式 less-1 less-4 sql注入常见类型包括字符型和数字型&#xff08;json这里不介绍&#xff09; 以sql-labs靶场为例&#xff1b; 字符型 less-1&#xff1a;输入参数id&#xff1a; 这里我将sql查找语句一起输出了&#xff1b; 我们发现…

书生大模型实战营-基础关-XTuner 微调个人小助手认知

XTuner 微调个人小助手认知 环境配置模型效果预览微调数据准备微调配置微调训练权重格式转换模型合并页面对话 环境配置 # 创建虚拟环境 conda create -n xtuner0812 python3.10 -y# 激活虚拟环境&#xff08;注意&#xff1a;后续的所有操作都需要在这个虚拟环境中进行&#…

锂电池剩余寿命预测 | Matlab基于LSTM-Attention的锂电池剩余寿命预测

目录 预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab基于LSTM-Attention的锂电池剩余寿命预测&#xff08;单变量&#xff09;&#xff0c;长短期记忆神经网络融合注意力机制&#xff08;自注意力机制&#xff0c;多头注意力机制&#xff09;&#xff08;单变量&…

有效字的字母异位词

给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 注意&#xff1a;若 s 和 t 中每个字符出现的次数都相同&#xff0c;则称 s 和 t 互为字母异位词。 示例 1: 输入: s "anagram", t "nagaram" 输出: true示例 2: 输…

8.14-LVS主从+nginx的haproxy+mysql的haproxy+读写分离

一、LVS-主从数据库 # nat # 添加规则 [rootDS ~]# ipvsadm -A -t 192.168.2.130:3306 -s rr [rootDS ~]# ipvsadm -a -t 192.168.2.130:3306 -r 192.168.2.40:3306 -m [rootDS ~]# ipvsadm -a -t 192.168.2.130:3306 -r 192.168.2.42:3310 -m [rootDS ~]# ipvsadm -Ln IP Vir…

javaweb学习笔记(8.10)

一、JS 1.1JS简介 Web标准&#xff1a;由3WC制订 三个组成部分&#xff1a; HTML---》网页的基础结构 CSS---》网页的表现效果 JavaScript---》网页的行为 简介&#xff1a;JS是一门跨平台、面向对象的脚本语言。用来控制网页行为的&#xff0c;使网页交互。 1.2JS的引入…

贷奇乐漏洞学习 --- 两个变态WAF绕过

代码分析 第一个WAF 代码 function dowith_sql($str) {$check preg_match(/select|insert|update|delete|\|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile/is, $str);if ($check) {echo "非法字符!";exit();}return $str;} 实现原理 这段PHP代码定义了一个…

Linux日常运维-主机名hosts

作者介绍&#xff1a;简历上没有一个精通的运维工程师。希望大家多多关注作者&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 本小章内容就是Linux进阶部分的日常运维部分&#xff0c;掌握这些日常运维技巧或者方法在我们的日常运维过程中会带来很多方…

探索消费新纪元:循环购模式的奥秘

在这个日新月异的消费时代&#xff0c;你是否听说过“消费1000送2000&#xff0c;每天领钱&#xff0c;提现无忧”的奇闻&#xff1f;或许你会疑惑&#xff0c;商家这是在慷慨解囊&#xff0c;还是在布下什么神秘的局&#xff1f;今天&#xff0c;让我作为你的私域电商向导&…

Linux应用--IO多路复用

一、I/O多路复用简介 socket通信&#xff0c;在Linux系统其是就是文件描述符&#xff0c;对应于内核中的缓冲区&#xff08;包含读缓冲区与写缓冲区&#xff09;&#xff0c;实质上是对读写缓冲区的操作&#xff1b;多路复用&#xff0c;多条路复用成一条路。 I/O多路复用使得程…

爬虫动态http代理ip:提高数据抓取的有效工具

爬虫动态HTTP代理IP的概述与应用 在网络爬虫的世界中&#xff0c;动态HTTP代理IP是一个非常重要的工具。它不仅能帮助用户提高数据抓取的效率&#xff0c;还能有效避免被目标网站封禁。本文将为您详细介绍什么是动态HTTP代理IP、其优势、使用场景及如何获取和配置。 1. 什么是…

NVDLA专题8:具体模块介绍——Convolution Accumulator

概述 卷积累加器(Convolution Accumulator&#xff0c; CACC)是CMAC之后的卷积流水线的一个阶段,CACC的定义在NV_NVDLA_cacc.v&#xff0c;module定义如下&#xff1a; module NV_NVDLA_cacc (cacc2sdp_ready //|< i,csb2cacc_req_pd //|<…

ZooKeeper服务器下载|安装|配置|启动|关闭|端口占用冲突解决

1、下载ZooKeeper ZooKeeper官网&#xff1a;https://zookeeper.apache.org/ 下载ZooKeeper二进制包 2、安装ZooKeeper 对ZooKeeper压缩包解压即可 tar -zxvf apache-zookeeper-3.9.2-bin.tar.gz -C /usr/local/3、配置ZooKeeper 来到ZooKeeper配置文件页面 cd conf复制z…

一文详解ETC1压缩纹理——OpenGL中ETC1纹理加载与渲染实践

ETC1(Ericsson Texture Compression)是一种有损纹理压缩技术,2005年初由爱立信研究院参与研发,目的是用于减少移动设备和嵌入式系统中纹理存储的内存占用,应用场景见于游戏、VR、AR等需要大量的纹理资源来创建高质量的视觉效果以及复杂的动画效果场景。 ETC1可提供RGB888像…

宠物医院收银系统源码

1.系统开发语言 核心开发语言: PHP、HTML5、Dart 后台接口: PHP7.3 后合管理网站: HTML5vue2.0element-uicssjs 线下收银台&#xff08;安卓/Windows版&#xff09;: Dart3 框架&#xff1a;Flutter 3.19.6 助手: uniapp 商城: uniapp 2.系统概况 针对宠物医院的一套一体化收…

Unity 流光shader的思路

先看一下直线方程&#xff1a; 1.x0.5y0: 2.x0.5y20: 3.由上面的函数图像可以看出 zxky (k是常量)&#xff0c;表示所有斜率为k的直线集合&#xff0c;z是直线在x轴的截距&#xff0c;每个z的取值都确定一条唯一的斜率为k的直线。 4.那么给z一个取值范围就可以画出一条斜的条…

vulnhub系列:devguru

vulnhub系列&#xff1a;devguru 靶机下载 一、信息收集 nmap扫描存活&#xff0c;根据mac地址寻找IP nmap 192.168.23.0/24nmap扫描端口&#xff0c;开放端口&#xff1a;22、80、8585 nmap 192.168.23.147 -p- -sV -Pn -O访问80端口 dirb目录扫描&#xff0c;存在 git 源…

c shell 脚本学习使用

1.cd /进入该目录等 2.rm -rf filename 删除文件 3、ctrl allt 打开终端窗口 4、ls 查看该路径下的文件 5 mkdir filename 创建文件夹 6、sudo chmod 777 filename 给予权限 首先对于vcs而言&#xff0c;建立其脚本有以下几个步骤: 1、setup synopsys_sim.setu…