Введение в написание скриптов на Питоне для Блендера 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:]: