Stage 1, Minimize Unnecessary Work
This should bring Blender's performance back to what we had in 2.7x.
The first step for this planning will be to perform benchmarks to
get an idea how much time these operations are taking,
so we can estimate how much of a speed improvement
we can expect to see for each proposed change.
This can help us prioritize changes.
Skip EditMesh to Mesh Conversion
Blender 2.7x supported edit-mesh without the creation of an "evaluation mesh".
For Blender 2.8x development it was convenient to always create this mesh
however this adds significant overhead, especially when making interactive mesh edits.
Exactly how to do this needs some design discussion with other module owners,
since it impacts the:
- Modifier stack.
- Render engine API.
- Python API & file IO.
Exact details for this may change.
- Support Delayed Mesh Creation: Initially this may mean locking the object upon request for an evaluation mesh, for common editing operations there would be no need to create this data.
For cases where we know the evaluation mesh is needed, the depsgraph could create this.
The end result should be that locking is avoided in common cases. Ideally we could avoid it entirely, however there may end up being some operations that require mesh data that we can't predict ahead of time.
- Modifier Stack Support for EditMesh:
Support deformations without converting to a "Mesh".
- Support edit-mesh for tools & UI code: Currently which assume an evaluation mesh is present. Listing this here since it's going to take time to go over all uses of Object.runtime.mesh_eval and find cases which should account for the edit-mesh, for example stats_object checks this.
- Multi-Thread EditMesh to Mesh Conversion
This can use 3 threads, vertices/edges/faces.
Splitting this up further could be done, I'd need to check if this would cause problems copying custom-data.
Minimize Data Send to the GPU
One part of this project is to minimize data sent to the GPU after each mesh edit.
- Selection: When changing selection, only the selection state arrays need to be refreshed.
- Deformation: When moving geometry, only vertex locations need be updated, along with derived data: Face centers, normals and possibly UV tangents.
- Custom Data Layers: When editing a UV layer, the updates could be limited to that layer and it's (UV tangents when present). The same goes for Vertex colors and Weight Paint colors.
This could be achieved by tagging a mesh as requiring data to be updated.
Optimize Edit-mesh to GPU Conversion
Benchmark current code, identify any bottlenecks to improve the performance.
As far as I know, nobody has checked on edit-mesh conversion performance,
since for 2.80 release we were mainly concerned with it working correctly.
Stage 2, Further Optimizations
This is mainly to note possible improvements.
This is only a rough outline, we can re-evaluate this once stage one is done.
Partial Geometry Updates
Currently when moving a single vertex, all normals are recalculated and the entire mesh is updated.
This would avoid two expensive operations:
- Recalculating all normals.
- Sending all vertex coordinates and normals the the GPU.
We could support tagging geometry to update, while this would only work for deformations,
this could give a significant speedup in the common case of transforming geometry.
Although there are complications with having to update connected normals, custom-normals and UV-tangents
making this a less straightforward task.
BMesh Support in the Modifier Stack
Avoid unnecessary BMesh conversions by allowing modifiers to pass BMesh data between modifiers.
Currently there aren't many optimizations relating to multi-object edit-mode.
- Every undo step includes all editable objects.
This can be optimized only to include tagged objects.
There are some difficulties with OpenGL and threading,
so the gains here might be limited, or better left until we move to Vulkan which handles this better.
The gains for edit-mesh aren't large unless the users is editing many meshes at once.
Listing this for completeness.