Ejemplo n.º 1
0
    def loadPreset(self, filename, selector, folder=mh.getSysDataPath("rigs/")):
        filepath = os.path.join(folder, filename + ".json")
        struct = io_json.loadJson(filepath)
        self.__init__()
        try:
            self.rigtype = struct["name"]
        except KeyError:
            pass
        try:
            self.description = struct["description"]
        except KeyError:
            pass
        try:
            self.merge = struct["merge"]
        except KeyError:
            pass
        try:
            settings = struct["settings"]
        except KeyError:
            settings = {}
        for key,value in list(settings.items()):
            expr = ("self.%s = %s" % (key, value))
            exec(expr)

        if selector is not None:
            selector.fromOptions(self)
        try:
            bones = struct["bones"]
        except KeyError:
            bones = None
        if bones:
            self.locale = Locale(bones=bones)
        return self.description
Ejemplo n.º 2
0
 def load(self, filepath=None):
     if self.bones:
         return
     if filepath:
         self.filepath = filepath
     struct = io_json.loadJson(self.filepath)
     #self.language = struct["language"]
     self.bones = struct["bones"]
Ejemplo n.º 3
0
 def load(self, filepath=None):
     if self.bones:
         return
     if filepath:
         self.filepath = filepath
     struct = io_json.loadJson(self.filepath)
     #self.language = struct["language"]
     self.bones = struct["bones"]
Ejemplo n.º 4
0
 def readVertexGroupFiles(self, files):
     vgroups = OrderedDict()
     for file in files:
         filepath = os.path.join(mh.getSysPath("shared/armature/data"), "vgrp_"+file+".json")
         log.message("Loading %s" % filepath)
         vglist = io_json.loadJson(filepath)
         for key,data in vglist:
             try:
                 vgroups[key] += data
             except KeyError:
                 vgroups[key] = data
         #readVertexGroups(filepath, vgroups, vgroups)
     return vgroups
Ejemplo n.º 5
0
 def readVertexGroupFiles(self, files):
     vgroups = OrderedDict()
     for file in files:
         try:
             folder, fname = file
         except:
             folder = getSysDataPath("vertexgroups")
             fname = file
         filepath = os.path.join(folder, "vgrp_" + fname + ".json")
         log.message("Loading %s" % filepath)
         vglist = io_json.loadJson(filepath)
         for key, data in vglist:
             try:
                 vgroups[key] += data
             except KeyError:
                 vgroups[key] = data
         #readVertexGroups(filepath, vgroups, vgroups)
     return vgroups
Ejemplo n.º 6
0
 def readVertexGroupFiles(self, files):
     vgroups = OrderedDict()
     for file in files:
         try:
             folder,fname = file
         except:
             folder = getSysDataPath("vertexgroups")
             fname = file
         filepath = os.path.join(folder, "vgrp_"+fname+".json")
         log.message("Loading %s" % filepath)
         vglist = io_json.loadJson(filepath)
         for key,data in vglist:
             try:
                 vgroups[key] += data
             except KeyError:
                 vgroups[key] = data
         #readVertexGroups(filepath, vgroups, vgroups)
     return vgroups
Ejemplo n.º 7
0
    def calcBindMatrices(self):
        import io_json
        self.bindMatrix = tm.rotation_matrix(math.pi/2, XUnit)
        self.bindInverse = la.inv(self.bindMatrix)

        if self.options.useTPose:
            filepath = "tools/blender26x/mh_mocap_tool/t_pose.json"
            blist = io_json.loadJson(filepath)
            for bname,quat in blist:
                pmat = tm.quaternion_matrix(quat)
                log.debug("TPose %s %s" % ( bname, pmat))
                self.bones[bname].matrixTPose = pmat
        else:
            for bone in list(self.bones.values()):
                bone.matrixTPose = None

        for bone in list(self.bones.values()):
            bone.calcBindMatrix()
Ejemplo n.º 8
0
    def loadPreset(self, filepath, selector):
        struct = io_json.loadJson(filepath)
        self._setDefaults()
        try:
            self.rigtype = struct["name"]
        except KeyError:
            pass
        try:
            self.description = struct["description"]
        except KeyError:
            pass
        try:
            self.merge = struct["merge"]
        except KeyError:
            pass
        try:
            self.terminals = struct["terminals"]
        except KeyError:
            pass
        try:
            self.useTerminators = struct["use_terminators"]
        except KeyError:
            pass
        try:
            settings = struct["settings"]
        except KeyError:
            settings = {}
        for key,value in settings.items():
            if hasattr(self, key):
                setattr(self, key, value)
            else:
                log.warning("Unknown property defined in armature options file %s" % filename)

        if selector is not None:
            selector.fromOptions(self)
        try:
            bones = struct["bones"]
        except KeyError:
            bones = None
        if bones:
            self.locale = Locale(bones=bones)
        return self.description
Ejemplo n.º 9
0
    def loadPreset(self, filepath, selector):
        struct = io_json.loadJson(filepath)
        self._setDefaults()
        try:
            self.rigtype = struct["name"]
        except KeyError:
            pass
        try:
            self.description = struct["description"]
        except KeyError:
            pass
        try:
            self.merge = struct["merge"]
        except KeyError:
            pass
        try:
            self.terminals = struct["terminals"]
        except KeyError:
            pass
        try:
            settings = struct["settings"]
        except KeyError:
            settings = {}
        for key,value in settings.items():
            if hasattr(self, key):
                setattr(self, key, value)
            else:
                log.warning("Unknown property defined in armature options file %s" % filename)

        if selector is not None:
            selector.fromOptions(self)
        try:
            bones = struct["bones"]
        except KeyError:
            bones = None
        if bones:
            self.locale = Locale(bones=bones)
        return self.description
