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()
Личные инструменты