[CC]手动点云分割

CloudCompare中手动点云分割功能ccGraphicalSegmentationTool,

点击应用按钮后将现有的点云分成segmented和remaining两个点云,

//停用点云分割功能
void MainWindow::deactivateSegmentationMode(bool state)

是通过ccPointCloud的可视选择集来实现的。其中用到了点云的swap需要参考!

//创建新的点云,可视的选择集
ccGenericPointCloud* ccPointCloud::createNewCloudFromVisibilitySelection(bool removeSelectedPoints)
{
	if (!isVisibilityTableInstantiated())
	{
		ccLog::Error(QString("[Cloud %1] Visibility table not instantiated!").arg(getName()));
		return 0;
	}

	//we create a new cloud with the "visible" points
	ccPointCloud* result = 0;
	{
		//we create a temporary entity with the visible points only
		CCLib::ReferenceCloud* rc = getTheVisiblePoints();
		if (!rc)
		{
			//a warning message has already been issued by getTheVisiblePoints!
			//ccLog::Warning("[ccPointCloud::createNewCloudFromVisibilitySelection] An error occurred during points selection!");
			return 0;
		}
		assert(rc->size() != 0);

		//convert selection to cloud
		result = partialClone(rc);

		//don't need this one anymore
		delete rc;
		rc = 0;
	}

	if (!result)
	{
		ccLog::Warning("[ccPointCloud::createNewCloudFromVisibilitySelection] An error occurred during segmentation!");
		return 0;
	}

	result->setName(getName()+QString(".segmented"));//切割出来的点云

	//shall the visible points be erased from this cloud?
	if (removeSelectedPoints && !isLocked())
	{
		//we drop the octree before modifying this cloud's contents
		deleteOctree();
		clearLOD();

		unsigned count = size();

		//we have to take care of scan grids first
		{
			//we need a map between old and new indexes
			std::vector<int> newIndexMap(size(), -1);
			{
				unsigned newIndex = 0;
				for (unsigned i=0; i<count; ++i)
				{
					if (m_pointsVisibility->getValue(i) != POINT_VISIBLE)
						newIndexMap[i] = newIndex++;
				}
			}

			//then update the indexes
			UpdateGridIndexes(newIndexMap, m_grids);

			//and reset the invalid (empty) ones
			//(DGM: we don't erase them as they may still be useful?)
			for (size_t i=0; i<m_grids.size(); ++i)
			{
				Grid::Shared& scanGrid = m_grids[i];
				if (scanGrid->validCount == 0)
				{
					scanGrid->indexes.clear();
				}
			}
		}

		//we remove all visible points
		unsigned lastPoint = 0;
		for (unsigned i=0; i<count; ++i)
		{
			//i持续增长,而lastPoint遇到==POINT_VISIBLE则跳过,起到迁移的效果
			if (m_pointsVisibility->getValue(i) != POINT_VISIBLE)
			{
				if (i != lastPoint)
					swapPoints(lastPoint,i);
				++lastPoint;
			}
		}

		//TODO: handle associated meshes

		resize(lastPoint);
		
		refreshBB(); //calls notifyGeometryUpdate + releaseVBOs
	}

	return result;
}

  调用的方法getTheVisiblePoints()

CCLib::ReferenceCloud* ccGenericPointCloud::getTheVisiblePoints() const
{
	unsigned count = size();
	assert(count == m_pointsVisibility->currentSize());

	if (!m_pointsVisibility || m_pointsVisibility->currentSize() != count)
	{
		ccLog::Warning("[ccGenericPointCloud::getTheVisiblePoints] No visibility table instantiated!");
		return 0;
	}

	//count the number of points to copy
	unsigned pointCount = 0;
	{
		for (unsigned i=0; i<count; ++i)
			if (m_pointsVisibility->getValue(i) == POINT_VISIBLE)
				++pointCount;
	}

	if (pointCount == 0)
	{
		ccLog::Warning("[ccGenericPointCloud::getTheVisiblePoints] No point in selection");
		return 0;
	}

	//we create an entity with the 'visible' vertices only
	CCLib::ReferenceCloud* rc = new CCLib::ReferenceCloud(const_cast<ccGenericPointCloud*>(this));
	if (rc->reserve(pointCount))
	{
		for (unsigned i=0; i<count; ++i)
			if (m_pointsVisibility->getValue(i) == POINT_VISIBLE)
				rc->addPointIndex(i); //can't fail (see above)
	}
	else
	{
		delete rc;
		rc = 0;
		ccLog::Error("[ccGenericPointCloud::getTheVisiblePoints] Not enough memory!");
	}

	return rc;
}

  

原文地址:https://www.cnblogs.com/yhlx125/p/6050782.html