#!/usr/bin/env python3 """ CAE Mesh Generator - Demo Launcher 演示版本启动器,包含完整的系统检查和演示数据准备 """ import os import sys import shutil import subprocess import webbrowser import time from pathlib import Path from datetime import datetime class DemoLauncher: def __init__(self): self.project_root = Path(__file__).parent.parent # 上一级目录 self.demo_data_dir = self.project_root / 'demo_data' self.demo_port = 5000 self.demo_url = f'http://localhost:{self.demo_port}' def print_banner(self): """打印演示横幅""" print("=" * 70) print("🚀 CAE网格生成助手 - 演示版本") print(" 基于AI的自动化涡扇叶片网格生成系统") print("=" * 70) print(f"启动时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") print(f"项目目录: {self.project_root}") print(f"演示地址: {self.demo_url}") print("=" * 70) def check_python_version(self): """检查Python版本""" print("\n📋 检查Python版本...") version = sys.version_info if version.major < 3 or (version.major == 3 and version.minor < 8): print(f"❌ Python版本过低: {version.major}.{version.minor}") print(" 需要Python 3.8或更高版本") return False print(f"✅ Python版本: {version.major}.{version.minor}.{version.micro}") return True def check_dependencies(self): """检查依赖包""" print("\n📦 检查依赖包...") required_packages = [ ('flask', 'Flask'), ('werkzeug', 'Werkzeug'), ] optional_packages = [ ('ansys.mechanical.core', 'ANSYS Mechanical'), ] missing_required = [] missing_optional = [] # 检查必需包 for package, name in required_packages: try: __import__(package) print(f"✅ {name}: 已安装") except ImportError: print(f"❌ {name}: 未安装") missing_required.append(package) # 检查可选包 for package, name in optional_packages: try: __import__(package) print(f"✅ {name}: 已安装 (完整功能)") except ImportError: print(f"⚠️ {name}: 未安装 (将使用演示模式)") missing_optional.append(package) if missing_required: print(f"\n❌ 缺少必需依赖: {', '.join(missing_required)}") print("请运行: pip install -r requirements.txt") return False if missing_optional: print(f"\n⚠️ 缺少可选依赖: {', '.join(missing_optional)}") print("系统将在演示模式下运行") return True def setup_directories(self): """设置目录结构""" print("\n📁 设置目录结构...") directories = [ 'uploads', 'results', 'temp', 'static/css', 'static/js', 'static/visualizations', 'templates', 'demo_data', 'logs' ] for directory in directories: dir_path = self.project_root / directory dir_path.mkdir(parents=True, exist_ok=True) print(f"✅ {directory}/") return True def create_demo_data(self): """创建演示数据""" print("\n🎯 准备演示数据...") # 创建示例STEP文件 sample_step_files = [ ('simple_blade.step', self.create_simple_blade_step()), ('complex_blade.step', self.create_complex_blade_step()), ('test_geometry.step', self.create_test_geometry_step()) ] for filename, content in sample_step_files: file_path = self.demo_data_dir / filename with open(file_path, 'w', encoding='utf-8') as f: f.write(content) print(f"✅ 创建示例文件: {filename}") # 创建演示说明文件 demo_guide = self.create_demo_guide() guide_path = self.demo_data_dir / 'DEMO_GUIDE.md' with open(guide_path, 'w', encoding='utf-8') as f: f.write(demo_guide) print(f"✅ 创建演示指南: DEMO_GUIDE.md") return True def create_simple_blade_step(self): """创建简单叶片STEP文件""" return """ISO-10303-21; HEADER; FILE_DESCRIPTION(('Simple Turbine Blade for CAE Mesh Generator Demo'),'2;1'); FILE_NAME('simple_blade.step','2025-01-01T00:00:00',('Demo'),('CAE Mesh Generator'),'Demo System','ANSYS',''); FILE_SCHEMA(('AUTOMOTIVE_DESIGN')); ENDSEC; DATA; /* 简单涡扇叶片几何定义 */ #1 = CARTESIAN_POINT('Origin',(0.0,0.0,0.0)); #2 = DIRECTION('X-Axis',(1.0,0.0,0.0)); #3 = DIRECTION('Y-Axis',(0.0,1.0,0.0)); #4 = DIRECTION('Z-Axis',(0.0,0.0,1.0)); #5 = AXIS2_PLACEMENT_3D('Global Coordinate System',#1,#4,#2); /* 叶片轮廓点 */ #10 = CARTESIAN_POINT('Leading Edge Root',(0.0,0.0,0.0)); #11 = CARTESIAN_POINT('Trailing Edge Root',(50.0,0.0,0.0)); #12 = CARTESIAN_POINT('Leading Edge Tip',(5.0,0.0,100.0)); #13 = CARTESIAN_POINT('Trailing Edge Tip',(45.0,0.0,100.0)); /* 叶片表面定义 */ #20 = CARTESIAN_POINT('Pressure Side 1',(0.0,5.0,0.0)); #21 = CARTESIAN_POINT('Pressure Side 2',(25.0,8.0,0.0)); #22 = CARTESIAN_POINT('Pressure Side 3',(50.0,5.0,0.0)); #23 = CARTESIAN_POINT('Suction Side 1',(0.0,-5.0,0.0)); #24 = CARTESIAN_POINT('Suction Side 2',(25.0,-8.0,0.0)); #25 = CARTESIAN_POINT('Suction Side 3',(50.0,-5.0,0.0)); ENDSEC; END-ISO-10303-21;""" def create_complex_blade_step(self): """创建复杂叶片STEP文件""" return """ISO-10303-21; HEADER; FILE_DESCRIPTION(('Complex Turbine Blade with Cooling Channels for CAE Mesh Generator Demo'),'2;1'); FILE_NAME('complex_blade.step','2025-01-01T00:00:00',('Demo'),('CAE Mesh Generator'),'Demo System','ANSYS',''); FILE_SCHEMA(('AUTOMOTIVE_DESIGN')); ENDSEC; DATA; /* 复杂涡扇叶片几何定义 - 包含冷却通道 */ #1 = CARTESIAN_POINT('Origin',(0.0,0.0,0.0)); #2 = DIRECTION('X-Axis',(1.0,0.0,0.0)); #3 = DIRECTION('Y-Axis',(0.0,1.0,0.0)); #4 = DIRECTION('Z-Axis',(0.0,0.0,1.0)); #5 = AXIS2_PLACEMENT_3D('Global Coordinate System',#1,#4,#2); /* 主叶片几何 */ #10 = CARTESIAN_POINT('LE Root',(0.0,0.0,0.0)); #11 = CARTESIAN_POINT('TE Root',(60.0,0.0,0.0)); #12 = CARTESIAN_POINT('LE Tip',(8.0,0.0,120.0)); #13 = CARTESIAN_POINT('TE Tip',(52.0,0.0,120.0)); /* 冷却通道几何 */ #30 = CARTESIAN_POINT('Cooling Channel 1 Start',(15.0,0.0,10.0)); #31 = CARTESIAN_POINT('Cooling Channel 1 End',(15.0,0.0,110.0)); #32 = CARTESIAN_POINT('Cooling Channel 2 Start',(30.0,0.0,10.0)); #33 = CARTESIAN_POINT('Cooling Channel 2 End',(30.0,0.0,110.0)); #34 = CARTESIAN_POINT('Cooling Channel 3 Start',(45.0,0.0,10.0)); #35 = CARTESIAN_POINT('Cooling Channel 3 End',(45.0,0.0,110.0)); /* 叶片根部连接 */ #40 = CARTESIAN_POINT('Root Connection 1',(-5.0,0.0,-10.0)); #41 = CARTESIAN_POINT('Root Connection 2',(65.0,0.0,-10.0)); #42 = CARTESIAN_POINT('Root Connection 3',(30.0,0.0,-15.0)); ENDSEC; END-ISO-10303-21;""" def create_test_geometry_step(self): """创建测试几何STEP文件""" return """ISO-10303-21; HEADER; FILE_DESCRIPTION(('Test Geometry for CAE Mesh Generator Validation'),'2;1'); FILE_NAME('test_geometry.step','2025-01-01T00:00:00',('Test'),('CAE Mesh Generator'),'Test System','ANSYS',''); FILE_SCHEMA(('AUTOMOTIVE_DESIGN')); ENDSEC; DATA; /* 测试几何 - 简单立方体用于验证 */ #1 = CARTESIAN_POINT('Origin',(0.0,0.0,0.0)); #2 = DIRECTION('X-Axis',(1.0,0.0,0.0)); #3 = DIRECTION('Y-Axis',(0.0,1.0,0.0)); #4 = DIRECTION('Z-Axis',(0.0,0.0,1.0)); #5 = AXIS2_PLACEMENT_3D('Global Coordinate System',#1,#4,#2); /* 立方体顶点 */ #10 = CARTESIAN_POINT('Vertex 1',(0.0,0.0,0.0)); #11 = CARTESIAN_POINT('Vertex 2',(10.0,0.0,0.0)); #12 = CARTESIAN_POINT('Vertex 3',(10.0,10.0,0.0)); #13 = CARTESIAN_POINT('Vertex 4',(0.0,10.0,0.0)); #14 = CARTESIAN_POINT('Vertex 5',(0.0,0.0,10.0)); #15 = CARTESIAN_POINT('Vertex 6',(10.0,0.0,10.0)); #16 = CARTESIAN_POINT('Vertex 7',(10.0,10.0,10.0)); #17 = CARTESIAN_POINT('Vertex 8',(0.0,10.0,10.0)); ENDSEC; END-ISO-10303-21;""" def create_demo_guide(self): """创建演示指南""" return """# CAE网格生成助手 - 演示指南 ## 欢迎使用演示版本! 本演示系统展示了基于AI的自动化涡扇叶片网格生成功能。 ### 🎯 演示目标 - 展示STEP文件上传和验证功能 - 演示自动化网格生成流程 - 展示网格质量检查和评估 - 展示结果可视化和导出功能 ### 📁 演示文件说明 1. **simple_blade.step** - 简单涡扇叶片几何 - 适合快速演示基本功能 - 预计处理时间:30-60秒 2. **complex_blade.step** - 复杂叶片几何,包含冷却通道 - 展示高级网格控制功能 - 预计处理时间:2-5分钟 3. **test_geometry.step** - 简单测试几何(立方体) - 用于功能验证 - 预计处理时间:10-30秒 ### 🚀 演示流程 #### 步骤1:文件上传 1. 打开演示网页界面 2. 点击上传区域或拖拽文件 3. 选择演示文件(推荐从simple_blade.step开始) 4. 等待文件验证完成 #### 步骤2:网格生成 1. 文件上传成功后,点击"开始生成"按钮 2. 观察实时进度显示和处理日志 3. 系统将自动完成以下步骤: - 几何导入和验证 - 自动识别关键区域 - 应用网格控制 - 生成网格 - 质量检查 #### 步骤3:结果查看 1. 查看网格统计信息 2. 查看质量评估报告 3. 查看可视化结果(如果可用) 4. 下载结果文件 ### 🔧 演示模式说明 - **完整模式**:如果安装了ANSYS Mechanical,将使用真实的网格生成功能 - **演示模式**:如果未安装ANSYS,将使用模拟数据展示完整流程 ### 📊 预期结果 #### Simple Blade (简单叶片) - 单元数量:约8,000-12,000 - 节点数量:约12,000-18,000 - 质量评分:75-85分 - 生成时间:30-60秒 #### Complex Blade (复杂叶片) - 单元数量:约25,000-40,000 - 节点数量:约35,000-55,000 - 质量评分:70-80分 - 生成时间:2-5分钟 #### Test Geometry (测试几何) - 单元数量:约1,000-2,000 - 节点数量:约1,500-3,000 - 质量评分:85-95分 - 生成时间:10-30秒 ### 🎨 界面功能 #### 侧边栏 - 处理流程步骤显示 - 系统状态监控 - 实时进度更新 #### 主界面 - 文件上传区域 - 进度显示和日志 - 结果统计和可视化 - 导出选项 ### 🔍 故障排除 #### 常见问题 1. **文件上传失败** - 确认文件格式为.step或.stp - 确认文件大小不超过100MB - 检查文件是否损坏 2. **网格生成失败** - 检查几何文件完整性 - 查看错误日志信息 - 尝试使用测试几何文件 3. **界面无响应** - 刷新浏览器页面 - 检查网络连接 - 查看浏览器控制台错误 #### 技术支持 如遇到问题,请: 1. 查看浏览器控制台错误信息 2. 查看应用日志文件 3. 尝试重启演示系统 ### 📈 性能优化建议 1. **文件选择**:首次使用建议从simple_blade.step开始 2. **浏览器**:推荐使用Chrome或Firefox最新版本 3. **系统资源**:确保有足够的内存和CPU资源 ### 🎉 演示完成后 演示完成后,您可以: 1. 查看生成的网格文件 2. 分析质量报告 3. 了解系统架构和技术实现 4. 探索更多高级功能 --- **祝您演示愉快!** 如有任何问题或建议,欢迎反馈。 """ def check_port_availability(self): """检查端口可用性""" print(f"\n🌐 检查端口 {self.demo_port} 可用性...") import socket with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: result = s.connect_ex(('localhost', self.demo_port)) if result == 0: print(f"⚠️ 端口 {self.demo_port} 已被占用") print("请关闭占用端口的程序或修改配置") return False else: print(f"✅ 端口 {self.demo_port} 可用") return True def start_application(self): """启动应用程序""" print(f"\n🚀 启动CAE网格生成助手...") print(f"访问地址: {self.demo_url}") print("按 Ctrl+C 停止应用") print("-" * 50) try: # 添加项目根目录到Python路径 sys.path.insert(0, str(self.project_root)) # 启动Flask应用 from app import create_app app = create_app() # 延迟打开浏览器 def open_browser(): time.sleep(2) print(f"\n🌐 正在打开浏览器: {self.demo_url}") webbrowser.open(self.demo_url) import threading browser_thread = threading.Thread(target=open_browser, daemon=True) browser_thread.start() # 启动应用 app.run( host='0.0.0.0', port=self.demo_port, debug=False, use_reloader=False ) except KeyboardInterrupt: print("\n\n👋 演示已停止") print("感谢使用CAE网格生成助手演示版本!") except Exception as e: print(f"\n❌ 启动失败: {e}") return False return True def run_demo(self): """运行完整演示""" self.print_banner() # 系统检查 checks = [ ("Python版本", self.check_python_version), ("依赖包", self.check_dependencies), ("目录结构", self.setup_directories), ("演示数据", self.create_demo_data), ("端口可用性", self.check_port_availability) ] for check_name, check_func in checks: if not check_func(): print(f"\n❌ {check_name}检查失败,演示无法启动") return False print("\n✅ 所有检查通过,准备启动演示...") print("\n📖 演示指南已创建在 demo_data/DEMO_GUIDE.md") print("建议先阅读演示指南了解使用方法") # 询问是否继续 try: response = input("\n是否现在启动演示?(y/N): ").strip().lower() if response in ['y', 'yes', '是']: return self.start_application() else: print("\n演示已取消。您可以稍后运行此脚本启动演示。") return True except KeyboardInterrupt: print("\n\n演示已取消。") return True def main(): """主函数""" launcher = DemoLauncher() success = launcher.run_demo() return 0 if success else 1 if __name__ == '__main__': sys.exit(main())