Skip to content

Instantly share code, notes, and snippets.

@dskjal dskjal/ikfk_snap_easy.py
Last active Jul 28, 2018

Embed
What would you like to do?
Blender で IK/FK スナップスクリプト簡易版
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
import bpy
import mathutils
num_bones = 2
armature_name = 'Armature'
ik_bone_name = 'forearm.L'
upper_arm_name = 'upper_arm.L'
ik_target_name = 'IK.L'
ik_pole_name = 'arm_pole.L'
def get_influece_data_path():
ik_bone = bpy.data.objects[armature_name].pose.bones[ik_bone_name]
return [ik_bone.constraints["IK"],'influence']
def get_ik_influence(data_path):
return exec("data_path[0].%s" % data_path[1])
def set_ik_influence(data_path, val):
exec("data_path[0].%s = %f" % (data_path[1], val))
def set_ik(data_path):
set_ik_influence(data_path, 1.0)
def set_fk(data_path):
set_ik_influence(data_path, 0.0)
def set_translation(matrix, loc):
trs = matrix.decompose()
rot = trs[1].to_matrix().to_4x4()
scale = mathutils.Matrix.Scale(1, 4, trs[2])
return mathutils.Matrix.Translation(loc) * (rot * scale)
#UI
class IKFK_Snap(bpy.types.Panel):
bl_label = "IK/FK Snap"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
@classmethod
def poll(self, context):
return context.object and context.object.type == 'ARMATURE'
def draw(self, context):
l = self.layout
influence_data_path = get_influece_data_path()
l.prop(influence_data_path[0],influence_data_path[1], slider=True)
l.operator('my.iktofk')
l.operator('my.fktoik')
class IKtoFKButton(bpy.types.Operator):
bl_idname = "my.iktofk"
bl_label = "IK -> FK"
def execute(self, context):
amt = bpy.data.objects[armature_name]
ik_bone = amt.pose.bones[ik_bone_name]
upper_arm = amt.pose.bones[upper_arm_name]
ik_target = amt.pose.bones[ik_target_name]
ik_pole = amt.pose.bones[ik_pole_name]
#copy fk matrix
set_fk(get_influece_data_path())
#pose update
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode='POSE')
#set ik target
ik_target.matrix = set_translation(ik_target.matrix, ik_bone.tail)
#set pole target
ik_pole.matrix = set_translation(ik_pole.matrix, upper_arm.tail)
return {'FINISHED'}
class FKtoIKButton(bpy.types.Operator):
bl_idname = "my.fktoik"
bl_label = "FK -> IK"
def execute(self, context):
amt = bpy.data.objects[armature_name]
ik_bone = amt.pose.bones[ik_bone_name]
upper_arm = amt.pose.bones[upper_arm_name]
ik_target = amt.pose.bones[ik_target_name]
ik_pole = amt.pose.bones[ik_pole_name]
# copy ik matrix
set_ik(get_influece_data_path())
#pose update
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode='POSE')
ik_bone_matrixes = []
it = ik_bone
for i in range(num_bones):
ik_bone_matrixes.append(it.matrix)
it = ik_bone.parent
# set ik matrix to fk bone
set_fk(get_influece_data_path())
it = ik_bone
for i in range(num_bones):
it.matrix = ik_bone_matrixes[i]
it = it.parent
return {'FINISHED'}
classes = (
IKFK_Snap,
IKtoFKButton,
FKtoIKButton
)
def register():
for cls in classes:
bpy.utils.register_class(cls)
def unregister():
for cls in reverse(classes):
bpy.utils.unregister_class(cls)
if __name__ == "__main__":
register()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.