简介:本文将详细介绍如何实现最基础的克隆功能并分析pcl源码
1. 源码
void MainWindow::doclone()
{
//选中对象检查,若选中为空返回
if (m_selectedEntities.size() == 0)
{
return;
}
//获取选中对象转为点云
ccPointCloud* m_cloud = ccHObjectCaster::ToPointCloud(m_selectedEntities[0]);
//创建一个新的点云
ccPointCloud* pc = new ccPointCloud(m_cloud->getName() + QString("-Clone"));
//为克隆对象分配内存
pc->reserve(m_selectedEntities.size());
size_t pointSize = m_cloud->size();
for (size_t i = 0; i < pointSize; ++i)
{
pc->addPoint(*m_cloud->getPoint(i));
}
//创建一个文件夹来放点云
ccHObject* CloudGroup = new ccHObject(QString("CloudGroup"));
CloudGroup->addChild(pc);
m_ccRoot->addElement(CloudGroup);
}
2. pcl库类详解
2.1 ccPointCloud类
ccPointCloud 是 CloudCompare 中表示点云的类。它包含了点云的所有数据,包括点的位置、颜色、法线等。
ccPointCloud 类包含许多成员变量,用于存储点云的不同属性:
点数据:
CCVector3* m_points: 存储点的坐标。
颜色数据:
RGBColor* m_rgbaColors: 存储点的颜色。
法线数据:
CCVector3* m_normals: 存储点的法线。
标量场数据:
std::vector<ccScalarField*> m_scalarFields: 存储多个标量场。
ccPointCloud 类提供了丰富的成员函数,用于操作和管理点云数据:
点操作:
addPoint(const CCVector3& P): 添加一个点。
resize(unsigned count): 调整点的数量。
getPoint(unsigned index) const: 获取指定索引的点。
颜色操作:
setPointColor(unsigned index, const ColorCompType* col): 设置指定索引点的颜色。
setRGBColor(const ColorCompType* col): 为所有点设置相同的颜色。
法线操作:
addNorm(const CCVector3& N): 添加一个法线。
setNormIndex(unsigned pointIndex, int normIndex): 为指定索引的点设置法线索引
2.2 ccHObjectCaster类
ccHObjectCaster 是 CloudCompare 的一个实用工具类,提供了一组静态方法,用于在不同的对象类型之间进行安全的类型转换。
它的作用是将通用的 ccHObject 指针(CloudCompare中的所有对象都继承自 ccHObject)转换为更具体的对象类型指针,如 ccPointCloud、ccMesh 等。
2.3 m_selectedEntities:
m_selectedEntities 是一个容器(通常是一个 std::vector 或类似的数据结构),包含了用户当前在 CloudCompare 中选择的对象,这些对象都是 ccHObject 类型的指针。例如,当用户在 CloudCompare 中选择了一些点云或其他对象时,这些对象会被存储在 m_selectedEntities 中。
3. 具体代码解析
ccPointCloud* m_cloud = ccHObjectCaster::ToPointCloud(m_selectedEntities[0]);
ccHObjectCaster::ToPointCloud(m_selectedEntities[0]):尝试将该 ccHObject 指针转换为 ccPointCloud 指针。这段代码的作用是从用户当前选择的对象中获取第一个对象,并尝试将其转换为点云对象。如果成功,m_cloud 将指向这个点云对象,否则为 nullptr。这样做的好处是可以确保后续对 m_cloud 的操作是基于 ccPointCloud 类型对象的,而不会因为类型错误而导致程序崩溃。
复制代码分析
pc->reserve(m_selectedEntities.size());
size_t pointSize = m_cloud->size();
for (size_t i = 0; i < pointSize; ++i)
{
pc->addPoint(*m_cloud->getPoint(i));
}
pc->reserve(m_selectedEntities.size());
预分配内存:为 pc 预分配内存,使其能够容纳 m_selectedEntities 中的点。这样做可以提高内存分配的效率。
size_t pointSize = m_cloud->size();
获取点的数量:pointSize 变量存储 m_cloud 中点的数量。
遍历点云:使用一个 for 循环,遍历 m_cloud 中的每个点。
添加点:在循环的每次迭代中,将 m_cloud 中的当前点添加到 pc 中。