模型体素化

背景:

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

目前的模型体素化的方式基本分为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];
							}

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

相关推荐
大白同学4211 小时前
【C++】C++11介绍(Ⅱ)
开发语言·c++
油炸自行车1 小时前
【Qt】编写Qt自定义Ui控件步骤
开发语言·c++·qt·ui·自定义ui控件·qt4 自定义ui控件
呱呱巨基3 小时前
C/C++ 内存管理
c++·笔记·学习
半桔3 小时前
【网络编程】TCP 服务器并发编程:多进程、线程池与守护进程实践
linux·服务器·网络·c++·tcp/ip
橘子134 小时前
C++实战:搜索引擎项目(二)
开发语言·c++·搜索引擎
应用市场4 小时前
Qt C++ 图形绘制完全指南:从基础到进阶实战
开发语言·c++·qt
青草地溪水旁4 小时前
设计模式(C++)详解—单例模式(2)
c++·单例模式
bkspiderx5 小时前
C++时区操作全版本指南(含C++03/C++11-17/C++20)
linux·开发语言·c++·c++20·时区
序属秋秋秋5 小时前
《C++进阶之STL》【哈希表】
数据结构·c++·stl·哈希算法·散列表·哈希表·哈希
青草地溪水旁6 小时前
设计模式(C++)详解——建造者模式(1)
c++·设计模式·建造者模式