makehumancommunity/makehuman-plugin-for-blender

can we please change blender units to decimeter?

black-punkduck opened this issue · 8 comments

The problem is: when we load the standard mesh or a mesh exported by mhx2 or one of the predefined meshes instead of using MPFB, MPFB already has influence with MhScaleMode ... (but you cannot see it in the custom properties of the scene until you change it one time).

However I used the normal meshes provided by MakeClothes, have MPFB installed and used MakeTarget to fix the hair helper. Funny enough it only moved by 1/10 ... it took me hours to find out, that the difference between last time and this time was, that I installed MPFB again to write the Documentation howto import clothes via MPFB. But it did not work. The hasattr() function was always true for MhScaleMode. Then I changed it to decimeter and it worked.

I will add a warning in MakeTarget maybe ... (when MhScaleMode is not 1 .. that it only does work with a human supplied by MPFB) .

A change in the settings would really help in beginning tbh ... for the users especially

meanwhile I overwrite MhScaleMode when I load the mesh via importobj or import-predefinied mesh from blendfile. In this case (and if available of course) it is set to 1 ...

I dunno, feel free to change it. Maybe there is a reason to use meter ... then leave it as it is.

After the merge of MakeClothes it should work anyway also without this change. You can then close the issue and take this as an information about the two different ways to work with makeclothes. On the one side import + targets and clothes or MPFB as a loader and clothes. Both should work, I will do a documentation about using non standard meshes and pro and cons soon and will explain both methods.

Not sure if I got all your problems correctly, but maybe you could evaluate getattr('MhxHuman', False) and then getattr('MhxScale') or getattr('MhScaleFactor') ... ?

Aranuvir: it is only about MakeClothes vs. MakeTarget vs MPFB .. if mhx2 (because of your MhxHuman etc. names) is also doing problems I did not yet check, I guess it would also have the problem. But at the moment I only have changed the 2 importers in MakeClothes. mhx2 used parallel with MPFB should maybe also change the MhScaleMode ...

when I load the human via blend-file or as an .obj I set the variable to 1, if existent. It is tested with hasattr, MhScaleMode is only available when MPFB is installed.

The 3rd tool MakeTarget uses MhScaleMode (if available) to multiply the target-distances. In my opinion for one project you would either use MPFB or load character from blend-file or .obj. The other variable used in MakeTarget is MhObjectType .. but that is always set by all the applications.

Maybe I'm completely confused now, but why don't you use MhxHuman and MhHuman to determine if it's a MHX-Human or a MPFB-Human and then read the value either from MhxScale or MhScaleFactor ... ?
When using another blend- or obj-file, it'll be up to you to handle the scale factor correctly.

hmm ... yes. Makeclothes has an own importer either it loads an .obj or appends an object from a .blend. Last method is the easiest because I already provided meshes with t-pose etc. Also a shape-key version with high-heels is available. I did not do the documentation for the shapekeys yet, but that really is one of the things which really works good, when you use the same target after loading the asset in MH. I totally neglected the third way with mhx2 import (although that I wrote it is possible). MakeTarget was dependent on MPFB in the beginning and now can be used without it. It was changed to work with a scale-factor of 1, when MPFB is not available.

new docs here, see "how to load a human": (http://www.makehumancommunity.org/wiki/Documentation:ClothesV2)

we have not yet decided where to put the meshes or tables. But the form to have the meshes completely prepared (e.g. with arms/torso groups instead of left/right/mid does help a lot. It is more flexible, when the mesh would change and we can use the features blender has. The files in the folder are scanned once and you get all objects which can be used as a mesh to do the modelling. The other way is to prepare the human in Makehuman and use MPFB.

mhx2 I have to check. It would be MakeTarget that has to be changed either to work with mhx2 and/or MPFB. Tbh. I would then prefer to reuse MhScaleFactor after loading with mhx2 when MPFB is also installed. Otherwise we will never be able to explain what happens, if questions will arise :)

I would then prefer to reuse MhScaleFactor after loading with mhx2 when MPFB is also installed.

This does absolutely make NO sense, since MhxScale is set accordingly on MHX import as MhScaleFactor is set on MPFB import... That's why I recommended to first use MhxHuman and MhHuman to determine whether the import came from MHX2 or MPFB.

Here is some pseudo-code:

self.myFancyScaleFactor = 1.0
human = context.active_object # expecting the human object here

if getattr(human, 'MhxHuman', False):
 
    # if MHX2 is not installed or not a MHX2 import it'll be False, else True

    self.myFancyScaleFactor = human.MhxScale

elif getattr(human, 'MhHuman', False):

    # if MPFB is not installed or not a MPFB import it'll be False, else True

    self.myFancyScaleFactor = human.MhScaleFactor

else: 

    # it's neither/nor and we have to do a little guess work to determine the scale. Probably suitable for obj imports. Though not
    # sure if the code will work correctly.
    # let's use the bound_box property of an object to calculate its scale. Usually 1m in MakeHuman is 10 BU in Blender 
    # with a scale factor of 1.0. The smallest model I was able to create inside MakeHuman was about 0,4m and the largest about 
    # 2,5m
    
    # get the human bounding box
    bbox = human.bound_box

    # convert it to a numpy array
    import numpy as np
    bb_array = np.array(bbox)
    
    # get the lowest and highest Z-value of the bounding box to determine the object size along the Z axis (assuming a common
    # Z-up modeling...)
    size = abs(np.amin(bb_array[:,2])) + abs(np.amax(bb_array[:,2]))
    
   if size < 3:  #BU. This was probably a meter scale import and the object was multiplied by 0.1
       self.myFancyScaleFactor = 0.1
   elif (size > 3) and (size < 30): #BU. This was probably a decimeter scale import and the object was multiplied by 1
        self.myFancyScaleFactor = 1
   else: This was probably a centimeter scale import and the object was multiplied by 10
        self.myFancyScaleFactor = 10

self.myTargetMultiplicationFactor = 1 / self.myFancyScaleFactor

# For those who don't like numpy there is probably a solution with Python lists ...

well, since the scale is attribute of the object and not of the scene/collection it could have been loaded with only one tool .. for me it would be okay, if we only have one scale-attribute.

The version Joel did was designed to work with makeclothes and maketarget. So the discussion would be not an issue here, it is an issue of maketarget then. I can change maketarget in that way.

Your solution (even without the evaluation of the size, when you then simply assume 1) would work. Whereas the whole task is not totally flexible because we have certain limits. E.g. Loading an existing target to a character of half the size which would be considered as factor "1" would result in factor 0.5 for the target. So atm 0.1, 1, 10 will work correctly.

Yes I can only try that the tools work together. I will take a look at maketarget again.

Maybe somewhen in the future only the way will be different either socket or file and the functionality could be the sum of both blender importers we use today. But I should not dream and divert now. ;)

Ok, I did not realize that attributes set by a plug-in will not be available if the plug-in is not available, even if the model was imported by that plug-in before. I think the easiest way to address this problem is to set the MhScale property accordingly during import via MHX2.