CloudCompare插件开发之如何设计界面ui与功能实现?

news2024/9/24 9:27:32

文章目录

  • 0.引言
  • 1.使用文件说明
  • 2.添加界面ui相关文件到插件目录
  • 3.修改工程相关文件并生成
  • 4.结果展示

0.引言

  CloudCompare源代码编译成功后,即可进行二次开发,可通过修改源码实现二次开发基础功能(见:CloudCompare如何进行二次开发?),也可修改源码实现二次开发界面ui设计与实现(见:CloudCompare二次开发之如何设计界面ui与功能实现?),二次开发也可进行插件式开发(见:CloudCompare如何进行二次开发之插件开发?),若想要实现更多自定义功能,可以自定义界面ui,并操作CloudCompare程序处理数据。本文讲解CloudCompare的插件能够被扩展的ui界面进行克隆点云操作。

1.使用文件说明

  本文使用的插件文件来自:CloudCompare插件开发之点云如何创建、保存并显示?
  本文使用的界面ui文件来自:CloudCompare二次开发之如何设计界面ui与功能实现?
  在这里插入图片描述

2.添加界面ui相关文件到插件目录

  CMake编译,将插件目录文件包含进工程。
  编译步骤见:CloudCompare如何进行二次开发之插件开发?。
  在这里插入图片描述

3.修改工程相关文件并生成

  (1)MyForm文件修改
  ①MyForm.h修改
  在这里插入图片描述

#pragma once
#include "ccOverlayDialog.h"  
#include "ui_MyForm2.h"  
  
class QMdiSubWindow;  
class ccGenericPointCloud;  
class ccPointCloud;  
  
class MyForm2 :public QWidget  
{  
    Q_OBJECT  
public:  
    //MyForm2(QWidget *parent = Q_NULLPTR);  
    MyForm2(ccPointCloud* pc, QWidget *parent = Q_NULLPTR);  
    //explicit MyForm2(QWidget* parent, ccPointCloud* pc);  
    virtual ~MyForm2() override;  
signals:  
    void sig(ccPointCloud* pcOut);  
    public slots:  
    void onClone();   //点云克隆  
    void closeForm();//关闭窗体  
private:  
    Ui::MyFormClass* m_ui = nullptr;  //功能界面  
    ccPointCloud* m_cloud = nullptr;  //选中的点云  
};

  ②MyFom.cpp修改

#pragma once
#include "MyForm2.h"  
#include "ccPointCloud.h"  
#include "OperateData_1.h"  
  
MyForm2::MyForm2(ccPointCloud* pc, QWidget* parent)  
    :QWidget(parent)  
    , m_cloud(pc)  
    , m_ui(new Ui::MyFormClass)  
  
{  
    m_ui->setupUi(this);  
    //信号槽连接  
    connect(m_ui->pushButton, &QAbstractButton::clicked, this, &MyForm2::onClone);  
    connect(m_ui->pushButton_2, &QAbstractButton::clicked, this, &MyForm2::closeForm);  
}  
MyForm2::~MyForm2()  
{  
    if (m_ui) {  
        delete m_ui;  
        m_ui = nullptr;  
    }  
    if (m_cloud) {  
        delete m_cloud;  
        m_cloud = nullptr;  
    }  
}  
  
void MyForm2::onClone()  
{  
    if (!m_cloud)  
    {  
        return;  
    }  
    //点到点的克隆  
    ccPointCloud* pc = new ccPointCloud(m_cloud->getName() + QString("-Clone"));  
    //为克隆对象分配内存  
    pc->reserve(m_cloud->size());  
    size_t pointSize = m_cloud->size();  
    for (size_t i = 0; i < pointSize; ++i)  
    {  
        pc->addPoint(*m_cloud->getPoint(i));  
    }  
    //发送信号给主窗体  
    emit sig(pc);  
}  
  
void MyForm2::closeForm()  
{  
    this->close();  
}

  (2)OperateData_1文件修改
  ①OperateData_1.h修改
  在这里插入图片描述

