Beispiel #1
0
def importDeformers(fileName):
    deformerDict = json.loads(open(fileName).read())
    fileDir = '\\'.join(fileName.split('\\')[:-1])

    for key in deformerDict.keys():
        geo = deformerDict[key]['geo']
        pm.select(geo)
        dfm = pm.nonLinear(name=key, type=deformerDict[key]['nlType'])
        pm.xform(dfm[1], ws=1, m=deformerDict[key]['mtx'])
        parent = deformerDict[key]['parent']
        if parent:
            dfm[1].setParent(parent)
        for param in deformerDict[key]['params'].keys():
            attr = pm.Attribute(('%s.%s' % (dfm[0].name(), param)))
            if not attr.isArray():
                attr.set(deformerDict[key]['params'][param])
        for conn in deformerDict[key]['conns'].keys():
            pm.Attribute(deformerDict[key]['conns'][conn]).connect(
                '%s.%s' % (dfm[0].name(), conn))
        for g in geo:
            weightsFile = '%s_%s_weights.xml' % (g, key)

            pm.select(g)
            try:
                pm.deformerWeights(weightsFile,
                                   im=1,
                                   deformer=dfm[0],
                                   path=fileDir)
            except:
                print 'unable to load weights:\n\tdeformer: %s\n\tshape: %s\n\tweightsFile: %s' % (
                    dfm[0], g, weightsFile)
Beispiel #2
0
def import_deformer_weights(WORKING_DIR):
    files = [x for x in os.listdir(WORKING_DIR) if x[-4:] == '.xml']

    for f in files:
        file_path = os.path.join(WORKING_DIR, f)
        deformer_xml = xml.etree.ElementTree.parse(file_path)

        # only made for one skincluster per mesh
        geo = None
        joints = []
        for atype in deformer_xml.findall('shape'):
            geo = pm.ls(atype.get('name'))[0]
        for atype in deformer_xml.findall('weights'):
            joints.append(atype.get('source'))
        print(str(geo) + " > " + str(joints))

        # create the skincluster and apply it to the geo
        # note: geo is shape-node
        skin_cluster = pm.skinCluster(joints,
                                      geo,
                                      toSelectedBones=True,
                                      bindMethod=0,
                                      skinMethod=0,
                                      normalizeWeights=0,
                                      inf=1)
        # already connected? then assign manually
        #skin_cluster = pm.ls("skinCluster1")[0]
        print(skin_cluster)

        pm.deformerWeights(f, deformer=skin_cluster, path=WORKING_DIR, im=1)
        pm.select(geo)
        mel.eval("skinPercent -normalize true " + skin_cluster)
Beispiel #3
0
    def rebind(self, mesh_display=pm.warning, joint_display=pm.warning):
        """
        Rebinds meshes with skin clusters based on the date in the stored info class variable.

        Args:
            mesh_display (method): How to display a missing mesh.

            joint_display (method): How to display a missing joint.
        """
        for mesh, info in self.info.items():

            path = info['path']
            if not pm.objExists(mesh):
                mesh_display(mesh + ' does not exist! Will not be rebound')
                os.remove(path)
                continue

            # make sure mesh is unique, and that joints exist
            mesh = pm.PyNode(mesh)
            joints = info['joints']
            joints = [
                pm.PyNode(joint)
                if pm.objExists(joint) else joint_display('Missed ' + joint)
                for joint in joints
            ]

            pm.select(mesh, joints)
            skin_name = info['skin']
            max_influences = info['max_influences']
            pm.skinCluster(tsb=True,
                           fnw=True,
                           mi=max_influences,
                           name=skin_name,
                           omi=True)

            directory = os.path.dirname(path)
            deformer_name = os.path.basename(path)
            pm.deformerWeights(deformer_name,
                               im=True,
                               m='index',
                               df=skin_name,
                               e=True,
                               p=directory)
            os.remove(path)
            print('# Imported deformer weights from ' + path + ' to ' +
                  mesh.nodeName())

        # select meshes to end it all
        pm.select(self.info.keys())

        if not os.listdir(self.directory):
            os.rmdir(self.directory)
