diff --git a/.gitignore b/.gitignore index fa793d4b..0d126761 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,4 @@ Resources/models/Women_1.glb /panda3d_imgui-1.1.0-py3-none-any.whl imgui.ini dist +build diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..be7f65fe --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,120 @@ +# 元泰 EG 项目开发指南 + +元泰 EG 是基于 Panda3D 的 3D 编辑器和游戏引擎。 + +--- + +## 🚀 快速开始 + +### 环境要求 + +- **Python 3.11.x**(必须) +- Windows 10/11 64位 +- Visual Studio Build Tools(用于构建) + +### 安装步骤 + +```bash +# 1. 检查 Python 版本(必须是 3.11) +python --version + +# 2. 验证版本 +python build_scripts/check_python_version.py + +# 3. 安装依赖 +pip install -r requirements/requirements-minimal.txt + +# 4. 运行程序 +python Start_Run.py +``` + +--- + +## 📦 构建安装程序 + +### Windows + +```powershell +# 在 VS Dev Shell 中执行 +.\build_scripts\build_windows.ps1 -Version "1.0.0" +``` + +详细步骤请参考 `build_scripts/BUILD_GUIDE.md` + +--- + +## 🗂️ 项目结构 + +``` +元泰 EG/ +├── AGENTS.md # 本文件 +├── main.py # 主程序入口 +├── Start_Run.py # 启动脚本 +├── requirements/ # 依赖配置 +│ ├── requirements-minimal.txt # 最小依赖(推荐) +│ └── requirements.txt # 完整依赖(旧) +├── build_scripts/ # 构建脚本和文档 +│ ├── build_windows.ps1 # Windows 构建脚本 +│ ├── build_linux.sh # Linux 构建脚本 +│ ├── BUILD_GUIDE.md # 构建指南 ⭐ +│ ├── BUILD_README.md # 构建说明 +│ ├── INSTALLER_GUIDE.md # 完整指南 +│ ├── QUICK_REFERENCE.md # 快速参考 +│ ├── ICON_GUIDE.md # 图标准备 +│ ├── PYTHON_VERSION_REQUIREMENT.md # Python版本要求 +│ └── PACKAGING_CHECKLIST.md # 打包检查清单 +├── core/ # 核心模块 +├── RenderPipelineFile/ # 渲染管线 +├── Resources/ # 资源文件 +└── ... +``` + +--- + +## 🛠️ 技术栈 + +- **Python**: 3.11.x(必须) +- **渲染引擎**: Panda3D 1.10.16 +- **UI框架**: imgui_bundle + p3dimgui +- **VR支持**: OpenVR 2.2.0 +- **图像处理**: Pillow + +### 已移除的依赖 + +为减少体积,已移除以下未使用的依赖: + +- ❌ PyQt5 (~50MB) +- ❌ PySide6 (~100MB) +- ❌ 相关 Qt 配套库 (~20MB) + +**总计节省 ~170MB** + +--- + +## 📚 重要文档 + +| 文档 | 位置 | 用途 | +|------|------|------| +| 构建指南 | `build_scripts/BUILD_GUIDE.md` | 从零开始构建 ⭐ | +| Python版本要求 | `build_scripts/PYTHON_VERSION_REQUIREMENT.md` | Python 3.11 安装指南 | +| 快速参考 | `build_scripts/QUICK_REFERENCE.md` | 命令速查 | +| 打包检查清单 | `build_scripts/PACKAGING_CHECKLIST.md` | 构建前检查 | + +--- + +## ⚠️ 重要提示 + +1. **Python 版本**: 必须使用 3.11,构建脚本会检查 +2. **构建环境**: Windows 必须在 VS Dev Shell 中构建 +3. **清理旧依赖**: 如果之前有安装 PyQt5/PySide6,建议卸载以节省空间 + +--- + +## 🔗 相关链接 + +- Python 3.11: https://www.python.org/downloads/release/python-3119/ +- Visual Studio Build Tools: https://visualstudio.microsoft.com/visual-cpp-build-tools/ + +--- + +**最后更新**: 2024年 diff --git a/RenderPipelineFile/rpcore/native/__init__.py b/RenderPipelineFile/rpcore/native/__init__.py index 3ba9d575..371a90c6 100644 --- a/RenderPipelineFile/rpcore/native/__init__.py +++ b/RenderPipelineFile/rpcore/native/__init__.py @@ -40,7 +40,22 @@ from rpcore.rpobject import RPObject NATIVE_CXX_LOADED = False # Read the configuration from the flag-file +# Fix for Nuitka/PyInstaller: try multiple methods to find the flag file +import os current_path = dirname(realpath(__file__)) + +# Nuitka standalone mode fix: if __file__ is empty or invalid, use sys.argv[0] +if not current_path or not isfile(join(current_path, "use_cxx.flag")): + # Try relative to executable + exe_dir = dirname(realpath(sys.argv[0])) + current_path = join(exe_dir, "RenderPipelineFile", "rpcore", "native") + + # Try one more fallback: check environment variable + if not isfile(join(current_path, "use_cxx.flag")): + rp_path = os.environ.get("RENDER_PIPELINE_PATH", "") + if rp_path: + current_path = join(rp_path, "rpcore", "native") + cxx_flag_path = join(current_path, "use_cxx.flag") if not isfile(cxx_flag_path): RPObject.global_error("CORE", "Could not find cxx flag, please run the setup.py!") diff --git a/build_scripts/ICON_GUIDE.md b/build_scripts/ICON_GUIDE.md new file mode 100644 index 00000000..3b6e792e --- /dev/null +++ b/build_scripts/ICON_GUIDE.md @@ -0,0 +1,285 @@ +# EG 图标准备指南 + +构建安装程序需要准备应用程序图标,本指南说明如何创建和放置图标文件。 + +--- + +## 📋 所需图标 + +| 平台 | 文件名 | 格式 | 推荐尺寸 | 用途 | +|------|--------|------|---------|------| +| Windows | `icons/app.ico` | ICO | 256x256 (多尺寸) | 可执行文件和安装程序图标 | +| Linux | `icons/app.png` | PNG | 256x256 | AppImage 和桌面图标 | + +--- + +## 🎨 图标要求 + +### Windows ICO 文件 + +ICO 文件可以包含多个尺寸的图标: +- **必须包含**: 256x256 (32位) +- **推荐包含**: 48x48, 32x32, 16x16 +- **可选**: 128x128, 64x64 + +**格式要求**: +- 支持透明背景 (32位,带 Alpha 通道) +- 大图标使用 PNG 压缩 +- 小图标使用 BMP 格式 + +### Linux PNG 文件 + +- **尺寸**: 256x256 像素 +- **格式**: PNG,带透明通道 +- **色彩**: RGBA (32位) + +--- + +## 🔧 创建图标的方法 + +### 方法 1: 使用现有图片转换 + +如果你有 PNG/JPG 格式的 logo: + +**Windows (ICO)**: +```bash +# 使用 ImageMagick +convert logo.png -define icon:auto-resize=256,128,64,48,32,16 icons/app.ico + +# 或在线工具 +# https://convertio.co/png-ico/ +# https://icoconvert.com/ +``` + +**Linux (PNG)**: +```bash +# 直接复制或调整大小 +cp logo.png icons/app.png + +# 或使用 ImageMagick 调整 +convert logo.png -resize 256x256 icons/app.png +``` + +### 方法 2: 使用专业工具设计 + +| 工具 | 平台 | 类型 | 链接 | +|------|------|------|------| +| Adobe Illustrator | Win/Mac | 专业矢量 | - | +| Figma | Web | 免费在线 | figma.com | +| Canva | Web | 免费在线 | canva.com | +| GIMP | Win/Mac/Linux | 免费开源 | gimp.org | +| Inkscape | Win/Mac/Linux | 免费矢量 | inkscape.org | + +### 方法 3: 使用 Python 脚本生成 + +如果你有源图片,可以使用 Python 生成: + +```python +#!/usr/bin/env python3 +"""图标生成脚本""" + +from PIL import Image +import os + +# 源图片路径 +source_image = "source_logo.png" # 你的源图片 +output_dir = "icons" + +# 确保输出目录存在 +os.makedirs(output_dir, exist_ok=True) + +# 打开源图片 +img = Image.open(source_image) + +# 转换为 RGBA 模式 (确保透明通道) +if img.mode != 'RGBA': + img = img.convert('RGBA') + +# 生成 Windows ICO (多尺寸) +icon_sizes = [(16, 16), (32, 32), (48, 48), (64, 64), (128, 128), (256, 256)] +ico_images = [] + +for size in icon_sizes: + resized = img.resize(size, Image.Resampling.LANCZOS) + ico_images.append(resized) + +# 保存 ICO (第一个图像作为根,其余作为子图标) +ico_images[0].save( + os.path.join(output_dir, "app.ico"), + format='ICO', + sizes=[(i.width, i.height) for i in ico_images], + append_images=ico_images[1:] +) + +print(f"✓ 生成: {output_dir}/app.ico") + +# 生成 Linux PNG (256x256) +png_size = (256, 256) +png_img = img.resize(png_size, Image.Resampling.LANCZOS) +png_img.save(os.path.join(output_dir, "app.png"), format='PNG') + +print(f"✓ 生成: {output_dir}/app.png") + +print("\n图标生成完成!") +``` + +**使用方法**: +```bash +# 安装依赖 +pip install Pillow + +# 运行脚本 +python generate_icons.py +``` + +### 方法 4: 从项目中提取 + +如果项目中有现有图标资源: + +```bash +# 查找项目中的图标文件 +find . -name "*.ico" -o -name "*.png" | grep -i icon + +# 复制到正确位置 +cp 找到的图标文件 icons/app.ico +cp 找到的图标文件 icons/app.png +``` + +--- + +## 📁 目录结构 + +放置图标后,项目结构应为: + +``` +EG/ +├── icons/ +│ ├── app.ico # Windows 图标 (必需) +│ ├── app.png # Linux 图标 (必需) +│ └── ... # 其他图标资源 +├── build_scripts/ +├── ... +``` + +--- + +## ✅ 验证图标 + +### Windows + +```powershell +# 检查文件存在 +Test-Path icons/app.ico + +# 查看 ICO 内容 (需要工具) +# 使用 Resource Hacker: http://www.angusj.com/resourcehacker/ +``` + +### Linux + +```bash +# 检查文件存在 +ls -la icons/app.png + +# 查看图片信息 +file icons/app.png +identify icons/app.png # 需要 ImageMagick + +# 预览 +xdg-open icons/app.png +``` + +--- + +## 🚀 测试图标 + +构建完成后,验证图标是否正确显示: + +### Windows + +1. **可执行文件图标**: + ```powershell + # 检查 dist/EG_1.0.0/EG.exe 的图标 + # 在资源管理器中查看,应该显示你的图标 + ``` + +2. **安装程序图标**: + ```powershell + # 检查 dist/EG_Setup_v1.0.0_x64.exe 的图标 + ``` + +### Linux + +```bash +# 检查 AppImage 图标 +./dist/EG-1.0.0-x86_64.AppImage --appimage-mount +ls squashfs-root/EG.png +``` + +--- + +## 🐛 常见问题 + +### 问题 1: ICO 文件无法识别 + +**症状**: Windows 显示默认图标 + +**解决**: +- 确保 ICO 包含 256x256 尺寸 +- 使用专业工具重新生成 +- 检查文件是否损坏 + +### 问题 2: Linux 图标不显示 + +**症状**: AppImage 使用默认图标 + +**解决**: +- 确认 `icons/app.png` 存在 +- 检查文件权限: `chmod 644 icons/app.png` +- 确认 PNG 格式正确: `file icons/app.png` + +### 问题 3: 图标模糊 + +**症状**: 图标显示模糊或锯齿 + +**解决**: +- 使用矢量源文件生成 +- 确保包含多个尺寸 +- 使用高质量缩放算法 (LANCZOS) + +--- + +## 📦 快速开始 + +如果你没有现成的图标,可以先使用占位图标: + +```bash +# Windows: 创建一个简单的 ICO +# 使用在线工具生成,或先跳过 (Nuitka 会使用默认图标) + +# Linux: 创建一个简单的 PNG +python3 -c " +from PIL import Image +import os +os.makedirs('icons', exist_ok=True) +img = Image.new('RGBA', (256, 256), (100, 150, 255, 255)) +img.save('icons/app.png') +print('Created placeholder icon') +" +``` + +**注意**: 发布前务必替换为正式图标! + +--- + +## 🎨 设计建议 + +1. **简洁明了**: 小尺寸下依然可识别 +2. **品牌一致性**: 与应用风格一致 +3. **透明背景**: 适应不同主题 +4. **测试多尺寸**: 确保 16x16 到 256x256 都清晰 +5. **考虑暗色主题**: 在深色背景下也可见 + +--- + +**文档版本**: 1.0 diff --git a/build_scripts/PACKAGING_CHECKLIST.md b/build_scripts/PACKAGING_CHECKLIST.md new file mode 100644 index 00000000..54bedffa --- /dev/null +++ b/build_scripts/PACKAGING_CHECKLIST.md @@ -0,0 +1,294 @@ +# EG 项目打包清单 + +本文档详细说明安装程序中包含的内容,以及打包决策依据。 + +--- + +## 📦 打包内容总览 + +### 代码部分 (由 Nuitka 编译) + +| 入口文件 | 处理方式 | 说明 | +|---------|---------|------| +| `Start_Run.py` | 编译为主程序 | 应用入口 | +| `main.py` | 被导入编译 | 主程序逻辑 | +| `core/` | 编译进可执行文件 | 核心模块 | +| `gui/` | 编译进可执行文件 | GUI模块 | +| `project/` | 编译进可执行文件 | 项目管理 | +| `scene/` | 编译进可执行文件 | 场景管理 | +| `ssbo_component/` | 编译进可执行文件 | SSBO组件 | +| `tools/` | 编译进可执行文件 | 工具模块 | +| `TransformGizmo/` | 编译进可执行文件 | 变换工具 | +| `ui/` | 编译进可执行文件 | UI模块 | + +### 数据资源 (复制到输出目录) + +| 目录/文件 | 用途 | 必要性 | +|----------|------|--------| +| `config/` | 配置文件 | ✅ 必须 | +| `icons/` | 图标资源 | ✅ 必须 | +| `RenderPipelineFile/` | 渲染管线 | ✅ 必须 | +| `Resources/` | 资源文件 | ✅ 必须 | +| `scripts/` | 脚本系统 | ✅ 必须 | +| `templates/` | 项目模板 | ✅ 必须 | +| `tex/` | 纹理资源 | ✅ 必须 | +| `vr_actions/` | VR配置 | ✅ 必须 | +| `imgui.ini` | ImGui配置 | ✅ 必须 | + +--- + +## ⚠️ 需要确认的问题 + +### 问题 1: `project/` 目录 + +**现状**: 当前配置中 **未包含** `project/` 目录 + +**分析**: + +- `project/` 包含 `project_manager.py`, `webgl_packager.py`, `__init__.py` +- `main.py` 中导入: `from project.project_manager import ProjectManager` + +**结论**: ⚠️ **必须包含!** 否则项目管理功能无法工作 + +**建议操作**: 添加到 `DATA_DIRECTORIES` + +```python +DATA_DIRECTORIES = [ + # ... 现有目录 ... + "project", # 添加此行 +] +``` + +--- + +### 问题 2: `new/` 目录 + +**现状**: 当前配置中 **未包含** + +**分析**: + +- 包含 `project.json` (空项目模板) +- 可能是"新建项目"的默认模板 + +**结论**: ✅ **建议包含** 作为默认项目模板 + +**建议操作**: 添加到 `DATA_DIRECTORIES` + +--- + +### 问题 3: `test_project/` 目录 + +**现状**: 当前配置中 **未包含** + +**分析**: + +- 包含示例 `project.json` +- 可用于演示功能 + +**选项**: + +1. **不包含** - 减小安装包体积 +2. **包含为可选组件** - 用户可选择安装 +3. **包含** - 方便新用户学习 + +**建议**: 选项 1 或 3,根据安装包大小决定 + +--- + +### 问题 4: Python 缓存文件 + +**现状**: 已排除 `__pycache__`, `*.pyc`, `*.pyo`, `*.pyd` + +**分析**: ✅ 正确,这些是由 Python 运行时生成的缓存,不需要分发 + +--- + +### 问题 5: 开发环境文件 + +**现状**: 已排除 `.git`, `.gitignore`, `.idea`, `.vscode` + +**分析**: ✅ 正确,这些是开发环境配置,用户不需要 + +--- + +### 问题 6: 构建脚本 + +**现状**: `build_scripts/` 未包含 + +**分析**: ✅ 正确,构建脚本不需要分发给最终用户 + +--- + +### 问题 7: 依赖文件 + +**现状**: `requirements/` 未包含 + +**分析**: + +- 最终用户不需要 `requirements.txt`(依赖已编译进可执行文件) +- 但如果提供 SDK/开发套件,可能需要 + +**结论**: ✅ 当前处理正确 + +--- + +## 🔧 修正后的配置 + +### 更新 DATA_DIRECTORIES + +```python +# ==================== 数据文件配置 ==================== +# 需要包含的目录 (相对于项目根目录) +DATA_DIRECTORIES = [ + # 配置和资源 + "config", + "icons", + "Resources", + "tex", + "templates", + + # 核心模块 (这些目录中的 .py 文件会被编译,但可能包含非 .py 资源) + "core", # 核心功能 + "gui", # GUI相关 + "project", # ⚠️ 新增: 项目管理 (包含非代码资源) + "scene", # 场景管理 + "scripts", # 脚本系统 + "ssbo_component", # SSBO编辑器 + "tools", # 工具模块 + "TransformGizmo", # 变换Gizmo + "ui", # UI模块 + + # 引擎和扩展 + "RenderPipelineFile", # 渲染管线 + "vr_actions", # VR配置 + + # 示例和模板 + "new", # ⚠️ 新增: 默认项目模板 + # "test_project", # 可选: 示例项目 +] +``` + +### Nuitka 包含包确认 + +当前配置: + +```python +"include_packages": [ + "Panda3D", + "direct", + "imgui_bundle", + "p3dimgui", + "openvr", + "PIL", + "yaml", + "psutil", +], +``` + +**需要添加**: + +- 检查 `requirements.txt` 中的其他依赖是否需要显式包含 + +--- + +## 📊 打包体积预估 + +| 目录 | 估算大小 | 说明 | +|------|---------|------| +| `RenderPipelineFile/` | ~50-100 MB | 渲染管线核心 | +| `Resources/` | 可变 | 用户资源 | +| `tex/` | ~10-50 MB | 默认纹理 | +| `icons/` | ~1-5 MB | 图标 | +| 其他代码目录 | ~5-10 MB | Python 源文件(编译前) | +| **总计** | **~100-200 MB** | 不含用户资源 | + +--- + +## ✅ 打包检查清单 + +### 构建前请确认 + +#### 目录配置 + +- [x] `config/` - 配置目录 ✅ +- [x] `core/` - 核心模块 ✅ +- [x] `gui/` - GUI模块 ✅ +- [x] `icons/` - 图标资源 ✅ +- [x] `project/` - 项目管理 ✅ **(已添加)** +- [x] `RenderPipelineFile/` - 渲染管线 ✅ +- [x] `Resources/` - 资源文件 ✅ +- [x] `scene/` - 场景管理 ✅ +- [x] `scripts/` - 脚本系统 ✅ +- [x] `ssbo_component/` - SSBO组件 ✅ +- [x] `templates/` - 模板 ✅ +- [x] `tex/` - 纹理 ✅ +- [x] `tools/` - 工具 ✅ +- [x] `TransformGizmo/` - 变换工具 ✅ +- [x] `ui/` - UI模块 ✅ +- [x] `vr_actions/` - VR配置 ✅ +- [x] `new/` - 默认项目模板 ✅ **(已添加)** + +#### 文件检查 + +- [ ] `icons/app.ico` - Windows图标 ⚠️ **需要添加** +- [ ] `icons/app.png` - Linux图标 ⚠️ **需要添加** +- [x] `imgui.ini` - ImGui配置 ✅ +- [x] `Start_Run.py` - 入口脚本 ✅ +- [x] `main.py` - 主程序 ✅ + +#### 清理检查 + +- [x] 排除了所有 `__pycache__` 和 `.pyc` 文件 ✅ +- [x] 排除了开发环境文件 (`.idea`, `.vscode`) ✅ +- [x] 排除了构建目录 (`build_scripts`, `dist`, `build`) ✅ +- [x] 排除了 `.git` 目录 ✅ + +#### 功能验证 + +- [ ] 测试构建成功 +- [ ] 测试安装程序能正常运行 +- [ ] 测试便携版能正常运行 +- [ ] 验证项目管理功能正常 +- [ ] 验证新建项目功能正常 + +--- + +## 🧪 验证方法 + +构建完成后,验证以下内容: + +```powershell +# Windows +# 1. 检查输出目录结构 +tree /f dist\EG_1.0.0 + +# 2. 运行程序测试基本功能 +dist\EG_1.0.0\EG.exe + +# 3. 检查关键文件是否存在 +Test-Path dist\EG_1.0.0\config +Test-Path dist\EG_1.0.0\Resources +Test-Path dist\EG_1.0.0\scripts +``` + +```bash +# Linux +# 1. 检查 AppImage 内容 +./dist/EG-1.0.0-x86_64.AppImage --appimage-mount + +# 2. 运行测试 +./dist/EG-1.0.0-x86_64.AppImage +``` + +--- + +## 🔒 安全注意事项 + +1. **代码保护**: Nuitka 编译后的机器码难以逆向,但资源文件(模型、纹理)是明文的 +2. **敏感配置**: 确保 `config/` 中没有包含 API 密钥等敏感信息 +3. **许可证**: 如果包含第三方资源,确保许可证允许再分发 + +--- + +**文档版本**: 1.0 +**最后更新**: 2024年 diff --git a/build_scripts/PYTHON_VERSION_REQUIREMENT.md b/build_scripts/PYTHON_VERSION_REQUIREMENT.md new file mode 100644 index 00000000..a900a368 --- /dev/null +++ b/build_scripts/PYTHON_VERSION_REQUIREMENT.md @@ -0,0 +1,99 @@ +# Python 版本要求 + +## 必须使用的版本 + +**Python 3.11.x** + +```bash +# 检查 Python 版本 +python --version +# 应显示: Python 3.11.x +``` + +## 为什么不支持其他版本? + +| 版本 | 状态 | 原因 | +|------|------|------| +| Python 3.10 | ❌ 不支持 | Panda3D 1.10.16 在 3.10 上有兼容性问题 | +| **Python 3.11** | ✅ **推荐** | 经过完整测试,所有功能正常 | +| Python 3.12 | ⚠️ 未测试 | 可能存在兼容性问题 | +| Python 3.13 | ⚠️ 不推荐 | 当前环境使用,但部分依赖可能有警告 | + +## Windows 安装 Python 3.11 + +### 方法 1: 官网下载 + +1. 访问: https://www.python.org/downloads/release/python-3119/ +2. 下载: `Windows installer (64-bit)` +3. 安装时勾选: + - ✅ `Add Python to PATH` + - ✅ `Use admin privileges when installing py.exe` + +### 方法 2: 使用 Chocolatey + +```powershell +# 安装 Chocolatey 后 +choco install python --version=3.11.9 +``` + +### 方法 3: 使用 pyenv-win + +```powershell +# 安装 pyenv-win +pip install pyenv-win + +# 安装 Python 3.11 +pyenv install 3.11.9 +pyenv global 3.11.9 +``` + +## 验证安装 + +```powershell +# 检查版本 +python --version +# Python 3.11.9 + +# 检查 pip +python -m pip --version +# pip 24.x from ... +``` + +## 安装项目依赖 + +```powershell +# 创建虚拟环境(推荐) +python -m venv venv +.\venv\Scripts\activate + +# 安装依赖 +python -m pip install -r requirements/requirements-minimal.txt +``` + +## 构建要求 + +构建安装程序时也必须使用 Python 3.11: + +```powershell +# 确保使用 Python 3.11 +python --version +# Python 3.11.x + +# 然后执行构建 +.\build_scripts\build_windows.ps1 +``` + +## 常见问题 + +### Q: 我已经安装了 Python 3.12/3.13,需要卸载吗? +**A**: 不需要卸载,可以同时安装多个版本。使用 `py -3.11` 或指定完整路径调用 Python 3.11。 + +### Q: 如何切换默认 Python 版本? +**A**: 修改系统 PATH 环境变量,将 Python 3.11 的路径放到其他版本前面。 + +### Q: 虚拟环境中可以使用不同版本吗? +**A**: 不可以,虚拟环境继承创建它的 Python 版本。需要用 Python 3.11 创建虚拟环境。 + +--- + +**最后更新**: 2024年 diff --git a/build_scripts/analyze_packaging.py b/build_scripts/analyze_packaging.py new file mode 100644 index 00000000..c52ba1ad --- /dev/null +++ b/build_scripts/analyze_packaging.py @@ -0,0 +1,326 @@ +#!/usr/bin/env python3 +""" +EG 打包分析工具 +用于分析项目结构和打包配置的完整性 +""" + +import os +import sys +from pathlib import Path +from typing import List, Set, Tuple + +# 项目根目录 +PROJECT_ROOT = Path(__file__).parent.parent.absolute() + +# 当前的打包配置 (从 setup.py 同步) +DATA_DIRECTORIES = [ + # 配置和资源 + "config", + "icons", + "Resources", + "tex", + "templates", + + # 核心模块 + "core", + "gui", + "project", + "scene", + "scripts", + "ssbo_component", + "tools", + "TransformGizmo", + "ui", + + # 引擎和扩展 + "RenderPipelineFile", + "vr_actions", + + # 项目模板 + "new", +] + +# 排除的模式 +EXCLUDE_PATTERNS = [ + "__pycache__", + "*.pyc", + "*.pyo", + "*.pyd", + ".git", + ".gitignore", + ".idea", + ".vscode", + "*.egg-info", + "*.egg", + "dist", + "build", + "*.spec", +] + +# 已知的开发/构建目录 (不应该打包) +DEV_DIRECTORIES = [ + ".git", + ".idea", + ".vscode", + "build", + "build_scripts", + "dist", + "test_project", # 示例项目,可选 + "__pycache__", +] + +# 已知的文档文件 (可选打包) +DOC_FILES = [ + "README.md", + "LICENSE.txt", + "CHANGELOG.md", + "AGENTS.md", +] + + +def get_directory_size(path: Path) -> Tuple[int, int]: + """计算目录大小和文件数量""" + total_size = 0 + file_count = 0 + + if not path.exists(): + return 0, 0 + + for item in path.rglob("*"): + if item.is_file(): + # 检查是否应该排除 + should_exclude = False + for pattern in EXCLUDE_PATTERNS: + if pattern.startswith("*"): + if item.name.endswith(pattern[1:]): + should_exclude = True + break + elif pattern in str(item.relative_to(path)): + should_exclude = True + break + + if not should_exclude: + total_size += item.stat().st_size + file_count += 1 + + return total_size, file_count + + +def format_size(size_bytes: int) -> str: + """格式化文件大小""" + for unit in ['B', 'KB', 'MB', 'GB']: + if size_bytes < 1024: + return f"{size_bytes:.2f} {unit}" + size_bytes /= 1024 + return f"{size_bytes:.2f} TB" + + +def analyze_project_structure(): + """分析项目结构""" + print("=" * 70) + print("EG 项目打包分析") + print("=" * 70) + print() + + # 获取所有目录 + all_dirs = [d for d in PROJECT_ROOT.iterdir() if d.is_dir()] + all_dir_names = {d.name for d in all_dirs} + + # 分类 + packaged_dirs = [] + dev_dirs = [] + missing_dirs = [] + unknown_dirs = [] + + for d in all_dirs: + name = d.name + if name in DATA_DIRECTORIES: + packaged_dirs.append(d) + elif name in DEV_DIRECTORIES: + dev_dirs.append(d) + elif name.startswith(".") or name in ["new", "test_project"]: + # 特殊目录 + if name not in DATA_DIRECTORIES: + missing_dirs.append(d) + else: + unknown_dirs.append(d) + + # 1. 已配置的打包目录 + print("📦 已配置的打包目录:") + print("-" * 70) + total_size = 0 + total_files = 0 + + for d in sorted(packaged_dirs, key=lambda x: x.name): + size, count = get_directory_size(d) + total_size += size + total_files += count + status = "✓" if d.exists() else "✗ 不存在" + print(f" {status:12} {d.name:25} {format_size(size):>12} ({count} 文件)") + + print("-" * 70) + print(f" {'总计':12} {'':25} {format_size(total_size):>12} ({total_files} 文件)") + print() + + # 2. 开发目录 (正确排除) + if dev_dirs: + print("🔧 开发/构建目录 (正确排除):") + print("-" * 70) + for d in sorted(dev_dirs, key=lambda x: x.name): + size, count = get_directory_size(d) + print(f" {'✓ 排除':12} {d.name:25} {format_size(size):>12}") + print() + + # 3. 未配置的目录 (需要检查) + if unknown_dirs: + print("⚠️ 未配置的目录 (请检查是否需要打包):") + print("-" * 70) + for d in sorted(unknown_dirs, key=lambda x: x.name): + size, count = get_directory_size(d) + print(f" {'? 待确认':12} {d.name:25} {format_size(size):>12} ({count} 文件)") + # 列出部分文件帮助判断 + files = list(d.iterdir())[:5] + for f in files: + file_type = "📁" if f.is_dir() else "📄" + print(f" {file_type} {f.name}") + if len(list(d.iterdir())) > 5: + print(f" ... 等 {len(list(d.iterdir())) - 5} 个文件") + print() + + # 4. 检查配置中但目录不存在的 + config_only = set(DATA_DIRECTORIES) - all_dir_names + if config_only: + print("⚠️ 配置中有但目录不存在:") + print("-" * 70) + for name in config_only: + print(f" ✗ 不存在 {name}") + print() + + # 5. 关键文件检查 + print("🔑 关键文件检查:") + print("-" * 70) + + critical_files = { + "Start_Run.py": "入口脚本", + "main.py": "主程序", + "imgui.ini": "ImGui配置", + "icons/app.ico": "Windows图标", + "icons/app.png": "Linux图标", + } + + for file, desc in critical_files.items(): + path = PROJECT_ROOT / file + exists = "✓" if path.exists() else "✗" + print(f" {exists:3} {file:25} ({desc})") + print() + + # 6. 建议 + print("💡 建议:") + print("-" * 70) + + suggestions = [] + + if unknown_dirs: + suggestions.append(f"有 {len(unknown_dirs)} 个未配置目录,请检查是否需要打包") + + if config_only: + suggestions.append(f"配置中有 {len(config_only)} 个目录不存在,请更新配置") + + # 检查图标 + if not (PROJECT_ROOT / "icons/app.ico").exists(): + suggestions.append("缺少 Windows 图标: icons/app.ico") + if not (PROJECT_ROOT / "icons/app.png").exists(): + suggestions.append("缺少 Linux 图标: icons/app.png") + + # 检查大小 + if total_size > 500 * 1024 * 1024: + suggestions.append(f"打包内容较大 ({format_size(total_size)}),考虑优化") + + if not suggestions: + print(" ✓ 一切正常!") + else: + for s in suggestions: + print(f" • {s}") + print() + + # 7. 预估输出 + print("📊 预估输出:") + print("-" * 70) + + # Nuitka 编译后大约增加 20-50MB 开销 + estimated_exe_size = total_size + 50 * 1024 * 1024 + print(f" 数据文件: {format_size(total_size)}") + print(f" 编译开销(预估): ~50 MB") + print(f" 总计(预估): {format_size(estimated_exe_size)}") + print(f" 压缩后(预估): {format_size(estimated_exe_size * 0.6)}") # 假设 60% 压缩率 + print() + + # 返回是否有问题 + has_issues = bool(unknown_dirs or config_only or not suggestions) + return has_issues + + +def generate_updated_config(): + """生成更新后的配置代码""" + print("=" * 70) + print("建议的配置更新") + print("=" * 70) + print() + + # 获取所有实际存在的目录 + all_dirs = {d.name for d in PROJECT_ROOT.iterdir() if d.is_dir()} + + # 自动分类 + auto_include = [] + auto_exclude = [] + + for name in sorted(all_dirs): + if name in DEV_DIRECTORIES: + auto_exclude.append(name) + elif name.startswith("."): + auto_exclude.append(name) + else: + auto_include.append(name) + + print("# 自动生成的配置建议:") + print() + print("DATA_DIRECTORIES = [") + for name in auto_include: + comment = "" + if name == "project": + comment = " # 项目管理模块" + elif name == "new": + comment = " # 默认项目模板" + elif name == "test_project": + comment = " # 示例项目 (可选)" + print(f' "{name}",{comment}') + print("]") + print() + + +def main(): + """主函数""" + import argparse + + parser = argparse.ArgumentParser(description="EG 打包分析工具") + parser.add_argument("--generate", action="store_true", help="生成配置建议") + + args = parser.parse_args() + + if args.generate: + generate_updated_config() + else: + has_issues = analyze_project_structure() + + print() + print("=" * 70) + if has_issues: + print("发现潜在问题,请检查上方输出") + sys.exit(1) + else: + print("✓ 分析完成,配置看起来正常") + sys.exit(0) + + +if __name__ == "__main__": + main() diff --git a/build_scripts/check_env.ps1 b/build_scripts/check_env.ps1 new file mode 100644 index 00000000..645e5781 --- /dev/null +++ b/build_scripts/check_env.ps1 @@ -0,0 +1,139 @@ +#!/usr/bin/env powershell +# EG Windows 构建环境检查脚本 + +Write-Host "========================================" -ForegroundColor Cyan +Write-Host " EG 构建环境检查" -ForegroundColor Cyan +Write-Host "========================================" -ForegroundColor Cyan + +$Issues = @() +$Warnings = @() + +# 检查 Python +Write-Host "`n[1/6] 检查 Python..." -ForegroundColor Yellow +try { + $PythonVersion = python --version 2>&1 + if ($PythonVersion -match "Python (\d+)\.(\d+)") { + $Major = [int]$Matches[1] + $Minor = [int]$Matches[2] + if ($Major -ge 3 -and $Minor -ge 8) { + Write-Host " ✓ $PythonVersion (符合要求)" -ForegroundColor Green + } else { + Write-Host " ⚠ $PythonVersion (建议 3.8+)" -ForegroundColor Yellow + $Warnings += "Python 版本较旧" + } + } +} catch { + Write-Host " ✗ Python 未找到" -ForegroundColor Red + $Issues += "需要安装 Python 3.8+" +} + +# 检查 pip +Write-Host "`n[2/6] 检查 pip..." -ForegroundColor Yellow +try { + $PipVersion = pip --version 2>&1 + Write-Host " ✓ $PipVersion" -ForegroundColor Green +} catch { + Write-Host " ✗ pip 未找到" -ForegroundColor Red + $Issues += "需要安装 pip" +} + +# 检查 PowerShell 执行策略 +Write-Host "`n[3/6] 检查 PowerShell 执行策略..." -ForegroundColor Yellow +$Policy = Get-ExecutionPolicy +if ($Policy -eq "Restricted") { + Write-Host " ✗ 当前策略: $Policy (需要修改)" -ForegroundColor Red + $Issues += "执行策略需要设置为 RemoteSigned: Set-ExecutionPolicy RemoteSigned -Scope CurrentUser" +} else { + Write-Host " ✓ 当前策略: $Policy" -ForegroundColor Green +} + +# 检查必要模块 +Write-Host "`n[4/6] 检查 Python 模块..." -ForegroundColor Yellow +$Modules = @("nuitka", "pyinstaller") +foreach ($mod in $Modules) { + $result = pip show $mod 2>$null + if ($result) { + $version = ($result | Select-String "Version:").ToString().Split(":")[1].Trim() + Write-Host " ✓ $mod $version" -ForegroundColor Green + } else { + Write-Host " ⚠ $mod 未安装 (将自动安装)" -ForegroundColor Yellow + } +} + +# 检查项目依赖 +Write-Host "`n[5/6] 检查项目依赖..." -ForegroundColor Yellow +$ReqFile = "$PSScriptRoot\..\requirements\requirements.txt" +if (Test-Path $ReqFile) { + Write-Host " ✓ 找到 requirements.txt" -ForegroundColor Green + + # 检查几个关键包 + $KeyPackages = @("Panda3D", "PyQt5", "openvr", "imgui-bundle") + foreach ($pkg in $KeyPackages) { + $result = pip show $pkg 2>$null + if ($result) { + Write-Host " ✓ $pkg" -ForegroundColor Green + } else { + Write-Host " ⚠ $pkg 未安装" -ForegroundColor Yellow + } + } +} else { + Write-Host " ✗ 未找到 requirements.txt" -ForegroundColor Red + $Warnings += "未找到依赖文件" +} + +# 检查 Inno Setup +Write-Host "`n[6/6] 检查 Inno Setup..." -ForegroundColor Yellow +$ISCCPaths = @( + "C:\Program Files (x86)\Inno Setup 6\ISCC.exe", + "C:\Program Files\Inno Setup 6\ISCC.exe" +) +$Found = $false +foreach ($path in $ISCCPaths) { + if (Test-Path $path) { + Write-Host " ✓ 找到: $path" -ForegroundColor Green + $Found = $true + break + } +} +if (!$Found) { + Write-Host " ⚠ Inno Setup 未找到 (可选,用于创建安装程序)" -ForegroundColor Yellow + Write-Host " 下载: https://jrsoftware.org/isdl.php" -ForegroundColor Gray + $Warnings += "Inno Setup 未安装 (可选)" +} + +# 检查编译器 +Write-Host "`n[7/6] 检查 C++ 编译器..." -ForegroundColor Yellow +$CL = Get-Command cl -ErrorAction SilentlyContinue +$GCC = Get-Command gcc -ErrorAction SilentlyContinue + +if ($CL) { + Write-Host " ✓ 找到 MSVC (cl)" -ForegroundColor Green +} elseif ($GCC) { + Write-Host " ✓ 找到 GCC" -ForegroundColor Green +} else { + Write-Host " ⚠ 未找到 C++ 编译器" -ForegroundColor Yellow + Write-Host " Nuitka 将尝试自动安装 MinGW64 或使用已安装的 Visual Studio" -ForegroundColor Gray + $Warnings += "未找到 C++ 编译器 (Nuitka 会尝试自动解决)" +} + +# 总结 +Write-Host "`n========================================" -ForegroundColor Cyan +if ($Issues.Count -eq 0 -and $Warnings.Count -eq 0) { + Write-Host " ✓ 环境检查通过!" -ForegroundColor Green + Write-Host " 可以开始构建" -ForegroundColor Green + exit 0 +} else { + if ($Issues.Count -gt 0) { + Write-Host " 发现问题 ($($Issues.Count)):" -ForegroundColor Red + foreach ($issue in $Issues) { + Write-Host " - $issue" -ForegroundColor Red + } + } + if ($Warnings.Count -gt 0) { + Write-Host " 警告 ($($Warnings.Count)):" -ForegroundColor Yellow + foreach ($warn in $Warnings) { + Write-Host " - $warn" -ForegroundColor Yellow + } + } + exit 1 +} diff --git a/build_scripts/check_env.sh b/build_scripts/check_env.sh new file mode 100644 index 00000000..3696e033 --- /dev/null +++ b/build_scripts/check_env.sh @@ -0,0 +1,137 @@ +#!/bin/bash +# EG Linux 构建环境检查脚本 + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +ISSUES=() +WARNINGS=() + +echo "========================================" +echo -e "${BLUE} EG 构建环境检查${NC}" +echo "========================================" + +# 检查 Python +echo "" +echo "[1/6] 检查 Python..." +if command -v python3 &> /dev/null; then + VERSION=$(python3 --version 2>&1) + echo -e " ${GREEN}✓${NC} $VERSION" +else + echo -e " ${RED}✗${NC} Python3 未找到" + ISSUES+=("需要安装 Python 3.8+") +fi + +# 检查 pip +echo "" +echo "[2/6] 检查 pip..." +if command -v pip3 &> /dev/null; then + VERSION=$(pip3 --version 2>&1 | awk '{print $2}') + echo -e " ${GREEN}✓${NC} pip $VERSION" +else + echo -e " ${RED}✗${NC} pip3 未找到" + ISSUES+=("需要安装 pip3") +fi + +# 检查 GCC +echo "" +echo "[3/6] 检查 GCC..." +if command -v gcc &> /dev/null; then + VERSION=$(gcc --version 2>&1 | head -1) + echo -e " ${GREEN}✓${NC} $VERSION" +else + echo -e " ${RED}✗${NC} GCC 未找到" + ISSUES+=("需要安装 GCC: sudo apt-get install build-essential") +fi + +# 检查 G++ +echo "" +echo "[4/6] 检查 G++..." +if command -v g++ &> /dev/null; then + VERSION=$(g++ --version 2>&1 | head -1) + echo -e " ${GREEN}✓${NC} $VERSION" +else + echo -e " ${RED}✗${NC} G++ 未找到" + ISSUES+=("需要安装 G++: sudo apt-get install build-essential") +fi + +# 检查 Python 模块 +echo "" +echo "[5/6] 检查 Python 模块..." +MODULES=("nuitka" "pyinstaller") +for mod in "${MODULES[@]}"; do + if pip3 show "$mod" &> /dev/null; then + VERSION=$(pip3 show "$mod" 2>/dev/null | grep Version | awk '{print $2}') + echo -e " ${GREEN}✓${NC} $mod $VERSION" + else + echo -e " ${YELLOW}⚠${NC} $mod 未安装 (将自动安装)" + fi +done + +# 检查项目依赖 +echo "" +echo "[6/6] 检查项目依赖..." +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +REQ_FILE="$SCRIPT_DIR/../requirements/requirements.txt" + +if [ -f "$REQ_FILE" ]; then + echo -e " ${GREEN}✓${NC} 找到 requirements.txt" + + # 检查关键包 + KEY_PKGS=("Panda3D" "PyQt5" "openvr" "imgui-bundle") + for pkg in "${KEY_PKGS[@]}"; do + # 转换为小写检查 + pkg_lower=$(echo "$pkg" | tr '[:upper:]' '[:lower:]') + if pip3 show "$pkg_lower" &> /dev/null; then + echo -e " ${GREEN}✓${NC} $pkg" + else + echo -e " ${YELLOW}⚠${NC} $pkg 未安装" + fi + done +else + echo -e " ${YELLOW}⚠${NC} 未找到 requirements.txt" + WARNINGS+=("未找到依赖文件") +fi + +# 检查额外工具 +echo "" +echo "[7/6] 检查额外工具..." +if command -v wget &> /dev/null; then + echo -e " ${GREEN}✓${NC} wget" +else + echo -e " ${YELLOW}⚠${NC} wget 未安装 (用于下载 appimagetool)" + WARNINGS+=("建议安装 wget") +fi + +# 检查 dpkg (用于构建 deb) +if command -v dpkg-deb &> /dev/null; then + echo -e " ${GREEN}✓${NC} dpkg-deb (可构建 DEB 包)" +else + echo -e " ${YELLOW}⚠${NC} dpkg-deb 未安装 (无法构建 DEB 包)" +fi + +# 总结 +echo "" +echo "========================================" +if [ ${#ISSUES[@]} -eq 0 ] && [ ${#WARNINGS[@]} -eq 0 ]; then + echo -e "${GREEN} ✓ 环境检查通过!${NC}" + echo -e "${GREEN} 可以开始构建${NC}" + exit 0 +else + if [ ${#ISSUES[@]} -gt 0 ]; then + echo -e "${RED} 发现问题 (${#ISSUES[@]}):${NC}" + for issue in "${ISSUES[@]}"; do + echo -e " ${RED}- $issue${NC}" + done + fi + if [ ${#WARNINGS[@]} -gt 0 ]; then + echo -e "${YELLOW} 警告 (${#WARNINGS[@]}):${NC}" + for warn in "${WARNINGS[@]}"; do + echo -e " ${YELLOW}- $warn${NC}" + done + fi + exit 1 +fi diff --git a/build_scripts/check_python_version.py b/build_scripts/check_python_version.py new file mode 100644 index 00000000..43e4b1c7 --- /dev/null +++ b/build_scripts/check_python_version.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 +""" +元泰 EG Python 版本检查脚本 +确保使用正确的 Python 版本 +""" + +import sys + +def check_python_version(): + """检查 Python 版本是否为 3.11""" + version_info = sys.version_info + version_string = f"{version_info.major}.{version_info.minor}.{version_info.micro}" + + print("=" * 50) + print("元泰 EG Python 版本检查") + print("=" * 50) + print(f"当前 Python 版本: {version_string}") + print(f"可执行文件路径: {sys.executable}") + print() + + if version_info[:2] == (3, 11): + print("✅ Python 版本正确 (3.11.x)") + print() + print("可以继续安装依赖和构建:") + print(" pip install -r requirements/requirements-minimal.txt") + return 0 + else: + print(f"❌ Python 版本错误!") + print(f" 需要: Python 3.11.x") + print(f" 当前: Python {version_string}") + print() + print("请参考 build_scripts/PYTHON_VERSION_REQUIREMENT.md 安装正确版本") + return 1 + +if __name__ == "__main__": + sys.exit(check_python_version()) diff --git a/icons/app.ico b/icons/app.ico new file mode 100644 index 00000000..3cdd2e77 Binary files /dev/null and b/icons/app.ico differ diff --git a/icons/app.png b/icons/app.png new file mode 100644 index 00000000..4066ce0a Binary files /dev/null and b/icons/app.png differ diff --git a/requirements/requirements-minimal.txt b/requirements/requirements-minimal.txt new file mode 100644 index 00000000..ff4800f4 --- /dev/null +++ b/requirements/requirements-minimal.txt @@ -0,0 +1,30 @@ +# 元泰 EG 最小依赖配置 (Python 3.11) +# 注意: 必须使用 Python 3.11,其他版本不保证兼容性 + +# Python 版本要求 +# python_version == "3.11" + +# 核心 3D 引擎 +Panda3D==1.10.16 +panda3d-frame==22.10.post1 +panda3d-imgui==1.1.0 + +# ImGui 绑定 +imgui-bundle==1.92.4 + +# VR 支持 +openvr>=2.5.101 + +# 图像处理 +Pillow==11.3.0 + +# YAML 配置解析 +PyYAML==5.4.1 + +# 其他工具 +psutil==5.9.0 + +# 注意: 已移除以下未使用的依赖 +# - PyQt5 (未使用,节省 ~50MB) +# - PySide6 (未使用,节省 ~100MB) +# - PyQt5-Qt5, PyQt5_sip, PySide6_Addons, PySide6_Essentials