path_to_obj_dir = os.path.join(‘C:\Temp\obj’)
n = 0
m = 0
get list of all files in directory
file_list = os.listdir(path_to_obj_dir)
get a list of files ending in ‘obj’
obj_list = [item for item in file_list if item[-3:] == ‘obj’]
loop through the strings in obj_list and add the files to the scene
for item in obj_list:
path_to_file = os.path.join(path_to_obj_dir, item)
bpy.ops.import_scene.obj(filepath = path_to_file)
n = n + 1
m = n-1
bpy.context.scene.layers[n] = True
bpy.context.scene.layers[m] = False
scene = bpy.context.scene
for obj in scene.objects:
obj.location.x += 1.0
The intention with the script is that It imports one obj on the first picked layer, then it moves to next layer and imports next .obj
Very nice to have when you got a lots of obj: to import and want to have them on seperate layers.
@wilnix and @dustractor
If you are going to invoke the file browser, I suggest using the files collection already available, the filter_glob, and adding the select all button to the draw method. This gives the opportunity to leave out a pesky obj monster that may be lurking.
bl_info = {"name":"Batch OBJ Import","category":"Import-Export"}
import bpy
from bpy.types import Operator, OperatorFileListElement
from bpy.props import (StringProperty, CollectionProperty, BoolProperty)
from bpy_extras.io_utils import ImportHelper
import os
class OBJIM_OT_batch_import_objs_from_dir(Operator, ImportHelper):
bl_idname = "objim.batch"
bl_label = "Batch Import .OBJ's in Path..."
directory = StringProperty(subtype="DIR_PATH")
filename_ext = ".obj"
filter_glob = StringProperty(default="*.obj", options={'HIDDEN'})
files = CollectionProperty(name="OBJ Files", type=OperatorFileListElement)
seperate_layers = BoolProperty(name="Seperate Layers",
default=False,
description="Import each OBJ into its own layer")
def invoke(self,context,event):
context.window_manager.fileselect_add(self)
return {"RUNNING_MODAL"}
def draw(self, context):
layout = self.layout
layout.operator("file.select_all_toggle")
layout.prop(self, "seperate_layers", toggle=True)
def execute(self,context):
for layer, file in enumerate(self.files):
objpath = os.path.join(self.directory, file.name)
bpy.ops.import_scene.obj(filepath=objpath)
if self.seperate_layers:
layers = [i == layer for i in range(20)]
for obj in context.selected_objects:
obj.layers = layers
return {"FINISHED"}
def register():
bpy.utils.register_module(__name__)
if __name__ == "__main__":
register()
# test call
bpy.ops.objim.batch('INVOKE_DEFAULT')
Otherwise, if you are going to import all objs in a folder, why bother with the file browser?
PS: I stuck in a flag for separate layers. You’ll have to put the workings in for “the first picked layer”
As obj files are often a bunch of objects, I put each file import on a separate layer.
PPS… also the import will have no layers if more than 20 files are selected.
probably don’t need to invoke the filebrowser, could rather just have a FILE_DIR stringprop for which directory to export to. Anyway heres a start.
It exports each mesh in selected_objects to <object.name>.obj in the directory selected.
import bpy
# ExportHelper is a helper class, defines filename and
# invoke() function which calls the file selector.
from bpy_extras.io_utils import ExportHelper
from bpy.props import StringProperty, BoolProperty, EnumProperty
from bpy.types import Operator
from os.path import join
class ExportSomeData(Operator, ExportHelper):
"""This appears in the tooltip of the operator and in the generated docs"""
bl_idname = "export_test.some_data" # important since its how bpy.ops.import_test.some_data is constructed
bl_label = "Export Some Data"
# ExportHelper mixin class uses this
filename_ext = ".obj"
directory = StringProperty(subtype="DIR_PATH")
filter_glob = StringProperty(
default="*.obj",
options={'HIDDEN'},
)
@classmethod
def poll(cls, context):
return bool(len([obj.name for obj in context.selected_objects if obj.type == 'MESH']))
def execute(self, context):
scene = context.scene
objs = [obj for obj in context.selected_objects if obj.type == 'MESH']
active_obj = scene.objects.active
for obj in objs:
bpy.ops.object.select_all(action='DESELECT')
obj.select = True
filepath = join(self.directory, "%s.obj" % obj.name)
bpy.ops.export_scene.obj(filepath=filepath, use_selection=True)
# return state
for obj in objs:
obj.select = True
scene.objects.active = active_obj
return {'FINISHED'}
# Only needed if you want to add into a dynamic menu
def menu_func_export(self, context):
self.layout.operator(ExportSomeData.bl_idname, text="Batch Export OBJs")
def register():
bpy.utils.register_class(ExportSomeData)
bpy.types.INFO_MT_file_export.append(menu_func_export)
def unregister():
bpy.utils.unregister_class(ExportSomeData)
bpy.types.INFO_MT_file_export.remove(menu_func_export)
if __name__ == "__main__":
register()
# test call
bpy.ops.export_test.some_data('INVOKE_DEFAULT')
Without looking into it too deeply, I’d assume it’s a scene exporter, and even tho the only_selected is checked it gives the assets from the scene.
A possible work around would be to create a dummy empty scene, link the object, export the scene, unlink the object etc.
Untested
import bpy
# ExportHelper is a helper class, defines filename and
# invoke() function which calls the file selector.
from bpy_extras.io_utils import ExportHelper
from bpy.props import StringProperty, BoolProperty, EnumProperty
from bpy.types import Operator
from os.path import join
class ExportSomeData(Operator, ExportHelper):
"""This appears in the tooltip of the operator and in the generated docs"""
bl_idname = "export_test.some_data" # important since its how bpy.ops.import_test.some_data is constructed
bl_label = "Export Some Data"
# ExportHelper mixin class uses this
filename_ext = ".obj"
directory = StringProperty(subtype="DIR_PATH")
filter_glob = StringProperty(
default="*.obj",
options={'HIDDEN'},
)
@classmethod
def poll(cls, context):
return bool(len([obj.name for obj in context.selected_objects if obj.type == 'MESH']))
def execute(self, context):
scene = context.scene
objs = [obj for obj in context.selected_objects if obj.type == 'MESH']
active_obj = scene.objects.active
dummy_scene = bpy.data.scenes.new("Dummy")
context.screen.scene = dummy_scene
for obj in objs:
#bpy.ops.object.select_all(action='DESELECT')
dummy_scene.objects.link(obj)
filepath = join(self.directory, "%s.obj" % obj.name)
bpy.ops.export_scene.obj(filepath=filepath)
dummy_scene.objects.unlink(obj)
# return state
bpy.ops.scene.delete()
context.screen.scene = scene
return {'FINISHED'}
# Only needed if you want to add into a dynamic menu
def menu_func_export(self, context):
self.layout.operator(ExportSomeData.bl_idname, text="Batch Export OBJs")
def register():
bpy.utils.register_class(ExportSomeData)
bpy.types.INFO_MT_file_export.append(menu_func_export)
def unregister():
bpy.utils.unregister_class(ExportSomeData)
bpy.types.INFO_MT_file_export.remove(menu_func_export)
if __name__ == "__main__":
register()
# test call
bpy.ops.export_test.some_data('INVOKE_DEFAULT')
Hi batFinger
I can not get this to work as an Addon, first what should I call the .py file?
/Wilnix
And the Code:
bl_info = {“name”:“Batch OBJ Import”,“category”:“Import-Export”}
import bpy
from bpy.types import Operator, OperatorFileListElement
from bpy.props import (StringProperty, CollectionProperty, BoolProperty)
from bpy_extras.io_utils import ImportHelper
seperate_layers = BoolProperty(name="Seperate Layers",
default=False,
description="Import each OBJ into its own layer")
def invoke(self,context,event):
context.window_manager.fileselect_add(self)
return {"RUNNING_MODAL"}
def draw(self, context):
layout = self.layout
layout.operator("file.select_all_toggle")
layout.prop(self, "seperate_layers", toggle=True)
def execute(self,context):
for layer, file in enumerate(self.files):
objpath = os.path.join(self.directory, file.name)
bpy.ops.import_scene.obj(filepath=objpath)
if self.seperate_layers:
layers = [i == layer for i in range(20)]
for obj in context.selected_objects:
obj.layers = layers
return {"FINISHED"}
def register():
bpy.utils.register_module(name)
if name == “main”:
register()
# test call
bpy.ops.objim.batch(‘INVOKE_DEFAULT’)