blenderpython/suw_core/command_dispatcher.py

671 lines
24 KiB
Python
Raw Normal View History

2025-08-01 17:13:30 +08:00
#!/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"}