Новичок в Blender Python: удаление запеченной анимации и процедурное управление костями арматуры с помощью пользовательсPython

Программы на Python
Ответить
Anonymous
 Новичок в Blender Python: удаление запеченной анимации и процедурное управление костями арматуры с помощью пользовательс

Сообщение Anonymous »


Отказ от ответственности: я не 3D-моделист и не аниматор, новичок...
Мои сильные стороны: Front-End Dev, аудиоинженерия, C#, Julia (сейчас я использую ChatGPT для Python и ненавижу его. Код внизу).
Я работаю в Blender 5.0 (модель изначально взята из Maya) с академической установкой FBX для гортани.
3D-модель гортани, исходный код FBX
Модель содержит каркас с костями с анатомическими названиями и несколько запеченных анимационных действий. Моя цель — удалить всю запеченную анимацию и заменить ее процедурным управлением с использованием драйверов, чтобы установка могла позже управляться внешними сигналами (аудио/ИИ).
Я написал скрипт Python, который очищает данные анимации на арматуре, удаляет все действия, добавляет к арматуре пользовательские свойства и устанавливает скриптовые драйверы на определенные кости позы (положение, вращение, масштаб). Скрипт выполняется с ошибками, появляются некоторые пользовательские свойства и создаются драйверы, но перемещение ползунков пользовательских свойств не приводит к перемещению костей.
Я пытаюсь понять, чего мне не хватает в архитектурном отношении, а не просто исправлять синтаксис. Возможные проблемы, которые я рассматриваю:
  • неправильные пути к данным для драйверов костей позы.
  • необходимость явного задания режима вращения костей позы.
  • трансформации переопределяются позой покоя или ограничениями.
  • драйверы создаются, но не оцениваются.
  • ограничения драйверов на костях позы при отсутствии ключевых кадров
  • неправильное наименование арматуры или проблемы с контекстом
Каков правильный или рекомендуемый подход в Blender для:
  • полного удаления запеченной анимации из импортированной rig, и
  • процедурно управлять костями позы, используя пользовательские свойства или внешние входные данные.
Использование драйверов - правильный подход здесь, или это должно быть сделано с ограничениями, обработчиками или полностью другой системой?
Моя КОНЕЧНАЯ цель — анимировать это в Three.js иorbitcontrols.js и мне нужно вызвать отдельные узлы или драйверы или что-то еще, чтобы заставить их перейти к аудио. Я сделал это с черепом, теперь пробую гортань и легкие, которые уже имеют гладкую поверхность и имеют элементы управления анимацией. Тогда крутой скайбокс.
import bpy
import math

# =====================================================
# CONFIG
# =====================================================
ARMATURE_NAME = "LarynxRig"

# =====================================================
# UTILITIES
# =====================================================
def get_armature(name):
obj = bpy.data.objects.get(name)
if not obj:
raise RuntimeError(f"Armature '{name}' not found")
if obj.type != 'ARMATURE':
raise RuntimeError(f"Object '{name}' is not an armature")
return obj

def clear_object_animation(obj):
if obj.animation_data:
obj.animation_data_clear()

def ensure_prop(obj, name, default=0.0):
if name not in obj:
obj[name] = default
ui = obj.id_properties_ui(name)
ui.update(
min=-1.0,
max=1.0,
soft_min=-1.0,
soft_max=1.0
)

def add_driver(pose_bone, data_path, index, prop_name, scale):
fcurve = pose_bone.driver_add(data_path, index)
drv = fcurve.driver
drv.type = 'SCRIPTED'

var = drv.variables.new()
var.name = "x"
var.targets[0].id = arm
var.targets[0].data_path = f'["{prop_name}"]'

drv.expression = f"x * {scale}"

# =====================================================
# STEP 1: GET ARMATURE
# =====================================================
arm = get_armature(ARMATURE_NAME)

# Ensure Object Mode
if bpy.context.mode != 'OBJECT':
bpy.ops.object.mode_set(mode='OBJECT')

# =====================================================
# STEP 2: STRIP ALL BAKED ANIMATION
# =====================================================
clear_object_animation(arm)

# Remove all Actions (safe for this file)
for action in list(bpy.data.actions):
bpy.data.actions.remove(action)

print("✔ Baked animations stripped")

# =====================================================
# STEP 3: CREATE PROCEDURAL CONTROL PROPERTIES
# =====================================================
ensure_prop(arm, "larynx_lift", 0.0) # pitch / emphasis
ensure_prop(arm, "inlet_constrict", 0.0) # voiced vs unvoiced
ensure_prop(arm, "epiglottis_tilt", 0.0) # swallow / shielding
ensure_prop(arm, "airflow", 0.0) # breath intensity

print("✔ Control properties installed")

# =====================================================
# STEP 4: INSTALL PROCEDURAL DRIVERS
# =====================================================

# ---- Larynx vertical movement (pitch, emphasis)
if "Larynx_ROOT" in arm.pose.bones:
pb = arm.pose.bones["Larynx_ROOT"]
add_driver(pb, "location", 1, "larynx_lift", 0.02)

# ---- Top half larynx tilt (epilaryngeal shaping)
if "B_Top_half_larynx" in arm.pose.bones:
pb = arm.pose.bones["B_Top_half_larynx"]
add_driver(pb, "rotation_euler", 0, "inlet_constrict", math.radians(8))

# ---- Corniculate cartilage constriction
if "B_Corniculate_cartilage" in arm.pose.bones:
pb = arm.pose.bones["B_Corniculate_cartilage"]
add_driver(pb, "location", 0, "inlet_constrict", -0.01)

# ---- Epiglottis tilt (secondary coupling)
if "B_Thyroepiglottic1" in arm.pose.bones:
pb = arm.pose.bones["B_Thyroepiglottic1"]
add_driver(pb, "rotation_euler", 0, "epiglottis_tilt", math.radians(10))

# ---- Trachea expansion (airflow feedback)
if "B_Trachea" in arm.pose.bones:
pb = arm.pose.bones["B_Trachea"]
add_driver(pb, "scale", 1, "airflow", 0.08)

print("✔ Procedural drivers installed")
print("🎉 Rig is now signal-driven and animation-free")


Подробнее здесь: https://stackoverflow.com/questions/798 ... bones-proc
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»