|
|
|
@@ -292,16 +292,15 @@ class GeometryUI(ui_utils.BaseUI):
|
|
|
|
|
# 将标签页添加到标签页控件
|
|
|
|
|
self.controls["tab_widget"].addTab(tab, lod_name)
|
|
|
|
|
|
|
|
|
|
# 添加垃圾桶按钮到标签页控件右侧
|
|
|
|
|
trash_icon = QtGui.QIcon(os.path.join(ICONS_PATH, "delete.png"))
|
|
|
|
|
trash_button = QtWidgets.QPushButton()
|
|
|
|
|
trash_button.setIcon(trash_icon)
|
|
|
|
|
trash_button.setIconSize(QtCore.QSize(28, 28))
|
|
|
|
|
trash_button.setFixedSize(28, 28)
|
|
|
|
|
trash_button.setToolTip(LANG.get("delete", "删除"))
|
|
|
|
|
trash_button.setStyleSheet("QPushButton { border: none; background-color: transparent; }")
|
|
|
|
|
self.controls["tab_widget"].setCornerWidget(trash_button, QtCore.Qt.TopRightCorner)
|
|
|
|
|
self.buttons["delete"] = trash_button
|
|
|
|
|
# 创建清理按钮
|
|
|
|
|
self.buttons["clear"] = QtWidgets.QPushButton(LANG.get("clear", "清理"))
|
|
|
|
|
self.buttons["clear"].setObjectName("clearButton")
|
|
|
|
|
self.buttons["clear"].setIcon(ui_utils.load_icon("delete.png"))
|
|
|
|
|
self.buttons["clear"].setIconSize(QtCore.QSize(16, 16))
|
|
|
|
|
self.buttons["clear"].setFixedSize(70, 20) # 减小按钮高度
|
|
|
|
|
self.buttons["clear"].setToolTip(LANG.get("clear_all_models", "清理所有模型"))
|
|
|
|
|
self.buttons["clear"].setStyleSheet("margin-right: 5px;")
|
|
|
|
|
self.buttons["clear"].setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
|
|
|
|
|
|
|
|
|
def create_bottom_buttons(self):
|
|
|
|
|
"""
|
|
|
|
@@ -329,55 +328,138 @@ class GeometryUI(ui_utils.BaseUI):
|
|
|
|
|
model_tools_layout.setSpacing(5)
|
|
|
|
|
|
|
|
|
|
# 第一行放置拓扑结构、选择LOD和创建LOD按钮
|
|
|
|
|
# 拓扑结构标签和下拉框
|
|
|
|
|
topology_label = QtWidgets.QLabel(LANG.get("topology_structure", "拓扑结构") + ":")
|
|
|
|
|
model_tools_layout.addWidget(topology_label, 0, 0)
|
|
|
|
|
# 创建三等分的水平布局
|
|
|
|
|
self.layouts["top_row_layout"] = QtWidgets.QHBoxLayout()
|
|
|
|
|
self.layouts["top_row_layout"].setContentsMargins(0, 0, 0, 0)
|
|
|
|
|
self.layouts["top_row_layout"].setSpacing(10) # 增加间距
|
|
|
|
|
|
|
|
|
|
# 创建三个容器小部件,每个占据一个均等部分
|
|
|
|
|
# 1. 拓扑结构部分
|
|
|
|
|
topology_container = QtWidgets.QWidget()
|
|
|
|
|
topology_container.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
|
|
|
|
|
topology_container_layout = QtWidgets.QHBoxLayout(topology_container)
|
|
|
|
|
topology_container_layout.setContentsMargins(5, 5, 5, 5)
|
|
|
|
|
|
|
|
|
|
topology_label = QtWidgets.QLabel(LANG.get("topology_structure", "拓扑结构") + ":")
|
|
|
|
|
self.controls["topology_combo"] = QtWidgets.QComboBox()
|
|
|
|
|
self.controls["topology_combo"].setObjectName("topologyCombo")
|
|
|
|
|
self.controls["topology_combo"].addItem("MetaHuman")
|
|
|
|
|
self.controls["topology_combo"].setMinimumWidth(100)
|
|
|
|
|
model_tools_layout.addWidget(self.controls["topology_combo"], 0, 1)
|
|
|
|
|
|
|
|
|
|
# 选择LOD标签和下拉框
|
|
|
|
|
topology_container_layout.addWidget(topology_label)
|
|
|
|
|
topology_container_layout.addWidget(self.controls["topology_combo"], 1) # 下拉框占据剩余空间
|
|
|
|
|
|
|
|
|
|
# 2. 选择LOD部分
|
|
|
|
|
lod_container = QtWidgets.QWidget()
|
|
|
|
|
lod_container.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
|
|
|
|
|
lod_container_layout = QtWidgets.QHBoxLayout(lod_container)
|
|
|
|
|
lod_container_layout.setContentsMargins(5, 5, 5, 5)
|
|
|
|
|
|
|
|
|
|
lod_label = QtWidgets.QLabel(LANG.get("select_lod", "选择LOD") + ":")
|
|
|
|
|
model_tools_layout.addWidget(lod_label, 0, 2)
|
|
|
|
|
|
|
|
|
|
self.controls["lod_combo"] = QtWidgets.QComboBox()
|
|
|
|
|
self.controls["lod_combo"].setObjectName("lodCombo")
|
|
|
|
|
self.controls["lod_combo"].addItem(LANG.get("all", "全部"))
|
|
|
|
|
for i in range(8): # LOD0~LOD7
|
|
|
|
|
self.controls["lod_combo"].addItem(f"LOD{i}")
|
|
|
|
|
self.controls["lod_combo"].setMinimumWidth(80)
|
|
|
|
|
model_tools_layout.addWidget(self.controls["lod_combo"], 0, 3)
|
|
|
|
|
|
|
|
|
|
# 创建LOD按钮
|
|
|
|
|
self.buttons["create_lod"] = QtWidgets.QPushButton()
|
|
|
|
|
self.buttons["create_lod"].setIcon(QtGui.QIcon(os.path.join(ICONS_PATH, "create_lod.png")))
|
|
|
|
|
self.buttons["create_lod"].setText(LANG.get("create_lod", "创建LOD"))
|
|
|
|
|
lod_container_layout.addWidget(lod_label)
|
|
|
|
|
lod_container_layout.addWidget(self.controls["lod_combo"], 1) # 下拉框占据剩余空间
|
|
|
|
|
|
|
|
|
|
# 3. 创建LOD按钮部分
|
|
|
|
|
button_container = QtWidgets.QWidget()
|
|
|
|
|
button_container.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
|
|
|
|
|
button_container_layout = QtWidgets.QHBoxLayout(button_container)
|
|
|
|
|
button_container_layout.setContentsMargins(5, 5, 5, 5)
|
|
|
|
|
|
|
|
|
|
self.buttons["create_lod"] = QtWidgets.QPushButton(LANG.get("create_lod", "创建LOD"))
|
|
|
|
|
self.buttons["create_lod"].setObjectName("createLodButton")
|
|
|
|
|
self.buttons["create_lod"].setIcon(ui_utils.load_icon("create_lod.png"))
|
|
|
|
|
self.buttons["create_lod"].setMinimumHeight(30)
|
|
|
|
|
model_tools_layout.addWidget(self.buttons["create_lod"], 0, 4)
|
|
|
|
|
|
|
|
|
|
# 设置按钮尺寸策略为水平扩展,使其宽度撑满容器
|
|
|
|
|
self.buttons["create_lod"].setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
|
|
|
|
|
|
|
|
|
|
button_container_layout.addWidget(self.buttons["create_lod"])
|
|
|
|
|
|
|
|
|
|
# 将三个容器添加到水平布局,均等分配空间
|
|
|
|
|
self.layouts["top_row_layout"].addWidget(topology_container, 1)
|
|
|
|
|
self.layouts["top_row_layout"].addWidget(lod_container, 1)
|
|
|
|
|
self.layouts["top_row_layout"].addWidget(button_container, 1)
|
|
|
|
|
|
|
|
|
|
# 将水平布局添加到模型工具布局
|
|
|
|
|
model_tools_layout.addLayout(self.layouts["top_row_layout"], 0, 0, 1, 5)
|
|
|
|
|
|
|
|
|
|
# 创建模型工具按钮
|
|
|
|
|
tool_buttons = [
|
|
|
|
|
{"name": "separate_model", "text": LANG.get("separate_model", "模型分离"), "icon": "polySplitVertex.png ", "row": 1, "col": 0, "colspan": 2},
|
|
|
|
|
{"name": "generate_face_components", "text": LANG.get("generate_face_components", "生成面部配件"), "icon": "meshes.png", "row": 1, "col": 2, "colspan": 3},
|
|
|
|
|
{"name": "fix_normals", "text": LANG.get("fix_normals", "修复法线"), "icon": "fix_normals.png", "row": 2, "col": 0, "colspan": 2},
|
|
|
|
|
{"name": "fix_vertex_order", "text": LANG.get("fix_vertex_order", "修复点序"), "icon": "normalConstraint.png ", "row": 2, "col": 2, "colspan": 3},
|
|
|
|
|
{"name": "fix_seams", "text": LANG.get("fix_seams", "修复接缝"), "icon": "polyChipOff.png ", "row": 3, "col": 0, "colspan": 2},
|
|
|
|
|
{"name": "optimize_scene", "text": LANG.get("optimize_scene", "优化场景"), "icon": "singlePerspLayout.png ", "row": 3, "col": 2, "colspan": 3}
|
|
|
|
|
]
|
|
|
|
|
# 设置按钮的尺寸策略,使其均等撑满一行
|
|
|
|
|
size_policy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
|
|
|
|
|
|
|
|
|
|
# 创建并添加按钮到布局
|
|
|
|
|
for btn_info in tool_buttons:
|
|
|
|
|
button = QtWidgets.QPushButton()
|
|
|
|
|
button.setText(btn_info["text"])
|
|
|
|
|
button.setIcon(QtGui.QIcon(os.path.join(ICONS_PATH, btn_info["icon"])))
|
|
|
|
|
button.setObjectName(f"{btn_info['name']}Button")
|
|
|
|
|
button.setMinimumHeight(30)
|
|
|
|
|
model_tools_layout.addWidget(button, btn_info["row"], btn_info["col"], 1, btn_info["colspan"])
|
|
|
|
|
self.buttons[btn_info["name"]] = button
|
|
|
|
|
# 创建每行按钮的布局
|
|
|
|
|
self.layouts["buttons_row1_layout"] = QtWidgets.QHBoxLayout()
|
|
|
|
|
self.layouts["buttons_row1_layout"].setContentsMargins(0, 0, 0, 0)
|
|
|
|
|
self.layouts["buttons_row1_layout"].setSpacing(10)
|
|
|
|
|
|
|
|
|
|
self.layouts["buttons_row2_layout"] = QtWidgets.QHBoxLayout()
|
|
|
|
|
self.layouts["buttons_row2_layout"].setContentsMargins(0, 0, 0, 0)
|
|
|
|
|
self.layouts["buttons_row2_layout"].setSpacing(10)
|
|
|
|
|
|
|
|
|
|
self.layouts["buttons_row3_layout"] = QtWidgets.QHBoxLayout()
|
|
|
|
|
self.layouts["buttons_row3_layout"].setContentsMargins(0, 0, 0, 0)
|
|
|
|
|
self.layouts["buttons_row3_layout"].setSpacing(10)
|
|
|
|
|
|
|
|
|
|
# 第一行按钮
|
|
|
|
|
self.buttons["separate_model"] = QtWidgets.QPushButton(LANG.get("separate_model", "模型分离"))
|
|
|
|
|
self.buttons["separate_model"].setObjectName("separateModelButton")
|
|
|
|
|
self.buttons["separate_model"].setIcon(ui_utils.load_icon("polySplitVertex.png"))
|
|
|
|
|
self.buttons["separate_model"].setMinimumHeight(30)
|
|
|
|
|
self.buttons["separate_model"].setSizePolicy(size_policy)
|
|
|
|
|
|
|
|
|
|
self.buttons["generate_face_components"] = QtWidgets.QPushButton(LANG.get("generate_face_components", "生成面部配件"))
|
|
|
|
|
self.buttons["generate_face_components"].setObjectName("generateFaceComponentsButton")
|
|
|
|
|
self.buttons["generate_face_components"].setIcon(ui_utils.load_icon("meshes.png"))
|
|
|
|
|
self.buttons["generate_face_components"].setMinimumHeight(30)
|
|
|
|
|
self.buttons["generate_face_components"].setSizePolicy(size_policy)
|
|
|
|
|
|
|
|
|
|
# 添加第一行按钮到布局
|
|
|
|
|
self.layouts["buttons_row1_layout"].addWidget(self.buttons["separate_model"])
|
|
|
|
|
self.layouts["buttons_row1_layout"].addWidget(self.buttons["generate_face_components"])
|
|
|
|
|
|
|
|
|
|
# 第二行按钮
|
|
|
|
|
self.buttons["fix_normals"] = QtWidgets.QPushButton(LANG.get("fix_normals", "修复法线"))
|
|
|
|
|
self.buttons["fix_normals"].setObjectName("fixNormalsButton")
|
|
|
|
|
self.buttons["fix_normals"].setIcon(ui_utils.load_icon("repair_normals.png"))
|
|
|
|
|
self.buttons["fix_normals"].setMinimumHeight(30)
|
|
|
|
|
self.buttons["fix_normals"].setSizePolicy(size_policy)
|
|
|
|
|
|
|
|
|
|
self.buttons["fix_vertex_order"] = QtWidgets.QPushButton(LANG.get("fix_vertex_order", "修复点序"))
|
|
|
|
|
self.buttons["fix_vertex_order"].setObjectName("fixVertexOrderButton")
|
|
|
|
|
self.buttons["fix_vertex_order"].setIcon(ui_utils.load_icon("repair_vertex_order.png"))
|
|
|
|
|
self.buttons["fix_vertex_order"].setMinimumHeight(30)
|
|
|
|
|
self.buttons["fix_vertex_order"].setSizePolicy(size_policy)
|
|
|
|
|
|
|
|
|
|
# 添加第二行按钮到布局
|
|
|
|
|
self.layouts["buttons_row2_layout"].addWidget(self.buttons["fix_normals"])
|
|
|
|
|
self.layouts["buttons_row2_layout"].addWidget(self.buttons["fix_vertex_order"])
|
|
|
|
|
|
|
|
|
|
# 第三行按钮
|
|
|
|
|
self.buttons["fix_seams"] = QtWidgets.QPushButton(LANG.get("fix_seams", "修复接缝"))
|
|
|
|
|
self.buttons["fix_seams"].setObjectName("fixSeamsButton")
|
|
|
|
|
self.buttons["fix_seams"].setIcon(ui_utils.load_icon("polyChipOff.png"))
|
|
|
|
|
self.buttons["fix_seams"].setMinimumHeight(30)
|
|
|
|
|
self.buttons["fix_seams"].setSizePolicy(size_policy)
|
|
|
|
|
|
|
|
|
|
self.buttons["optimize_scene"] = QtWidgets.QPushButton(LANG.get("optimize_scene", "优化场景"))
|
|
|
|
|
self.buttons["optimize_scene"].setObjectName("optimizeSceneButton")
|
|
|
|
|
self.buttons["optimize_scene"].setIcon(ui_utils.load_icon("singlePerspLayout.png"))
|
|
|
|
|
self.buttons["optimize_scene"].setMinimumHeight(30)
|
|
|
|
|
self.buttons["optimize_scene"].setSizePolicy(size_policy)
|
|
|
|
|
|
|
|
|
|
# 添加第三行按钮到布局
|
|
|
|
|
self.layouts["buttons_row3_layout"].addWidget(self.buttons["fix_seams"])
|
|
|
|
|
self.layouts["buttons_row3_layout"].addWidget(self.buttons["optimize_scene"])
|
|
|
|
|
|
|
|
|
|
# 将按钮行添加到模型工具布局
|
|
|
|
|
model_tools_layout.addLayout(self.layouts["buttons_row1_layout"], 1, 0, 1, 5)
|
|
|
|
|
model_tools_layout.addLayout(self.layouts["buttons_row2_layout"], 2, 0, 1, 5)
|
|
|
|
|
model_tools_layout.addLayout(self.layouts["buttons_row3_layout"], 3, 0, 1, 5)
|
|
|
|
|
|
|
|
|
|
# 添加布局到底部区域
|
|
|
|
|
bottom_layout.addWidget(model_tools_group)
|
|
|
|
@@ -396,6 +478,10 @@ class GeometryUI(ui_utils.BaseUI):
|
|
|
|
|
# 添加标题标签
|
|
|
|
|
self.layouts["main_layout"].addWidget(self.controls["title_label"])
|
|
|
|
|
|
|
|
|
|
# 将清理按钮直接添加到标签页控件的右上角
|
|
|
|
|
# 设置标签页控件的角落部件
|
|
|
|
|
self.controls["tab_widget"].setCornerWidget(self.buttons["clear"], QtCore.Qt.TopRightCorner)
|
|
|
|
|
|
|
|
|
|
# 添加标签页控件到主布局
|
|
|
|
|
self.layouts["main_layout"].addWidget(self.controls["tab_widget"])
|
|
|
|
|
|
|
|
|
@@ -439,8 +525,8 @@ class GeometryUI(ui_utils.BaseUI):
|
|
|
|
|
create_load_callback(lod_name, part)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# 连接垃圾桶按钮
|
|
|
|
|
self.buttons["delete"].clicked.connect(utils_geometry.delete)
|
|
|
|
|
# 连接清理按钮
|
|
|
|
|
self.buttons["clear"].clicked.connect(utils_geometry.clean)
|
|
|
|
|
|
|
|
|
|
# 连接拓扑结构下拉框
|
|
|
|
|
self.controls["topology_combo"].currentIndexChanged.connect(utils_geometry.update_topology)
|
|
|
|
|