497 lines
17 KiB
Python
497 lines
17 KiB
Python
# Maya Image Plane Node Plugin Test Script
|
|
# This script tests the plugin functionality using mayapy.exe
|
|
# Usage: mayapy.exe test_plugin.py
|
|
|
|
import sys
|
|
import os
|
|
|
|
# Test Results Storage
|
|
test_results = {
|
|
"passed": [],
|
|
"failed": [],
|
|
"errors": []
|
|
}
|
|
|
|
def log_test(test_name, passed, message=""):
|
|
"""Log test result"""
|
|
if passed:
|
|
test_results["passed"].append(test_name)
|
|
print(f"[PASS] {test_name}")
|
|
else:
|
|
test_results["failed"].append(test_name)
|
|
print(f"[FAIL] {test_name}: {message}")
|
|
if message:
|
|
print(f" {message}")
|
|
|
|
def setup_maya_module_path():
|
|
"""Setup Maya module path"""
|
|
module_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "maya")
|
|
module_path = os.path.normpath(module_path)
|
|
os.environ["MAYA_MODULE_PATH"] = module_path
|
|
print(f"MAYA_MODULE_PATH set to: {module_path}")
|
|
return module_path
|
|
|
|
def test_plugin_loading():
|
|
"""Test 1: Plugin Loading Test"""
|
|
print("\n" + "="*50)
|
|
print("TEST 1: Plugin Loading Test")
|
|
print("="*50)
|
|
|
|
try:
|
|
import maya.standalone
|
|
maya.standalone.initialize()
|
|
print("Maya standalone initialized")
|
|
except Exception as e:
|
|
log_test("Initialize Maya Standalone", False, str(e))
|
|
return False
|
|
|
|
try:
|
|
import maya.cmds as cmds
|
|
|
|
# Get plugin path
|
|
plugin_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "maya", "2023", "plug-ins", "MayaImagePlaneNode.mll")
|
|
plugin_path = os.path.normpath(plugin_path)
|
|
|
|
print(f"Plugin path: {plugin_path}")
|
|
print(f"Plugin exists: {os.path.exists(plugin_path)}")
|
|
|
|
# Load plugin
|
|
result = cmds.loadPlugin(plugin_path)
|
|
log_test("Load Plugin MayaImagePlaneNode", result is not None, f"Result: {result}")
|
|
|
|
# Check if plugin is loaded
|
|
plugins = cmds.pluginInfo(q=True, listPlugins=True)
|
|
plugin_loaded = "MayaImagePlaneNode" in plugins
|
|
log_test("Plugin in plugin list", plugin_loaded, f"Plugins: {plugins}")
|
|
|
|
return plugin_loaded
|
|
|
|
except Exception as e:
|
|
log_test("Load Plugin", False, str(e))
|
|
import traceback
|
|
traceback.print_exc()
|
|
return False
|
|
|
|
def test_plugin_unloading():
|
|
"""Test 1b: Plugin Unloading Test"""
|
|
print("\n" + "="*50)
|
|
print("TEST 1b: Plugin Unloading Test")
|
|
print("="*50)
|
|
|
|
try:
|
|
import maya.cmds as cmds
|
|
|
|
# Unload plugin
|
|
cmds.unloadPlugin("MayaImagePlaneNode")
|
|
log_test("Unload Plugin MayaImagePlaneNode", True)
|
|
|
|
# Verify unloaded
|
|
plugins = cmds.pluginInfo(q=True, listPlugins=True)
|
|
plugin_unloaded = "MayaImagePlaneNode" not in plugins
|
|
log_test("Plugin removed from list", plugin_unloaded)
|
|
|
|
return plugin_unloaded
|
|
|
|
except Exception as e:
|
|
log_test("Unload Plugin", False, str(e))
|
|
return False
|
|
|
|
def test_node_creation():
|
|
"""Test 2: Node Creation Test"""
|
|
print("\n" + "="*50)
|
|
print("TEST 2: Node Creation Test")
|
|
print("="*50)
|
|
|
|
try:
|
|
import maya.cmds as cmds
|
|
|
|
# Load plugin first if not loaded
|
|
if "MayaImagePlaneNode" not in cmds.pluginInfo(q=True, listPlugins=True):
|
|
plugin_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "maya", "2023", "plug-ins", "MayaImagePlaneNode.mll")
|
|
cmds.loadPlugin(plugin_path)
|
|
|
|
# Create node
|
|
node_name = cmds.createNode("imagePlaneVideo")
|
|
node_created = node_name is not None
|
|
log_test("Create Node imagePlaneVideo", node_created, f"Node: {node_name}")
|
|
|
|
# Verify node type
|
|
node_type = cmds.nodeType(node_name)
|
|
correct_type = node_type == "imagePlaneVideo"
|
|
log_test("Node type is imagePlaneVideo", correct_type, f"Type: {node_type}")
|
|
|
|
return node_created and correct_type
|
|
|
|
except Exception as e:
|
|
log_test("Create Node", False, str(e))
|
|
import traceback
|
|
traceback.print_exc()
|
|
return False
|
|
|
|
def test_node_attributes():
|
|
"""Test 3: Node Attributes Test"""
|
|
print("\n" + "="*50)
|
|
print("TEST 3: Node Attributes Test")
|
|
print("="*50)
|
|
|
|
try:
|
|
import maya.cmds as cmds
|
|
|
|
# Load plugin first
|
|
if "MayaImagePlaneNode" not in cmds.pluginInfo(q=True, listPlugins=True):
|
|
plugin_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "maya", "2023", "plug-ins", "MayaImagePlaneNode.mll")
|
|
cmds.loadPlugin(plugin_path)
|
|
|
|
# Create node if not exists
|
|
if not cmds.objExists("imagePlaneVideo1"):
|
|
cmds.createNode("imagePlaneVideo")
|
|
|
|
node_name = "imagePlaneVideo1"
|
|
|
|
# List all attributes
|
|
attrs = cmds.listAttr(node_name)
|
|
print(f"Attributes: {attrs}")
|
|
|
|
# Required input attributes
|
|
required_attrs = [
|
|
"videoFile",
|
|
"currentTime",
|
|
"frameRate",
|
|
"playbackRate",
|
|
"useMayaFrameRate",
|
|
"loop",
|
|
"postEffectCrop",
|
|
"postEffectResize",
|
|
"postEffectFlip",
|
|
"cacheSize"
|
|
]
|
|
|
|
# Output attributes
|
|
output_attrs = [
|
|
"outFrameWidth",
|
|
"outFrameHeight",
|
|
"outFrameTimestamp",
|
|
"outFrameCount",
|
|
"outIsValid",
|
|
"outCacheHitRatio"
|
|
]
|
|
|
|
# Test input attributes
|
|
for attr in required_attrs:
|
|
attr_exists = cmds.attributeQuery(attr, node=node_name, exists=True)
|
|
log_test(f"Attribute: {attr}", attr_exists)
|
|
|
|
# Test output attributes
|
|
for attr in output_attrs:
|
|
attr_exists = cmds.attributeQuery(attr, node=node_name, exists=True)
|
|
log_test(f"Output Attribute: {attr}", attr_exists)
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
log_test("List Attributes", False, str(e))
|
|
import traceback
|
|
traceback.print_exc()
|
|
return False
|
|
|
|
def test_attribute_functionality():
|
|
"""Test 4: Attribute Functionality Test"""
|
|
print("\n" + "="*50)
|
|
print("TEST 4: Attribute Functionality Test")
|
|
print("="*50)
|
|
|
|
try:
|
|
import maya.cmds as cmds
|
|
|
|
# Load plugin first
|
|
if "MayaImagePlaneNode" not in cmds.pluginInfo(q=True, listPlugins=True):
|
|
plugin_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "maya", "2023", "plug-ins", "MayaImagePlaneNode.mll")
|
|
cmds.loadPlugin(plugin_path)
|
|
|
|
# Create node if not exists
|
|
if not cmds.objExists("imagePlaneVideo1"):
|
|
cmds.createNode("imagePlaneVideo")
|
|
|
|
node_name = "imagePlaneVideo1"
|
|
|
|
# Test video file attribute
|
|
test_video_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "test_video.mp4")
|
|
test_video_path = os.path.normpath(test_video_path)
|
|
|
|
try:
|
|
cmds.setAttr(f"{node_name}.videoFile", test_video_path, type="string")
|
|
video_file = cmds.getAttr(f"{node_name}.videoFile")
|
|
log_test("Set videoFile attribute", video_file == test_video_path, f"Set: {video_file}")
|
|
except Exception as e:
|
|
log_test("Set videoFile attribute", False, str(e))
|
|
|
|
# Test currentTime attribute
|
|
try:
|
|
cmds.setAttr(f"{node_name}.currentTime", 1.0)
|
|
current_time = cmds.getAttr(f"{node_name}.currentTime")
|
|
log_test("Set currentTime attribute", current_time == 1.0, f"Value: {current_time}")
|
|
except Exception as e:
|
|
log_test("Set currentTime attribute", False, str(e))
|
|
|
|
# Test frameRate attribute
|
|
try:
|
|
cmds.setAttr(f"{node_name}.frameRate", 24.0)
|
|
frame_rate = cmds.getAttr(f"{node_name}.frameRate")
|
|
log_test("Set frameRate attribute", frame_rate == 24.0, f"Value: {frame_rate}")
|
|
except Exception as e:
|
|
log_test("Set frameRate attribute", False, str(e))
|
|
|
|
# Test playbackRate attribute (0.25x to 4.0x)
|
|
playback_rates = [0.25, 0.5, 1.0, 2.0, 4.0]
|
|
for rate in playback_rates:
|
|
try:
|
|
cmds.setAttr(f"{node_name}.playbackRate", rate)
|
|
actual_rate = cmds.getAttr(f"{node_name}.playbackRate")
|
|
log_test(f"Set playbackRate={rate}", abs(actual_rate - rate) < 0.01, f"Value: {actual_rate}")
|
|
except Exception as e:
|
|
log_test(f"Set playbackRate={rate}", False, str(e))
|
|
|
|
# Test useMayaFrameRate attribute
|
|
try:
|
|
cmds.setAttr(f"{node_name}.useMayaFrameRate", True)
|
|
use_maya = cmds.getAttr(f"{node_name}.useMayaFrameRate")
|
|
log_test("Set useMayaFrameRate=True", use_maya == True)
|
|
|
|
cmds.setAttr(f"{node_name}.useMayaFrameRate", False)
|
|
use_maya = cmds.getAttr(f"{node_name}.useMayaFrameRate")
|
|
log_test("Set useMayaFrameRate=False", use_maya == False)
|
|
except Exception as e:
|
|
log_test("Set useMayaFrameRate attribute", False, str(e))
|
|
|
|
# Test loop attribute
|
|
try:
|
|
cmds.setAttr(f"{node_name}.loop", True)
|
|
loop = cmds.getAttr(f"{node_name}.loop")
|
|
log_test("Set loop=True", loop == True)
|
|
except Exception as e:
|
|
log_test("Set loop attribute", False, str(e))
|
|
|
|
# Test postEffectCrop attribute (4 values)
|
|
try:
|
|
cmds.setAttr(f"{node_name}.postEffectCrop", 10, 20, 30, 40)
|
|
crop = cmds.getAttr(f"{node_name}.postEffectCrop")
|
|
log_test("Set postEffectCrop", crop == [10, 20, 30, 40], f"Value: {crop}")
|
|
except Exception as e:
|
|
log_test("Set postEffectCrop attribute", False, str(e))
|
|
|
|
# Test postEffectResize attribute (2 values)
|
|
try:
|
|
cmds.setAttr(f"{node_name}.postEffectResize", 800, 600)
|
|
resize = cmds.getAttr(f"{node_name}.postEffectResize")
|
|
log_test("Set postEffectResize", resize == [800, 600], f"Value: {resize}")
|
|
except Exception as e:
|
|
log_test("Set postEffectResize attribute", False, str(e))
|
|
|
|
# Test postEffectFlip attribute (2 values)
|
|
try:
|
|
cmds.setAttr(f"{node_name}.postEffectFlip", 1, 0) # Horizontal flip
|
|
flip = cmds.getAttr(f"{node_name}.postEffectFlip")
|
|
log_test("Set postEffectFlip", flip == [1, 0], f"Value: {flip}")
|
|
except Exception as e:
|
|
log_test("Set postEffectFlip attribute", False, str(e))
|
|
|
|
# Test cacheSize attribute
|
|
try:
|
|
cmds.setAttr(f"{node_name}.cacheSize", 100)
|
|
cache_size = cmds.getAttr(f"{node_name}.cacheSize")
|
|
log_test("Set cacheSize", cache_size == 100, f"Value: {cache_size}")
|
|
except Exception as e:
|
|
log_test("Set cacheSize attribute", False, str(e))
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
log_test("Attribute Functionality Test", False, str(e))
|
|
import traceback
|
|
traceback.print_exc()
|
|
return False
|
|
|
|
def test_output_attributes():
|
|
"""Test 5: Output Attributes Test"""
|
|
print("\n" + "="*50)
|
|
print("TEST 5: Output Attributes Test")
|
|
print("="*50)
|
|
|
|
try:
|
|
import maya.cmds as cmds
|
|
|
|
# Load plugin first
|
|
if "MayaImagePlaneNode" not in cmds.pluginInfo(q=True, listPlugins=True):
|
|
plugin_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "maya", "2023", "plug-ins", "MayaImagePlaneNode.mll")
|
|
cmds.loadPlugin(plugin_path)
|
|
|
|
# Create node if not exists
|
|
if not cmds.objExists("imagePlaneVideo1"):
|
|
cmds.createNode("imagePlaneVideo")
|
|
|
|
node_name = "imagePlaneVideo1"
|
|
|
|
# Set video file
|
|
test_video_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "test_video.mp4")
|
|
test_video_path = os.path.normpath(test_video_path)
|
|
cmds.setAttr(f"{node_name}.videoFile", test_video_path, type="string")
|
|
|
|
# Force recompute
|
|
cmds.getAttr(f"{node_name}.outFrameWidth")
|
|
|
|
# Test output attributes
|
|
output_attrs = {
|
|
"outFrameWidth": None,
|
|
"outFrameHeight": None,
|
|
"outFrameTimestamp": None,
|
|
"outFrameCount": None,
|
|
"outIsValid": None,
|
|
"outCacheHitRatio": None
|
|
}
|
|
|
|
for attr in output_attrs.keys():
|
|
try:
|
|
value = cmds.getAttr(f"{node_name}.{attr}")
|
|
output_attrs[attr] = value
|
|
log_test(f"Get {attr}", value is not None, f"Value: {value}")
|
|
except Exception as e:
|
|
log_test(f"Get {attr}", False, str(e))
|
|
|
|
# Validate output values
|
|
if output_attrs["outFrameWidth"]:
|
|
log_test("outFrameWidth > 0", output_attrs["outFrameWidth"] > 0)
|
|
|
|
if output_attrs["outFrameHeight"]:
|
|
log_test("outFrameHeight > 0", output_attrs["outFrameHeight"] > 0)
|
|
|
|
if output_attrs["outFrameCount"]:
|
|
log_test("outFrameCount > 0", output_attrs["outFrameCount"] > 0)
|
|
|
|
if output_attrs["outIsValid"] is not None:
|
|
# Note: May be False if video not properly loaded
|
|
log_test("outIsValid accessible", True)
|
|
|
|
if output_attrs["outCacheHitRatio"] is not None:
|
|
log_test("outCacheHitRatio in range [0,1]", 0 <= output_attrs["outCacheHitRatio"] <= 1)
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
log_test("Output Attributes Test", False, str(e))
|
|
import traceback
|
|
traceback.print_exc()
|
|
return False
|
|
|
|
def test_ffmpeg_dll_dependencies():
|
|
"""Test 6: FFmpeg DLL Dependencies Test"""
|
|
print("\n" + "="*50)
|
|
print("TEST 6: FFmpeg DLL Dependencies Test")
|
|
print("="*50)
|
|
|
|
try:
|
|
import maya.cmds as cmds
|
|
|
|
# Load plugin first
|
|
if "MayaImagePlaneNode" not in cmds.pluginInfo(q=True, listPlugins=True):
|
|
plugin_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "maya", "2023", "plug-ins", "MayaImagePlaneNode.mll")
|
|
cmds.loadPlugin(plugin_path)
|
|
|
|
# Check FFmpeg DLLs
|
|
plugin_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "maya", "2023", "plug-ins")
|
|
|
|
required_dlls = [
|
|
"avcodec-62.dll",
|
|
"avformat-62.dll",
|
|
"avutil-60.dll",
|
|
"swscale-9.dll"
|
|
]
|
|
|
|
for dll in required_dlls:
|
|
dll_path = os.path.join(plugin_dir, dll)
|
|
dll_exists = os.path.exists(dll_path)
|
|
log_test(f"FFmpeg DLL: {dll}", dll_exists, f"Path: {dll_path}")
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
log_test("FFmpeg DLL Dependencies Test", False, str(e))
|
|
import traceback
|
|
traceback.print_exc()
|
|
return False
|
|
|
|
def print_test_summary():
|
|
"""Print test summary"""
|
|
print("\n" + "="*50)
|
|
print("TEST SUMMARY")
|
|
print("="*50)
|
|
print(f"Passed: {len(test_results['passed'])}")
|
|
print(f"Failed: {len(test_results['failed'])}")
|
|
print(f"Errors: {len(test_results['errors'])}")
|
|
|
|
if test_results['failed']:
|
|
print("\nFailed Tests:")
|
|
for test in test_results['failed']:
|
|
print(f" - {test}")
|
|
|
|
if test_results['errors']:
|
|
print("\nErrors:")
|
|
for error in test_results['errors']:
|
|
print(f" - {error}")
|
|
|
|
return len(test_results['failed']) == 0 and len(test_results['errors']) == 0
|
|
|
|
def main():
|
|
"""Main test function"""
|
|
print("Maya Image Plane Node Plugin Test")
|
|
print("="*50)
|
|
|
|
# Setup module path
|
|
setup_maya_module_path()
|
|
|
|
# Run tests
|
|
all_passed = True
|
|
|
|
# Test 1: Plugin Loading
|
|
if not test_plugin_loading():
|
|
all_passed = False
|
|
|
|
# Test 1b: Plugin Unloading
|
|
if not test_plugin_unloading():
|
|
all_passed = False
|
|
|
|
# Reload plugin for subsequent tests
|
|
try:
|
|
import maya.cmds as cmds
|
|
plugin_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "maya", "2023", "plug-ins", "MayaImagePlaneNode.mll")
|
|
cmds.loadPlugin(plugin_path)
|
|
except:
|
|
pass
|
|
|
|
# Test 2: Node Creation
|
|
if not test_node_creation():
|
|
all_passed = False
|
|
|
|
# Test 3: Node Attributes
|
|
if not test_node_attributes():
|
|
all_passed = False
|
|
|
|
# Test 4: Attribute Functionality
|
|
if not test_attribute_functionality():
|
|
all_passed = False
|
|
|
|
# Test 5: Output Attributes
|
|
if not test_output_attributes():
|
|
all_passed = False
|
|
|
|
# Test 6: FFmpeg DLL Dependencies
|
|
if not test_ffmpeg_dll_dependencies():
|
|
all_passed = False
|
|
|
|
# Print summary
|
|
print_test_summary()
|
|
|
|
return 0 if all_passed else 1
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|