Problemas con Script pra Rig UI personalizada.
Estoy haciendo un rig para la falda de un personaje con IK/FK y asi ahorrarme cloth simulations.
Las mecanicas funcionan bien asi que ahora intento hacer un Script para poder snapear los huesos IK a los FK pulsando un botón.
Se que hay algunos addons con esta misma propiedad pero están pensados para brazos con cadenas de tres huesos y mi falda tiene cadenas de ocho huesos.
Este es mi codigo, paso el .py por Dropbox:
https://www.dropbox.com/scl/fi/h73z9...=w1yebkfs&dl=0
En el panel del 3D_View me sale la opción de visibilidad de colecciones y me sale el slider de la influencia IK manejada por Drivers, con esa parte no hay problema. Pero cuando llego al panel del IK SNAP no me aparece ningún boton, es más, sospecho que mi funcion para reposicionar los huesos no debe ser correcta. La verdad es que no soy programador asi que estoy un poco perdido, agradecería un ayudita si puede ser.
Snap IK/FK en el Rig de una Falda
Hola Nobie, para estos casos, ChatGPT puede ayudarte al instante sin tener que esperar. Le he comentado tu problema y me dice esto:
Tu script tiene una buena base para crear un panel de UI personalizado en Blender, pero hay algunos problemas que deben corregirse, especialmente en el operador de "IK_to_FK Snap" y en la definición de propiedades.
Problemas y Soluciones
Definición del operador para el botón de "IK_to_FK Snap": El operador IK_to_FK debe registrarse como una clase que herede de bpy.types.Operator, y luego debe llamarse correctamente desde el panel. Actualmente, IK_to_FK está definido como una función dentro de la clase RIG_PT_Snaping_Panel, lo cual causará errores.
Error en el botón "IK_to_FK": El botón que has creado en el método draw de la clase RIG_PT_Snaping_Panel no funcionará porque el operador "IK_to_FK" no está bien definido y registrado. Además, en la función layout.operator deberías usar el identificador del operador en lugar de llamarlo directamente.
Corrección en el uso de matrices: Cambiar la matriz de un hueso directamente puede causar problemas si el hueso está restringido por otros sistemas (como IK o constraints). Es posible que necesites modificar la matriz de pose en lugar de la matriz general.
Código Corregido
Código:
bl_info = {
"name": "Falda Rig",
"author": "Ignacio Noreña",
"version": (0, 0, 1),
"blender": (4, 0, 0),
"location": "3D Viewport > Sidebar > FALDA RIG",
"description": "Custom Cloth IK/FK Rig",
"category": "Testing",
}
import bpy
# Propiedades del Panel
ARMATURE_NAME = "FAUST"
PANEL_NAME = "FALDA RIG"
# Panel para colecciones
class RIG_PT_Collections_Panel(bpy.types.Panel):
bl_label = "Bone Collections"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = PANEL_NAME
def draw(self, context):
ARMATURE = bpy.data.objects[ARMATURE_NAME]
collections = ARMATURE.data.collections
layout = self.layout
layout.prop(collections["Falda"], 'is_visible', toggle=True, text='FALDA')
layout.prop(collections["Falda.F (IK)"], 'is_visible', toggle=True, text='FALDA.F (IK)')
layout.prop(collections["Falda.B (IK)"], 'is_visible', toggle=True, text='FALDA.B (IK)')
layout.prop(collections["Falda.F (FK)"], 'is_visible', toggle=True, text='FALDA.F (FK)')
layout.prop(collections["Falda.B (FK)"], 'is_visible', toggle=True, text='FALDA.B (FK)')
layout.prop(collections["Paper.L (IK)"], 'is_visible', toggle=True, text='Paper.L (IK)')
layout.prop(collections["Paper.R (IK)"], 'is_visible', toggle=True, text='Paper.R (IK)')
layout.prop(collections["Paper.L (FK)"], 'is_visible', toggle=True, text='Paper.L (FK)')
layout.prop(collections["Paper.R (FK)"], 'is_visible', toggle=True, text='Paper.R (FK)')
# Panel para el switch de IK/FK
class RIG_PT_IKFK_Panel(bpy.types.Panel):
bl_label = "IK/FK SWITCH"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = PANEL_NAME
def draw(self, context):
ARMATURE = bpy.data.objects[ARMATURE_NAME]
root = ARMATURE.pose.bones["root"]
layout = self.layout
layout.prop(root, '["Falda_IK_Influence"]', text="IK_Influence", slider=True)
# Operador para el Snap IK to FK
class RIG_OT_IK_to_FK(bpy.types.Operator):
bl_idname = "rig.ik_to_fk"
bl_label = "IK to FK Snap"
bl_description = "Snapea los huesos IK a FK"
def execute(self, context):
ARMATURE = bpy.data.objects[ARMATURE_NAME]
# Define los huesos IK y FK
IK_bones = [
'FFR_IK_007', 'FC_IK_007', 'FFL_IK_007', 'FBL_IK_007',
'FBR_IK_007', 'FBC_IK_007', 'PaperL_IK_005', 'PaperR_IK_005'
]
FK_bones = [
'FFR_FK_007', 'FC_FK_007', 'FFL_FK_007', 'FBL_FK_007',
'FBR_FK_007', 'FBC_FK_007', 'PaperL_FK_005', 'PaperR_FK_005'
]
# Asigna la matriz de cada hueso IK al correspondiente FK
for ik_bone, fk_bone in zip(IK_bones, FK_bones):
ARMATURE.pose.bones[ik_bone].matrix = ARMATURE.pose.bones[fk_bone].matrix
return {'FINISHED'}
# Panel para el snap de IK/FK
class RIG_PT_Snaping_Panel(bpy.types.Panel):
bl_label = "IK/FK SNAPPING"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = PANEL_NAME
def draw(self, context):
layout = self.layout
layout.operator("rig.ik_to_fk", text="IK SNAP")
# Registro y desregistro de clases
def register():
bpy.utils.register_class(RIG_PT_Collections_Panel)
bpy.utils.register_class(RIG_PT_IKFK_Panel)
bpy.utils.register_class(RIG_PT_Snaping_Panel)
bpy.utils.register_class(RIG_OT_IK_to_FK)
def unregister():
bpy.utils.unregister_class(RIG_PT_Collections_Panel)
bpy.utils.unregister_class(RIG_PT_IKFK_Panel)
bpy.utils.unregister_class(RIG_PT_Snaping_Panel)
bpy.utils.unregister_class(RIG_OT_IK_to_FK)
if __name__ == "__main__":
register()
Explicaciones de las correcciones
Clase RIG_OT_IK_to_FK: Se crea una clase específica para el operador de snap IK_to_FK, que hereda de bpy.types.Operator. Esto permite que el operador funcione correctamente y esté disponible en el panel.
Registro del operador: El operador RIG_OT_IK_to_FK se registra y se llama correctamente en el panel RIG_PT_Snaping_Panel.
Asignación de matrices: La asignación de matrices entre los huesos IK y FK se mantiene. Sin embargo, asegúrate de que no haya restricciones que impidan la asignación directa.
Con estos ajustes, tu script debería poder ejecutar el snap de huesos IK a FK usando el botón en el panel de Blender.