import bpy import bmesh from bpy.types import Operator, Panel, PropertyGroup, UIList from bpy.props import StringProperty, IntProperty, FloatVectorProperty, FloatProperty, BoolProperty, EnumProperty, CollectionProperty, PointerProperty import os import tempfile import subprocess import sys import json import platform import time # Import bl_info from utils from .utils import bl_info # Import utility functions from .utils import install_pillow, get_system_fonts, get_font_enum_items # Import preset system functions from .presets import ( initialize_presets, refresh_presets, refresh_presets_sync, ensure_presets_available, migrate_presets_if_needed ) # Import core generation functions from .core import generate_texture_image, generate_preview # Import property groups from .properties import ( TEXT_TEXTURE_ImageOverlay, TEXT_TEXTURE_Preset, TEXT_TEXTURE_Properties ) # Import operators from .operators import ( TEXT_TEXTURE_OT_generate, TEXT_TEXTURE_OT_generate_shader, TEXT_TEXTURE_OT_refresh_preview, TEXT_TEXTURE_OT_view_preview_zoom, TEXT_TEXTURE_OT_save_preset, TEXT_TEXTURE_OT_save_preset_enter, TEXT_TEXTURE_OT_load_preset, TEXT_TEXTURE_OT_delete_preset, TEXT_TEXTURE_OT_refresh_presets, TEXT_TEXTURE_OT_add_overlay, TEXT_TEXTURE_OT_remove_overlay, TEXT_TEXTURE_OT_duplicate_overlay, TEXT_TEXTURE_OT_delete_overlay, TEXT_TEXTURE_OT_move_overlay, TEXT_TEXTURE_OT_open_panel, TEXT_TEXTURE_OT_refresh_fonts, TEXT_TEXTURE_OT_set_anchor_point, TEXT_TEXTURE_OT_sync_margins, TEXT_TEXTURE_OT_export_presets, TEXT_TEXTURE_OT_import_presets, TEXT_TEXTURE_OT_show_migration_report ) # Import UI panels and functions from .ui import ( TEXT_TEXTURE_PT_panel, TEXT_TEXTURE_PT_panel_3d, TEXT_TEXTURE_PT_panel_properties, menu_func_node_editor, menu_func_view3d, menu_func_image ) # ============================================================================ # REGISTRATION # ============================================================================ classes = ( TEXT_TEXTURE_ImageOverlay, TEXT_TEXTURE_Preset, TEXT_TEXTURE_Properties, TEXT_TEXTURE_OT_generate, TEXT_TEXTURE_OT_generate_shader, TEXT_TEXTURE_OT_refresh_preview, TEXT_TEXTURE_OT_view_preview_zoom, TEXT_TEXTURE_OT_add_overlay, TEXT_TEXTURE_OT_remove_overlay, TEXT_TEXTURE_OT_duplicate_overlay, TEXT_TEXTURE_OT_delete_overlay, TEXT_TEXTURE_OT_move_overlay, TEXT_TEXTURE_OT_open_panel, TEXT_TEXTURE_OT_save_preset, TEXT_TEXTURE_OT_save_preset_enter, TEXT_TEXTURE_OT_set_anchor_point, TEXT_TEXTURE_OT_sync_margins, TEXT_TEXTURE_OT_load_preset, TEXT_TEXTURE_OT_delete_preset, TEXT_TEXTURE_OT_refresh_fonts, TEXT_TEXTURE_OT_refresh_presets, TEXT_TEXTURE_OT_export_presets, TEXT_TEXTURE_OT_import_presets, TEXT_TEXTURE_OT_show_migration_report, TEXT_TEXTURE_PT_panel, TEXT_TEXTURE_PT_panel_3d, TEXT_TEXTURE_PT_panel_properties, ) def register(): print("[TTG DEBUG] ========== ADDON REGISTRATION START ==========") for cls in classes: print(f"[TTG DEBUG] Registering class: {cls.__name__}") try: bpy.utils.register_class(cls) print(f"[TTG DEBUG] Successfully registered: {cls.__name__}") except Exception as e: print(f"[TTG DEBUG] FAILED to register {cls.__name__}: {e}") print("[TTG DEBUG] Registering scene properties...") bpy.types.Scene.text_texture_props = PointerProperty(type=TEXT_TEXTURE_Properties) print("[TTG DEBUG] Scene properties registered successfully") # CRITICAL FIX: Force UI refresh after registration print("[TTG DEBUG] Forcing UI refresh...") try: # Update all areas to ensure panels are properly displayed for window in bpy.context.window_manager.windows: for area in window.screen.areas: area.tag_redraw() print("[TTG DEBUG] UI refresh completed successfully") except Exception as e: print(f"[TTG DEBUG] UI refresh failed: {e}") # Add to menus bpy.types.NODE_MT_add.append(menu_func_node_editor) bpy.types.VIEW3D_MT_add.append(menu_func_view3d) bpy.types.VIEW3D_MT_mesh_add.append(menu_func_view3d) bpy.types.NODE_MT_node.append(menu_func_node_editor) # Add to Image menu if available if hasattr(bpy.types, 'IMAGE_MT_image'): bpy.types.IMAGE_MT_image.append(menu_func_image) # Initialize presets using reliable synchronization - no timer chains needed print("[TTG DEBUG] Registration completed - initializing presets with reliable system") # Use the new reliable initialization system try: # Perform migration check first migration_result = migrate_presets_if_needed() if migration_result['migrated_count'] > 0: print(f"[TTG DEBUG] Migrated {migration_result['migrated_count']} presets during registration") # Initialize presets using the simplified system initialize_presets() print("[TTG DEBUG] Preset initialization completed successfully") except Exception as e: print(f"[TTG DEBUG] Error during preset initialization: {e}") # Don't fail registration if preset initialization fails import traceback traceback.print_exc() # Add handler to reload presets when blend file changes @bpy.app.handlers.persistent def on_file_load(dummy): """Reload presets when a blend file is loaded""" try: print("[TTG] Reloading presets after file load...") # Use reliable synchronous refresh instead of timer success = refresh_presets_sync() if success: print("[TTG] Presets reloaded successfully after file load") else: print("[TTG] Warning: Preset reload failed after file load") except Exception as e: print(f"[TTG] Error reloading presets: {e}") import traceback traceback.print_exc() # Register the file load handler if on_file_load not in bpy.app.handlers.load_post: bpy.app.handlers.load_post.append(on_file_load) print("[TTG DEBUG] ========== ADDON REGISTRATION END ==========") def unregister(): # Clean up preview try: if bpy.context.scene: props = bpy.context.scene.text_texture_props if props and props.preview_image: bpy.data.images.remove(props.preview_image) except Exception: pass if "TextTexturePreview" in bpy.data.images: bpy.data.images.remove(bpy.data.images["TextTexturePreview"]) # Remove file load handler try: for handler in bpy.app.handlers.load_post[:]: if handler.__name__ == 'on_file_load' and 'TTG' in str(handler): bpy.app.handlers.load_post.remove(handler) except Exception as e: print(f"Error removing file load handler: {e}") # Remove from menus bpy.types.NODE_MT_add.remove(menu_func_node_editor) bpy.types.VIEW3D_MT_add.remove(menu_func_view3d) bpy.types.VIEW3D_MT_mesh_add.remove(menu_func_view3d) bpy.types.NODE_MT_node.remove(menu_func_node_editor) if hasattr(bpy.types, 'IMAGE_MT_image'): bpy.types.IMAGE_MT_image.remove(menu_func_image) for cls in reversed(classes): bpy.utils.unregister_class(cls) del bpy.types.Scene.text_texture_props if __name__ == "__main__": register()