Page 1 of 1

New Year, new features in MakeHuman?

PostPosted: Sat Dec 29, 2018 8:57 pm
by punkduck
We all know Makehuman has a pretty good basemesh and a skeleton that works fine for most of our purposes. After doing a lot of assets, talking about skins and materials, doing hair in Blender, sharing characters with Mindfront etc. two things happened.

First I was interested how skeletons are working and second I became more and more aware of a genre which I normally neglected. I try to do my pictures in a more natural way, sometimes waiting for hours until the picture is done. So I do normally not use games and I also have only one life and not a second virtual one.

But to see your character running (even less perfect than it could be when you do a "perfect" animation in Blender) is fun to view. A perfect animation normally needs much more work on our characters like shape-keys or additional jiggle bones etc.... but it is cool also.

Elvaerwyn invited me to a Canadian OpenSim community. It took some time to understand what I should do there. Not really knowing what I did I installed firestorm (which is the client caching the world information) and was running around in a very imaginative world. Although I was rather clumsy in the beginning, I was fascinated. The next day Elv presented the complete french lingerie I have added to the assets on a dancing character. So I asked how these characters are animated and got in touch with OpenSim and Bento skeleton.

After that time went by. Inbetween I was not very lucky about breast movement, so I changed the skeleton for a more natural breast movement of a female character in Blender.


Now I had the question if such a skeleton change is possible in MakeHuman ... An own skeleton does not mean a simplified version, like the game engine one. I wanted to be able to change the bones like I did in Blender.

It first looked as if there are limits, because all bones end in a cube and there was no cube where my new breast bones started. But the breast bone also did not end on a cube, in default skeleton it ends on a single vertex. And why a cube? The position of one vertex is sufficient. And lowerarm01.L and lowerarm02.L meet somewhere in the middle of two cubes ...

So first thing I did. I had to understand how the is skeleton is created. So I learned, that you can use a number of vertices and create the arithmetic mean value to place the bone "somewhere" inside the body. That is the reason for the joint between e.g. lowerarm01.L und lowerarm02.L needs no own cube.

How do we get the vertex numbers?

Well that is simple. Import base.obj into blender. Make sure you use "Keep Vertex Order". The base mesh is an Wavefront .obj. When you only have the base.npz in your makehuman directory you can of course load it from github. (the directory is called <installpath>/data/3dobjs/base.obj normally)

After importing. use the scripting in Blender. There you find an interactive console. Enter the statement

Code: Select all = True

Now in edit mode you will see the indices numbers.


The result the first different skeleton in Makehuman. Using vertices on left and right side of the body and one of the cubes in spine area, I was able to create a skeleton like this


The effect is nearly unvisible, because the weighting is still the same. Well I changed weighting in Blender ... Now I was able to use create a push up bra without working with targets and other things as well ;)

So can I also do an own weighting? Well the standard weight file is in <installpath>/data/rigs/default_weights.mhw.

It is a rather big uncomfortable JSON file ... and it is directly referenced from the default skeleton <installpath>/data/rigs/default.mhskel

So yes, we can do it. We can also add an own weight file. But then I have to recreate the whole weighting myself. No I do not want that.

The weighting of fingers, legs and face is fine, only the weighting in breast area must be changed. Of course the helpers also. So I had to do a copy of the weighting file which is referenced in default_skeleton file and I have to change this.

When I do weighting in Blender I often did not fix a problem, I mostly created new problems. So I need that more controlled. We work on the basemesh, can we copy weights from left to right, can we only change one vertex group or can normalize it later?

to be continued ...

Re: New Year, new features in MakeHuman?

PostPosted: Sat Dec 29, 2018 9:16 pm
by punkduck
... next step

Doing all this Elv ask me why not trying that with a Bento-like skeleton. That will take weeks I answered. I was rather disaffected now. Creating all this ... and do I have all information I need, does this make sense, are there hidden limits?

But why not trying. Christmas time is boring, so use it.

So I started to create the skeleton manually, bone by bone. Using the OpenSim as a template in the beginning, but already with changed positions of clavicle/shoulder area and also between torso and chest.

Then I added the fingers by renaming the bones one by one. The hands of bento have no metacarpal bones so I leaved them out. So the hands itself have to get new weights. At the end I have to do the face. To place the bones means 20 hours of work. But here it is.


Next topic, weighting ... first I want to get weights from the OpenSim skeleton in MH. So I exported the base character using mhx2. Fortunately it was loaded into Blender using the same vertex numbers. Well all fingers are still not poseable.

