75 lines
3.4 KiB
Python
75 lines
3.4 KiB
Python
"""
|
|
scene_setup.py
|
|
--------------
|
|
One-shot scene initialisation: camera, area light, world background,
|
|
render engine, and default playlist.
|
|
|
|
Call ``setup_scene()`` once after ``register()`` (typically from
|
|
``__main__`` or a startup hook).
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import bpy
|
|
|
|
from .constants import (
|
|
CAMERA_LOCATION, CAMERA_ROTATION,
|
|
LIGHT_LOCATION, LIGHT_ENERGY,
|
|
)
|
|
from .materials import prewarm_materials_and_blends
|
|
|
|
|
|
def setup_scene() -> None:
|
|
"""Configure the Blender scene for knot animation playback."""
|
|
scene = bpy.context.scene
|
|
|
|
# ── Timeline ─────────────────────────────────────────────────────────────
|
|
scene.frame_start = 1
|
|
scene.frame_end = 600
|
|
scene.render.fps = 24
|
|
|
|
# ── Render engine ────────────────────────────────────────────────────────
|
|
scene.render.engine = 'CYCLES'
|
|
scene.cycles.samples = 64
|
|
|
|
# ── Remove default objects ───────────────────────────────────────────────
|
|
for name in ("Cube", "Light", "Camera"):
|
|
obj = bpy.data.objects.get(name)
|
|
if obj:
|
|
bpy.data.objects.remove(obj, do_unlink=True)
|
|
|
|
# ── Camera ───────────────────────────────────────────────────────────────
|
|
cam_data = bpy.data.cameras.new("KnotCamera")
|
|
cam_data.lens = 50
|
|
cam_obj = bpy.data.objects.new("KnotCamera", cam_data)
|
|
cam_obj.location = CAMERA_LOCATION
|
|
cam_obj.rotation_euler = CAMERA_ROTATION
|
|
scene.collection.objects.link(cam_obj)
|
|
scene.camera = cam_obj
|
|
|
|
# ── Area Light ───────────────────────────────────────────────────────────
|
|
light_data = bpy.data.lights.new("KnotLight", type='AREA')
|
|
light_data.energy = LIGHT_ENERGY
|
|
light_data.size = 3.0
|
|
light_obj = bpy.data.objects.new("KnotLight", light_data)
|
|
light_obj.location = LIGHT_LOCATION
|
|
scene.collection.objects.link(light_obj)
|
|
|
|
# ── World background: dark gradient ──────────────────────────────────────
|
|
world = scene.world
|
|
if world is None:
|
|
world = bpy.data.worlds.new("KnotWorld")
|
|
scene.world = world
|
|
bg_node = world.node_tree.nodes.get("Background")
|
|
if bg_node:
|
|
bg_node.inputs["Color"].default_value = (0.02, 0.02, 0.05, 1.0)
|
|
bg_node.inputs["Strength"].default_value = 0.2
|
|
|
|
# ── Default playlist ─────────────────────────────────────────────────────
|
|
# NOTE: An empty CollectionProperty is falsy in Python; use len() to test.
|
|
if len(scene.knot_list) == 0:
|
|
bpy.ops.knot.populate() # also calls prewarm_materials_and_blends()
|
|
else:
|
|
prewarm_materials_and_blends(scene) # ensure shaders exist for existing list
|
|
|
|
print("[KnotScript] Scene setup complete.")
|