diff --git a/openpype/hosts/nuke/api/lib.py b/openpype/hosts/nuke/api/lib.py index c08db978d3..a5a631cc70 100644 --- a/openpype/hosts/nuke/api/lib.py +++ b/openpype/hosts/nuke/api/lib.py @@ -48,7 +48,6 @@ from openpype.pipeline.colorspace import ( get_imageio_config ) from openpype.pipeline.workfile import BuildWorkfile - from . import gizmo_menu from .constants import ASSIST @@ -2678,6 +2677,18 @@ def process_workfile_builder(): open_file(last_workfile_path) +def start_workfile_template_builder(): + from .workfile_template_builder import ( + build_workfile_template + ) + + # to avoid looping of the callback, remove it! + log.info("Starting workfile template builder...") + build_workfile_template(workfile_creation_enabled=True) + + # remove callback since it would be duplicating the workfile + nuke.removeOnCreate(start_workfile_template_builder, nodeClass="Root") + @deprecated def recreate_instance(origin_node, avalon_data=None): """Recreate input instance to different data diff --git a/openpype/hosts/nuke/api/pipeline.py b/openpype/hosts/nuke/api/pipeline.py index 2496d66c1d..d649ffae7f 100644 --- a/openpype/hosts/nuke/api/pipeline.py +++ b/openpype/hosts/nuke/api/pipeline.py @@ -33,6 +33,7 @@ from .lib import ( add_publish_knob, WorkfileSettings, process_workfile_builder, + start_workfile_template_builder, launch_workfiles_app, check_inventory_versions, set_avalon_knob_data, @@ -48,7 +49,6 @@ from .workfile_template_builder import ( NukePlaceholderLoadPlugin, NukePlaceholderCreatePlugin, build_workfile_template, - update_workfile_template, create_placeholder, update_placeholder, ) @@ -156,6 +156,7 @@ def add_nuke_callbacks(): nuke.addOnCreate( workfile_settings.set_context_settings, nodeClass="Root") nuke.addOnCreate(workfile_settings.set_favorites, nodeClass="Root") + nuke.addOnCreate(start_workfile_template_builder, nodeClass="Root") nuke.addOnCreate(process_workfile_builder, nodeClass="Root") # fix ffmpeg settings on script diff --git a/openpype/hosts/nuke/api/workfile_template_builder.py b/openpype/hosts/nuke/api/workfile_template_builder.py index 1b81f24e86..fb0afb3d55 100644 --- a/openpype/hosts/nuke/api/workfile_template_builder.py +++ b/openpype/hosts/nuke/api/workfile_template_builder.py @@ -1,7 +1,5 @@ import collections - import nuke - from openpype.pipeline import registered_host from openpype.pipeline.workfile.workfile_template_builder import ( AbstractTemplateBuilder, @@ -14,7 +12,6 @@ from openpype.pipeline.workfile.workfile_template_builder import ( from openpype.tools.workfile_template_build import ( WorkfileBuildPlaceholderDialog, ) - from .lib import ( find_free_space_to_paste_nodes, get_extreme_positions, @@ -45,7 +42,7 @@ class NukeTemplateBuilder(AbstractTemplateBuilder): get_template_preset implementation) Returns: - bool: Wether the template was succesfully imported or not + bool: Wether the template was successfully imported or not """ # TODO check if the template is already imported @@ -55,7 +52,6 @@ class NukeTemplateBuilder(AbstractTemplateBuilder): return True - class NukePlaceholderPlugin(PlaceholderPlugin): node_color = 4278190335 @@ -947,9 +943,9 @@ class NukePlaceholderCreatePlugin( siblings_input.setInput(0, copy_output) -def build_workfile_template(*args): +def build_workfile_template(*args, **kwargs): builder = NukeTemplateBuilder(registered_host()) - builder.build_template() + builder.build_template(*args, **kwargs) def update_workfile_template(*args): diff --git a/openpype/hosts/nuke/api/workio.py b/openpype/hosts/nuke/api/workio.py index 65b86bf01b..5692f8e63c 100644 --- a/openpype/hosts/nuke/api/workio.py +++ b/openpype/hosts/nuke/api/workio.py @@ -13,7 +13,7 @@ def has_unsaved_changes(): def save_file(filepath): path = filepath.replace("\\", "/") - nuke.scriptSaveAs(path) + nuke.scriptSaveAs(path, overwrite=1) nuke.Root()["name"].setValue(path) nuke.Root()["project_directory"].setValue(os.path.dirname(path)) nuke.Root().setModified(False) diff --git a/openpype/pipeline/workfile/workfile_template_builder.py b/openpype/pipeline/workfile/workfile_template_builder.py index 27214af79f..0ce59de8ad 100644 --- a/openpype/pipeline/workfile/workfile_template_builder.py +++ b/openpype/pipeline/workfile/workfile_template_builder.py @@ -28,6 +28,7 @@ from openpype.settings import ( get_project_settings, get_system_settings, ) +from openpype.host import IWorkfileHost from openpype.host import HostBase from openpype.lib import ( Logger, @@ -440,7 +441,9 @@ class AbstractTemplateBuilder(object): self, template_path=None, level_limit=None, - keep_placeholders=None + keep_placeholders=None, + create_first_version=None, + workfile_creation_enabled=False ): """Main callback for building workfile from template path. @@ -457,6 +460,11 @@ class AbstractTemplateBuilder(object): keep_placeholders (bool): Add flag to placeholder data for hosts to decide if they want to remove placeholder after it is used. + create_first_version (bool): create first version of a workfile + workfile_creation_enabled (bool): If True, it might create + first version but ignore + process if version is created + """ template_preset = self.get_template_preset() @@ -465,6 +473,30 @@ class AbstractTemplateBuilder(object): if keep_placeholders is None: keep_placeholders = template_preset["keep_placeholder"] + if create_first_version is None: + create_first_version = template_preset["create_first_version"] + + # check if first version is created + created_version_workfile = self.create_first_workfile_version() + + # if first version is created, import template + # and populate placeholders + if ( + create_first_version + and workfile_creation_enabled + and created_version_workfile + ): + self.import_template(template_path) + self.populate_scene_placeholders( + level_limit, keep_placeholders) + + # save workfile after template is populated + self.save_workfile(created_version_workfile) + + # ignore process if first workfile is enabled + # but a version is already created + if workfile_creation_enabled: + return self.import_template(template_path) self.populate_scene_placeholders( @@ -516,6 +548,39 @@ class AbstractTemplateBuilder(object): pass + def create_first_workfile_version(self): + """ + Create first version of workfile. + + Should load the content of template into scene so + 'populate_scene_placeholders' can be started. + + Args: + template_path (str): Fullpath for current task and + host's template file. + """ + last_workfile_path = os.environ.get("AVALON_LAST_WORKFILE") + self.log.info("__ last_workfile_path: {}".format(last_workfile_path)) + if os.path.exists(last_workfile_path): + # ignore in case workfile existence + self.log.info("Workfile already exists, skipping creation.") + return False + + # Create first version + self.log.info("Creating first version of workfile.") + self.save_workfile(last_workfile_path) + + # Confirm creation of first version + return last_workfile_path + + def save_workfile(self, workfile_path): + """Save workfile in current host.""" + # Save current scene, continue to open file + if isinstance(self.host, IWorkfileHost): + self.host.save_workfile(workfile_path) + else: + self.host.save_file(workfile_path) + def _prepare_placeholders(self, placeholders): """Run preparation part for placeholders on plugins. @@ -699,6 +764,8 @@ class AbstractTemplateBuilder(object): # switch to remove placeholders after they are used keep_placeholder = profile.get("keep_placeholder") + create_first_version = profile.get("create_first_version") + # backward compatibility, since default is True if keep_placeholder is None: keep_placeholder = True @@ -732,7 +799,8 @@ class AbstractTemplateBuilder(object): self.log.info("Found template at: '{}'".format(path)) return { "path": path, - "keep_placeholder": keep_placeholder + "keep_placeholder": keep_placeholder, + "create_first_version": create_first_version } solved_path = None @@ -761,7 +829,8 @@ class AbstractTemplateBuilder(object): return { "path": solved_path, - "keep_placeholder": keep_placeholder + "keep_placeholder": keep_placeholder, + "create_first_version": create_first_version } diff --git a/openpype/settings/defaults/project_settings/nuke.json b/openpype/settings/defaults/project_settings/nuke.json index 2545411e0a..c249955dc8 100644 --- a/openpype/settings/defaults/project_settings/nuke.json +++ b/openpype/settings/defaults/project_settings/nuke.json @@ -565,7 +565,17 @@ ] }, "templated_workfile_build": { - "profiles": [] + "profiles": [ + { + "task_types": [ + "Compositing" + ], + "task_names": [], + "path": "{project[name]}/templates/comp.nk", + "keep_placeholder": true, + "create_first_version": true + } + ] }, "filters": {} } diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_templated_workfile_build.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_templated_workfile_build.json index b244460bbf..7bab28fd88 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_templated_workfile_build.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_templated_workfile_build.json @@ -34,6 +34,12 @@ "label": "Keep placeholders", "type": "boolean", "default": true + }, + { + "key": "create_first_version", + "label": "Create first version", + "type": "boolean", + "default": true } ] }