Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multisort Python

I'm trying to write a custom exporter for Blender in Python. However, I'm having some trouble figuring out how I could use Python's native sort implementation to sort my vertices in the way I need.

Basically, I need to export the vertices in such a way where they can form a grid like this, assuming that V is a double.

V V V V V
V V V V V
V V V V V
V V V V V

The "engine" that I'm writing automatically retrieves the X and Z value of the coordinate based on where it is in the vertex map shown above. The V represents the Y coordinate. So this 5 by 5 map of vertices would create a 4 by 4 faced mesh.

However, in Blender, vertices appear to be ordered individually for each face of a mesh, rather in a format like mine. So, in order to export it, I need to order the coordinates first by depth (Y coordinate in Blender) and then by width (X coordinate in Blender). It would have to behave like a SQL query, where the first paramter given takes precedence in order compared to the second.

Here is what my code currently looks like

#!BPY

"""
Name: 'VaV Export'
Blender: 269
Group: 'Export'
Tooltip: 'Export to VaV file format'
"""
import Blender
import bpy

class Coordinate:
    def __init__(self, posX, posY):
        self.posX = posX
        self.posY = posY

    def sortX(self, other):
        if posX < other.posX:
            return 1

    def sortY(self, other):
        if posY < other.posY:
            return 1



def write(filename):
    out = open(filename, "w")
    terraindata = bpy.data.meshes["Terrain"]
    vertices = terraindata.vertices
    vertices = sorted(vertices, key = lambda x: x.co.y, reverse = True)
    vertices = sorted(vertices, key = lambda x: x.co.x, reverse = False)
    print(vertices)

Blender.Window.FileSelector(write, "Export")

The first call to sorted() successfully orders it according to depth (Y). However, The 2nd call to sorted messes up the order (as expected). How could I amend this to allow both sorts to occur without the 2nd messing up the first?

Thanks for your time in advance!

like image 319
dreadiscool Avatar asked Feb 26 '14 21:02

dreadiscool


People also ask

How do you sort two times in Python?

@moose, @Amyth, to reverse to only one attribute, you can sort twice: first by the secondary s = sorted(s, key = operator. itemgetter(2)) then by the primary s = sorted(s, key = operator. itemgetter(1), reverse=True) Not ideal, but works.

Can you sort by two keys Python?

How do you sort multiple keys in Python? Use a lambda function with a tuple to sort with two keys Call sorted(iterable, key: NoneType=None) with a collection as iterable . For key , create a lambda function that takes an element as a parameter and returns a 2-tuple of mapped to values.

How do you sort a list with two parameters in Python?

Use sorted() and a lambda expression to sort a list by two fields. Call sorted(a_list, key = k) with k as lambda x: x[i], x[j] to sort list by the i -th element and then by the j -th element.

How do you sort a list by different values in Python?

Use the Python List sort() method to sort a list in place. The sort() method sorts the string elements in alphabetical order and sorts the numeric elements from smallest to largest. Use the sort(reverse=True) to reverse the default sort order.


2 Answers

Change

vertices = sorted(vertices, key = lambda x: x.co.y, reverse = True)

to

vertices = sorted(vertices, key = lambda x: (x.co.y, x.co.x), reverse = True)

...and that should do it.

like image 71
a p Avatar answered Oct 19 '22 17:10

a p


If I understand correctly, you want to order your vertices by decreasing y coordinate, with coordinates with equal y values ordered by increasing x coordinate. If that's right, you can return a tuple (-x.co.y, x.co.x) from your key function to sorted and Python will do both the whole sorting at once.

An alternative would be to take a page from radix sort and sort by least-significant coordinate (e.g. x) first, then by the more significant coordinate (y). This will work since Python's sort is stable.

like image 43
Blckknght Avatar answered Oct 19 '22 19:10

Blckknght