Ejemplo n.º 10
0
    def createBones(self, boneInfo):
        amt = self.armature
        options = amt.options

        if amt.done:
            halt
        amt.done = True

        self.addBones(rig_bones.Armature, boneInfo)
        self.addBones(rig_face.Armature, boneInfo)

        for bname in options.terminals.keys():
            pname, _offset = options.terminals[bname]
            parent = boneInfo[pname]
            self.addBones({bname: (0, pname, 0, parent.layers)}, boneInfo)

        if options.useMasterBone:
            self.master = 'master'
            self.addBones(rig_control.MasterArmature, boneInfo)

        if options.useReverseHip:
            hiphead, hiptail = self.headsTails["hips"]
            self.headsTails["root"] = (hiptail, (hiptail, (0, 0, -2)))
            self.headsTails["hips"] = (hiptail, hiphead)
            self.customShapes["hips"] = "GZM_CircleHips"
            self.root = "root"
            root = boneInfo["root"] = Bone(amt, "root")
            root.type = "Null"
            root.fromInfo((0, None, F_WIR, L_MAIN))
            hips = boneInfo["hips"]
            hips.parent = "root"
            hips.conn = False
            hips.lockLocation = (1, 1, 1)
            spine = boneInfo["spine"]
            spine.parent = "root"
            spine.conn = False

        if options.useMuscles:
            self.addBones(rig_muscle.Armature, boneInfo)

        if options.useFaceRig:
            self.addBones(rig_face.FaceRigArmature, boneInfo)

        if options.useHeadControl:
            self.addBones(rig_control.HeadArmature, boneInfo)
            if options.useConstraints:
                self.setConstraints(rig_control.HeadConstraints)
                self.propDrivers += rig_control.HeadPropDrivers

        if options.useSockets and options.useConstraints:
            self.changeParents(rig_control.SocketParents, boneInfo)
            self.addBones(rig_control.SocketArmature, boneInfo)
            self.setConstraints(rig_control.SocketConstraints)
            self.lrPropDrivers += rig_control.SocketPropLRDrivers

        if options.useIkLegs and options.useConstraints:
            self.addBones(rig_control.RevFootArmature, boneInfo)
            self.setConstraints(rig_control.RevFootConstraints)
            self.addBones(rig_control.MarkerArmature, boneInfo)
            self.lrPropDrivers += rig_control.IkLegPropLRDrivers
            self.addIkChains(rig_bones.Armature, boneInfo,
                             rig_control.IkLegChains)
            self.reparentMarkers(rig_control.LegMarkers, boneInfo)

        if options.useIkArms and options.useConstraints:
            self.addBones(rig_control.IkArmArmature, boneInfo)
            self.setConstraints(rig_control.IkArmConstraints)
            self.lrPropDrivers += rig_control.IkArmPropLRDrivers
            self.addIkChains(rig_bones.Armature, boneInfo,
                             rig_control.IkArmChains)

        if options.useFingers and options.useConstraints:
            self.addBones(rig_control.FingerArmature, boneInfo)

        if options.useConstraints and options.useLocks:
            for bname, limits in self.rotationLimits.items():
                try:
                    bone = boneInfo[bname]
                except KeyError:
                    continue
                minX, maxX, minY, maxY, minZ, maxZ = limits
                lockX, lockY, lockZ = bone.lockRotation
                if minX == maxX == 0:
                    lockX = 1
                if minY == maxY == 0:
                    lockY = 1
                if minZ == maxZ == 0:
                    lockZ = 1
                bone.lockRotation = lockX, lockY, lockZ
                if minX != None and options.useRotationLimits and bone.lockRotation != (
                        1, 1, 1):
                    cns = ("LimitRot", C_LOCAL, 0.8,
                           ["LimitRot", limits, (1, 1, 1)])
                    self.addConstraint(bname, cns)

            for bname, limits in self.locationLimits.items():
                try:
                    bone = boneInfo[bname]
                except KeyError:
                    continue
                minX, maxX, minY, maxY, minZ, maxZ = limits
                cns = ("LimitLoc", C_LOCAL, 1,
                       ["LimitLoc", limits, (1, 1, 1, 1, 1, 1)])
                self.addConstraint(bname, cns)

        if options.useCorrectives:
            self.addCSysBones(rig_control.CoordinateSystems, boneInfo)

        if options.addConnectingBones:
            extras = []
            for bone in boneInfo.values():
                if bone.parent:
                    head, _ = self.headsTails[bone.name]
                    _, ptail = self.headsTails[bone.parent]
                    if head != ptail:
                        connector = Bone(amt, "_" + bone.name)
                        connector.layers = L_HELP
                        connector.parent = bone.parent
                        bone.parent = connector.name
                        extras.append(connector)
                        self.headsTails[connector.name] = (ptail, head)
            for bone in extras:
                boneInfo[bone.name] = bone

        if options.useCustomShapes:
            struct = io_json.loadJson("data/mhx/gizmos.json")
            addDict(struct, self.gizmos)

        vgroups = self.readVertexGroupFiles(self.vertexGroupFiles)
        addDict(vgroups, amt.vertexWeights)

        if options.merge:
            self.mergeBones(options.merge, boneInfo)
        else:
            if options.mergeSpine:
                self.mergeBones(rig_merge.SpineMergers, boneInfo)
            if options.mergeShoulders:
                self.mergeBones(rig_merge.ShoulderMergers, boneInfo)
            if options.mergeFingers:
                self.mergeBones(rig_merge.FingerMergers, boneInfo)
            if options.mergePalms:
                self.mergeBones(rig_merge.PalmMergers, boneInfo)
            if options.mergeHead:
                self.mergeBones(rig_merge.HeadMergers, boneInfo)

        if options.useDeformNames or options.useDeformBones:
            generic = mergeDicts([
                rig_bones.Armature,
                rig_face.Armature,
            ])
            if options.useDeformBones:
                self.addDeformBones(generic, boneInfo)
                self.renameDeformBones(rig_muscle.Armature,
                                       rig_muscle.CustomShapes, boneInfo)
                if options.useConstraints:
                    self.renameConstraints(rig_muscle.Constraints, boneInfo)
            custom = {}
            if options.useCustomShapes:
                addDict(rig_muscle.CustomShapes, custom)
                if options.useFaceRig:
                    addDict(rig_face.FaceRigCustomShapes, custom)
            self.addDeformVertexGroups(vgroups, custom)
            #self.renameDeformVertexGroups(rig_muscle.Armature)

        if options.useSplitBones or options.useSplitNames:
            if options.useSplitBones:
                self.addSplitBones(boneInfo)
            self.addSplitVertexGroups(vgroups)

        if options.useLeftRight:
            leftright = self.readVertexGroupFiles(["leftright"])
            for name, vgroup in leftright.items():
                amt.vertexWeights[name] = vgroup

        for bname, bone in boneInfo.items():
            if bone.parent:
                bone.parent = self.getRealBoneName(bone.parent, boneInfo)
                parent = boneInfo[bone.parent]
                parent.children.append(bone)
            elif self.master:
                if bone.name == self.master:
                    amt.roots.append(bone)
                else:
                    bone.parent = self.master
                    master = boneInfo[self.master]
                    master.children.append(bone)
            else:
                amt.roots.append(bone)

        for root in amt.roots:
            self.sortBones(root, amt.hierarchy)

        for bname, data in self.customShapes.items():
            bname = self.getRealBoneName(bname, boneInfo, False)
            try:
                amt.bones[bname].customShape = data
            except KeyError:
                log.message("Warning: custom shape for undefined bone %s" %
                            bname)

        for bname, data in self.constraints.items():
            bname = self.getRealBoneName(bname, boneInfo, False)
            try:
                amt.bones[bname].constraints = data
            except KeyError:
                log.message("Warning: constraint for undefined bone %s" %
                            bname)
