Correct bone roll
Материал из Blender3D.
Этот скрипт занимается тем, что должна бы делать, но почти никогда не делает команда Recalculate bone roll angles (Ctrl+N) в режиме редактирования костей. Чтобы использовать скрипт, выполните его в окне блендеровского текстового редактора, предварительно выделив нужные кости.
Писано для блендера 2.43.
import Blender
from Blender import *
def lookAtSelection():
activeObject = Scene.GetCurrent().getActiveObject()
if activeObject:
if activeObject.getType() == "Armature":
armatureDataName = activeObject.getData().name
processSelection(armatureDataName)
else:
print "The active object is not an armature."
else:
print "No active object was found in the scene."
return
def rollCorrection(head, tail, thirdPoint, matrix):
theNormal = Mathutils.TriangleNormal(head, tail, thirdPoint)
xVector = Mathutils.Vector(matrix[0]).resize3D()
zVector = Mathutils.Vector(matrix[2]).resize3D()
angleForX = Mathutils.AngleBetweenVecs(theNormal, xVector)
angleForZ = Mathutils.AngleBetweenVecs(theNormal, zVector)
rotationSign = 0
if angleForZ < 90:
rotationSign = -1
elif angleForZ > 90:
rotationSign = 1
correctionAngle = rotationSign*(angleForX - 180)
print " ", correctionAngle
return correctionAngle
def processSelection(armatureDataName):
inEditMode = Window.EditMode()
if inEditMode:
Window.EditMode(0)
targetArmature = Armature.Get(armatureDataName)
for bone in targetArmature.bones.values():
if Armature.BONE_SELECTED in bone.options:
thirdPoint = findThirdPoint(targetArmature.name, bone.name)
print "Roll correction for", bone.name+':'
boneHead = bone.head['ARMATURESPACE']
boneTail = bone.tail['ARMATURESPACE']
boneMatrix = bone.matrix['ARMATURESPACE']
targetArmature.makeEditable()
# get editbone rather than just bone:
targetArmature.bones[bone.name].roll +=\
rollCorrection(
boneHead,
boneTail,
thirdPoint,
boneMatrix)
targetArmature.update()
Blender.Redraw()
if inEditMode:
Window.EditMode(1)
return
def findThirdPoint(armatureDataName, boneName):
bone = Armature.Get(armatureDataName).bones[boneName]
parentBone = bone.parent
if parentBone:
thirdPoint = parentBone.head['ARMATURESPACE']
else:
thirdPoint = Mathutils.Vector(
bone.matrix['ARMATURESPACE'][2]).resize3D()
return thirdPoint
lookAtSelection()

