Script to load_and_retarget BVH files in blender

MakeHuman python API, python plugins, etc

Moderator: joepal

Script to load_and_retarget BVH files in blender

Postby chriscalef » Mon Feb 20, 2017 4:52 pm

Hey everybody,

I have a directory of BVH files and my goal in Blender is to procedurally duplicate my makeHuman figure once per BVH file, and then load one BVH file per character such that they can all play their own files simultaneously.

The reason I am doing this is my application, MegaMotion (megamotionsoftware.com) is capable of outputting scene animations as sets of BVH files. In order to aid in the setup, I made megamotion also export an xml file at the same time, describing each character's location in the world.

It is almost working, but my only problem is that when I run through my loop and duplicate my character, each time I can locate the new character where it needs to go, but when I call load_and_retarget to load the BVH file, the animation gets loaded onto the first character I duplicated, *not* the most recent character, who is still the selected_object.

Is there a way to tell bpy.ops.mcp that it should be working with a different object in the scene (the one that is selected) instead of whatever logic it is using to get stuck on the first one?

I'll include the script in a moment, but just to be clear, the behavior is like this: I have a model named "Jill". My script loads my XML file and begins to duplicate Jill, once for each sceneShape element in the file. The first duplicate is named Jill.001. Now, on every pass, I create a new Jill.002, .003, etc, but on every pass, Jill.001 is the one that loads the animation, and none of the rest of them get any.

Here is my full script:

Code: Select all

import bpy
import os

from xml.dom.minidom import parse
from xml.dom.minidom import Node

#(These functions borrowed from Todd McIntosh on stackexchange.com)
def CheckSelectStatus(p):
    for c in p.children:
        #print(c.name)
        c['hideSelectWasTrue'] = False
        if bpy.data.objects[c.name].hide_select == True:
            bpy.data.objects[c.name].hide_select = False
            c['hideSelectWasTrue'] = True
        c.select = True
        CheckSelectStatus(c)

def RestoreSelectStatusAndUnselect(p):
    for c in p.children:
        if c['hideSelectWasTrue'] == True:
            bpy.data.objects[c.name].hide_select = True
        c.select = False
        RestoreSelectStatusAndUnselect(c)
       



scene_path = "F:/bvhWork/Bigger_Nav_Test/"
full_path_to_xml = scene_path + "bvhExport.xml"

dom = parse(full_path_to_xml)
sceneShapeGroup = dom.getElementsByTagName("sceneShapeGroup")[0]

sceneShapes = sceneShapeGroup.getElementsByTagName("sceneShape")
for shape in sceneShapes:
    id = int(shape.getAttribute("id"))
    name = shape.getAttribute("name")
    groupID = int(shape.getAttribute("shapeGroup"))
    posX = float(shape.getAttribute("pos_x"))
    posY = float(shape.getAttribute("pos_y"))
    posZ = float(shape.getAttribute("pos_z"))
    rotX = float(shape.getAttribute("rot_x"))
    rotY = float(shape.getAttribute("rot_y"))
    rotZ = float(shape.getAttribute("rot_z"))
    rotA = float(shape.getAttribute("rot_a"))
    scaleX = float(shape.getAttribute("scale_x"))
    scaleY = float(shape.getAttribute("scale_y"))
    scaleZ = float(shape.getAttribute("scale_z"))
   
    if groupID == 1:  #arbitrary, we can make as many groups as we want

        #deselect everything
        bpy.ops.object.select_all(action='DESELECT')
       
        #select Jill, if group 1, musc_male if group 2
        jill = bpy.data.objects["Jill"]
        jill.select = True
        CheckSelectStatus(jill)
       
        #print (bpy.ops.object.name)
       
        #call duplicate_move
        bpy.ops.object.duplicate_move()
       
        #print (bpy.ops.object.name)
       
        #unselect Jill
        RestoreSelectStatusAndUnselect(jill)
       
        #translate, rotate, possibly scale new figure
        bpy.ops.transform.translate(value=(posX,posY,posZ))
        bpy.ops.transform.rotate(value=rotA,axis=(rotX,rotY,rotZ))
       
        #toggle pose mode on new figure
        #bpy.ops.object.posemode_toggle()
        #print(bpy.context.mode)
        bpy.ops.object.mode_set(mode='POSE', toggle=False)
       
        #call load and retarget with bvh path
        path_to_bvh = scene_path + str(id) + ".bvh"
        bpy.ops.mcp.load_and_retarget(filepath=path_to_bvh)
   
        bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
       
        print (bpy.context.selected_objects)
       
        print ("sceneShapeID: " + str(id) + " name " + name + " group " + str(groupID) +
            " pos " + str(posX) + " " + str(posY) + " " + str(posZ) + " path " + path_to_bvh)       
       

   

