Is it possible to reorder the vertices of a mesh in Animation Nodes? For instance, based on their x location or distance from some object.
-
$\begingroup$ Do you mean the indices of the vertices? Do you want to change their order? If that is what you want, then yes, but what do you want the new order to be based on? $\endgroup$– Omar EmaraCommented Apr 1, 2018 at 16:31
-
$\begingroup$ On, some object location! Or X axis. $\endgroup$– Sergey GolubevCommented Apr 1, 2018 at 18:45
1 Answer
Yes we can, matter of fact, we have a node called Sort List just for that. For instance, If I were to sort the vertices based on their x locations, I would do:
e.x
means we want to sort based on the x location of the element. Now, if I wanted to sort it based on the distance between it and some other vector, the distance can be used as a Key List:
For more info on how to use the Sort List Node, see the documentation.
But wait! It is not that simple. After reordering the vertices, the edge and polygon indices will now be pointing to wrong vertices. So we have to correct them such that they point to the new indices of vertices. To do that, we have to know at which index did each of the vertices landed in the new list, in other words, we want a list that tells us the new indices of the vertices. The sort list only returns the the sorted list, so we will have to use some other method. The best method I know would be to use numpy.argsort
which returns the new indices of the list elements instead of the list elements themselves. So, in an expression node, I will write:
numpy.argsort(list.asMemoryView())
Where list
is the required list to be sorted and it should be numeric type, not an object. Make sure to import numpy in the advanced node settings by replacing math
with numpy
. Now that we have the indices list, we can get the sorted list by getting the elements at those indices:
Now that we have computed the the sorted vertices list. We can go ahead and compute the new edge and polygon indices lists. We are going to compute them by looking at their indices and seeing what is the indices of those indices in the computed indices list, in other words, we are going to search for each of the indices and use their index to create new edge and polygon indices. However, instead of using the search node which is expensive, we are going to create an inverse look up table which is easily done as follows:
Where the iterator is the indices list and the parameter is an integer list of the same length, possibly the indices list itself. Next, we are going to loop over edges and polygon, get the indices from the new indices list at their indices and create edge and polygon indices from those new indices:
And then we compute the new edges and polygon and output them:
And you can see that they became sorted from left to right, that is, from the lowest x value to the highest:
Similarly, I can sort based on the distance from the origin as follows:
Which produces:
-
$\begingroup$ Hello Omar, I just tried this and didn't get the same result. Would you mind taking a look to see where I'm going wrong? https://imgur.com/a/AUyLk (P.s. the Polygon indices is deliberately disconnected to make the mesh easier to see) $\endgroup$ Commented Apr 13, 2018 at 9:43
-
$\begingroup$ @DavidGilson The Inverse Look Up Table is what is wrong here. Notice that the last node is not a generator, it is a Reassign Parameter node. The output of the node is actually the input New Vertices which we specified in the advanced node settings (Where we added the the reassign node as well). I recommend you visit the Loops documentation to learn more about this before continuing. $\endgroup$ Commented Apr 13, 2018 at 17:36