MakeHuman is constructed using two main application components:
- The python interpreter that include an OpenGL 3D engine and forms the intentionally small core of the application is written in C.
- The vast majority of the functional components, including the GUI and service functions are written in Python
Retaining this very small, highly optimised and stable C core avoids
the need for pyopenGL and therefore avoids the need for Windows users
to install the full Python package and to manually install a seris of
extra packages with associated dependencies and consequent installation
issues.
Although the majority of the development effort is focused on Python
code (which is an interpreted language so doesn't require the
application to be rebuilt for each code change), the C core does result
in developers having to install the C development environment in order
that they can perform a complete build.
The application is written in a
layered fashion as detailed below.
This figure illustrates the two main components of the MakeHuman
Application along with the integration layer that connects them. The
Python code delivers MakeHuman Specific functionality. The C
application provides a Python interpreter and exposes a set of generic
MakeHuman functions through the integration layer. The integration
layer consists of a set of C functions enabling events to be passed up
to Python code and a dynamically generated Python module enabling C
functions to be called from the Python code.
C code
The C language is a compiled programming language, requiring developers
to install a development environment in order to be able to build
changes to the C source code into the application. The C layer is
intended to be relatively stable and provides generic functionality to
the Python code, minimising the need for C development.
The 3D graphics environment as a whole, including most of the 3D mesh
handling functionality is delivered using OpenGL calls embedded within
the C application code. User interaction and user events are handled
using the SDL (Simple Direct Media Layer) library within the C
application code. The SDL library manages low-level events (e.g. Mouse
clicks, Mouse Movements, Keystrokes etc.) and makes those events
available to the application event loop.
C Data Structures
The principal data structures used by the C code are contained within
the 'G.' global structure. This global data structure is defined in the
file 'core.h' in the 'include' directory within SVN. Certain state
information is held directly in 'G.', such as camera settings, viewport
dimensions etc. Information required to define the 3D objects, such as
the humanoid figure and the GUI controls is nested within the
'G.world.' data structure, which is a pointer to an array of object3D
data structures. Each object3D data structure contains the information
needed to define a single object to OpenGL (verts, norms, UV, colors
etc.).
These data structures are detailed in the C code documentation at
http://makehuman.sourceforge.net/C_Docs/ (Note: the number version 0.9.2 is wrong).
Python code
Python is an interpreted language which means that you can add
functionality into the Python layer without needing to recompile or
rebuild the application.
The MakeHuman application incorporates a complete Python interpreter
enabling you to add Python functionality to the a released version of
the application without having to install any development software. To
add Python functionality to the version of MakeHuman currently under
development you do need a development environment to build the
application from source code stored in SVN.
MakeHuman functionality is delivered through a combination of core
Python modules and plugin Python modules assigned as function
attributes on a Python Scene3D object that is instantiated by the main
Python module (main.py) at application startup. The application is
event driven using the SDL library in the C core to detect registered
user events. These events are passed up to the Python functions that
have been registered to handle those events on the Scene3D object. The
Python event handling functions can interact with the C core through
the generic MakeHuman functions exposed through the integration layer
to perform the required functionality before returning control to the
application event loop to await the next event reported by SDL.
Python Data Structures
The data used to populate the C data structures is maintained through
Python code and a copy of that data is held in Python data structures.
Python application components load the 3D object data required to
populate the corresponding C data structures from object files. That
data is loaded into instances of Python classes, that are defined in
the file 'module3d.py' (in the 'mh_core' directory in SVN) before being
transposed and copied down into the C data structures. These classes
can be seen as being organised in a sort of hierarchical structure; A
single Scene3D object holds references to the set of Object3D objects
used to describe the humanoid model and the various GUI controls. Each
Object3D object contains lists of references to the FaceGroup, Face and
Vert objects that are used to construct a single 3D object.
The data structures contained within these classes are detailed in the Python API documentation at
http://makehuman.sourceforge.net/API/module3d-module.html .
Integration Layer
Specific low-level and high level functionality and events are exposed
through a C/Python integration layer enabling high-level GUI operations
to be delivered using interpreted Python code. The integration layer
passes calls from the C code to the main Python module to handle events
detected by the SDL module. These calls are made by functions in
core.c which use the
PyRun_SimpleString
function to invoke Python functions. The integration layer also
incorporates a series of C functions exposed through a Python class
(named 'mh.') that is dynamically generated by
main.c when the application starts. This class is created using the
Py_InitModule
function which registers a series of C functions as Python methods on
the 'mh.' class. This provides a mechanism by which the various Python
modules (called in response to an event), can interact with the generic
functions and the global data structure in the C core.
Program entry
When the application starts, it starts by initializing
all global variables. Then it prepares to call the main python entry,
first setting the program name, initializing python, passing the
program arguments and creating the makehuman python module.
When all that is done, main.py is called. This is done using
PyRun_SimpleString("execfile(\"main.py\")");
The reason this method is preferred instead of
PyRun_SimpleFile is that the latter might crash on windows because of
incompatible structures. Python 2.6 is compiled with Visual Studio 9,
which filestructures are different from MinGW or Visual Studio 8.
Python entry
The main python script starts by loading the necessary
modules, and creating the scene object. This object contains a list of
the objects in the scene, as well as a dictionary mapping selection
color to object. After the scene is created, the base mesh as well as
the GUI meshes are loaded into the scene. At that point in time, all 3D
geometry has been imported into the python runtime, but not yet into
OpenGL.
Thus the next logical step is to copy the geometry to
the C runtime which creates the necessary OpenGL vertex buffers (and
textures?). Finally the event handlers are connected and the GUI is switched to modeling mode. At that point, the Python script calls startWindow which creates the window in the C runtime and starts the event loop.
SDL event loop
In most modern GUI's, an event loop takes control once
everything is initialized. Our loop blocks on SDL_WaitEvent which waits
for user input and/or timers. When an event occurs, it is translated
and passed to the Python runtime. After handling the event, Python
returns control to the event loop.
Redrawing is done by placing an expose event into the
event queue. We don't just call draw directly because, if
running on a slow system, the event queue would fill up and, after the
user has finishes generating input events, a history of those events would be 'played' out. This
is solved in two steps. Instead of calling draw directly, an expose
event is posted in the event queue. This makes the drawing asynchronous just like the
input events. This would still give the same problem, as many events
would be posted, which can't be handled in time. To avoid this we mark
that an expose event was put into the queue, and we don't place a new
one in the queue until it is taken out of the queue and processed. This
makes sense as we don't need to tell the system twice or more times to
redraw, once an event is pending a redraw will occur eventually.
This way the system stays as responsive as possible, while drawing at the smoothest frame rate possible.
// The event loop
while not finished
wait for event
check event type
input: pass to python
expose: draw and clear pending flag
custom: call python timer
quit: finished
// The redraw method
if pending flag
return
set pending flag
queue expose event
A similar strategy is used for timers. instead of
calling the python callback directly from the SDL timer callback, we
push a custom event into the queue and only if there isn't already one in the
queue. This is done because the SDL timer callback is called from
another thread, which might crash the Python runtime. Once the event loop finishes, the OpenGL textures are
freed. And the event loop function returns. This brings control
back to the Python runtime which finishes it's main script and returns
as well.
Program Exit
Application
This is the main object in a certain application, it sets up the default categories and views, and loads the plugins.
Category
A category collects different tasks which work on similar aspects of the model, like modelling.
Task
A
task makes it possible to work on a certain aspect of the model, or
implements another function in the application like saving or loading.
Object
A 3d mesh which can be clicked on.
EventHandler
An
EventHandler is a class which can receive events. Handlers for events
can be attached to the EventHandler by defining the method in the class:
class MyClass(EventHandler):
def onMyEvent(self, event):
print("got onMyEvent")
However
sometimes it can be bothersome to create a sub class each time you need
different behavior in the handler. For this you can use the event
decorator:
class MyParentClass:
def __init__():
self.myFirstClass = MyClass()
@self.myFirstClass.event
def onMyEvent(event):
print("got onMyEvent in myFirstClass")
self.mySecondClass = MyClass()
@self.mySecondClass.event
def onMyEvent(event):
print("got onMyEvent in mySecondClass")
However
note that using self here, will always give MyParentClass. If you need
the self of the MyClass instance, use self.myFirstClass or
self.mySecondClass in the handler.
View (EventHandler)
A
view is a container holding other views and objects. When it is shown
or hidden, all the views and objects it contains are shown or hidden as
well (providing they are not individually hidden themselves). Views
also have the notion of a focus. There is only one view which can have
the focus at a time. The focussed view will receive all keyboard input.
Additional properties are:
- parent: optional, defaults to None.
- visible: optional, defaults to True.
Additional events are:
- onShow/onHide: fired when the view's visibility changes.
- onFocus/onBlur: fired when the view's focus status changes.
Widgets
Button (View)
A
button is a standard push button. It has a selected state, which is
only true when it is being pushed (between mouse down and mouse up).
Additional properties are:
- selected: boolean indicating whether a button is showing itself as selected.
- selectedTexture: a string indicating the optional texture to use when the button is selected.
Additional events are:
- onSelected: fired when the button's selected status changes.
ToggleButton (Button)
A ToggleButton is a button which stays selected after you click it once, and deselects when you click it again.
Additional properties are:
RadioButton (Button)
A
RadioButton is a button which can be put in a group. When one of the
RadioButtons in a group is selected, all the others are deselected.
Additional properties are:
- group: a list of RadioButtons which are exclusive.
Slider
A Slider is a widget allowing the user to select a value in a certain range.
Additional properties are:
- backgroundTexture: a string indicating the texture to use as the background of the slider.
- sliderTexture: a string indicating the texture to use as the slider of the slider.
- value: optional current value, if not given defaults to 0.0.
- min: optional minimum value, if not given defaults to 0.0.
- max: optional maximum value, if not given defaults to 1.0.
Additional events are:
- onChange: fired when the slider's value changes.
ProgressBar
A ProgressBar shows the progress of a lengthy operation.
Additional properties are:
- backgroundMesh: a string indicating the mesh to use as the background of the progressbar.
- backgroundTexture: a string indicating the texture to use as the background of the progressbar.
- backgroundPosition: position of the background
- barMes : a string indicating the mesh to use as the bar of the progressbar.
- barTexture: a string indicating the texture to use as the bar of the progressbar.
- barPosition: position of the bar
Event flow
Mouse event
Application -> View under mouse
Remarks:
- If left click, set focus if the view accepts focus.
- MouseUp is only received after MouseDown
- MouseDragged is between iMouseDown and MouseUp
- MouseMoved is not between iMouseDown and MouseUp
Keyboard event
Application -> Focus View
OpenGL Notes
Most of the 3D mesh handling functionality is delivered using OpenGL
embedded within the C application code. OpenGL is a 3D graphics library
that enables a 3D world to be defined, with a camera, objects, lights,
textures etc. It then enables that 3D world to be visualised as a 2D
representation that can be displayed on a computer screen and provides
functions to enable an application (in response to user input) to
navigate around the scene.
Basics
OpenGL takes a 3D scene and draws it into a 2D viewing area on your screen known as the viewport.
OpenGL can project the scene onto the viewport in a variety of different ways, but the most common are:
- Perspective projection, as you would get if you could place a camera in the scene
- Orthographic projection, as a draftsman may contstruct technical drawings such as plans and elevations.
MakeHuman
only uses
Perspective projection.
Projection Transformation - You tell OpenGL how to
project 3D objects onto the 2D viewport by defining a projection
transformation, which indicates whether you wish to use perspective or
orthographic projection (or an alternative projection pattern) and
specifies other projection settings.
This can be imagined as being comparable to specifying the
characteristics of a camera (field of view, aspect ratio etc.) where an
orthographic projection is equivalent to a camera at an infinite
distance. The main difference being that with OpenGL you can change the
settings between drawing different objects, which is a bit like taking
a photo, changing the lens and moving the camera, then taking another
photo without winding the film on.
MakeHuman sets a perspective projection using the function
gluPerspective(fovAngle,aspectRatio,near,far) where:
- fovAngle: is the vertical field of view angle (45 degrees)
- aspectRatio: is the viewport width divided by the viewport height which, by default, is 800/600 (4/3)
- near: is the distance to the centre of the viewing plane (0.1)
- far: is the distance to the centre of the rear clippling plane (100)
Modelview Transformation - For OpenGL to know what to
display in the viewport it also needs to know where the camera is
relative to the 3D model. For this you need to define a modelview which
defines the position and orientation of the camera and the position and
orientation of objects that go to make up the model inside a virtual 3D
world. You do this by moving through and around the 3D world and by
creating objects relative to your current position. OpenGL keeps track
of your current position and orientation in the 3D world by recording
the modelview transformation.
Both the projection transformation and the modelview transformation are
stored internally in 4x4 transformation matrices. You can modify these
matrices by calling functions that apply direct transformations
(translations and rotations) or by calling functions that calculate
transformations (e.g. the gluPerspective function outlined above). To
apply transformations you need to first make one of these matrices the
current matrix. Subsequent transformations are applied cumulatively to
the current matrix. The glMatrixMode function is used to set the
current matrix mode:
- glMatrixMode(GL_PROJECTION) makes the projection
transformation the current matrix so that projection settings can be
applied, such as the Field of View angle and Aspect Ratio.
- glMatrixMode(GL_MODELVIEW)
makes the modelview transformation matrix the current matrix so that
subsequent translations and rotations move the current location through
the 3D world.
Resetting a transformation matrix
Matrix transformations that you apply are applied cumulatively. It is
therefore often necessary to reset the matrix to its default 'no
transformation' state so that you can apply a fresh set of
transformations. OpenGL uses the transformation and modelview matrices
to transform coordinates by performing a matrix multiplication. If you
multiply by an identity matrix then the result is the same as the thing
you started with, so to reset one of these matrices to an initial state
where the transformation has no effect you can simply load the identity
matrix using the function glLoadIdentity(). This loads the identity
matrix into whichever transformation matrix is currently active,
resetting it to the default 'no transformation' state.
Coordinates
OpenGL world space coordinates are unitless, so 2 units can represent
milimeters, inches or light years. Interpretation of world space
coordinates is up to the application. OpenGL uses a right handed
coordinate system, so, if you are looking at the origin with the +X
axis stretching away to the right and the +Y axis pointing straight up,
the +Z axis will be heading out of the screen straight towards you and
the -Z axis will be dissapearing away from you into the distance.
MakeHuman uses the default OpenGL modelview camera settings which are
equivalent to invoking gluLookAt(0,0,0, 0,0,-1, 0,1,0). This places the
camera at the origin, looking straight into the model along the -Z axis
with the +Y axis pointing straight up. This means that a 2 unit wide
and 2 unit high object centred at <0,0,-1> will roughly fill the
viewport, as will a 4x4 object at twice the distance from the viewpoint.
Drawing objects
MakeHuman contains multiple objects. The Humanoid object is the main
object, but it is surrounded by a set of control objects. Each object
is constructed using triangular faces. The position and orientation of
each face is defined relative to the object of which it is a part. The
positions and orientations of the vertices and normals of the faces are
defined relative to the face they're on. The sequence in which face
vertices are defined is significant in OpenGL. If the face is viewed
from the front, the sequence of points runs counter clockwise. If the
face is viewed from the back the points run clockwise. Faces viewed
from behind may be invisible or may have a different color/texture
defined to the front face.
The glPushMatrix and glPopMatrix functions can be used to store away a
copy of a matrix that can subsequently restored. MakeHuman uses this
before and after drawing each object to store a copy of the modelview
matrix and restore it.
The C Development Environment
A development environment enables you to compile and build a new copy
of MakeHuman from source code held in the MakeHuman code repository. To
simply run the MakeHuman application on Windows, Mac OS-X or Linux, you
should not need a development environment as you can usually just use
the current released version, which comes with an installer for your
operating system. The released software incorporates a Python
interpreter, so plugin developers can write, test and use Python
scripts without necessarily requiring a separate Python development
environment (see the Plugin Development section of this guide).
You do need a development environment to:
- Participate in the development of the MakeHuman
- Build a copy of the application currently under development
- Build a copy of the application to run on a platform that is not officially supported.
To participate in the development of the MakeHuman code as a MakeHuman
Team member you will also need to familiarise yourself with the
Coding standard and
Build Processes contained within this document.
The 'C' compiler is platform dependent. The following are recommended for MakeHuman development:
Windows 'C' Development Environment
The supported environments for MakeHuman 'C' code development are
MinGW and
Microsoft Visual C++
- To roughly build MakeHuman, you can simply run the compile_src.bat file (maybe you need to adjust it, in order to match your local paths).
- A better result is obtained using Visual C++ (see section Mingw vs. Visual C. below). Actually there is not a VC project file in svn, but it will be added before the release 1.0 final.
Windows Visual C++
-
Python 2.6 (headers + python26.lib + python26.dll)
-
SDL 1.2.13 (headers + SDLmain.lib + SDL.lib + SDL.dll)
-
SDL_Image 1.2.7 (headers + SDL_Image.dll + optionally jpeg.dll, libpng12-0.dll, libtiff-3.dll, zlib1.dll)
Windows gcc
-
Python 2.6 (headers + libpython26.a + python26.dll)
-
SDL 1.2.13 (headers + libSDLmain.a + libSDL.dll.a + SDL.dll)
-
SDL_Image 1.2.7 (headers + SDL_Image.dll + optionally jpeg.dll, libpng12-0.dll, libtiff-3.dll, zlib1.dll)
The MakeHuman application uses functions from the SDL_image libraries
which needs to be linked into the program during the build. You will
need to place the set of associated DLL's in a directory accessible
during the build.
The DLL files are available for different platforms from
http://www.libsdl.org/projects/SDL_image/release/. For example, a zip archive is available for Windows called :
http://www.libsdl.org/projects/SDL_image/release/SDL_image-1.2.7-win32.zip. Just copy all of the DLL's from the archive into a directory in your build path before you build the MakeHuman application.
MinGW vs Windows Visual C++
An SDL program needs to be linked to a static library
called SDLmain, which provides the main/WinMain entry of your program.
The original main entry is renamed using a #define when including SDL.
The visual C++ version of this SDLMain called SDLmain.lib is compiled
using
--disable-stdio-redirect while the MinGW version called libSDLmain.a
seems to be compiled without this flag. This makes the MinGW version
redirect all output to two files, stdout.txt and stderr.txt. Python
doesn't like this, and output from python will fail in this case. A
workaround is to redirect Python's output itself to file before it does
any output:
f=open("outFile.txt", "w")
sys.stdout = f
.. ..
f.close()
Adding this redirection is implemented in main.c, only when building on windows with gcc:
#if defined(__GNUC__) && defined(__WIN32__)
err = PyRun_SimpleString("import sys\nf = open(\"outFile.txt\", \"w\")\nsys.stdout = f\nexecfile(\"main.py\")\nf.close()");
#else
err = PyRun_SimpleString("execfile(\"main.py\")");
#endif
The real cause why Python fails is still to be examined.
Another workaround is rebuilding SDL for MinGW using the --disable-stdio-redirect flag.
Linux 'C' Development Environment
Linux gcc
-
Python 2.5 (headers + libpython2.5.a)
-
SDL 1.2.13 (headers + libSDLmain.a + libSDL.a + libSDL.so)
-
SDL_Image 1.2.7 (headers + libSDL_image-1.2.so.0)
Using Ubuntu or Debian, this mean you need to install, by synaptics, the following packages:
- build-essential
- python2.5-dev
- libsdl1.2-dev
- libsdl-image1.2
- scons
The compiler (of course, GCC) is included in build-essential package.
Compile under Linux is very simple. If you have all packages listed above correctly installed, you must just open the console, go in MH folder and type "
scons".
SCons
is a Python-based cross-platform build environment that can be used to
simplify the build processes for cross-platform applications. Knowledge
required to successfully build the application can be built into SCon
scripts, which can validate the environment and provide user-friendly
information to the person performing the build in the event that the
environment is incomplete. A draft
SConstruct
build script is provided in the current MakeHuman SVN build directory,
although at the time of writing it is likely still to need adapting for
your particular platform. is an useful utility (
http://www.scons.org/ ) and in future we will use it for Windows too.
Mac OS-X 'C' Development Environment (To be updated)
The Project source files stored under SVN contain an
Xcode
project that is currently out of date. Until a new project file is
available MakeHuman needs to be built using a 'make' shell command. SVN
also includes files needed to adapt the 'C' source code for Mac OS-X
builds.
Whether using an Xcode project or the 'make' shell command to build
MakeHuman you will need to install the Xcode Tools which include the
GCC C Compiler. Xcode is not installed by default, but is part of the
"OS-X Developer Tools" package which is available on your OS-X
installation DVD. If you don't have the DVD you may download an image
of this DVD free of charge from the Apple developer site at
http://developer.apple.com.
Currently the build process uses a 'make' shell command which is
unusual for OS-X. OS-X build processes usually use the 'Xcode'
development system which provides a fully Integrated Development
Environment (IDE) that incorporates editors, a build system, dependency
generation, debugging support etc. An Xcode project file for the
current source deck is under development. For further information about
the Xcode Tools please refer to
http://developer.apple.com/tools/xcode/ .
The standard OS-X build process uses an Xcode project to build the source downloaded from SVN.
You have two choices to compile the source deck that you download from SVN:
- Either you may use a makefile to perform the build. You
can use the file ' compile_src_osx.sh' which is used to launch a 'make'
command specifying the 'Makefile_osx' file as the parameter file. ie
'make -f Makefile_osx'. This command compiles and builds the C core.
- You may load the Xcode project file named MakeHuman.xcodeproj into the Xcode Development IDE and perform the build within the Development system.
Both ways assumes that you have already installed the free
Xcode package which incorporates a C/C++, and Objective-C++ compiler.
NOTE: Since the latest version of MakeHuman uses
Python 2.5 or above, MakeHuman will run only on Mac OS X Version 10.5.
or above because prior versions will be shipped with older versions of
Python and
not work!
If you are using a different Interactive Development Environment (IDE)
then you will need to use a text editor to adjust the makefile
parameter file before launching the shell script.
In Addition the build system will use some custom Open Source
Frameworks which are not maintained by the MakeHuman team. However the
SVN contains these Frameworks so you don't have to bother to explicit
download them.
The Python Development Environment
The vast majority of the functionality delivered by MakeHuman is
written in Python which has been used to develop GUI components,
service functions and even certain processor intensive functions, such
as subdivision. The rationale for developing in Python is that it
results in highly human readable code, it is largely free of 'silent
crashes', it is easier to find coders to contribute to the development
and is far easier to debug than 'C'. The price we have to pay is with
the performance of some processor intensive algorithms.
The MakeHuman application incorporates a Python interpreter enabling
Python plugins to be developed against a released version of the
MakeHuman application without the need for a separate Python
Development Environment. This Python interpreter is link-edited into
the application whenever the 'C' code is compiled/built, so in order to
compile and build the MakeHuman application you will need a Python
Development Environment installed on your machine.
Once built, you will be able to run and test any changes made to Python
code without having to rebuild the MakeHuman application. You'll simply
need to restart the application to pick up your Python changes.
However, to incorporate any changes to the 'C' code made by you or by
other developers and downloaded by you from the SVN repository you will
need to recompile and rebuild the MakeHuman application.
Python is available free from
http://www.python.org/) . The Python installer is about 10MB. The installed Python interpreter occupies about 60MB of disk space.
To participate in the development of the MakeHuman code as a MakeHuman
Team member you will also need to familiarise yourself with the
coding standards and
build processes contained within this document
Obtain MakeHuman Source
Anyone can get a copy of the MakeHuman source deck by pointing an SVN client application at the repository.
SubVersion (SVN) Client
To be able to participate fully as a MakeHuman developer you will need
an SVN client application. This will enable you to take a local copy of
the MakeHuman files, regularly update your local copy from the SVN
repository and (if you are member of MHteam) commit changes that you have made (and properly tested)
back to the SVN repository. SVN update permissions are controlled by
the MakeHuman development team, so you'll need an administrator to authorise you with write
access.
Different subversion client applications are available for different
Operating Systems, many of which are free to use. They each work in
slightly different ways, but the differences are relatively minor. See
http://subversion.tigris.org/ for a list of Third party SVN client applications.
For example, the Tortoise client for Windows acts as a Windows shell.
Once installed it adds SVN client options to the popup menu that is
displayed whenever you right click a file or a sub-directory in the
Windows file explorer. To obtain a new copy of the MakeHuman SVN
development directory structure you select the '
SVN Checkout' option from the explorer menu and enter the URL of the MakeHuman SVN repository.
Other SVN clients provide a comparable mechanism for checking out a
copy of the SVN directory structure and will also require the URL:
http://makehuman.googlecode.com/svn/trunk/
Coding Style
Python
Python code must be written following the rules of PEP 8 and PEP 12.
Do not write Python getters and setters unless you can prove that you
need something more than simple attribute access. Instead read
http://dirtsimple.org/2004/12/python-is-not-java.html and use the 'built-in' property.
Getters and setters waste CPU time, but more important, they waste
programmer time for those writing, testing and reading the code.
C
C code must be formatted using Astyle software, from
http://astyle.sourceforge.net/ (ANSI style).
Coding Rules
- Indenting (astyle options for C).
- Follow the established MakeHuman naming conventions.
- Add clear and concise comments to your code. Explain what the code does in real-world terms, don't just paraphrase the code.
- Add information that can be read by the current automated API document generation utilities (see the Documentation section of this guide).
The openGL core is entirely contained within the file
glmodule.c and ad heres to the following rules:
- "only-what-is-absolutely-needed" is coded in C
- pointers are avoided where at all possible
- complex patterns are avoided
- the C coding is kept stylistically as simple and readable as possible
SVN usage
- Test all changes before submitting to the repository. As
an absolute minimum make sure your changes won't break the build for
other developers.
- Commit changes as soon as possible so that other developers aren't developing against out of date code.
- Ask
for permission before writing into another persons repository. SVN
write permission doesn't give you the right to write without bounds!
- Only insert files in SVN that aren't available through another place. EDITORIAL NOTE: This needs clarification
Bugreports
Where to report bugs?:
Check existing bug reports before submitting your own to avoid duplication. If you have additional information add a comment.
EDITORIAL NOTE: Check SVN supports this.
Bug reports should specify:
- The Operating System or systems affected, or at least the OS upon which the bug was observed.
- MakeHuman version information, including whether it is a pre-built or self-built installation.
- Precise
and concise information about which modules, methods, classes etc. are
involved if this is known. If you think it's down to a certain module,
say so, but also say if you're not sure.
- If the bug is in a build of code that is under development, indicate the date that you downloaded it.
- If you suspect your bug is related to an existing bug report or reports, say so and indicate which ones.
Plugin Development
Editorial note: to updateThe MakeHuman application is an Open Source application that has been
structured to encourage the development of plugin applications using
the Python programming language. The application incorporates a Python
interpreter which enables developers to write Python scripts for
MakeHuman without needing to install a development environment. This
document assumes that plugin developers already have a reasonable
understanding of general application development concepts and of the
Python programming language.
Introduction
This section of the document describes how to go about developing a
MakeHuman plugin. The specific approach required will clearly vary
depending upon the purpose and design of the plugin you wish to create,
so this text is structured to attempt to help you to categorise the
type of plugin and assess the type of development that you will need to
undertake to develop your plugin.
MakeHuman functionality is largely implemented in the Python
programming language, but relies upon a small and efficient C
application that provides generic core functions. Plugin developers
should familiarise themselves with the
Application Overview
section of this Developers Guide, which describes the relationship
between these two language components and explains the general design
of the MakeHuman application.
It is anticipated that most of the work involved in developing plugins
will be in coding Python scripts. However, it is foreseen that some
changes to the central C code could be required from time to time to
add support for functionality required to develop certain specific
types of plugin. It should be noted that such changes to the C core
will need to be performed in collaboration and consultation with the
MakeHuman team to ensure that they do not adversely affect core
functions, performance, reliability or cross-platform compatibility.
For changes to the core C application you will need to install a full
development environment (see the
Development Environment section of this guide).
Existing Plugins
Each of the different application modes, along with the export and
rendering functions to integrate with different renderers are coded as
plugins and can serve as an example to plugin developers to illustrate
how extra plugins can be implemented.
Python Interpreter
The MakeHuman application incorporates a Python interpreter which can
be used to invoke a plugin. The MakeHuman Python interpreter provides
the plugin with access to the Application Programming Interface exposed
by the MakeHuman application. If you write a Python script called
'foo.py' you can invoke it with the command "makehuman foo.py".
Plugin Categories
It is anticipated that future development will include conversion
utilities to integrate with an extended range of modeller and rendering
applications, feature enhancements, such as animation features,
clothing, hair and prop integration and tools/utilities.
There are plugins under development for extended characters based upon
alternative meshes, for example a 'toon' mesh for cartoon-like
characters with exagerated features. It is also possible to envisage
plugins to support the modelling of other types of creature.
The following list cannot be comprehensive, but is provided as a guide
to help you categorise the type of plugin you intend to develop.
Export/Import format converters
These can generally be built using the classes, functions and data structures provided by the MakeHuman API documentation at
http://makehuman.sourceforge.net/API/
. Python source for the Renderman and POV-Ray export functions is
already provided in the plugin directory and can be used as an example.
When designing a converter you will need to have a reasonable
understanding of the model format that you wish to develop and the
features that you plan to support. The humanoid mesh should be fairly
straight-forward to convert. An instance of the Object3D class contains
the humanoid object with references to the Vert objects which store
vertex data and the Face objects that point to the 3 Vert objects used
to define each face. You are also likely to need information about the
surface normals and potentialy UV-Mapping data if you plan to support
uv-mapping of texture maps. Each face of the model is assigned to a
face group. See the section
Full API in this document for the URLs of the various pages used to document these face groups.
Developer Tools and Utilities
In this context the term tools and utilities is used to refer to things
like the Morph Target Generator that is incorporated into the MakeHuman
application, but which is only expected to be used as a utility to
enhance the MakeHuman application and not something that is used by the
average user.
Feature enhancements
The MakeHuman application currently supports the modelling and posing
of humanoid characters, but it does not yet support many of the
features that users will need such as hair, clothing and other props,
animation etc. It is anticipated that most such enhancements can be
coded using Python without requiring changes to the C code. An example
of some of the things that could fall into this category include:
- Finger Nail color picker
- Animation controls
- Hair
- Clothes
- Shoes
- Prop
- Text to Speech Generators
- ...
Other models and model types
The MakeHuman humanoid model uses a single base mesh with mesh
deformations being applied using morph targets that map specifically to
this one mesh.
However, the application code works in a highly generic way and could
potentially be used with alternative base meshes. For example, the same
application code could be used to manipulate a quadraped if an
appropriate base mesh and corresponding morph targets were developed:
- Toons
- Aliens
- Quadrapeds
- Birds
- ...
Consistency
It may also make sense to develop specific plugins/application
functions that can be used by multiple plugins. For example, it would
be messy for someone to develop a finger nail color picker that worked
differently to a color picker for hair color or lipstick. Also, list
boxes and data entry panels should all function in a consistent manner,
otherwise users will need to re-learn the basics of the interface for
each plugin.
SVN quick intro