#ifndef EXAMPLE_PLUGIN_HEADER
#define EXAMPLE_PLUGIN_HEADER  
  
//##########################################################################  
//#                                                                        #  
//#                CLOUDCOMPARE PLUGIN: OperateData_1                     #  
//#                                                                        #  
//#  This program is free software; you can redistribute it and/or modify  #  
//#  it under the terms of the GNU General Public License as published by  #  
//#  the Free Software Foundation; version 2 of the License.               #  
//#                                                                        #  
//#  This program is distributed in the hope that it will be useful,       #  
//#  but WITHOUT ANY WARRANTY; without even the implied warranty of        #  
//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         #  
//#  GNU General Public License for more details.                          #  
//#                                                                        #  
//#                             COPYRIGHT: XXX                             #  
//#                                                                        #  
//##########################################################################  
  
#include "ccStdPluginInterface.h"  
#include "MyForm2.h"  
  
//! Example qCC plugin  
/** Replace 'MySecondPlugin' by your own plugin class name throughout and then  
    check 'MySecondPlugin.cpp' for more directions.  
    Each plugin requires an info.json file to provide information about itself -  
    the name, authors, maintainers, icon, etc..  
    The one method you are required to implement is 'getActions'. This should  
    return all actions (QAction objects) for the plugin. CloudCompare will  
    automatically add these with their icons in the plugin toolbar and to the  
    plugin menu. If        your plugin returns        several actions, CC will create a  
    dedicated toolbar and a        sub-menu for your plugin. You are responsible for  
    connecting these actions to        methods in your plugin.  
    Use the ccStdPluginInterface::m_app variable for access to most of the CC  
    components (database, 3D views, console, etc.) - see the ccMainAppInterface  
    class in ccMainAppInterface.h.  
  
**/  
class OperateData_1 : public QObject, public ccStdPluginInterface  
{  
    Q_OBJECT  
        Q_INTERFACES(ccStdPluginInterface)  
    // Replace "Example" by your plugin name (IID should be unique - let's hope your plugin name is unique ;)  
    // The info.json file provides information about the plugin to the loading system and  
    // it is displayed in the plugin information dialog.  
    Q_PLUGIN_METADATA(IID "cccorp.cloudcompare.plugin.Example" FILE "info.json")  
public:  
    explicit OperateData_1(QObject *parent = nullptr);  
    ~OperateData_1() override = default;  
    //OperateData_1(QObject * parent);  
    // inherited from ccStdPluginInterface  
    void onNewSelection(const ccHObject::Container &amp;selectedEntities) override;  
    QList<QAction *> getActions() override;  
private:  
    /*** ADD YOUR CUSTOM ACTIONS HERE ***/  
    void doAction();  
    //! Default action  
    /** You can add as many actions as you want in a plugin.  
        Each action will correspond to an icon in the dedicated  
        toolbar and an entry in the plugin menu.  
  
    **/  
    QAction* m_action;  
    private slots:  
    void onClone(ccPointCloud*);   //点云克隆  
private:  
    MyForm2* myForm2 = nullptr;  
};  
  
#endif

  ②OperateData_1.cpp修改
  在这里插入图片描述

//##########################################################################
//#                                                                        #  
//#                CLOUDCOMPARE PLUGIN: OperateData_1                      #  
//#                                                                        #  
//#  This program is free software; you can redistribute it and/or modify  #  
//#  it under the terms of the GNU General Public License as published by  #  
//#  the Free Software Foundation; version 2 of the License.               #  
//#                                                                        #  
//#  This program is distributed in the hope that it will be useful,       #  
//#  but WITHOUT ANY WARRANTY; without even the implied warranty of        #  
//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         #  
//#  GNU General Public License for more details.                          #  
//#                                                                        #  
//#                             COPYRIGHT: XXX                             #  
//#                                                                        #  
//##########################################################################  
  
