Skip to content

Commit

Permalink
fix: QOL support for PySide6, basic standalone mode
Browse files Browse the repository at this point in the history
This commits adds:
- Qt.py as an abstraction for  PySide2/6, in order to support Maya 2025.
- Replaced QRegExp with python's built-in re module.
- Standalone mode by executing ReferenceImporterMain.py with python.
- Relative imports.
  • Loading branch information
JaimeFlorian27 committed Apr 1, 2024
1 parent 9d665eb commit 7567164
Show file tree
Hide file tree
Showing 10 changed files with 2,214 additions and 57 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ __pycache__/
# Distribution / packaging
.Python
build/
bin/
develop-eggs/
dist/
downloads/
Expand Down Expand Up @@ -148,4 +149,4 @@ cython_debug/
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
#.idea/
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ Script that automates the importing of video reference into Maya, automatically
## 2. Copy the contents of the zip to you Maya scripts folder
>found under 'Documents/maya/***InsertMayaVerion***/scripts'
## 2. Run the following command in Maya
from ReferenceImporterMain import ReferenceImporterDialog
ReferenceImporterDialog.run()
import reference_importer
reference_importer.run()
make sure to run it using Python

# Usage
Expand All @@ -24,4 +24,4 @@ make sure to run it using Python
### 3. Set output sequence name and format
### 4. Set output directory for the sequence
### 5. (Optional) auto creation of image plane in Maya for the sequence
### 6. Import the video!!
### 6. Import the video!!
79 changes: 51 additions & 28 deletions ReferenceImporterMain.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,72 @@
# Reference Importer v1.1, made by Jaime Florian
# Video Demonstration: https://www.youtube.com/watch?v=ObX9NU2BmZo

import os
import sys
libs = os.path.abspath(os.path.dirname(__file__))
libs = os.path.join(libs,'lib')
sys.path.append(libs)
from PySide2 import QtCore,QtGui,QtWidgets
import maya.cmds as cmds
import maya.OpenMaya as om
import maya.OpenMayaUI as omui
from shiboken2 import wrapInstance
from reference_importer import ImageSequencer, Ui
from pathlib import Path

VENDOR_PATH = Path(__file__).parent.resolve() / "vendor"
sys.path.insert(0, str(VENDOR_PATH))

import os
import re
from Qt import QtCore,QtWidgets
from Qt.QtCompat import wrapInstance

try:
import maya.cmds as cmds
import maya.OpenMaya as om
import maya.OpenMayaUI as omui
IN_MAYA = True
except ImportError:
IN_MAYA = False

from .reference_importer import ImageSequencer, Ui



def maya_main_window():
"""
Return the Maya main window widget as a Python object
"""
if not IN_MAYA:
return None

main_window_ptr = omui.MQtUtil.mainWindow()
return wrapInstance(int(main_window_ptr), QtWidgets.QWidget)
class ReferenceImporterDialog(QtWidgets.QDialog):

dlg_instance = None
qapp_instance = None

@classmethod
def run(cls):
if not cls.dlg_instance:
cls.dlg_instance = ReferenceImporterDialog()
if IN_MAYA:
if not cls.dlg_instance:
cls.dlg_instance = ReferenceImporterDialog()

if cls.dlg_instance.isHidden():
cls.dlg_instance.show()
else:
cls.dlg_instance.raise_()
cls.dlg_instance.activateWindow()
if cls.dlg_instance.isHidden():
cls.dlg_instance.show()
else:
cls.dlg_instance.raise_()
cls.dlg_instance.activateWindow()
return

if not cls.qapp_instance:
cls.qapp_instance = QtWidgets.QApplication(sys.argv)

dialog = ReferenceImporterDialog()
dialog.show()
cls.qapp_instance.exec_()

def __init__(self,parent=maya_main_window()):
def __init__(self, parent=maya_main_window()):
super(ReferenceImporterDialog,self).__init__(parent)
self.setWindowFlags(self.windowFlags() ^ QtCore.Qt.WindowContextHelpButtonHint)
self.imageSequencer = ImageSequencer()
self.ui = Ui(self)
self.CreateConnections()
self.ui.pushButton_create_image_sequence.setDisabled(True)
if not IN_MAYA:
self.ui.checkBox_imagePlane.setDisabled(True)

def CreateConnections(self):
self.ui.pushButton_fileExplorer_input.clicked.connect(self.SetInput)
Expand Down Expand Up @@ -107,14 +131,13 @@ def CheckText(self):
except Exception as e:
raise e

