Cal3D exporter for Blender 2.5x

Is someone interested in helping me to write a Cal3D exporter for Blender 2.5x? I managed to export static meshes but there’s still a lot of open questions. Right now I’m dealing with these two issues:

  1. In Cal3D, every vertex has an array of bone influences which in turn contain a bone id and a weight value. This is how I try to get these… does that make sense?

armatures = [modifier for modifier in object.modifiers if modifier.type == "ARMATURE"]
armature = armatures[0].object
poseBones = armature.pose.bones

tempVertices = []
for i, face in enumerate(mesh.faces):
    for j, vertexIndex in enumerate(face.vertices) :

        vertex = mesh.vertices[vertexIndex]

        # [...]
        # first i fetch vertex position, normal and texture coordinates, etc.
        # then i attempt to collect all bone influences for this vertex:
        boneInfluences = []

        for vertexGroup in vertex.groups :

            groupIndex =
            boneName = object.vertex_groups[groupIndex].name
            if boneName in poseBones :

                bone = poseBones[boneName]
                boneInfluences.append( BoneInfluence(, vertexGroup.weight) )

        tempVertices.append( Vertex(position, Vector.normalized(normal), textureCoords, boneInfluences) )
for vertex in tempVertices :

    for influence in vertex.boneInfluences :

        influence.weight /= len(vertex.boneInfluences)
  1. Bones require a rotation and translation both in absolute coordinates and in bone space. How can I access this information in Python?

Thank you!

Two quick questions:

  • Is the old API’s Bone.matrix[‘BONESPACE’] equivalent to Bone.matrix or Bone.matrix_local?
  • Previously, one could do Vector * Matrix, now only Matrix * Vector is accepted… is this the same?


About BL 2.57 (meanwhile!!!)
importing mathutils only VectorMatrix is possible (MM too, naturally)

In 2.57 you can get much info yourself,
a is an armature with three bones

From the console e.g.
>> a.loc
location lock_location lock_rotation lock_rotation_w lock_rotations_4d lock_scale
>>> a.mat
material_slots matrix_basis matrix_local matrix_world
>>> a.matrix_
matrix_basis matrix_local matrix_world
>>> a.matrix_basis
Matrix((1.0, 0.0, 0.0, 0.0),
(0.0, 1.0, 0.0, 0.0),
(0.0, 0.0, 1.0, 0.0),
(0.0, 0.0, 0.0, 1.0))

