Skip to content

Instantly share code, notes, and snippets.

@wakarase
Created March 14, 2023 20:51
Show Gist options
  • Save wakarase/801343a4d98165be9bcb793b5a227dd7 to your computer and use it in GitHub Desktop.
Save wakarase/801343a4d98165be9bcb793b5a227dd7 to your computer and use it in GitHub Desktop.
# BlenderユーザーのためのPython入門
# 第26節 ギャグマシーンを作成する
import bpy
import math
import random
# 人体を構成する10個のオブジェクトです。
objs = []
# 身体の各部分に許容する回転角です。
rot_range = (10, 45, 90, 90, 90, 90, 90, 90, 90, 90)
def make_cube(parent, loc, scale, pivot, name):
"""立方体を作ります。
parent: 親にするオブジェクトです。
loc: 立方体の中心の座標です。
scale: 軸ごとの拡大縮小率です。
pivot: 立方体の中心から相対的な、回転中心です。
name: オブジェクトに与える名前です。
"""
# scaleの値は半分にしたほうがよさそうです。
x, y, z = scale
x, y, z = x / 2, y / 2, z / 2
scale = x, y, z
bpy.ops.mesh.primitive_cube_add(location=loc, scale=scale)
obj = bpy.context.active_object
# 回転中心のローカル座標からワールド座標を得ます。
x = obj.location.x + pivot[0]
y = obj.location.y + pivot[1]
z = obj.location.z + pivot[2]
bpy.context.scene.cursor.location = (x, y, z)
bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
if parent is not None:
obj.parent = parent
if name:
obj.name = name
return obj
def set_animation(obj, frame, rotation):
"""objの第frameフレームに回転角rotationでキーフレームを登録します。"""
bpy.context.scene.frame_set(frame)
obj.rotation_euler = rotation
obj.keyframe_insert(data_path="rotation_euler")
for m in bpy.data.meshes:
"""既存のメッシュ、つまり以前に作った立方体などを削除します。"""
bpy.data.meshes.remove(m)
# 人体の各部となる立方体を配置します。
loc = (0, 0, 0)
scale = (3, 1.5, 4)
pivot = (0, 0, -2)
objs.append(make_cube(None, loc, scale, pivot, 'Hip'))
loc = (0, 0, 5)
scale = (2, 2, 2)
pivot = (0, 0, -1)
objs.append(make_cube(objs[0], loc, scale, pivot, 'Head'))
loc = (2.5, 0, 3.5)
scale = (2, 1, 1)
pivot = (-1, 0, 0)
objs.append(make_cube(objs[0], loc, scale, pivot, 'UpperArm.L'))
loc = (3, 0, 0)
scale = (2, 1, 1)
pivot = (-1, 0, 0)
objs.append(make_cube(objs[2], loc, scale, pivot, 'LowerArm.L'))
loc = (-2.5, 0, 3.5)
scale = (2, 1, 1)
pivot = (1, 0, 0)
objs.append(make_cube(objs[0], loc, scale, pivot, 'UpperArm.R'))
loc = (-3, 0, 0)
scale = (2, 1, 1)
pivot = (1, 0, 0)
objs.append(make_cube(objs[4], loc, scale, pivot, 'LowerArm.R'))
loc = (0.8, 0, -1)
scale = (1.25, 1.25, 2)
pivot = (0, 0, 1)
objs.append(make_cube(objs[0], loc, scale, pivot, 'UpperLeg.L'))
loc = (0, 0, -3)
scale = (1.25, 1.25, 2)
pivot = (0, 0, 1)
objs.append(make_cube(objs[6], loc, scale, pivot, 'LowerLeg.L'))
loc = (-0.8, 0, -1)
scale = (1.25, 1.25, 2)
pivot = (0, 0, 1)
objs.append(make_cube(objs[0], loc, scale, pivot, 'UpperLeg.R'))
loc = (0, 0, -3)
scale = (1.25, 1.25, 2)
pivot = (0, 0, 1)
objs.append(make_cube(objs[8], loc, scale, pivot, 'LowerLeg.R'))
for o in range(len(objs)): # 人体の各部分について。
obj = objs[o]
obj.animation_data_clear()
obj.rotation_mode = "XYZ"
set_animation(obj, 0, (0, 0, 0)) # 開始フレームでは直立姿勢です。
for frame in range(25, 250, 25):
rot = rot_range[o] # 身体の各部分に許容する回転角です。
# 一様分布でランダムな回転角を与えます。
x = math.radians(random.uniform(-rot, rot))
y = math.radians(random.uniform(-rot, rot))
z = math.radians(random.uniform(-rot, rot))
set_animation(obj, frame, (x, y, z))
set_animation(obj, 250, (0, 0, 0)) # 終了フレームでは直立姿勢です。
bpy.context.scene.frame_start = 0
bpy.context.scene.frame_end = 250
bpy.context.scene.frame_set(0)
def set_material():
"""人体各部に同じマテリアルを割り当てます。"""
for material in bpy.data.materials:
bpy.data.materials.remove(material)
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['Base Color' ].default_value = (0.5, 0.5, 0.5, 1)
principled_bsdf.inputs['Roughness' ].default_value = 0.0
principled_bsdf.inputs['Transmission'].default_value = 1.0
for object in objs:
bpy.context.view_layer.objects.active = object
bpy.context.object.data.materials.append(material)
bpy.ops.object.select_all(action='DESELECT')
set_material()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment