EG/main.py
2025-10-27 14:59:34 +08:00

818 lines
30 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

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

import warnings
from core.Command_System import CommandManager
from core.InfoPanelManager import InfoPanelManager
from core.patrol_system import PatrolSystem
from demo.video_integration import VideoManager
warnings.filterwarnings("ignore", category=DeprecationWarning)
import sys
import builtins
from PyQt5.QtWidgets import (QApplication, QMainWindow, QMenuBar, QMenu, QAction,
QDockWidget, QTreeWidget, QListWidget, QWidget, QVBoxLayout, QTreeWidgetItem,
QLabel, QLineEdit, QFormLayout, QDoubleSpinBox, QScrollArea, QTreeView, QInputDialog, QFileDialog, QMessageBox, QDialog, QGroupBox, QHBoxLayout, QPushButton, QDialogButtonBox)
from PyQt5.QtCore import Qt, QDir, QUrl
from PyQt5.QtGui import QDrag, QPainter, QPixmap
from PyQt5.QtWidgets import QFileSystemModel
from QMeta3D.QMeta3DWidget import QMeta3DWidget
from panda3d.core import loadPrcFileData
loadPrcFileData("", "assertions 0")
from core.world import CoreWorld
from core.selection import SelectionSystem
from core.event_handler import EventHandler
from core.tool_manager import ToolManager
from core.script_system import ScriptManager
from core.patrol_system import PatrolSystem
from core.Command_System import CommandManager
from gui.gui_manager import GUIManager
from core.terrain_manager import TerrainManager
from scene.scene_manager import SceneManager
from project.project_manager import ProjectManager
from ui.widgets import CustomMeta3DWidget, CustomFileView, CustomTreeWidget
from ui.property_panel import PropertyPanelManager
from ui.interface_manager import InterfaceManager
from panda3d.core import (CardMaker, Vec4, Vec3, ColorAttrib, MaterialAttrib,
GeomNode, NodePath, Material, CollisionTraverser,
CollisionHandlerQueue, CollisionNode, CollisionRay,
Plane, Point3, Point2, BitMask32, CollisionSphere,
CollisionPlane, ModelPool, Filename, ModelRoot,
AmbientLight, DirectionalLight, TextureAttrib, DriveInterface, WindowProperties)
from panda3d.egg import EggData, EggVertexPool, EggPolygon
from direct.task import Task
from direct.task.TaskManagerGlobal import taskMgr
from direct.showbase.ShowBase import ShowBase
from direct.showbase.DirectObject import DirectObject
from direct.showbase.ShowBaseGlobal import globalClock, aspect2d
import os
import json
import datetime
from direct.actor.Actor import Actor
from PyQt5.sip import wrapinstance
#from RenderPipelineFile.toolkit.material_editor.main import MaterialEditor
class MyWorld(CoreWorld):
def __init__(self):
super().__init__()
# 初始化选择和变换系统
self.selection = SelectionSystem(self)
# 绑定F键用于聚焦选中节点
self.accept("f", self.onFocusKeyPressed)
self.accept("F", self.onFocusKeyPressed) # 大写F
#初始化巡检系统
self.patrol_system = PatrolSystem(self)
self.accept("p",self.onPatrolKeyPressed)
self.accept("P",self.onPatrolKeyPressed)
# 初始化事件处理系统
self.event_handler = EventHandler(self)
# 初始化工具管理系统
self.tool_manager = ToolManager(self)
# 初始化脚本管理系统
self.script_manager = ScriptManager(self)
# 初始化GUI管理系统
self.gui_manager = GUIManager(self)
# 初始化视频管理
self.video_manager = VideoManager(self)
# 初始化场景管理系统
self.scene_manager = SceneManager(self)
# 初始化项目管理系统
self.project_manager = ProjectManager(self)
# 初始化属性面板管理系统
self.property_panel = PropertyPanelManager(self)
# 初始化界面管理系统
self.interface_manager = InterfaceManager(self)
# 启动脚本系统
self.script_manager.start_system()
#self.material_editor = None
self.terrain_manager = TerrainManager(self)
self.terrain_edit_radius = 3.0
self.terrain_edit_strength=0.3
self.terrain_edit_operation = "add"
self.info_panel_manager = InfoPanelManager(self)
self.command_manager = CommandManager()
# 初始化碰撞管理器
from core.collision_manager import CollisionManager
self.collision_manager = CollisionManager(self)
# 初始化VR管理器
try:
from core.vr import VRManager
self.vr_manager = VRManager(self)
print("✓ VR管理器初始化完成")
except Exception as e:
print(f"⚠ VR管理器初始化失败: {e}")
self.vr_manager = None
# 调试选项
self.debug_collision = True # 是否显示碰撞体
# 默认启用模型间碰撞检测(可选)
self.enableModelCollisionDetection(enable=True, frequency=0.1, threshold=0.5)
try:
self.property_panel = PropertyPanelManager(self)
print("✓ 属性面板管理器初始化完成")
except Exception as e:
print(f"⚠ 属性面板管理器初始化失败: {e}")
import traceback
traceback.print_exc()
self.property_panel = None
print("✓ MyWorld 初始化完成")
print("✅ 碰撞管理器已初始化")
# ==================== 兼容性属性 ====================
# 保留models属性以兼容现有代码
@property
def models(self):
"""模型列表的兼容性属性"""
return self.scene_manager.models
@models.setter
def models(self, value):
"""模型列表的兼容性设置器"""
self.scene_manager.models = value
# 保留gui_elements属性以兼容现有代码
@property
def gui_elements(self):
"""GUI元素列表的兼容性属性"""
return self.gui_manager.gui_elements
@gui_elements.setter
def gui_elements(self, value):
"""GUI元素列表的兼容性设置器"""
self.gui_manager.gui_elements = value
# 保留gui_elements属性以兼容现有代码
@property
def Spotlight(self):
"""GUI元素列表的兼容性属性"""
return self.scene_manager.Spotlight
@Spotlight.setter
def Spotlight(self, value):
"""GUI元素列表的兼容性设置器"""
self.scene_manager.Spotlight = value
@property
def Pointlight(self):
return self.scene_manager.Pointlight
@Pointlight.setter
def Pointlight(self,value):
self.scene_manager.Pointlight = value
# 保留guiEditMode属性以兼容现有代码
@property
def guiEditMode(self):
"""GUI编辑模式的兼容性属性"""
return self.gui_manager.guiEditMode
@guiEditMode.setter
def guiEditMode(self, value):
"""GUI编辑模式的兼容性设置器"""
self.gui_manager.guiEditMode = value
# 保留currentTool属性以兼容现有代码
@property
def currentTool(self):
"""当前工具的兼容性属性"""
return self.tool_manager.currentTool
@currentTool.setter
def currentTool(self, value):
"""当前工具的兼容性设置器"""
self.tool_manager.currentTool = value
# 保留treeWidget属性以兼容现有代码
@property
def treeWidget(self):
"""树形控件的兼容性属性"""
return self.interface_manager.treeWidget
@treeWidget.setter
def treeWidget(self, value):
"""树形控件的兼容性设置器"""
self.interface_manager.treeWidget = value
#保留terrains属性以兼容现有代码
@property
def terrains(self):
"""地形列表的兼容性属性"""
return self.terrain_manager.terrains
@terrains.setter
def terrains(self,value):
"""地形列表的兼容性设置器"""
self.terrain_manager.terrains = value
# ==================== GUI管理功能代理 ====================
# GUI元素创建方法 - 代理到gui_manager
def createGUIButton(self, pos=(0, 0, 0), text="按钮", size=0.1):
"""创建2D GUI按钮"""
return self.gui_manager.createGUIButton(pos, text, size)
def createGUILabel(self, pos=(0, 0, 0), text="标签", size=0.08):
"""创建2D GUI标签"""
return self.gui_manager.createGUILabel(pos, text, size)
def createGUIEntry(self, pos=(0, 0, 0), placeholder="输入文本...", size=0.08):
"""创建2D GUI文本输入框"""
return self.gui_manager.createGUIEntry(pos, placeholder, size)
def createGUI3DText(self, pos=(0, 0, 0), text="3D文本", size=1):
"""创建3D空间文本"""
return self.gui_manager.createGUI3DText(pos, text, size)
def createGUI3DImage(self,pos=(0,0,0),text="3D图片",size=(1,1,1)):
"""创建3D图片"""
return self.gui_manager.createGUI3DImage(pos,text,size)
def createGUI2DImage(self, pos=(0, 0, 0), image_path=None, size=2):
"""创建2D GUI图片"""
return self.gui_manager.createGUI2DImage(pos, image_path, size)
def createVideoScreen(self,pos=(0,0,0),size=1,video_path=None):
"""创建视频屏幕"""
return self.gui_manager.createVideoScreen(pos,size,video_path)
def create2DVideoScreen(self,pos=(0,0,0),size=0.2,video_path=None):
"""创建2D视频屏幕"""
return self.gui_manager.createGUI2DVideoScreen(pos,size,video_path)
def createSphericalVideo(self,pos=(0,0,0),radius=5.0,video_path=None):
"""创建360度视频"""
return self.gui_manager.createSphericalVideo(pos,radius,video_path)
def playSphericalVideo(self,spherical_video_node):
return self.gui_manager.playSphericalVideo(spherical_video_node)
def pauseSphericalVideo(self,spherical_video_node):
return self.gui_manager.pauseSphericalVideo(spherical_video_node)
def setSphericalVideoTime(self,spherical_video_node,time_seconds):
return self.gui_manager.setSphericalVideoTime(spherical_video_node,time_seconds)
def createSpotLight(self,pos=(0,0,5)):
"""创建聚光灯"""
return self.scene_manager.createSpotLight(pos)
def createPointLight(self,pos=(0,0,5)):
"""创建点光源"""
return self.scene_manager.createPointLight(pos)
def createGUIVirtualScreen(self, pos=(0, 0, 0), size=(2, 1), text="虚拟屏幕"):
"""创建3D虚拟屏幕"""
return self.gui_manager.createGUIVirtualScreen(pos, size, text)
def createGUISlider(self, pos=(0, 0, 0), text="滑块", scale=0.3):
"""创建2D GUI滑块"""
return self.gui_manager.createGUISlider(pos, text, scale)
# GUI元素管理方法 - 代理到gui_manager
def deleteGUIElement(self, gui_element):
"""删除GUI元素"""
return self.gui_manager.deleteGUIElement(gui_element)
def editGUIElement(self, gui_element, property_name, value):
"""编辑GUI元素属性"""
return self.gui_manager.editGUIElement(gui_element, property_name, value)
def duplicateGUIElement(self, gui_element):
"""复制GUI元素"""
return self.gui_manager.duplicateGUIElement(gui_element)
def editGUIElementDialog(self, gui_element):
"""显示GUI元素编辑对话框"""
return self.gui_manager.editGUIElementDialog(gui_element)
# GUI事件处理方法 - 代理到gui_manager
def onGUIButtonClick(self, button_id):
"""GUI按钮点击事件处理"""
return self.gui_manager.onGUIButtonClick(button_id)
def onGUIEntrySubmit(self, text, entry_id):
"""GUI输入框提交事件处理"""
return self.gui_manager.onGUIEntrySubmit(text, entry_id)
# GUI编辑模式方法 - 代理到gui_manager
def toggleGUIEditMode(self):
"""切换GUI编辑模式"""
return self.gui_manager.toggleGUIEditMode()
def enterGUIEditMode(self):
"""进入GUI编辑模式"""
return self.gui_manager.enterGUIEditMode()
def exitGUIEditMode(self):
"""退出GUI编辑模式"""
return self.gui_manager.exitGUIEditMode()
def createGUIEditPanel(self):
"""创建GUI编辑面板"""
return self.gui_manager.createGUIEditPanel()
def openGUIPreviewWindow(self):
"""打开独立的GUI预览窗口"""
return self.gui_manager.openGUIPreviewWindow()
def closeGUIPreviewWindow(self):
"""关闭GUI预览窗口"""
return self.gui_manager.closeGUIPreviewWindow()
# GUI工具和选择方法 - 代理到gui_manager
def setGUICreateTool(self, tool_type):
"""设置GUI创建工具"""
return self.gui_manager.setGUICreateTool(tool_type)
def deleteSelectedGUI(self):
"""删除选中的GUI元素"""
return self.gui_manager.deleteSelectedGUI()
def copySelectedGUI(self):
"""复制选中的GUI元素"""
return self.gui_manager.copySelectedGUI()
def handleGUIEditClick(self, hitPos):
"""处理GUI编辑模式下的点击"""
return self.gui_manager.handleGUIEditClick(hitPos)
def createGUIAtPosition(self, world_pos, gui_type):
"""在指定位置创建GUI元素"""
return self.gui_manager.createGUIAtPosition(world_pos, gui_type)
def findClickedGUI(self, hitNode):
"""查找被点击的GUI元素"""
return self.gui_manager.findClickedGUI(hitNode)
def selectGUIInTree(self, gui_element):
"""在树形控件中选中GUI元素"""
return self.gui_manager.selectGUIInTree(gui_element)
def updateGUISelection(self, gui_element):
"""更新GUI元素选择状态"""
return self.gui_manager.updateGUISelection(gui_element)
# GUI属性面板方法 - 代理到gui_manager
def selectGUIColor(self, gui_element):
"""选择GUI元素颜色"""
return self.gui_manager.selectGUIColor(gui_element)
def editGUI2DPosition(self, gui_element, axis, value):
"""编辑2D GUI元素位置"""
return self.gui_manager.editGUI2DPosition(gui_element, axis, value)
# ==================== 事件处理代理 ====================
def onTreeItemClicked(self, item, column):
"""处理树形控件项目点击事件 - 代理到interface_manager"""
return self.interface_manager.onTreeItemClicked(item, column)
def setTreeWidget(self, treeWidget):
"""设置树形控件引用 - 代理到interface_manager"""
return self.interface_manager.setTreeWidget(treeWidget)
def mousePressEventLeft(self, evt):
"""处理鼠标左键按下事件 - 代理到event_handler"""
return self.event_handler.mousePressEventLeft(evt)
def mouseReleaseEventLeft(self, evt):
"""处理鼠标左键释放事件 - 代理到event_handler"""
return self.event_handler.mouseReleaseEventLeft(evt)
def wheelForward(self, data=None):
"""处理滚轮向前滚动(前进) - 代理到event_handler"""
return self.event_handler.wheelForward(data)
def wheelBackward(self, data=None):
"""处理滚轮向后滚动(后退) - 代理到event_handler"""
return self.event_handler.wheelBackward(data)
def mousePressEventMiddle(self, evt):
"""处理鼠标中键按下事件 - 代理到event_handler"""
return self.event_handler.mousePressEventMiddle(evt)
def mouseReleaseEventMiddle(self, evt):
"""处理鼠标中键释放事件 - 代理到event_handler"""
return self.event_handler.mouseReleaseEventMiddle(evt)
def mouseMoveEvent(self, evt):
"""处理鼠标移动事件 - 代理到event_handler"""
return self.event_handler.mouseMoveEvent(evt)
# ==================== 射线显示控制 ====================
def toggleRayDisplay(self):
"""切换射线显示状态 - 代理到event_handler"""
return self.event_handler.toggleRayDisplay()
def setRayDisplay(self, show=True):
"""设置射线显示状态 - 代理到event_handler"""
self.event_handler.showRay = show
if not show:
self.event_handler.clearRay()
return show
def getRayDisplay(self):
"""获取射线显示状态 - 代理到event_handler"""
return self.event_handler.showRay
def setRayLifetime(self, seconds):
"""设置射线显示时长(秒) - 代理到event_handler"""
self.event_handler.rayLifetime = seconds
print(f"射线显示时长设置为: {seconds}")
def getRayLifetime(self):
"""获取射线显示时长 - 代理到event_handler"""
return self.event_handler.rayLifetime
# ==================== 属性面板代理 ====================
def setPropertyLayout(self, layout):
"""设置属性面板布局引用 - 代理到property_panel"""
return self.property_panel.setPropertyLayout(layout)
def clearPropertyPanel(self):
"""清空属性面板 - 代理到property_panel"""
return self.property_panel.clearPropertyPanel()
def updatePropertyPanel(self, item):
"""更新属性面板显示 - 代理到property_panel"""
return self.property_panel.updatePropertyPanel(item)
def updateGUIPropertyPanel(self, gui_element):
"""更新GUI元素属性面板 - 代理到property_panel"""
return self.property_panel.updateGUIPropertyPanel(gui_element)
def removeActorForModel(self,model):
return self.property_panel.removeActorForModel( model)
def updateNodeVisibilityAfterDrag(self,item):
return self.property_panel.updateNodeVisibilityAfterDrag(item)
# ==================== 工具管理代理 ====================
def setCurrentTool(self, tool):
"""设置当前工具 - 代理到tool_manager"""
return self.tool_manager.setCurrentTool(tool)
# ==================== 场景管理功能代理 ====================
# 模型导入和处理方法 - 代理到scene_manager
def importModel(self, filepath):
"""导入模型到场景"""
# 自动转换FBX等格式为GLB以获得更好的动画支持不再弹窗询问
# 如果你不想自动转换,可以将 auto_convert 改为 False
auto_convert = False
print(f"[模型导入] 文件: {filepath}, 自动转换GLB: {auto_convert}")
return self.scene_manager.importModel(filepath, auto_convert_to_glb=auto_convert)
def importModelAsync(self, filepath):
"""异步导入模型"""
return self.scene_manager.importModelAsync(filepath)
# 材质和几何体处理方法 - 代理到scene_manager
def processMaterials(self, model):
"""处理模型材质"""
return self.scene_manager.processMaterials(model)
def processModelGeometry(self, model):
"""处理模型几何体"""
return self.scene_manager.processModelGeometry(model)
# 碰撞系统方法 - 代理到scene_manager
def setupCollision(self, model):
"""为模型设置碰撞检测"""
return self.scene_manager.setupCollision(model)
# 场景树管理方法 - 代理到scene_manager
def updateSceneTree(self):
"""更新场景树显示"""
return self.scene_manager.updateSceneTree()
# 场景保存和加载方法 - 代理到scene_manager
def saveScene(self, filename):
"""保存场景到BAM文件"""
return self.scene_manager.saveScene(filename)
def loadScene(self, filename):
"""从BAM文件加载场景"""
return self.scene_manager.loadScene(filename)
# 模型管理方法 - 代理到scene_manager
def deleteModel(self, model):
"""删除模型"""
return self.scene_manager.deleteModel(model)
def clearAllModels(self):
"""清除所有模型"""
return self.scene_manager.clearAllModels()
def getModels(self):
"""获取模型列表"""
return self.scene_manager.getModels()
def getModelCount(self):
"""获取模型数量"""
return self.scene_manager.getModelCount()
def findModelByName(self, name):
"""根据名称查找模型"""
return self.scene_manager.findModelByName(name)
# ==================== 脚本系统功能代理 ====================
# 脚本系统控制方法 - 代理到script_manager
def startScriptSystem(self):
"""启动脚本系统"""
return self.script_manager.start_system()
def stopScriptSystem(self):
"""停止脚本系统"""
return self.script_manager.stop_system()
def enableHotReload(self, enabled=True):
"""启用/禁用热重载"""
self.script_manager.hot_reload_enabled = enabled
if enabled:
self.script_manager.start_hot_reload()
else:
self.script_manager.stop_hot_reload()
# 脚本创建和加载方法 - 代理到script_manager
def createScript(self, script_name, template="basic"):
"""创建新脚本文件"""
return self.script_manager.create_script_file(script_name, template)
def loadScript(self, script_path):
"""从文件加载脚本"""
return self.script_manager.load_script_from_file(script_path)
def loadAllScripts(self, directory=None):
"""从目录加载所有脚本"""
return self.script_manager.load_all_scripts_from_directory(directory)
def reloadScript(self, script_name):
"""重新加载脚本"""
return self.script_manager.reload_script(script_name)
# 脚本挂载和管理方法 - 代理到script_manager
def addScript(self, game_object, script_name):
"""为游戏对象添加脚本"""
return self.script_manager.add_script_to_object(game_object, script_name)
def removeScript(self, game_object, script_name):
"""从游戏对象移除脚本"""
return self.script_manager.remove_script_from_object(game_object, script_name)
def getScripts(self, game_object):
"""获取对象上的所有脚本"""
return self.script_manager.get_scripts_on_object(game_object)
def getScript(self, game_object, script_name):
"""获取对象上的特定脚本"""
return self.script_manager.get_script_on_object(game_object, script_name)
# 脚本信息查询方法 - 代理到script_manager
def getAvailableScripts(self):
"""获取所有可用的脚本名称"""
return self.script_manager.get_available_scripts()
def getScriptInfo(self, script_name):
"""获取脚本信息"""
return self.script_manager.get_script_info(script_name)
def listAllScripts(self):
"""列出所有脚本信息"""
return self.script_manager.list_all_scripts()
def loadCesiumTileset(self,tileset_url,position=(0,0,0)):
return self.scene_manager.load_cesium_tileset(tileset_url,position)
def addCesiumTileset(self,name,url,position=(0,0,0)):
if hasattr(self,'gui_manager') and self.gui_manager:
return self.gui_manager.addCesiumTilesetToScene(name,url,position)
else:
return self.scene_manager.load_cesium_tileset(url,position)
# ==================== 地形管理功能代理 ====================
# 地形创建方法 - 代理到terrain_manager
def createTerrainFromHeightMap(self, heightmap_path, scale=(1, 1, 1)):
"""从高度图创建地形"""
return self.terrain_manager.createTerrainFromHeightMap(heightmap_path, scale)
def createFlatTerrain(self, size=(0.3, 0.3), resolution=256):
"""创建平面地形"""
return self.terrain_manager.createFlatTerrain(size, resolution)
def updateTerrain(self):
"""更新所有地形的LOD"""
return self.terrain_manager.updateTerrain()
def getTerrainHeight(self, terrain_info, x, y):
"""获取地形上指定点的高度"""
return self.terrain_manager.getTerrainHeight(terrain_info, x, y)
def setTerrainEditParameters(self,radius=None,strength=None,operation=None):
if radius is not None:
self.terrain_edit_radius = float(radius)
if strength is not None:
self.terrain_edit_strenght = float(strength)
if operation is not None:
self.terrain_edit_operation = operation
print(f"地形编辑参数已更新: 半径={self.terrain_edit_radius}, 强度={self.terrain_edit_strength}, 操作={self.terrain_edit_operation}")
def getTerrainEditParameters(self):
"""获取当前地形编辑参数"""
return {
'radius': self.terrain_edit_radius,
'strength': self.terrain_edit_strength,
'operation': self.terrain_edit_operation
}
def modifyTerrainHeight(self, terrain_info, x, y, radius, strength, operation="add"):
"""修改地形高度的便捷方法"""
if hasattr(self, 'terrain_manager'):
return self.terrain_manager.modifyTerrainHeight(terrain_info, x, y, radius, strength, operation)
return False
# 添加碰撞管理相关的代理方法
def enableModelCollisionDetection(self, enable=True, frequency=0.1, threshold=0.5):
"""启用模型间碰撞检测"""
return self.collision_manager.enableModelCollisionDetection(enable, frequency, threshold)
def detectModelCollisions(self, specific_models=None, log_results=True):
"""检测模型间碰撞"""
return self.collision_manager.detectModelCollisions(specific_models, log_results)
def getCollisionHistory(self, limit=None):
"""获取碰撞历史"""
return self.collision_manager.getCollisionHistory(limit)
def getCollisionStatistics(self):
"""获取碰撞统计"""
return self.collision_manager.getCollisionStatistics()
def setupKeyboardEvents(self):
"""设置键盘事件"""
try:
# 绑定 F 键用于聚焦选中节点
self.accept("f", self.onFocusKeyPressed)
self.accept("F", self.onFocusKeyPressed) # 大写F
print("✓ 键盘事件绑定完成")
except Exception as e:
print(f"设置键盘事件失败: {e}")
def onFocusKeyPressed(self):
"""处理 F 键按下事件"""
try:
#print("检测到 F 键按下")
# 检查是否有选中的节点
if hasattr(self, 'selection') and self.selection.selectedNode:
#print(f"当前选中节点: {self.selection.selectedNode.getName()}")
# 调用选择系统的聚焦功能(可以选择带动画或不带动画的版本)
# self.selection.focusCameraOnSelectedNode() # 无动画版本
self.selection.focusCameraOnSelectedNodeAdvanced() # 带动画版本
else:
print("当前没有选中任何节点")
except Exception as e:
print(f"处理 F 键事件失败: {e}")
def onPatrolKeyPressed(self):
"""处理 P 键按下事件 - 控制巡检系统"""
try:
print("检测到 P 键按下")
if not self.patrol_system.is_patrolling:
# 如果巡检系统没有点,创建默认巡检路线
if not self.patrol_system.patrol_points:
self.createDefaultPatrolRoute()
# 开始巡检
if self.patrol_system.start_patrol():
print("✓ 巡检已开始")
else:
print("✗ 巡检启动失败")
else:
# 停止巡检
if self.patrol_system.stop_patrol():
print("✓ 巡检已停止")
else:
print("✗ 巡检停止失败")
except Exception as e:
print(f"处理 P 键事件失败: {e}")
def createDefaultPatrolRoute(self):
"""创建默认巡检路线(使用自动朝向)"""
try:
# 清空现有巡检点
self.patrol_system.clear_patrol_points()
# 添加巡检点使用None表示朝向下一个点
self.patrol_system.add_patrol_point((0, -10, 2), (0,0,0), 1.5)
self.patrol_system.add_patrol_point((10, -10, 2), (0,0,0), 1.5)
self.patrol_system.add_patrol_point((10, 5, 2), (0,0,0), 1.5)
self.patrol_system.add_patrol_point((10, 0, 5), (0,0,0), 1.5)
# 最后一个点可以指定特定的朝向或者也设为None继续循环
self.patrol_system.add_patrol_point((0, -10, 2), None, 2.5)
print("✓ 默认自动朝向巡检路线已创建")
self.patrol_system.list_patrol_points()
except Exception as e:
print(f"创建默认自动朝向巡检路线失败: {e}")
def _serializeNode(self, node):
"""序列化节点数据"""
try:
return self.world.scene_manager.serializeNode(node)
except Exception as e:
print(f"序列化节点失败: {e}")
return None
def _deserializeNode(self, node_data, parent_node):
"""反序列化节点数据"""
try:
return self.world.scene_manager.deserializeNode(node_data, parent_node)
except Exception as e:
print(f"反序列化节点失败: {e}")
return None
# ==================== 项目管理功能代理 ====================
# 以下函数代理到project_manager模块的对应功能
def updateWindowTitle(window, project_name=None):
"""更新窗口标题 - 代理到project_manager"""
from project.project_manager import updateWindowTitle as pm_updateWindowTitle
return pm_updateWindowTitle(window, project_name)
def createNewProject(parent_window):
"""创建新项目 - 代理到project_manager"""
world = parent_window.centralWidget().world
return world.project_manager.createNewProject(parent_window)
def saveProject(appw):
"""保存项目 - 代理到project_manager"""
world = appw.centralWidget().world
return world.project_manager.saveProject(appw)
def openProject(appw):
"""打开项目 - 代理到project_manager"""
world = appw.centralWidget().world
return world.project_manager.openProject(appw)
def openProjectForPath(project_path, appw):
"""打开项目 - 代理到project_manager"""
world = appw.centralWidget().world
return world.project_manager.openProjectForPath(project_path, appw)
def buildPackage(appw):
"""打包项目 - 代理到project_manager"""
world = appw.centralWidget().world
return world.project_manager.buildPackage(appw)
def run(args = None):
world = MyWorld()
# 使用新的UI模块创建主窗口
from ui.main_window import setup_main_window
print(f'Path is {args}')
app, main_window = setup_main_window(world, args)
# 启动应用程序
sys.exit(app.exec_())
if __name__ == "__main__":
run()