Makehuman a Manual

28
MakeHuman: A manual Marc Flerackers March 16, 2011

Transcript of Makehuman a Manual

Page 1: Makehuman a Manual

MakeHuman: A manual

Marc Flerackers

March 16, 2011

Page 2: Makehuman a Manual

Contents

Preface iv

I General usage 1

1 The view 21.1 Mouse movement . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.2 Keyboard movement . . . . . . . . . . . . . . . . . . . . . . . . . . 21.3 View options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

1.3.1 Background . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.3.2 Anaglyphs . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.3.3 Wireframe . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.3.4 Smooth . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

1.4 Cameras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.5 Undo, redo and reset . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2 Modeling 42.1 Macro modeling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42.2 Detail modeling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.2.1 Face . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.2.2 Breasts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.2.3 Stomach, pelvis and buttocks . . . . . . . . . . . . . . . . . . 52.2.4 Genitals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.3 Micro modeling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

3 Files 63.1 Save and Load . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63.2 Export . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

3.2.1 Wavefront (obj) . . . . . . . . . . . . . . . . . . . . . . . . . 73.2.1.1 Eyebrows . . . . . . . . . . . . . . . . . . . . . . 73.2.1.2 Diamonds . . . . . . . . . . . . . . . . . . . . . . 73.2.1.3 Skeleton . . . . . . . . . . . . . . . . . . . . . . . 73.2.1.4 Groups . . . . . . . . . . . . . . . . . . . . . . . . 73.2.1.5 Subdivide . . . . . . . . . . . . . . . . . . . . . . 7

i

Page 3: Makehuman a Manual

CONTENTS ii

3.2.1.6 Hair . . . . . . . . . . . . . . . . . . . . . . . . . 73.2.2 Blender exchange (mhx) . . . . . . . . . . . . . . . . . . . . 7

3.2.2.1 Version . . . . . . . . . . . . . . . . . . . . . . . . 83.2.2.2 Expressions . . . . . . . . . . . . . . . . . . . . . 83.2.2.3 Rig . . . . . . . . . . . . . . . . . . . . . . . . . . 8

3.2.3 Collada (dae) . . . . . . . . . . . . . . . . . . . . . . . . . . 83.2.4 Quake (md5) . . . . . . . . . . . . . . . . . . . . . . . . . . 83.2.5 Stereolithography (stl) . . . . . . . . . . . . . . . . . . . . . 8

3.2.5.1 Format . . . . . . . . . . . . . . . . . . . . . . . . 83.2.5.2 Subdivide . . . . . . . . . . . . . . . . . . . . . . 8

3.3 Ethnics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

4 Posing 94.1 Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94.2 Poses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

5 Rendering 105.1 General . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105.2 Aqsis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

5.2.1 Shading rate . . . . . . . . . . . . . . . . . . . . . . . . . . 115.2.2 Samples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115.2.3 Skin oil . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

5.3 Povray . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115.3.1 Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115.3.2 Action . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

5.4 LuxRender . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115.5 Settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

5.5.1 Dimensions . . . . . . . . . . . . . . . . . . . . . . . . . . . 115.5.2 Hair . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

5.5.2.1 Clump radius . . . . . . . . . . . . . . . . . . . . 115.5.2.2 Clump children . . . . . . . . . . . . . . . . . . . 115.5.2.3 Multistrand children . . . . . . . . . . . . . . . . . 115.5.2.4 Randomness . . . . . . . . . . . . . . . . . . . . . 11

6 Advanced Modeling 126.1 Measure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126.2 Asymmetry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126.3 Randomize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

7 Settings 137.1 Shader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137.2 Slider behavior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137.3 Mouse behavior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147.4 Units . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147.5 Shortcuts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

Page 4: Makehuman a Manual

CONTENTS iii

II Development 15

8 Writing plugins 168.1 Plugins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168.2 GUI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168.3 Morph targets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178.4 Undo-redo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188.5 Meshes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198.6 The camera . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198.7 GUI controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208.8 Layout guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218.9 Asynchronous calls and animation . . . . . . . . . . . . . . . . . . . 22

Page 5: Makehuman a Manual

Preface

