# main_simple.py - 使用QOpenGLWidget的新主程序 import sys import os from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QHBoxLayout, QWidget, QPushButton, QFileDialog from PyQt5.QtCore import Qt from OpenGL.GLUT import glutInit from glWidget_simple import Simple3DWidget from handle_simple import Dataload class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle('力山特喷涂机器人操作软件') self.setGeometry(100, 100, 1200, 800) # 创建中央部件 central_widget = QWidget() self.setCentralWidget(central_widget) # 创建布局 layout = QHBoxLayout() central_widget.setLayout(layout) # 创建3D渲染器 self.gl_widget = Simple3DWidget() # 创建控制面板 control_panel = QWidget() control_panel.setFixedWidth(200) control_layout = QVBoxLayout() control_panel.setLayout(control_layout) # 创建按钮 self.open_button = QPushButton("打开STL文件") self.switch_button = QPushButton("切换显示模式") self.axes_button = QPushButton("坐标系显示") self.point_button = QPushButton("选点模式") self.color_button = QPushButton("选色模式") self.open_button.clicked.connect(self.open_file) self.switch_button.clicked.connect(self.gl_widget.toggle_display_mode) self.axes_button.clicked.connect(self.gl_widget.toggle_axes_display_mode) self.point_button.clicked.connect(self.gl_widget.point_mode) self.color_button.clicked.connect(self.gl_widget.color_mode) control_layout.addWidget(self.open_button) control_layout.addWidget(self.switch_button) control_layout.addWidget(self.axes_button) control_layout.addWidget(self.point_button) control_layout.addWidget(self.color_button) # 添加一些空间 control_layout.addStretch() # 添加到主布局 layout.addWidget(control_panel) layout.addWidget(self.gl_widget) # 连接信号 self.gl_widget.pointPicked.connect(self.on_point_picked) # 创建数据加载器 self.dataload = Dataload() self.gl_widget.picking_color_map = self.dataload.picking_color_map def open_file(self): """打开文件对话框,选择 3D 模型文件并根据类型调用对应加载函数""" # 设置文件过滤器 filter = ( "3D Model Files (*.stp *.step *.stl);;" "STL Files (*.stl);;" "All Files (*)" ) file_path, _ = QFileDialog.getOpenFileName( self, "选择 3D 模型文件", "", # 初始路径,可改为上次打开的目录 filter ) if not file_path: print("用户取消选择") return if not os.path.exists(file_path): print(f"❌ 文件不存在: {file_path}") return # 获取文件扩展名(转小写,便于判断) ext = os.path.splitext(file_path)[1].lower() print(f"选中的文件: {file_path}") print(f"文件扩展名: {ext}") # 根据扩展名分发到不同加载函数 if ext in ['.stp', '.step']: self.load_step_file(file_path) # 加载 STEP 文件 elif ext == '.stl': self.load_stl_file(file_path) # 加载 STL 文件 else: print(f"❌ 不支持的文件格式: {ext}") # 可选:弹出警告框 from PyQt5.QtWidgets import QMessageBox QMessageBox.warning(self, "不支持的格式", f"无法加载文件类型: {ext}") def load_stl_file(self, file_path): """加载STL文件""" print(f"📁 正在加载: {file_path}") # 使用Dataload类加载数据 vertices, colors,triangles, normals, edges = self.dataload.load_data_from_file(file_path) if len(vertices) == 0: print("❌ 加载失败") return # 设置数据到渲染器 self.gl_widget.face_normals = self.dataload.face_normals self.gl_widget.original_colors = self.dataload.original_colors self.gl_widget.set_data(vertices, colors,triangles, normals, edges) print("✅ 数据已设置到渲染器") def load_step_file(self, file_path): """加载STL文件""" print(f"📁 正在加载: {file_path}") # 使用Dataload类加载数据 vertices, colors, triangles, normals = self.dataload.load_step_file(file_path) if len(vertices) == 0: print("❌ 加载失败") return # 设置数据到渲染器 self.gl_widget.set_data(vertices, colors, triangles, normals) print("✅ 数据已设置到渲染器") def on_point_picked(self, x, y, z): """点拾取回调""" print(f"✅ 拾取到点: ({x:.3f}, {y:.3f}, {z:.3f})") def main(): print("当前工作目录:", os.getcwd()) app = QApplication(sys.argv) # 初始化 GLUT(必须在创建任何 OpenGL 上下文前调用) glutInit(sys.argv) window = MainWindow() window.show() print("✅ 3D模型查看器启动成功") print("点击'打开STL文件'按钮来加载模型") return app.exec_() if __name__ == "__main__": main()