Home Website Youtube GitHub

Faster way to import multiple Skin Packs

Hello. Does anyone know if there is a faster way to import all your skin pack instead of doing it one by one? Is it possible to script this?

2 Likes

Hi Chantelle,

Yes of course. Everything can be scripted. :slight_smile:

Here is the shortest example possible, and then the actual script I use. But the actual script I use depends on the network path that I designed. I keep all of my build scripts and data files in a per-character folder, and then find that folder by querying the character name from the guide.

Short example:

from mgear.core import skin

skinPath = r"P:\my\production\drive\characters\billy\billySkin.jSkinPack"
skin.importSkinPack(skinpath)

My production example
Note: In os.path, you can use .. in the path to go UP a directory. So I climb up to my root rigging directory

import os
import sys
import pymel.core as pm
import mgear.shifter.custom_step as cstp
from mgear.core import skin


class CustomShifterStep(cstp.customShifterMainStep):
    def __init__(self):
        self.name = "import_skinning"
        self.charName = pm.PyNode('guide').rig_name.get()


    def run(self, stepDict):
        char = self.charName
        # Start by getting the path of this script that is running.
        postpath = os.path.abspath(os.path.dirname(__file__))
        # Then climb up to my root rigging directory
        basepath = os.path.abspath(os.path.join(postpath, '../../../..'))
        dataPath = 'data'
        # Here join will make a template that looks like basepath + dataPath + etc.
        # EXAMPLE: 'P:\production\rigging\data\characters\billy\skinning\skin.jSkinPack'
        skinpath = os.path.abspath(os.path.join(basepath, dataPath, 'characters', char, 'skinning', 'skin.jSkinPack'))
        
        if os.path.isfile(skinpath):
            skin.importSkinPack(skinpath)
        else:
            return False
        
        return

2 Likes

Ah that’s fantastic! This is a big help! Thank you very much!

Hi chrislesage,
I have a vehicle with multiple meshes and would like to transfer the skinning to the reference file. It is a custom rig and I didn’t use mgear for it. Is it still possible to use the export and import skin weights from mgear or the script you mentioned?

Thanks :slight_smile:

Hi @Utkarsh_Agnihotri yes it is! I use the export and import skin commands all the time.

The names and vertex count of your geo must match.

The script I shared looks at an mGear character .rig_name. So that requires mGear. And part of my script is also meant to find my directory in my production server.

But you could just use the:

skin.importSkinPack(skinpath) commands without all that extra stuff. Or just use the menu commands instead.

Here is a script I use to generically export skinning. It saves it to the same path as your currently saved file.

To export skinning (saves to your scene path ./skinning)

from mgear.core import skin
import pymel.core as pm
import sys
import os

# Set the basePath and make the dirs if necessary
basePath = os.path.split(pm.sceneName())[0]
skinPath = os.path.abspath(os.path.join(basePath, 'skinning'))
if not os.path.exists(skinPath):
    os.makedirs(skinPath)
configSkinPath = r"{}/{}.jSkin"


### Snippet: Export mGear weights
for each in pm.ls(type='skinCluster'):
    skinGeo = [x for x in each.outputs() if x.type() == 'transform']
    if skinGeo:
        newName = '{}_SkinCluster'.format(skinGeo[0])
        each.rename(newName)
for oBodyPart in pm.selected():
    bodyPart = oBodyPart.name()
    skinConfigPath = os.path.abspath(configSkinPath.format(skinPath, bodyPart))
    skin.exportSkin(skinConfigPath, [oBodyPart])
    print(skinConfigPath)

And to import skinning

from mgear.core import skin
import pymel.core as pm
import sys
import os

# Set the basePath and make the dirs if necessary
basePath = os.path.split(pm.sceneName())[0]
skinPath = os.path.abspath(os.path.join(basePath, 'skinning'))
if not os.path.exists(skinPath):
    os.makedirs(skinPath)
configSkinPath = r"{}/{}.jSkin"

### Snippet: Import mGear weights
for oBodyPart in pm.selected():
    bodyPart = oBodyPart.name()
    skinConfigPath = os.path.abspath(configSkinPath.format(skinPath, bodyPart))
    skin.importSkin(skinConfigPath, [oBodyPart])
    print(skinConfigPath)

Hi Chrisledage,
Thanks for the quick reply. I used the export script and it executes without any issue but it didn’t create any .jSkin file in the folder. :confused:
But the menu function worked.

So does the menu work as a solution for you, or do you want the script to work?

If it didn’t create jSkin files, there must be some output in your script editor output. Either an error, or maybe the path formatted incorrectly.

(Also you need to select the geo that you want to export.)

Main thing I was aiming for was to convert an imported asset to reference. So I wanted to transfer the skin weights and deformed sets to the duplicated mesh or reference.
I tried skin packs but I was not properly applying the skin weights. So I wrote a small script with the help of internet :). Now it works.
I used the following script:

import pymel.core as pm

sel = pm.ls(sl=1)

for s in sel:
#get joint skinned to the mesh
bind_joint = pm.listHistory(s, type=“joint”)

#get skin cluster
source_skinClstr = pm.listHistory(s,type= “skinCluster”)[0]

#get deformer sets
s_shape = pm.listRelatives(s, s =1)[0]
deformer_set = pm.listSets(type =2, object = s_shape)[-1]

#get a reference or duplicate mesh
s_ref = “file name:”+ s

#bind duplicate mesh to the joints
destination_skinClstr= pm.skinCluster(bind_joint, s_ref, tsb=True, bm=0, sm=0, nw=1)

#copy skin weights
pm.copySkinWeights( ss=source_skinClstr, ds=destination_skinClstr, noMirror=True )