Skip to content
Snippets Groups Projects
io_import_scene_mhx.py 133 KiB
Newer Older
  • Learn to ignore specific revisions
  •                 cnslist.append((pb, cns, cns.influence))
                    cns.influence = 0
    
        for (pb, cns, inf) in cnslist:
            amt.bones.active = pb.bone
            cns.influence = 1
            #print("Childof %s %s %s %.2f" % (amt.name, pb.name, cns.name, inf))
            bpy.ops.constraint.childof_clear_inverse(constraint=cns.name, owner='BONE')
            bpy.ops.constraint.childof_set_inverse(constraint=cns.name, owner='BONE')
            cns.influence = 0
    
        for (pb, cns, inf) in cnslist:
            cns.influence = inf
        return
    
    
    #
    #    postProcess(args)
    #
    
    def postProcess(args):
        human = args[0]
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        try:
    
            ob = loadedData['Object'][human]
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        except:
            ob = None
        if toggle & T_Diamond == 0 and ob:
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    #
    #    deleteDiamonds(ob)
    #    Delete joint diamonds in main mesh
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        bpy.context.scene.objects.active = ob
        if not bpy.context.object:
            return
    
        print("Delete helper geometry in %s" % bpy.context.object)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        bpy.ops.object.mode_set(mode='EDIT')
        bpy.ops.mesh.select_all(action='DESELECT')
        bpy.ops.object.mode_set(mode='OBJECT')
        me = ob.data
    
        invisioNum = -1
        for mn,mat in enumerate(me.materials):
            if "Invis" in mat.name:
                invisioNum = mn
                break
        if invisioNum < 0:
            print("WARNING: Nu Invisio material found. Cannot delete helper geometry")
    
                if f.material_index >= invisioNum:
                    for vn in f.vertices:
                        me.vertices[vn].select = True
    
                if f.material_index >= invisioNum:
                    for vn in f.vertices:
                        me.vertices[vn].select = True
    
            theMessage = "\n  *** WARNING ***\nHelper deletion turned off due to Blender crash.\nHelpers can be deleted by deleting all selected vertices in Edit mode\n     **********\n"
            print(theMessage)
        else:
            bpy.ops.object.mode_set(mode='EDIT')
            print("Do delete")
            bpy.ops.mesh.delete(type='VERT')
            print("Verts deleted")
            bpy.ops.object.mode_set(mode='OBJECT')
            print("Back to object mode")
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    defaultKey(ext, args, tokens, var, exclude, glbals, lcals):
    
        #string = string.encode('utf-8', 'strict')
    
        # Alpha 7 compatibility
        if string[0:2] == "&_":
            string = "Mhf"+string[2:]
            alpha7 = True
        elif string[0] == "&":
            string = "Mha"+string[1:]
            alpha7 = True
        elif string[0] == "*":
            string = "Mhs"+string[1:]
            alpha7 = True
    
        elif len(string) > 4 and string[0:4] == "Hide":
    
        if string[0] == "_":
            return None,None
        elif (len(string) > 3 and
              string[0:3] in ["Mha", "Mhf", "Mhs", "Mhh", "Mhv", "Mhc"]):
    
            name = string.replace("-","_")
    
            return string, '["%s"]' % string
    
    
    def defProp(args, var, glbals, lcals):
        proptype = args[0]
        name = propNames(args[1])[0]
    
        rest = 'description="%s"' % args[3].replace("_", " ")
        if len(args) > 4:
            rest += ", " + args[4]
    
        if name:
    
            #expr = 'bpy.types.Object.%s = %sProperty(%s)' % (name, proptype, rest)
            expr = '%s["%s"] = %s' % (var, name, value)
    
            exec(expr, glbals, lcals)
    
    def defNewProp(name, proptype, rest):
        expr = 'bpy.types.Object.%s = %sProperty(%s)' % (name, proptype, rest)
        print(expr)
        exec(expr)
    
    
    def setProperty(args, var, glbals, lcals):
        global theProperty
        tip = ""
        name = propNames(args[0])[0]
        value = args[1]
        if name:
            expr = '%s["%s"] = %s' % (var, name, value)
            exec(expr, glbals, lcals)
    
            if len(args) > 2:
                tip = 'description="%s"' % args[2].replace("_", " ")
            if value in ["True", "False"]:
                proptype = "Bool"
            elif value[0] in ["'",'"']:
                proptype = "String"
            elif "." in value:
                proptype = "Float"
            else:
                proptype = "Int"
            theProperty = (name, tip, proptype)
    
    
    def defineProperty(args):
        global theProperty
        if theProperty is None:
            return
        (name, tip, proptype) = theProperty
        if len(args) >= 2 and proptype != "Bool":
            if "BOOLEAN" in args[1]:
                proptype = "Bool"
            else:
    
                tip = tip + "," + args[1].replace(":", "=").replace('"', " ")
    
        expr = "bpy.types.Object.%s = %sProperty(%s)" % (name, proptype, tip)
        theProperty = None
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    def defaultKey(ext, args, tokens, var, exclude, glbals, lcals):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
        if ext == 'Property':
    
            return setProperty(args, var, glbals, lcals)
    
        elif ext == 'PropKeys':
            return defineProperty(args)
    
        elif ext == 'DefProp':
            return defProp(args, var, glbals, lcals)
    
    
        if ext == 'bpyops':
            expr = "bpy.ops.%s" % args[0]
            print(expr)
            exec(expr)
            return
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        nvar = "%s.%s" % (var, ext)
        #print(ext)
        if ext in exclude:
            return
        #print("D", nvar)
    
        if len(args) == 0:
    
            MyError("Key length 0: %s" % ext)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        rnaType = args[0]
        if rnaType == 'Add':
            print("*** Cannot Add yet ***")
            return
    
        elif rnaType == 'Refer':
            typ = args[1]
            name = args[2]
            data = "loadedData['%s']['%s']" % (typ, name)
    
        elif rnaType == 'Struct' or rnaType == 'Define':
            typ = args[1]
            name = args[2]
            try:
                data = eval(nvar, glbals, lcals)
            except:
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            # print("Old structrna", nvar, data)
    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                try:
                    creator = args[3]
                except:
                    creator = None
                # print("Creator", creator, eval(var,glbals,lcals))
    
                try:
                    rna = eval(var,glbals,lcals)
                    data = eval(creator)
                except:
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                # print("New struct", nvar, typ, data)
    
            if rnaType == 'Define':
                loadedData[typ][name] = data
    
            if data:
                for (key, val, sub) in tokens:
                    defaultKey(key, val, sub, "data", [], globals(), locals())
    
            print("Struct done", nvar)
            return
    
        elif rnaType == 'PropertyRNA':
    
            MyError("PropertyRNA!")
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            #print("PropertyRNA ", ext, var)
            for (key, val, sub) in tokens:
                defaultKey(ext, val, sub, nvar, [], glbals, lcals)
            return
    
        elif rnaType == 'Array':
            for n in range(1, len(args)):
                expr = "%s[%d] = %s" % (nvar, n-1, args[n])
                exec(expr, glbals, lcals)
            if len(args) > 0:
                expr = "%s[0] = %s" % (nvar, args[1])
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            return
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        elif rnaType == 'List':
            data = []
            for (key, val, sub) in tokens:
                elt = eval(val[1], glbals, lcals)
                data.append(elt)
    
        elif rnaType == 'Matrix':
            return
            i = 0
            n = len(tokens)
            for (key, val, sub) in tokens:
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                    for j in range(n):
                        expr = "%s[%d][%d] = %g" % (nvar, i, j, float(val[j]))
                        exec(expr, glbals, lcals)
                    i += 1
            return
    
        else:
            try:
                data = loadedData[rnaType][args[1]]
                #print("From loaded", rnaType, args[1], data)
                return data
            except:
                data = rnaType
    
        #print(var, ext, data)
        expr = "%s = %s" % (nvar, data)
        try:
            exec(expr, glbals, lcals)
        except:
            pushOnTodoList(var, expr, glbals, lcals)
        return
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        global todo
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        print(dir(eval(var, glbals, lcals)))
    
        MyError(
            "Unrecognized expression %s.\n"  % expr +
            "This can mean that Blender's python API has changed\n" +
            "since the MHX file was exported. Try to export again\n" +
            "from an up-to-date MakeHuman nightly build.\n" +
            "Alternatively, your Blender version may be obsolete.\n" +
            "Download an up-to-date version from www.graphicall.org")
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        todo.append((expr, glbals, lcals))
        return
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    parseBoolArray(mask):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def parseBoolArray(mask):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        list = []
        for c in mask:
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                list.append(False)
            else:
                list.append(True)
        return list
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    parseMatrix(args, tokens)
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def parseMatrix(args, tokens):
    
        matrix = mathutils.Matrix()
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        i = 0
        for (key, val, sub) in tokens:
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                matrix[i][0] = float(val[0])
                matrix[i][1] = float(val[1])
                matrix[i][2] = float(val[2])
                matrix[i][3] = float(val[3])
                i += 1
        return matrix
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    parseDefault(data, tokens, subkeys, exclude):
    
    def parseDefault(data, tokens, subkeys, exclude):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            if key in subkeys.keys():
                for (key2, val2, sub2) in sub:
                    defaultKey(key2, val2, sub2, "data.%s" % subkeys[key], [], globals(), locals())
            else:
                defaultKey(key, val, sub, "data", exclude, globals(), locals())
    
    
    def parseCollection(data, tokens, exclude):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    extractBpyType(data):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    def extractBpyType(data):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        typeSplit = str(type(data)).split("'")
        if typeSplit[0] != '<class ':
            return None
        classSplit = typeSplit[1].split(".")
        if classSplit[0] == 'bpy' and classSplit[1] == 'types':
            return classSplit[2]
        elif classSplit[0] == 'bpy_types':
            return classSplit[1]
        else:
            return None
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    Bool(string):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def Bool(string):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        if string == 'True':
            return True
        elif string == 'False':
            return False
        else:
    
            MyError("Bool %s?" % string)
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    invalid(condition):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def invalid(condition):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        global rigLeg, rigArm, toggle
        res = eval(condition, globals())
        try:
            res = eval(condition, globals())
            #print("%s = %s" % (condition, res))
            return not res
        except:
            #print("%s invalid!" % condition)
            return True
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    clearScene(context):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    def clearScene():
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        global toggle
        scn = bpy.context.scene
        for n in range(len(scn.layers)):
            scn.layers[n] = True
    
        return scn
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        print("clearScene %s %s" % (toggle & T_Replace, scn))
        if not toggle & T_Replace:
            return scn
    
        for ob in scn.objects:
    
            if ob.type in ['MESH', 'ARMATURE', 'EMPTY', 'CURVE', 'LATTICE']:
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                scn.objects.active = ob
    
                try:
                    bpy.ops.object.mode_set(mode='OBJECT')
                except:
                    pass
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                scn.objects.unlink(ob)
                del ob
    
    
        for grp in bpy.data.groups:
            grp.name = "#" + grp.name
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        #print(scn.objects)
        return scn
    
    #
    #    hideLayers(args):
    #    args = sceneLayers sceneHideLayers boneLayers boneHideLayers or nothing
    #
    
    def hideLayers(args):
        if len(args) > 1:
            sceneLayers = int(args[2], 16)
            sceneHideLayers = int(args[3], 16)
            boneLayers = int(args[4], 16)
    
            # boneHideLayers = int(args[5], 16)
            boneHideLayers = 0
    
        else:
            sceneLayers = 0x00ff
            sceneHideLayers = 0
            boneLayers = 0
            boneHideLayers = 0
    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        scn = bpy.context.scene
    
        mask = 1
        hidelayers = []
        for n in range(20):
            scn.layers[n] = True if sceneLayers & mask else False
            if sceneHideLayers & mask:
                hidelayers.append(n)
            mask = mask << 1
    
        for ob in scn.objects:
            for n in hidelayers:
                if ob.layers[n]:
                    ob.hide = True
    
            human = args[1]
            try:
                ob = loadedData['Object'][human]
            except:
                return
    
            mask = 1
            hidelayers = []
            for n in range(32):
                ob.data.layers[n] = True if boneLayers & mask else False
                if boneHideLayers & mask:
                    hidelayers.append(n)
                mask = mask << 1
    
            for b in ob.data.bones:
                for n in hidelayers:
                    if b.layers[n]:
                        b.hide = True
    
        return
    
    
    #
    #    readDefaults():
    #    writeDefaults():
    #
    
    ConfigFile = '~/mhx_import.cfg'
    
    
    def readDefaults():
    
        global toggle, toggleSettings, theScale
    
        path = os.path.realpath(os.path.expanduser(ConfigFile))
        try:
            fp = open(path, 'rU')
            print('Storing defaults')
        except:
            print('Cannot open "%s" for reading' % path)
            return
        bver = ''
    
            words = line.split()
            if len(words) >= 3:
                try:
                    toggle = int(words[0],16)
                    theScale = float(words[1])
                except:
    
                    print('Configuration file "%s" is corrupt' % path)
    
        global toggleSettings, theScale
    
        path = os.path.realpath(os.path.expanduser(ConfigFile))
        try:
            fp = open(path, 'w')
            print('Storing defaults')
        except:
            print('Cannot open "%s" for writing' % path)
            return
    
        fp.write("%x %f Graphicall" % (toggleSettings, theScale))
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return
    
    ###################################################################################
    #
    #   Postprocessing of rigify rig
    #
    
    #
    ###################################################################################
    
    
    class RigifyBone:
        def __init__(self, eb):
            self.name = eb.name
            self.realname = None
            self.realname1 = None
            self.realname2 = None
            self.fkname = None
            self.ikname = None
    
            self.head = eb.head.copy()
            self.tail = eb.tail.copy()
            self.roll = eb.roll
            self.deform = eb.use_deform
            self.parent = None
            self.child = None
            self.connect = False
            self.original = False
    
        def __repr__(self):
            return ("<RigifyBone %s %s %s>" % (self.name, self.realname, self.realname1))
    
    def rigifyMhx(context):
        from collections import OrderedDict
    
    
        print("Modifying MHX rig to Rigify")
    
        ob = context.object
        if ob.type == 'ARMATURE':
            rig = ob
        elif ob.type == 'MESH':
            rig = ob.parent
        else:
            rig = None
        if not(rig and rig.type == 'ARMATURE'):
            raise NameError("Rigify: %s is neither an armature nor has armature parent" % ob)
        rig.MhxRigify = True
        scn.objects.active = rig
    
        group = None
        for grp in bpy.data.groups:
            if rig.name in grp.objects:
                group = grp
                break
    
        print("Group: %s" % group)
    
        # Setup info about MHX bones
    
        bones = OrderedDict()
        bpy.ops.object.mode_set(mode='EDIT')
        for eb in rig.data.edit_bones:
            bone = bones[eb.name] = RigifyBone(eb)
    
                bone.parent = eb.parent.name
                bones[bone.parent].child = eb.name
    
        bpy.ops.object.mode_set(mode='OBJECT')
    
        # Create metarig
    
        try:
            bpy.ops.object.armature_human_metarig_add()
        except AttributeError:
            raise MyError("The Rigify add-on is not enabled. It is found under rigging.")
    
        bpy.ops.object.location_clear()
        bpy.ops.object.rotation_clear()
        bpy.ops.object.scale_clear()
        bpy.ops.transform.resize(value=(100, 100, 100))
        bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
    
        bpy.ops.object.mode_set(mode='EDIT')
    
            try:
                eb = meta.data.edit_bones[bone.name]
            except KeyError:
                eb = None
            if eb:
                eb.head = bone.head
                eb.tail = bone.tail
                eb.roll = bone.roll
                bone.original = True
            elif bone.extra:
                extra.append(bone.name)
                bone.original = True
                eb = meta.data.edit_bones.new(bone.name)
                eb.use_connect = False
                eb.head = bones[bone.parent].tail
                eb.tail = bones[bone.child].head
                eb.roll = bone.roll
                parent = meta.data.edit_bones[bone.parent]
                child = meta.data.edit_bones[bone.child]
                child.parent = eb
                child.head = bones[bone.child].head
                parent.tail = bones[bone.parent].tail
                eb.parent = parent
                eb.use_connect = True
    
        # Add rigify properties to extra bones
    
        bpy.ops.object.mode_set(mode='OBJECT')
    
        for bname in extra:
            pb = meta.pose.bones[bname]
    
        bpy.ops.pose.rigify_generate()
    
        gen = context.object
        print("Generated", gen)
    
        for bone in bones.values():
            if bone.original:
                setBoneName(bone, gen)
    
        bpy.ops.object.mode_set(mode='EDIT')
        layers = 32*[False]
        layers[1] = True
        for bone in bones.values():
            if not bone.original:
                if bone.deform:
                    bone.realname = "DEF-" + bone.name
                else:
                    bone.realname = "MCH-" + bone.name
                eb = gen.data.edit_bones.new(bone.realname)
                eb.head = bone.head
                eb.tail = bone.tail
                eb.roll = bone.roll
                eb.use_deform = bone.deform
                if bone.parent:
                    parent = bones[bone.parent]
                    if parent.realname:
                        eb.parent = gen.data.edit_bones[parent.realname]
                    elif parent.realname1:
                        eb.parent = gen.data.edit_bones[parent.realname1]
                    else:
                        print(bone)
                eb.use_connect = (eb.parent != None and eb.parent.tail == eb.head)
                eb.layers = layers
    
        bpy.ops.object.mode_set(mode='OBJECT')
        for bone in bones.values():
            if not bone.original:
                pb = gen.pose.bones[bone.realname]
                db = rig.pose.bones[bone.name]
                pb.rotation_mode = db.rotation_mode
                for cns1 in db.constraints:
                    cns2 = pb.constraints.new(cns1.type)
    
                    fixConstraint(cns1, cns2, gen, bones)
    
        # Add MHX properties
    
        if rig.animation_data:
            for fcu1 in rig.animation_data.drivers:
                rna,channel = fcu1.data_path.rsplit(".", 1)
                pb = eval("gen.%s" % rna)
                fcu2 = pb.driver_add(channel, fcu1.array_index)
    
    
        # Copy MHX morph drivers and change armature modifier
        for ob in rig.children:
            if ob.type == 'MESH':
                ob.parent = gen
    
                if ob.data.animation_data:
                    for fcu in ob.data.animation_data.drivers:
                        print(ob, fcu.data_path)
    
                if ob.data.shape_keys and ob.data.shape_keys.animation_data:
                    for fcu in ob.data.shape_keys.animation_data.drivers:
                        print(skey, fcu.data_path)
    
                for mod in ob.modifiers:
                    if mod.type == 'ARMATURE' and mod.object == rig:
    
    
        # Parent widgets under empty
        empty = bpy.data.objects.new("Widgets", None)
        scn.objects.link(empty)
        empty.layers = 20*[False]
        empty.layers[19] = True
    
        for ob in scn.objects:
            if ob.type == 'MESH' and ob.name[0:4] == "WGT-" and not ob.parent:
                ob.parent = empty
    
        gen.show_x_ray = True
        gen.data.draw_type = 'STICK'
    
        name = rig.name
        scn.objects.unlink(rig)
        del rig
        gen.name = name
    
        print("MHX rig %s successfully rigified" % name)
    
    def setBoneName(bone, gen):
        fkname = bone.name.replace(".", ".fk.")
        try:
            gen.data.bones[fkname]
            bone.fkname = fkname
            bone.ikname = fkname.replace(".fk.", ".ik")
        except KeyError:
            pass
    
        defname = "DEF-" + bone.name
        try:
            gen.data.bones[defname]
            bone.realname = defname
            return
        except KeyError:
            pass
    
        defname1 = "DEF-" + bone.name + ".01"
        try:
            gen.data.bones[defname1]
            bone.realname1 = defname1
            bone.realname2 = defname1.replace(".01.", ".02.")
            return
        except KeyError:
            pass
    
        defname1 = "DEF-" + bone.name.replace(".", ".01.")
        try:
            gen.data.bones[defname1]
            bone.realname1 = defname1
            bone.realname2 = defname1.replace(".01.", ".02")
    
        try:
            gen.data.edit_bones[bone.name]
            bone.realname = bone.name
        except KeyError:
            pass
    
    def fixConstraint(cns1, cns2, gen, bones):
        for key in dir(cns1):
            if ((key[0] != "_") and
                (key not in ["bl_rna", "type", "rna_type", "is_valid", "error_location", "error_rotation"])):
                expr = ("cns2.%s = cns1.%s" % (key, key))
                exec(expr)
    
        cns2.target = gen
    
        if cns1.type == 'STRETCH_TO':
            bone = bones[cns1.subtarget]
            if bone.realname:
                cns2.subtarget = bone.realname
                cns2.head_tail = cns1.head_tail
            elif not bone.realname1:
                print(bone)
                halt
            elif cns1.head_tail < 0.5:
                cns2.subtarget = bone.realname1
                cns2.head_tail = 2*cns1.head_tail
            else:
                cns2.subtarget = bone.realname2
                cns2.head_tail = 2*cns1.head_tail-1
    
        elif cns1.type == 'TRANSFORM':
            bone = bones[cns1.subtarget]
            if bone.fkname:
                cns2.subtarget = bone.fkname
            elif bone.ikname:
                cns2.subtarget = bone.ikname
            else:
                cns2.subtarget = bone.realname
    
    
    def copyDriver(fcu1, fcu2, id):
        drv1 = fcu1.driver
        drv2 = fcu2.driver
    
        for var1 in drv1.variables:
            var2 = drv2.variables.new()
            var2.name = var1.name
            var2.type = var1.type
            targ1 = var1.targets[0]
            targ2 = var2.targets[0]
            targ2.id = id
            targ2.data_path = targ1.data_path
    
        drv2.type = drv1.type
        drv2.expression = drv1.expression
        drv2.show_debug_info = drv1.show_debug_info
    
    
    def changeDriverTarget(fcu, id):
        for var in fcu.driver.variables:
            targ = var.targets[0]
    
    
    #
    #   class OBJECT_OT_RigifyMhxButton(bpy.types.Operator):
    #
    
    class OBJECT_OT_RigifyMhxButton(bpy.types.Operator):
        bl_idname = "mhxrig.rigify_mhx"
        bl_label = "Rigify MHX rig"
    
    
        def execute(self, context):
    
    #
    #   class RigifyMhxPanel(bpy.types.Panel):
    #
    
    class RigifyMhxPanel(bpy.types.Panel):
        bl_label = "Rigify MHX"
        bl_space_type = "VIEW_3D"
        bl_region_type = "UI"
    
        @classmethod
        def poll(cls, context):
            if context.object:
    
                return context.object.MhxRigify
    
            return False
    
        def draw(self, context):
    
    Thomas Dinges's avatar
    Thomas Dinges committed
            self.layout.operator("mhxrig.rigify_mhx")
    
            return
    
    ###################################################################################
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    #    Error popup
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    ###################################################################################
    
    from bpy.props import StringProperty, FloatProperty, EnumProperty, BoolProperty
    
    
    class ErrorOperator(bpy.types.Operator):
        bl_idname = "mhx.error"
        bl_label = "Error when loading MHX file"
    
        def execute(self, context):
            return {'RUNNING_MODAL'}
    
        def invoke(self, context, event):
            global theErrorLines
            maxlen = 0
            for line in theErrorLines:
                if len(line) > maxlen:
                    maxlen = len(line)
            width = 20+5*maxlen
            height = 20+5*len(theErrorLines)
            #self.report({'INFO'}, theMessage)
            wm = context.window_manager
            return wm.invoke_props_dialog(self, width=width, height=height)
    
        def draw(self, context):
            global theErrorLines
    
                self.layout.label(line)
    
    def MyError(message):
        global theMessage, theErrorLines, theErrorStatus
        theMessage = message
        theErrorLines = message.split('\n')
        theErrorStatus = True
        bpy.ops.mhx.error('INVOKE_DEFAULT')
    
        raise MhxError(theMessage)
    
    class MhxError(Exception):
        def __init__(self, value):
            self.value = value
        def __str__(self):
            return repr(self.value)
    
    
    class SuccessOperator(bpy.types.Operator):
        bl_idname = "mhx.success"
        bl_label = "MHX file successfully loaded:"
        message = StringProperty()
    
        def execute(self, context):
            return {'RUNNING_MODAL'}
    
        def invoke(self, context, event):
            wm = context.window_manager
            return wm.invoke_props_dialog(self)
    
        def draw(self, context):
    
            self.layout.label(self.message + theMessage)
    
    
    ###################################################################################
    #
    #    User interface
    #
    ###################################################################################
    
    
    
    MhxBoolProps = [
        ("enforce", "Enforce version", "Only accept MHX files of correct version", T_EnforceVersion),
    
        #("crash_safe", "Crash-safe", "Disable features that have caused Blender crashes", T_CrashSafe),
    
        ("mesh", "Mesh", "Use main mesh", T_Mesh),
        ("proxy", "Proxies", "Use proxies", T_Proxy),
    
        #("armature", "Armature", "Use armature", T_Armature),
    
        #("replace", "Replace scene", "Replace scene", T_Replace),
    
        ("cage", "Cage", "Load mesh deform cage", T_Cage),
        ("clothes", "Clothes", "Include clothes", T_Clothes),
    
        ("shapekeys", "Shapekeys", "Include shapekeys", T_Shapekeys),
        ("shapedrivers", "Shapekey drivers", "Include shapekey drivers", T_ShapeDrivers),
    
        #("symm", "Symmetric shapes", "Keep shapekeys symmetric", T_Symm),
    
        ("diamond", "Helper geometry", "Keep helper geometry", T_Diamond),
    
        ("rigify", "Rigify", "Create rigify control rig", T_Rigify),
    
    ]
    
    class ImportMhx(bpy.types.Operator, ImportHelper):
    
        """Import from MHX file format (.mhx)"""
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        bl_idname = "import_scene.makehuman_mhx"
        bl_description = 'Import from MHX file format (.mhx)'
        bl_label = "Import MHX"
        bl_space_type = "PROPERTIES"
        bl_region_type = "WINDOW"
    
        bl_options = {'UNDO'}
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
        filename_ext = ".mhx"
        filter_glob = StringProperty(default="*.mhx", options={'HIDDEN'})
    
        filepath = StringProperty(subtype='FILE_PATH')
    
        scale = FloatProperty(name="Scale", description="Default meter, decimeter = 1.0", default = theScale)
        advanced = BoolProperty(name="Advanced settings", description="Use advanced import settings", default=False)
    
        for (prop, name, desc, flag) in MhxBoolProps:
    
            expr = '%s = BoolProperty(name="%s", description="%s", default=(toggleSettings&%s != 0))' % (prop, name, desc, flag)
    
        def draw(self, context):
            layout = self.layout
            layout.prop(self, "scale")
            layout.prop(self, "advanced")
            if self.advanced:
                for (prop, name, desc, flag) in MhxBoolProps:
                    layout.prop(self, prop)
    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        def execute(self, context):
    
            global toggle, toggleSettings, theScale, MhxBoolProps
            if not self.advanced:
                toggle = DefaultToggle
            else:
                toggle = T_Armature
                for (prop, name, desc, flag) in MhxBoolProps:
                    expr = '(%s if self.%s else 0)' % (flag, prop)
                    toggle |=  eval(expr)
                toggleSettings = toggle
    
            print("execute flags %x" % toggle)