317 lines
9.0 KiB
Python
317 lines
9.0 KiB
Python
|
#!/usr/bin/env python3
|
|||
|
# -*- coding: utf-8 -*-
|
|||
|
"""
|
|||
|
SUW Observer - Python翻译版本
|
|||
|
原文件: SUWObserver.rb
|
|||
|
用途: 观察者类,监听Blender中的事件
|
|||
|
"""
|
|||
|
|
|||
|
from typing import Optional, List, Any
|
|||
|
|
|||
|
try:
|
|||
|
import bpy
|
|||
|
from bpy.app.handlers import persistent
|
|||
|
BLENDER_AVAILABLE = True
|
|||
|
except ImportError:
|
|||
|
BLENDER_AVAILABLE = False
|
|||
|
# 定义一个假的persistent装饰器
|
|||
|
|
|||
|
def persistent(func):
|
|||
|
return func
|
|||
|
print("⚠️ Blender API 不可用,观察者功能将被禁用")
|
|||
|
|
|||
|
|
|||
|
class SUWToolsObserver:
|
|||
|
"""工具观察者类 - 监听工具变化"""
|
|||
|
|
|||
|
cloned_zone = None
|
|||
|
|
|||
|
def __init__(self):
|
|||
|
self.current_tool = None
|
|||
|
|
|||
|
def on_active_tool_changed(self, context, tool_name: str, tool_id: int):
|
|||
|
"""当活动工具改变时调用"""
|
|||
|
try:
|
|||
|
from .suw_core import get_selection_manager
|
|||
|
|
|||
|
# 工具ID常量(对应SketchUp的工具ID)
|
|||
|
MOVE_TOOL_ID = 21048
|
|||
|
ROTATE_TOOL_ID = 21129
|
|||
|
SCALE_TOOL_ID = 21236
|
|||
|
|
|||
|
selection_manager = get_selection_manager()
|
|||
|
if tool_id == SCALE_TOOL_ID:
|
|||
|
# 注意:这里需要根据实际需求调用相应的方法
|
|||
|
# 暂时使用sel_clear作为替代
|
|||
|
selection_manager.sel_clear()
|
|||
|
else:
|
|||
|
# 暂时使用sel_clear作为替代
|
|||
|
selection_manager.sel_clear()
|
|||
|
|
|||
|
except ImportError:
|
|||
|
print(f"工具变化: {tool_name} (ID: {tool_id})")
|
|||
|
|
|||
|
|
|||
|
class SUWSelectionObserver:
|
|||
|
"""选择观察者类 - 监听选择变化"""
|
|||
|
|
|||
|
def __init__(self):
|
|||
|
self.last_selection = []
|
|||
|
|
|||
|
def on_selection_bulk_change(self, selection: List[Any]):
|
|||
|
"""当选择批量改变时调用"""
|
|||
|
try:
|
|||
|
from .suw_core import get_selection_manager
|
|||
|
from .suw_client import set_cmd
|
|||
|
|
|||
|
selection_manager = get_selection_manager()
|
|||
|
|
|||
|
if len(selection) <= 0:
|
|||
|
# 检查是否有订单ID且之前有选择
|
|||
|
if self._has_order_id() and selection_manager.selected_uid():
|
|||
|
set_cmd("r01", {}) # 切换到订单编辑界面
|
|||
|
|
|||
|
selection_manager.sel_clear() # 清除数据
|
|||
|
return
|
|||
|
|
|||
|
# 过滤SUWood对象
|
|||
|
suw_objs = self._filter_suw_objects(selection)
|
|||
|
|
|||
|
if not suw_objs:
|
|||
|
if self._has_order_id() and selection_manager.selected_uid():
|
|||
|
set_cmd("r01", {})
|
|||
|
selection_manager.sel_clear()
|
|||
|
|
|||
|
elif len(suw_objs) == 1:
|
|||
|
# 选择单个SUWood对象
|
|||
|
self._clear_selection()
|
|||
|
selection_manager.sel_local(suw_objs[0])
|
|||
|
|
|||
|
except ImportError:
|
|||
|
print(f"选择变化: {len(selection)} 个对象")
|
|||
|
|
|||
|
def _filter_suw_objects(self, selection: List[Any]) -> List[Any]:
|
|||
|
"""过滤SUWood对象"""
|
|||
|
suw_objs = []
|
|||
|
|
|||
|
for obj in selection:
|
|||
|
if self._is_suw_object(obj):
|
|||
|
suw_objs.append(obj)
|
|||
|
|
|||
|
return suw_objs
|
|||
|
|
|||
|
def _is_suw_object(self, obj: Any) -> bool:
|
|||
|
"""检查是否是SUWood对象"""
|
|||
|
if not BLENDER_AVAILABLE:
|
|||
|
return False
|
|||
|
|
|||
|
# 检查对象是否有SUWood属性
|
|||
|
return (
|
|||
|
obj and
|
|||
|
hasattr(obj, 'get') and
|
|||
|
obj.get("uid") is not None
|
|||
|
)
|
|||
|
|
|||
|
def _has_order_id(self) -> bool:
|
|||
|
"""检查是否有订单ID"""
|
|||
|
if not BLENDER_AVAILABLE:
|
|||
|
return False
|
|||
|
|
|||
|
scene = bpy.context.scene
|
|||
|
return scene.get("order_id") is not None
|
|||
|
|
|||
|
def _clear_selection(self):
|
|||
|
"""清除选择"""
|
|||
|
if BLENDER_AVAILABLE:
|
|||
|
bpy.ops.object.select_all(action='DESELECT')
|
|||
|
|
|||
|
|
|||
|
class SUWModelObserver:
|
|||
|
"""模型观察者类 - 监听模型事件"""
|
|||
|
|
|||
|
def on_save_model(self, context):
|
|||
|
"""当模型保存时调用"""
|
|||
|
try:
|
|||
|
from .suw_client import set_cmd
|
|||
|
from .suw_constants import SUWood
|
|||
|
|
|||
|
if not BLENDER_AVAILABLE:
|
|||
|
return
|
|||
|
|
|||
|
scene = bpy.context.scene
|
|||
|
order_id = scene.get("order_id")
|
|||
|
|
|||
|
if order_id is None:
|
|||
|
return
|
|||
|
|
|||
|
params = {
|
|||
|
"method": SUWood.SUSceneSave,
|
|||
|
"order_id": order_id
|
|||
|
}
|
|||
|
set_cmd("r00", params)
|
|||
|
|
|||
|
except ImportError:
|
|||
|
print("模型保存事件")
|
|||
|
|
|||
|
|
|||
|
class SUWAppObserver:
|
|||
|
"""应用观察者类 - 监听应用级事件"""
|
|||
|
|
|||
|
def __init__(self):
|
|||
|
self.tools_observer = SUWToolsObserver()
|
|||
|
self.selection_observer = SUWSelectionObserver()
|
|||
|
self.model_observer = SUWModelObserver()
|
|||
|
|
|||
|
def on_new_model(self, context):
|
|||
|
"""当新建模型时调用"""
|
|||
|
try:
|
|||
|
from .suw_core import init_all_managers
|
|||
|
from .suw_client import set_cmd
|
|||
|
from .suw_constants import SUWood
|
|||
|
|
|||
|
# 初始化所有管理器
|
|||
|
init_all_managers()
|
|||
|
|
|||
|
# 注册观察者
|
|||
|
self._register_observers()
|
|||
|
|
|||
|
params = {
|
|||
|
"method": SUWood.SUSceneNew
|
|||
|
}
|
|||
|
set_cmd("r00", params)
|
|||
|
|
|||
|
except ImportError:
|
|||
|
print("新建模型事件")
|
|||
|
|
|||
|
def on_open_model(self, context, filepath: str):
|
|||
|
"""当打开模型时调用"""
|
|||
|
try:
|
|||
|
from .suw_core import init_all_managers
|
|||
|
from .suw_client import set_cmd
|
|||
|
from .suw_constants import SUWood
|
|||
|
|
|||
|
# 初始化所有管理器
|
|||
|
init_all_managers()
|
|||
|
|
|||
|
# 注册观察者
|
|||
|
self._register_observers()
|
|||
|
|
|||
|
if not BLENDER_AVAILABLE:
|
|||
|
return
|
|||
|
|
|||
|
scene = bpy.context.scene
|
|||
|
order_id = scene.get("order_id")
|
|||
|
|
|||
|
# 如果有订单ID,清除相关实体
|
|||
|
if order_id is not None:
|
|||
|
self._clear_suw_entities()
|
|||
|
|
|||
|
params = {
|
|||
|
"method": SUWood.SUSceneOpen
|
|||
|
}
|
|||
|
if order_id is not None:
|
|||
|
params["order_id"] = order_id
|
|||
|
|
|||
|
set_cmd("r00", params)
|
|||
|
|
|||
|
except ImportError:
|
|||
|
print(f"打开模型事件: {filepath}")
|
|||
|
|
|||
|
def _register_observers(self):
|
|||
|
"""注册观察者"""
|
|||
|
if BLENDER_AVAILABLE:
|
|||
|
# 在Blender中注册相关的处理器
|
|||
|
self._register_handlers()
|
|||
|
|
|||
|
def _register_handlers(self):
|
|||
|
"""注册Blender处理器"""
|
|||
|
if not BLENDER_AVAILABLE:
|
|||
|
return
|
|||
|
|
|||
|
# 注册保存处理器
|
|||
|
if self._save_handler not in bpy.app.handlers.save_pre:
|
|||
|
bpy.app.handlers.save_pre.append(self._save_handler)
|
|||
|
|
|||
|
# 注册加载处理器
|
|||
|
if self._load_handler not in bpy.app.handlers.load_post:
|
|||
|
bpy.app.handlers.load_post.append(self._load_handler)
|
|||
|
|
|||
|
@persistent
|
|||
|
def _save_handler(self, context):
|
|||
|
"""保存处理器"""
|
|||
|
self.model_observer.on_save_model(context)
|
|||
|
|
|||
|
@persistent
|
|||
|
def _load_handler(self, context):
|
|||
|
"""加载处理器"""
|
|||
|
filepath = bpy.data.filepath
|
|||
|
self.on_open_model(context, filepath)
|
|||
|
|
|||
|
def _clear_suw_entities(self):
|
|||
|
"""清除SUWood实体"""
|
|||
|
if not BLENDER_AVAILABLE:
|
|||
|
return
|
|||
|
|
|||
|
scene = bpy.context.scene
|
|||
|
objects_to_delete = []
|
|||
|
|
|||
|
for obj in scene.objects:
|
|||
|
if obj.get("uid") is not None:
|
|||
|
objects_to_delete.append(obj)
|
|||
|
|
|||
|
# 删除对象
|
|||
|
for obj in objects_to_delete:
|
|||
|
bpy.data.objects.remove(obj, do_unlink=True)
|
|||
|
|
|||
|
|
|||
|
# 全局观察者实例
|
|||
|
_app_observer = None
|
|||
|
|
|||
|
|
|||
|
def get_app_observer():
|
|||
|
"""获取应用观察者实例"""
|
|||
|
global _app_observer
|
|||
|
if _app_observer is None:
|
|||
|
_app_observer = SUWAppObserver()
|
|||
|
return _app_observer
|
|||
|
|
|||
|
|
|||
|
def register_observers():
|
|||
|
"""注册所有观察者"""
|
|||
|
observer = get_app_observer()
|
|||
|
observer._register_observers()
|
|||
|
print("✅ SUWood 观察者已注册")
|
|||
|
|
|||
|
|
|||
|
def unregister_observers():
|
|||
|
"""注销所有观察者"""
|
|||
|
if not BLENDER_AVAILABLE:
|
|||
|
return
|
|||
|
|
|||
|
observer = get_app_observer()
|
|||
|
|
|||
|
# 移除处理器
|
|||
|
try:
|
|||
|
if observer._save_handler in bpy.app.handlers.save_pre:
|
|||
|
bpy.app.handlers.save_pre.remove(observer._save_handler)
|
|||
|
|
|||
|
if observer._load_handler in bpy.app.handlers.load_post:
|
|||
|
bpy.app.handlers.load_post.remove(observer._load_handler)
|
|||
|
|
|||
|
print("✅ SUWood 观察者已注销")
|
|||
|
|
|||
|
except Exception as e:
|
|||
|
print(f"❌ 注销观察者时出错: {e}")
|
|||
|
|
|||
|
|
|||
|
if __name__ == "__main__":
|
|||
|
print("🚀 SUW观察者测试")
|
|||
|
|
|||
|
if BLENDER_AVAILABLE:
|
|||
|
print("Blender API 可用,注册观察者...")
|
|||
|
register_observers()
|
|||
|
else:
|
|||
|
print("Blender API 不可用,创建观察者实例进行测试...")
|
|||
|
observer = get_app_observer()
|
|||
|
print(f"观察者创建成功: {observer.__class__.__name__}")
|