4

I have two files one .bvh and the other is .c3d and I want to convert them to .bvh files if anyone could please advise how to do this as I need to work on bvh only.

Tak
  • 6,293
  • 7
  • 43
  • 85
  • Can you provide both files for testing? You can import the .c3d into blender and export it as .bvh. http://stackoverflow.com/questions/20499320/how-to-import-c3d-files-into-blender – Jaroslav Jerryno Novotny May 14 '15 at 09:12
  • @Jerryno this is the c3d file https://www.dropbox.com/s/dfmi0wffsurl0ae/file.c3d?dl=0 and in the link you provided it shows how to import .c3d file into blender (which I already did), my problem is how to convert it into .bvh – Tak May 14 '15 at 09:18
  • @batFINGER I've tried it but once I try to unzip the compressed file it needs a password, any thoughts? – Tak Mar 14 '16 at 03:09
  • @batFINGER did you have the chance to check my previous comment? – Tak Mar 15 '16 at 09:41
  • Yep, sorry looks like a bum steer, both downloading program, or the even bigger zip created from a small sample c3d from http://www.c3d.org – batFINGER Mar 15 '16 at 10:11
  • @batFINGER I don't understand. So does this work or not? – Tak Mar 15 '16 at 10:21
  • No, didn't get it to work either. Could you repost your c3d file link, might get around to writing a script to automate @Jerryno 's method, or at least make a hierarchal structure from the names. – batFINGER Mar 16 '16 at 05:28
  • @batFINGER sorry for the late reply. Here is a link to the file https://www.dropbox.com/s/px9qe3vdsp0cak0/File1.c3d?dl=0 – Tak Mar 22 '16 at 12:14

2 Answers2

5

You can import .c3d file in blender like this:

https://stackoverflow.com/questions/20499320/how-to-import-c3d-files-into-blender

The problem is it won't be an armature, but animated locations of points:

enter image description here

Some points will be dead in the center (marked).

  1. Adjust the frame range to fit the mocap data
  2. Delete the dead markers
  3. Re-build the armature - add armature to scene

    • looks like we have markers from both sides for each leg - that means the bones will be somewhere in between markers

    • Building the armature:

      • select a marker (or two if I want position in between) and align 3D cursor with 'Shift-S > Cursor to Selected'
      • then enter edit-mode of armature and select a joint and 'Shift-S > Selection to Cursor'
      • this way I can place all the bones (joints) precisely

        enter image description here

      • also recalculate the Roll of the bones with 'Ctrl+N > Cursor' with 3D cursor on some reference marker

    • Name the bones properly

    • Constraining location of root bones:

      • use copy_location constraint
      • or two of them with second on 50% influence to get in-between position of two markers
      • similar for center of 3 markers, you get the idea
    • Constraining bones direction

      • use damped_track constraint
      • also multiple of them with adjusted influence for center of group of markers

        enter image description here

  4. Bake the animation to Action with Pose > Animation

    Bake Action: visual_keying_ON, clear_constraints_ON

  5. Export armature as .bvh from the blender main menu (you might need to enable BVH addon).

These steps will result in having a .c3d file converted to a .bvh file. A sample .blend file with rigged markers here:

