Page 1 of 1

Err while using CloudSamplingTools::subsampleCloudRandomly()

Posted: Wed Feb 03, 2021 8:17 am
by CCNewbieL6
Hello everyone:
I want to subsample a cloud in my plugin.
When I execute these codes, it is ok:

Code: Select all

......
ccHObject *loadedObj = m_app->getSelectedEntities()[0]; // I opened a cloud "airplane_0001.txt" in CloudCompare
ccPointCloud* pc = static_cast<ccPointCloud*>(loadedObj);
ReferenceCloud* SubsampledEnt = CloudSamplingTools::subsampleCloudRandomly(pc, (unsigned int)1024); // OK
......
But when I execute this, the program crush:

Code: Select all

......
//Load Parameters:
        QString txtfile = "D:/HJ/test/airplane_0001.txt"; //file_path
	FileIOFilter::LoadParameters loadp;
	loadp.alwaysDisplayLoadDialog = false;
	loadp.shiftHandlingMode = ccGlobalShiftManager::NO_DIALOG_AUTO_SHIFT;
	loadp.autoComputeNormals = false;
	loadp.parentWidget = m_app->getMainWindow();
	loadp.sessionStart = true;
	CC_FILE_ERROR res;

ccHObject *loadedObj = FileIOFilter::LoadFromFile(txtfile, loadp, res, AsciiFilter::GetFileFilter());
ccPointCloud* pc = static_cast<ccPointCloud*>(loadedObj);
ReferenceCloud* SubsampledEnt = CloudSamplingTools::subsampleCloudRandomly(pc, (unsigned int)1024); //always crush here
......
airplane_0001.txt always exist.

This phenomenon means that the objects loaded by CloudCompare and by manual are different.

Re: Err while using CloudSamplingTools::subsampleCloudRandomly()

Posted: Wed Feb 03, 2021 5:20 pm
by WargodHernandez
You should check that pc is not null before using it. I'm betting it is null because *loadedObj should point to a ccHObject container which the actual point cloud is loaded into as a child

Re: Err while using CloudSamplingTools::subsampleCloudRandomly()

Posted: Thu Feb 04, 2021 3:37 am
by CCNewbieL6
Oh, yes. I have already added an "if-else" clause, like this:

Code: Select all

......
//Load Parameters:
        QString txtfile = "D:/HJ/test/airplane_0001.txt"; //file_path
	FileIOFilter::LoadParameters loadp;
	loadp.alwaysDisplayLoadDialog = false;
	loadp.shiftHandlingMode = ccGlobalShiftManager::NO_DIALOG_AUTO_SHIFT;
	loadp.autoComputeNormals = false;
	loadp.parentWidget = m_app->getMainWindow();
	loadp.sessionStart = true;
	CC_FILE_ERROR res;

ccHObject *loadedObj = FileIOFilter::LoadFromFile(txtfile, loadp, res, AsciiFilter::GetFileFilter());
if (res == CC_FERR_NO_ERROR && loadedObj){
			m_app->addToDB(loadedObj);  // ok here
			ccPointCloud* pc = static_cast<ccPointCloud*>(loadedObj); // maybe ok, because plugin will not crush here
			ccPointCloud* pcSubsampled = new ccPointCloud("pcSubsampled");//ok
			ReferenceCloud* SubsampledEnt = CloudSamplingTools::subsampleCloudRandomly(pc, (unsigned int)1024); //always crush here

......
		}
		else{
			ccLog::Error(QString("Failed to load file: %1, Error # = %2").arg(txtfile).arg(res));
		}
For the code readable, I deleted the "if" clause in last post. The err still here.
The loadedObj is not null, because it can be add to DB (m_app->addToDB(loadedObj);) and the cloud graph was shown in CloudCompare.

Re: Err while using CloudSamplingTools::subsampleCloudRandomly()

Posted: Thu Feb 04, 2021 3:39 am
by WargodHernandez
Loadedobj can't be cast to ccPointCloud, it is a hierarchy object not the cloud itself

Re: Err while using CloudSamplingTools::subsampleCloudRandomly()

Posted: Thu Feb 04, 2021 4:01 am
by CCNewbieL6
If err occured there, but why the first codes fragment in the first post runs correctly?
There I want to read a cloud file and subsample it.
So I have to cast ccHObject* to ccPointCloud*, then put it into the function subsampleCloudRandomly().
If this method to convert the pointer is wrong, which is the correct one?
Excuse me, I am new there. I do not know much about this field.

Re: Err while using CloudSamplingTools::subsampleCloudRandomly()

Posted: Thu Feb 04, 2021 4:24 am
by CCNewbieL6
I find it! You are right!
Just now, I add an "if" clause there:

Code: Select all

......
m_app->addToDB(loadedObj);
			//ccPointCloud* pc = static_cast<ccPointCloud*>(loadedObj);
			ccPointCloud* cloud = ccHObjectCaster::ToPointCloud(loadedObj);

			ccPointCloud* pcSubsampled = new ccPointCloud("pcSubsampled");

			// This "if" was activited:
			if (!cloud || cloud->size() == 0){ 
				ccLog::Warning("[ccSubsamplingDlg::getSampledCloud] Invalid input cloud!");
				return;
			}

			unsigned count = static_cast<unsigned>(1024);

			CCCoreLib::ReferenceCloud* SubsampledEnt = CCCoreLib::CloudSamplingTools::subsampleCloudRandomly(cloud, count);
......

ccHObjectCaster::ToPointCloud() cannot cast ccHObject to PointCloud here.
But static_cast<ccPointCloud*>(loadedObj) can. And it will not activite the "if" clause. Then the err occured again.

Re: Err while using CloudSamplingTools::subsampleCloudRandomly()

Posted: Thu Feb 04, 2021 5:26 am
by CCNewbieL6
I solved it:
To cast ccHObject* to ccPointCloud*, try this:

Code: Select all

......
ccHObject *loadedObj = FileIOFilter::LoadFromFile(txtfile, loadp, res, AsciiFilter::GetFileFilter());
ccHObject::Container clouds;
loadedObj->filterChildren(clouds, true, CC_TYPES::POINT_CLOUD);
ccPointCloud* cloud = static_cast<ccPointCloud*>(clouds[0]);
......