【问题标题】:Speed up Voxelization / Intersection Tests加快体素化/相交测试
【发布时间】:2021-01-03 02:02:49
【问题描述】:

我目前正在研究基于稀疏八叉树的 STL 体素化。 我有一个包含大约 100,000 个三角形的文件,格式为--- [ [ Point1 x-coordinate , Point1y , Point1z ] , [P2x , P2y , P2z] , [P3x , P3y , P3z] ] 每个三角形。

我有一个用于船体体素化的工作解决方案,但它非常慢(在我的计算机上需要 10 秒)。 它需要大约 1 秒。 (8 级深八叉树的总实体体素化大约需要 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,y,z value for all of the three vertices'


    bbtrxmin = min(P1x, P2x, P3x)
    bbtrxmax = max(P1x, P2x, P3x)
    bbtrymin = min(P1y, P2y, P3y)
    bbtrymax = max(P1y, P2y, P3y)
    bbtrzmin = min(P1z, P2z, P3z)
    bbtrzmax = max(P1z, P2z, P3z)

因为我对编程完全陌生,所以我不知道我可以改变什么来加快这个过程。我已经搜索了另一种算法,但没有太大变化。

我尝试过的事情:

备选方案 A:

P1t=triangle[0]
P2t=triangle[1]
P3t=triangle[2]

bbtrxmin = min(P1t[0], P2t[0], P3t[0])
bbtrxmax = max(P1t[0], P2t[0], P3t[0])
bbtrymin = min(P1t[1], P2t[1], P3t[1])
bbtrymax = max(P1t[1], P2t[1], P3t[1])
bbtrzmin = min(P1t[2], P2t[2], P3t[2])
bbtrzmax = max(P1t[2], P2t[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 Voxelization 过程有什么建议吗?也许我什至不需要检查所有三角形?我已经阅读了很多论文,其中大多数都检查了每个三角形,但是如果您对此有任何好主意,我愿意接受。

非常感谢您。

编辑 17.09.2020:

我现在使用 PyPy 是因为我希望 JIT Comiler 可以显着提高速度。 我做了一些测试,结果很好。 一切都运行得更快,但瓶颈仍然是以下代码:

bbtrxmax = max(P1x, P2x, P3x)
bbtrymin = min(P1y, P2y, P3y)
bbtrymax = max(P1y, P2y, P3y)
bbtrzmin = min(P1z, P2z, P3z)
bbtrzmax = max(P1z, P2z, P3z)

确定边界框。其余代码(大约 100 行不同变量的代码在 300 毫秒内运行,100,000 次重复需要 4 秒以上。

有什么新建议吗?

【问题讨论】:

    标签: python optimization bounding-box triangulation voxel


    【解决方案1】:

    我不是 100% 确定我理解您想要做什么:您需要每个三角形一个边界框还是所有三角形的整体边界框?似乎是第一个但只是检查。

    解决此问题的几种可能方法:

    • 尝试使用 NumPy 数组,因为 min() 和 .max() 操作可以作用于整个数组切片(一维向量、二维数组等...)
    • 当需要原始速度时,Numba、Cython 和 f2py 可能是不错的选择:对于 Cython,您可能希望混合使用 Python 和 C(或直接用 C 编写循环)。 F2py 包装了 fortran 模块,看起来在您的情况下编写代码非常容易。

    【讨论】:

    • 对不起,我不够具体。我需要每个三角形一个边界框,通过体素八叉树检查边界框和体素是否相交。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-31
    • 2011-01-04
    • 1970-01-01
    • 2011-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多