Home Technical Talk

Blender Python (2.79): Index Vertices Based on Their Bone?

polycounter lvl 6
Offline / Send Message
MrQuetch polycounter lvl 6
Hello, everyone.

I'm writing a Blender Python script for exporting custom models to an old video game engine's model format. This is something that I've been struggling with for awhile now. So, I have a test model that has been rigged. However, I need to change the vertex indices. Unfortunately, Blender has no option for me to change the vertex indices in the way that I desire. I can only sort vertices on the Z or X axis, by material, etc,. What I need to do is traverse through every bone - from the very first bone (the root bone). And, along the way, change the vertex indices based on what bone they are connected to.



Here's an example of what I have in Blender. The vertices here are not indexed in the proper order. But, this is essentially what I want. In this case, the first bone looks like it contains 4 vertices. But, it actually has 5. There is a vertex exactly where the root of the bone is - by using the snapping tool. Basically, each vertex rotates from its root vertex - the ones circled in green. To further add to my example, bone 2 would contain 13 vertices. It's 13 because it's including the root vertex. Otherwise, you could see that it has 12.

Overall, bone 1 should have vertex indices: 0, 1, 2, 3, and 4. And, bone 2 should have vertex indices: 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, and 17. Bones 3 and 4 should have 5 vertices, just like bone 1. In other words, each bone should not redefine the same vertex indices from another bone. I hope I'm making sense. I'm still getting familiar with Python, and I just can't wrap my head around this concept - despite having looked at several other sources.

Any help is greatly appreciated.

Replies

  • RN
    Offline / Send Message
    RN sublime tool
    The cool thing is you don't need to actually reorder the mesh vertices, you only need to output the vertices as if they were ordered. You can "lie" whenever you need to write the index of a vertex, it can be whatever you want.
    - Traverse the PoseBone chain from the root bone to the leaf bone(s).
    - Use an incremental counter variable to give a unique incremental index for every vertex that you come across (vertices with weights on the current bone that you're looking into).
  • MrQuetch
    Offline / Send Message
    MrQuetch polycounter lvl 6
    RN said:
    The cool thing is you don't need to actually reorder the mesh vertices, you only need to output the vertices as if they were ordered. You can "lie" whenever you need to write the index of a vertex, it can be whatever you want.
    - Traverse the PoseBone chain from the root bone to the leaf bone(s).
    - Use an incremental counter variable to give a unique incremental index for every vertex that you come across (vertices with weights on the current bone that you're looking into).
    Hi again, RN.

    Thank you so much for getting back to me on short notice. That part about, "lying" a vertex's index seems much easier to me than using its actual index - I just need to make sure I get the right ones. I hope this isn't too much to ask for... But, how may I go about doing that? I can't seem to find a set way of doing it. Recently, I read somewhere that there are three different types of bones in Blender... There are pose bones, edit bones, and something else... Which one would be best to reference? Does it really matter? If it means anything, in this particular game engine, all vertices that are attached to a bone always have a weight of 1. So, I guess I can just check if its weight is greater than 0? I hope I'm still making sense.
  • rollin
    Offline / Send Message
    rollin polycounter
    What game is this for?
    And does this mean you can't - per definition - assign one vert to multiple bones?

    Anyway: if you write an exporter you can give each vertex your own indices. You just have to handle / order them that way before writing to the output
  • RN
    Offline / Send Message
    RN sublime tool
    MrQuetch said:
    There are pose bones, edit bones, and something else... Which one would be best to reference?
    Each of those collections gives access to bone types that have slightly different attributes, pose bones and edit bones being the most useful (the third seems to be Object-mode bones). You can only access armature.data.edit_bones in Edit mode.

    You should really try to come up with these algorithms yourself, it's the only way to improve. To do what you want you need to know how to use dictionaries, lists (preferably a collections.deque object) and loops
  • MrQuetch
    Offline / Send Message
    MrQuetch polycounter lvl 6
    rollin said:
    What game is this for?
    And does this mean you can't - per definition - assign one vert to multiple bones?

    Anyway: if you write an exporter you can give each vertex your own indices. You just have to handle / order them that way before writing to the output
    Hey, rolin.

    This is for Little Big Adventure 2 / Twinsen's Odyssey (1997). Actually, each bone has a root vertex, and multiple vertices can be offset from that one. I thought my explaining might be difficult to get across - I apologize for that. The models are entirely written in hexadecimal notation. If it helps understanding, this is the small technical document I've been using: http://lbafileinfo.kazekr.net/index.php?title=LBA2:3D_model

    It hasn't been update in awhile, but where it lists the bone data - there are two missing entries. The 3rd entry is the amount of vertices that are in that bone - including its own root vertex (from the bone origin - not the world origin), and the 4th entry is just padding - to keep the files byte-aligned.

    RN mentioned the way I could write vertex data, so that will definitely be useful.
  • MrQuetch
    Offline / Send Message
    MrQuetch polycounter lvl 6
    RN said:
    MrQuetch said:
    There are pose bones, edit bones, and something else... Which one would be best to reference?
    Each of those collections gives access to bone types that have slightly different attributes, pose bones and edit bones being the most useful (the third seems to be Object-mode bones). You can only access armature.data.edit_bones in Edit mode.

    You should really try to come up with these algorithms yourself, it's the only way to improve. To do what you want you need to know how to use dictionaries, lists (preferably a collections.deque object) and loops

    Ah. Thank you for the clarification. I'll probably go with the pose or edit bones, then. I'll see what one works better for my workflow. To be fair, this is my 5th / 6th attempt on trying to do this - in three different languages: GML, Maxscript, and Python. I've been so close, and somehow fall short on the relationship between the bones and the vertices. However, I think I know what I need to do, now... I've been thinking about this in-depth for the past few days, and have other ideas to try. Stupidly put, I really just need to offset the bones from each other, too - I failed to see that for the longest time. And, I admittedly feel really ashamed about it.
  • MrQuetch
    Offline / Send Message
    MrQuetch polycounter lvl 6
    Ok... I think I'm getting to where I want to be now. I have code, but it's only for testing, and is really messy. I'm going to try writing the full script for what I want to do now. Hopefully, it works out. I'm having a much easier time referencing things.
Sign In or Register to comment.