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:
authorSybren A. Stüvel <sybren@stuvel.eu>2015-11-07 15:23:29 +0300
committerSybren A. Stüvel <sybren@stuvel.eu>2015-11-07 15:23:29 +0300
commit91715100aa8145edc21e5448e79b19ee88603662 (patch)
treea9f6ca947bcd45fd87f57a9b2d24514603e9bdd0
parent407d0ea752b3af73d3f13ba072671bd09eefecb1 (diff)
BVH import: added option to update scene from the BVH.
This commit adds two options to the BVH importer to adjust the scene's frame rate and duration to that of the BVH file. Since different BVHs have different frame rates, this makes it possible to import BVH files for inspection in Blender without having to manually open the BVH file to find its frame rate and duration. The scene is only extended to fit the BVH file, and never shortened. There already exists an option for the opposite, to scale the BVH animation data to the scene's frame rate. This did not take into account the scene.render.fps_base property, which is also fixed by this commit. This closes task T34919. Reviewers: campbellbarton Reviewed By: campbellbarton Maniphest Tasks: T34919 Differential Revision: https://developer.blender.org/D1608
-rw-r--r--io_anim_bvh/__init__.py12
-rw-r--r--io_anim_bvh/import_bvh.py52
2 files changed, 57 insertions, 7 deletions
diff --git a/io_anim_bvh/__init__.py b/io_anim_bvh/__init__.py
index 57f879c0..85534048 100644
--- a/io_anim_bvh/__init__.py
+++ b/io_anim_bvh/__init__.py
@@ -92,6 +92,18 @@ class ImportBVH(bpy.types.Operator, ImportHelper, ImportBVHOrientationHelper):
"BVH frame maps directly to a Blender frame"),
default=False,
)
+ update_scene_fps = BoolProperty(
+ name="Update scene framerate",
+ description="Sets 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. Does not shorten scene "
+ "when the BVH fits in its entirety",
+ default=False,
+ )
use_cyclic = BoolProperty(
name="Loop",
description="Loop the animation playback",
diff --git a/io_anim_bvh/import_bvh.py b/io_anim_bvh/import_bvh.py
index 08f7cb5b..9aa562f0 100644
--- a/io_anim_bvh/import_bvh.py
+++ b/io_anim_bvh/import_bvh.py
@@ -20,7 +20,7 @@
# Script copyright (C) Campbell Barton
-from math import radians
+from math import radians, ceil
import bpy
from mathutils import Vector, Euler, Matrix
@@ -114,6 +114,7 @@ def read_bvh(context, file_path, rotate_mode='XYZ', global_scale=1.0):
bvh_nodes = {None: None}
bvh_nodes_serial = [None]
+ bvh_frame_count = None
bvh_frame_time = None
channelIndex = -1
@@ -205,8 +206,13 @@ def read_bvh(context, file_path, rotate_mode='XYZ', global_scale=1.0):
# Frames: n
# Frame Time: dt
if len(file_lines[lineIdx]) == 1 and file_lines[lineIdx][0].lower() == 'motion':
- lineIdx += 2 # Read frame rate.
+ lineIdx += 1 # Read frame count.
+ if (len(file_lines[lineIdx]) == 2 and
+ 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
file_lines[lineIdx][0].lower() == 'frame' and
file_lines[lineIdx][1].lower() == 'time:'):
@@ -292,7 +298,7 @@ def read_bvh(context, file_path, rotate_mode='XYZ', global_scale=1.0):
bvh_node.rest_tail_local.y = bvh_node.rest_tail_local.y + global_scale / 10
bvh_node.rest_tail_world.y = bvh_node.rest_tail_world.y + global_scale / 10
- return bvh_nodes, bvh_frame_time
+ return bvh_nodes, bvh_frame_time, bvh_frame_count
def bvh_node_dict2objects(context, bvh_name, bvh_nodes, rotate_mode='NATIVE', frame_start=1, IMPORT_LOOP=False):
@@ -611,13 +617,15 @@ def load(operator,
frame_start=1,
global_matrix=None,
use_fps_scale=False,
+ update_scene_fps=False,
+ update_scene_duration=False
):
import time
t1 = time.time()
print('\tparsing bvh %r...' % filepath, end="")
- bvh_nodes, bvh_frame_time = read_bvh(context, filepath,
+ bvh_nodes, bvh_frame_time, bvh_frame_count = read_bvh(context, filepath,
rotate_mode=rotate_mode,
global_scale=global_scale)
@@ -625,9 +633,39 @@ def load(operator,
scene = context.scene
frame_orig = scene.frame_current
- fps = scene.render.fps
- if bvh_frame_time is None:
- bvh_frame_time = 1.0 / scene.render.fps
+ scene_fps = scene.render.fps / scene.render.fps_base
+
+ if update_scene_fps:
+ # Update the scene's FPS settings from the BVH, but only if the BVH contains enough info.
+ if bvh_frame_time is None:
+ raise ValueError('Unable to update scene frame time, as the BVH file does not '
+ 'contain the frame duration in its MOTION section.')
+
+ new_fps = 1.0 / bvh_frame_time
+ if scene.render.fps != new_fps or scene.render.fps_base != 1.0:
+ print(' updating scene FPS (was %f) to BVH FPS (%f)' % (scene_fps, new_fps))
+ scene.render.fps = new_fps
+ scene.render.fps_base = 1.0
+
+ # Now that we have a 1-to-1 mapping of Blender frames and BVH frames, there is no need
+ # to scale the FPS any more. It's even better not to, to prevent roundoff errors.
+ use_fps_scale = False
+ else:
+ if bvh_frame_time is None:
+ print('BVH did not contain frame duration in its MOTION section, using scene FPS.')
+ bvh_frame_time = 1.0 / scene_fps
+
+ if update_scene_duration:
+ if use_fps_scale:
+ if bvh_frame_count is None:
+ raise ValueError('Unable to extend the scene duration, as the BVH file does not '
+ 'contain the number of frames in its MOTION section.')
+ scaled_frame_count = int(ceil(bvh_frame_count * bvh_frame_time * scene_fps))
+ bvh_last_frame = frame_start + scaled_frame_count
+ else:
+ bvh_last_frame = frame_start + bvh_frame_count
+ if context.scene.frame_end < bvh_last_frame:
+ context.scene.frame_end = bvh_last_frame
t1 = time.time()
print('\timporting to blender...', end="")