-
Auto-snap para IK y fk
Hola a todos. Me estoy blenderizando, bueno, creo que ya he terminado de blenderizarme y me he convertido en un blenderadicto, estoy trasteando con el tema de los rigs y quería darle una vuelta de tuerca más y poner un control con autosnap IK/FK, el tema ese de que se me pase de IK a FK y viceversa sin perder las posiciones y rotaciones, como de programar no tengo ni idea estuve buscando a ver si alguien había hecho algo de eso y encontré un enlace, con un blend con su código, pero no consigo que me funcione, el lo hizo para la v 2.5 pero en la actual no consigo que chute. Sé que han cambiado algunas cosas en el tema de la programación, pero es que, yo de esto ni, idea, a ver si alguien me echa una manita que agradezco de antemano y aquí dejo la información:
El video en cuestión es este.
Y el código que no sé por qué no funciona es este, edito para que quede más mono.
Código:
Import Bpy.
Import Mathutils.
From Mathutils import *
###########################.
Class snap_fk_ik(Bpy, types. Panel):
Bl_label = Snap FK/IK
Bl_space_type = view_3d.
Bl_region_type = UI
# bl_context = object.
Def draw_header(self, context):
Layout = self, Layout Def draw(self, context):
Layout = self, Layout.
Col = Layout, column()
Row = col, row(align=true).
Row.operator(snap_fk, text=FK-->ik)
Row.operator(snap_ik, text=ik-->FK).
################################.
Def getmat(bone, active, context, ignoreparent):
Helper function for visual transform copy, gets the active transform in bone space.
Data_bone = context, active_object, data, Bones[bone, name]
#all matrices are in armature space unless commented otherwise.
Otherloc = active, Matrix #final 4x4 (*.mat) of target, location.
Bonemat_local = Matrix(data_bone, matrix_local) #self rest Matrix.
If data_bone, parent:
Parentposemat = Matrix(
Context, active_object, pose, Bones[data_bone, parent, name].Matrix)
Parentbonemat = Matrix(data_bone, parent, matrix_local)
Else:
Parentposemat = bonemat_local, copy(), identity()
Parentbonemat = bonemat_local, copy(), identity()
If parentbonemat == parentposemat or ignoreparent:
Newmat = bonemat_local, invert() * otherloc.
Else:
Bonemat = parentbonemat, invert() * bonemat_local.
Newmat = bonemat, invert() * parentposemat, invert() * otherloc.
Return newmat.
###############################.
Def rotcopy(item, mat):
Copy rotation todo item from Matrix (*.mat) depending on item, rotation_mode.
If item, rotation_mode == quaternion:
Item, rotation_cuaternión = mat, rotation_part(), to_quat()
Elif item, rotation_mode == axis_angle:
Quat = mat, rotation_part(), to_quat()
Item, rotation_axis_angle = Vector([quat, axis[0], quat, axis[1], quat, axis[2], quat, angle])
Else:
Item, rotation_euler = mat, rotation_part(), to_euler(item, rotation_mode).
###############################.
Def pvislocexec(bone, active, context):
Bone, location = getmat(bone, active, context, false), translation_part()
Def pvisrotexec(bone, active, context):
Rotcopy(bone, getmat(bone, active, context, not context, active_object, data, Bones[bone, name].use_inherit_rotation))
Def pvisscaexec(bone, active, context):
Bone, scale = getmat(bone, active, context, not context, active_object, data, Bones[bone, name].use_inherit_scale)\
.scale_part()
############################## Def snap_it(set1, set2, context):
##set org bone Snap IK/fk_set data = context, active_object, data.
Postura = context, active_object, pose con_in = pose, Bones[org, upper].constraints[ct-ik].
Con_in, influence = set1 con_in = pose, Bones[org, upper].constraints[ct-FK].
Con_in, influence = set2 con_in = pose, Bones[org, fore].constraints[ct-ik].
Con_in, influence = set1 con_in = pose, Bones[org, fore].constraints[ct-FK].
Con_in, influence = set2 con_in = pose, Bones[org, hand].constraints[ct-ik].
Con_in, influence = set1 con_in = pose, Bones[org, hand].constraints[ct-FK].
Con_in, influence = set2.
#####################################.
Def con_set_it(bname, cname, set1, context):
Data = context, active_object, data.
Postura = context, active_object, pose con_in = pose, Bones[bname].constraints[cname].
Con_in, influence = set1.
##################################### Def snap_it2(bname, cname, context):
##Snap rot_loc_sca IK/FK data = context, active_object, data.
Postura = context, active_object, pose pvisrotexec(pose, Bones[bname], pose, Bones[cname], context)
Pvislocexec(pose, Bones[bname], pose, Bones[cname], context)
Pvisscaexec(pose, Bones[bname], pose, Bones[cname], context).
###############################.
Def sel_layer1(a):
If a == 1:
Bpy, ops, pose, armature_layers(layers=(true, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false)) Def sel_layer2(a):
If a == 1:
Bpy, ops, pose, armature_layers(layers=(true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false))
Def sel_layer_all(a):
If a == 1:
Bpy, ops, pose, armature_layers(layers=(true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false)).
#####################################.
Class snap_fk(Bpy, types. Operator):
Bl_label = fk_snap.
Bl_idname = snap_fk.
# bl_options = {register, undo}.
@classmethod.
Def Poll(cls, context):
Return context, mode == pose Def invoke (self, context, event):
Sel_layer_all(1) pose = context, active_object, pose snap_it2(FK, upper,ik, upper, context)
Bpy, ops, object, posemode_toggle ()
Bpy, ops, object, posemode_toggle ()
snap_it2(FK, fore,ik, fore, context)
Bpy, ops, object, posemode_toggle ()
Bpy, ops, object, posemode_toggle ()
snap_it2(FK, hand,ik, hand, context)
Bpy, ops, object, posemode_toggle ()
Bpy, ops, object, posemode_toggle () con_set_it(org, fore,stretch to,0, context)
Bpy, ops, object, posemode_toggle ()
Bpy, ops, object, posemode_toggle () con_set_it(org, upper,stretch to,0, context)
Bpy, ops, object, posemode_toggle ()
Bpy, ops, object, posemode_toggle ()
snap_it(0,1, context)
Bpy, ops, object, posemode_toggle ()
Bpy, ops, object, posemode_toggle () sel_layer2(1) print(ok)
Return {finished}.
################################### class snap_ik(Bpy, types. Operator):
Bl_label = ik_snap.
Bl_idname = snap_ik.
# bl_options = {register, undo}.
@classmethod.
Def Poll(cls, context):
Return context, mode == pose Def invoke (self, context, event):
Sel_layer_all(1) pose = context, active_object, pose.
con_set_it(ik, fore,ik,0, context)
Bpy, ops, object, posemode_toggle ()
Bpy, ops, object, posemode_toggle ()
snap_it2(ik, upper,FK, upper, context)
Bpy, ops, object, posemode_toggle ()
Bpy, ops, object, posemode_toggle ()
snap_it2(ik, fore,FK, fore, context)
Bpy, ops, object, posemode_toggle ()
Bpy, ops, object, posemode_toggle ()
snap_it2(ik, hand,FK, hand, context)
Bpy, ops, object, posemode_toggle ()
Bpy, ops, object, posemode_toggle ()
snap_it2(ik, pole,ik, pole, handle, context)
Bpy, ops, object, posemode_toggle ()
Bpy, ops, object, posemode_toggle ()
con_set_it(ik, fore,ik,1, context)
Bpy, ops, object, posemode_toggle ()
Bpy, ops, object, posemode_toggle ()
snap_it2(dummie, pole, a,ik, pole, handle, context)
Bpy, ops, object, posemode_toggle ()
Bpy, ops, object, posemode_toggle ()
snap_it2(dummie, pole, b,ik, pole, context)
Bpy, ops, object, posemode_toggle ()
Bpy, ops, object, posemode_toggle ()
snap_it2(dummie, pole, a,ik, pole, context)
Bpy, ops, object, posemode_toggle ()
Bpy, ops, object, posemode_toggle ()
snap_it2(ik, pole,dummie, pole, b, context)
Bpy, ops, object, posemode_toggle ()
Bpy, ops, object, posemode_toggle () con_set_it(org, fore,stretch to,0, context)
Bpy, ops, object, posemode_toggle ()
Bpy, ops, object, posemode_toggle () con_set_it(org, upper,stretch to,0, context)
Bpy, ops, object, posemode_toggle ()
Bpy, ops, object, posemode_toggle ()
snap_it(1,0, context)
Bpy, ops, object, posemode_toggle ()
Bpy, ops, object, posemode_toggle () sel_layer1(1) print(ok)
Return {finished}
-
Auto-snap para IK y fk
Buenas, sí no sabes programar, sólo te queda esperar a que alguien lo rescriba. Ayer lo probé y no funcionaba, primero hay que registrar los class, que antes no hacía falta y me daba problemas con el id_ name, sería echarle horas y a saber sí sale. Suerte.
-
Auto-snap para IK y fk
Rulflink. Pues la verdad es que mucha idea no tengo, pero trasteando he hecho lo mismo que tú con el registro y esas cosas, de las mayúsculas y demás, he encontrado un punto donde se bloquea todo y no sé por qué, más que nada porque no se ni para que hace eso el tío, da pocas explicaciones en la programación.
Código:
Def getmat(bone, active, context, ignoreparent):
Helper function for visual transform copy.
Gets the active transform in bone space.
Data_bone = context, active_object, data, Bones[bone, name].
#all matrices are in armature space unless commented otherwise.
Otherloc = active, Matrix #final 4x4 (*.mat) of target, location.
Bonemat_local = Matrix(data_bone, matrix_local) #self rest Matrix.
If data_bone, parent:
Parentposemat = Matrix(context, active_object, pose, Bones[data_bone, parent, name].Matrix).
Parentbonemat = Matrix(data_bone, parent, matrix_local).
Else:
Parentposemat = bonemat_local, copy(), identity()# aquí se me va todo al carajo y me da un error.
Parentbonemat = bonemat_local, copy(), identity().
If parentbonemat == parentposemat or ignoreparent:
Newmat = bonemat_local, invert() * otherloc.
Else:
Bonemat = parentbonemat, invert() * bonemat_local.
Newmat = bonemat, invert() * parentposemat, invert() * otherloc.
Return newmat.
###############################.
La cuestión es que, a partir de ese `punto con el identify(), que no se para que cojones sirve, se va todo a mamar, creo que si me entero que cojones está haciendo el tipo en esa función tal vez me aclare un poco de por dónde tirar, pero ahora mismo estoy bloqueado porque no entiendo que está haciendo, a ver si con un poco de cabezonería sale.
-
1 Archivos adjunto(s)
Auto-snap para IK y fk
Listo calisto, al final era una chorrada, una chorrada de copia y pega, el tío que había hecho el tema había copiado funciones de la addon copy attribute y con las nuevas versiones no funcionaba, pero como el addon ya ha sido actualizado con solo copiar y pegar las funciones se ha solucionado el tema.
Pero siempre hay un, pero, el tío este, un tal kunkun, para calcular la posición del pole cuando se pasa de FK ha IK usaba un par de huesos enlazados brazo, es decir que salían del codo y cogía la posición del segundo hueso, y claro esto no es así, esa no sería la posición del pole, así que, lo he modificado y usando 3 huesos consigo la posición buena del pole, pero, otra vez otro, pero, a mí no me gusta esa solución de poner unos hueso con unos constraint para encontrar la posición, creo que podría hacerse matemáticamente, ya que la posición sería la suma del Vector brazo más el inverso (no sé si esta es la palabra correcta es decir invertir la dirección del Vector) del antebrazo desde el codo, pero a mi eso se me escapa, no encuentro donde pegar y copiar eso así que, si alguien se anima, solo falta un función para hacerlo elegante y que calcule la posición del pole, por lo demás funciona.
Aquí dejo el blend por si alguien se anima.
-- IMÁGENES ADJUNTAS --
https://www.foro3d.com/attachment.ph...hmentid=152777