671 lines
24 KiB
Python
671 lines
24 KiB
Python
#!/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"}
|