addon(插件)用来扩展 Blender 的功能,跟其他软件里的 plugin(插件)一样,去掉不会影响软件的运行。插件可以加到 Blender 的用户偏好设置目录里,或者就在你所编辑的.blend文件里。前者需要你手动开启才能使用;后者勾选 Text Editor 里的 Register 选框后会 Blender 在加载的时候启用,或者通过点击 Register 选框旁边的 Run Script(快捷键Alt + P)运行。

  Blender 插件的路径是 C:\Program Files\Blender Foundation\Blender\2.76\scripts\addons,我假设你用的也是64位的2.76版本Blender软件,而且没有修改安装路径。比如常用的图片作为平面加载的插件对应文件:io_import_images_as_planes.py,启用的话进入用户偏好设置(快捷键Ctrl + Alt + U)的 Add-ons Tab,搜索过滤,勾选后面的选框,在菜单的 File > Import 里多出了一行 Images as Planes。

  插件里定义了一个或多个operator,恕我没有翻译成数学里的算子、C++ 里面的操作符。Blender 的所有 UI 功能是通过 operator 完成的,operator 可绑定到菜单、按钮或快捷键上供调用。operator 的基类是 bpy.types.Operator,自定义 operator 时需要继承自它。

  好了,我们学习写插件吧!
  打开 Blender 的 Text Editor ,我假设你对 Blender 的界面布局有了初步了解。Text Editor 可当 README 使用,程序员在接触新的项目工程时,通过 README 大概了解其功能,同样,Blender 工程在退出时会保存当前界面,其他人打开时,文字简介第一眼就看得到。你可以写入自己的博客地址和大名让旁人围观学习。

  我们的第一个Operator,say hello to Blender!

import bpy

class HelloWorldOperator(bpy.types.Operator):
  bl_idname = "wm.hello_world"
  bl_label = "Hello World"   def execute(self, context):
    print("Hello World!")
    return {'FINISHED'} bpy.utils.register_class(HelloWorldOperator)

  operator 使用前必须注册,bl_idname 顾名思义,就是 operator 的名字,写法像包名,用点号分割,点号左边的名必须属于 bpy.ops 之一,在 Blender 内部的 Python 控制台下,dir(bpy.ops) 列出所有的名字。bl_idname 对内使用,唯一标识符;bl_label 对外可见,UI文本,可以空格搜索;bl_description 是提示信息,鼠标指针停放其上可见,如果bl_label意思明了,也可以不用填写。Python 不区分单引号与双引号,都可以括字符串。或者说,C/C++ 用单引号与双引号区分字符与字符串,但 Python 统一解释成字符串。

>>> type(bpy.ops)
<class 'bpy.ops.BPyOps'>

>>> dir(bpy.ops)
['action', 'anim', 'armature', 'boid', 'brush', 'buttons', 'camera', 'clip', 'cloth', 'console', 'constraint', 'curve', 'cycles', 'dpaint', 'ed', 'export_anim', 'export_mesh', 'export_scene', 'file', 'fluid', 'font', 'gpencil', 'graph', 'group', 'image', 'import_anim', 'import_curve', 'import_image', 'import_mesh', 'import_scene', 'info', 'lamp', 'lattice', 'logic', 'marker', 'mask', 'material', 'mball', 'mesh', 'nla', 'node', 'object', 'outliner', 'paint', 'paintcurve', 'palette', 'particle', 'pose', 'poselib', 'ptcache', 'render', 'rigidbody', 'safe_areas', 'scene', 'screen', 'script', 'sculpt', 'sequencer', 'sketch', 'sound', 'surface', 'text', 'texture', 'time', 'transform', 'ui', 'uv', 'view2d', 'view3d', 'wm', 'world']

>>> print("Hello World!")
Hello World!

>>> bpy.ops.wm.hello_world()
Hello World!
{'FINISHED'}

