diff --git a/lib/render_workers/blender_worker.py b/lib/render_workers/blender_worker.py index cb2c23c..3688c00 100644 --- a/lib/render_workers/blender_worker.py +++ b/lib/render_workers/blender_worker.py @@ -34,28 +34,77 @@ class Blender(BaseRenderEngine): 'formats': cls.get_formats()} @classmethod - def run_python_expression(cls, path, python_expression): - if os.path.exists(path): + def run_python_expression(cls, project_path, python_expression): + if os.path.exists(project_path): try: - return subprocess.run([cls.renderer_path(), '-b', path, '--python-expr', python_expression], + return subprocess.run([cls.renderer_path(), '-b', project_path, '--python-expr', python_expression], capture_output=True) except Exception as e: logger.warning(f"Error running python expression in blender: {e}") pass else: - raise FileNotFoundError + raise FileNotFoundError(f'Project file not found: {project_path}') @classmethod - def run_python_script(cls, path, python_path): - if os.path.exists(path) and os.path.exists(python_path): + def run_python_script(cls, project_path, script_path): + if os.path.exists(project_path) and os.path.exists(script_path): try: - return subprocess.run([cls.renderer_path(), '-b', path, '--python', python_path], + return subprocess.run([cls.renderer_path(), '-b', project_path, '--python', script_path], capture_output=True) except Exception as e: logger.warning(f"Error running python expression in blender: {e}") pass - else: - raise FileNotFoundError + elif not os.path.exists(project_path): + raise FileNotFoundError(f'Project file not found: {project_path}') + elif not os.path.exists(script_path): + raise FileNotFoundError(f'Python script not found: {script_path}') + raise Exception("Uncaught exception") + + @classmethod + def get_scene_info(cls, project_path): + scene_info = None + try: + results = cls.run_python_script(project_path, os.path.join(os.path.dirname(os.path.realpath(__file__)), + 'scripts', 'get_blender_info.py')) + result_text = results.stdout.decode() + for line in result_text.splitlines(): + if line.startswith('SCENE_DATA:'): + raw_data = line.split('SCENE_DATA:')[-1] + scene_info = json.loads(raw_data) + break + except Exception as e: + logger.error(f'Error getting file details for .blend file: {e}') + return scene_info + + @classmethod + def pack_project_file(cls, project_path): + # Credit to L0Lock for pack script - https://blender.stackexchange.com/a/243935 + pack_expression = "import bpy\n" \ + "bpy.ops.file.pack_all()\n" \ + "myPath = bpy.data.filepath\n" \ + "myPath = str(myPath)\n" \ + "bpy.ops.wm.save_as_mainfile(filepath=myPath[:-6]+'_packed'+myPath[-6:])" + + try: + results = Blender.run_python_expression(project_path, pack_expression) + + result_text = results.stdout.decode() + dir_name = os.path.dirname(project_path) + + # report any missing textures + not_found = re.findall("(Unable to pack file, source path .*)\n", result_text) + for err in not_found: + logger.error(err) + + p = re.compile('Info: Saved "(.*)"') + match = p.search(result_text) + if match: + new_path = os.path.join(dir_name, match.group(1)) + logger.info(f'Blender file packed successfully to {new_path}') + return new_path + except Exception as e: + logger.error(f'Error packing .blend file: {e}') + return None class BlenderRenderWorker(BaseRenderWorker): @@ -78,7 +127,7 @@ class BlenderRenderWorker(BaseRenderWorker): self.__frame_percent_complete = 0.0 # Scene Info - self.scene_info = get_scene_info(input_path) + self.scene_info = Blender.get_scene_info(input_path) self.total_frames = (int(self.scene_info.get('frame_end', 0)) - int(self.scene_info.get('frame_start', 0)) + 1) \ if self.render_all_frames else 1 self.current_frame = int(self.scene_info.get('frame_start', 0)) @@ -165,53 +214,6 @@ class BlenderRenderWorker(BaseRenderWorker): return max(total_percent, 0) -def pack_blender_files(path): - # Credit to L0Lock for pack script - https://blender.stackexchange.com/a/243935 - pack_script = "import bpy\n" \ - "bpy.ops.file.pack_all()\n" \ - "myPath = bpy.data.filepath\n" \ - "myPath = str(myPath)\n" \ - "bpy.ops.wm.save_as_mainfile(filepath=myPath[:-6]+'_packed'+myPath[-6:])" - - try: - results = Blender.run_python_script(path, pack_script) - - result_text = results.stdout.decode() - dir_name = os.path.dirname(path) - - # report any missing textures - not_found = re.findall("(Unable to pack file, source path .*)\n", result_text) - for err in not_found: - logger.error(err) - - p = re.compile('Info: Saved "(.*)"') - match = p.search(result_text) - if match: - new_path = os.path.join(dir_name, match.group(1)) - logger.info(f'Blender file packed successfully to {new_path}') - return new_path - except Exception as e: - logger.error(f'Error packing .blend file: {e}') - return None - - -def get_scene_info(path): - - scene_info = None - try: - results = Blender.run_python_script(path, os.path.join(os.path.dirname(os.path.realpath(__file__)), - 'scripts', 'get_blender_info.py')) - result_text = results.stdout.decode() - for line in result_text.splitlines(): - if line.startswith('SCENE_DATA:'): - raw_data = line.split('SCENE_DATA:')[-1] - scene_info = json.loads(raw_data) - break - except Exception as e: - logger.error(f'Error getting file details for .blend file: {e}') - return scene_info - - if __name__ == '__main__': print(Blender.full_report()) diff --git a/scheduler_gui.py b/scheduler_gui.py index 68e86e5..84b0a77 100755 --- a/scheduler_gui.py +++ b/scheduler_gui.py @@ -11,6 +11,8 @@ from tkinter.ttk import Frame, Label, Entry, Combobox import psutil import requests + +from lib.render_workers.blender_worker import Blender from lib.utilities.server_helper import post_job_to_server logger = logging.getLogger() @@ -285,8 +287,7 @@ class ScheduleJob(Frame): # get file stats if self.chosen_file: - from lib.render_workers.blender_worker import get_scene_info - scene_data = get_scene_info(self.chosen_file) + scene_data = Blender.get_scene_info(self.chosen_file) # blender settings self.blender_frame = Frame(self) @@ -361,8 +362,7 @@ class ScheduleJob(Frame): temp_files = [] if renderer == 'blender': if self.blender_pack_textures.get(): - from lib.render_workers.blender_worker import pack_blender_files - new_path = pack_blender_files(path=input_path) + new_path = Blender.pack_project_file(project_path=input_path) if new_path: logger.info(f'Packed Blender file successfully: {new_path}') input_path = new_path