Shapekeys Memory Bug

hi all,

I come from Lightwave and I’m new to Blender so maybe I miss something. I just played around with some tutorials on shapekeys and found something weird.

Using the standard Windows monitor, I measured the memory Blender uses for shapekeys both on ram and on disk.

When creating a new shapekey it seems that Blender allocates a vertex list for the whole object, for every new shapekey, even if the shapekey is empty or not used.

So for example, if you use shapekeys for facial expressions, the whole body of the character is included in the shapekey vertex list, for every shapekey you make. If you have 30 shapekeys for facial expression, then the whole body takes memory 30 times together with the face of the character.

Actually the only workaround I found is to keep the face of the character in a separate object, so to limit shapekeys memory usage to the face vertex list. For some characters this works fine but for others this method shows a visible seam where I separated the face and this is not visually acceptable.

I didn’t find any way to limit a shapekey vertex list to only a part of an object. Even if I use the shapekey vertex group, it is used only as a mask to limit influence, but the whole object is included in the shapekey vertex list.

It is easy to understand that this is a major memory hog. I hope I miss something and that some experienced Blender user can point me to a solution.

I’m also wondering how it is possible that nobody noticed this before. I googled the web but I didn’t find anything on this subject.

In Lightwave shapekeys are called endomorphs. An endomorph only stores vertices that are changed from the base form. So for example if I create an endomorph for a facial expression, then only the changed face vertices are stored in the endomorph. This saves memory and also make morph operations faster because less vertices are to be computed.

comments welcome and needed, thanks :smiley:

p.s. fast and easy steps to reproduce the problem

  1. model a simple character using monkey as head and some balls as body, join them in a single object and apply a subd modifier so to get a dense mesh to better measure memory usage, save as monkey.blend

  2. create a number of shape keys and leave them empty, save as emptykeys.blend

  3. modify the shape keys to only affect the head and save as headkeys.blend

  4. modify the shape keys to also afffect the body and save as bodykeys.blend

  5. close and reopen blender, with the empty scene measure memory usage. Then load monkey.blend and measure memory. Then load emptykeys.blend and measure memory. Then load headkeys.blend and measure memory. Then load bodykeys.blend and measure memory. My results are:

40 Mb empty scene
75 Mb monkey (no keys)
90 Mb empty keys
90 Mb head keys
90 Mb body keys

80 Mb my workaround: head keys with head as separate object (saves 10 Mb)

this means the head keys alone take 5 Mb ram, and there is a waste of 10 Mb ram to also store unused body vertices in the shapekeys

Just a couple of more tips on the subject I discovered along the way. When I have time I’m going to try to report this issue to the developers. Meanwhile the tips below can save your day.

  1. One easier way to see how many vertices a shapekey takes is to look at the outliner in datablock mode under the shapekeys entry. This way you don’t have to do memory tests as I did.

Outliner > Datablocks > Shape Keys > Key > Key Blocks > [your shapekey here] > Data

  1. As I said you can cut off the head of your character to a different object to optimize memory usage in shapekeys. But depending on the character this may leave a seam visible, especially when using subdivision.

One way to make the cut not visible is to leave one extra polygon row in every half of the two pieces (eg. the head and the neck). This way the poly normals will be the same where the cut takes place and the seam will not be visible. This also works well with subdivision since the extra row also takes care of the “subd weighting”.

duplicate the object
in the first object cut the head plus one poly row
in the second object cut the body plus one poly row

A further refining would be to make the extra row invisible using a transparent material, but I found that in many cases this is not necessary.

bye :slight_smile:

just some data I got with makehuman characters http://www.makehuman.org
this test is for a character imported with face shapekeys
the optimized version just cuts off the head as a separate object

you can see there’s a huge saving in memory usage :slight_smile:

84 Mb empty scene
143 Mb makehuman (takes 59 Mb)
100 Mb makehuman with optimized shapekeys (takes 16 Mb, saves 43 Mb)

good news … I did a bug report and Bastien of the Blender team added the request to the TODO list, hopefully they will fix it :slight_smile:
https://developer.blender.org/T39287