2017-09-16 23 views
2

私は問題をよく包括的に説明する方法がわかりません。だから私はあなたの例を紹介します...四角形と三角形のメッシュを三角形だけで構成されたメッシュに変換します

は、私は、各クワッドまたは三角形のための頂点のインデックスを示す。この配列を持っている:

>>> 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 

しかし、結果の三角形が配列の最後にあることは望ましくありません。そして元のクワッドの前にイエス

+0

ので、出力は例えば、リストの可変数を持っているでしょう最初のelemには2つのリストがありますか? – Divakar

+0

または、それらをすべて列に入れて合計12行を与えることはできますか? @Divakar、noope。 – Divakar

+0

各要素には3つのアイテムがあります –

答えて

1

各行の1行シフトを2行として複製し、最後に三角形をマスクすることができます。実装はこのようになります -

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] 

サンプル実行 -

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]]) 

可能な改善

我々は一つとしてout0[:,0,1:]out0[:,1,1:]ための2つのステップの割り当てを置き換えるためにnp.lib.stride_tricks.as_stridedを導入することができますし、うまくいけばそれを改善するはずです -

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] 
+0

私は、私の例 'v_raw_to_tris'と' transform1'と 'transform2'の機能を使って非常に密なメッシュでベンチマークを行いました。結果は、「0.056070998899599545,0.05587086547734543,0.06008279023626528」であった。 'transform1'関数が勝者のようです。私は結果をテストします –

+0

あなたがベンチマークであることを涼しくします。私のソリューションはスピードの点で何をしていますか? – Chiel

+0

@ Mano-Wiiうん、それは本当に限界的な改善です。私はあなたがすでに元の方法で効率的なツールを使用していると考えています。 – Divakar

0

これはかなりコンパクトなコードで動作します。最初に、すべての四角形を三角形に分割し、その後、すでに三角形であった四角形からすべての二番目の要素を削除します。分割後の削除は、アルゴリズムを簡単に保ちます。

import numpy as np 

a = np.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]]) 

b = np.empty((a.shape[0], 2, 3)) 
b[:,0,:] = a[:,(0,1,2)] 
b[:,1,:] = a[:,(0,2,3)] 
b.shape = (-1, 3) 

idx_to_delete = 2*np.flatnonzero(a[:,-1] == 0)+1 
b = np.delete(b, idx_to_delete, axis=0) 

出力は次のようになります。

In [4]: print(b) 
    [[ 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.]] 
関連する問題