模型体素化

背景:

在三维模型深度处理的时候,有时候需要对模型进行区域划分.并赋予一定的材质,力学等属性,所以,需要对模型进行划分.

目前的模型体素化的方式基本分为cpu,gpu,都是投影射线法进行的, 在调研了一些已知的开源算法和项目,并测试后发现,大部分的开源项目也都是基于抽壳进行的计算,并不满足自己项目(岩土,GIS)等方面的要求,所以这里自己按照已有的理论,进行了修改,从而做了一个空间内部填充的全体素化,而且后续也方便进行不规则体素的操作.里面使用了bsvtree进行加速处理.

结果:

改两个参数:的效果.

计算时间加长了一点,不过很多细节保留了下来

换个模型试一下:

实现过程以及关键代码:

计算流程:

1.实现流程,求解模型的OBB盒子,按照其最大面积那个面,按照sizeX,sizeY进行拆分.

2.计算一系列等距射线,构建bsvTree进行模型结构化,进行快速求交,

3.获取交点后,处理交点为1和>1的多种情况,按照射线法向,进行距离迭代插值判定,依据奇偶规则进行区分内外盒子.到此,模型内外以及壳表面区分完成,进行体素绘制;

关键代码:

cpp 复制代码
	mDimStartZ = 0;
							int GetInterCheckFirst = 0;//我们获取当前的.
							double threoldValue = gridSizePerDim[2] / 2.0;//阈值.
			
							/// <summary>
							/// 获取尺寸数据.
							/// </summary>
						
							SigleT defalutData;
							defalutData.zL = 0;
							defalutData.isStatus = false;
							auto GetInterData = [&](int index)-> decltype(&interSectListL[0]) {
								if (index < interSectListL.size())
								{
									return &interSectListL[index];
								}
								else
								{
									return nullptr;
								}
							};

							SigleT*firstCheckData = nullptr;//获取第一个值.
							SigleT*secondChckData = nullptr;

							//全部体素,第三个循环
							bool isOpenAddStatus = false;
							while (mDimStartZ < ZLength)
							{
								firstCheckData = GetInterData(GetInterCheckFirst);
								if (firstCheckData == nullptr)
								{
									mDimStartZ += gridSizePerDim[2];
									continue;
								}

								CurP[0] = FaceStartPoint[0] + mDimStartX;
								CurP[1] = FaceStartPoint[1] + mDimStartY;
								CurP[2] = FaceStartPoint[2] + mDimStartZ;
								if (intersecCount == 1)
								{
									CurP[2] = FaceStartPoint[2]+ firstCheckData->zL;
									AddVoxelDatas(CurP.GetData());//创建.
									break;
								}
								else
								{
									secondChckData = GetInterData(GetInterCheckFirst + 1);
									if (secondChckData == nullptr)
									{
										mDimStartZ += gridSizePerDim[2];
										continue;
									}

									double firstDiffer = mDimStartZ - firstCheckData->zL;//取负数
									double secondDiffer = mDimStartZ - secondChckData->zL;
									double absValue = std::abs(firstDiffer);

									if (absValue < threoldValue)//横切边界.
									{
										AddVoxelDatas(CurP.GetData());
										isOpenAddStatus = true;//激活.
									}
									else //填充.
									{
										if (isOpenAddStatus == true)
										{
											AddVoxelDatas(CurP.GetData());
										}
									}
									if (secondDiffer > 0)//奇偶变换.
									{
										GetInterCheckFirst++;
										isOpenAddStatus = false;//每次变换,关闭,直到下一次循环激活为止.
									}

								}

								mDimStartZ += gridSizePerDim[2];
							}

到此,任意模型体素化代码完成.

相关推荐
Ajiang28247353041 小时前
对于C++中stack和queue的认识以及priority_queue的模拟实现
开发语言·c++
‘’林花谢了春红‘’6 小时前
C++ list (链表)容器
c++·链表·list
机器视觉知识推荐、就业指导8 小时前
C++设计模式:建造者模式(Builder) 房屋建造案例
c++
Yang.9910 小时前
基于Windows系统用C++做一个点名工具
c++·windows·sql·visual studio code·sqlite3
熬夜学编程的小王10 小时前
【初阶数据结构篇】双向链表的实现(赋源码)
数据结构·c++·链表·双向链表
zz40_10 小时前
C++自己写类 和 运算符重载函数
c++
六月的翅膀10 小时前
C++:实例访问静态成员函数和类访问静态成员函数有什么区别
开发语言·c++
liujjjiyun10 小时前
小R的随机播放顺序
数据结构·c++·算法
¥ 多多¥11 小时前
c++中mystring运算符重载
开发语言·c++·算法