This manual, like the MakeHuman software, is under constant construction and willchange with the software. The latest edition can always be found on the makehumanwebsite. MakeHuman is a 3d modeling tool which is build for one single purpose:creating a professional 3d human model. The base mesh has gone through many iter-ations to perfect the topology and all the modifications which are available to the userare morphs which are modeled by hand by skilled artists. While the software is buildwith usability and simplicity in mind, there will always be questions, that’s what Part Iof this manual is for. It is modeled on the application and follows the menu system andoptions closely. Part II focuses on developing with MakeHuman, to create your ownplugin and add functionality to the main application.

This manual is provided under an Attribution-NonCommercial-NoDerivs 3.0 Un-ported (CC BY-NC-ND 3.0) license.

iv

Page 6: Makehuman a Manual

Part I

General usage

1

Page 7: Makehuman a Manual

Chapter 1

The view

1.1 Mouse movementThe model can be freely moved and rotated using the mouse. Keep the left buttonpressed to rotate the model. Keep the right button pressed to translate the model. Zoom-ing can be done by using the scroll wheel, or by keeping both the left and right buttonpressed. If the manipulation speed is too slow, hold shift to speed up movement.

1.2 Keyboard movementThe following keyboard navigation is the standard navigation. It can be customized insettings, shortcuts. Use the arrow keys to move the model around. Use the 2, 4, 6 and8 keys to rotate the model. Use the + and - keys to zoom. There are 3 standard viewswhich have shortcut keys. For a side view press 7, for a front view press 1 and for a topview press 3. The . key resets both position and zoom.

1.3 View optionsThere are 4 view options which might help during modeling: background, anaglyphs,wireframe and smooth.

1.3.1 BackgroundThe background mode shows an image file on top of the model. This is useful whenthe model should resemble an existing sketch, photograph or render. The first time it isactivated, it shows a list of files from the ~/makehuman/backgrounds folder to choosefrom. Afterward the background button toggles the background on and off. To chooseanother image go to library, background.

2

Page 8: Makehuman a Manual

CHAPTER 1. THE VIEW 3

1.3.2 AnaglyphsAnaglyphs mode renders the view from two viewpoints in red and cyan. When view-ing this using red-cyan 3d glasses you can see the model in real 3d. There are twoanaglyphs modes which use a slightly different method to render both views, so ittakes two presses of the button to turn it back off.

1.3.3 WireframeWireframe mode is good to see the topology and how vertices and faces are changedby certain modifications.

1.3.4 SmoothSmooth view might be too slow to work with on some systems. It subdivides themesh with Catmull-Clark subdivision and keeps this subdivided mesh updated whenmodifying the model.

1.4 CamerasThere are two camera viewpoints between which can be quickly toggled, global cameraand face camera.

1.5 Undo, redo and resetThese are not view options, but they appear throughout the application. Undo andredo are quite straightforward, they undo the last modification or redo the last undonemodification. Reset removes all modifications, be careful as it is impossible to undothis action.

Page 9: Makehuman a Manual

Chapter 2

Modeling

2.1 Macro modelingMacro modeling is the roughest step in modeling a human, but it also has the biggestimpact on the resulting mesh. Macro modeling has 5 sliders. The first 4 sliders modifythe 4 main dimensions of the human: gender, age, muscle and weight. The last slider,height, modifies the proportions. The functionality of the gender and age sliders arestraightforward. Gender goes from female to male, initially it is at 50% of each, whichgives a neutral gender. Age goes from 12 years old to 70 years old, initially it is at 25years old. The muscle and weight sliders influence each other. Only increasing muscleyou doesn’t create a bodybuilder, that also requires weight. Similarly only increasingweight doesn’t create a really fat model, that also requires less muscle. Finally assaid before the height slider doesn’t just scale the model vertically, but it changes the

4

Page 10: Makehuman a Manual

CHAPTER 2. MODELING 5

proportions too. It goes from dwarf to giant.

2.2 Detail modelingDetail modeling lets you move and scale large body parts. The moving and scalingis not just geometrical, but preserves body shapes. Manipulation is done on the meshitself. Click and drag to transform the bodypart which lights up. Besides these trans-formations, detail modeling also lets you change some other details of the model.

