1   推荐资源 2   开发技巧 cycles API直接查看cycles源码,properties.py blender -r -R注册blend后缀名文件,小r为静默注册-v显示版本 blender排错cmd工具:blender_debug_log.bat 用户偏好设置-开发额外选项+Python工具提示+工具提示
开启「开发额外选项」后,右键UI组件,可以查看源代码。
在寻找UI组件所在类目时,可查看Python工具提示信息。
在查找一些操作命令时,可以在blender里操作后在控制台看执行的语句。活用blender控制台进行调试。
live edit状态去除bl_info(meta元数据),其余状态一样
Operator 的 bl_label 的 translation context 必须为 Operator。 Operator 的 bl_description 的 translation context 必须为 *。
blender主程序目录下,有debug.cmd工具可以用于生成blender崩溃的日志。
3   常见API总结 4   插件升级功能 5   常见问题总结 5.1   调用operator出现poll()函数报错 在Blender的插件开发中,业务逻辑功能若能避免使用bpy.ops函数就尽量避免使用,因为大量使用ops函数不仅影响性能,而且还可能引发poll函数RuntimeError异常。二次代码开发,更推荐使用Blender原生API类接口实现业务逻辑功能。
问题现象:RuntimeError: Operator bpy.ops.object.empty_image_add.poll() failed, context is incorrect
问题原因:Blender代码设计中,很多operator都有一个poll函数专门用于检测鼠标指针是否在一个有效的窗口区域或者检测当前物体是否在正确的模式中(例如编辑模式,权重绘制模式),如果poll函数返回失败值的话,就会引发RuntimeError异常。
解决方法: context override的代码实现,如下代码适用于所有blender版本:
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 class ContextExecuterOverride : def __init__ (self, window, screen, area, region ): self .window, self .screen, self .area, self .region = window, screen, area, region self .legacy = not hasattr (bpy.context, "temp_override" ) if self .legacy: self .context = bpy.context.copy() self .context['window' ] = window self .context['screen' ] = screen self .context['area' ] = area self .context['region' ] = region else : self .context = bpy.context.temp_override(window=window, screen=screen, area=area, region=region) def __enter__ (self ): if not self .legacy: self .context.__enter__() return self def __exit__ (self, exc_type, exc_value, traceback ): if not self .legacy: self .context.__exit__(self , exc_type, exc_value, traceback) return self class ContextScriptExecuter (): def __init__ (self, area_type, ui_type=None , script=None ): self .area_type = area_type self .ui_type = ui_type if ui_type else area_type self .script = script def script_content (self, override ): self .script(override) def execute_script (self ): window = bpy.context.window screen = window.screen areas = [area for area in screen.areas if area.type == self .area_type] area = areas[0 ] if len (areas) else screen.areas[0 ] prev_ui_type = area.ui_type area.ui_type = self .ui_type regions = [region for region in area.regions if region.type == 'WINDOW' ] region = regions[0 ] if len (regions) else None with ContextExecuterOverride(window=window, screen=screen, area=area, region=region) as override: self .script_content(override) area.ui_type = prev_ui_type
具体context override代码的使用例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ContextScriptExecuter( area_type="VIEW_3D" , script=lambda override: ( bpy.ops.object .empty_image_add( override.context, filepath=blueprint_front ) if override.legacy else bpy.ops.object .empty_image_add(filepath=blueprint_front_path) ), ).execute_script() ContextScriptExecuter( area_type="VIEW_3D" , script=lambda override: ( bpy.ops.view3d.view_axis(override.context, type ="FRONT" ) if override.legacy else bpy.ops.view3d.view_axis(type ="FRONT" ) ), ).execute_script()
6   参考文献 [1] 「切换语言」使用手册 - Blender 插件,参考文献小节[EB/OL]. https://mister-kin.github.io/works/software-works/toggle-language/#%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE . [2] poll() failed, context incorrect? - Example: bpy.ops.view3d.background_image_add()[EB/OL]. https://blender.stackexchange.com/questions/6101/poll-failed-context-incorrect-example-bpy-ops-view3d-background-image-add . [3] Context override[EB/OL]. https://b3d.interplanety.org/en/context-override/ . [4] Blender 插件开发 技巧/误区/指南/笔记[EB/OL]. https://blog.csdn.net/qq_36288357/article/details/143528487 .