4
$\begingroup$

Looking for a script that runs through the animation frames and at each keyframe it exports just the mesh as a .fbx (no cameras, bones or helpers) at that specific frame, preferably with a filename that includes the frame number.

If nothing like this exists, I'll attempt to write it myself soon, but I've never written a blender script before and it's been years since I used Python at all, so I may need some instruction (library reference or similar).

Using this output as an input for morph targets in another application.

$\endgroup$
2
  • $\begingroup$ There is the Lightwave pointcache .mdd exporter (with blender - enable it). Could be a place to start as it exports mesh at each frame but all into one file. You can browse/search blenders api reference online $\endgroup$
    – sambler
    May 30, 2015 at 11:54
  • $\begingroup$ What about exporting obj's instead of fbx? $\endgroup$
    – p2or
    May 31, 2015 at 15:58

2 Answers 2

5
$\begingroup$

You may get away with

I.e. select your meshes and run

import bpy

PATH = "your_path.%03d.fbx"

for i in range(100):
    bpy.context.scene.frame_set(i)
    bpy.ops.export_scene.fbx(
        filepath=PATH % i,
        object_types={'MESH'},
        use_selection=True
        )

The source code of export_scene.fbx resides in scripts/addons/io_scene_fbx.

$\endgroup$
2
$\begingroup$

This is my first draft at a solution. When I re-import one of the exported meshes it looks good. It is possible that someone else can find a better way to do it, and I welcome comments (and feel free to post a modified solution based on my code).

http://web.purplefrog.com/~thoth/blender/python-cookbook/pose-sequence-to-fbx.html

import bpy

def find_modifier_of_type(obj, type):
    for mod in obj.modifiers:
        if mod.type==type:
            return mod
    return None

def duplicate_and_apply_armature(scn, src):

    scn.objects.active = src
    for obj in scn.objects:
        obj.select = ( obj==src)

    bpy.ops.object.duplicate(linked=False)

    dup_obj = bpy.context.active_object

    dup_obj.name = "duplicate for %d"%scn.frame_current

    mod = find_modifier_of_type(dup_obj, 'ARMATURE')

    bpy.ops.object.modifier_apply(modifier=mod.name)

    return dup_obj


def find_pose_frames(obj):

    frames = set()

    mod = find_modifier_of_type(obj, 'ARMATURE')
    if mod is None:
        raise BaseException("active object does not have an ARMATURE modifier")
    arm = mod.object

    action = arm.animation_data.action
    for fc in action.fcurves:
        if fc.data_path[:10] != "pose.bones":
            # don't care about whatever this is
            continue
        for kp in fc.keyframe_points:
            frames.add(kp.co.x)

    return sorted(frames)

def mission1(scn, obj):

    export_pattern = "/tmp/cube-%d.fbx"
    for fr in find_pose_frames(obj):
        scn.frame_set(fr)
        dup_obj = duplicate_and_apply_armature(scn, obj)

        # this function has a LOT of flags, and I don't know what they all do.
        bpy.ops.export_scene.fbx(filepath=(export_pattern %scn.frame_current),  use_selection=True)

        scn.objects.unlink(dup_obj)

    scn.objects.active = obj


scn = bpy.context.scene
mission1(scn, bpy.context.active_object)
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .