CloudCompare插件开发之如何将点云文件打开、处理并显示?

这篇具有很好参考价值的文章主要介绍了CloudCompare插件开发之如何将点云文件打开、处理并显示?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

0.引言

  CloudCompaer是一款优秀的开源软件,在点云处理时可以根据实际要求开发合适的插件,本文需求是将点云文件打开、处理并显示,网上资源可以找到点云简单处理和显示的代码,但对于文件打开的源代码几乎没有,本文通过查阅大量资料和研究源代码实现了点云文件打开,从而达到本文将点云文件打开、处理并显示的目标。本文是CloudCompare插件开发的拓展篇,关于插件开发基础可以参考:CloudCompare如何进行二次开发之插件开发?

1.将点云文件打开、处理并显示的效果

(1)CloudCompare自带打开功能打开点云初始文件
点云文件怎么打开,CloudCompare,c++,git,github,qt,visualstudio
(2)插件打开点云初始文件、处理并显示
点云文件怎么打开,CloudCompare,c++,git,github,qt,visualstudio

2.代码实现

(1)引用的命名空间

#include <QtGui>
#include "MySecondPlugin.h"
#include "qinputdialog.h"
#include "ccProgressDialog.h"
#include "ccPointCloud.h"

(2)设置插件按钮不用选择点云即可使用

void MySecondPlugin::onNewSelection(const ccHObject::Container &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);//设置插件按钮不用选择点云即可使用
}

(3)点云文件打开、处理并显示代码

