Speed up FBX export of vertex cos with numpy #104448

Merged
Bastien Montagne merged 1 commits from Mysteryem/blender-addons:fbx_numpy_vertex_cos_pr into main 2023-02-28 18:05:03 +01:00
Member

Use buffer matching the single precision float type of the vertex cos data in foreach_get to avoid having to iterate and cast every element in the C foreach_getset function when single precision float is not 64 bits (it's usually 32 bits). Numpy does the casting to the 64 bit fbx type much faster with .astype when needed.

Replace use of vcos_transformed_gen mesh transform helper with numpy version.

~35 (1538 vertices) to 55 (best) (24578 vertices) to 20 (6M to 25M vertices) times faster when geom_mat_co is None
~21 (1538 vertices) to 50 (best) (24578 vertices) to 23 (6M to 25M vertices) times faster when geom_mat_co is set

Relative to the original implementation, the numpy implementation seems to perform increasingly faster the more vertices there are until about 25k vertices and then starts getting slower at a decreasing rate, to the point that there is pretty much no change in the relative speedup between 6M and 25M vertices.

This patch slightly changes the exported cos when geom_mat_co is set by skipping a cast from double to single precision before casting as float64 (usually double precision):
The original code would multiply mathutils.Matrix (single precision) and mathutils.Vector (single precision) together, which casts the Matrix elements to double precision, performs the multiplication, and then casts the result back to single precision. These single precision multiplied vectors would then be cast to float64 to be exported.
The new code performs the same cast of the matrix to double precision, but skips the step of casting back to single precision, instead casting directly to float64.
Even if the new code were to cast back to single precision float and then to float64 like the original code, there does tend to be a small difference in the result, presumably due to precision error.


mathutils column vector multiplication for reference, note the use of double precision math:

int column_vector_multiplication(float r_vec[MAX_DIMENSIONS], VectorObject *vec, MatrixObject *mat)

This patch depends on
#104447
I wasn't sure if I should include its commit in this PR, I have included it for now.

Use buffer matching the single precision float type of the vertex cos data in foreach_get to avoid having to iterate and cast every element in the C foreach_getset function when single precision float is not 64 bits (it's usually 32 bits). Numpy does the casting to the 64 bit fbx type much faster with .astype when needed. Replace use of vcos_transformed_gen mesh transform helper with numpy version. ~35 (1538 vertices) to 55 (best) (24578 vertices) to 20 (6M to 25M vertices) times faster when geom_mat_co is None ~21 (1538 vertices) to 50 (best) (24578 vertices) to 23 (6M to 25M vertices) times faster when geom_mat_co is set Relative to the original implementation, the numpy implementation seems to perform increasingly faster the more vertices there are until about 25k vertices and then starts getting slower at a decreasing rate, to the point that there is pretty much no change in the relative speedup between 6M and 25M vertices. This patch slightly changes the exported cos when geom_mat_co is set by skipping a cast from double to single precision before casting as float64 (usually double precision): The original code would multiply mathutils.Matrix (single precision) and mathutils.Vector (single precision) together, which casts the Matrix elements to double precision, performs the multiplication, and then casts the result back to single precision. These single precision multiplied vectors would then be cast to float64 to be exported. The new code performs the same cast of the matrix to double precision, but skips the step of casting back to single precision, instead casting directly to float64. Even if the new code were to cast back to single precision float and then to float64 like the original code, there does tend to be a small difference in the result, presumably due to precision error. ----- mathutils column vector multiplication for reference, note the use of double precision math: https://projects.blender.org/blender/blender/src/commit/4675ee3c7342c151311a1a2d74acacecd64c4545/source/blender/python/mathutils/mathutils_Vector.c#L2047 This patch depends on https://projects.blender.org/blender/blender-addons/pulls/104447 I wasn't sure if I should include its commit in this PR, I have included it for now.
Thomas Barlow requested review from Bastien Montagne 2023-02-28 01:21:00 +01:00
Bastien Montagne force-pushed fbx_numpy_vertex_cos_pr from 147df61eb6 to 6315b3d566 2023-02-28 18:03:42 +01:00 Compare
Bastien Montagne approved these changes 2023-02-28 18:04:26 +01:00
Bastien Montagne left a comment
Owner

LGTM.

LGTM.
Bastien Montagne merged commit 6054d1bef8 into main 2023-02-28 18:05:03 +01:00
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#104448
No description provided.