2.2.1 FaceMany facial features like eyes, nose, ears, mouth, jaw, head shape can be modifiedusing the sliders in the corresponding categories. Face age varies from young to oldand face angle from slanted up to slated down.

2.2.2 BreastsBreasts have two sliders, size and firmness. Since this is only sufficient for a subset ofshapes, more sliders are planned.

2.2.3 Stomach, pelvis and buttocksThe stomach goes from bulging to firm. For female models this can be used to simulatemid to late pregnancy. The pelvis goes from wide to thin and the buttocks from roundto firm.

2.2.4 GenitalsThe genital slider goes from female to male genitals, initially it is in the center, whichmeans no genitals.

2.3 Micro modelingMicro modeling, like detail modeling lets you move and scale body parts, but on amuch finer level.

Page 11: Makehuman a Manual

Chapter 3

Files

3.1 Save and LoadSaving and loading happens in a custom and optimized format for MakeHuman withthe mhm extension. It is advised to always save in this format also when you exportmodels, since you can’t load any other format back into MakeHuman. This is importantwhen you want to make changes at a later stage of production.

6

Page 12: Makehuman a Manual

CHAPTER 3. FILES 7

3.2 Export

3.2.1 Wavefront (obj)Wavefront obj is a good format when you need a simple mesh for an external renderer.It comes with an mtl file defining the material.

3.2.1.1 Eyebrows

For some uses, like raytracing, the eyebrow geometry causes problems. If this is thecase, uncheck it to avoid it from being exported.

3.2.1.2 Diamonds

The diamond geometry is used to keep track of the skeleton. However in most casesthis is not needed. In case the diamond geometry is desired, check it to export it.

3.2.1.3 Skeleton

This option exports the skeleton in Biovision hierarchical data (bvh) format which isgenerally used for motion capture. Note however that the model is not rigged to thisskeleton.

3.2.1.4 Groups

Whether groups are useful depends on the software used. Many importers also give theoption to import the groups or not. Groups can be used to select specific body parts formodification or deletion. If groups are not desired, uncheck it.

3.2.1.5 Subdivide

If a high poly mesh is needed, and the modeler or renderer used does not have a goodsubdivision algorithm, you can check the subdivide option to export a mesh with 4times the amount of faces, generated with Catmull-Clark subdivision.

3.2.1.6 Hair

If hair is present, it can be exported as a polygon mesh or as curves. Again it dependson the software which is going to import the file whether mesh or curves is the bestoption.

3.2.2 Blender exchange (mhx)The Blender exchange format is a custom format designed to bring a rigged model intoBlender. It comes with a skeleton, forward and inverse kinematics with limits, rendermaterials, lip-sync and more.

Page 13: Makehuman a Manual

CHAPTER 3. FILES 8

3.2.2.1 Version

Currently it is still possible to export for Blender 2.4, however this may change onceBlender 2.5 is stable.

3.2.2.2 Expressions

If checked, all expressions available within MakeHuman are exported to the mhx, thismakes the export considerably bigger in size.

3.2.2.3 Rig

Two rigs are available, mhx rig or game rig. For posing and animating the mhx rig ispreferred.

3.2.3 Collada (dae)

3.2.4 Quake (md5)The md5 exporter is not yet fully functional, the skin is not correctly attached to theskeleton.

3.2.5 Stereolithography (stl)Stereolithography is a format used for 3d printing.

3.2.5.1 Format

The binary format is a lot more compact than the ASCII format. However the latter isprovided for compatibility reasons.

3.2.5.2 Subdivide

If a high poly mesh is needed, and the exernal modeler or renderer does not have agood subdivision algorithm, you can check the subdivide option to export a mesh with4 times the amount of faces, generated with Catmull-Clark subdivision.

3.3 EthnicsEthnics are models which try to closely resemble people from a specific region in theworld. They are model files with a special finishing morph for features which cannotbe created with the tools in MakeHuman. To load an ethnic, the main ethnic is selected,then one of the sub ethnics of that ethnic. The gender and age are also chosen beforeloading. While the these can, theoretically, be modified afterward, it is advised tochoose the gender and age as close as to what you need.

Page 14: Makehuman a Manual

Chapter 4

Posing

4.1 ExpressionsTo make an expression on the model’s face, choose the expression category on theright, then drag the slider from the desired expression on the left as much to the rightas needed.

