1 # ##### BEGIN GPL LICENSE BLOCK #####
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 # ##### END GPL LICENSE BLOCK #####
24 ./blender.bin --background --python source/tests/batch_import.py -- \
25 --operator="bpy.ops.import_scene.obj" \
31 ./blender.bin --background --python source/tests/batch_import.py -- \
32 --operator="bpy.ops.import_scene.autodesk_3ds" \
35 --start=0 --end=1000 \
38 ./blender.bin --background --addons io_curve_svg --python source/tests/batch_import.py -- \
39 --operator="bpy.ops.import_curve.svg" \
42 --start=0 --end=1000 \
54 for scene in bpy.data.scenes:
55 for obj in scene.objects[:]:
56 scene.objects.unlink(obj)
59 # remove obdata, for now only worry about the startup scene
60 for bpy_data_iter in (bpy.data.objects, bpy.data.meshes, bpy.data.lamps, bpy.data.cameras):
61 for id_data in bpy_data_iter:
62 bpy_data_iter.remove(id_data)
65 def batch_import(operator="",
73 _reset_all = addon_utils.reset_all # XXX, hack
77 path = os.path.normpath(path)
78 path = os.path.abspath(path)
80 match_upper = match.upper()
81 pattern_match = lambda a: fnmatch.fnmatchcase(a.upper(), match_upper)
83 def file_generator(path):
84 for dirpath, dirnames, filenames in os.walk(path):
87 if dirpath.startswith("."):
90 for filename in filenames:
91 if pattern_match(filename):
92 yield os.path.join(dirpath, filename)
94 print("Collecting %r files in %s" % (match, path), end="")
96 files = list(file_generator(path))
97 files_len = len(files)
98 end = min(end, len(files))
99 print(" found %d" % files_len, end="")
102 files = files[start:end]
103 if len(files) != files_len:
104 print(" using a subset in (%d, %d), total %d" % (start, end, len(files)), end="")
112 for i, f in enumerate(files):
113 print(" %s(filepath=%r) # %d of %d" % (operator, f, i + start, len(files)))
115 # hack so loading the new file doesnt undo our loaded addons
116 addon_utils.reset_all = lambda: None # XXX, hack
118 bpy.ops.wm.read_factory_settings()
120 addon_utils.reset_all = _reset_all # XXX, hack
123 result = op(filepath=f)
125 if 'FINISHED' in result:
131 fout = os.path.join(save_path, os.path.relpath(f, path))
132 fout_blend = os.path.splitext(fout)[0] + ".blend"
134 print("\tSaving: %r" % fout_blend)
136 fout_dir = os.path.dirname(fout_blend)
137 if not os.path.exists(fout_dir):
138 os.makedirs(fout_dir)
140 bpy.ops.wm.save_as_mainfile(filepath=fout_blend)
142 print("finished, done:%d, fail:%d" % (tot_done, tot_fail))
148 # get the args passed to blender after "--", all of which are ignored by blender specifically
149 # so python may receive its own arguments
153 argv = [] # as if no args are passed
155 argv = argv[argv.index("--") + 1:] # get all args after "--"
157 # When --help or no args are given, print this help
158 usage_text = "Run blender in background mode with this script:"
159 usage_text += " blender --background --python " + __file__ + " -- [options]"
161 parser = optparse.OptionParser(usage=usage_text)
163 # Example background utility, add some text and renders or saves it (with options)
164 # Possible types are: string, int, long, choice, float and complex.
165 parser.add_option("-o", "--operator", dest="operator", help="This text will be used to render an image", type="string")
166 parser.add_option("-p", "--path", dest="path", help="Path to use for searching for files", type='string')
167 parser.add_option("-m", "--match", dest="match", help="Wildcard to match filename", type="string")
168 parser.add_option("-s", "--save_path", dest="save_path", help="Save the input file to a blend file in a new location", metavar='string')
169 parser.add_option("-S", "--start", dest="start", help="From collected files, start with this index", metavar='int')
170 parser.add_option("-E", "--end", dest="end", help="From collected files, end with this index", metavar='int')
172 options, args = parser.parse_args(argv) # In this example we wont use the args
178 if not options.operator:
179 print("Error: --operator=\"some string\" argument not given, aborting.")
183 if options.start is None:
186 if options.end is None:
187 options.end = sys.maxsize
189 # Run the example function
190 batch_import(operator=options.operator,
192 save_path=options.save_path,
194 start=int(options.start),
195 end=int(options.end),
198 print("batch job finished, exiting")
201 if __name__ == "__main__":