模型体素化

背景:

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

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

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

相关推荐
煤泥做不到的!42 分钟前
挑战一个月基本掌握C++(第十一天)进阶文件,异常处理,动态内存
开发语言·c++
F-2H44 分钟前
C语言:指针4(常量指针和指针常量及动态内存分配)
java·linux·c语言·开发语言·前端·c++
axxy20001 小时前
leetcode之hot100---24两两交换链表中的节点(C++)
c++·leetcode·链表
若亦_Royi2 小时前
C++ 的大括号的用法合集
开发语言·c++
ragnwang6 小时前
C++ Eigen常见的高级用法 [学习笔记]
c++·笔记·学习
lqqjuly9 小时前
特殊的“Undefined Reference xxx“编译错误
c语言·c++
冰红茶兑滴水9 小时前
云备份项目--工具类编写
linux·c++
刘好念9 小时前
[OpenGL]使用 Compute Shader 实现矩阵点乘
c++·计算机图形学·opengl·glsl
酒鬼猿10 小时前
C++进阶(二)--面向对象--继承
java·开发语言·c++
姚先生9710 小时前
LeetCode 209. 长度最小的子数组 (C++实现)
c++·算法·leetcode