Milkshape to Blender batch convert

I’m pretty new to Blender and Python and I’m trying to adapt a script I’ve found in another forum to batch convert a few hundred milkshape 3d files to blender.

I am currently baffled as to why the code is not working as when run it cannot find bpy.ops.import_scene.ms3d even though that importer is enabled and i can manually do this inside of blender through the ui. I am currently loading up the script in the text editor and running it through there and I get the error:

Attribute Error : calling “bpy.ops.import_scene.ms3d” error, cannot be found

I suspect that my call to bpy.ops.export_scene.blend may also be incorrect too but I’m currently hung up on the first issue. If anybody could possibly take the time to help a newbie out I would be most grateful!

Thanks in advance for any help and advice!

My script is pasted below:


CONVERT_DIR = "C:/Dev/ms3dmodels"


import os


def file_iter(path, ext):
    for dirpath, dirnames, filenames in os.walk(path):
        for filename in filenames:
            ext = os.path.splitext(filename)[1]
            if ext.lower().endswith(ext):
                yield os.path.join(dirpath, filename)


import bpy




def reset_blend():
    bpy.ops.wm.read_factory_settings()


    for scene in bpy.data.scenes:
        for obj in scene.objects:
            scene.objects.unlink(obj)


    # only worry about data in the startup scene
    for bpy_data_iter in (
            bpy.data.objects,
            bpy.data.meshes,
            bpy.data.lamps,
            bpy.data.cameras,
            ):
        for id_data in bpy_data_iter:
            bpy_data_iter.remove(id_data)




def convert_recursive(base_path):
    print("Converting...");
        
    for filepath_src in file_iter(base_path, ".ms3d"):
        filepath_dst = os.path.splitext(filepath_src)[0] + ".blend"


        print("Converting %r -> %r" % (filepath_src, filepath_dst))


        reset_blend()


        bpy.ops.import_scene.ms3d(filepath=filepath_src)
        bpy.ops.export_scene.blend(filepath=filepath_dst)




if __name__ == "__main__":
    convert_recursive(CONVERT_DIR)

Hi!
Did you instal addons for import-export .ms3d files ? https://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Import-Export/MilkShape3D_MS3D
This is required for your work.

Yes I have the .ms3d importer installed, I can manually import .ms3d via the import menu, it is enabled and set as default. I can also see the ms3d import scripts in the addons directory inside of the blender install.

I suspect that maybe its something to do with the way the script is setup… and perhaps its only setup for importing via UI?

I’m not really sure as im only a n00b with Python.

I’m seeing that the bl_idname is declared inside of ms3d_ui.py and not init.py? is this the problem maybe?

[TABLE="class: highlight tab-size js-file-line-container"]





class Ms3dImportOperator(Operator, ImportHelper):



    """ Load a MilkShape3D MS3D File """



    bl_idname = 'import_scene.ms3d'

[/TABLE]

Do you have activated the User prefs > File>Auto run python file please?

Solution 1 > your script is correct!, I see only this python possiblity!

EDIT 1:
Solution 2 > You can too remove this line and try again without:
bpy.ops.wm.read_factory_settings()

Try it. This code works well for me.


CONVERT_DIR = "C:/Dev/ms3dmodels"


import os


def file_iter(path, ext):
    for dirpath, dirnames, filenames in os.walk(path):
        for filename in filenames:
            curr_ext = os.path.splitext(filename)[1]
            if curr_ext.lower().endswith(ext):
                yield os.path.join(dirpath, filename)


import bpy




def reset_blend():
    for scene in bpy.data.scenes:
        for ob in bpy.context.scene.objects:
            ob.select = True
            bpy.ops.object.delete()


def convert_recursive(base_path):
    print("Converting...");
        
    for filepath_src in file_iter(base_path, ".ms3d"):
        filepath_dst = os.path.splitext(filepath_src)[0] + ".blend"


        print("Converting %r -> %r" % (filepath_src, filepath_dst))


        reset_blend()


        bpy.ops.import_scene.ms3d(filepath=filepath_src)
    #    bpy.ops.export_scene.blend(filepath=filepath_dst)
        bpy.ops.wm.save_as_mainfile(filepath=filepath_dst)




if __name__ == "__main__":
    convert_recursive(CONVERT_DIR)

Thanks for the help guys! I managed to get this working by enabling the autorun, ticking “register” before running the script (not sure if i had to do that or not) and also modifying the script slightly… pasting the script below in case it helps anybody in the future.

Thanks again!

CONVERT_DIR = "C:/Dev/ms3dmodels"


import os




def file_iter(path, ext):
    for dirpath, dirnames, filenames in os.walk(path):
        for filename in filenames:
            curr_ext = os.path.splitext(filename)[1]
            if curr_ext.lower().endswith(ext):
                yield os.path.join(dirpath, filename)




import bpy








def reset_blend():
    for scene in bpy.data.scenes:
        for obj in scene.objects:
            scene.objects.unlink(obj)




def convert_recursive(base_path):
    print("Converting...");
        
    for filepath_src in file_iter(base_path, ".ms3d"):
        filepath_dst = os.path.splitext(filepath_src)[0] + ".blend"




        print("Converting %r -> %r" % (filepath_src, filepath_dst))




        reset_blend()




        bpy.ops.import_scene.ms3d(filepath=filepath_src)
    #    bpy.ops.export_scene.blend(filepath=filepath_dst)
        bpy.ops.wm.save_as_mainfile(filepath=filepath_dst)








if __name__ == "__main__":
    convert_recursive(CONVERT_DIR)