dom.unlink()


Also, here is the XML file, in case anyone wants to see it:

Code: Select all
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<sceneShapeGroup>
    <sceneShape id="1514" name="Mike_0_0" shapeGroup="1" pos_x="-3" pos_y="0" pos_z="0" rot_x="1" rot_y="0" rot_z="0" rot_a="0.000690534" scale_x="0.7" scale_y="0.7" scale_z="0.7" />
    <sceneShape id="1515" name="Mike_0_1" shapeGroup="1" pos_x="-3" pos_y="-3" pos_z="0" rot_x="1" rot_y="0" rot_z="0" rot_a="0.000690534" scale_x="0.7" scale_y="0.7" scale_z="0.7" />
    <sceneShape id="1516" name="Mike_0_2" shapeGroup="1" pos_x="-3" pos_y="-6" pos_z="0" rot_x="1" rot_y="0" rot_z="0" rot_a="0.000690534" scale_x="0.7" scale_y="0.7" scale_z="0.7" />
    <sceneShape id="1517" name="Mike_1_0" shapeGroup="1" pos_x="0" pos_y="0" pos_z="0" rot_x="1" rot_y="0" rot_z="0" rot_a="0.000690534" scale_x="0.7" scale_y="0.7" scale_z="0.7" />
    <sceneShape id="1518" name="Mike_1_1" shapeGroup="1" pos_x="0" pos_y="-3" pos_z="0" rot_x="1" rot_y="0" rot_z="0" rot_a="0.000690534" scale_x="0.7" scale_y="0.7" scale_z="0.7" />
    <sceneShape id="1519" name="Mike_1_2" shapeGroup="1" pos_x="0" pos_y="-6" pos_z="0" rot_x="1" rot_y="0" rot_z="0" rot_a="0.000690534" scale_x="0.7" scale_y="0.7" scale_z="0.7" />
    <sceneShape id="1520" name="Mike_2_0" shapeGroup="1" pos_x="3" pos_y="0" pos_z="0" rot_x="1" rot_y="0" rot_z="0" rot_a="0.000690534" scale_x="0.7" scale_y="0.7" scale_z="0.7" />
    <sceneShape id="1521" name="Mike_2_1" shapeGroup="1" pos_x="3" pos_y="-3" pos_z="0" rot_x="1" rot_y="0" rot_z="0" rot_a="0.000690534" scale_x="0.7" scale_y="0.7" scale_z="0.7" />
    <sceneShape id="1522" name="Mike_2_2" shapeGroup="1" pos_x="3" pos_y="-6" pos_z="0" rot_x="1" rot_y="0" rot_z="0" rot_a="0.000690534" scale_x="0.7" scale_y="0.7" scale_z="0.7" />
    <sceneShape id="1523" name="Target_0_0" shapeGroup="3" pos_x="-12" pos_y="0" pos_z="0" rot_x="1" rot_y="0" rot_z="0" rot_a="0.000690534" scale_x="1" scale_y="1" scale_z="0.5" />
    <sceneShape id="1524" name="Target_1_0" shapeGroup="3" pos_x="12" pos_y="0" pos_z="0" rot_x="1" rot_y="0" rot_z="0" rot_a="0.000690534" scale_x="1" scale_y="1" scale_z="0.5" />
    <sceneShape id="1525" name="OtherTarget_0_0" shapeGroup="3" pos_x="-12" pos_y="-24" pos_z="0" rot_x="1" rot_y="0" rot_z="0" rot_a="0.000690534" scale_x="1" scale_y="1" scale_z="0.5" />
    <sceneShape id="1526" name="OtherTarget_1_0" shapeGroup="3" pos_x="12" pos_y="-24" pos_z="0" rot_x="1" rot_y="0" rot_z="0" rot_a="0.000690534" scale_x="1" scale_y="1" scale_z="0.5" />
</sceneShapeGroup>

chriscalef
 
Posts: 2
Joined: Sat Aug 13, 2016 11:56 pm

Re: Script to load_and_retarget BVH files in blender

Postby chriscalef » Tue Feb 21, 2017 7:22 pm

FIXED!

I had to go into makeWalk code, in retarget.py, in loadRetargetSimplify, and change the target rig from context.object to context.selected_objects[0].

Whew!
chriscalef
 
Posts: 2
Joined: Sat Aug 13, 2016 11:56 pm


Return to Python scripts

Who is online

Users browsing this forum: No registered users and 1 guest

cron