It is possible to export all object from a scene into different obj files (each object in a obj file separately)?
6 Answers
There doesn't exist a way to do this in the options of the obj importer so what you could do is run a script that loops over the items in your scene, check if it is a mesh and export the current selection to its own file relative to the path your blend file is saved.
Blender 3.1+
As of Blender 3.1.0 the name of the operator has been changed to obj_export()
and is now part of the WindowManager
namespace bpy.ops.wm.obj_export(filepath="//")
:
import bpy
import os
# Get the path where the blend file is located
basedir = bpy.path.abspath('//')
# Deselect all objects
bpy.ops.object.select_all(action='DESELECT')
# loop through all the objects in the scene
scene = bpy.context.scene
for ob in scene.objects:
# Select each object
ob.select_set(True)
# Make sure that we only export meshes
if ob.type == 'MESH':
# Export the currently selected object to its own file based on its name
bpy.ops.wm.obj_export(
filepath=os.path.join(basedir, ob.name + '.obj'),
export_selected_objects=True,
)
# Deselect the object and move on to another if any more are left
ob.select_set(False)
Blender 2.8+
As of Blender 2.8.0 the selection attribute (Object.select
) has been removed in favor of get/set functions Object.select_set(State)
and Object.select_get()
to set and get the current selection state of each object:
import bpy
import os
# Get the path where the blend file is located
basedir = bpy.path.abspath('//')
# Deselect all objects
bpy.ops.object.select_all(action='DESELECT')
# loop through all the objects in the scene
scene = bpy.context.scene
for ob in scene.objects:
# Select each object
ob.select_set(True)
# Make sure that we only export meshes
if ob.type == 'MESH':
# Export the currently selected object to its own file based on its name
bpy.ops.export_scene.obj(
filepath=os.path.join(basedir, ob.name + '.obj'),
use_selection=True,
)
# Deselect the object and move on to another if any more are left
ob.select_set(False)
Blender 2.7x
import bpy
import os
# Get the path where the blend file is located
basedir = bpy.path.abspath('//')
# Deselect all objects
bpy.ops.object.select_all(action='DESELECT')
# Loop through all the objects in the scene
scene = bpy.context.scene
for ob in scene.objects:
# Make the current object active and select it
scene.objects.active = ob
ob.select = True
# Make sure that we only export meshes
if ob.type == 'MESH':
# Export the currently selected object to its own file based on its name
bpy.ops.export_scene.obj(
filepath=os.path.join(basedir, ob.name + '.obj'),
use_selection=True,
)
# Deselect the object and move on to another if any more are left
ob.select = False
To further tweak your export options, see the parameters that
bpy.ops.export_scene_obj()
accepts.
For example, you can include normals with use_normals=True
, change forward axis with axis_forward
etc.
There are more stringent checks that could be made but for simple use cases and if used properly, this should suffice.
Also see How to batch import Wavefront OBJ files?.
To have it export only selected objects, comment line 7
and change line 11
.
# Remove
bpy.ops.object.select_all(action='DESELECT')
# Change to this where instead of the entire scene, we only look through selected objects
for ob in bpy.context.selected_objects:
or keep line 11
and add another line
for ob in scene.objects:
# Add the check to see if in selected objects here
if ob in bpy.context.selected_objects:
# adjust indentation
...
...
NB: Make sure the layers you have objects on are selected otherwise you will just get an empty file.
-
$\begingroup$ ok, thanks. And how i control options of export with your script (the scale, the axis...)? $\endgroup$– GabrielSDec 8, 2013 at 22:46
-
$\begingroup$ @GabrielS all the options that you can pass to
bpy.ops.export_scene.obj
are here, blender.org/documentation/blender_python_api_2_69_release/… $\endgroup$– iKlsRDec 8, 2013 at 22:47 -
$\begingroup$ @iKlsR, best only link to
_release
pages, we deleteblender_python_api_2_69_4
dirs occasionally. $\endgroup$ Dec 9, 2013 at 5:19 -
$\begingroup$ @iKlsR your script work fine and i have custome it to fit what i want. One more thing. how can i modify the script to export only selected objects? Thanks $\endgroup$– GabrielSDec 9, 2013 at 11:09
-
Following Add-on allows to batch export the current selection or simply all scene geometry objects as separate wavefront .obj
files. All usual options like Apply Modifiers or Write Materials are available in the Properties Panel N too.
io_batch_export_objs.py
(updated for 3.3+)
# ##### 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": "OBJ Batch Export",
"author": "p2or, brockmann, trippeljojo",
"version": (0, 3),
"blender": (3, 3, 0),
"location": "File > Import-Export",
"description": "Export multiple OBJ files, their UVs and Materials",
"warning": "",
"wiki_url": "",
"tracker_url": "",
"category": "Import-Export"}
import bpy
import os
from bpy_extras.io_utils import ExportHelper
from bpy.props import (BoolProperty,
IntProperty,
FloatProperty,
StringProperty,
EnumProperty,
CollectionProperty
)
class WM_OT_batchExportObjs(bpy.types.Operator, ExportHelper):
"""Batch export the scene to separate obj files"""
bl_idname = "export_scene.batch_obj"
bl_label = "Batch export OBJ's"
bl_options = {'PRESET', 'UNDO'}
# ExportHelper mixin class uses this
filename_ext = ".obj"
filter_glob = StringProperty(
default="*.obj;*.mtl",
options={'HIDDEN'},)
axis_forward: EnumProperty(
name="Axis Forward",
items=(('X', "X", "Positive X Axis"),
('Y', "Y", "Positive Y Axis"),
('Z', "Z", "Positive Z Axis"),
('NEGATIVE_X', "-X", "Negative X Axis"),
('NEGATIVE_Y', "-Y", "Negative Y Axis"),
('NEGATIVE_Z', "-Z (Default)", "Negative Z Axis"),),
default='NEGATIVE_Z')
axis_up: EnumProperty(
name="Axis Up",
items=(('X', "X Up", "Positive X Axis"),
('Y', "Y Up (Default)", "Positive Y Axis"),
('Z', "Z Up", "Positive Z Axis"),
('NEGATIVE_X', "-X Up", "Negative X Axis"),
('NEGATIVE_Y', "-Y Up", "Negative Y Axis"),
('NEGATIVE_Z', "-Z Up", "Negative Z Axis"),),
default='Y')
scale_factor: FloatProperty(
name="Scale",
min=0.01, max=1000.0,
default=1.0,)
selection_only: BoolProperty(
name="Selection Only",
description="Export selected objects only",
default=True,)
eval_mode: EnumProperty(
name="Evaluation Mode",
items=(('DAG_EVAL_VIEWPORT', "Viewport (Default)", "Objects as they appear in the Viewport"),
('DAG_EVAL_RENDER', "Render", "Objects as they appear in Render"),),
default='DAG_EVAL_VIEWPORT')
modifiers_apply: BoolProperty(
name="Apply Modifiers",
description="Apply Modifiers to exported meshes",
default=False)
write_uvs: BoolProperty(
name="Include UVs",
description="Write out the active UV coordinates",
default=True)
write_normals: BoolProperty(
name="Write Normals",
description="Export one normal per vertex and per face, to represent flat faces and sharp edges",
default=True)
write_materials: BoolProperty(
name="Write Materials",
description="Write out the MTL file",
default=True)
triangulate_faces: BoolProperty(
name="Triangulate Faces",
description="Convert all faces to triangles",
default=False)
write_nurbs: BoolProperty(
name="Write Nurbs",
description="Write nurbs curves as OBJ nurbs rather than "
"converting to geometry",
default=False)
group_by_object: BoolProperty(
name="Objects as OBJ Groups ",
description="",
default=False)
group_by_material: BoolProperty(
name="Material Groups",
description="",
default=False)
group_by_vertex: BoolProperty(
name="Polygroups",
description="",
default=False)
smoothing_groups: BoolProperty(
name="Smooth Groups",
description="Write sharp edges as smooth groups",
default=False)
smoothing_group_bitflags: BoolProperty(
name="Bitflag Smooth Groups",
description="Same as 'Smooth Groups', but generate smooth groups IDs as bitflags "
"(produces at most 32 different smooth groups, usually much less)",
default=False)
def execute(self, context):
# Get the current folder
folder_path = os.path.dirname(self.filepath)
# Get all objects selected in the viewport
viewport_selection = candidates = context.selected_objects
if self.selection_only == False:
candidates = [o for o in context.scene.objects]
# Deselect all objects
bpy.ops.object.select_all(action='DESELECT')
for obj in [o for o in candidates if o.type == 'MESH']:
obj.select_set(True)
file_path = os.path.join(folder_path, "{}.obj".format(obj.name))
bpy.ops.wm.obj_export(
filepath=file_path,
export_animation=False,
forward_axis=self.axis_forward,
up_axis=self.axis_up,
scaling_factor=self.scale_factor,
apply_modifiers=self.modifiers_apply,
export_selected_objects=True,
export_eval_mode=self.eval_mode,
export_uv=self.write_uvs,
export_normals=self.write_normals,
export_materials=self.write_materials,
export_triangulated_mesh=self.triangulate_faces,
export_curves_as_nurbs=self.write_nurbs,
export_object_groups=self.group_by_object,
export_material_groups = self.group_by_material,
export_vertex_groups = self.group_by_vertex,
export_smooth_groups=self.smoothing_groups,
smooth_group_bitflags=self.smoothing_group_bitflags
)
obj.select_set(False)
# Restore Viewport Selection
for obj in viewport_selection:
obj.select_set(True)
return {'FINISHED'}
def menu_func_import(self, context):
self.layout.operator(WM_OT_batchExportObjs.bl_idname, text="Wavefront Batch (.obj)")
def register():
bpy.utils.register_class(WM_OT_batchExportObjs)
bpy.types.TOPBAR_MT_file_export.append(menu_func_import)
def unregister():
bpy.utils.unregister_class(WM_OT_batchExportObjs)
bpy.types.TOPBAR_MT_file_export.remove(menu_func_import)
if __name__ == "__main__":
register()
# test call
#bpy.ops.export_scene.batch_obj('INVOKE_DEFAULT')
Gist: https://gist.github.com/p2or/e5ad6a67effef4be2a53d334230380e4
io_batch_export_objs.py
(updated for 3.1+)
# ##### 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": "OBJ Batch Export",
"author": "p2or, brockmann, trippeljojo",
"version": (0, 3),
"blender": (3, 1, 0),
"location": "File > Import-Export",
"description": "Export multiple OBJ files, their UVs and Materials",
"warning": "",
"wiki_url": "",
"tracker_url": "",
"category": "Import-Export"}
import bpy
import os
from bpy_extras.io_utils import ExportHelper
from bpy.props import (BoolProperty,
IntProperty,
FloatProperty,
StringProperty,
EnumProperty,
CollectionProperty
)
class WM_OT_batchExportObjs(bpy.types.Operator, ExportHelper):
"""Batch export the scene to separate obj files"""
bl_idname = "export_scene.batch_obj"
bl_label = "Batch export OBJ's"
bl_options = {'PRESET', 'UNDO'}
# ExportHelper mixin class uses this
filename_ext = ".obj"
filter_glob = StringProperty(
default="*.obj;*.mtl",
options={'HIDDEN'},)
# Object Properties
axis_forward: EnumProperty(
name="Axis Forward",
items=(('X_FORWARD', "X", "Positive X Axis"),
('Y_FORWARD', "Y", "Positive Y Axis"),
('Z_FORWARD', "Z", "Positive Z Axis"),
('NEGATIVE_X_FORWARD', "-X", "Negative X Axis"),
('NEGATIVE_Y_FORWARD', "-Y", "Negative Y Axis"),
('NEGATIVE_Z_FORWARD', "-Z (Default)", "Negative Z Axis"),),
default='NEGATIVE_Z_FORWARD')
axis_up: EnumProperty(
name="Axis Up",
items=(('X_UP', "X Up", "Positive X Axis"),
('Y_UP', "Y Up (Default)", "Positive Y Axis"),
('Z_UP', "Z Up", "Positive Z Axis"),
('NEGATIVE_X_UP', "-X Up", "Negative X Axis"),
('NEGATIVE_Y_UP', "-Y Up", "Negative Y Axis"),
('NEGATIVE_Z_UP', "-Z Up", "Negative Z Axis"),),
default='Y_UP')
scale_factor: FloatProperty(
name="Scale",
min=0.01, max=1000.0,
default=1.0,)
selection_only: BoolProperty(
name="Selection Only",
description="Export selected objects only",
default=True,)
eval_mode: EnumProperty(
name="Evaluation Mode",
items=(('DAG_EVAL_VIEWPORT', "Viewport (Default)", "Objects as they appear in the Viewport"),
('DAG_EVAL_RENDER', "Render", "Objects as they appear in Render"),),
default='DAG_EVAL_VIEWPORT')
# Geometry Export
write_uvs: BoolProperty(
name="Include UVs",
description="Write out the active UV coordinates",
default=True)
write_normals: BoolProperty(
name="Write Normals",
description="Export one normal per vertex and per face, to represent flat faces and sharp edges",
default=True)
write_materials: BoolProperty(
name="Write Materials",
description="Write out the MTL file",
default=True)
triangulate_faces: BoolProperty(
name="Triangulate Faces",
description="Convert all faces to triangles",
default=False)
write_nurbs: BoolProperty(
name="Write Nurbs",
description="Write nurbs curves as OBJ nurbs rather than "
"converting to geometry",
default=False)
# Grouping
group_by_object: BoolProperty(
name="Objects as OBJ Groups ",
description="",
default=False)
group_by_material: BoolProperty(
name="Material Groups",
description="",
default=False)
group_by_vertex: BoolProperty(
name="Polygroups",
description="",
default=False)
smoothing_groups: BoolProperty(
name="Smooth Groups",
description="Write sharp edges as smooth groups",
default=False)
smoothing_group_bitflags: BoolProperty(
name="Bitflag Smooth Groups",
description="Same as 'Smooth Groups', but generate smooth groups IDs as bitflags "
"(produces at most 32 different smooth groups, usually much less)",
default=False)
def execute(self, context):
# Get the current folder
folder_path = os.path.dirname(self.filepath)
# Get all objects selected in the viewport
viewport_selection = candidates = context.selected_objects
if self.selection_only == False:
candidates = [o for o in context.scene.objects]
# Deselect all objects
bpy.ops.object.select_all(action='DESELECT')
for obj in [o for o in candidates if o.type == 'MESH']:
obj.select_set(True)
file_path = os.path.join(folder_path, "{}.obj".format(obj.name))
bpy.ops.wm.obj_export(
filepath=file_path,
export_animation=False,
# Object Properties
forward_axis=self.axis_forward,
up_axis=self.axis_up,
scaling_factor=self.scale_factor,
export_selected_objects=True,
export_eval_mode=self.eval_mode,
# Geometry Export
export_uv=self.write_uvs,
export_normals=self.write_normals,
export_materials=self.write_materials,
export_triangulated_mesh=self.triangulate_faces,
export_curves_as_nurbs=self.write_nurbs,
# Grouping
export_object_groups=self.group_by_object,
export_material_groups = self.group_by_material,
export_vertex_groups = self.group_by_vertex,
export_smooth_groups=self.smoothing_groups,
smooth_group_bitflags=self.smoothing_group_bitflags
)
obj.select_set(False)
# Restore Viewport Selection
for obj in viewport_selection:
obj.select_set(True)
return {'FINISHED'}
def menu_func_import(self, context):
self.layout.operator(WM_OT_batchExportObjs.bl_idname, text="Wavefront Batch (.obj)")
def register():
bpy.utils.register_class(WM_OT_batchExportObjs)
bpy.types.TOPBAR_MT_file_export.append(menu_func_import)
def unregister():
bpy.utils.unregister_class(WM_OT_batchExportObjs)
bpy.types.TOPBAR_MT_file_export.remove(menu_func_import)
if __name__ == "__main__":
register()
# test call
#bpy.ops.export_scene.batch_obj('INVOKE_DEFAULT')
io_batch_export_objs.py
(updated for 2.8+)
# ##### 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": "Export multiple OBJ files",
"author": "p2or, brockmann, trippeljojo",
"version": (0, 2, 0),
"blender": (2, 80, 0),
"location": "File > Import-Export",
"description": "Export multiple OBJ files, UV's, materials",
"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,
StringProperty,
EnumProperty,
CollectionProperty
)
class ExportMultipleObjs(bpy.types.Operator, ExportHelper):
"""Batch export objects as obj files"""
bl_idname = "export_scene.batch_obj"
bl_label = "Batch export OBJ's"
bl_options = {'PRESET', 'UNDO'}
# ExportHelper mixin class uses this
filename_ext = ".obj"
filter_glob = StringProperty(
default="*.obj;*.mtl",
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_animation_setting: BoolProperty(
name="Animation",
description="Write out an OBJ for each frame",
default=False,
)
# object group
use_mesh_modifiers_setting: BoolProperty(
name="Apply Modifiers",
description="Apply modifiers (preview resolution)",
default=True,
)
# extra data group
use_edges_setting: BoolProperty(
name="Include Edges",
description="",
default=True,
)
use_smooth_groups_setting: BoolProperty(
name="Smooth Groups",
description="Write sharp edges as smooth groups",
default=False,
)
use_smooth_groups_bitflags_setting: BoolProperty(
name="Bitflag Smooth Groups",
description="Same as 'Smooth Groups', but generate smooth groups IDs as bitflags "
"(produces at most 32 different smooth groups, usually much less)",
default=False,
)
use_normals_setting: BoolProperty(
name="Write Normals",
description="Export one normal per vertex and per face, to represent flat faces and sharp edges",
default=False,
)
use_uvs_setting: BoolProperty(
name="Include UVs",
description="Write out the active UV coordinates",
default=True,
)
use_materials_setting: BoolProperty(
name="Write Materials",
description="Write out the MTL file",
default=True,
)
use_triangles_setting: BoolProperty(
name="Triangulate Faces",
description="Convert all faces to triangles",
default=False,
)
use_nurbs_setting: BoolProperty(
name="Write Nurbs",
description="Write nurbs curves as OBJ nurbs rather than "
"converting to geometry",
default=False,
)
use_vertex_groups_setting: BoolProperty(
name="Polygroups",
description="",
default=False,
)
use_blen_objects_setting: BoolProperty(
name="Objects as OBJ Objects",
description="",
default=True,
)
group_by_object_setting: BoolProperty(
name="Objects as OBJ Groups ",
description="",
default=False,
)
group_by_material_setting: BoolProperty(
name="Material Groups",
description="",
default=False,
)
keep_vertex_order_setting: BoolProperty(
name="Keep Vertex Order",
description="",
default=False,
)
axis_forward_setting: EnumProperty(
name="Forward",
items=(('X', "X Forward", ""),
('Y', "Y Forward", ""),
('Z', "Z Forward", ""),
('-X', "-X Forward", ""),
('-Y', "-Y Forward", ""),
('-Z', "-Z Forward", ""),
),
default='-Z',
)
axis_up_setting: EnumProperty(
name="Up",
items=(('X', "X Up", ""),
('Y', "Y Up", ""),
('Z', "Z Up", ""),
('-X', "-X Up", ""),
('-Y', "-Y Up", ""),
('-Z', "-Z Up", ""),
),
default='Y',
)
global_scale_setting: FloatProperty(
name="Scale",
min=0.01, max=1000.0,
default=1.0,
)
path_mode_setting: EnumProperty(
name="Path Mode",
items=(('AUTO', "Auto", ""),
('ABSOLUTE', "Absolute", ""),
('RELATIVE', "Relative", ""),
('MATCH', "Match", ""),
('STRIP', "Strip", ""),
('COPY', "Copy", ""),
),
default='AUTO',
)
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':
file_path = os.path.join(folder_path, "{}.obj".format(item.name))
bpy.ops.export_scene.obj(
filepath=file_path,
use_selection=self.use_selection_setting,
axis_forward=self.axis_forward_setting,
axis_up=self.axis_up_setting,
use_animation=self.use_animation_setting,
use_mesh_modifiers=self.use_mesh_modifiers_setting,
use_edges=self.use_edges_setting,
use_smooth_groups=self.use_smooth_groups_setting,
use_smooth_groups_bitflags=self.use_smooth_groups_bitflags_setting,
use_normals=self.use_normals_setting,
use_uvs=self.use_uvs_setting,
use_materials=self.use_materials_setting,
use_triangles=self.use_triangles_setting,
use_nurbs=self.use_nurbs_setting,
use_vertex_groups=self.use_vertex_groups_setting,
use_blen_objects=self.use_blen_objects_setting,
group_by_object=self.group_by_object_setting,
group_by_material=self.group_by_material_setting,
keep_vertex_order=self.keep_vertex_order_setting,
global_scale=self.global_scale_setting,
path_mode=self.path_mode_setting
)
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(ExportMultipleObjs.bl_idname, text="Wavefront Batch (.obj)")
def register():
bpy.utils.register_class(ExportMultipleObjs)
bpy.types.TOPBAR_MT_file_export.append(menu_func_import)
def unregister():
bpy.utils.unregister_class(ExportMultipleObjs)
bpy.types.TOPBAR_MT_file_export.remove(menu_func_import)
if __name__ == "__main__":
register()
# test call
#bpy.ops.export_scene.multiple_objs('INVOKE_DEFAULT')
Blender 2.7x: https://gist.github.com/p2or/e8ca8c93398e3c586d2b8cb2c4346552
Note: The add-on is just a wrapper of bpy.ops.wm.obj_export()
or bpy.ops.export_scene.obj()
operator in versions prior to Blender 3.2.0
until exporting multiple files is supported officially.
To import multiple obj files see this answer: How to batch import Wavefront OBJ files?
-
$\begingroup$ Is there a way to export the object with the center of object for the mesh instead of the global origin? $\endgroup$ Jan 21, 2020 at 4:15
-
$\begingroup$ I figured it out, I added a
use_mesh_as_center
option that sets the mesh's location to (0, 0, 0) before exporting and resets it back to its original after $\endgroup$ Jan 21, 2020 at 5:28 -
$\begingroup$ Hi @p2or, thanks for the great answer. Do you know if there is a way to save modifiers along with the .obj, so that importing them later will preserve them? (I have a relevant question here: blender.stackexchange.com/questions/181143/…) $\endgroup$ Jun 5, 2020 at 14:17
-
1$\begingroup$ .obj is a pretty old file format and doesn't allow to preserve any modifiers. Even when using alembic or usd, there is no way to preserve that (in 2020). If there is a serious reason to do that, I'd suggest to save all the modifier properties in a json string as text file and check for that file when loading the data back in. Cheers @ComputerScientist $\endgroup$– p2orJun 6, 2020 at 12:58
Working example for Blender 2.8 to batch export, just change the path
import bpy
#example path to store files
path = 'path\subpath\name'
#store selection
obs = bpy.context.selected_objects
for ob in obs:
#deselect all but just one object and make it active
bpy.ops.object.select_all(action='DESELECT')
ob.select_set(state=True)
bpy.context.view_layer.objects.active = ob
#store object location then zero it out
location = ob.location.copy()
bpy.ops.object.location_clear()
#export fbx
filename = path + ob.name + '.obj'
bpy.ops.export_scene.obj(filepath=filename, use_selection=True)
#restore location
ob.location = location
#reselect originally selected objects
for ob in obs:
ob.select_set(state=True)
For me iKlsR's method did not work when trying to export multiple meshes. I got all meshes in the first exported file. The other exports were rather random, some contained nothing, others contained 3 objects. I have changed some code around and it works for me now.
Method for exporting a selection.
import bpy
import os
# get the current path and make a new folder for the exported meshes
path = bpy.path.abspath('//objs' + os.sep)
os.makedirs(path)
for object in bpy.context.selected_objects:
# deselect all meshes
bpy.ops.object.select_all(action='DESELECT')
# select the object
object.select = True
# export object with its name as file name
bpy.ops.export_scene.obj(
filepath=path + object.name + '.obj',
use_selection=True,
)
-
$\begingroup$ thanks for directing me here. I had to modify your version a little more to get it to work on OSX. path = bpy.path.abspath('//') #os.makedirs(path) It was creating a folder but not putting the .obj files into it and it was also prefixing all the names with "objs/" Also, it crashed upon second run unless I deleted the empty folder it's trying to re-create. $\endgroup$ Mar 8, 2014 at 14:56
-
$\begingroup$ feel free edit my answer, however the code i posted worked for me $\endgroup$– VaderMar 8, 2014 at 15:21
For Blender 2.92.1
multiobj_exporter.py
import bpy
import os
basedir = 'absolute path'
sel_objs = [obj for obj in bpy.context.scene.objects if obj.type == 'MESH']
bpy.ops.object.select_all(action='DESELECT')
for obj in sel_objs:
bpy.context.view_layer.objects.active = obj
obj.select_set(True)
bpy.ops.export_scene.obj(
filepath=os.path.join(basedir, obj.name + '.obj'),
use_selection=True,
)
obj.select_set(False)
the code worked with only background option like below because an context error occurred. If anyone know the reason why, please tell me.
$ blender --background --python multiobj_exporter.py