Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2018-10-06 05:39:20 +0300
committerCampbell Barton <ideasman42@gmail.com>2018-10-06 05:44:23 +0300
commitf5fd80872aa8edb8f8217819f0c06cc7c974650c (patch)
tree08f8519af19ea12fe785f191e6c154edd23b769e
parent6d62e07f8bcd6d09ced189796b26ed905586f267 (diff)
Cleanup: BVH import/export
- Use tuple unpacking. - Remove unused operator argument.
-rw-r--r--io_anim_bvh/__init__.py224
-rw-r--r--io_anim_bvh/export_bvh.py105
-rw-r--r--io_anim_bvh/import_bvh.py231
3 files changed, 312 insertions, 248 deletions
diff --git a/io_anim_bvh/__init__.py b/io_anim_bvh/__init__.py
index 8a63fbbc..4a4983ff 100644
--- a/io_anim_bvh/__init__.py
+++ b/io_anim_bvh/__init__.py
@@ -26,10 +26,13 @@ bl_info = {
"location": "File > Import-Export",
"description": "Import-Export BVH from armature objects",
"warning": "",
- "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
- "Scripts/Import-Export/BVH_Importer_Exporter",
+ "wiki_url": (
+ "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
+ "Scripts/Import-Export/BVH_Importer_Exporter"
+ ),
"support": 'OFFICIAL',
- "category": "Import-Export"}
+ "category": "Import-Export",
+}
if "bpy" in locals():
import importlib
@@ -40,18 +43,18 @@ if "bpy" in locals():
import bpy
from bpy.props import (
- StringProperty,
- FloatProperty,
- IntProperty,
- BoolProperty,
- EnumProperty,
- )
+ StringProperty,
+ FloatProperty,
+ IntProperty,
+ BoolProperty,
+ EnumProperty,
+)
from bpy_extras.io_utils import (
- ImportHelper,
- ExportHelper,
- orientation_helper_factory,
- axis_conversion,
- )
+ ImportHelper,
+ ExportHelper,
+ orientation_helper_factory,
+ axis_conversion,
+)
ImportBVHOrientationHelper = orientation_helper_factory("ImportBVHOrientationHelper", axis_forward='-Z', axis_up='Y')
@@ -66,74 +69,85 @@ class ImportBVH(bpy.types.Operator, ImportHelper, ImportBVHOrientationHelper):
filename_ext = ".bvh"
filter_glob = StringProperty(default="*.bvh", options={'HIDDEN'})
- target = EnumProperty(items=(
+ target = EnumProperty(
+ items=(
('ARMATURE', "Armature", ""),
('OBJECT', "Object", ""),
- ),
- name="Target",
- description="Import target type",
- default='ARMATURE')
+ ),
+ name="Target",
+ description="Import target type",
+ default='ARMATURE',
+ )
global_scale = FloatProperty(
- name="Scale",
- description="Scale the BVH by this value",
- min=0.0001, max=1000000.0,
- soft_min=0.001, soft_max=100.0,
- default=1.0,
- )
+ name="Scale",
+ description="Scale the BVH by this value",
+ min=0.0001, max=1000000.0,
+ soft_min=0.001, soft_max=100.0,
+ default=1.0,
+ )
frame_start = IntProperty(
- name="Start Frame",
- description="Starting frame for the animation",
- default=1,
- )
+ name="Start Frame",
+ description="Starting frame for the animation",
+ default=1,
+ )
use_fps_scale = BoolProperty(
- name="Scale FPS",
- description=("Scale the framerate from the BVH to the current scenes, "
- "otherwise each BVH frame maps directly to a Blender frame"),
- default=False,
- )
+ name="Scale FPS",
+ description=(
+ "Scale the framerate from the BVH to the current scenes, "
+ "otherwise each BVH frame maps directly to a Blender frame"
+ ),
+ default=False,
+ )
update_scene_fps = BoolProperty(
- name="Update Scene FPS",
- description="Set the scene framerate to that of the BVH file (note that this "
- "nullifies the 'Scale FPS' option, as the scale will be 1:1)",
- default=False
- )
+ name="Update Scene FPS",
+ description=(
+ "Set the scene framerate to that of the BVH file (note that this "
+ "nullifies the 'Scale FPS' option, as the scale will be 1:1)"
+ ),
+ default=False
+ )
update_scene_duration = BoolProperty(
- name="Update Scene Duration",
- description="Extend the scene's duration to the BVH duration (never shortens the scene)",
- default=False,
- )
+ name="Update Scene Duration",
+ description="Extend the scene's duration to the BVH duration (never shortens the scene)",
+ default=False,
+ )
use_cyclic = BoolProperty(
- name="Loop",
- description="Loop the animation playback",
- default=False,
- )
+ name="Loop",
+ description="Loop the animation playback",
+ default=False,
+ )
rotate_mode = EnumProperty(
- name="Rotation",
- description="Rotation conversion",
- items=(('QUATERNION', "Quaternion",
- "Convert rotations to quaternions"),
- ('NATIVE', "Euler (Native)",
- "Use the rotation order defined in the BVH file"),
- ('XYZ', "Euler (XYZ)", "Convert rotations to euler XYZ"),
- ('XZY', "Euler (XZY)", "Convert rotations to euler XZY"),
- ('YXZ', "Euler (YXZ)", "Convert rotations to euler YXZ"),
- ('YZX', "Euler (YZX)", "Convert rotations to euler YZX"),
- ('ZXY', "Euler (ZXY)", "Convert rotations to euler ZXY"),
- ('ZYX', "Euler (ZYX)", "Convert rotations to euler ZYX"),
- ),
- default='NATIVE',
- )
+ name="Rotation",
+ description="Rotation conversion",
+ items=(
+ ('QUATERNION', "Quaternion",
+ "Convert rotations to quaternions"),
+ ('NATIVE', "Euler (Native)",
+ "Use the rotation order defined in the BVH file"),
+ ('XYZ', "Euler (XYZ)", "Convert rotations to euler XYZ"),
+ ('XZY', "Euler (XZY)", "Convert rotations to euler XZY"),
+ ('YXZ', "Euler (YXZ)", "Convert rotations to euler YXZ"),
+ ('YZX', "Euler (YZX)", "Convert rotations to euler YZX"),
+ ('ZXY', "Euler (ZXY)", "Convert rotations to euler ZXY"),
+ ('ZYX', "Euler (ZYX)", "Convert rotations to euler ZYX"),
+ ),
+ default='NATIVE',
+ )
def execute(self, context):
- keywords = self.as_keywords(ignore=("axis_forward",
- "axis_up",
- "filter_glob",
- ))
+ keywords = self.as_keywords(
+ ignore=(
+ "axis_forward",
+ "axis_up",
+ "filter_glob",
+ )
+ )
- global_matrix = axis_conversion(from_forward=self.axis_forward,
- from_up=self.axis_up,
- ).to_4x4()
+ global_matrix = axis_conversion(
+ from_forward=self.axis_forward,
+ from_up=self.axis_up,
+ ).to_4x4()
keywords["global_matrix"] = global_matrix
@@ -148,46 +162,47 @@ class ExportBVH(bpy.types.Operator, ExportHelper):
filename_ext = ".bvh"
filter_glob = StringProperty(
- default="*.bvh",
- options={'HIDDEN'},
- )
+ default="*.bvh",
+ options={'HIDDEN'},
+ )
global_scale = FloatProperty(
- name="Scale",
- description="Scale the BVH by this value",
- min=0.0001, max=1000000.0,
- soft_min=0.001, soft_max=100.0,
- default=1.0,
- )
+ name="Scale",
+ description="Scale the BVH by this value",
+ min=0.0001, max=1000000.0,
+ soft_min=0.001, soft_max=100.0,
+ default=1.0,
+ )
frame_start = IntProperty(
- name="Start Frame",
- description="Starting frame to export",
- default=0,
- )
+ name="Start Frame",
+ description="Starting frame to export",
+ default=0,
+ )
frame_end = IntProperty(
- name="End Frame",
- description="End frame to export",
- default=0,
- )
+ name="End Frame",
+ description="End frame to export",
+ default=0,
+ )
rotate_mode = EnumProperty(
- name="Rotation",
- description="Rotation conversion",
- items=(('NATIVE', "Euler (Native)",
- "Use the rotation order defined in the BVH file"),
- ('XYZ', "Euler (XYZ)", "Convert rotations to euler XYZ"),
- ('XZY', "Euler (XZY)", "Convert rotations to euler XZY"),
- ('YXZ', "Euler (YXZ)", "Convert rotations to euler YXZ"),
- ('YZX', "Euler (YZX)", "Convert rotations to euler YZX"),
- ('ZXY', "Euler (ZXY)", "Convert rotations to euler ZXY"),
- ('ZYX', "Euler (ZYX)", "Convert rotations to euler ZYX"),
- ),
- default='NATIVE',
- )
+ name="Rotation",
+ description="Rotation conversion",
+ items=(
+ ('NATIVE', "Euler (Native)",
+ "Use the rotation order defined in the BVH file"),
+ ('XYZ', "Euler (XYZ)", "Convert rotations to euler XYZ"),
+ ('XZY', "Euler (XZY)", "Convert rotations to euler XZY"),
+ ('YXZ', "Euler (YXZ)", "Convert rotations to euler YXZ"),
+ ('YZX', "Euler (YZX)", "Convert rotations to euler YZX"),
+ ('ZXY', "Euler (ZXY)", "Convert rotations to euler ZXY"),
+ ('ZYX', "Euler (ZYX)", "Convert rotations to euler ZYX"),
+ ),
+ default='NATIVE',
+ )
root_transform_only = BoolProperty(
- name="Root Translation Only",
- description="Only write out translation channels for the root bone",
- default=False,
- )
+ name="Root Translation Only",
+ description="Only write out translation channels for the root bone",
+ default=False,
+ )
@classmethod
def poll(cls, context):
@@ -208,7 +223,7 @@ class ExportBVH(bpy.types.Operator, ExportHelper):
keywords = self.as_keywords(ignore=("check_existing", "filter_glob"))
from . import export_bvh
- return export_bvh.save(self, context, **keywords)
+ return export_bvh.save(context, **keywords)
def menu_func_import(self, context):
@@ -232,5 +247,6 @@ def unregister():
bpy.types.INFO_MT_file_import.remove(menu_func_import)
bpy.types.INFO_MT_file_export.remove(menu_func_export)
+
if __name__ == "__main__":
register()
diff --git a/io_anim_bvh/export_bvh.py b/io_anim_bvh/export_bvh.py
index ed80ed59..21225581 100644
--- a/io_anim_bvh/export_bvh.py
+++ b/io_anim_bvh/export_bvh.py
@@ -24,14 +24,15 @@
import bpy
-def write_armature(context,
- filepath,
- frame_start,
- frame_end,
- global_scale=1.0,
- rotate_mode='NATIVE',
- root_transform_only=False,
- ):
+def write_armature(
+ context,
+ filepath,
+ frame_start,
+ frame_end,
+ global_scale=1.0,
+ rotate_mode='NATIVE',
+ root_transform_only=False,
+):
def ensure_rot_order(rot_order_str):
if set(rot_order_str) != {'X', 'Y', 'Z'}:
@@ -91,11 +92,11 @@ def write_armature(context,
file.write("%sROOT %s\n" % (indent_str, bone_name))
file.write("%s{\n" % indent_str)
- file.write("%s\tOFFSET %.6f %.6f %.6f\n" % (indent_str, loc.x * global_scale, loc.y * global_scale, loc.z * global_scale))
+ file.write("%s\tOFFSET %.6f %.6f %.6f\n" % (indent_str, *(loc * global_scale)))
if (bone.use_connect or root_transform_only) and bone.parent:
- file.write("%s\tCHANNELS 3 %srotation %srotation %srotation\n" % (indent_str, rot_order_str[0], rot_order_str[1], rot_order_str[2]))
+ file.write("%s\tCHANNELS 3 %srotation %srotation %srotation\n" % (indent_str, *rot_order_str))
else:
- file.write("%s\tCHANNELS 6 Xposition Yposition Zposition %srotation %srotation %srotation\n" % (indent_str, rot_order_str[0], rot_order_str[1], rot_order_str[2]))
+ file.write("%s\tCHANNELS 6 Xposition Yposition Zposition %srotation %srotation %srotation\n" % (indent_str, *rot_order_str))
if my_children:
# store the location for the children
@@ -111,7 +112,7 @@ def write_armature(context,
file.write("%s\tEnd Site\n" % indent_str)
file.write("%s\t{\n" % indent_str)
loc = bone.tail_local - node_locations[bone_name]
- file.write("%s\t\tOFFSET %.6f %.6f %.6f\n" % (indent_str, loc.x * global_scale, loc.y * global_scale, loc.z * global_scale))
+ file.write("%s\t\tOFFSET %.6f %.6f %.6f\n" % (indent_str, *(loc * global_scale)))
file.write("%s\t}\n" % indent_str)
file.write("%s}\n" % indent_str)
@@ -149,22 +150,34 @@ def write_armature(context,
class DecoratedBone:
__slots__ = (
- "name", # bone name, used as key in many places
+ # Bone name, used as key in many places.
+ "name",
"parent", # decorated bone parent, set in a later loop
- "rest_bone", # blender armature bone
- "pose_bone", # blender pose bone
- "pose_mat", # blender pose matrix
- "rest_arm_mat", # blender rest matrix (armature space)
- "rest_local_mat", # blender rest batrix (local space)
- "pose_imat", # pose_mat inverted
- "rest_arm_imat", # rest_arm_mat inverted
- "rest_local_imat", # rest_local_mat inverted
- "prev_euler", # last used euler to preserve euler compability in between keyframes
- "skip_position", # is the bone disconnected to the parent bone?
+ # Blender armature bone.
+ "rest_bone",
+ # Blender pose bone.
+ "pose_bone",
+ # Blender pose matrix.
+ "pose_mat",
+ # Blender rest matrix (armature space).
+ "rest_arm_mat",
+ # Blender rest batrix (local space).
+ "rest_local_mat",
+ # Pose_mat inverted.
+ "pose_imat",
+ # Rest_arm_mat inverted.
+ "rest_arm_imat",
+ # Rest_local_mat inverted.
+ "rest_local_imat",
+ # Last used euler to preserve euler compability in between keyframes.
+ "prev_euler",
+ # Is the bone disconnected to the parent bone?
+ "skip_position",
"rot_order",
"rot_order_str",
- "rot_order_str_reverse", # needed for the euler order when converting from a matrix
- )
+ # Needed for the euler order when converting from a matrix.
+ "rot_order_str_reverse",
+ )
_eul_order_lookup = {
'XYZ': (0, 1, 2),
@@ -173,7 +186,7 @@ def write_armature(context,
'YZX': (1, 2, 0),
'ZXY': (2, 0, 1),
'ZYX': (2, 1, 0),
- }
+ }
def __init__(self, bone_name):
self.name = bone_name
@@ -216,10 +229,7 @@ def write_armature(context,
bones_decorated = [DecoratedBone(bone_name) for bone_name in serialized_names]
# Assign parents
- bones_decorated_dict = {}
- for dbone in bones_decorated:
- bones_decorated_dict[dbone.name] = dbone
-
+ bones_decorated_dict = {dbone.name: dbone for dbone in bones_decorated}
for dbone in bones_decorated:
parent = dbone.rest_bone.parent
if parent:
@@ -227,7 +237,7 @@ def write_armature(context,
del bones_decorated_dict
# finish assigning parents
- scene = bpy.context.scene
+ scene = context.scene
frame_current = scene.frame_current
file.write("MOTION\n")
@@ -244,7 +254,7 @@ def write_armature(context,
trans = Matrix.Translation(dbone.rest_bone.head_local)
itrans = Matrix.Translation(-dbone.rest_bone.head_local)
- if dbone.parent:
+ if dbone.parent:
mat_final = dbone.parent.rest_arm_mat * dbone.parent.pose_imat * dbone.pose_mat * dbone.rest_arm_imat
mat_final = itrans * mat_final * trans
loc = mat_final.to_translation() + (dbone.rest_bone.head_local - dbone.parent.rest_bone.head_local)
@@ -272,20 +282,21 @@ def write_armature(context,
print("BVH Exported: %s frames:%d\n" % (filepath, frame_end - frame_start + 1))
-def save(operator, context, filepath="",
- frame_start=-1,
- frame_end=-1,
- global_scale=1.0,
- rotate_mode="NATIVE",
- root_transform_only=False,
- ):
-
- write_armature(context, filepath,
- frame_start=frame_start,
- frame_end=frame_end,
- global_scale=global_scale,
- rotate_mode=rotate_mode,
- root_transform_only=root_transform_only,
- )
+def save(
+ context, filepath="",
+ frame_start=-1,
+ frame_end=-1,
+ global_scale=1.0,
+ rotate_mode="NATIVE",
+ root_transform_only=False,
+):
+ write_armature(
+ context, filepath,
+ frame_start=frame_start,
+ frame_end=frame_end,
+ global_scale=global_scale,
+ rotate_mode=rotate_mode,
+ root_transform_only=root_transform_only,
+ )
return {'FINISHED'}
diff --git a/io_anim_bvh/import_bvh.py b/io_anim_bvh/import_bvh.py
index df733a73..a12ef0cc 100644
--- a/io_anim_bvh/import_bvh.py
+++ b/io_anim_bvh/import_bvh.py
@@ -28,22 +28,41 @@ from mathutils import Vector, Euler, Matrix
class BVH_Node:
__slots__ = (
- 'name', # bvh joint name
- 'parent', # BVH_Node type or None for no parent
- 'children', # a list of children of this type.
- 'rest_head_world', # worldspace rest location for the head of this node
- 'rest_head_local', # localspace rest location for the head of this node
- 'rest_tail_world', # worldspace rest location for the tail of this node
- 'rest_tail_local', # worldspace rest location for the tail of this node
- 'channels', # list of 6 ints, -1 for an unused channel, otherwise an index for the BVH motion data lines, loc triple then rot triple
- 'rot_order', # a triple of indices as to the order rotation is applied. [0,1,2] is x/y/z - [None, None, None] if no rotation.
- 'rot_order_str', # same as above but a string 'XYZ' format.
- 'anim_data', # a list one tuple's one for each frame. (locx, locy, locz, rotx, roty, rotz), euler rotation ALWAYS stored xyz order, even when native used.
- 'has_loc', # Convenience function, bool, same as (channels[0]!=-1 or channels[1]!=-1 or channels[2]!=-1)
- 'has_rot', # Convenience function, bool, same as (channels[3]!=-1 or channels[4]!=-1 or channels[5]!=-1)
- 'index', # index from the file, not strictly needed but nice to maintain order
- 'temp', # use this for whatever you want
- )
+ # Bvh joint name.
+ 'name',
+ # BVH_Node type or None for no parent.
+ 'parent',
+ # A list of children of this type..
+ 'children',
+ # Worldspace rest location for the head of this node.
+ 'rest_head_world',
+ # Localspace rest location for the head of this node.
+ 'rest_head_local',
+ # Worldspace rest location for the tail of this node.
+ 'rest_tail_world',
+ # Worldspace rest location for the tail of this node.
+ 'rest_tail_local',
+ # List of 6 ints, -1 for an unused channel,
+ # otherwise an index for the BVH motion data lines,
+ # loc triple then rot triple.
+ 'channels',
+ # A triple of indices as to the order rotation is applied.
+ # [0,1,2] is x/y/z - [None, None, None] if no rotation..
+ 'rot_order',
+ # Same as above but a string 'XYZ' format..
+ 'rot_order_str',
+ # A list one tuple's one for each frame: (locx, locy, locz, rotx, roty, rotz),
+ # euler rotation ALWAYS stored xyz order, even when native used.
+ 'anim_data',
+ # Convenience function, bool, same as: (channels[0] != -1 or channels[1] != -1 or channels[2] != -1).
+ 'has_loc',
+ # Convenience function, bool, same as: (channels[3] != -1 or channels[4] != -1 or channels[5] != -1).
+ 'has_rot',
+ # Index from the file, not strictly needed but nice to maintain order.
+ 'index',
+ # Use this for whatever you want.
+ 'temp',
+ )
_eul_order_lookup = {
(None, None, None): 'XYZ', # XXX Dummy one, no rotation anyway!
@@ -53,7 +72,7 @@ class BVH_Node:
(1, 2, 0): 'YZX',
(2, 0, 1): 'ZXY',
(2, 1, 0): 'ZYX',
- }
+ }
def __init__(self, name, rest_head_world, rest_head_local, parent, channels, rot_order, index):
self.name = name
@@ -73,16 +92,18 @@ class BVH_Node:
self.children = []
- # list of 6 length tuples: (lx,ly,lz, rx,ry,rz)
- # even if the channels aren't used they will just be zero
- #
+ # List of 6 length tuples: (lx, ly, lz, rx, ry, rz)
+ # even if the channels aren't used they will just be zero.
self.anim_data = [(0, 0, 0, 0, 0, 0)]
def __repr__(self):
- return ("BVH name: '%s', rest_loc:(%.3f,%.3f,%.3f), rest_tail:(%.3f,%.3f,%.3f)" %
- (self.name,
- self.rest_head_world.x, self.rest_head_world.y, self.rest_head_world.z,
- self.rest_head_world.x, self.rest_head_world.y, self.rest_head_world.z))
+ return (
+ "BVH name: '%s', rest_loc:(%.3f,%.3f,%.3f), rest_tail:(%.3f,%.3f,%.3f)" % (
+ self.name,
+ *self.rest_head_world,
+ *self.rest_head_world,
+ )
+ )
def sorted_nodes(bvh_nodes):
@@ -107,7 +128,7 @@ def read_bvh(context, file_path, rotate_mode='XYZ', global_scale=1.0):
# Create hierarchy as empties
if file_lines[0][0].lower() == 'hierarchy':
- #print 'Importing the BVH Hierarchy for:', file_path
+ # print 'Importing the BVH Hierarchy for:', file_path
pass
else:
raise Exception("This is not a BVH file")
@@ -121,8 +142,7 @@ def read_bvh(context, file_path, rotate_mode='XYZ', global_scale=1.0):
lineIdx = 0 # An index for the file.
while lineIdx < len(file_lines) - 1:
- #...
- if file_lines[lineIdx][0].lower() == 'root' or file_lines[lineIdx][0].lower() == 'joint':
+ if file_lines[lineIdx][0].lower() in {'root', 'joint'}:
# Join spaces into 1 word with underscores joining it.
if len(file_lines[lineIdx]) > 2:
@@ -134,7 +154,7 @@ def read_bvh(context, file_path, rotate_mode='XYZ', global_scale=1.0):
# Make sure the names are unique - Object names will match joint names exactly and both will be unique.
name = file_lines[lineIdx][1]
- #print '%snode: %s, parent: %s' % (len(bvh_nodes_serial) * ' ', name, bvh_nodes_serial[-1])
+ # print '%snode: %s, parent: %s' % (len(bvh_nodes_serial) * ' ', name, bvh_nodes_serial[-1])
lineIdx += 2 # Increment to the next line (Offset)
rest_head_local = Vector((float(file_lines[lineIdx][1]), float(file_lines[lineIdx][2]), float(file_lines[lineIdx][3]))) * global_scale
@@ -185,16 +205,18 @@ def read_bvh(context, file_path, rotate_mode='XYZ', global_scale=1.0):
# If we have another child then we can call ourselves a parent, else
bvh_nodes_serial.append(bvh_node)
- # Account for an end node
- if file_lines[lineIdx][0].lower() == 'end' and file_lines[lineIdx][1].lower() == 'site': # There is sometimes a name after 'End Site' but we will ignore it.
- lineIdx += 2 # Increment to the next line (Offset)
+ # Account for an end node.
+ # There is sometimes a name after 'End Site' but we will ignore it.
+ if file_lines[lineIdx][0].lower() == 'end' and file_lines[lineIdx][1].lower() == 'site':
+ # Increment to the next line (Offset)
+ lineIdx += 2
rest_tail = Vector((float(file_lines[lineIdx][1]), float(file_lines[lineIdx][2]), float(file_lines[lineIdx][3]))) * global_scale
bvh_nodes_serial[-1].rest_tail_world = bvh_nodes_serial[-1].rest_head_world + rest_tail
bvh_nodes_serial[-1].rest_tail_local = bvh_nodes_serial[-1].rest_head_local + rest_tail
- # Just so we can remove the Parents in a uniform way - End has kids
- # so this is a placeholder
+ # Just so we can remove the parents in a uniform way,
+ # the end has kids so this is a placeholder.
bvh_nodes_serial.append(None)
if len(file_lines[lineIdx]) == 1 and file_lines[lineIdx][0] == '}': # == ['}']
@@ -208,15 +230,16 @@ def read_bvh(context, file_path, rotate_mode='XYZ', global_scale=1.0):
if len(file_lines[lineIdx]) == 1 and file_lines[lineIdx][0].lower() == 'motion':
lineIdx += 1 # Read frame count.
if (len(file_lines[lineIdx]) == 2 and
- file_lines[lineIdx][0].lower() == 'frames:'):
+ file_lines[lineIdx][0].lower() == 'frames:'):
bvh_frame_count = int(file_lines[lineIdx][1])
lineIdx += 1 # Read frame rate.
- if (len(file_lines[lineIdx]) == 3 and
+ if (
+ len(file_lines[lineIdx]) == 3 and
file_lines[lineIdx][0].lower() == 'frame' and
- file_lines[lineIdx][1].lower() == 'time:'):
-
+ file_lines[lineIdx][1].lower() == 'time:'
+ ):
bvh_frame_time = float(file_lines[lineIdx][2])
lineIdx += 1 # Set the cursor to the first frame
@@ -227,7 +250,7 @@ def read_bvh(context, file_path, rotate_mode='XYZ', global_scale=1.0):
# Remove the None value used for easy parent reference
del bvh_nodes[None]
- # Dont use anymore
+ # Don't use anymore
del bvh_nodes_serial
# importing world with any order but nicer to maintain order
@@ -237,7 +260,7 @@ def read_bvh(context, file_path, rotate_mode='XYZ', global_scale=1.0):
while lineIdx < len(file_lines):
line = file_lines[lineIdx]
for bvh_node in bvh_nodes_list:
- #for bvh_node in bvh_nodes_serial:
+ # for bvh_node in bvh_nodes_serial:
lx = ly = lz = rx = ry = rz = 0.0
channels = bvh_node.channels
anim_data = bvh_node.anim_data
@@ -279,7 +302,7 @@ def read_bvh(context, file_path, rotate_mode='XYZ', global_scale=1.0):
bvh_node.rest_tail_local = bvh_node.rest_head_local + bvh_node.children[0].rest_head_local
else:
# allow this, see above
- #if not bvh_node.children:
+ # if not bvh_node.children:
# raise Exception("bvh node has no end and no children. bad file")
# Removed temp for now
@@ -364,16 +387,17 @@ def bvh_node_dict2objects(context, bvh_name, bvh_nodes, rotate_mode='NATIVE', fr
return objects
-def bvh_node_dict2armature(context,
- bvh_name,
- bvh_nodes,
- bvh_frame_time,
- rotate_mode='XYZ',
- frame_start=1,
- IMPORT_LOOP=False,
- global_matrix=None,
- use_fps_scale=False,
- ):
+def bvh_node_dict2armature(
+ context,
+ bvh_name,
+ bvh_nodes,
+ bvh_frame_time,
+ rotate_mode='XYZ',
+ frame_start=1,
+ IMPORT_LOOP=False,
+ global_matrix=None,
+ use_fps_scale=False,
+):
if frame_start < 1:
frame_start = 1
@@ -521,7 +545,7 @@ def bvh_node_dict2armature(context,
for frame_i in range(1, num_frame):
time[frame_i] += float(frame_i)
- #print("bvh_frame_time = %f, dt = %f, num_frame = %d"
+ # print("bvh_frame_time = %f, dt = %f, num_frame = %d"
# % (bvh_frame_time, dt, num_frame]))
for i, bvh_node in enumerate(bvh_nodes_list):
@@ -537,7 +561,7 @@ def bvh_node_dict2armature(context,
bvh_loc = bvh_node.anim_data[frame_i + skip_frame][:3]
bone_translate_matrix = Matrix.Translation(
- Vector(bvh_loc) - bvh_node.rest_head_local)
+ Vector(bvh_loc) - bvh_node.rest_head_local)
location[frame_i] = (bone_rest_matrix_inv *
bone_translate_matrix).to_translation()
@@ -549,7 +573,7 @@ def bvh_node_dict2armature(context,
for frame_i in range(num_frame):
keyframe_points[frame_i].co = \
- (time[frame_i], location[frame_i][axis_i])
+ (time[frame_i], location[frame_i][axis_i])
if bvh_node.has_rot:
data_path = None
@@ -580,7 +604,7 @@ def bvh_node_dict2armature(context,
rotate[frame_i] = bone_rotation_matrix.to_quaternion()
else:
rotate[frame_i] = bone_rotation_matrix.to_euler(
- pose_bone.rotation_mode, prev_euler)
+ pose_bone.rotation_mode, prev_euler)
prev_euler = rotate[frame_i]
# For each Euler angle x, y, z (or Quaternion w, x, y, z).
@@ -591,7 +615,7 @@ def bvh_node_dict2armature(context,
for frame_i in range(0, num_frame):
keyframe_points[frame_i].co = \
- (time[frame_i], rotate[frame_i][axis_i])
+ (time[frame_i], rotate[frame_i][axis_i])
for cu in action.fcurves:
if IMPORT_LOOP:
@@ -607,28 +631,30 @@ def bvh_node_dict2armature(context,
return arm_ob
-def load(context,
- filepath,
- *,
- target='ARMATURE',
- rotate_mode='NATIVE',
- global_scale=1.0,
- use_cyclic=False,
- frame_start=1,
- global_matrix=None,
- use_fps_scale=False,
- update_scene_fps=False,
- update_scene_duration=False,
- report=print
- ):
-
+def load(
+ context,
+ filepath,
+ *,
+ target='ARMATURE',
+ rotate_mode='NATIVE',
+ global_scale=1.0,
+ use_cyclic=False,
+ frame_start=1,
+ global_matrix=None,
+ use_fps_scale=False,
+ update_scene_fps=False,
+ update_scene_duration=False,
+ report=print
+):
import time
t1 = time.time()
print("\tparsing bvh %r..." % filepath, end="")
- bvh_nodes, bvh_frame_time, bvh_frame_count = read_bvh(context, filepath,
- rotate_mode=rotate_mode,
- global_scale=global_scale)
+ bvh_nodes, bvh_frame_time, bvh_frame_count = read_bvh(
+ context, filepath,
+ rotate_mode=rotate_mode,
+ global_scale=global_scale,
+ )
print("%.4f" % (time.time() - t1))
@@ -637,9 +663,12 @@ def load(context,
# Broken BVH handling: guess frame rate when it is not contained in the file.
if bvh_frame_time is None:
- report({'WARNING'}, "The BVH file does not contain frame duration in its MOTION "
- "section, assuming the BVH and Blender scene have the same "
- "frame rate")
+ report(
+ {'WARNING'},
+ "The BVH file does not contain frame duration in its MOTION "
+ "section, assuming the BVH and Blender scene have the same "
+ "frame rate"
+ )
bvh_frame_time = scene.render.fps_base / scene.render.fps
# No need to scale the frame rate, as they're equal now anyway.
use_fps_scale = False
@@ -652,8 +681,7 @@ def load(context,
use_fps_scale = False
if update_scene_duration:
- _update_scene_duration(context, report, bvh_frame_count, bvh_frame_time, frame_start,
- use_fps_scale)
+ _update_scene_duration(context, report, bvh_frame_count, bvh_frame_time, frame_start, use_fps_scale)
t1 = time.time()
print("\timporting to blender...", end="")
@@ -661,21 +689,23 @@ def load(context,
bvh_name = bpy.path.display_name_from_filepath(filepath)
if target == 'ARMATURE':
- bvh_node_dict2armature(context, bvh_name, bvh_nodes, bvh_frame_time,
- rotate_mode=rotate_mode,
- frame_start=frame_start,
- IMPORT_LOOP=use_cyclic,
- global_matrix=global_matrix,
- use_fps_scale=use_fps_scale,
- )
+ bvh_node_dict2armature(
+ context, bvh_name, bvh_nodes, bvh_frame_time,
+ rotate_mode=rotate_mode,
+ frame_start=frame_start,
+ IMPORT_LOOP=use_cyclic,
+ global_matrix=global_matrix,
+ use_fps_scale=use_fps_scale,
+ )
elif target == 'OBJECT':
- bvh_node_dict2objects(context, bvh_name, bvh_nodes,
- rotate_mode=rotate_mode,
- frame_start=frame_start,
- IMPORT_LOOP=use_cyclic,
- # global_matrix=global_matrix, # TODO
- )
+ bvh_node_dict2objects(
+ context, bvh_name, bvh_nodes,
+ rotate_mode=rotate_mode,
+ frame_start=frame_start,
+ IMPORT_LOOP=use_cyclic,
+ # global_matrix=global_matrix, # TODO
+ )
else:
report({'ERROR'}, "Invalid target %r (must be 'ARMATURE' or 'OBJECT')" % target)
@@ -693,8 +723,11 @@ def _update_scene_fps(context, report, bvh_frame_time):
# Broken BVH handling: prevent division by zero.
if bvh_frame_time == 0.0:
- report({'WARNING'}, "Unable to update scene frame rate, as the BVH file "
- "contains a zero frame duration in its MOTION section")
+ report(
+ {'WARNING'},
+ "Unable to update scene frame rate, as the BVH file "
+ "contains a zero frame duration in its MOTION section",
+ )
return
scene = context.scene
@@ -707,13 +740,17 @@ def _update_scene_fps(context, report, bvh_frame_time):
scene.render.fps_base = 1.0
-def _update_scene_duration(context, report, bvh_frame_count, bvh_frame_time, frame_start,
- use_fps_scale):
+def _update_scene_duration(
+ context, report, bvh_frame_count, bvh_frame_time, frame_start,
+ use_fps_scale):
"""Extend the scene's duration so that the BVH file fits in its entirety."""
if bvh_frame_count is None:
- report({'WARNING'}, "Unable to extend the scene duration, as the BVH file does not "
- "contain the number of frames in its MOTION section")
+ report(
+ {'WARNING'},
+ "Unable to extend the scene duration, as the BVH file does not "
+ "contain the number of frames in its MOTION section",
+ )
return
# Not likely, but it can happen when a BVH is just used to store an armature.