def ValidateTimecode(self, text, ):
timecode_rx = QtCore.QRegExp('([0-9]{2}[:]){1,2}[0-9]{2}[.]?[0-9]{0,2}')
timecode_validator = QtGui.QRegExpValidator(timecode_rx, self)
state = timecode_validator.validate(text,0)
if state[0] == QtGui.QRegExpValidator.Acceptable :
return True

else :
def ValidateTimecode(self, text):
timecode_rx = r'([0-9]{2}[:]){1,2}[0-9]{2}[.]?[0-9]{0,2}'
state = re.fullmatch(timecode_rx, text)
if state:
return True
else:
return False

def CreateImageSequence(self):
Expand All @@ -136,12 +159,12 @@ def CreateImageSequence(self):
trim_start,trim_end,
output_file)

if self.ui.checkBox_imagePlane.isChecked():
if self.ui.checkBox_imagePlane.isChecked() and IN_MAYA:
output_file = output_file.replace('%03d', '001')
image_plane = cmds.imagePlane(fn = output_file)
cmds.setAttr("%s.useFrameExtension"%image_plane[0],True)
except Exception as e:
raise e

if 'name' == "__main__":
pass
if __name__ == "__main__":
ReferenceImporterDialog.run()
4 changes: 2 additions & 2 deletions __init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from ReferenceImporterMain import ReferenceImporterDialog
from .ReferenceImporterMain import ReferenceImporterDialog

def run():
ReferenceImporterDialog.run()


if __name__ == "__main__":
run()
run()
Binary file removed lib/ffmpeg/ffmpeg.exe
Binary file not shown.
4 changes: 2 additions & 2 deletions reference_importer/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
from imageSequence import ImageSequencer
from ui import Ui
from .imageSequence import ImageSequencer
from .ui import Ui
24 changes: 8 additions & 16 deletions reference_importer/imageSequence.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
import sys
import os
from pathlib import Path
import subprocess


Expand All @@ -18,32 +17,25 @@ def __init__(self, video_file="",
self.padding = padding
self.trim_start = 0
self.trim_end = 0
self.encoding = 'cp1252'
self.ffmpeg_path = os.path.abspath(os.path.dirname(__file__)
).decode(self.encoding)
self.ffmpeg_path = os.path.join(self.ffmpeg_path,
'..',
'lib',
'ffmpeg',
'ffmpeg')
self.ffmpeg_path = Path(__file__).parent.parent.resolve() / "bin" / "ffmpeg"

def getDuration(self, video_file):
command = (u'"%s" -i "%s" 2>&1 | findstr "Duration"' %(self.ffmpeg_path,video_file)).encode(self.encoding)
command = (u'"%s" -i "%s" 2>&1 | findstr "Duration"' %(self.ffmpeg_path,video_file))
try:
process = subprocess.check_output(command, shell=True).encode(self.encoding)
process = subprocess.check_output(command, shell=True)
process = str(process).strip()
process = process.split(" ")
process = process[1][0:11]
process = process[3][0:11]
except Exception as e:
raise e
return process
def createSequence(self,input_file, frameRate,start_trim,end_trim, output_file):
command = ('"%s" -i "%s" -r %s -vf scale=1280:-1 -q:v 3 -ss %s -to %s "%s"' % (self.ffmpeg_path,input_file,frameRate,start_trim,end_trim,output_file)).encode(self.encoding)
command = ('"%s" -i "%s" -r %s -vf scale=1280:-1 -q:v 3 -ss %s -to %s "%s"' % (self.ffmpeg_path,input_file,frameRate,start_trim,end_trim,output_file))
try:
subprocess.call(command)
subprocess.run(command, shell=True)
except Exception as e:
raise e


if __name__ == "__main__":
pass
pass
2 changes: 1 addition & 1 deletion reference_importer/ui/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from main_dialog_ui import Ui
from .main_dialog_ui import Ui
11 changes: 7 additions & 4 deletions reference_importer/ui/main_dialog_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################

from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
# Use Qt.py to support multiple Qt versions.
# Should already be in sys.path when running through ReferenceImporterMain.py.

from Qt.QtCore import *
from Qt.QtGui import *
from Qt.QtWidgets import *


class Ui(object):
Expand Down Expand Up @@ -145,7 +148,7 @@ def __init__(self, Dialog):
# setupUi

def setTexts(self, Dialog):
Dialog.setWindowTitle(u"Reference Importer v1.1")
Dialog.setWindowTitle(u"Reference Importer v1.1.2")
self.groupBox_input.setTitle(u"Input")
self.label_video_file.setText(u"Video File")
self.pushButton_fileExplorer_input.setText(u"Open...")
Expand Down
Loading

0 comments on commit 7567164

Please sign in to comment.