Blender Python脚本编写,尝试在执行大量计算时避免UI锁定

10
我在Blender中编写脚本处理N个物体。当运行我的脚本时,它会锁定用户界面,使其无法使用。我希望编写一个能防止这种情况发生的程序,以便我可以看到屏幕上正在发生的事情,并使用自定义UI来显示进度条。您有什么关于如何在Python或Blender中实现此功能的想法吗?大多数计算只需要几分钟,而我知道这个请求可能会比正常情况下的计算时间更长。感谢您的任何帮助。
负责大部分工作的函数是一个for循环(for a in b)。
2个回答

18

如果您想在Blender中进行大型计算,并仍然拥有响应式的用户界面,您可能需要查看使用Python定时器的模型操作符。

做法类似于以下内容:

class YourOperator(bpy.types.Operator):
    bl_idname = "youroperatorname"
    bl_label = "Your Operator"

    _updating = False
    _calcs_done = False
    _timer = None

    def do_calcs(self):
        # would be good if you can break up your calcs
        # so when looping over a list, you could do batches
        # of 10 or so by slicing through it.
        # do your calcs here and when finally done
       _calcs_done = True

    def modal(self, context, event):
        if event.type == 'TIMER' and not self._updating:
            self._updating = True
            self.do_calcs()
            self._updating = False
        if _calcs_done:
            self.cancel(context)

        return {'PASS_THROUGH'}

    def execute(self, context):
        context.window_manager.modal_handler_add(self)
        self._updating = False
        self._timer = context.window_manager.event_timer_add(0.5, context.window)
        return {'RUNNING_MODAL'}

    def cancel(self, context):
        context.window_manager.event_timer_remove(self._timer)
        self._timer = None
        return {'CANCELLED'}

你需要自己负责正确的模块导入和操作员注册。

我有一个康威生命游戏模态操作符实现来展示如何使用: https://www.dropbox.com/s/b73idbwv7mw6vgc/gol.blend?dl=0


很遗憾,您的Dropbox链接已过期... @jesterKing - Samoth
1
在Blender2.83中,“event_time_add”需要窗口作为关键字。因此,该行代码必须更新为:“event_timer_add(0.5, window=context.window)”。 - NumesSanguis
我觉得我遇到了一个问题。模态框似乎仍在运行。即使由于IF而不执行代码块。这肯定是不可取的吧? - Gary Carlyle Cook

1
我建议您使用greenlets生成新进程。Greenlets通常更容易使用,因为您不需要担心锁和竞争条件,但它们不能在每种情况下使用。使用multiprocessthreading模块肯定可以解决问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接