Metahuman_DNA_Calibration/dna_viewer/ui/dna_viewer_window.py

247 lines
7.6 KiB
Python
Raw Normal View History

2022-10-31 18:15:50 +08:00
import logging
from pathlib import Path
from typing import Optional
from maya.cmds import confirmDialog
from PySide2 import QtCore, QtWidgets
from ..builder.scene import Scene
from ..config.aas import AdditionalAssemblyScript
from ..config.analog_gui import AnalogGui
from ..config.character import Character
from ..config.gui import Gui
from ..config.rig_logic import RigLogic
from ..config.units import AngleUnit, LinearUnit
from ..const.ui import (
MARGIN_BOTTOM,
MARGIN_LEFT,
MARGIN_RIGHT,
MARGIN_TOP,
SPACING,
WINDOW_OBJECT,
WINDOW_SIZE_HEIGHT_MAX,
WINDOW_SIZE_HEIGHT_MIN,
WINDOW_SIZE_WIDTH_MAX,
WINDOW_SIZE_WIDTH_MIN,
WINDOW_TITLE,
)
from ..reader.dna import DNA
from ..ui.elements import Elements
from ..ui.elements_creator import ElementsCreator
from .widgets import QHLine
def show_dna_viewer_window() -> None:
DnaViewerWindow.show_window()
class DnaViewerWindow(QtWidgets.QMainWindow):
"""
UI Window
Attributes
----------
@type elements: Elements
@param elements: The object containing references to the UI elements
@type elements_creator: ElementsCreator
@param elements_creator: The class used for creating UI elements
@type build_scene_successful: bool
@param build_scene_successful: A flag representing if building of the scene was a success
@type character_config: Character
@param character_config: The character configuration that will be processed
"""
window: QtWidgets.QMainWindow = None
def __init__(self, parent: QtWidgets.QWidget = None) -> None:
super().__init__(parent)
self.elements = Elements()
self.elements_creator = ElementsCreator(self, self.elements)
self.setup_window()
self.create_ui()
self.build_scene_successful = False
self.character_config: Optional[Character] = None
def setup_window(self) -> None:
"""A method for setting up the window"""
self.setWindowFlags(
self.windowFlags()
| QtCore.Qt.WindowTitleHint
| QtCore.Qt.WindowMaximizeButtonHint
| QtCore.Qt.WindowMinimizeButtonHint
| QtCore.Qt.WindowCloseButtonHint
)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.setObjectName(WINDOW_OBJECT)
self.setWindowTitle(WINDOW_TITLE)
self.setWindowFlags(QtCore.Qt.Window)
self.setFocusPolicy(QtCore.Qt.StrongFocus)
def create_ui(self) -> None:
"""Fills the window with UI elements"""
self.elements.main_widget = self.create_main_widget()
self.setCentralWidget(self.elements.main_widget)
self.set_size()
def create_main_widget(self) -> QtWidgets.QWidget:
"""
Creates the widget containing the UI elements
@rtype: QtWidgets.QWidget
@returns: the main widget
"""
header = self.elements_creator.create_header()
body = self.elements_creator.create_body()
widget = QtWidgets.QWidget()
layout = QtWidgets.QVBoxLayout(widget)
layout.addLayout(header)
layout.addWidget(QHLine())
layout.addLayout(body)
layout.setContentsMargins(MARGIN_LEFT, MARGIN_TOP, MARGIN_RIGHT, MARGIN_BOTTOM)
layout.setSpacing(SPACING)
return widget
def set_size(self) -> None:
"""Sets the window size"""
self.setMaximumSize(WINDOW_SIZE_WIDTH_MAX, WINDOW_SIZE_HEIGHT_MAX)
self.setMinimumSize(WINDOW_SIZE_WIDTH_MIN, WINDOW_SIZE_HEIGHT_MIN)
self.resize(WINDOW_SIZE_WIDTH_MIN, WINDOW_SIZE_HEIGHT_MIN)
def process(self) -> None:
"""Start the build process of creation of scene from provided configuration from the UI"""
self.character_config = self.get_character_config()
self.elements.main_widget.setEnabled(False)
self.build_scene()
self.elements.main_widget.setEnabled(True)
def get_character_config(self) -> Character:
"""
Gets the character config from the UI elements
@rtype: Character
@returns: character configuration object
"""
gui_path = self.elements.get_gui_path()
gui_options = Gui(gui_path=gui_path) if gui_path else None
analog_gui_path = self.elements.get_analog_gui_path()
analog_gui_options = (
AnalogGui(gui_path=analog_gui_path) if analog_gui_path else None
)
aas_path = self.elements.get_aas_path()
aas = (
AdditionalAssemblyScript(
path=aas_path,
module_name=Path(aas_path).stem,
)
if aas_path
else None
)
riglogic = (
RigLogic() if Elements.is_checked(self.elements.rig_logic_cb) else None
)
config = Character(
dna=self.elements.dna,
create_character_node=False,
create_display_layers=False,
meshes=self.elements.mesh_tree_list.get_selected_meshes(),
gui_options=gui_options,
analog_gui_options=analog_gui_options,
aas=aas,
rig_logic_config=riglogic,
)
config.options = self.elements.get_build_options()
return config
def set_progress(self, text: str = None, value: int = None) -> None:
"""Setting text and/or value to progress bar"""
if text is not None:
self.elements.progress_bar.setFormat(text)
if value is not None:
self.elements.progress_bar.setValue(value)
def build_scene(self) -> None:
"""Start building the scene"""
try:
self.set_progress(text="Processing in progress...", value=0)
dna_file_path = Elements.get_file_path(self.elements.select_dna_path)
if dna_file_path:
DNA.load_dna(dna_file_path)
self.set_progress(value=33)
builder = Scene()
builder.config.with_character(self.character_config)
builder.config.with_linear_unit(unit=LinearUnit.cm).with_angle_unit(
unit=AngleUnit.degree
)
self.set_progress(value=66)
builder.build()
self.set_progress(text="Processing completed", value=100)
except Exception as e:
self.set_progress(text="Processing failed", value=100)
logging.error(e)
confirmDialog(message=e, button=["ok"], icon="critical")
@staticmethod
def show_window() -> None:
if DnaViewerWindow.window is None:
DnaViewerWindow.window = DnaViewerWindow(
parent=DnaViewerWindow.maya_main_window()
)
DnaViewerWindow.activate_window()
@staticmethod
def maya_main_window() -> QtWidgets.QWidget:
"""
Gets the MayaWindow instance
@throws RuntimeError
@rtype: QtWidgets.QWidget
@returns: main window instance
"""
for obj in QtWidgets.QApplication.topLevelWidgets():
if obj.objectName() == "MayaWindow":
return obj
raise RuntimeError("Could not find MayaWindow instance")
@staticmethod
def activate_window() -> None:
"""Shows window if minimized"""
try:
DnaViewerWindow.window.show()
if DnaViewerWindow.window.windowState() & QtCore.Qt.WindowMinimized:
DnaViewerWindow.window.setWindowState(QtCore.Qt.WindowActive)
DnaViewerWindow.window.raise_()
DnaViewerWindow.window.activateWindow()
except RuntimeError as e:
print(e)
if str(e).rstrip().endswith("already deleted."):
DnaViewerWindow.window = None
DnaViewerWindow.show_window()