计算几何体顶点索引与顶点法线

16 篇文章 5 订阅
11 篇文章 3 订阅
  • 传入顶点,计算顶点索引
/*
*输入:vertexArray三角面片的顶点数组
*返回:顶点索引数组
*/
osg::DrawElementsUInt* CalcVertexIndexs(const osg::Vec3Array* vertexArray)
{
	//顶点去重
	osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array();//去重后的顶点
	{
		int nums = vertexArray->size();
		for (unsigned int i = 0; i < nums; i++)
		{
			osg::Vec3d vt = vertexArray->at(i);

			bool bFind = false;//是否存在
			osg::Vec3Array::iterator iter = vertices->begin();
			for (; iter != vertices->end(); ++iter)
			{
				osg::Vec3d _vt = *iter;
				if (_vt == vt)
				{
					bFind = true;
					break;
				}
			}

			if (!bFind)
			{
				vertices->push_back(vt);
			}
		}
	}
	int nums = vertices->size();

	//获取索引
	//osg::ref_ptr<osg::DrawElementsUInt> arrayIndexs = new osg::DrawElementsUInt(GL_TRIANGLE_STRIP);
	osg::ref_ptr<osg::DrawElementsUInt> arrayIndexs = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES);
	{
		int nums = vertexArray->size();
		for (unsigned int i = 0; i < nums; i += 3)
		{
			bool bFind0 = false;
			bool bFind1 = false;
			bool bFind2 = false;
			int index0 = 0;
			int index1 = 0;
			int index2 = 0;

			osg::Vec3d vt0 = vertexArray->at(i);
			osg::Vec3d vt1 = vertexArray->at(i + 1);
			osg::Vec3d vt2 = vertexArray->at(i + 2);

			//从去重后的顶点中获取索引
			osg::Vec3Array::iterator iter = vertices->begin();
			for (int index = 0; iter != vertices->end(); ++iter, ++index)
			{
				osg::Vec3d _vt = *iter;
				if (_vt == vt0)
				{
					bFind0 = true;
					index0 = index;//第1个顶点索引
				}
				else if (_vt == vt1) {
					bFind1 = true;
					index1 = index;//第2个顶点索引
				}
				else if (_vt == vt2) {
					bFind2 = true;
					index2 = index;//第3个顶点索引
				}

				if (bFind0 && bFind1 && bFind2)
				{
					arrayIndexs->push_back(index0);
					arrayIndexs->push_back(index1);
					arrayIndexs->push_back(index2);
					break;
				}
			}
		}
	}
	return arrayIndexs.release();
}
  • 传入顶点和顶点索引,计算顶点法线
struct VertexAttribute
{
	int index;	  //顶点索引
	int shareNums;//顶点共享次数
	osg::Vec3d normal;
	VertexAttribute()
	{
		index = -1;
		shareNums = 0;
		normal.set(0.0, 0.0, 0.0);
	}
};

/*
*输入1:vertexArray顶点数组(去重后的)
*输入2:indexArray顶点索引数组
*返回 :顶点法线数组
*/
osg::Vec3Array*  CalcNormals(const osg::Vec3Array* vertexArray, const osg::DrawElementsUInt* indexArray)
{
	osg::ref_ptr<osg::Vec3Array>normalArray = new osg::Vec3Array;

	std::map<int, VertexAttribute> vertexAttribMap;

	int indexNums = indexArray->size();
	for (unsigned int i = 0; i < indexNums; i += 3)
	{
		int index0 = indexArray->at(i);
		int index1 = indexArray->at(i + 1);
		int index2 = indexArray->at(i + 2);

		osg::Vec3d vertex0 = vertexArray->at(index0);//顶点0
		osg::Vec3d vertex1 = vertexArray->at(index1);//顶点1
		osg::Vec3d vertex2 = vertexArray->at(index2);//顶点2

		osg::Vec3d vector01(vertex1 - vertex0);
		osg::Vec3d vector02(vertex2 - vertex0);
		osg::Vec3d normal012 = vector01 ^ vector02;
		normal012.normalize();

		std::map<int, VertexAttribute>::iterator iter = vertexAttribMap.find(index0);
		if (iter == vertexAttribMap.end())
		{
			VertexAttribute vertexAttrib;
			vertexAttrib.index = index0;
			vertexAttrib.shareNums = 1;
			vertexAttrib.normal = normal012;
			vertexAttribMap[index0] = vertexAttrib;
		}
		else {
			VertexAttribute _vertexAttrib = iter->second;
			_vertexAttrib.shareNums += 1;
			_vertexAttrib.normal = (_vertexAttrib.normal + normal012) / _vertexAttrib.shareNums;
		}

		iter = vertexAttribMap.find(index1);
		if (iter == vertexAttribMap.end())
		{
			VertexAttribute vertexAttrib;
			vertexAttrib.index = index1;
			vertexAttrib.shareNums = 1;
			vertexAttrib.normal = normal012;
			vertexAttribMap[index1] = vertexAttrib;
		}
		else {
			VertexAttribute _vertexAttrib = iter->second;
			_vertexAttrib.shareNums += 1;
			_vertexAttrib.normal = (_vertexAttrib.normal + normal012) / _vertexAttrib.shareNums;
		}

		iter = vertexAttribMap.find(index2);
		if (iter == vertexAttribMap.end())
		{
			VertexAttribute vertexAttrib;
			vertexAttrib.index = index2;
			vertexAttrib.shareNums = 1;
			vertexAttrib.normal = normal012;
			vertexAttribMap[index2] = vertexAttrib;
		}
		else {
			VertexAttribute _vertexAttrib = iter->second;
			_vertexAttrib.shareNums += 1;
			_vertexAttrib.normal = (_vertexAttrib.normal + normal012) / _vertexAttrib.shareNums;
		}
	}

	int vertexNums = vertexArray->size();
	for (unsigned int i = 0; i < vertexNums; i ++)
	{
		int index = i;

		std::map<int, VertexAttribute>::iterator iter = vertexAttribMap.find(index);
		if (iter != vertexAttribMap.end())
		{
			normalArray->push_back(iter->second.normal);
		}
	}
	return normalArray.release();
}

OFF文件

OFF
	8	12	0
	 0.5	-0.5	-0.5 
	 0.5	 0.5	-0.5 
	-0.5	 0.5	-0.5 
	-0.5	-0.5	-0.5 
	 0.5	-0.5	 0.5 
	 0.5	 0.5	 0.5 
	-0.5	 0.5	 0.5 
	-0.5	-0.5	 0.5 
	3	0	1	3
	3	1	2	3
	3	4	6	5
	3	7	6	4
	3	0	3	4
	3	4	3	7
	3	1	5	2
	3	2	5	6
	3	0	4	1
	3	1	4	5
	3	2	6	3
	3	3	6	7

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小胖七少爷

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值