This commit is contained in:
2025-05-05 19:57:27 +08:00
parent 46d93efb3c
commit f4f0c8196c
10 changed files with 2459 additions and 411 deletions

View File

@@ -60,6 +60,8 @@ class MainWindow(QtWidgets.QWidget):
self.setWindowTitle(TOOL_NAME)
self.setObjectName(f"{TOOL_NAME}MainWindow")
self.setMinimumSize(1200, 800)
self.setStyleSheet("")
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
# 设置窗口图标
if os.path.exists(TOOL_ICON):

View File

@@ -86,14 +86,10 @@ class BehaviourUI(ui_utils.BaseUI):
包括按钮、标签、列表等
"""
# 标题标签
self.controls["title_label"] = QtWidgets.QLabel(LANG.get("behaviour_title", "角色行为"))
self.controls["title_label"] = QtWidgets.QLabel(LANG.get("behaviour_title", "行为"))
self.controls["title_label"].setObjectName("behaviourTitleLabel")
self.controls["title_label"].setAlignment(QtCore.Qt.AlignCenter)
# 创建主分割器
self.splitters["main_splitter"] = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
self.splitters["main_splitter"].setObjectName("behaviourMainSplitter")
# 左侧面板
self.controls["left_panel"] = QtWidgets.QWidget()
self.controls["left_panel"].setObjectName("behaviourLeftPanel")
@@ -102,56 +98,150 @@ class BehaviourUI(ui_utils.BaseUI):
self.controls["right_panel"] = QtWidgets.QWidget()
self.controls["right_panel"].setObjectName("behaviourRightPanel")
# 左侧面板控件
# Blendshape列表组
self.controls["blendshape_group"] = QtWidgets.QGroupBox(LANG.get("blendshape_group", "Blendshape列表"))
self.controls["blendshape_group"].setObjectName("blendshapeGroup")
# 左侧面板控件 - Raw Control
self.controls["raw_control_group"] = QtWidgets.QGroupBox("Raw Control [000]")
self.controls["raw_control_group"].setObjectName("rawControlGroup")
# Blendshape列表
self.controls["blendshape_list"] = QtWidgets.QListWidget()
self.controls["blendshape_list"].setObjectName("blendshapeList")
# 搜索框
self.controls["search_input"] = QtWidgets.QLineEdit()
self.controls["search_input"].setObjectName("searchInput")
self.controls["search_input"].setPlaceholderText(LANG.get("search", "搜索..."))
# Blendshape刷新按钮
self.buttons["refresh_blendshape"] = QtWidgets.QPushButton(LANG.get("refresh", "刷新"))
self.buttons["refresh_blendshape"].setObjectName("refreshBlendshapeButton")
# 控制列表
self.controls["control_list"] = QtWidgets.QListWidget()
self.controls["control_list"].setObjectName("controlList")
# Blendshape过滤组
self.controls["blendshape_filter_group"] = QtWidgets.QGroupBox(LANG.get("blendshape_filter", "Blendshape过滤"))
self.controls["blendshape_filter_group"].setObjectName("blendshapeFilterGroup")
# 底部滑块和按钮
self.controls["bottom_slider"] = QtWidgets.QSlider(QtCore.Qt.Horizontal)
self.controls["bottom_slider"].setObjectName("bottomSlider")
self.controls["bottom_slider"].setMinimum(0)
self.controls["bottom_slider"].setMaximum(100)
self.controls["bottom_slider"].setValue(10)
# Blendshape过滤输入框
self.controls["blendshape_filter_input"] = QtWidgets.QLineEdit()
self.controls["blendshape_filter_input"].setObjectName("blendshapeFilterInput")
self.controls["blendshape_filter_input"].setPlaceholderText(LANG.get("filter_placeholder", "输入过滤条件"))
# 页码按钮
self.buttons["page_all"] = QtWidgets.QPushButton("All")
self.buttons["page_all"].setObjectName("pageAllButton")
self.buttons["page_all"].setCheckable(True)
self.buttons["page_all"].setChecked(True)
# 次级Blendshape列表组
self.controls["secondary_blendshape_group"] = QtWidgets.QGroupBox(LANG.get("secondary_blendshape_group", "次级Blendshape"))
self.controls["secondary_blendshape_group"].setObjectName("secondaryBlendshapeGroup")
self.buttons["page_2"] = QtWidgets.QPushButton("2")
self.buttons["page_2"].setObjectName("page2Button")
self.buttons["page_2"].setCheckable(True)
# 次级Blendshape列表
self.controls["secondary_blendshape_list"] = QtWidgets.QListWidget()
self.controls["secondary_blendshape_list"].setObjectName("secondaryBlendshapeList")
self.buttons["page_3"] = QtWidgets.QPushButton("3")
self.buttons["page_3"].setObjectName("page3Button")
self.buttons["page_3"].setCheckable(True)
# 次级Blendshape刷新按钮
self.buttons["refresh_secondary_blendshape"] = QtWidgets.QPushButton(LANG.get("refresh", "刷新"))
self.buttons["refresh_secondary_blendshape"].setObjectName("refreshSecondaryBlendshapeButton")
self.buttons["page_4"] = QtWidgets.QPushButton("4")
self.buttons["page_4"].setObjectName("page4Button")
self.buttons["page_4"].setCheckable(True)
# 右侧面板控件
# Blendshape操作组
self.controls["blendshape_ops_group"] = QtWidgets.QGroupBox(LANG.get("blendshape_operations", "Blendshape操作"))
self.controls["blendshape_ops_group"].setObjectName("blendshapeOpsGroup")
self.buttons["page_5"] = QtWidgets.QPushButton("5")
self.buttons["page_5"].setObjectName("page5Button")
self.buttons["page_5"].setCheckable(True)
# Blendshape操作按钮
self.buttons["export_blendshape"] = QtWidgets.QPushButton(LANG.get("export_blendshape", "导出Blendshape"))
self.buttons["import_blendshape"] = QtWidgets.QPushButton(LANG.get("import_blendshape", "导入Blendshape"))
self.buttons["edit_range"] = QtWidgets.QPushButton(LANG.get("edit_range", "编辑范围"))
self.buttons["mirror_blendshape"] = QtWidgets.QPushButton(LANG.get("mirror_blendshape", "镜像Blendshape"))
self.buttons["find_flip_target"] = QtWidgets.QPushButton(LANG.get("find_flip_target", "查找翻转目标"))
self.buttons["page_6"] = QtWidgets.QPushButton("6")
self.buttons["page_6"].setObjectName("page6Button")
self.buttons["page_6"].setCheckable(True)
# 表情控制组
self.controls["expression_control_group"] = QtWidgets.QGroupBox(LANG.get("expression_control", "表情控制"))
self.controls["expression_control_group"].setObjectName("expressionControlGroup")
# 左下角按钮
self.buttons["range_minus"] = QtWidgets.QPushButton("-")
self.buttons["range_minus"].setObjectName("rangeMinusButton")
self.buttons["range_plus"] = QtWidgets.QPushButton("+")
self.buttons["range_plus"].setObjectName("rangePlusButton")
# 右侧面板控件 - Related BlendShapes
self.controls["blendshapes_group"] = QtWidgets.QGroupBox("Related BlendShapes [000]")
self.controls["blendshapes_group"].setObjectName("blendshapesGroup")
# BlendShapes列表
self.controls["blendshapes_list"] = QtWidgets.QListWidget()
self.controls["blendshapes_list"].setObjectName("blendshapesList")
# 底部滑块和按钮
self.controls["bs_slider"] = QtWidgets.QSlider(QtCore.Qt.Horizontal)
self.controls["bs_slider"].setObjectName("bsSlider")
self.controls["bs_slider"].setMinimum(0)
self.controls["bs_slider"].setMaximum(100)
self.controls["bs_slider"].setValue(0)
# BlendShape操作按钮
self.buttons["reset_blendshape"] = QtWidgets.QPushButton(LANG.get("reset_blendshape", "重置混合形状"))
self.buttons["reset_blendshape"].setObjectName("resetBlendshapeButton")
self.buttons["mirror_blendshape"] = QtWidgets.QPushButton(LANG.get("mirror_blendshape", "镜像混合形状"))
self.buttons["mirror_blendshape"].setObjectName("mirrorBlendshapeButton")
self.buttons["add_blendshape"] = QtWidgets.QPushButton(LANG.get("add_blendshape", "添加混合形状"))
self.buttons["add_blendshape"].setObjectName("addBlendshapeButton")
self.buttons["remove_blendshape"] = QtWidgets.QPushButton(LANG.get("remove_blendshape", "移除混合形状"))
self.buttons["remove_blendshape"].setObjectName("removeBlendshapeButton")
self.buttons["update_blendshape"] = QtWidgets.QPushButton(LANG.get("update_blendshape", "更新混合形状"))
self.buttons["update_blendshape"].setObjectName("updateBlendshapeButton")
self.buttons["isolate_blendshape"] = QtWidgets.QPushButton(LANG.get("isolate_blendshape", "隔离混合形状"))
self.buttons["isolate_blendshape"].setObjectName("isolateBlendshapeButton")
self.buttons["new_blendshape"] = QtWidgets.QPushButton(LANG.get("new_blendshape", "新建混合形状"))
self.buttons["new_blendshape"].setObjectName("newBlendshapeButton")
self.buttons["combine_blendshape"] = QtWidgets.QPushButton(LANG.get("combine_blendshape", "组合混合形状"))
self.buttons["combine_blendshape"].setObjectName("combineBlendshapeButton")
# 底部标签页按钮
self.buttons["tab_bs"] = QtWidgets.QPushButton("BS")
self.buttons["tab_bs"].setObjectName("tabBsButton")
self.buttons["tab_bs"].setCheckable(True)
self.buttons["tab_bs"].setChecked(True)
self.buttons["tab_psd"] = QtWidgets.QPushButton("PSD")
self.buttons["tab_psd"].setObjectName("tabPsdButton")
self.buttons["tab_psd"].setCheckable(True)
self.buttons["tab_key"] = QtWidgets.QPushButton("KEY")
self.buttons["tab_key"].setObjectName("tabKeyButton")
self.buttons["tab_key"].setCheckable(True)
self.buttons["tab_jnt"] = QtWidgets.QPushButton("JNT")
self.buttons["tab_jnt"].setObjectName("tabJntButton")
self.buttons["tab_jnt"].setCheckable(True)
self.buttons["tab_ark"] = QtWidgets.QPushButton("ARK")
self.buttons["tab_ark"].setObjectName("tabArkButton")
self.buttons["tab_ark"].setCheckable(True)
self.buttons["tab_ctr"] = QtWidgets.QPushButton("CTR")
self.buttons["tab_ctr"].setObjectName("tabCtrButton")
self.buttons["tab_ctr"].setCheckable(True)
# 底部滑块
self.controls["bottom_main_slider"] = QtWidgets.QSlider(QtCore.Qt.Horizontal)
self.controls["bottom_main_slider"].setObjectName("bottomMainSlider")
self.controls["bottom_main_slider"].setMinimum(0)
self.controls["bottom_main_slider"].setMaximum(100)
self.controls["bottom_main_slider"].setValue(0)
# 底部按钮
self.buttons["exchange_from_expression"] = QtWidgets.QPushButton(LANG.get("exchange_from_expression", "交换从表情"))
self.buttons["exchange_from_expression"].setObjectName("exchangeFromExpressionButton")
self.buttons["reset_selected_expression"] = QtWidgets.QPushButton(LANG.get("reset_selected_expression", "重置选定表情"))
self.buttons["reset_selected_expression"].setObjectName("resetSelectedExpressionButton")
self.buttons["import_expression"] = QtWidgets.QPushButton(LANG.get("import_expression", "导入表情"))
self.buttons["import_expression"].setObjectName("importExpressionButton")
self.buttons["control_panel_search"] = QtWidgets.QPushButton(LANG.get("control_panel_search", "控制面板搜索"))
self.buttons["control_panel_search"].setObjectName("controlPanelSearchButton")
self.buttons["select_related_keys"] = QtWidgets.QPushButton(LANG.get("select_related_keys", "选择相关键值"))
self.buttons["select_related_keys"].setObjectName("selectRelatedKeysButton")
self.buttons["import_map_expression"] = QtWidgets.QPushButton(LANG.get("import_map_expression", "导入表情映射"))
self.buttons["import_map_expression"].setObjectName("importMapExpressionButton")
# 表情控制按钮
self.buttons["reset_expression"] = QtWidgets.QPushButton(LANG.get("reset_expression", "还原默认表情"))
self.buttons["find_expression"] = QtWidgets.QPushButton(LANG.get("find_expression", "查找选择表情"))
@@ -161,76 +251,154 @@ class BehaviourUI(ui_utils.BaseUI):
def create_layouts(self):
"""
创建行为系统UI布局
组织控件的排列和层次结构
安排控件的位置和尺寸
"""
# 主布局
self.layouts["main_layout"] = QtWidgets.QVBoxLayout(self.main_widget)
self.layouts["main_layout"].setContentsMargins(5, 5, 5, 5)
self.layouts["main_layout"].setSpacing(5)
self.layouts["main_layout"] = QtWidgets.QVBoxLayout(self)
self.layouts["main_layout"].setContentsMargins(2, 2, 2, 2)
self.layouts["main_layout"].setSpacing(2)
# 添加标题标签
self.layouts["main_layout"].addWidget(self.controls["title_label"])
# 添加主分割器
# 创建主分割器
self.splitters["main_splitter"] = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
self.splitters["main_splitter"].setObjectName("behaviourMainSplitter")
self.layouts["main_layout"].addWidget(self.splitters["main_splitter"])
# 将左右面板添加到主分割器
self.splitters["main_splitter"].addWidget(self.controls["left_panel"])
self.splitters["main_splitter"].addWidget(self.controls["right_panel"])
# 左侧面板布局
self.layouts["left_layout"] = QtWidgets.QVBoxLayout(self.controls["left_panel"])
self.layouts["left_layout"].setContentsMargins(5, 5, 5, 5)
self.layouts["left_layout"].setSpacing(5)
# Blendshape列表组布局
self.layouts["blendshape_layout"] = QtWidgets.QVBoxLayout(self.controls["blendshape_group"])
self.layouts["blendshape_layout"].addWidget(self.controls["blendshape_list"])
self.layouts["blendshape_layout"].addWidget(self.buttons["refresh_blendshape"])
# Raw Control组布局
self.layouts["raw_control_layout"] = QtWidgets.QVBoxLayout(self.controls["raw_control_group"])
self.layouts["raw_control_layout"].setContentsMargins(5, 10, 5, 5)
self.layouts["raw_control_layout"].setSpacing(5)
# Blendshape过滤组布局
self.layouts["blendshape_filter_layout"] = QtWidgets.QVBoxLayout(self.controls["blendshape_filter_group"])
self.layouts["blendshape_filter_layout"].addWidget(self.controls["blendshape_filter_input"])
# 搜索框
self.layouts["raw_control_layout"].addWidget(self.controls["search_input"])
# 次级Blendshape列表组布局
self.layouts["secondary_blendshape_layout"] = QtWidgets.QVBoxLayout(self.controls["secondary_blendshape_group"])
self.layouts["secondary_blendshape_layout"].addWidget(self.controls["secondary_blendshape_list"])
self.layouts["secondary_blendshape_layout"].addWidget(self.buttons["refresh_secondary_blendshape"])
# 控制列表
self.layouts["raw_control_layout"].addWidget(self.controls["control_list"])
# 添加组到左侧面板布局
self.layouts["left_layout"].addWidget(self.controls["blendshape_group"])
self.layouts["left_layout"].addWidget(self.controls["blendshape_filter_group"])
self.layouts["left_layout"].addWidget(self.controls["secondary_blendshape_group"])
self.layouts["left_layout"].addStretch()
# 底部滑块
self.layouts["raw_control_layout"].addWidget(self.controls["bottom_slider"])
# 页码按钮行
self.layouts["page_buttons_layout"] = QtWidgets.QHBoxLayout()
self.layouts["page_buttons_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["page_buttons_layout"].setSpacing(2)
self.layouts["page_buttons_layout"].addWidget(self.buttons["page_all"])
self.layouts["page_buttons_layout"].addWidget(self.buttons["page_2"])
self.layouts["page_buttons_layout"].addWidget(self.buttons["page_3"])
self.layouts["page_buttons_layout"].addWidget(self.buttons["page_4"])
self.layouts["page_buttons_layout"].addWidget(self.buttons["page_5"])
self.layouts["page_buttons_layout"].addWidget(self.buttons["page_6"])
self.layouts["raw_control_layout"].addLayout(self.layouts["page_buttons_layout"])
# 左下角按钮行
self.layouts["range_buttons_layout"] = QtWidgets.QHBoxLayout()
self.layouts["range_buttons_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["range_buttons_layout"].setSpacing(2)
self.layouts["range_buttons_layout"].addWidget(self.buttons["range_minus"])
self.layouts["range_buttons_layout"].addWidget(self.buttons["range_plus"])
self.layouts["range_buttons_layout"].addStretch()
self.layouts["raw_control_layout"].addLayout(self.layouts["range_buttons_layout"])
# 添加Raw Control组到左侧面板
self.layouts["left_layout"].addWidget(self.controls["raw_control_group"])
# 右侧面板布局
self.layouts["right_layout"] = QtWidgets.QVBoxLayout(self.controls["right_panel"])
self.layouts["right_layout"].setContentsMargins(5, 5, 5, 5)
self.layouts["right_layout"].setSpacing(5)
# Blendshape操作组布局
self.layouts["blendshape_ops_layout"] = QtWidgets.QVBoxLayout(self.controls["blendshape_ops_group"])
self.layouts["blendshape_ops_layout"].addWidget(self.buttons["export_blendshape"])
self.layouts["blendshape_ops_layout"].addWidget(self.buttons["import_blendshape"])
self.layouts["blendshape_ops_layout"].addWidget(self.buttons["edit_range"])
self.layouts["blendshape_ops_layout"].addWidget(self.buttons["mirror_blendshape"])
self.layouts["blendshape_ops_layout"].addWidget(self.buttons["find_flip_target"])
# BlendShapes组布局
self.layouts["blendshapes_layout"] = QtWidgets.QVBoxLayout(self.controls["blendshapes_group"])
self.layouts["blendshapes_layout"].setContentsMargins(5, 10, 5, 5)
self.layouts["blendshapes_layout"].setSpacing(5)
# 表情控制组布局
self.layouts["expression_control_layout"] = QtWidgets.QVBoxLayout(self.controls["expression_control_group"])
self.layouts["expression_control_layout"].addWidget(self.buttons["reset_expression"])
self.layouts["expression_control_layout"].addWidget(self.buttons["find_expression"])
self.layouts["expression_control_layout"].addWidget(self.buttons["find_control_panel"])
# BlendShapes列表
self.layouts["blendshapes_layout"].addWidget(self.controls["blendshapes_list"])
# 添加组到右侧面板布局
self.layouts["right_layout"].addWidget(self.controls["blendshape_ops_group"])
self.layouts["right_layout"].addWidget(self.controls["expression_control_group"])
self.layouts["right_layout"].addStretch()
# 滑块
self.layouts["blendshapes_layout"].addWidget(self.controls["bs_slider"])
# 创建分割器大小处理器
self.resize_handlers["main_splitter"] = ui_utils.SplitterResizeHandler(
self.main_widget, self.splitters["main_splitter"], is_horizontal=True
)
# BlendShape操作按钮网格
self.layouts["bs_buttons_grid"] = QtWidgets.QGridLayout()
self.layouts["bs_buttons_grid"].setContentsMargins(0, 0, 0, 0)
self.layouts["bs_buttons_grid"].setSpacing(2)
# 添加按钮到网格
self.layouts["bs_buttons_grid"].addWidget(self.buttons["reset_blendshape"], 0, 0)
self.layouts["bs_buttons_grid"].addWidget(self.buttons["mirror_blendshape"], 0, 1)
self.layouts["bs_buttons_grid"].addWidget(self.buttons["add_blendshape"], 1, 0)
self.layouts["bs_buttons_grid"].addWidget(self.buttons["remove_blendshape"], 1, 1)
self.layouts["bs_buttons_grid"].addWidget(self.buttons["update_blendshape"], 2, 0)
self.layouts["bs_buttons_grid"].addWidget(self.buttons["isolate_blendshape"], 2, 1)
self.layouts["bs_buttons_grid"].addWidget(self.buttons["new_blendshape"], 3, 0)
self.layouts["bs_buttons_grid"].addWidget(self.buttons["combine_blendshape"], 3, 1)
self.layouts["blendshapes_layout"].addLayout(self.layouts["bs_buttons_grid"])
# 标签页按钮行
self.layouts["tab_buttons_layout"] = QtWidgets.QHBoxLayout()
self.layouts["tab_buttons_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["tab_buttons_layout"].setSpacing(2)
self.layouts["tab_buttons_layout"].addWidget(self.buttons["tab_bs"])
self.layouts["tab_buttons_layout"].addWidget(self.buttons["tab_psd"])
self.layouts["tab_buttons_layout"].addWidget(self.buttons["tab_key"])
self.layouts["tab_buttons_layout"].addWidget(self.buttons["tab_jnt"])
self.layouts["tab_buttons_layout"].addWidget(self.buttons["tab_ark"])
self.layouts["tab_buttons_layout"].addWidget(self.buttons["tab_ctr"])
self.layouts["blendshapes_layout"].addLayout(self.layouts["tab_buttons_layout"])
# 添加BlendShapes组到右侧面板
self.layouts["right_layout"].addWidget(self.controls["blendshapes_group"])
# 底部工具面板
self.layouts["bottom_panel"] = QtWidgets.QVBoxLayout()
self.layouts["bottom_panel"].setContentsMargins(2, 2, 2, 2)
self.layouts["bottom_panel"].setSpacing(2)
# 底部滑块
self.layouts["bottom_panel"].addWidget(self.controls["bottom_main_slider"])
# 底部按钮网格
self.layouts["bottom_buttons_grid"] = QtWidgets.QGridLayout()
self.layouts["bottom_buttons_grid"].setContentsMargins(0, 0, 0, 0)
self.layouts["bottom_buttons_grid"].setSpacing(2)
# 添加底部按钮
self.layouts["bottom_buttons_grid"].addWidget(self.buttons["exchange_from_expression"], 0, 0)
self.layouts["bottom_buttons_grid"].addWidget(self.buttons["reset_selected_expression"], 0, 1)
self.layouts["bottom_buttons_grid"].addWidget(self.buttons["import_expression"], 0, 2)
self.layouts["bottom_buttons_grid"].addWidget(self.buttons["control_panel_search"], 1, 0)
self.layouts["bottom_buttons_grid"].addWidget(self.buttons["select_related_keys"], 1, 1)
self.layouts["bottom_buttons_grid"].addWidget(self.buttons["import_map_expression"], 1, 2)
self.layouts["bottom_panel"].addLayout(self.layouts["bottom_buttons_grid"])
# 添加底部面板到主布局
self.layouts["main_layout"].addLayout(self.layouts["bottom_panel"])
# 将左右面板添加到主分割器
self.splitters["main_splitter"].addWidget(self.controls["left_panel"])
self.splitters["main_splitter"].addWidget(self.controls["right_panel"])
# 设置分割器初始大小和伸缩因子
self.splitters["main_splitter"].setSizes([500, 500])
# 设置分割器的伸缩因子,确保左右栏能够自动调整宽度
for i in range(self.splitters["main_splitter"].count()):
self.splitters["main_splitter"].setStretchFactor(i, 1)
#======================================= CONNECTION =====================================
def create_connections(self):
@@ -238,23 +406,65 @@ class BehaviourUI(ui_utils.BaseUI):
连接信号和槽
设置UI控件的交互行为
"""
# Blendshape列表按钮连接
self.buttons["refresh_blendshape"].clicked.connect(utils_behaviour.behaviour_temp_utils_function)
# 导入行为工具函数
from scripts.utils import utils_behaviour
# Blendshape过滤连接
self.controls["blendshape_filter_input"].textChanged.connect(utils_behaviour.behaviour_temp_utils_function)
# 左侧面板连接
# 搜索框连接
self.controls["search_input"].textChanged.connect(utils_behaviour.filter_controls)
# 次级Blendshape按钮连接
self.buttons["refresh_secondary_blendshape"].clicked.connect(utils_behaviour.behaviour_temp_utils_function)
# 控制列表连接
self.controls["control_list"].itemClicked.connect(utils_behaviour.control_selected)
self.controls["control_list"].itemSelectionChanged.connect(utils_behaviour.update_control_selection)
# Blendshape操作按钮连接
self.buttons["export_blendshape"].clicked.connect(utils_behaviour.behaviour_temp_utils_function)
self.buttons["import_blendshape"].clicked.connect(utils_behaviour.behaviour_temp_utils_function)
self.buttons["edit_range"].clicked.connect(utils_behaviour.behaviour_temp_utils_function)
self.buttons["mirror_blendshape"].clicked.connect(utils_behaviour.behaviour_temp_utils_function)
self.buttons["find_flip_target"].clicked.connect(utils_behaviour.behaviour_temp_utils_function)
# 底部滑块连接
self.controls["bottom_slider"].valueChanged.connect(utils_behaviour.update_control_value)
# 表情控制按钮连接
self.buttons["reset_expression"].clicked.connect(utils_behaviour.behaviour_temp_utils_function)
self.buttons["find_expression"].clicked.connect(utils_behaviour.behaviour_temp_utils_function)
self.buttons["find_control_panel"].clicked.connect(utils_behaviour.behaviour_temp_utils_function)
# 页码按钮连接
self.buttons["page_all"].clicked.connect(lambda: utils_behaviour.switch_page("all"))
self.buttons["page_2"].clicked.connect(lambda: utils_behaviour.switch_page("2"))
self.buttons["page_3"].clicked.connect(lambda: utils_behaviour.switch_page("3"))
self.buttons["page_4"].clicked.connect(lambda: utils_behaviour.switch_page("4"))
self.buttons["page_5"].clicked.connect(lambda: utils_behaviour.switch_page("5"))
self.buttons["page_6"].clicked.connect(lambda: utils_behaviour.switch_page("6"))
# 左下角按钮连接
self.buttons["range_minus"].clicked.connect(utils_behaviour.decrease_range)
self.buttons["range_plus"].clicked.connect(utils_behaviour.increase_range)
# 右侧面板连接
# BlendShapes列表连接
self.controls["blendshapes_list"].itemClicked.connect(utils_behaviour.blendshape_selected)
self.controls["blendshapes_list"].itemSelectionChanged.connect(utils_behaviour.update_blendshape_selection)
# 滑块连接
self.controls["bs_slider"].valueChanged.connect(utils_behaviour.update_blendshape_value)
# BlendShape操作按钮连接
self.buttons["reset_blendshape"].clicked.connect(utils_behaviour.reset_blendshape)
self.buttons["mirror_blendshape"].clicked.connect(utils_behaviour.mirror_blendshape)
self.buttons["add_blendshape"].clicked.connect(utils_behaviour.add_blendshape)
self.buttons["remove_blendshape"].clicked.connect(utils_behaviour.remove_blendshape)
self.buttons["update_blendshape"].clicked.connect(utils_behaviour.update_blendshape)
self.buttons["isolate_blendshape"].clicked.connect(utils_behaviour.isolate_blendshape)
self.buttons["new_blendshape"].clicked.connect(utils_behaviour.new_blendshape)
self.buttons["combine_blendshape"].clicked.connect(utils_behaviour.combine_blendshape)
# 标签页按钮连接
self.buttons["tab_bs"].clicked.connect(lambda: utils_behaviour.switch_tab("bs"))
self.buttons["tab_psd"].clicked.connect(lambda: utils_behaviour.switch_tab("psd"))
self.buttons["tab_key"].clicked.connect(lambda: utils_behaviour.switch_tab("key"))
self.buttons["tab_jnt"].clicked.connect(lambda: utils_behaviour.switch_tab("jnt"))
self.buttons["tab_ark"].clicked.connect(lambda: utils_behaviour.switch_tab("ark"))
self.buttons["tab_ctr"].clicked.connect(lambda: utils_behaviour.switch_tab("ctr"))
# 底部滑块连接
self.controls["bottom_main_slider"].valueChanged.connect(utils_behaviour.update_main_value)
# 底部按钮连接
self.buttons["exchange_from_expression"].clicked.connect(utils_behaviour.exchange_from_expression)
self.buttons["reset_selected_expression"].clicked.connect(utils_behaviour.reset_selected_expression)
self.buttons["import_expression"].clicked.connect(utils_behaviour.import_expression)
self.buttons["control_panel_search"].clicked.connect(utils_behaviour.control_panel_search)
self.buttons["select_related_keys"].clicked.connect(utils_behaviour.select_related_keys)
self.buttons["import_map_expression"].clicked.connect(utils_behaviour.import_map_expression)