Beispiel #4
0
def saveDeformers():
    saveFilePath = pm.fileDialog2(fileFilter='*.json')[0]
    if saveFilePath:
        saveFileDir = '/'.join(saveFilePath.split('/')[:-1]) + '/'
        dfms = [dfm for dfm in pm.ls() if pm.nodeType(dfm) in deformerTypes]
        deformerDict = {}

        for dfm in dfms:
            key = dfm.name()
            handle = getHandle(dfm)
            deformerDict[key] = {}
            deformerDict[key]['nlType'] = getNonlinearType(dfm)
            deformerDict[key]['mtx'] = pm.xform(handle, q=1, ws=1, m=1)
            parent = None
            if handle.getParent():
                parent = handle.getParent().name()
            deformerDict[key]['parent'] = parent
            deformerDict[key]['params'] = {}
            deformerDict[key]['geo'] = [
                geo for geo in pm.nonLinear(dfm, q=1, geometry=1)
            ]
            for geo in deformerDict[key]['geo']:
                fileName = '%s_%s_weights.xml' % (geo, key)
                toSkip = [node.name() for node in dfms if not node == dfm]
                pm.deformerWeights(fileName,
                                   export=1,
                                   sh=geo,
                                   skip=toSkip,
                                   path=saveFileDir)
            attrs = [
                a for a in pm.listAttr(dfm)
                if pm.Attribute('%s.%s' %
                                (key, a)).isKeyable() and not 'weight' in a
            ]
            for attr in attrs:
                deformerDict[key]['params'][attr] = pm.getAttr(
                    '%s.%s' % (dfm.name(), attr))
            deformerDict[key]['conns'] = {}
            for attr in attrs:
                if not pm.Attribute('%s.%s' % (key, attr)).isArray():
                    conn = pm.listConnections('%s.%s' % (key, attr),
                                              plugs=1,
                                              d=0)
                    if conn:
                        deformerDict[key]['conns'][attr] = conn[0].name()

        with open(saveFilePath, 'w') as outfile:
            json.dump(deformerDict, outfile)
Beispiel #5
0
    def unbind(self, meshes=None, bind_pose=True):
        """
        Unbinds the skin clusters from the given meshes (will use selection or all meshes in scene if None).
        Stores skin cluster weights in a temp file to be rebound with the rebind method.

        Args:
            meshes (list): Meshes to unbind.

            bind_pose (boolean): If True will move joints back to the bind pose before unbinding.

        Returns:
            (dictionary): All the info gathered  from unbinding joints.
        """
        # reset info
        self.info = {}
        scene_path = pm.sceneName()
        scene_name = os.path.splitext(
            scene_path.name)[0] + '_' if scene_path else ''
        meshes = myu.validateSelect(meshes, find='mesh', parent=True)
        pcu.validateDirectory(self.directory)

        for mesh in meshes:
            # get the skin of the mesh, if it doesnt exist then we don't need to store skin weights
            mesh_name = mesh.nodeName()
            skin = mesh.listHistory(type='skinCluster')

            if not skin:
                continue

            # get the info we need to rebind the mesh: skin name, max influences, and joints influencing mesh
            # stored as string in case object gets deleted and renamed after unbinding
            skin = skin[0].nodeName()
            max_influences = pm.skinCluster(mesh, q=True, mi=True)
            joints = [
                joint.nodeName()
                for joint in pm.skinCluster(skin, q=True, influence=True)
            ]

            if bind_pose:
                returnToBindPose(joints)

            # select mesh, export skin weights, and detach skin using MEL because pm.bindSkin(delete=True) has errors.
            pm.select(mesh)
            deformer_name = scene_name + mesh_name + '.xml'
            path = pm.deformerWeights(deformer_name,
                                      export=True,
                                      deformer=skin,
                                      path=self.directory)
            pm.mel.eval('doDetachSkin "2" { "1","1" }')

            self.info[mesh_name] = {
                'skin': skin,
                'max_influences': max_influences,
                'joints': joints,
                'path': path
            }

        pm.select(meshes)
        return self.info