4.2 Poses

9

Page 15: Makehuman a Manual

Chapter 5

Rendering

5.1 GeneralFor rendering, MakeHuman uses one of the installed external renderers. You only needto install the renderer of your choice.

5.2 AqsisAqsis, a renderman compliant renderer, can be downloaded from http://www.aqsis.org/.

10

Page 16: Makehuman a Manual

CHAPTER 5. RENDERING 11

5.2.1 Shading rate

5.2.2 Samples

5.2.3 Skin oil

5.3 PovrayPovray, or the Persistence of Vision Raytracer, can be downloaded from http://www.povray.org/.

5.3.1 FormatThere is both support for the older array format and the newer mesh2 format.

5.3.2 ActionDetermines whether only the pov files are written or whether Povray is also launchedto render the file.

5.4 LuxRenderLuxRender, a physically based and unbiased rendering engine, can be downloadedfrom http://www.luxrender.net.

5.5 SettingsSome of the rendering settings are valid for all renderers. These include the dimensionsof the rendered image and the hair settings.

5.5.1 DimensionsThe width and height of the rendered image

5.5.2 Hair5.5.2.1 Clump radius

5.5.2.2 Clump children

5.5.2.3 Multistrand children

5.5.2.4 Randomness

Page 17: Makehuman a Manual

Chapter 6

Advanced Modeling

6.1 MeasureMeasure has sliders which modify the length and/or circumference of specific bodyparts and shows the length and/or circumference of many body parts in centimeters.You can change the units to inches in Settings. Note that modifying one parametermight have impact on other measurements too.

6.2 AsymmetrySometimes a perfect symmetric model is not what is desired. Asymmetry can makesome features of the model’s face or body asymmetric.

6.3 RandomizeWhen a lot of different models are needed, or some inspiration is needed, it is some-times better to let the pseudorandom generator decide how the macro modeling is done.An existing model can also be modified by randomization of its macro features.

12

Page 18: Makehuman a Manual

Chapter 7

Settings

7.1 ShaderMakeHuman can make use of GLSL shaders to give a better preview of how the modelwill look when rendered.

7.2 Slider behaviorMakeHuman does not require a very fast computer, though some operations might betoo heavy for some systems. Turning off normal recalculation or turning off real-timeupdates completely might help in making MakeHuman usable on low-end systems.

13

Page 19: Makehuman a Manual

CHAPTER 7. SETTINGS 14

7.3 Mouse behaviorThis allows you to fine-tune the speed of moving the model using the mouse. Both thenormal speed and the speed when holding down shift can be modified.

7.4 UnitsMetric or imperial units can be chosen. Note that imperial units will use inches through-out the program, also for longer lengths.

7.5 ShortcutsAll shortcuts can be customized.

Page 20: Makehuman a Manual

Part II

Development

15

Page 21: Makehuman a Manual

Chapter 8

Writing plugins

8.1 PluginsMakehuman has a simple plugin framework which makes it easy to add and removefeatures. At startup, MakeHuman now looks for .py files in the plugins folder which arenot starting with an underscore (which makes it easier to disable unwanted plugins).It loads them one by one and calls the load entry point passing a reference to theapplication. The plugin can use this reference to add the necessary GUI widgets orcode to the application.

The rules for plugins are very simple:

• A plugin is a .py file in the plugins folder with a load entry point.

• A plugin only imports core files.

The reason a plugin cannot import other plugins is that it would make it difficult toknow which files belong to which plugin. We still need to define a convention forshared files beyond the core MakeHuman files. To get started look at example.py orany of the other plugins to see how you can create your own feature in MakeHuman.

8.2 GUIThe GUI in MakeHuman is still far from finished. Since the first alpha there have beenmany changes already and many other will come. This is because when features areadded or modified, we can run out of space, or start to see things differently. Some-times we experiment to see how a modifier can be manipulated in a different way. Forexample in the details and microdetails we chose to have tools manipulating the modeldirectly instead of using sliders. Another idea for the macrodetails was a multidimen-sional slider, like a radar chart which would replace all five sliders. It is impossible topour the GUI into into its final form while we are still adding functionality and gettingnew ideas. However don’t let the lack of guidelines stop you from adding a GUI toyour own plugins. The current GUI API is very usable, and gets more mature every

