Files
2026-03-17 14:58:51 -06:00

220 lines
6.9 KiB
Python

# SPDX-FileCopyrightText: 2025 Blender Studio Tools Authors
#
# SPDX-License-Identifier: GPL-3.0-or-later
from . import categories
from . import utils
from .import json_io
import bpy
import inspect
from bpy.app.handlers import persistent
from . import lighting_overrider_execution
from .lighting_overrider_execution import force_reload_external, settings_from_datablock
@persistent
def write_execution_script_on_save(dummy):
meta_settings = getattr(bpy.context.scene, 'LOR_Settings')
if not meta_settings.enabled:
return
bpy.ops.lighting_overrider.generate_execution_script()
return
def load_settings(context, name, path=None):
''' Return text datablock of the settings specified with a name. If a filepath is specified (re)load from disk.
'''
meta_settings = getattr(bpy.context.scene, 'LOR_Settings')
if not meta_settings:
return None
settings = utils.get_settings(meta_settings)
if path:
path += f'/{name}.settings.json'
settings_db = bpy.data.texts.get(f'{name}.settings.json')
if settings_db:
force_reload_external(context, settings_db)
return settings_from_datablock(settings_db)
if path:
if not os.path.isfile(path):
open(path, 'a').close()
bpy.ops.text.open(filepath=bpy.path.relpath(path))
settings_db = bpy.data.texts.get(f'{name}.settings.json')
else:
settings_db = bpy.data.texts.new(f'{name}.settings.json')
return settings_from_datablock(settings_db)
def apply_settings(data):
for cat in categories.modules:
cat_name = cat.__name__.split(".")[-1]
cat.apply_settings(data[cat_name])
return
def generate_execution_script() -> str:
script = inspect.getsource(lighting_overrider_execution)
return script
class LOR_OT_generate_execution_script(bpy.types.Operator):
"""
"""
bl_idname = "lighting_overrider.generate_execution_script"
bl_label = "Generate Execution Script"
bl_description = "Generate script for automatic execution of the overrides based on the JSON settings"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
meta_settings = context.scene.LOR_Settings
if not meta_settings.execution_script:
meta_settings.execution_script = utils.find_execution_script()
if not meta_settings.execution_script:
text = bpy.data.texts.new('LOR_execution_script.py')
meta_settings.execution_script = text
else:
text = meta_settings.execution_script
text.from_string(generate_execution_script())
text.use_module = True
return {'FINISHED'}
def run_execution_script(context):
meta_settings = context.scene.LOR_Settings
settings = utils.get_settings(meta_settings)
if not meta_settings.execution_script:
return False
script = meta_settings.execution_script
exec(script.as_string(), globals())
return True
class LOR_OT_run_execution_script(bpy.types.Operator):
"""
"""
bl_idname = "lighting_overrider.run_execution_script"
bl_label = "Run Execution Script"
bl_description = "Run script for automatic execution of the overrides based on the JSON settings"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
meta_settings = context.scene.LOR_Settings
settings = utils.get_settings(meta_settings)
return bool(meta_settings.execution_script)
def execute(self, context):
if not run_execution_script(context):
return {'CANCELLED'}
return {'FINISHED'}
class LOR_OT_reload_libraries(bpy.types.Operator):
""" Reloads all libraries to show the fresh file without overrides
"""
bl_idname = "lighting_overrider.reload_libraries"
bl_label = "Reload Libraries"
bl_description = "Reload all libraries"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
utils.reload_libraries()
return {'FINISHED'}
class LOR_OT_reload_run_execution_script(bpy.types.Operator):
""" Reloads all libraries and runs the override script to show how the file will look after load
"""
bl_idname = "lighting_overrider.reload_run_execution_script"
bl_label = "Reload Libraries and Run Execution Script"
bl_description = "Reload all libraries and run script for automatic execution of the overrides based on the JSON settings"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
meta_settings = context.scene.LOR_Settings
return bool(meta_settings.execution_script)
def execute(self, context):
utils.reload_libraries()
if not run_execution_script(context):
return {'CANCELLED'}
return {'FINISHED'}
class LOR_OT_apply_JSON(bpy.types.Operator):
"""
"""
bl_idname = "lighting_overrider.apply_json"
bl_label = "Apply JSON"
bl_description = "Apply settings from specified JSON text datablock"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
meta_settings = context.scene.LOR_Settings
settings = utils.get_settings(meta_settings)
return bool(settings.text_datablock)
def execute(self, context):
meta_settings = context.scene.LOR_Settings
settings = utils.get_settings(meta_settings)
text = settings.text_datablock
data = json_io.read_data_from_json(text)
apply_settings(data)
utils.kick_evaluation()
return {'FINISHED'}
class LOR_OT_write_apply_JSON(bpy.types.Operator):
"""
"""
bl_idname = "lighting_overrider.write_apply_json"
bl_label = "Write and Apply JSON"
bl_description = "Write and apply settings in specified JSON text datablock"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
meta_settings = context.scene.LOR_Settings
settings = utils.get_settings(meta_settings)
return bool(settings.text_datablock)
def execute(self, context):
meta_settings = context.scene.LOR_Settings
settings = utils.get_settings(meta_settings)
text = settings.text_datablock
data = json_io.pack_settings_data(settings)
json_io.write_data_to_json( text, data)
settings.is_dirty = False
apply_settings(data)
utils.kick_evaluation()
return {'FINISHED'}
classes = (
LOR_OT_apply_JSON,
LOR_OT_write_apply_JSON,
LOR_OT_generate_execution_script,
LOR_OT_reload_libraries,
LOR_OT_run_execution_script,
LOR_OT_reload_run_execution_script,
)
def register():
for c in classes:
bpy.utils.register_class(c)
bpy.app.handlers.save_pre.append(write_execution_script_on_save)
def unregister():
for c in classes:
bpy.utils.unregister_class(c)