Initial commit
This commit is contained in:
136
skills/addon/commands/animation.py
Normal file
136
skills/addon/commands/animation.py
Normal file
@@ -0,0 +1,136 @@
|
||||
"""
|
||||
Animation 관련 명령 핸들러
|
||||
애니메이션 재생, NLA 트랙 관리
|
||||
"""
|
||||
|
||||
import bpy
|
||||
from typing import List
|
||||
from ..utils.logger import get_logger
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
def list_animations(armature_name: str) -> List[str]:
|
||||
"""
|
||||
아마추어의 애니메이션 액션 목록
|
||||
|
||||
Args:
|
||||
armature_name: 아마추어 이름
|
||||
|
||||
Returns:
|
||||
액션 이름 리스트
|
||||
|
||||
Raises:
|
||||
ValueError: 아마추어를 찾을 수 없는 경우
|
||||
"""
|
||||
logger.debug(f"Listing animations for armature: {armature_name}")
|
||||
|
||||
armature = bpy.data.objects.get(armature_name)
|
||||
if not armature:
|
||||
logger.error(f"Armature '{armature_name}' not found")
|
||||
raise ValueError(f"Armature '{armature_name}' not found")
|
||||
|
||||
actions = []
|
||||
if armature.animation_data:
|
||||
for action in bpy.data.actions:
|
||||
if action.id_root == 'OBJECT':
|
||||
actions.append(action.name)
|
||||
|
||||
logger.info(f"Found {len(actions)} animations for {armature_name}")
|
||||
return actions
|
||||
|
||||
|
||||
def play_animation(armature_name: str, action_name: str, loop: bool = True) -> str:
|
||||
"""
|
||||
애니메이션 재생
|
||||
|
||||
Args:
|
||||
armature_name: 아마추어 이름
|
||||
action_name: 액션 이름
|
||||
loop: 루프 재생 여부
|
||||
|
||||
Returns:
|
||||
결과 메시지
|
||||
|
||||
Raises:
|
||||
ValueError: 아마추어 또는 액션을 찾을 수 없는 경우
|
||||
"""
|
||||
logger.info(f"Playing animation: {action_name} on {armature_name}")
|
||||
|
||||
armature = bpy.data.objects.get(armature_name)
|
||||
if not armature:
|
||||
logger.error(f"Armature '{armature_name}' not found")
|
||||
raise ValueError(f"Armature '{armature_name}' not found")
|
||||
|
||||
action = bpy.data.actions.get(action_name)
|
||||
if not action:
|
||||
logger.error(f"Action '{action_name}' not found")
|
||||
raise ValueError(f"Action '{action_name}' not found")
|
||||
|
||||
if not armature.animation_data:
|
||||
armature.animation_data_create()
|
||||
|
||||
armature.animation_data.action = action
|
||||
bpy.context.scene.frame_set(int(action.frame_range[0]))
|
||||
bpy.ops.screen.animation_play()
|
||||
|
||||
logger.info(f"Started playing {action_name}")
|
||||
return f"Playing {action_name}"
|
||||
|
||||
|
||||
def stop_animation() -> str:
|
||||
"""
|
||||
애니메이션 중지
|
||||
|
||||
Returns:
|
||||
결과 메시지
|
||||
"""
|
||||
logger.info("Stopping animation playback")
|
||||
bpy.ops.screen.animation_cancel()
|
||||
return "Animation stopped"
|
||||
|
||||
|
||||
def add_to_nla(armature_name: str, action_name: str, track_name: str) -> str:
|
||||
"""
|
||||
NLA 트랙에 애니메이션 추가
|
||||
|
||||
Args:
|
||||
armature_name: 아마추어 이름
|
||||
action_name: 액션 이름
|
||||
track_name: 트랙 이름
|
||||
|
||||
Returns:
|
||||
결과 메시지
|
||||
|
||||
Raises:
|
||||
ValueError: 아마추어 또는 액션을 찾을 수 없는 경우
|
||||
"""
|
||||
logger.info(f"Adding {action_name} to NLA track {track_name} on {armature_name}")
|
||||
|
||||
armature = bpy.data.objects.get(armature_name)
|
||||
if not armature:
|
||||
logger.error(f"Armature '{armature_name}' not found")
|
||||
raise ValueError(f"Armature '{armature_name}' not found")
|
||||
|
||||
action = bpy.data.actions.get(action_name)
|
||||
if not action:
|
||||
logger.error(f"Action '{action_name}' not found")
|
||||
raise ValueError(f"Action '{action_name}' not found")
|
||||
|
||||
if not armature.animation_data:
|
||||
armature.animation_data_create()
|
||||
|
||||
# NLA 트랙 생성 또는 찾기
|
||||
nla_tracks = armature.animation_data.nla_tracks
|
||||
track = nla_tracks.get(track_name)
|
||||
|
||||
if not track:
|
||||
track = nla_tracks.new()
|
||||
track.name = track_name
|
||||
logger.debug(f"Created new NLA track: {track_name}")
|
||||
|
||||
# 액션을 스트립으로 추가
|
||||
strip = track.strips.new(action.name, int(action.frame_range[0]), action)
|
||||
logger.info(f"Added strip {strip.name} to track {track_name}")
|
||||
|
||||
return f"Added {action_name} to NLA track {track_name}"
|
||||
Reference in New Issue
Block a user