MetaFusion/scripts/ui/rigging.py
2025-02-11 00:04:32 +08:00

357 lines
13 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#===================================== 1. Module Imports =====================================
import maya.OpenMayaUI as omui
from scripts import config
import maya.cmds as cmds
import maya.mel as mel
import webbrowser
import sys
import os
from scripts import config
QtCore, QtGui, QtWidgets, wrapInstance = config.Qt()
if QtCore is None or QtGui is None or QtWidgets is None or wrapInstance is None:
print(f"Qt加载失败: {QtCore}, {QtGui}, {QtWidgets}, {wrapInstance}")
class RiggingTab(QtWidgets.QWidget):
def __init__(self, parent=None):
super(RiggingTab, self).__init__(parent)
self._setup_ui()
self._create_connections()
def _setup_ui(self):
"""设置UI布局"""
# === Main Layout ===
self.main_layout = QtWidgets.QVBoxLayout(self)
self.main_layout.setContentsMargins(0, 0, 0, 0)
self.main_layout.setSpacing(0)
# === DNA预览区域 ===
self.preview_area = self._create_preview_area()
# === 设置区域 ===
self.settings_area = QtWidgets.QWidget()
settings_layout = QtWidgets.QVBoxLayout(self.settings_area)
settings_layout.setContentsMargins(8, 8, 8, 8)
settings_layout.setSpacing(4)
# === 资产设置 ===
asset_group = QtWidgets.QWidget()
asset_layout = QtWidgets.QGridLayout(asset_group)
asset_layout.setContentsMargins(0, 0, 0, 0)
asset_layout.setSpacing(4)
# 项目路径
path_label = QtWidgets.QLabel("项目路径:")
self.path_edit = QtWidgets.QLineEdit()
self.path_edit.setText("D:/Personal/Document/maya/SuperRiggingEditor/files/data/MetaHuman")
self.path_btn = QtWidgets.QPushButton("加载...")
self.path_btn.setIcon(QtGui.QIcon(":fileOpen.png")) # 使用Maya内置图标
self.path_btn.setFixedWidth(60) # 调整按钮宽度
self.path_btn.setFixedHeight(24)
# 预设文件
preset_label = QtWidgets.QLabel("预设文件:")
self.preset_edit = QtWidgets.QLineEdit()
self.preset_edit.setText("nal/Document/maya/SuperRiggingEditor/files/presets/metahuman/MH_Ada.dna")
self.preset_btn = QtWidgets.QPushButton("加载...")
self.preset_btn.setIcon(QtGui.QIcon(":fileOpen.png")) # 使用Maya内置图标
self.preset_btn.setFixedWidth(60) # 调整按钮宽度
self.preset_btn.setFixedHeight(24)
# 数据分层
layer_label = QtWidgets.QLabel("数据分层:")
self.layer_combo = QtWidgets.QComboBox()
self.layer_combo.addItem("行为(包括基础定义)")
self.override_check = QtWidgets.QCheckBox("覆盖表情")
self.override_check.setChecked(True)
self.override_check.setStyleSheet("""
QCheckBox {
background: transparent;
}
QCheckBox::indicator {
width: 16px;
height: 16px;
background: #3D3D3D;
border: 1px solid #555555;
border-radius: 2px;
}
QCheckBox::indicator:checked {
background: #3D3D3D;
image: url(:checkboxChecked.png);
}
QCheckBox::indicator:unchecked {
background: #3D3D3D;
image: url(:checkboxUnchecked.png);
}
QCheckBox::indicator:hover {
border: 1px solid #666666;
}
""")
# 添加到资产布局
asset_layout.addWidget(path_label, 0, 0)
asset_layout.addWidget(self.path_edit, 0, 1)
asset_layout.addWidget(self.path_btn, 0, 2)
asset_layout.addWidget(preset_label, 1, 0)
asset_layout.addWidget(self.preset_edit, 1, 1)
asset_layout.addWidget(self.preset_btn, 1, 2)
asset_layout.addWidget(layer_label, 2, 0)
asset_layout.addWidget(self.layer_combo, 2, 1)
asset_layout.addWidget(self.override_check, 2, 2)
# === 描述设置 ===
desc_group = QtWidgets.QWidget()
desc_layout = QtWidgets.QGridLayout(desc_group)
desc_layout.setContentsMargins(0, 0, 0, 0)
desc_layout.setSpacing(4)
# 设置列的拉伸因子,使左右两侧均等
desc_layout.setColumnStretch(0, 0) # 左侧标签不拉伸
desc_layout.setColumnStretch(1, 1) # 左侧控件拉伸
desc_layout.setColumnStretch(2, 0) # 右侧标签不拉伸
desc_layout.setColumnStretch(3, 1) # 右侧控件拉伸
# 左侧设置
left_settings = [
("名称:", "Archetype", "line"),
("原型:", "其他", "combo"),
("性别:", "女性", "combo"),
("年龄:", "24", "spin")
]
# 右侧设置
right_settings = [
("变换单位:", "厘米", "combo"),
("旋转单位:", "角度", "combo"),
("向上轴:", "Z轴向上", "combo"),
("LOD计数:", "8", "spin")
]
# 添加左侧设置
for row, (label_text, default_value, control_type) in enumerate(left_settings):
label = QtWidgets.QLabel(label_text)
label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) # 标签左对齐
label.setFixedWidth(50) # 固定标签宽度
if control_type == "line":
control = QtWidgets.QLineEdit(default_value)
elif control_type == "combo":
control = QtWidgets.QComboBox()
control.addItem(default_value)
elif control_type == "spin":
control = QtWidgets.QSpinBox()
control.setValue(int(default_value))
desc_layout.addWidget(label, row, 0)
desc_layout.addWidget(control, row, 1)
# 添加右侧设置
for row, (label_text, default_value, control_type) in enumerate(right_settings):
label = QtWidgets.QLabel(label_text)
label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) # 标签左对齐
label.setFixedWidth(70) # 固定标签宽度,右侧标签略宽
if control_type == "line":
control = QtWidgets.QLineEdit(default_value)
elif control_type == "combo":
control = QtWidgets.QComboBox()
control.addItem(default_value)
elif control_type == "spin":
control = QtWidgets.QSpinBox()
control.setValue(int(default_value))
desc_layout.addWidget(label, row, 2)
desc_layout.addWidget(control, row, 3)
# 设置列间距
desc_layout.setHorizontalSpacing(8) # 增加列之间的间距
# === 底部按钮 ===
button_group = QtWidgets.QWidget()
button_layout = QtWidgets.QHBoxLayout(button_group)
button_layout.setContentsMargins(8, 4, 8, 4)
button_layout.setSpacing(4) # 减小按钮间距
# 创建功能按钮
self.clear_btn = self._create_tool_button("清空选项", "delete.png", "delete.png")
self.import_btn = self._create_tool_button("导入骨架", "HIKCharacterToolSkeleton.png", "kinJoint.png")
self.create_btn = self._create_tool_button("创建骨架", "HIKcreateControlRig.png", "kinHandle.png")
# 设置按钮的大小策略
for btn in [self.clear_btn, self.import_btn, self.create_btn]:
btn.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
btn.setMinimumHeight(32)
button_layout.addWidget(btn)
if btn != self.create_btn:
button_layout.addSpacing(4)
# === 添加到主设置布局 ===
settings_layout.addWidget(asset_group)
settings_layout.addWidget(desc_group)
settings_layout.addStretch()
settings_layout.addWidget(button_group)
# === 添加到主布局 ===
self.main_layout.addWidget(self.preview_area, stretch=1)
self.main_layout.addWidget(self.settings_area)
# === 设置样式 ===
self._setup_style()
def _create_preview_area(self):
"""创建DNA预览区域"""
widget = QtWidgets.QWidget()
layout = QtWidgets.QVBoxLayout(widget)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(0)
# 预览区域 - 单个大框
preview_widget = QtWidgets.QFrame()
preview_widget.setStyleSheet("""
QFrame {
background: #1D1D1D;
border: 1px solid #555555;
}
""")
preview_widget.setMinimumHeight(300) # 调整预览区域高度
# 底部控制区域
control_widget = QtWidgets.QWidget()
control_layout = QtWidgets.QHBoxLayout(control_widget)
control_layout.setContentsMargins(8, 4, 8, 4)
control_layout.setSpacing(8)
# 左侧数值显示和滑块
value_widget = QtWidgets.QWidget()
value_layout = QtWidgets.QHBoxLayout(value_widget)
value_layout.setContentsMargins(0, 0, 0, 0)
value_layout.setSpacing(4)
self.scale_value = QtWidgets.QLabel("90")
self.scale_value.setFixedWidth(30)
self.scale_value.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
self.scale_slider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
self.scale_slider.setRange(0, 100)
self.scale_slider.setValue(90)
self.scale_slider.valueChanged.connect(self._on_scale_changed) # 添加滑块值变化事件
value_layout.addWidget(self.scale_value)
value_layout.addWidget(self.scale_slider)
# 右侧按钮
self.export_btn = QtWidgets.QPushButton("导出预设")
self.export_btn.setIcon(QtGui.QIcon(":save.png")) # 使用Maya内置图标
self.export_btn.setFixedHeight(24)
self.export_btn.setMinimumWidth(80) # 设置最小宽度
self.import_btn = QtWidgets.QPushButton("导入预设")
self.import_btn.setIcon(QtGui.QIcon(":fileOpen.png")) # 使用Maya内置图标
self.import_btn.setFixedHeight(24)
self.import_btn.setMinimumWidth(80) # 设置最小宽度
# 添加到控制布局
# 设置这行高度
control_layout.setContentsMargins(0, 0, 0, 0)
control_layout.setSpacing(4)
control_layout.addWidget(value_widget)
control_layout.addWidget(self.export_btn)
control_layout.addWidget(self.import_btn)
# 添加到主布局
layout.addWidget(preview_widget)
layout.addWidget(control_widget)
return widget
def _create_tool_button(self, text, icon_name, fallback_icon=None):
"""创建工具按钮"""
btn = QtWidgets.QPushButton(text)
# 尝试使用自定义图标如果失败则使用Maya内置图标
icon_path = f"{config.ICONS_PATH}/{icon_name}"
if os.path.exists(icon_path):
btn.setIcon(QtGui.QIcon(icon_path))
elif fallback_icon:
btn.setIcon(QtGui.QIcon(f":{fallback_icon}"))
return btn
def _setup_style(self):
"""设置样式"""
self.setStyleSheet("""
QWidget {
background: #2D2D2D;
color: #CCCCCC;
}
QLabel {
background: transparent;
}
QLineEdit, QComboBox {
background: #3D3D3D;
border: 1px solid #555555;
border-radius: 2px;
padding: 4px;
color: #CCCCCC;
min-height: 22px;
}
QPushButton {
background: #3D3D3D;
border: 1px solid #555555;
border-radius: 2px;
padding: 4px 8px;
color: #CCCCCC;
}
QPushButton:hover {
background: #454545;
}
QPushButton:pressed {
background: #2A2A2A;
}
QCheckBox {
spacing: 8px;
background: transparent;
}
QCheckBox::indicator {
width: 16px;
height: 16px;
}
QSlider::groove:horizontal {
border: 1px solid #555555;
height: 4px;
background: #3D3D3D;
margin: 0px;
border-radius: 2px;
}
QSlider::handle:horizontal {
background: #CCCCCC;
border: 1px solid #555555;
width: 12px;
height: 12px;
margin: -4px 0;
border-radius: 6px;
}
QSlider::handle:horizontal:hover {
background: #FFFFFF;
}
""")
def _on_scale_changed(self, value):
"""滑块值变化事件处理"""
self.scale_value.setText(str(value))
def _create_connections(self):
"""创建信号连接"""
# 滑块值变化事件
self.scale_slider.valueChanged.connect(self._on_scale_changed)
# TODO: 添加信号连接
pass
if __name__ == "__main__":
pass