Ejemplo n.º 11
0
def loadBinaryProxy(path, human, type):
    log.debug("Loading binary proxy %s.", path)

    npzfile = np.load(path)
    #if type is None:
    #    proxyType = npzfile['proxyType'].tostring()
    #else:
    proxyType = type

    proxy = Proxy(path, proxyType, human)

    proxy.name = npzfile['name'].tostring()
    proxy.uuid = npzfile['uuid'].tostring()
    proxy.basemesh = npzfile['basemesh'].tostring()

    proxy.tags = set(_unpackStringList(npzfile['tags_str'], npzfile['tags_idx']))

    if 'z_depth' in npzfile:
        proxy.z_depth = int(npzfile['z_depth'])

    if 'max_pole' in npzfile:
        proxy.max_pole = int(npzfile['max_pole'])

    proxy.num_refverts = int(npzfile['num_refverts'])

    if proxy.num_refverts == 3:
        proxy.ref_vIdxs = npzfile['ref_vIdxs']
        proxy.offsets = npzfile['offsets']
        proxy.weights = npzfile['weights']
    else:
        num_refs = npzfile['ref_vIdxs'].shape[0]
        proxy.ref_vIdxs = np.zeros((num_refs,3), dtype=np.uint32)
        proxy.ref_vIdxs[:,0] = npzfile['ref_vIdxs']
        proxy.offsets = np.zeros((num_refs,3), dtype=np.float32)
        proxy.weights = np.zeros((num_refs,3), dtype=np.float32)
        proxy.weights[:,0] = npzfile['weights']

    if "deleteVerts" in npzfile:
        proxy.deleteVerts = npzfile['deleteVerts']

    # Reconstruct reverse vertex (and weights) mapping
    proxy._reloadReverseMapping()

    proxy.tmatrix = TMatrix()

    proxy.uvLayers = {}
    for uvIdx, uvName in enumerate(_unpackStringList(npzfile['uvLayers_str'], npzfile['uvLayers_idx'])):
        uvLayers[uvIdx] = uvName

    proxy.material = material.Material(proxy.name)
    if 'material_file' in npzfile:
        proxy._material_file = npzfile['material_file'].tostring()
    if proxy.material_file:
        proxy.material.fromFile(proxy.material_file)

    proxy._obj_file = npzfile['obj_file'].tostring()

    if 'vertexgroup_file' in npzfile:
        proxy._vertexgroup_file = npzfile['vertexgroup_file'].tostring()
        if proxy.vertexgroup_file:
            proxy.vertexGroups = io_json.loadJson(proxy.vertexgroup_file)

    # Just set the defaults for these, no idea if they are still relevant
    proxy.wire = False
    proxy.cage = False
    proxy.modifiers = []
    proxy.shapekeys = []


    if proxy.z_depth == -1:
        log.warning('Proxy file %s does not specify a Z depth. Using 50.', path)
        proxy.z_depth = 50

    return proxy
