Order of vertices in a mesh


I have built some kind of random shape generator which in realtime alters the shape of a cube with 60 vertices.
However I’ve noticed that the vertices aren’t in any specific order (or are they?) so that getting them is a real pain in the *ss.

The order for the top row for example is:

top_left = [23, 40, 48]
top_middle = [20, 37]
top_right = [24, 36, 43]

But it would make sense if they’d be ordered from 0 to 8…?

Do I miss something or what is the system of blender applying order to the vertices of a given shape?

You might try selecting all verticies in your mesh in Edit Mode, hit spacebar, and search for ‘Sort Mesh Elements’. There are several sub-options there so you might have to play around. I don’t know if that will make a difference, but it does seem to deal with re-ordering the verts/faces. I’ve had to use this a couple times when dealing with transparent objects (where you have one mesh sitting inside another, in the same object).

There is no order within the faces. The engine does not care and how should such an order look like?

There is an order within the vertices of a face. It determines the direction the face is oriented too (face normal).

If you want to “create” your own shape, you can pick any face and work with that. Just make sure you remember which one was processed already.

Thanks that already helps!
@Monster: what do you mean by picking a face? I thought I can only pick vertices to alter a shape in bge? Or how would that look like?

It’s not possible to reliably get the verticies in order, but you can build a dictionary of them and then order that.

import bge
import mathutils
controller = bge.logic.getCurrentController()
own= controller.owner
meshList = own.meshes
mesh = meshList[0]
matID = 0
length = mesh.getVertexArrayLength(matID)
own['verts'] = {}

for v in range(length):
    vert = mesh.getVertex( matID, v)
    xyz_pos = vert.getXYZ().to_tuple(2)
    if xyz_pos not in verts:
        own['verts'][xyz_pos] = [vert]

That will give you a dictionary of verts which you can get by their position.
You can then sort the dictionary keys, using sorted().

keys = [key for key in own['verts']]
x_sorted_verts = sorted(keys, key=lambda vert_key: vert_key[0])
far_left_vert = own['verts'][x_sorted_verts[0]]

You can do other things with them by comparing their values too. Like if you want to get all the verts which are below 0.0 on the z axis you could do this:

subzero_verts = [key for key in own['verts'] if key[2] < 0.0]

for s_z_key in subzero_verts:
    vert_list = own['verts'][s_z_key]
    for vert in vert_list:
        vert.color = [0.0,0.0,1.0]

.to_tuple(2) will make a vector in to a tuple, which can be used as a dictionary key. The (2) means it is rounded to 2 decimal points. so 3.14743536356 becomes 3.14, which should be enough to stop verts being all clumped together under one entry. Some verts of course will share the same location as others, so you have to deal with them at the same time, as I did above by doing for vert in vert_list:

Also note that there are sometimes still problems with getting verts from a mesh which has both triangles and quads. Convert your mesh to all triangles or all quads before playing to avoid errors.

This is great…!
@smoking_mirror please check PN :slight_smile: