FBX Export: Speed up shape key weights and normals.

* Add `break` statement once `vg_idx` is found.
* Get `me.vertices` outside the main loop.
* Replace lists with arrays to skip the step of converting from list to array
  in `elem_data_single_float64_array`.

No changes are made to the exported file with this patch.

The `break` statement is the main speedup in most cases.
The other changes only result in about a 5-10% speedup (observed by comparing
cases where vg_idx is not in the vertex's weights, so all weights on the
vertex have to be iterated).

Differential Revision: https://developer.blender.org/D17168
This commit is contained in:
Mysteryem 2023-02-01 10:31:44 +01:00 committed by Bastien Montagne
parent fe59d382b4
commit 6ff03383f4
2 changed files with 8 additions and 5 deletions

View File

@ -3,7 +3,7 @@
bl_info = {
"name": "FBX format",
"author": "Campbell Barton, Bastien Montagne, Jens Restemeier",
"version": (4, 37, 3),
"version": (4, 37, 4),
"blender": (3, 4, 0),
"location": "File > Import-Export",
"description": "FBX IO meshes, UV's, vertex colors, materials, textures, cameras, lamps and actions",

View File

@ -755,17 +755,19 @@ def fbx_data_mesh_shapes_elements(root, me_obj, me, scene_data, fbx_me_tmpl, fbx
channels = []
vertices = me.vertices
for shape, (channel_key, geom_key, shape_verts_co, shape_verts_idx) in shapes.items():
# Use vgroups as weights, if defined.
if shape.vertex_group and shape.vertex_group in me_obj.bdata.vertex_groups:
shape_verts_weights = [0.0] * (len(shape_verts_co) // 3)
shape_verts_weights = array.array(data_types.ARRAY_FLOAT64, [0.0]) * (len(shape_verts_co) // 3)
vg_idx = me_obj.bdata.vertex_groups[shape.vertex_group].index
for sk_idx, v_idx in enumerate(shape_verts_idx):
for vg in me.vertices[v_idx].groups:
for vg in vertices[v_idx].groups:
if vg.group == vg_idx:
shape_verts_weights[sk_idx] = vg.weight * 100.0
break
else:
shape_verts_weights = [100.0] * (len(shape_verts_co) // 3)
shape_verts_weights = array.array(data_types.ARRAY_FLOAT64, [100.0]) * (len(shape_verts_co) // 3)
channels.append((channel_key, shape, shape_verts_weights))
geom = elem_data_single_int64(root, b"Geometry", get_fbx_uuid_from_key(geom_key))
@ -781,7 +783,8 @@ def fbx_data_mesh_shapes_elements(root, me_obj, me, scene_data, fbx_me_tmpl, fbx
elem_data_single_int32_array(geom, b"Indexes", shape_verts_idx)
elem_data_single_float64_array(geom, b"Vertices", shape_verts_co)
if write_normals:
elem_data_single_float64_array(geom, b"Normals", [0.0] * len(shape_verts_co))
elem_data_single_float64_array(geom, b"Normals",
array.array(data_types.ARRAY_FLOAT64, [0.0]) * len(shape_verts_co))
# Yiha! BindPose for shapekeys too! Dodecasigh...
# XXX Not sure yet whether several bindposes on same mesh are allowed, or not... :/