OSG中的DelaunayTriangulator三角化方法和结果转化为PCL的mesh形式

本文的目的是了解OSG::DelaunayTriangulator方法实现三角化的相关知识

最初的目的是想利用osg中的Delaunay三角化方法进行3维点云的网格重建,但是最终没能达到目的,本文知识记录了我的学习过程、相关的理论方法以及相关的知识,如果有误,希望可以联系我进行改正;

基础:使用该方法必须安装OpenSceneGraph库,可以直接安装或者源码编译安装,后者安装麻烦但是便于查看跟踪代码,由于笔者编译源码没有成功,所以笔者这里是直接安装,然后根据源码中的代码去仔细观察学习他的实现过程,理论知识见Delaunay三角化算法,首先了解一下OSG中的Delaunay三角化方法的过程:

ps:整个方法是基于三维点投影到xy所在二维平面进行三角化的,这也是没能达到最初的目的的原因,也可能还有其他原因,但是目前笔者还没有研究出来;

1、添加约束顶点(需要手动添加约束,否则这一步是不起作用的)

2、按照xy最小值最大值,增加四个扩充顶点,按照xyz的优先顺序将所有的点进行排序

3、由扩充点构成两个超级三角形

4、对于数据集中的每一个数据顶点,建立一个边集合

     对于每一个三角形

     如果该点x值减去对应外接圆圆心的x大于半径,则该三角形移除,加入discardTri(数据点是排好序的,后面的点不可能存在该三角形对应的外接圆内部);

     如果该点在该三角形的外接圆中,则移除该三角形,并将它的边加入到边集合中,对于重复的边进行标记(该边所在的两个三角形的外接圆都包含当前新加入的顶点);

5、如果有需要进行约束三角化,这个阶段有可能会增加新的顶点

6、删除四个扩充的顶点和相关的三角形,并将后面约束三角化中新增的顶点索引向前移动4个位置,输出顶点和三角形信息,然后三角化过程结束;

第二步,关于代码实现,调用该函数,并将三角化后的结果转换为PCL中的mesh类型,由于第一次使用OSG,很多数据结构不清楚,关于类型的转换踩了很多坑,所以记录一下

void swDelaunyTrangulate(pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud, pcl::PolygonMesh &mesh){
//void swDelaunyTrangulate(pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud, osg::Node* node){
	osg::ref_ptr<osg::Vec3Array> vertexArray = new osg::Vec3Array();
	for (int i = 0; i < cloud->points.size(); i++){
		pcl::PointXYZ p = cloud->points[i];
		vertexArray->push_back(osg::Vec3(p.x, p.y, p.z));
	}
	std::cout << "转换点的数组结束" << std::endl;
	time_t time1, time2;
	time(&time1);
	//pcl::PolygonMesh mesh;
	pcl::toPCLPointCloud2(*cloud, mesh.cloud);
	osg::ref_ptr<osgUtil::DelaunayTriangulator> dt = new osgUtil::DelaunayTriangulator();
	dt->setInputPointArray(vertexArray);
	dt->triangulate(); 
	std::cout << "三角化结束" << std::endl;
	time(&time2);
	std::cout << "OSG Triangulate time : " << time2 - time1 << "s" << std::endl;
	转化为osg中的node形式进行写出网格模型
	//osg::Geometry* geom = new osg::Geometry();
	//geom->setVertexArray(vertexArray);
	//geom->addPrimitiveSet(dt->getTriangles());
	//osg::Geode* geode = new osg::Geode();
	//geode->addDrawable(geom);
	//node = (osg::Node*)(geode);
 
	//osgDB::writeNodeFile(*node, "delaunay_chef_view1.obj");
 
 
	osg::DrawElementsUInt* deu = dt->getTriangles();
	osg::VectorGLuint ptVector = deu->asVector();
	std::cout << " deu->size()  " << deu->size() << "; ptVector.size()/3  "<<ptVector.size()/3<< std::endl;
	std::cout << "triangles  size : " << ptVector.size()/3 << std::endl;
	//将osg中的三角形格式转化为pcl中的mesh类型
	for (int i = 0; i < ptVector.size(); i=i+3){
		pcl::Vertices tri;
		tri.vertices.push_back(ptVector[i]);
		tri.vertices.push_back(ptVector[i+1]);
		tri.vertices.push_back(ptVector[i+2]);
		mesh.polygons.push_back(tri);
	}
	std::cout << "三角形网格转换结束" << std::endl;
 
	return;
}

由于OSG中的模型读写比较麻烦,所以这里转换为PCL中的mesh进行读写;

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值