1
0
forked from Rowland/EG

Merge remote-tracking branch 'origin/addRender' into main_ch_eg

# Conflicts:
#	scene/scene_manager.py
This commit is contained in:
陈横 2025-09-11 17:11:51 +08:00
commit 8f6bcc9b5a
4 changed files with 117 additions and 19 deletions

View File

@ -288,6 +288,7 @@ class CoreWorld(Panda3DWorld):
self.cam.setPos(0, -50, 20)
self.cam.lookAt(0, 0, 0)
self.camLens.setFov(80)
# self.cam.setTag("is_scene_element", "1")
print("✓ 相机设置完成")
def _setupLighting(self):
@ -321,6 +322,7 @@ class CoreWorld(Panda3DWorld):
self.ground.setP(-90)
self.ground.setZ(-0.1)
self.ground.setColor(0.8, 0.8, 0.8, 1)
# self.ground.setTag("is_scene_element", "1")
# 创建支持贴图的材质
mat = Material()

View File

@ -168,6 +168,7 @@ class SceneManager:
# 添加文件标签用于保存/加载
model.setTag("file", model_name)
model.setTag("is_model_root", "1")
model.setTag("is_scene_element", "1")
# 记录应用的处理选项
if apply_unit_conversion:
@ -914,12 +915,25 @@ class SceneManager:
print(f"场景文件不存在: {filename}")
return False
tree_widget = self._get_tree_widget()
# 清除当前场景
print("\n清除当前场景...")
for model in self.models:
if not model.isEmpty():
model.removeNode()
self.models.clear()
tree_widget.delete_item(model)
# 清除灯光
for light_node in self.Spotlight:
tree_widget.delete_item(light_node)
for light_node in self.Pointlight:
tree_widget.delete_item(light_node)
for terrain in self.world.terrain_manager.terrains:
tree_widget.delete_item(terrain)
# 清除tilesets
for tileset_info in self.tilesets:
tree_widget.delete_item(tileset_info['node'])
for light in self.Spotlight:
if not light.isEmpty():
@ -958,6 +972,8 @@ class SceneManager:
print("场景加载失败")
return False
# tree_widget.create_model_items(scene)
# 遍历场景中的所有模型节点
# 用于存储处理后的灯光节点,避免重复处理
processed_lights = []
# 用于存储处理后的GUI元素避免重复处理
@ -1211,6 +1227,7 @@ class SceneManager:
# 更新场景树
self.updateSceneTree()
# self._get_tree_widget().create_model_items(scene)
print(f"加载完成GUI元素数量: {len(self.world.gui_elements)}")
if len(self.world.gui_elements) > 0:

View File

