跳转到内容

Blender 3D:从新手到专业/高级教程/Python 脚本/程序化对象创建

来自维基教科书,开放世界中的开放书籍

文本块

[编辑 | 编辑源代码]

Blender 文档可以包含文本块,它们与3D 场景中的文本对象不同(尽管前者可以转换为后者)。除了生成文本对象之外,文本块可以根据你的需要服务于任何目的;例如,将其用于将工作流程说明与文档一起传递给同事;在用户打开文档时看到的初始布局中显示版权或帮助信息;或者保存一个 Python 脚本,用户可以通过运行该脚本对文档执行一些有用的操作。

文本块在文本编辑器窗口中进行编辑。文本编辑器还提供命令来从外部文件加载文本块的内容,或将其保存到外部文件。以及执行文本作为 Python 脚本。

你的第一个脚本

[编辑 | 编辑源代码]

打开一个新的默认 Blender 文档。垂直将 3D 视图分成两部分。将其中一侧的类型更改为文本编辑器窗口。在标题中,你会看到一个小的弹出菜单,只显示一个双箭头;单击它,它应该显示三个项目:“文本”、“添加新”和“打开新”。“添加新”创建一个新的空文本块,而“打开新”通过从外部文件读取内容来创建一个新的文本块。但“文本”已经是默认空文本块的名称,所以只需使用它;一旦你选中它,你应该会看到一个红色插入光标出现在左上角,表示你可以开始输入。

与交互式 Python 控制台不同,没有为你自动导入任何内容。因此,像在任何其他 Python 脚本中一样,你需要提及你要访问的每个模块。

让我们编写一个脚本,将一个新的网格基本体插入 Blender 文档,即一个四面体。首先,我们需要创建一个新的网格数据块,我们将其命名为“四面体”。

NewMesh = Blender.Mesh.New("Tetrahedron")

然后我们需要定义顶点的坐标;对于边长为 1 Blender 单位的四面体,合适的数值是 , , 。或在 Python 中

NewMesh.verts.extend \
  (
    [
        (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)),
    ]
  )

我们还需要定义对象的表面;每个表面都是通过列出顶点数组中的索引序列来定义的(你不需要担心定义边;Blender 会从表面中推断出它们)

NewMesh.faces.extend \
  (
    [[0, 1, 2], [0, 1, 3], [1, 2, 3], [2, 0, 3]]
  )

这足以满足网格的要求,现在我们创建一个实际的对象数据块,它将出现在场景中(我们也将其命名为“四面体”)

TheObj = Blender.Object.New("Mesh", "Tetrahedron")

将它链接到我们刚刚制作的网格

TheObj.link(NewMesh)

为了使对象出现在场景中,它必须链接到场景

TheScene = Blender.Scene.GetCurrent()
TheScene.link(TheObj)

最后,告诉 Blender 场景已更改

TheScene.update()

并重新绘制 3D 视图以显示更新的场景

Blender.Window.Redraw()

将它们整合在一起

[编辑 | 编辑源代码]

你的完整脚本应该如下所示,包括引用的导入mathBlender模块;请注意,还使用了指令来确保“/”运算符始终返回实数,而不是整数;这是 Python 2.x 中的良好实践,因为它从 Python 3.0 开始成为强制行为。

from __future__ import division
import math
import Blender

NewMesh = Blender.Mesh.New("Tetrahedron")
NewMesh.verts.extend \
  (
    [
        (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)),
    ]
  )
NewMesh.faces.extend \
  (
    [[0, 1, 2], [0, 1, 3], [1, 2, 3], [2, 0, 3]]
  )
TheObj = Blender.Object.New("Mesh", "Tetrahedron")
TheObj.link(NewMesh)
TheScene = Blender.Scene.GetCurrent()
TheScene.link(TheObj)
TheScene.update()
Blender.Window.Redraw()

在你的 3D 视图中,删除任何默认立方体,以避免它遮挡物体。现在回到显示上述脚本的文本编辑器窗口,并按  ALT + P  来执行它;你应该会看到你的新四面体出现在 3D 视图中!

如果你遇到错误

[编辑 | 编辑源代码]

如果运行脚本时出现任何错误,Blender 将显示一条神秘的消息来通知你。例如,以下简单的单行脚本

raise RuntimeError("Uh-oh")

显示此消息

要获取更多详细信息,你必须查看标准错误;在 Linux/Unix 系统上,如果你是从命令行调用 Blender,则消息将出现在终端会话中;否则,它将附加到你的~/.xsessionerrors文件中,如果你从 GUI 启动了 Blender。在 Windows 上,消息将出现在控制台窗口中。通过在适当的位置四处查找,你应该能够找到完整的 Python 回溯

Traceback (most recent call last):
  File "Text.001", line 1, in <module>
RuntimeError: Uh-oh
华夏公益教科书