Blender V2.61 - r43446
|
00001 # ##### BEGIN GPL LICENSE BLOCK ##### 00002 # 00003 # This program is free software; you can redistribute it and/or 00004 # modify it under the terms of the GNU General Public License 00005 # as published by the Free Software Foundation; either version 2 00006 # of the License, or (at your option) any later version. 00007 # 00008 # This program is distributed in the hope that it will be useful, 00009 # but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 # GNU General Public License for more details. 00012 # 00013 # You should have received a copy of the GNU General Public License 00014 # along with this program; if not, write to the Free Software Foundation, 00015 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00016 # 00017 # ##### END GPL LICENSE BLOCK ##### 00018 00019 # <pep8 compliant> 00020 00021 """ 00022 Example Usage: 00023 00024 ./blender.bin --background --python source/tests/batch_import.py -- \ 00025 --operator="bpy.ops.import_scene.obj" \ 00026 --path="/fe/obj" \ 00027 --match="*.obj" \ 00028 --start=0 --end=10 \ 00029 --save_path=/tmp/test 00030 00031 ./blender.bin --background --python source/tests/batch_import.py -- \ 00032 --operator="bpy.ops.import_scene.autodesk_3ds" \ 00033 --path="/fe/" \ 00034 --match="*.3ds" \ 00035 --start=0 --end=1000 \ 00036 --save_path=/tmp/test 00037 00038 ./blender.bin --background --addons io_curve_svg --python source/tests/batch_import.py -- \ 00039 --operator="bpy.ops.import_curve.svg" \ 00040 --path="/usr/" \ 00041 --match="*.svg" \ 00042 --start=0 --end=1000 \ 00043 --save_path=/tmp/test 00044 00045 """ 00046 00047 import os 00048 import sys 00049 00050 00051 def clear_scene(): 00052 import bpy 00053 unique_obs = set() 00054 for scene in bpy.data.scenes: 00055 for obj in scene.objects[:]: 00056 scene.objects.unlink(obj) 00057 unique_obs.add(obj) 00058 00059 # remove obdata, for now only worry about the startup scene 00060 for bpy_data_iter in (bpy.data.objects, bpy.data.meshes, bpy.data.lamps, bpy.data.cameras): 00061 for id_data in bpy_data_iter: 00062 bpy_data_iter.remove(id_data) 00063 00064 00065 def batch_import(operator="", 00066 path="", 00067 save_path="", 00068 match="", 00069 start=0, 00070 end=sys.maxsize, 00071 ): 00072 import addon_utils 00073 _reset_all = addon_utils.reset_all # XXX, hack 00074 00075 import fnmatch 00076 00077 path = os.path.normpath(path) 00078 path = os.path.abspath(path) 00079 00080 match_upper = match.upper() 00081 pattern_match = lambda a: fnmatch.fnmatchcase(a.upper(), match_upper) 00082 00083 def file_generator(path): 00084 for dirpath, dirnames, filenames in os.walk(path): 00085 00086 # skip '.svn' 00087 if dirpath.startswith("."): 00088 continue 00089 00090 for filename in filenames: 00091 if pattern_match(filename): 00092 yield os.path.join(dirpath, filename) 00093 00094 print("Collecting %r files in %s" % (match, path), end="") 00095 00096 files = list(file_generator(path)) 00097 files_len = len(files) 00098 end = min(end, len(files)) 00099 print(" found %d" % files_len, end="") 00100 00101 files.sort() 00102 files = files[start:end] 00103 if len(files) != files_len: 00104 print(" using a subset in (%d, %d), total %d" % (start, end, len(files)), end="") 00105 00106 import bpy 00107 op = eval(operator) 00108 00109 tot_done = 0 00110 tot_fail = 0 00111 00112 for i, f in enumerate(files): 00113 print(" %s(filepath=%r) # %d of %d" % (operator, f, i + start, len(files))) 00114 00115 # hack so loading the new file doesnt undo our loaded addons 00116 addon_utils.reset_all = lambda: None # XXX, hack 00117 00118 bpy.ops.wm.read_factory_settings() 00119 00120 addon_utils.reset_all = _reset_all # XXX, hack 00121 clear_scene() 00122 00123 result = op(filepath=f) 00124 00125 if 'FINISHED' in result: 00126 tot_done += 1 00127 else: 00128 tot_fail += 1 00129 00130 if save_path: 00131 fout = os.path.join(save_path, os.path.relpath(f, path)) 00132 fout_blend = os.path.splitext(fout)[0] + ".blend" 00133 00134 print("\tSaving: %r" % fout_blend) 00135 00136 fout_dir = os.path.dirname(fout_blend) 00137 if not os.path.exists(fout_dir): 00138 os.makedirs(fout_dir) 00139 00140 bpy.ops.wm.save_as_mainfile(filepath=fout_blend) 00141 00142 print("finished, done:%d, fail:%d" % (tot_done, tot_fail)) 00143 00144 00145 def main(): 00146 import optparse 00147 00148 # get the args passed to blender after "--", all of which are ignored by blender specifically 00149 # so python may receive its own arguments 00150 argv = sys.argv 00151 00152 if "--" not in argv: 00153 argv = [] # as if no args are passed 00154 else: 00155 argv = argv[argv.index("--") + 1:] # get all args after "--" 00156 00157 # When --help or no args are given, print this help 00158 usage_text = "Run blender in background mode with this script:" 00159 usage_text += " blender --background --python " + __file__ + " -- [options]" 00160 00161 parser = optparse.OptionParser(usage=usage_text) 00162 00163 # Example background utility, add some text and renders or saves it (with options) 00164 # Possible types are: string, int, long, choice, float and complex. 00165 parser.add_option("-o", "--operator", dest="operator", help="This text will be used to render an image", type="string") 00166 parser.add_option("-p", "--path", dest="path", help="Path to use for searching for files", type='string') 00167 parser.add_option("-m", "--match", dest="match", help="Wildcard to match filename", type="string") 00168 parser.add_option("-s", "--save_path", dest="save_path", help="Save the input file to a blend file in a new location", metavar='string') 00169 parser.add_option("-S", "--start", dest="start", help="From collected files, start with this index", metavar='int') 00170 parser.add_option("-E", "--end", dest="end", help="From collected files, end with this index", metavar='int') 00171 00172 options, args = parser.parse_args(argv) # In this example we wont use the args 00173 00174 if not argv: 00175 parser.print_help() 00176 return 00177 00178 if not options.operator: 00179 print("Error: --operator=\"some string\" argument not given, aborting.") 00180 parser.print_help() 00181 return 00182 00183 if options.start is None: 00184 options.start = 0 00185 00186 if options.end is None: 00187 options.end = sys.maxsize 00188 00189 # Run the example function 00190 batch_import(operator=options.operator, 00191 path=options.path, 00192 save_path=options.save_path, 00193 match=options.match, 00194 start=int(options.start), 00195 end=int(options.end), 00196 ) 00197 00198 print("batch job finished, exiting") 00199 00200 00201 if __name__ == "__main__": 00202 main()