>>>

  脚本里的一行 print("Hello World!") 一行,输出 Hello World! 信息到控制台,直接运行是看不到输出结果的。你可以像上面一样,在控制台输入 bpy.ops.wm.hello_world() 测试,注意不要有前导空格。

  下面稍微修改一下,来一个 UI 版的 HelloWorld。

import bpy

class HelloWorldOperator(bpy.types.Operator):
  bl_idname = "wm.hello_world"
  bl_label = "Hello World"
  bl_description = "This is an operator test."   def execute(self, context):
    #print("Hello World!")
    self.report({'INFO'}, "Hello World!")
    return {'FINISHED'}   def invoke(self, context, event):
    wm = context.window_manager
    return wm.invoke_props_dialog(self) bpy.utils.register_class(HelloWorldOperator)

  上面命令行版的 HelloWorld,替换一下 self.report({'INFO'}, "Hello World!")
  在3D视图里敲击空格键,输入 Hello World 就可以搜索到,注意是实时搜索,输入几个字母就可以看见条目了。鼠标点击这个条目,会弹出一个对话框,标题就是bl_label,点击OK后消失,Blender 界面菜单一行 logo 附近会 toast 显示 "Hello World!" 消息。你也可以在 Python 控制台输入 bpy.ops.wm.hello_world() 测试新定义的 operator。

>>> bpy.ops.wm.hello_world()
Info: Hello World!
{'FINISHED'}

>>>

  invoke 方法完成后需要返回字符串集合,即用{}括起,表示一个set。告诉 Blender operator 在运行状态 {'RUNNING_MODAL'},还是取消了操作 {'CANCELLED'} 等,return {"FINISHED"} 则表示成功执行。

  第二个operator,添加一个正四面体(regular tetrahedron)。
  汉语与英语比的一个优势是——星期一到日、一月到十二月、正四面体到正二十面体都是用数字表示的,记住数字就会写;而英语撇开了数字,光月份就有十二个单词,英语的词汇量就是这么增加上去的。
  四面体其实就是三棱锥,但正三棱锥不一定是正四面体!正三棱锥要求侧面是等腰三角形,正四面体要求是等边三角形。关于正四面体的几何性质,希望大家还记得。正四面体是三维空间最简单的几何体,甲烷CH4的分子模型可以当成正四面体来讲解,碳原子作为外界面的圆心。二面角的角度为arccos(1/3),取碳原子为坐标原点,则四个氢原子的坐标为,任两个氢原子距离为2。
  正四面体可以从圆锥体构造,添加圆锥 (Shift + A 后选择Cone),左边面板的 vertices 选择3,得到三菱锥后,用球形化(Shift + Alt + S) 或通过菜单 Object > Transform >  To Sphere 就可以了。

  正四面体也很容易从正方体构造出,选取正方体的对面上交叉的对角线,连接这四个顶点,就可以构成正四面体。像这样:

  Blender采用BU(Blender Unit)单位,正四面体的边长为1,顶点(0, -1 / math.sqrt(3),0),(0.5, 1 / (2 * math.sqrt(3)), 0), (-0.5, 1 / (2 * math.sqrt(3)), 0),(0, 0, math.sqrt(2 / 3))。上面用系统的正方体(边长为2BU)构造的话,边长为2*sqrt(2),顶点(1, 1, 1),(-1, -1, 1), (1, -1, -1),(-1, 1, -1),顶点都是整数哦!

