Blender scripting: generating meshes from bones
Published & Updated
Introducing my first Blender script: a tool to generate low-poly meshes from armatures. The goal was to speed up the process of prototyping simple character rigs, and to learn more about Blender and Python. The results aren't aesthetically amazing, but the script provides a very quick starting point.
This task proved challenging as most resources out there on Blender are now outdated, and I've found the API to be a little obtuse. Of course, as I experiment more, I'm sure it'll make more sense with time and practice. Here's the code if you want to try it out yourself:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This script creates a new mesh based off of an armature. | |
# To use, run the script while an armature is selected. | |
import bpy | |
import bmesh | |
from mathutils import Matrix,Vector | |
def makeMeshFromArmature(): | |
armature = bpy.context.active_object | |
try: armature.data.bones | |
except NameError: return | |
except AttributeError: return | |
bones = armature.data.bones | |
# make new mesh: | |
mesh = bpy.data.meshes.new('Armature Mesh') | |
# make new object: | |
mesh_obj = bpy.data.objects.new("Mesh from Armature", mesh) | |
# place new object in current collection: | |
bpy.context.collection.objects.link(mesh_obj) | |
# make it the active object: | |
bpy.context.view_layer.objects.active = mesh_obj | |
# select it as well: | |
mesh_obj.select_set(True) | |
# loop through bones to make bmesh: | |
bm = bmesh.new() | |
for bone in armature.data.bones: | |
#matrix from object to bone: | |
m1 = bone.matrix_local | |
#matrix to scale the bone (non-proportionally): | |
m2 = Matrix.Diagonal(Vector((0.2,bone.length,0.2,1.0))) | |
# matrix to slide the cube to center of bone: | |
m3 = Matrix.Translation(Vector((0.0,bone.length/2,0.0))) | |
# create the cube in the mesh: | |
bmesh.ops.create_cube(bm, size=1.0, matrix=m1 @ m3 @ m2) | |
# copy bmesh data into mesh: | |
bm.to_mesh(mesh) | |
bm.free() | |
# deselect all: | |
bpy.ops.object.select_all(action='DESELECT') | |
makeMeshFromArmature() |