从源码看Blender执行外部python文件
从文档中找到去年的一些blender源码记录,整一下share出来。以下内容来自源码2.83,具体哪个commit已经记不得了。
当不关心Blender源码时
我们可以使用命令
[blender_run_path] --background --python [python.py] -- [python args]
在后台执行blender的运行。
blender_run_path 示例:
若blender.exe在Windows目录 C:\Program Files\Blender Foundation\Blender 2.83 下,则
blender_run_path应该为"C:\Program Files\Blender Foundation\Blender 2.83\blender"。
只执行[blender_run_path] --background 时,blender会后台启动并自动退出,因而在运行blender命令行时,需要指定python的文件,blender后台运行才能执行其python脚本下的操作。cmd命令指示符是可以的,powershell好像有点问题。
blender命令行运行插件
需要import bpy,之后当引用插件中的某个operator时,输入 bpy.ops.bl_idname(),即可执行插件中的某个operator。
在源码中是怎么做的呢?
带着好奇搜寻了一下代码,发现在blender中,对于要执行的python代码,是以 c++中使用CPython的接口来执行python入口文件。具体的,在做相应上下文初始化、配置等之后,在windows版本中,以PyRun_String的方式来执行,而在其他平台,则以PyRun_File来运行。这部分逻辑位于 source\blender\python\intern\bpy_interface_run.c 中,具体的,都在python_script_exec 函数数内。
关于在windows中用 PyRun_String 的方式执行的原因,官方注释说是因为python的源码手册介绍到 FILE 这个数据结构在不同的C语言库中会有异议,因此他们改用PyRun_String的方式来做。而且,他们传给python的c++接口的文件,只有被执行的带有主入口的一个python文件。这个python文件中对其他项目的import库如何被寻找,这个python的入参解析等等,都交给python本身的c++接口来实现,目前看 blender 并没有直接对这部分内容做处理;
除了输入文件的方式,还可以直接传入python的字符串内容,具体的还是在bpy_interface_run.c 中,blender对字符串解析之后变成一个特殊的buffer,这个buffer通过Py_CompileStringObject 来执行。
我们把断点放在 bpy_interface_run.c 中的 python_script_exec 函数中,看到整个调用堆栈相对来说比较简单。

在这边,我们把注意力放在堆栈的最开始,也就是下图所示的blender的主入口处。可以发现,主入口所在的文件,其实就是blender源码结构中的 blender\source\creator 模块。

更具体一些,在 blender\source\creator\creator.c 中的 int main 函数。
