[Bf-extensions-cvs] [4c22bc1] fbx_io_development: Change how units conversions are handled (making lookup in a dict each time is not optimal).

Bastien Montagne noreply at git.blender.org
Sun Jul 6 19:16:02 CEST 2014


Commit: 4c22bc1a1d37241840e31bedd23a1175b654746a
Author: Bastien Montagne
Date:   Sun Jul 6 18:45:51 2014 +0200
https://developer.blender.org/rBA4c22bc1a1d37241840e31bedd23a1175b654746a

Change how units conversions are handled (making lookup in a dict each time is not optimal).

===================================================================

M	io_scene_fbx/export_fbx_bin.py
M	io_scene_fbx/fbx_utils.py
M	io_scene_fbx/import_fbx.py

===================================================================

diff --git a/io_scene_fbx/export_fbx_bin.py b/io_scene_fbx/export_fbx_bin.py
index 0f94273..3c46fa7 100644
--- a/io_scene_fbx/export_fbx_bin.py
+++ b/io_scene_fbx/export_fbx_bin.py
@@ -61,7 +61,7 @@ from .fbx_utils import (
     FBX_LIGHT_TYPES, FBX_LIGHT_DECAY_TYPES,
     RIGHT_HAND_AXES, FBX_FRAMERATES,
     # Miscellaneous utils.
-    units_convert, units_convert_iter, matrix4_to_array, similar_values, similar_values_iter,
+    units_convertor, units_convertor_iter, matrix4_to_array, similar_values, similar_values_iter,
     # UUID from key.
     get_fbx_uuid_from_key,
     # Key generators.
@@ -92,6 +92,16 @@ from .fbx_utils import (
     FBXSettingsMedia, FBXSettings, FBXData,
 )
 
+# Units convertors!
+convert_sec_to_ktime = units_convertor("second", "ktime")
+convert_sec_to_ktime_iter = units_convertor_iter("second", "ktime")
+
+convert_mm_to_inch = units_convertor("millimeter", "inch")
+
+convert_rad_to_deg = units_convertor("radian", "degree")
+convert_rad_to_deg_iter = units_convertor_iter("radian", "degree")
+
+
 ##### Templates #####
 # TODO: check all those "default" values, they should match Blender's default as much as possible, I guess?
 
@@ -614,8 +624,8 @@ def fbx_data_camera_elements(root, cam_obj, scene_data):
     height = render.resolution_y
     aspect = width / height
     # Film width & height from mm to inches
-    filmwidth = units_convert(cam_data.sensor_width, "millimeter", "inch")
-    filmheight = units_convert(cam_data.sensor_height, "millimeter", "inch")
+    filmwidth = convert_mm_to_inch(cam_data.sensor_width)
+    filmheight = convert_mm_to_inch(cam_data.sensor_height)
     filmaspect = filmwidth / filmheight
     # Film offset
     offsetx = filmwidth * cam_data.shift_x
@@ -1451,7 +1461,7 @@ def fbx_data_object_elements(root, ob_obj, scene_data):
 
     # Object transform info.
     loc, rot, scale, matrix, matrix_rot = ob_obj.fbx_object_tx(scene_data)
-    rot = tuple(units_convert_iter(rot, "radian", "degree"))
+    rot = tuple(convert_rad_to_deg_iter(rot))
 
     tmpl = elem_props_template_init(scene_data.templates, b"Model")
     # For now add only loc/rot/scale...
@@ -1506,7 +1516,7 @@ def fbx_data_animation_elements(root, scene_data):
     fps = scene.render.fps / scene.render.fps_base
 
     def keys_to_ktimes(keys):
-        return (int(v) for v in units_convert_iter((f / fps for f, _v in keys), "second", "ktime"))
+        return (int(v) for v in convert_sec_to_ktime_iter((f / fps for f, _v in keys)))
 
     # Animation stacks.
     for astack_key, alayers, alayer_key, name, f_start, f_end in animations:
@@ -1518,8 +1528,8 @@ def fbx_data_animation_elements(root, scene_data):
         astack_props = elem_properties(astack)
         r = scene_data.scene.render
         fps = r.fps / r.fps_base
-        start = int(units_convert(f_start / fps, "second", "ktime"))
-        end = int(units_convert(f_end / fps, "second", "ktime"))
+        start = int(convert_sec_to_ktime(f_start / fps))
+        end = int(convert_sec_to_ktime(f_end / fps))
         elem_props_template_set(astack_tmpl, astack_props, "p_timestamp", b"LocalStart", start)
         elem_props_template_set(astack_tmpl, astack_props, "p_timestamp", b"LocalStop", end)
         elem_props_template_set(astack_tmpl, astack_props, "p_timestamp", b"ReferenceStart", start)
@@ -1741,7 +1751,7 @@ def fbx_animations_do(scene_data, ref_id, f_start, f_end, start_zero, objects=No
             loc, rot, scale, _m, _mr = ob_obj.fbx_object_tx(scene_data, rot_euler_compat=p_rot)
             p_rots[ob_obj] = rot
             anim_loc.add_keyframe(real_currframe, loc)
-            anim_rot.add_keyframe(real_currframe, tuple(units_convert_iter(rot, "radian", "degree")))
+            anim_rot.add_keyframe(real_currframe, tuple(convert_rad_to_deg_iter(rot)))
             anim_scale.add_keyframe(real_currframe, scale)
         for ob_obj in objects:
             ob_obj.dupli_list_clear()
@@ -2534,8 +2544,8 @@ def fbx_takes_elements(root, scene_data):
     for astack_key, animations, alayer_key, name, f_start, f_end in animations:
         scene = scene_data.scene
         fps = scene.render.fps / scene.render.fps_base
-        start_ktime = int(units_convert(f_start / fps, "second", "ktime"))
-        end_ktime = int(units_convert(f_end / fps, "second", "ktime"))  # +1 is unity hack...
+        start_ktime = int(convert_sec_to_ktime(f_start / fps))
+        end_ktime = int(convert_sec_to_ktime(f_end / fps))
 
         take = elem_data_single_string(takes, b"Take", name)
         elem_data_single_string(take, b"FileName", name + b".tak")
diff --git a/io_scene_fbx/fbx_utils.py b/io_scene_fbx/fbx_utils.py
index 4a16fa5..5874d83 100644
--- a/io_scene_fbx/fbx_utils.py
+++ b/io_scene_fbx/fbx_utils.py
@@ -163,16 +163,19 @@ UNITS = {
 }
 
 
-def units_convert(val, u_from, u_to):
-    """Convert value."""
+def units_convertor(u_from, u_to):
+    """Return a convertor between specified units."""
     conv = UNITS[u_to] / UNITS[u_from]
-    return val * conv
+    return lambda v: v * conv
 
 
-def units_convert_iter(it, u_from, u_to):
-    """Convert value."""
-    conv = UNITS[u_to] / UNITS[u_from]
-    return (v * conv for v in it)
+def units_convertor_iter(u_from, u_to):
+    """Return an iterable convertor between specified units."""
+    conv = units_convertor(u_from, u_to)
+    def convertor(it):
+        for v in it:
+            yield(conv(v))
+    return convertor
 
 
 def matrix4_to_array(mat):
diff --git a/io_scene_fbx/import_fbx.py b/io_scene_fbx/import_fbx.py
index 4e574ec..3e862df 100644
--- a/io_scene_fbx/import_fbx.py
+++ b/io_scene_fbx/import_fbx.py
@@ -38,7 +38,7 @@ from . import parse_fbx, fbx_utils
 
 from .parse_fbx import data_types, FBXElem
 from .fbx_utils import (
-    units_convert_iter,
+    units_convertor_iter,
     array_to_matrix4,
     similar_values,
     similar_values_iter,
@@ -47,6 +47,9 @@ from .fbx_utils import (
 # global singleton, assign on execution
 fbx_elem_nil = None
 
+# Units convertors...
+convert_deg_to_rad_iter = units_convertor_iter("degree", "radian")
+
 
 def elem_find_first(elem, id_search, default=None):
     for fbx_item in elem.elems:
@@ -275,7 +278,7 @@ def blen_read_object_transform_do(transform_data):
     lcl_translation = Matrix.Translation(transform_data.loc)
 
     # rotation
-    to_rot = lambda rot, rot_ord: Euler(units_convert_iter(rot, "degree", "radian"), rot_ord).to_matrix().to_4x4()
+    to_rot = lambda rot, rot_ord: Euler(convert_deg_to_rad_iter(rot), rot_ord).to_matrix().to_4x4()
     lcl_rot = to_rot(transform_data.rot, transform_data.rot_ord) * transform_data.rot_alt_mat
     pre_rot = to_rot(transform_data.pre_rot, transform_data.rot_ord)
     pst_rot = to_rot(transform_data.pst_rot, transform_data.rot_ord)
@@ -1313,13 +1316,15 @@ def load(operator, context, filepath="",
     global fbx_elem_nil
     fbx_elem_nil = FBXElem('', (), (), ())
 
-    import os
+    import os, time
     from bpy_extras.io_utils import axis_conversion
     from mathutils import Matrix
 
     from . import parse_fbx
     from .fbx_utils import RIGHT_HAND_AXES, FBX_FRAMERATES
 
+    start_time = time.process_time()
+
     # detect ascii files
     if is_ascii(filepath, 24):
         operator.report({'ERROR'}, "ASCII FBX files are not supported %r" % filepath)
@@ -2153,4 +2158,5 @@ def load(operator, context, filepath="",
                                 material.use_raytrace = False
     _(); del _
 
+    print('Import finished in %.4f sec.' % (time.process_time() - start_time))
     return {'FINISHED'}



More information about the Bf-extensions-cvs mailing list