Rigify Meta-Rig for ManuelbastioniLAB add-on

edit:
https://blenderartists.org/forum/showthread.php?443436-Addon-Meta-Rig-for-Manuel-Bastioni-Lab-Addon-for-an-Addon

Hi!

I wrote a little add-on that “snaps” most of the bones from the meta rig to the rig from ManuelbastioniLAB.

usage:

Rigify Meta-Rig for MLAB:

  • create character with ManuelbastioniLAB
  • select the Armature (usually “MBlab_sk<long number>”) in object mode
  • click the button “Rigify Meta-Rig for MLAB” in the ManuelbastioniLAB tab
  • set/remove face rig
  • bones ‘pelvis.L’ and pelvis.R’ have to be snapped to ‘spine’ manually
  • make legs of new Meta-Rig straight before generating

Rename Vertex Groups (to match Rigify Meta-Rig or MLAB rig):

  • select the character mesh first

I put this post in Python Support because it has some issues:
The pelvis.L and pelvis.R have to be set manually.
The legs have to be straightened! The legs in MLAB (without IK) are “dent in”. Rigify expects them to be straight (pointing a little to -y). Otherwise the pole targets are over cross after the generation of the Rigify rig.

Ideas and solutions are welcome.


bl_info = {
    "name": "Rigify Meta-Rig for ManuelBastioniLAB",
    "author": "Daniel Engler",
    "version": (0, 3),
    "blender": (2, 79, 0),
    "location": "View3D &gt; ManuelBastioniLAB",
    "description": "Adds a new Rigify Meta-Rig for ManuelBastioniLAB Characters",
    "category": "Characters",
    }

import bpy

metarig_bone_names = { # metarig_bone : mlab_bone
    "spine":"pelvis",
    "spine.001":"spine01",
    "spine.002":"spine02",
    "spine.003":"spine03",
    "spine.006":"head",
    "spine.005":"neck",
    "breast.L":"breast_L",
    "foot.L":"foot_L",
    "toe.L":"toes_L",
    "shoulder.L":"clavicle_L",
    "hand.L":"hand_L",
    "thumb.01.L":"thumb01_L",
    "thumb.02.L":"thumb02_L",
    "thumb.03.L":"thumb03_L",
    "palm.01.L":"index00_L",
    "f_index.01.L":"index01_L",
    "f_index.02.L":"index02_L",
    "f_index.03.L":"index03_L",
    "palm.02.L":"middle00_L",
    "f_middle.01.L":"middle01_L",
    "f_middle.02.L":"middle02_L",
    "f_middle.03.L":"middle03_L",
    "palm.03.L":"ring00_L",
    "f_ring.01.L":"ring01_L",
    "f_ring.02.L":"ring02_L",
    "f_ring.03.L":"ring03_L",
    "palm.04.L":"pinky00_L",
    "f_pinky.01.L":"pinky01_L",
    "f_pinky.02.L":"pinky02_L",
    "f_pinky.03.L":"pinky03_L",
    "breast.R":"breast_R",
    "foot.R":"foot_R",
    "toe.R":"toes_R",
    "shoulder.R":"clavicle_R",
    "hand.R":"hand_R",
    "thumb.01.R":"thumb01_R",
    "thumb.02.R":"thumb02_R",
    "thumb.03.R":"thumb03_R",
    "palm.01.R":"index00_R",
    "f_index.01.R":"index01_R",
    "f_index.02.R":"index02_R",
    "f_index.03.R":"index03_R",
    "palm.02.R":"middle00_R",
    "f_middle.01.R":"middle01_R",
    "f_middle.02.R":"middle02_R",
    "f_middle.03.R":"middle03_R",
    "palm.03.R":"ring00_R",
    "f_ring.01.R":"ring01_R",
    "f_ring.02.R":"ring02_R",
    "f_ring.03.R":"ring03_R",
    "palm.04.R":"pinky00_R",
    "f_pinky.01.R":"pinky01_R",
    "f_pinky.02.R":"pinky02_R",
    "f_pinky.03.R":"pinky03_R",
}
metarig_bone_names_special = { # metarig_bone : mlab_bone
    "upper_arm.L":"upperarm_L",
    "forearm.L":"lowerarm_L",
    "thigh.L":"thigh_L",
    "shin.L":"calf_L",
    "upper_arm.R":"upperarm_R",
    "forearm.R":"lowerarm_R",
    "thigh.R":"thigh_R",
    "shin.R":"calf_R",
}

mlab_bone_names = { # mlab_bone : DEF-metarig_bone
    "upperarm_twist_L":"DEF-upper_arm.L",
    "upperarm_L":"DEF-upper_arm.L.001",
    "lowerarm_twist_L":"DEF-forearm.L.001",
    "lowerarm_L":"DEF-forearm.L",
    "thigh_twist_L":"DEF-thigh.L",
    "thigh_L":"DEF-thigh.L.001",
    "calf_twist_L":"DEF-shin.L",
    "calf_L":"DEF-shin.L.001",
    "upperarm_twist_R":"DEF-upper_arm.R",
    "upperarm_R":"DEF-upper_arm.R.001",
    "lowerarm_twist_R":"DEF-forearm.R.001",
    "lowerarm_R":"DEF-forearm.R",
    "thigh_twist_R":"DEF-thigh.R",
    "thigh_R":"DEF-thigh.R.001",
    "calf_twist_R":"DEF-shin.R",
    "calf_R":"DEF-shin.R.001",
}

