Mesh Struct of Arrays Refactor #95965
Labels
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset System
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Code Documentation
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
FBX
Interest
Freestyle
Interest
Geometry Nodes
Interest
glTF
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Viewport & EEVEE
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Asset Browser Project
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Asset System
Module
Core
Module
Development Management
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Module
Viewport & EEVEE
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Severity
High
Severity
Low
Severity
Normal
Severity
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
4 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#95965
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Background
Currently, Blender uses an array of structs format to store some specific mesh data. Instead of storing each data layer in a separate array, arbitrary data (mostly flags and data that was added years ago) is grouped together in specific structs.
Switching to a struct of arrays format can provide significant performance improvements and code simplification. Besides memory usage improvements and general improvements to the efficiency of accessing data, sometimes processing data can be avoided completely. Here is a more complete list of the benefits:
The Goal
#93602
Vertex data should become
float3
, with all other data moving to separate places.#95966
Edges store a lot of flags currently, which should be moved to runtime data or separate boolean attributes.
The final goal should be that the edge layer is just two vertex indices.
#95967
Material indices should move to a separate generic integer attribute, as should the smooth flag. The size of each face is redundant with the offset stored in the next polygon, so we should use the same offsets system as curves to halve the memory usage.
#102359
Face corners should be split into separate arrays, to prioritize performance in hot loops when only edge or vertices are accessed and to make the data access more generic.
This can be handled separately, but I wanted to note that the flag should be removed from
MLoopUV
, which would becomefloat2
, just like mesh vertex positions.Open Questions
Backward Compatibility
Generally this is easy, we just need to add versioning code that adds the new custom data layers
The hard part about backwards compatibility is using the same name for the DNA structs after the refactoring, because we don't want to keep the deprecated members in the structs.
This could be implemented as a special case in file reading code, only for
MPoly
andMEdge
.Forward Compatibility
See comment for current plan: #95965#1393317
Forward compatibility is already a bit harder. As these refactors land, more and more mesh data would not load correctly in earlier versions.
For runtime data like normals, a fix can be a bit simpler, like tagging normals dirty when reading from the future version (see
add07576a0
).But that obviously isn't a solution for most things.
There are a few possibilities that I know of:
Because of the reasoning above, I strongly prefer option 3.
Edit-Data Attributes
Some data like selections should not be propagated like other attributes. Additionally, their addressing needs a bit of design.
See #97452 for the latest proposal.
Wouldn't it be worth storing selection & hidden state in a single flag array? As both as used a lot for tool & drawing code, I don't see much advantage in storing them separately.
There could be an advantage if the arrays were created & removed as needed, so de-selecting all could free the selection array, revealing all could free the hidden array, although this has pros/cons (having to always account for NULL layer anywhere selection checks are needed complicates access).
If both are always allocated though, storing them separately doesn't seem necessary.
I don't think combining multiple flags into a single attribute would be the right choice, for a few reasons:
.hide
layers, nothing is hidden-- all processing related to hide status can be skipped (this means that with well designed code you don't need to worry about NULL layers really)..selection
layers, everything is selected (or nothing, depending on what we decide), this can also simplify code.Yes, this is exactly what I want to do, I think it's where the potential memory usage improvements come in, for common cases when these layers aren't used.
Besides that, I think there is a misconception that because multiple data sources are used in the same algorithm they have to be stored together.
I see it as a benefit to the algorithm if it can have generic inputs that come from different sources instead.
To add my 2c: In the case of uvmaps (storing 3 bools) storing them separately is cheaper memorywise than it used to be. Used to a a 32 bit int, vs now 3 bools. The bools are currently stored as chars. But we could optimize that if needed.
So in any case memory is not an argument to stuff multiple flags in a single variable in this case, imo.
Here is an update on the forward compatibility topic based on discussion in D14583:
This issue was referenced by
2480b55f21
This issue was referenced by
12becbf0df
This issue was referenced by
6c774feba2
I have one more PR that's slightly related for the cached triangulation (#106774), but that doesn't affect the file format so it can be done any time. Otherwise, this task is done!