Skip to main content
Glama
ferocknew

Fusion360 LLM Assistant

by ferocknew
common.py9.49 kB
""" Fusion360 MCP Addin 公共方法模块 """ import os import sys import logging import traceback from datetime import datetime def setup_logging(): """设置日志记录""" try: # 获取插件目录 script_dir = os.path.dirname(os.path.abspath(__file__)) log_dir = os.path.join(script_dir, 'logs') # 创建日志目录 if not os.path.exists(log_dir): os.makedirs(log_dir) # 创建日志文件名(按日期) timestamp = datetime.now().strftime('%Y%m%d_%H%M%S') log_file = os.path.join(log_dir, f'fusion360_mcp_addin_{timestamp}.log') # 配置日志器 logger = logging.getLogger('fusion360_mcp_addin') logger.setLevel(logging.DEBUG) # 清除已有的处理器 for handler in logger.handlers[:]: logger.removeHandler(handler) # 创建文件处理器 file_handler = logging.FileHandler(log_file, encoding='utf-8') file_handler.setLevel(logging.DEBUG) # 创建格式化器 formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) file_handler.setFormatter(formatter) # 添加处理器 logger.addHandler(file_handler) logger.info("=== Fusion360 MCP Addin 启动 ===") logger.info(f"日志文件: {log_file}") logger.info(f"Python 版本: {sys.version}") logger.info(f"工作目录: {os.getcwd()}") return logger except Exception as e: return None def log_safe(logger, level, message, exception=None): """安全的日志记录""" try: if logger: if exception: message = f"{message}\n异常详情: {str(exception)}\n堆栈跟踪:\n{traceback.format_exc()}" if level == 'debug': logger.debug(message) elif level == 'info': logger.info(message) elif level == 'warning': logger.warning(message) elif level == 'error': logger.error(message) elif level == 'critical': logger.critical(message) else: # 如果日志器不可用,写入临时文件 script_dir = os.path.dirname(os.path.abspath(__file__)) temp_log = os.path.join(script_dir, 'temp_error.log') with open(temp_log, 'a', encoding='utf-8') as f: timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S') f.write(f"{timestamp} - {level.upper()} - {message}\n") if exception: f.write(f"异常: {str(exception)}\n") f.write(f"堆栈: {traceback.format_exc()}\n") f.write("-" * 50 + "\n") except: pass # 即使日志记录失败也不应该影响主程序 def get_fusion360_status(app, logger=None): """获取 Fusion 360 状态""" try: if logger: log_safe(logger, 'debug', "获取 Fusion 360 状态") if not app: return {"success": False, "error": "应用未初始化"} status = { "success": True, "app_name": app.productName, "version": app.version, "active_document": None, "units": "mm" } if app.activeDocument: status["active_document"] = app.activeDocument.name if logger: log_safe(logger, 'info', f"Fusion 360 状态: {status}") return status except Exception as e: if logger: log_safe(logger, 'error', "获取 Fusion 360 状态失败", e) return {"success": False, "error": str(e)} def get_objects_safe(app, logger=None): """安全地获取对象列表""" try: if logger: log_safe(logger, 'debug', "获取对象列表") if not app or not app.activeDocument: return {"success": False, "error": "没有活动文档"} import adsk.fusion design = adsk.fusion.Design.cast(app.activeProduct) if not design: return {"success": False, "error": "当前不是设计环境"} objects = [] rootComp = design.rootComponent # 获取实体 for i, body in enumerate(rootComp.bRepBodies): if i >= 10: # 限制返回数量,避免过多数据 break objects.append({ "id": body.entityToken, "name": body.name if body.name else f"实体{i+1}", "type": "body", "visible": body.isVisible }) result = {"success": True, "objects": objects} if logger: log_safe(logger, 'info', f"获取到 {len(objects)} 个对象") return result except Exception as e: if logger: log_safe(logger, 'error', "获取对象列表失败", e) return {"success": False, "error": str(e)} def handle_document_request_safe(app, data, logger=None): """安全处理文档创建请求""" try: if logger: log_safe(logger, 'info', f"处理文档创建请求: {data}") import adsk.core parameters = data.get('parameters', {}) name = parameters.get('name', '新建文档') # 创建新文档(简化版本,避免单位设置问题) doc = app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType) if doc: doc.name = name result = {"success": True, "document_id": doc.name} if logger: log_safe(logger, 'info', f"文档创建成功: {result}") else: result = {"success": False, "error": "文档创建失败"} if logger: log_safe(logger, 'error', "文档创建失败") return result except Exception as e: if logger: log_safe(logger, 'error', "文档创建失败", e) return {"success": False, "error": str(e)} def handle_object_request_safe(app, data, logger=None): """安全处理对象创建请求""" try: if logger: log_safe(logger, 'info', f"处理对象创建请求: {data}") parameters = data.get('parameters', {}) object_type = parameters.get('type') obj_params = parameters.get('parameters', {}) # 只支持简单的圆柱体创建 if object_type == 'extrude' and obj_params.get('base_feature') == 'circle': return create_simple_cylinder_safe(app, obj_params, logger) else: result = {"success": False, "error": f"不支持的对象类型: {object_type}"} if logger: log_safe(logger, 'warning', f"不支持的对象类型: {object_type}") return result except Exception as e: if logger: log_safe(logger, 'error', "对象创建请求处理失败", e) return {"success": False, "error": str(e)} def create_simple_cylinder_safe(app, params, logger=None): """安全创建简单圆柱体""" try: if logger: log_safe(logger, 'info', f"开始创建圆柱体,参数: {params}") import adsk.core import adsk.fusion if not app or not app.activeDocument: if logger: log_safe(logger, 'error', "没有活动文档") return {"success": False, "error": "没有活动文档"} design = adsk.fusion.Design.cast(app.activeProduct) if not design: if logger: log_safe(logger, 'error', "当前不是设计环境") return {"success": False, "error": "当前不是设计环境"} if logger: log_safe(logger, 'debug', "获取根组件") rootComp = design.rootComponent # 创建草图 if logger: log_safe(logger, 'debug', "创建草图") sketches = rootComp.sketches sketch = sketches.add(rootComp.xYConstructionPlane) # 创建圆 radius = float(params.get('radius', 2.5)) if logger: log_safe(logger, 'debug', f"创建圆,半径: {radius}") center = adsk.core.Point3D.create(0, 0, 0) circle = sketch.sketchCurves.sketchCircles.addByCenterRadius(center, radius) # 创建拉伸 if logger: log_safe(logger, 'debug', "创建拉伸特征") profile = sketch.profiles.item(0) extrudes = rootComp.features.extrudeFeatures extrudeInput = extrudes.createInput(profile, adsk.fusion.FeatureOperations.NewBodyFeatureOperation) height = float(params.get('height', 5.0)) if logger: log_safe(logger, 'debug', f"设置拉伸高度: {height}") distance = adsk.core.ValueInput.createByReal(height) extrudeInput.setDistanceExtent(False, distance) if logger: log_safe(logger, 'debug', "执行拉伸操作") extrudeFeature = extrudes.add(extrudeInput) result = { "success": True, "object_id": extrudeFeature.entityToken, "type": "extrude", "parameters": params } if logger: log_safe(logger, 'info', f"圆柱体创建成功: {result}") return result except Exception as e: if logger: log_safe(logger, 'error', f"创建圆柱体失败", e) return {"success": False, "error": str(e)}

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ferocknew/fusion360_mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server