[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