Firstly, I want to thank you for all the time and attention you've obviously put into this code.
On Tue, Mar 2, 2010 at 12:27 AM, Friedrich Romstedt <friedrichromstedt@gmail.com> wrote:
The loop I can replace by numpy operations:
>>> v_array
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
>>> n_array
array([[ 0.1, 0.2, 0.3],
[ 0.4, 0.5, 0.6]])
>>> f_list
array([[0, 1, 2, 0],
[2, 1, 0, 1]])
Retrieving the v1 vectors:
>>> v1s = v_array[f_list[:, 0]]
>>> v1s
array([[1, 2, 3],
[7, 8, 9]])
Retrieving the normal vectors:
>>> ns = n_array[f_list[:, 3]]
>>> ns
array([[ 0.1, 0.2, 0.3],
[ 0.4, 0.5, 0.6]])
Now how to calculate the pairwise dot product (I suppress the
difference of v1 to some_point for now):
>>> inner = numpy.inner(ns, v1s)
>>> inner
array([[ 1.4, 5. ],
[ 3.2, 12.2]])
This calculates *all* pairwise dot products, we have to select the
diagonal of this square ndarray:
>>> dotprods = inner[[numpy.arange(0, 2), numpy.arange(0, 2)]]
>>> dotprods
array([ 1.4, 12.2])
Now we can create a boolean array saying where the dotprod is > 0
(i.e, angle < 90°), and select those triangles:
>>> select = dotprods > 0
>>> select
array([ True, True], dtype=bool)
>>> selected = f_list[select]
>>> selected
array([[0, 1, 2, 0],
[2, 1, 0, 1]])
In this case it's the full list. Now build the triangles corners array:
>>> corners = v_array[selected[:, :3]]
>>> corners
array([[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]],
[[7, 8, 9],
[4, 5, 6],
[1, 2, 3]]])
>>>
This has indices [triangle, vertex number (0, 1, or 2), xyz].
And compute the edges (I think you can make use of them):
>>> edges_dist = numpy.asarray([corners[:, 1] - corners[:, 0], corners[:, 2] - corners[:, 0], corners[:, 2] - corners[:, 1]])
>>> edges_dist
array([[[ 3, 3, 3],
[-3, -3, -3]],
[[ 6, 6, 6],
[-6, -6, -6]],
[[ 3, 3, 3],
[-3, -3, -3]]])
This has indices [corner number, triangle, xyz].
I think it's easier to compare then "reversed" edges, because then
edge[i, j] == -edge[k, l]?
But of course:
>>> edges = numpy.asarray([[corners[:, 0], corners[:, 1]], [corners[:, 1], corners[:, 2]], [corners[:, 2], corners[:, 0]]])
>>> edges
array([[[[1, 2, 3],
[7, 8, 9]],
[[4, 5, 6],
[4, 5, 6]]],
[[[4, 5, 6],
[4, 5, 6]],[1, 2, 3]]],
[[7, 8, 9],
[[[7, 8, 9],
[1, 2, 3]],
[[1, 2, 3],
[7, 8, 9]]]])
This has indices [edge number (0, 1, or 2), corner number in edge (0
or 1), triangle].
But this may not be what you want (not flattened in triangle number).
Therefore:
>>> edges0 = numpy.asarray([corners[:, 0], corners[:, 1]])
>>> edges1 = numpy.asarray([corners[:, 1], corners[:, 2]])
>>> edges2 = numpy.asarray([corners[:, 2], corners[:, 0]])
>>> edges0
array([[[1, 2, 3],
[7, 8, 9]],
[[4, 5, 6],
[4, 5, 6]]])
>>> edges1
array([[[4, 5, 6],
[4, 5, 6]],[1, 2, 3]]])
[[7, 8, 9],
>>> edges2
array([[[7, 8, 9],
[1, 2, 3]],
[[1, 2, 3],
[7, 8, 9]]])
>>> edges = numpy.concatenate((edges0, edges1, edges2), axis = 0)
>>> edges
array([[[1, 2, 3],
[7, 8, 9]],
[[4, 5, 6],
[4, 5, 6]],
[[4, 5, 6],
[4, 5, 6]],[1, 2, 3]],
[[7, 8, 9],
[[1, 2, 3],
[[7, 8, 9],
[1, 2, 3]],
[7, 8, 9]]])
This should be as intended.
The indices are [flat edge number, edge side (left or right), xyz].
Now I guess you have to iterate over all pairs of them, don't know a
numpy accelerated method. Maybe it's even faster to draw the edges
twice than to invest O(N_edges ** 2) complexity for comparing?
It may seem a bit complicated, but I hope this impression is mainly
because of the many outputs ...
I double-checked everything, *hope* everything is correct.
So far from me,
Friedrich