[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [24309] trunk/blender/release/scripts/io/ import_bvh.py: quick update of bvh importer for blender 2.5, mostly this is to test the python api.
Campbell Barton
ideasman42 at gmail.com
Wed Nov 4 15:33:39 CET 2009
Revision: 24309
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=24309
Author: campbellbarton
Date: 2009-11-04 15:33:37 +0100 (Wed, 04 Nov 2009)
Log Message:
-----------
quick update of bvh importer for blender 2.5, mostly this is to test the python api.
- bvh joint rotations are not working quite right yet
Modified Paths:
--------------
trunk/blender/release/scripts/io/import_bvh.py
Modified: trunk/blender/release/scripts/io/import_bvh.py
===================================================================
--- trunk/blender/release/scripts/io/import_bvh.py 2009-11-04 14:31:14 UTC (rev 24308)
+++ trunk/blender/release/scripts/io/import_bvh.py 2009-11-04 14:33:37 UTC (rev 24309)
@@ -1,52 +1,18 @@
-#!BPY
+import math
-"""
-Name: 'Motion Capture (.bvh)...'
-Blender: 242
-Group: 'Import'
-Tip: 'Import a (.bvh) motion capture file'
-"""
+# import Blender
+import bpy
+# import BPyMessages
+import Mathutils
+Vector= Mathutils.Vector
+Euler= Mathutils.Euler
+Matrix= Mathutils.Matrix
+RotationMatrix= Mathutils.RotationMatrix
+TranslationMatrix= Mathutils.TranslationMatrix
-__author__ = "Campbell Barton"
-__url__ = ("blender.org", "blenderartists.org")
-__version__ = "1.90 06/08/01"
+# NASTY GLOBAL
+ROT_STYLE = 'QUAT'
-__bpydoc__ = """\
-This script imports BVH motion capture data to Blender.
-as empties or armatures.
-"""
-
-# --------------------------------------------------------------------------
-# BVH Import v2.0 by Campbell Barton (AKA Ideasman)
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-# --------------------------------------------------------------------------
-
-import Blender
-import bpy
-import BPyMessages
-Vector= Blender.Mathutils.Vector
-Euler= Blender.Mathutils.Euler
-Matrix= Blender.Mathutils.Matrix
-RotationMatrix = Blender.Mathutils.RotationMatrix
-TranslationMatrix= Blender.Mathutils.TranslationMatrix
-
DEG2RAD = 0.017453292519943295
class bvh_node_class(object):
@@ -101,13 +67,21 @@
MATRIX_IDENTITY_4x4 = Matrix([1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1])
def eulerRotate(x,y,z, rot_order):
+
# Clamp all values between 0 and 360, values outside this raise an error.
- mats=[RotationMatrix(x%360,3,'x'), RotationMatrix(y%360,3,'y'), RotationMatrix(z%360,3,'z')]
+ mats=[RotationMatrix(math.radians(x%360),3,'x'), RotationMatrix(math.radians(y%360),3,'y'), RotationMatrix(math.radians(z%360),3,'z')]
# print rot_order
# Standard BVH multiplication order, apply the rotation in the order Z,X,Y
- return (mats[rot_order[2]]*(mats[rot_order[1]]* (mats[rot_order[0]]* MATRIX_IDENTITY_3x3))).toEuler()
+
+ #XXX, order changes???
+ #eul = (mats[rot_order[2]]*(mats[rot_order[1]]* (mats[rot_order[0]]* MATRIX_IDENTITY_3x3))).toEuler()
+ eul = (MATRIX_IDENTITY_3x3*mats[rot_order[0]]*(mats[rot_order[1]]* (mats[rot_order[2]]))).toEuler()
+
+ eul = math.degrees(eul.x), math.degrees(eul.y), math.degrees(eul.z)
+
+ return eul
-def read_bvh(file_path, GLOBAL_SCALE=1.0):
+def read_bvh(context, file_path, GLOBAL_SCALE=1.0):
# File loading stuff
# Open the file for importing
file = open(file_path, 'rU')
@@ -247,8 +221,12 @@
if channels[2] != -1:
lz= GLOBAL_SCALE * float( line[channels[2]] )
- if channels[3] != -1 or channels[4] != -1 or channels[5] != -1:
- rx, ry, rz = eulerRotate(float( line[channels[3]] ), float( line[channels[4]] ), float( line[channels[5]] ), bvh_node.rot_order)
+ if channels[3] != -1 or channels[4] != -1 or channels[5] != -1:
+ rx, ry, rz = float( line[channels[3]] ), float( line[channels[4]] ), float( line[channels[5]] )
+
+ if ROT_STYLE != 'NATIVE':
+ rx, ry, rz = eulerRotate(rx, ry, rz, bvh_node.rot_order)
+
#x,y,z = x/10.0, y/10.0, z/10.0 # For IPO's 36 is 360d
# Make interpolation not cross between 180d, thjis fixes sub frame interpolation and time scaling.
@@ -268,13 +246,13 @@
lineIdx += 1
# Assign children
- for bvh_node in bvh_nodes.itervalues():
+ for bvh_node in bvh_nodes.values():
bvh_node_parent= bvh_node.parent
if bvh_node_parent:
bvh_node_parent.children.append(bvh_node)
# Now set the tip of each bvh_node
- for bvh_node in bvh_nodes.itervalues():
+ for bvh_node in bvh_nodes.values():
if not bvh_node.rest_tail_world:
if len(bvh_node.children)==0:
@@ -311,12 +289,12 @@
-def bvh_node_dict2objects(bvh_nodes, IMPORT_START_FRAME= 1, IMPORT_LOOP= False):
+def bvh_node_dict2objects(context, bvh_nodes, IMPORT_START_FRAME= 1, IMPORT_LOOP= False):
if IMPORT_START_FRAME<1:
IMPORT_START_FRAME= 1
- scn= bpy.data.scenes.active
+ scn= context.scene
scn.objects.selected = []
objects= []
@@ -327,20 +305,20 @@
return ob
# Add objects
- for name, bvh_node in bvh_nodes.iteritems():
+ for name, bvh_node in bvh_nodes.items():
bvh_node.temp= add_ob(name)
# Parent the objects
- for bvh_node in bvh_nodes.itervalues():
+ for bvh_node in bvh_nodes.values():
bvh_node.temp.makeParent([ bvh_node_child.temp for bvh_node_child in bvh_node.children ], 1, 0) # ojbs, noninverse, 1 = not fast.
# Offset
- for bvh_node in bvh_nodes.itervalues():
+ for bvh_node in bvh_nodes.values():
# Make relative to parents offset
bvh_node.temp.loc= bvh_node.rest_head_local
# Add tail objects
- for name, bvh_node in bvh_nodes.iteritems():
+ for name, bvh_node in bvh_nodes.items():
if not bvh_node.children:
ob_end= add_ob(name + '_end')
bvh_node.temp.makeParent([ob_end], 1, 0) # ojbs, noninverse, 1 = not fast.
@@ -348,10 +326,10 @@
# Animate the data, the last used bvh_node will do since they all have the same number of frames
- for current_frame in xrange(len(bvh_node.anim_data)):
+ for current_frame in range(len(bvh_node.anim_data)):
Blender.Set('curframe', current_frame+IMPORT_START_FRAME)
- for bvh_node in bvh_nodes.itervalues():
+ for bvh_node in bvh_nodes.values():
lx,ly,lz,rx,ry,rz= bvh_node.anim_data[current_frame]
rest_head_local= bvh_node.rest_head_local
@@ -366,28 +344,47 @@
-def bvh_node_dict2armature(bvh_nodes, IMPORT_START_FRAME= 1, IMPORT_LOOP= False):
+def bvh_node_dict2armature(context, bvh_nodes, IMPORT_START_FRAME= 1, IMPORT_LOOP= False):
if IMPORT_START_FRAME<1:
IMPORT_START_FRAME= 1
# Add the new armature,
- scn = bpy.data.scenes.active
- scn.objects.selected = []
+ scn = context.scene
+#XXX scn.objects.selected = []
+ for ob in scn.objects:
+ ob.selected = False
- arm_data= bpy.data.armatures.new()
- arm_ob = scn.objects.new(arm_data)
- scn.objects.context = [arm_ob]
- scn.objects.active = arm_ob
+#XXX arm_data= bpy.data.armatures.new()
+#XXX arm_ob = scn.objects.new(arm_data)
+ bpy.ops.object.armature_add()
+ arm_ob= scn.objects[-1]
+ arm_data= arm_ob.data
+
+
+
+
+#XXX scn.objects.context = [arm_ob]
+#XXX scn.objects.active = arm_ob
+ arm_ob.selected= True
+ scn.objects.active= arm_ob
+ print(scn.objects.active)
+
+
# Put us into editmode
- arm_data.makeEditable()
+#XXX arm_data.makeEditable()
+ bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
+ bpy.ops.object.mode_set(mode='EDIT', toggle=False)
+
+
+
# Get the average bone length for zero length bones, we may not use this.
average_bone_length= 0.0
nonzero_count= 0
- for bvh_node in bvh_nodes.itervalues():
+ for bvh_node in bvh_nodes.values():
l= (bvh_node.rest_head_local-bvh_node.rest_tail_local).length
if l:
average_bone_length+= l
@@ -401,14 +398,22 @@
average_bone_length = average_bone_length/nonzero_count
+#XXX - sloppy operator code
+ bpy.ops.armature.delete()
+ bpy.ops.armature.select_all_toggle()
+ bpy.ops.armature.delete()
+
ZERO_AREA_BONES= []
- for name, bvh_node in bvh_nodes.iteritems():
+ for name, bvh_node in bvh_nodes.items():
# New editbone
- bone= bvh_node.temp= Blender.Armature.Editbone()
+ bpy.ops.armature.bone_primitive_add(name="Bone")
+#XXX bone= bvh_node.temp= Blender.Armature.Editbone()
+ bone= bvh_node.temp= arm_data.edit_bones[-1]
+
bone.name= name
- arm_data.bones[name]= bone
+# arm_data.bones[name]= bone
bone.head= bvh_node.rest_head_world
bone.tail= bvh_node.rest_tail_world
@@ -425,9 +430,9 @@
bone.tail.y= bone.tail.y+average_bone_length
ZERO_AREA_BONES.append(bone.name)
-
- for bvh_node in bvh_nodes.itervalues():
+
+ for bvh_node in bvh_nodes.values():
if bvh_node.parent:
# bvh_node.temp is the Editbone
@@ -439,33 +444,83 @@
bvh_node.parent and\
bvh_node.parent.temp.name not in ZERO_AREA_BONES and\
bvh_node.parent.rest_tail_local == bvh_node.rest_head_local:
- bvh_node.temp.options= [Blender.Armature.CONNECTED]
+ bvh_node.temp.connected= True
# Replace the editbone with the editbone name,
# to avoid memory errors accessing the editbone outside editmode
- for bvh_node in bvh_nodes.itervalues():
+ for bvh_node in bvh_nodes.values():
bvh_node.temp= bvh_node.temp.name
- arm_data.update()
+#XXX arm_data.update()
# Now Apply the animation to the armature
# Get armature animation data
- pose= arm_ob.getPose()
- pose_bones= pose.bones
+ bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
+ bpy.ops.object.mode_set(mode='POSE', toggle=False)
- action = Blender.Armature.NLA.NewAction("Action")
- action.setActive(arm_ob)
+ pose= arm_ob.pose
+ pose_bones= pose.pose_channels
+
+
+ if ROT_STYLE=='NATIVE':
+ eul_order_lookup = {\
+ (0,1,2):'XYZ',
+ (0,2,1):'XZY',
+ (1,0,2):'YXZ',
+ (1,2,0):'YZX',
+ (2,0,1):'ZXY',
+ (2,1,0):'ZYZ'
+ }
+
+ for bvh_node in bvh_nodes.values():
+ bone_name= bvh_node.temp # may not be the same name as the bvh_node, could have been shortened.
+ pose_bone= pose_bones[bone_name]
+ pose_bone.rotation_mode = eul_order_lookup[tuple(bvh_node.rot_order)]
+
+ elif ROT_STYLE=='XYZ':
+ for pose_bone in pose_bones:
+ pose_bone.rotation_mode = 'XYZ'
+ else:
+ # Quats default
+ pass
+
+
+ bpy.ops.pose.select_all_toggle() # set
+ bpy.ops.anim.insert_keyframe_menu(type=-4) # XXX - -4 ???
+
+
+
+
+
+ #for p in pose_bones:
+ # print(p)
+
+
+#XXX action = Blender.Armature.NLA.NewAction("Action")
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list