From 78d0bf2f5504c6c96ecba2cbb2f916217552d7d4 Mon Sep 17 00:00:00 2001 From: Zdenek Dolezal Date: Thu, 12 Dec 2024 11:06:20 +0100 Subject: [PATCH] refactor(external_bpy): Move clean temp dir to SetupUtility, don't call setup in external mode Adjust, so the part using bpy isn't imported in CLI, where bpy might not be available. --- blenderproc/__init__.py | 5 +- blenderproc/command_line.py | 7 ++- blenderproc/python/utility/Initializer.py | 6 +-- blenderproc/python/utility/SetupUtility.py | 55 +++++++++++++--------- blenderproc/python/utility/Utility.py | 7 --- 5 files changed, 44 insertions(+), 36 deletions(-) diff --git a/blenderproc/__init__.py b/blenderproc/__init__.py index 42b6f22a8..33bedabab 100644 --- a/blenderproc/__init__.py +++ b/blenderproc/__init__.py @@ -34,7 +34,10 @@ # Also clean the python path as this might disturb the pip installs if "PYTHONPATH" in os.environ: del os.environ["PYTHONPATH"] - SetupUtility.setup([]) + + if not is_using_external_bpy_module(): + SetupUtility.setup([]) + from .api import loader from .api import utility from .api import sampler diff --git a/blenderproc/command_line.py b/blenderproc/command_line.py index c6cc525ab..7993f62d4 100644 --- a/blenderproc/command_line.py +++ b/blenderproc/command_line.py @@ -12,7 +12,6 @@ # pylint: disable=wrong-import-position from blenderproc.python.utility.SetupUtility import SetupUtility, is_using_external_bpy_module from blenderproc.python.utility.InstallUtility import InstallUtility -from blenderproc.python.utility.Utility import Utility # pylint: enable=wrong-import-position @@ -179,7 +178,7 @@ def cli(): finally: assert script_directory in sys.path sys.path.remove(script_directory) - Utility.clean_temp_dir() + SetupUtility.clean_temp_dir() else: # Install blender, if not already done custom_blender_path, blender_install_path = InstallUtility.determine_blender_install_path(args) @@ -207,7 +206,7 @@ def cli(): # Listen for SIGTERM signal, so we can properly clean up and terminate the child process def handle_sigterm(_signum, _frame): - Utility.clean_temp_dir() + SetupUtility.clean_temp_dir() p.terminate() signal.signal(signal.SIGTERM, handle_sigterm) @@ -222,7 +221,7 @@ def handle_sigterm(_signum, _frame): p.wait() # Clean up - Utility.clean_temp_dir() + SetupUtility.clean_temp_dir() sys.exit(p.returncode) # Import the required entry point diff --git a/blenderproc/python/utility/Initializer.py b/blenderproc/python/utility/Initializer.py index 0bb15e6a8..7352fc23b 100644 --- a/blenderproc/python/utility/Initializer.py +++ b/blenderproc/python/utility/Initializer.py @@ -9,7 +9,7 @@ import bpy from blenderproc.python.utility.GlobalStorage import GlobalStorage -from blenderproc.python.utility.Utility import Utility, reset_keyframes +from blenderproc.python.utility.Utility import reset_keyframes from blenderproc.python.utility.SetupUtility import SetupUtility, is_using_external_bpy_module from blenderproc.python.camera import CameraUtility from blenderproc.python.utility.DefaultConfig import DefaultConfig @@ -17,7 +17,7 @@ def handle_sigterm(_signum, _frame): - Utility.clean_temp_dir() + SetupUtility.clean_temp_dir() def init(clean_up_scene: bool = True): @@ -39,7 +39,7 @@ def init(clean_up_scene: bool = True): # this is the only mandatory initialization point and any of the code in command_line.py # isn't executed. SetupUtility.setup_utility_paths(SetupUtility.determine_temp_dir(None)) - atexit.register(Utility.clean_temp_dir) + atexit.register(SetupUtility.clean_temp_dir) signal.signal(signal.SIGTERM, handle_sigterm) if clean_up_scene: diff --git a/blenderproc/python/utility/SetupUtility.py b/blenderproc/python/utility/SetupUtility.py index 885cba066..1f271ff5a 100644 --- a/blenderproc/python/utility/SetupUtility.py +++ b/blenderproc/python/utility/SetupUtility.py @@ -4,6 +4,7 @@ import sys import tarfile from sys import platform +import shutil import subprocess import importlib from io import BytesIO @@ -17,14 +18,14 @@ from blenderproc.python.utility.DefaultConfig import DefaultConfig -def is_using_external_bpy_module(): +def is_using_external_bpy_module() -> bool: """Returns True if the external bpy module is used, False otherwise. At this point we don't check whether 'bpy' is available, this is handled in the first lines of __init__.py. When using external by module, we assume it's available all the time as the script had to fail before. - If using blenderproc's Blender installation, setup goes through the InstallUtility and + If using BlenderProc's Blender installation, setup goes through the InstallUtility and SetupUtility. """ return os.environ.get("USE_EXTERNAL_BPY_MODULE", "0") == "1" @@ -59,26 +60,28 @@ def setup(user_required_packages: Optional[List[str]] = None, blender_path: Opti :return: List of sys.argv after removing blender specific commands """ - if not is_using_external_bpy_module(): - packages_path = SetupUtility.setup_pip(user_required_packages, blender_path, major_version, reinstall_packages) - if not SetupUtility.main_setup_called: - SetupUtility.main_setup_called = True - sys.path.append(packages_path) - is_debug_mode = "--background" not in sys.argv - - # Setup temporary directory - if is_debug_mode: - SetupUtility.setup_utility_paths("examples/debugging/temp") - else: - SetupUtility.setup_utility_paths(sys.argv[sys.argv.index("--") + 2]) + if is_using_external_bpy_module(): + raise RuntimeError("USE_EXTERNAL_BPY_MODULE is set, calling this is not necessary in external mode.") + + packages_path = SetupUtility.setup_pip(user_required_packages, blender_path, major_version, reinstall_packages) + if not SetupUtility.main_setup_called: + SetupUtility.main_setup_called = True + sys.path.append(packages_path) + is_debug_mode = "--background" not in sys.argv + + # Setup temporary directory + if is_debug_mode: + SetupUtility.setup_utility_paths("examples/debugging/temp") + else: + SetupUtility.setup_utility_paths(sys.argv[sys.argv.index("--") + 2]) - # Only prepare args in non-debug mode (In debug mode the arguments are already ready to use) - if not is_debug_mode: - # Cut off blender specific arguments - sys.argv = sys.argv[sys.argv.index("--") + 1:sys.argv.index("--") + 2] + \ - sys.argv[sys.argv.index("--") + 3:] - elif debug_args is not None: - sys.argv = ["debug"] + debug_args + # Only prepare args in non-debug mode (In debug mode the arguments are already ready to use) + if not is_debug_mode: + # Cut off blender specific arguments + sys.argv = sys.argv[sys.argv.index("--") + 1:sys.argv.index("--") + 2] + \ + sys.argv[sys.argv.index("--") + 3:] + elif debug_args is not None: + sys.argv = ["debug"] + debug_args return sys.argv @@ -95,6 +98,16 @@ def setup_utility_paths(temp_dir: str): Utility.temp_dir = resolve_path(temp_dir) os.makedirs(Utility.temp_dir, exist_ok=True) + @staticmethod + def clean_temp_dir() -> None: + """ Removes the temporary directory if it exists. """ + # pylint: disable=import-outside-toplevel,cyclic-import + from blenderproc.python.utility.Utility import Utility + # pylint: enable=import-outside-toplevel,cyclic-import + if os.path.exists(Utility.temp_dir): + print("Cleaning temporary directory") + shutil.rmtree(Utility.temp_dir) + @staticmethod def determine_python_paths(blender_path: Optional[str], major_version: Optional[str]) -> Union[str, str, str, str]: """ Determines python binary, custom pip packages and the blender pip packages path. diff --git a/blenderproc/python/utility/Utility.py b/blenderproc/python/utility/Utility.py index e2c1f76c6..d71fe3435 100644 --- a/blenderproc/python/utility/Utility.py +++ b/blenderproc/python/utility/Utility.py @@ -102,13 +102,6 @@ def get_temporary_directory() -> str: """ return Utility.temp_dir - @staticmethod - def clean_temp_dir() -> None: - """ Removes the temporary directory if it exists. """ - if os.path.exists(Utility.temp_dir): - print("Cleaning temporary directory") - shutil.rmtree(Utility.temp_dir) - @staticmethod def merge_dicts(source: Dict[Any, Any], destination: Dict[Any, Any]) -> Dict[Any, Any]: """ Recursively copies all key value pairs from src to dest (Overwrites existing)