Weighting a MakeHuman Mesh
Posted: Thu May 02, 2019 7:41 pm
The last weekends Elvaerwyn and I used for some work on new proxies.
Elv created new proxies with more loopcuts in "flexible" regions like knees, elbows or the lowerarm/wrist area. Since a proxy is not different from a piece of cloth, we have the same problem, bones may influence parts more than they should do.
In MakeHuman a new weighting instead of the weight-copy is one of the possibilities. I am pretty sure, most people don't know that each piece of cloth could have an own weight-map based on the default skeleton. Check the standard shoes.
If the parameter
is set in the .proxy or .mhclo file, then the weights are not copied, instead the weights from this file will be used. The weights file is in JSON format, so it is also human readable. It contains an array of pairs of vertex-number and assigned weight for each bone.
I will now explain how you can do your own, so with some skill everybody else can do it for clothes or proxies.
Especially for proxies a fully symmetric mesh will make weighting easier. If it is not symmetric we have to weight both sides individual. This results in unpredictable behavior.
Let's assume this had been done. To test it, there is a script create_mirror_tab on github.
https://github.com/black-punkduck/MakeHuman-Helpers/blob/master/create_mirror_tab.py
If the mirror table contains unmatched lines (lines with vertex number -1), then it is not possible. Here is my real life example ...
If it is not a 100% symmetric try with -m 0.003. If that does not help and there are still differences the mesh is not symmetric. You can try the script on the base.obj.
So weighting is not very easy. Therefore it is best we start with the weights assigned by MakeHuman itself. Use your new proxy on a default female or male mesh, that is only the gender slider moved completely to left or right. Then add the default skeleton with toes and export with mhx2. The character is ready to weight and the vertex order is still the same.
In Blender import without modifications. Now change the weights.
Lets take an example. When I first explained MakeHuman to someone, of course I had a female with the default proxy and she sat nude and relaxed on chair. Unfortunately my texture is .. ehm ... well ... rather natural. The rest of the explanation I had to do the next day. A gynecologist would have been happy ... I guess.
To avoid this (btw also for male characters) I had to change weights in the crotch region. The next picture will explain how I did that.
Step 1:
First I select the region where I wanted to lower the influence of the upperlegs. So I completely set upperleg02 to zero by removing it and upperleg01 to 0.05 by simply assigning this value. With the vertices selected, look for upperleg in the vertex groups box and press remove for upperleg02. For upperleg01 assign "Weight:" to 0.05
Step 2:
Now change to weight paint mode and select the button to make the selected vertices from edit mode also visible in weight-paint mode. Press "normalize all" and do not lock active group (example is without upperleg assigned to 0.05) Normalizing means to change weight so that the sum of the weights equals to one.
Step 3:
Now increase the selection (CTRL NUM +).
Step 4:
And press smooth a few times with all groups.
Now the influences of the upperlegs are reduced, most weight is bound to spine05 and it looks better ...
Similar we can change weights for the knees. We just have to change the influence of the upperleg and lowerleg, The next image is an example of before and after the change. I only did the change on left side.
So we have created all the weights. Since I did not found an MHW exporter I wrote my own. You can download it from github.
https://github.com/black-punkduck/MakeHuman-Helpers/blob/master/mhw_export.py
I only tested it for 2.79 so far.
Put the file in the plugins directory of Blender and activate it (category is MakeHuman, so same as MakeClothes etc.). Select your weighted character in Object mode and export the weights with Export MHW. There is a small box, where you can add additional parameters.
All values smaller than the precision (3 = 3 digits after comma) will be ignored and the JSON file is created with the values grouped in four columns (a kind of beautification for readability).
In case you use a symmetric mesh and tested symmetry before you can use the generated mirror-table. At the moment this is not implemented in Blender. The script must be executed on shell/cli, the name of the generated mirror-table must be put in a configuration file. The script already creates a symmetric weights table. The command will be changed so it also creates the header in case of "=all=" in the next days. At the moment you have to add them manually. The script is also on Github in the same directory.
Without the ORIENTATION parameter left side is copied to the right side.
Unfortunately I only could test this on Ubuntu Linux. MacOS will work identical, as far as the python interpreter is found. I guess in windows the python interpreter must be written in front of the command. Maybe someone tries that and gives response (e.g. create_mirror_tab.py on original base mesh). All commands create the output into standard output, nothing will be overwritten by accident.
Elv created new proxies with more loopcuts in "flexible" regions like knees, elbows or the lowerarm/wrist area. Since a proxy is not different from a piece of cloth, we have the same problem, bones may influence parts more than they should do.
In MakeHuman a new weighting instead of the weight-copy is one of the possibilities. I am pretty sure, most people don't know that each piece of cloth could have an own weight-map based on the default skeleton. Check the standard shoes.
If the parameter
- Code: Select all
vertexboneweights_file <weightsfilename.mhw>
is set in the .proxy or .mhclo file, then the weights are not copied, instead the weights from this file will be used. The weights file is in JSON format, so it is also human readable. It contains an array of pairs of vertex-number and assigned weight for each bone.
I will now explain how you can do your own, so with some skill everybody else can do it for clothes or proxies.
Especially for proxies a fully symmetric mesh will make weighting easier. If it is not symmetric we have to weight both sides individual. This results in unpredictable behavior.
Let's assume this had been done. To test it, there is a script create_mirror_tab on github.
https://github.com/black-punkduck/MakeHuman-Helpers/blob/master/create_mirror_tab.py
If the mirror table contains unmatched lines (lines with vertex number -1), then it is not possible. Here is my real life example ...
- Code: Select all
./create_mirror_tab.py -b /data/punkduck/makehuman/v1/data/proxymeshes/elvs_maleproxy1.obj >/tmp/mirror_table.txt
16238 vertices processed
0 unmirrored vertices
If it is not a 100% symmetric try with -m 0.003. If that does not help and there are still differences the mesh is not symmetric. You can try the script on the base.obj.
So weighting is not very easy. Therefore it is best we start with the weights assigned by MakeHuman itself. Use your new proxy on a default female or male mesh, that is only the gender slider moved completely to left or right. Then add the default skeleton with toes and export with mhx2. The character is ready to weight and the vertex order is still the same.
In Blender import without modifications. Now change the weights.
Lets take an example. When I first explained MakeHuman to someone, of course I had a female with the default proxy and she sat nude and relaxed on chair. Unfortunately my texture is .. ehm ... well ... rather natural. The rest of the explanation I had to do the next day. A gynecologist would have been happy ... I guess.
To avoid this (btw also for male characters) I had to change weights in the crotch region. The next picture will explain how I did that.
Step 1:
First I select the region where I wanted to lower the influence of the upperlegs. So I completely set upperleg02 to zero by removing it and upperleg01 to 0.05 by simply assigning this value. With the vertices selected, look for upperleg in the vertex groups box and press remove for upperleg02. For upperleg01 assign "Weight:" to 0.05
Step 2:
Now change to weight paint mode and select the button to make the selected vertices from edit mode also visible in weight-paint mode. Press "normalize all" and do not lock active group (example is without upperleg assigned to 0.05) Normalizing means to change weight so that the sum of the weights equals to one.
Step 3:
Now increase the selection (CTRL NUM +).
Step 4:
And press smooth a few times with all groups.
Now the influences of the upperlegs are reduced, most weight is bound to spine05 and it looks better ...
Similar we can change weights for the knees. We just have to change the influence of the upperleg and lowerleg, The next image is an example of before and after the change. I only did the change on left side.
So we have created all the weights. Since I did not found an MHW exporter I wrote my own. You can download it from github.
https://github.com/black-punkduck/MakeHuman-Helpers/blob/master/mhw_export.py
I only tested it for 2.79 so far.
Put the file in the plugins directory of Blender and activate it (category is MakeHuman, so same as MakeClothes etc.). Select your weighted character in Object mode and export the weights with Export MHW. There is a small box, where you can add additional parameters.
All values smaller than the precision (3 = 3 digits after comma) will be ignored and the JSON file is created with the values grouped in four columns (a kind of beautification for readability).
In case you use a symmetric mesh and tested symmetry before you can use the generated mirror-table. At the moment this is not implemented in Blender. The script must be executed on shell/cli, the name of the generated mirror-table must be put in a configuration file. The script already creates a symmetric weights table. The command will be changed so it also creates the header in case of "=all=" in the next days. At the moment you have to add them manually. The script is also on Github in the same directory.
- Code: Select all
symmetrize.py -f weightfile "=all=" >/tmp/mirrored_weights
Without the ORIENTATION parameter left side is copied to the right side.
Unfortunately I only could test this on Ubuntu Linux. MacOS will work identical, as far as the python interpreter is found. I guess in windows the python interpreter must be written in front of the command. Maybe someone tries that and gives response (e.g. create_mirror_tab.py on original base mesh). All commands create the output into standard output, nothing will be overwritten by accident.