16

Page 22: Makehuman a Manual

CHAPTER 8. WRITING PLUGINS 17

day. The layout at the moment is a two level tab control. The tabs at the top repre-sent categories, like modeling, files, rendering. The ones at the bottom are the tasksin the current category and refine the more broad category in macrodetail, detail andmicrodetail modeling, or saving, loading and exporting. So when creating your plugin,the first thought should be "In which category does it belong?". From experience weknow that it can be a though question to answer. Sometimes the only answer is addinga new category. This is what we initially did for measurement for example.

1 def load(app):2 category = gui3d.Category(app, "Measurement")

Next you probably want your own task to implement your feature. While it’s pos-sible to attach functionality to an instance of gui3d.Task, it’s often easier to derive yourown class. When you create an instance of your class, you pass the parent of your task,which can either be an existing category

1 def load(app):2 taskview = HairPropertiesTaskView(app.categories["Modelling"])

or the new one which you added.1 def load(app):2 category = gui3d.Category(app, "Measurement")3 taskview = MeasurementTaskView(category)

In your derived task you will then add the necessary controls to let the user interact.A good place to see how to use the different controls is the example plugin. You willsee that even if you don’t add any controls, the model is already visible. This is becausethe model is attached to the root of the GUI tree. In the onShow event of your task youmight want to reset the camera position, like we do in the save task, or hide the model,like we do in the load task. Just don’t forget to reset the state when your task getshidden in onHide.

8.3 Morph targetsWhatever your plugin does, there’s a big chance that it will modify the model. Asmany of you probably know, MakeHuman doesn’t work mathematically or procedu-ral, but artistically. This means that you don’t just drag vertices when moving a partof the body, but you actually apply a morph made by an artist. There are differentkind of morphs targets which are applied in different ways. Macro targets, whichare the most complex internally, are ironically the easiest to use: human.setGender,human.setAge, human.setWeight and human.setMuscle can be used to change the cor-responding macro features. Height was originally not there, so you had to make themodifier yourself. We will look at that in a moment. Detail and micro detail targetsboth come in pairs. For example one target to move a body part to the left, and anothertarget to move the same body part to the right. Therefore you should never apply bothtargets at the same time. This means that when you apply one, and later you want toapply the other, you need to remove the first. While you could use human.setDetail tothis, it is easier to use the Modifier class which does all of the needed logic behind thethe method modifier.setValue, it has an accompanying modifier.getValue which has thereverse logic. To use it, you create a modifier passing the two opposite targets:

Page 23: Makehuman a Manual

CHAPTER 8. WRITING PLUGINS 18

1 modifier = humanmodifier.Modifier(2 "data/targets/macrodetails/universal-stature-dwarf.target",3 "data/targets/macrodetails/universal-stature-giant.target")4 modifier.setValue(human, 0.0)

A value between -1.0 and 0.0 will use the dwarf target, while a value between 0.0and 1.0 will use the giant target. Using 0.0 will remove both targets. While using amodifier also applies the target, to keep changes interactive other targets are not reap-plied and normals are not recalculated. Once you have made the necessary changes,you commit them using human.applyAllTargets. Which does exactly what it says. Itapplies all the targets one by one and additionally recalculates the normals. Reapplyingall targets minimizes the size of mathematical error in the final model.

8.4 Undo-redoOne of the first features written was undo-redo. Having this from the start saves usa lot of time later as we add this functionality to each kind of model modificationimmediately. It is important that every modification is undo-able, since just one undo-able modification would leave the user without the possibility to undo anything. So it’scrucial that if you write a plugin which modifies the model, you also make undo work.The Application class has several methods to work with actions. An action is a classwith two methods, do and undo. If the action itself does the modification you can useapp.do to add it to the undo stack. If you did the modification yourself already duringuser interaction, you can add the action using app.did. The application won’t call thedo method of the action in that case. If you want to make your own undo-redo buttons,you can use app.undo and app.redo. To illustrate, here is the action we use to changethe hair color:

1 class Action:2 def __init__(self, human, before, after, postAction = None):3 self.name = "Change hair color"4 self.human = human5 self.before = before6 self.after = after7 self.postAction = postAction89 def do(self):

