本次为记录贴,记录常用的一些blender操作快捷键。将不定时更新。在blender中使用python能够代替鼠标,完成各类操作。代码编写可以在文本编辑器或者python控制台中。文本编辑器可以处理多行代码,在使用bpy时需要import,而在控制台中只能处理一行代码,不需要import。
首先介绍一个常用操作,当想了解一个项目下面的子项时可以点击自动补全按钮。如bpy.(加.)。对应键盘的快捷操作是Ctrl+space,而在笔记本上需要额外加上Fn键。
此外,在视图界面的许多操作,当鼠标在该操作停留一段时间,会在下方显示对应的python语句。
首先是选择操作,作者在学习时看的是一本将api三维书,书中版本可能比2.8会老一些,故有些属性显示没有而报错。可以使用第二板块的技巧来查找最新的方式会是什么。
例如在2.78c中就是
bpy.data.objects[objName].select = True
而我的版本2.8中则是
bpy.data.objects[objName].select_set(True)
显示选中物体的名称(context)
bpy.context.selected_objects
此外,还可以根据选中的object,调用其属性来显示
[k.name for k in bpy.context.selected_objects]
此处需要添加 [ ],否则将会报错。
类似的,还可以显示其他属性,如位置属性:
[k.location for k in bpy.context.selected_objects]
取消当前所有选择
bpy.ops.object.select_all(action='DESELECT')
此外,还可以对选定的物体进行操作,一是根据物体名称进行操作。
bpy.data.objects["Cube"].location=(2,2,2)
在blender中存在着选中和激活两种状态。什么叫做激活?在blender中只能使一个物体处于激活状态,界面中被激活的物体上会有一个小蓝点,在显示窗口的右下角也会显示当前被激活物体的名称。
当只选中了一个物体时,该物体既被选中又被激活,而当选中多个物体时,只有第一个选中的物体为激活状态。
例如,使用如下代码只会显示被激活物体的名字
bpy.context.object.name
利用在上一节的部分知识可以用python写出一份完整的代码,如下例
import bpy
def mySpecifier(objName):
# Return the datablock
return bpy.data.objects[objName]
# Store a reference to the datablock
myCube = mySpecifier('Cube')
# Output the location of the origin
print(myCube.location)
# Works exactly the same as above
myCube = bpy.data.objects['Cube']
print(myCube.location)
这里的输出不在python控制台显示,而是需要打开系统控制台
另外一个比较长的项目作为本次的结尾,其中包含了旋转,新建,激活等各种方法以及类的使用。代码可以直接运行。
import bpy
# Selecting objects by name
def select(objName):
bpy.ops.object.select_all(action='DESELECT')
bpy.data.objects[objName].select_set(True)
# Activating objects by name
def activate(objName):
bpy.context.view_layer.objects.active=bpy.data.objects[objName]
class sel:
"""Function Class for operating on SELECTED objects"""
# Differential
def translate(v):
bpy.ops.transform.translate(value=v, constraint_axis=(True, True, True))
# Differential
def scale(v):
bpy.ops.transform.resize(value=v, constraint_axis=(True, True, True))
# Differential
def rotate_x(v):
bpy.ops.transform.rotate(value=v, orient_axis='X')
# Differential
def rotate_y(v):
bpy.ops.transform.rotate(value=v, orient_axis='Y')
# Differential
def rotate_z(v):
bpy.ops.transform.rotate(value=v, orient_axis='Z')
class act:
"""Function Class for operating on ACTIVE objects"""
# Declarative
def location(v):
bpy.context.object.location = v
# Declarative
def scale(v):
bpy.context.object.scale = v
# Declarative
def rotation(v):
bpy.context.object.rotation_euler = v
# Rename the active object
def rename(objName):
bpy.context.object.name = objName
class spec:
"""Function Class for operating on SPECIFIED objects"""
# Declarative
def scale(objName, v):
bpy.data.objects[objName].scale = v
# Declarative
def location(objName, v):
bpy.data.objects[objName].location = v
# Declarative
def rotation(objName, v):
bpy.data.objects[objName].rotation_euler = v
class create:
"""Function Class for CREATING Objects"""
def cube(objName):
bpy.ops.mesh.primitive_cube_add(size=0.5, location=(0, 0, 0))
act.rename(objName)
def sphere(objName):
bpy.ops.mesh.primitive_uv_sphere_add(radius=0.5, location=(0, 0, 0))
act.rename(objName)
def cone(objName):
bpy.ops.mesh.primitive_cone_add(radius1=0.5, location=(0, 0, 0))
act.rename(objName)
# Delete an object by name
def delete(objName):
select(objName)
bpy.ops.object.delete(use_global=False)
# Delete all objects
def delete_all():
if(len(bpy.data.objects) != 0):
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)
if __name__ == "__main__":
# Create a cube
create.cube('PerfectCube')
# Differential transformations combine
sel.translate((0, 1, 2))
sel.scale((1, 1, 2))
sel.scale((0.5, 1, 1))
sel.rotate_x(3.1415 / 8)
sel.rotate_x(3.1415 / 7)
sel.rotate_z(3.1415 / 3)
# Create a cone
create.cone('PointyCone')
# Declarative transformations overwrite
act.location((-2, -2, 0))
spec.scale('PointyCone', (1.5, 2.5, 2))
# Create a Sphere
create.sphere('SmoothSphere')
# Declarative transformations overwrite
spec.location('SmoothSphere', (2, 0, 0))
act.rotation((0, 0, 3.1415 / 3))
act.scale((1, 3, 1))