python - 将四边形和三角形的网格转换为仅由三角形组成的网格

标签 python arrays performance numpy

我不知道如何全面地解释我的问题。因此,我将向您展示一个示例...

我有这个数组指示每个四边形或三角形的顶点索引:

>>> faces
array([[0, 1, 2, 3],
       [4, 7, 6, 5],
       [0, 4, 1, 0],
       [1, 5, 6, 2],
       [2, 6, 7, 3],
       [4, 0, 3, 7],
       [1, 4, 5, 0]])

三角形是以0结尾的元素

我想做这样的转换:

>>> faces
array([[0, 1, 2, 3],  #->[[0, 1, 2], [0, 2, 3],
       [4, 7, 6, 5],  #-> [4, 7, 6], [4, 6, 5],
       [0, 4, 1, 0],  #-> [0, 4, 1],
       [1, 5, 6, 2],  #-> [1, 5, 6], [1, 6, 2],
       [2, 6, 7, 3],  #-> [2, 6, 7], [2, 7, 3],
       [4, 0, 3, 7],  #-> [4, 0, 3], [4, 3, 7],
       [1, 4, 5, 0]]) #-> [1, 4, 5]]

那么我怎样才能有效地进行这种转换呢?

我做了一个以不同方式解决它的函数。将四边形得到的三角形放在数组的末尾。

def v_raw_to_tris(tessfaces):
    len_tessfaces = len(tessfaces)
    quad_indices = tessfaces[:, 3].nonzero()[0]
    t3 = np.empty(((len_tessfaces + len(quad_indices)), 3), 'i4')

    t3[:len_tessfaces] = tessfaces[:, :3]
    t3[len_tessfaces:] = tessfaces[quad_indices][:, (0, 2, 3)]

    return t3

但我不希望生成的三角形位于数组的末尾。是的,在原来的四边形前面

最佳答案

我们可以将每一行的一次性移位复制为两行,并在最后屏蔽掉三角形的行。实现看起来像这样 -

def transform1(a):
    idx = np.flatnonzero(a[:,-1] == 0)
    out0 = np.empty((a.shape[0],2,3),dtype=a.dtype)      

    out0[:,0,1:] = a[:,1:-1]
    out0[:,1,1:] = a[:,2:]

    out0[...,0] = a[:,0,None]

    out0.shape = (-1,3)

    mask = np.ones(out0.shape[0],dtype=bool)
    mask[idx*2+1] = 0
    return out0[mask]

sample 运行-

In [94]: a
Out[94]: 
array([[0, 1, 2, 3],
       [4, 7, 6, 5],
       [0, 4, 1, 0],
       [1, 5, 6, 2],
       [2, 6, 7, 3],
       [4, 0, 3, 7],
       [1, 4, 5, 0]])

In [95]: transform1(a)
Out[95]: 
array([[0, 1, 2],
       [0, 2, 3],
       [4, 7, 6],
       [4, 6, 5],
       [0, 4, 1],
       [1, 5, 6],
       [1, 6, 2],
       [2, 6, 7],
       [2, 7, 3],
       [4, 0, 3],
       [4, 3, 7],
       [1, 4, 5]])

可能的改进

我们可以介绍np.lib.stride_tricks.as_stridedout0[:,0,1:]out0[:,1,1:] 的两步赋值替换为一个,希望能改进它,比如所以-

from numpy.lib.stride_tricks import as_strided
def strided_axis1(a, L):
    s0,s1 = a.strides
    m,n = a.shape
    nL = n-L+1
    return as_strided(a, (m,nL,L),(s0,s1,s1))

def transform2(a):
    idx = np.flatnonzero(a[:,-1] == 0)
    out0 = np.empty((a.shape[0],2,3),dtype=a.dtype)    
    out0[...,1:] = strided_axis1(a[:,1:], 2)    
    out0[...,0] = a[:,0,None]
    out0.shape = (-1,3)
    mask = np.ones(out0.shape[0],dtype=bool)
    mask[idx*2+1] = 0
    return out0[mask]

关于python - 将四边形和三角形的网格转换为仅由三角形组成的网格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46255402/

相关文章:

python - Heroku 上的 Flask 存在 MailGun 配置问题

java - 片段说明字节数组到端口号

Java 遍历一维数组和二维数组

java - 基本的面向对象编程

html - 选定的链接需要突出显示

Android 性能 XML Drawable vs CSS3 vs Images

c++ - 找到其他节点的最快方法

python - 拆分 pandas 中的地址列

python - 在 Python 中导入 C++ dll 失败

python - 你如何为 numpy 和 Pandas 修复 "runtimeError: package fails to pass a sanity check"?