#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ SUW Core - Command Dispatcher Module 拆分自: suw_impl.py (剩余所有命令方法) 用途: 命令分发器、选择管理、显示控制、辅助功能 版本: 1.0.0 作者: SUWood Team """ from .geometry_utils import MAT_TYPE_OBVERSE, MAT_TYPE_NORMAL, MAT_TYPE_NATURE from .dimension_manager import dimension_manager from .data_manager import data_manager, get_data_manager from .door_drawer_manager import door_drawer_manager from .hardware_manager import hardware_manager from .deletion_manager import deletion_manager from .selection_manager import selection_manager from .machining_manager import machining_manager from .part_creator import part_creator from .material_manager import material_manager from .memory_manager import memory_manager import logging from typing import Dict, Any, Optional # 设置日志 logger = logging.getLogger(__name__) # 检查Blender可用性 try: import bpy BLENDER_AVAILABLE = True except ImportError: BLENDER_AVAILABLE = False # 导入依赖模块 # ==================== 命令分发器类 ==================== class CommandDispatcher: """命令分发器 - 负责所有命令分发和控制操作""" def __init__(self): """ 初始化命令分发器 - 完全独立,不依赖suw_impl """ # 使用全局数据管理器 self.data_manager = get_data_manager() self.selected_parts = set() self.mat_type = MAT_TYPE_NORMAL # 命令映射表 self.command_map = { 'c00': self.c00, 'c01': self.c01, 'c02': self.c02, 'c03': self.c03, 'c04': self.c04, 'c05': self.c05, 'c07': self.c07, 'c08': self.c08, 'c09': self.c09, 'c0a': self.c0a, 'c0c': self.c0c, 'c0d': self.c0d, 'c0e': self.c0e, 'c0f': self.c0f, 'c10': self.c10, 'c11': self.c11, 'c12': self.c12, 'c13': self.c13, 'c14': self.c14, 'c15': self.c15, 'c16': self.c16, 'c17': self.c17, 'c18': self.c18, 'c1a': self.c1a, 'c1b': self.c1b, 'c23': self.c23, 'c24': self.c24, 'c25': self.c25, 'c28': self.c28, 'c30': self.c30, 'set_config': self.set_config, } logger.info("CommandDispatcher 初始化完成") # ==================== 材质控制命令 ==================== def c11(self, data: Dict[str, Any]): """part_obverse - 设置零件正面显示""" try: # 【修复】调用材质管理器的c11方法 from .material_manager import material_manager, init_material_manager if not material_manager: init_material_manager() from .material_manager import material_manager if material_manager: return material_manager.c11(data) else: logger.warning("MaterialManager 初始化失败") return None except Exception as e: logger.error(f"设置零件正面显示失败: {e}") return None def c30(self, data: Dict[str, Any]): """part_nature - 设置零件自然显示""" try: # 【修复】调用材质管理器的c30方法 from .material_manager import material_manager, init_material_manager if not material_manager: init_material_manager() from .material_manager import material_manager if material_manager: return material_manager.c30(data) else: logger.warning("MaterialManager 初始化失败") return None except Exception as e: logger.error(f"设置零件自然显示失败: {e}") return None def _is_selected_part(self, part): """检查零件是否被选中""" return part in self.selected_parts # ==================== 核心功能命令 ==================== def c02(self, data: Dict[str, Any]): """add_texture - 添加纹理""" try: # 【修复】直接检查全局变量,如果为None就创建 from .material_manager import material_manager, init_material_manager if not material_manager: init_material_manager() from .material_manager import material_manager if material_manager: return material_manager.c02(data) else: logger.warning("MaterialManager 初始化失败") return None except Exception as e: logger.warning(f"MaterialManager 初始化失败: {e}") return None def c04(self, data: Dict[str, Any]): """add_part - 添加部件""" try: from .part_creator import part_creator, init_part_creator if not part_creator: init_part_creator() from .part_creator import part_creator if part_creator: return part_creator.c04(data) else: logger.warning("PartCreator 初始化失败") return None except Exception as e: logger.warning(f"PartCreator 初始化失败: {e}") return None def c05(self, data: Dict[str, Any]): """add_machining - 添加加工""" try: from .machining_manager import machining_manager, init_machining_manager if not machining_manager: init_machining_manager() from .machining_manager import machining_manager if machining_manager: return machining_manager.c05(data) else: logger.warning("MachiningManager 初始化失败") return None except Exception as e: logger.warning(f"MachiningManager 初始化失败: {e}") return None def c07(self, data: Dict[str, Any]): """add_dimension - 添加尺寸标注""" try: from .dimension_manager import dimension_manager, init_dimension_manager if not dimension_manager: init_dimension_manager() from .dimension_manager import dimension_manager if dimension_manager: return dimension_manager.c07(data) else: logger.warning("DimensionManager 初始化失败") return None except Exception as e: logger.warning(f"DimensionManager 初始化失败: {e}") return None def c08(self, data: Dict[str, Any]): """add_hardware - 添加五金""" try: from .hardware_manager import hardware_manager, init_hardware_manager if not hardware_manager: init_hardware_manager() from .hardware_manager import hardware_manager if hardware_manager: return hardware_manager.c08(data) else: logger.warning("HardwareManager 初始化失败") return None except Exception as e: logger.warning(f"HardwareManager 初始化失败: {e}") return None def c09(self, data: Dict[str, Any]): """del_entity - 删除实体""" try: from .deletion_manager import deletion_manager, init_deletion_manager if not deletion_manager: init_deletion_manager() from .deletion_manager import deletion_manager if deletion_manager: return deletion_manager.c09(data) else: logger.warning("DeletionManager 初始化失败") return None except Exception as e: logger.warning(f"DeletionManager 初始化失败: {e}") return None def c0a(self, data: Dict[str, Any]): """del_machining - 删除加工""" try: logger.info("删除加工") from .machining_manager import machining_manager, init_machining_manager if not machining_manager: init_machining_manager() from .machining_manager import machining_manager if machining_manager: return machining_manager.c0a(data) else: logger.warning("MachiningManager 初始化失败") return None except Exception as e: logger.error(f"删除加工失败: {e}") return None def c0c(self, data: Dict[str, Any]): """del_dimension - 删除尺寸标注""" try: logger.info("删除尺寸标注") # 【修复】应该路由到DimensionManager而不是DeletionManager from .dimension_manager import dimension_manager, init_dimension_manager if not dimension_manager: init_dimension_manager() from .dimension_manager import dimension_manager if dimension_manager: return dimension_manager.c0c(data) else: logger.warning("DimensionManager 初始化失败") return None except Exception as e: logger.error(f"c0c命令执行失败: {e}") return None def c03(self, data: Dict[str, Any]): """add_zone - 添加区域""" try: from .deletion_manager import deletion_manager, init_deletion_manager if not deletion_manager: init_deletion_manager() from .deletion_manager import deletion_manager if deletion_manager: return deletion_manager.c03(data) else: logger.warning("DeletionManager 初始化失败") return None except Exception as e: logger.warning(f"DeletionManager 初始化失败: {e}") return None # ==================== 选择和导航命令 ==================== def c15(self, data: Dict[str, Any]): """sel_unit - 显示框架 / 清除选择状态""" try: from .selection_manager import selection_manager, init_selection_manager if not selection_manager: init_selection_manager() from .selection_manager import selection_manager if selection_manager: return selection_manager.c15(data) else: logger.warning("SelectionManager 初始化失败") return None except Exception as e: logger.error(f"c15命令执行失败: {e}") return None def c16(self, data: Dict[str, Any]): """sel_zone - 选择区域""" try: from .selection_manager import selection_manager, init_selection_manager if not selection_manager: init_selection_manager() from .selection_manager import selection_manager if selection_manager: return selection_manager.c16(data) else: logger.warning("SelectionManager 初始化失败") return None except Exception as e: logger.warning(f"SelectionManager 初始化失败: {e}") return None def c17(self, data: Dict[str, Any]): """sel_elem - 选择元素""" try: from .selection_manager import selection_manager, init_selection_manager if not selection_manager: init_selection_manager() from .selection_manager import selection_manager if selection_manager: return selection_manager.c17(data) else: logger.warning("SelectionManager 初始化失败") return None except Exception as e: logger.warning(f"SelectionManager 初始化失败: {e}") return None # ==================== 模式切换命令 ==================== def c10(self, data: Dict[str, Any]): """set_doorinfo - 设置门信息""" try: logger.info("设置门信息") from .door_drawer_manager import door_drawer_manager, init_door_drawer_manager if not door_drawer_manager: init_door_drawer_manager() from .door_drawer_manager import door_drawer_manager if door_drawer_manager: return door_drawer_manager.c10(data) else: logger.warning("DoorDrawerManager 初始化失败") return None except Exception as e: logger.error(f"设置门信息失败: {e}") return None def c1a(self, data: Dict[str, Any]): """open_doors - 打开门板""" try: logger.info("打开门板") from .door_drawer_manager import door_drawer_manager, init_door_drawer_manager if not door_drawer_manager: init_door_drawer_manager() from .door_drawer_manager import door_drawer_manager if door_drawer_manager: return door_drawer_manager.c1a(data) else: logger.warning("DoorDrawerManager 初始化失败") return None except Exception as e: logger.error(f"打开门板失败: {e}") return None def c1b(self, data: Dict[str, Any]): """slide_drawers - 打开抽屉""" try: logger.info("打开抽屉") from .door_drawer_manager import door_drawer_manager, init_door_drawer_manager if not door_drawer_manager: init_door_drawer_manager() from .door_drawer_manager import door_drawer_manager if door_drawer_manager: return door_drawer_manager.c1b(data) else: logger.warning("DoorDrawerManager 初始化失败") return None except Exception as e: logger.error(f"打开抽屉失败: {e}") return None # ==================== 控制命令 ==================== def c18(self, data: Dict[str, Any]): """hide_door - 隐藏门板""" try: logger.info("隐藏门板") from .door_drawer_manager import door_drawer_manager, init_door_drawer_manager if not door_drawer_manager: init_door_drawer_manager() from .door_drawer_manager import door_drawer_manager if door_drawer_manager: return door_drawer_manager.c18(data) else: logger.warning("DoorDrawerManager 初始化失败") return None except Exception as e: logger.error(f"隐藏门板失败: {e}") return None def c28(self, data: Dict[str, Any]): """hide_drawer - 隐藏抽屉""" try: logger.info("隐藏抽屉") from .door_drawer_manager import door_drawer_manager, init_door_drawer_manager if not door_drawer_manager: init_door_drawer_manager() from .door_drawer_manager import door_drawer_manager if door_drawer_manager: return door_drawer_manager.c28(data) else: logger.warning("DoorDrawerManager 初始化失败") return None except Exception as e: logger.error(f"隐藏抽屉失败: {e}") return None def c0f(self, data: Dict[str, Any]): """refresh_view - 刷新视图""" try: logger.info("刷新视图") # 刷新Blender视图 from .selection_manager import get_selection_manager sm = get_selection_manager() if sm: return sm.view_front_and_zoom_extents() except Exception as e: logger.error(f"刷新视图失败: {e}") # ==================== 图层控制命令 ==================== def c23(self, data: Dict[str, Any]): """hide_layer - 隐藏图层""" try: layer_name = data.get("layer") logger.info(f"隐藏图层: {layer_name}") if BLENDER_AVAILABLE and layer_name: # 隐藏指定图层 if hasattr(bpy.data, 'collections') and layer_name in bpy.data.collections: collection = bpy.data.collections[layer_name] collection.hide_viewport = True except Exception as e: logger.error(f"隐藏图层失败: {e}") def c24(self, data: Dict[str, Any]): """show_layer - 显示图层""" try: layer_name = data.get("layer") logger.info(f"显示图层: {layer_name}") if BLENDER_AVAILABLE and layer_name: # 显示指定图层 if hasattr(bpy.data, 'collections') and layer_name in bpy.data.collections: collection = bpy.data.collections[layer_name] collection.hide_viewport = False except Exception as e: logger.error(f"显示图层失败: {e}") def c25(self, data: Dict[str, Any]): """toggle_layer - 切换图层""" try: layer_name = data.get("layer") logger.info(f"切换图层: {layer_name}") if BLENDER_AVAILABLE and layer_name: # 切换指定图层显示状态 if hasattr(bpy.data, 'collections') and layer_name in bpy.data.collections: collection = bpy.data.collections[layer_name] collection.hide_viewport = not collection.hide_viewport except Exception as e: logger.error(f"切换图层失败: {e}") # ==================== 视图控制命令 ==================== def c00(self, data: Dict[str, Any]): """zoom_extents - 缩放到全部""" try: logger.info("缩放到全部") if BLENDER_AVAILABLE: # 缩放到所有对象 bpy.ops.view3d.view_all() except Exception as e: logger.error(f"缩放到全部失败: {e}") def c01(self, data: Dict[str, Any]): """zoom_selection - 缩放到选择""" try: logger.info("缩放到选择") if BLENDER_AVAILABLE: # 缩放到选中对象 bpy.ops.view3d.view_selected() except Exception as e: logger.error(f"缩放到选择失败: {e}") # ==================== 保存和导出命令 ==================== def c12(self, data: Dict[str, Any]): """create_contour - 创建轮廓""" try: logger.info("创建轮廓") from .dimension_manager import dimension_manager, init_dimension_manager if not dimension_manager: init_dimension_manager() from .dimension_manager import dimension_manager if dimension_manager: return dimension_manager.c12(data) else: logger.warning("DimensionManager 初始化失败") return None except Exception as e: logger.error(f"创建轮廓失败: {e}") def c13(self, data: Dict[str, Any]): """save_pixmap - 保存图像""" try: logger.info("保存图像") # 图像保存功能暂时简化 return True except Exception as e: logger.error(f"保存图像失败: {e}") def c14(self, data: Dict[str, Any]): """pre_save_pixmap - 预保存图像""" try: logger.info("预保存图像") # 预保存功能暂时简化 return True except Exception as e: logger.error(f"预保存图像失败: {e}") # ==================== 标注和显示命令 ==================== def c0d(self, data: Dict[str, Any]): """parts_seqs - 设置零件序列信息""" try: from .explosion_manager import explosion_manager, init_explosion_manager if not explosion_manager: init_explosion_manager() from .explosion_manager import explosion_manager if explosion_manager: return explosion_manager.c0d(data) else: logger.warning("ExplosionManager 初始化失败") return None except Exception as e: logger.warning(f"ExplosionManager 初始化失败: {e}") return None def c0e(self, data: Dict[str, Any]): """explode_zones - 炸开柜体""" try: from .explosion_manager import explosion_manager, init_explosion_manager if not explosion_manager: init_explosion_manager() from .explosion_manager import explosion_manager if explosion_manager: return explosion_manager.c0e(data) else: logger.warning("ExplosionManager 初始化失败") return None except Exception as e: logger.warning(f"ExplosionManager 初始化失败: {e}") return None # ==================== 分发器方法 ==================== def dispatch_command(self, command: str, data: Dict[str, Any]): """分发命令到相应的处理器""" try: if command in self.command_map: handler = self.command_map[command] return handler(data) else: logger.warning(f"未知命令: {command}") return None except Exception as e: logger.error(f"命令分发失败 {command}: {e}") return None def get_dispatcher_stats(self) -> Dict[str, Any]: """获取分发器统计信息""" try: stats = { "manager_type": "CommandDispatcher", "available_commands": list(self.command_map.keys()), "command_count": len(self.command_map), "mat_type": getattr(self, 'mat_type', MAT_TYPE_NORMAL), "selected_parts_count": len(self.selected_parts), "blender_available": BLENDER_AVAILABLE } return stats except Exception as e: logger.error(f"获取分发器统计失败: {e}") return {"error": str(e)} def set_config(self, data: dict): """全局/单元配置命令""" try: from .selection_manager import selection_manager, init_selection_manager if not selection_manager: init_selection_manager() from .selection_manager import selection_manager if selection_manager: return selection_manager.set_config(data) else: logger.warning("SelectionManager 初始化失败") return None except Exception as e: logger.error(f"set_config命令执行失败: {e}") return None # ==================== 模块实例 ==================== # 全局实例,将由SUWImpl初始化时设置 command_dispatcher = None def init_command_dispatcher(): """初始化命令分发器 - 不再需要suw_impl参数""" global command_dispatcher command_dispatcher = CommandDispatcher() return command_dispatcher def get_command_dispatcher(): """获取命令分发器实例""" global command_dispatcher if command_dispatcher is None: command_dispatcher = init_command_dispatcher() return command_dispatcher def get_dispatcher_stats(): """获取命令分发器统计信息""" if command_dispatcher: return command_dispatcher.get_dispatcher_stats() return {"error": "CommandDispatcher not initialized"}