"""
タイトル: Blender 基本シーン設定スクリプト
説明:
Blenderでの基本的なシーン設定を効率化するスクリプト。
ステージクリア、カメラ・照明の設置、背景色の指定、プリミティブオブジェクトの配置、マテリアル生成などの機能を含む。
すべての処理を個別の関数に分割して再利用可能に設計されています。
作成日: 2024年11月18日
バージョン: 1.6.0
以下読み込み方書式
import sys
import os
# スクリプトのあるディレクトリをPythonパスに追加
script_dir = os.path.dirname(bpy.data.filepath)
if script_dir not in sys.path:
sys.path.append(script_dir)
# インポート
from setup_stage import clear_stage,create_camera,create_light,set_background_color
"""
import bpy
import math
import mathutils
def clear_stage(keep_camera=True, keep_lights=True):
for obj in bpy.data.objects:
if (obj.type == 'CAMERA' and keep_camera) or (obj.type == 'LIGHT' and keep_lights):
continue
bpy.data.objects.remove(obj, do_unlink=True)
def clear_materials():
try:
for mat in bpy.data.materials:
bpy.data.materials.remove(mat, do_unlink=True)
print("すべてのマテリアルを削除しました。")
return True
except Exception as e:
print(f"マテリアル削除中にエラーが発生しました: {e}")
return False
def create_camera(location=(0, 0, 10), rotation=(math.radians(90), 0, 0), name="Camera"):
bpy.ops.object.camera_add(location=location)
camera = bpy.context.object
camera.name = name
camera.rotation_euler = rotation
return camera
def point_camera(camera, target=None, target_location=None):
"""
Args:
camera (bpy.types.Object): カメラオブジェクト。
target (bpy.types.Object): カメラが向く対象のオブジェクト(指定しない場合は target_location を使用)。
target_location (tuple): カメラが向く座標 (x, y, z)。target が None の場合に有効。
Returns:
bool: 成功した場合は True、失敗した場合は False。
"""
try:
if target is not None:
target_location = target.matrix_world.translation
elif target_location is None:
raise ValueError("target または target_location のいずれかを指定する必要があります。")
camera_location = camera.matrix_world.translation
direction = camera_location -mathutils.Vector(target_location)
direction.normalize()
rotation = direction.to_track_quat('Z', 'Y').to_euler()
camera.rotation_euler = rotation
return True
except Exception as e:
print(f"カメラの向き変更中にエラーが発生しました: {e}")
return False
def create_light(location=(10, 10, 10), rotation=(math.radians(0), math.radians(45), 0), light_type='SUN', energy=1000, color=(1.0, 1.0, 1.0), name="Light"):
bpy.ops.object.light_add(type=light_type, location=location)
light = bpy.context.object
light.name = name
light.rotation_euler = rotation
light.data.energy = energy
light.data.color = color
return light
def point_light(light_object, target_location):
try:
if light_object.type != 'LIGHT':
raise ValueError(f"Object '{light_object.name}' is not a light.")
light_location = mathutils.Vector(light_object.location)
direction = mathutils.Vector(target_location) - light_location
rotation = direction.to_track_quat('-Z', 'Y').to_euler()
light_object.rotation_euler = rotation
return True
except Exception as e:
print(f"照明の向き変更中にエラーが発生しました: {e}")
return False
def set_background_color(color=(0.0, 0.0, 0.0, 1.0)):
bpy.context.scene.world.use_nodes = True
bg_node = bpy.context.scene.world.node_tree.nodes.get("Background")
if bg_node:
bg_node.inputs[0].default_value = color
return True
else:
print("背景ノードが見つかりません。スキップします。")
return False
def initialize_stage(
camera_location=(0, 10, 10),
camera_rotation=(math.radians(45), math.radians(0), math.radians(180)),
light_location=(5, 5, 5),
light_rotation=(math.radians(-45), math.radians(0), 0),
light_type='SUN',
light_energy=5,
light_color=(1.0, 1.0, 1.0),
background_color=(0.0, 0.0, 0.5, 1.0),
keep_camera=False,
keep_lights=False,
keep_matelials=True):
clear_stage(keep_camera=keep_camera, keep_lights=keep_lights)
if keep_matelials:
clear_materials()
camera = create_camera(location=camera_location, rotation=camera_rotation, name="Camera")
light = create_light(location=light_location, rotation=light_rotation, light_type=light_type, color=light_color, energy=light_energy, name="Light")
set_background_color(color=background_color)
return camera,light
def create_material(name="Material", color=(1.0, 1.0, 1.0, 1.0)):
mat = bpy.data.materials.get(name)
if not mat:
mat = bpy.data.materials.new(name=name)
mat.use_nodes = True
bsdf = mat.node_tree.nodes.get("Principled BSDF")
if bsdf:
bsdf.inputs["Base Color"].default_value = color
return mat
def create_primitive_object(object_type='SPHERE', location=(0, 0, 0), scale=(1, 1, 1), rotation=(0, 0, 0), color=(1.0, 1.0, 1.0, 1.0), name="Object"):
if object_type.upper() == 'SPHERE':
bpy.ops.mesh.primitive_uv_sphere_add(location=location)
elif object_type.upper() == 'CUBE':
bpy.ops.mesh.primitive_cube_add(location=location)
elif object_type.upper() == 'CYLINDER':
bpy.ops.mesh.primitive_cylinder_add(location=location)
elif object_type.upper() == 'CONE':
bpy.ops.mesh.primitive_cone_add(location=location)
elif object_type.upper() == 'PLANE':
bpy.ops.mesh.primitive_plane_add(location=location)
else:
raise ValueError(f"Unsupported object type: {object_type}")
obj = bpy.context.object
obj.name = name
obj.scale = scale
obj.rotation_euler = rotation
mat = create_material(name=f"{name}_Material", color=color)
obj.data.materials.append(mat)
return obj
if __name__ == "__main__":
camera, light = initialize_stage(
camera_location=(20, 10, 10),
camera_rotation=(math.radians(90), 0, 0),
light_location=(0, 10, 10),
light_type='SPOT',
light_energy=5000,
light_color=(1.0, 1.0, 0.3),
background_color=(0.0, 0.3, 0.8, 1.0),
keep_camera=False,
keep_lights=False,
keep_matelials=True
)
target_location = (0, 0, 0)
point_camera(camera, target_location=(0, -1, 0))
point_light(light, target_location)
create_primitive_object(object_type='PLANE', location=(0, 0, 0), scale=(25, 25, 25), rotation=(0, 0, 0), color=(0.5, 0.9, 0.5, 1.0), name="Plane")
create_primitive_object(object_type='SPHERE', location=(-2, 0, 1.5), scale=(1, 1, 1), rotation=(0, 0, 0), color=(1.0, 0.0, 0.0, 1.0), name="RedSphere")
create_primitive_object(object_type='CUBE', location=(2, 0, 1.5), scale=(1, 1, 1), rotation=(math.radians(45), math.radians(45), math.radians(45)), color=(0.0, 0.0, 1.0, 1.0), name="BlueCube")