网站如何做分享,网站开发需求描述,做网站的上海公司有哪些,cc域名网站需要备案吗插件#xff1a;
https://wwamf.lanzouu.com/iOGce3f47nra
https://www.bilibili.com/video/BV1ZwiwBxELf/
有了这个插件#xff0c;就可以在ide里面为所欲为地调用blender方法了
正在连接到Blender服务器...--- 使用 exec 端点 ---
执行成功!
返回结果: obj: Cube
obj: …插件https://wwamf.lanzouu.com/iOGce3f47nrahttps://www.bilibili.com/video/BV1ZwiwBxELf/有了这个插件就可以在ide里面为所欲为地调用blender方法了正在连接到Blender服务器... --- 使用 exec 端点 --- 执行成功! 返回结果: obj: Cube obj: Light obj: Camera --- 删除所有物体 --- (E:\code\my_python_server\micromambavenv) PS E:\code\my_python_server ^C (E:\code\my_python_server\micromambavenv) PS E:\code\my_python_server (E:\code\my_python_server\micromambavenv) PS E:\code\my_python_server e:; cd e:\code\my_python_server; e:\code\my_python_server\micromambavenv\python.exe c:\Users\njsgcs\.vscode\extensions\ms-python.debugpy-2025.18.0-win32-x64\bundled\libs\debugpy\launcher 59039 -- E:\code\my_python_server\blender_cline\demo.py 正在连接到Blender服务器... --- 使用 exec 端点 --- --- 删除所有物体 --- 删除所有物体成功! 返回结果: 信息: 已删除 3 个物体 --- 创建立方体 --- (E:\code\my_python_server\micromambavenv) PS E:\code\my_python_server ^C (E:\code\my_python_server\micromambavenv) PS E:\code\my_python_server (E:\code\my_python_server\micromambavenv) PS E:\code\my_python_server e:; cd e:\code\my_python_server; e:\code\my_python_server\micromambavenv\python.exe c:\Users\njsgcs\.vscode\extensions\ms-python.debugpy-2025.18.0-win32-x64\bundled\libs\debugpy\launcher 50734 -- E:\code\my_python_server\blender_cline\demo.py 正在连接到Blender服务器... --- 使用 exec 端点 --- --- 删除所有物体 --- --- 创建立方体 --- 立方体创建成功! 返回结果: Code executed successfullyimport requests import json def call_blender_api(endpoint, code): 调用Blender API执行代码 url fhttp://localhost:8080{endpoint} payload { code: code } try: response requests.post(url, jsonpayload) return response.json() except requests.exceptions.RequestException as e: print(f请求错误: {e}) return None def get_all_objects(): 获取当前场景中的所有物体并打印名称 # 您提供的代码 code import bpy # 获取当前场景中的所有物体 all_objects bpy.context.scene.objects # 打印每个物体的名称 result [] for obj in all_objects: obj_info fobj: {obj.name} result.append(obj_info) print(obj_info) result # 使用 /api/exec 端点执行代码块 response call_blender_api(/api/exec, code) if response: if response[status] success: print(执行成功!) print(返回结果:, response[result]) else: print(执行失败:, response[message]) else: print(无法连接到Blender服务器) def delete_all_objects(): 删除当前场景中的所有物体 code import bpy # 选择所有对象 bpy.ops.object.select_all(actionSELECT) # 删除选中的对象 bpy.ops.object.delete() 所有物体已删除 # 使用 /api/exec 端点执行代码块 response call_blender_api(/api/exec, code) if response: if response[status] success: print(删除所有物体成功!) print(返回结果:, response[result]) else: print(删除失败:, response[message]) else: print(无法连接到Blender服务器) def create_cube(): 在Blender场景中创建一个立方体 code import bpy # 添加一个立方体 bpy.ops.mesh.primitive_cube_add( location(0, 0, 0) # 设置立方体的位置 ) # 获取新创建的立方体对象 cube bpy.context.active_object cube.name MyCube # 重命名立方体 f立方体已创建名称: {cube.name} # 使用 /api/exec 端点执行代码块 response call_blender_api(/api/exec, code) if response: if response[status] success: print(立方体创建成功!) print(返回结果:, response[result]) else: print(创建失败:, response[message]) else: print(无法连接到Blender服务器) if __name__ __main__: # 确保Blender服务器正在运行 print(正在连接到Blender服务器...) # 方法1: 使用exec端点执行完整代码块推荐 print(\n--- 使用 exec 端点 ---) #get_all_objects() # 示例删除所有物体 print(\n--- 删除所有物体 ---) #delete_all_objects() print(\n--- 创建立方体 ---) create_cube()# __init__.py Blender API Server Plugin Blender API服务器插件允许通过HTTP API控制Blender import bpy import sys import os from bpy.props import IntProperty, StringProperty, BoolProperty from bpy.types import AddonPreferences, Operator, Panel # 将当前目录添加到Python路径 blender_api_dir os.path.dirname(__file__) if blender_api_dir not in sys.path: sys.path.insert(0, blender_api_dir) # 导入API模块 from .api import init_blender_server, stop_blender_server_timer, is_server_running_timer bl_info { name: exec Server, author: Your Name, version: (1, 0, 0), blender: (2, 80, 0), location: View3D Sidebar API Server, description: 提供HTTP API接口来控制Blender, warning: , doc_url: , category: Development, } class BLENDER_API_PT_server_panel(Panel): API服务器控制面板 bl_label API Server bl_idname BLENDER_API_PT_server_panel bl_space_type VIEW_3D bl_region_type UI bl_category API Server def draw(self, context): layout self.layout scene context.scene # 服务器状态 col layout.column() if is_server_running_timer(): col.label(textServer Status: Running, iconCHECKMARK) else: col.label(textServer Status: Stopped, iconX) # 服务器控制按钮 col.separator() row col.row() if is_server_running_timer(): row.operator(blender_api.stop_server, textStop Server, iconX) else: row.operator(blender_api.start_server, textStart Server, iconPLAY) # 服务器信息 col.separator() col.label(textServer Info:) col.label(textHost: localhost) col.label(textPort: 8080) col.label(textEndpoints:) col.label(text - POST /api/eval) col.label(text - POST /api/exec) col.label(text - POST /api/clear_scene) class BLENDER_API_OT_start_server(Operator): 启动API服务器 bl_idname blender_api.start_server bl_label Start API Server bl_description 启动HTTP API服务器 def execute(self, context): success init_blender_server() if success: self.report({INFO}, API Server started successfully) else: self.report({ERROR}, Failed to start API Server) return {FINISHED} class BLENDER_API_OT_stop_server(Operator): 停止API服务器 bl_idname blender_api.stop_server bl_label Stop API Server bl_description 停止HTTP API服务器 def execute(self, context): from .api import stop_blender_server_timer stop_blender_server_timer() self.report({INFO}, API Server stopped) return {FINISHED} classes ( BLENDER_API_PT_server_panel, BLENDER_API_OT_start_server, BLENDER_API_OT_stop_server, ) def register(): 注册插件 from .api import register as api_register api_register() # 调用API模块的注册函数 for cls in classes: bpy.utils.register_class(cls) def unregister(): 注销插件 from .api import unregister as api_unregister api_unregister() # 调用API模块的注销函数 for cls in reversed(classes): bpy.utils.unregister_class(cls) if __name__ __main__: register()import bpy import sys import json import ast from http.server import BaseHTTPRequestHandler import threading import socket from io import StringIO import select import errno from urllib.parse import urlparse, parse_qs class BlenderAPIHandler: def __init__(self, request_data, client_socket, address): self.request_data request_data self.client_socket client_socket self.address address # 解析请求 self.parse_request() def parse_request(self): 解析HTTP请求 request_str self.request_data.decode(utf-8) lines request_str.split(\r\n) # 解析请求行 request_line lines[0] parts request_line.split( ) self.method parts[0] self.path parts[1] # 解析头部 self.headers {} i 1 while i len(lines) and lines[i] ! : header_line lines[i] if : in header_line: key, value header_line.split(:, 1) self.headers[key.strip().lower()] value.strip() i 1 # 提取请求体 body_start request_str.find(\r\n\r\n) 4 self.body request_str[body_start:] if body_start 3 else def handle_request(self): 处理请求 if self.method POST: if self.path /api/eval: self.handle_eval() elif self.path /api/exec: self.handle_exec() else: self.send_response(404, {status: error, message: Endpoint not found}) else: self.send_response(405, {status: error, message: Method not allowed}) def handle_eval(self): 处理eval请求 try: request_data json.loads(self.body) code_string request_data.get(code, ) if not code_string: response {status: error, message: No code provided} else: # 执行代码并捕获结果 result self.execute_blender_code(code_string) response {status: success, result: result} except json.JSONDecodeError: response {status: error, message: Invalid JSON format} except Exception as e: response {status: error, message: str(e)} self.send_response(200, response) def handle_exec(self): 处理exec请求 try: request_data json.loads(self.body) code_string request_data.get(code, ) if not code_string: response {status: error, message: No code provided} else: # 使用exec执行代码块 result self.execute_blender_code_exec(code_string) response {status: success, result: result} except json.JSONDecodeError: response {status: error, message: Invalid JSON format} except Exception as e: response {status: error, message: str(e)} self.send_response(200, response) def execute_blender_code(self, code_string): 执行Blender代码字符串用于单个表达式 try: # 验证语法 try: parsed ast.parse(code_string, modeeval) except SyntaxError as e: raise Exception(fSyntax error in code: {str(e)}) # 完全开放的执行环境 result eval(code_string) return result except Exception as e: raise Exception(fError executing code: {str(e)}) def execute_blender_code_exec(self, code_string): 使用exec执行Blender代码块 try: # 验证语法 try: parsed ast.parse(code_string) except SyntaxError as e: raise Exception(fSyntax error in code: {str(e)}) # 捕获print输出 captured_output StringIO() old_stdout sys.stdout sys.stdout captured_output try: # 完全开放的执行环境 exec(code_string) finally: # 恢复标准输出 sys.stdout old_stdout # 返回捕获的输出 output captured_output.getvalue() return output if output else Code executed successfully except Exception as e: raise Exception(fError executing code: {str(e)}) def send_response(self, status_code, data): 发送HTTP响应 try: response_body json.dumps(data, defaultstr) response_headers [ fHTTP/1.1 {status_code} OK, Content-Type: application/json, fContent-Length: {len(response_body)}, Connection: close, \r\n ] response_str \r\n.join(response_headers) response_body self.client_socket.send(response_str.encode()) except Exception as e: print(fError sending response: {e}) class BlenderHTTPServer: 纯socket实现的HTTP服务器 def __init__(self, hostlocalhost, port8080): self.host host self.port port self.socket None self.running False def start(self): 启动服务器 if self.running: print(Server already running) return False try: # 创建非阻塞socket self.socket socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.socket.bind((self.host, self.port)) self.socket.listen(5) self.socket.setblocking(False) # 设置为非阻塞模式 self.running True print(fBlender API server running on {self.host}:{self.port}) # 注册定时器函数 bpy.app.timers.register(self._handle_requests, persistentTrue) return True except Exception as e: print(fFailed to start server: {e}) return False def _handle_requests(self): 处理HTTP请求的定时器函数 if not self.running: return None # 停止定时器 try: # 检查是否有新的连接 ready, _, _ select.select([self.socket], [], [], 0) # 非阻塞检查 if ready: client_socket, address self.socket.accept() # 设置客户端socket为非阻塞模式 client_socket.setblocking(False) # 读取请求数据 request_data self._read_request(client_socket) if request_data: # 创建处理线程 thread threading.Thread( targetself._process_request_data, args(request_data, client_socket, address) ) thread.daemon True thread.start() except socket.error as e: if e.errno ! errno.EAGAIN and e.errno ! errno.EWOULDBLOCK: print(fSocket error: {e}) except Exception as e: print(fError handling requests: {e}) # 每0.1秒调用一次 return 0.1 def _read_request(self, client_socket): 读取HTTP请求数据 try: # 首先尝试接收数据 data b while True: try: chunk client_socket.recv(1024) if not chunk: break data chunk # 检查是否接收到了完整的HTTP头部 if b\r\n\r\n in data: # 解析Content-Length头部 header_end data.find(b\r\n\r\n) headers data[:header_end].decode(utf-8) content_length 0 for line in headers.split(\r\n): if line.lower().startswith(content-length:): content_length int(line.split(:)[1].strip()) break # 检查是否接收了完整的请求体 body_start header_end 4 if len(data) body_start content_length: break except socket.error as e: if e.errno errno.EWOULDBLOCK or e.errno errno.EAGAIN: # 非阻塞模式下暂时没有数据 break else: raise e return data except Exception as e: print(fError reading request: {e}) return None def _process_request_data(self, request_data, client_socket, address): 处理请求数据 try: # 创建处理器 handler BlenderAPIHandler(request_data, client_socket, address) # 在主线程上调度执行 def execute_on_main_thread(): handler.handle_request() return None # 停止定时器 bpy.app.timers.register(execute_on_main_thread, first_interval0.0) except Exception as e: print(fError processing request: {e}) def stop(self): 停止服务器 self.running False if self.socket: self.socket.close() self.socket None print(Server stopped) # 全局服务器实例 blender_timer_server None def start_blender_server_with_timer(port8080): 启动使用Blender定时器的服务器 global blender_timer_server if blender_timer_server is None: blender_timer_server BlenderHTTPServer(portport) return blender_timer_server.start() def stop_blender_server_timer(): 停止使用定时器的服务器 global blender_timer_server if blender_timer_server: blender_timer_server.stop() blender_timer_server None def is_server_running_timer(): 检查使用定时器的服务器是否正在运行 global blender_timer_server return blender_timer_server is not None and blender_timer_server.running def init_blender_server(): 在Blender中初始化服务器使用定时器方式 success start_blender_server_with_timer(8080) if success: print(Blender server initialized with timer and running in background) return True else: print(Failed to initialize Blender server) return False # Blender插件兼容代码 def register(): 注册到Blender用于插件 init_blender_server() def unregister(): 从Blender取消注册用于插件 stop_blender_server_timer() if __name__ __main__: # 直接运行时模拟Blender环境 print(Starting server in timer mode...) start_blender_server_with_timer(8080) # 保持运行 try: import time while True: time.sleep(1) except KeyboardInterrupt: print(Shutting down...) stop_blender_server_timer()