Введение в написание скриптов на Питоне для Блендера 2.5x. Примеры кода - страница 32

стр.



>#----------------------------------------------------------

># File simple_bvh_import.py

># Simple bvh importer

>#----------------------------------------------------------  


>bl_info = {

>    'name': 'Simple BVH importer (.bvh)',

>    'author': 'Thomas Larsson',

>    'version': (1, 0, 0),

>    'blender': (2, 5, 7),

>    'api': 34786,

>    'location': "File > Import",

>    'description': 'Simple import of Biovision bvh',

>    'category': 'Import-Export'}  


>import bpy, os, math, mathutils, time

>from mathutils import Vector, Matrix

>from io_utils import ImportHelper  


>#

># class CNode:

># 


>class CNode:

>    def __init__(self, words, parent):

>        name = words[1]

>        for word in words[2:]:

>            name += ' '+word


>    self.name = name

>    self.parent = parent

>    self.children = []

>    self.head = Vector((0,0,0))

>    self.offset = Vector((0,0,0))

>    if parent:

>        parent.children.append(self)

>    self.channels = []

>    self.matrix = None

>    self.inverse = None

>    return 


>    def __repr__(self):

>        return "CNode %s" % (self.name)  


>    def display(self, pad):

>        vec = self.offset

>        if vec.length < Epsilon:

>            c = '*'

>        else: c = ' '

>        print("%s%s%10s (%8.3f %8.3f %8.3f)" %

>            (c, pad, self.name, vec[0], vec[1], vec[2]))

>        for child in self.children:

>            child.display(pad+" ")

>        return 


>    def build(self, amt, orig, parent):

>        self.head = orig + self.offset

>        if not self.children:

>            return self.head


>        zero = (self.offset.length < Epsilon)

>        eb = amt.edit_bones.new(self.name)

>        if parent:

>            eb.parent = parent

>        eb.head = self.head

>        tails = Vector((0,0,0))

>        for child in self.children:

>            tails += child.build(amt, self.head, eb)

>        n = len(self.children)

>        eb.tail = tails/n

>        (trans,quat,scale) = eb.matrix.decompose()

>        self.matrix = quat.to_matrix()

>        self.inverse = self.matrix.copy()

>        self.inverse.invert()

>        if zero:

>            return eb.tail

>        else:

>            return eb.head 


>#

># readBvhFile(context, filepath, rot90, scale):

># 


>Location = 1

>Rotation = 2

>Hierarchy = 1

>Motion = 2

>Frames = 3 


>Deg2Rad = math.pi/180

>Epsilon = 1e-5 


>def readBvhFile(context, filepath, rot90, scale):

>    fileName = os.path.realpath(os.path.expanduser(filepath))

>    (shortName, ext) = os.path.splitext(fileName)

>    if ext.lower() != ".bvh":

>        raise NameError("Not a bvh file: " + fileName)

>    print( "Loading BVH file "+ fileName )


>    time1 = time.clock()

>    level = 0

>    nErrors = 0

>    scn = context.scene


>    fp = open(fileName, "rU")

>    print( "Reading skeleton" )

>    lineNo = 0

>    for line in fp:

>        words= line.split()

>        lineNo += 1

>        if len(words) == 0:

>            continue

>        key = words[0].upper()

>        if key == 'HIERARCHY':

>            status = Hierarchy

>        elif key == 'MOTION':

>            if level != 0:

>                raise NameError("Tokenizer out of kilter %d" % level)

>            amt = bpy.data.armatures.new("BvhAmt")

>            rig = bpy.data.objects.new("BvhRig", amt)

>            scn.objects.link(rig)

>            scn.objects.active = rig

>            bpy.ops.object.mode_set(mode='EDIT')

>            root.build(amt, Vector((0,0,0)), None)

>#root.display('')

>            bpy.ops.object.mode_set(mode='OBJECT')

>            status = Motion

>        elif status == Hierarchy:

>            if key == 'ROOT':

>                node = CNode(words, None)

>                root = node

>                nodes = [root]

>            elif key == 'JOINT':

>                node = CNode(words, node)

>                nodes.append(node)

>            elif key == 'OFFSET':

>                (x,y,z) = (float(words[1]), float(words[2]), float(words[3]))

>                if rot90:

>                    node.offset = scale*Vector((x,-z,y))

>                else:

>                    node.offset = scale*Vector((x,y,z))

>            elif key == 'END':

>                node = CNode(words, node)

>            elif key == 'CHANNELS':

>                oldmode = None

>                for word in words[2:]: