When we create a field on the add-on interface panel, the value of which changes something in the node tree, each time the user changes the field value the node tree recompiles. If the user changes the value in that field by holding and moving the mouse, too frequent node tree recompilation will cause Blender to hangs.
This problem can be solved using decorators for deferred updating of the node tree.
Code by Skarn.
Decorators definition:
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 |
The code uses the third-party “Boltons” library, which needs to be included to the add-on for proper work.
This code defines two decorators: “delay_execution” – to delay execution by time, and “on_release” – to delay until the user releases the held mouse button.
In the add-on we can use these decorators:
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 |
Here the “sun_direction” node property will update only when the user releases the held mouse button.