Image
-- **************************************************
-- Provide Moho with the name of this script object
-- **************************************************

ScriptName = "AE_FixIK"

-- **************************************************
-- General information about this script
-- **************************************************

AE_FixIK = {}

function AE_FixIK:Name()
	return 'Fix IK'
end

function AE_FixIK:Version()
	return '1.0'
end

function AE_FixIK:UILabel()
	return 'Fix IK'
end

function AE_FixIK:Creator()
	return 'Alexandra Evseeva'
end

function AE_FixIK:Description()
	return 'Select two bones with broken IK between them'
end

function AE_FixIK:ColorizeIcon()
	return true
end

-- **************************************************
-- Is Relevant / Is Enabled
-- **************************************************

function AE_FixIK:IsRelevant(moho)
	if not moho:Skeleton() then return false end
	return true
end

function AE_FixIK:IsEnabled(moho)
	if not moho:Skeleton() then return false end
	return true
end

-- **************************************************
-- AE_FixIKDialog
-- **************************************************

local AE_FixIKDialog = {}

function AE_FixIKDialog:new()
	local d = LM.GUI.SimpleDialog('Fix IK', AE_FixIKDialog)
	local l = d:GetLayout()

	return d
end

-- **************************************************
-- The guts of this script
-- **************************************************

function AE_FixIK:Run(moho)
	--[[
	local dlog = AE_FixIKDialog:new(moho)
	if (dlog:DoModal() == LM.GUI.MSG_CANCEL) then
		return
	end
	--]]
	
	moho.document:SetDirty()
	moho.document:PrepUndo(nil)
	
	local skel = moho:Skeleton() 
	
	-- get first and second selected bones, have to be child and parent
	local selectedBones = {}
	for i=0, skel:CountBones()-1 do
		if skel:Bone(i).fSelected then table.insert(selectedBones, skel:Bone(i)) end
	end
	if #selectedBones ~= 2 then return LM.GUI.Alert(LM.GUI.ALERT_WARNING, "You have to select TWO bones") end
	local childBone = nil
	local parentBone = nil
	if selectedBones[1].fAnimParent:GetValue(moho.frame) == skel:BoneID(selectedBones[2]) then
		childBone, parentBone = selectedBones[1], selectedBones[2]
	elseif selectedBones[2].fAnimParent:GetValue(moho.frame) == skel:BoneID(selectedBones[1]) then
		childBone, parentBone = selectedBones[2], selectedBones[1]	
	end
	if not childBone or not parentBone then return LM.GUI.Alert(LM.GUI.ALERT_WARNING, "These two bones are not parent and child") end
	local targetBone = skel:Bone(childBone.fTargetBone:GetValue(moho.frame))
	if  not targetBone then return LM.GUI.Alert(LM.GUI.ALERT_WARNING, childBone:Name() .. " has no target. Nothing to IK") end
	
	-- find each parent's child wish is not the selected child and set its ignore to IK
	
	local additionalChildrenFound = false
	for i=0, skel:CountBones()-1 do
		if i ~= skel:BoneID(childBone) and skel:Bone(i).fAnimParent:GetValue(moho.frame) == skel:BoneID(parentBone) then
			if not skel:Bone(i).fIgnoredByIK then additionalChildrenFound = true end
			skel:Bone(i).fIgnoredByIK  = true
		end
	end 
	
	childBone.fIgnoredByIK = false
	parentBone.fIgnoredByIK = false
	
	if skel:IsBoneParent(skel:BoneID(targetBone), skel:BoneID(parentBone)) then
		for i=0, skel:CountBones()-1 do
			skel:Bone(i).fSelected = false
		end
		targetBone.fSelected = true
		return LM.GUI.Alert(LM.GUI.ALERT_WARNING, targetBone:Name() .. " is a child of a selected bone. Please unparent it to fix IK")
	end
	
end

Fix IK
Listed

Script type: Button/Menu

Uploaded: Aug 26 2022, 07:26

Remove restrictions preventing the use of IK for selected two bones
Select two bones forming IK chain, then use command

Installation Options:

This script, and all other scripts on this site are distributed as free software under the GNU General Public License 3.0 or later.
Downloads count: 719