diff --git a/pype/hosts/resolve/__init__.py b/pype/hosts/resolve/__init__.py index 72d6314b5e..b7e6c7dee3 100644 --- a/pype/hosts/resolve/__init__.py +++ b/pype/hosts/resolve/__init__.py @@ -1,17 +1,29 @@ +from .utils import ( + setup, + get_resolve_module +) + from .pipeline import ( install, uninstall, ls, containerise, publish, - launch_workfiles_app + launch_workfiles_app, + maintained_selection ) -from .utils import ( - setup, - get_resolve_module +from .lib import ( + get_project_manager, + get_current_project, + get_current_sequence, + set_project_manager_to_folder_name ) +from .menu import launch_pype_menu + +from .plugin import Creator + from .workio import ( open_file, save_file, @@ -21,12 +33,7 @@ from .workio import ( work_root ) -from .lib import ( - get_project_manager, - set_project_manager_to_folder_name -) - -from .menu import launch_pype_menu +bmd = None __all__ = [ # pipeline @@ -37,6 +44,7 @@ __all__ = [ "reload_pipeline", "publish", "launch_workfiles_app", + "maintained_selection", # utils "setup", @@ -44,16 +52,24 @@ __all__ = [ # lib "get_project_manager", + "get_current_project", + "get_current_sequence", "set_project_manager_to_folder_name", # menu "launch_pype_menu", + # plugin + "Creator", + # workio "open_file", "save_file", "current_file", "has_unsaved_changes", "file_extensions", - "work_root" + "work_root", + + # singleton with black magic resolve module + "bmd" ] diff --git a/pype/hosts/resolve/action.py b/pype/hosts/resolve/action.py index 31830937c1..a9803cef4e 100644 --- a/pype/hosts/resolve/action.py +++ b/pype/hosts/resolve/action.py @@ -21,9 +21,9 @@ class SelectInvalidAction(pyblish.api.Action): def process(self, context, plugin): try: - from pype.hosts.resolve.utils import get_resolve_module - resolve = get_resolve_module() - self.log.debug(resolve) + from . import get_project_manager + pm = get_project_manager() + self.log.debug(pm) except ImportError: raise ImportError("Current host is not Resolve") diff --git a/pype/hosts/resolve/lib.py b/pype/hosts/resolve/lib.py index 2e759ab96c..25e177eb1c 100644 --- a/pype/hosts/resolve/lib.py +++ b/pype/hosts/resolve/lib.py @@ -1,5 +1,4 @@ import sys -from .utils import get_resolve_module from pype.api import Logger log = Logger().get_logger(__name__, "resolve") @@ -9,12 +8,26 @@ self.pm = None def get_project_manager(): + from . import bmd if not self.pm: - resolve = get_resolve_module() - self.pm = resolve.GetProjectManager() + self.pm = bmd.GetProjectManager() return self.pm +def get_current_project(): + # initialize project manager + get_project_manager() + + return self.pm.GetCurrentProject() + + +def get_current_sequence(): + # get current project + project = get_current_project() + + return project.GetCurrentTimeline() + + def set_project_manager_to_folder_name(folder_name): """ Sets context of Project manager to given folder by name. diff --git a/pype/hosts/resolve/pipeline.py b/pype/hosts/resolve/pipeline.py index 8dfb94486b..91d06da274 100644 --- a/pype/hosts/resolve/pipeline.py +++ b/pype/hosts/resolve/pipeline.py @@ -2,7 +2,7 @@ Basic avalon integration """ import os -# import sys +import contextlib from avalon.tools import workfiles from avalon import api as avalon from pyblish import api as pyblish @@ -11,8 +11,6 @@ from pype.api import Logger log = Logger().get_logger(__name__, "resolve") -# self = sys.modules[__name__] - AVALON_CONFIG = os.environ["AVALON_CONFIG"] LOAD_PATH = os.path.join(pype.PLUGINS_DIR, "resolve", "load") @@ -38,11 +36,13 @@ def install(): See the Maya equivalent for inspiration on how to implement this. """ + from . import get_resolve_module # Disable all families except for the ones we explicitly want to see family_states = [ "imagesequence", - "mov" + "mov", + "clip" ] avalon.data["familiesStateDefault"] = False avalon.data["familiesStateToggled"] = family_states @@ -57,6 +57,8 @@ def install(): avalon.register_plugin_path(avalon.Creator, CREATE_PATH) avalon.register_plugin_path(avalon.InventoryAction, INVENTORY_PATH) + get_resolve_module() + def uninstall(): """Uninstall all tha was installed @@ -138,3 +140,44 @@ def publish(parent): """Shorthand to publish from within host""" from avalon.tools import publish return publish.show(parent) + + +@contextlib.contextmanager +def maintained_selection(): + """Maintain selection during context + + Example: + >>> with maintained_selection(): + ... node['selected'].setValue(True) + >>> print(node['selected'].value()) + False + """ + from . import get_current_project + project = get_current_project() + nodes = [] + previous_selection = None + + # deselect all nodes + reset_selection() + + try: + # do the operation + yield + finally: + # unselect all selection in case there is some + reset_selection() + # and select all previously selected nodes + if previous_selection: + try: + for n in nodes: + if n not in previous_selection: + continue + n['selected'].setValue(True) + except ValueError as e: + log.warning(e) + + +def reset_selection(): + """Deselect all selected nodes + """ + pass diff --git a/pype/hosts/resolve/plugin.py b/pype/hosts/resolve/plugin.py index 628d4bdb26..513b9984f4 100644 --- a/pype/hosts/resolve/plugin.py +++ b/pype/hosts/resolve/plugin.py @@ -1,6 +1,7 @@ from avalon import api -# from pype.hosts.resolve import lib as drlib +from pype.hosts import resolve from avalon.vendor import qargparse +from pype.api import config def get_reference_node_parents(ref): @@ -73,3 +74,21 @@ class SequenceLoader(api.Loader): """Remove an existing `container` """ pass + + +class Creator(api.Creator): + """Creator class wrapper + """ + marker_color = "Purple" + + def __init__(self, *args, **kwargs): + super(Creator, self).__init__(*args, **kwargs) + self.presets = config.get_presets()['plugins']["resolve"][ + "create"].get(self.__class__.__name__, {}) + + # adding basic current context resolve objects + self.project = resolve.get_current_project() + self.sequence = resolve.get_current_sequence() + + # TODO: make sure no duplicity of subsets are in workfile + return diff --git a/pype/hosts/resolve/utility_scripts/test.py b/pype/hosts/resolve/utility_scripts/test.py new file mode 100644 index 0000000000..4c43507e62 --- /dev/null +++ b/pype/hosts/resolve/utility_scripts/test.py @@ -0,0 +1,19 @@ +#! python3 +import sys +from pype.api import Logger + +log = Logger().get_logger(__name__) + + +def main(): + import pype.hosts.resolve as bmdvr + bm = bmdvr.utils.get_resolve_module() + log.info(f"blackmagicmodule: {bm}") + +import DaVinciResolveScript as bmd +print(f"_>> bmd.scriptapp(Resolve): {bmd.scriptapp('Resolve')}") + + +if __name__ == "__main__": + result = main() + sys.exit(not bool(result)) diff --git a/pype/hosts/resolve/utils.py b/pype/hosts/resolve/utils.py index f5add53a6b..74ce2dc98f 100644 --- a/pype/hosts/resolve/utils.py +++ b/pype/hosts/resolve/utils.py @@ -9,18 +9,16 @@ import os import shutil from pypeapp import Logger - log = Logger().get_logger(__name__, "resolve") -self = sys.modules[__name__] -self.bmd = None - def get_resolve_module(): + from pype.hosts import resolve # dont run if already loaded - if self.bmd: - return self.bmd - + if resolve.bmd: + log.info(("resolve module is assigned to " + f"`pype.hosts.resolve.bmd`: {resolve.bmd}")) + return resolve.bmd try: """ The PYTHONPATH needs to be set correctly for this import @@ -71,8 +69,10 @@ def get_resolve_module(): ) sys.exit() # assign global var and return - self.bmd = bmd.scriptapp("Resolve") - return self.bmd + bmd = bmd.scriptapp("Resolve") + resolve.bmd = bmd + log.info(("Assigning resolve module to " + f"`pype.hosts.resolve.bmd`: {resolve.bmd}")) def _sync_utility_scripts(env=None): diff --git a/pype/hosts/resolve/workio.py b/pype/hosts/resolve/workio.py index e1e30a8734..9d8d320a3c 100644 --- a/pype/hosts/resolve/workio.py +++ b/pype/hosts/resolve/workio.py @@ -2,8 +2,9 @@ import os from pypeapp import Logger -from .lib import ( +from . import ( get_project_manager, + get_current_project, set_project_manager_to_folder_name ) @@ -26,7 +27,7 @@ def save_file(filepath): pm = get_project_manager() file = os.path.basename(filepath) fname, _ = os.path.splitext(file) - project = pm.GetCurrentProject() + project = get_current_project() name = project.GetName() if "Untitled Project" not in name: diff --git a/pype/plugins/resolve/create/create_shot_clip.py b/pype/plugins/resolve/create/create_shot_clip.py index 97d5663922..43a8ab0cbd 100644 --- a/pype/plugins/resolve/create/create_shot_clip.py +++ b/pype/plugins/resolve/create/create_shot_clip.py @@ -1,8 +1,7 @@ -import avalon.api from pype.hosts import resolve -class CreateShotClip(avalon.api.Creator): +class CreateShotClip(resolve.Creator): """Publishable clip""" label = "Shot" @@ -10,6 +9,9 @@ class CreateShotClip(avalon.api.Creator): icon = "film" defaults = ["Main"] + presets = None + def process(self): - project = resolve.get_current_project() - self.log.info(f"Project name: {project.GetName()}") + print(f"Project name: {self.project.GetName()}") + print(f"Sequence name: {self.sequence.GetName()}") + print(self.presets)