""" Generic Blender functions """ import os from pathlib import Path import subprocess import json from textwrap import dedent import bpy class attr_set(): """Receive a list of tuple [(data_path:python_obj, "attribute":str, "wanted value":str)] before with statement : Store existing values, assign wanted value after with statement: Restore values to their old values """ def __init__(self, attrib_list): """Initialization Args: attrib_list (list[tuple]): a list of tuple with the """ self.store = [] for item in attrib_list: prop, attr = item[:2] self.store.append( (prop, attr, getattr(prop, attr)) ) for item in attrib_list: prop, attr = item[:2] if len(item) >= 3: setattr(prop, attr, item[2]) def __enter__(self): return self def __exit__(self, exc_type, exc_value, exc_traceback): for prop, attr, old_val in self.store: setattr(prop, attr, old_val) def abspath(path): path = os.path.abspath(bpy.path.abspath(path)) return Path(path) def get_scene_settings(): return bpy.context.scene.vsetb_settings def get_strip_settings(): scn = bpy.context.scene strip = bpy.context.active_sequence_strip if not strip: return return strip.vsetb_strip_settings def norm_arg(arg_name): return "--" + arg_name.replace(' ', '-') def norm_value(value): if isinstance(value, (tuple, list)): values = [] for v in value: if not isinstance(v, str): v = json.dumps(v) values.append(v) return values if isinstance(value, Path): return str(value) if not isinstance(value, str): value = json.dumps(value) return value def get_bl_cmd(blender=None, background=False, focus=True, blendfile=None, script=None, output=None, **kargs): cmd = [str(blender)] if blender else [bpy.app.binary_path] if background: cmd += ['--background'] if not focus and not background: cmd += ['--no-window-focus'] cmd += ['--window-geometry', '5000', '0', '10', '10'] cmd += ['--python-use-system-env'] if blendfile: cmd += [str(blendfile)] if output: cmd += ['-o', str(output)] if script: cmd += ['--python', str(script)] if kargs: cmd += ['--'] for k, v in kargs.items(): k = norm_arg(k) v = norm_value(v) cmd += [k] if isinstance(v, (tuple, list)): cmd += v else: cmd += [v] return cmd def background_render(output=None): #bpy.context.scene.render.filepath = '{output}' output = os.path.abspath(bpy.path.abspath(output)) script_code = dedent(f""" import bpy bpy.context.scene.render.filepath = '{str(output)}' bpy.ops.render.render(animation=True) bpy.ops.wm.quit_blender() """) tmp_blend = Path(bpy.app.tempdir) / Path(bpy.data.filepath).name bpy.ops.wm.save_as_mainfile(filepath=str(tmp_blend), copy=True) script_path = Path(bpy.app.tempdir) / 'render_blender_background.py' script_path.write_text(script_code) cmd = get_bl_cmd(blendfile=tmp_blend, script=script_path, background=True) print('Background Render...') print(cmd) subprocess.Popen(cmd) def get_addon_prefs(): addon_name = __package__.split('.')[0] return bpy.context.preferences.addons[addon_name].preferences