你打开 Blender,想新建一个文件开始今天的练习。默认场景里那个方方正正的立方体、那盏暖色的灯光、还有那台看着有点复古的摄影机,又一次出现在眼前。你太熟悉它们了,熟悉到觉得有点碍事。
于是你习惯性地按下 A 键全选,再按下 X 键,弹出一个确认框,你敲下回车。一秒之内,世界清空,一片空白。
这个动作你重复过无数次,肌肉记忆比大脑反应还快。但今天,我们换一种方式。
不按键盘,不点鼠标,只用几行代码,让 Blender 听懂另一种语言。这是 oeasy 教程里很特别的一节——在脚本工作区,用 Python 跟你的 3D 世界对话。
把选择权交给代码
打开 Blender,在顶部菜单栏找到那个写着 "Scripting" 的工作区。界面变了,左边是一大片白色的文本编辑器,下面是 Python 控制台,右边还保留着 3D 视图。这个地方,就是你和 Blender 用代码交流的角落。
先看看当前场景里有什么。在控制台里输入:
import bpy
for obj in bpy.data.objects:
print(obj.name)
敲下回车,下方会输出三行字:Cube、Light、Camera。这就是默认场景里那三个老朋友。bpy.data.objects 是 Blender 内部的一份名单,记录着当前文件里所有的对象。用 for 循环挨个打印名字,就像在点名。
现在想删掉立方体。手动操作的话,你得先点击选中它,再按删除键。代码怎么表达这个过程?
删东西之前,得先告诉 Blender "你要删的是谁"。这涉及两个步骤:选中,然后删除。
在 Blender 的 Python 世界里,有一个东西叫 bpy.ops.object,里面装满了对物体进行操作的命令。选中用的命令是 select_all,删除用的命令是 delete。
在控制台里敲入这行:
bpy.ops.object.select_all(action='SELECT')
回车,再看 3D 视图里,立方体、灯光、摄影机全部被框上了高亮边框——全选成功了。接着敲:
bpy.ops.object.delete()
回车,世界清空。三个对象从 bpy.data.objects 的名单里彻底消失了。
就是这么简单。两行代码,干了手动操作两三秒才能完成的事。看起来没节省多少时间,但这扇门一旦推开,后面的事情就不一样了。
让脚本替你动手
刚才是在控制台里一行一行敲,适合测试和探索。想把这套动作用在更多地方,得把它写成脚本。
在脚本编辑区点 "New",新建一个文本文件。把刚才那两行代码敲进去:
import bpy
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
点击 "Run Script" 按钮(或者按 Alt+P),场景清空。
写脚本的好处是,你可以反复用,也可以在此基础上加更多东西。比如删完之后马上创建一个新的立方体:
import bpy
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
bpy.ops.mesh.primitive_cube_add(size=2, location=(0,0,1))
运行一下,旧的都没了,一个新的边长为 2、位置在 (0,0,1) 的立方体出现在场景里。
这就是脚本的爽快之处:把一系列操作打包成一个动作。以后每次想从零开始,不用再手动删删减减,运行一下脚本,世界立刻清空,然后按你的想法重新构建。
那些让你摔跟头的坑
第一次照抄代码的时候,十有八九会遇到这么个情况:
敲完 bpy.ops.object.select_all(action='SELECT') 和 bpy.ops.object.delete(),点运行,底下弹出一行红字:NameError: name 'bpy' is not defined。
懵了。明明刚才在控制台里敲得好好的,怎么写成脚本就报错?
原因很简单:控制台是交互式的,你每敲一行它都记着上下文。但脚本是个独立的世界,第一行如果不告诉它要用什么工具,它后面就不知道 bpy 是谁。
解决方法就是代码里最上面那一行:import bpy。导入之后,Blender 的 Python API 才能用。这就像做菜之前先拿出锅和铲,东西就在那儿,但得先拿出来才能用。
还有个坑是关于选中的。
有人想只删立方体,不删灯光和摄影机,于是写:
import bpy
bpy.ops.object.delete()
运行,底下提示:Operator bpy.ops.object.delete.poll() Failed, context is incorrect。
为什么?因为 delete 命令不知道你要删谁。你没告诉它哪个对象是选中的,它就只能干瞪眼。
正确的做法是先选中立方体。怎么用代码选中单个对象?
import bpy
bpy.data.objects['Cube'].select_set(True)
bpy.ops.object.delete()
bpy.data.objects['Cube'] 是找到名字叫 "Cube" 的那个对象,.select_set(True) 是把它设为选中状态。然后再删除,就可以了。
如果想删的是灯光,把 Cube 换成 Light 就行。想删摄影机,换成 Camera。
从手动到自动
手动操作的时候,选中、删除,眼睛看着界面,手指配合大脑,每一步都清清楚楚。换成代码,这些步骤变成了函数调用和参数传递。刚开始可能觉得多此一举,明明手点更快,干嘛要写代码?
但手点有个上限。假设场景里有 100 个对象,你想删掉其中 50 个名字带 "Cube" 的,手动一个一个找得点到什么时候?写几行代码,一秒搞定:
import bpy
for obj in bpy.data.objects:
if "Cube" in obj.name:
obj.select_set(True)
else:
obj.select_set(False)
bpy.ops.object.delete()
这段代码的意思是:遍历所有对象,如果名字里包含 "Cube",就选中;否则取消选中。然后删除所有选中的。
条件判断 + 循环,让删除这件事从 "手动挑拣" 变成了 "按规则自动筛选"。这才是脚本工作区真正的价值——不是重复你已经会的手动操作,而是做那些手动操作做不了、或者做起来太慢的事。
写在脚本里的自由
oeasy 在教程里反复演示了一个动作:新建文件,写几行脚本,运行,场景清空。这个动作看起来简单,但每运行一次,都是在提醒你一件事:在 Blender 里,手不是唯一的工具。
那些默认的立方体、灯光、摄影机,是 Blender 给你的起点,但不是束缚。你完全可以用代码把它们一键清空,然后用代码再一键创建出新的世界。
下次打开 Blender,不急着按 A 和 X,试着在脚本工作区敲几行代码,让 Python 替你清空场景。刚开始可能会碰到 NameError,可能会忘了选中的步骤,但这些坑踩过一次,后面就是平路。
当你习惯用 import bpy 开启每一次脚本,你会发现 3D 创作多了一个维度——除了眼睛看、手去点,还有代码在背后静静执行你的指令。那种感觉,像多了个帮手。