Ejemplo n.º 12
0
def loadTextProxy(human, filepath, type="Clothes"):
    from codecs import open
    try:
        fp = open(filepath, "rU", encoding="utf-8")
    except IOError:
        log.error("*** Cannot open %s", filepath)
        return None

    folder = os.path.realpath(os.path.expanduser(os.path.dirname(filepath)))
    proxy = Proxy(filepath, type, human)
    refVerts = []

    status = 0
    vnum = 0
    for line in fp:
        words = line.split()

        if len(words) == 0:
            # Reset status on empty line
            #status = 0
            continue

        if words[0].startswith('#') or words[0].startswith('//'):
            # Comment
            continue

        key = words[0]

        if key == 'name':
            proxy.name = " ".join(words[1:])
        elif key == 'uuid':
            proxy.uuid = " ".join(words[1:])
        elif key == 'tag':
            proxy.tags.append( " ".join(words[1:]).lower() )
        elif key == 'z_depth':
            proxy.z_depth = int(words[1])
        elif key == 'max_pole':
            proxy.max_pole = int(words[1])

        elif key == 'verts':
            status = doRefVerts
        elif key == 'weights':
            status = doWeights
            if proxy.weights == None:
                proxy.weights = {}
            weights = []
            proxy.weights[words[1]] = weights
        elif key == "delete_verts":
            status = doDeleteVerts

        elif key == 'obj_file':
            proxy._obj_file = _getFileName(folder, words[1], ".obj")

        elif key == 'vertexgroup_file':
            proxy.vertexgroup_file = _getFileName(folder, words[1], ".json")
            proxy.vertexGroups = io_json.loadJson(proxy.vertexgroup_file)

        elif key == 'material':
            matFile = _getFileName(folder, words[1], ".mhmat")
            proxy._material_file = matFile
            proxy.material.fromFile(proxy.material_file)

        elif key == 'backface_culling':
            # TODO remove in future
            log.warning('Deprecated parameter "backface_culling" used in proxy file. Set property backfaceCull in material instead.')
        elif key == 'transparent':
            # TODO remove in future
            log.warning('Deprecated parameter "transparent" used in proxy file. Set property in material file instead.')

        elif key == 'uvLayer':
            if len(words) > 2:
                layer = int(words[1])
                uvFile = words[2]
            else:
                layer = 0
                uvFile = words[1]
            #uvMap = material.UVMap(proxy.name+"UV"+str(layer))
            #uvMap.read(proxy.mesh, _getFileName(folder, uvFile, ".mhuv"))
            # Delayed load, only store path here
            proxy.uvLayers[layer] = _getFileName(folder, uvFile, ".mhuv")

        elif key == 'x_scale':
            proxy.tmatrix.getScaleData(words, 0)
        elif key == 'y_scale':
            proxy.tmatrix.getScaleData(words, 1)
        elif key == 'z_scale':
            proxy.tmatrix.getScaleData(words, 2)

        elif key == 'shear_x':
            proxy.tmatrix.getShearData(words, 0, None)
        elif key == 'shear_y':
            proxy.tmatrix.getShearData(words, 1, None)
        elif key == 'shear_z':
            proxy.tmatrix.getShearData(words, 2, None)
        elif key == 'l_shear_x':
            proxy.tmatrix.getShearData(words, 0, 'Left')
        elif key == 'l_shear_y':
            proxy.tmatrix.getShearData(words, 1, 'Left')
        elif key == 'l_shear_z':
            proxy.tmatrix.getShearData(words, 2, 'Left')
        elif key == 'r_shear_x':
            proxy.tmatrix.getShearData(words, 0, 'Right')
        elif key == 'r_shear_y':
            proxy.tmatrix.getShearData(words, 1, 'Right')
        elif key == 'r_shear_z':
            proxy.tmatrix.getShearData(words, 2, 'Right')

        elif key == 'uniform_scale':
            proxy.uniformScale = True
            if len(words) > 1:
                proxy.scaleCorrect = float(words[1])
            proxy.uniformizeScale()

        # TODO are these still used? otherwise we can issue deprecation warnings
        # Blender-only properties
        elif key == 'wire':
            proxy.wire = True
        elif key == 'cage':
            proxy.cage = True
        elif key == 'subsurf':
            levels = int(words[1])
            if len(words) > 2:
                render = int(words[2])
            else:
                render = levels+1
            proxy.modifiers.append( ['subsurf', levels, render] )
        elif key == 'shrinkwrap':
            offset = float(words[1])
            proxy.modifiers.append( ['shrinkwrap', offset] )
        elif key == 'solidify':
            thickness = float(words[1])
            offset = float(words[2])
            proxy.modifiers.append( ['solidify', thickness, offset] )
        elif key == 'shapekey':
            proxy.shapekeys.append( _getFileName(folder, words[1], ".target") )
        elif key == 'basemesh':
            proxy.basemesh = words[1]

        elif key in ['objfile_layer', 'uvtex_layer', 'use_projection', 'mask_uv_layer', 'texture_uv_layer', 'delete']:
            log.warning('Deprecated parameter "%s" used in proxy file. Please remove.', key)


        elif status == doRefVerts:
            refVert = ProxyRefVert(human)
            refVerts.append(refVert)
            if len(words) == 1:
                proxy.num_refverts = 1
                refVert.fromSingle(words, vnum, proxy.vertWeights)
            else:
                proxy.num_refverts = 3
                refVert.fromTriple(words, vnum, proxy.vertWeights)
            vnum += 1

        elif status == doWeights:
            v = int(words[0])
            w = float(words[1])
            weights.append((v,w))

        elif status == doDeleteVerts:
            sequence = False
            for v in words:
                if v == "-":
                    sequence = True
                else:
                    v1 = int(v)
                    if sequence:
                        for vn in range(v0,v1+1):
                            proxy.deleteVerts[vn] = True
                        sequence = False
                    else:
                        proxy.deleteVerts[v1] = True
                    v0 = v1

        else:
            log.warning('Unknown keyword %s found in proxy file %s', key, filepath)

    if proxy.z_depth == -1:
        log.warning('Proxy file %s does not specify a Z depth. Using 50.', filepath)
        proxy.z_depth = 50

    proxy._finalize(refVerts)

    return proxy
