#!/usr/bin/env python # -*- coding: utf-8 -*- # @Site : Virtuos Games # @Author : ZHou Shuhua """ Skin API UI Functions Provides UI functions for weight export, import, and skin unbind Supports all Maya versions with pymel and cmds compatibility """ # Try to import pymel, fall back to cmds if unavailable try: import pymel.core as pm except ImportError: pm = None import maya.cmds as cmds import maya.mel as mel try: from . import apiVtxAttribs except ImportError: import rigging_tools.skin_api.apiVtxAttribs as apiVtxAttribs def WeightExport(): """ Export skin weights for selected objects """ try: # Check if there are selected objects if pm: selectedNodes = pm.ls(sl=True) if not selectedNodes: pm.warning("Please select at least one skinned object") return else: selectedNodes = cmds.ls(sl=True) if not selectedNodes: cmds.warning("Please select at least one skinned object") return # 使用 ApiVtxAttribs 类导出权重 api = apiVtxAttribs.ApiVtxAttribs() msg = api.exportSkinWeights(selected=True, saveJointInfo=True) if msg: print(msg) if pm: pm.confirmDialog( title="Export Success", message="Skin weights exported successfully!", button=["OK"] ) else: cmds.confirmDialog( title="Export Success", message="Skin weights exported successfully!", button=["OK"] ) else: print("Export cancelled") except Exception as e: error_msg = f"Failed to export skin weights: {str(e)}" if pm: pm.error(error_msg) else: cmds.error(error_msg) def WeightImport(): """ Import skin weights to selected or matching objects in scene """ try: # Check if there are selected objects if pm: selectedNodes = pm.ls(sl=True) else: selectedNodes = cmds.ls(sl=True) useSelection = len(selectedNodes) > 0 print(f"Import mode: {'selected objects' if useSelection else 'all matching objects'}") # Use ApiVtxAttribs class to import weights api = apiVtxAttribs.ApiVtxAttribs() msg = api.importSkinWeights(selected=useSelection, stripJointNamespaces=False, addNewToHierarchy=True) print(f"Import result: {repr(msg)}") if msg and msg != False: print(msg) if "No valid objects found" in str(msg): warning_msg = "No valid objects found in scene!\nMake sure:\n1. Object names match\n2. Vertex counts match\n3. Objects exist in scene" if pm: pm.warning(warning_msg) pm.confirmDialog( title="Import Failed", message=warning_msg, button=["OK"] ) else: cmds.warning(warning_msg) cmds.confirmDialog( title="Import Failed", message=warning_msg, button=["OK"] ) elif "Could not find" in str(msg): if pm: pm.warning(msg) else: cmds.warning(msg) else: # Import successful if pm: pm.confirmDialog( title="Import Complete", message="Skin weights imported successfully!", button=["OK"] ) else: cmds.confirmDialog( title="Import Complete", message="Skin weights imported successfully!", button=["OK"] ) else: print("Import cancelled or no file selected") except Exception as e: import traceback error_msg = f"Failed to import skin weights: {str(e)}\n{traceback.format_exc()}" print(error_msg) if pm: pm.error(error_msg) else: cmds.error(error_msg) def UnbindSkin(): """ Unbind skin from selected objects """ try: # Check selected objects if pm: selectedNodes = pm.ls(sl=True) if not selectedNodes: pm.warning("Please select at least one object") return else: selectedNodes = cmds.ls(sl=True) if not selectedNodes: cmds.warning("Please select at least one object") return # Confirmation dialog if pm: result = pm.confirmDialog( title="Unbind Skin", message=f"Are you sure you want to unbind skin from {len(selectedNodes)} object(s)?", button=["Yes", "No"], defaultButton="Yes", cancelButton="No", dismissString="No" ) else: result = cmds.confirmDialog( title="Unbind Skin", message=f"Are you sure you want to unbind skin from {len(selectedNodes)} object(s)?", button=["Yes", "No"], defaultButton="Yes", cancelButton="No", dismissString="No" ) if result != "Yes": print("Unbind cancelled") return # Use MEL command to unbind skin mel.eval('doDetachSkin "2" { "1","1" };') print("Skin unbound successfully!") if pm: pm.confirmDialog( title="Unbind Complete", message="Skin unbound successfully!", button=["OK"] ) else: cmds.confirmDialog( title="Unbind Complete", message="Skin unbound successfully!", button=["OK"] ) except Exception as e: error_msg = f"Failed to unbind skin: {str(e)}" if pm: pm.error(error_msg) else: cmds.error(error_msg)