Skip to content

Instantly share code, notes, and snippets.

@wakarase
Created March 14, 2023 10:27
Show Gist options
  • Save wakarase/da19267696bd5cd23941f57ad59c0265 to your computer and use it in GitHub Desktop.
Save wakarase/da19267696bd5cd23941f57ad59c0265 to your computer and use it in GitHub Desktop.
# BlenderユーザーのためのPython入門
# 第25節 ボーンを作成してボーンアニメーションさせる
import bpy
import math
import mathutils
class BoneAnimation():
def __init__(self):
"""既存のアーマチュアとメッシュを削除します。"""
for armature in bpy.data.armatures:
assert isinstance(armature, bpy.types.Armature)
bpy.data.armatures.remove(armature)
for mesh in bpy.data.meshes:
assert isinstance(mesh, bpy.types.Mesh)
bpy.data.meshes.remove(mesh)
for material in bpy.data.materials:
assert isinstance(material, bpy.types.Material)
bpy.data.materials.remove(material)
def make_objects(self):
"""アーマチュアとメッシュを作ります。"""
bpy.ops.object.add(type='ARMATURE')
self.armature_object = bpy.context.active_object
bpy.ops.mesh.primitive_cylinder_add(end_fill_type='TRIFAN')
self.mesh_object = bpy.context.active_object
bpy.context.view_layer.objects.active = self.armature_object
def make_bones(self):
"""2つのボーンを配置します。"""
bpy.ops.object.mode_set(mode='EDIT')
armature = self.armature_object.data
assert isinstance(armature, bpy.types.Armature)
edit_bone = armature.edit_bones.new('Bone')
assert isinstance(edit_bone, bpy.types.EditBone)
edit_bone.head = (0, 0, -1)
edit_bone.tail = (0, 0, 0)
parent = edit_bone
edit_bone = armature.edit_bones.new('Bone2')
assert isinstance(edit_bone, bpy.types.EditBone)
edit_bone.head = parent.tail
edit_bone.tail = (0, 0, 1)
edit_bone.parent = parent
bpy.ops.object.mode_set(mode='OBJECT')
bpy.context.view_layer.objects.active = self.mesh_object
bpy.context.view_layer.objects.active = self.armature_object
bpy.ops.object.parent_set(type='ARMATURE_AUTO')
def make_animation(self):
"""ボーンアニメーションのキーフレームを設定します。"""
object = self.armature_object
pose = object.pose
assert isinstance(pose, bpy.types.Pose)
pose_bone = pose.bones['Bone2']
assert isinstance(pose_bone, bpy.types.PoseBone)
rotations = [(0, 0, 0), (90, 0, 0), (-90, 0, 0), (0, 90, 0), (0, -90, 0), (0, 0, 90), (0, 0, -90), (0, 0, 0)]
pose_bone.rotation_mode = 'XYZ'
for i, (x, y, z) in enumerate(rotations):
euler = pose_bone.rotation_euler
assert isinstance(euler, mathutils.Euler)
euler.x = math.radians(x)
euler.y = math.radians(y)
euler.z = math.radians(z)
pose_bone.keyframe_insert('rotation_euler', frame=35 * i)
def make_material(self):
"""マテリアル等の設定をします。"""
object = self.mesh_object
bpy.context.view_layer.objects.active = object
material = bpy.data.materials.new('MyMaterial')
material.use_nodes = True
node_tree = material.node_tree
assert isinstance(node_tree, bpy.types.ShaderNodeTree)
principled_bsdf = node_tree.nodes['Principled BSDF']
assert isinstance(principled_bsdf, bpy.types.ShaderNodeBsdfPrincipled)
principled_bsdf.inputs['Metallic' ].default_value = 1.0
principled_bsdf.inputs['Roughness'].default_value = 0.0
bpy.context.object.data.materials.append(material)
# bpy.ops.object.shade_smooth()
if __name__ == '__main__':
bone = BoneAnimation()
bone.make_objects()
bone.make_bones()
bone.make_animation()
bone.make_material()
bpy.context.scene.frame_set(1)
print('Done.')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment