CloudCompare:获取点云信息 实现移位(取点-存点)v2.10.3 +VS2017 + Qt5.9.8

 选择点云,实现移位功能。

分享给有需要的人,代码质量勿喷。

1、xjShift.h

#ifndef XJ_SHIFT_HEADER
#define XJ_SHIFT_HEADER

#include "ccStdPluginInterface.h"

#include "ShiftDlg.h"

//Qt
#include <QtGui>
#include <QApplication>
#include <QtConcurrentRun>
#include <QApplication>
#include <QProgressDialog>
#include <QMainWindow>

//qCC_db
#include <ccPointCloud.h>

//CCLib
#include <ccScalarField.h>

//System
#include <algorithm>
#if defined(CC_WINDOWS)
#include "windows.h"
#else
#include <time.h>
#endif

class xjShift : public QObject, public ccStdPluginInterface
{
	Q_OBJECT
	Q_INTERFACES(ccStdPluginInterface)
	Q_PLUGIN_METADATA(IID "cccorp.cloudcompare.plugin.xjShift" FILE "info.json")

public:

	//! Default constructor
	explicit xjShift(QObject* parent = nullptr);

	//inherited from ccStdPluginInterface
	virtual void onNewSelection(const ccHObject::Container& selectedEntities);
	virtual QList<QAction *> getActions() override;

protected slots:

	//! Slot called when associated ation is triggered
	void doAction();

protected:

	//! Associated action
	QAction* m_action;
};

#endif

2、xjShift.cpp

xjShift::xjShift(QObject* parent/*=nullptr*/)
    : QObject(parent)
    , ccStdPluginInterface(":/CC/plugin/xjShift/info.json")
    , m_action(nullptr)
{
}

void xjShift::onNewSelection(const ccHObject::Container& selectedEntities)
{
	if (m_action)
		m_action->setEnabled(selectedEntities.size() >= 1);
		//m_action->setEnabled(selectedEntities.size()==1 && selectedEntities[0]->isA(CC_TYPES::POINT_CLOUD));
}