Beispiel #6
0
def reset(obj):
    obj = pym.PyNode(obj)
    dmN = pym.listHistory(obj, type="deltaMush")[0]
    scenePath = os.path.dirname(pym.sceneName())
    if scenePath == "":
        scenePath = pym.workspace.path
    fileName = os.path.basename(pym.sceneName())
    wmPath = os.path.join(
        scenePath,
        "_deformer_wm"
    ).replace("\\", "/")

    if not os.path.exists(wmPath):
        os.makedirs(wmPath)

    partName = obj.name()
    if ":" in partName:
        partName = partName.split(":")[-1]
    assetName = fileName.split("_")[0]
    wmName = "deltaMush_{0}_{1}.xml".format(partName, assetName)
    pym.deformerWeights(wmName, export=True, path=wmPath, deformer=dmN)
    dmAttrs = {}
    for attr in DeltaMush_Attrs:
        val = dmN.getAttr(attr)
        dmAttrs[attr] = val
    dmN.setGeometry([obj], rm=True)
    pym.delete(dmN)

    if obj.namespace() != '':
        dmNewName = "{0}:{1}_{2}_deltaMush".format(
            obj.namespace(), partName, assetName
        )
    else:
        dmNewName = "{0}_{1}_deltaMush".format(partName, assetName)

    dmN = pym.deltaMush(obj, n=dmNewName)
    for attr in dmAttrs:
        dmN.setAttr(attr, dmAttrs[attr])
    pym.deformerWeights(wmName, im=True, path=wmPath, deformer=dmN)
Beispiel #7
0
def export_deformer_weights(geo, path):
    assert geo.type() == 'transform'
    shape = [
        sh for sh in pm.listRelatives(geo, s=1) if sh.name() == geo + "Shape"
    ][0]
    assert shape.type() == 'mesh'

    # due to our export it's only going to be 1 cluster anyway
    cl = shape.listConnections(t='skinCluster')[0]
    name = shape.name() + "_" + cl.name() + ".xml"
    try:
        file_name = pm.deformerWeights(name, deformer=cl, path=path, export=1)
    except:
        print(shape.name() + " has no skinClusters to export.")
Beispiel #8
0
def skin_mesh(meshes, main_node):
    """

    :param meshes:
    :param main_node: Main network node.
    :return:
    """
    try:
        pymel.skinCluster(meshes, edit=True, unbind=True)
    except:
        pass

    xml = 'body_skin_weights.xml'

    path = os.path.join(siteCustomize.ROOT_DIR, 'skin_data')
    root = main_node.spine[0].jnts[0]

    skin_list = []

    for jnt in root.listRelatives(allDescendents=True):
        if jnt.hasAttr('_skin') and jnt._skin.get() == 'True':
            skin_list.append(jnt)

    skin_list.append(root)

    skin_list.extend(meshes)

    skin_cluster = pymel.skinCluster(skin_list,
                                     toSelectedBones=True,
                                     maximumInfluences=4)

    pymel.deformerWeights(xml,
                          im=True,
                          deformer=skin_cluster,
                          method='index',
                          path=path)
Beispiel #9
0
dM.reset("iBird43:BODY")
p
dm = pym.ls(sl=1)[0]
dm.name()
dm.listAttr()
pym.workspace.path

mainCTL = pym.ls("main_control", type="transform", r=True)[0]
wiregrp = pym.ls("WIRE", r=True)[0]
for child in wiregrp.listRelatives(ad=True, type="mesh"):
    dMN = child.listHistory(type="deltaMush")
    if dMN:
        print child.name()
        dM.connectScale(child, mainCTL)

dM.connectScale("iBird43:BODY", "iBird43:main_control")

dm = pym.deltaMush("BODY", n="iBird43_BODY_dm")
pym.deltaMush("deltaMush20", g=["BODY"], rm=True, e=True)
pym.deltaMush("BODY", n="iBird43_deltaMush")
dm20 = pym.PyNode("BODY")
dm20.namespace()
pym.delete(dm20)
pym.sceneName()
dmN = pym.listHistory("BODY", type="deltaMush")[0]
pym.deformerWeights("deltamush_BODY_iBird43.xml", export=True, path="E:/FreeLanceWork/Genoma/PRJ_FLOWER/scenes/iBird43/_deformer_wm", deformer=dmN)
dmN.setGeometry(["BODY"], rm=True)
pym.delete(dmN)
dmN = pym.deltaMush("BODY", n="iBird43_deltaMush")
pym.deformerWeights("deltamush_BODY_iBird43.xml", im=True, path="E:/FreeLanceWork/Genoma/PRJ_FLOWER/scenes/iBird43/_deformer_wm", deformer=dmN)