【转载】Blender Interface & Blender Addon

431 阅读2分钟

原文链接

Blender Interface

Blender 主要有两种 UI:

  • 继承自 bpy.types.Panel, 有 properties 和 draw function
  • bpy.types.Operator, 有 properties, execute function, 可选的 invoke function

一个注册文件中所有类的方法是 bpy.utils.register_module(__name__)

Panels and buttons

可以通过以下代码添加一个按钮

self.layout.operator("hello.hello", text='Hej').country = "Sweden"

UILayout.operator 具有额外参数:

  • text: 按钮上的字
  • text_ctxt: 用于翻译
  • translate: 是否翻译
  • icon: 图标, 比如 QUESTION, ERROR, CANCEL
  • emboss: bool, 是否显示按钮的凸起

同时这个函数具有返回值, 可以对对应的 operator 设置调用时的 properties, 可以设置多个 properties, 如下:

op = row.operator("transform.translate")
op.value = (1,-1,-1)
op.proportional_size = 1

和 operator 一样, panel 同样有 bl_* 的前缀, 常用的有

  • bl_idname: id
  • bl_label: label, 提示性文字, 标题
  • bl_space_type: 属于哪个 space, 如 VIEW_3DPROPERTIES
  • bl_region_type: 属于哪个 region, 如 TOOLSTOOL_PROPS
  • bl_context: 取决于具体环境, 这三项从上到下决定了具体 panel 的具体位置

可重载函数:

  • classmethod poll(context): 返回 bool, 是否绘制 ui
  • draw_header(context): 用来绘制标题
  • draw(context): 用来绘制 panel

Panel properties

除了 operator, 还可以使用 panel 控制 properties, 如下:

layout.prop(ob, 'myRnaInt')         # RNA properties
layout.prop(ob, '["myRnaInt"]')     # ID properties

以及一些常用的 ui 元素:

  • layout.template_ID: ID 链接
  • prop_menu_enum: 枚举类菜单

Panel layout

  • layout.row(): 在同一行, 有一个参数, align, 表示元素是否为紧凑排列
  • layout.column(): 同 row, 按列排列
  • layout.alignment: 设置对齐方式
  • layout.box(): 包围盒
  • layout.separator(): 分隔符
  • layout.split(): 有一个参数 percentage, 按行宽度百分比拆分

menu

找到对应的菜单, 使用 prepend/append 函数添加绘制函数

bpy.types.INFO_MT_mesh_add.prepend(menu_func)
bpy.types.INFO_MT_mesh_add.append(menu_func)

bpy.types.INFO_MT_mesh_add.remove(menu_func)

A modal operator

modal operator 和普通的 operator 的 区别 是, Operator.modal 被重载用来处理事件, 主要用于交互式的 operator

modal 函数的返回值有 4 种 :

  • FINISHED: 结束
  • CANCELLED: 取消
  • RUNNING_MODAL: 等待下一个事件触发继续运行
  • PASS_THROUGH: 不知道… 把 blender 整个代码搜了一遍也只有很少很集中的地方用到了, 应该不用也没问题, 感觉像是多个 modal operator 调用时处理的事情?

可以通过重载 __init__ 和 __del__ 获得 modal operator 开始和结束的信息

在调用时使用语句 context.window_manager.modal_handler_add(self)

Blender Addon

bl_info,包含字段仅用于在 user preference 显示用

registerunregister 将会被调用,当在 user preference 里对 addon 激活和关闭时

bpy.types.Operator 继承

  1. bl_idname: 必须,且唯一,用于 api 调用
  2. bl_label: 必须,表示操作名称
  3. __doc__: 用于显示为 tooltip
  4. bl_options: 枚举类集合
  • REGISTER 默认选项
  • UNDO 支持撤销
  • BLOCKING
  • MACRO
  • GRAB_POINTER
  • PRESET 在操作设置显示一个 preset 按钮
  • INTERNAL 无法从外部搜索到
  1. execute(context): 运行 op,同时返回状态

Operator Property

通过在类内部声明 property,可以让 operator 拥有参数输入,并且在最后一次操作面板里会出现一个简单地面板,显示所有 property

添加菜单

bpy.types.VIEW3D_MT_object.append(menu_func)

类似于重载 menu 类中的 draw 函数,append 为在 draw 之前运行,prepend 在之后运行,以及 remove

def menu_func(self, context):
    self.layout.operator(ObjectCursorArray.bl_idname)

通过 layout.operator 绘制一个操纵 operator 的菜单项