Files
blender-portable-repo/scripts/addons/lighting_overrider/utils.py
T
2026-03-17 14:58:51 -06:00

198 lines
6.1 KiB
Python

# SPDX-FileCopyrightText: 2025 Blender Studio Tools Authors
#
# SPDX-License-Identifier: GPL-3.0-or-later
import os
import bpy
from pathlib import Path
def executions_script_source_exists(context):
meta_settings = context.scene.LOR_Settings
path = meta_settings.execution_script_source
path = bpy.path.abspath(path)
return os.path.isfile(path)
def find_execution_script():
execution_script = bpy.data.texts.get('LOR_execution_script.py')
return execution_script
def find_settings(context):
meta_settings = getattr(context.scene, 'LOR_Settings')
if not meta_settings:
return None, None
sequence_name = meta_settings.sequence_settings.name
shot_name = meta_settings.shot_settings.name
try:
sequence_settings_db = context.scene['LOR_sequence_settings']
except:
sequence_settings_db = None
try:
shot_settings_db = context.scene['LOR_shot_settings']
except:
shot_settings_db = None
if not sequence_settings_db:
sequence_settings_db = bpy.data.texts.get(f'{sequence_name}.settings.json')
if not shot_settings_db:
shot_settings_db = bpy.data.texts.get(f'{shot_name}.settings.json')
if not sequence_settings_db:
filepath = Path(bpy.context.blend_data.filepath)
path = filepath.parents[1].as_posix()+f'/{sequence_name}.settings.json'
if not os.path.isfile(path):
open(path, 'a').close()
bpy.ops.text.open(filepath=bpy.path.relpath(path))
if not shot_settings_db:
shot_settings_db = bpy.data.texts.new(f'{shot_name}.settings.json')
return sequence_settings_db, shot_settings_db
def get_settings(meta_settings):
''' Returns the currently active settings group.
'''
if meta_settings.settings_toggle == 'SHOT':
settings = meta_settings.shot_settings
elif meta_settings.settings_toggle == 'SEQUENCE':
settings = meta_settings.sequence_settings
return settings
def mark_dirty(self, context):
meta_settings = context.scene.LOR_Settings
settings = get_settings(meta_settings)
if settings.is_dirty:
return
settings.is_dirty = True
return
def reload_libraries():
for lib in bpy.data.libraries:
lib.reload()
return
def reload_settings(context):#TODO find a way to run this on load_post handler
meta_settings = context.scene.LOR_Settings
for settings in [meta_settings.sequence_settings, meta_settings.shot_settings]:
if not settings.text_datablock:
continue
if settings.text_datablock.is_in_memory:
continue
override = context.copy()
if not override['area']:
return
area_type = override['area'].type
override['area'].type = 'TEXT_EDITOR'
override['edit_text'] = settings.text_datablock
bpy.ops.text.reload(override)
override['area'].type = area_type
return
def get_instances_across_all_libraries(name, path) -> list:#TODO
return
def kick_evaluation(objects=None):
if not objects:
objects = bpy.data.objects
for ob in objects:
ob.update_tag()
return
def split_by_suffix(list, sfx):
with_suffix = [name[:-len(sfx)] for name in list if name.endswith(sfx)]
without_suffix = [name for name in list if not name.endswith(sfx)]
return without_suffix, with_suffix
def parse_rna_path_to_elements(rna_path, delimiter='.'):
''' Returns the element strings of an RNA path split by '.' delimiter, disregarding any delimiter in a string within the path.
'''
if not delimiter in rna_path:
return [rna_path]
parse = rna_path
# replace escape chars with whitespaces
parse_elements = parse.split(r'\\')
parse = ' '.join(parse_elements)
parse_elements = parse.split('\\')
parse = parse_elements[0]
for el in parse_elements[1:]:
parse += ' '
parse += el[1:]
# replace strings within path with whitespaces
parse_elements = parse.split('"')
parse = parse_elements[0]
for el1, el2 in zip(parse_elements[1::2], parse_elements[2::2]):
parse += '"'+' '*len(el1)+'"'
parse += el2
parse_elements = parse.split(delimiter)
elements = []
for el in parse_elements:
elements += [rna_path[:len(el)]]
rna_path = rna_path[len(el)+len(delimiter):]
return elements
def parse_rna_path_for_custom_property(rna_path):
''' Returns the rna path of the datablock and the name of the custom property for an rna path that describes a custom property.
'''
if not '][' in rna_path:
return False
parse_elements = parse_rna_path_to_elements(rna_path, delimiter='][')
return parse_elements[0]+']', '"'.join(parse_elements[1].split('"')[1:-1])
def mute_fcurve(db, path):
if not db.animation_data:
return
if not db.animation_data.action:
return
fcurve = db.animation_data.action.fcurves.find(path)
c = 0
while fcurve or c<=4:
if fcurve:
fcurve.mute = True
c += 1
fcurve = db.animation_data.action.fcurves.find(path, index=c)
return
def mute_driver(db, path):
if not db.animation_data:
return
if not db.animation_data.drivers:
return
driver = db.animation_data.drivers.find(path)
c = 0
while driver or c<=4:
if driver:
driver.mute = True
c += 1
driver = db.animation_data.drivers.find(path, index=c)
return
def mute_animation_on_rna_path(rna_path):
path_elements = parse_rna_path_to_elements(rna_path)
db_path = '.'.join(path_elements[:3])
if 'session_uid' in dir(eval(db_path)):
data_block = eval(db_path)
path = '.'.join(path_elements[3:])
else: # handle custom props
db_path, c_prop = parse_rna_path_for_custom_property(rna_path)
data_block = eval(db_path)
path = f'["{c_prop}"]'
if data_block.id_type in ['ACTION', 'BRUSH', 'COLLECTION', 'IMAGE', 'LIBRARY', 'PALETTE', 'PAINTCURVE', 'SCREEN', 'TEXT', 'WINDOWMANAGER', 'WORKSPACE']:
return
mute_fcurve(data_block, path)
mute_driver(data_block, path)
return