Ejemplo n.º 13
0
    def createBones(self, boneInfo):
        amt = self.armature
        options = amt.options

        if amt.done:
            halt
        amt.done = True

        self.addBones(rig_bones.Armature, boneInfo)
        if options.useTerminators:
            self.addBones(rig_bones.TerminatorArmature, boneInfo)
        self.addBones(rig_face.Armature, boneInfo)

        for bname in options.terminals.keys():
            pname,_offset = options.terminals[bname]
            parent = boneInfo[pname]
            self.addBones({bname: (0, pname, 0, parent.layers)}, boneInfo)

        if options.useMasterBone:
            self.master = 'master'
            self.addBones(rig_control.MasterArmature, boneInfo)

        if options.useReverseHip:
            hiphead, hiptail = self.headsTails["hips"]
            self.headsTails["root"] = (hiptail, (hiptail,(0,0,-2)))
            self.headsTails["hips"] = (hiptail, hiphead)
            self.customShapes["hips"] = "GZM_CircleHips"
            self.root = "root"
            root = boneInfo["root"] = Bone(amt, "root")
            root.type = "Null"
            root.fromInfo((0, None, F_WIR, L_MAIN))
            hips = boneInfo["hips"]
            hips.parent = "root"
            hips.conn = False
            hips.lockLocation = (1,1,1)
            spine = boneInfo["spine"]
            spine.parent = "root"
            spine.conn = False

        if options.useMuscles:
            self.addBones(rig_muscle.Armature, boneInfo)

        if options.useFaceRig:
            self.addBones(rig_face.FaceRigArmature, boneInfo)

        if options.useHeadControl:
            self.addBones(rig_control.HeadArmature, boneInfo)
            if options.useConstraints:
                self.setConstraints(rig_control.HeadConstraints)
                self.propDrivers += rig_control.HeadPropDrivers

        if options.useSockets and options.useConstraints:
            self.changeParents(rig_control.SocketParents, boneInfo)
            self.addBones(rig_control.SocketArmature, boneInfo)
            self.setConstraints(rig_control.SocketConstraints)
            self.lrPropDrivers += rig_control.SocketPropLRDrivers

        if options.useIkLegs and options.useConstraints:
            self.addBones(rig_control.RevFootArmature, boneInfo)
            self.setConstraints(rig_control.RevFootConstraints)
            self.addBones(rig_control.MarkerArmature, boneInfo)
            self.lrPropDrivers += rig_control.IkLegPropLRDrivers
            self.addIkChains(rig_bones.Armature, boneInfo, rig_control.IkLegChains)
            self.reparentMarkers(rig_control.LegMarkers, boneInfo)

        if options.useIkArms and options.useConstraints:
            self.addBones(rig_control.IkArmArmature, boneInfo)
            self.setConstraints(rig_control.IkArmConstraints)
            self.lrPropDrivers += rig_control.IkArmPropLRDrivers
            self.addIkChains(rig_bones.Armature, boneInfo, rig_control.IkArmChains)

        if options.useFingers and options.useConstraints:
            self.addBones(rig_control.FingerArmature, boneInfo)

        if options.useConstraints and options.useLocks:
            for bname,limits in self.rotationLimits.items():
                try:
                    bone = boneInfo[bname]
                except KeyError:
                    continue
                minX,maxX, minY,maxY, minZ,maxZ = limits
                lockX,lockY,lockZ = bone.lockRotation
                if minX == maxX == 0:
                    lockX = 1
                if minY == maxY == 0:
                    lockY = 1
                if minZ == maxZ == 0:
                    lockZ = 1
                bone.lockRotation = lockX,lockY,lockZ
                if minX != None and options.useRotationLimits and bone.lockRotation != (1,1,1):
                    cns = ("LimitRot", C_LOCAL, 0.8, ["LimitRot", limits, (1,1,1)])
                    self.addConstraint(bname, cns)

            for bname,limits in self.locationLimits.items():
                try:
                    bone = boneInfo[bname]
                except KeyError:
                    continue
                minX,maxX, minY,maxY, minZ,maxZ = limits
                cns = ("LimitLoc", C_LOCAL, 1, ["LimitLoc", limits, (1,1,1,1,1,1)])
                self.addConstraint(bname, cns)

        if options.useCorrectives:
            self.addCSysBones(rig_control.CoordinateSystems, boneInfo)

        if options.addConnectingBones:
            extras = []
            for bone in boneInfo.values():
                if bone.parent:
                    head,_ = self.headsTails[bone.name]
                    _,ptail = self.headsTails[bone.parent]
                    if head != ptail:
                        connector = Bone(amt, "_"+bone.name)
                        connector.layers = L_HELP
                        connector.parent = bone.parent
                        bone.parent = connector.name
                        extras.append(connector)
                        self.headsTails[connector.name] = (ptail, head)
            for bone in extras:
                boneInfo[bone.name] = bone

        if options.useCustomShapes:
            addDict(io_json.loadJson("data/mhx/gizmos-face.json"), self.gizmos)
            if options.useCustomShapes == "all":
                addDict(io_json.loadJson("data/mhx/gizmos.json"), self.gizmos)

        vgroups = self.readVertexGroupFiles(self.vertexGroupFiles)
        addDict(vgroups, amt.vertexWeights)

        if options.merge:
            self.mergeBones(options.merge, boneInfo)
        else:
            if options.mergeSpine:
                self.mergeBones(rig_merge.SpineMergers, boneInfo)
            if options.mergeShoulders:
                self.mergeBones(rig_merge.ShoulderMergers, boneInfo)
            if options.mergeFingers:
                self.mergeBones(rig_merge.FingerMergers, boneInfo)
            if options.mergePalms:
                self.mergeBones(rig_merge.PalmMergers, boneInfo)
            if options.mergeHead:
                self.mergeBones(rig_merge.HeadMergers, boneInfo)

        if options.useDeformNames or options.useDeformBones:
            generic = mergeDicts([
                rig_bones.Armature,
                rig_face.Armature,
            ])
            if options.useDeformBones:
                self.addDeformBones(generic, boneInfo)
                self.renameDeformBones(rig_muscle.Armature, rig_muscle.CustomShapes, boneInfo)
                if options.useConstraints:
                    self.renameConstraints(rig_muscle.Constraints, boneInfo)
            custom = {}
            if options.useCustomShapes:
                if options.useCustomShapes == "all":
                    if options.useMuscles:
                        addDict(rig_muscle.CustomShapes, custom)
                if options.useFaceRig:
                    addDict(rig_face.FaceRigCustomShapes, custom)
            self.addDeformVertexGroups(vgroups, custom)
            #self.renameDeformVertexGroups(rig_muscle.Armature)

        if options.useSplitBones or options.useSplitNames:
            if options.useSplitBones:
                self.addSplitBones(boneInfo)
            self.addSplitVertexGroups(vgroups)

        if options.useLeftRight:
            leftright = self.readVertexGroupFiles(["leftright"])
            for name,vgroup in leftright.items():
                amt.vertexWeights[name] = vgroup

        for bname,bone in boneInfo.items():
            if bone.parent:
                bone.parent = self.getRealBoneName(bone.parent, boneInfo)
                parent = boneInfo[bone.parent]
                parent.children.append(bone)
            elif self.master:
                if bone.name == self.master:
                    amt.roots.append(bone)
                else:
                    bone.parent = self.master
                    master = boneInfo[self.master]
                    master.children.append(bone)
            else:
                amt.roots.append(bone)

        for root in amt.roots:
            self.sortBones(root, amt.hierarchy)

        for bname,data in self.customShapes.items():
            bname = self.getRealBoneName(bname, boneInfo, False)
            try:
                amt.bones[bname].customShape = data
            except KeyError:
                log.message("Warning: custom shape for undefined bone %s" % bname)

        for bname,data in self.constraints.items():
            bname = self.getRealBoneName(bname, boneInfo, False)
            try:
                amt.bones[bname].constraints = data
            except KeyError:
                log.message("Warning: constraint for undefined bone %s" % bname)
