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.
Member

Unlike Blender, FBX shape keys are sparse data, meaning that it's not a
problem for large FBX meshes to have many shape keys that affect only
very few vertices. In Blender, because each shape key has as many shape
key coordinates as there are vertices in the mesh, it can result in
reading/writing a lot of data when importing/exporting FBX.

Due to the current implementation of shape keys in Blender, accessing
their data with foreach_set/foreach_get is slower compared to properties
with raw array access, such as most mesh attribute properties.

This PR avoids the issue of slower access to shape keys by constructing
an array view of the internal shape key data memory and using that array
to access the data directly.

To try and make the access to the internal shape key data safer, this
patch does checks when attempting to get the data and does a more
in-depth check the first time it tries to get internal shape key data.


This PR provides an alternative to blender/blender#116637, where, instead of adding to the current Python API, FBX IO is updated to access shape key data directly using the pointer to the first data element.

The overall effect on import/export duration varies depending on the file, but for most of my rigged humanoid models that have a 'face' mesh, separated from the rest of the model, that has facial shape keys (oculus visemes, apple arkit blend shapes or similar) the export duration is about 1.07-1.09 times faster (original duration ~0.2s). For a much larger model I have which instead has a full humanoid body with facial shape keys as a single mesh, the export duration is about 1.45 times faster (original duration ~2.4s).

The effect on import duration was roughly the same as the effect on export duration in an earlier version of this patch which performed two extra copies of the shape key data array. These two extra copies have been removed now so imports should be slightly faster, but probably not by much.

I'm not sure what the general sentiment is of accessing Blender data directly through pointers in add-ons. Most other properties accessed with foreach_get/set by FBX IO have raw array access internally so are quite fast already.


The individual fast_mesh_shape_key_co_foreach_get calls scale much better than foreach_get:
image

Unlike Blender, FBX shape keys are sparse data, meaning that it's not a problem for large FBX meshes to have many shape keys that affect only very few vertices. In Blender, because each shape key has as many shape key coordinates as there are vertices in the mesh, it can result in reading/writing a lot of data when importing/exporting FBX. Due to the current implementation of shape keys in Blender, accessing their data with foreach_set/foreach_get is slower compared to properties with raw array access, such as most mesh attribute properties. This PR avoids the issue of slower access to shape keys by constructing an array view of the internal shape key data memory and using that array to access the data directly. To try and make the access to the internal shape key data safer, this patch does checks when attempting to get the data and does a more in-depth check the first time it tries to get internal shape key data. --- This PR provides an alternative to https://projects.blender.org/blender/blender/pulls/116637, where, instead of adding to the current Python API, FBX IO is updated to access shape key data directly using the pointer to the first data element. The overall effect on import/export duration varies depending on the file, but for most of my rigged humanoid models that have a 'face' mesh, separated from the rest of the model, that has facial shape keys (oculus visemes, apple arkit blend shapes or similar) the export duration is about 1.07-1.09 times faster (original duration ~0.2s). For a much larger model I have which instead has a full humanoid body with facial shape keys as a single mesh, the export duration is about 1.45 times faster (original duration ~2.4s). The effect on import duration was roughly the same as the effect on export duration in an earlier version of this patch which performed two extra copies of the shape key data array. These two extra copies have been removed now so imports should be slightly faster, but probably not by much. I'm not sure what the general sentiment is of accessing Blender data directly through pointers in add-ons. Most other properties accessed with foreach_get/set by FBX IO have raw array access internally so are quite fast already. --- The individual `fast_mesh_shape_key_co_foreach_get` calls scale much better than `foreach_get`: ![image](/attachments/538a3da5-960d-4c77-bf25-0d681879d471)
Thomas Barlow added 3 commits 2024-01-15 05:42:06 +01:00

As stated in blender/blender!116637, I would much rather avoid such dark and dangerous magic in our python code. ;)

Nice proof of concept though!

As stated in blender/blender!116637, I would much rather avoid such dark and dangerous magic in our python code. ;) Nice proof of concept though!
Thomas Barlow closed this pull request 2024-01-16 21:39:25 +01:00
Thomas Barlow deleted branch fbx_shape_key_pointer_access 2024-01-16 21:39:57 +01:00

Pull request closed

Sign in to join this conversation.
No reviewers
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender-addons#105126
No description provided.