Skip to content
Snippets Groups Projects
io_import_scene_mhx.py 129 KiB
Newer Older
  • Learn to ignore specific revisions
  • bodyLanguageVisemes = ({
        'Rest' : [
    
            ('MouthWidth_L', 0),
            ('MouthWidth_R', 0),
            ('MouthNarrow_L', 0),
            ('MouthNarrow_R', 0),
            ('LipsPart', 0.6),
            ('UpLipsMidHeight', 0),
            ('LoLipsMidHeight', 0),
    
            ('MouthWidth_L', 0),
            ('MouthWidth_R', 0),
            ('MouthNarrow_L', 0),
            ('MouthNarrow_R', 0),
            ('LipsPart', 0.4),
            ('UpLipsMidHeight', 0),
            ('LoLipsMidHeight', 0),
    
            ('MouthWidth_L', 0),
            ('MouthWidth_R', 0),
            ('MouthNarrow_L', 0),
            ('MouthNarrow_R', 0),
            ('LipsPart', 0),
            ('UpLipsMidHeight', 0),
            ('LoLipsMidHeight', 0),
    
            ('MouthWidth_L', 0),
            ('MouthWidth_R', 0),
            ('MouthNarrow_L', 1.0),
            ('MouthNarrow_R', 1.0),
            ('LipsPart', 0),
            ('UpLipsMidHeight', 0),
            ('LoLipsMidHeight', 0),
    
            ('MouthWidth_L', 0),
            ('MouthWidth_R', 0),
            ('MouthNarrow_L', 0.9),
            ('MouthNarrow_R', 0.9),
            ('LipsPart', 0),
            ('UpLipsMidHeight', 0),
            ('LoLipsMidHeight', 0),
    
            ('MouthWidth_L', 0),
            ('MouthWidth_R', 0),
            ('MouthNarrow_L', 0.5),
            ('MouthNarrow_R', 0.5),
            ('LipsPart', 0),
            ('UpLipsMidHeight', 0.2),
            ('LoLipsMidHeight', -0.2),
    
            ('MouthWidth_L', 0.2),
            ('MouthWidth_R', 0.2),
            ('MouthNarrow_L', 0),
            ('MouthNarrow_R', 0),
            ('LipsPart', 1.0),
            ('UpLipsMidHeight', 0),
            ('LoLipsMidHeight', 0.3),
    
            ('MouthWidth_L', 0),
            ('MouthWidth_R', 0),
            ('MouthNarrow_L', 0),
            ('MouthNarrow_R', 0),
            ('LipsPart', 0),
            ('UpLipsMidHeight', 0.5),
            ('LoLipsMidHeight', -0.7),
    
            ('MouthWidth_L', 0.8),
            ('MouthWidth_R', 0.8),
            ('MouthNarrow_L', 0),
            ('MouthNarrow_R', 0),
            ('LipsPart', 0),
            ('UpLipsMidHeight', 1.0),
            ('LoLipsMidHeight', 0),
    
            ('MouthWidth_L', 0.2),
            ('MouthWidth_R', 0.2),
            ('MouthNarrow_L', 0),
            ('MouthNarrow_R', 0),
            ('LipsPart', 0),
            ('UpLipsMidHeight', 0.6),
            ('LoLipsMidHeight', -0.6),
    
            ('MouthWidth_L', 0),
            ('MouthWidth_R', 0),
            ('MouthNarrow_L', 0),
            ('MouthNarrow_R', 0),
            ('LipsPart', 0),
            ('UpLipsMidHeight', 0.4),
            ('LoLipsMidHeight', 0),
    
            ('MouthWidth_L', 0),
            ('MouthWidth_R', 0),
            ('MouthNarrow_L', 0),
            ('MouthNarrow_R', 0),
            ('LipsPart', 0),
            ('UpLipsMidHeight', 0.5),
            ('LoLipsMidHeight', -0.6),
    
            ('MouthWidth_L', 0),
            ('MouthWidth_R', 0),
            ('MouthNarrow_L', 0),
            ('MouthNarrow_R', 0),
            ('LipsPart', 0),
            ('UpLipsMidHeight', 0),
            ('LoLipsMidHeight', 0),
    
            ('MouthWidth_L', 0),
            ('MouthWidth_R', 0),
            ('MouthNarrow_L', 0),
            ('MouthNarrow_R', 0),
            ('LipsPart', 0),
            ('UpLipsMidHeight', 0.5),
            ('LoLipsMidHeight', -0.5),
    
            ('MouthWidth_L', 0),
            ('MouthWidth_R', 0),
            ('MouthNarrow_L', 0),
            ('MouthNarrow_R', 0),
            ('LipsPart', 0),
            ('UpLipsMidHeight', 0.5),
            ('LoLipsMidHeight', -0.5),
    
    VisemePanelBones = {
        'MouthOpen' :       ('PJaw', (0,0.25)),
        'UpLipsMidHeight' : ('PUpLipMid', (0,-0.25)),
        'LoLipsMidHeight' : ('PLoLipMid', (0,-0.25)),
        'LoLipsIn':         ('PLoLipMid', (-0.25,0)),
    
        'MouthWidth_L' :    ('PMouth_L', (0.25,0)),
        'MouthWidth_R' :    ('PMouth_R', (-0.25,0)),
    
        'MouthNarrow_L' :   ('PMouth_L', (-0.25,0)),
        'MouthNarrow_R' :   ('PMouth_R', (0.25,0)),
    
        'TongueBackHeight': ('PTongue', (-0.25, 0)),
        'TongueHeight' :    ('PTongue', (0, -0.25)),
    
        'UpLidUp_L' :       ('PUpLid_L', (0,1.0)),
        'UpLidUp_R' :       ('PUpLid_R', (0,1.0)),
    
        'LoLidDown_L' :     ('PLoLid_L', (0,-1.0)),
        'LoLidDown_R' :     ('PLoLid_R', (0,-1.0)),
    }
    
    VisemeList = [
        ('Rest', 'Etc', 'AH'),
        ('MBP', 'OO', 'O'),
        ('R', 'FV', 'S'),
        ('SH', 'EE', 'EH'),
        ('TH', 'L', 'G')
    ]
    
    
    #
    #   makeVisemes(ob, scn):
    #   class VIEW3D_OT_MhxMakeVisemesButton(bpy.types.Operator):
    #
    
    def makeVisemes(ob, scn):
    
        if ob.type != 'MESH':
            print("Active object %s is not a mesh" % ob)
            return
        if not ob.data.shape_keys:
            print("%s has no shapekeys" % ob)
            return
        try:
            ob.data.shape_keys.key_blocks["VIS_Rest"]
            print("Visemes already created")
            return
    
        try:
            ob.data.shape_keys.key_blocks["MouthOpen"]
        except KeyError:
            print("Mesh does not have face shapes")
            return
    
        for (vis,shapes) in bodyLanguageVisemes.items():
    
            vkey = ob.shape_key_add(name="VIS_%s" % vis)
    
            print(vkey.name)
            for n,v in enumerate(verts):
                vkey.data[n].co = v.co
    
            for (name,value) in shapes:
                if name[-2:] == "_R":
                    continue
                skey = ob.data.shape_keys.key_blocks[name]
                factor = 0.75*value
                for n,v in enumerate(verts):
                    vkey.data[n].co += factor*(skey.data[n].co - v.co)
    
    class VIEW3D_OT_MhxMakeVisemesButton(bpy.types.Operator):
        bl_idname = "mhx.make_visemes"
        bl_label = "Generate viseme shapekeys"
    
        bl_options = {'UNDO'}
    
    
        def execute(self, context):
            makeVisemes(context.object, context.scene)
    
    MohoVisemes = dict({
    
        "rest" : "Rest",
        "etc" : "Etc",
        "AI" : "AH",
        "O" : "O",
        "U" : "OO",
        "WQ" : "AH",
        "L" : "L",
        "E" : "EH",
        "MBP" : "MBP",
        "FV" : "FV",
    
    MagpieVisemes = dict({
    
        "E" : "EH",
        "O" : "O",
        "UW" : "AH",
        "MBP" : "MBP",
        "L" : "L",
        "FV" : "FV",
        "Sh" : "SH",
    
    })
    
    #
    #    setViseme(context, vis, setKey, frame):
    #    setBoneLocation(context, pbone, loc, mirror, setKey, frame):
    #    class VIEW3D_OT_MhxVisemeButton(bpy.types.Operator):
    #
    
    def getVisemeSet(context, rig):
    
            return stopStaringVisemes
    
        elif rig.MhxVisemeSet == "BodyLanguage":
    
            return bodyLanguageVisemes
        else:
    
            raise MhxError("Unknown viseme set %s" % visset)
    
    def setVisemeAlpha7(context, vis, visemes, setKey, frame):
    
        (rig, mesh) = getMhxRigMesh(context.object)
        isPanel = False
        isProp = False
        shapekeys = None
        scale = 0.75
    
        if rig.MhxShapekeyDrivers:
    
                scale *= rig.pose.bones['PFace'].bone.length
                isPanel = True
    
                isProp = True
        elif mesh:
            shapekeys = mesh.data.shape_keys.key_blocks
    
        for (skey, value) in visemes[vis]:
            if isPanel:
                (b, (x,z)) = VisemePanelBones[skey]
    
                loc = mathutils.Vector((float(x*value),0,float(z*value)))
    
                pb = rig.pose.bones[b]
                pb.location = loc*scale
                if setKey or context.tool_settings.use_keyframe_insert_auto:
                    for n in range(3):
                        pb.keyframe_insert('location', index=n, frame=frame, group=pb.name)
            elif isProp:
    
                skey = 'Mhf' + skey
    
                try:
                    prop = rig[skey]
                except:
                    continue
                rig[skey] = value*scale
                if setKey or context.tool_settings.use_keyframe_insert_auto:
    
                    rig.keyframe_insert('["%s"]' % skey, frame=frame, group="Visemes")
    
            elif shapekeys:
                try:
                    shapekeys[skey].value = value*scale
                except:
                    continue
                if setKey or context.tool_settings.use_keyframe_insert_auto:
    
                    shapekeys[skey].keyframe_insert("value", frame=frame)
    
        updatePose(context)
    
    
    class VIEW3D_OT_MhxVisemeButton(bpy.types.Operator):
        bl_idname = 'mhx.pose_viseme'
        bl_label = 'Viseme'
    
        bl_options = {'UNDO'}
    
        viseme = StringProperty()
    
        def invoke(self, context, event):
    
            (rig, mesh) = getMhxRigMesh(context.object)
            visemes = getVisemeSet(context, rig)
            setVisemeAlpha7(context, self.viseme, visemes, False, context.scene.frame_current)
    
    
    def readLipsync(context, filepath, offs, struct):
    
        if rig.MhxVisemeSet:
            visemes = getVisemeSet(context, rig)
        else:
    
            props = getProps(rig, "Mhv")
            visemes = {}
            oldKeys = []
            for prop in props:
                dummy,units = getUnitsFromString("x;"+rig[prop])
                visemes[prop] = units
            props = getProps(rig, "Mhsmouth")
            auto = context.tool_settings.use_keyframe_insert_auto
            auto = True
            factor = rig.MhxStrength
    
        context.scene.objects.active = rig
    
        for line in fp:
            words= line.split()
            if len(words) < 2:
    
                frame = int(words[0])+offs
    
                setVisemeAlpha7(context, vis, visemes, True, frame)
    
            else:
                setMhmProps(rig, shapekeys, "Mhsmouth", visemes["Mhv"+vis], factor, auto, frame)
    
        updatePose(context)
    
        print("Lipsync file %s loaded" % filepath)
    
    class VIEW3D_OT_MhxMohoButton(bpy.types.Operator, ImportHelper):
        bl_idname = "mhx.pose_load_moho"
        bl_label = "Load Moho (.dat)"
    
        bl_options = {'UNDO'}
    
        filename_ext = ".dat"
        filter_glob = StringProperty(default="*.dat", options={'HIDDEN'})
    
        filepath = StringProperty(subtype='FILE_PATH')
    
        def execute(self, context):
            readLipsync(context, self.properties.filepath, context.scene.frame_start - 1, MohoVisemes)
            return{'FINISHED'}
    
    
        def invoke(self, context, event):
            context.window_manager.fileselect_add(self)
    
    
    
    class MhxLipsyncPanel(bpy.types.Panel):
        bl_label = "MHX Lipsync"
        bl_space_type = "VIEW_3D"
        bl_region_type = "UI"
    
        bl_options = {'DEFAULT_CLOSED'}
    
        @classmethod
        def poll(cls, context):
    
            return pollMhx(context.object)
    
                if not visemes:
                    layout.label("No visemes found")
                    return
    
                layout.operator("mhx.pose_reset_expressions", text="Reset visemes").prefix="Mhsmouth"
                layout.operator("mhx.pose_key_expressions", text="Key visemes").prefix="Mhsmouth"
    
                layout.prop(rig, "MhxStrength")
                layout.separator()
    
                    if n % 3 == 0:
                        row = layout.row()
                        n = 0
    
                    row.operator("mhx.pose_mhm", text=prop[3:]).data="Mhsmouth;"+rig[prop]
    
                    n += 1
                while n % 3 != 0:
                    row.label("")
                    n += 1
                layout.separator()
                row = layout.row()
    
                row.operator("mhx.pose_mhm", text="Blink").data="Mhsmouth;eye_left_closure:1;eye_right_closure:1"
                row.operator("mhx.pose_mhm", text="Unblink").data="Mhsmouth;eye_left_closure:0;eye_right_closure:0"
            else:
    
                for (vis1, vis2, vis3) in VisemeList:
                    row = layout.row()
                    row.operator("mhx.pose_viseme", text=vis1).viseme = vis1
                    row.operator("mhx.pose_viseme", text=vis2).viseme = vis2
                    row.operator("mhx.pose_viseme", text=vis3).viseme = vis3
                layout.separator()
                row = layout.row()
                row.operator("mhx.pose_viseme", text="Blink").viseme = 'Blink'
                row.operator("mhx.pose_viseme", text="Unblink").viseme = 'Unblink'
                layout.separator()
                layout.operator("mhx.make_visemes")
    
            layout.separator()
            row = layout.row()
    
            #layout.operator("mhx.update")
    
    #   updatePose(context):
    
    #   class VIEW3D_OT_MhxUpdateButton(bpy.types.Operator):
    #
    
    
    def updatePose(context):
        scn = context.scene
    
        bpy.ops.object.posemode_toggle()
        bpy.ops.object.posemode_toggle()
    
        return
    
    class VIEW3D_OT_MhxUpdateButton(bpy.types.Operator):
        bl_idname = "mhx.update"
        bl_label = "Update"
    
        def execute(self, context):
    
            updatePose(context)
    
    ###################################################################################
    
    ###################################################################################
    
    
    class VIEW3D_OT_MhxResetExpressionsButton(bpy.types.Operator):
        bl_idname = "mhx.pose_reset_expressions"
        bl_label = "Reset expressions"
    
        bl_options = {'UNDO'}
    
    
        def execute(self, context):
    
            shapekeys = getMhmShapekeys(rig, mesh)
            clearMhmProps(rig, shapekeys, self.prefix, context.tool_settings.use_keyframe_insert_auto, context.scene.frame_current)
    
            updatePose(context)
    
    
    
    class VIEW3D_OT_MhxKeyExpressionsButton(bpy.types.Operator):
        bl_idname = "mhx.pose_key_expressions"
        bl_label = "Key expressions"
    
        bl_options = {'UNDO'}
    
    
        def execute(self, context):
    
            props = getProps(rig, self.prefix)
    
            frame = context.scene.frame_current
    
    Thomas Larsson's avatar
    Thomas Larsson committed
                rig.keyframe_insert('["%s"]'%prop, frame=frame)
    
            updatePose(context)
    
    
    class VIEW3D_OT_MhxPinExpressionButton(bpy.types.Operator):
        bl_idname = "mhx.pose_pin_expression"
        bl_label = "Pin"
    
        bl_options = {'UNDO'}
    
    
        def execute(self, context):
    
            words = self.data.split(";")
            prefix = words[0]
            expression = words[1]
    
            if context.tool_settings.use_keyframe_insert_auto:
                frame = context.scene.frame_current
    
                        rig[prop] = 1.0
                    else:
                        rig[prop] = 0.0
                    if abs(rig[prop] - old) > 1e-3:
    
    Thomas Larsson's avatar
    Thomas Larsson committed
                        rig.keyframe_insert('["%s"]'%prop, frame=frame)
    
                        rig[prop] = 1.0
                    else:
                        rig[prop] = 0.0
    
            updatePose(context)
    
    def getMhmShapekeys(rig, mesh):
        if rig.MhxShapekeyDrivers:
            return None
        else:
            return mesh.data.shape_keys.key_blocks
    
    
    def setMhmProps(rig, shapekeys, prefix, units, factor, auto, frame):
        clearMhmProps(rig, shapekeys, prefix, auto, frame)
    
        for (prop, value) in units:
    
            if shapekeys:
                skey = prop[3:].replace("_","-")
                shapekeys[skey].value = factor*value
                if auto:
    
                    shapekeys[skey].keyframe_insert("value", frame=frame)
    
    def clearMhmProps(rig, shapekeys, prefix, auto, frame):
    
        props = getProps(rig, prefix)
        for prop in props:
    
            if shapekeys:
                skey = prop[3:].replace("_","-")
                shapekeys[skey].value = 0.0
                if auto:
    
                    shapekeys[skey].keyframe_insert("value", frame=frame)
    
                    rig.keyframe_insert('["%s"]'%prop, frame=frame)
    
        prefix = words[0]
    
        for word in words[1:]:
    
            prop = "Mhs" + unit[0]
            value = float(unit[1])
    
            units.append((prop, value))
    
    
    class VIEW3D_OT_MhxMhmButton(bpy.types.Operator):
        bl_idname = "mhx.pose_mhm"
        bl_label = "Mhm"
        bl_options = {'UNDO'}
        data = StringProperty()
    
    
            rig,mesh = getMhxRigMesh(context.object)
    
            auto = context.tool_settings.use_keyframe_insert_auto
            frame = context.scene.frame_current
    
            prefix,units = getUnitsFromString(self.data)
    
            setMhmProps(rig, shapekeys, prefix, units, rig.MhxStrength, auto, frame)
    
        props = []
        for prop in rig.keys():
            if prop.startswith(prefix):
    
        return props
    
    
    
    class MhxExpressionsPanel(bpy.types.Panel):
        bl_label = "MHX Expressions"
        bl_space_type = "VIEW_3D"
        bl_region_type = "UI"
    
        bl_options = {'DEFAULT_CLOSED'}
    
        @classmethod
        def poll(cls, context):
            return pollMhx(context.object)
    
        def draw(self, context):
            layout = self.layout
            rig,mesh = getMhxRigMesh(context.object)
            if not rig:
    
            layout.operator("mhx.pose_reset_expressions").prefix="Mhs"
            layout.operator("mhx.pose_key_expressions").prefix="Mhs"
    
            layout.prop(rig, "MhxStrength")
            layout.separator()
            for prop in exprs:
    
                layout.operator("mhx.pose_mhm", text=prop[3:]).data="Mhs;"+rig[prop]
    
    def drawShapePanel(self, context, prefix, name):
        layout = self.layout
        rig,mesh = getMhxRigMesh(context.object)
        if not rig:
            print("No MHX rig found")
            return
        if not rig.MhxShapekeyDrivers:
            layout.label("No shapekey drivers.")
            layout.label("Set %s values in mesh context instead" % name)
            return
        props = getProps(rig, prefix)
        if not props:
            layout.label("No %ss found" % name)
            return
    
        layout.operator("mhx.pose_reset_expressions", text="Reset %ss" % name).prefix=prefix
    
    Thomas Larsson's avatar
    Thomas Larsson committed
        layout.operator("mhx.pose_key_expressions", text="Key %ss" % name).prefix=prefix
    
        #layout.operator("mhx.update")
    
        layout.separator()
        for prop in props:
            row = layout.split(0.85)
    
            row.prop(rig, '["%s"]' % prop, text=prop[3:])
    
            row.operator("mhx.pose_pin_expression", text="", icon='UNPINNED').data = (prefix + ";" + prop)
        return
    
    
    
    class MhxExpressionUnitsPanel(bpy.types.Panel):
    
    Thomas Larsson's avatar
    Thomas Larsson committed
        bl_label = "MHX Expression Tuning"
    
        bl_space_type = "VIEW_3D"
        bl_region_type = "UI"
        bl_options = {'DEFAULT_CLOSED'}
    
        @classmethod
        def poll(cls, context):
    
            return pollMhx(context.object)
    
            drawShapePanel(self, context, "Mhs", "expression")
    
    
    class MhxCustomShapePanel(bpy.types.Panel):
        bl_label = "MHX Custom Shapes"
        bl_space_type = "VIEW_3D"
        bl_region_type = "UI"
        bl_options = {'DEFAULT_CLOSED'}
    
        @classmethod
        def poll(cls, context):
            return pollMhx(context.object)
    
        def draw(self, context):
            drawShapePanel(self, context, "Mhc", "custom shape")
    
        restInv = pb.bone.matrix_local.inverted()
    
            parInv = pb.parent.matrix.inverted()
            parRest = pb.parent.bone.matrix_local
    
            return restInv * (parRest * (parInv * gmat))
    
    def getGlobalMatrix(mat, pb):
        gmat = pb.bone.matrix_local * mat
        if pb.parent:
            parMat = pb.parent.matrix
            parRest = pb.parent.bone.matrix_local
            return parMat * (parRest.inverted() * gmat)
        else:
            return gmat
    
    def matchPoseTranslation(pb, src, auto):
        pmat = getPoseMatrix(src.matrix, pb)
        insertLocation(pb, pmat, auto)
    
        pb.location = mat.to_translation()
        if auto:
            pb.keyframe_insert("location", group=pb.name)
        bpy.ops.object.mode_set(mode='OBJECT')
        bpy.ops.object.mode_set(mode='POSE')
    
    def matchPoseRotation(pb, src, auto):
        pmat = getPoseMatrix(src.matrix, pb)
        insertRotation(pb, pmat, auto)
    
    
    def printMatrix(string,mat):
        print(string)
        for i in range(4):
            print("    %.4g %.4g %.4g %.4g" % tuple(mat[i]))
    
        q = mat.to_quaternion()
        if pb.rotation_mode == 'QUATERNION':
            pb.rotation_quaternion = q
    
            if auto:
                pb.keyframe_insert("rotation_quaternion", group=pb.name)
    
        else:
            pb.rotation_euler = q.to_euler(pb.rotation_mode)
    
            if auto:
                pb.keyframe_insert("rotation_euler", group=pb.name)
    
        bpy.ops.object.mode_set(mode='OBJECT')
        bpy.ops.object.mode_set(mode='POSE')
    
    
    
    def matchIkLeg(legIk, toeFk, mBall, mToe, mHeel, auto):
        rmat = toeFk.matrix.to_3x3()
        tHead = Vector(toeFk.matrix.col[3][:3])
        ty = rmat.col[1]
        tail = tHead + ty * toeFk.bone.length
    
    
        try:
            zBall = mBall.matrix.col[3][2]
        except AttributeError:
            return
    
        zToe = mToe.matrix.col[3][2]
        zHeel = mHeel.matrix.col[3][2]
    
        x = Vector(rmat.col[0])
        y = Vector(rmat.col[1])
        z = Vector(rmat.col[2])
    
        if zHeel > zBall and zHeel > zToe:
            # 1. foot.ik is flat
            if abs(y[2]) > abs(z[2]):
                y = -z
            y[2] = 0
        else:
            # 2. foot.ik starts at heel
            hHead = Vector(mHeel.matrix.col[3][:3])
            y = tail - hHead
    
        y.normalize()
        x -= x.dot(y)*y
        x.normalize()
        z = x.cross(y)
        head = tail - y * legIk.bone.length
    
        # Create matrix
        gmat = Matrix()
        gmat.col[0][:3] = x
        gmat.col[1][:3] = y
        gmat.col[2][:3] = z
        gmat.col[3][:3] = head
        pmat = getPoseMatrix(gmat, legIk)
    
        insertLocation(legIk, pmat, auto)
        insertRotation(legIk, pmat, auto)
    
    
    
    def matchPoleTarget(pb, above, below, auto):
        x = Vector(above.matrix.col[1][:3])
        y = Vector(below.matrix.col[1][:3])
        p0 = Vector(below.matrix.col[3][:3])
        n = x.cross(y)
        if abs(n.length) > 1e-4:
            z = x - y
            n = n/n.length
            z -= z.dot(n)*n
            p = p0 + z/z.length*3.0
        else:
            p = p0
        gmat = Matrix.Translation(p)
        pmat = getPoseMatrix(gmat, pb)
        insertLocation(pb, pmat, auto)
    
    
    def matchPoseReverse(pb, src, auto):
        gmat = src.matrix
        tail = gmat.col[3] + src.length * gmat.col[1]
        rmat = Matrix((gmat.col[0], -gmat.col[1], -gmat.col[2], tail))
        rmat.transpose()
        pmat = getPoseMatrix(rmat, pb)
        pb.matrix_basis = pmat
        insertRotation(pb, pmat, auto)
    
    
    def matchPoseScale(pb, src, auto):
        pmat = getPoseMatrix(src.matrix, pb)
        pb.scale = pmat.to_scale()
    
        if auto:
            pb.keyframe_insert("scale", group=pb.name)
        bpy.ops.object.mode_set(mode='OBJECT')
        bpy.ops.object.mode_set(mode='POSE')
    
        prop,old,suffix = setSnapProp(rig, data, 1.0, context, False)
    
        auto = context.scene.tool_settings.use_keyframe_insert_auto
    
        print("Snap FK Arm%s" % suffix)
    
    Thomas Larsson's avatar
    Thomas Larsson committed
        snapFk,cnsFk = getSnapBones(rig, "ArmFK", suffix)
    
    Thomas Larsson's avatar
    Thomas Larsson committed
        muteConstraints(cnsFk, True)
    
        snapIk,cnsIk = getSnapBones(rig, "ArmIK", suffix)
        (uparmIk, loarmIk, elbow, elbowPt, handIk) = snapIk
    
        matchPoseRotation(uparmFk, uparmIk, auto)
        matchPoseScale(uparmFk, uparmIk, auto)
    
        matchPoseRotation(loarmFk, loarmIk, auto)
        matchPoseScale(loarmFk, loarmIk, auto)
    
        restoreSnapProp(rig, prop, old, context)
    
        try:
            matchHand = rig["MhaHandFollowsWrist" + suffix]
        except KeyError:
            matchHand = True
        if matchHand:
    
            matchPoseRotation(handFk, handIk, auto)
            matchPoseScale(handFk, handIk, auto)
    
        prop,old,suffix = setSnapProp(rig, data, 0.0, context, True)
        auto = context.scene.tool_settings.use_keyframe_insert_auto
    
    
        print("Snap IK Arm%s" % suffix)
    
    Thomas Larsson's avatar
    Thomas Larsson committed
        snapIk,cnsIk = getSnapBones(rig, "ArmIK", suffix)
    
        (uparmIk, loarmIk, elbow, elbowPt, handIk) = snapIk
    
    Thomas Larsson's avatar
    Thomas Larsson committed
        snapFk,cnsFk = getSnapBones(rig, "ArmFK", suffix)
    
    Thomas Larsson's avatar
    Thomas Larsson committed
        muteConstraints(cnsIk, True)
    
        matchPoseTranslation(handIk, handFk, auto)
        matchPoseRotation(handIk, handFk, auto)
    
    
        matchPoleTarget(elbowPt, uparmFk, loarmFk, auto)
    
    
        #matchPoseRotation(uparmIk, uparmFk, auto)
        #matchPoseRotation(loarmIk, loarmFk, auto)
    
    
        restoreSnapProp(rig, prop, old, context)
        #muteConstraints(cnsIk, False)
    
        prop,old,suffix = setSnapProp(rig, data, 1.0, context, False)
    
        auto = context.scene.tool_settings.use_keyframe_insert_auto
    
        print("Snap FK Leg%s" % suffix)
    
        snap,_ = getSnapBones(rig, "Leg", suffix)
        (upleg, loleg, foot, toe) = snap
    
        snapIk,cnsIk = getSnapBones(rig, "LegIK", suffix)
    
        (uplegIk, lolegIk, kneePt, ankleIk, legIk, footRev, toeRev, mBall, mToe, mHeel) = snapIk
    
    Thomas Larsson's avatar
    Thomas Larsson committed
        snapFk,cnsFk = getSnapBones(rig, "LegFK", suffix)
    
        (uplegFk, lolegFk, footFk, toeFk) = snapFk
    
    Thomas Larsson's avatar
    Thomas Larsson committed
        muteConstraints(cnsFk, True)
    
        matchPoseRotation(uplegFk, uplegIk, auto)
        matchPoseScale(uplegFk, uplegIk, auto)
    
        matchPoseRotation(lolegFk, lolegIk, auto)
        matchPoseScale(lolegFk, lolegIk, auto)
    
        restoreSnapProp(rig, prop, old, context)
    
    Thomas Larsson's avatar
    Thomas Larsson committed
        if not rig["MhaLegIkToAnkle" + suffix]:
    
            matchPoseReverse(footFk, footRev, auto)
            matchPoseReverse(toeFk, toeRev, auto)
    
        scn = context.scene
    
        prop,old,suffix = setSnapProp(rig, data, 0.0, context, True)
    
        auto = scn.tool_settings.use_keyframe_insert_auto