But how can I get the right weights for the fingers using new bone names. Also only for the body.

Time to write a first script. I first did it in perl. But then changed it to python, because I must also do scripts in python for Blender, I thought. And I am still a beginner ... you might see that, when you look at the scripts. And I just created a github user ... so why not using this for the project.

The first script I did should extract (and summarize) the weights and should be able to transpose the default names into the Bento names. So before I have to create a table which transposes the names,

Here it is:

and then I did a script called extract_weights:

and to make it more flexible for later use I created a configuration file in JSON:

Since I need an own printer for the weights (I didn't like the JSON printer) I put that in a small class which is called All output is done to standard output, so nothing is overwritten accidentally.

So I created the weights of the fingers this way. Next step was changing the weights in Blender in wrist area. How can I do the changes only on one side and later do the mirroring with a script and how can I get a file like this JSON file in MH from Blender?

As I had no idea, I read a bit about blender scripting, and created this script:

Since it is not yet perfect I put it somewhere, but not in the blender path. I simply loaded it and started it. If you will do it yourself, make sure it finds the This I will redo in future, because also the output filename must be changed in the code.

Now I had to select the mesh and the output is written to a temporary file. This file can be used as a new weights file.

Really? No, it is not a good idea, you will loose all helper weights now. So it has to be merged. And I only did one side of the weighting.

Since the basemesh is fixed in a way, you can determine the mirror vertex only one time and do a table of 19158 lines. The script is called You have to do that once and put the file somewhere. Make sure that mirror_vertices in mh_helper.json points to this file then.

Now call the symmetrize command. Either it creates the opposite group depending on the name or it symmetrizes one group without a hint of left or right side.

The file I got I wanted to merge. But only fingers and wrists. So I extracted these parts and wrote a merge script. It either replaces the weights of a group (also deletes unwanted ones) or simply merges them, merging means that the new value is taken instead of the old one.

So I got my fingers working. The same I did with the head. But that took longer because it was a bunch a bones.

Now the helpers:

I could simply copy the weights for eyes from default to Bento for the eyes and eyelashes. The tongue and teeth I had to do new. The tongue has only two bones.

Weighting the helper the workflow is more complicate:

  • export a mhx2 base character
  • import that in Blender
  • import base.obj in blender as one object without groups or delete unwanted vertex group names, but keep vertex order
  • move base mesh to a position si that it overlaps the mhx2 character.
  • throw away all but the skeleton of the mhx2 character
  • hide everything but the tongue and teeth of the base mesh
  • set the weighting of the teeth to mFaceTeethUpper and mFaceTeethLower = 1 according to the teeth in helper mesh.
  • create two groups for the tongue mFaceTongueBase, mFaceTongueTip do a weighting only for these groups on the tongue, e.g. by creating loops with a value of 1 and smoothing this.
  • export it with the JSON tool
  • make sure your weightfile only contains these 4 groups
  • do a symmetrize on it
  • merge it into the other weights you already have

Because of the different weight between torso and chest, I also did a small weight change on the tight helper. So my first skeleton was ready to go. It must be tested.

I was not so keen on trying that a 100s of times in an OpenSim world so I installed a local OpenSimulator from

It took some hours to do that on a Linux box but I simply would not use my "guest login" in Canada ...

Elv mentioned that it is not possible to export via Collada from MH directly to blender. She used Collada export to Blender and in Blender again Collada export with activated "Export to SL/OpenSim".

Since Collada export and import does weird things with the bones and the export in Blender is the new exporter then, I was sure that the mhx2 format will also work for the way from MakeHuman to Blender. But the character has to look in negative x direction. And so rotating and applying must be used. Since I was not happy with the t-pose I did a new one now facing to negative x.

So now I could use the way:
  • export with mhx2 using meter size
  • import in Blender
  • export with as collada dae using SL/OpenSim activated

Of course there are some more things to learn when you will put an Avatar in OpenSim, like the hair should be double sided etc. But I was happy to get my Dani in OpenSimulator. Because I never did an own hairdo for her. Elv did one for me. So here she is in OpenSimulator.


When you analyze the skeleton, you can see, that the red bones are already detected.


Re: New Year, new features in MakeHuman?

PostPosted: Sat Dec 29, 2018 9:38 pm
by punkduck
Next step: is it possible to add wings like in the Bento skeleton to MakeHuman?

The bad information: No, not without appending additional parts to the helpers and to change the base mesh.

Is a change possible to keep it compatible? Yes. I am working with that new base mesh in old MakeHuman since a few days.

I loaded the base.obj mesh into Blender (options see above). I added a cube at the end of the base mesh and hoped about a very small change. Just 8 vertices, 14 vt rows for UV map and 6 new planes in the end ...

Forget about that. :cry:

Unfortunately I did not find a method to even save the obj in the way I have loaded it. So I decided to write another script in python, which simply should merge the new helpers to the base mesh at the end. And Unix diff should only print a few lines, so only the new ones.

I call it, you will also find that on github. It simply reads the v and vt and f lines, then it takes the new exported wavefront object (vertices start at 1) and appends it to the regular base mesh. Unix diff printed out exactly the lines I added.

So I was able to simply add the bones for the wings now using the coordinates from the helper geometry. Here we go:


Then I did a weighting of the wings-helper and added that to my weightfile using the symmetrize script again. Of course no target is now changing the wings. So if you decrease your character to the size of a kid, the wings will fly over the character. But that is acceptable at the moment. And of course it is possible to add the movement of these vertices to the target also.

So finally: it is possible to move wings we have in our assets with the skeleton?!

For the last step I wanted to use the wings Elv did and to change MakeClothes to accept the new helper. Unfortunately MakeClothes does not work with configuration files ... so I had to change 6 python scripts to accept a base mesh called "extended". At least it was not that complicated because the code I changed also accepted old alpha7 and alpha8a meshes. So it was already built to accept other meshes. Well I added another one ...

A good idea for the future is to use a json configuration to allow meshes without changing the code.

Also in my case I simply ignored that all the additional meshes used by MakeClothes are created by targets. For a first try it is sufficient that the base mesh with helpers creates our wings. Not the female one and also not the one for kids.

The rest was rather easy now. I took the wings, placed them over the helpers. Tnen I created two vertex groups: left- and right-wing, I assigned the wings and helpers to the groups and pressed the make button and ... it works.


The images of flying Dani are created by rotating the wings bones ...


So I don't know, if people are interested, I will at least create the standard skeleton without wings for all of us. I also plan another skeleton. With less bones for the tongue but maybe so called jiggle bones. But for better use of the bento-compliant skeleton I have to do some fixes in face area again.

Considering wings. I will also do the tail. The number of changes in MakeClothes were limited and also a base mesh with additional parts is possible.

Targets should get a component maybe on what meshes they work (some of them especially from user repo forgot to move clothes as well).

The scripts I did are rather helpful. The hair of my original basemesh was assymmetrical weighted, With the scripts you can change that easily.

Take this as an idea ... not more but also not less. I must admit it was fun to do this although I need three weeks to get a result like that. :D

Re: New Year, new features in MakeHuman?

PostPosted: Sat Dec 29, 2018 11:27 pm
by loki1950
Looks like you had a productive Christmas punkduck all I managed was to set up a new laptop see my updated sig still haven't installed Mint 19 for a dual booting yet Lenovo makes getting into the BIOS tricky :twisted: that and having to get to the BIOS just to get the boot menu as well but what do expect for a laptop for the corporate market.

Enjoy the Choice :)