import bpy
from math import sqrt
from mathutils import Vector class MakeTetrahedron(bpy.types.Operator):
bl_idname = "mesh.make_tetrahedron"
bl_label = "Add Tetrahedron" def invoke(self, context, event):
vertices = \
[
Vector((0, -1/sqrt(3),0)),
Vector((0.5, 1/(2 * sqrt(3)), 0)),
Vector((-0.5, 1/(2 * sqrt(3)), 0)),
Vector((0, 0, sqrt(2/3))),
]
edges = []
faces = [[0, 1, 2], [0, 1, 3], [1, 2, 3], [2, 0, 3]] tetrahedron = bpy.data.meshes.new("Tetrahedron")
tetrahedron.from_pydata(vertices, edges, faces)
tetrahedron.update()
object = bpy.data.objects.new("Tetrahedron", tetrahedron)
context.scene.objects.link(object)
return {"FINISHED"}
#end invoke
#end MakeTetrahedron bpy.utils.register_class(MakeTetrahedron)

  内容多一行写不下的话,个人喜欢括号列对齐,需要在行尾添加反斜杠,表示续行,不写会报错的。如果不喜欢这种写法,可以下一行的括号拿上来就成。
  Python 支持 UTF-8 编码,也就是说类名、方法名、变量名可以用 Unicode 字符,当然包括中文。如果你不知道正四面体的英文是tetrahedron,请不要用拼音代替。我见过一些新手写Java代码,不懂的单词懒得查字典,就用拼音(比如阶乘函数写成 jiecheng),看着就想揍人,你写中文,编译器又不会怪你。不过话又说回来,最好用 ASCII 字符,注意下代码工程是用美式英语还是英式英语,其他字符可出现在注释里。

  上面的代码中,先给出了正四面体的数据(如果仅仅是要一个四面体,可以 Mesh > Add Cone,Vertices 选择3就可以了),vertices/edges/faces。Mesh.from_pydata函数利用 V/E/F 这些数据构造出网面。Python 跟 C/C++/Java一样,索引从0开始计数,MATLAB/Lua 从1开始计数。从0开始计数是有很多好处的。上面提供 faces 数据,edges 留空,表示实体(Solid)模型,如果提供以下数据,则会得到正四面体的线框(wireframe)模型。faces的第一个面[0, 1, 2] 表示由线段 [0, 1], [1, 2], [2, 0] 构成的面,最后一个线段用来封闭面。注意面不一定得是三角形。而且索引的顺序需要保持一致,要么都顺时针,要么都逆时针,否则后期需要翻转法线(Ctrl + N)。

    vertices = ... # same as above
edges = [[0, 1], [0, 2], [0, 3], [1, 2], [2, 3], [3, 1]]
faces = []

  注意要么提供 edges 数据,要么提供 faces 数据,两者都提供的话很可能导致 Blender 崩溃。(好吧,我告诉了你一种让Blender崩溃的方法。)你可以用数学公式生成顶点、边、面的数据,赋值给上面的 vertices、edges、faces 变量,在导入这些数据后,Mesh 数据有变,需 update() 一下。
  网面创建了,接下来 mesh 附属到 object datablock,最后链接到场景里。好了,我们完成了。最后一句的注册 register_class 时有必要的,不然按空格是搜索不到的。上面只能通过空格键搜索使用,如果想在UI界面调用话,需要让 bpy.types.Panel 登场了。

  我假设你熟悉 Python 语言,知道类继承的写法,知道缩进的意思。如果你在运行的时候出现语法错误,Blender 会弹出窗口显示出来,可能是混用了tab和空格,也可能是其他小错误,修改正确后重新执行即可。

  用上我们的operator,下面创建了甲烷CH4分子的棍棒模型。

参考:
Operators (bpy.ops)Operator (bpy.struct)
Blender interface with Python scripts

