Skip to content
Snippets Groups Projects
io_import_scene_mhx.py 122 KiB
Newer Older
  • Learn to ignore specific revisions
  •         row = layout.row()
            row.label("IK Leg")
            row.operator("mhx.snap_ik_fk", text="Snap L IK Leg").data = "&LegIk_L 4 5 12"
            row.operator("mhx.snap_ik_fk", text="Snap R IK Leg").data = "&LegIk_R 20 21 28"
            row = layout.row()
    
            row.label("Ankle")
            row.operator("mhx.fix_ankle", text="Fix L Ankle").suffix = "_L"
            row.operator("mhx.fix_ankle", text="Fix R Ankle").suffix = "_R"
    
            row.label("")
            row.operator("mhx.clear_ankle", text="Clear L Ankle").suffix = "_L"
            row.operator("mhx.clear_ankle", text="Clear R Ankle").suffix = "_R"
    
        def toggleButton(self, row, rig, prop, fk, ik):
            if rig[prop] > 0.5:
                row.operator("mhx.toggle_fk_ik", text="IK").toggle = prop + " 0" + fk + ik
            else:
                row.operator("mhx.toggle_fk_ik", text="FK").toggle = prop + " 1" + ik + fk
                
    
    
    ###################################################################################    
    #
    #    Posing panel
    #
    ###################################################################################          
    #
    #    class MhxDriversPanel(bpy.types.Panel):
    #
    
    class MhxDriversPanel(bpy.types.Panel):
        bl_label = "MHX Drivers"
        bl_space_type = "VIEW_3D"
        bl_region_type = "UI"
    
        bl_options = {'DEFAULT_CLOSED'}
    
        
        @classmethod
        def poll(cls, context):
            return pollMhxRig(context.object)
    
        def draw(self, context):
            lProps = []
            rProps = []
            props = []
            plist = list(context.object.keys())
            plist.sort()
            for prop in plist:
    
                elif prop[-2:] == '_R':
    
            ob = context.object
            layout = self.layout
    
            for (prop, pname) in props:
                layout.prop(ob, '["%s"]' % prop, text=pname)
    
            layout.label("Left")
            for (prop, pname) in lProps:
                layout.prop(ob, '["%s"]' % prop, text=pname)
            layout.label("Right")
            for (prop, pname) in rProps:
                layout.prop(ob, '["%s"]' % prop, text=pname)
            return
    
    
    ###################################################################################    
    #
    #    Visibility panel
    #
    ###################################################################################          
    #
    #    class MhxVisibilityPanel(bpy.types.Panel):
    #
    
    class MhxVisibilityPanel(bpy.types.Panel):
        bl_label = "MHX Visibility"
        bl_space_type = "VIEW_3D"
        bl_region_type = "UI"
    
        bl_options = {'DEFAULT_CLOSED'}
    
        
        @classmethod
        def poll(cls, context):
            return pollMhxRig(context.object)
    
        def draw(self, context):
            ob = context.object
    
            props = list(ob.keys())
            props.sort()
            for prop in props:
                if prop[0:4] == "Hide": 
    
                    layout.prop(ob, '["%s"]' % prop)
            layout.separator()
            layout.operator("mhx.update_textures")
    
            layout.separator()
            layout.operator("mhx.add_hiders")
            layout.operator("mhx.remove_hiders")
    
    class VIEW3D_OT_MhxUpdateTexturesButton(bpy.types.Operator):
        bl_idname = "mhx.update_textures"
        bl_label = "Update"
    
        def execute(self, context):
            scn = context.scene
            for mat in bpy.data.materials:
                if mat.animation_data:
                    try:
                        mat["MhxDriven"]
                    except:
                        continue
                    for driver in mat.animation_data.drivers:
                        prop = mat.path_resolve(driver.data_path)
                        value = driver.evaluate(scn.frame_current)
                        #print("Update %s[%d] = %s" % (driver.data_path, driver.array_index, value))
                        prop[driver.array_index] = value
            return{'FINISHED'}    
    
            
    class VIEW3D_OT_MhxAddHidersButton(bpy.types.Operator):
        bl_idname = "mhx.add_hiders"
        bl_label = "Add Hide Property"
    
        def execute(self, context):
            rig = context.object
            for ob in context.scene.objects:
                if ob.select and ob != rig:
                    prop = "Hide%s" % ob.name        
                    rig[prop] = False        
                    addHider(ob, "hide", rig, prop)
                    addHider(ob, "hide_render", rig, prop)
            return{'FINISHED'}    
                    
    def addHider(ob, attr, rig, prop):
        fcu = ob.driver_add(attr)
        drv = fcu.driver
        drv.type = 'SCRIPTED'
        drv.expression = "x"
        drv.show_debug_info = True
        var = drv.variables.new()
        var.name = "x"
        targ = var.targets[0]
        targ.id = rig
        targ.data_path = '["%s"]' % prop
        return
    
    class VIEW3D_OT_MhxRemoveHidersButton(bpy.types.Operator):
        bl_idname = "mhx.remove_hiders"
        bl_label = "Remove Hide Property"
    
        def execute(self, context):
            rig = context.object
            for ob in context.scene.objects:
                if ob.select and ob != rig:
                    ob.driver_remove("hide")
                    ob.driver_remove("hide_render")
                    del rig["Hide%s" % ob.name]
            return{'FINISHED'}    
            
    
    ###################################################################################    
    #
    #    Layers panel
    #
    ###################################################################################    
    
    MhxLayers = [
        (( 0,    'Root', 'MhxRoot'),
         ( 8,    'Face', 'MhxFace')),
        (( 9,    'Tweak', 'MhxTweak'),
         (10,    'Head', 'MhxHead')),
        (( 1,    'FK Spine', 'MhxFKSpine'),
         (17,    'IK Spine', 'MhxIKSpine')),
        ((13,    'Inv FK Spine', 'MhxInvFKSpine'),
    
        ('Left', 'Right'),
        (( 2,    'IK Arm', 'MhxIKArm'),
         (18,    'IK Arm', 'MhxIKArm')),
        (( 3,    'FK Arm', 'MhxFKArm'),
         (19,    'FK Arm', 'MhxFKArm')),
        (( 4,    'IK Leg', 'MhxIKLeg'),
         (20,    'IK Leg', 'MhxIKLeg')),
        (( 5,    'FK Leg', 'MhxFKLeg'),
         (21,    'FK Leg', 'MhxFKLeg')),
    
        ((12,    'Extra', 'MhxExtra'),
         (28,    'Extra', 'MhxExtra')),
    
        (( 6,    'Fingers', 'MhxFingers'),
         (22,    'Fingers', 'MhxFingers')),
        (( 7,    'Links', 'MhxLinks'),
         (23,    'Links', 'MhxLinks')),
        ((11,    'Palm', 'MhxPalm'),
         (27,    'Palm', 'MhxPalm')),
    ]
    
    #
    #    class MhxLayersPanel(bpy.types.Panel):
    #
    
    class MhxLayersPanel(bpy.types.Panel):
        bl_label = "MHX Layers"
        bl_space_type = "VIEW_3D"
        bl_region_type = "UI"
    
        #bl_options = {'DEFAULT_CLOSED'}
    
        
        @classmethod
        def poll(cls, context):
            return pollMhxRig(context.object)
    
        def draw(self, context):
            layout = self.layout
    
            layout.operator("mhx.pose_enable_all_layers")
            layout.operator("mhx.pose_disable_all_layers")
    
            amt = context.object.data
            for (left,right) in MhxLayers:
                row = layout.row()
                if type(left) == str:
                    row.label(left)
                    row.label(right)
                else:
                    for (n, name, prop) in [left,right]:
                        row.prop(amt, "layers", index=n, toggle=True, text=name)
            return
    
    
    class VIEW3D_OT_MhxEnableAllLayersButton(bpy.types.Operator):
        bl_idname = "mhx.pose_enable_all_layers"
        bl_label = "Enable all layers"
    
    
        def execute(self, context):
            rig = getMhxRig(context.object)
            for (left,right) in MhxLayers:
                if type(left) != str:
                    for (n, name, prop) in [left,right]:
    
                        rig.data.layers[n] = True
            return{'FINISHED'}    
    
    class VIEW3D_OT_MhxDisableAllLayersButton(bpy.types.Operator):
        bl_idname = "mhx.pose_disable_all_layers"
        bl_label = "Disable all layers"
    
        def execute(self, context):
            rig = getMhxRig(context.object)
            layers = 32*[False]
            pb = context.active_pose_bone
            if pb:
                for n in range(32):
                    if pb.bone.layers[n]:
                        layers[n] = True
                        break
            else:
                layers[0] = True
            rig.data.layers = layers            
    
            return{'FINISHED'}    
                    
    ###################################################################################    
    #
    #    Common functions
    #
    ###################################################################################    
    #
    #   pollMhxRig(ob):
    #   getMhxRig(ob):
    #
    
    def pollMhxRig(ob):
        try:
            return (ob["MhxRig"] == "MHX")
        except:
            return False
            
    def getMhxRig(ob):
        if ob.type == 'ARMATURE':
            rig = ob
        elif ob.type == 'MESH':
            rig = ob.parent
        else:
            return None
        try:        
            if (rig["MhxRig"] == "MHX"):
                return rig
            else:
                return None
        except:
            return None
        
            
    #
    #    setInterpolation(rig):
    #
    
    def setInterpolation(rig):
        if not rig.animation_data:
            return
        act = rig.animation_data.action
        if not act:
            return
        for fcu in act.fcurves:
            for pt in fcu.keyframe_points:
                pt.interpolation = 'LINEAR'
            fcu.extrapolation = 'CONSTANT'
        return
        
    ###################################################################################    
    #
    #    initialize and register
    #
    ###################################################################################    
    
    
    def menu_func(self, context):
    
        self.layout.operator(ImportMhx.bl_idname, text="MakeHuman (.mhx)...")
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    def register():
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        bpy.types.INFO_MT_file_import.append(menu_func)
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    def unregister():
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        try:
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        except:
            pass
    
        try:
            bpy.types.INFO_MT_file_import.remove(menu_func)
        except:
            pass
    
    if __name__ == "__main__":
        unregister()
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        register()