This commit is contained in:
2025-11-30 14:36:56 +08:00
parent d849862405
commit 9a26200542
10 changed files with 0 additions and 544 deletions

View File

@@ -1,42 +0,0 @@
# Maya 2023 Plugin Directory Structure
## Directory Description
- **shelves/** - Shelf files (.mel format)
- shelf_NexusLauncher.mel - NexusLauncher shelf
- **scripts/** - Python/MEL scripts
- userSetup.py - Automatically executed when Maya starts
- nexus_test.py - Test script
- **plug-ins/** - Maya plugin files (.py or .mll)
- Place Maya plugin files here
- **icons/** - Tool icons
- Place icon files used by shelf buttons here
## Usage
1. Configure in NexusLauncher's config.json:
```json
"maya_plugin_path": "E:/Zoroot/Dev/NexusLauncher/template/plugins/maya"
```
2. Start Maya 2023, the system will automatically:
- Load NexusLauncher shelf
- Execute userSetup.py
- Set correct environment variables
3. Testing:
- Check if "NexusLauncher" shelf appears
- Click the "Test" button
- A confirmation dialog should appear
## Environment Variables
Automatically set on startup:
- MAYA_SHELF_PATH - Points to shelves directory
- MAYA_SCRIPT_PATH - Points to scripts directory
- PYTHONPATH - Points to scripts directory
- MAYA_PLUG_IN_PATH - Points to plug-ins directory
- XBMLANGPATH - Points to icons directory

View File

@@ -1,117 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Shelf Reload Script
Run this script in Maya Script Editor to reload NexusLauncher shelf
"""
import maya.cmds as cmds
import maya.mel as mel
def reload_shelf():
"""Reload NexusLauncher shelf"""
print("\n" + "=" * 60)
print("Reloading NexusLauncher Shelf")
print("=" * 60)
# 1. Delete old shelf
if cmds.shelfLayout('NexusLauncher', exists=True):
old_buttons = cmds.shelfLayout('NexusLauncher', query=True, childArray=True) or []
print(f"[1/4] Deleting old shelf (had {len(old_buttons)} button(s))...")
cmds.deleteUI('NexusLauncher', layout=True)
print(" ✓ Old shelf deleted")
else:
print("[1/4] No existing shelf found")
# 2. Reload shelf (using new method)
import os
shelf_paths = os.environ.get('MAYA_SHELF_PATH', '')
# Find shelf file
shelf_file_found = None
if shelf_paths:
path_separator = ';' if os.name == 'nt' else ':'
for shelf_path in shelf_paths.split(path_separator):
shelf_file = os.path.join(shelf_path.strip(), "shelf_NexusLauncher.mel")
if os.path.exists(shelf_file):
shelf_file_found = shelf_file.replace("\\", "/")
break
if not shelf_file_found:
print("[2/4] ✗ Could not find shelf_NexusLauncher.mel in MAYA_SHELF_PATH")
return False
print(f"[2/4] Loading shelf from: {shelf_file_found}")
try:
# Disable auto-save
mel.eval('optionVar -intValue "saveLastLoadedShelf" 0;')
# Create shelf layout
mel.eval('''
global string $gShelfTopLevel;
setParent $gShelfTopLevel;
shelfLayout -cellWidth 35 -cellHeight 34 NexusLauncher;
''')
# Set parent and execute shelf script
mel.eval('setParent NexusLauncher;')
mel.eval(f'source "{shelf_file_found}";')
mel.eval('shelf_NexusLauncher();')
print(" ✓ Shelf loaded (temporary, won't be saved)")
except Exception as e:
print(f" ✗ Failed to load shelf: {e}")
import traceback
traceback.print_exc()
return False
# 3. Verify shelf
if cmds.shelfLayout('NexusLauncher', exists=True):
print("[3/4] Verifying shelf...")
buttons = cmds.shelfLayout('NexusLauncher', query=True, childArray=True) or []
if buttons:
print(f" ✓ Shelf has {len(buttons)} button(s)")
# Display button details
for i, btn in enumerate(buttons, 1):
try:
label = cmds.shelfButton(btn, query=True, label=True)
annotation = cmds.shelfButton(btn, query=True, annotation=True)
source_type = cmds.shelfButton(btn, query=True, sourceType=True)
print(f" Button {i}: {label} ({source_type})")
print(f" {annotation}")
except Exception as e:
print(f" ✗ Error querying button {i}: {e}")
else:
print(" ⚠ Warning: Shelf exists but has no buttons!")
return False
else:
print("[3/4] ✗ Shelf not found after loading!")
return False
# 4. Test button command
print("[4/4] Testing button command...")
try:
import nexus_test
print(" ✓ nexus_test module imported")
# Run test
print(" Running test...")
nexus_test.run_test()
print(" ✓ Test executed successfully!")
except Exception as e:
print(f" ✗ Test failed: {e}")
import traceback
traceback.print_exc()
return False
print("=" * 60)
print("✓ Shelf reload complete!")
print("=" * 60 + "\n")
return True
if __name__ == '__main__':
reload_shelf()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -1,55 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
NexusLauncher Example Plugin
Example plugin - demonstrates how to create a Maya plugin
'''
import sys
import maya.api.OpenMaya as om
def maya_useNewAPI():
'''Tell Maya to use Maya Python API 2.0'''
pass
class NexusExampleCmd(om.MPxCommand):
'''Example command'''
kPluginCmdName = 'nexusExample'
def __init__(self):
om.MPxCommand.__init__(self)
@staticmethod
def cmdCreator():
return NexusExampleCmd()
def doIt(self, args):
print('[NexusLauncher] Example plugin command executed!')
om.MGlobal.displayInfo('NexusLauncher Example Plugin is working!')
def initializePlugin(plugin):
'''Initialize plugin'''
pluginFn = om.MFnPlugin(plugin, 'NexusLauncher', '1.0', 'Any')
try:
pluginFn.registerCommand(
NexusExampleCmd.kPluginCmdName,
NexusExampleCmd.cmdCreator
)
print('[NexusLauncher] Example plugin loaded successfully')
except:
sys.stderr.write(f'Failed to register command: {NexusExampleCmd.kPluginCmdName}')
raise
def uninitializePlugin(plugin):
'''Uninitialize plugin'''
pluginFn = om.MFnPlugin(plugin)
try:
pluginFn.deregisterCommand(NexusExampleCmd.kPluginCmdName)
print('[NexusLauncher] Example plugin unloaded')
except:
sys.stderr.write(f'Failed to deregister command: {NexusExampleCmd.kPluginCmdName}')
raise

View File

@@ -1,30 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
NexusLauncher Test Script
Test script - verify plugin system is working properly
"""
import maya.cmds as cmds
def run_test():
"""Run test"""
result = cmds.confirmDialog(
title='NexusLauncher Test',
message='NexusLauncher plugin system is working!\n\nPlugin system is running normally!',
button=['OK'],
defaultButton='OK',
cancelButton='OK',
dismissString='OK'
)
print("=" * 50)
print("[NexusLauncher] Test executed successfully!")
print("[NexusLauncher] Test executed successfully!")
print("=" * 50)
return result
if __name__ == "__main__":
run_test()

View File

@@ -1,222 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Maya Startup Script
Automatically executed when Maya starts
"""
import maya.cmds as cmds
import maya.mel as mel
import os
import sys
def load_nexus_shelf():
"""Load NexusLauncher shelf (force refresh)"""
try:
# Get shelf path from environment variable (may contain multiple paths separated by semicolons)
shelf_paths = os.environ.get('MAYA_SHELF_PATH', '')
if not shelf_paths:
print("[NexusLauncher] MAYA_SHELF_PATH not set, trying alternative method...")
# Fallback method: infer from current script directory
try:
script_dir = os.path.dirname(os.path.abspath(__file__))
shelf_paths = os.path.join(os.path.dirname(script_dir), "shelves")
except:
print("[NexusLauncher] Could not determine shelf path, skipping shelf load")
return
# Split multiple paths (Windows uses semicolon, Unix uses colon)
path_separator = ';' if os.name == 'nt' else ':'
shelf_path_list = shelf_paths.split(path_separator)
# First check if shelf file exists
shelf_file_found = None
for shelf_path in shelf_path_list:
shelf_path = shelf_path.strip()
if not shelf_path:
continue
shelf_file = os.path.join(shelf_path, "shelf_NexusLauncher.mel")
shelf_file = shelf_file.replace("\\", "/")
print(f"[NexusLauncher] Checking: {shelf_file}")
if os.path.exists(shelf_file):
shelf_file_found = shelf_file
print(f"[NexusLauncher] ✓ Found shelf file: {shelf_file}")
break
# If shelf file not found, skip loading
if not shelf_file_found:
print("[NexusLauncher] ✗ Could not find shelf_NexusLauncher.mel in any MAYA_SHELF_PATH")
print("[NexusLauncher] Skipping shelf load (no file found)")
return
# After finding shelf file, delete old one before loading new one
# Note: loadNewShelf does not automatically delete shelf with same name, must delete manually
existing_shelves = cmds.lsUI(type='shelfLayout') or []
if 'NexusLauncher' in existing_shelves:
print("[NexusLauncher] Removing existing shelf before reload...")
try:
cmds.deleteUI('NexusLauncher', layout=True)
print("[NexusLauncher] ✓ Removed old shelf")
except Exception as e:
print(f"[NexusLauncher] Warning: Could not remove old shelf: {e}")
# Key: Use custom method to load shelf, avoid loadNewShelf auto-save
print(f"[NexusLauncher] Loading shelf from: {shelf_file_found}")
# Method: Use mel.eval to execute shelf file, then immediately delete saved config
try:
# 1. First disable auto-save (attempt)
mel.eval('optionVar -intValue "saveLastLoadedShelf" 0;')
# 2. Create shelf layout
mel.eval('''
global string $gShelfTopLevel;
if (`shelfLayout -exists NexusLauncher`) {
deleteUI -layout NexusLauncher;
}
setParent $gShelfTopLevel;
shelfLayout -cellWidth 35 -cellHeight 34 NexusLauncher;
''')
print(f"[NexusLauncher] ✓ Created shelf layout")
# 3. Set parent to shelf, then execute shelf file to create buttons
mel.eval('setParent NexusLauncher;')
mel.eval(f'source "{shelf_file_found}";')
mel.eval('shelf_NexusLauncher();')
print(f"[NexusLauncher] ✓ Executed shelf script")
# 4. Verify shelf
if cmds.shelfLayout('NexusLauncher', exists=True):
new_buttons = cmds.shelfLayout('NexusLauncher', query=True, childArray=True) or []
if new_buttons:
print(f"[NexusLauncher] ✓ Shelf loaded successfully with {len(new_buttons)} button(s)")
# 5. Ensure no config file is saved
try:
maya_version = cmds.about(version=True).split()[0]
maya_app_dir = os.environ.get('MAYA_APP_DIR', '')
if maya_app_dir:
shelf_config = os.path.join(maya_app_dir, maya_version, "prefs", "shelves", "shelf_NexusLauncher.mel")
if os.path.exists(shelf_config):
os.remove(shelf_config)
print(f"[NexusLauncher] ✓ Removed auto-saved config")
except Exception as e:
print(f"[NexusLauncher] Warning: {e}")
print(f"[NexusLauncher] ✓ Shelf is temporary (won't be saved)")
else:
print("[NexusLauncher] ⚠ Warning: Shelf has no buttons!")
else:
print("[NexusLauncher] ✗ Error: Shelf failed to load")
except Exception as e:
print(f"[NexusLauncher] Error loading shelf: {e}")
import traceback
print(traceback.format_exc())
except Exception as e:
import traceback
print(f"[NexusLauncher] Failed to load shelf: {e}")
print(traceback.format_exc())
def load_nexus_plugins():
"""Load NexusLauncher plugins"""
try:
# Get plugin path
plugin_path = os.environ.get('MAYA_PLUG_IN_PATH', '')
if not plugin_path:
print("[NexusLauncher] MAYA_PLUG_IN_PATH not set, skipping plugin load")
return
print(f"[NexusLauncher] MAYA_PLUG_IN_PATH: {plugin_path}")
# Load example plugin
plugin_file = "nexus_example_plugin.py"
if cmds.pluginInfo(plugin_file, query=True, loaded=True):
print(f"[NexusLauncher] Plugin already loaded: {plugin_file}")
else:
try:
cmds.loadPlugin(plugin_file)
print(f"[NexusLauncher] ✓ Loaded plugin: {plugin_file}")
# Set to auto-load
cmds.pluginInfo(plugin_file, edit=True, autoload=True)
print(f"[NexusLauncher] ✓ Set plugin to auto-load")
except Exception as e:
print(f"[NexusLauncher] Failed to load plugin {plugin_file}: {e}")
except Exception as e:
print(f"[NexusLauncher] Error loading plugins: {e}")
def print_environment():
"""Print environment variables (for debugging)"""
print("=" * 60)
print("[NexusLauncher] Environment Variables:")
print(f" MAYA_SHELF_PATH: {os.environ.get('MAYA_SHELF_PATH', 'Not set')}")
print(f" MAYA_SCRIPT_PATH: {os.environ.get('MAYA_SCRIPT_PATH', 'Not set')}")
print(f" PYTHONPATH: {os.environ.get('PYTHONPATH', 'Not set')}")
print(f" MAYA_PLUG_IN_PATH: {os.environ.get('MAYA_PLUG_IN_PATH', 'Not set')}")
print(f" XBMLANGPATH: {os.environ.get('XBMLANGPATH', 'Not set')}")
print("=" * 60)
def cleanup_on_exit():
"""Clean up NexusLauncher shelf config file when Maya exits"""
try:
# Check if launched by NexusLauncher
shelf_paths = os.environ.get('MAYA_SHELF_PATH', '')
is_nexus_launcher = False
if shelf_paths:
path_separator = ';' if os.name == 'nt' else ':'
for shelf_path in shelf_paths.split(path_separator):
shelf_file = os.path.join(shelf_path.strip(), "shelf_NexusLauncher.mel")
if os.path.exists(shelf_file):
is_nexus_launcher = True
break
if not is_nexus_launcher:
return
# Delete config file (if exists)
try:
maya_version = cmds.about(version=True).split()[0]
maya_app_dir = os.environ.get('MAYA_APP_DIR', '')
if maya_app_dir:
shelf_config = os.path.join(maya_app_dir, maya_version, "prefs", "shelves", "shelf_NexusLauncher.mel")
if os.path.exists(shelf_config):
os.remove(shelf_config)
print(f"[NexusLauncher] ✓ Cleaned up shelf config on exit")
except Exception as e:
print(f"[NexusLauncher] Warning: Could not clean up shelf config: {e}")
except Exception as e:
print(f"[NexusLauncher] Error during cleanup: {e}")
def register_exit_callback():
"""Register cleanup callback on exit"""
try:
# Use scriptJob to execute cleanup when Maya exits
cmds.scriptJob(event=["quitApplication", cleanup_on_exit], protected=True)
print("[NexusLauncher] ✓ Registered exit cleanup callback")
except Exception as e:
print(f"[NexusLauncher] Warning: Could not register exit callback: {e}")
# Execute after Maya startup completes
cmds.evalDeferred(load_nexus_shelf)
cmds.evalDeferred(load_nexus_plugins)
cmds.evalDeferred(print_environment)
cmds.evalDeferred(register_exit_callback)
print("[NexusLauncher] userSetup.py executed")

View File

@@ -1,78 +0,0 @@
global proc shelf_NexusLauncher () {
global string $gBuffStr;
global string $gBuffStr0;
global string $gBuffStr1;
shelfButton
-enableCommandRepeat 1
-flexibleWidthType 3
-flexibleWidthValue 32
-enable 1
-width 35
-height 34
-manage 1
-visible 1
-preventOverride 0
-annotation "NexusLauncher Test - Click to verify plugin system"
-enableBackground 0
-backgroundColor 0 0 0
-highlightColor 0.321569 0.521569 0.65098
-align "center"
-label "NL"
-labelOffset 0
-rotation 0
-flipX 0
-flipY 0
-useAlpha 1
-font "boldLabelFont"
-imageOverlayLabel "NL"
-overlayLabelColor 1 1 1
-overlayLabelBackColor 0.2 0.5 0.8 0.9
-image "nexus_test.png"
-image1 "nexus_test.png"
-style "iconOnly"
-marginWidth 0
-marginHeight 1
-command "import nexus_test\nnexus_test.run_test()"
-sourceType "python"
-commandRepeatable 1
-flat 1
;
shelfButton
-enableCommandRepeat 1
-flexibleWidthType 3
-flexibleWidthValue 32
-enable 1
-width 35
-height 34
-manage 1
-visible 1
-preventOverride 0
-annotation "Batch Extrusion - Create shell mesh layers with vertex colors"
-enableBackground 0
-backgroundColor 0 0 0
-highlightColor 0.321569 0.521569 0.65098
-align "center"
-label "BE"
-labelOffset 0
-rotation 0
-flipX 0
-flipY 0
-useAlpha 1
-font "boldLabelFont"
-imageOverlayLabel "BE"
-overlayLabelColor 1 1 1
-overlayLabelBackColor 0.8 0.4 0.2 0.9
-image "batchextrusion.png"
-image1 "batchextrusion.png"
-style "iconOnly"
-marginWidth 0
-marginHeight 1
-command "import batchextrusion\nbatchextrusion.show_batch_extrusion_ui()"
-sourceType "python"
-commandRepeatable 1
-flat 1
;
}