WIP: FBX IO: Speed up shape key access using pointers #105126

Closed
Thomas Barlow wants to merge 3 commits from Mysteryem:fbx_shape_key_pointer_access into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
2 changed files with 17 additions and 11 deletions
Showing only changes of commit 562c371eac - Show all commits

View File

@ -768,15 +768,23 @@ def fast_mesh_shape_key_co_foreach_get(shape_key, seq):
shape_key.data.foreach_get("co", seq)
def fast_mesh_shape_key_co_foreach_set(shape_key, seq):
co_memory_as_array = _shape_key_co_memory_as_ndarray(shape_key)
def fast_mesh_shape_key_dvcos_foreach_set(new_shape_key, dvcos, indices, mesh_positions_fallback_vector_view):
"""
FBX Shape key data are sparse vectors relative to the mesh, unlike Blender shape keys which are coordinates.
The newly created shape keys must have been created with `from_mix=False`, so that they match the mesh positions.
"""
co_memory_as_array = _shape_key_co_memory_as_ndarray(new_shape_key)
if co_memory_as_array is not None:
co_memory_as_array[:] = seq
# Memory has been set directly, so call .update() manually.
# TODO: Not sure if this is required
shape_key.data.update()
co_memory_as_array_vector_view = co_memory_as_array.view()
co_memory_as_array_vector_view.shape = (-1, 3)
co_memory_as_array_vector_view[indices] += dvcos
# Memory has been set directly, so call .update().
new_shape_key.data.update()
else:
shape_key.data.foreach_set("co", seq)
shape_cos = mesh_positions_fallback_vector_view.copy()
shape_cos[indices] += dvcos
new_shape_key.data.foreach_set("co", shape_cos.ravel())
# ##### Attribute utils. #####

View File

@ -51,7 +51,7 @@ from .fbx_utils import (
FBX_KTIME_V7,
FBX_KTIME_V8,
FBX_TIMECODE_DEFINITION_TO_KTIME_PER_SECOND,
fast_mesh_shape_key_co_foreach_set,
fast_mesh_shape_key_dvcos_foreach_set,
)
LINEAR_INTERPOLATION_VALUE = bpy.types.Keyframe.bl_rna.properties['interpolation'].enum_items['LINEAR'].value
@ -2001,9 +2001,7 @@ def blen_read_shapes(fbx_tmpl, fbx_data, objects, me, scene):
# Only need to set the shape key co if there are any non-zero dvcos.
if dvcos.any():
shape_cos = me_vcos_vector_view.copy()
shape_cos[indices] += dvcos
fast_mesh_shape_key_co_foreach_set(kb, shape_cos.ravel())
fast_mesh_shape_key_dvcos_foreach_set(kb, dvcos, indices, me_vcos_vector_view)
shape_key_values_in_range &= expand_shape_key_range(kb, weight)