void MySecondPlugin::doAction()
{
	if (m_app == nullptr)
	{
		// m_app should have already been initialized by CC when plugin is loaded
		Q_ASSERT(false);

	return;
	}

	/*** HERE STARTS THE ACTION ***/

	// Put your code here
	// --> you may want to start by asking for parameters (with a custom dialog, etc.)
	/*
	* 点云格式为:x,y,z
	* 
	*/ 
	
	//【打开文件】将数据预处理到点云文件
	//打开文件选择对话框
	char szFileName[MAX_PATH] = { 0 };
	OPENFILENAME openFileName = { 0 };
	openFileName.lStructSize = sizeof(OPENFILENAME);
	openFileName.nMaxFile = MAX_PATH;
	openFileName.lpstrFilter = "csv文件(*.csv)\0*.csv\0所有文件(*.*)\0*.*\0\0";
	openFileName.lpstrFile = szFileName;
	openFileName.nFilterIndex = 1;
	openFileName.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
	if (!::GetOpenFileName(&openFileName))return;
	//打开点云文件
	const QString fileName = openFileName.lpstrFile;
	QFile file(fileName);
	if (!file.open(QIODevice::ReadOnly))return;
	QTextStream stream(&file);
	QStringList qsl;
	std::vector<QVector3D>* vq = new std::vector<QVector3D>();
	int countOne = 0;
	stream.seek(0);
	QStringList strs = (stream.readAll()).split('\n');
	for (size_t i = 0; i < strs.size(); i++)
	{
		qsl = strs.takeAt(i).split(',');
		if (qsl.size() != 3) continue;
		QVector3D* qv3d = new QVector3D(qsl.at(0).toFloat(), qsl.at(1).toFloat(), qsl.at(2).toFloat());
		vq->push_back(*qv3d);
	}
	file.close();

	//将点云文件保存到CloudCompare(cc)标准数据集
	ccPointCloud* myPc = new ccPointCloud(QString("myPc"));
	myPc->reserve(vq->size());
	for (size_t i = 0; i < vq->size(); i++)
	{
		const CCVector3* vcc = new CCVector3(vq->at(i).x(), vq->at(i).y(), vq->at(i).z());
		myPc->addPoint(*vcc);
	}

	//【点云处理】指定参数切割部分点云
	得到点云
	//const ccHObject::Container& selectedEntities = m_app->getSelectedEntities();//此处为选择已有点云的操作
	//size_t selNum = selectedEntities.size();//此处为选择已有点云的操作
	size_t selNum = 1;

	//传入参数
	bool isOK;
	QString s_percentage = QInputDialog::getText(NULL, QString::fromLocal8Bit("参数"), QString::fromLocal8Bit("输入留下点的百分比0-1"), QLineEdit::Normal, "", &isOK);
	if (!isOK) {
		ccLog::Print("error");
		return;
	}

	//留下点的个数
	double percentage = s_percentage.toDouble();
	if (percentage < 0 || percentage>1) {
		ccLog::Print("error percentage allow 0-1");
		return;
	}

	//加个进度条
	ccProgressDialog pDlg(true, 0);
	CCLib::GenericProgressCallback* progressCb = &pDlg;
	if (progressCb) {
		if (progressCb->textCanBeEdited()) {
			progressCb->setMethodTitle("compute");
			progressCb->setInfo(qPrintable(QString("waiting...")));
		}
		progressCb->update(0);
		progressCb->start();
	}
	std::vector<ccHObject*> allCloud;

	//随机数
	qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));

	for (size_t i = 0; i < selNum; i++)
	{
		//ccHObject* ent = selectedEntities[i];//此处为选择已有点云的操作
		ccHObject* ent = myPc;

	if (!ent->isA(CC_TYPES::POINT_CLOUD)) {
		continue;
	}

	//ccPointCloud* cloud = ccHObjectCaster::ToPointCloud(selectedEntities[i]);//此处为选择已有点云的操作
	ccPointCloud* cloud = myPc;

	//计算点云中心
	CCVector3 weight;

	CCVector3 bmin, bmax;
	cloud->getBoundingBox(bmin, bmax);
	weight = (bmin + bmax) / 2;

	//遍历索引
	std::vector<size_t> m_index(cloud->size());

	//以递增的方式填充
	std::iota(m_index.begin(), m_index.end(), 0);

	//随机一个方向
	double theta = M_PI*(double)qrand() / (double)(RAND_MAX + 1);
	double phi = 2 * M_PI*(double)qrand() / (double)(RAND_MAX + 1);

	CCVector3 dir(sin(theta)*cos(phi), sin(theta)*sin(phi), cos(theta));

	std::vector<double> m_value;

	for (size_t i = 0; i < m_index.size(); i++)
	{
		CCVector3 P;
		cloud->getPoint(m_index[i], P);
		double temp = (P - weight).dot(dir);
		m_value.push_back(temp);
	}
	//对m_index进行排序
	std::sort(m_index.begin(), m_index.end(), [&m_value](auto i1, auto i2) {return m_value[i1] < m_value[i2];});
	m_index.erase(m_index.begin(), m_index.begin() + (1 - percentage)*cloud->size());

	//新点云
	//ccPointCloud* pcc = new ccPointCloud(QString("cq") + cloud->getName());
	ccPointCloud* pcc = new ccPointCloud(cloud->getName() + QString("-Clone"));
	pcc->reserve(m_index.size());
	//pcc->reserveTheNormsTable();//分配法向量内存,本环境报错

	for (size_t i = 0; i < m_index.size(); i++)
	{
		pcc->addPoint(*cloud->getPoint(m_index[i]));
		//pcc->addNorm(cloud->getPointNormal(m_index[i]));//分配法向量内存,本环境报错
	}

	allCloud.push_back(pcc);
	progressCb->update((float)100.0*i / selNum);
	}

	if (progressCb) {
		progressCb->stop();
	}

	//【显示点云】
	//新建一个文件夹来放点云
	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();

	// This is how you can output messages
	 Display a standard message in the console
	//QString show = QString::number(selNum) + "," + s_percentage + "," + QString::number(percentage);
	//m_app->dispToConsole(show, ccMainAppInterface::STD_CONSOLE_MESSAGE);

	 Display a warning message in the console
	//m_app->dispToConsole("[MySecondPlugin] Warning: example plugin shouldn't be used as is", ccMainAppInterface::WRN_CONSOLE_MESSAGE);

	 Display an error message in the console AND pop-up an error box
	//m_app->dispToConsole("Example plugin shouldn't be used - it doesn't do anything!", ccMainAppInterface::ERR_CONSOLE_MESSAGE);

	/*** HERE ENDS THE ACTION ***/
}

参考资料:
[1] cacrle. CloudCompare如何进行二次开发之插件开发?; 2023-03-11 [ accessed 2023-03-26 ].
[2] 点云PCL. CloudCompare插件开发教程; 2020-06-20 [ accessed 2023-03-26 ].文章来源地址https://www.toymoban.com/news/detail-676479.html