10 self.human.hairColor = self.after11 if self.postAction:12 self.postAction()13 return True1415 def undo(self):16 self.human.hairColor = self.before17 if self.postAction:18 self.postAction()19 return True

The postAction is a handy way to specify a method to keep your GUI in sync withthe changes. In this case we update the color control to show the correct color whenthe user chooses to undo or redo the hair color change.

Page 24: Makehuman a Manual

CHAPTER 8. WRITING PLUGINS 19

8.5 MeshesWhen writing exporters, subdivision or polygon reducing algorithms it can be usefulto know how the mesh is stored in Python (the C side has a different compact butless convenient representation). An Object3D has three important lists: object.verts,object.faces and object.faceGroups. The first two lists contain instances of Vertex andFace. The facesGroups contain FaceGroup objects. A FaceGroup specifies the nameof the group and the faces that make up the group. A Face references 3 vertices inface.verts. A Vert or vertex holds its coordinates in vert.co and normal in vert.no. If weput all this together, we can write a simple Wavefront object exporter now:

1 f = open(filename, ’w’)23 for v in obj.verts:4 f.write("v %f %f %f\n" %tuple(v.co))56 for uv in obj.uvValues:7 f.write("vt %f %f\n" %tuple(uv))89 for v in obj.verts:

10 f.write("vn %f %f %f\n" %tuple(v.no))1112 for g in obj.faceGroups:13 f.write("g %s\n" %(g.name))14 for fc in g.faces:15 f.write("f")16 for v in fc.verts:17 f.write(" %i/%i/%i " %(v.idx + 1, fc.uv[i] + 1, v.idx + 1))1819 f.close()

As you can see, we take the uv values from obj.uvValues. The uv values are ref-erenced in two places, obj.uvValues holds all the uv values of each vertex by index.Face.uv is a list with the uv values of each vertex of the face. The reason is that whilenormals are per vertex, uv values are per face-vertex, because a vertex can have a dif-ferent uv depending on which face is drawn.

8.6 The cameraWhen your plugin allows editing a certain part of the model, it’s often good to focusthe camera on that region. There are two camera’s used in MakeHuman, accessiblefrom the application class as modelCamera and guiCamera. The camera which we areinterested in is the modelCamera. The application class itself is accessible in everyGUI control as app. A camera has the following properties:

• fovAngle: The field of view angle.

• nearPlane: The near clipping plane.

• farPlane: The far clipping plane.

• projection: The projection type, 0 for orthogonal, 1 for perspective.

• stereoMode: The stereo mode, 0 for no stereo, 1 for toe-in, 2 for off-axis.

Page 25: Makehuman a Manual

CHAPTER 8. WRITING PLUGINS 20

• eyeSeparation: The eye separation.

• eyeX, eyeY, eyeZ: The position of the eye.

• focusX, focusY, focusZ: The position of the focus.

• upX, upY, upZ: The up vector.

The properties you’ll use to position the camera are the eye and focus position. TheApplication class has a few methods for camera presets, like setFaceCamera to focuson the face. We’ll look at what this method does to better understand how to positionthe camera:

First we get the currently selected human (yes, we do anticipate having more thanone human in the scene).

1 human = self.scene3d.selectedHuman

Next we get the vertices which belong to the head by facegroup names.2 headNames = [group.name for group in human.meshData.facesGroups if ("head" in

group.name or "jaw" in group.name)]3 self.headVertices, self.headFaces = human.meshData.getVerticesAndFacesForGroups(

headNames)

We calculate the center of these vertices as this will become our focus point atwhich we will look at.

4 center = centroid([v.co for v in self.headVertices])

Now we are ready to set the eye and focus positions. We set the focus to the centerposition, and the eye a bit to the back.

5 self.modelCamera.eyeX = center[0]6 self.modelCamera.eyeY = center[1]7 self.modelCamera.eyeZ = 108 self.modelCamera.focusX = center[0]9 self.modelCamera.focusY = center[1]

10 self.modelCamera.focusZ = 0

Finally we reset the human’s position and rotation so that our calculations are assimple as the ones above.

11 human.setPosition([0.0, 0.0, 0.0])12 human.setRotation([0.0, 0.0, 0.0])

If we would allow the human to be translated and rotated, we would need to takethis transformation into account, as above we calculated the center of the untrans-formed mesh.

8.7 GUI controlsWhether you are writing an exporter, modeling feature or mesh algorithm, sooner orlater you will need to add some controls in order to interact with the user. MakeHumanhas a lot of the usual controls which you find in in other GUI toolkits:

• Button: A regular push button.

Page 26: Makehuman a Manual

CHAPTER 8. WRITING PLUGINS 21

• ToggleButton: A button which has two states, selected and deselected, clickingthe button toggles between the states. Used for making an on/off choice.

• CheckBox: A togglebutton, but with a check box look.

• RadioButton: A button which is part of a group, clicking one of the buttonsselects it and deselects the others. Used for a multiple choice.

• Slider: Used to select a value from a discrete or continous range.

• TextEdit: A one line text field.

• TextView: A label.

• GroupBox: Used to group a few controls together under a title.

8.8 Layout guidelinesTo have a consistent look, it is important that all tasks use the same layout practices.

GroupBoxes on the left side have x=10. The first GroupBox starts at y=80. Con-trols start 25 pixels lower, and after the last control there are 6 extra pixels (besides the4 pixels spacing from the last control). So the total height of a GroupBox is 25+con-tent+6. Sliders start at x=10 and are 128 pixels wide, so there is no border left or right.Buttons start at x=18 and are 112 wide, so there are 8 pixels of border on each side. Be-tween controls there are 4 pixels. Sliders are 32 pixels high and Buttons are 20 pixelshigh. This means that the space to the next control for a Slider is 36, and for a Button24. So the height of a GroupBox can be calculated as 25+36*sliders+24*buttons+6.Between GroupBoxes there are 10 pixels.

Page 27: Makehuman a Manual

CHAPTER 8. WRITING PLUGINS 22

Figure 8.1: Padding in yellow, spacing in fuschia, size in green

Labels only have the first letter capitalized, unless there is an acronym that needsto be in uppercase.

8.9 Asynchronous calls and animationWhen doing lengthy operations it is important not to block the GUI from redrawing.Since everything runs in one thread, it is easy to block the event loop in your plugin.There are 4 ways to avoid this, depending on the need.

If no user interaction is needed, a progressbar can be used. A progressbar usesthe redrawNow() method of the application. This redraws the screen outside the eventloop. Instead of creating your own progressbar, it is advised to use the progress method,which uses the global progressbar. Calling progress with a value greater than zeroshows the progressbar, a value of zero hides it.

Page 28: Makehuman a Manual

CHAPTER 8. WRITING PLUGINS 23

1 inc = 1.0 / n2 value = inc3 for i in xrange(n):4 # Shows the progressbar the first time5 self.app.progress(value)6 ..7 value += inc8 # Hides the progressbar9 self.app.progress(0)

If user interaction is desired during the operation, either asynchronous calls, a timeror a thread can be used.

Asynchronous calls are used when a lengthy operation can be split in several units.It is used for example in the startup procedure as well as for the plugin loading loop.The mh.callAsync(method) queues the calling of method in the event loop, so it willbe called when the event gets processed. In case different methods need to be calledafter each other, as in the startup procedure, callAsync is used to call the next method.

1 def method1(self):2 ..3 mh.callAsync(self.method2)

In case of the plugin loading loop, it calls the same method until it is done.1 def method(self):2 ..3 if continue:4 mh.callAsync(self.method)

This is not to be used for animations, as it takes very little time between callingcallAsync and the event loop calling the method. Calling time.sleep(dt) to avoid thisshould not be done as it blocks the main thread. For animations use timers instead. Anexample of this can be found in the BvhPlayer plugin. The method mh.addTimer(interval,method) adds a timer which calls the given method every interval milliseconds. It re-turns a value to be used by removeTimer to stop the timer.

1 def play(self):2 self.timer = mh.addTimer(33, self.nextFrame)34 def pause(self):5 mh.removeTimer(self.timer)67 def nextframe(self):8 ..

If a lengthy operation includes blocking on sockets or pipes, it is advised to use apython thread. However this has been shown to be problematic on Linux. See the clockplugin example for example code on how to use threads.