I am editing the default OBJ exporter of Blender (io_scene_obj) to create my own version which supports bone weights, for skeletal animation.
I now know how to access the bone weights per vertex in the Object, however I need to correlate those Object vertices to the Mesh vertices.
I am able to fetch the "vertex index" of the vertex with this piece of code:
import bpy
arm = bpy.data.objects['Armature']
obj = bpy.data.objects['Cube']
obj_verts = obj.data.vertices
obj_group_names = [g.name for g in obj.vertex_groups]
for bone in arm.pose.bones:
if bone.name not in obj_group_names:
continue
gidx = obj.vertex_groups[bone.name].index
bone_verts = [v for v in obj_verts if gidx in [g.group for g in v.groups]]
for v in bone_verts:
for g in v.groups:
if g.group == gidx:
w = g.weight
print('Vertex',v.index,'has a weight of',w,'for bone',bone.name)
however I am not sure how to use this vertex index. is it a direct index into me.vertices? (I sure hope it is) Please note that I triangulate the mesh before I export it. I keep the vertex order though, so it should be the same.
Here's what I'm planning to do: My file format has a new kind of line:
vc f f f
and it modifies the f lines:
f position/uv/norm/skel position/uv/norm/skel position/uv/norm/skel
the vc lines were originally designed to hold color information like this
#Solid red
vc 1.0 0.0 0.0
#Solid green
vc 0.0 1.0 0.0
However I realized that this exact same system could contain skeletal animation information. Here are the steps:
1) Get the 3 most influential weights on a vertex
2) Make them add up to 1
3) Divide them by 2
4) Add the Bone ID to it
Here's an example:
#Bone 1 influences this vertex 100 percent, there are no others
vc 1.5 0.0 0.0
#50 percent influenced by bone 1, 25 percent by bone 2, and 25 percent by bone 3
vc 1.25 2.125 3.125
In order for this to work, I need to figure out how much each vertex (3D point, with X, Y, and Z) is weighted by each bone, pick the top 3 per vertex (and if there aren't 3, stick in a fake 0 bone with 0 weight for every missing spot) and write it to file in VC lines. If I do this for every 3d point, then I can simply use the same indices as the positions for the f lines.
f A/B/C/A
How could I achieve this?
I assume that there is only one armature in the scene called 'Armature' and that the only mesh currently being exported (But not necessarily the only one in the scene) is influenced by it.
I have access to the list of Objects to be exported, so I can access both the triangulated mesh from bpy.data.meshes[] and the object from bpy.data.objects[]