>>> a.bound_box[
bound_box[0] bound_box[1] bound_box[2] bound_box[3] bound_box[4] bound_box[5] bound_box[6] bound_box[7]
>>> dir(a)
[‘doc’, ‘module’, ‘slots’, ‘active_material’, ‘active_material_index’, ‘active_shape_key’, ‘active_shape_key_index’, ‘animation_data’, ‘animation_data_clear’, ‘animation_data_create’, ‘animation_visualisation’, ‘bl_rna’, ‘bound_box’, ‘children’, ‘collision’, ‘color’, ‘constraints’, ‘copy’, ‘data’, ‘delta_location’, ‘delta_rotation_euler’, ‘delta_rotation_quaternion’, ‘delta_scale’, ‘dimensions’, ‘draw_bounds_type’, ‘draw_type’, ‘dupli_faces_scale’, ‘dupli_frames_end’, ‘dupli_frames_off’, ‘dupli_frames_on’, ‘dupli_frames_start’, ‘dupli_group’, ‘dupli_list’, ‘dupli_list_clear’, ‘dupli_list_create’, ‘dupli_type’, ‘empty_draw_size’, ‘empty_draw_type’, ‘field’, ‘find_armature’, ‘game’, ‘grease_pencil’, ‘hide’, ‘hide_render’, ‘hide_select’, ‘is_duplicator’, ‘is_modified’, ‘is_visible’, ‘layers’, ‘library’, ‘location’, ‘lock_location’, ‘lock_rotation’, ‘lock_rotation_w’, ‘lock_rotations_4d’, ‘lock_scale’, ‘material_slots’, ‘matrix_basis’, ‘matrix_local’, ‘matrix_world’, ‘mode’, ‘modifiers’, ‘motion_path’, ‘name’, ‘parent’, ‘parent_bone’, ‘parent_type’, ‘parent_vertices’, ‘particle_systems’, ‘pass_index’, ‘pose’, ‘pose_library’, ‘proxy’, ‘proxy_group’, ‘ray_cast’, ‘rna_type’, ‘rotation_axis_angle’, ‘rotation_euler’, ‘rotation_mode’, ‘rotation_quaternion’, ‘scale’, ‘select’, ‘shape_key_add’, ‘show_axis’, ‘show_bounds’, ‘show_name’, ‘show_only_shape_key’, ‘show_texture_space’, ‘show_transparent’, ‘show_wire’, ‘show_x_ray’, ‘soft_body’, ‘tag’, ‘time_offset’, ‘to_mesh’, ‘track_axis’, ‘type’, ‘up_axis’, ‘update_tag’, ‘use_dupli_faces_scale’, ‘use_dupli_frames_speed’, ‘use_dupli_vertices_rotation’, ‘use_fake_user’, ‘use_shape_key_edit_mode’, ‘use_slow_parent’, ‘use_time_offset_add_parent’, ‘use_time_offset_edit’, ‘use_time_offset_parent’, ‘use_time_offset_particle’, ‘user_clear’, ‘users’, ‘users_group’, ‘users_scene’, ‘vertex_groups’]


or with respect to bones (edit mode and one bone selected)
>>> b=C.active_bone
>>> dir(b)
[‘doc’, ‘module’, ‘slots’, ‘align_orientation’, ‘align_roll’, ‘bbone_in’, ‘bbone_out’, ‘bbone_segments’, ‘bbone_x’, ‘bbone_z’, ‘bl_rna’, ‘envelope_distance’, ‘envelope_weight’, ‘head’, ‘head_radius’, ‘hide’, ‘hide_select’, ‘layers’, ‘lock’, ‘matrix’, ‘name’, ‘parent’, ‘rna_type’, ‘roll’, ‘select’, ‘select_head’, ‘select_tail’, ‘show_wire’, ‘tail’, ‘tail_radius’, ‘transform’, ‘use_connect’, ‘use_cyclic_offset’, ‘use_deform’, ‘use_envelope_multiply’, ‘use_inherit_rotation’, ‘use_inherit_scale’, ‘use_local_location’]


Thank you for the info but that doesn’t really answer my question - I know which matrices are available, I’m just not sure whether what used to be Bone.matrix[‘BONESPACE’] now maps to Bone.matrix or Bone.matrix_local.
I can only do Matrix * Vector… trying to do it the other way around(as it was in the original version of the exporter) yields the following error message: “TypeError: Matrix multiplication: not supported between ‘mathutils.Matrix’ and ‘mathutils.Vector’ types”. I just want to make sure changing the order of the arguments doesn’t change the result.

If only matrix*vector is possible, you do not have the latest stable version 2.57 of Blender!
>>> m
Matrix((1.0, 0.0, 0.0),
(0.0, 1.0, 0.0),
(0.0, 0.0, 1.0))

>>> v= Vector([1,2,3])
>>> v
Vector((1.0, 2.0, 3.0))

>>> v*m
Vector((1.0, 2.0, 3.0))

>>> m*v
Traceback (most recent call last):
File “<blender_console>”, line 1, in <module>
TypeError: Matrix multiplication: not supported between ‘mathutils.Matrix’ and ‘mathutils.Vector’ types

On the M*V thing, apparently everyone else does it the way it is now – you used to have to modify code to get it to work in blender it seems and now you don’t.

To get a bone weight, I can’t remember the exact method (…complicated) but the general idea is to loop over the verts in a mesh and check their weights in a vertex group where the ones in the group return their weight and it throws an exception if the vert isn’t in the group.

Something like:

for vert in verts:

So based on this thread I can only assume that at the moment there is no working Cal3D exporter for Blender 2.5x, correct? If not, then I would like to contribute in any way I can. I need a Cal3D exporter for developing products in IMVU as well many others in the IMVU community. Maybe we could round up a few good heads and get this thing figured out.

Please note that the script exists for 2.49 and it’s actually found in cal3d home. It needs to be ported to 2.5.

You can find the script here:

We are using it with 2.49 and works well, but with 2.5 it gives errors for the new API changes.

i’ve started porting the 2.49b script to the new API… the attached blender file contains a simple model with an armature and the modified part of the original s/cript which exports the skeleton. i’ve marked all my changes with # XXX.

translation and local translation are still wrong most of the time… maybe someone can have a look and spot the mistake?

guy25b.blend (440 KB)

i just see i was wrong about vm and mv - you were right, only v*m is possible in 2.57, i mixed it up.

i still don’t know whether what used to be Bone.matrix[‘BONESPACE’] now maps to Bone.matrix or Bone.matrix_local; the same question applies to b.head[‘BONESPACE’] and b.tail[‘BONESPACE’] - do these map to b.tail and b.head or to b.tail_local and b.head_local?

ok i figured it out:

b.head[‘BONESPACE’] = b.head
b.tail[‘BONESPACE’] = b.tail
b.matrix[‘BONESPACE’] = b.matrix

guy25b.blend (504 KB)

skeletons are now exported properly. here’s the updated file.

I just finished maintaining blender exporter to cal3d for blender api 2.8
Should have lot of issues because of the new PBR pipeline of Blender
give feedback here