diff --git a/CMakeLists.txt b/CMakeLists.txt index 07f6339..632b0de 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,5 +5,5 @@ project(MediaPlane LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) -# Add subdirectory for MayaImagePlaneNode plugin -add_subdirectory(src/MayaImagePlaneNode) +# Add subdirectory for MayaMediaPlaneNode plugin +add_subdirectory(src/MayaMediaPlaneNode) diff --git a/README.md b/README.md index 3f7087e..5ccaf87 100644 --- a/README.md +++ b/README.md @@ -24,29 +24,38 @@ A Maya plugin for displaying video frames in Maya Viewport 2.0. ``` MediaPlane/ +├── README.md # This file ├── CMakeLists.txt # Top-level CMake configuration ├── CMakePresets.json # CMake preset configurations +├── PLAN.md # Project plan +├── IMPLEMENTATION_GUIDE.md # Implementation guide +├── TEST_PLAN.md # Test plan +├── .gitignore # Git ignore file ├── cmake/ │ └── modules/ │ ├── FindMaya.cmake # Maya SDK finder module │ └── FindFFmpeg.cmake # FFmpeg finder module ├── src/ -│ └── MayaImagePlaneNode/ +│ └── MayaMediaPlaneNode/ │ ├── CMakeLists.txt # Plugin CMake configuration │ ├── Plugin.cpp # Maya plugin entry point │ ├── AETemplateMediaPlane.mel # Attribute Editor template -│ ├── MayaMediaPlaneNode.h # Node header file -│ ├── MayaMediaPlaneNode.cpp # Node implementation -│ ├── FFmpegVideoDecoder.h # FFmpeg decoder header -│ ├── FFmpegVideoDecoder.cpp # FFmpeg decoder implementation -│ ├── FrameCache.h # Frame cache header -│ ├── FrameCache.cpp # Frame cache implementation -│ └── MediaPlane.mod # Maya module file +│ ├── MayaMediaPlaneNode.h # Node header file +│ ├── MayaMediaPlaneNode.cpp # Node implementation +│ ├── FFmpegVideoDecoder.h # FFmpeg decoder header +│ ├── FFmpegVideoDecoder.cpp # FFmpeg decoder implementation +│ ├── FrameCache.h # Frame cache header +│ ├── FrameCache.cpp # Frame cache implementation +│ └── MediaPlane.mod # Maya module file ├── test/ -│ ├── test_plugin.py # Python test script -│ ├── test_maya_plugin.cpp # C++ test code -│ └── test_viewport.mel # MEL test script -└── docs/ # Documentation directory +│ ├── test_plugin.py # Python test script +│ ├── test_maya_plugin.cpp # C++ test code +│ ├── test_viewport.mel # MEL viewport test script +│ ├── test_video.mp4 # Test video file +│ └── TEST_REPORT.md # Test report +├── docs/ # Documentation directory +├── install/ # Installation directory +└── third_party/ # Third-party dependencies ``` ## Build Instructions @@ -111,25 +120,20 @@ createNode MediaPlane; ### Use AE Template -The plugin includes a custom Attribute Editor template. When the plugin loads, you'll see instructions in the Script Editor. To manually load the AE template: +The plugin includes a custom Attribute Editor template (AETemplateMediaPlane.mel). After installation, the MEL file is automatically placed in the Maya scripts directory and will be loaded when the plugin is loaded. + +For manual loading in Script Editor: ```mel // Source the AE template source "AETemplateMediaPlane.mel"; ``` -For automatic loading, copy the MEL file to your Maya scripts directory: +Or copy to your Maya scripts directory: ``` C:\Users\\Documents\maya\2023\scripts\ ``` -Or add this to your `userSetup.mel`: -```mel -// Add to userSetup.mel -if (!`exists AETemplateMediaPlane`) - source "AETemplateMediaPlane.mel"; -``` - ### Set Video File ```mel diff --git a/install/Maya2023/plug-ins/Maya2023/MayaMediaPlaneNode.mll b/install/Maya2023/plug-ins/Maya2023/MayaMediaPlaneNode.mll new file mode 100644 index 0000000..86acb90 Binary files /dev/null and b/install/Maya2023/plug-ins/Maya2023/MayaMediaPlaneNode.mll differ diff --git a/src/MayaImagePlaneNode/AETemplateMediaPlane.mel b/install/Maya2023/scripts/AETemplateMediaPlane.mel similarity index 100% rename from src/MayaImagePlaneNode/AETemplateMediaPlane.mel rename to install/Maya2023/scripts/AETemplateMediaPlane.mel diff --git a/src/MayaMediaPlaneNode/AETemplateMediaPlane.mel b/src/MayaMediaPlaneNode/AETemplateMediaPlane.mel new file mode 100644 index 0000000..ea173a8 --- /dev/null +++ b/src/MayaMediaPlaneNode/AETemplateMediaPlane.mel @@ -0,0 +1,112 @@ +// AETemplateMediaPlane.mel +// Attribute Editor Template for MayaMediaPlaneNode +// This file customizes the appearance of MediaPlane node attributes in Maya's Attribute Editor + +global proc AETemplateMediaPlane(string $nodeName) +{ + editorTemplate -beginScrollLayout; + + // Video File Section + editorTemplate -beginLayout "Video File" -collapse 0; + // Use custom control for video file with browse button + editorTemplate -callCustom "AETemplateMediaPlaneVideoFileCreate" "AETemplateMediaPlaneVideoFileUpdate" "videoFile"; + editorTemplate -endLayout; + + // Playback Section + editorTemplate -beginLayout "Playback" -collapse 0; + editorTemplate -addControl "currentTime"; + editorTemplate -addControl "frameRate"; + editorTemplate -addControl "playbackRate"; + editorTemplate -addControl "useMayaFrameRate"; + editorTemplate -addControl "loop"; + editorTemplate -endLayout; + + // Post Effects Section + editorTemplate -beginLayout "Post Effects" -collapse 0; + editorTemplate -addControl "postEffectCrop"; + editorTemplate -addControl "postEffectResize"; + editorTemplate -addControl "postEffectFlip"; + editorTemplate -endLayout; + + // Cache Section + editorTemplate -beginLayout "Cache" -collapse 0; + editorTemplate -addControl "cachePolicy"; + editorTemplate -addControl "cacheSize"; + editorTemplate -addControl "clearCache"; + editorTemplate -addControl "outCacheHitRatio"; + editorTemplate -endLayout; + + // Output Section + editorTemplate -beginLayout "Output" -collapse 0; + editorTemplate -addControl "outFrameWidth"; + editorTemplate -addControl "outFrameHeight"; + editorTemplate -addControl "outFrameTimestamp"; + editorTemplate -addControl "outFrameCount"; + editorTemplate -addControl "outIsValid"; + editorTemplate -endLayout; + + // Add AE call to the base class + editorTemplate -addExtraControls; + + editorTemplate -endScrollLayout; +} + +// Custom control creation for video file with browse button +global proc AETemplateMediaPlaneVideoFileCreate(string $nodeName) +{ + setUITemplate -pushTemplate attributeEditorTemplate; + + // Create label and textField in a row + rowLayout -numberOfColumns 3 + -columnWidth3 120 320 80 + -adjustableColumn 2 + -columnAlign3 "right" "center" "center" + -rowAttach 1 "left" 0; + + text -label "videoFile"; + + textField -tx "" -width 320 "AETemplateMediaPlaneVideoFileTextField"; + + button -label "Browse..." -width 80 + -command "AETemplateMediaPlaneBrowseButton()" + "AETemplateMediaPlaneBrowseButton"; + + setUITemplate -popTemplate; +} + +// Update callback for video file control +global proc AETemplateMediaPlaneVideoFileUpdate(string $nodeName) +{ + string $value = `getAttr ($nodeName + ".videoFile")`; + textField -edit -tx $value "AETemplateMediaPlaneVideoFileTextField"; +} + +// Browse button command +global proc AETemplateMediaPlaneBrowseButton() +{ + // Get the current text field value + string $currentFile = `textField -q -tx "AETemplateMediaPlaneVideoFileTextField"`; + + // Set up file filters + string $filters = "Video Files (*.mp4 *.mov *.avi *.mkv *.webm);;MP4 (*.mp4);;MOV (*.mov);;AVI (*.avi);;MKV (*.mkv);;WebM (*.webm);;All Files (*.*)"; + + // Open file dialog + string $result[] = `fileDialog2 + -fileFilter $filters + -dialogStyle 2 + -caption "Select Video File" + -startingDirectory ($currentFile != "" ? `dirname $currentFile` : "")`; + + // If user selected a file, update the text field + if (size($result) > 0) + { + textField -edit -tx $result[0] "AETemplateMediaPlaneVideoFileTextField"; + } +} + +// Registration procedure +global proc AEregisterMediaPlaneNode() +{ + // Register the AE template for MediaPlane node + // This is called from the plugin initialization +} diff --git a/src/MayaImagePlaneNode/CMakeLists.txt b/src/MayaMediaPlaneNode/CMakeLists.txt similarity index 82% rename from src/MayaImagePlaneNode/CMakeLists.txt rename to src/MayaMediaPlaneNode/CMakeLists.txt index e4292fe..d2bb13f 100644 --- a/src/MayaImagePlaneNode/CMakeLists.txt +++ b/src/MayaMediaPlaneNode/CMakeLists.txt @@ -1,5 +1,5 @@ -# MayaImagePlaneNode Plugin CMakeLists.txt -# This is a standalone project for the Maya Image Plane Node plugin +# MayaMediaPlaneNode Plugin CMakeLists.txt +# This is a standalone project for the Maya Media Plane Node plugin cmake_minimum_required(VERSION 3.14) @@ -37,6 +37,9 @@ set(PLUGIN_SRCS set(MOD_FILES MediaPlane.mod +) + +set(MEL_SCRIPTS AETemplateMediaPlane.mel ) @@ -44,23 +47,23 @@ set(MOD_FILES # Build Plugin # ============================================ -add_library(MayaImagePlaneNode MODULE ${PLUGIN_SRCS}) +add_library(MayaMediaPlaneNode MODULE ${PLUGIN_SRCS}) -set_target_properties(MayaImagePlaneNode PROPERTIES +set_target_properties(MayaMediaPlaneNode PROPERTIES PREFIX "" # No prefix for Maya plugin SUFFIX ".mll" # Maya plugin extension on Windows - OUTPUT_NAME "MayaImagePlaneNode" + OUTPUT_NAME "MayaMediaPlaneNode" ) # Link libraries -target_link_libraries(MayaImagePlaneNode PRIVATE +target_link_libraries(MayaMediaPlaneNode PRIVATE ${MAYA_LIBRARIES} ${FFMPEG_LIBRARIES} ) # Set Windows-specific properties if(WIN32) - set_target_properties(MayaImagePlaneNode PROPERTIES + set_target_properties(MayaMediaPlaneNode PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE COMPILE_FLAGS "/MDd" ) @@ -85,7 +88,7 @@ set(PLUGIN_INSTALL_DIR "plug-ins/${MAYA_VERSION_NUM}") set(BIN_INSTALL_DIR "bin") # Install plugin -install(TARGETS MayaImagePlaneNode +install(TARGETS MayaMediaPlaneNode RUNTIME DESTINATION ${PLUGIN_INSTALL_DIR} LIBRARY DESTINATION ${PLUGIN_INSTALL_DIR} ) @@ -94,6 +97,11 @@ install(FILES ${MOD_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX} ) +# Install MEL scripts to Maya scripts directory +install(FILES ${MEL_SCRIPTS} + DESTINATION "scripts" +) + # Install FFmpeg DLLs if(EXISTS "${FFMPEG_DLL_DIR}") file(GLOB FFMPEG_DLLS "${FFMPEG_DLL_DIR}/*.dll") @@ -109,7 +117,7 @@ endif() # Print configuration summary message(STATUS "===========================================") -message(STATUS "MayaImagePlaneNode Configuration Summary") +message(STATUS "MayaMediaPlaneNode Configuration Summary") message(STATUS "===========================================") message(STATUS "Maya Version: ${MAYA_VERSION}") message(STATUS "Maya Location: ${MAYA_LOCATION}") diff --git a/src/MayaImagePlaneNode/FFmpegVideoDecoder.cpp b/src/MayaMediaPlaneNode/FFmpegVideoDecoder.cpp similarity index 100% rename from src/MayaImagePlaneNode/FFmpegVideoDecoder.cpp rename to src/MayaMediaPlaneNode/FFmpegVideoDecoder.cpp diff --git a/src/MayaImagePlaneNode/FFmpegVideoDecoder.h b/src/MayaMediaPlaneNode/FFmpegVideoDecoder.h similarity index 100% rename from src/MayaImagePlaneNode/FFmpegVideoDecoder.h rename to src/MayaMediaPlaneNode/FFmpegVideoDecoder.h diff --git a/src/MayaImagePlaneNode/FrameCache.cpp b/src/MayaMediaPlaneNode/FrameCache.cpp similarity index 100% rename from src/MayaImagePlaneNode/FrameCache.cpp rename to src/MayaMediaPlaneNode/FrameCache.cpp diff --git a/src/MayaImagePlaneNode/FrameCache.h b/src/MayaMediaPlaneNode/FrameCache.h similarity index 100% rename from src/MayaImagePlaneNode/FrameCache.h rename to src/MayaMediaPlaneNode/FrameCache.h diff --git a/src/MayaImagePlaneNode/MayaMediaPlaneNode.cpp b/src/MayaMediaPlaneNode/MayaMediaPlaneNode.cpp similarity index 100% rename from src/MayaImagePlaneNode/MayaMediaPlaneNode.cpp rename to src/MayaMediaPlaneNode/MayaMediaPlaneNode.cpp diff --git a/src/MayaImagePlaneNode/MayaMediaPlaneNode.h b/src/MayaMediaPlaneNode/MayaMediaPlaneNode.h similarity index 100% rename from src/MayaImagePlaneNode/MayaMediaPlaneNode.h rename to src/MayaMediaPlaneNode/MayaMediaPlaneNode.h diff --git a/src/MayaImagePlaneNode/MediaPlane.mod b/src/MayaMediaPlaneNode/MediaPlane.mod similarity index 100% rename from src/MayaImagePlaneNode/MediaPlane.mod rename to src/MayaMediaPlaneNode/MediaPlane.mod diff --git a/src/MayaImagePlaneNode/Plugin.cpp b/src/MayaMediaPlaneNode/Plugin.cpp similarity index 100% rename from src/MayaImagePlaneNode/Plugin.cpp rename to src/MayaMediaPlaneNode/Plugin.cpp