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