Calling MH as a library called from other programs

MakeHuman python API, python plugins, etc

Moderator: joepal

Re: Calling MH as a library called from other programs

Postby PapaRaven » Fri Jun 05, 2009 5:09 pm

What a funny coincidence Temujin -- I did the exact same thing before seeing that mflerackers had updated SConstruct (some time ago) to produce the exact same result. So even before running the .sh version, you would have seen mh.so built, if you used scons (I'm really beginning to appreciate scons).

The mh.so module imports fine in a pure Python context, i.e. if you run it directly like you probably did: python ./test.py
... but if you run it from within Blender (no idea whether this is your goal), then it throws a segmentation fault. Hence the tweak I mentioned about changing to a "static Global G" declaration.

I'm sorta slow; I'm still tweaking my environment for the next step(s). And this (static, etc.) may not ultimately even be the correct solution.

Good luck to you
PapaRaven
 
Posts: 11
Joined: Sun Sep 14, 2008 5:10 am

Re: Calling MH as a library called from other programs

Postby mflerackers » Sat Jun 06, 2009 4:41 am

I think the static in the header will also create a new variable for each c file where it is included. Try running main.py.
MakeHuman project Developer
mflerackers
 
Posts: 636
Joined: Thu Feb 05, 2009 11:53 am
Location: Kyoto

Re: Calling MH as a library called from other programs

Postby PapaRaven » Sun Jun 07, 2009 6:35 pm

It would indeed create several instances without being wrapped in that macro. The macro ought to prevent that though.

I'll try main.py momentarily...

[Edit:]
I remember now I did try main.py already. Basically I had to move the path appends before the import mh, and even then the appends needed to be changed to absolute paths (very odd since there were local symlinks to take care of pathing issues):
Code: Select all
...
import sys
if 'nt' in sys.builtin_module_names:
    sys.path.append("./pythonmodules")

sys.path.append("/home/dev/makehuman/1.0.0trunk/makehuman/")
sys.path.append("/home/dev/makehuman/1.0.0trunk/makehuman/mh_plugins")
sys.path.append("/home/dev/makehuman/1.0.0trunk/makehuman/mh_core")

import mh
import os
import subprocess
import webbrowser
...

The MakeHuman window gets created, but nothing gets drawn, i.e. it is black. This seems to create a modal window at best, and it won't close, so I end up having to kill the Blender process (xkill on the black MakeHuman window also kills Blender).

So I can't tell yet really whether this works in Blender, what magic steps are missing, etc. Yesterday instead of hacking code I was hacking blackberry bushes, so today I'll try monkeying around with this some more. Like I said before, I'm no speed demon. :roll:
PapaRaven
 
Posts: 11
Joined: Sun Sep 14, 2008 5:10 am

Re: Calling MH as a library called from other programs

Postby m.e » Wed Aug 12, 2009 8:24 am

How is this going?
m.e
 
Posts: 56
Joined: Wed Jul 23, 2008 9:20 am
Location: Shenzhen/Hong Kong

Re: Calling MH as a library called from other programs

Postby PapaRaven » Wed Aug 12, 2009 8:35 am

There's something fundamental missing, and I just don't know what that is. Just petered-out I'm afraid. Maybe at some point I'll try writing something to just import the mesh into Blender, cleanly and without further manual tweaking required, but that may change when I finally have the time to look into it.
PapaRaven
 
Posts: 11
Joined: Sun Sep 14, 2008 5:10 am

Re: Calling MH as a library called from other programs

Postby m.e » Thu Aug 20, 2009 1:06 pm

Which version are you using? I have had a look at 1.0 alpha3b; is that what you are using?

The code looks like the MH GUI code is all mixed up with the underlying model* code. As I understand it, the work-flow would be to create the model# using MH but then to animate it using Blender, so Blender would need to be able to read the MH model file (and any other files MH might need), to feed any pose and expression parameters through to MH, and retrieve the resulting mesh (and update the corresponding Blender mesh and display it). All this means (I think) that the MH GUI would not be used.

* model in the sense of model-view-controller that is, not the 3D model.

# the 3D model this time
m.e
 
Posts: 56
Joined: Wed Jul 23, 2008 9:20 am
Location: Shenzhen/Hong Kong

Re: Calling MH as a library called from other programs

Postby m.e » Sat Aug 29, 2009 12:38 pm

I am putting together a dummy mh module so you don't need to call the MH user interface code. I have not tried running it yet. Let me know any comments Current code (as is where is) [improved version]:
Code: Select all
#!/usr/bin/python
# -*- coding: utf-8 -*-


def getKeyModifiers(self):
    return 0


def updatePickingBuffer(self):
    return


def getColorPicked(self):
    return []


def getCameraRotations(self):
    return [0.0, 0.0]


def setCameraRotations(self, GrotX, GrotY):
    return


def getCameraTranslations(self):
    return [0.0, 0.0]


def setCameraTranslations(self, GtranslX, GtranslY):
    return


def getCameraZoom(self):
    return 0.0


def setCameraZoom(self, Gzoom):
    return


def getCameraSettings(self):
    return [
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        ]


def setCameraSettings(
    self,
    GtranslX,
    GtranslY,
    Gzoom,
    ):
    return


def getMousePos2D(self):
    return []


def getMousePos3D(self):
    return [0.0, 0.0, 0.0]


def getMousePosGUI(self):
    return [0.0, 0.0, 0.0]


def convertToScreen(
    self,
    screen,
    screen1,
    screen2,
    camera,
    ):
    return [0.0, 0.0, 0.0]


def convertToWorld2D(
    self,
    screen,
    screen1,
    camera,
    ):
    return [0.0, 0.0, 0.0]


def convertToWorld3D(
    self,
    screen,
    screen1,
    screen2,
    camera,
    ):
    return [0.0, 0.0, 0.0]


def getWindowSize(self):
    return []


def startWindow(self, useTimer):
    return


def startEventLoop(self):
    return


def shutDown(self):
    return


def redraw(self, async):
    return


def setFullscreen(self, fullscreen):
    return


def setClearColor(
    self,
    r,
    g,
    b,
    a,
    ):
    return


def LoadTexture(self, filename, texture):
    return 0


def CreateVertexShader(self, vertexShaderSource):
    return 0


def CreateFragmentShader(self, source):
    return 0


def CreateShader(self, vertexShader, fragmentShader):
    return 0


def GrabScreen(
    self,
    x,
    y,
    width,
    height,
    filename,
    ):
    return


def setTimeTimer(self, milliseconds):
    return


def getPath(self):
    return ''

Last edited by m.e on Mon Aug 31, 2009 4:22 am, edited 1 time in total.
m.e
 
Posts: 56
Joined: Wed Jul 23, 2008 9:20 am
Location: Shenzhen/Hong Kong

Re: Calling MH as a library called from other programs

Postby m.e » Mon Aug 31, 2009 4:18 am

This runs under blender with a dummy mh.py (change the file path of course to point to your mh file):
Code: Select all
import module3d
import files3d
mainScene = module3d.Scene3D()
myModel = "/home/martin/whatever/models/aaa.mhm"
humanMesh = files3d.loadMesh(mainScene, myModel)
print "Mesh name is ", humanMesh.name
print len(humanMesh.verts), " vertexes"
print len(humanMesh.faces), " faces"
print len(humanMesh.facesGroups), " face groups"
for fg in humanMesh.facesGroups:
   print "face group ", fg.name
   print len(fg.faces), " faces"
m.e
 
Posts: 56
Joined: Wed Jul 23, 2008 9:20 am
Location: Shenzhen/Hong Kong

Re: Calling MH as a library called from other programs

Postby m.e » Wed Sep 02, 2009 11:51 am

I'm getting there... ignore most of the previous but I have got some code working.
m.e
 
Posts: 56
Joined: Wed Jul 23, 2008 9:20 am
Location: Shenzhen/Hong Kong

Here it is

Postby m.e » Wed Sep 02, 2009 12:44 pm

OK, I have got some code running... Here it is. Note that this runs under Blender not MH. It just loads up an MH figure into Blender.

If you want to use it, you will need to edit the code a bit, at least to put in your file paths, and make sure that the right directory paths are in place.

Also, it's very rough code, and there is no user interface. I just got it going. You can help by improving it.
Code: Select all
#!/usr/bin/python
# -*- coding: utf-8 -*-

#makehuman modules
import mh
import module3d
import human
import humanmodifier
import sys

#blender modules
import Blender


def modifyHuman(human, fileName):
    f = open(fileName, 'r')

    for data in f.readlines():
        lineData = data.split()

        if len(lineData) > 0:
            if lineData[0] == 'version':
                print 'Version ' + lineData[1]
            elif lineData[0] == 'tags':
                for tag in lineData:
                    print 'Tag ' + tag
            elif lineData[0] == 'gender':
                human.setGender(float(lineData[1]))
            elif lineData[0] == 'age':
                human.setAge(float(lineData[1]))
            elif lineData[0] == 'muscle':
                human.setMuscle(float(lineData[1]))
            elif lineData[0] == 'weight':
                human.setWeight(float(lineData[1]))
            elif lineData[0] == 'height':
                modifier = humanmodifier.Modifier(human,
                        'data/targets/macrodetails/universal-stature-dwarf.target'
                        ,
                        'data/targets/macrodetails/universal-stature-giant.target'
                        )
                modifier.setValue(float(lineData[1]))
            elif lineData[0] == 'ethnic':
                human.targetsEthnicStack[lineData[1]] = \
                    float(lineData[2])
            elif lineData[0] == 'detail':
                human.targetsDetailStack['data/targets/details/'
                         + lineData[1] + '.target'] = float(lineData[2])
            elif lineData[0] == 'microdetail':
                human.targetsDetailStack['data/targets/microdetails/'
                         + lineData[1] + '.target'] = float(lineData[2])

    f.close()
    del human.targetsEthnicStack['neutral']
    human.targetsEthnicStack['neutral'] = 1.0\
         - sum(human.targetsEthnicStack.values())

    print 'applying targets...'
    human.applyAllTargets()
    print 'modified'


class DummyApp:

    def __init__(self, scene):
        self.app = self
        self.scene3d = scene
        self.scene3d.application = self
        self.app = self
        self.canHaveFocus = False
        self.children = []
        self.objects = []
        self.categories = {}
        self.currentCategory = None
        self.currentTask = None
        self.focusView = None
        self.focusObject = None
        self.focusGroup = None
        self.mouseDownObject = None
        self.enteredObject = None
        self.tool = None
        self.selectedGroup = None
        self.undoStack = []
        self.redoStack = []

    def isVisible(self):
        return False

    def getThemeResource(self, a, b):
        return 'data/themes/default/images/progressbar.png'




def getMakeHumanMesh():
    print 'making scene...'
    scene = module3d.Scene3D()
    print 'making application...'
    scene.application = DummyApp(scene)

    print 'making human...'
    humanData = human.Human(scene, 'data/3dobjs/base.obj')
    print 'updating application...'
    scene.application.scene3d.update()
    print 'redrawing application...'
    scene.application.scene3d.redraw(0)
    if humanData.app.scene3d == None:
        sys.exit('humanData.app.scene3d == None')
    if humanData.mesh == None:
        sys.exit('humanData has no mesh')
    print len(humanData.meshData.verts), ' vertexes'
    print len(humanData.meshData.faces), ' faces'
    for v in humanData.meshData.verts:
        if v.object == None:
            sys.exit('vert has no object')

    print 'adding texture...'
    humanData.setTexture('data/textures/texture.tif')
    print 'modifying...'
    modifyHuman(humanData,
                '/home/martin/mh/makehuman-read-only/makehuman/models/test3.mhm'
                )
    print len(humanData.meshData.verts), ' vertexes'
    print len(humanData.meshData.faces), ' faces'
    return humanData.meshData

print '-----------------------------'
meshData = getMakeHumanMesh()

coords = []
faces = []

print 'creating Blender verts...'
for v in meshData.verts:
   #print 'adding %f %f %f'%(v.co[0], v.co[1],v.co[2])
   coords.append([v.co[0], v.co[1],v.co[2]])
print 'creating Blender faces...'
for f in meshData.faces:
   #print 'adding %f %f %f'%(f.verts[0],f.verts[1],f.verts[2])
   faces.append([f.verts[0].idx,f.verts[1].idx,f.verts[2].idx] )
print 'loading into Blender...'
scene = Blender.Scene.GetCurrent()
mesh = Blender.Mesh.New()
mesh.verts.extend(coords)         
mesh.faces.extend(faces) 
scene.objects.new(mesh,'MakeHuman')
Blender.Redraw()   
print 'all done'    


#2 this needs to be in mh.py
Code: Select all
#!/usr/bin/python
# -*- coding: utf-8 -*-


def getKeyModifiers(self):
    return 0


def updatePickingBuffer(self):
    return


def getColorPicked(self):
    return []


def getCameraRotations(self):
    return [0.0, 0.0]


def setCameraRotations(self, GrotX, GrotY):
    return


def getCameraTranslations(self):
    return [0.0, 0.0]


def setCameraTranslations(self, GtranslX, GtranslY):
    return


def getCameraZoom(self):
    return 0.0


def setCameraZoom(self, Gzoom):
    return


def getCameraSettings(self):
    return [
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        ]


def setCameraSettings(
    self,
    GtranslX,
    GtranslY,
    Gzoom,
    ):

    return


def getMousePos2D(self):
    return []


def getMousePos3D(self):
    return [0.0, 0.0, 0.0]


def getMousePosGUI(self):
    return [0.0, 0.0, 0.0]


def convertToScreen(
    self,
    screen,
    screen1,
    screen2,
    camera,
    ):

    return [0.0, 0.0, 0.0]


def convertToWorld2D(
    self,
    screen,
    screen1,
    camera,
    ):

    return [0.0, 0.0, 0.0]


def convertToWorld3D(
    self,
    screen,
    screen1,
    screen2,
    camera,
    ):

    return [0.0, 0.0, 0.0]


def getWindowSize(self):
    return []


def startWindow(self, useTimer):
    return


def startEventLoop(self):
    return


def shutDown(self):
    return


def redraw(async):
    return


def setFullscreen(fullscreen):
    return


def setClearColor(
    self,
    r,
    g,
    b,
    a,
    ):

    return


def loadTexture(filename, texture):
    return 0


def createVertexShader(self, vertexShaderSource):
    return 0


def createFragmentShader(self, source):
    return 0


def createShader(self, vertexShader, fragmentShader):
    return 0


def grabScreen(
    self,
    x,
    y,
    width,
    height,
    filename,
    ):

    return


def setTimeTimer(self, milliseconds):
    return


def getPath(self):
    return ''


class Object3D:

    def __init__(self, vertexBufferSize, indexBuffer):
        print 'object 3d created'

    def setVertCoord(self, i, j):
        return

    def setNormCoord(self, coIdx, no):
        return

    def setUVCoord(self, uvIdx, uvValues):
        return

    def setColorIDComponent(self, coIdx, colorID):
        return

    def setColorComponent(self, colIdx, faceColor):
        return

    def setTranslation(
        self,
        x,
        y,
        z,
        ):

        return

    def setRotation(
        self,
        rx,
        ry,
        rz,
        ):

        return

    def setScale(
        self,
        sx,
        sy,
        sz,
        ):

        return


world = []
print 'fake mh loaded.'

Here's how I run blender:
Code: Select all
#!/bin/bash
cd $HOME/blender/blender
PYTHONPATH=~/git/mh:~/mh/makehuman-read-only/makehuman/mh_core/:~/mh/makehuman-read-only/makehuman/mh_plugins/ ./blender-softwaregl
m.e
 
Posts: 56
Joined: Wed Jul 23, 2008 9:20 am
Location: Shenzhen/Hong Kong

PreviousNext

Return to Python scripts

Who is online

Users browsing this forum: No registered users and 1 guest

cron