Re: New Year, new features in MakeHuman?

PostPosted: Sun Dec 30, 2018 7:03 pm
by RobBaer
Incredibly interesting. I'm still trying to wrap my head around all you've done. This could be a great thing for MH. The wings and tail project look great.

Dani got a nice hairdoo, but she looks lonely in opensim :)

Re: New Year, new features in MakeHuman?

PostPosted: Mon Dec 31, 2018 10:22 am
by joepal
This sounds like extremely important work. And many people have been asking for a bento skeleton.

I'm wondering if some parts of your workflow could be automated and/or merged in the new blender integration, which has the upside of now also working with blender 2.80. For example, I'm thinking there must be an easier way to work with weighting than what we have now.

Re: New Year, new features in MakeHuman?

PostPosted: Mon Dec 31, 2018 1:43 pm
by punkduck
joepal wrote:This sounds like extremely important work. And many people have been asking for a bento skeleton.

I'm wondering if some parts of your workflow could be automated and/or merged in the new blender integration, which has the upside of now also working with blender 2.80. For example, I'm thinking there must be an easier way to work with weighting than what we have now.

Thank you, I really appreciate the comments and I know that people working with OpenSim or Second Life have some problems or at least hope to get a simpler workflow. The reason why I also corrected (or at least try to correct) this triangle topic. The last three weeks I tried to understand more of MakeHuman internals ... and slowly I feel familiar with parts of the software. But first let's write a line about a comment RobBaer did:

RobBael wrote:Dani got a nice hairdoo, but she looks lonely in opensim

Well Dani is alone in my own OpenSimulator. The reason: you need two players to get two characters. And I was too lazy and just created one using the boring name "test user".

I took the wings and added them to Dani in my OpenSimulator. Now I learned, why a lot of assets Elv did are double sided. In Sim-World backface-culling cannot be changed, so you always see only the side with the normals pointing to the viewers side. So I double the feathers of the wings and flipped the normals in Blender before saving them.

So that's Dani in OpenSim flying:


And the hairdo is triangle based. Elv send me lots of them. Even a Heidi Klum look-alike and for all the older guys in here we know how she looked like ... or not ? ;)

Okay let's concentrate on the Bento. For all of you interested in the face bones of Bento in MakeHuman here you can see them.


Meanwhile I added the tail, to do this I added another helper. The next picture shows an overlay of the bento skeleton and this extended helper.


As a test I did a very simple tail (a cylinder mainly, slightly changed to a cone). This is skeleton view in MakeHuman:


I put Dani as "whatever-that-maybe" (cat, squirrel, yeti?) into Blender to show the bones working. Looks like this:


The bones you can see in the next picture. I am still not satisfied with connection between mPelvis (the root bone) and mTail1 (this first tail bone) because for normal creatures a tail is part of the spine. At least I have to change the weighting, because I put some of the helpers weights to mPelvis instead of mTorso (the bone above the root bone) and when she bends down, the tail does not follow. But as I said, it is still a study not yet perfect.


Okay. That's all for this year. Now I will install a laptop, same like Loki1950 mentioned. With Ubuntu, no Windows. And without Nvidia card ... so maybe ... but I am still not that good, Joel :(


I wish all members of the team and this community a very good new year now. And I like to thank the members I worked with, especially


and not to forget


for cooperation and communication.

Re: New Year, new features in MakeHuman?

PostPosted: Sat Jan 05, 2019 5:01 pm
by punkduck
I will add a few words about targets for new helpers:

I loaded the helper mesh (my own one) in maketarget, since makeclothes and maketarget use the same functions I had not to change more of the code.

I made a simple target, which normally should be included (or linked?) in the resizing target (Makehuman: Main/Macro/Age). So I made the wings smaller and moved them down and a bit to the front. Here is a quick and dirty version.


Now I saved this as a target using "selected verts only". Then I created a wings folder for the targets in MH and put the target into this folder.

I took the wings, a character, resized him to a kid and just added some assets just for fun:


This cool small guy already uses bones for the wings, this is also done by resizing the wings, because the bones follow the vertices of the target.


Now the next question. What will happen when I load the skeleton (with wings) I did and only use base.obj instead of my extended one?

Well because of the missing helper you have two problems, The wing bones have no positions for the joints and there is no place for the weights of the wings. MH will crash then at the moment.

A solution would be to ignore the bones "outside" (using vertex numbers higher than the base mesh) and do the same for the weights not needed. A few hours of work and I found the code where to do it best.

