1
$\begingroup$

I have 97 MDD files created from different meshes (armature deformed, cloth deformed etc). Is there a way to select multiple meshes and export them as individual MDD files?

I have seen that there's another post which provides an add-on to export selected objects to FBX, but unfortunately I do not have the skills adapting it to work for MDD files: Exporting multiple meshes individually at once

My progress so far: I've found someone trying to export multiple MDD at once on another forum, and it seems that there's a Python command line to export a MDD: bpy.ops.export_shape.mdd(fps=24, frame_start=1, frame_end=250). Also, there's a python template for Batch exporting:

import bpy
import os

# export to blend file location
basedir = os.path.dirname(bpy.data.filepath)

if not basedir:
    raise Exception("Blend file is not saved")

view_layer = bpy.context.view_layer

obj_active = view_layer.objects.active
selection = bpy.context.selected_objects

bpy.ops.object.select_all(action='DESELECT')

for obj in selection:

    obj.select_set(True)

    # some exporters only use the active object
    view_layer.objects.active = obj

    name = bpy.path.clean_name(obj.name)
    fn = os.path.join(basedir, name)

    bpy.ops.export_scene.fbx(filepath=fn + ".fbx", use_selection=True)

    # Can be used for multiple formats
    # bpy.ops.export_scene.x3d(filepath=fn + ".x3d", use_selection=True)

    obj.select_set(False)

    print("written:", fn)


view_layer.objects.active = obj_active

for obj in selection:
    obj.select_set(True)

How can I export multiple .MDD files ?

$\endgroup$
9
  • $\begingroup$ Is there any mdd exporter already? If so you just have to replace export_scene.fbx() operator and all corresponding properties/arguments. $\endgroup$ – brockmann Dec 20 '20 at 18:06
  • $\begingroup$ @brockmann (I deleted my answer and edited my original post). What do you mean ? Yes, there's a .mdd exporter built in Blender but no option for Batch exporting is displayed. As I said, I don't understand how Python works, and replacing the ".fbx" by ".mdd" gives me an error. Also, I don't know any Python functions, neither specific .mdd arguments. So I need help here, I guess mixing the Batch Export template with the specific .mdd exporting function will do the trick ? $\endgroup$ – Pdhm Dec 20 '20 at 18:22
  • $\begingroup$ Modified the code of the linked answer: pasteall.org/UhqR Make sure the other mdd exporter is enabled, run the code in the text editor, please test and report back. $\endgroup$ – brockmann Dec 20 '20 at 18:41
  • $\begingroup$ Hey, thanks for your help. Yes, the MDD exporter add-on is enabled. Copy/Pasted the code in the text editor, saved it and hitted run : bpy.ops.text.run_script() in the system console aand.. that's it. Nothing else happens, no .mdd output in the directory, no loading time after hitting the Play button :/ $\endgroup$ – Pdhm Dec 21 '20 at 9:49
  • $\begingroup$ Go to File > Export > Batch export mdd to execute the process (as usual). $\endgroup$ – brockmann Dec 21 '20 at 9:50
1
$\begingroup$

Addon based on this answer, adapted to export all objects in selection to single .mdd files. Make sure 'NewTekk MDD format' add-on is enabled and install the add-on as usual:

enter image description here

batch_mdd_export.py

# ##### BEGIN GPL LICENSE BLOCK #####
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software Foundation,
#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
​
bl_info = {
    "name": "Batch export MDD files",
    "author": "brockmann",
    "version": (0, 1, 0),
    "blender": (2, 80, 0),
    "location": "File > Import-Export",
    "description": "Batch Export Objects in Selection to MDD",
    "warning": "",
    "wiki_url": "",
    "tracker_url": "",
    "category": "Import-Export"}
​
​
import bpy
import os
​
from bpy_extras.io_utils import ExportHelper
​
from bpy.props import (BoolProperty,
                       FloatProperty,
                       IntProperty,
                       StringProperty,
                       EnumProperty,
                       CollectionProperty
                       )
​
​
class Batch_MDD_Export(bpy.types.Operator, ExportHelper):
    """Batch export objects to fbx files"""
    bl_idname = "export_scene.batch_mdd"
    bl_label = "Batch export MDD"
    bl_options = {'PRESET', 'UNDO'}
​
    # ExportHelper mixin class uses this
    filename_ext = ".mdd"
​
    filter_glob : StringProperty(
            default="*.mdd",
            options={'HIDDEN'},
            )
​
    # List of operator properties, the attributes will be assigned
    # to the class instance from the operator setting before calling.
    
    # Context group
    use_selection_setting: BoolProperty(
            name="Selection Only",
            description="Export selected objects only",
            default=True,
            )
​
    use_rest_frame: BoolProperty(
            name="Use Rest Frame",
            description="ToDo",
            default=False,
            )
            
    frames_per_second: FloatProperty(
            name="FPS",
            description="ToDo",
            min=1, max=60,
            default=25,
            )
​
    frame_start: IntProperty(
            name="Frame Start",
            description="ToDo",
            default=1,
            )
    
    frame_end: IntProperty(
            name="Frame End",
            description="ToDo",
            default=250,
            )
            
    def execute(self, context):                
​
        # get the folder
        folder_path = os.path.dirname(self.filepath)
​
        # get objects selected in the viewport
        viewport_selection = context.selected_objects
​
        # get export objects
        obj_export_list = viewport_selection
        if self.use_selection_setting == False:
            obj_export_list = [i for i in context.scene.objects]
​
        # deselect all objects
        bpy.ops.object.select_all(action='DESELECT')
​
        for item in obj_export_list:
            item.select_set(True)
            if item.type == 'MESH':
                context.view_layer.objects.active = item # Set active object
                file_path = os.path.join(folder_path, "{}.mdd".format(item.name))
​
                # MDD settings
                bpy.ops.export_shape.mdd(
                        filepath=file_path,
                        fps=self.frames_per_second,
                        frame_start=self.frame_start,
                        frame_end=self.frame_end
                        )
​
            item.select_set(False)
​
        # restore viewport selection
        for ob in viewport_selection:
            ob.select_set(True)
​
        return {'FINISHED'}
​
​
# Only needed if you want to add into a dynamic menu
def menu_func_import(self, context):
    self.layout.operator(Batch_MDD_Export.bl_idname, text="MDD Batch Export (.mdd)")
​
​
def register():
    bpy.utils.register_class(Batch_MDD_Export)
    bpy.types.TOPBAR_MT_file_export.append(menu_func_import)
​
​
def unregister():
    bpy.utils.unregister_class(Batch_MDD_Export)
    bpy.types.TOPBAR_MT_file_export.remove(menu_func_import)
​
​
if __name__ == "__main__":
    register()
​
    # test call
    #bpy.ops.export_scene.batch_mdd('INVOKE_DEFAULT')

I added all possible arguments of the 'lightwave point cache' operator export_shape.mdd(), see line 117. You can change them or add new properties to the operator, wasn't sure.

$\endgroup$
4
  • $\begingroup$ Hey, just giving you a feedback : it seems that this script exports the same mesh (the active one, so the first one) over and over. In my case I have the same .mdd for 97 times. I understand that the "for" is used to do an incremental .mdd export but I was not able to find how to correct it. Could you give it a try ? Sorry to ask for your help again :/ $\endgroup$ – Pdhm Dec 22 '20 at 12:52
  • $\begingroup$ Oh and I forgot to mention that the names are correctly set ! $\endgroup$ – Pdhm Dec 22 '20 at 13:17
  • $\begingroup$ Not sure I can properly test the output since I don't have access to Lightwave. Might be necessary to set the current object to the active one, updated the code: pasteall.org/2ukq Does that work? @Pdhm $\endgroup$ – brockmann Dec 22 '20 at 13:28
  • 1
    $\begingroup$ First, thanks for helping me in such an efficient way, I really appreciate it. Secondly : YES it worked ! :) I tested it on three .mdd exports for a limited amount of frames but it worked. I'll give a try over a lot more now but I need an hour of calculation. Will update you in a couple of hours. Again, thank you very much ! $\endgroup$ – Pdhm Dec 22 '20 at 13:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.