到了这里,关于CloudCompare插件开发之如何将点云文件打开、处理并显示?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • CloudCompare 二次开发(6)——插件中拖拽添加Qt窗口(区域生长算法为例)

    本文由CSDN点云侠原创,原文链接。爬虫网站自重。   手动拖拽的方式搭建Qt对话框界面的制作流程,以PCL中的点云区域生长算法为例进行制作。 1、将 ....pluginsexample 路径下的 ExamplePlugin 复制一份并修改名字为 CCPointCloudProcess 。 2、创建窗口UI文件 使用任意Qt工程新建对话

    2023年04月11日
    浏览(56)
  • QT6+CloudCompare显示3D点云

        CloudCompare是一个三维点云(网格)编辑和处理软件。最初,它被设计用来对稠密的三维点云进行直接比较。它依赖于一种特定的八叉树结构,在进行点云对比这类任务时具有出色的性能。此外,由于大多数点云都是由地面激光扫描仪采集的,CloudCompare的目的是在一台标准

    2023年04月08日
    浏览(48)
  • 【CloudCompare教程】008:基于点云的三维模型重建(泊松重建)

    本文讲述基于点云的三维模型重建方法,PoissonRecon是“Poisson Surface Reconstruction”的缩写,它是由约翰霍普金斯大学的Misha Kazhdan47提出的三角形网格生成算法的简单接口。 加载兔子点云,如下图所示: 在三维模型构建之前,应先计算法向量,否则会有以下提示:点云必须具有

    2024年02月07日
    浏览(51)
  • CloudCompare二次开发之如何设计界面ui与功能实现?

      CloudCompare源代码编译成功后,即可进行二次开发,可以通过修改源码实现二次开发,二次开发基础功能见(CloudCompare如何进行二次开发?),若想要实现更多自定义功能,可以自定义界面ui,并操作CloudCompare程序处理数据。本文讲解界面ui设计,修改相应的文件,使Cloud

    2023年04月20日
    浏览(41)
  • Cloudcompare2.12.2使用vs2022带插件编译以及在WSL中编译cloudCompare【最新实践】

    安装需要: windows上编译需要:vs2022、qt5.15.2 (msvc)、cmake-gui、Cloudcompare2.12.2(源码)、CCCoreLib(源码,提供cloudCompare的算法库) linux上编译需要:cmake、qt的一些依赖包、Cloudcompare2.12.2(源码)、CCCoreLib cloudCompare插件编译所需依赖库或工具:PDAL、PCL、LasTools 1.1、提前准备 首先安

    2024年02月04日
    浏览(47)
  • Unity 打开文件选择框(Standalone File Browser插件)

    Works in editor and runtime. 支持运行时+编辑器模式 Open file/folder, save file dialogs supported. 支持打开文件/文件夹,以及保存文件 Multiple file selection. 支持文件多选 File extension filter. 支持文件后缀过滤 Mono/IL2CPP backends supported. Linux support by Ricardo Rodrigues. 支持Linux,感谢 Ricardo Rodrigues. Ba

    2024年01月17日
    浏览(37)
  • CloudCompare如何使用基础功能?

      CloudCompare是一款优秀的开源点云处理软件,在研究点云的过程中,会用到其中一些点云处理功能。为快速熟悉软件的基础功能,本文介绍相应的功能按键的作用。         (1)Open:打开文件,可以打开如下点云格式      (2)Open Recent… :打开最近的文件   

    2024年02月08日
    浏览(36)
  • CloudCompare 二次开发(20)——二次曲面拟合

    本文由CSDN点云侠原创,原文链接。爬虫网站自重。   由CloudCompare——点云二次曲面拟合一文知:CloudCompare软件中的已经集成了二次曲面拟合功能,但是计算出来的拟合参数是不正确的。因此,本文在原有算法的基础上进行修改,使输出的参数结果正确。 mainwindow.cpp 文件

    2024年02月06日
    浏览(50)
  • 实现一个vscode插件:打开多个vscode项目时根据.nvmrc文件自动切换nvm

    开发背景与最终功能 需要维护一些老项目,同时开发新项目时,切换nvm很烦人 最终实现vscode插件:每个vscode实例打开一个项目,切换vscode实例时能自动切换版本(需要项目根目录有一个.nvmrc文件) 插件下载 vscode插件市场搜索 vscode-nvmrc 设计思路 项目根目录新建 .nvmrc 文件,

    2024年02月15日
    浏览(41)
  • cloudcompare 编译安装解决无法load pcd文件问题

    参考 https://github.com/CloudCompare/CloudCompare/blob/master/BUILD.md 特别注意 git clone是时要带–recursive 编译后,一定要sudo make install,否则在build/qCC/下启动CloudCompare无法加载pcd文件。

    2024年02月03日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包