求三角网的边界, 用以改进QEM算法简化破洞问题

目前大多三维化简算法对于GIS行业的倾斜模型, 非标准模型简化效果都不佳, (非闭和的三维体,俗称一张皮) 特别是三角网的边界上破洞太多, 瓦片与瓦片间有缝隙, 如下图:

本文编写了一种最简单的边界求解方法用以改进三维切片的简化破洞问题.

主要步骤如下:

首先确认判定什么是边界

再次要清除无效数据

最后标定所有顶点数据即可, 被标定的数据将在折边时候强行过滤掉, 将不会折边

示意图:(点0 是非边界的判断, 只需判断他相关的所有三角形对应的边个数是不是2, 0,1出现两次,0,2,两次0, 3两次

无效数据判定:

目前发现有以下无效数据,  三点重合的三角形, 2点重合的三角形,  对于这种直接不认为为边界,

求边界得主要代码如下:


	void cache_border_order(int vi,int vj, std::map<unsigned long long, int>& maps)
	{
		unsigned long long vii = vi;
		vii = vii << 32;
		unsigned long long key1 = vii + (vj);
		if (maps.find(key1) != maps.end())
		{
			maps[key1] = maps[key1] + 1;
		}
		else
		{
			maps[key1] = 1;
		}
	}
	bool is_border(int vi,const std::vector<int> &ti)
	{
		if (ti.size() <= 2)
			return true;
		std::map<unsigned long long, int> tcountmap = {};
		for (int i = 0; i < ti.size(); i++)
		{
			int a[2] = { 0,1 };
			int tii = 0;
			//无效三角形
			if (triangles[ti[i]].v[0] == triangles[ti[i]].v[1] ||
				triangles[ti[i]].v[0] == triangles[ti[i]].v[2] ||
				triangles[ti[i]].v[1] == triangles[ti[i]].v[2])
				continue;
			for (int j = 0; j < 3; j++)
			{
				if (vi == triangles[ti[i]].v[j])
				{
					tii = j;
					break;
				}				
			}
			if (tii == 2)
			{
				a[0] = 0;a[1] = 1;
			}
			else if (tii == 1)
			{
				a[0] = 0;a[1] = 2;
			}
			else if (tii == 0)
			{
				a[0] = 1;a[1] = 2;
			}
			cache_border_order(vi, triangles[ti[i]].v[a[0]], tcountmap);
			cache_border_order(vi, triangles[ti[i]].v[a[1]], tcountmap);
		}

		for (auto it = tcountmap.begin(); it != tcountmap.end(); it++)
		{
			if (it->second < 2)
				return true;
		}
		return false; 
	}

	void simplify_mark_border()
	{
		for (int i = 0; i < vertices.size(); i++)
		{
			std::vector<int> contaions_triangles = {};
			for (int j = 0; j < triangles.size(); j++)
			{
				//无效三角形
				if (triangles[i].v[0] == triangles[i].v[1] ||
					triangles[i].v[0] == triangles[i].v[2] ||
					triangles[i].v[1] == triangles[i].v[2])
					continue;
				if (triangles[j].v[0] == i || triangles[j].v[1] == i || triangles[j].v[2] == i)
				{
					contaions_triangles.push_back(j);
				}
			}
			if (is_border(i, contaions_triangles))
			{
				vertices[i].border = 1;
				vertices[i].cannotdel = true;
				//for (int j = 0; j < triangles.size(); j++)
				//{
				//	triangles[j].cannotdel = true;
				//}
			}
			else
			{
				vertices[i].border = 0;
				vertices[i].cannotdel = false;
			}
			//if (vertices[i].border != vertices[i].candel)
			//{
			//	printf("%d\n", i);
			//}
		}

最终效果:

 最终和cesuimlab对比了下, 虽然效果没它好, 但是胜在简化效率高一个数据量级别;

 完整代码下载链接: 三维简化的改进破洞问题-C++文档类资源-CSDN下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值