Ejemplo n.º 14
0
    def createBones(self, boneInfo):
        amt = self.armature
        options = amt.options

        if amt.done:
            halt
        amt.done = True

        self.addBones(rig_bones.Armature, boneInfo)
        self.addBones(rig_face.Armature, boneInfo)

        if options.useMasterBone:
            self.master = 'master'
            self.addBones(rig_control.MasterArmature, boneInfo)

        if options.useReverseHip:
            hiphead, hiptail = self.headsTails["hips"]
            self.headsTails["root"] = (hiptail, (hiptail,(0,0,-2)))
            self.headsTails["hips"] = (hiptail, hiphead)
            self.customShapes["hips"] = "GZM_CircleHips"
            self.root = "root"
            root = boneInfo["root"] = Bone(amt, "root")
            root.type = "Null"
            root.fromInfo((0, None, F_WIR, L_MAIN))
            hips = boneInfo["hips"]
            hips.parent = "root"
            hips.conn = False
            hips.lockLocation = (1,1,1)
            spine = boneInfo["spine"]
            spine.parent = "root"
            spine.conn = False

        if options.useMuscles:
            self.addBones(rig_muscle.Armature, boneInfo)

        if options.useHeadControl:
            self.addBones(rig_control.HeadArmature, boneInfo)
            if options.useConstraints:
                self.setConstraints(rig_control.HeadConstraints)
                self.propDrivers += rig_control.HeadPropDrivers

        if options.useIkLegs and options.useConstraints:
            self.addBones(rig_control.IkLegArmature, boneInfo)
            self.setConstraints(rig_control.IkLegConstraints)
            #addDict(rig_control.IkLegChains, self.ikChains)
            addDict(rig_control.IkLegParents, self.parents)
            self.lrPropDrivers += rig_control.IkLegPropLRDrivers
            self.addIkChains(rig_bones.Armature, boneInfo, rig_control.IkLegChains)

        if options.useIkArms and options.useConstraints:
            self.addBones(rig_control.IkArmArmature, boneInfo)
            self.setConstraints(rig_control.IkArmConstraints)
            #addDict(rig_control.IkArmChains, self.ikChains)
            addDict(rig_control.IkArmParents, self.parents)
            self.lrPropDrivers += rig_control.IkArmPropLRDrivers
            self.addIkChains(rig_bones.Armature, boneInfo, rig_control.IkArmChains)

        if options.useFingers and options.useConstraints:
            self.addBones(rig_control.FingerArmature, boneInfo)

        if options.useConstraints and options.useRotationLimits:
            for bname,limits in list(self.rotationLimits.items()):
                try:
                    bone = boneInfo[bname]
                except KeyError:
                    continue
                minX,maxX, minY,maxY, minZ,maxZ = limits
                if minX != None:
                    cns = ("LimitRot", C_LOCAL, 0.8, ["LimitRot", limits, (1,1,1)])
                    self.addConstraint(bname, cns)
                lockX,lockY,lockZ = bone.lockRotation
                if minY == maxY == 0:
                    lockY = 1
                if minZ == maxZ == 0:
                    lockZ = 1
                bone.lockRotation = lockX,lockY,lockZ

        if options.useCorrectives:
            self.addCSysBones(rig_control.CoordinateSystems, boneInfo)

        if options.addConnectingBones:
            extras = []
            for bone in list(boneInfo.values()):
                if bone.parent:
                    head,_ = self.headsTails[bone.name]
                    _,ptail = self.headsTails[bone.parent]
                    if head != ptail:
                        connector = Bone(amt, "_"+bone.name)
                        connector.parent = bone.parent
                        bone.parent = connector.name
                        extras.append(connector)
                        self.headsTails[connector.name] = (ptail, head)

            for bone in extras:
                boneInfo[bone.name] = bone

        if options.useCustomShapes:
            struct = io_json.loadJson("shared/armature/gizmos.json")
            for name,gizmo in list(self.customShapes.items()):
                if gizmo:
                    self.gizmos[gizmo] = struct[gizmo]

        if False and options.custom:
            (custJoints, custHeadsTails, custArmature, self.customProps) = exportutils.custom.setupCustomRig(options)
            self.joints += custJoints
            self.headsTails += custHeadsTails
            self.boneDefs += custArmature

        vgroups = self.getVertexGroups(boneInfo)

        if options.merge:
            self.mergeBones(options.merge, boneInfo)
        else:
            if options.mergeSpine:
                self.mergeBones(rig_merge.SpineMergers, boneInfo)
            if options.mergeShoulders:
                self.mergeBones(rig_merge.ShoulderMergers, boneInfo)
            if options.mergeFingers:
                self.mergeBones(rig_merge.FingerMergers, boneInfo)
            if options.mergePalms:
                self.mergeBones(rig_merge.PalmMergers, boneInfo)
            if options.mergeHead:
                self.mergeBones(rig_merge.HeadMergers, boneInfo)

        if options.useDeformNames or options.useDeformBones:
            generic = mergeDicts([
                rig_bones.Armature,
                rig_face.Armature,
            ])
            if options.useDeformBones:
                self.addDeformBones(generic, boneInfo)
                self.renameDeformBones(rig_muscle.Armature, rig_muscle.CustomShapes, boneInfo)
                if options.useConstraints:
                    self.renameConstraints(rig_muscle.Constraints, boneInfo)
            self.addDeformVertexGroups(vgroups, rig_muscle.CustomShapes)
            #self.renameDeformVertexGroups(rig_muscle.Armature)

        if options.useSplitBones or options.useSplitNames:
            if options.useSplitBones:
                self.addSplitBones(boneInfo)
            self.addSplitVertexGroups(vgroups)

        if options.useLeftRight:
            leftright = self.readVertexGroupFiles(["leftright"])
            for name,vgroup in list(leftright.items()):
                amt.vertexWeights[name] = vgroup

        for bname,bone in list(boneInfo.items()):
            if bone.parent:
                try:
                    parent = boneInfo[bone.parent]
                except KeyError:
                    log.message("Missing %s from %s" % (bone.parent, bone))
                    log.message(str(list(boneInfo.keys())))
                    halt
                parent.children.append(bone)
            elif self.master:
                if bone.name == self.master:
                    amt.roots.append(bone)
                else:
                    bone.parent = self.master
                    master = boneInfo[self.master]
                    master.children.append(bone)
            else:
                amt.roots.append(bone)

        for root in amt.roots:
            self.sortBones(root, amt.hierarchy)

        for bname,data in list(self.customShapes.items()):
            try:
                amt.bones[bname].customShape = data
            except KeyError:
                log.message("Warning: custom shape for undefined bone %s" % bname)

        for bname,data in list(self.constraints.items()):
            try:
                amt.bones[bname].constraints = data
            except KeyError:
                log.message("Warning: constraint for undefined bone %s" % bname)