// First:  
//        Replace all occurrences of 'OperateData_1' by your own plugin class name in this file.  
//        This includes the resource path to info.json in the constructor.  
  
// Second:  
//        Open OperateData_1.qrc, change the "prefix" and the icon filename for your plugin.  
//        Change the name of the file to <yourPluginName>.qrc  
  
// Third:  
//        Open the info.json file and fill in the information about the plugin.  
//         "type" should be one of: "Standard", "GL", or "I/O" (required)  
//         "name" is the name of the plugin (required)  
//         "icon" is the Qt resource path to the plugin's icon (from the .qrc file)  
//         "description" is used as a tootip if the plugin has actions and is displayed in the plugin dialog  
//         "authors", "maintainers", and "references" show up in the plugin dialog as well  
  
#include <QtGui>  
  
#include "OperateData_1.h"  
#include "qinputdialog.h"  
#include "ccProgressDialog.h"  
#include "ccPointCloud.h"  
#include<iostream>  
#include<fstream>  
#include "qtextstream.h"  
#include "math.h"  
#include<qfiledialog.h>  
  
using namespace std;  
  
// Default constructor:  
//        - pass the Qt resource path to the info.json file (from <yourPluginName>.qrc file)  
//  - constructor should mainly be used to initialize actions and other members  
OperateData_1::OperateData_1(QObject *parent)  
    : QObject(parent)  
    , ccStdPluginInterface(":/CC/plugin/OperateData_1/info.json")  
    , m_action(nullptr)  
  
{  
}  
  
// This method should enable or disable your plugin actions  
// depending on the currently selected entities ('selectedEntities').  
void OperateData_1::onNewSelection(const ccHObject::Container &amp;selectedEntities)  
{  
    if (m_action == nullptr)  
    {  
        return;  
    }  
    // If you need to check for a specific type of object, you can use the methods  
    // in ccHObjectCaster.h or loop and check the objects' classIDs like this:  
    //  
    //        for ( ccHObject *object : selectedEntities )  
    //        {  
    //                if ( object->getClassID() == CC_TYPES::VIEWPORT_2D_OBJECT )  
    //                {  
    //                        // ... do something with the viewports  
    //                }  
    //        }  
    // For example - only enable our action if something is selected.  
    //m_action->setEnabled(!selectedEntities.empty());  
    m_action->setEnabled(true);  
}  
  
// This method returns all the 'actions' your plugin can perform.  
// getActions() will be called only once, when plugin is loaded.  
QList<QAction *> OperateData_1::getActions()  
{  
    // default action (if it has not been already created, this is the moment to do it)  
    if (!m_action)  
    {  
        // Here we use the default plugin name, description, and icon,  
        // but each action should have its own.  
        m_action = new QAction(getName(), this);  
        m_action->setToolTip(getDescription());  
        m_action->setIcon(getIcon());  
    // Connect appropriate signal  
    connect(m_action, &amp;QAction::triggered, this, &amp;OperateData_1::doAction);  
    }  
    return{ m_action };  
}  
  
