Skip to content

Instantly share code, notes, and snippets.

@IngoClemens
Created March 24, 2023 20:19
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save IngoClemens/36224dc4203de8c01360700fe8f3171a to your computer and use it in GitHub Desktop.
Save IngoClemens/36224dc4203de8c01360700fe8f3171a to your computer and use it in GitHub Desktop.
Python wrapper for SHAPES export and import
from maya import cmds, mel
# ----------------------------------------------------------------------
# Blend shape setup export and import.
# ----------------------------------------------------------------------
def exportCompleteSetup(mesh, filePath, rebuild=False):
"""Exports all blend shape nodes from the given mesh with their
respective setup.
The rebuild of the setup is optional.
:param mesh: The name of the mesh to process.
:type mesh: str
:param filePath: The path to export to.
:type filePath: str
:param rebuild: True, if the setup should be rebuilt.
:type rebuild: bool
"""
# Store the preference settings.
options = {}
options["SHAPESFileType"] = cmds.optionVar(query="SHAPESFileType")
options["SHAPESUseCustomDataPath"] = cmds.optionVar(query="SHAPESUseCustomDataPath")
options["SHAPESCustomDataPath"] = cmds.optionVar(query="SHAPESCustomDataPath")
options["SHAPESUseCustomNodeDataExportPath"] = cmds.optionVar(query="SHAPESUseCustomNodeDataExportPath")
options["SHAPESCustomNodeDataExportPath"] = cmds.optionVar(query="SHAPESCustomNodeDataExportPath")
options["SHAPESExportOptions"] = cmds.optionVar(query="SHAPESExportOptions")
# Set the preferences for the export.
cmds.optionVar(intValue=("SHAPESFileType", 0))
cmds.optionVar(intValue=("SHAPESUseCustomDataPath", 1))
cmds.optionVar(stringValue=("SHAPESCustomDataPath", filePath))
cmds.optionVar(intValue=("SHAPESUseCustomNodeDataExportPath", 0))
cmds.optionVar(stringValue=("SHAPESCustomNodeDataExportPath", ""))
# Options: export only, all targets, maya ASCII.
cmds.optionVar(stringValue=("SHAPESExportOptions", "1,1,1"))
# Make sure that the export path is existing.
filePath = mel.eval("shapesUtil_getExportPath(\"\", 1)")
# Load the SHAPES UI.
mel.eval("SHAPES")
# Load the selected mesh.
mel.eval("shapesMain_getMeshSelection 1")
# Get the blend shape node.
bsNode = mel.eval("string $temp = $gShapes_bsNode")
# Get all blend shape nodes from the mesh.
nodeList = mel.eval("shapesMain_listBlendShapeNodes {} -1".format(mesh))
for node in nodeList:
cmds.optionMenu("shpUI_bsOption", edit=True, value=node)
mel.eval("shapesMain_updateSelectedBsNode")
mel.eval("shapesUI_buildExportUI 1")
mel.eval("shapesUtil_exportShapeSetup 1 \"{}\" \"\"".format(filePath))
if rebuild:
mel.eval("shapesAction_deleteBlendShapeNode")
# Set the preferences back.
cmds.optionVar(intValue=("SHAPESFileType", options["SHAPESFileType"]))
cmds.optionVar(intValue=("SHAPESUseCustomDataPath", options["SHAPESUseCustomDataPath"]))
cmds.optionVar(stringValue=("SHAPESCustomDataPath", options["SHAPESCustomDataPath"]))
cmds.optionVar(intValue=("SHAPESUseCustomNodeDataExportPath", options["SHAPESUseCustomNodeDataExportPath"]))
cmds.optionVar(stringValue=("SHAPESCustomNodeDataExportPath", options["SHAPESCustomNodeDataExportPath"]))
cmds.optionVar(stringValue=("SHAPESExportOptions", options["SHAPESExportOptions"]))
# Rebuild the setup.
if rebuild:
for node in nodeList:
rebuildSetup("{}/{}.mel".format(filePath, node))
cmds.select(mesh, replace=True)
mel.eval("shapesMain_getMeshSelection 1")
def rebuildSetup(filePath):
"""Rebuild the exported blend shape setup from the given file.
:param filePath: The file path if the blend shape setup.
:type filePath: str
"""
mel.eval('shapesUtil_performImportShapeSetup "{}"'.format(filePath))
# ----------------------------------------------------------------------
# Blend shape deltas export to a json file.
# ----------------------------------------------------------------------
def exportBlendShapeDeltas(bsNode, filePath):
"""Export the blend shape deltas to the given json file.
:param bsNode: The name of the blend shape node.
:type bsNode: str
:param filePath: The full path of the json file to export the deltas
to, including the file extension.
:type filePath: str
:return: True, if the export was successful.
:rtype: bool
"""
# Store the current blend shape node.
temp = mel.eval("string $temp = $gShapes_bsNode")
# Set the blend shape node for getting the targets and ids.
mel.eval('$gShapes_bsNode = "{}"'.format(bsNode))
# Get all target names.
names = mel.eval("shapesData_getShapeList()")
items = []
for name in names:
# Get index for each target.
ids = mel.eval('shapesData_getShapeIds(1, {{"{}"}})'.format(name))
items.append("-index {} -channelName {}".format(ids[0], name))
# Build the command string.
cmd = ["br_blendShapeExportData -delta -fileName"]
cmd.append('"{}"'.format(filePath))
cmd.append(" ".join(items))
cmd.append(bsNode)
# Execute the command.
result = mel.eval(" ".join(cmd))
# Restore the previous the blend shape node.
mel.eval('$gShapes_bsNode = "{}"'.format(temp))
return bool(result)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment