#!/usr/bin/env python # -*- coding: utf-8 -*- """ MG-Picker Studio Module Animation picker tool for Maya """ import os import maya.cmds as cmds import maya.mel as mel def get_maya_version(): """ 获取当前 Maya 版本号 返回格式: '2023', '2024' 等 """ try: maya_version = cmds.about(version=True) # Maya 版本格式可能是 "2023" 或 "2023.1" 等,取主版本号 return maya_version.split('.')[0] except Exception as e: print("Failed to get Maya version: " + str(e)) return None def find_compatible_plugin(plugin_dir, maya_version): """ 查找兼容的 MGPicker 插件 优先使用完全匹配的版本,如果没有则向下查找最接近的版本 Args: plugin_dir: 插件目录路径 maya_version: Maya 版本号字符串,如 '2023' Returns: 插件名称(不含扩展名),如果找不到则返回 None """ if not maya_version: return None try: maya_ver_int = int(maya_version) except ValueError: print("Invalid Maya version format: " + str(maya_version)) return None # 列出所有可用的插件版本 available_versions = [] if os.path.exists(plugin_dir): for filename in os.listdir(plugin_dir): if filename.startswith("MGPicker_") and filename.endswith(".mll"): # 提取版本号,例如从 "MGPicker_2023x64.mll" 提取 "2023" try: version_str = filename.replace("MGPicker_", "").replace("x64.mll", "") ver_int = int(version_str) available_versions.append((ver_int, filename.replace(".mll", ""))) except ValueError: continue if not available_versions: return None # 按版本号排序 available_versions.sort(reverse=True) # 首先尝试完全匹配 for ver, plugin_name in available_versions: if ver == maya_ver_int: print("Found exact match plugin for Maya " + str(maya_version) + ": " + plugin_name) return plugin_name # 如果没有完全匹配,使用小于等于当前版本的最高版本 for ver, plugin_name in available_versions: if ver <= maya_ver_int: print("Using compatible plugin for Maya " + str(maya_version) + ": " + plugin_name + " (version " + str(ver) + ")") return plugin_name # 如果当前版本比所有可用版本都旧,使用最旧的版本 oldest_ver, oldest_plugin = available_versions[-1] print("Warning: Maya " + str(maya_version) + " is older than available plugins. Using oldest: " + oldest_plugin + " (version " + str(oldest_ver) + ")") return oldest_plugin def get_mgpicker_path(): """Get MG-Picker Studio installation path""" current_dir = os.path.dirname(os.path.abspath(__file__)) return current_dir.replace("\\", "/") def load_plugin(): """ Load MGPicker plugin 自动检测 Maya 版本并加载对应的插件 """ # 获取当前 Maya 版本 maya_version = get_maya_version() if not maya_version: print("Warning: Could not determine Maya version") return False print("Detected Maya version: " + str(maya_version)) # 查找兼容的插件 mgpicker_path = get_mgpicker_path() plugin_dir = os.path.join(mgpicker_path, "MGPicker_Program", "Plug-ins") plugin_name = find_compatible_plugin(plugin_dir, maya_version) if not plugin_name: print("Error: No compatible MGPicker plugin found for Maya " + str(maya_version)) return False # Check if plugin is already loaded try: if cmds.pluginInfo(plugin_name, query=True, loaded=True): print("MGPicker plugin already loaded: " + plugin_name) return True except RuntimeError: # Plugin not registered yet, will try to load pass # Get the plugin path plugin_path = os.path.join(plugin_dir, plugin_name + ".mll") plugin_path = plugin_path.replace("\\", "/") if not os.path.exists(plugin_path): print("Error: Plugin file not found: " + plugin_path) return False try: cmds.loadPlugin(plugin_path) print("MGPicker plugin loaded successfully: " + plugin_path) return True except Exception as e: print("Failed to load MGPicker plugin: " + str(e)) import traceback traceback.print_exc() return False def is_window_open(): """ 检查 MGPicker 窗口是否已经打开 Returns: bool: 如果窗口已打开返回 True """ # MGPicker 的主窗口名称 window_names = [ 'MG_PickerStudio_Window', 'MGPickerStudioWindow', 'mgPickerStudioWindow' ] for window_name in window_names: if cmds.window(window_name, exists=True): return True return False def show_existing_window(): """ 显示已存在的 MGPicker 窗口 Returns: bool: 如果成功显示窗口返回 True """ window_names = [ 'MG_PickerStudio_Window', 'MGPickerStudioWindow', 'mgPickerStudioWindow' ] for window_name in window_names: if cmds.window(window_name, exists=True): try: # 尝试显示窗口 cmds.showWindow(window_name) print("MGPicker window already open, bringing to front") return True except: pass return False def start(mode=1, force_new=False): """ Start MG-Picker Studio Args: mode (int): 0 for designer mode, 1 for animator mode (default) force_new (bool): 如果为 True,强制创建新窗口(不推荐) """ # 检查窗口是否已经打开 if not force_new and is_window_open(): if show_existing_window(): return else: print("Warning: MGPicker window exists but cannot be shown. Will try to create new window.") # Load plugin first if not load_plugin(): cmds.warning("Failed to load MGPicker plugin") return # Get MGPicker path mgpicker_path = get_mgpicker_path() program_path = os.path.join(mgpicker_path, "MGPicker_Program") # Set global variables mel.eval('global string $MGPicker_ProgramPath = "' + mgpicker_path + '/"') mel.eval('global string $MGPicker_ProgramFolder = "MGPicker_Program"') mel.eval('global string $MGPicker_ScriptEntry = "MG_PickerStudio"') # Source the main MEL script main_mel = os.path.join(program_path, "MGPicker_WrittenByMiguel.mel").replace("\\", "/") try: mel.eval('source "' + main_mel + '"') # Open MGPicker window with mode parameter # mode 0: designer mode, mode 1: animator mode mel.eval('MG_PickerStudio ' + str(mode)) print("MG-Picker Studio started in " + ("designer" if mode == 0 else "animator") + " mode") except Exception as e: cmds.warning("Failed to start MG-Picker Studio: " + str(e)) __all__ = ['start', 'load_plugin']