In my case skeleton loader should always know the highest vertex number, the parameter "mesh" is not mandatory ... :( but using this and throwing away all bones might work.

I did it like this (shared/

Code: Select all
def fromFile(self, filepath, mesh=None):
        Load skeleton from json rig file.


        if mesh is None:            # this should be set always :-(
            maxverts = 19158        # base mesh atm
            maxverts = len (mesh.coord)
            print ("maxverts from mesh")

        for joint_name, v_idxs in list(skelData.get("joints", dict()).items()):
            if isinstance(v_idxs, list) and len(v_idxs) > 0:
                c = 1
                for ind in v_idxs:          # check if vertex-maximum fits to mesh
                    if ind >= maxverts:
                if c == 1:
                    self.joint_pos_idxs[joint_name] = v_idxs  # joint position is created
                    skelData["joints"].pop (joint_name)  # joint will be deleted, it is outside the mesh

        # now throw away all bones having no head or tail
        for bone, v in list (skelData.get("bones", dict()).items()):
            if v["head"] not in self.joint_pos_idxs or v["tail"] not in self.joint_pos_idxs:
                print ("Delete bone", bone)
                skelData["bones"].pop (bone)

        self.planes = skelData.get("planes", dict())

The print statements are just for debugging. We have to do that for the weights also, it is done in shared/ where I will need only a bigger buffer for the targets:

Code: Select all
    def _build_vertex_weights_data(self, vertexWeightsDict, vertexCount=None, rootBone="root"):
        Build a consistent set of per-bone vertex weights from a dictionary loaded
        from (json) data file.
        The format of vertexWeightsDict is expected to be:
            { "bone_name": [(v_idx, v_weight), ...], ... }

        The output format is of the form:
            { "bone_name": ([v_idx, ...], [v_weight, ...]), ... }
        With weights normalized, doubles merged, and unweighted vertices
        assigned to the root bone.
        WEIGHT_THRESHOLD = 1e-4  # Threshold for including bone weight

        # what are these lines for (punkduck) :)
        first_entry = list(vertexWeightsDict.keys())[0] if len(vertexWeightsDict) > 0 else None
        if len(vertexWeightsDict) > 0 and \
           len(vertexWeightsDict[first_entry]) == 2 and \
           isinstance(vertexWeightsDict[first_entry], tuple) and \
           isinstance(vertexWeightsDict[first_entry][1], np.ndarray) and \
           isinstance(vertexWeightsDict[first_entry][2], np.ndarray):
            # Input dict is already in the expected format, presume it does not
            # need to be built again
            if vertexCount is not None:
                self._vertexCount = vertexCount
                self._vertexCount = max([vn for vg in list(vertexWeightsDict.values()) for vn in vg[0]])+1
            return vertexWeightsDict

        # to allow weights on additional vertex numbers, we need a buffer which will contain all weights from the file if file contains more weights then needed.
        vcount = max([vn for vg in list(vertexWeightsDict.values()) for vn,_ in vg])+1
        if vertexCount is not None and vertexCount > vcount:
            vcount = vertexCount

        self._vertexCount = vcount
        print ("Vcount is now: " + str(self._vertexCount))

        # Normalize weights and put them in np format
        wtot = np.zeros(vcount, np.float32)

So with these changes also the old base.obj can be used. But then only the human part of the Bento is used. The targets will also crash MH, for the ASCII version I also was able to build a solution, but for the binary one I did not try.

So we can do more than one base object. My proposal is, to keep the existing base mesh as it is. But we may do "overlays" following the vertices at the end, so the base mesh is the same but the appended parts (helpers but also details) may be individual in future. Since different individual meshes will not compatible to each other (besides the base mesh at the beginning), the targets used on the meshes but maybe the skeleton and weights should have a reference to this mesh. So that a target which was made for a wing will not deform e.g. a fish tail for a mermaid because of the same vertex number.

Just ideas ... :ugeek:

Re: New Year, new features in MakeHuman?

PostPosted: Sun Jan 06, 2019 9:40 am
by wolgade
punkduck wrote:So we can do more than one base object. My proposal is, to keep the existing base mesh as it is. But we may do "overlays" following the vertices at the end, so the base mesh is the same but the appended parts (helpers but also details) may be individual in future. Since different individual meshes will not compatible to each other (besides the base mesh at the beginning), the targets used on the meshes but maybe the skeleton and weights should have a reference to this mesh. So that a target which was made for a wing will not deform e.g. a fish tail for a mermaid because of the same vertex number.

Interesting idea, but it requires a completely different approach on how to manage content (anything below $PATH/data). On the other hand, this might be a good idea anyway. My clothes folder is a bloody mess.

Re: New Year, new features in MakeHuman?

PostPosted: Sun Jan 20, 2019 4:49 pm
by punkduck
I just forgot to add an image as a proof.

Yes the new bones of Bento also work in face and finger region in OpenSim.

Elvaerwyn made a quick BVH using Avastar, a Blender plugin which is a must for people doing characters and poses for their own Second Life or OpenSim characters, it is not for free but it is cheaper than buy all things form SL And it is for your creativity.

The main differences between BVH from Avastar in Blender and the BVH directly included are the bone rotations.

I was not able to change these rotations in Makehuman or when exported (atm) and the different rotation does also make not much sense when the character is only used in Blender.


Here is the skeleton for download:

and here the pose you need for export with mhx2

Of course you can use the skeleton for non-Sim world also. Some things are better, others not so good, ihmo ... here are some silly face poses ;) The manipulation of eyebrows is simpler, lips are more complicate, shoulders have less bones (not necessarily good), you can change ears (Easter bunny :lol: ) and there is also the bone that makes a man a man (it works on the helper-mesh but don't expect highlights)


Wing-bones and tail will need a modified helpermesh. In my system this allready works, even in "old" mh1.1. Maybe in next version ...