// This is an example of an action's method called when the corresponding action  
// is triggered (i.e. the corresponding icon or menu entry is clicked in CC's  
// main interface). You can access most of CC's components (database,  
// 3D views, console, etc.) via the 'm_app' variable (see the ccMainAppInterface  
// class in ccMainAppInterface.h).  
void OperateData_1::doAction()  
{  
    if (m_app == nullptr)  
    {  
        // m_app should have already been initialized by CC when plugin is loaded  
        Q_ASSERT(false);  
    return;  
    }  
    const ccHObject::Container&amp; selectedEntities = m_app->getSelectedEntities();//此处为选择已有点云的操作  
    ccPointCloud* cloud = ccHObjectCaster::ToPointCloud(selectedEntities[0]);//此处为选择已有点云的操作  
    myForm2 = new MyForm2(cloud);  
    connect(myForm2, SIGNAL(sig(ccPointCloud*)), this, SLOT(onClone(ccPointCloud*)));  
    myForm2->show();  
    创建点云  
    //ccPointCloud* myPc = new ccPointCloud(QString("myPc"));  
    //int pointCount = 10000;//设置创建10000个点  
    //myPc->reserve(pointCount);  
    //for (size_t i = 0; i < pointCount; i++)  
    //{  
    //        float angle = (i % 360)*3.1415926 / 180;  
    //        float x = 100 * cos(angle);  
    //        float y = 100 * sin(angle);  
    //        float z = int(i / 360) * 1;  
    //        const CCVector3* vcc = new CCVector3(x, y, z);  
    //        myPc->addPoint(*vcc);  
    //}  
    保存点云  
    //QString dirPath = QFileDialog::getExistingDirectory(nullptr, "please select a saving path");  
    //if (dirPath.isEmpty()) {  
    //        m_app->dispToConsole("The user did not select a folder.");  
    //        return;  
    //}  
    //QString filename =  QString(myPc->getName());  
    //QFile file(dirPath + "\\" + filename + ".txt");  
    //if (!file.exists()) {  
    //        file.open(QIODevice::ReadWrite | QIODevice::Text);  
    //        file.close();  
    //}  
    //file.open(QIODevice::Text | QIODevice::Truncate | QIODevice::WriteOnly);  
    //QTextStream out(&amp;file);  
    //int precision = 3;  
    //for (int i = 0; i<myPc->size(); i++) {  
    //        float x = myPc->getPoint(i)->x;  
    //        float y = myPc->getPoint(i)->y;  
    //        float z = myPc->getPoint(i)->z;  
    //        out << QString("%1,%2,%3").arg(x, 0, 'r', precision).arg(y, 0, 'r', precision).arg(z, 0, 'r', precision) << endl;  
    //}  
    //file.close();  
    显示点云  
    //std::vector<ccHObject*> allCloud;  
    //allCloud.push_back(myPc);  
    //ccHObject* CloudGroup = new ccHObject(QString("CloudGroup"));  
    //for (size_t i = 0; i < allCloud.size(); i++)  
    //{  
    //        CloudGroup->addChild(allCloud[i]);  
    //}  
    //m_app->addToDB(CloudGroup);  
    //m_app->refreshAll();  
    //m_app->updateUI();  
}  
  
void OperateData_1::onClone(ccPointCloud* myPc)  
{  
    //显示点云  
    std::vector<ccHObject*> allCloud;  
    allCloud.push_back(myPc);  
    ccHObject* CloudGroup = new ccHObject(QString("CloudGroup"));  
    for (size_t i = 0; i < allCloud.size(); i++)  
    {  
        CloudGroup->addChild(allCloud[i]);  
    }  
    m_app->addToDB(CloudGroup);  
    m_app->refreshAll();  
    m_app->updateUI();  
}

  (3)OperateData_1插件生成
  在这里插入图片描述

4.结果展示

  在这里插入图片描述

参考资料:
[1] cacrle. Visual Studio如何使用Qt开发桌面软件?; 2023-04-18 [accessed 2023-04-20].
[2] cacrle. CloudCompare如何进行二次开发?; 2023-04-19 [accessed 2023-04-20].
[3] cacrle. CloudCompare如何进行二次开发之插件开发?; 2023-04-19 [accessed 2023-04-20].
[4] cacrle. CloudCompare二次开发之如何设计界面ui与功能实现?; 2023-04-19 [accessed 2023-04-20].
[5] 问也去. CloudCompare实现点选点云功能; 2021-09-23 [accessed 2023-04-20].
[6] 进击の小黑. CloudCompare简单二次开发教程 上(界面设计与ui文件编译); 2020-12-17 [accessed 2023-04-20].
[7] 进击の小黑. CloudCompare简单二次开发 下(功能实现); 2020-12-18 [accessed 2023-04-20].
[8] shaomq2187. VS2019已有项目中添加Qt; 2021-11-08 [accessed 2023-04-20].
[9] wb175208. VS2013 在配置中手动添加宏定义; 2018-04-08 [accessed 2023-04-20].

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

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