Blender 脚本之 Operator 初探的更多相关文章

  1. Unity3D脚本语言UnityScript初探

    译者注: Unity3D中支持三种语言:JavaScript.C#.Boo,很多人不知道如何选择,通过这篇译文,我们可以搞清楚这三者语言的来龙去脉,对选择主语言有一定的借鉴意义. 首先,Unity是基 ...

  2. Blender插件编写指南

    前言 Blender插件是Blender的利器, 用户可以使用各种插件扩充Blender的功能. Blender Python插件以bpy.props, bpy.types.Operator, bpy ...

  3. [Blender] Blender 获取 Instance 的信息

    最近希望用 Blender 生成 Instance 的能力,将生成的导入游戏引擎中来渲染.Instance Rendering 是个好东西,特别是针对大场景,渲染成批的基本相同的物体的时候非常有用. ...

  4. (一)使用Blender导出GameMaker支持的模型脚本

    源于YOYO论坛帖子:http://gmc.yoyogames.com/index.php?showtopic=603723 既然想做3D,那就先从模型的导入开始,具体的源文件,可以在“(二)使用等高 ...

  5. MVC的验证(模型注解和非侵入式脚本的结合使用) .Net中初探Redis .net通过代码发送邮件 Log4net (Log for .net) 使用GDI技术创建ASP.NET验证码 Razor模板引擎 (RazorEngine) .Net程序员应该掌握的正则表达式

    MVC的验证(模型注解和非侵入式脚本的结合使用)   @HtmlHrlper方式创建的标签,会自动生成一些属性,其中一些属性就是关于验证 如图示例: 模型注解 通过模型注解后,MVC的验证,包括前台客 ...

  6. Blender插件之操作器(Operator)实战

    前言 在Blender中, 操作器(Operator)是它的核心. 用户通过各种操作器来创建和操作场景中的物体. 操作器对象继承自 class bpy.types.Operator(bpy_struc ...

  7. python脚本初探---新手如何直接编写一个hello world模块即可执行的.py文件

    废话不多说,就讲一下这个背景吧: 事情是这个样子的~ 本着好学的精神,咱就买了本书,学习python结果呢,发现python的教程都是一个样子滴,上来的第一个hello world 都是通过IDLE来 ...

  8. Linux学习之路(三)Shell脚本初探

    本文参考链接:http://www.runoob.com/linux/linux-shell.html 基本说明 Shell脚本(shell script)是一种为shell编写的脚本程序.其中she ...

  9. Blender Python脚本的6个技巧

    https://www.youtube.com/watch?v=vFoh3S8MLBI&index=3&list=PLw8Sjaw0TPm0J9DXj3XGi1_9fxXezlzrM ...

随机推荐

  1. python学习笔记(一)

    • Python能干嘛?[1]科学计算[2]图形化开发[3]系统脚本[4]Web服务器[5]网络爬虫[6]服务器集群自动化运维 • 常用工具:easy_install.pip.ipython.Subl ...

  2. ng-class结合三目运算

    ng-class文档:https://docs.angularjs.org/api/ng/directive/ngClass 但是在实际项目中可能会用到三目运算,实例如下: <ul> &l ...

  3. Lua IDE

    http://blog.csdn.net/visualcatsharp/article/details/37653107

  4. XML文件(1)--使用DOM示例

    其他依赖字段/方法 // 书籍列表 private List<Book> bookList = new LinkedList<Book>(); /** * 根据xml文件,得到 ...

  5. js中获取窗口高度的方法

    取窗口滚动条滚动高度 function getScrollTop() { var scrollTop=0; if(document.documentElement&&document. ...

  6. AD域-让共享目录只显示用户有权限访问的文件夹

    问题: 在AD域中,我们一般都会用到共享,如果有很多部门,我们可能还会按部门.职位配置权限.比如CSD,IT,PA等,但文件夹一多,用户看着就头大,而且用户没权限访问的文件夹误点击进去还会提示无权限访 ...

  7. SQL Server需要监控哪些计数器

    常规计数器 收集操作系统服务器的服务器性能信息,包括Processor.磁盘.网络.内存 Processor 处理器 1.1 % Processor Time指处理器用来执行非闲置线程时间的百分比.通 ...

  8. 【Win10】SplitView控件

    SplitView是Win10中的新控件. 用于呈现两部分视图. 一个视图是主要内容,另一个视图是用于导航.(也就是通常说的汉堡菜单.) 主要结构: <SplitView> <Spl ...

  9. Velocity 局部定制模板

    Velocity介绍 Velocity是一个基于java的template engine.它允许Web designer引用Java Code中定义的方法.Web designer可以和Java工程师 ...

  10. UI第十九节——UICollectionView

    UICollectionView其实就是UITableView的升级版,在布局方面比UITableView更出色.下面,先看代码吧 #import "RootViewController.h ...