void xjShift::doAction()
{
	assert(m_app);
	if (!m_app)
		return;

	//1 judge
	const ccHObject::Container& selectedEntities = m_app->getSelectedEntities();
	size_t selNum = selectedEntities.size();
	if (selNum!=1)
	{
		m_app->dispToConsole(tr("Select only one cloud!"),ccMainAppInterface::ERR_CONSOLE_MESSAGE);
		return;
	}

	ccHObject* ent = selectedEntities[0];
	assert(ent);
	if (!ent || !ent->isA(CC_TYPES::POINT_CLOUD))
	{
		m_app->dispToConsole(tr("Select a real point cloud!"),ccMainAppInterface::ERR_CONSOLE_MESSAGE);
		return;
	}

	//2 input cloud
	ccPointCloud* pc = static_cast<ccPointCloud*>(ent);
	unsigned count = pc->size();
	bool hasNorms = pc->hasNormals();
	CCVector3 bbMin, bbMax;
	pc->getBoundingBox(bbMin,bbMax);
	const CCVector3d& globalShift = pc->getGlobalShift();
	double globalScale = pc->getGlobalScale();

	//3 result point cloud
	QString pcname = ent->getName();
	if (pcname.contains(" - Cloud"))
		pcname.replace(" - Cloud", "_Shift");
	else
		pcname += "_Shift";
	ccPointCloud *resultPC = new ccPointCloud(pcname);
	if (!resultPC->reserveThePointsTable(count))
	{
		m_app->dispToConsole(tr("Not enough memory"), ccMainAppInterface::ERR_CONSOLE_MESSAGE);
		delete resultPC;
		return;
	}

	//4 simulation parameters
	ShiftDlg xjShiftDlg(m_app->getMainWindow());
	if (!xjShiftDlg.exec())
		return;

	double  Xdis = xjShiftDlg.spinX->value();
	double  Ydis = xjShiftDlg.spinY->value();
	double  Zdis = xjShiftDlg.spinZ->value();

	//5 progress
	QProgressDialog *pDlg = new QProgressDialog(tr("running..."), QString(), 0, 100, m_app->getMainWindow());
	pDlg->setWindowTitle(tr("point cloud shift"));
	pDlg->show();
	QApplication::processEvents();

#pragma region update coordinate
	pDlg->setLabelText(tr("update coordinates..."));
	float x = 0, y = 0, z = 0;
	for (unsigned i = 0; i < count; ++i)
	{
		x = (pc->getPoint(i)->x) + Xdis;
		y = (pc->getPoint(i)->y) + Ydis;
		z = (pc->getPoint(i)->z) + Zdis;

		存点方式1
		//const CCVector3 &P1 = CCVector3(x,y,z);
		//resultPC->addPoint(P1);

		存点方式2
		//CCVector3 P(x,y,z);
		//resultPC->addPoint(P);

		存点方式3
		const CCVector3* X = new CCVector3(x, y, z);
		resultPC->addPoint(*X);

		//progress:coordinate
		pDlg->setValue(100.0*i / count);
	}
	resultPC->invalidateBoundingBox();
#pragma endregion

#pragma region update normal
	if (pc->hasNormals())
	{
		pDlg->setLabelText("update normals...");
		if (resultPC->reserveTheNormsTable())
		{
			for (unsigned i = 0; i < count; i++)
			{
				const CompressedNormType& nor = pc->getPointNormalIndex(i);
				resultPC->addNormIndex(nor);
				//progress:normal
				pDlg->setValue(100.0*i / count);
			}
			resultPC->showNormals(true);
		}
		else
		{
			m_app->dispToConsole(tr("Not enough memory: normal"), ccMainAppInterface::ERR_CONSOLE_MESSAGE);
			delete resultPC;
			return;
		}
	}
#pragma endregion

#pragma region update scalar field
	unsigned sfCount = pc->getNumberOfScalarFields();
	if (sfCount != 0)
	{
		for (unsigned k = 0; k < sfCount; ++k)
		{
			const ccScalarField* sf = static_cast<ccScalarField*>(pc->getScalarField(k));
			assert(sf);
			if (sf)
			{
				QString sfName = QString(QLatin1String(sf->getName()));//QString::fromUtf8(sf->getName());
				pDlg->setLabelText("update scalar field:" + sfName + "...");
				//we create a new scalar field with same name
				int sfIdx = resultPC->addScalarField(sf->getName());
				if (sfIdx >= 0)
				{
					const ccScalarField* oldsf = static_cast<ccScalarField*>(pc->getScalarField(sfIdx));
					ccScalarField* currentScalarField = static_cast<ccScalarField*>(resultPC->getScalarField(sfIdx));
					assert(currentScalarField);
					if (currentScalarField->resizeSafe(count))
					{
						currentScalarField->setGlobalShift(sf->getGlobalShift());

						//we copy data to new SF
						for (unsigned i = 0; i < count; i++)
						{
							//const ScalarType val= oldsf->getValue(i);
							//currentScalarField->setValue(i,val);
							currentScalarField->setValue(i, oldsf->getValue(i));
							//progress:scalar field
							pDlg->setValue(100.0*i / count);
						}
						currentScalarField->computeMinAndMax();
						currentScalarField->importParametersFrom(sf);//copy display parameters
					}
					else
					{
						//if we don't have enough memory, we cancel SF creation
						resultPC->deleteScalarField(sfIdx);
						QString infor = tr("Not enough memory: SF ") + sfName;
						m_app->dispToConsole(infor, ccMainAppInterface::ERR_CONSOLE_MESSAGE);
						delete resultPC;
						return;
					}
				}
			}
		}
		unsigned copiedSFCount = pc->getNumberOfScalarFields();
		if (copiedSFCount)
		{
			//we display the same scalar field as the source (if we managed to copy it!)
			if (pc->getCurrentDisplayedScalarField())
			{
				int sfIdx = resultPC->getScalarFieldIndexByName(pc->getCurrentDisplayedScalarField()->getName());
				if (sfIdx >= 0)
					resultPC->setCurrentDisplayedScalarField(sfIdx);
				else
					resultPC->setCurrentDisplayedScalarField(static_cast<int>(copiedSFCount) - 1);
			}
			resultPC->showNormals(false);
			resultPC->showSF(true);
		}
	}
#pragma endregion

#pragma region update colors
	if (pc->hasColors())
	{
		pDlg->setLabelText("update colors...");
		if (resultPC->reserveTheRGBTable())
		{
			for (unsigned i = 0; i < count; i++)
			{
				const ccColor::Rgb& rgb = pc->getPointColor(i);
				resultPC->addRGBColor(rgb);
				//progress:colors
				pDlg->setValue(100.0*i / count);
			}
			resultPC->showNormals(false);
			resultPC->showSF(false);
			resultPC->showColors(true);
		}
		else
		{
			m_app->dispToConsole(tr("Not enough memory: colors"), ccMainAppInterface::ERR_CONSOLE_MESSAGE);
			delete resultPC;
			return;
		}
	}
#pragma endregion

	//6 progress
	delete pDlg;
	pDlg = nullptr;


	//7 result refresh
	if (resultPC)
	{
		ent->setEnabled(false);
		m_app->dispToConsole(tr("[Point Cloud Shift] The previously selected entity has been hidden!"), ccMainAppInterface::STD_CONSOLE_MESSAGE);

		resultPC->setGlobalShift(pc->getGlobalShift());
		resultPC->setGlobalScale(pc->getGlobalScale());
		resultPC->setDisplay(ent->getDisplay());
		resultPC->prepareDisplayForRefresh();
		resultPC->refreshDisplay();

		m_app->addToDB(resultPC);
		m_app->setSelectedInDB(resultPC, true);
		m_app->refreshAll();
		m_app->zoomOnSelectedEntities();
	}
}

3、界面ShiftDlg.h

#ifndef SHIFT_DLG_H
#define SHIFT_DLG_H

#include <QWidget>
#include <QDialog>
#include "ui_ShiftDlg.h"

class ShiftDlg : public QDialog, public Ui::ShiftDlg
{
	Q_OBJECT

public:
	explicit ShiftDlg(QWidget * parent = 0);
};

#endif // SHIFT_DLG_H

4、界面ShiftDlg.cpp

#include "ShiftDlg.h"

ShiftDlg::ShiftDlg(QWidget *parent)
	: QDialog(parent,Qt::Tool)
	,Ui::ShiftDlg()
{
	setupUi(this);
	
	//OK-Cancel
	connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
	connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

累了就要打游戏

把我养胖,搞代码

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值