相关文章

#mysql binlog 备份恢复数据流程#

模式&#xff1a;mysql全量备份binlog日志完整恢复数据 首先&#xff0c;数据库在误操作之前必须已经开启了binlog日志功能&#xff0c;且binlog日志的保存周期必须大于全备份的时间周期&#xff01; 所谓恢复&#xff0c;就是让将全备份的数据全部恢复后&#xff0c;再使用my…

HTB-Time

HTB-Time 信息收集80端口 立足pericles -> root 信息收集 80端口 有两个功能&#xff0c;一个是美化JSON数据。 一个是验证JSON&#xff0c;并且输入{“abc”:“abc”}之类的会出现报错。 Validation failed: Unhandled Java exception: com.fasterxml.jackson.core.JsonPa…

当⻉借⼒阿⾥云落地云原⽣架构转型,运维降本、效率稳定性双升

作者&#xff1a;当贝技术团队 随着业务飞速发展&#xff0c;当贝的传统 IT 资产也渐显臃肿&#xff0c;为了避免制约发展的瓶颈&#xff0c;痛定思痛&#xff0c;技术团队果断变革&#xff1a;核心业务云原生化之后&#xff0c;运维效率、整体稳定性和研发效率均得到了全面提…

网络基础知识

网络基础知识 一、什么是二层互通与三层互通&#xff1f;1.1 二层网络互通1.2 三层网络互通 二、什么是Overlay网络&#xff1f;2.1 Underlay网络2.2 Overlay网络2.3 Underlay网络 vs Overlay网络 三、什么是SNMP&#xff1f;3.1 SNMP概念3.2 为什么需要SNMP&#xff1f;3.3 SN…

基于ubuntu18.04.6 LTS服务器安装nvidia驱动

1对于一个刚刚配置的服务器&#xff0c;首先nvidia-smi&#xff0c;自然无法显示Driver Version、最高cuda版本等信息。 nvidia-smi: command not found 需要我们自己安装nvidia驱动 2禁用老驱动 禁用自带nouveau驱动 sudo vim /etc/modprobe.d/blacklist.conf 打开后在CONF文…

本地配置nacos例子

nacos的加载顺序 0、application.properties 1、bootstrap.properties 2、bootstrap-{profile}.properties #本地启动 nacos的配置文件的生成规则&#xff0c;当我正常启动项目时 nacos的配置文件名字生成规则为 ${spring.application.name}.yaml spring:application:name…

面试redis之两大金刚,你懂吗

前言 Redis持久化&#xff0c;一个老掉牙的问题&#xff0c;但是面试官就是喜欢问。这也是我们学Redis必会的一个知识点。Redis作为内存数据库&#xff0c;它工作时&#xff0c;数据都保存在内存里&#xff0c;这也是它为什么很快的一个原因。但存到内存里肯定是有丢数据的风险…

为什么我们能判断声音的远近

想象一下&#xff0c;当我们走在路上时&#xff0c;听到了头顶的鸟儿在树梢间的叫声&#xff0c;即使无法透过浓密的树叶看见它&#xff0c;也可以大致知道鸟儿的距离。此时身后传来由远到近自行车铃铛声&#xff0c;我们并不需要回过头去看&#xff0c;便为它让开了道路。这些…

查找文件路径——whereis、which、locate、find命令

目录标题 whereis命令——通过环境变量查找所有文件&#xff08;包括可执行文件&#xff09;which命令——查找系统命令文件与whereis命令区别 locate命令——全局搜索find命令&#xff08;全盘搜索&#xff09;find命令中的参数及作用按照文件名搜索按照文件大小搜索按照修改时…

离散数学-考纲版-02-谓词

