提示和技巧
以下是各种建议,在你写脚本时候时有用,有些是python特点有些是blender特有的。
使用终端
当写脚本时,打开终端很有用,不是指内嵌的python终端,俄式系统终端,有三种方式使用终端:
1. 你可以查看脚本运行print()的输出,可以查看debug消息
2. 错误追踪,打印在终端里,但是在blender用户界面不会产生
3. 如果脚本运行太长时间,你有时候加入无限循环可以按ctrl-c来退出脚本
注意:linux下终端直接运行blender,windows可以在help菜单中打开终端
界面终端
获取操作命令
你可以在菜单和按钮的tips上ctrl-c复制命令道键盘
获取数据路径
查找设置中的数据块ID的路径往往不是那么简单,在设置界面中按钮右键选择Copy Data Path,如果无法产生,只有属性名字被复制
注意:使用同样的方法可以获取动画路径,通过:
bpy.types.FCurve.data_path和bpy.types.DriverTarget.data_path
显示所有的操作
Blender日志记录所有的操作在info界面,这只会显示注册的操作,避免在info信息中出现:
bpy.ops.view3d.smoothview和bpy.ops.view3d.zoom
为了测试在终端中看到所有操作是有用的,启动blender时加上--debug-wm参数,或者当Blender运行时设置bpy.app.debug_wm为True
使用外部编辑器
Blender文本编辑器对于小的修改和写测试很好用,但是它全特征和大的工程。你需要用单独的编辑器或者使用Python-IDE
编辑外部文本,然后在Blender中打开同样的文本可以;但是最优的,以下是最优的两种方式,你可以在blender中更方便的使用外部文件
以下是一些例子,你仍需要在blender中文本块,但是引用一个外部文件而不是直接including
l 执行外部脚本
相当于直接运行脚本,从文本块中引用一个脚本路径:
filename="/full/path/to/myscript.py"
exec(compile(open(filename).read(), filename, 'exec'))
你也许想引用和blender文件相关的脚本
importbpy
importos
filename= os.path.join(os.path.dirname(bpy.data.filepath),"myscript.py")
exec(compile(open(filename).read(), filename, 'exec'))
l 执行模块
这个例子显示以模块加载一个脚本并执行模块
importmyscript
importimportlib
importlib.reload(myscript)
myscript.main()
注意脚本每次都会重新加载,这会强制修改版本,而不是在sys.modules缓存,缓存只在重启Blender软件时使用
这和直接执行脚本的区别是在模块中直接调用一个函数,这个例子中是main函数但是它可以是任意的函数,它有一个优势是你可以从小的脚本给函数中传递参数,这个在测试不同的设置中很快。
它的另一个问题是不得不在Python模块中搜索路径,但这不是最好的方法,为了测试你可以扩展搜索路径,下面的例子,添加当前blend文件路径到搜索路径,然后再作为模块加载脚本。
importsys
importos
importbpy
blend_dir= os.path.dirname(bpy.data.filepath)
if blend_dir notin sys.path:
sys.path.append(blend_dir)
importmyscript
importimportlib
importlib.reload(myscript)
myscript.main()
不要使用Blender!
开发你自己的脚本,通过界面手动加载运行脚本,打开文件导入等等
对于无法交互的脚本,直接在命令行运行不通过命令行更高效:
blender --background --python myscript.py
你可以运行blend文件来运行脚本文件(脚本中有被操作的数据)
blender myscene.blend --background --python myscript.py
注意:你也许需要加入blender的执行文件全路径
一旦你以这种后台方式运行脚本,你会查看脚本的输出,当然这完全依赖于你的任务,不过以下是一些建议:
1. 渲染图片的输出,使用图片视图,每次写覆盖同样的图片
2. 保存一个新的blend文件或者使用blender一个导出器导出文件
3. 如果结果可以被作为文本显示—打印或者将它写到一个文件中
然而这个需要费时来设置,测试更改,你甚至可以让blender每隔几秒运行脚本,附带结果的视图更新
使用外部工具
当没有快速的可获取的python模块来执行明确的任务,最好记住你能够让python执行外部命令,来处理数据和读取结果数据
使用外部程序添加外部依赖库,也许会限制谁能使用脚本,但是可以快速设置你自己的管道或写一个一次性的脚本,这很方便
例子包括:
1. 以批量模式运行Gimp执行用户脚本,用于高级图片处理
2. 通过使用外部网格操作工具和读入结果来输出3D模型
3. 在读取之前,转化文件格式为可识别的格式
捆绑Python和拓展
Blender在官网发布的版本包括在各个平台的完整的Python安装,这会使blender无法找到系统安装的各种扩展,有两种方法处理:
1. 删除Blender-python的子路径,Blender会使用系统的Python,依赖于你的平台,你需要明确引用python安装路径,使用PYTHONPATH环境变量
PYTHONPATH=/usr/lib/python3.5 ./blender
注意:Python版本必须和blender的版本
2. 把拓展工具复制和连接进Blender的Python子路径,使得blender可以获取这些子路径,你也可以复制整个Python安装路径到Blender的子路径,代替Blender中的。只要python版本匹配并且创建同样的相对路径。这样有一个好处你可以限制捆绑其他的软件和Blender以及游戏玩家,包括你依赖的拓展插件。
脚本加入Python解释器
在脚本的中间,你需要检查一些变量,运行一些函数,挖掘什么在运行。
importcode
code.interact(local=locals())
如果你需要获取全局和局部变量,这样做:
importcode
namespace=globals().copy()
namespace.update(locals())
code.interact(local=namespace)
下面的例子,是一行代码,很容易直接贴进你的代码:
__import__('code').interact(local=dict(globals(), **locals()))
code.interact可以加载代码中的任意一行,暂停脚本运行,启动交互解释器,解释之后退出解释器,脚本继续运行。
如果你安装了IPython,你可以使用embed()函数,用在当前命名空间,IPython,可以自动补全,它有一些标准python有用的功能。
importIPython
IPython.embed()
不得不承认,这个会导致python的debug支持,但是它仍旧很方便
注意:这在游戏引擎上也有效,这使得检查运行中的游戏状态更方便
高级特性
Blender作为一个模块
从python观点来看,将所有的都看作插件,使得Python脚本和很多组件连接,这样的优势是:
1. 你可以使用外部文本编辑器或者IDE,用Blender Python API 并且在IDE执行脚本,检查脚本运行时的变量
2. 编辑器或者IDE可以自动补全Blender模块和变量
3. 已经存在的脚本可以导入Blender API不需要在blender内部运行
将blender作为一个python模块运行需要特殊的设置方法
具体的设置方法,详见BuildingBlender as a Python module
Python安全性
因为可以获取已经移除的数据,很难跟踪程序奔溃的原因。在获取数据的过程中,来引发Python的异常,使得CMake生成WITH_PYTHON_SAFETY。
添加数据跟踪使得获取数据慢了两倍,这也是发布版本没有添加这个功能的原因。