View File

@@ -84,7 +84,7 @@ class DefinitionUI(ui_utils.BaseUI):
self.controls["title_label"].setObjectName("definitionTitleLabel")
self.controls["title_label"].setAlignment(QtCore.Qt.AlignCenter)
# 创建主分割器
# 主分割器
self.splitters["main_splitter"] = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
self.splitters["main_splitter"].setObjectName("definitionMainSplitter")
@@ -97,66 +97,108 @@ class DefinitionUI(ui_utils.BaseUI):
self.controls["right_panel"].setObjectName("definitionRightPanel")
# 左侧面板控件
# LOD组
self.controls["lod_group"] = QtWidgets.QGroupBox(LANG.get("lod_group", "LOD"))
self.controls["lod_group"].setObjectName("lodGroup")
# LODs
self.controls["lods_group"] = QtWidgets.QGroupBox("LODs")
self.controls["lods_group"].setObjectName("lodsGroup")
# LOD列表
self.controls["lod_list"] = QtWidgets.QListWidget()
self.controls["lod_list"].setObjectName("lodList")
# LODs列表
self.controls["lods_list"] = QtWidgets.QListWidget()
self.controls["lods_list"].setObjectName("lodsList")
# LOD刷新按钮
self.buttons["refresh_lod"] = QtWidgets.QPushButton(LANG.get("refresh", "刷新"))
self.buttons["refresh_lod"].setObjectName("refreshLodButton")
# 定义LOD关联按钮
self.buttons["define_lod_relations"] = QtWidgets.QPushButton(LANG.get("define_lod_relations", "定义LOD关联"))
self.buttons["define_lod_relations"].setObjectName("defineLodRelationsButton")
# Meshes组
self.controls["meshes_group"] = QtWidgets.QGroupBox(LANG.get("meshes_group", "几何体"))
self.controls["meshes_group"] = QtWidgets.QGroupBox("Meshes [000]")
self.controls["meshes_group"].setObjectName("meshesGroup")
# Meshes列表
self.controls["meshes_list"] = QtWidgets.QListWidget()
self.controls["meshes_list"].setObjectName("meshesList")
# Meshes刷新按钮
self.buttons["refresh_meshes"] = QtWidgets.QPushButton(LANG.get("refresh", "刷新"))
self.buttons["refresh_meshes"].setObjectName("refreshMeshesButton")
# 创建几何体按钮
self.buttons["create_geometry"] = QtWidgets.QPushButton(LANG.get("create_geometry", "创建几何体"))
self.buttons["create_geometry"].setObjectName("createGeometryButton")
# 右侧面板控件
# Joints组
self.controls["joints_group"] = QtWidgets.QGroupBox(LANG.get("joints_group", "关节"))
self.controls["joints_group"] = QtWidgets.QGroupBox("Joints [000]")
self.controls["joints_group"].setObjectName("jointsGroup")
# Joints列表
self.controls["joints_list"] = QtWidgets.QListWidget()
self.controls["joints_list"].setObjectName("jointsList")
# Joints刷新按钮
self.buttons["refresh_joints"] = QtWidgets.QPushButton(LANG.get("refresh", "刷新"))
self.buttons["refresh_joints"].setObjectName("refreshJointsButton")
# BlendShapes组
self.controls["blendshapes_group"] = QtWidgets.QGroupBox("BlendShapes [000]")
self.controls["blendshapes_group"].setObjectName("blendshapesGroup")
# 右侧面板控件
# 写入组
self.controls["write_group"] = QtWidgets.QGroupBox(LANG.get("write_group", "写入"))
self.controls["write_group"].setObjectName("writeGroup")
# BlendShapes列表
self.controls["blendshapes_list"] = QtWidgets.QListWidget()
self.controls["blendshapes_list"].setObjectName("blendshapesList")
# 写入按钮
self.buttons["write_joint_default"] = QtWidgets.QPushButton(LANG.get("write_joint_default", "写入关节默认位置"))
self.buttons["write_geometry"] = QtWidgets.QPushButton(LANG.get("write_geometry", "写入几何体"))
self.buttons["write_skinning"] = QtWidgets.QPushButton(LANG.get("write_skinning", "写入蒙皮"))
self.buttons["write_blendshape"] = QtWidgets.QPushButton(LANG.get("write_blendshape", "写入混合变形目标"))
# AnimatedMap组
self.controls["animatedmap_group"] = QtWidgets.QGroupBox("AnimatedMap [000]")
self.controls["animatedmap_group"].setObjectName("animatedmapGroup")
# 创建组
self.controls["create_group"] = QtWidgets.QGroupBox(LANG.get("create_group", "创建"))
self.controls["create_group"].setObjectName("createGroup")
# AnimatedMap列表
self.controls["animatedmap_list"] = QtWidgets.QListWidget()
self.controls["animatedmap_list"].setObjectName("animatedmapList")
# 创建按钮
self.buttons["create_blendshape"] = QtWidgets.QPushButton(LANG.get("create_blendshape", "创建混合变形"))
self.buttons["bind_skin"] = QtWidgets.QPushButton(LANG.get("bind_skin", "绑定蒙皮"))
# 底部工具面板
# 导入部分
self.controls["import_label"] = QtWidgets.QLabel(LANG.get("import", "导入"))
self.controls["import_label"].setObjectName("importLabel")
self.controls["import_label"].setAlignment(QtCore.Qt.AlignCenter)
self.buttons["import_joint_system"] = QtWidgets.QPushButton(LANG.get("import_joint_system", "导入关节系统"))
self.buttons["import_joint_system"].setObjectName("importJointSystemButton")
self.buttons["import_geometry"] = QtWidgets.QPushButton(LANG.get("import_geometry", "导入几何体"))
self.buttons["import_geometry"].setObjectName("importGeometryButton")
self.buttons["import_blendshape_target"] = QtWidgets.QPushButton(LANG.get("import_blendshape_target", "导入形状混合目标"))
self.buttons["import_blendshape_target"].setObjectName("importBlendshapeTargetButton")
self.buttons["import_animated_map"] = QtWidgets.QPushButton(LANG.get("import_animated_map", "导入动画贴图"))
self.buttons["import_animated_map"].setObjectName("importAnimatedMapButton")
# 创建部分
self.controls["create_label"] = QtWidgets.QLabel(LANG.get("create", "创建"))
self.controls["create_label"].setObjectName("createLabel")
self.controls["create_label"].setAlignment(QtCore.Qt.AlignCenter)
self.buttons["create_neutral_pose"] = QtWidgets.QPushButton(LANG.get("create_neutral_pose", "创建中性姿势"))
self.buttons["create_neutral_pose"].setObjectName("createNeutralPoseButton")
self.buttons["bind_geometry"] = QtWidgets.QPushButton(LANG.get("bind_geometry", "绑定几何体"))
self.buttons["bind_geometry"].setObjectName("bindGeometryButton")
self.buttons["take_pose"] = QtWidgets.QPushButton(LANG.get("take_pose", "取消姿势"))
self.buttons["take_pose"].setObjectName("takePoseButton")
# 工具部分
self.controls["tools_label"] = QtWidgets.QLabel(LANG.get("tools", "工具"))
self.controls["tools_label"].setObjectName("toolsLabel")
self.controls["tools_label"].setAlignment(QtCore.Qt.AlignCenter)
self.buttons["reposition_all_joints"] = QtWidgets.QPushButton(LANG.get("reposition_all_joints", "重新定位所有关节"))
self.buttons["reposition_all_joints"].setObjectName("repositionAllJointsButton")
self.buttons["reposition_selected_joints"] = QtWidgets.QPushButton(LANG.get("reposition_selected_joints", "重新定位选定关节"))
self.buttons["reposition_selected_joints"].setObjectName("repositionSelectedJointsButton")
self.buttons["reposition_all_head_joints"] = QtWidgets.QPushButton(LANG.get("reposition_all_head_joints", "重新定位所有头部关节"))
self.buttons["reposition_all_head_joints"].setObjectName("repositionAllHeadJointsButton")
self.buttons["quick_preset"] = QtWidgets.QPushButton(LANG.get("quick_preset", "快速预设"))
self.buttons["quick_preset"].setObjectName("quickPresetButton")
self.buttons["unbind_skin"] = QtWidgets.QPushButton(LANG.get("unbind_skin", "取消蒙皮"))
# 工具组
self.controls["tools_group"] = QtWidgets.QGroupBox(LANG.get("tools_group", "工具"))
self.controls["tools_group"].setObjectName("toolsGroup")
# 工具按钮
self.buttons["reposition_head_joints"] = QtWidgets.QPushButton(LANG.get("reposition_head_joints", "重新定位头部关节"))
self.buttons["reposition_body_joints"] = QtWidgets.QPushButton(LANG.get("reposition_body_joints", "重新定位身体关节"))
@@ -180,71 +222,137 @@ class DefinitionUI(ui_utils.BaseUI):
# 添加主分割器
self.layouts["main_layout"].addWidget(self.splitters["main_splitter"])
# 将左右面板添加到主分割器
self.splitters["main_splitter"].addWidget(self.controls["left_panel"])
self.splitters["main_splitter"].addWidget(self.controls["right_panel"])
# 左侧面板布局
self.layouts["left_layout"] = QtWidgets.QVBoxLayout(self.controls["left_panel"])
self.layouts["left_layout"].setContentsMargins(5, 5, 5, 5)
self.layouts["left_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["left_layout"].setSpacing(5)
# LOD组布局
self.layouts["lod_layout"] = QtWidgets.QVBoxLayout(self.controls["lod_group"])
self.layouts["lod_layout"].addWidget(self.controls["lod_list"])
self.layouts["lod_layout"].addWidget(self.buttons["refresh_lod"])
# 左侧分割器
self.splitters["left_splitter"] = QtWidgets.QSplitter(QtCore.Qt.Vertical)
self.splitters["left_splitter"].setObjectName("definitionLeftSplitter")
self.layouts["left_layout"].addWidget(self.splitters["left_splitter"])
# LODs组布局
self.layouts["lods_layout"] = QtWidgets.QVBoxLayout(self.controls["lods_group"])
self.layouts["lods_layout"].setContentsMargins(5, 5, 5, 5)
self.layouts["lods_layout"].setSpacing(5)
# 添加LODs列表
self.layouts["lods_layout"].addWidget(self.controls["lods_list"])
# 定义LOD关联按钮
self.layouts["lods_layout"].addWidget(self.buttons["define_lod_relations"])
# Meshes组布局
self.layouts["meshes_layout"] = QtWidgets.QVBoxLayout(self.controls["meshes_group"])
self.layouts["meshes_layout"].setContentsMargins(5, 5, 5, 5)
self.layouts["meshes_layout"].setSpacing(5)
# 添加Meshes列表
self.layouts["meshes_layout"].addWidget(self.controls["meshes_list"])
self.layouts["meshes_layout"].addWidget(self.buttons["refresh_meshes"])
# Joints组布局
self.layouts["joints_layout"] = QtWidgets.QVBoxLayout(self.controls["joints_group"])
self.layouts["joints_layout"].addWidget(self.controls["joints_list"])
self.layouts["joints_layout"].addWidget(self.buttons["refresh_joints"])
# 创建几何体按钮
self.layouts["meshes_layout"].addWidget(self.buttons["create_geometry"])
# 添加到左侧面板布局
self.layouts["left_layout"].addWidget(self.controls["lod_group"])
self.layouts["left_layout"].addWidget(self.controls["meshes_group"])
self.layouts["left_layout"].addWidget(self.controls["joints_group"])
self.layouts["left_layout"].addStretch()
# 添加到左侧分割器
self.splitters["left_splitter"].addWidget(self.controls["lods_group"])
self.splitters["left_splitter"].addWidget(self.controls["meshes_group"])
# 右侧面板布局
self.layouts["right_layout"] = QtWidgets.QVBoxLayout(self.controls["right_panel"])
self.layouts["right_layout"].setContentsMargins(5, 5, 5, 5)
self.layouts["right_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["right_layout"].setSpacing(5)
# 写入组布局
self.layouts["write_layout"] = QtWidgets.QVBoxLayout(self.controls["write_group"])
self.layouts["write_layout"].addWidget(self.buttons["write_joint_default"])
self.layouts["write_layout"].addWidget(self.buttons["write_geometry"])
self.layouts["write_layout"].addWidget(self.buttons["write_skinning"])
self.layouts["write_layout"].addWidget(self.buttons["write_blendshape"])
# 右侧分割器
self.splitters["right_splitter"] = QtWidgets.QSplitter(QtCore.Qt.Vertical)
self.splitters["right_splitter"].setObjectName("definitionRightSplitter")
self.layouts["right_layout"].addWidget(self.splitters["right_splitter"])
# 创建组布局
self.layouts["create_layout"] = QtWidgets.QVBoxLayout(self.controls["create_group"])
self.layouts["create_layout"].addWidget(self.buttons["create_blendshape"])
self.layouts["create_layout"].addWidget(self.buttons["bind_skin"])
# Joints组布局
self.layouts["joints_layout"] = QtWidgets.QVBoxLayout(self.controls["joints_group"])
self.layouts["joints_layout"].setContentsMargins(5, 5, 5, 5)
self.layouts["joints_layout"].setSpacing(5)
# 添加Joints列表
self.layouts["joints_layout"].addWidget(self.controls["joints_list"])
# BlendShapes组布局
self.layouts["blendshapes_layout"] = QtWidgets.QVBoxLayout(self.controls["blendshapes_group"])
self.layouts["blendshapes_layout"].setContentsMargins(5, 5, 5, 5)
self.layouts["blendshapes_layout"].setSpacing(5)
# 添加BlendShapes列表
self.layouts["blendshapes_layout"].addWidget(self.controls["blendshapes_list"])
# AnimatedMap组布局
self.layouts["animatedmap_layout"] = QtWidgets.QVBoxLayout(self.controls["animatedmap_group"])
self.layouts["animatedmap_layout"].setContentsMargins(5, 5, 5, 5)
self.layouts["animatedmap_layout"].setSpacing(5)
# 添加AnimatedMap列表
self.layouts["animatedmap_layout"].addWidget(self.controls["animatedmap_list"])
# 添加到右侧分割器
self.splitters["right_splitter"].addWidget(self.controls["joints_group"])
self.splitters["right_splitter"].addWidget(self.controls["blendshapes_group"])
self.splitters["right_splitter"].addWidget(self.controls["animatedmap_group"])
# 底部工具面板
self.layouts["bottom_panel"] = QtWidgets.QHBoxLayout()
self.layouts["bottom_panel"].setContentsMargins(0, 10, 0, 0)
self.layouts["bottom_panel"].setSpacing(10)
# 导入部分布局
self.layouts["import_layout"] = QtWidgets.QVBoxLayout()
self.layouts["import_layout"].setSpacing(5)
self.layouts["import_layout"].addWidget(self.controls["import_label"])
self.layouts["import_layout"].addWidget(self.buttons["import_joint_system"])
self.layouts["import_layout"].addWidget(self.buttons["import_geometry"])
self.layouts["import_layout"].addWidget(self.buttons["import_blendshape_target"])
self.layouts["import_layout"].addWidget(self.buttons["import_animated_map"])
# 创建部分布局
self.layouts["create_layout"] = QtWidgets.QVBoxLayout()
self.layouts["create_layout"].setSpacing(5)
self.layouts["create_layout"].addWidget(self.controls["create_label"])
self.layouts["create_layout"].addWidget(self.buttons["create_neutral_pose"])
self.layouts["create_layout"].addWidget(self.buttons["bind_geometry"])
self.layouts["create_layout"].addWidget(self.buttons["take_pose"])
self.layouts["create_layout"].addWidget(self.buttons["unbind_skin"])
# 工具布局
self.layouts["tools_layout"] = QtWidgets.QVBoxLayout(self.controls["tools_group"])
self.layouts["tools_layout"].addWidget(self.buttons["reposition_head_joints"])
self.layouts["tools_layout"].addWidget(self.buttons["reposition_body_joints"])
# 工具部分布局
self.layouts["tools_layout"] = QtWidgets.QVBoxLayout()
self.layouts["tools_layout"].setSpacing(5)
self.layouts["tools_layout"].addWidget(self.controls["tools_label"])
self.layouts["tools_layout"].addWidget(self.buttons["reposition_all_joints"])
self.layouts["tools_layout"].addWidget(self.buttons["reposition_selected_joints"])
self.layouts["tools_layout"].addWidget(self.buttons["reposition_all_head_joints"])
self.layouts["tools_layout"].addWidget(self.buttons["quick_preset"])
# 添加组到右侧面板布局
self.layouts["right_layout"].addWidget(self.controls["write_group"])
self.layouts["right_layout"].addWidget(self.controls["create_group"])
self.layouts["right_layout"].addWidget(self.controls["tools_group"])
self.layouts["right_layout"].addStretch()
# 添加三列到底部面板
self.layouts["bottom_panel"].addLayout(self.layouts["import_layout"])
self.layouts["bottom_panel"].addLayout(self.layouts["create_layout"])
self.layouts["bottom_panel"].addLayout(self.layouts["tools_layout"])
# 创建分割器大小处理器
self.resize_handlers["main_splitter"] = ui_utils.SplitterResizeHandler(
self.main_widget, self.splitters["main_splitter"], is_horizontal=True
)
# 添加底部面板到主布局
self.layouts["main_layout"].addLayout(self.layouts["bottom_panel"])
# 设置分割器初始大小
# 主分割器左右各半
self.splitters["main_splitter"].setSizes([500, 500])
# 左侧分割器上下各半
self.splitters["left_splitter"].setSizes([250, 250])
# 右侧分割器均匀分配
right_item_height = 1000 // self.splitters["right_splitter"].count()
self.splitters["right_splitter"].setSizes([right_item_height] * self.splitters["right_splitter"].count())
# 设置分割器的伸缩因子,确保左右栏能够自动调整宽度
for i in range(self.splitters["main_splitter"].count()):
self.splitters["main_splitter"].setStretchFactor(i, 1)
# 将左右面板添加到主分割器
self.splitters["main_splitter"].addWidget(self.controls["left_panel"])
self.splitters["main_splitter"].addWidget(self.controls["right_panel"])
#======================================= CONNECTION =====================================
def create_connections(self):
@@ -252,24 +360,49 @@ class DefinitionUI(ui_utils.BaseUI):
连接信号和槽
设置UI控件的交互行为
"""
# 刷新按钮连接
self.buttons["refresh_lod"].clicked.connect(utils_definition.definition_temp_utils_function)
self.buttons["refresh_meshes"].clicked.connect(utils_definition.definition_temp_utils_function)
self.buttons["refresh_joints"].clicked.connect(utils_definition.definition_temp_utils_function)
# 左侧面板连接
# LODs列表连接
self.controls["lods_list"].itemClicked.connect(utils_definition.lod_selected)
self.controls["lods_list"].itemSelectionChanged.connect(utils_definition.update_lod_selection)
# 写入按钮连接
self.buttons["write_joint_default"].clicked.connect(utils_definition.definition_temp_utils_function)
self.buttons["write_geometry"].clicked.connect(utils_definition.definition_temp_utils_function)
self.buttons["write_skinning"].clicked.connect(utils_definition.definition_temp_utils_function)
self.buttons["write_blendshape"].clicked.connect(utils_definition.definition_temp_utils_function)
# 定义LOD关联按钮连接
self.buttons["define_lod_relations"].clicked.connect(utils_definition.define_lod_relations)
# 创建按钮连接
self.buttons["create_blendshape"].clicked.connect(utils_definition.definition_temp_utils_function)
self.buttons["bind_skin"].clicked.connect(utils_definition.definition_temp_utils_function)
self.buttons["unbind_skin"].clicked.connect(utils_definition.definition_temp_utils_function)
# Meshes列表连接
self.controls["meshes_list"].itemClicked.connect(utils_definition.mesh_selected)
self.controls["meshes_list"].itemSelectionChanged.connect(utils_definition.update_mesh_selection)
# 工具按钮连接
self.buttons["reposition_head_joints"].clicked.connect(utils_definition.definition_temp_utils_function)
self.buttons["reposition_body_joints"].clicked.connect(utils_definition.definition_temp_utils_function)
self.buttons["reposition_all_joints"].clicked.connect(utils_definition.definition_temp_utils_function)
self.buttons["quick_preset"].clicked.connect(utils_definition.definition_temp_utils_function)
# 创建几何体按钮连接
self.buttons["create_geometry"].clicked.connect(utils_definition.create_geometry)
# 右侧面板连接
# Joints列表连接
self.controls["joints_list"].itemClicked.connect(utils_definition.joint_selected)
self.controls["joints_list"].itemSelectionChanged.connect(utils_definition.update_joint_selection)
# BlendShapes列表连接
self.controls["blendshapes_list"].itemClicked.connect(utils_definition.blendshape_selected)
self.controls["blendshapes_list"].itemSelectionChanged.connect(utils_definition.update_blendshape_selection)
# AnimatedMap列表连接
self.controls["animatedmap_list"].itemClicked.connect(utils_definition.animatedmap_selected)
self.controls["animatedmap_list"].itemSelectionChanged.connect(utils_definition.update_animatedmap_selection)
# 底部工具面板连接
# 导入部分按钮连接
self.buttons["import_joint_system"].clicked.connect(utils_definition.import_joint_system)
self.buttons["import_geometry"].clicked.connect(utils_definition.import_geometry)
self.buttons["import_blendshape_target"].clicked.connect(utils_definition.import_blendshape_target)
self.buttons["import_animated_map"].clicked.connect(utils_definition.import_animated_map)
# 创建部分按钮连接
self.buttons["create_neutral_pose"].clicked.connect(utils_definition.create_neutral_pose)
self.buttons["bind_geometry"].clicked.connect(utils_definition.bind_geometry)
self.buttons["take_pose"].clicked.connect(utils_definition.take_pose)
self.buttons["unbind_skin"].clicked.connect(utils_definition.unbind_skin)
# 工具部分按钮连接
self.buttons["reposition_all_joints"].clicked.connect(utils_definition.reposition_all_joints)
self.buttons["reposition_selected_joints"].clicked.connect(utils_definition.reposition_selected_joints)
self.buttons["reposition_all_head_joints"].clicked.connect(utils_definition.reposition_all_head_joints)
self.buttons["quick_preset"].clicked.connect(utils_definition.quick_preset)

View File

@@ -89,10 +89,6 @@ class GeometryUI(ui_utils.BaseUI):
self.controls["title_label"].setObjectName("geometryTitleLabel")
self.controls["title_label"].setAlignment(QtCore.Qt.AlignCenter)
# 创建主分割器
self.splitters["main_splitter"] = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
self.splitters["main_splitter"].setObjectName("geometryMainSplitter")
# 左侧面板
self.controls["left_panel"] = QtWidgets.QWidget()
self.controls["left_panel"].setObjectName("geometryLeftPanel")
@@ -101,49 +97,141 @@ class GeometryUI(ui_utils.BaseUI):
self.controls["right_panel"] = QtWidgets.QWidget()
self.controls["right_panel"].setObjectName("geometryRightPanel")
# 左侧面板控件
# 模型列表组
self.controls["model_group"] = QtWidgets.QGroupBox(LANG.get("model_group", "模型列表"))
# 左侧面板控件 - LOD列表
self.controls["lod_group"] = QtWidgets.QGroupBox("LOD [000]")
self.controls["lod_group"].setObjectName("lodGroup")
# LOD列表
self.controls["lod_list"] = QtWidgets.QListWidget()
self.controls["lod_list"].setObjectName("lodList")
# 添加测试项目
for i in range(4):
item = QtWidgets.QListWidgetItem(f"LOD{i}")
self.controls["lod_list"].addItem(item)
# LOD操作按钮
self.buttons["add_lod"] = QtWidgets.QPushButton(LANG.get("add_lod", "添加LOD"))
self.buttons["add_lod"].setObjectName("addLodButton")
self.buttons["remove_lod"] = QtWidgets.QPushButton(LANG.get("remove_lod", "移除LOD"))
self.buttons["remove_lod"].setObjectName("removeLodButton")
self.buttons["duplicate_lod"] = QtWidgets.QPushButton(LANG.get("duplicate_lod", "复制LOD"))
self.buttons["duplicate_lod"].setObjectName("duplicateLodButton")
# 左侧面板控件 - 模型列表
self.controls["model_group"] = QtWidgets.QGroupBox("Models [000]")
self.controls["model_group"].setObjectName("modelGroup")
# 模型列表
self.controls["model_list"] = QtWidgets.QListWidget()
self.controls["model_list"].setObjectName("modelList")
# 模型刷新按钮
self.buttons["refresh_models"] = QtWidgets.QPushButton(LANG.get("refresh", "刷新"))
self.buttons["refresh_models"].setObjectName("refreshModelsButton")
# LOD过滤组
self.controls["lod_filter_group"] = QtWidgets.QGroupBox(LANG.get("lod_filter_group", "LOD过滤"))
self.controls["lod_filter_group"].setObjectName("lodFilterGroup")
# LOD选择
self.controls["lod_label"] = QtWidgets.QLabel(LANG.get("lod", "LOD:"))
self.controls["lod_combo"] = QtWidgets.QComboBox()
self.controls["lod_combo"].setObjectName("lodCombo")
# 右侧面板控件
# 模型操作组
self.controls["model_ops_group"] = QtWidgets.QGroupBox(LANG.get("model_operations", "模型操作"))
self.controls["model_ops_group"].setObjectName("modelOpsGroup")
# 模型操作按钮
self.buttons["pick_model"] = QtWidgets.QPushButton(LANG.get("pick_model", "拾取模型"))
self.buttons["load_model"] = QtWidgets.QPushButton(LANG.get("load_model", "加载模型"))
self.buttons["create_lod"] = QtWidgets.QPushButton(LANG.get("create_lod", "创建LOD"))
self.buttons["auto_load"] = QtWidgets.QPushButton(LANG.get("auto_load", "自动加载"))
self.buttons["add_model"] = QtWidgets.QPushButton(LANG.get("add_model", "添加模型"))
self.buttons["add_model"].setObjectName("addModelButton")
# 模型工具组
self.buttons["remove_model"] = QtWidgets.QPushButton(LANG.get("remove_model", "移除模型"))
self.buttons["remove_model"].setObjectName("removeModelButton")
self.buttons["duplicate_model"] = QtWidgets.QPushButton(LANG.get("duplicate_model", "复制模型"))
self.buttons["duplicate_model"].setObjectName("duplicateModelButton")
# 右侧面板控件 - 模型属性
self.controls["model_properties_group"] = QtWidgets.QGroupBox(LANG.get("model_properties", "模型属性"))
self.controls["model_properties_group"].setObjectName("modelPropertiesGroup")
# 模型名称标签和输入框
self.controls["model_name_label"] = QtWidgets.QLabel(LANG.get("name", "名称:"))
self.controls["model_name_label"].setObjectName("modelNameLabel")
self.controls["model_name_input"] = QtWidgets.QLineEdit()
self.controls["model_name_input"].setObjectName("modelNameInput")
self.controls["model_name_input"].setPlaceholderText(LANG.get("enter_model_name", "输入模型名称"))
# 模型类型标签和下拉框
self.controls["model_type_label"] = QtWidgets.QLabel(LANG.get("type", "类型:"))
self.controls["model_type_label"].setObjectName("modelTypeLabel")
self.controls["model_type_combo"] = QtWidgets.QComboBox()
self.controls["model_type_combo"].setObjectName("modelTypeCombo")
self.controls["model_type_combo"].addItems(["Base", "Head", "Body", "Accessory", "Other"])
# 模型可见性复选框
self.controls["model_visible_check"] = QtWidgets.QCheckBox(LANG.get("visible", "可见"))
self.controls["model_visible_check"].setObjectName("modelVisibleCheck")
self.controls["model_visible_check"].setChecked(True)
# 模型属性按钮
self.buttons["apply_properties"] = QtWidgets.QPushButton(LANG.get("apply", "应用"))
self.buttons["apply_properties"].setObjectName("applyPropertiesButton")
self.buttons["reset_properties"] = QtWidgets.QPushButton(LANG.get("reset", "重置"))
self.buttons["reset_properties"].setObjectName("resetPropertiesButton")
# 右侧面板控件 - 模型工具
self.controls["model_tools_group"] = QtWidgets.QGroupBox(LANG.get("model_tools", "模型工具"))
self.controls["model_tools_group"].setObjectName("modelToolsGroup")
# 模型工具按钮
self.buttons["standardize_names"] = QtWidgets.QPushButton(LANG.get("standardize_names", "标准化命名"))
self.buttons["standardize_names"].setObjectName("standardizeNamesButton")
self.buttons["auto_group"] = QtWidgets.QPushButton(LANG.get("auto_group", "自动分组"))
self.buttons["generate_accessories"] = QtWidgets.QPushButton(LANG.get("generate_accessories", "生成面部配件"))
self.buttons["auto_group"].setObjectName("autoGroupButton")
self.buttons["generate_accessories"] = QtWidgets.QPushButton(LANG.get("generate_accessories", "生成配件"))
self.buttons["generate_accessories"].setObjectName("generateAccessoriesButton")
self.buttons["fix_seams"] = QtWidgets.QPushButton(LANG.get("fix_seams", "修复接缝"))
self.buttons["fix_seams"].setObjectName("fixSeamsButton")
self.buttons["fix_vertex_order"] = QtWidgets.QPushButton(LANG.get("fix_vertex_order", "修复点序"))
self.buttons["fix_vertex_order"].setObjectName("fixVertexOrderButton")
# 底部工具面板
# 导入部分
self.controls["import_group"] = QtWidgets.QGroupBox(LANG.get("import", "导入"))
self.controls["import_group"].setObjectName("importGroup")
self.buttons["import_model"] = QtWidgets.QPushButton(LANG.get("import_model", "导入模型"))
self.buttons["import_model"].setObjectName("importModelButton")
self.buttons["import_fbx"] = QtWidgets.QPushButton(LANG.get("import_fbx", "导入FBX"))
self.buttons["import_fbx"].setObjectName("importFbxButton")
self.buttons["import_obj"] = QtWidgets.QPushButton(LANG.get("import_obj", "导入OBJ"))
self.buttons["import_obj"].setObjectName("importObjButton")
# 导出部分
self.controls["export_group"] = QtWidgets.QGroupBox(LANG.get("export", "导出"))
self.controls["export_group"].setObjectName("exportGroup")
self.buttons["export_model"] = QtWidgets.QPushButton(LANG.get("export_model", "导出模型"))
self.buttons["export_model"].setObjectName("exportModelButton")
self.buttons["export_fbx"] = QtWidgets.QPushButton(LANG.get("export_fbx", "导出 FBX"))
self.buttons["export_fbx"].setObjectName("exportFbxButton")
self.buttons["export_obj"] = QtWidgets.QPushButton(LANG.get("export_obj", "导出 OBJ"))
self.buttons["export_obj"].setObjectName("exportObjButton")
# 工具部分
self.controls["tools_group"] = QtWidgets.QGroupBox(LANG.get("tools", "工具"))
self.controls["tools_group"].setObjectName("toolsGroup")
self.buttons["check_model"] = QtWidgets.QPushButton(LANG.get("check_model", "检查模型"))
self.buttons["check_model"].setObjectName("checkModelButton")
self.buttons["optimize_model"] = QtWidgets.QPushButton(LANG.get("optimize_model", "优化模型"))
self.buttons["optimize_model"].setObjectName("optimizeModelButton")
self.buttons["clean_model"] = QtWidgets.QPushButton(LANG.get("clean_model", "清理模型"))
self.buttons["clean_model"].setObjectName("cleanModelButton")
self.buttons["uv_tools"] = QtWidgets.QPushButton(LANG.get("uv_tools", "UV工具"))
self.buttons["uv_tools"].setObjectName("uvToolsButton")
#========================================= LAYOUT =======================================
def create_layouts(self):
@@ -152,69 +240,181 @@ class GeometryUI(ui_utils.BaseUI):
组织控件的排列和层次结构
"""
# 主布局
self.layouts["main_layout"] = QtWidgets.QVBoxLayout(self.main_widget)
self.layouts["main_layout"].setContentsMargins(5, 5, 5, 5)
self.layouts["main_layout"].setSpacing(5)
self.layouts["main_layout"] = QtWidgets.QVBoxLayout(self)
self.layouts["main_layout"].setContentsMargins(2, 2, 2, 2)
self.layouts["main_layout"].setSpacing(2)
# 添加标题标签
self.layouts["main_layout"].addWidget(self.controls["title_label"])
# 添加主分割器
# 创建主分割器
self.splitters["main_splitter"] = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
self.splitters["main_splitter"].setObjectName("geometryMainSplitter")
self.layouts["main_layout"].addWidget(self.splitters["main_splitter"])
# 将左右面板添加到主分割器
self.splitters["main_splitter"].addWidget(self.controls["left_panel"])
self.splitters["main_splitter"].addWidget(self.controls["right_panel"])
# 左侧面板布局
self.layouts["left_layout"] = QtWidgets.QVBoxLayout(self.controls["left_panel"])
self.layouts["left_layout"].setContentsMargins(5, 5, 5, 5)
self.layouts["left_layout"].setSpacing(5)
# 模型列表组布局
self.layouts["model_list_layout"] = QtWidgets.QVBoxLayout(self.controls["model_group"])
self.layouts["model_list_layout"].addWidget(self.controls["model_list"])
self.layouts["model_list_layout"].addWidget(self.buttons["refresh_models"])
# LOD组布局
self.layouts["lod_group_layout"] = QtWidgets.QVBoxLayout(self.controls["lod_group"])
self.layouts["lod_group_layout"].setContentsMargins(5, 10, 5, 5)
self.layouts["lod_group_layout"].setSpacing(5)
# LOD过滤组布局
self.layouts["lod_filter_layout"] = QtWidgets.QHBoxLayout(self.controls["lod_filter_group"])
self.layouts["lod_filter_layout"].addWidget(self.controls["lod_label"])
self.layouts["lod_filter_layout"].addWidget(self.controls["lod_combo"])
# LOD列表
self.layouts["lod_group_layout"].addWidget(self.controls["lod_list"])
# 添加组到左侧面板布局
# LOD操作按钮行
self.layouts["lod_buttons_layout"] = QtWidgets.QHBoxLayout()
self.layouts["lod_buttons_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["lod_buttons_layout"].setSpacing(2)
self.layouts["lod_buttons_layout"].addWidget(self.buttons["add_lod"])
self.layouts["lod_buttons_layout"].addWidget(self.buttons["remove_lod"])
self.layouts["lod_buttons_layout"].addWidget(self.buttons["duplicate_lod"])
self.layouts["lod_group_layout"].addLayout(self.layouts["lod_buttons_layout"])
# 模型组布局
self.layouts["model_group_layout"] = QtWidgets.QVBoxLayout(self.controls["model_group"])
self.layouts["model_group_layout"].setContentsMargins(5, 10, 5, 5)
self.layouts["model_group_layout"].setSpacing(5)
# 模型列表
self.layouts["model_group_layout"].addWidget(self.controls["model_list"])
# 模型操作按钮行
self.layouts["model_buttons_layout"] = QtWidgets.QHBoxLayout()
self.layouts["model_buttons_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["model_buttons_layout"].setSpacing(2)
self.layouts["model_buttons_layout"].addWidget(self.buttons["add_model"])
self.layouts["model_buttons_layout"].addWidget(self.buttons["remove_model"])
self.layouts["model_buttons_layout"].addWidget(self.buttons["duplicate_model"])
self.layouts["model_group_layout"].addLayout(self.layouts["model_buttons_layout"])
# 添加组到左侧面板
self.layouts["left_layout"].addWidget(self.controls["lod_group"])
self.layouts["left_layout"].addWidget(self.controls["model_group"])
self.layouts["left_layout"].addWidget(self.controls["lod_filter_group"])
self.layouts["left_layout"].addStretch()
# 右侧面板布局
self.layouts["right_layout"] = QtWidgets.QVBoxLayout(self.controls["right_panel"])
self.layouts["right_layout"].setContentsMargins(5, 5, 5, 5)
self.layouts["right_layout"].setSpacing(5)
# 模型操作组布局
self.layouts["model_ops_layout"] = QtWidgets.QVBoxLayout(self.controls["model_ops_group"])
self.layouts["model_ops_layout"].addWidget(self.buttons["pick_model"])
self.layouts["model_ops_layout"].addWidget(self.buttons["load_model"])
self.layouts["model_ops_layout"].addWidget(self.buttons["create_lod"])
self.layouts["model_ops_layout"].addWidget(self.buttons["auto_load"])
# 模型属性组布局
self.layouts["model_properties_layout"] = QtWidgets.QVBoxLayout(self.controls["model_properties_group"])
self.layouts["model_properties_layout"].setContentsMargins(5, 10, 5, 5)
self.layouts["model_properties_layout"].setSpacing(5)
# 模型名称行
self.layouts["model_name_layout"] = QtWidgets.QHBoxLayout()
self.layouts["model_name_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["model_name_layout"].setSpacing(5)
self.layouts["model_name_layout"].addWidget(self.controls["model_name_label"])
self.layouts["model_name_layout"].addWidget(self.controls["model_name_input"])
self.layouts["model_properties_layout"].addLayout(self.layouts["model_name_layout"])
# 模型类型行
self.layouts["model_type_layout"] = QtWidgets.QHBoxLayout()
self.layouts["model_type_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["model_type_layout"].setSpacing(5)
self.layouts["model_type_layout"].addWidget(self.controls["model_type_label"])
self.layouts["model_type_layout"].addWidget(self.controls["model_type_combo"])
self.layouts["model_properties_layout"].addLayout(self.layouts["model_type_layout"])
# 可见性复选框
self.layouts["model_properties_layout"].addWidget(self.controls["model_visible_check"])
# 属性按钮行
self.layouts["properties_buttons_layout"] = QtWidgets.QHBoxLayout()
self.layouts["properties_buttons_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["properties_buttons_layout"].setSpacing(5)
self.layouts["properties_buttons_layout"].addWidget(self.buttons["apply_properties"])
self.layouts["properties_buttons_layout"].addWidget(self.buttons["reset_properties"])
self.layouts["model_properties_layout"].addLayout(self.layouts["properties_buttons_layout"])
# 模型工具组布局
self.layouts["model_tools_layout"] = QtWidgets.QVBoxLayout(self.controls["model_tools_group"])
self.layouts["model_tools_layout"].addWidget(self.buttons["standardize_names"])
self.layouts["model_tools_layout"].addWidget(self.buttons["auto_group"])
self.layouts["model_tools_layout"].addWidget(self.buttons["generate_accessories"])
self.layouts["model_tools_layout"].addWidget(self.buttons["fix_seams"])
self.layouts["model_tools_layout"].addWidget(self.buttons["fix_vertex_order"])
self.layouts["model_tools_layout"].setContentsMargins(5, 10, 5, 5)
self.layouts["model_tools_layout"].setSpacing(5)
# 添加组到右侧面板布局
self.layouts["right_layout"].addWidget(self.controls["model_ops_group"])
# 模型工具按钮网格
self.layouts["tools_grid"] = QtWidgets.QGridLayout()
self.layouts["tools_grid"].setContentsMargins(0, 0, 0, 0)
self.layouts["tools_grid"].setSpacing(5)
self.layouts["tools_grid"].addWidget(self.buttons["standardize_names"], 0, 0)
self.layouts["tools_grid"].addWidget(self.buttons["auto_group"], 0, 1)
self.layouts["tools_grid"].addWidget(self.buttons["generate_accessories"], 1, 0)
self.layouts["tools_grid"].addWidget(self.buttons["fix_seams"], 1, 1)
self.layouts["tools_grid"].addWidget(self.buttons["fix_vertex_order"], 2, 0, 1, 2)
self.layouts["model_tools_layout"].addLayout(self.layouts["tools_grid"])
# 添加组到右侧面板
self.layouts["right_layout"].addWidget(self.controls["model_properties_group"])
self.layouts["right_layout"].addWidget(self.controls["model_tools_group"])
self.layouts["right_layout"].addStretch()
# 创建分割器大小处理器
self.resize_handlers["main_splitter"] = ui_utils.SplitterResizeHandler(
self.main_widget, self.splitters["main_splitter"], is_horizontal=True
)
# 底部工具面板
self.layouts["bottom_panel"] = QtWidgets.QHBoxLayout()
self.layouts["bottom_panel"].setContentsMargins(2, 2, 2, 2)
self.layouts["bottom_panel"].setSpacing(5)
# 导入组布局
self.layouts["import_layout"] = QtWidgets.QVBoxLayout(self.controls["import_group"])
self.layouts["import_layout"].setContentsMargins(5, 10, 5, 5)
self.layouts["import_layout"].setSpacing(5)
self.layouts["import_layout"].addWidget(self.buttons["import_model"])
self.layouts["import_layout"].addWidget(self.buttons["import_fbx"])
self.layouts["import_layout"].addWidget(self.buttons["import_obj"])
# 导出组布局
self.layouts["export_layout"] = QtWidgets.QVBoxLayout(self.controls["export_group"])
self.layouts["export_layout"].setContentsMargins(5, 10, 5, 5)
self.layouts["export_layout"].setSpacing(5)
self.layouts["export_layout"].addWidget(self.buttons["export_model"])
self.layouts["export_layout"].addWidget(self.buttons["export_fbx"])
self.layouts["export_layout"].addWidget(self.buttons["export_obj"])
# 工具组布局
self.layouts["tools_layout"] = QtWidgets.QVBoxLayout(self.controls["tools_group"])
self.layouts["tools_layout"].setContentsMargins(5, 10, 5, 5)
self.layouts["tools_layout"].setSpacing(5)
self.layouts["tools_layout"].addWidget(self.buttons["check_model"])
self.layouts["tools_layout"].addWidget(self.buttons["optimize_model"])
self.layouts["tools_layout"].addWidget(self.buttons["clean_model"])
self.layouts["tools_layout"].addWidget(self.buttons["uv_tools"])
# 添加组到底部面板
self.layouts["bottom_panel"].addWidget(self.controls["import_group"])
self.layouts["bottom_panel"].addWidget(self.controls["export_group"])
self.layouts["bottom_panel"].addWidget(self.controls["tools_group"])
# 添加底部面板到主布局
self.layouts["main_layout"].addLayout(self.layouts["bottom_panel"])
# 将左右面板添加到主分割器
self.splitters["main_splitter"].addWidget(self.controls["left_panel"])
self.splitters["main_splitter"].addWidget(self.controls["right_panel"])
# 设置分割器初始大小和伸缩因子
self.splitters["main_splitter"].setSizes([500, 500])
# 设置分割器的伸缩因子,确保左右栏能够自动调整宽度
for i in range(self.splitters["main_splitter"].count()):
self.splitters["main_splitter"].setStretchFactor(i, 1)
#======================================= CONNECTION =====================================
def create_connections(self):
@@ -222,21 +422,58 @@ class GeometryUI(ui_utils.BaseUI):
连接信号和槽
设置UI控件的交互行为
"""
# 模型列表按钮连接
self.buttons["refresh_models"].clicked.connect(utils_geometry.geometry_temp_utils_function)
# 导入几何工具函数
from scripts.utils import utils_geometry
# LOD过滤连接
self.controls["lod_combo"].currentIndexChanged.connect(utils_geometry.geometry_temp_utils_function)
# 左侧面板连接
# LOD列表连接
self.controls["lod_list"].itemClicked.connect(utils_geometry.lod_selected)
self.controls["lod_list"].itemSelectionChanged.connect(utils_geometry.update_lod_selection)
# LOD操作按钮连接
self.buttons["add_lod"].clicked.connect(utils_geometry.add_lod)
self.buttons["remove_lod"].clicked.connect(utils_geometry.remove_lod)
self.buttons["duplicate_lod"].clicked.connect(utils_geometry.duplicate_lod)
# 模型列表连接
self.controls["model_list"].itemClicked.connect(utils_geometry.model_selected)
self.controls["model_list"].itemSelectionChanged.connect(utils_geometry.update_model_selection)
# 模型操作按钮连接
self.buttons["pick_model"].clicked.connect(utils_geometry.geometry_temp_utils_function)
self.buttons["load_model"].clicked.connect(utils_geometry.geometry_temp_utils_function)
self.buttons["create_lod"].clicked.connect(utils_geometry.geometry_temp_utils_function)
self.buttons["auto_load"].clicked.connect(utils_geometry.geometry_temp_utils_function)
self.buttons["add_model"].clicked.connect(utils_geometry.add_model)
self.buttons["remove_model"].clicked.connect(utils_geometry.remove_model)
self.buttons["duplicate_model"].clicked.connect(utils_geometry.duplicate_model)
# 右侧面板连接
# 模型属性连接
self.controls["model_name_input"].textChanged.connect(utils_geometry.update_model_name)
self.controls["model_type_combo"].currentIndexChanged.connect(utils_geometry.update_model_type)
self.controls["model_visible_check"].stateChanged.connect(utils_geometry.toggle_model_visibility)
# 属性按钮连接
self.buttons["apply_properties"].clicked.connect(utils_geometry.apply_properties)
self.buttons["reset_properties"].clicked.connect(utils_geometry.reset_properties)
# 模型工具按钮连接
self.buttons["standardize_names"].clicked.connect(utils_geometry.geometry_temp_utils_function)
self.buttons["auto_group"].clicked.connect(utils_geometry.geometry_temp_utils_function)
self.buttons["generate_accessories"].clicked.connect(utils_geometry.geometry_temp_utils_function)
self.buttons["fix_seams"].clicked.connect(utils_geometry.geometry_temp_utils_function)
self.buttons["fix_vertex_order"].clicked.connect(utils_geometry.geometry_temp_utils_function)
self.buttons["standardize_names"].clicked.connect(utils_geometry.standardize_names)
self.buttons["auto_group"].clicked.connect(utils_geometry.auto_group)
self.buttons["generate_accessories"].clicked.connect(utils_geometry.generate_accessories)
self.buttons["fix_seams"].clicked.connect(utils_geometry.fix_seams)
self.buttons["fix_vertex_order"].clicked.connect(utils_geometry.fix_vertex_order)
# 底部工具面板连接
# 导入按钮连接
self.buttons["import_model"].clicked.connect(utils_geometry.import_model)
self.buttons["import_fbx"].clicked.connect(utils_geometry.import_fbx)
self.buttons["import_obj"].clicked.connect(utils_geometry.import_obj)
# 导出按钮连接
self.buttons["export_model"].clicked.connect(utils_geometry.export_model)
self.buttons["export_fbx"].clicked.connect(utils_geometry.export_fbx)
self.buttons["export_obj"].clicked.connect(utils_geometry.export_obj)
# 工具按钮连接
self.buttons["check_model"].clicked.connect(utils_geometry.check_model)
self.buttons["optimize_model"].clicked.connect(utils_geometry.optimize_model)
self.buttons["clean_model"].clicked.connect(utils_geometry.clean_model)
self.buttons["uv_tools"].clicked.connect(utils_geometry.uv_tools)

View File

@@ -87,10 +87,6 @@ class RiggingUI(ui_utils.BaseUI):
self.controls["title_label"].setObjectName("riggingTitleLabel")
self.controls["title_label"].setAlignment(QtCore.Qt.AlignCenter)
# 创建主分割器
self.splitters["main_splitter"] = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
self.splitters["main_splitter"].setObjectName("riggingMainSplitter")
# 左侧面板
self.controls["left_panel"] = QtWidgets.QWidget()
self.controls["left_panel"].setObjectName("riggingLeftPanel")
@@ -99,37 +95,202 @@ class RiggingUI(ui_utils.BaseUI):
self.controls["right_panel"] = QtWidgets.QWidget()
self.controls["right_panel"].setObjectName("riggingRightPanel")
# 左侧面板控件
# DNA浏览器组
self.controls["dna_browser_group"] = QtWidgets.QGroupBox(LANG.get("dna_browser", "DNA浏览器"))
self.controls["dna_browser_group"].setObjectName("dnaBrowserGroup")
# 左侧面板控件 - 骨骼列表
self.controls["skeleton_group"] = QtWidgets.QGroupBox("Skeleton [000]")
self.controls["skeleton_group"].setObjectName("skeletonGroup")
# DNA浏览器列表
self.controls["dna_list"] = QtWidgets.QListWidget()
self.controls["dna_list"].setObjectName("dnaList")
# 骨骼列表
self.controls["skeleton_list"] = QtWidgets.QListWidget()
self.controls["skeleton_list"].setObjectName("skeletonList")
# DNA浏览器刷新按钮
self.buttons["refresh_dna"] = QtWidgets.QPushButton(LANG.get("refresh", "刷新"))
self.buttons["refresh_dna"].setObjectName("refreshDnaButton")
# 右侧面板控件
# DNA操作组
self.controls["dna_ops_group"] = QtWidgets.QGroupBox(LANG.get("dna_operations", "DNA操作"))
self.controls["dna_ops_group"].setObjectName("dnaOpsGroup")
# DNA操作按钮
self.buttons["import_skeleton"] = QtWidgets.QPushButton(LANG.get("import_skeleton", "导入骨骼"))
self.buttons["generate_body"] = QtWidgets.QPushButton(LANG.get("generate_body", "生成身体"))
self.buttons["calibrate_dna"] = QtWidgets.QPushButton(LANG.get("calibrate_dna", "DNA校准"))
# 骨骼操作组
self.controls["skeleton_ops_group"] = QtWidgets.QGroupBox(LANG.get("skeleton_operations", "骨骼操作"))
self.controls["skeleton_ops_group"].setObjectName("skeletonOpsGroup")
# 添加测试项目
for i in range(5):
item = QtWidgets.QListWidgetItem(f"Joint_{i}")
self.controls["skeleton_list"].addItem(item)
# 骨骼操作按钮
self.buttons["calibrate_skeleton"] = QtWidgets.QPushButton(LANG.get("calibrate_skeleton", "骨骼位置校准"))
self.buttons["add_joint"] = QtWidgets.QPushButton(LANG.get("add_joint", "添加关节"))
self.buttons["add_joint"].setObjectName("addJointButton")
self.buttons["remove_joint"] = QtWidgets.QPushButton(LANG.get("remove_joint", "移除关节"))
self.buttons["remove_joint"].setObjectName("removeJointButton")
self.buttons["duplicate_joint"] = QtWidgets.QPushButton(LANG.get("duplicate_joint", "复制关节"))
self.buttons["duplicate_joint"].setObjectName("duplicateJointButton")
# 左侧面板控件 - 控制器列表
self.controls["controller_group"] = QtWidgets.QGroupBox("Controllers [000]")
self.controls["controller_group"].setObjectName("controllerGroup")
# 控制器列表
self.controls["controller_list"] = QtWidgets.QListWidget()
self.controls["controller_list"].setObjectName("controllerList")
# 添加测试项目
for i in range(3):
item = QtWidgets.QListWidgetItem(f"Controller_{i}")
self.controls["controller_list"].addItem(item)
# 控制器操作按钮
self.buttons["add_controller"] = QtWidgets.QPushButton(LANG.get("add_controller", "添加控制器"))
self.buttons["add_controller"].setObjectName("addControllerButton")
self.buttons["remove_controller"] = QtWidgets.QPushButton(LANG.get("remove_controller", "移除控制器"))
self.buttons["remove_controller"].setObjectName("removeControllerButton")
self.buttons["duplicate_controller"] = QtWidgets.QPushButton(LANG.get("duplicate_controller", "复制控制器"))
self.buttons["duplicate_controller"].setObjectName("duplicateControllerButton")
# 右侧面板控件 - 关节属性
self.controls["joint_properties_group"] = QtWidgets.QGroupBox(LANG.get("joint_properties", "关节属性"))
self.controls["joint_properties_group"].setObjectName("jointPropertiesGroup")
# 关节名称标签和输入框
self.controls["joint_name_label"] = QtWidgets.QLabel(LANG.get("name", "名称:"))
self.controls["joint_name_label"].setObjectName("jointNameLabel")
self.controls["joint_name_input"] = QtWidgets.QLineEdit()
self.controls["joint_name_input"].setObjectName("jointNameInput")
self.controls["joint_name_input"].setPlaceholderText(LANG.get("enter_joint_name", "输入关节名称"))
# 关节位置标签和输入框
self.controls["joint_position_label"] = QtWidgets.QLabel(LANG.get("position", "位置:"))
self.controls["joint_position_label"].setObjectName("jointPositionLabel")
# X坐标
self.controls["joint_x_label"] = QtWidgets.QLabel("X:")
self.controls["joint_x_label"].setObjectName("jointXLabel")
self.controls["joint_x_input"] = QtWidgets.QLineEdit("0.0")
self.controls["joint_x_input"].setObjectName("jointXInput")
# Y坐标
self.controls["joint_y_label"] = QtWidgets.QLabel("Y:")
self.controls["joint_y_label"].setObjectName("jointYLabel")
self.controls["joint_y_input"] = QtWidgets.QLineEdit("0.0")
self.controls["joint_y_input"].setObjectName("jointYInput")
# Z坐标
self.controls["joint_z_label"] = QtWidgets.QLabel("Z:")
self.controls["joint_z_label"].setObjectName("jointZLabel")
self.controls["joint_z_input"] = QtWidgets.QLineEdit("0.0")
self.controls["joint_z_input"].setObjectName("jointZInput")
# 关节旋转标签和输入框
self.controls["joint_rotation_label"] = QtWidgets.QLabel(LANG.get("rotation", "旋转:"))
self.controls["joint_rotation_label"].setObjectName("jointRotationLabel")
# X旋转
self.controls["joint_rx_label"] = QtWidgets.QLabel("X:")
self.controls["joint_rx_label"].setObjectName("jointRXLabel")
self.controls["joint_rx_input"] = QtWidgets.QLineEdit("0.0")
self.controls["joint_rx_input"].setObjectName("jointRXInput")
# Y旋转
self.controls["joint_ry_label"] = QtWidgets.QLabel("Y:")
self.controls["joint_ry_label"].setObjectName("jointRYLabel")
self.controls["joint_ry_input"] = QtWidgets.QLineEdit("0.0")
self.controls["joint_ry_input"].setObjectName("jointRYInput")
# Z旋转
self.controls["joint_rz_label"] = QtWidgets.QLabel("Z:")
self.controls["joint_rz_label"].setObjectName("jointRZLabel")
self.controls["joint_rz_input"] = QtWidgets.QLineEdit("0.0")
self.controls["joint_rz_input"].setObjectName("jointRZInput")
# 关节缩放标签和输入框
self.controls["joint_scale_label"] = QtWidgets.QLabel(LANG.get("scale", "缩放:"))
self.controls["joint_scale_label"].setObjectName("jointScaleLabel")
# X缩放
self.controls["joint_sx_label"] = QtWidgets.QLabel("X:")
self.controls["joint_sx_label"].setObjectName("jointSXLabel")
self.controls["joint_sx_input"] = QtWidgets.QLineEdit("1.0")
self.controls["joint_sx_input"].setObjectName("jointSXInput")
# Y缩放
self.controls["joint_sy_label"] = QtWidgets.QLabel("Y:")
self.controls["joint_sy_label"].setObjectName("jointSYLabel")
self.controls["joint_sy_input"] = QtWidgets.QLineEdit("1.0")
self.controls["joint_sy_input"].setObjectName("jointSYInput")
# Z缩放
self.controls["joint_sz_label"] = QtWidgets.QLabel("Z:")
self.controls["joint_sz_label"].setObjectName("jointSZLabel")
self.controls["joint_sz_input"] = QtWidgets.QLineEdit("1.0")
self.controls["joint_sz_input"].setObjectName("jointSZInput")
# 关节属性按钮
self.buttons["apply_joint_properties"] = QtWidgets.QPushButton(LANG.get("apply", "应用"))
self.buttons["apply_joint_properties"].setObjectName("applyJointPropertiesButton")
self.buttons["reset_joint_properties"] = QtWidgets.QPushButton(LANG.get("reset", "重置"))
self.buttons["reset_joint_properties"].setObjectName("resetJointPropertiesButton")
# 右侧面板控件 - 绑定工具
self.controls["binding_tools_group"] = QtWidgets.QGroupBox(LANG.get("binding_tools", "绑定工具"))
self.controls["binding_tools_group"].setObjectName("bindingToolsGroup")
# 绑定工具按钮
self.buttons["create_binding"] = QtWidgets.QPushButton(LANG.get("create_binding", "创建绑定"))
self.buttons["create_binding"].setObjectName("createBindingButton")
self.buttons["copy_skin"] = QtWidgets.QPushButton(LANG.get("copy_skin", "复制蒙皮"))
self.buttons["copy_skin"].setObjectName("copySkinButton")
self.buttons["mirror_skin"] = QtWidgets.QPushButton(LANG.get("mirror_skin", "镜像蒙皮"))
self.buttons["mirror_skin"].setObjectName("mirrorSkinButton")
self.buttons["paint_weights"] = QtWidgets.QPushButton(LANG.get("paint_weights", "绘制权重"))
self.buttons["paint_weights"].setObjectName("paintWeightsButton")
# 底部工具面板
# DNA部分
self.controls["dna_group"] = QtWidgets.QGroupBox(LANG.get("dna", "DNA"))
self.controls["dna_group"].setObjectName("dnaGroup")
self.buttons["import_dna"] = QtWidgets.QPushButton(LANG.get("import_dna", "导入DNA"))
self.buttons["import_dna"].setObjectName("importDnaButton")
self.buttons["export_dna"] = QtWidgets.QPushButton(LANG.get("export_dna", "导出DNA"))
self.buttons["export_dna"].setObjectName("exportDnaButton")
self.buttons["calibrate_dna"] = QtWidgets.QPushButton(LANG.get("calibrate_dna", "校准DNA"))
self.buttons["calibrate_dna"].setObjectName("calibrateDnaButton")
# 骨骼部分
self.controls["skeleton_tools_group"] = QtWidgets.QGroupBox(LANG.get("skeleton_tools", "骨骼工具"))
self.controls["skeleton_tools_group"].setObjectName("skeletonToolsGroup")
self.buttons["import_skeleton"] = QtWidgets.QPushButton(LANG.get("import_skeleton", "导入骨骼"))
self.buttons["import_skeleton"].setObjectName("importSkeletonButton")
self.buttons["export_skeleton"] = QtWidgets.QPushButton(LANG.get("export_skeleton", "导出骨骼"))
self.buttons["export_skeleton"].setObjectName("exportSkeletonButton")
self.buttons["calibrate_skeleton"] = QtWidgets.QPushButton(LANG.get("calibrate_skeleton", "校准骨骼"))
self.buttons["calibrate_skeleton"].setObjectName("calibrateSkeletonButton")
# 工具部分
self.controls["rigging_tools_group"] = QtWidgets.QGroupBox(LANG.get("rigging_tools", "绑定工具"))
self.controls["rigging_tools_group"].setObjectName("riggingToolsGroup")
self.buttons["generate_controllers"] = QtWidgets.QPushButton(LANG.get("generate_controllers", "生成控制器"))
self.buttons["generate_controllers"].setObjectName("generateControllersButton")
self.buttons["generate_body"] = QtWidgets.QPushButton(LANG.get("generate_body", "生成身体"))
self.buttons["generate_body"].setObjectName("generateBodyButton")
self.buttons["clean_rigging"] = QtWidgets.QPushButton(LANG.get("clean_rigging", "清理绑定"))
self.buttons["clean_rigging"].setObjectName("cleanRiggingButton")
#========================================= LAYOUT =======================================
def create_layouts(self):
@@ -138,60 +299,232 @@ class RiggingUI(ui_utils.BaseUI):
组织控件的排列和层次结构
"""
# 主布局
self.layouts["main_layout"] = QtWidgets.QVBoxLayout(self.main_widget)
self.layouts["main_layout"].setContentsMargins(5, 5, 5, 5)
self.layouts["main_layout"].setSpacing(5)
self.layouts["main_layout"] = QtWidgets.QVBoxLayout(self)
self.layouts["main_layout"].setContentsMargins(2, 2, 2, 2)
self.layouts["main_layout"].setSpacing(2)
# 添加标题标签
self.layouts["main_layout"].addWidget(self.controls["title_label"])
# 添加主分割器
# 创建主分割器
self.splitters["main_splitter"] = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
self.splitters["main_splitter"].setObjectName("riggingMainSplitter")
self.layouts["main_layout"].addWidget(self.splitters["main_splitter"])
# 将左右面板添加到主分割器
self.splitters["main_splitter"].addWidget(self.controls["left_panel"])
self.splitters["main_splitter"].addWidget(self.controls["right_panel"])
# 左侧面板布局
self.layouts["left_layout"] = QtWidgets.QVBoxLayout(self.controls["left_panel"])
self.layouts["left_layout"].setContentsMargins(5, 5, 5, 5)
self.layouts["left_layout"].setSpacing(5)
# DNA浏览器组布局
self.layouts["dna_browser_layout"] = QtWidgets.QVBoxLayout(self.controls["dna_browser_group"])
self.layouts["dna_browser_layout"].addWidget(self.controls["dna_list"])
self.layouts["dna_browser_layout"].addWidget(self.buttons["refresh_dna"])
# 骨骼组布局
self.layouts["skeleton_group_layout"] = QtWidgets.QVBoxLayout(self.controls["skeleton_group"])
self.layouts["skeleton_group_layout"].setContentsMargins(5, 10, 5, 5)
self.layouts["skeleton_group_layout"].setSpacing(5)
# 添加组到左侧面板布局
self.layouts["left_layout"].addWidget(self.controls["dna_browser_group"])
self.layouts["left_layout"].addStretch()
# 骨骼列表
self.layouts["skeleton_group_layout"].addWidget(self.controls["skeleton_list"])
# 骨骼操作按钮行
self.layouts["skeleton_buttons_layout"] = QtWidgets.QHBoxLayout()
self.layouts["skeleton_buttons_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["skeleton_buttons_layout"].setSpacing(2)
self.layouts["skeleton_buttons_layout"].addWidget(self.buttons["add_joint"])
self.layouts["skeleton_buttons_layout"].addWidget(self.buttons["remove_joint"])
self.layouts["skeleton_buttons_layout"].addWidget(self.buttons["duplicate_joint"])
self.layouts["skeleton_group_layout"].addLayout(self.layouts["skeleton_buttons_layout"])
# 控制器组布局
self.layouts["controller_group_layout"] = QtWidgets.QVBoxLayout(self.controls["controller_group"])
self.layouts["controller_group_layout"].setContentsMargins(5, 10, 5, 5)
self.layouts["controller_group_layout"].setSpacing(5)
# 控制器列表
self.layouts["controller_group_layout"].addWidget(self.controls["controller_list"])
# 控制器操作按钮行
self.layouts["controller_buttons_layout"] = QtWidgets.QHBoxLayout()
self.layouts["controller_buttons_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["controller_buttons_layout"].setSpacing(2)
self.layouts["controller_buttons_layout"].addWidget(self.buttons["add_controller"])
self.layouts["controller_buttons_layout"].addWidget(self.buttons["remove_controller"])
self.layouts["controller_buttons_layout"].addWidget(self.buttons["duplicate_controller"])
self.layouts["controller_group_layout"].addLayout(self.layouts["controller_buttons_layout"])
# 添加组到左侧面板
self.layouts["left_layout"].addWidget(self.controls["skeleton_group"])
self.layouts["left_layout"].addWidget(self.controls["controller_group"])
# 右侧面板布局
self.layouts["right_layout"] = QtWidgets.QVBoxLayout(self.controls["right_panel"])
self.layouts["right_layout"].setContentsMargins(5, 5, 5, 5)
self.layouts["right_layout"].setSpacing(5)
# DNA操作组布局
self.layouts["dna_ops_layout"] = QtWidgets.QVBoxLayout(self.controls["dna_ops_group"])
self.layouts["dna_ops_layout"].addWidget(self.buttons["import_skeleton"])
self.layouts["dna_ops_layout"].addWidget(self.buttons["generate_body"])
self.layouts["dna_ops_layout"].addWidget(self.buttons["calibrate_dna"])
# 关节属性组布局
self.layouts["joint_properties_layout"] = QtWidgets.QVBoxLayout(self.controls["joint_properties_group"])
self.layouts["joint_properties_layout"].setContentsMargins(5, 10, 5, 5)
self.layouts["joint_properties_layout"].setSpacing(5)
# 骨骼操作组布局
self.layouts["skeleton_ops_layout"] = QtWidgets.QVBoxLayout(self.controls["skeleton_ops_group"])
self.layouts["skeleton_ops_layout"].addWidget(self.buttons["calibrate_skeleton"])
self.layouts["skeleton_ops_layout"].addWidget(self.buttons["create_binding"])
self.layouts["skeleton_ops_layout"].addWidget(self.buttons["copy_skin"])
# 关节名称行
self.layouts["joint_name_layout"] = QtWidgets.QHBoxLayout()
self.layouts["joint_name_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["joint_name_layout"].setSpacing(5)
# 添加组到右侧面板布局
self.layouts["right_layout"].addWidget(self.controls["dna_ops_group"])
self.layouts["right_layout"].addWidget(self.controls["skeleton_ops_group"])
self.layouts["right_layout"].addStretch()
self.layouts["joint_name_layout"].addWidget(self.controls["joint_name_label"])
self.layouts["joint_name_layout"].addWidget(self.controls["joint_name_input"])
# 创建分割器大小处理器
self.resize_handlers["main_splitter"] = ui_utils.SplitterResizeHandler(
self.main_widget, self.splitters["main_splitter"], is_horizontal=True
)
self.layouts["joint_properties_layout"].addLayout(self.layouts["joint_name_layout"])
# 关节位置行
self.layouts["joint_position_layout"] = QtWidgets.QVBoxLayout()
self.layouts["joint_position_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["joint_position_layout"].setSpacing(2)
self.layouts["joint_position_layout"].addWidget(self.controls["joint_position_label"])
# 位置坐标行
self.layouts["position_coords_layout"] = QtWidgets.QGridLayout()
self.layouts["position_coords_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["position_coords_layout"].setSpacing(5)
self.layouts["position_coords_layout"].addWidget(self.controls["joint_x_label"], 0, 0)
self.layouts["position_coords_layout"].addWidget(self.controls["joint_x_input"], 0, 1)
self.layouts["position_coords_layout"].addWidget(self.controls["joint_y_label"], 1, 0)
self.layouts["position_coords_layout"].addWidget(self.controls["joint_y_input"], 1, 1)
self.layouts["position_coords_layout"].addWidget(self.controls["joint_z_label"], 2, 0)
self.layouts["position_coords_layout"].addWidget(self.controls["joint_z_input"], 2, 1)
self.layouts["joint_position_layout"].addLayout(self.layouts["position_coords_layout"])
self.layouts["joint_properties_layout"].addLayout(self.layouts["joint_position_layout"])
# 关节旋转行
self.layouts["joint_rotation_layout"] = QtWidgets.QVBoxLayout()
self.layouts["joint_rotation_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["joint_rotation_layout"].setSpacing(2)
self.layouts["joint_rotation_layout"].addWidget(self.controls["joint_rotation_label"])
# 旋转坐标行
self.layouts["rotation_coords_layout"] = QtWidgets.QGridLayout()
self.layouts["rotation_coords_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["rotation_coords_layout"].setSpacing(5)
self.layouts["rotation_coords_layout"].addWidget(self.controls["joint_rx_label"], 0, 0)
self.layouts["rotation_coords_layout"].addWidget(self.controls["joint_rx_input"], 0, 1)
self.layouts["rotation_coords_layout"].addWidget(self.controls["joint_ry_label"], 1, 0)
self.layouts["rotation_coords_layout"].addWidget(self.controls["joint_ry_input"], 1, 1)
self.layouts["rotation_coords_layout"].addWidget(self.controls["joint_rz_label"], 2, 0)
self.layouts["rotation_coords_layout"].addWidget(self.controls["joint_rz_input"], 2, 1)
self.layouts["joint_rotation_layout"].addLayout(self.layouts["rotation_coords_layout"])
self.layouts["joint_properties_layout"].addLayout(self.layouts["joint_rotation_layout"])
# 关节缩放行
self.layouts["joint_scale_layout"] = QtWidgets.QVBoxLayout()
self.layouts["joint_scale_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["joint_scale_layout"].setSpacing(2)
self.layouts["joint_scale_layout"].addWidget(self.controls["joint_scale_label"])
# 缩放坐标行
self.layouts["scale_coords_layout"] = QtWidgets.QGridLayout()
self.layouts["scale_coords_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["scale_coords_layout"].setSpacing(5)
self.layouts["scale_coords_layout"].addWidget(self.controls["joint_sx_label"], 0, 0)
self.layouts["scale_coords_layout"].addWidget(self.controls["joint_sx_input"], 0, 1)
self.layouts["scale_coords_layout"].addWidget(self.controls["joint_sy_label"], 1, 0)
self.layouts["scale_coords_layout"].addWidget(self.controls["joint_sy_input"], 1, 1)
self.layouts["scale_coords_layout"].addWidget(self.controls["joint_sz_label"], 2, 0)
self.layouts["scale_coords_layout"].addWidget(self.controls["joint_sz_input"], 2, 1)
self.layouts["joint_scale_layout"].addLayout(self.layouts["scale_coords_layout"])
self.layouts["joint_properties_layout"].addLayout(self.layouts["joint_scale_layout"])
# 属性按钮行
self.layouts["properties_buttons_layout"] = QtWidgets.QHBoxLayout()
self.layouts["properties_buttons_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["properties_buttons_layout"].setSpacing(5)
self.layouts["properties_buttons_layout"].addWidget(self.buttons["apply_joint_properties"])
self.layouts["properties_buttons_layout"].addWidget(self.buttons["reset_joint_properties"])
self.layouts["joint_properties_layout"].addLayout(self.layouts["properties_buttons_layout"])
# 绑定工具组布局
self.layouts["binding_tools_layout"] = QtWidgets.QVBoxLayout(self.controls["binding_tools_group"])
self.layouts["binding_tools_layout"].setContentsMargins(5, 10, 5, 5)
self.layouts["binding_tools_layout"].setSpacing(5)
# 绑定工具按钮网格
self.layouts["binding_tools_grid"] = QtWidgets.QGridLayout()
self.layouts["binding_tools_grid"].setContentsMargins(0, 0, 0, 0)
self.layouts["binding_tools_grid"].setSpacing(5)
self.layouts["binding_tools_grid"].addWidget(self.buttons["create_binding"], 0, 0)
self.layouts["binding_tools_grid"].addWidget(self.buttons["copy_skin"], 0, 1)
self.layouts["binding_tools_grid"].addWidget(self.buttons["mirror_skin"], 1, 0)
self.layouts["binding_tools_grid"].addWidget(self.buttons["paint_weights"], 1, 1)
self.layouts["binding_tools_layout"].addLayout(self.layouts["binding_tools_grid"])
# 添加组到右侧面板
self.layouts["right_layout"].addWidget(self.controls["joint_properties_group"])
self.layouts["right_layout"].addWidget(self.controls["binding_tools_group"])
# 底部工具面板
self.layouts["bottom_panel"] = QtWidgets.QHBoxLayout()
self.layouts["bottom_panel"].setContentsMargins(2, 2, 2, 2)
self.layouts["bottom_panel"].setSpacing(5)
# DNA组布局
self.layouts["dna_layout"] = QtWidgets.QVBoxLayout(self.controls["dna_group"])
self.layouts["dna_layout"].setContentsMargins(5, 10, 5, 5)
self.layouts["dna_layout"].setSpacing(5)
self.layouts["dna_layout"].addWidget(self.buttons["import_dna"])
self.layouts["dna_layout"].addWidget(self.buttons["export_dna"])
self.layouts["dna_layout"].addWidget(self.buttons["calibrate_dna"])
# 骨骼工具组布局
self.layouts["skeleton_tools_layout"] = QtWidgets.QVBoxLayout(self.controls["skeleton_tools_group"])
self.layouts["skeleton_tools_layout"].setContentsMargins(5, 10, 5, 5)
self.layouts["skeleton_tools_layout"].setSpacing(5)
self.layouts["skeleton_tools_layout"].addWidget(self.buttons["import_skeleton"])
self.layouts["skeleton_tools_layout"].addWidget(self.buttons["export_skeleton"])
self.layouts["skeleton_tools_layout"].addWidget(self.buttons["calibrate_skeleton"])
# 绑定工具组布局
self.layouts["rigging_tools_layout"] = QtWidgets.QVBoxLayout(self.controls["rigging_tools_group"])
self.layouts["rigging_tools_layout"].setContentsMargins(5, 10, 5, 5)
self.layouts["rigging_tools_layout"].setSpacing(5)
self.layouts["rigging_tools_layout"].addWidget(self.buttons["generate_controllers"])
self.layouts["rigging_tools_layout"].addWidget(self.buttons["generate_body"])
self.layouts["rigging_tools_layout"].addWidget(self.buttons["clean_rigging"])
# 添加组到底部面板
self.layouts["bottom_panel"].addWidget(self.controls["dna_group"])
self.layouts["bottom_panel"].addWidget(self.controls["skeleton_tools_group"])
self.layouts["bottom_panel"].addWidget(self.controls["rigging_tools_group"])
# 添加底部面板到主布局
self.layouts["main_layout"].addLayout(self.layouts["bottom_panel"])
# 将左右面板添加到主分割器
self.splitters["main_splitter"].addWidget(self.controls["left_panel"])
self.splitters["main_splitter"].addWidget(self.controls["right_panel"])
# 设置分割器初始大小和伸缩因子
self.splitters["main_splitter"].setSizes([500, 500])
# 设置分割器的伸缩因子,确保左右栏能够自动调整宽度
for i in range(self.splitters["main_splitter"].count()):
self.splitters["main_splitter"].setStretchFactor(i, 1)
#======================================= CONNECTION =====================================
def create_connections(self):

View File

@@ -81,33 +81,62 @@ class ToolbarUI(ui_utils.BaseUI):
创建工具栏UI控件
包括按钮、标签、输入框等
"""
# 标题标签
self.controls["title_label"] = QtWidgets.QLabel(LANG.get("toolbar_title", "工具栏"))
self.controls["title_label"].setObjectName("toolbarTitleLabel")
self.controls["title_label"].setAlignment(QtCore.Qt.AlignCenter)
# 创建顶部工具栏
self.controls["toolbar_frame"] = QtWidgets.QFrame()
self.controls["toolbar_frame"].setObjectName("toolbarFrame")
self.controls["toolbar_frame"].setFrameShape(QtWidgets.QFrame.StyledPanel)
self.controls["toolbar_frame"].setFrameShadow(QtWidgets.QFrame.Raised)
# 预设组
self.controls["preset_group"] = QtWidgets.QGroupBox(LANG.get("preset_group", "预设"))
self.controls["preset_group"].setObjectName("presetGroup")
# 创建工具栏按钮
# 第一行按钮
self.buttons["new_file"] = self._create_tool_button("新建文件", ":/icons/new_file.png")
self.buttons["open_file"] = self._create_tool_button("打开文件", ":/icons/open_file.png")
self.buttons["link_file"] = self._create_tool_button("链接文件", ":/icons/link_file.png")
self.buttons["unlink_file"] = self._create_tool_button("取消链接", ":/icons/unlink_file.png")
self.buttons["import_file"] = self._create_tool_button("导入文件", ":/icons/import_file.png")
self.buttons["export_file"] = self._create_tool_button("导出文件", ":/icons/export_file.png")
self.buttons["save_file"] = self._create_tool_button("保存文件", ":/icons/save_file.png")
self.buttons["user_info"] = self._create_tool_button("用户信息", ":/icons/user_info.png")
self.buttons["help"] = self._create_tool_button("帮助", ":/icons/help.png")
self.buttons["settings"] = self._create_tool_button("设置", ":/icons/settings.png")
self.buttons["print"] = self._create_tool_button("打印", ":/icons/print.png")
# 预设标签和下拉框
self.controls["preset_label"] = QtWidgets.QLabel(LANG.get("preset", "预设:"))
self.controls["preset_combo"] = QtWidgets.QComboBox()
self.controls["preset_combo"].setObjectName("presetCombo")
# 第二行按钮和下拉框
self.buttons["model_view"] = self._create_tool_button("模型视图", ":/icons/model_view.png", checkable=True)
self.buttons["model_view"].setChecked(True)
self.buttons["definition_view"] = self._create_tool_button("定义视图", ":/icons/definition_view.png", checkable=True)
self.buttons["table_view"] = self._create_tool_button("表格视图", ":/icons/table_view.png", checkable=True)
self.buttons["define_view"] = self._create_tool_button("自定义视图", ":/icons/define_view.png", checkable=True)
# 预设按钮
self.buttons["load_preset"] = QtWidgets.QPushButton(LANG.get("load_preset", "加载预设"))
self.buttons["save_preset"] = QtWidgets.QPushButton(LANG.get("save_preset", "保存预设"))
# 下拉框
self.controls["model_combo"] = QtWidgets.QComboBox()
self.controls["model_combo"].setObjectName("modelCombo")
self.controls["model_combo"].addItem("MetaHuman")
self.controls["model_combo"].setMinimumWidth(120)
# DNA操作组
self.controls["dna_group"] = QtWidgets.QGroupBox(LANG.get("dna_operations", "DNA操作"))
self.controls["dna_group"].setObjectName("dnaGroup")
# 帮助按钮
self.buttons["help_button"] = QtWidgets.QPushButton()
self.buttons["help_button"].setIcon(QtGui.QIcon(":/icons/question.png"))
self.buttons["help_button"].setObjectName("helpButton")
self.buttons["help_button"].setFixedSize(24, 24)
self.buttons["help_button"].setToolTip(LANG.get("help_tooltip", "帮助"))
def _create_tool_button(self, tooltip, icon_path, checkable=False):
"""
创建工具栏按钮
"""
button = QtWidgets.QPushButton()
button.setToolTip(LANG.get(tooltip, tooltip))
# 尝试设置图标,如果图标文件不存在则使用文字
if os.path.exists(icon_path.replace(":/icons/", f"{ICONS_PATH}/")):
button.setIcon(QtGui.QIcon(icon_path))
else:
button.setText(LANG.get(tooltip, tooltip))
# DNA操作按钮
self.buttons["import_dna"] = QtWidgets.QPushButton(LANG.get("import_dna", "导入DNA"))
self.buttons["export_dna"] = QtWidgets.QPushButton(LANG.get("export_dna", "导出DNA"))
self.buttons["create_rl4"] = QtWidgets.QPushButton(LANG.get("create_rl4", "创建RL4节点"))
self.buttons["delete_rl4"] = QtWidgets.QPushButton(LANG.get("delete_rl4", "删除RL4节点"))
button.setObjectName(f"{tooltip.replace(' ', '_').lower()}_button")
button.setFixedSize(32, 32)
button.setCheckable(checkable)
return button
#========================================= LAYOUT =======================================
def create_layouts(self):
@@ -117,46 +146,61 @@ class ToolbarUI(ui_utils.BaseUI):
"""
# 主布局
self.layouts["main_layout"] = QtWidgets.QVBoxLayout(self.main_widget)
self.layouts["main_layout"].setContentsMargins(5, 5, 5, 5)
self.layouts["main_layout"].setSpacing(5)
self.layouts["main_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["main_layout"].setSpacing(0)
# 添加标题标签
self.layouts["main_layout"].addWidget(self.controls["title_label"])
# 添加工具栏框架
self.layouts["main_layout"].addWidget(self.controls["toolbar_frame"])
# 预设组布局
self.layouts["preset_layout"] = QtWidgets.QVBoxLayout(self.controls["preset_group"])
# 工具栏框架布局
self.layouts["toolbar_layout"] = QtWidgets.QVBoxLayout(self.controls["toolbar_frame"])
self.layouts["toolbar_layout"].setContentsMargins(5, 5, 5, 5)
self.layouts["toolbar_layout"].setSpacing(2)
# 预设选择布局
self.layouts["preset_select_layout"] = QtWidgets.QHBoxLayout()
self.layouts["preset_select_layout"].addWidget(self.controls["preset_label"])
self.layouts["preset_select_layout"].addWidget(self.controls["preset_combo"])
# 第一行按钮布局
self.layouts["toolbar_row1"] = QtWidgets.QHBoxLayout()
self.layouts["toolbar_row1"].setSpacing(2)
self.layouts["toolbar_row1"].addWidget(self.buttons["new_file"])
self.layouts["toolbar_row1"].addWidget(self.buttons["open_file"])
self.layouts["toolbar_row1"].addWidget(self.buttons["link_file"])
self.layouts["toolbar_row1"].addWidget(self.buttons["unlink_file"])
self.layouts["toolbar_row1"].addWidget(self._create_separator())
self.layouts["toolbar_row1"].addWidget(self.buttons["import_file"])
self.layouts["toolbar_row1"].addWidget(self.buttons["export_file"])
self.layouts["toolbar_row1"].addWidget(self.buttons["save_file"])
self.layouts["toolbar_row1"].addWidget(self._create_separator())
self.layouts["toolbar_row1"].addWidget(self.buttons["user_info"])
self.layouts["toolbar_row1"].addWidget(self.buttons["help"])
self.layouts["toolbar_row1"].addWidget(self.buttons["settings"])
self.layouts["toolbar_row1"].addWidget(self.buttons["print"])
self.layouts["toolbar_row1"].addStretch()
# 预设按钮布局
self.layouts["preset_buttons_layout"] = QtWidgets.QHBoxLayout()
self.layouts["preset_buttons_layout"].addWidget(self.buttons["load_preset"])
self.layouts["preset_buttons_layout"].addWidget(self.buttons["save_preset"])
# 第二行按钮布局
self.layouts["toolbar_row2"] = QtWidgets.QHBoxLayout()
self.layouts["toolbar_row2"].setSpacing(2)
self.layouts["toolbar_row2"].addWidget(self.buttons["model_view"])
self.layouts["toolbar_row2"].addWidget(self.buttons["definition_view"])
self.layouts["toolbar_row2"].addWidget(self.buttons["table_view"])
self.layouts["toolbar_row2"].addWidget(self.buttons["define_view"])
self.layouts["toolbar_row2"].addWidget(self._create_separator())
self.layouts["toolbar_row2"].addWidget(self.controls["model_combo"])
self.layouts["toolbar_row2"].addStretch()
self.layouts["toolbar_row2"].addWidget(self.buttons["help_button"])
# 添加到预设组布局
self.layouts["preset_layout"].addLayout(self.layouts["preset_select_layout"])
self.layouts["preset_layout"].addLayout(self.layouts["preset_buttons_layout"])
# DNA操作组布局
self.layouts["dna_layout"] = QtWidgets.QVBoxLayout(self.controls["dna_group"])
# DNA操作按钮布局
self.layouts["dna_buttons_layout"] = QtWidgets.QGridLayout()
self.layouts["dna_buttons_layout"].addWidget(self.buttons["import_dna"], 0, 0)
self.layouts["dna_buttons_layout"].addWidget(self.buttons["export_dna"], 0, 1)
self.layouts["dna_buttons_layout"].addWidget(self.buttons["create_rl4"], 1, 0)
self.layouts["dna_buttons_layout"].addWidget(self.buttons["delete_rl4"], 1, 1)
# 添加到DNA操作组布局
self.layouts["dna_layout"].addLayout(self.layouts["dna_buttons_layout"])
# 添加组到主布局
self.layouts["main_layout"].addWidget(self.controls["preset_group"])
self.layouts["main_layout"].addWidget(self.controls["dna_group"])
self.layouts["main_layout"].addStretch()
# 添加行到工具栏布局
self.layouts["toolbar_layout"].addLayout(self.layouts["toolbar_row1"])
self.layouts["toolbar_layout"].addLayout(self.layouts["toolbar_row2"])
def _create_separator(self):
"""
创建分隔线
"""
separator = QtWidgets.QFrame()
separator.setFrameShape(QtWidgets.QFrame.VLine)
separator.setFrameShadow(QtWidgets.QFrame.Sunken)
separator.setFixedWidth(2)
separator.setFixedHeight(24)
return separator
#======================================= CONNECTION =====================================
def create_connections(self):
@@ -164,13 +208,28 @@ class ToolbarUI(ui_utils.BaseUI):
连接信号和槽
设置UI控件的交互行为
"""
# 预设按钮连接
self.buttons["load_preset"].clicked.connect(utils_toolbar.toolbar_temp_utils_function)
self.buttons["save_preset"].clicked.connect(utils_toolbar.toolbar_temp_utils_function)
# 第一行按钮连接
self.buttons["new_file"].clicked.connect(utils_toolbar.new_file)
self.buttons["open_file"].clicked.connect(utils_toolbar.open_file)
self.buttons["link_file"].clicked.connect(utils_toolbar.link_file)
self.buttons["unlink_file"].clicked.connect(utils_toolbar.unlink_file)
self.buttons["import_file"].clicked.connect(utils_toolbar.import_file)
self.buttons["export_file"].clicked.connect(utils_toolbar.export_file)
self.buttons["save_file"].clicked.connect(utils_toolbar.save_file)
self.buttons["user_info"].clicked.connect(utils_toolbar.show_user_info)
self.buttons["help"].clicked.connect(utils_toolbar.show_help)
self.buttons["settings"].clicked.connect(utils_toolbar.show_settings)
self.buttons["print"].clicked.connect(utils_toolbar.print_file)
# DNA操作按钮连接
self.buttons["import_dna"].clicked.connect(utils_toolbar.toolbar_temp_utils_function)
self.buttons["export_dna"].clicked.connect(utils_toolbar.toolbar_temp_utils_function)
self.buttons["create_rl4"].clicked.connect(utils_toolbar.toolbar_temp_utils_function)
self.buttons["delete_rl4"].clicked.connect(utils_toolbar.toolbar_temp_utils_function)
# 第二行按钮连接
self.buttons["model_view"].clicked.connect(lambda: utils_toolbar.change_view("model"))
self.buttons["definition_view"].clicked.connect(lambda: utils_toolbar.change_view("definition"))
self.buttons["table_view"].clicked.connect(lambda: utils_toolbar.change_view("table"))
self.buttons["define_view"].clicked.connect(lambda: utils_toolbar.change_view("define"))
# 下拉框连接
self.controls["model_combo"].currentIndexChanged.connect(utils_toolbar.model_changed)
# 帮助按钮连接
self.buttons["help_button"].clicked.connect(utils_toolbar.show_help)

View File

@@ -9,16 +9,267 @@ Behaviour function module
#===================================== IMPORT MODULES =====================================
import maya.cmds as cmds
import pymel.core as pm
import maya.mel as mel
from maya import OpenMayaUI as omui
from Qt import QtWidgets, QtCore, QtGui
from Qt.QtCompat import wrapInstance
import webbrowser
import subprocess
import importlib
import traceback
import sys
import os
# 导入配置
import config
from scripts.ui import localization
LANG = localization.LANG
#========================================== FUNCTIONS ========================================
# 左侧面板功能
# 搜索相关功能
def filter_controls(text):
"""
过滤控制列表
"""
print(f"过滤控制列表: {text}")
# 这里实现过滤控制列表的功能
return True
# 控制列表相关功能
def control_selected(item):
"""
控制项目被选中
"""
print(f"控制项目被选中: {item.text()}")
# 这里实现控制项目选中的功能
return True
def update_control_selection():
"""
更新控制选择
"""
print("更新控制选择")
# 这里实现更新控制选择的功能
return True
def update_control_value(value):
"""
更新控制值
"""
print(f"更新控制值: {value}")
# 这里实现更新控制值的功能
return True
# 页码相关功能
def switch_page(page):
"""
切换页面
"""
print(f"切换页面: {page}")
# 这里实现切换页面的功能
return True
# 范围相关功能
def decrease_range():
"""
减小范围
"""
print("减小范围")
# 这里实现减小范围的功能
return True
def increase_range():
"""
增加范围
"""
print("增加范围")
# 这里实现增加范围的功能
return True
# 右侧面板功能
# BlendShapes相关功能
def blendshape_selected(item):
"""
混合形状项目被选中
"""
print(f"混合形状项目被选中: {item.text()}")
# 这里实现混合形状项目选中的功能
return True
def update_blendshape_selection():
"""
更新混合形状选择
"""
print("更新混合形状选择")
# 这里实现更新混合形状选择的功能
return True
def update_blendshape_value(value):
"""
更新混合形状值
"""
print(f"更新混合形状值: {value}")
# 这里实现更新混合形状值的功能
return True
# BlendShape操作相关功能
def reset_blendshape():
"""
重置混合形状
"""
print("重置混合形状")
# 这里实现重置混合形状的功能
return True
def mirror_blendshape():
"""
镜像混合形状
"""
print("镜像混合形状")
# 这里实现镜像混合形状的功能
return True
def add_blendshape():
"""
添加混合形状
"""
print("添加混合形状")
# 这里实现添加混合形状的功能
return True
def remove_blendshape():
"""
移除混合形状
"""
print("移除混合形状")
# 这里实现移除混合形状的功能
return True
def update_blendshape():
"""
更新混合形状
"""
print("更新混合形状")
# 这里实现更新混合形状的功能
return True
def isolate_blendshape():
"""
隔离混合形状
"""
print("隔离混合形状")
# 这里实现隔离混合形状的功能
return True
def new_blendshape():
"""
新建混合形状
"""
print("新建混合形状")
# 这里实现新建混合形状的功能
return True
def combine_blendshape():
"""
组合混合形状
"""
print("组合混合形状")
# 这里实现组合混合形状的功能
return True
# 标签页相关功能
def switch_tab(tab):
"""
切换标签页
"""
print(f"切换标签页: {tab}")
# 这里实现切换标签页的功能
return True
# 底部相关功能
def update_main_value(value):
"""
更新主值
"""
print(f"更新主值: {value}")
# 这里实现更新主值的功能
return True
def exchange_from_expression():
"""
交换从表情
"""
print("交换从表情")
# 这里实现交换从表情的功能
return True
def reset_selected_expression():
"""
重置选定表情
"""
print("重置选定表情")
# 这里实现重置选定表情的功能
return True
def import_expression():
"""
导入表情
"""
print("导入表情")
try:
file_path = cmds.fileDialog2(
fileFilter="Expression Files (*.exp);;JSON Files (*.json);;All Files (*.*)",
dialogStyle=2,
fileMode=1
)
if file_path:
# 这里实现导入表情的功能
print(f"将从{file_path[0]}导入表情")
except Exception as e:
print(f"导入表情时出错: {e}")
return True
def control_panel_search():
"""
控制面板搜索
"""
print("控制面板搜索")
# 这里实现控制面板搜索的功能
return True
def select_related_keys():
"""
选择相关键值
"""
print("选择相关键值")
# 这里实现选择相关键值的功能
return True
def import_map_expression():
"""
导入表情映射
"""
print("导入表情映射")
try:
file_path = cmds.fileDialog2(
fileFilter="Map Files (*.map);;JSON Files (*.json);;All Files (*.*)",
dialogStyle=2,
fileMode=1
)
if file_path:
# 这里实现导入表情映射的功能
print(f"将从{file_path[0]}导入表情映射")
except Exception as e:
print(f"导入表情映射时出错: {e}")
return True
# 保留原来的函数作为兼容性考虑
def behaviour_temp_utils_function():
"""
Placeholder function for behaviour module
This function will be replaced with actual functionality in future updates
"""
print("Behaviour module temporary function called")
print("Behaviour module temporary function called")
return True

View File

@@ -3,21 +3,278 @@
"""
Definition function module
定义统工具函数模块 - 提供定义统UI所需的所有功能函数
定义统工具函数模块 - 提供定义统UI所需的所有功能函数
"""
#===================================== IMPORT MODULES =====================================
import maya.cmds as cmds
import pymel.core as pm
import maya.mel as mel
from maya import OpenMayaUI as omui
from Qt import QtWidgets, QtCore, QtGui
from Qt.QtCompat import wrapInstance
import webbrowser
import subprocess
import importlib
import traceback
import sys
import os
# 导入配置
import config
from scripts.ui import localization
LANG = localization.LANG
#========================================== FUNCTIONS ========================================
# 左侧面板功能
# LODs相关功能
def lod_selected(item):
"""
LOD项目被选中
"""
print(f"LOD项目被选中: {item.text()}")
# 这里实现LOD项目选中的功能
return True
def update_lod_selection():
"""
更新LOD选择
"""
print("更新LOD选择")
# 这里实现更新LOD选择的功能
return True
def define_lod_relations():
"""
定义LOD关联
"""
print("定义LOD关联")
# 这里实现定义LOD关联的功能
return True
# Meshes相关功能
def mesh_selected(item):
"""
网格项目被选中
"""
print(f"网格项目被选中: {item.text()}")
# 这里实现网格项目选中的功能
return True
def update_mesh_selection():
"""
更新网格选择
"""
print("更新网格选择")
# 这里实现更新网格选择的功能
return True
def create_geometry():
"""
创建几何体
"""
print("创建几何体")
# 这里实现创建几何体的功能
return True
# 右侧面板功能
# Joints相关功能
def joint_selected(item):
"""
关节项目被选中
"""
print(f"关节项目被选中: {item.text()}")
# 这里实现关节项目选中的功能
return True
def update_joint_selection():
"""
更新关节选择
"""
print("更新关节选择")
# 这里实现更新关节选择的功能
return True
# BlendShapes相关功能
def blendshape_selected(item):
"""
形状混合项目被选中
"""
print(f"形状混合项目被选中: {item.text()}")
# 这里实现形状混合项目选中的功能
return True
def update_blendshape_selection():
"""
更新形状混合选择
"""
print("更新形状混合选择")
# 这里实现更新形状混合选择的功能
return True
# AnimatedMap相关功能
def animatedmap_selected(item):
"""
动画贴图项目被选中
"""
print(f"动画贴图项目被选中: {item.text()}")
# 这里实现动画贴图项目选中的功能
return True
def update_animatedmap_selection():
"""
更新动画贴图选择
"""
print("更新动画贴图选择")
# 这里实现更新动画贴图选择的功能
return True
# 底部工具面板功能
# 导入部分功能
def import_joint_system():
"""
导入关节系统
"""
print("导入关节系统")
try:
file_path = cmds.fileDialog2(
fileFilter="Maya Files (*.ma *.mb);;FBX Files (*.fbx);;All Files (*.*)",
dialogStyle=2,
fileMode=1
)
if file_path:
# 这里实现导入关节系统的功能
print(f"将从{file_path[0]}导入关节系统")
except Exception as e:
print(f"导入关节系统时出错: {e}")
return True
def import_geometry():
"""
导入几何体
"""
print("导入几何体")
try:
file_path = cmds.fileDialog2(
fileFilter="Maya Files (*.ma *.mb);;FBX Files (*.fbx);;OBJ Files (*.obj);;All Files (*.*)",
dialogStyle=2,
fileMode=1
)
if file_path:
# 这里实现导入几何体的功能
print(f"将从{file_path[0]}导入几何体")
except Exception as e:
print(f"导入几何体时出错: {e}")
return True
def import_blendshape_target():
"""
导入形状混合目标
"""
print("导入形状混合目标")
try:
file_path = cmds.fileDialog2(
fileFilter="Maya Files (*.ma *.mb);;FBX Files (*.fbx);;OBJ Files (*.obj);;All Files (*.*)",
dialogStyle=2,
fileMode=1
)
if file_path:
# 这里实现导入形状混合目标的功能
print(f"将从{file_path[0]}导入形状混合目标")
except Exception as e:
print(f"导入形状混合目标时出错: {e}")
return True
def import_animated_map():
"""
导入动画贴图
"""
print("导入动画贴图")
try:
file_path = cmds.fileDialog2(
fileFilter="Image Files (*.jpg *.jpeg *.png *.tif *.tiff);;All Files (*.*)",
dialogStyle=2,
fileMode=1
)
if file_path:
# 这里实现导入动画贴图的功能
print(f"将从{file_path[0]}导入动画贴图")
except Exception as e:
print(f"导入动画贴图时出错: {e}")
return True
# 创建部分功能
def create_neutral_pose():
"""
创建中性姿势
"""
print("创建中性姿势")
# 这里实现创建中性姿势的功能
return True
def bind_geometry():
"""
绑定几何体
"""
print("绑定几何体")
# 这里实现绑定几何体的功能
return True
def take_pose():
"""
取消姿势
"""
print("取消姿势")
# 这里实现取消姿势的功能
return True
def unbind_skin():
"""
取消蒙皮
"""
print("取消蒙皮")
# 这里实现取消蒙皮的功能
return True
# 工具部分功能
def reposition_all_joints():
"""
重新定位所有关节
"""
print("重新定位所有关节")
# 这里实现重新定位所有关节的功能
return True
def reposition_selected_joints():
"""
重新定位选定关节
"""
print("重新定位选定关节")
# 这里实现重新定位选定关节的功能
return True
def reposition_all_head_joints():
"""
重新定位所有头部关节
"""
print("重新定位所有头部关节")
# 这里实现重新定位所有头部关节的功能
return True
def quick_preset():
"""
快速预设
"""
print("快速预设")
# 这里实现快速预设的功能
return True
# 保留原来的函数作为兼容性考虑
def definition_temp_utils_function():
"""
Placeholder function for definition module
This function will be replaced with actual functionality in future updates
"""
print("Definition module temporary function called")
print("Definition module temporary function called")
return True

View File

@@ -3,17 +3,362 @@
"""
Geometry function module
几何模型工具函数模块 - 提供几何模型UI所需的所有功能函数
"""
#===================================== IMPORT MODULES =====================================
import maya.cmds as cmds
import pymel.core as pm
import maya.mel as mel
from maya import OpenMayaUI as omui
from Qt import QtWidgets, QtCore, QtGui
from Qt.QtCompat import wrapInstance
import webbrowser
import subprocess
import importlib
import traceback
import sys
import os
# 导入配置
import config
from scripts.ui import localization
LANG = localization.LANG
#========================================== FUNCTIONS ========================================
# 左侧面板功能
# LOD相关功能
def lod_selected(item):
"""
LOD项目被选中
"""
print(f"LOD项目被选中: {item.text()}")
# 这里实现LOD项目选中的功能
return True
def update_lod_selection():
"""
更新LOD选择
"""
print("更新LOD选择")
# 这里实现更新LOD选择的功能
return True
def add_lod():
"""
添加LOD
"""
print("添加LOD")
# 这里实现添加LOD的功能
return True
def remove_lod():
"""
移除LOD
"""
print("移除LOD")
# 这里实现移除LOD的功能
return True
def duplicate_lod():
"""
复制LOD
"""
print("复制LOD")
# 这里实现复制LOD的功能
return True
# 模型相关功能
def model_selected(item):
"""
模型项目被选中
"""
print(f"模型项目被选中: {item.text()}")
# 这里实现模型项目选中的功能
return True
def update_model_selection():
"""
更新模型选择
"""
print("更新模型选择")
# 这里实现更新模型选择的功能
return True
def add_model():
"""
添加模型
"""
print("添加模型")
# 这里实现添加模型的功能
return True
def remove_model():
"""
移除模型
"""
print("移除模型")
# 这里实现移除模型的功能
return True
def duplicate_model():
"""
复制模型
"""
print("复制模型")
# 这里实现复制模型的功能
return True
# 右侧面板功能
# 模型属性相关功能
def update_model_name(text):
"""
更新模型名称
"""
print(f"更新模型名称: {text}")
# 这里实现更新模型名称的功能
return True
def update_model_type(index):
"""
更新模型类型
"""
print(f"更新模型类型: {index}")
# 这里实现更新模型类型的功能
return True
def toggle_model_visibility(state):
"""
切换模型可见性
"""
print(f"切换模型可见性: {state}")
# 这里实现切换模型可见性的功能
return True
def apply_properties():
"""
应用属性
"""
print("应用属性")
# 这里实现应用属性的功能
return True
def reset_properties():
"""
重置属性
"""
print("重置属性")
# 这里实现重置属性的功能
return True
# 模型工具相关功能
def standardize_names():
"""
标准化命名
"""
print("标准化命名")
# 这里实现标准化命名的功能
return True
def auto_group():
"""
自动分组
"""
print("自动分组")
# 这里实现自动分组的功能
return True
def generate_accessories():
"""
生成配件
"""
print("生成配件")
# 这里实现生成配件的功能
return True
def fix_seams():
"""
修复接缝
"""
print("修复接缝")
# 这里实现修复接缝的功能
return True
def fix_vertex_order():
"""
修复点序
"""
print("修复点序")
# 这里实现修复点序的功能
return True
# 底部工具面板功能
# 导入相关功能
def import_model():
"""
导入模型
"""
print("导入模型")
try:
file_path = cmds.fileDialog2(
fileFilter="Maya Files (*.ma *.mb);;All Files (*.*)",
dialogStyle=2,
fileMode=1
)
if file_path:
# 这里实现导入模型的功能
print(f"将从{file_path[0]}导入模型")
except Exception as e:
print(f"导入模型时出错: {e}")
return True
def import_fbx():
"""
导入FBX
"""
print("导入FBX")
try:
file_path = cmds.fileDialog2(
fileFilter="FBX Files (*.fbx);;All Files (*.*)",
dialogStyle=2,
fileMode=1
)
if file_path:
# 这里实现导入FBX的功能
print(f"将从{file_path[0]}导入FBX")
mel.eval(f'FBXImport -file "{file_path[0]}";')
except Exception as e:
print(f"导入FBX时出错: {e}")
return True
def import_obj():
"""
导入OBJ
"""
print("导入OBJ")
try:
file_path = cmds.fileDialog2(
fileFilter="OBJ Files (*.obj);;All Files (*.*)",
dialogStyle=2,
fileMode=1
)
if file_path:
# 这里实现导入OBJ的功能
print(f"将从{file_path[0]}导入OBJ")
cmds.file(file_path[0], i=True, type="OBJ", ignoreVersion=True, options="mo=1")
except Exception as e:
print(f"导入OBJ时出错: {e}")
return True
# 导出相关功能
def export_model():
"""
导出模型
"""
print("导出模型")
try:
file_path = cmds.fileDialog2(
fileFilter="Maya Files (*.ma *.mb);;All Files (*.*)",
dialogStyle=2,
fileMode=2
)
if file_path:
# 这里实现导出模型的功能
print(f"将模型导出到{file_path[0]}")
except Exception as e:
print(f"导出模型时出错: {e}")
return True
def export_fbx():
"""
导出 FBX
"""
print("导出 FBX")
try:
file_path = cmds.fileDialog2(
fileFilter="FBX Files (*.fbx);;All Files (*.*)",
dialogStyle=2,
fileMode=2
)
if file_path:
# 这里实现导出 FBX的功能
print(f"将模型导出到{file_path[0]}")
mel.eval('FBXExportSmoothingGroups -v true;')
mel.eval('FBXExportHardEdges -v false;')
mel.eval('FBXExportTangents -v false;')
mel.eval('FBXExportSmoothMesh -v true;')
mel.eval('FBXExportInstances -v false;')
mel.eval('FBXExportReferencedContainersContent -v false;')
mel.eval('FBXExportBakeComplexAnimation -v false;')
mel.eval('FBXExportUseSceneName -v false;')
mel.eval('FBXExportQuaternion -v euler;')
mel.eval('FBXExportShapes -v true;')
mel.eval('FBXExportSkins -v true;')
mel.eval('FBXExportConstraints -v false;')
mel.eval('FBXExportCameras -v false;')
mel.eval('FBXExportLights -v false;')
mel.eval('FBXExportEmbeddedTextures -v false;')
mel.eval('FBXExportInputConnections -v false;')
mel.eval('FBXExportUpAxis y;')
mel.eval(f'FBXExport -f "{file_path[0]}" -s;')
except Exception as e:
print(f"导出 FBX时出错: {e}")
return True
def export_obj():
"""
导出 OBJ
"""
print("导出 OBJ")
try:
file_path = cmds.fileDialog2(
fileFilter="OBJ Files (*.obj);;All Files (*.*)",
dialogStyle=2,
fileMode=2
)
if file_path:
# 这里实现导出 OBJ的功能
print(f"将模型导出到{file_path[0]}")
cmds.file(file_path[0], force=True, options="groups=1;ptgroups=1;materials=1;smoothing=1;normals=1", type="OBJexport", pr=True, exportSelected=True)
except Exception as e:
print(f"导出 OBJ时出错: {e}")
return True
# 工具相关功能
def check_model():
"""
检查模型
"""
print("检查模型")
# 这里实现检查模型的功能
return True
def optimize_model():
"""
优化模型
"""
print("优化模型")
# 这里实现优化模型的功能
return True
def clean_model():
"""
清理模型
"""
print("清理模型")
# 这里实现清理模型的功能
return True
def uv_tools():
"""
UV工具
"""
print("UV工具")
# 这里实现UV工具的功能
return True
# 保留原来的函数作为兼容性考虑
def geometry_temp_utils_function():
"""
Placeholder function for geometry module

View File

@@ -4,12 +4,233 @@
#===================================== IMPORT MODULES =====================================
import maya.cmds as cmds
import pymel.core as pm
import maya.mel as mel
from maya import OpenMayaUI as omui
from Qt import QtWidgets, QtCore, QtGui
from Qt.QtCompat import wrapInstance
import webbrowser
import subprocess
import importlib
import traceback
import sys
import os
# 导入配置
import config
from scripts.ui import localization
LANG = localization.LANG
#========================================== FUNCTIONS ========================================
# 第一行按钮功能
def new_file():
"""
创建新文件
"""
print("创建新文件")
try:
if cmds.file(q=True, modified=True):
result = cmds.confirmDialog(
title=LANG.get("confirm_save", "确认保存"),
message=LANG.get("save_changes", "是否保存更改?"),
button=[LANG.get("save", "保存"), LANG.get("dont_save", "不保存"), LANG.get("cancel", "取消")],
defaultButton=LANG.get("save", "保存"),
cancelButton=LANG.get("cancel", "取消"),
dismissString=LANG.get("cancel", "取消")
)
if result == LANG.get("save", "保存"):
cmds.file(save=True)
elif result == LANG.get("cancel", "取消"):
return
cmds.file(new=True, force=True)
print("新文件已创建")
except Exception as e:
print(f"创建新文件时出错: {e}")
return True
def open_file():
"""
打开文件
"""
print("打开文件")
try:
file_path = cmds.fileDialog2(
fileFilter="Maya Files (*.ma *.mb);;All Files (*.*)",
dialogStyle=2,
fileMode=1
)
if file_path:
cmds.file(file_path[0], open=True, force=True)
print(f"文件已打开: {file_path[0]}")
except Exception as e:
print(f"打开文件时出错: {e}")
return True
def link_file():
"""
链接文件
"""
print("链接文件")
try:
file_path = cmds.fileDialog2(
fileFilter="Maya Files (*.ma *.mb);;All Files (*.*)",
dialogStyle=2,
fileMode=1
)
if file_path:
# 这里实现链接文件的功能
print(f"文件已链接: {file_path[0]}")
except Exception as e:
print(f"链接文件时出错: {e}")
return True
def unlink_file():
"""
取消链接
"""
print("取消链接")
# 这里实现取消链接的功能
return True
def import_file():
"""
导入文件
"""
print("导入文件")
try:
file_path = cmds.fileDialog2(
fileFilter="Maya Files (*.ma *.mb);;FBX Files (*.fbx);;OBJ Files (*.obj);;All Files (*.*)",
dialogStyle=2,
fileMode=1
)
if file_path:
# 根据文件扩展名选择导入方法
file_ext = os.path.splitext(file_path[0])[1].lower()
if file_ext == ".fbx":
cmds.file(file_path[0], i=True, type="FBX")
elif file_ext == ".obj":
cmds.file(file_path[0], i=True, type="OBJ")
else: # .ma or .mb
cmds.file(file_path[0], i=True)
print(f"文件已导入: {file_path[0]}")
except Exception as e:
print(f"导入文件时出错: {e}")
return True
def export_file():
"""
导出文件
"""
print("导出文件")
try:
file_path = cmds.fileDialog2(
fileFilter="Maya Files (*.ma *.mb);;FBX Files (*.fbx);;OBJ Files (*.obj);;All Files (*.*)",
dialogStyle=2,
fileMode=0
)
if file_path:
# 根据文件扩展名选择导出方法
file_ext = os.path.splitext(file_path[0])[1].lower()
if file_ext == ".fbx":
cmds.file(file_path[0], force=True, options="v=0;", type="FBX export", pr=True, ea=True)
elif file_ext == ".obj":
cmds.file(file_path[0], force=True, options="groups=1;ptgroups=1;materials=1;smoothing=1;normals=1", type="OBJexport", pr=True, ea=True)
else: # .ma or .mb
cmds.file(file_path[0], force=True, type="mayaAscii" if file_ext == ".ma" else "mayaBinary", pr=True, ea=True)
print(f"文件已导出: {file_path[0]}")
except Exception as e:
print(f"导出文件时出错: {e}")
return True
def save_file():
"""
保存文件
"""
print("保存文件")
try:
current_file = cmds.file(q=True, sceneName=True)
if current_file:
cmds.file(save=True)
print(f"文件已保存: {current_file}")
else:
file_path = cmds.fileDialog2(
fileFilter="Maya ASCII (*.ma);;Maya Binary (*.mb)",
dialogStyle=2,
fileMode=0
)
if file_path:
file_ext = os.path.splitext(file_path[0])[1].lower()
file_type = "mayaAscii" if file_ext == ".ma" else "mayaBinary"
cmds.file(rename=file_path[0])
cmds.file(save=True, type=file_type)
print(f"文件已保存: {file_path[0]}")
except Exception as e:
print(f"保存文件时出错: {e}")
return True
def show_user_info():
"""
显示用户信息
"""
print("显示用户信息")
# 这里实现显示用户信息的功能
return True
def show_help():
"""
显示帮助信息
"""
print("显示帮助信息")
try:
if hasattr(config, "TOOL_HELP_URL") and config.TOOL_HELP_URL:
webbrowser.open(config.TOOL_HELP_URL)
else:
cmds.confirmDialog(
title=LANG.get("help", "帮助"),
message=LANG.get("help_not_available", "帮助文档暂不可用"),
button=[LANG.get("ok", "确定")],
defaultButton=LANG.get("ok", "确定")
)
except Exception as e:
print(f"显示帮助信息时出错: {e}")
return True
def show_settings():
"""
显示设置
"""
print("显示设置")
# 这里实现显示设置的功能
return True
def print_file():
"""
打印文件
"""
print("打印文件")
# 这里实现打印文件的功能
return True
# 第二行按钮功能
def change_view(view_type):
"""
切换视图类型
"""
print(f"切换到{view_type}视图")
# 这里实现切换视图的功能
return True
def model_changed(index):
"""
模型选择改变
"""
print(f"模型选择改变: {index}")
# 这里实现模型选择改变的功能
return True
# 保留原来的函数作为兼容性考虑
def toolbar_temp_utils_function():
"""
Placeholder function for toolbar module