Ejemplo n.º 15
0
def readProxyFile(obj, filepath, type="Clothes"):
    try:
        fp = open(filepath, "rU")
    except IOError:
        log.error("*** Cannot open %s", filepath)
        return None

    folder = os.path.realpath(os.path.expanduser(os.path.dirname(filepath)))

    proxy = Proxy(filepath, type)
    proxy.deleteVerts = np.zeros(len(obj.coord), bool)

    proxy.z_depth = -1
    proxy.max_pole = None
    proxy.useProjection = True
    proxy.ignoreOffset = False
    status = 0
    vnum = 0
    for line in fp:
        words = line.split()

        if len(words) == 0:
            # Reset status on empty line
            #status = 0
            continue

        if words[0].startswith('#') or words[0].startswith('//'):
            # Comment
            continue

        key = words[0]

        if key == 'name':
            proxy.name = " ".join(words[1:])
        elif key == 'uuid':
            proxy.uuid = " ".join(words[1:])
        elif key == 'tag':
            proxy.tags.append( " ".join(words[1:]).lower() )
        elif key == 'z_depth':
            proxy.z_depth = int(words[1])
        elif key == 'max_pole':
            proxy.max_pole = int(words[1])

        elif key == 'verts':
            status = doRefVerts
        elif key == 'weights':
            status = doWeights
            if proxy.weights == None:
                proxy.weights = {}
            weights = []
            proxy.weights[words[1]] = weights
        elif key == "delete_verts":
            status = doDeleteVerts

        elif key == 'obj_file':
            proxy.obj_file = getFileName(folder, words[1], ".obj")

        elif key == 'vertexgroup_file':
            proxy.vertexgroup_file = getFileName(folder, words[1], ".json")
            proxy.vertexGroups = io_json.loadJson(proxy.vertexgroup_file)

        elif key == 'material':
            matFile = getFileName(folder, words[1], ".mhmat")
            proxy.material_file = matFile
            proxy.material.fromFile(matFile)

        elif key == 'mhx_material':
            # Read .mhx material file (or only set a filepath reference to it)
            # MHX material file is supposed to contain only shading parameters that are specific for blender export that are not stored in the .mhmat file
            matFile = getFileName(folder, words[1], ".mhx")
            proxy.mhxMaterial_file = matFile
            #readMaterial(line, material, proxy, False)
            pass
        elif key == 'useBaseMaterials':
            # TODO deprecated?
            proxy.useBaseMaterials = True

        elif key == 'backface_culling':
            # TODO remove in future
            log.warning('Deprecated parameter "backface_culling" used in proxy file. Set property backfaceCull in material instead.')
        elif key == 'transparent':
            # TODO remove in future
            log.warning('Deprecated parameter "transparent" used in proxy file. Set property in material file instead.')

        elif key == 'uvLayer':
            if len(words) > 2:
                layer = int(words[1])
                uvFile = words[2]
            else:
                layer = 0
                uvFile = words[1]
            #uvMap = material.UVMap(proxy.name+"UV"+str(layer))
            #uvMap.read(proxy.mesh, getFileName(folder, uvFile, ".mhuv"))
            # Delayed load, only store path here
            proxy.uvLayers[layer] = getFileName(folder, uvFile, ".mhuv")

        elif key == 'x_scale':
            proxy.scaleData[0] = getScaleData(words)
            proxy.scale[0] = proxy.getScale(proxy.scaleData[0], obj, 0)
        elif key == 'y_scale':
            proxy.scaleData[1] = getScaleData(words)
            proxy.scale[1] = proxy.getScale(proxy.scaleData[1], obj, 1)
        elif key == 'z_scale':
            proxy.scaleData[2] = getScaleData(words)
            proxy.scale[2] = proxy.getScale(proxy.scaleData[2], obj, 2)
        elif key == 'uniform_scale':
            proxy.uniformScale = True
            if len(words) > 1:
                proxy.scaleCorrect = float(words[1])
            proxy.uniformizeScale()
        elif key == 'use_projection':
            # TODO still used?
            proxy.useProjection = int(words[1])
        elif key == 'ignoreOffset':
            # TODO still used?
            proxy.ignoreOffset = int(words[1])
        elif key == 'delete':
            proxy.deleteGroups.append(words[1])

        elif key == 'mask_uv_layer':
            if len(words) > 1:
                proxy.maskLayer = int(words[1])
        elif key == 'texture_uv_layer':
            if len(words) > 1:
                proxy.textureLayer = int(words[1])

        # TODO keep this costume stuff?
        elif key == 'clothing':
            if len(words) > 2:
                clothingPiece = (words[1], words[2])
            else:
                clothingPiece = (words[1], None)
            proxy.clothings.append(clothingPiece)
        elif key == 'transparencies':
            uuid = words[1]
            proxy.transparencies[uuid] = words[2].lower() in ["1", "yes", "true", "enable", "enabled"]

        # Blender-only properties
        elif key == 'wire':
            proxy.wire = True
        elif key == 'cage':
            proxy.cage = True
        elif key == 'subsurf':
            levels = int(words[1])
            if len(words) > 2:
                render = int(words[2])
            else:
                render = levels+1
            proxy.modifiers.append( ['subsurf', levels, render] )
        elif key == 'shrinkwrap':
            offset = float(words[1])
            proxy.modifiers.append( ['shrinkwrap', offset] )
        elif key == 'solidify':
            thickness = float(words[1])
            offset = float(words[2])
            proxy.modifiers.append( ['solidify', thickness, offset] )
        elif key == 'shapekey':
            proxy.shapekeys.append( getFileName(folder, words[1], ".target") )
        elif key == 'basemesh':
            proxy.basemesh = words[1]

        elif key in ['objfile_layer', 'uvtex_layer']:
            pass


        elif status == doRefVerts:
            refVert = ProxyRefVert(obj)
            proxy.refVerts.append(refVert)
            if len(words) == 1:
                refVert.fromSingle(words, vnum, proxy)
            else:
                refVert.fromTriple(words, vnum, proxy)
            vnum += 1

        elif status == doWeights:
            v = int(words[0])
            w = float(words[1])
            weights.append((v,w))

        elif status == doDeleteVerts:
            sequence = False
            for v in words:
                if v == "-":
                    sequence = True
                else:
                    v1 = int(v)
                    if sequence:
                        for vn in range(v0,v1+1):
                            proxy.deleteVerts[vn] = True
                        sequence = False
                    else:
                        proxy.deleteVerts[v1] = True
                    v0 = v1

        else:
            log.warning('Unknown keyword %s found in proxy file %s', key, filepath)

    if proxy.z_depth == -1:
        log.warning('Proxy file %s does not specify a Z depth. Using 50.', filepath)
        proxy.z_depth = 50

    return proxy