Jaroslav Jerryno Novotny
  • 51,077
  • 7
  • 129
  • 218
  • Is it possible to share with me a file with the modified steps so that I can go through them and have a reference? – Tak May 15 '15 at 01:37
  • @shepherd yep, I'll rig one leg or something and give the .blend. I suspect this is a dog am I right? (for anatomy reference) – Jaroslav Jerryno Novotny May 15 '15 at 05:27
  • @shepherd, yep, you only add 1 armature object to the scene and then you add bones to it in edit-mode (Tab). You can extrude a bone from a joint with E or add a new bone to 3D cursor location with Shift-A. This way you end only with 1 object with multiple bones inside.) If you have multiple armatures you can fix it with selecting them and joining them into one with Ctrl-J – Jaroslav Jerryno Novotny May 16 '15 at 18:37
  • Thank you very much again. I've been using these steps manually but now I need a script as I have many files. I've followed the answer below given by batFINGER and constructed the armature found here https://www.dropbox.com/s/nx8xsk4z0pavaxx/ArmatureToTpose.blend?dl=0 then I try to put the armature in Tpose to parent to my mesh with automatic weighting using the batFINGER's answer found here http://blender.stackexchange.com/a/53981/2517 you will find that the mesh is doesn't look good, kinda twisted and during the animation it get's ugly, I'm not sure why? is it because of the bone roll value? – Tak Nov 19 '16 at 09:31
  • so as you suggested, I've used DAMPED_TRACK instead of TRACK_TO used by batFINGER. And the mesh still looks bad using con = pb.constraints.new('DAMPED_TRACK') con.target = bpy.data.objects.get(pb.name) con.track_axis = 'TRACK_Y' con.influence = 1 – Tak Nov 19 '16 at 09:33
  • A screenshot when using TRACK_TO at frame 70 can be found here https://www.dropbox.com/s/lbqw9xj3jzxur05/TRACK_TOFrame70twisted.PNG?dl=0 and a screenshot when using DAMPED_TRACK at frame 70 can be found here https://www.dropbox.com/s/lryeqaxxa6h7518/DAMPED_TRACKFrame70twisted.PNG?dl=0 . The mesh I'm using can be found here https://www.dropbox.com/s/rzl5k98zkdhlw4y/human_mesh_good.dae?dl=0 Could you please have a look and let me know what you think? I'm really trying to figure out why this is happening and don't know. So I'd be grateful if you could please have a look. – Tak Nov 19 '16 at 09:34
  • @Tak Hi, the constraints need to be damped_track for sure. Reset all pose bone transforms and check if the 'pose' pose and 'rest' pose are the same - they need to be. If not, some constraints are rotating bones on their own so "Apply pose as rest pose": http://blender.stackexchange.com/a/49804/7777. Also constraints rotate in Y axis only +-180°, so if your point cloud is making rotations beyond that you will see bone flipping. There is no defense against it in Blender, other than making rotations with drivers instead of constraints. I need to inspect the .blend with animation for better help – Jaroslav Jerryno Novotny Nov 19 '16 at 10:16
  • thank you very much. Yes please if you could have a look at my file and see the screenshots. This is the file where I made the TPose https://www.dropbox.com/s/aujsase0ymgue7j/ArmatureToTpose2.blend?dl=0 I'm not sure, may be I did it wrong (like with bone rotations,...etc) – Tak Nov 19 '16 at 10:26
  • @Tak There is definitely a flip on the bone MyBone_1_3_1_1 between frames 6 and 7. It is hard to tell why though. Do you have a file where the animation is not baked but is driven by the point-cloud and constraints? If not your best and fastest option is to clean the animation manually. – Jaroslav Jerryno Novotny Nov 19 '16 at 13:45
  • as requested, kindly find the file containing the .c3d points found here https://www.dropbox.com/s/vnzfszkplhyd8dv/c3d.blend?dl=0 , thank you very much for your help and kind assistance, I really appreciate it. – Tak Nov 20 '16 at 00:03
  • I've posted what you requested on the chat room here: http://chat.stackexchange.com/rooms/48803/room-for-tak-and-jerryno so if you could please have a look. Thank you very much. – Tak Nov 22 '16 at 23:20
  • Hello Jerryno, I hope you are well. Could you please join this room http://chat.stackexchange.com/rooms/54096/room-for-tak-and-jerryno ? I need your help as I'm really stuck for weeks now so I'll b really grateful. – Tak Feb 22 '17 at 22:33
  • Hi @Tak, yes joining the room. I am writing this comment because I am not sure if SE notifies with chat rooms correctly (sometimes I don't get notification for new room chat messages). – Jaroslav Jerryno Novotny Feb 23 '17 at 15:27
  • Hello Jerryno, Could we please have a quick chat here http://chat.stackexchange.com/rooms/55778/room-for-tak-and-jerryno ? I need your advice in something I've been trying to solve but no hope for me. – Tak Mar 21 '17 at 20:41
1

Created a script to create a hierarchal armature and add constraints to animate.

enter image description here

Firstly import the c3d with a prefix, I've chosen "GT_", this makes it easier to clean up.

import bpy
context = bpy.context
scene = context.scene
prefix = "GT_"
# select all imported with prefix GT_
obs = [o for o in scene.objects if o.name.startswith(prefix)]
root = "RootDog"

# clean up unwanted objects could look for flat action sum.

text = bpy.data.texts.get("C3D_bones")
if not text:
    text = bpy.data.texts.new("C3D_bones")

text.clear()

bones = {}    
for o in obs:
    if o.location.length < 0.0000001:
        scene.objects.unlink(o)
        bpy.data.objects.remove(o)
    else:
        name = o.name[3:]
        print(bones)
        bones[name] = {"parent":None,
                       "tail":root}

names = sorted(bones.keys())
text.write("%s\n" % root)
for name in names: 
    if name == root:
        continue    
    text.write("\t%s\n" % name)   

It creates a text object with a simple structure. Tabs must be used to indent. Like

RootDog
    LBackElbow
    LBackLeg
    LBackPaw

Which was quite simple to edit into, and I renamed to "C3DBones.txt" to avoid overwriting with previous script.

RootDog
    RFrontWaistDog
        RBackWaistDog
            RBackElbow
                RBackLeg
                    RBackPaw
    LFrontWaistDog
        LBackWaistDog
            LBackElbow
                LBackLeg
                    LBackPaw
    LowBackDog
        MidbackDog
            TopSpineDog
                RFShoulderDog
                    RElbowDog
                        RForeLeg
                            RPaw
                LFhoulderDog
                    LElbowDog
                        LForeLeg
                            LPaw                    
                MidDoghead
                    LeftDogHead
                    RightDogHead

Lastly, the hierarchy is used to create a rig and add constraints.

import bpy
from mathutils import Vector
context = bpy.context
scene = context.scene

text = bpy.data.texts.get("C3D_bones.txt")
prefix = "GT_"
parent_level = 0
parents = [None] * 16


arm = bpy.data.armatures.new("Armature")

rig = bpy.data.objects.new("C3DRig", arm)
scene.objects.link(rig)
scene.objects.active = rig
scene.update()
bpy.ops.object.mode_set(mode='EDIT')

for l in text.lines:

    body = l.body
    level = 0
    while body.startswith("\t"):
        body = body[1:]
        level += 1
    print(l.body, level)
    body = "%s%s" % (prefix, body)
    bone = arm.edit_bones.new(body)

    o = scene.objects.get(body)
    if not o:
        print("No %s" % body)
        continue

    bone.tail = o.location
    parent_level = max(level-1, 0)
    parents[level] = o
    parent = parents[parent_level]

    bone.parent = arm.edit_bones.get(parent.name)
    if bone.parent:
        bone.head = bone.parent.tail

bone = arm.edit_bones.get(parents[0].name)
if bone:    
    bone.head = bone.tail + Vector([0, 0, 1])
    bpy.ops.object.mode_set(mode='OBJECT')
else:
    print("no root bone")    

# do something with pose bones

for pb in rig.pose.bones:
    con = pb.constraints.new('COPY_LOCATION')
    if not pb.parent:
        con.target = bpy.data.objects.get(pb.name) 
        continue

    con.target = bpy.data.objects.get(pb.parent.name)
    con = pb.constraints.new('TRACK_TO')
    con.target = bpy.data.objects.get(pb.name)

batFINGER
  • 84,216
  • 10
  • 108
  • 233
  • Thanks for that. Could you send me a link of the blend file please? – Tak Mar 23 '16 at 02:25
  • 1
    Done, note it only creates a rig and animates it off the c3d empties. Connect bones where desired and add limit rot constraints etc to fix bone roll, or use the methods suggested by @Jerryno. Also the root bone loc is kinda crap. Might need to add a constrained empty half way between the waists and use that instead of RootDog. Once that is done I'd pose into a rest position, and change to this rest pos. (currently has the rest pose of the pose of the frame on which the 2nd script is run) – batFINGER Mar 23 '16 at 03:52
  • 1
    Sample with tween waist empty as root. http://www.pasteall.org/blend/41189 – batFINGER Mar 23 '16 at 05:59
  • Is it possible to make the constructed root bone very small so it's not visible? I've tried doing this from the 3d view and it looks like this can be done by going to editmode then selecting the tail of it and then translating it by -1 along the Z-axis. – Tak Nov 14 '16 at 11:58
  • I was able to solve it using context.object.data.edit_bones[0].select_head = True then bpy.ops.transform.translate(value=(0, 0, -0.99), constraint_axis=(False, False, True), constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1) {'FINISHED'} – Tak Nov 14 '16 at 12:42
  • I've been using this to create my armature, but I want to avoid the bone roll. As shown in this file some bones will have this problem where the bone rolls between the rest position (frame0 tpose) and the rest of the animation. Could you please help me fix it as I've been trying to fix it for more than a week now please? https://www.dropbox.com/s/cresv2kdm448frw/steps.blend?dl=0 – Tak Feb 20 '17 at 13:46
  • Hello batFINGER, could you please guide me and advise how to tackle my problem, is it possible to fix this rolling issue when the armature is constructed using this script? I'd really appreciate it if you could please advise as I'm really stuck for a long time now and I can't find a way, so I'd be grateful for your advice. Thank you very much – Tak Feb 22 '17 at 08:45