class MetarigForMLAB(bpy.types.Operator):
    """Add new Meta-Rig for ManuelBastioniLAB Characters
    - MLAB Armature must be selected
    - bones 'pelvis.L' and pelvis.R' have to be snapped to 'spine' manually
    - bone 'face' has to be snapped to 'spine.006 (if needed)"""
    bl_idname = "object.metarigformlab_operator"
    bl_label = "Rigify Meta-Rig for MLAB"
    
    def execute(self, context):
        bone_data = {}
        mlab_rig = context.active_object
        if mlab_rig.type == 'ARMATURE':
            bpy.ops.object.mode_set(mode='EDIT')
            # get bone data from mlab rig and store vectors (head, tail) in bone_data dictionary
            for metarig_bone, mlab_bone in metarig_bone_names.items():
                b = mlab_rig.data.edit_bones[mlab_bone]
                bone_data[metarig_bone] = (b.head.copy(),b.tail.copy())
            # repeat for special bones
            for metarig_bone, mlab_bone in metarig_bone_names_special.items():
                b = mlab_rig.data.edit_bones[mlab_bone]
                bone_data[metarig_bone] = (b.head.copy(),b.tail.copy())
            bpy.ops.object.mode_set(mode='OBJECT')
            
            # create and select meta rig
            bpy.ops.object.armature_human_metarig_add()
            meta_rig = context.active_object
            bpy.ops.object.mode_set(mode='EDIT')
            # go through all bones in meta rig, pass the ones not needed
            for b in meta_rig.data.edit_bones:
                try:
                    h, t = bone_data[b.name]
                    b.head = h
                    b.tail = t
                except:
                    pass            
            bpy.ops.object.mode_set(mode='OBJECT')

        return {'FINISHED'}

class RenameVertexGroupsFromMlabToRigify(bpy.types.Operator):
    """Rename Vertex Groups to match Rigify Meta-Rig
    - select the character mesh first"""
    bl_idname = "object.renamevertexgroupsfrommlabtorigify_operator" # best name ever
    bl_label = "MLAB to Rigify"
    
    def execute(self, context):
        mlab_mesh = context.active_object
        if mlab_mesh.type == 'MESH':
            # add bone names from mlab_bone_names dict and add renamed to metarig_bone_names dict
            for metarig_bone, mlab_bone in metarig_bone_names.items():
                mlab_bone_names[mlab_bone] = "DEF-" + metarig_bone
            # go through mlab_bone_names dictinary and try rename vertex groups
            for mlab_bone, metarig_bone in mlab_bone_names.items():
                try:
                    mlab_mesh.vertex_groups[mlab_bone].name = metarig_bone
                except:
                    pass
                
        return {'FINISHED'}

class RenameVertexGroupsFromRigifyToMlab(bpy.types.Operator):
    """Rename Vertex Groups to match Rigify Meta-Rig
    - select the character mesh first"""
    bl_idname = "object.renamevertexgroupsfromrigifytomlab_operator" # best name ever
    bl_label = "Rigify to MLAB"
    
    def execute(self, context):
        mlab_mesh = context.active_object
        print("--------------------")
        if mlab_mesh.type == 'MESH':
            # add bone names from mlab_bone_names dict and add renamed to metarig_bone_names dict
            for metarig_bone, mlab_bone in metarig_bone_names.items():
                mlab_bone_names[mlab_bone] = "DEF-" + metarig_bone
            # go through mlab_bone_names dictinary and try rename vertex groups
            for mlab_bone, metarig_bone in mlab_bone_names.items():
                try:
                    mlab_mesh.vertex_groups[metarig_bone].name = mlab_bone
                    print(metarig_bone)
                except:
                    pass
                
        return {'FINISHED'}

class MetarigForMLABPanel(bpy.types.Panel):
    bl_label = 'Rigify Meta-Rig for MLAB'
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'TOOLS'
    bl_context = 'objectmode'
    bl_category = 'ManuelBastioniLAB'
    
    def draw(self, context):
        layout = self.layout
        layout.operator(MetarigForMLAB.bl_idname)
        layout.label(text="Rename Vertex Groups:")
        layout.operator(RenameVertexGroupsFromMlabToRigify.bl_idname)
        layout.operator(RenameVertexGroupsFromRigifyToMlab.bl_idname)

def register():
    bpy.utils.register_class(MetarigForMLAB)
    bpy.utils.register_class(RenameVertexGroupsFromMlabToRigify)
    bpy.utils.register_class(RenameVertexGroupsFromRigifyToMlab)
    bpy.utils.register_class(MetarigForMLABPanel)

if __name__ == "__main__":
    register()

edit: update
new button to rename vertex groups to match Rigify bones added
twist bones from MLAB are now taken in consideration to match additional deform bones in Rigify Meta-Rig

PS: This is my first add-on.

Looks interesting – I’ll have to try this out.

Works great, thank you :slight_smile:
I’m collecting all the usefull utilities concerning rigify.
Maybe you’d consider moving a step further and adding a funcionality to be able to rename the deform bones (after rig generation) to mach the vertex groups of the mesh

Well, I did it the other way and added a function to rename the vertex groups of the MLAB character.

Great, this will help a lot. Because of the numer of spine (neck) bones some manual tweeking is required, but that’s not a big deal.