文章目录 2. 谓词参考2.1 命题2.1 个体谓词和量词2.1.1 个体2.1.2 谓词2.1.3 量词引入个体域符号化量词真值确定谓词符号化举例示例一示例二示例三示例四 2.3谓词合式公式2.3.1 四类符号2.3.2 项2.3.3 合式公式 2.4 自由变元与约束变元2.4.1 定义2.4.2 判定2.4.3 两个规则2.4.4…

【京东】商品详情页+商品列表数据采集

作为国内最大的电商平台之一&#xff0c;京东数据采集具有多个维度。 有人需要采集商品信息&#xff0c;包括品类、品牌、产品名、价格、销量等字段&#xff0c;以了解商品销售状况、热门商品属性&#xff0c;进行市场扩大和重要决策&#xff1b; 有人需要采集产品评论&…

Android OpenGL 渲染相机预览画面显示体系

OpenGL能进行高效得渲染图形图像&#xff0c;并支持各种复杂的特效和动画。 而在 Android 当中&#xff0c;运用的是OpenGL ES&#xff0c;它是OpenGL的一个轻量级版本&#xff0c;专门用于在移动设备、游戏控制台、嵌入式系统等嵌入式环境中使用。 它可以做相机滤镜或者图片…

基于html+css的图片展示31

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

yield用法理解,配有代码块和解析

包含 yield 关键字的函数&#xff0c;是一个生成器 yield和return的区别 1、return是返回return关键字的值&#xff0c;被调用一次就返回一次&#xff0c;return只能放在一个函数代码块的最后面&#xff0c;运行到return的时候&#xff0c;就结束循环&#xff0c;结束这个函数…

IO、存储、硬盘、文件系统相关常识

目录 IO 文件系统 存储 存储这些数据的硬盘 IO io分为io设备和io接口, 我们日常生活中的打印机, 固态硬盘等都是io设备. IO&#xff08;Input-Output&#xff09;是指计算机中输入输出的相关操作&#xff0c;包括数据的读取、存储、传输和显示等。存储是指将数据保存在计算…

美国肝素钠专用树脂,医药肝素钠提取工艺专用树脂

具有控制孔径的大孔强碱性Ⅰ型阴离子交换树脂 Tulsimer A-72 MP 是一款具有便于颜色和有机物去除的控制孔径的&#xff0c;专门开发的大孔强碱性Ⅰ型阴离子交换树脂。 Tulsimer A-72 MP专门应用于去除COD以及其他有机物等。 Tulsimer A-72 MP 由于其本身的大孔特性而显示出…

电巢携手中国自动化学会:计算机能有感情史了

4月22日&#xff0c;为了促进模式识别、数据挖掘和计算机视觉等相关领域从业者进一步了解领域内最新发展动态与前沿技术进展&#xff0c;由中国自动化学会主办&#xff0c;中国自动化学会模式识别与机器智能&#xff08;CAA-PRMI&#xff09;专委会、中国计算机学会&#xff08…

Python OpenCV 蓝图:6~7

原文&#xff1a;OpenCV with Python Blueprints 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【ApacheCN 计算机视觉 译文集】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 当别人说你没有底线的时候&#xff0c;你最好真…

【Cartopy基础入门】如何更好的确定边界显示

原文作者&#xff1a;我辈理想 版权声明&#xff1a;文章原创&#xff0c;转载时请务必加上原文超链接、作者信息和本声明。 Cartopy基础入门 【Cartopy基础入门】Cartopy的安装 【Cartopy基础入门】Geojson数据的加载 【Cartopy基础入门】如何更好的确定边界显示 文章目录 Ca…

苯酚吸附树脂

苯酚作为一种重要的化工原料&#xff0c;主要用于生产酚醛树脂&#xff0c;双酚A&#xff0c;己内酰胺&#xff0c;壬基酚&#xff0c;水杨酸等&#xff0c;此外还可以做溶剂&#xff0c;试剂盒消毒剂等&#xff0c;在合成纤维&#xff0c;合成橡胶&#xff0c;塑料&#xff0c…