blenderpython/suw_observer.py

317 lines
9.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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__}")