I am sure this is a very simple thing to do. But because of my inexperience, I am having trouble with it. I havent gotten much from reading the blender python api. The answer was probably right in my face, but I just didnt know what to do. I just want to know how to make a script that exports weight values to a text file. As well as bone elements - like the rotation matrix (3x3 mat) the children of the bone and the offset of the bone. Oh and also the vertexGroups (like the vertices that each bone influences).
While the answer is in Blender's API docs, the relationships aren't clearly spelt out so you need to "get" some of the relationships to know how it fits together.
You access EditBones through
bpy.data.armatures['Armature'].edit_bones or while the armature is in edit mode with
object.data.edit_bones, while you will find PoseBones in
While an EditBone does have a
matrix property that combines the location and rotation of the bone, it relies mostly on the
roll properties of each bone and doesn't keep any rotation properties. The PoseBones use the
head as the origin and then the
rotation_mode to determine whether the
rotation_axis_angle or the
rotation_quaternion property is used.
Both EditBones and PoseBones have a
children property to list any children the bone may have.
A mesh object's data includes a list of it's vertices and each of these vertices has a groups property that lists the groups that the vertex is associated with. This list contains the group index (which matches the vertex group index above) and the weight used for each group. The group weight is the same value you edit using weight painting.
When an armature deforms a mesh it finds vertices that use a group with the same name as the bone and uses the weight to define how much to influence the vertex.
So while looping through the armature bones, using the bone name you can get the vertex group index for the bone, then get the vertices it influences.
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: w = v.groups[gidx].weight print('Vertex',v.index,'has a weight of',w,'for bone',bone.name)
The sambler's answer worked to me, but I had to add a condition in the loop:
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)
Because when you access to the items of v.groups, the indices are not the same as the gidx indices. The indices gidx are the indices bones without taking into account those bones that do not affect any vertex and the indices of v.groups start from 0 to 6-9 at most, the items of v.groups are the bones that affect to this vertex v. You go through the items of v.groups searching for the item that has the same index group (accessing for example through v.groups.groups to get the value of gidx)