http://www.makehumancommunity.org/forum/viewtopic.php?f=15&t=13398&start=30
to implement a plugin. I want to take a list of 20 measurements and apply them to the current model. First, I wrote a namespace for 1_mhapi, _avatar.py, which pulls partly from 0_modeling_a_measurement.py:
_avatar.py
https://gist.github.com/lychrel/954e3fa0c279f1e08104519b02055fed
- Code: Select all
#!/usr/bin/python
from namespace import NameSpace
import mh
import humanmodifier
import material
import gui
import gui3d
import log
import os
import algos3d
import events3d
from cStringIO import StringIO
from core import G
from codecs import open
import math
import numpy as np
import guicommon
import module3d
import getpath
import guimodifier
import language
class Avatar(NameSpace):
"""this namespace wraps the model_all avatar generation function"""
def __init__(self,api):
self.api = api
NameSpace.__init__(self)
self.human = api.internals.getHuman()
self.trace()
self.ruler = Ruler()
@property
def measure(mod_name):
return modifiers[mod_name].fullName
def getMeasure(self, measure):
human = G.app.selectedHuman
measure = self.ruler.getMeasure(human, measure)
return measure
def displayToData(modifier, modifier_name, measurement):
# make measurement jive with ruler
mod_name_ruler = 'measure/' + modifier_name + '-decr|incr' # this part is silly
modValue = 0.0 # start all values at 0.0
goal = float(value) # standalone
measure = getMeasure(mod_name_ruler)
minValue = -1.0
maxValue = 1.0
if math.fabs(measure - goal) < 0.01:
return modValue # modifier val (start at 0.0)
else:
tries = 10
while tries:
if math.fabs(measure - goal) < 0.01:
break;
if goal < measure:
maxValue = modValue
if value == minValue:
break
modValue = minValue + (modValue - minValue) / 2.0
modifier.updateValue(modValue, 0)
measure = getMeasure(mod_name_ruler) # new measurement method
else:
minValue = modValue
if value == maxValue:
break
modValue = modValue + (maxValue - modValue) / 2.0
modifier.updateValue(modValue, 0)
measure = getMeasure(mod_name_ruler) # new measurement method
tries -= 1
return modValue
def model_all(self, measurements):
modifier_names = ['measure-neck-circ',
'measure-neck-height',
'measure-upperarm-circ',
'measure-upperarm-length',
'measure-lowerarm-length',
'measure-wrist-circ',
'measure-frontchest-dist',
'measure-bust-circ',
'measure-underbust-circ',
'measure-waist-circ',
'measure-napetowaist-dist',
'measure-waisttohip-dist',
'measure-shoulder-dist',
'measure-hips-circ',
'measure-upperleg-height',
'measure-thigh-circ',
'measure-lowerleg-height',
'measure-calf-circ',
'measure-knee-circ',
'measure-ankle-circ']
# create/init all modifiers! (is this the right way to do it?)
modifiers = humanmodifier.loadModifiers(getpath.getSysDataPath('modifiers/measurement_modifiers.json'), app.selectedHuman)
# apply all other measurements
for mod, name, meas in zip(modifiers, modifier_names, measurements):
displayToData(mod, name, meas)
"""
Ruler class for measuring mesh
"""
class Ruler:
"""
This class contains ...
"""
def __init__(self):
# these are tables of vertex indices for each body measurement of interest
# TODO define in data file?
self.Measures = {}
self.Measures['measure/measure-neck-circ-decr|incr'] = [7514,10358,7631,7496,7488,7489,7474,7475,7531,7537,7543,7549,7555,7561,7743,7722,856,1030,1051,850,844,838,832,826,820,756,755,770,769,777,929,3690,804,800,808,801,799,803,7513,7515,7521,7514]
self.Measures['measure/measure-neck-height-decr|incr'] = [853,854,855,856,857,858,1496,1491]
self.Measures['measure/measure-upperarm-circ-decr|incr']=[8383,8393,8392,8391,8390,8394,8395,8399,10455,10516,8396,8397,8398,8388,8387,8386,10431,8385,8384,8389]
self.Measures['measure/measure-upperarm-length-decr|incr'] = [8274,10037]
self.Measures['measure/measure-lowerarm-length-decr|incr'] = [10040,10548]
self.Measures['measure/measure-wrist-circ-decr|incr']=[10208,10211,10212,10216,10471,10533,10213,10214,10215,10205,10204,10203,10437,10202,10201,10206,10200,10210,10209,10208]
self.Measures['measure/measure-frontchest-dist-decr|incr']=[1437,8125]
self.Measures['measure/measure-bust-circ-decr|incr']=[8439,8455,8462,8446,8478,8494,8557,8510,8526,8542,10720,10601,10603,10602,10612,10611,10610,10613,10604,10605,10606,3942,3941,3940,3950,3947,3948,3949,3938,3939,3937,4065,1870,1854,1838,1885,1822,1806,1774,1790,1783,1767,1799,8471]
self.Measures['measure/measure-underbust-circ-decr|incr'] = [10750,10744,10724,10725,10748,10722,10640,10642,10641,10651,10650,10649,10652,10643,10644,10645,10646,10647,10648,3988,3987,3986,3985,3984,3983,3982,3992,3989,3990,3991,3980,3981,3979,4067,4098,4073,4072,4094,4100,4082,4088, 4088]
self.Measures['measure/measure-waist-circ-decr|incr'] = [4121,10760,10757,10777,10776,10779,10780,10778,10781,10771,10773,10772,10775,10774,10814,10834,10816,10817,10818,10819,10820,10821,4181,4180,4179,4178,4177,4176,4175,4196,4173,4131,4132,4129,4130,4128,4138,4135,4137,4136,4133,4134,4108,4113,4118,4121]
self.Measures['measure/measure-napetowaist-dist-decr|incr']=[1491,4181]
self.Measures['measure/measure-waisttohip-dist-decr|incr']=[4121,4341]
self.Measures['measure/measure-shoulder-dist-decr|incr'] = [7478,8274]
self.Measures['measure/measure-hips-circ-decr|incr'] = [4341,10968,10969,10971,10970,10967,10928,10927,10925,10926,10923,10924,10868,10875,10861,10862,4228,4227,4226,4242,4234,4294,4293,4296,4295,4297,4298,4342,4345,4346,4344,4343,4361,4341]
self.Measures['measure/measure-upperleg-height-decr|incr'] = [10970,11230]
self.Measures['measure/measure-thigh-circ-decr|incr'] = [11071,11080,11081,11086,11076,11077,11074,11075,11072,11073,11069,11070,11087,11085,11084,12994,11083,11082,11079,11071]
self.Measures['measure/measure-lowerleg-height-decr|incr'] = [11225,12820]
self.Measures['measure/measure-calf-circ-decr|incr'] = [11339,11336,11353,11351,11350,13008,11349,11348,11345,11337,11344,11346,11347,11352,11342,11343,11340,11341,11338,11339]
self.Measures['measure/measure-ankle-circ-decr|incr'] = [11460,11464,11458,11459,11419,11418,12958,12965,12960,12963,12961,12962,12964,12927,13028,12957,11463,11461,11457,11460]
self.Measures['measure/measure-knee-circ-decr|incr'] = [11223,11230,11232,11233,11238,11228,11229,11226,11227,11224,11225,11221,11222,11239,11237,11236,13002,11235,11234,11223]
self._validate()
def _validate(self):
"""
Verify currectness of ruler specification
"""
names = []
for n,v in self.Measures.items():
if len(v) % 2 != 0:
names.append(n)
if len(names) > 0:
raise RuntimeError("One or more measurement rulers contain an uneven number of vertex indices. It's required that they are pairs indicating the begin and end point of every line to draw. Rulers with uneven index count: %s" % ", ".join(names))
def getMeasure(self, human, measurementname):
measure = 0
vindex1 = self.Measures[measurementname][0]
for vindex2 in self.Measures[measurementname]:
vec = human.meshData.coord[vindex1] - human.meshData.coord[vindex2]
measure += math.sqrt(vec.dot(vec))
vindex1 = vindex2
return 10.0 * measure # removed non-metric mode
and then I tried to write a plugin meant to test it:
10_modeling_all_measurements.py
https://gist.github.com/lychrel/2d657db92ad7a1b846e3bddbca0ac23a
- Code: Select all
#!/usr/bin/python2.7
# -*- coding: utf-8 -*-
import math
import numpy as np
import guicommon
import module3d
import humanmodifier
import gui
import log
import getpath
from core import G
import guimodifier
import language
class Test(object):
def __init__(self, __measurements):
self.measurements = __measurements
self.mhm = G.app.mhapi.avatar.model_all(self.measurements)
def load(app):
"""
Plugin load function, needed by design.
"""
category = app.getCategory('Modelling')
test = Test([10]*20)
# TODO ??
#taskview.showGroup('neck')
def unload(app):
pass
I moved _avatar into the 1_mhapi folder with the other namespaces and the plugin into MakeHuman/resources/plugins (I'm on OSX), but I couldn't get it to load. When running Makehuman from the executable in the application's MacOS directory, I get the following output:
- Code: Select all
/Applications/MakeHuman/MakeHuman.app/Contents/MacOS/MakeHuman ; exit;
MakeHuman Copyright (C) 2001-2017 http://www.makehuman.org
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions. For details use the option --license
Cannot open file '/Applications/MakeHuman/MakeHuman.app/Contents/Resources/icons/makehuman_bg.svg', because: No such file or directory
Cannot open file '/Applications/MakeHuman/MakeHuman.app/Contents/Resources/icons/makehuman_bg.svg', because: No such file or directory
QPixmap::scaled: Pixmap is a null pixmap
QPixmap::scaled: Pixmap is a null pixmap
2017-06-06 10:21:20.882 MakeHuman[63993:960753] IMKClient Stall detected, *please Report* your user scenario attaching a spindump (or sysdiagnose) that captures the problem - (imkxpc_attributesForCharacterIndex:reply:) block performed very slowly (2.00 secs).
TRACE 1_mhapi.namespace.__init__():19
TRACE 1_mhapi.api.__init__():10
TRACE 1_mhapi.namespace.__init__():19
TRACE 1_mhapi._assets.__init__():18
TRACE 1_mhapi.namespace.__init__():19
TRACE 1_mhapi._internals.__init__():18
TRACE 1_mhapi.namespace.__init__():19
TRACE 1_mhapi._mesh.__init__():11
TRACE 1_mhapi.namespace.__init__():19
TRACE 1_mhapi._locations.__init__():15
TRACE 1_mhapi.namespace.__init__():19
TRACE 1_mhapi._version.__init__():12
abort: no repository found in '/Applications/MakeHuman/MakeHuman.app/Contents' (.hg not found)!
TRACE 1_mhapi.namespace.__init__():19
TRACE 1_mhapi._viewport.__init__():11
TRACE 1_mhapi.namespace.__init__():19
TRACE 1_mhapi._internals.getHuman():22
TRACE 1_mhapi._modifiers.__init__():25
TRACE 1_mhapi.namespace.__init__():19
TRACE 1_mhapi._ui.__init__():67
libpng warning: iCCP: known incorrect sRGB profile
TRACE 1_mhapi._locations.getSystemDataPath():36
TRACE 1_mhapi._locations.getUserDataPath():49
TRACE 1_mhapi._locations.getUserHomePath():41
TRACE 1_mhapi._locations.getSystemDataPath():36
TRACE 1_mhapi._locations.getUserDataPath():49
which doesn't even mention any errors in _avatar.py or my plugin.
Am I skipping some step or doing something obviously incorrect? I'm not sure what to make of those error messages, as they don't seem to pertain to the plugin I wrote. I'm relatively new to MakeHuman, and I'd greatly appreciate any help I can get.