From 9c221a36c30a05de6c9b67e17b4ca941f01a4c31 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Sun, 29 Jan 2023 15:22:52 +0300 Subject: [PATCH 01/68] use recommended Reactor env variables --- openpype/hosts/fusion/deploy/fusion_shared.prefs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openpype/hosts/fusion/deploy/fusion_shared.prefs b/openpype/hosts/fusion/deploy/fusion_shared.prefs index 998c6a6d66..5bfde9a5c9 100644 --- a/openpype/hosts/fusion/deploy/fusion_shared.prefs +++ b/openpype/hosts/fusion/deploy/fusion_shared.prefs @@ -4,8 +4,7 @@ Global = { Paths = { Map = { ["OpenPype:"] = "$(OPENPYPE_FUSION)/deploy", - ["Reactor:"] = "$(REACTOR)", - + ["Reactor:"] = "$(REACTOR_INSTALL_PATHMAP)/Reactor", ["Config:"] = "UserPaths:Config;OpenPype:Config", ["Scripts:"] = "UserPaths:Scripts;Reactor:System/Scripts;OpenPype:Scripts", ["UserPaths:"] = "UserData:;AllData:;Fusion:;Reactor:Deploy" From bb0d128f1d4b22f6744eed58ad91f649b8642d83 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Sun, 29 Jan 2023 22:37:07 +0300 Subject: [PATCH 02/68] nightly version is not parsed --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ceab9eeff1..2fc4f6fe39 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "OpenPype" -version = "3.15.1-nightly.1" # OpenPype +version = "3.15.1" # OpenPype description = "Open VFX and Animation pipeline with support." authors = ["OpenPype Team "] license = "MIT License" From c1f88602a09bd7b476344f2a1fbf8efb8789734d Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Tue, 31 Jan 2023 03:14:43 +0300 Subject: [PATCH 03/68] split get comp and get fusion, add get comp name just in case --- openpype/hosts/fusion/api/lib.py | 22 +++++++++++++++++++--- openpype/hosts/fusion/api/workio.py | 7 ++----- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/openpype/hosts/fusion/api/lib.py b/openpype/hosts/fusion/api/lib.py index a33e5cf289..851e9ec94a 100644 --- a/openpype/hosts/fusion/api/lib.py +++ b/openpype/hosts/fusion/api/lib.py @@ -302,10 +302,26 @@ def get_frame_path(path): return filename, padding, ext +def get_comp_name(comp=None): + """Get basename of the comp's filename""" + if comp: + comp_name = os.path.basename(comp.GetAttrs()["COMPS_FileName"]) + return comp_name + + +def get_fusion(): + """Get Fusion instance""" + app = getattr(sys.modules["BlackmagicFusion"], "scriptapp", None) + if app: + fusion = app("Fusion", "localhost") + return fusion + + def get_current_comp(): - """Hack to get current comp in this session""" - fusion = getattr(sys.modules["__main__"], "fusion", None) - return fusion.CurrentComp if fusion else None + """Get current comp in this session""" + fusion = get_fusion() + comp = fusion.CurrentComp + return comp @contextlib.contextmanager diff --git a/openpype/hosts/fusion/api/workio.py b/openpype/hosts/fusion/api/workio.py index 939b2ff4be..da36a83988 100644 --- a/openpype/hosts/fusion/api/workio.py +++ b/openpype/hosts/fusion/api/workio.py @@ -2,7 +2,7 @@ import sys import os -from .lib import get_current_comp +from .lib import get_fusion, get_current_comp def file_extensions(): @@ -20,10 +20,7 @@ def save_file(filepath): def open_file(filepath): - # Hack to get fusion, see - # openpype.hosts.fusion.api.pipeline.get_current_comp() - fusion = getattr(sys.modules["__main__"], "fusion", None) - + fusion = get_fusion() return fusion.LoadComp(filepath) From c0c859b6f1f0c34db4c0024a4b751c9715d5c6bf Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Tue, 31 Jan 2023 03:15:43 +0300 Subject: [PATCH 04/68] set a temporary profile folder, copy existing prefs there --- .../hosts/fusion/hooks/pre_fusion_setup.py | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index d043d54322..f6cec86e3b 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -1,4 +1,7 @@ import os +import shutil +import platform +from pathlib import Path from openpype.lib import PreLaunchHook, ApplicationLaunchFailed from openpype.hosts.fusion import FUSION_HOST_DIR @@ -17,6 +20,25 @@ class FusionPrelaunch(PreLaunchHook): """ app_groups = ["fusion"] + def get_profile_source(self): + fusion_prefs_path = "Blackmagic Design/Fusion/Profiles/Default/Fusion.prefs" + if platform.system() == "Windows": + prefs_source = Path(os.getenv("AppData")) / fusion_prefs_path + elif platform.system() == "Darwin": + prefs_source = Path(os.path.expanduser("~/Library/Application Support/")) / fusion_prefs_path + elif platform.system() == "Linux": + prefs_source = Path(os.path.expanduser("~/.fusion")) / fusion_prefs_path + + return str(prefs_source) + + def copy_existing_prefs(self, profile_directory: str): + dest_folder = os.path.join(profile_directory, "Default") + os.makedirs(dest_folder, exist_ok=True) + prefs_source = self.get_profile_source() + if os.path.exists(prefs_source): + shutil.copy(prefs_source, dest_folder) + self.log.info(f"successfully copied preferences:\n {prefs_source} to {dest_folder}") + def execute(self): # making sure python 3 is installed at provided path # Py 3.3-3.10 for Fusion 18+ or Py 3.6 for Fu 16-17 @@ -50,12 +72,20 @@ class FusionPrelaunch(PreLaunchHook): # TODO: Detect Fusion version to only set for specific Fusion build self.launch_context.env["FUSION16_PYTHON36_HOME"] = py3_dir - # Add our Fusion Master Prefs which is the only way to customize + # Add custom Fusion Master Prefs and the temporary profile directory variables to customize # Fusion to define where it can read custom scripts and tools from self.log.info(f"Setting OPENPYPE_FUSION: {FUSION_HOST_DIR}") self.launch_context.env["OPENPYPE_FUSION"] = FUSION_HOST_DIR + profile_dir_var = "FUSION16_PROFILE_DIR" # used by Fusion 16, 17 and 18 pref_var = "FUSION16_MasterPrefs" # used by Fusion 16, 17 and 18 + profile_dir = os.path.join(FUSION_HOST_DIR, "deploy", "Prefs") prefs = os.path.join(FUSION_HOST_DIR, "deploy", "fusion_shared.prefs") + + # now copy the default Fusion profile to a working directory + if not os.path.exists(profile_dir): + self.copy_existing_prefs(profile_dir) + self.log.info(f"Setting {profile_dir_var}: {profile_dir}") + self.launch_context.env[profile_dir_var] = profile_dir self.log.info(f"Setting {pref_var}: {prefs}") self.launch_context.env[pref_var] = prefs From 0c23f212c08811d2fb3cafa2980f0344afee5a5b Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Tue, 31 Jan 2023 03:18:20 +0300 Subject: [PATCH 05/68] remove Reactor mapping as it is copied from existing prefs --- openpype/hosts/fusion/deploy/fusion_shared.prefs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openpype/hosts/fusion/deploy/fusion_shared.prefs b/openpype/hosts/fusion/deploy/fusion_shared.prefs index 5bfde9a5c9..d9451ea295 100644 --- a/openpype/hosts/fusion/deploy/fusion_shared.prefs +++ b/openpype/hosts/fusion/deploy/fusion_shared.prefs @@ -4,10 +4,9 @@ Global = { Paths = { Map = { ["OpenPype:"] = "$(OPENPYPE_FUSION)/deploy", - ["Reactor:"] = "$(REACTOR_INSTALL_PATHMAP)/Reactor", ["Config:"] = "UserPaths:Config;OpenPype:Config", ["Scripts:"] = "UserPaths:Scripts;Reactor:System/Scripts;OpenPype:Scripts", - ["UserPaths:"] = "UserData:;AllData:;Fusion:;Reactor:Deploy" + ["UserPaths:"] = "UserData:;GIT:;AllData:;Fusion:;Reactor:Deploy" }, }, Script = { From cfd718d943dc4b0cf22eb5bff5a10b12dfe4cf3b Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Thu, 2 Feb 2023 00:07:27 +0300 Subject: [PATCH 06/68] rollback the get_fusion, properly return comp name --- openpype/hosts/fusion/api/lib.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/fusion/api/lib.py b/openpype/hosts/fusion/api/lib.py index 851e9ec94a..ac30e1ff99 100644 --- a/openpype/hosts/fusion/api/lib.py +++ b/openpype/hosts/fusion/api/lib.py @@ -305,16 +305,13 @@ def get_frame_path(path): def get_comp_name(comp=None): """Get basename of the comp's filename""" if comp: - comp_name = os.path.basename(comp.GetAttrs()["COMPS_FileName"]) - return comp_name + return comp.GetAttrs()["COMPS_Name"] def get_fusion(): """Get Fusion instance""" - app = getattr(sys.modules["BlackmagicFusion"], "scriptapp", None) - if app: - fusion = app("Fusion", "localhost") - return fusion + fusion = getattr(sys.modules["__main__"], "fusion", None) + return fusion def get_current_comp(): From 324eaa26b91cbcef39d416bc6cd5bbf9e848cb65 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Fri, 3 Feb 2023 02:21:14 +0300 Subject: [PATCH 07/68] use temp folder to store the prefs, check if FUSION16_PROFILE_DIR exists --- .../hosts/fusion/hooks/pre_fusion_setup.py | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index f6cec86e3b..01b2a37b74 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -19,8 +19,14 @@ class FusionPrelaunch(PreLaunchHook): """ app_groups = ["fusion"] + OPENPYPE_FUSION_PROFILE_DIR = "~/.openpype/hosts/fusion/prefs" def get_profile_source(self): + fusion_var_prefs_dir = os.getenv("FUSION16_PROFILE_DIR") + if fusion_var_prefs_dir and Path(fusion_var_prefs_dir).is_dir(): + self.log.info(f"local Fusion prefs environment is set to {fusion_var_prefs_dir}") + return os.path.join(fusion_var_prefs_dir, "Fusion.prefs") + fusion_prefs_path = "Blackmagic Design/Fusion/Profiles/Default/Fusion.prefs" if platform.system() == "Windows": prefs_source = Path(os.getenv("AppData")) / fusion_prefs_path @@ -32,16 +38,19 @@ class FusionPrelaunch(PreLaunchHook): return str(prefs_source) def copy_existing_prefs(self, profile_directory: str): - dest_folder = os.path.join(profile_directory, "Default") - os.makedirs(dest_folder, exist_ok=True) + dest_folder = Path(profile_directory) / "Default" + dest_folder.mkdir(exist_ok=True, parents=True) prefs_source = self.get_profile_source() - if os.path.exists(prefs_source): - shutil.copy(prefs_source, dest_folder) - self.log.info(f"successfully copied preferences:\n {prefs_source} to {dest_folder}") + if not Path(prefs_source).exists(): + self.log.warning(f"Fusion preferences file not found in {prefs_source}") + return + shutil.copy(prefs_source, dest_folder) + self.log.info(f"successfully copied preferences:\n {prefs_source} to {dest_folder}") def execute(self): # making sure python 3 is installed at provided path # Py 3.3-3.10 for Fusion 18+ or Py 3.6 for Fu 16-17 + py3_var = "FUSION_PYTHON3_HOME" fusion_python3_home = self.launch_context.env.get(py3_var, "") @@ -79,10 +88,11 @@ class FusionPrelaunch(PreLaunchHook): profile_dir_var = "FUSION16_PROFILE_DIR" # used by Fusion 16, 17 and 18 pref_var = "FUSION16_MasterPrefs" # used by Fusion 16, 17 and 18 - profile_dir = os.path.join(FUSION_HOST_DIR, "deploy", "Prefs") + profile_dir = os.path.expanduser(self.OPENPYPE_FUSION_PROFILE_DIR) prefs = os.path.join(FUSION_HOST_DIR, "deploy", "fusion_shared.prefs") # now copy the default Fusion profile to a working directory + # only if the openpype profile folder does not exist if not os.path.exists(profile_dir): self.copy_existing_prefs(profile_dir) self.log.info(f"Setting {profile_dir_var}: {profile_dir}") From 3b0f5601338b3299de1493b00754633a55053bf5 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Fri, 3 Feb 2023 02:22:02 +0300 Subject: [PATCH 08/68] remove custom pathmap --- openpype/hosts/fusion/deploy/fusion_shared.prefs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/fusion/deploy/fusion_shared.prefs b/openpype/hosts/fusion/deploy/fusion_shared.prefs index d9451ea295..0225b2209b 100644 --- a/openpype/hosts/fusion/deploy/fusion_shared.prefs +++ b/openpype/hosts/fusion/deploy/fusion_shared.prefs @@ -6,7 +6,7 @@ Global = { ["OpenPype:"] = "$(OPENPYPE_FUSION)/deploy", ["Config:"] = "UserPaths:Config;OpenPype:Config", ["Scripts:"] = "UserPaths:Scripts;Reactor:System/Scripts;OpenPype:Scripts", - ["UserPaths:"] = "UserData:;GIT:;AllData:;Fusion:;Reactor:Deploy" + ["UserPaths:"] = "UserData:;AllData:;Fusion:;Reactor:Deploy" }, }, Script = { @@ -14,4 +14,4 @@ Global = { Python3Forced = true }, }, -} \ No newline at end of file +} From 13a364377d93fe33317a6b17b861b89f187fe54b Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Fri, 3 Feb 2023 02:23:30 +0300 Subject: [PATCH 09/68] use get comp filename from lib --- openpype/hosts/fusion/api/lib.py | 20 +++++++++++--------- openpype/hosts/fusion/api/workio.py | 10 +++------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/openpype/hosts/fusion/api/lib.py b/openpype/hosts/fusion/api/lib.py index ac30e1ff99..ec96d6cf18 100644 --- a/openpype/hosts/fusion/api/lib.py +++ b/openpype/hosts/fusion/api/lib.py @@ -302,14 +302,8 @@ def get_frame_path(path): return filename, padding, ext -def get_comp_name(comp=None): - """Get basename of the comp's filename""" - if comp: - return comp.GetAttrs()["COMPS_Name"] - - def get_fusion(): - """Get Fusion instance""" + """Get current Fusion instance""" fusion = getattr(sys.modules["__main__"], "fusion", None) return fusion @@ -317,8 +311,16 @@ def get_fusion(): def get_current_comp(): """Get current comp in this session""" fusion = get_fusion() - comp = fusion.CurrentComp - return comp + if fusion: + comp = fusion.CurrentComp + return comp + + +def get_comp_filename(): + """Get comp's Filename""" + comp = get_current_comp() + if comp: + return comp.GetAttrs()["COMPS_FileName"] @contextlib.contextmanager diff --git a/openpype/hosts/fusion/api/workio.py b/openpype/hosts/fusion/api/workio.py index da36a83988..048e6e090a 100644 --- a/openpype/hosts/fusion/api/workio.py +++ b/openpype/hosts/fusion/api/workio.py @@ -2,7 +2,7 @@ import sys import os -from .lib import get_fusion, get_current_comp +from .lib import get_fusion, get_current_comp, get_comp_filename def file_extensions(): @@ -25,12 +25,8 @@ def open_file(filepath): def current_file(): - comp = get_current_comp() - current_filepath = comp.GetAttrs()["COMPS_FileName"] - if not current_filepath: - return None - - return current_filepath + current_filepath = get_comp_filename() + return current_filepath or None def work_root(session): From 62319248a10f91488b1417fe52cd78a3fac8e24c Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Fri, 3 Feb 2023 02:26:34 +0300 Subject: [PATCH 10/68] do not override Userpaths --- openpype/hosts/fusion/deploy/fusion_shared.prefs | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/hosts/fusion/deploy/fusion_shared.prefs b/openpype/hosts/fusion/deploy/fusion_shared.prefs index 0225b2209b..8d0e45eae5 100644 --- a/openpype/hosts/fusion/deploy/fusion_shared.prefs +++ b/openpype/hosts/fusion/deploy/fusion_shared.prefs @@ -6,7 +6,6 @@ Global = { ["OpenPype:"] = "$(OPENPYPE_FUSION)/deploy", ["Config:"] = "UserPaths:Config;OpenPype:Config", ["Scripts:"] = "UserPaths:Scripts;Reactor:System/Scripts;OpenPype:Scripts", - ["UserPaths:"] = "UserData:;AllData:;Fusion:;Reactor:Deploy" }, }, Script = { From be90410047508cd4826b933dd57361f3fa576c2c Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Fri, 3 Feb 2023 13:12:35 +0300 Subject: [PATCH 11/68] use pathlib over os.path, check if FUSION_PROFILE is set --- .../hosts/fusion/hooks/pre_fusion_setup.py | 65 +++++++++++-------- 1 file changed, 38 insertions(+), 27 deletions(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index 01b2a37b74..eadcb481e3 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -20,32 +20,41 @@ class FusionPrelaunch(PreLaunchHook): """ app_groups = ["fusion"] OPENPYPE_FUSION_PROFILE_DIR = "~/.openpype/hosts/fusion/prefs" + PROFILE_NUMBER = 16 - def get_profile_source(self): - fusion_var_prefs_dir = os.getenv("FUSION16_PROFILE_DIR") + def get_fusion_profile(self) -> str: + return os.getenv(f"FUSION{self.PROFILE_NUMBER}_PROFILE", "Default") + + def get_profile_source(self) -> Path: + fusion_var_prefs_dir = os.getenv(f"FUSION{self.PROFILE_NUMBER}_PROFILE_DIR") + + # if FUSION16_PROFILE_DIR variable exists, return the profile filepath if fusion_var_prefs_dir and Path(fusion_var_prefs_dir).is_dir(): - self.log.info(f"local Fusion prefs environment is set to {fusion_var_prefs_dir}") - return os.path.join(fusion_var_prefs_dir, "Fusion.prefs") - - fusion_prefs_path = "Blackmagic Design/Fusion/Profiles/Default/Fusion.prefs" + fusion_profile = self.get_fusion_profile() + fusion_prefs_dir = Path(fusion_var_prefs_dir, fusion_profile) + self.log.info(f"Local Fusion prefs environment is set to {fusion_prefs_dir}") + fusion_prefs_filepath = fusion_prefs_dir / "Fusion.prefs" + return fusion_prefs_filepath + + # otherwise get the profile from default prefs location + fusion_prefs_path = f"Blackmagic Design/Fusion/Profiles/{fusion_var_prefs_dir}/Fusion.prefs" if platform.system() == "Windows": prefs_source = Path(os.getenv("AppData")) / fusion_prefs_path elif platform.system() == "Darwin": - prefs_source = Path(os.path.expanduser("~/Library/Application Support/")) / fusion_prefs_path + prefs_source = Path("~/Library/Application Support/", fusion_prefs_path).expanduser() elif platform.system() == "Linux": - prefs_source = Path(os.path.expanduser("~/.fusion")) / fusion_prefs_path + prefs_source = Path("~/.fusion", fusion_prefs_path).expanduser() + + return prefs_source - return str(prefs_source) - - def copy_existing_prefs(self, profile_directory: str): - dest_folder = Path(profile_directory) / "Default" + def copy_existing_prefs(self, copy_from: Path, copy_to: Path) -> None: + dest_folder = copy_to / self.get_fusion_profile() dest_folder.mkdir(exist_ok=True, parents=True) - prefs_source = self.get_profile_source() - if not Path(prefs_source).exists(): - self.log.warning(f"Fusion preferences file not found in {prefs_source}") + if not copy_from.exists(): + self.log.warning(f"Fusion preferences file not found in {copy_from}") return - shutil.copy(prefs_source, dest_folder) - self.log.info(f"successfully copied preferences:\n {prefs_source} to {dest_folder}") + shutil.copy(str(copy_from), str(dest_folder)) # compatible with Python >= 3.6 + self.log.info(f"successfully copied preferences:\n {copy_from} to {dest_folder}") def execute(self): # making sure python 3 is installed at provided path @@ -54,12 +63,12 @@ class FusionPrelaunch(PreLaunchHook): py3_var = "FUSION_PYTHON3_HOME" fusion_python3_home = self.launch_context.env.get(py3_var, "") - self.log.info(f"Looking for Python 3 in: {fusion_python3_home}") for path in fusion_python3_home.split(os.pathsep): - # Allow defining multiple paths to allow "fallback" to other + # Allow defining multiple paths, separated by os.pathsep, to allow "fallback" to other # path. But make to set only a single path as final variable. py3_dir = os.path.normpath(path) if os.path.isdir(py3_dir): + self.log.info(f"Looking for Python 3 in: {py3_dir}") break else: raise ApplicationLaunchFailed( @@ -88,14 +97,16 @@ class FusionPrelaunch(PreLaunchHook): profile_dir_var = "FUSION16_PROFILE_DIR" # used by Fusion 16, 17 and 18 pref_var = "FUSION16_MasterPrefs" # used by Fusion 16, 17 and 18 - profile_dir = os.path.expanduser(self.OPENPYPE_FUSION_PROFILE_DIR) - prefs = os.path.join(FUSION_HOST_DIR, "deploy", "fusion_shared.prefs") + op_profile_dir = Path(self.OPENPYPE_FUSION_PROFILE_DIR).expanduser() + op_master_prefs = Path(FUSION_HOST_DIR, "deploy", "fusion_shared.prefs") + prefs_source = self.get_profile_source() + self.log.info(f"Got Fusion prefs file: {prefs_source}") # now copy the default Fusion profile to a working directory # only if the openpype profile folder does not exist - if not os.path.exists(profile_dir): - self.copy_existing_prefs(profile_dir) - self.log.info(f"Setting {profile_dir_var}: {profile_dir}") - self.launch_context.env[profile_dir_var] = profile_dir - self.log.info(f"Setting {pref_var}: {prefs}") - self.launch_context.env[pref_var] = prefs + if not op_profile_dir.exists(): + self.copy_existing_prefs(prefs_source, op_profile_dir) + self.log.info(f"Setting {profile_dir_var}: {op_profile_dir}") + self.launch_context.env[profile_dir_var] = str(op_profile_dir) + self.log.info(f"Setting {pref_var}: {op_master_prefs}") + self.launch_context.env[pref_var] = str(op_master_prefs) From 95280aef00d3886170f593e47129bb6560502c2b Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Fri, 3 Feb 2023 13:44:30 +0300 Subject: [PATCH 12/68] fix get fusion profile --- openpype/hosts/fusion/hooks/pre_fusion_setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index eadcb481e3..4f000a12b2 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -26,18 +26,18 @@ class FusionPrelaunch(PreLaunchHook): return os.getenv(f"FUSION{self.PROFILE_NUMBER}_PROFILE", "Default") def get_profile_source(self) -> Path: + fusion_profile = self.get_fusion_profile() fusion_var_prefs_dir = os.getenv(f"FUSION{self.PROFILE_NUMBER}_PROFILE_DIR") # if FUSION16_PROFILE_DIR variable exists, return the profile filepath if fusion_var_prefs_dir and Path(fusion_var_prefs_dir).is_dir(): - fusion_profile = self.get_fusion_profile() fusion_prefs_dir = Path(fusion_var_prefs_dir, fusion_profile) self.log.info(f"Local Fusion prefs environment is set to {fusion_prefs_dir}") fusion_prefs_filepath = fusion_prefs_dir / "Fusion.prefs" return fusion_prefs_filepath # otherwise get the profile from default prefs location - fusion_prefs_path = f"Blackmagic Design/Fusion/Profiles/{fusion_var_prefs_dir}/Fusion.prefs" + fusion_prefs_path = f"Blackmagic Design/Fusion/Profiles/{fusion_profile}/Fusion.prefs" if platform.system() == "Windows": prefs_source = Path(os.getenv("AppData")) / fusion_prefs_path elif platform.system() == "Darwin": From 9bba80ff6196cff4c4579bcb78db9f8ef1623081 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Fri, 3 Feb 2023 20:32:38 +0300 Subject: [PATCH 13/68] add copy fusion prefs global settings --- .../system_settings/applications.json | 8 +++++- .../host_settings/schema_fusion.json | 25 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/openpype/settings/defaults/system_settings/applications.json b/openpype/settings/defaults/system_settings/applications.json index 936407a49b..5d75b3b606 100644 --- a/openpype/settings/defaults/system_settings/applications.json +++ b/openpype/settings/defaults/system_settings/applications.json @@ -835,6 +835,10 @@ "linux": "/opt/Python/3.6/bin" } }, + "copy_fusion_settings": { + "copy_prefs": false, + "prefs_path": "~/.openpype/hosts/fusion/prefs" + }, "variants": { "18": { "executables": { @@ -1302,7 +1306,9 @@ "variant_label": "Current", "use_python_2": false, "executables": { - "windows": ["C:/Program Files/CelAction/CelAction2D Studio/CelAction2D.exe"], + "windows": [ + "C:/Program Files/CelAction/CelAction2D Studio/CelAction2D.exe" + ], "darwin": [], "linux": [] }, diff --git a/openpype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json b/openpype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json index 5960da7774..360813bcb5 100644 --- a/openpype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json +++ b/openpype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json @@ -19,6 +19,31 @@ "label": "Environment", "type": "raw-json" }, + { + "type": "splitter" + }, + { + "type": "dict", + "key": "copy_fusion_settings", + "collapsible": true, + "checkbox_key": "copy_prefs", + "label": "Copy Fusion preferences", + "children": [ + { + "type": "boolean", + "key": "copy_prefs", + "label": "Enabled" + }, + { + "key": "prefs_path", + "type": "path", + "label": "Local prefs directory" + } + ] + }, + { + "type": "splitter" + }, { "type": "dict-modifiable", "key": "variants", From 3ff8aa5c958e79000bd82967de82e436947c11fd Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Mon, 13 Feb 2023 00:39:55 +0300 Subject: [PATCH 14/68] use system settings to get data, add force sync option --- .../hosts/fusion/hooks/pre_fusion_setup.py | 71 ++++++++++++------- .../system_settings/applications.json | 3 +- .../host_settings/schema_fusion.json | 7 +- 3 files changed, 55 insertions(+), 26 deletions(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index 4f000a12b2..4dc11abce9 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -4,6 +4,7 @@ import platform from pathlib import Path from openpype.lib import PreLaunchHook, ApplicationLaunchFailed from openpype.hosts.fusion import FUSION_HOST_DIR +from openpype.settings import get_system_settings class FusionPrelaunch(PreLaunchHook): @@ -19,14 +20,18 @@ class FusionPrelaunch(PreLaunchHook): """ app_groups = ["fusion"] - OPENPYPE_FUSION_PROFILE_DIR = "~/.openpype/hosts/fusion/prefs" PROFILE_NUMBER = 16 - def get_fusion_profile(self) -> str: + def get_fusion_profile_name(self) -> str: + """usually set to 'Default', unless FUSION16_PROFILE is set""" return os.getenv(f"FUSION{self.PROFILE_NUMBER}_PROFILE", "Default") def get_profile_source(self) -> Path: - fusion_profile = self.get_fusion_profile() + """Get the Fusion preferences (profile) location. + Check https://www.steakunderwater.com/VFXPedia/96.0.243.189/indexad6a.html?title=Per-User_Preferences_and_Paths#Setting_the_profile_directory + for reference. + """ + fusion_profile = self.get_fusion_profile_name() fusion_var_prefs_dir = os.getenv(f"FUSION{self.PROFILE_NUMBER}_PROFILE_DIR") # if FUSION16_PROFILE_DIR variable exists, return the profile filepath @@ -44,11 +49,32 @@ class FusionPrelaunch(PreLaunchHook): prefs_source = Path("~/Library/Application Support/", fusion_prefs_path).expanduser() elif platform.system() == "Linux": prefs_source = Path("~/.fusion", fusion_prefs_path).expanduser() - + self.log.info(f"Got Fusion prefs file: {prefs_source}") return prefs_source - def copy_existing_prefs(self, copy_from: Path, copy_to: Path) -> None: - dest_folder = copy_to / self.get_fusion_profile() + def get_copy_fusion_prefs_settings(self): + """Git copy prefserences options from the global application settings""" + copy_status = copy_path = None + try: + copy_status, copy_path, force_sync = get_system_settings()["applications"]["fusion"][ + "copy_fusion_settings"].values() + except ValueError: + self.log.error('Copy prefs settings not found') + finally: + return copy_status, copy_path, force_sync + + def copy_existing_prefs(self, copy_from: Path, copy_to: Path, force_sync: bool) -> None: + """On the first Fusion launch copy the Fusion profile to the working directory. + If the Openpype profile folder exists, skip copying, unless Force sync is checked. + If the prefs were not copied on the first launch, clean Fusion profile + will be created in openpype_fusion_profile_dir. + """ + if copy_to.exists() and not force_sync: + self.log.info("Local Fusion preferences folder exists, skipping profile copy") + return + self.log.info(f"Starting copying Fusion preferences") + self.log.info(f"force_sync option is set to {force_sync}") + dest_folder = copy_to / self.get_fusion_profile_name() dest_folder.mkdir(exist_ok=True, parents=True) if not copy_from.exists(): self.log.warning(f"Fusion preferences file not found in {copy_from}") @@ -88,25 +114,22 @@ class FusionPrelaunch(PreLaunchHook): # Fusion 16 and 17 use FUSION16_PYTHON36_HOME instead of # FUSION_PYTHON3_HOME and will only work with a Python 3.6 version # TODO: Detect Fusion version to only set for specific Fusion build - self.launch_context.env["FUSION16_PYTHON36_HOME"] = py3_dir + self.launch_context.env[f"FUSION{self.PROFILE_NUMBER}_PYTHON36_HOME"] = py3_dir - # Add custom Fusion Master Prefs and the temporary profile directory variables to customize - # Fusion to define where it can read custom scripts and tools from + # Add custom Fusion Master Prefs and the temporary profile directory variables + # to customize Fusion to define where it can read custom scripts and tools from self.log.info(f"Setting OPENPYPE_FUSION: {FUSION_HOST_DIR}") self.launch_context.env["OPENPYPE_FUSION"] = FUSION_HOST_DIR - profile_dir_var = "FUSION16_PROFILE_DIR" # used by Fusion 16, 17 and 18 - pref_var = "FUSION16_MasterPrefs" # used by Fusion 16, 17 and 18 - op_profile_dir = Path(self.OPENPYPE_FUSION_PROFILE_DIR).expanduser() - op_master_prefs = Path(FUSION_HOST_DIR, "deploy", "fusion_shared.prefs") - prefs_source = self.get_profile_source() - self.log.info(f"Got Fusion prefs file: {prefs_source}") - - # now copy the default Fusion profile to a working directory - # only if the openpype profile folder does not exist - if not op_profile_dir.exists(): - self.copy_existing_prefs(prefs_source, op_profile_dir) - self.log.info(f"Setting {profile_dir_var}: {op_profile_dir}") - self.launch_context.env[profile_dir_var] = str(op_profile_dir) - self.log.info(f"Setting {pref_var}: {op_master_prefs}") - self.launch_context.env[pref_var] = str(op_master_prefs) + copy_status, openpype_fusion_profile_dir, force_sync = self.get_copy_fusion_prefs_settings() + if copy_status: + prefs_source = self.get_profile_source() + openpype_fusion_profile_dir = Path(openpype_fusion_profile_dir).expanduser() + self.copy_existing_prefs(prefs_source, openpype_fusion_profile_dir, force_sync) + fusion_profile_dir_variable = f"FUSION{self.PROFILE_NUMBER}_PROFILE_DIR" + pref_var = f"FUSION{self.PROFILE_NUMBER}_MasterPrefs" + openpype_master_prefs = Path(FUSION_HOST_DIR, "deploy", "fusion_shared.prefs") + self.log.info(f"Setting {fusion_profile_dir_variable}: {openpype_fusion_profile_dir}") + self.launch_context.env[fusion_profile_dir_variable] = str(openpype_fusion_profile_dir) + self.log.info(f"Setting {pref_var}: {openpype_master_prefs}") + self.launch_context.env[pref_var] = str(openpype_master_prefs) diff --git a/openpype/settings/defaults/system_settings/applications.json b/openpype/settings/defaults/system_settings/applications.json index 5d75b3b606..9fb730568e 100644 --- a/openpype/settings/defaults/system_settings/applications.json +++ b/openpype/settings/defaults/system_settings/applications.json @@ -837,7 +837,8 @@ }, "copy_fusion_settings": { "copy_prefs": false, - "prefs_path": "~/.openpype/hosts/fusion/prefs" + "prefs_path": "~/.openpype/hosts/fusion/prefs", + "force_sync": false }, "variants": { "18": { diff --git a/openpype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json b/openpype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json index 360813bcb5..48355932ae 100644 --- a/openpype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json +++ b/openpype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json @@ -27,7 +27,7 @@ "key": "copy_fusion_settings", "collapsible": true, "checkbox_key": "copy_prefs", - "label": "Copy Fusion preferences", + "label": "Copy Fusion settings when launched from OpenPype", "children": [ { "type": "boolean", @@ -38,6 +38,11 @@ "key": "prefs_path", "type": "path", "label": "Local prefs directory" + }, + { + "key":"force_sync", + "type": "boolean", + "label": "Always sync preferences on launch" } ] }, From 76bdcb49ea019fe7028bce87916b14dcf4a829f1 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Mon, 13 Feb 2023 00:40:51 +0300 Subject: [PATCH 15/68] get the prefs path correctly --- openpype/hosts/fusion/hooks/pre_fusion_setup.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index 4dc11abce9..267ee71315 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -61,7 +61,7 @@ class FusionPrelaunch(PreLaunchHook): except ValueError: self.log.error('Copy prefs settings not found') finally: - return copy_status, copy_path, force_sync + return copy_status, Path(copy_path).expanduser(), force_sync def copy_existing_prefs(self, copy_from: Path, copy_to: Path, force_sync: bool) -> None: """On the first Fusion launch copy the Fusion profile to the working directory. @@ -124,12 +124,11 @@ class FusionPrelaunch(PreLaunchHook): copy_status, openpype_fusion_profile_dir, force_sync = self.get_copy_fusion_prefs_settings() if copy_status: prefs_source = self.get_profile_source() - openpype_fusion_profile_dir = Path(openpype_fusion_profile_dir).expanduser() self.copy_existing_prefs(prefs_source, openpype_fusion_profile_dir, force_sync) fusion_profile_dir_variable = f"FUSION{self.PROFILE_NUMBER}_PROFILE_DIR" - pref_var = f"FUSION{self.PROFILE_NUMBER}_MasterPrefs" + master_prefs_variable = f"FUSION{self.PROFILE_NUMBER}_MasterPrefs" openpype_master_prefs = Path(FUSION_HOST_DIR, "deploy", "fusion_shared.prefs") self.log.info(f"Setting {fusion_profile_dir_variable}: {openpype_fusion_profile_dir}") self.launch_context.env[fusion_profile_dir_variable] = str(openpype_fusion_profile_dir) - self.log.info(f"Setting {pref_var}: {openpype_master_prefs}") - self.launch_context.env[pref_var] = str(openpype_master_prefs) + self.log.info(f"Setting {master_prefs_variable}: {openpype_master_prefs}") + self.launch_context.env[master_prefs_variable] = str(openpype_master_prefs) From 632beeb1c7ae00146910a3cfa27a8ef855edbc84 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Mon, 13 Feb 2023 00:41:29 +0300 Subject: [PATCH 16/68] use english interface by default --- .../hosts/fusion/deploy/fusion_shared.prefs | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/openpype/hosts/fusion/deploy/fusion_shared.prefs b/openpype/hosts/fusion/deploy/fusion_shared.prefs index 8d0e45eae5..17ac3ad37a 100644 --- a/openpype/hosts/fusion/deploy/fusion_shared.prefs +++ b/openpype/hosts/fusion/deploy/fusion_shared.prefs @@ -1,16 +1,20 @@ { Locked = true, Global = { - Paths = { - Map = { - ["OpenPype:"] = "$(OPENPYPE_FUSION)/deploy", - ["Config:"] = "UserPaths:Config;OpenPype:Config", - ["Scripts:"] = "UserPaths:Scripts;Reactor:System/Scripts;OpenPype:Scripts", - }, - }, - Script = { - PythonVersion = 3, - Python3Forced = true - }, + Paths = { + Map = { + ["OpenPype:"] = "$(OPENPYPE_FUSION)/deploy", + ["Config:"] = "UserPaths:Config;OpenPype:Config", + ["Scripts:"] = "UserPaths:Scripts;Reactor:System/Scripts;OpenPype:Scripts", }, + }, + Script = { + PythonVersion = 3, + Python3Forced = true + }, + UserInterface = { + Skin = "Neutral", + Language = "en_US" + }, + }, } From 807fd736fc7ce26b6e2553cfa9c1c53d7e13360f Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Mon, 13 Feb 2023 01:50:05 +0300 Subject: [PATCH 17/68] fix typo --- openpype/hosts/fusion/hooks/pre_fusion_setup.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index 267ee71315..3bb345b72f 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -28,8 +28,7 @@ class FusionPrelaunch(PreLaunchHook): def get_profile_source(self) -> Path: """Get the Fusion preferences (profile) location. - Check https://www.steakunderwater.com/VFXPedia/96.0.243.189/indexad6a.html?title=Per-User_Preferences_and_Paths#Setting_the_profile_directory - for reference. + Check https://www.steakunderwater.com/VFXPedia/96.0.243.189/indexad6a.html?title=Per-User_Preferences_and_Paths for reference. """ fusion_profile = self.get_fusion_profile_name() fusion_var_prefs_dir = os.getenv(f"FUSION{self.PROFILE_NUMBER}_PROFILE_DIR") @@ -53,7 +52,7 @@ class FusionPrelaunch(PreLaunchHook): return prefs_source def get_copy_fusion_prefs_settings(self): - """Git copy prefserences options from the global application settings""" + """Get copy prefserences options from the global application settings""" copy_status = copy_path = None try: copy_status, copy_path, force_sync = get_system_settings()["applications"]["fusion"][ From 718f4e748d86177617e12915eae7c53fdc3a5eec Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov <11698866+movalex@users.noreply.github.com> Date: Fri, 17 Feb 2023 00:46:40 +0300 Subject: [PATCH 18/68] Update openpype/hosts/fusion/hooks/pre_fusion_setup.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- .../hosts/fusion/hooks/pre_fusion_setup.py | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index 3bb345b72f..9ae57d2a17 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -53,14 +53,21 @@ class FusionPrelaunch(PreLaunchHook): def get_copy_fusion_prefs_settings(self): """Get copy prefserences options from the global application settings""" - copy_status = copy_path = None - try: - copy_status, copy_path, force_sync = get_system_settings()["applications"]["fusion"][ - "copy_fusion_settings"].values() - except ValueError: - self.log.error('Copy prefs settings not found') - finally: - return copy_status, Path(copy_path).expanduser(), force_sync + copy_fusion_settings = ( + self.data + ["system_settings"] + ["applications"] + ["fusion"] + .get("copy_fusion_settings", {}) + ) + if not copy_fusion_settings: + self.log.error("Copy prefs settings not found") + copy_status = copy_fusion_settings.get("copy_status", False) + force_sync = copy_fusion_settings.get("force_sync", False) + copy_path = copy_fusion_settings.get("copy_path") or None + if copy_path: + copy_path = Path(copy_path).expanduser() + return copy_status, copy_path, force_sync def copy_existing_prefs(self, copy_from: Path, copy_to: Path, force_sync: bool) -> None: """On the first Fusion launch copy the Fusion profile to the working directory. From dacc90f9ad8ddab10ad60f814950db818e3327f3 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Fri, 17 Feb 2023 13:31:52 +0300 Subject: [PATCH 19/68] remove redundant get gomp name function --- openpype/hosts/fusion/api/lib.py | 7 ------- openpype/hosts/fusion/api/workio.py | 3 ++- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/openpype/hosts/fusion/api/lib.py b/openpype/hosts/fusion/api/lib.py index ec96d6cf18..f175d3a1d3 100644 --- a/openpype/hosts/fusion/api/lib.py +++ b/openpype/hosts/fusion/api/lib.py @@ -316,13 +316,6 @@ def get_current_comp(): return comp -def get_comp_filename(): - """Get comp's Filename""" - comp = get_current_comp() - if comp: - return comp.GetAttrs()["COMPS_FileName"] - - @contextlib.contextmanager def comp_lock_and_undo_chunk(comp, undo_queue_name="Script CMD"): """Lock comp and open an undo chunk during the context""" diff --git a/openpype/hosts/fusion/api/workio.py b/openpype/hosts/fusion/api/workio.py index 048e6e090a..8012d600da 100644 --- a/openpype/hosts/fusion/api/workio.py +++ b/openpype/hosts/fusion/api/workio.py @@ -25,7 +25,8 @@ def open_file(filepath): def current_file(): - current_filepath = get_comp_filename() + comp = get_current_comp() + current_filepath = comp.GetAttrs()["COMPS_FileName"] return current_filepath or None From d77c0e252be994a242d7004b675a8247abfc8326 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Fri, 17 Feb 2023 13:49:32 +0300 Subject: [PATCH 20/68] move fusion prefs settings to project_settings --- .../hosts/fusion/hooks/pre_fusion_setup.py | 23 +++++++------- .../defaults/project_settings/fusion.json | 5 ++++ .../system_settings/applications.json | 5 ---- .../schema_project_fusion.json | 24 +++++++++++++++ .../host_settings/schema_fusion.json | 30 ------------------- 5 files changed, 39 insertions(+), 48 deletions(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index 9ae57d2a17..ad2ec7eb2d 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -4,7 +4,6 @@ import platform from pathlib import Path from openpype.lib import PreLaunchHook, ApplicationLaunchFailed from openpype.hosts.fusion import FUSION_HOST_DIR -from openpype.settings import get_system_settings class FusionPrelaunch(PreLaunchHook): @@ -39,11 +38,10 @@ class FusionPrelaunch(PreLaunchHook): self.log.info(f"Local Fusion prefs environment is set to {fusion_prefs_dir}") fusion_prefs_filepath = fusion_prefs_dir / "Fusion.prefs" return fusion_prefs_filepath - # otherwise get the profile from default prefs location fusion_prefs_path = f"Blackmagic Design/Fusion/Profiles/{fusion_profile}/Fusion.prefs" if platform.system() == "Windows": - prefs_source = Path(os.getenv("AppData")) / fusion_prefs_path + prefs_source = Path(os.getenv("AppData"), fusion_prefs_path) elif platform.system() == "Darwin": prefs_source = Path("~/Library/Application Support/", fusion_prefs_path).expanduser() elif platform.system() == "Linux": @@ -55,8 +53,7 @@ class FusionPrelaunch(PreLaunchHook): """Get copy prefserences options from the global application settings""" copy_fusion_settings = ( self.data - ["system_settings"] - ["applications"] + ["project_settings"] ["fusion"] .get("copy_fusion_settings", {}) ) @@ -73,7 +70,7 @@ class FusionPrelaunch(PreLaunchHook): """On the first Fusion launch copy the Fusion profile to the working directory. If the Openpype profile folder exists, skip copying, unless Force sync is checked. If the prefs were not copied on the first launch, clean Fusion profile - will be created in openpype_fusion_profile_dir. + will be created in fusion_profile_dir. """ if copy_to.exists() and not force_sync: self.log.info("Local Fusion preferences folder exists, skipping profile copy") @@ -127,14 +124,14 @@ class FusionPrelaunch(PreLaunchHook): self.log.info(f"Setting OPENPYPE_FUSION: {FUSION_HOST_DIR}") self.launch_context.env["OPENPYPE_FUSION"] = FUSION_HOST_DIR - copy_status, openpype_fusion_profile_dir, force_sync = self.get_copy_fusion_prefs_settings() + copy_status, fusion_profile_dir, force_sync = self.get_copy_fusion_prefs_settings() if copy_status: prefs_source = self.get_profile_source() - self.copy_existing_prefs(prefs_source, openpype_fusion_profile_dir, force_sync) + self.copy_existing_prefs(prefs_source, fusion_profile_dir, force_sync) fusion_profile_dir_variable = f"FUSION{self.PROFILE_NUMBER}_PROFILE_DIR" master_prefs_variable = f"FUSION{self.PROFILE_NUMBER}_MasterPrefs" - openpype_master_prefs = Path(FUSION_HOST_DIR, "deploy", "fusion_shared.prefs") - self.log.info(f"Setting {fusion_profile_dir_variable}: {openpype_fusion_profile_dir}") - self.launch_context.env[fusion_profile_dir_variable] = str(openpype_fusion_profile_dir) - self.log.info(f"Setting {master_prefs_variable}: {openpype_master_prefs}") - self.launch_context.env[master_prefs_variable] = str(openpype_master_prefs) + master_prefs = Path(FUSION_HOST_DIR, "deploy", "fusion_shared.prefs") + self.log.info(f"Setting {fusion_profile_dir_variable}: {fusion_profile_dir}") + self.launch_context.env[fusion_profile_dir_variable] = str(fusion_profile_dir) + self.log.info(f"Setting {master_prefs_variable}: {master_prefs}") + self.launch_context.env[master_prefs_variable] = str(master_prefs) diff --git a/openpype/settings/defaults/project_settings/fusion.json b/openpype/settings/defaults/project_settings/fusion.json index 720178e17a..74863ece43 100644 --- a/openpype/settings/defaults/project_settings/fusion.json +++ b/openpype/settings/defaults/project_settings/fusion.json @@ -16,5 +16,10 @@ "linux": [] } } + }, + "copy_fusion_settings": { + "copy_status": false, + "copy_path": "~/.openpype/hosts/fusion/prefs", + "force_sync": false } } \ No newline at end of file diff --git a/openpype/settings/defaults/system_settings/applications.json b/openpype/settings/defaults/system_settings/applications.json index 9fb730568e..d498bccda9 100644 --- a/openpype/settings/defaults/system_settings/applications.json +++ b/openpype/settings/defaults/system_settings/applications.json @@ -835,11 +835,6 @@ "linux": "/opt/Python/3.6/bin" } }, - "copy_fusion_settings": { - "copy_prefs": false, - "prefs_path": "~/.openpype/hosts/fusion/prefs", - "force_sync": false - }, "variants": { "18": { "executables": { diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_fusion.json b/openpype/settings/entities/schemas/projects_schema/schema_project_fusion.json index 8c62d75815..540f840aad 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_fusion.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_fusion.json @@ -45,6 +45,30 @@ ] } ] + }, + { + "type": "dict", + "key": "copy_fusion_settings", + "collapsible": true, + "checkbox_key": "copy_status", + "label": "Copy Fusion settings on launch", + "children": [ + { + "type": "boolean", + "key": "copy_status", + "label": "Enabled" + }, + { + "key": "copy_path", + "type": "path", + "label": "Local prefs directory" + }, + { + "key":"force_sync", + "type": "boolean", + "label": "Force sync preferences" + } + ] } ] } diff --git a/openpype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json b/openpype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json index 48355932ae..5960da7774 100644 --- a/openpype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json +++ b/openpype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json @@ -19,36 +19,6 @@ "label": "Environment", "type": "raw-json" }, - { - "type": "splitter" - }, - { - "type": "dict", - "key": "copy_fusion_settings", - "collapsible": true, - "checkbox_key": "copy_prefs", - "label": "Copy Fusion settings when launched from OpenPype", - "children": [ - { - "type": "boolean", - "key": "copy_prefs", - "label": "Enabled" - }, - { - "key": "prefs_path", - "type": "path", - "label": "Local prefs directory" - }, - { - "key":"force_sync", - "type": "boolean", - "label": "Always sync preferences on launch" - } - ] - }, - { - "type": "splitter" - }, { "type": "dict-modifiable", "key": "variants", From 87ab9e35983241b255347d7f98daafadac09def6 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Fri, 17 Feb 2023 13:50:08 +0300 Subject: [PATCH 21/68] rename get_fusion module --- openpype/hosts/fusion/api/lib.py | 4 ++-- openpype/hosts/fusion/api/workio.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/fusion/api/lib.py b/openpype/hosts/fusion/api/lib.py index f175d3a1d3..709d3cbdc6 100644 --- a/openpype/hosts/fusion/api/lib.py +++ b/openpype/hosts/fusion/api/lib.py @@ -302,7 +302,7 @@ def get_frame_path(path): return filename, padding, ext -def get_fusion(): +def get_fusion_module(): """Get current Fusion instance""" fusion = getattr(sys.modules["__main__"], "fusion", None) return fusion @@ -310,7 +310,7 @@ def get_fusion(): def get_current_comp(): """Get current comp in this session""" - fusion = get_fusion() + fusion = get_fusion_module() if fusion: comp = fusion.CurrentComp return comp diff --git a/openpype/hosts/fusion/api/workio.py b/openpype/hosts/fusion/api/workio.py index 8012d600da..f51c4fa9c1 100644 --- a/openpype/hosts/fusion/api/workio.py +++ b/openpype/hosts/fusion/api/workio.py @@ -2,7 +2,7 @@ import sys import os -from .lib import get_fusion, get_current_comp, get_comp_filename +from .lib import get_fusion_module, get_current_comp, get_comp_filename def file_extensions(): @@ -20,7 +20,7 @@ def save_file(filepath): def open_file(filepath): - fusion = get_fusion() + fusion = get_fusion_module() return fusion.LoadComp(filepath) From 39ee896d7ebb4ab22d7d747bd2693e79bb7d9512 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov <11698866+movalex@users.noreply.github.com> Date: Sat, 18 Feb 2023 07:47:42 +0300 Subject: [PATCH 22/68] Update openpype/hosts/fusion/api/lib.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- openpype/hosts/fusion/api/lib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/api/lib.py b/openpype/hosts/fusion/api/lib.py index 709d3cbdc6..4830c3b3df 100644 --- a/openpype/hosts/fusion/api/lib.py +++ b/openpype/hosts/fusion/api/lib.py @@ -311,7 +311,7 @@ def get_fusion_module(): def get_current_comp(): """Get current comp in this session""" fusion = get_fusion_module() - if fusion: + if fusion is not None: comp = fusion.CurrentComp return comp From 7fe1473dde672e83dc62236d697cc70bd0feebc9 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Tue, 21 Feb 2023 00:13:53 +0300 Subject: [PATCH 23/68] disable root toggle, rename settings --- .../defaults/project_settings/fusion.json | 2 +- .../projects_schema/schema_project_fusion.json | 17 ++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/openpype/settings/defaults/project_settings/fusion.json b/openpype/settings/defaults/project_settings/fusion.json index 74863ece43..97c1c52579 100644 --- a/openpype/settings/defaults/project_settings/fusion.json +++ b/openpype/settings/defaults/project_settings/fusion.json @@ -18,8 +18,8 @@ } }, "copy_fusion_settings": { + "copy_path": "~/.openpype/hosts/fusion/profiles", "copy_status": false, - "copy_path": "~/.openpype/hosts/fusion/prefs", "force_sync": false } } \ No newline at end of file diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_fusion.json b/openpype/settings/entities/schemas/projects_schema/schema_project_fusion.json index 540f840aad..464cf2c06d 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_fusion.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_fusion.json @@ -50,23 +50,22 @@ "type": "dict", "key": "copy_fusion_settings", "collapsible": true, - "checkbox_key": "copy_status", - "label": "Copy Fusion settings on launch", + "label": "Local Fusion profile settings", "children": [ - { - "type": "boolean", - "key": "copy_status", - "label": "Enabled" - }, { "key": "copy_path", "type": "path", - "label": "Local prefs directory" + "label": "Local Fusion profile directory" + }, + { + "type": "boolean", + "key": "copy_status", + "label": "Copy profile on first launch" }, { "key":"force_sync", "type": "boolean", - "label": "Force sync preferences" + "label": "Resync profile on each launch" } ] } From 7466f576ba9d8c1ca37b272320ae47c251018ca5 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Tue, 21 Feb 2023 00:14:17 +0300 Subject: [PATCH 24/68] remove redundant import --- openpype/hosts/fusion/api/workio.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/api/workio.py b/openpype/hosts/fusion/api/workio.py index f51c4fa9c1..fbb5a588f4 100644 --- a/openpype/hosts/fusion/api/workio.py +++ b/openpype/hosts/fusion/api/workio.py @@ -2,7 +2,7 @@ import sys import os -from .lib import get_fusion_module, get_current_comp, get_comp_filename +from .lib import get_fusion_module, get_current_comp def file_extensions(): From 1235894970870e0317a3c275c4acbea52504c762 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Tue, 21 Feb 2023 02:41:32 +0300 Subject: [PATCH 25/68] copy all fusion pref files, update docs --- .../hosts/fusion/hooks/pre_fusion_setup.py | 47 ++++++++++++------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index ad2ec7eb2d..949f86d981 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -17,35 +17,40 @@ class FusionPrelaunch(PreLaunchHook): as set in openpype/hosts/fusion/deploy/fusion_shared.prefs to enable the OpenPype menu and force Python 3 over Python 2. + PROFILE_NUMBER is used because from the Fusion v16 the profile folder + is project-specific, but then it was abandoned by devs, + and despite it is already Fusion version 18, still FUSION16_PROFILE_DIR is used. + The variable is added in case the version number will be updated or deleted + so we could easily change the version or disable it. """ app_groups = ["fusion"] PROFILE_NUMBER = 16 + def get_fusion_profile_name(self) -> str: """usually set to 'Default', unless FUSION16_PROFILE is set""" return os.getenv(f"FUSION{self.PROFILE_NUMBER}_PROFILE", "Default") def get_profile_source(self) -> Path: """Get the Fusion preferences (profile) location. - Check https://www.steakunderwater.com/VFXPedia/96.0.243.189/indexad6a.html?title=Per-User_Preferences_and_Paths for reference. + Check Per-User_Preferences_and_Paths on VFXpedia for reference. """ fusion_profile = self.get_fusion_profile_name() fusion_var_prefs_dir = os.getenv(f"FUSION{self.PROFILE_NUMBER}_PROFILE_DIR") - # if FUSION16_PROFILE_DIR variable exists, return the profile filepath + # if FUSION16_PROFILE_DIR variable exists if fusion_var_prefs_dir and Path(fusion_var_prefs_dir).is_dir(): fusion_prefs_dir = Path(fusion_var_prefs_dir, fusion_profile) self.log.info(f"Local Fusion prefs environment is set to {fusion_prefs_dir}") - fusion_prefs_filepath = fusion_prefs_dir / "Fusion.prefs" - return fusion_prefs_filepath - # otherwise get the profile from default prefs location - fusion_prefs_path = f"Blackmagic Design/Fusion/Profiles/{fusion_profile}/Fusion.prefs" + return fusion_prefs_dir + # otherwise get the profile folder from default location + fusion_prefs_dir = f"Blackmagic Design/Fusion/Profiles/{fusion_profile}" if platform.system() == "Windows": - prefs_source = Path(os.getenv("AppData"), fusion_prefs_path) + prefs_source = Path(os.getenv("AppData"), fusion_prefs_dir) elif platform.system() == "Darwin": - prefs_source = Path("~/Library/Application Support/", fusion_prefs_path).expanduser() + prefs_source = Path("~/Library/Application Support/", fusion_prefs_dir).expanduser() elif platform.system() == "Linux": - prefs_source = Path("~/.fusion", fusion_prefs_path).expanduser() + prefs_source = Path("~/.fusion", fusion_prefs_dir).expanduser() self.log.info(f"Got Fusion prefs file: {prefs_source}") return prefs_source @@ -67,10 +72,11 @@ class FusionPrelaunch(PreLaunchHook): return copy_status, copy_path, force_sync def copy_existing_prefs(self, copy_from: Path, copy_to: Path, force_sync: bool) -> None: - """On the first Fusion launch copy the Fusion profile to the working directory. - If the Openpype profile folder exists, skip copying, unless Force sync is checked. - If the prefs were not copied on the first launch, clean Fusion profile - will be created in fusion_profile_dir. + """On the first Fusion launch copy the contents of Fusion profile directory + to the working predefined location. If the Openpype profile folder exists, + skip copying, unless re-sync is checked. + If the prefs were not copied on the first launch, + clean Fusion profile will be created in fusion_profile_dir. """ if copy_to.exists() and not force_sync: self.log.info("Local Fusion preferences folder exists, skipping profile copy") @@ -82,7 +88,10 @@ class FusionPrelaunch(PreLaunchHook): if not copy_from.exists(): self.log.warning(f"Fusion preferences file not found in {copy_from}") return - shutil.copy(str(copy_from), str(dest_folder)) # compatible with Python >= 3.6 + for file in copy_from.iterdir(): + if file.suffix in (".prefs", ".def", ".blocklist", "fu"): + # convert Path to str to be compatible with Python 3.6 and above + shutil.copy(str(file), str(dest_folder)) self.log.info(f"successfully copied preferences:\n {copy_from} to {dest_folder}") def execute(self): @@ -93,8 +102,9 @@ class FusionPrelaunch(PreLaunchHook): fusion_python3_home = self.launch_context.env.get(py3_var, "") for path in fusion_python3_home.split(os.pathsep): - # Allow defining multiple paths, separated by os.pathsep, to allow "fallback" to other - # path. But make to set only a single path as final variable. + # Allow defining multiple paths, separated by os.pathsep, + # to allow "fallback" to other path. + # But make to set only a single path as final variable. py3_dir = os.path.normpath(path) if os.path.isdir(py3_dir): self.log.info(f"Looking for Python 3 in: {py3_dir}") @@ -119,8 +129,9 @@ class FusionPrelaunch(PreLaunchHook): # TODO: Detect Fusion version to only set for specific Fusion build self.launch_context.env[f"FUSION{self.PROFILE_NUMBER}_PYTHON36_HOME"] = py3_dir - # Add custom Fusion Master Prefs and the temporary profile directory variables - # to customize Fusion to define where it can read custom scripts and tools from + # Add custom Fusion Master Prefs and the temporary + # profile directory variables to customize Fusion + # to define where it can read custom scripts and tools from self.log.info(f"Setting OPENPYPE_FUSION: {FUSION_HOST_DIR}") self.launch_context.env["OPENPYPE_FUSION"] = FUSION_HOST_DIR From 2d6cc7788199c26e338ab6e960aef1fc25caca9b Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Tue, 21 Feb 2023 02:42:36 +0300 Subject: [PATCH 26/68] fle formatting --- .../hosts/fusion/hooks/pre_fusion_setup.py | 45 ++++++++++++------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index 949f86d981..3f521bb60d 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -17,16 +17,16 @@ class FusionPrelaunch(PreLaunchHook): as set in openpype/hosts/fusion/deploy/fusion_shared.prefs to enable the OpenPype menu and force Python 3 over Python 2. - PROFILE_NUMBER is used because from the Fusion v16 the profile folder + PROFILE_NUMBER is used because from the Fusion v16 the profile folder is project-specific, but then it was abandoned by devs, and despite it is already Fusion version 18, still FUSION16_PROFILE_DIR is used. The variable is added in case the version number will be updated or deleted so we could easily change the version or disable it. """ + app_groups = ["fusion"] PROFILE_NUMBER = 16 - def get_fusion_profile_name(self) -> str: """usually set to 'Default', unless FUSION16_PROFILE is set""" return os.getenv(f"FUSION{self.PROFILE_NUMBER}_PROFILE", "Default") @@ -41,14 +41,18 @@ class FusionPrelaunch(PreLaunchHook): # if FUSION16_PROFILE_DIR variable exists if fusion_var_prefs_dir and Path(fusion_var_prefs_dir).is_dir(): fusion_prefs_dir = Path(fusion_var_prefs_dir, fusion_profile) - self.log.info(f"Local Fusion prefs environment is set to {fusion_prefs_dir}") + self.log.info( + f"Local Fusion prefs environment is set to {fusion_prefs_dir}" + ) return fusion_prefs_dir # otherwise get the profile folder from default location fusion_prefs_dir = f"Blackmagic Design/Fusion/Profiles/{fusion_profile}" if platform.system() == "Windows": prefs_source = Path(os.getenv("AppData"), fusion_prefs_dir) elif platform.system() == "Darwin": - prefs_source = Path("~/Library/Application Support/", fusion_prefs_dir).expanduser() + prefs_source = Path( + "~/Library/Application Support/", fusion_prefs_dir + ).expanduser() elif platform.system() == "Linux": prefs_source = Path("~/.fusion", fusion_prefs_dir).expanduser() self.log.info(f"Got Fusion prefs file: {prefs_source}") @@ -56,11 +60,8 @@ class FusionPrelaunch(PreLaunchHook): def get_copy_fusion_prefs_settings(self): """Get copy prefserences options from the global application settings""" - copy_fusion_settings = ( - self.data - ["project_settings"] - ["fusion"] - .get("copy_fusion_settings", {}) + copy_fusion_settings = self.data["project_settings"]["fusion"].get( + "copy_fusion_settings", {} ) if not copy_fusion_settings: self.log.error("Copy prefs settings not found") @@ -71,7 +72,9 @@ class FusionPrelaunch(PreLaunchHook): copy_path = Path(copy_path).expanduser() return copy_status, copy_path, force_sync - def copy_existing_prefs(self, copy_from: Path, copy_to: Path, force_sync: bool) -> None: + def copy_existing_prefs( + self, copy_from: Path, copy_to: Path, force_sync: bool + ) -> None: """On the first Fusion launch copy the contents of Fusion profile directory to the working predefined location. If the Openpype profile folder exists, skip copying, unless re-sync is checked. @@ -79,21 +82,25 @@ class FusionPrelaunch(PreLaunchHook): clean Fusion profile will be created in fusion_profile_dir. """ if copy_to.exists() and not force_sync: - self.log.info("Local Fusion preferences folder exists, skipping profile copy") + self.log.info( + "Local Fusion preferences folder exists, skipping profile copy" + ) return self.log.info(f"Starting copying Fusion preferences") self.log.info(f"force_sync option is set to {force_sync}") dest_folder = copy_to / self.get_fusion_profile_name() - dest_folder.mkdir(exist_ok=True, parents=True) + dest_folder.mkdir(exist_ok=True, parents=True) if not copy_from.exists(): self.log.warning(f"Fusion preferences file not found in {copy_from}") return for file in copy_from.iterdir(): if file.suffix in (".prefs", ".def", ".blocklist", "fu"): # convert Path to str to be compatible with Python 3.6 and above - shutil.copy(str(file), str(dest_folder)) - self.log.info(f"successfully copied preferences:\n {copy_from} to {dest_folder}") - + shutil.copy(str(file), str(dest_folder)) + self.log.info( + f"successfully copied preferences:\n {copy_from} to {dest_folder}" + ) + def execute(self): # making sure python 3 is installed at provided path # Py 3.3-3.10 for Fusion 18+ or Py 3.6 for Fu 16-17 @@ -102,7 +109,7 @@ class FusionPrelaunch(PreLaunchHook): fusion_python3_home = self.launch_context.env.get(py3_var, "") for path in fusion_python3_home.split(os.pathsep): - # Allow defining multiple paths, separated by os.pathsep, + # Allow defining multiple paths, separated by os.pathsep, # to allow "fallback" to other path. # But make to set only a single path as final variable. py3_dir = os.path.normpath(path) @@ -135,7 +142,11 @@ class FusionPrelaunch(PreLaunchHook): self.log.info(f"Setting OPENPYPE_FUSION: {FUSION_HOST_DIR}") self.launch_context.env["OPENPYPE_FUSION"] = FUSION_HOST_DIR - copy_status, fusion_profile_dir, force_sync = self.get_copy_fusion_prefs_settings() + ( + copy_status, + fusion_profile_dir, + force_sync, + ) = self.get_copy_fusion_prefs_settings() if copy_status: prefs_source = self.get_profile_source() self.copy_existing_prefs(prefs_source, fusion_profile_dir, force_sync) From 04c40b6c727fa7320360eb97dfddf5bf065095f0 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Thu, 2 Mar 2023 19:10:18 +0300 Subject: [PATCH 27/68] check if local profile folder exists, cleanup a bit --- .../hosts/fusion/hooks/pre_fusion_setup.py | 52 ++++++++++--------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index f7b5e684cb..19d59d3806 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -17,26 +17,26 @@ class FusionPrelaunch(PreLaunchHook): as set in openpype/hosts/fusion/deploy/fusion_shared.prefs to enable the OpenPype menu and force Python 3 over Python 2. - PROFILE_NUMBER is used because from the Fusion v16 the profile folder + VERSION variable is used because from the Fusion v16 the profile folder is project-specific, but then it was abandoned by devs, - and despite it is already Fusion version 18, still FUSION16_PROFILE_DIR is used. - The variable is added in case the version number will be updated or deleted - so we could easily change the version or disable it. + and despite it is already Fusion version 18, still FUSION16_PROFILE_DIR + is used. The variable is added in case the version number will be + updated or deleted so we could easily change the version or disable it. """ app_groups = ["fusion"] - PROFILE_NUMBER = 16 + VERSION = 16 def get_fusion_profile_name(self) -> str: """usually set to 'Default', unless FUSION16_PROFILE is set""" - return os.getenv(f"FUSION{self.PROFILE_NUMBER}_PROFILE", "Default") + return os.getenv(f"FUSION{self.VERSION}_PROFILE", "Default") def get_profile_source(self) -> Path: """Get the Fusion preferences (profile) location. Check Per-User_Preferences_and_Paths on VFXpedia for reference. """ fusion_profile = self.get_fusion_profile_name() - fusion_var_prefs_dir = os.getenv(f"FUSION{self.PROFILE_NUMBER}_PROFILE_DIR") + fusion_var_prefs_dir = os.getenv(f"FUSION{self.VERSION}_PROFILE_DIR") # if FUSION16_PROFILE_DIR variable exists if fusion_var_prefs_dir and Path(fusion_var_prefs_dir).is_dir(): @@ -46,7 +46,7 @@ class FusionPrelaunch(PreLaunchHook): ) return fusion_prefs_dir # otherwise get the profile folder from default location - fusion_prefs_dir = f"Blackmagic Design/Fusion/Profiles/{fusion_profile}" + fusion_prefs_dir = f"Blackmagic Design/Fusion/Profiles/{fusion_profile}" #noqa if platform.system() == "Windows": prefs_source = Path(os.getenv("AppData"), fusion_prefs_dir) elif platform.system() == "Darwin": @@ -59,7 +59,7 @@ class FusionPrelaunch(PreLaunchHook): return prefs_source def get_copy_fusion_prefs_settings(self): - """Get copy prefserences options from the global application settings""" + """Get copy preferences options from the global application settings""" copy_fusion_settings = self.data["project_settings"]["fusion"].get( "copy_fusion_settings", {} ) @@ -75,9 +75,9 @@ class FusionPrelaunch(PreLaunchHook): def copy_existing_prefs( self, copy_from: Path, copy_to: Path, force_sync: bool ) -> None: - """On the first Fusion launch copy the contents of Fusion profile directory - to the working predefined location. If the Openpype profile folder exists, - skip copying, unless re-sync is checked. + """On the first Fusion launch copy the contents of Fusion profile + directory to the working predefined location. If the Openpype profile + folder exists, skip copying, unless re-sync is checked. If the prefs were not copied on the first launch, clean Fusion profile will be created in fusion_profile_dir. """ @@ -89,13 +89,17 @@ class FusionPrelaunch(PreLaunchHook): self.log.info(f"Starting copying Fusion preferences") self.log.info(f"force_sync option is set to {force_sync}") dest_folder = copy_to / self.get_fusion_profile_name() - dest_folder.mkdir(exist_ok=True, parents=True) + try: + dest_folder.mkdir(exist_ok=True, parents=True) + except Exception: + self.log.warn(f"Could not create folder at {dest_folder}") + return if not copy_from.exists(): - self.log.warning(f"Fusion preferences file not found in {copy_from}") + self.log.warning(f"Fusion preferences not found in {copy_from}") return for file in copy_from.iterdir(): - if file.suffix in (".prefs", ".def", ".blocklist", "fu"): - # convert Path to str to be compatible with Python 3.6 and above + if file.suffix in (".prefs", ".def", ".blocklist", ".fu"): + # convert Path to str to be compatible with Python 3.6+ shutil.copy(str(file), str(dest_folder)) self.log.info( f"successfully copied preferences:\n {copy_from} to {dest_folder}" @@ -134,26 +138,26 @@ class FusionPrelaunch(PreLaunchHook): # Fusion 16 and 17 use FUSION16_PYTHON36_HOME instead of # FUSION_PYTHON3_HOME and will only work with a Python 3.6 version # TODO: Detect Fusion version to only set for specific Fusion build - self.launch_context.env[f"FUSION{self.PROFILE_NUMBER}_PYTHON36_HOME"] = py3_dir + self.launch_context.env[f"FUSION{self.VERSION}_PYTHON36_HOME"] = py3_dir #noqa # Add custom Fusion Master Prefs and the temporary # profile directory variables to customize Fusion # to define where it can read custom scripts and tools from self.log.info(f"Setting OPENPYPE_FUSION: {FUSION_HOST_DIR}") self.launch_context.env["OPENPYPE_FUSION"] = FUSION_HOST_DIR - ( copy_status, fusion_profile_dir, force_sync, ) = self.get_copy_fusion_prefs_settings() - if copy_status: + if copy_status and fusion_profile_dir is not None: prefs_source = self.get_profile_source() - self.copy_existing_prefs(prefs_source, fusion_profile_dir, force_sync) - fusion_profile_dir_variable = f"FUSION{self.PROFILE_NUMBER}_PROFILE_DIR" - master_prefs_variable = f"FUSION{self.PROFILE_NUMBER}_MasterPrefs" + self.copy_existing_prefs(prefs_source, fusion_profile_dir, force_sync) #noqa + else: + fusion_profile_dir_variable = f"FUSION{self.VERSION}_PROFILE_DIR" + self.log.info(f"Setting {fusion_profile_dir_variable}: {fusion_profile_dir}") #noqa + self.launch_context.env[fusion_profile_dir_variable] = str(fusion_profile_dir) #noqa + master_prefs_variable = f"FUSION{self.VERSION}_MasterPrefs" master_prefs = Path(FUSION_HOST_DIR, "deploy", "fusion_shared.prefs") - self.log.info(f"Setting {fusion_profile_dir_variable}: {fusion_profile_dir}") - self.launch_context.env[fusion_profile_dir_variable] = str(fusion_profile_dir) self.log.info(f"Setting {master_prefs_variable}: {master_prefs}") self.launch_context.env[master_prefs_variable] = str(master_prefs) From 997351bfe2ded1e44d76f5d7bf6fecf5771c7105 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Thu, 2 Mar 2023 19:16:44 +0300 Subject: [PATCH 28/68] tame the hound --- openpype/hosts/fusion/hooks/pre_fusion_setup.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index 19d59d3806..129aadf1a5 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -46,7 +46,7 @@ class FusionPrelaunch(PreLaunchHook): ) return fusion_prefs_dir # otherwise get the profile folder from default location - fusion_prefs_dir = f"Blackmagic Design/Fusion/Profiles/{fusion_profile}" #noqa + fusion_prefs_dir = f"Blackmagic Design/Fusion/Profiles/{fusion_profile}" # noqa if platform.system() == "Windows": prefs_source = Path(os.getenv("AppData"), fusion_prefs_dir) elif platform.system() == "Darwin": @@ -138,7 +138,7 @@ class FusionPrelaunch(PreLaunchHook): # Fusion 16 and 17 use FUSION16_PYTHON36_HOME instead of # FUSION_PYTHON3_HOME and will only work with a Python 3.6 version # TODO: Detect Fusion version to only set for specific Fusion build - self.launch_context.env[f"FUSION{self.VERSION}_PYTHON36_HOME"] = py3_dir #noqa + self.launch_context.env[f"FUSION{self.VERSION}_PYTHON36_HOME"] = py3_dir # noqa # Add custom Fusion Master Prefs and the temporary # profile directory variables to customize Fusion @@ -152,11 +152,11 @@ class FusionPrelaunch(PreLaunchHook): ) = self.get_copy_fusion_prefs_settings() if copy_status and fusion_profile_dir is not None: prefs_source = self.get_profile_source() - self.copy_existing_prefs(prefs_source, fusion_profile_dir, force_sync) #noqa + self.copy_existing_prefs(prefs_source, fusion_profile_dir, force_sync) # noqa else: fusion_profile_dir_variable = f"FUSION{self.VERSION}_PROFILE_DIR" - self.log.info(f"Setting {fusion_profile_dir_variable}: {fusion_profile_dir}") #noqa - self.launch_context.env[fusion_profile_dir_variable] = str(fusion_profile_dir) #noqa + self.log.info(f"Setting {fusion_profile_dir_variable}: {fusion_profile_dir}") # noqa + self.launch_context.env[fusion_profile_dir_variable] = str(fusion_profile_dir) # noqa master_prefs_variable = f"FUSION{self.VERSION}_MasterPrefs" master_prefs = Path(FUSION_HOST_DIR, "deploy", "fusion_shared.prefs") self.log.info(f"Setting {master_prefs_variable}: {master_prefs}") From 7c9c2864c51a58d7dcb4768d5483fcf35615c3e9 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Sat, 4 Mar 2023 15:41:49 +0300 Subject: [PATCH 29/68] add up to 3 decimals to fps allows input 23.976 to the FPS settings both in Project Manager and the Project Anatomy. --- .../schemas/schema_anatomy_attributes.json | 2 +- .../project_manager/project_manager/delegates.py | 5 ++++- .../tools/project_manager/project_manager/view.py | 14 ++++++++++---- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_attributes.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_attributes.json index 3667c9d5d8..a728024376 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_attributes.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_attributes.json @@ -10,7 +10,7 @@ "type": "number", "key": "fps", "label": "Frame Rate", - "decimal": 2, + "decimal": 3, "minimum": 0 }, { diff --git a/openpype/tools/project_manager/project_manager/delegates.py b/openpype/tools/project_manager/project_manager/delegates.py index 79e9554b0f..023dd668ec 100644 --- a/openpype/tools/project_manager/project_manager/delegates.py +++ b/openpype/tools/project_manager/project_manager/delegates.py @@ -83,15 +83,18 @@ class NumberDelegate(QtWidgets.QStyledItemDelegate): decimals(int): How many decimal points can be used. Float will be used as value if is higher than 0. """ - def __init__(self, minimum, maximum, decimals, *args, **kwargs): + def __init__(self, minimum, maximum, decimals, step, *args, **kwargs): super(NumberDelegate, self).__init__(*args, **kwargs) self.minimum = minimum self.maximum = maximum self.decimals = decimals + self.step = step def createEditor(self, parent, option, index): if self.decimals > 0: editor = DoubleSpinBoxScrollFixed(parent) + editor.setSingleStep(self.step) + editor.setDecimals(self.decimals) else: editor = SpinBoxScrollFixed(parent) diff --git a/openpype/tools/project_manager/project_manager/view.py b/openpype/tools/project_manager/project_manager/view.py index fa08943ea5..0dd04aa7b9 100644 --- a/openpype/tools/project_manager/project_manager/view.py +++ b/openpype/tools/project_manager/project_manager/view.py @@ -26,10 +26,11 @@ class NameDef: class NumberDef: - def __init__(self, minimum=None, maximum=None, decimals=None): + def __init__(self, minimum=None, maximum=None, decimals=None, step=None): self.minimum = 0 if minimum is None else minimum self.maximum = 999999999 if maximum is None else maximum self.decimals = 0 if decimals is None else decimals + self.step = 1 if decimals is None else step class TypeDef: @@ -73,14 +74,14 @@ class HierarchyView(QtWidgets.QTreeView): "type": TypeDef(), "frameStart": NumberDef(1), "frameEnd": NumberDef(1), - "fps": NumberDef(1, decimals=2), + "fps": NumberDef(1, decimals=3, step=0.01), "resolutionWidth": NumberDef(0), "resolutionHeight": NumberDef(0), "handleStart": NumberDef(0), "handleEnd": NumberDef(0), "clipIn": NumberDef(1), "clipOut": NumberDef(1), - "pixelAspect": NumberDef(0, decimals=2), + "pixelAspect": NumberDef(0, decimals=2, step=0.1), "tools_env": ToolsDef() } @@ -96,6 +97,10 @@ class HierarchyView(QtWidgets.QTreeView): "stretch": QtWidgets.QHeaderView.Interactive, "width": 140 }, + "fps": { + "stretch": QtWidgets.QHeaderView.Interactive, + "width": 65 + }, "tools_env": { "stretch": QtWidgets.QHeaderView.Interactive, "width": 200 @@ -148,7 +153,8 @@ class HierarchyView(QtWidgets.QTreeView): delegate = NumberDelegate( item_type.minimum, item_type.maximum, - item_type.decimals + item_type.decimals, + item_type.step ) elif isinstance(item_type, TypeDef): From 384d928d854d086fea75a4ae418e1d81357879d1 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Sat, 4 Mar 2023 22:19:58 +0300 Subject: [PATCH 30/68] set fps and pixel aspect precision steps default values --- openpype/tools/project_manager/project_manager/view.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/tools/project_manager/project_manager/view.py b/openpype/tools/project_manager/project_manager/view.py index 0dd04aa7b9..b35491c5b2 100644 --- a/openpype/tools/project_manager/project_manager/view.py +++ b/openpype/tools/project_manager/project_manager/view.py @@ -74,14 +74,14 @@ class HierarchyView(QtWidgets.QTreeView): "type": TypeDef(), "frameStart": NumberDef(1), "frameEnd": NumberDef(1), - "fps": NumberDef(1, decimals=3, step=0.01), + "fps": NumberDef(1, decimals=3, step=1), "resolutionWidth": NumberDef(0), "resolutionHeight": NumberDef(0), "handleStart": NumberDef(0), "handleEnd": NumberDef(0), "clipIn": NumberDef(1), "clipOut": NumberDef(1), - "pixelAspect": NumberDef(0, decimals=2, step=0.1), + "pixelAspect": NumberDef(0, decimals=2, step=0.01), "tools_env": ToolsDef() } From 962984d29614a7ba7d86f391ba61013a871947f9 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Wed, 8 Mar 2023 02:04:54 +0300 Subject: [PATCH 31/68] add separate fusion profile hook --- openpype/hosts/fusion/__init__.py | 2 + openpype/hosts/fusion/addon.py | 9 ++ .../fusion/hooks/pre_fusion_profile_hook.py | 109 ++++++++++++++++++ .../hosts/fusion/hooks/pre_fusion_setup.py | 105 +---------------- 4 files changed, 125 insertions(+), 100 deletions(-) create mode 100644 openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py diff --git a/openpype/hosts/fusion/__init__.py b/openpype/hosts/fusion/__init__.py index ddae01890b..baaaa9d6fc 100644 --- a/openpype/hosts/fusion/__init__.py +++ b/openpype/hosts/fusion/__init__.py @@ -1,10 +1,12 @@ from .addon import ( FusionAddon, FUSION_HOST_DIR, + FUSION_PROFILE_VERSION ) __all__ = ( "FusionAddon", "FUSION_HOST_DIR", + "FUSION_PROFILE_VERSION" ) diff --git a/openpype/hosts/fusion/addon.py b/openpype/hosts/fusion/addon.py index d1bd1566b7..777c38629a 100644 --- a/openpype/hosts/fusion/addon.py +++ b/openpype/hosts/fusion/addon.py @@ -3,6 +3,15 @@ from openpype.modules import OpenPypeModule, IHostAddon FUSION_HOST_DIR = os.path.dirname(os.path.abspath(__file__)) +FUSION_PROFILE_VERSION = 16 + +# FUSION_PROFILE_VERSION variable is used by the pre-launch hooks. +# Since Fusion v16, the profile folder became project-specific, +# but then it was abandoned by BlackmagicDesign devs, and now, despite it is +# already Fusion version 18, still FUSION16_PROFILE_DIR is used. +# The variable is added in case the version number will be +# updated or deleted so we could easily change the version or disable it. + class FusionAddon(OpenPypeModule, IHostAddon): name = "fusion" diff --git a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py new file mode 100644 index 0000000000..4af67c1c0d --- /dev/null +++ b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py @@ -0,0 +1,109 @@ +import os +import shutil +import platform +from pathlib import Path +from openpype.lib import PreLaunchHook, ApplicationLaunchFailed +from openpype.hosts.fusion import FUSION_PROFILE_VERSION as VERSION + + +class FusionCopyPrefsPrelaunch(PreLaunchHook): + """Prepares local Fusion profile directory, copies existing Fusion profile + """ + + app_groups = ["fusion"] + + def get_fusion_profile_name(self) -> str: + """usually set to 'Default', unless FUSION16_PROFILE is set""" + return os.getenv(f"FUSION{VERSION}_PROFILE", "Default") + + def get_profile_source(self) -> Path: + """Get the Fusion preferences (profile) location. + Check Per-User_Preferences_and_Paths on VFXpedia for reference. + """ + fusion_profile = self.get_fusion_profile_name() + fusion_var_prefs_dir = os.getenv(f"FUSION{VERSION}_PROFILE_DIR") + + # if FUSION16_PROFILE_DIR variable exists + if fusion_var_prefs_dir and Path(fusion_var_prefs_dir).is_dir(): + fusion_prefs_dir = Path(fusion_var_prefs_dir, fusion_profile) + self.log.info( + f"Local Fusion prefs environment is set to {fusion_prefs_dir}" + ) + return fusion_prefs_dir + # otherwise get the profile folder from default location + fusion_prefs_dir = f"Blackmagic Design/Fusion/Profiles/{fusion_profile}" # noqa + if platform.system() == "Windows": + prefs_source = Path(os.getenv("AppData"), fusion_prefs_dir) + elif platform.system() == "Darwin": + prefs_source = Path( + "~/Library/Application Support/", fusion_prefs_dir + ).expanduser() + elif platform.system() == "Linux": + prefs_source = Path("~/.fusion", fusion_prefs_dir).expanduser() + self.log.info(f"Got Fusion prefs file: {prefs_source}") + return prefs_source + + def get_copy_fusion_prefs_settings(self): + """Get copy preferences options from the global application settings""" + copy_fusion_settings = self.data["project_settings"]["fusion"].get( + "copy_fusion_settings", {} + ) + if not copy_fusion_settings: + self.log.error("Copy prefs settings not found") + copy_status = copy_fusion_settings.get("copy_status", False) + force_sync = copy_fusion_settings.get("force_sync", False) + copy_path = copy_fusion_settings.get("copy_path") or None + if copy_path: + copy_path = Path(copy_path).expanduser() + return copy_status, copy_path, force_sync + + def copy_existing_prefs( + self, copy_from: Path, copy_to: Path, force_sync: bool + ) -> None: + """On the first Fusion launch copy the contents of Fusion profile + directory to the working predefined location. If the Openpype profile + folder exists, skip copying, unless re-sync is checked. + If the prefs were not copied on the first launch, + clean Fusion profile will be created in fusion_profile_dir. + """ + if copy_to.exists() and not force_sync: + self.log.info( + "Local Fusion preferences folder exists, skipping profile copy" + ) + return + self.log.info(f"Starting copying Fusion preferences") + self.log.info(f"force_sync option is set to {force_sync}") + dest_folder = copy_to / self.get_fusion_profile_name() + try: + dest_folder.mkdir(exist_ok=True, parents=True) + except Exception: + self.log.warn(f"Could not create folder at {dest_folder}") + return + if not copy_from.exists(): + self.log.warning(f"Fusion preferences not found in {copy_from}") + return + for file in copy_from.iterdir(): + if file.suffix in (".prefs", ".def", ".blocklist", ".fu"): + # convert Path to str to be compatible with Python 3.6+ + shutil.copy(str(file), str(dest_folder)) + self.log.info( + f"successfully copied preferences:\n {copy_from} to {dest_folder}" + ) + + def execute(self): + ( + copy_status, + fusion_profile_dir, + force_sync, + ) = self.get_copy_fusion_prefs_settings() + + # do a copy of Fusion profile if copy_status toggle is enabled + if copy_status and fusion_profile_dir is not None: + prefs_source = self.get_profile_source() + self.copy_existing_prefs(prefs_source, fusion_profile_dir, force_sync) # noqa + + # Add temporary profile directory variables to customize Fusion + # to define where it can read custom scripts and tools from + fusion_profile_dir_variable = f"FUSION{VERSION}_PROFILE_DIR" + self.log.info(f"Setting {fusion_profile_dir_variable}: {fusion_profile_dir}") # noqa + self.launch_context.env[fusion_profile_dir_variable] = str(fusion_profile_dir) # noqa \ No newline at end of file diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index 129aadf1a5..bce221d357 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -4,6 +4,7 @@ import platform from pathlib import Path from openpype.lib import PreLaunchHook, ApplicationLaunchFailed from openpype.hosts.fusion import FUSION_HOST_DIR +from openpype.hosts.fusion import FUSION_PROFILE_VERSION as VERSION class FusionPrelaunch(PreLaunchHook): @@ -16,94 +17,9 @@ class FusionPrelaunch(PreLaunchHook): This also sets FUSION16_MasterPrefs to apply the fusion master prefs as set in openpype/hosts/fusion/deploy/fusion_shared.prefs to enable the OpenPype menu and force Python 3 over Python 2. - - VERSION variable is used because from the Fusion v16 the profile folder - is project-specific, but then it was abandoned by devs, - and despite it is already Fusion version 18, still FUSION16_PROFILE_DIR - is used. The variable is added in case the version number will be - updated or deleted so we could easily change the version or disable it. """ app_groups = ["fusion"] - VERSION = 16 - - def get_fusion_profile_name(self) -> str: - """usually set to 'Default', unless FUSION16_PROFILE is set""" - return os.getenv(f"FUSION{self.VERSION}_PROFILE", "Default") - - def get_profile_source(self) -> Path: - """Get the Fusion preferences (profile) location. - Check Per-User_Preferences_and_Paths on VFXpedia for reference. - """ - fusion_profile = self.get_fusion_profile_name() - fusion_var_prefs_dir = os.getenv(f"FUSION{self.VERSION}_PROFILE_DIR") - - # if FUSION16_PROFILE_DIR variable exists - if fusion_var_prefs_dir and Path(fusion_var_prefs_dir).is_dir(): - fusion_prefs_dir = Path(fusion_var_prefs_dir, fusion_profile) - self.log.info( - f"Local Fusion prefs environment is set to {fusion_prefs_dir}" - ) - return fusion_prefs_dir - # otherwise get the profile folder from default location - fusion_prefs_dir = f"Blackmagic Design/Fusion/Profiles/{fusion_profile}" # noqa - if platform.system() == "Windows": - prefs_source = Path(os.getenv("AppData"), fusion_prefs_dir) - elif platform.system() == "Darwin": - prefs_source = Path( - "~/Library/Application Support/", fusion_prefs_dir - ).expanduser() - elif platform.system() == "Linux": - prefs_source = Path("~/.fusion", fusion_prefs_dir).expanduser() - self.log.info(f"Got Fusion prefs file: {prefs_source}") - return prefs_source - - def get_copy_fusion_prefs_settings(self): - """Get copy preferences options from the global application settings""" - copy_fusion_settings = self.data["project_settings"]["fusion"].get( - "copy_fusion_settings", {} - ) - if not copy_fusion_settings: - self.log.error("Copy prefs settings not found") - copy_status = copy_fusion_settings.get("copy_status", False) - force_sync = copy_fusion_settings.get("force_sync", False) - copy_path = copy_fusion_settings.get("copy_path") or None - if copy_path: - copy_path = Path(copy_path).expanduser() - return copy_status, copy_path, force_sync - - def copy_existing_prefs( - self, copy_from: Path, copy_to: Path, force_sync: bool - ) -> None: - """On the first Fusion launch copy the contents of Fusion profile - directory to the working predefined location. If the Openpype profile - folder exists, skip copying, unless re-sync is checked. - If the prefs were not copied on the first launch, - clean Fusion profile will be created in fusion_profile_dir. - """ - if copy_to.exists() and not force_sync: - self.log.info( - "Local Fusion preferences folder exists, skipping profile copy" - ) - return - self.log.info(f"Starting copying Fusion preferences") - self.log.info(f"force_sync option is set to {force_sync}") - dest_folder = copy_to / self.get_fusion_profile_name() - try: - dest_folder.mkdir(exist_ok=True, parents=True) - except Exception: - self.log.warn(f"Could not create folder at {dest_folder}") - return - if not copy_from.exists(): - self.log.warning(f"Fusion preferences not found in {copy_from}") - return - for file in copy_from.iterdir(): - if file.suffix in (".prefs", ".def", ".blocklist", ".fu"): - # convert Path to str to be compatible with Python 3.6+ - shutil.copy(str(file), str(dest_folder)) - self.log.info( - f"successfully copied preferences:\n {copy_from} to {dest_folder}" - ) def execute(self): # making sure python 3 is installed at provided path @@ -138,26 +54,15 @@ class FusionPrelaunch(PreLaunchHook): # Fusion 16 and 17 use FUSION16_PYTHON36_HOME instead of # FUSION_PYTHON3_HOME and will only work with a Python 3.6 version # TODO: Detect Fusion version to only set for specific Fusion build - self.launch_context.env[f"FUSION{self.VERSION}_PYTHON36_HOME"] = py3_dir # noqa + self.launch_context.env[f"FUSION{VERSION}_PYTHON36_HOME"] = py3_dir # noqa # Add custom Fusion Master Prefs and the temporary # profile directory variables to customize Fusion # to define where it can read custom scripts and tools from self.log.info(f"Setting OPENPYPE_FUSION: {FUSION_HOST_DIR}") self.launch_context.env["OPENPYPE_FUSION"] = FUSION_HOST_DIR - ( - copy_status, - fusion_profile_dir, - force_sync, - ) = self.get_copy_fusion_prefs_settings() - if copy_status and fusion_profile_dir is not None: - prefs_source = self.get_profile_source() - self.copy_existing_prefs(prefs_source, fusion_profile_dir, force_sync) # noqa - else: - fusion_profile_dir_variable = f"FUSION{self.VERSION}_PROFILE_DIR" - self.log.info(f"Setting {fusion_profile_dir_variable}: {fusion_profile_dir}") # noqa - self.launch_context.env[fusion_profile_dir_variable] = str(fusion_profile_dir) # noqa - master_prefs_variable = f"FUSION{self.VERSION}_MasterPrefs" + + master_prefs_variable = f"FUSION{VERSION}_MasterPrefs" master_prefs = Path(FUSION_HOST_DIR, "deploy", "fusion_shared.prefs") self.log.info(f"Setting {master_prefs_variable}: {master_prefs}") - self.launch_context.env[master_prefs_variable] = str(master_prefs) + self.launch_context.env[master_prefs_variable] = str(master_prefs) \ No newline at end of file From e1950a175fbb1a58a1ffeea9ad7620e1a2d05d02 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Wed, 8 Mar 2023 02:11:57 +0300 Subject: [PATCH 32/68] hound comments --- openpype/hosts/fusion/addon.py | 2 +- openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py | 4 ++-- openpype/hosts/fusion/hooks/pre_fusion_setup.py | 2 -- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/fusion/addon.py b/openpype/hosts/fusion/addon.py index 777c38629a..6621f88056 100644 --- a/openpype/hosts/fusion/addon.py +++ b/openpype/hosts/fusion/addon.py @@ -5,7 +5,7 @@ FUSION_HOST_DIR = os.path.dirname(os.path.abspath(__file__)) FUSION_PROFILE_VERSION = 16 -# FUSION_PROFILE_VERSION variable is used by the pre-launch hooks. +# FUSION_PROFILE_VERSION variable is used by the pre-launch hooks. # Since Fusion v16, the profile folder became project-specific, # but then it was abandoned by BlackmagicDesign devs, and now, despite it is # already Fusion version 18, still FUSION16_PROFILE_DIR is used. diff --git a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py index 4af67c1c0d..b91c699cc3 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py @@ -2,7 +2,7 @@ import os import shutil import platform from pathlib import Path -from openpype.lib import PreLaunchHook, ApplicationLaunchFailed +from openpype.lib import PreLaunchHook from openpype.hosts.fusion import FUSION_PROFILE_VERSION as VERSION @@ -11,7 +11,7 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): """ app_groups = ["fusion"] - + def get_fusion_profile_name(self) -> str: """usually set to 'Default', unless FUSION16_PROFILE is set""" return os.getenv(f"FUSION{VERSION}_PROFILE", "Default") diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index bce221d357..e62c2d7ab7 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -1,6 +1,4 @@ import os -import shutil -import platform from pathlib import Path from openpype.lib import PreLaunchHook, ApplicationLaunchFailed from openpype.hosts.fusion import FUSION_HOST_DIR From 39e694374626544f7dce258c86c5ac2809a0cf19 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Wed, 8 Mar 2023 02:35:00 +0300 Subject: [PATCH 33/68] hound comments --- openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py | 3 ++- openpype/hosts/fusion/hooks/pre_fusion_setup.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py index b91c699cc3..e3a00a3e66 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py @@ -106,4 +106,5 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): # to define where it can read custom scripts and tools from fusion_profile_dir_variable = f"FUSION{VERSION}_PROFILE_DIR" self.log.info(f"Setting {fusion_profile_dir_variable}: {fusion_profile_dir}") # noqa - self.launch_context.env[fusion_profile_dir_variable] = str(fusion_profile_dir) # noqa \ No newline at end of file + self.launch_context.env[fusion_profile_dir_variable] = str(fusion_profile_dir) # noqa + \ No newline at end of file diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index e62c2d7ab7..ccad28401d 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -63,4 +63,5 @@ class FusionPrelaunch(PreLaunchHook): master_prefs_variable = f"FUSION{VERSION}_MasterPrefs" master_prefs = Path(FUSION_HOST_DIR, "deploy", "fusion_shared.prefs") self.log.info(f"Setting {master_prefs_variable}: {master_prefs}") - self.launch_context.env[master_prefs_variable] = str(master_prefs) \ No newline at end of file + self.launch_context.env[master_prefs_variable] = str(master_prefs) + \ No newline at end of file From a5e0e057db3aa1de71da3d24f75c6833c5219aa0 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Wed, 8 Mar 2023 02:37:59 +0300 Subject: [PATCH 34/68] good boy --- openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py | 1 - openpype/hosts/fusion/hooks/pre_fusion_setup.py | 1 - 2 files changed, 2 deletions(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py index e3a00a3e66..7172809252 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py @@ -107,4 +107,3 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): fusion_profile_dir_variable = f"FUSION{VERSION}_PROFILE_DIR" self.log.info(f"Setting {fusion_profile_dir_variable}: {fusion_profile_dir}") # noqa self.launch_context.env[fusion_profile_dir_variable] = str(fusion_profile_dir) # noqa - \ No newline at end of file diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index ccad28401d..c39b9cd150 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -64,4 +64,3 @@ class FusionPrelaunch(PreLaunchHook): master_prefs = Path(FUSION_HOST_DIR, "deploy", "fusion_shared.prefs") self.log.info(f"Setting {master_prefs_variable}: {master_prefs}") self.launch_context.env[master_prefs_variable] = str(master_prefs) - \ No newline at end of file From b7ac37701bfc24c69bde5e5fd7a853766d4cc87d Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Thu, 9 Mar 2023 23:57:12 +0300 Subject: [PATCH 35/68] WIP get fusion host version (the wrong way) --- openpype/hosts/fusion/__init__.py | 4 +- openpype/hosts/fusion/addon.py | 33 +++++-- .../fusion/hooks/pre_fusion_profile_hook.py | 91 +++++++++++-------- .../hosts/fusion/hooks/pre_fusion_setup.py | 9 +- 4 files changed, 87 insertions(+), 50 deletions(-) diff --git a/openpype/hosts/fusion/__init__.py b/openpype/hosts/fusion/__init__.py index baaaa9d6fc..f0e7843fff 100644 --- a/openpype/hosts/fusion/__init__.py +++ b/openpype/hosts/fusion/__init__.py @@ -1,12 +1,12 @@ from .addon import ( + get_fusion_profile_number, FusionAddon, FUSION_HOST_DIR, - FUSION_PROFILE_VERSION ) __all__ = ( + "get_fusion_profile_number", "FusionAddon", "FUSION_HOST_DIR", - "FUSION_PROFILE_VERSION" ) diff --git a/openpype/hosts/fusion/addon.py b/openpype/hosts/fusion/addon.py index 6621f88056..4b0ce59aaf 100644 --- a/openpype/hosts/fusion/addon.py +++ b/openpype/hosts/fusion/addon.py @@ -1,16 +1,35 @@ import os +import re from openpype.modules import OpenPypeModule, IHostAddon +from openpype.lib import Logger FUSION_HOST_DIR = os.path.dirname(os.path.abspath(__file__)) -FUSION_PROFILE_VERSION = 16 -# FUSION_PROFILE_VERSION variable is used by the pre-launch hooks. -# Since Fusion v16, the profile folder became project-specific, -# but then it was abandoned by BlackmagicDesign devs, and now, despite it is -# already Fusion version 18, still FUSION16_PROFILE_DIR is used. -# The variable is added in case the version number will be -# updated or deleted so we could easily change the version or disable it. +def get_fusion_profile_number(module: str, app_data: str) -> int: + """ + FUSION_PROFILE_VERSION variable is used by the pre-launch hooks. + Since Fusion v16, the profile folder variable became version-specific, + but then it was abandoned by BlackmagicDesign devs, and now, despite it is + already Fusion version 18, still FUSION16_PROFILE_DIR is used. + The variable is added in case the version number will be + updated or deleted so we could easily change the version or disable it. + """ + + log = Logger.get_logger(__name__) + + if not app_data: + return + fusion16_profile_versions = ("16", "17", "18") + try: + app_version = re.search(r"fusion/(\d+)", app_data).group(1) + log.info(f"{module} found Fusion profile version: {app_version}") + if app_version in fusion16_profile_versions: + return 16 + elif app_version == "9": + return 9 + except AttributeError: + log.info("Fusion version was not found in the app data") class FusionAddon(OpenPypeModule, IHostAddon): diff --git a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py index 7172809252..356292c85b 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py @@ -2,8 +2,9 @@ import os import shutil import platform from pathlib import Path +from pprint import pprint from openpype.lib import PreLaunchHook -from openpype.hosts.fusion import FUSION_PROFILE_VERSION as VERSION +from openpype.hosts.fusion import get_fusion_profile_number class FusionCopyPrefsPrelaunch(PreLaunchHook): @@ -11,40 +12,49 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): """ app_groups = ["fusion"] + order = 2 + + def get_fusion_profile_name(self, app_version) -> str: + # Returns 'Default', unless FUSION16_PROFILE is set + return os.getenv(f"FUSION{app_version}_PROFILE", "Default") - def get_fusion_profile_name(self) -> str: - """usually set to 'Default', unless FUSION16_PROFILE is set""" - return os.getenv(f"FUSION{VERSION}_PROFILE", "Default") + def check_profile_variable(self, app_version) -> Path: + # Get FUSION_PROFILE_DIR variable + fusion_profile = self.get_fusion_profile_name(app_version) + fusion_var_prefs_dir = os.getenv(f"FUSION{app_version}_PROFILE_DIR") - def get_profile_source(self) -> Path: - """Get the Fusion preferences (profile) location. - Check Per-User_Preferences_and_Paths on VFXpedia for reference. - """ - fusion_profile = self.get_fusion_profile_name() - fusion_var_prefs_dir = os.getenv(f"FUSION{VERSION}_PROFILE_DIR") - - # if FUSION16_PROFILE_DIR variable exists + # Check if FUSION_PROFILE_DIR exists if fusion_var_prefs_dir and Path(fusion_var_prefs_dir).is_dir(): - fusion_prefs_dir = Path(fusion_var_prefs_dir, fusion_profile) + fu_prefs_dir = Path(fusion_var_prefs_dir, fusion_profile) self.log.info( - f"Local Fusion prefs environment is set to {fusion_prefs_dir}" + f"{fusion_var_prefs_dir} is set to {fu_prefs_dir}" ) - return fusion_prefs_dir - # otherwise get the profile folder from default location - fusion_prefs_dir = f"Blackmagic Design/Fusion/Profiles/{fusion_profile}" # noqa + return fu_prefs_dir + + def get_profile_source(self, app_version) -> Path: + """Get Fusion preferences profile location. + See Per-User_Preferences_and_Paths on VFXpedia for reference. + """ + fusion_profile = self.get_fusion_profile_name(app_version) + profile_source = self.check_profile_variable(app_version) + if profile_source: + return profile_source + # otherwise get default location of the profile folder + fu_prefs_dir = f"Blackmagic Design/Fusion/Profiles/{fusion_profile}" if platform.system() == "Windows": - prefs_source = Path(os.getenv("AppData"), fusion_prefs_dir) + profile_source = Path(os.getenv("AppData"), fu_prefs_dir) elif platform.system() == "Darwin": - prefs_source = Path( - "~/Library/Application Support/", fusion_prefs_dir + profile_source = Path( + "~/Library/Application Support/", fu_prefs_dir ).expanduser() elif platform.system() == "Linux": - prefs_source = Path("~/.fusion", fusion_prefs_dir).expanduser() - self.log.info(f"Got Fusion prefs file: {prefs_source}") - return prefs_source + profile_source = Path("~/.fusion", fu_prefs_dir).expanduser() + self.log.info(f"Got Fusion prefs file: {profile_source}") + return profile_source def get_copy_fusion_prefs_settings(self): - """Get copy preferences options from the global application settings""" + # Get copy preferences options from the global application settings + copy_fusion_settings = self.data["project_settings"]["fusion"].get( "copy_fusion_settings", {} ) @@ -57,14 +67,14 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): copy_path = Path(copy_path).expanduser() return copy_status, copy_path, force_sync - def copy_existing_prefs( + def copy_fusion_profile( self, copy_from: Path, copy_to: Path, force_sync: bool ) -> None: """On the first Fusion launch copy the contents of Fusion profile directory to the working predefined location. If the Openpype profile folder exists, skip copying, unless re-sync is checked. If the prefs were not copied on the first launch, - clean Fusion profile will be created in fusion_profile_dir. + clean Fusion profile will be created in fu_profile_dir. """ if copy_to.exists() and not force_sync: self.log.info( @@ -73,11 +83,10 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): return self.log.info(f"Starting copying Fusion preferences") self.log.info(f"force_sync option is set to {force_sync}") - dest_folder = copy_to / self.get_fusion_profile_name() try: - dest_folder.mkdir(exist_ok=True, parents=True) + copy_to.mkdir(exist_ok=True, parents=True) except Exception: - self.log.warn(f"Could not create folder at {dest_folder}") + self.log.warn(f"Could not create folder at {copy_to}") return if not copy_from.exists(): self.log.warning(f"Fusion preferences not found in {copy_from}") @@ -85,25 +94,31 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): for file in copy_from.iterdir(): if file.suffix in (".prefs", ".def", ".blocklist", ".fu"): # convert Path to str to be compatible with Python 3.6+ - shutil.copy(str(file), str(dest_folder)) + shutil.copy(str(file), str(copy_to)) self.log.info( - f"successfully copied preferences:\n {copy_from} to {dest_folder}" + f"successfully copied preferences:\n {copy_from} to {copy_to}" ) def execute(self): ( copy_status, - fusion_profile_dir, + fu_profile_dir, force_sync, ) = self.get_copy_fusion_prefs_settings() + # Get launched application context and return correct app version + app_data = self.launch_context.env.get("AVALON_APP_NAME", "fusion/18") + app_version = get_fusion_profile_number(__name__, app_data) + fu_profile = self.get_fusion_profile_name(app_version) + # do a copy of Fusion profile if copy_status toggle is enabled - if copy_status and fusion_profile_dir is not None: - prefs_source = self.get_profile_source() - self.copy_existing_prefs(prefs_source, fusion_profile_dir, force_sync) # noqa + if copy_status and fu_profile_dir is not None: + profile_source = self.get_profile_source(app_version) + dest_folder = Path(fu_profile_dir, fu_profile) + self.copy_fusion_profile(profile_source, dest_folder, force_sync) # Add temporary profile directory variables to customize Fusion # to define where it can read custom scripts and tools from - fusion_profile_dir_variable = f"FUSION{VERSION}_PROFILE_DIR" - self.log.info(f"Setting {fusion_profile_dir_variable}: {fusion_profile_dir}") # noqa - self.launch_context.env[fusion_profile_dir_variable] = str(fusion_profile_dir) # noqa + fu_profile_dir_variable = f"FUSION{app_version}_PROFILE_DIR" + self.log.info(f"Setting {fu_profile_dir_variable}: {fu_profile_dir}") + self.launch_context.env[fu_profile_dir_variable] = str(fu_profile_dir) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index c39b9cd150..7139252d2f 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -2,7 +2,7 @@ import os from pathlib import Path from openpype.lib import PreLaunchHook, ApplicationLaunchFailed from openpype.hosts.fusion import FUSION_HOST_DIR -from openpype.hosts.fusion import FUSION_PROFILE_VERSION as VERSION +from openpype.hosts.fusion import get_fusion_profile_number class FusionPrelaunch(PreLaunchHook): @@ -18,10 +18,13 @@ class FusionPrelaunch(PreLaunchHook): """ app_groups = ["fusion"] + order = 1 def execute(self): # making sure python 3 is installed at provided path # Py 3.3-3.10 for Fusion 18+ or Py 3.6 for Fu 16-17 + app_data = self.launch_context.env.get("AVALON_APP_NAME", "fusion/18") + app_version = get_fusion_profile_number(__name__, app_data) py3_var = "FUSION_PYTHON3_HOME" fusion_python3_home = self.launch_context.env.get(py3_var, "") @@ -52,7 +55,7 @@ class FusionPrelaunch(PreLaunchHook): # Fusion 16 and 17 use FUSION16_PYTHON36_HOME instead of # FUSION_PYTHON3_HOME and will only work with a Python 3.6 version # TODO: Detect Fusion version to only set for specific Fusion build - self.launch_context.env[f"FUSION{VERSION}_PYTHON36_HOME"] = py3_dir # noqa + self.launch_context.env[f"FUSION{app_version}_PYTHON36_HOME"] = py3_dir # Add custom Fusion Master Prefs and the temporary # profile directory variables to customize Fusion @@ -60,7 +63,7 @@ class FusionPrelaunch(PreLaunchHook): self.log.info(f"Setting OPENPYPE_FUSION: {FUSION_HOST_DIR}") self.launch_context.env["OPENPYPE_FUSION"] = FUSION_HOST_DIR - master_prefs_variable = f"FUSION{VERSION}_MasterPrefs" + master_prefs_variable = f"FUSION{app_version}_MasterPrefs" master_prefs = Path(FUSION_HOST_DIR, "deploy", "fusion_shared.prefs") self.log.info(f"Setting {master_prefs_variable}: {master_prefs}") self.launch_context.env[master_prefs_variable] = str(master_prefs) From d01114595645868da87baf337f8a8e84dabc682b Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Fri, 10 Mar 2023 00:02:26 +0300 Subject: [PATCH 36/68] hound --- .../hosts/fusion/hooks/pre_fusion_profile_hook.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py index 356292c85b..4369935b49 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py @@ -2,7 +2,6 @@ import os import shutil import platform from pathlib import Path -from pprint import pprint from openpype.lib import PreLaunchHook from openpype.hosts.fusion import get_fusion_profile_number @@ -13,7 +12,7 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): app_groups = ["fusion"] order = 2 - + def get_fusion_profile_name(self, app_version) -> str: # Returns 'Default', unless FUSION16_PROFILE is set return os.getenv(f"FUSION{app_version}_PROFILE", "Default") @@ -39,8 +38,8 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): profile_source = self.check_profile_variable(app_version) if profile_source: return profile_source - # otherwise get default location of the profile folder - fu_prefs_dir = f"Blackmagic Design/Fusion/Profiles/{fusion_profile}" + # otherwise get default location of the profile folder + fu_prefs_dir = f"Blackmagic Design/Fusion/Profiles/{fusion_profile}" if platform.system() == "Windows": profile_source = Path(os.getenv("AppData"), fu_prefs_dir) elif platform.system() == "Darwin": @@ -110,12 +109,12 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): app_data = self.launch_context.env.get("AVALON_APP_NAME", "fusion/18") app_version = get_fusion_profile_number(__name__, app_data) fu_profile = self.get_fusion_profile_name(app_version) - + # do a copy of Fusion profile if copy_status toggle is enabled if copy_status and fu_profile_dir is not None: profile_source = self.get_profile_source(app_version) dest_folder = Path(fu_profile_dir, fu_profile) - self.copy_fusion_profile(profile_source, dest_folder, force_sync) + self.copy_fusion_profile(profile_source, dest_folder, force_sync) # Add temporary profile directory variables to customize Fusion # to define where it can read custom scripts and tools from From a04f44dcf9e97ef3fd7d8a028c8334d15ffd850d Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Fri, 10 Mar 2023 00:26:05 +0300 Subject: [PATCH 37/68] use FUSION_PYTHON36_HOME for Fusion 9 --- openpype/hosts/fusion/hooks/pre_fusion_setup.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index 7139252d2f..4c73a0eee3 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -55,15 +55,13 @@ class FusionPrelaunch(PreLaunchHook): # Fusion 16 and 17 use FUSION16_PYTHON36_HOME instead of # FUSION_PYTHON3_HOME and will only work with a Python 3.6 version # TODO: Detect Fusion version to only set for specific Fusion build - self.launch_context.env[f"FUSION{app_version}_PYTHON36_HOME"] = py3_dir + if app_version == 9: + self.launch_context.env[f"FUSION_PYTHON36_HOME"] = py3_dir + elif app_version == 16: + self.launch_context.env[f"FUSION{app_version}_PYTHON36_HOME"] = py3_dir # Add custom Fusion Master Prefs and the temporary # profile directory variables to customize Fusion # to define where it can read custom scripts and tools from self.log.info(f"Setting OPENPYPE_FUSION: {FUSION_HOST_DIR}") self.launch_context.env["OPENPYPE_FUSION"] = FUSION_HOST_DIR - - master_prefs_variable = f"FUSION{app_version}_MasterPrefs" - master_prefs = Path(FUSION_HOST_DIR, "deploy", "fusion_shared.prefs") - self.log.info(f"Setting {master_prefs_variable}: {master_prefs}") - self.launch_context.env[master_prefs_variable] = str(master_prefs) From d586231aa11ec76fbde4c9357369d2ed0ffa40c5 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Fri, 10 Mar 2023 00:28:41 +0300 Subject: [PATCH 38/68] move masterprefs setup to the correct hook --- openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py index 4369935b49..543e90cc75 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py @@ -3,7 +3,7 @@ import shutil import platform from pathlib import Path from openpype.lib import PreLaunchHook -from openpype.hosts.fusion import get_fusion_profile_number +from openpype.hosts.fusion import FUSION_HOST_DIR, get_fusion_profile_number class FusionCopyPrefsPrelaunch(PreLaunchHook): @@ -121,3 +121,8 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): fu_profile_dir_variable = f"FUSION{app_version}_PROFILE_DIR" self.log.info(f"Setting {fu_profile_dir_variable}: {fu_profile_dir}") self.launch_context.env[fu_profile_dir_variable] = str(fu_profile_dir) + + master_prefs_variable = f"FUSION{app_version}_MasterPrefs" + master_prefs = Path(FUSION_HOST_DIR, "deploy", "fusion_shared.prefs") + self.log.info(f"Setting {master_prefs_variable}: {master_prefs}") + self.launch_context.env[master_prefs_variable] = str(master_prefs) From 71e8af5a22007678257412ab2052b2034727729d Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Fri, 10 Mar 2023 00:29:49 +0300 Subject: [PATCH 39/68] noqa line --- openpype/hosts/fusion/hooks/pre_fusion_setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index 4c73a0eee3..e30d241096 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -58,7 +58,7 @@ class FusionPrelaunch(PreLaunchHook): if app_version == 9: self.launch_context.env[f"FUSION_PYTHON36_HOME"] = py3_dir elif app_version == 16: - self.launch_context.env[f"FUSION{app_version}_PYTHON36_HOME"] = py3_dir + self.launch_context.env[f"FUSION{app_version}_PYTHON36_HOME"] = py3_dir # noqa # Add custom Fusion Master Prefs and the temporary # profile directory variables to customize Fusion From 8a00c8ae33a910c40eee4bfcacad352119d3975d Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Fri, 10 Mar 2023 00:31:47 +0300 Subject: [PATCH 40/68] remove unused import --- openpype/hosts/fusion/hooks/pre_fusion_setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index e30d241096..38627b40c1 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -1,5 +1,4 @@ import os -from pathlib import Path from openpype.lib import PreLaunchHook, ApplicationLaunchFailed from openpype.hosts.fusion import FUSION_HOST_DIR from openpype.hosts.fusion import get_fusion_profile_number From 5b3cc605d8be1dafdc1114372ae7e9b7e80e3ff4 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Tue, 14 Mar 2023 04:18:48 +0300 Subject: [PATCH 41/68] add some comments --- openpype/hosts/fusion/addon.py | 12 ++++++------ .../hosts/fusion/hooks/pre_fusion_profile_hook.py | 2 ++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/fusion/addon.py b/openpype/hosts/fusion/addon.py index 4b0ce59aaf..e3464f4be4 100644 --- a/openpype/hosts/fusion/addon.py +++ b/openpype/hosts/fusion/addon.py @@ -14,6 +14,10 @@ def get_fusion_profile_number(module: str, app_data: str) -> int: already Fusion version 18, still FUSION16_PROFILE_DIR is used. The variable is added in case the version number will be updated or deleted so we could easily change the version or disable it. + + app_data derives from `launch_context.env.get("AVALON_APP_NAME")`. + For the time being we will encourage user to set a version number + set in the system settings key for the Blackmagic Fusion. """ log = Logger.get_logger(__name__) @@ -42,15 +46,11 @@ class FusionAddon(OpenPypeModule, IHostAddon): def get_launch_hook_paths(self, app): if app.host_name != self.host_name: return [] - return [ - os.path.join(FUSION_HOST_DIR, "hooks") - ] + return [os.path.join(FUSION_HOST_DIR, "hooks")] def add_implementation_envs(self, env, _app): # Set default values if are not already set via settings - defaults = { - "OPENPYPE_LOG_NO_COLORS": "Yes" - } + defaults = {"OPENPYPE_LOG_NO_COLORS": "Yes"} for key, value in defaults.items(): if not env.get(key): env[key] = value diff --git a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py index 543e90cc75..dc6a4bf85d 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py @@ -122,6 +122,8 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): self.log.info(f"Setting {fu_profile_dir_variable}: {fu_profile_dir}") self.launch_context.env[fu_profile_dir_variable] = str(fu_profile_dir) + # setup masterprefs file to partially alter existing or newly generated + # Fusion profile, to add OpenPype menu, scripts and and config files. master_prefs_variable = f"FUSION{app_version}_MasterPrefs" master_prefs = Path(FUSION_HOST_DIR, "deploy", "fusion_shared.prefs") self.log.info(f"Setting {master_prefs_variable}: {master_prefs}") From 00a901120b3a5c0ed258af9bf03084c1c7e994de Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Thu, 16 Mar 2023 02:58:54 +0300 Subject: [PATCH 42/68] check for suported fusion version --- openpype/hosts/fusion/addon.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/openpype/hosts/fusion/addon.py b/openpype/hosts/fusion/addon.py index e3464f4be4..cb4dc76481 100644 --- a/openpype/hosts/fusion/addon.py +++ b/openpype/hosts/fusion/addon.py @@ -4,6 +4,8 @@ from openpype.modules import OpenPypeModule, IHostAddon from openpype.lib import Logger FUSION_HOST_DIR = os.path.dirname(os.path.abspath(__file__)) +FUSION16_PROFILE_VERSIONS = (16, 17, 18) +FUSION9_PROFILE_VERSION = 9 def get_fusion_profile_number(module: str, app_data: str) -> int: @@ -15,8 +17,10 @@ def get_fusion_profile_number(module: str, app_data: str) -> int: The variable is added in case the version number will be updated or deleted so we could easily change the version or disable it. - app_data derives from `launch_context.env.get("AVALON_APP_NAME")`. - For the time being we will encourage user to set a version number + Currently valid Fusion versions are stored in FUSION16_PROFILE_VERSIONS + + app_data derives from `launch_context.env.get("AVALON_APP_NAME")`. + For the time being we will encourage user to set a version number set in the system settings key for the Blackmagic Fusion. """ @@ -24,16 +28,18 @@ def get_fusion_profile_number(module: str, app_data: str) -> int: if not app_data: return - fusion16_profile_versions = ("16", "17", "18") + try: app_version = re.search(r"fusion/(\d+)", app_data).group(1) - log.info(f"{module} found Fusion profile version: {app_version}") - if app_version in fusion16_profile_versions: + log.debug(f"{module} found Fusion profile version: {app_version}") + if app_version in map(str, FUSION16_PROFILE_VERSIONS): return 16 - elif app_version == "9": + elif app_version == str(FUSION9_PROFILE_VERSION): return 9 + else: + log.info(f"Found unsupported Fusion version: {app_version}") except AttributeError: - log.info("Fusion version was not found in the app data") + log.info("Fusion version was not found in the AVALON_APP_NAME data") class FusionAddon(OpenPypeModule, IHostAddon): From ef5c081b5fb77c7709bf780f552d0cc72f16a369 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Thu, 16 Mar 2023 02:59:18 +0300 Subject: [PATCH 43/68] add execution order --- openpype/hosts/fusion/hooks/pre_fusion_ocio_hook.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_ocio_hook.py b/openpype/hosts/fusion/hooks/pre_fusion_ocio_hook.py index 6bf0f55081..47645b7e3f 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_ocio_hook.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_ocio_hook.py @@ -7,6 +7,7 @@ from openpype.pipeline.template_data import get_template_data_with_names class FusionPreLaunchOCIO(PreLaunchHook): """Set OCIO environment variable for Fusion""" app_groups = ["fusion"] + order = 3 def execute(self): """Hook entry method.""" From b305aac21dd14f8d58656b8be197926ca4505316 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Thu, 16 Mar 2023 03:01:35 +0300 Subject: [PATCH 44/68] fix docs --- .../hosts/fusion/hooks/pre_fusion_profile_hook.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py index dc6a4bf85d..08ba9c4157 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py @@ -25,9 +25,7 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): # Check if FUSION_PROFILE_DIR exists if fusion_var_prefs_dir and Path(fusion_var_prefs_dir).is_dir(): fu_prefs_dir = Path(fusion_var_prefs_dir, fusion_profile) - self.log.info( - f"{fusion_var_prefs_dir} is set to {fu_prefs_dir}" - ) + self.log.info(f"{fusion_var_prefs_dir} is set to {fu_prefs_dir}") return fu_prefs_dir def get_profile_source(self, app_version) -> Path: @@ -106,7 +104,7 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): ) = self.get_copy_fusion_prefs_settings() # Get launched application context and return correct app version - app_data = self.launch_context.env.get("AVALON_APP_NAME", "fusion/18") + app_data = self.launch_context.env.get("AVALON_APP_NAME") app_version = get_fusion_profile_number(__name__, app_data) fu_profile = self.get_fusion_profile_name(app_version) @@ -122,8 +120,9 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): self.log.info(f"Setting {fu_profile_dir_variable}: {fu_profile_dir}") self.launch_context.env[fu_profile_dir_variable] = str(fu_profile_dir) - # setup masterprefs file to partially alter existing or newly generated - # Fusion profile, to add OpenPype menu, scripts and and config files. + # Add custom Fusion Master Prefs and the temporary + # profile directory variables to customize Fusion + # to define where it can read custom scripts and tools from master_prefs_variable = f"FUSION{app_version}_MasterPrefs" master_prefs = Path(FUSION_HOST_DIR, "deploy", "fusion_shared.prefs") self.log.info(f"Setting {master_prefs_variable}: {master_prefs}") From f3e20c0af9c4a68858150a52720fb1be1cb1675b Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Thu, 16 Mar 2023 03:03:39 +0300 Subject: [PATCH 45/68] force check Fusion number version in app settings --- .../hosts/fusion/hooks/pre_fusion_setup.py | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index 38627b40c1..b9f568bad2 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -1,7 +1,9 @@ import os from openpype.lib import PreLaunchHook, ApplicationLaunchFailed -from openpype.hosts.fusion import FUSION_HOST_DIR -from openpype.hosts.fusion import get_fusion_profile_number +from openpype.hosts.fusion import ( + FUSION_HOST_DIR, + get_fusion_profile_number, +) class FusionPrelaunch(PreLaunchHook): @@ -22,8 +24,14 @@ class FusionPrelaunch(PreLaunchHook): def execute(self): # making sure python 3 is installed at provided path # Py 3.3-3.10 for Fusion 18+ or Py 3.6 for Fu 16-17 - app_data = self.launch_context.env.get("AVALON_APP_NAME", "fusion/18") + app_data = self.launch_context.env.get("AVALON_APP_NAME") app_version = get_fusion_profile_number(__name__, app_data) + if not app_version: + raise ApplicationLaunchFailed( + "Fusion version information not found in System settings.\n" + "The key field in the 'applications/fusion/variants' " + "should consist a number, corresponding to the Fusion version" + ) py3_var = "FUSION_PYTHON3_HOME" fusion_python3_home = self.launch_context.env.get(py3_var, "") @@ -57,10 +65,9 @@ class FusionPrelaunch(PreLaunchHook): if app_version == 9: self.launch_context.env[f"FUSION_PYTHON36_HOME"] = py3_dir elif app_version == 16: - self.launch_context.env[f"FUSION{app_version}_PYTHON36_HOME"] = py3_dir # noqa + self.launch_context.env[ + f"FUSION{app_version}_PYTHON36_HOME" + ] = py3_dir - # Add custom Fusion Master Prefs and the temporary - # profile directory variables to customize Fusion - # to define where it can read custom scripts and tools from self.log.info(f"Setting OPENPYPE_FUSION: {FUSION_HOST_DIR}") self.launch_context.env["OPENPYPE_FUSION"] = FUSION_HOST_DIR From a63e297186f2fbbda5b115db9f8027d037d86d3f Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Thu, 16 Mar 2023 03:08:20 +0300 Subject: [PATCH 46/68] remove unused import --- openpype/hosts/fusion/api/workio.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/hosts/fusion/api/workio.py b/openpype/hosts/fusion/api/workio.py index fbb5a588f4..fa4b62c123 100644 --- a/openpype/hosts/fusion/api/workio.py +++ b/openpype/hosts/fusion/api/workio.py @@ -1,5 +1,4 @@ """Host API required Work Files tool""" -import sys import os from .lib import get_fusion_module, get_current_comp From d0656e92a54e43468ab6bec24e0031a685cc9145 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov <11698866+movalex@users.noreply.github.com> Date: Thu, 16 Mar 2023 12:47:19 +0300 Subject: [PATCH 47/68] Update openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py Co-authored-by: Roy Nieterau --- openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py index 08ba9c4157..c69ac10b67 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py @@ -46,7 +46,7 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): ).expanduser() elif platform.system() == "Linux": profile_source = Path("~/.fusion", fu_prefs_dir).expanduser() - self.log.info(f"Got Fusion prefs file: {profile_source}") + self.log.info(f"Locating source Fusion prefs directory: {profile_source}") return profile_source def get_copy_fusion_prefs_settings(self): From d0f74f134865a95c1fa1d8e6e5135f842f424509 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov <11698866+movalex@users.noreply.github.com> Date: Thu, 16 Mar 2023 12:48:04 +0300 Subject: [PATCH 48/68] Update openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py Co-authored-by: Roy Nieterau --- openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py index c69ac10b67..ba8997fd74 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py @@ -75,7 +75,7 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): """ if copy_to.exists() and not force_sync: self.log.info( - "Local Fusion preferences folder exists, skipping profile copy" + "Destination Fusion preferences folder exists, skipping profile copy" ) return self.log.info(f"Starting copying Fusion preferences") From 3396784820145e0656b6905b4f5e99697e9f9994 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Thu, 16 Mar 2023 21:32:48 +0300 Subject: [PATCH 49/68] use dictionary to store fusion versions and variables --- openpype/hosts/fusion/__init__.py | 6 ++-- openpype/hosts/fusion/addon.py | 50 +++++++++++++++++-------------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/openpype/hosts/fusion/__init__.py b/openpype/hosts/fusion/__init__.py index f0e7843fff..1da11ba9d1 100644 --- a/openpype/hosts/fusion/__init__.py +++ b/openpype/hosts/fusion/__init__.py @@ -1,12 +1,14 @@ from .addon import ( - get_fusion_profile_number, + get_fusion_version, FusionAddon, FUSION_HOST_DIR, + FUSION_VERSIONS_DICT, ) __all__ = ( - "get_fusion_profile_number", + "get_fusion_version", "FusionAddon", "FUSION_HOST_DIR", + "FUSION_VERSIONS_DICT", ) diff --git a/openpype/hosts/fusion/addon.py b/openpype/hosts/fusion/addon.py index cb4dc76481..2ea16e0d6b 100644 --- a/openpype/hosts/fusion/addon.py +++ b/openpype/hosts/fusion/addon.py @@ -4,24 +4,29 @@ from openpype.modules import OpenPypeModule, IHostAddon from openpype.lib import Logger FUSION_HOST_DIR = os.path.dirname(os.path.abspath(__file__)) -FUSION16_PROFILE_VERSIONS = (16, 17, 18) -FUSION9_PROFILE_VERSION = 9 + +# FUSION_VERSIONS_DICT is used by the pre-launch hooks +# The keys correspond to all currently supported Fusion versions +# Values is the list of corresponding python_home variables and a profile +# number, which is used to specify pufion profile derectory variable. +FUSION_VERSIONS_DICT = { + 9: ["FUSION_PYTHON36_HOME", 9], + 16: ["FUSION16_PYTHON36_HOME", 16], + 17: ["FUSION16_PYTHON36_HOME", 16], + 18: ["FUSION_PYTHON3_HOME", 16], +} -def get_fusion_profile_number(module: str, app_data: str) -> int: +def get_fusion_version(app_data): """ - FUSION_PROFILE_VERSION variable is used by the pre-launch hooks. - Since Fusion v16, the profile folder variable became version-specific, - but then it was abandoned by BlackmagicDesign devs, and now, despite it is - already Fusion version 18, still FUSION16_PROFILE_DIR is used. - The variable is added in case the version number will be - updated or deleted so we could easily change the version or disable it. + The function is triggered by the prelaunch hooks to get the fusion version. - Currently valid Fusion versions are stored in FUSION16_PROFILE_VERSIONS + `app_data` is obtained by prelaunch hooks from the + `launch_context.env.get("AVALON_APP_NAME")`. - app_data derives from `launch_context.env.get("AVALON_APP_NAME")`. - For the time being we will encourage user to set a version number - set in the system settings key for the Blackmagic Fusion. + To get a correct Fusion version, a version number should be present + in the `applications/fusion/variants` key + int the Blackmagic Fusion Application Settings. """ log = Logger.get_logger(__name__) @@ -29,17 +34,16 @@ def get_fusion_profile_number(module: str, app_data: str) -> int: if not app_data: return - try: - app_version = re.search(r"fusion/(\d+)", app_data).group(1) - log.debug(f"{module} found Fusion profile version: {app_version}") - if app_version in map(str, FUSION16_PROFILE_VERSIONS): - return 16 - elif app_version == str(FUSION9_PROFILE_VERSION): - return 9 + app_version_candidates = re.findall("\d+", app_data) + for app_version in app_version_candidates: + if int(app_version) in FUSION_VERSIONS_DICT: + return int(app_version) else: - log.info(f"Found unsupported Fusion version: {app_version}") - except AttributeError: - log.info("Fusion version was not found in the AVALON_APP_NAME data") + log.info( + "Unsupported Fusion version: {app_version}".format( + app_version=app_version + ) + ) class FusionAddon(OpenPypeModule, IHostAddon): From e61ec028e24f5e0dfcceb3de1902c03f66c8edd7 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Thu, 16 Mar 2023 21:33:11 +0300 Subject: [PATCH 50/68] delete unused module --- openpype/hosts/fusion/api/workio.py | 38 ----------------------------- 1 file changed, 38 deletions(-) delete mode 100644 openpype/hosts/fusion/api/workio.py diff --git a/openpype/hosts/fusion/api/workio.py b/openpype/hosts/fusion/api/workio.py deleted file mode 100644 index fa4b62c123..0000000000 --- a/openpype/hosts/fusion/api/workio.py +++ /dev/null @@ -1,38 +0,0 @@ -"""Host API required Work Files tool""" -import os - -from .lib import get_fusion_module, get_current_comp - - -def file_extensions(): - return [".comp"] - - -def has_unsaved_changes(): - comp = get_current_comp() - return comp.GetAttrs()["COMPB_Modified"] - - -def save_file(filepath): - comp = get_current_comp() - comp.Save(filepath) - - -def open_file(filepath): - fusion = get_fusion_module() - return fusion.LoadComp(filepath) - - -def current_file(): - comp = get_current_comp() - current_filepath = comp.GetAttrs()["COMPS_FileName"] - return current_filepath or None - - -def work_root(session): - work_dir = session["AVALON_WORKDIR"] - scene_dir = session.get("AVALON_SCENEDIR") - if scene_dir: - return os.path.join(work_dir, scene_dir) - else: - return work_dir From 502198d00b4420d766a4a87c6f71c63d7e35ebf8 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Thu, 16 Mar 2023 21:53:12 +0300 Subject: [PATCH 51/68] update fusion hooks to get correct version and variables --- .../fusion/hooks/pre_fusion_profile_hook.py | 61 +++++++++++++------ .../hosts/fusion/hooks/pre_fusion_setup.py | 38 +++++------- 2 files changed, 56 insertions(+), 43 deletions(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py index ba8997fd74..b6ddacb571 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py @@ -3,24 +3,38 @@ import shutil import platform from pathlib import Path from openpype.lib import PreLaunchHook -from openpype.hosts.fusion import FUSION_HOST_DIR, get_fusion_profile_number +from openpype.hosts.fusion import ( + FUSION_HOST_DIR, + FUSION_VERSIONS_DICT, + get_fusion_version, +) class FusionCopyPrefsPrelaunch(PreLaunchHook): - """Prepares local Fusion profile directory, copies existing Fusion profile + """ + Prepares local Fusion profile directory, copies existing Fusion profile. + This also sets FUSION MasterPrefs variable, which is used + to apply Master.prefs file to override some Fusion profile settings to: + - enable the OpenPype menu + - force Python 3 over Python 2 + - force English interface + - force grey color scheme (because it is better that the purple one!) + Master.prefs is defined in openpype/hosts/fusion/deploy/fusion_shared.prefs """ app_groups = ["fusion"] order = 2 - def get_fusion_profile_name(self, app_version) -> str: + def get_fusion_profile_name(self, profile_version) -> str: # Returns 'Default', unless FUSION16_PROFILE is set - return os.getenv(f"FUSION{app_version}_PROFILE", "Default") + return os.getenv(f"FUSION{profile_version}_PROFILE", "Default") - def check_profile_variable(self, app_version) -> Path: + def get_fusion_profile_dir(self, profile_version) -> Path: # Get FUSION_PROFILE_DIR variable - fusion_profile = self.get_fusion_profile_name(app_version) - fusion_var_prefs_dir = os.getenv(f"FUSION{app_version}_PROFILE_DIR") + fusion_profile = self.get_fusion_profile_name(profile_version) + fusion_var_prefs_dir = os.getenv( + f"FUSION{profile_version}_PROFILE_DIR" + ) # Check if FUSION_PROFILE_DIR exists if fusion_var_prefs_dir and Path(fusion_var_prefs_dir).is_dir(): @@ -28,12 +42,12 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): self.log.info(f"{fusion_var_prefs_dir} is set to {fu_prefs_dir}") return fu_prefs_dir - def get_profile_source(self, app_version) -> Path: + def get_profile_source(self, profile_version) -> Path: """Get Fusion preferences profile location. See Per-User_Preferences_and_Paths on VFXpedia for reference. """ - fusion_profile = self.get_fusion_profile_name(app_version) - profile_source = self.check_profile_variable(app_version) + fusion_profile = self.get_fusion_profile_name(profile_version) + profile_source = self.get_fusion_profile_dir(profile_version) if profile_source: return profile_source # otherwise get default location of the profile folder @@ -46,7 +60,9 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): ).expanduser() elif platform.system() == "Linux": profile_source = Path("~/.fusion", fu_prefs_dir).expanduser() - self.log.info(f"Locating source Fusion prefs directory: {profile_source}") + self.log.info( + f"Locating source Fusion prefs directory: {profile_source}" + ) return profile_source def get_copy_fusion_prefs_settings(self): @@ -82,14 +98,20 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): self.log.info(f"force_sync option is set to {force_sync}") try: copy_to.mkdir(exist_ok=True, parents=True) - except Exception: - self.log.warn(f"Could not create folder at {copy_to}") + except PermissionError: + self.log.warn(f"Creating the folder not permitted at {copy_to}") return if not copy_from.exists(): self.log.warning(f"Fusion preferences not found in {copy_from}") return for file in copy_from.iterdir(): - if file.suffix in (".prefs", ".def", ".blocklist", ".fu"): + if file.suffix in ( + ".prefs", + ".def", + ".blocklist", + ".fu", + ".toolbars", + ): # convert Path to str to be compatible with Python 3.6+ shutil.copy(str(file), str(copy_to)) self.log.info( @@ -105,25 +127,26 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): # Get launched application context and return correct app version app_data = self.launch_context.env.get("AVALON_APP_NAME") - app_version = get_fusion_profile_number(__name__, app_data) - fu_profile = self.get_fusion_profile_name(app_version) + app_version = get_fusion_version(app_data) + _, profile_version = FUSION_VERSIONS_DICT[app_version] + fu_profile = self.get_fusion_profile_name(profile_version) # do a copy of Fusion profile if copy_status toggle is enabled if copy_status and fu_profile_dir is not None: - profile_source = self.get_profile_source(app_version) + profile_source = self.get_profile_source(profile_version) dest_folder = Path(fu_profile_dir, fu_profile) self.copy_fusion_profile(profile_source, dest_folder, force_sync) # Add temporary profile directory variables to customize Fusion # to define where it can read custom scripts and tools from - fu_profile_dir_variable = f"FUSION{app_version}_PROFILE_DIR" + fu_profile_dir_variable = f"FUSION{profile_version}_PROFILE_DIR" self.log.info(f"Setting {fu_profile_dir_variable}: {fu_profile_dir}") self.launch_context.env[fu_profile_dir_variable] = str(fu_profile_dir) # Add custom Fusion Master Prefs and the temporary # profile directory variables to customize Fusion # to define where it can read custom scripts and tools from - master_prefs_variable = f"FUSION{app_version}_MasterPrefs" + master_prefs_variable = f"FUSION{profile_version}_MasterPrefs" master_prefs = Path(FUSION_HOST_DIR, "deploy", "fusion_shared.prefs") self.log.info(f"Setting {master_prefs_variable}: {master_prefs}") self.launch_context.env[master_prefs_variable] = str(master_prefs) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index b9f568bad2..a014268c8f 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -2,20 +2,19 @@ import os from openpype.lib import PreLaunchHook, ApplicationLaunchFailed from openpype.hosts.fusion import ( FUSION_HOST_DIR, - get_fusion_profile_number, + FUSION_VERSIONS_DICT, + get_fusion_version, ) class FusionPrelaunch(PreLaunchHook): - """Prepares OpenPype Fusion environment - - Requires FUSION_PYTHON3_HOME to be defined in the environment for Fusion - to point at a valid Python 3 build for Fusion. That is Python 3.3-3.10 - for Fusion 18 and Fusion 3.6 for Fusion 16 and 17. - - This also sets FUSION16_MasterPrefs to apply the fusion master prefs - as set in openpype/hosts/fusion/deploy/fusion_shared.prefs to enable - the OpenPype menu and force Python 3 over Python 2. + """ + Prepares OpenPype Fusion environment. + Requires correct Python home variable to be defined in the environment + settings for Fusion to point at a valid Python 3 build for Fusion. + Python3 versions that are supported by Fusion: + Fusion 9, 16, 17 : Python 3.6 + Fusion 18 : Python 3.6 - 3.10 """ app_groups = ["fusion"] @@ -25,15 +24,14 @@ class FusionPrelaunch(PreLaunchHook): # making sure python 3 is installed at provided path # Py 3.3-3.10 for Fusion 18+ or Py 3.6 for Fu 16-17 app_data = self.launch_context.env.get("AVALON_APP_NAME") - app_version = get_fusion_profile_number(__name__, app_data) + app_version = get_fusion_version(app_data) if not app_version: raise ApplicationLaunchFailed( "Fusion version information not found in System settings.\n" "The key field in the 'applications/fusion/variants' " "should consist a number, corresponding to the Fusion version" ) - - py3_var = "FUSION_PYTHON3_HOME" + py3_var, _ = FUSION_VERSIONS_DICT[app_version] fusion_python3_home = self.launch_context.env.get(py3_var, "") for path in fusion_python3_home.split(os.pathsep): @@ -42,7 +40,6 @@ class FusionPrelaunch(PreLaunchHook): # But make to set only a single path as final variable. py3_dir = os.path.normpath(path) if os.path.isdir(py3_dir): - self.log.info(f"Looking for Python 3 in: {py3_dir}") break else: raise ApplicationLaunchFailed( @@ -57,17 +54,10 @@ class FusionPrelaunch(PreLaunchHook): self.launch_context.env[py3_var] = py3_dir # Fusion 18+ requires FUSION_PYTHON3_HOME to also be on PATH - self.launch_context.env["PATH"] += ";" + py3_dir + if app_version > 17: + self.launch_context.env["PATH"] += ";" + py3_dir - # Fusion 16 and 17 use FUSION16_PYTHON36_HOME instead of - # FUSION_PYTHON3_HOME and will only work with a Python 3.6 version - # TODO: Detect Fusion version to only set for specific Fusion build - if app_version == 9: - self.launch_context.env[f"FUSION_PYTHON36_HOME"] = py3_dir - elif app_version == 16: - self.launch_context.env[ - f"FUSION{app_version}_PYTHON36_HOME" - ] = py3_dir + self.launch_context.env[py3_var] = py3_dir self.log.info(f"Setting OPENPYPE_FUSION: {FUSION_HOST_DIR}") self.launch_context.env["OPENPYPE_FUSION"] = FUSION_HOST_DIR From 4d252b698af788f22fd18607289991fc6cac9d48 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Thu, 16 Mar 2023 21:54:45 +0300 Subject: [PATCH 52/68] fix regex escape sequence --- openpype/hosts/fusion/addon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/addon.py b/openpype/hosts/fusion/addon.py index 2ea16e0d6b..0eb7e09003 100644 --- a/openpype/hosts/fusion/addon.py +++ b/openpype/hosts/fusion/addon.py @@ -34,7 +34,7 @@ def get_fusion_version(app_data): if not app_data: return - app_version_candidates = re.findall("\d+", app_data) + app_version_candidates = re.findall(r"\d+", app_data) for app_version in app_version_candidates: if int(app_version) in FUSION_VERSIONS_DICT: return int(app_version) From 5ebdbcf2d284ec7c02f58454e81c998f64b423e2 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Thu, 16 Mar 2023 21:55:58 +0300 Subject: [PATCH 53/68] remove whitespaces --- openpype/hosts/fusion/hooks/pre_fusion_setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index a014268c8f..a337a4245e 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -10,11 +10,11 @@ from openpype.hosts.fusion import ( class FusionPrelaunch(PreLaunchHook): """ Prepares OpenPype Fusion environment. - Requires correct Python home variable to be defined in the environment + Requires correct Python home variable to be defined in the environment settings for Fusion to point at a valid Python 3 build for Fusion. Python3 versions that are supported by Fusion: Fusion 9, 16, 17 : Python 3.6 - Fusion 18 : Python 3.6 - 3.10 + Fusion 18 : Python 3.6 - 3.10 """ app_groups = ["fusion"] From dacd50061b602d73ede815cb46e1c656fe41dc9d Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Thu, 16 Mar 2023 22:19:46 +0300 Subject: [PATCH 54/68] fix line length --- openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py index b6ddacb571..6e7d2558fd 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py @@ -91,7 +91,7 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): """ if copy_to.exists() and not force_sync: self.log.info( - "Destination Fusion preferences folder exists, skipping profile copy" + "Destination Fusion preferences folder already exists" ) return self.log.info(f"Starting copying Fusion preferences") From 30d38ab3d1da328551a52c9ae47391af4b49ada6 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Thu, 16 Mar 2023 22:21:02 +0300 Subject: [PATCH 55/68] fix typo, early check if no fusion version found --- openpype/hosts/fusion/addon.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/addon.py b/openpype/hosts/fusion/addon.py index 0eb7e09003..7314267124 100644 --- a/openpype/hosts/fusion/addon.py +++ b/openpype/hosts/fusion/addon.py @@ -26,7 +26,7 @@ def get_fusion_version(app_data): To get a correct Fusion version, a version number should be present in the `applications/fusion/variants` key - int the Blackmagic Fusion Application Settings. + of the Blackmagic Fusion Application Settings. """ log = Logger.get_logger(__name__) @@ -35,6 +35,8 @@ def get_fusion_version(app_data): return app_version_candidates = re.findall(r"\d+", app_data) + if not app_version_candidates: + return for app_version in app_version_candidates: if int(app_version) in FUSION_VERSIONS_DICT: return int(app_version) From 97af187f8077d987851b121b02e50dc8a351caa6 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Thu, 16 Mar 2023 22:46:20 +0300 Subject: [PATCH 56/68] catch typos, update comment --- openpype/hosts/fusion/addon.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/fusion/addon.py b/openpype/hosts/fusion/addon.py index 7314267124..e7c7a03fa2 100644 --- a/openpype/hosts/fusion/addon.py +++ b/openpype/hosts/fusion/addon.py @@ -7,8 +7,8 @@ FUSION_HOST_DIR = os.path.dirname(os.path.abspath(__file__)) # FUSION_VERSIONS_DICT is used by the pre-launch hooks # The keys correspond to all currently supported Fusion versions -# Values is the list of corresponding python_home variables and a profile -# number, which is used to specify pufion profile derectory variable. +# Each value is a list of corresponding Python home variables and a profile +# number, which is used by the profile hook to set Fusion profile variables. FUSION_VERSIONS_DICT = { 9: ["FUSION_PYTHON36_HOME", 9], 16: ["FUSION16_PYTHON36_HOME", 16], From 3c3722d4082417bb3a2605cf2af4ee9a0448f299 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Fri, 17 Mar 2023 00:30:25 +0300 Subject: [PATCH 57/68] use os.pathsep to build the PATH variable --- openpype/hosts/fusion/hooks/pre_fusion_setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index a337a4245e..64c498dd01 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -54,8 +54,8 @@ class FusionPrelaunch(PreLaunchHook): self.launch_context.env[py3_var] = py3_dir # Fusion 18+ requires FUSION_PYTHON3_HOME to also be on PATH - if app_version > 17: - self.launch_context.env["PATH"] += ";" + py3_dir + if app_version >= 18: + self.launch_context.env["PATH"] += os.pathsep + py3_dir self.launch_context.env[py3_var] = py3_dir From fcb723068336eca63635b231cdbd6e7760182981 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Fri, 17 Mar 2023 00:57:47 +0300 Subject: [PATCH 58/68] use immutable values --- openpype/hosts/fusion/addon.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/fusion/addon.py b/openpype/hosts/fusion/addon.py index e7c7a03fa2..345e348c3b 100644 --- a/openpype/hosts/fusion/addon.py +++ b/openpype/hosts/fusion/addon.py @@ -10,10 +10,10 @@ FUSION_HOST_DIR = os.path.dirname(os.path.abspath(__file__)) # Each value is a list of corresponding Python home variables and a profile # number, which is used by the profile hook to set Fusion profile variables. FUSION_VERSIONS_DICT = { - 9: ["FUSION_PYTHON36_HOME", 9], - 16: ["FUSION16_PYTHON36_HOME", 16], - 17: ["FUSION16_PYTHON36_HOME", 16], - 18: ["FUSION_PYTHON3_HOME", 16], + 9: ("FUSION_PYTHON36_HOME", 9), + 16: ("FUSION16_PYTHON36_HOME", 16), + 17: ("FUSION16_PYTHON36_HOME", 16), + 18: ("FUSION_PYTHON3_HOME", 16), } From d299824e219a41dc2043925916d20c90ab633d32 Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Fri, 17 Mar 2023 01:02:51 +0300 Subject: [PATCH 59/68] ok, do not force grey interface in masterprefs (purple is still bad!) --- openpype/hosts/fusion/deploy/fusion_shared.prefs | 1 - openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py | 1 - 2 files changed, 2 deletions(-) diff --git a/openpype/hosts/fusion/deploy/fusion_shared.prefs b/openpype/hosts/fusion/deploy/fusion_shared.prefs index 17ac3ad37a..b379ea7c66 100644 --- a/openpype/hosts/fusion/deploy/fusion_shared.prefs +++ b/openpype/hosts/fusion/deploy/fusion_shared.prefs @@ -13,7 +13,6 @@ Global = { Python3Forced = true }, UserInterface = { - Skin = "Neutral", Language = "en_US" }, }, diff --git a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py index 6e7d2558fd..15c9424990 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py @@ -18,7 +18,6 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): - enable the OpenPype menu - force Python 3 over Python 2 - force English interface - - force grey color scheme (because it is better that the purple one!) Master.prefs is defined in openpype/hosts/fusion/deploy/fusion_shared.prefs """ From 3b62d0f4a7dfba155d588cfa3c40e6fe5075a61a Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Fri, 17 Mar 2023 01:03:22 +0300 Subject: [PATCH 60/68] clarify the error message --- openpype/hosts/fusion/hooks/pre_fusion_setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index 64c498dd01..f27cd1674b 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -28,8 +28,8 @@ class FusionPrelaunch(PreLaunchHook): if not app_version: raise ApplicationLaunchFailed( "Fusion version information not found in System settings.\n" - "The key field in the 'applications/fusion/variants' " - "should consist a number, corresponding to the Fusion version" + "The key field in the 'applications/fusion/variants' should " + "consist a number, corresponding to major Fusion version." ) py3_var, _ = FUSION_VERSIONS_DICT[app_version] fusion_python3_home = self.launch_context.env.get(py3_var, "") From bec46399857dd13cf482dc28688a1ffec9a15dac Mon Sep 17 00:00:00 2001 From: Alexey Bogomolov Date: Fri, 17 Mar 2023 01:14:39 +0300 Subject: [PATCH 61/68] revert change --- openpype/hosts/fusion/hooks/pre_fusion_ocio_hook.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_ocio_hook.py b/openpype/hosts/fusion/hooks/pre_fusion_ocio_hook.py index 47645b7e3f..6bf0f55081 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_ocio_hook.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_ocio_hook.py @@ -7,7 +7,6 @@ from openpype.pipeline.template_data import get_template_data_with_names class FusionPreLaunchOCIO(PreLaunchHook): """Set OCIO environment variable for Fusion""" app_groups = ["fusion"] - order = 3 def execute(self): """Hook entry method.""" From 00b83e58792db4e33d5d218ce942a8667d724265 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 17 Mar 2023 16:21:27 +0100 Subject: [PATCH 62/68] Refactor `app_data` -> `app_name` --- openpype/hosts/fusion/addon.py | 8 ++++---- openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/fusion/addon.py b/openpype/hosts/fusion/addon.py index 345e348c3b..45683cfbde 100644 --- a/openpype/hosts/fusion/addon.py +++ b/openpype/hosts/fusion/addon.py @@ -17,11 +17,11 @@ FUSION_VERSIONS_DICT = { } -def get_fusion_version(app_data): +def get_fusion_version(app_name): """ The function is triggered by the prelaunch hooks to get the fusion version. - `app_data` is obtained by prelaunch hooks from the + `app_name` is obtained by prelaunch hooks from the `launch_context.env.get("AVALON_APP_NAME")`. To get a correct Fusion version, a version number should be present @@ -31,10 +31,10 @@ def get_fusion_version(app_data): log = Logger.get_logger(__name__) - if not app_data: + if not app_name: return - app_version_candidates = re.findall(r"\d+", app_data) + app_version_candidates = re.findall(r"\d+", app_name) if not app_version_candidates: return for app_version in app_version_candidates: diff --git a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py index 15c9424990..cf168194c3 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py @@ -125,8 +125,8 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): ) = self.get_copy_fusion_prefs_settings() # Get launched application context and return correct app version - app_data = self.launch_context.env.get("AVALON_APP_NAME") - app_version = get_fusion_version(app_data) + app_name = self.launch_context.env.get("AVALON_APP_NAME") + app_version = get_fusion_version(app_name) _, profile_version = FUSION_VERSIONS_DICT[app_version] fu_profile = self.get_fusion_profile_name(profile_version) From 35157c81de68b6bcb049ce610b31809856273624 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 17 Mar 2023 16:30:04 +0100 Subject: [PATCH 63/68] Report if Fusion version not detected --- .../hosts/fusion/hooks/pre_fusion_profile_hook.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py index cf168194c3..3a4d827428 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py @@ -2,7 +2,7 @@ import os import shutil import platform from pathlib import Path -from openpype.lib import PreLaunchHook +from openpype.lib import PreLaunchHook, ApplicationLaunchFailed from openpype.hosts.fusion import ( FUSION_HOST_DIR, FUSION_VERSIONS_DICT, @@ -127,6 +127,15 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): # Get launched application context and return correct app version app_name = self.launch_context.env.get("AVALON_APP_NAME") app_version = get_fusion_version(app_name) + if app_version is None or True: + version_names = ", ".join(str(x) for x in FUSION_VERSIONS_DICT) + raise ApplicationLaunchFailed( + "Unable to detect valid Fusion version number from app " + f"name: {app_name}.\nMake sure to include at least a digit " + "to indicate the Fusion version like '18'.\n" + f"Detectable Fusion versions are: {version_names}" + ) + _, profile_version = FUSION_VERSIONS_DICT[app_version] fu_profile = self.get_fusion_profile_name(profile_version) From 3160a0ede09c859f1a40651af3bf805d1dca2fc7 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 17 Mar 2023 16:30:21 +0100 Subject: [PATCH 64/68] Remove the debugging logic :) --- openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py index 3a4d827428..ee80a9c90a 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py @@ -127,7 +127,7 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): # Get launched application context and return correct app version app_name = self.launch_context.env.get("AVALON_APP_NAME") app_version = get_fusion_version(app_name) - if app_version is None or True: + if app_version is None: version_names = ", ".join(str(x) for x in FUSION_VERSIONS_DICT) raise ApplicationLaunchFailed( "Unable to detect valid Fusion version number from app " From f6be90d7a415636e2e848ee4c0f3766dbf87eda6 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 17 Mar 2023 16:33:16 +0100 Subject: [PATCH 65/68] Debug log instead of info log --- openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py index ee80a9c90a..4e5ff4159b 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py @@ -93,8 +93,8 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): "Destination Fusion preferences folder already exists" ) return - self.log.info(f"Starting copying Fusion preferences") - self.log.info(f"force_sync option is set to {force_sync}") + self.log.info("Starting copying Fusion preferences") + self.log.debug(f"force_sync option is set to {force_sync}") try: copy_to.mkdir(exist_ok=True, parents=True) except PermissionError: From c71651e29e7c51e13513095c5f43180645375404 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 17 Mar 2023 16:37:51 +0100 Subject: [PATCH 66/68] Match other method calls to `warning` --- openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py index 4e5ff4159b..b0a4e19f44 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py @@ -98,7 +98,7 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): try: copy_to.mkdir(exist_ok=True, parents=True) except PermissionError: - self.log.warn(f"Creating the folder not permitted at {copy_to}") + self.log.warning(f"Creating the folder not permitted at {copy_to}") return if not copy_from.exists(): self.log.warning(f"Fusion preferences not found in {copy_from}") From 6a06f80db0e600fdc28d85a8ccac839a38c64ead Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 17 Mar 2023 16:39:39 +0100 Subject: [PATCH 67/68] Cosmetics + do not add new line because its confusing in command line logs --- openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py index b0a4e19f44..339cf35a7d 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py @@ -114,7 +114,7 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): # convert Path to str to be compatible with Python 3.6+ shutil.copy(str(file), str(copy_to)) self.log.info( - f"successfully copied preferences:\n {copy_from} to {copy_to}" + f"Successfully copied preferences: {copy_from} to {copy_to}" ) def execute(self): From ae44c0de29af77db9d3e9a342acc5b341cab4954 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 17 Mar 2023 16:42:23 +0100 Subject: [PATCH 68/68] Report the existing folder in the log --- openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py index 339cf35a7d..fd726ccda1 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_profile_hook.py @@ -90,7 +90,8 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): """ if copy_to.exists() and not force_sync: self.log.info( - "Destination Fusion preferences folder already exists" + "Destination Fusion preferences folder already exists: " + f"{copy_to} " ) return self.log.info("Starting copying Fusion preferences")