GOOGLE ADS

Donnerstag, 14. April 2022

Verwandeln Sie ein Netz aus Quads und Dreiecken in ein Netz, das nur aus Dreiecken besteht

Ich weiß nicht, wie ich mein Problem gut umfassend erklären soll. Deshalb zeige ich Ihnen ein Beispiel...

Ich habe dieses Array, das die Vertices-Indizes für jedes Quad oder Dreieck angibt:

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

Dreiecke sind die Elemente, die mit enden0

Ich möchte eine Transformation wie folgt vornehmen:

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

Wie kann ich diese Transformation also effizient gestalten?

Ich habe eine Funktion, die es anders löst. Platzieren Sie die von den Quads erhaltenen Dreiecke am Ende des Arrays.

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

Aber ich möchte nicht, dass die resultierenden Dreiecke am Ende des Arrays stehen. Und ja vor den originalen Quads


Lösung des Problems

Wir könnten jede Reihe mit dem einmaligen Verschieben für jede Reihe als zwei Reihen replizieren und die dreieckigen am Ende ausblenden. Die Implementierung würde in etwa so aussehen -

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]

Probelauf -

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

Mögliche Verbesserung

Wir können einführen np.lib.stride_tricks.as_strided, um die zweistufigen Zuweisungen für zu ersetzenout0[:,0,1:] und out0[:,1,1:]als eine zu ersetzen, und das sollte es hoffentlich verbessern, so -

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]

Keine Kommentare:

Kommentar veröffentlichen

Warum werden SCHED_FIFO-Threads derselben physischen CPU zugewiesen, obwohl CPUs im Leerlauf verfügbar sind?

Lösung des Problems Wenn ich das richtig verstehe, versuchen Sie, SCHED_FIFO mit aktiviertem Hyperthreading ("HT") zu verwenden, ...