问题描述
我目前正在基于稀疏八叉树进行STL体素化。 我有一个文件,其中每个三角形大约有100,000个三角形,格式为[[[Point1 x-coordinate,Point1y,Point1z],[P2x,P2y,P2z],[P3x,P3y,P3z]]。
我为船体的体素化提供了一个可行的解决方案,但是它非常慢(在我的计算机上为10秒)。 大约需要1秒。 (使用八级深八叉树进行总固体体素化大约需要2秒钟)
现在,我正在解析每个三角形的八叉树。 对于相交检查,我需要计算100,000个三角形中每个三角形的定向边界框。在解析每个三角形的八叉树之前。
仅计算所有100,000个三角形的边界框已花费约0.800秒。那很长。 我正在PyCharm中使用“标准” Python 3。如果我没记错的话,我认为它是CPython。
for triangle in triangle_list:
'this variables represent the x,y,z value of all three vertices of the triangle'
'in tests this method was found to be superior to the 2D array way '
P1x = triangle[0][0]
P1y = triangle[0][1]
P1z = triangle[0][2]
P2x = triangle[1][0]
P2y = triangle[1][1]
P2z = triangle[1][2]
P3x = triangle[2][0]
P3y = triangle[2][1]
P3z = triangle[2][2]
'the bounding box for the triangle is determined'
'i used python integrated min max methods to find the smalles x,z value for all of the three vertices'
bbtrxmin = min(P1x,P2x,P3x)
bbtrxmax = max(P1x,P3x)
bbtrymin = min(P1y,P2y,P3y)
bbtrymax = max(P1y,P3y)
bbtrzmin = min(P1z,P2z,P3z)
bbtrzmax = max(P1z,P3z)
因为我是编程的新手,所以我不知道可以进行哪些更改以加快处理速度。我已经在寻找另一种算法,但是并没有太大改变。
我尝试过的事情:
替代A:
P1t=triangle[0]
P2t=triangle[1]
P3t=triangle[2]
bbtrxmin = min(P1t[0],P2t[0],P3t[0])
bbtrxmax = max(P1t[0],P3t[0])
bbtrymin = min(P1t[1],P2t[1],P3t[1])
bbtrymax = max(P1t[1],P3t[1])
bbtrzmin = min(P1t[2],P2t[2],P3t[2])
bbtrzmax = max(P1t[2],P3t[2])
替代B:
def maX(a,b):
if a > b:
return a
else:
return b
def miN(a,b):
if a < b:
return a
else:
return b
P1t=triangle[0]
P2t=triangle[1]
P3t=triangle[2]
bbtrxmin = miN(P1t[0],miN(P2t[0],P3t[0]))
bbtrxmax = maX(P1t[0],maX(P2t[0],P3t[0]))
bbtrymin = miN(P1t[1],miN(P2t[1],P3t[1]))
bbtrymax = maX(P1t[1],maX(P2t[1],P3t[1]))
bbtrzmin = miN(P1t[2],miN(P2t[2],P3t[2]))
bbtrzmax = maX(P1t[2],maX(P2t[2],P3t[2]))
替代方案A稍慢一些,但没有显着差异。 备选方案B约为1秒(不包括功能定义)。 此操作的最大目标不应超过0.100秒。
您是否知道如何加快针对100,000个三角形的简单3D定向边界框的计算?我必须使用Python,但可以更改编译器。
您对如何加快整个STL / Octree体素化过程有何建议?也许我什至不需要检查所有三角形?我读了很多论文,其中大多数都检查了每个三角形,但是如果您有什么好主意,我可以接受。
非常感谢您。
编辑17.09.2020:
我现在正在使用PyPy,因为我希望JIT Comiler可以大大提高速度。 我做了一些测试,结果很好。 一切都以更快的速度运行,但是瓶颈仍然是以下代码:
bbtrxmax = max(P1x,P3x)
bbtrymin = min(P1y,P3y)
bbtrymax = max(P1y,P3y)
bbtrzmin = min(P1z,P3z)
bbtrzmax = max(P1z,P3z)
确定边界框。其余代码(大约300行带有不同变量的代码在300毫秒内运行,并且该位在100,000次重复中耗时4秒。
有什么新建议吗?
解决方法
我不是100%肯定我了解您要尝试做的事情:每个三角形需要一个边界框还是所有三角形都需要一个整体边界框?似乎像第一个,但只是检查。
几种解决此问题的方法:
- 尝试使用NumPy数组,因为min()和.max()操作可以在整个数组切片上工作(一维矢量,二维数组等)
- 当需要原始速度时,Numba,Cython和f2py可能是不错的选择:对于Cython,您可能需要混合使用Python和C(或直接在C中编写循环)。 F2py包装了fortran模块,在您的情况下,看起来很容易编写代码。