Page MenuHome

limit the number of bone deform weights per vertex. Many game engines require a limit of 4.
Closed, ResolvedPublicPATCH

Description

Purpose: Make armatures suitable for export to file types that limit the number of deform bones per vertex.

Attached are two patches, one for the changes to code, another for the UI to add a "Limit Weights" button to the Weight Paint Tools menu.

Usage: In weight paint mode, select the mesh to have its weights culled. Click on "Limit Weights" button. A sub-panel will appear "Limit Number of Vertex Weights" with a slider field "Limit" which you can set to the appropriate level. The default level is 4, and it gets executed upon pressing "Limit Weights" so you will need to do an "undo" if your max bone limit is above 4. The checkbox "All Deform Weights" will consider all vertex weights, not just bone deform weights.

Background: Blender does not limit the number of deform weights per vertex, but many game engies do. Vertex Buffer Objects (VBOs) are limited in versions of OpenGL where hardware skinning deforms the mesh according to animation of the underlying bones. Meshes may have thousands of vertices, while an armature is usually between 20 and 60 bones. Therefore, storing animations on the bones and using that to drive the mesh deformations saves a tremendous amount of data. “Skinning” or driving the deformations of the mesh with the bone matrices, often takes place on the GPU where there may be a hard limit to the number of bone weights. Some versions/implimentations of openGL have a limit of 4, while the iPhone has a limit of 3.

Vertex Groups and Weights: Any collection of vertices can be put into a group. Particle emitters, hair and armatures all make use of vertex groups and the weights could correspond to emission rate, hair length and bone influence respectively, always ranging from 0 to 1.

Description: The “Lim Number Deform Weights” operator is available through the Weight Paint UI panel in Blender. An object is selected and the operator is applied. The result should leave non-deform weights (hair, particle emitters, etc) in tact while culling deform bone weights to the user-specified number. The default number of weights is 4, set in a panel below the button. The script will execute with the default when you press the button, so if you need to set the limit higher, you will need to “undo” = ctrl+z, to undo the cull to 4 bones, then select the value you want and re-apply.

Most rigs will not need more than 4 bones for good skinning, but facial rigs are an exception with 8 or more deform weights per vertex not un-common. A typical workflow might require high-res skinning for video sequences of characters talking, but then exporting to a low-res skinned mesh for exporting to a game engine for gameplay.

Exporters: The operator should be exposed so that exporter scripts can easily make use of it. If there are multiple characters in a scene we will want to be able to apply the script to all armature skinned objects in it. I'd like it to be added to the ExportSettings in the collada export panel.

Notes: Testing the patch was made much easier by using the new Show Vertex Group Weights script http://wiki.blender.org/index.php?title=Extensions:2.6/Py/Scripts/Modeling/Show_Vertex_Group_Weights
For more details and a maintained page on this tool see wiki.blender.org/ http://wiki.blender.org/index.php/User:Kesten/Projects/LimitNumVertexWeights

Event Timeline

Fixed a memory leak from not freeing the array returned by valid_map.

There is still one memroy leak being reported (running ./blend --debug . Looks like it's unhapy with the way i delete dv->dw and re-assign it.

Also, need more testing on "undo". It works until you leave edit mode. A normal workflow might not discover the need to "undo" a limit-bone-weight action until it's too late.

New patch with the one fix.

Fixed the second memory leak. Had a MEM_FreeN outside of the "for" loop scope.

Now all cull_num_weights specific error messages like these are gone.
ReportMessage len: 36 0x52934d8
vertex_group_cull_num_weights len: 40 0x68b5de8
vertex_group_cull_num_weights len: 32 0x6a15278

but there are two remaining. Perhaps they are from another function?
Error: Not freed memory blocks: 2
Report len: 40 0x6245eb8
ReportMessage len: 36 0x6245f28

attached a new patch - limitBoneWeights2.patch



Campbell Barton (campbellbarton) changed the task status from Unknown Status to Resolved.Oct 9 2012, 12:57 PM

great addition! is is really a problem and couple export scripts use their own solution for this. Would be great if there was another way to use this limiter from py scripts without relying on context.object / operator