@ -6,7 +6,7 @@
- 停靠窗口设置
- 事件连接和信号处理
"""
import os
import sys
from PyQt5.QtGui import QKeySequence, QIcon
@ -69,6 +69,20 @@ class MainWindow(QMainWindow):
int(screen.height() / 2 - self.height() / 2),
)
@staticmethod
def get_icon_path(icon_name):
"""获取图标文件的完整路径"""
# 假设 icons 文件夹在项目根目录下
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
icon_path = os.path.join(project_root, "icons", icon_name)
# 检查文件是否存在如果不存在则返回默认值或None
if not os.path.exists(icon_path):
print(f"警告: 图标文件不存在: {icon_path}")
return "" # 返回空字符串QIcon会处理空路径
return icon_path
def setupEmbeddedToolbar(self):
"""创建Unity风格的内嵌工具栏"""
# 创建工具栏容器
@ -109,8 +123,11 @@ class MainWindow(QMainWindow):
# 选择工具
self.selectTool = QToolButton()
self.selectTool.setIcon(QIcon("icons/select_tool.png")) # 使用图标资源
self.selectTool.setText('选择')
icon_path = self.get_icon_path("select_tool.png")
if icon_path and os.path.exists(icon_path):
self.selectTool.setIcon(QIcon(icon_path))
else:
self.selectTool.setText('选择') # 如果没有图标则显示文字
self.selectTool.setIconSize(QSize(16, 16))
self.selectTool.setCheckable(True)
self.selectTool.setToolTip("选择工具 (Q)")
@ -120,8 +137,11 @@ class MainWindow(QMainWindow):
# 移动工具
self.moveTool = QToolButton()
self.moveTool.setIcon(QIcon("icons/move_tool.png"))
self.moveTool.setText('移动')
icon_path = self.get_icon_path("move_tool.png")
if icon_path and os.path.exists(icon_path):
self.moveTool.setIcon(QIcon(icon_path))
else:
self.moveTool.setText('移动')
self.moveTool.setIconSize(QSize(16, 16))
self.moveTool.setCheckable(True)
self.moveTool.setToolTip("移动工具 (W)")
@ -131,8 +151,11 @@ class MainWindow(QMainWindow):
# 旋转工具
self.rotateTool = QToolButton()
self.rotateTool.setIcon(QIcon("icons/rotate_tool.png"))
self.rotateTool.setText('旋转')
icon_path = self.get_icon_path("rotate_tool.png")
if icon_path and os.path.exists(icon_path):
self.rotateTool.setIcon(QIcon(icon_path))
else:
self.rotateTool.setText('旋转')
self.rotateTool.setIconSize(QSize(16, 16))
self.rotateTool.setCheckable(True)
self.rotateTool.setToolTip("旋转工具 (E)")
@ -142,8 +165,11 @@ class MainWindow(QMainWindow):
# 缩放工具
self.scaleTool = QToolButton()
self.scaleTool.setIcon(QIcon("icons/scale_tool.png"))
self.scaleTool.setText('缩放')
icon_path = self.get_icon_path("scale_tool.png")
if icon_path and os.path.exists(icon_path):
self.scaleTool.setIcon(QIcon(icon_path))
else:
self.scaleTool.setText('缩放')
self.scaleTool.setIconSize(QSize(16, 16))
self.scaleTool.setCheckable(True)
self.scaleTool.setToolTip("缩放工具 (R)")

View File

@ -18,7 +18,7 @@ from PyQt5.QtCore import Qt, QUrl, QMimeData
from PyQt5.QtGui import QDrag, QPainter, QPixmap, QPen, QBrush
from PyQt5.sip import wrapinstance
from direct.showbase.ShowBaseGlobal import aspect2d
from panda3d.core import ModelRoot
from panda3d.core import ModelRoot, NodePath
from QPanda3D.QPanda3DWidget import QPanda3DWidget
from scene import util
@ -1474,12 +1474,9 @@ class CustomTreeWidget(QTreeWidget):
def showContextMenu(self, position):
"""显示右键菜单 - 复用主菜单的创建动作"""
if not self.selectedItems():
print("没有选中的项目,不显示右键菜单")
return
item = self.selectedItems()[0]
print(f"为项目 '{item.text(0)}' 显示右键菜单")
if self.selectedItems():
item = self.selectedItems()[0]
print(f"为项目 '{item.text(0)}' 显示右键菜单")
# 创建右键菜单
menu = QMenu(self)
@ -2187,6 +2184,62 @@ class CustomTreeWidget(QTreeWidget):
except Exception as e:
print(e)
def _findSceneRoot(self):
"""查找场景根节点"""
for i in range(self.topLevelItemCount()):
top_item = self.topLevelItem(i)
if top_item.data(0, Qt.UserRole + 1) == "SCENE_ROOT":
return top_item
return None
def create_model_items(self, model):
if not model:
print("传入的参数model为空")
return
# 创建根节点项
# root_item = QTreeWidgetItem(self)
# root_item.setText(0, model.getName() or "Unnamed Node")
# root_item.setText(1, model.node().getTypeName())
# root_item.setIcon(0, self.item_icons.get('model', self.item_icons['default']))
# 存储NodePath引用以便后续操作
# root_item.setData(0, Qt.UserRole, model)
root_item = self._findSceneRoot()
# 递归添加子节点
self._add_children_recursive(root_item, model)
return root_item
def _add_children_recursive(self, parent_item, node_path: NodePath):
"""递归添加子节点到树项"""
print(f'开始递归添加子节点')
# 获取所有子节点
children = node_path.getChildren()
for i in range(children.getNumPaths()):
child_node: NodePath = children.getPath(i)
# 过滤条件
if not child_node.hasTag("is_scene_element"):
print(f"不存在------------------------{child_node.hasTag('is_scene_element')}")
continue
print(f"存在------------------------{child_node.getName()}")
# 创建子项
child_item = QTreeWidgetItem(parent_item)
child_item.setText(0, child_node.getName() or f"Child_{i}")
# 存储NodePath引用
child_item.setData(0, Qt.UserRole, child_node)
# 添加额外信息(可选)
# self._add_node_info(child_item, child_node)
# 递归处理子节点的子节点
if child_node.getNumChildren() > 0:
self._add_children_recursive(child_item, child_node)
# ==================== 辅助方法 ====================
def _findSceneRoot(self):
"""查找场景根节点"""