Scripting Tipps and Examples
Offical API-Doc Links:
- BlendData: Main data structure representing a .blend file and all its data-blocks
- Scene
- Object - Object Operators
- Mesh: MeshVertex - MeshEdge - MeshLoop - MeshPolygon
- Curve: Spline - SplinePoint - BezierSplinePoint
- Material - Is "None" by default, as most objects don't start with a material. Query first!
Tutorial Links:
Offical
- Tips and Tricks
- Scripting Tips
- Basic Menu Example
- BMesh Module (bmesh): Short for "Blender Mesh", this module provides access to blenders bmesh data structures.
- Modal Operators
3rd Party Tutorials
Cheatsheet
Selection
WARNING: Blender makes a huge difference between "Selected Object" and "Active Object"! The active object is the object actually edited (as in operators usually apply to the active object), while a selected objects is merely part of the selection. While one object can be both selected and active at the same time, that is not necessarily a given! Hence when changing the selection, make sure you're wether you need to set the active object!
print(bpy.context.active_object) #last selected and active object
print(bpy.context.object) #last selected (but not actively selected!) object
print(bpy.context.selected_objects) # list of selected objects
print(bpy.context.selectable_objects) # list of selectable objects
print(bpy.data.objects['Cube']) # Get object by name
See also: bpy.context
# Set selection
bpy.data.objects['Cube'].select_set(True)
# Set active object
bpy.context.view_layer.objects.active = bpy.data.objects['Cube']
This is my little selection script that simply selects a group of objects:
def select(*objs):
bpy.ops.object.select_all(action='DESELECT')
if len(objs)==0:
return
for obj in objs:
obj.select_set(True)
bpy.context.view_layer.objects.active = objs[0]
Interaction Mode
Setting an interaction mode:
bpy.ops.object.mode_set_with_submode(mode="OBJECT")
bpy.ops.object.mode_set(mode="EDIT")
bpy.ops.mesh.select_mode(type="FACE")
Querying an interaction mode:
mode = bpy.context.active_object.mode # active_object is the last selected object
# or
mode = bpy.context.mode
*see bpy.context.mode
Querying the mesh sub mode:
# it's a tuple of 3 bools
vertex, edge, face = context.scene.tool_settings.mesh_select_mode
# result: true false false
Blender Forum about Selection Issues
Creating new objects:
def add_mesh(name, verts, faces, edges=None, col_name="Collection"):
if edges is None:
edges = []
mesh = bpy.data.meshes.new(name)
obj = bpy.data.objects.new(mesh.name, mesh)
col = bpy.data.collections.get(col_name)
col.objects.link(obj)
bpy.context.view_layer.objects.active = obj
mesh.from_pydata(verts, edges, faces)
verts = [( 1.0, 1.0, 0.0),
( 1.0, -1.0, 0.0),
(-1.0, -1.0, 0.0),
(-1.0, 1.0, 0.0),
]
faces = [[0, 1, 2, 3]]
add_mesh("myBeautifulMesh_1", verts, faces)
Ref: Polygons Vertices from_pydata
Converting Filepaths
Blender uses its own relative file path format. To convert this, use bpy.path.abspath and bpy.path.relpath.
WARNING: Paths need to be absolute to use them in any other context than blender. This includes checking for existence via os.path.exists.
UI Stuff
Progress bar updates:
from time import sleep
import bpy
wm=bpy.context.window_manager
wm.progress_begin(0, 100) #(*min*, *max*)
for i in range(100):
sleep(.01)
wm.progress_update(i)
wm.progress_end()
Examples
Quickly import a full list of OBJ-files:
import bpy
import os
src_path=r"D:\Games\itch.io\kenney-game-assets-1\3D assets\Fantasy Town Kit\Models\OBJ format"
for f in os.scandir(src_path):
if f.name[-4:].lower()==".obj":
print("Importing {}".format(f.path))
# fix that!
bpy.ops.import_scene.obj(filepath=f.path) # "filepath=" is important