Если в панелях интерфейса аддона присутствует поле, значение которого меняет что-то в нодовом дереве, при изменении значения в этом поле нодовое дерево каждый раз перекомпилируется. Если пользователь меняет значение в таком поле зажав и двигая мышкой, слишком частая перекомпиляция нодового дерева приведет к заметным подвисаниям Blender.
Проблему лагов можно решить, используя декораторы для отложенного обновления нодового дерева.
Автор кода: Skarn
Определение декораторов:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
import bpy from functools import partial from time import time from ..third_party.boltons.funcutils import wraps def parametrized(dec): def layer(*args, **kwargs): def repl(f): return dec(f, *args, **kwargs) return repl return layer @parametrized def delay_execution(func, delay_sec=1.0): lock = False def timer(*args, **kwargs): nonlocal lock lock = False func(*args, **kwargs) @wraps(func) def wrapped(*args, **kwargs): nonlocal lock if not lock: lock = True bpy.app.timers.register(partial(timer, *args, **kwargs), first_interval=delay_sec) return wrapped @parametrized def on_release(func, delay_sec=1.5): exec_time = time() def timer(*args, **kwargs): nonlocal exec_time if not abs(exec_time - time()) < delay_sec: func(*args, **kwargs) @wraps(func) def wrapped(*args, **kwargs): nonlocal exec_time exec_time = time() bpy.app.timers.register(partial(timer, *args, **kwargs), first_interval=max(1.0, delay_sec)) return wrapped |
В коде используется сторонняя библиотека “Boltons”, которую нужно включить в проект аддона для корректной работы.
Здесь определяются два декоратора: delay_execution для задержки выполнения по времени и on_release – для задержки до момента, когда пользователь отпустит зажатую кнопку мышки.
Далее эти декораторы могут использоваться в коде например так:
1 2 3 4 5 |
@on_release() def update_sun_direction(self, context): properties = bpy.data.node_groups.get('MO_Properties') if properties: properties.nodes['SunDirection'].inputs[1].default_value = self.sun_direction |
Здесь обновление положения источника света в свойстве sun_direction нода произойдет только когда пользователь отпустит зажатую кнопку мышки.