在Blender完全加载后执行脚本



Blender完全加载后,我如何自动执行python脚本?

上下文

我的脚本基于种子生成场景。我想创建几千个图像,但由于Blender在一百代左右后会泄露内存,所以一切都变得非常缓慢,最终崩溃。我想通过每次会话只创建x个图像来解决这个问题,并在每次会话后完全重新启动Blender。

问题

如果我手动加载混合文件并单击脚本编辑器中的播放按钮,一切都会按预期进行。当我尝试在启动后调用脚本时,它在add_curve_spirals.py的第184行崩溃,因为context.space_dataNone

由于手动启动脚本运行良好,问题是Blender处于某种错误的状态。无论是否使用GUI(--background(启动它都不会影响这一点。

失败的解决方案

  • blender myfile.blend --python myscript.py在上下文完全就绪之前执行脚本,从而产生错误
  • 使用处理程序延迟执行(bpy.app.handlers.load_post(在完全加载文件后调用我的脚本,但上下文仍然没有准备好,它会产生错误
  • 将Blender中的脚本设置为启动时自动执行(文本/寄存器(也会产生错误
  • 使用套接字,如这里所建议的,稍后将命令发送到Blender。等待插入命令的服务器脚本在启动过程中会阻止Blender并阻止其完全加载,因此效果与直接执行脚本相同
  • 使用定时事件(bpy.app.timers.register(render_fun, first_interval=10)

这些都是我发现的自动执行脚本的方法。在任何情况下,脚本似乎执行得太早/处于错误的状态,并且都以相同的方式失败。

我想强调的是,剧本不是这里的问题。即使我可以围绕特定的行进行工作,也可能会出现许多类似的问题,我不想重写整个脚本。那么,在正确的状态下自动调用它的最佳方式是什么呢?

事实证明,问题出在执行上下文上。这一点在手动调用定时事件后变得很清楚,例如,在场景完全加载后,定时事件仍然在错误的上下文中执行。

由于崩溃发生在add_curve_spirals插件中,因此解决方案是提供一个上下文覆盖运算符调用。我的剧本的其余部分对上下文不太敏感,效果也很好。

我不清楚我应该如何覆盖上下文,但这目前有效(从互联网的其他部分收集,所以我不了解所有细节(:

def get_context():
# create a context that works when blender is executed from the command line.
idx = bpy.context.window_manager.windows[:].index(bpy.context.window)
window = bpy.context.window_manager.windows[idx]
screen = window.screen
views_3d = sorted(
[a for a in screen.areas if a.type == 'VIEW_3D'],
key=lambda a: (a.width * a.height))

a = views_3d[0]
# override
o = {"window" : window,
"screen" : screen,
"area" : a,
"space_data": a.spaces.active,
"region" : a.regions[-1]
}
return o

最终调用:bpy.ops.curve.spirals(get_context(), spiral_type='ARCH', radius = radius, turns = turns, dif_z = dif_z, ...

相关内容

  • 没有找到相关文章