diff --git a/circle.json b/circle.json new file mode 100644 index 0000000..a6369f3 --- /dev/null +++ b/circle.json @@ -0,0 +1,339 @@ +{ + "p": [ + 0.0, + 0.0, + 0.0 + ], + "q": [ + 1.0, + 0.0, + 0.0, + 0.0 + ], + "name": "", + "children": [ + { + "p": [ + -6.0, + 0.0, + 0.0 + ], + "q": [ + 1.0, + 0.0, + 0.0, + 0.0 + ], + "name": "E0", + "face_type": "symm", + "face_geometry": "circle", + "face_f": 1e10, + "face_g": 1e10, + "draw_material": "nothing" + }, + { + "p": [ + -6.0, + 0.0, + 0.0 + ], + "q": [ + 1.0, + 0.0, + 0.0, + 0.0 + ], + "name": "M00", + "face_type": "symm", + "face_geometry": "parabola", + "face_f": 5.0, + "face_g": 1e10, + "draw_material": "metal" + }, + { + "p": [ + -6.0, + 0.0, + 0.0 + ], + "q": [ + 1.0, + 0.0, + 0.0, + 0.0 + ], + "name": "M10", + "face_type": "symm", + "face_geometry": "parabola", + "face_f": 1.0, + "face_g": 1e10, + "draw_material": "metal" + }, + { + "p": [ + -6.0, + 0.0, + -5.974533048268448 + ], + "q": [ + 0.9238795325112867, + -0.0, + 0.3826834323650898, + 0.0 + ], + "name": "M20", + "face_type": "symm", + "face_geometry": "circle", + "face_f": 1e10, + "face_g": 1e10, + "draw_material": "metal" + }, + { + "p": [ + 6.0, + 0.0, + 0.0 + ], + "q": [ + 0.0, + 0.0, + 0.0, + 1.0 + ], + "name": "E1", + "face_type": "symm", + "face_geometry": "circle", + "face_f": 1e10, + "face_g": 1e10, + "draw_material": "nothing" + }, + { + "p": [ + 6.0, + 0.0, + 0.0 + ], + "q": [ + 0.0, + 0.0, + 0.0, + 1.0 + ], + "name": "M01", + "face_type": "symm", + "face_geometry": "parabola", + "face_f": 5.0, + "face_g": 1e10, + "draw_material": "metal" + }, + { + "p": [ + 6.0, + 0.0, + 0.0 + ], + "q": [ + 0.0, + 0.0, + 0.0, + 1.0 + ], + "name": "M11", + "face_type": "symm", + "face_geometry": "parabola", + "face_f": 1.0, + "face_g": 1e10, + "draw_material": "metal" + }, + { + "p": [ + 6.0, + 0.0, + -5.974533048268448 + ], + "q": [ + 0.0, + -0.3826834323650898, + 0.0, + 0.9238795325112867 + ], + "name": "M21", + "face_type": "symm", + "face_geometry": "circle", + "face_f": 1e10, + "face_g": 1e10, + "draw_material": "metal" + }, + { + "p": [ + -1.9818052586129662, + 0.0, + -5.974533048268448 + ], + "q": [ + 0.9238795325112867, + 0.0, + -0.3826834323650898, + 0.0 + ], + "name": "M30", + "face_type": "symm", + "face_geometry": "circle", + "face_f": 1e10, + "face_g": 1e10, + "draw_material": "metal" + }, + { + "p": [ + 1.9818052586129662, + 0.0, + -5.974533048268448 + ], + "q": [ + 0.9238795325112867, + -0.0, + 0.3826834323650898, + 0.0 + ], + "name": "M31", + "face_type": "symm", + "face_geometry": "circle", + "face_f": 1e10, + "face_g": 1e10, + "draw_material": "metal" + }, + { + "p": [ + 0.0, + 0.0, + 0.0 + ], + "q": [ + 1.0, + 0.0, + 0.0, + 0.0 + ], + "name": "M6", + "face_type": "symm", + "face_geometry": "parabola", + "face_f": 5.0, + "face_g": 1e10, + "draw_material": "metal" + }, + { + "p": [ + 0.0, + 0.0, + 0.0 + ], + "q": [ + 1.0, + 0.0, + 0.0, + 0.0 + ], + "name": "M7", + "face_type": "symm", + "face_geometry": "hyperbola", + "face_f": 1.0, + "face_g": -6.875220831710909, + "draw_material": "metal" + }, + { + "p": [ + 0.0, + 0.0, + -7.875220831710909 + ], + "q": [ + 1.0, + 0.0, + 0.0, + 0.0 + ], + "name": "D0", + "face_type": "symm", + "face_geometry": "circle", + "face_f": 1e10, + "face_g": 1e10, + "draw_material": "metal" + }, + { + "p": [ + -1.9818052586129662, + 0.0, + 0.0 + ], + "q": [ + 0.9238795325112867, + 0.0, + -0.3826834323650898, + 0.0 + ], + "name": "M40", + "face_type": "symm", + "face_geometry": "circle", + "face_f": 1e10, + "face_g": 1e10, + "draw_material": "metal" + }, + { + "p": [ + -1.0, + 0.0, + 0.0 + ], + "q": [ + 0.9238795325112867, + -0.0, + 0.3826834323650898, + 0.0 + ], + "name": "M50", + "face_type": "symm", + "face_geometry": "circle", + "face_f": 1e10, + "face_g": 1e10, + "draw_material": "metal" + }, + { + "p": [ + 1.9818052586129662, + 0.0, + 0.0 + ], + "q": [ + 0.9238795325112867, + -0.0, + 0.3826834323650898, + 0.0 + ], + "name": "M41", + "face_type": "symm", + "face_geometry": "circle", + "face_f": 1e10, + "face_g": 1e10, + "draw_material": "metal" + }, + { + "p": [ + 1.0, + 0.0, + 0.0 + ], + "q": [ + 0.9238795325112867, + 0.0, + -0.3826834323650898, + 0.0 + ], + "name": "M51", + "face_type": "symm", + "face_geometry": "circle", + "face_f": 1e10, + "face_g": 1e10, + "draw_material": "metal" + } + ] +} \ No newline at end of file diff --git a/optical_system.blend b/optical_system.blend index b09abf1..7cf2e89 100644 Binary files a/optical_system.blend and b/optical_system.blend differ diff --git a/optical_system.blend1 b/optical_system.blend1 new file mode 100644 index 0000000..15a6dd7 Binary files /dev/null and b/optical_system.blend1 differ diff --git a/optical_system.glb b/optical_system.glb index a061330..ae07fcd 100644 Binary files a/optical_system.glb and b/optical_system.glb differ diff --git a/optical_system_render.png b/optical_system_render.png index f84a2b2..010325e 100644 Binary files a/optical_system_render.png and b/optical_system_render.png differ diff --git a/run_blender_input.py b/run_blender_input.py new file mode 100644 index 0000000..57fdda7 --- /dev/null +++ b/run_blender_input.py @@ -0,0 +1,171 @@ +#!/usr/bin/env python3 +""" +运行脚本 - 使用Blender生成3D光学系统模型 + +使用方法: +1. 确保已安装Blender +2. 运行此脚本: python run_blender_input.py -i jsonfile.json + +输出文件: +- optical_system.obj - 3D模型文件 +- optical_system.glb - Web友好格式 +- optical_system.blend - Blender工程文件 +- optical_system_render.png - 渲染图像 +""" + +import subprocess +import sys +import os +import platform +import argparse + +def find_blender(): + """查找Blender可执行文件""" + system = platform.system() + + common_paths = [] + if system == "Windows": + common_paths = [ + r"C:\Program Files\Blender Foundation\Blender 3.6\blender.exe", + r"C:\Program Files\Blender Foundation\Blender 4.0\blender.exe", + r"C:\Program Files (x86)\Blender Foundation\Blender 3.6\blender.exe", + ] + elif system == "Darwin": # macOS + common_paths = [ + "/Applications/Blender.app/Contents/MacOS/Blender", + "/usr/local/bin/blender", + ] + elif system == "Linux": + common_paths = [ + "/usr/bin/blender", + "/usr/local/bin/blender", + "/snap/bin/blender", + ] + + # 首先尝试从PATH中找到blender + try: + result = subprocess.run(["which", "blender"], capture_output=True, text=True) + if result.returncode == 0: + return result.stdout.strip() + except: + pass + + # 尝试常见路径 + for path in common_paths: + if os.path.exists(path): + return path + + return None + +def run_blender_script(json_file): + """运行Blender脚本""" + blender_path = find_blender() + + if not blender_path: + print("❌ 错误:未找到Blender安装") + print("\n请确保已安装Blender并且可以从命令行访问") + print("下载地址: https://www.blender.org/download/") + return False + + print(f"✅ 找到Blender: {blender_path}") + + script_path = os.path.abspath("toModel.py") + if not os.path.exists(script_path): + print(f"❌ 错误:未找到脚本文件 {script_path}") + return False + + json_path = os.path.abspath(json_file) + if not os.path.exists(json_path): + print(f"❌ 错误:未找到JSON数据文件 {json_path}") + return False + + print(f"📄 使用JSON文件: {json_path}") + print("🚀 开始运行Blender脚本...") + print("这可能需要几分钟时间,请耐心等待...") + + try: + # 运行Blender脚本,传递JSON文件路径 + cmd = [ + blender_path, + "--background", # 后台运行 + "--python", script_path, + "--", # 分隔符,后面的参数会传递给Python脚本 + json_path + ] + + result = subprocess.run(cmd, capture_output=True, text=True, timeout=300) + + if result.returncode == 0: + print("✅ Blender脚本执行成功!") + print("\n输出信息:") + print(result.stdout) + + # 检查生成的文件 + expected_files = [ + "optical_system.obj", + "optical_system.glb", + "optical_system.blend", + "optical_system_render.png" + ] + + print("\n📁 生成的文件:") + for filename in expected_files: + if os.path.exists(filename): + size = os.path.getsize(filename) + print(f"✅ {filename} ({size:,} bytes)") + else: + print(f"❌ {filename} (未找到)") + + return True + else: + print("❌ Blender脚本执行失败") + print("错误输出:") + print(result.stderr) + if result.stdout: + print("标准输出:") + print(result.stdout) + return False + + except subprocess.TimeoutExpired: + print("❌ 脚本执行超时(超过5分钟)") + return False + except Exception as e: + print(f"❌ 执行时出错: {e}") + return False + +def main(): + # 设置命令行参数解析 + parser = argparse.ArgumentParser( + description="使用Blender生成3D光学系统模型", + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=""" +使用示例: + python run_blender_input.py -i data.json + python run_blender_input.py --input config.json + """ + ) + + parser.add_argument( + "-i", "--input", + required=True, + help="输入的JSON文件路径" + ) + + args = parser.parse_args() + + print("🎨 Blender 3D光学系统建模脚本") + print("=" * 40) + + if run_blender_script(args.input): + print("\n🎉 任务完成!") + print("\n您可以:") + print("1. 使用Blender打开 optical_system.blend 文件进行编辑") + print("2. 在3D软件中导入 optical_system.obj 文件") + print("3. 在Web浏览器中查看 optical_system.glb 文件") + print("4. 查看渲染图像 optical_system_render.png") + else: + print("\n❌ 任务失败,请检查错误信息") + sys.exit(1) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/toModel.py b/toModel.py index 2882b1a..c3ab4e6 100644 --- a/toModel.py +++ b/toModel.py @@ -3,6 +3,19 @@ import json import mathutils import os import bmesh +import sys + +# 获取命令行参数 +def get_json_path(): + """从命令行参数获取JSON文件路径""" + if len(sys.argv) > 5: # Blender传递的参数格式: blender --background --python script.py -- json_path + # 查找 -- 分隔符后的参数 + for i, arg in enumerate(sys.argv): + if arg == "--" and i + 1 < len(sys.argv): + return sys.argv[i + 1] + + # 如果没有找到参数,使用默认路径 + return "./e8caffb4622e03b1495bbc1ed13fce13.json" # 清空场景 bpy.ops.wm.read_factory_settings(use_empty=True) @@ -11,12 +24,23 @@ bpy.ops.wm.read_factory_settings(use_empty=True) bpy.context.scene.render.engine = 'CYCLES' # 加载 JSON 文件 -json_path = "./e8caffb4622e03b1495bbc1ed13fce13.json" -with open(json_path, 'r', encoding='utf-8') as f: - data = json.load(f) +json_path = get_json_path() +print(f"尝试加载JSON文件:{json_path}") -print(f"已加载JSON文件:{json_path}") -print(f"包含 {len(data['children'])} 个对象") +try: + with open(json_path, 'r', encoding='utf-8') as f: + data = json.load(f) + print(f"✅ 成功加载JSON文件:{json_path}") + print(f"包含 {len(data['children'])} 个对象") +except FileNotFoundError: + print(f"❌ 错误:找不到JSON文件 {json_path}") + sys.exit(1) +except json.JSONDecodeError as e: + print(f"❌ 错误:JSON文件格式错误 {e}") + sys.exit(1) +except Exception as e: + print(f"❌ 错误:加载JSON文件时出错 {e}") + sys.exit(1) # 创建金属材质 def create_metal_material():