diff --git a/openpype/plugins/publish/integrate_new.py b/openpype/plugins/publish/integrate_new.py index 19b12e953d0..9769f0d165c 100644 --- a/openpype/plugins/publish/integrate_new.py +++ b/openpype/plugins/publish/integrate_new.py @@ -297,7 +297,14 @@ def register(self, instance): else: orig_transfers = list(instance.data['transfers']) - template_name = self.template_name_from_instance(instance) + task_name = io.Session.get("AVALON_TASK") + family = self.main_family_from_instance(instance) + + key_values = {"families": family, "tasks": task_name} + profile = filter_profiles(self.template_name_profiles, key_values, + logger=self.log) + if profile: + template_name = profile["template_name"] published_representations = {} for idx, repre in enumerate(instance.data["representations"]): @@ -853,68 +860,6 @@ def main_family_from_instance(self, instance): family = instance.data["families"][0] return family - def template_name_from_instance(self, instance): - template_name = self.default_template_name - if not self.template_name_profiles: - self.log.debug(( - "Template name profiles are not set." - " Using default \"{}\"" - ).format(template_name)) - return template_name - - # Task name from session? - task_name = io.Session.get("AVALON_TASK") - family = self.main_family_from_instance(instance) - - matching_profiles = {} - highest_value = -1 - self.log.debug( - "Template name profiles:\n{}".format(self.template_name_profiles) - ) - for name, filters in self.template_name_profiles.items(): - value = 0 - families = filters.get("families") - if families: - if family not in families: - continue - value += 1 - - tasks = filters.get("tasks") - if tasks: - if task_name not in tasks: - continue - value += 1 - - if value > highest_value: - matching_profiles = {} - highest_value = value - - if value == highest_value: - matching_profiles[name] = filters - - if len(matching_profiles) == 1: - template_name = tuple(matching_profiles.keys())[0] - self.log.debug( - "Using template name \"{}\".".format(template_name) - ) - - elif len(matching_profiles) > 1: - template_name = tuple(matching_profiles.keys())[0] - self.log.warning(( - "More than one template profiles matched" - " Family \"{}\" and Task: \"{}\"." - " Using first template name in row \"{}\"." - ).format(family, task_name, template_name)) - - else: - self.log.debug(( - "None of template profiles matched" - " Family \"{}\" and Task: \"{}\"." - " Using default template name \"{}\"" - ).format(family, task_name, template_name)) - - return template_name - def get_rootless_path(self, anatomy, path): """ Returns, if possible, path without absolute portion from host (eg. 'c:\' or '/opt/..') diff --git a/openpype/settings/defaults/project_anatomy/templates.json b/openpype/settings/defaults/project_anatomy/templates.json index 2b16f59d017..63477b9d827 100644 --- a/openpype/settings/defaults/project_anatomy/templates.json +++ b/openpype/settings/defaults/project_anatomy/templates.json @@ -11,7 +11,7 @@ "path": "{@folder}/{@file}" }, "render": { - "folder": "{root[work]}/{project[name]}/{hierarchy}/{asset}/publish/render/{subset}/{@version}", + "folder": "{root[work]}/{project[name]}/{hierarchy}/{asset}/publish/{family}/{subset}/{@version}", "file": "{project[code]}_{asset}_{subset}_{@version}<_{output}><.{@frame}>.{ext}", "path": "{@folder}/{@file}" }, diff --git a/openpype/settings/defaults/project_settings/global.json b/openpype/settings/defaults/project_settings/global.json index c9b61e03751..843389c89ab 100644 --- a/openpype/settings/defaults/project_settings/global.json +++ b/openpype/settings/defaults/project_settings/global.json @@ -116,19 +116,22 @@ ] }, "IntegrateAssetNew": { - "template_name_profiles": { - "publish": { + "template_name_profiles": [ + { "families": [], - "tasks": [] + "tasks": [], + "template_name": "publish" }, - "render": { + { "families": [ "review", "render", "prerender" - ] + ], + "tasks": [], + "template_name": "render" } - }, + ], "subset_grouping_profiles": [ { "families": [], diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json index 8b0828be23b..534638ecc31 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json @@ -420,9 +420,39 @@ "is_group": true, "children": [ { - "type": "raw-json", + "type": "list", "key": "template_name_profiles", - "label": "template_name_profiles" + "label": "Template name profiles", + "use_label_wrap": true, + "object_type": { + "type": "dict", + "children": [ + { + "type": "label", + "label": "" + }, + { + "key": "families", + "label": "Families", + "type": "list", + "object_type": "text" + }, + { + "key": "tasks", + "label": "Task names", + "type": "list", + "object_type": "text" + }, + { + "type": "separator" + }, + { + "type": "text", + "key": "template_name", + "label": "Template name" + } + ] + } }, { "type": "list", diff --git a/website/docs/project_settings/assets/global_integrate_new_subset_group.png b/website/docs/project_settings/assets/global_integrate_new_subset_group.png new file mode 100644 index 00000000000..92638984cc7 Binary files /dev/null and b/website/docs/project_settings/assets/global_integrate_new_subset_group.png differ diff --git a/website/docs/project_settings/assets/global_integrate_new_template_name_profile.png b/website/docs/project_settings/assets/global_integrate_new_template_name_profile.png new file mode 100644 index 00000000000..8529761a507 Binary files /dev/null and b/website/docs/project_settings/assets/global_integrate_new_template_name_profile.png differ diff --git a/website/docs/project_settings/settings_project_global.md b/website/docs/project_settings/settings_project_global.md index a90e5caeef1..4fee57d5758 100644 --- a/website/docs/project_settings/settings_project_global.md +++ b/website/docs/project_settings/settings_project_global.md @@ -13,32 +13,45 @@ Project settings can have project specific values. Each new project is using stu Projects always use default project values unless they have [project override](../admin_settings#project-overrides) (orage colour). Any changes in default project may affect all existing projects. ::: -## Publish plugins - -Publish plugins used across all integrations. +## Profile filters -### Extract Review -Plugin responsible for automatic FFmpeg conversion to variety of formats. +Many of the settings are using a concept of **Profile filters** -Extract review is using profile filtering to be able render different outputs for different situations. +You can define multiple profiles to choose from for different contexts. Each filter is evaluated and a +profile with filters matching the current context the most, is used. -**Profile filters** +You can define profile without any filters and use it as **default**. -You can define multiple profiles for different contexts. Profile with filters matching the current context the most, is used. You can define profile without filters and use it as **default**. Only **one or none** profile will be processed per instance. +Only **one or none** profile will be returned per context. All context filters are lists which may contain strings or Regular expressions (RegEx). - **`hosts`** - Host from which publishing was triggered. `["maya", "nuke"]` -- **`families`** - Main family of processed instance. `["plate", "model"]` +- **`families`** - Main family of processed subset. `["plate", "model"]` +- **`tasks`** - Currently processed task. `["modeling", "animation"]` :::important Filtering Filters are optional. In case when multiple profiles match current context, profile with higher number of matched filters has higher priority that profile without filters. +(Eg. order of when filter is added doesn't matter, only the precision of matching does.) ::: +## Publish plugins + +Publish plugins used across all integrations. + + +### Extract Review +Plugin responsible for automatic FFmpeg conversion to variety of formats. + +Extract review is using [profile filtering](#profile-filters) to be able render different outputs for different situations. + +Applicable context filters: + **`hosts`** - Host from which publishing was triggered. `["maya", "nuke"]` +- **`families`** - Main family of processed subset. `["plate", "model"]` + ![global_extract_review_profiles](assets/global_extract_review_profiles.png) **Output Definitions** - Profile may generate multiple outputs from a single input. Each output must define unique name and output extension (use the extension without a dot e.g. **mp4**). All other settings of output definition are optional. ![global_extract_review_output_defs](assets/global_extract_review_output_defs.png) @@ -67,3 +80,36 @@ Profile may generate multiple outputs from a single input. Each output must defi ![global_extract_review_letter_box_settings](assets/global_extract_review_letter_box_settings.png) ![global_extract_review_letter_box](assets/global_extract_review_letter_box.png) + +### IntegrateAssetNew + +Saves information for all published subsets into DB, published assets are available for other hosts, tools and tasks after. +#### Template name profiles + +Allows to select [anatomy template](admin_settings_project_anatomy.md#templates) based on context of subset being published. + +For example for `render` profile you might want to publish and store assets in different location (based on anatomy setting) then for `publish` profile. +[Profile filtering](#profile-filters) is used to select between appropriate template for each context of published subsets. + +Applicable context filters: +- **`hosts`** - Host from which publishing was triggered. `["maya", "nuke"]` +- **`tasks`** - Current task. `["modeling", "animation"]` + + ![global_integrate_new_template_name_profile](assets/global_integrate_new_template_name_profile.png) + +(This image shows use case where `render` anatomy template is used for subsets of families ['review, 'render', 'prerender'], `publish` template is chosen for all other.) + +#### Subset grouping profiles + +Published subsets might be grouped together for cleaner and easier selection in **[Loader](artist_tools.md#subset-groups)** + +Group name is chosen with use of [profile filtering](#profile-filters) + +Applicable context filters: +- **`families`** - Main family of processed subset. `["plate", "model"]` +- **`hosts`** - Host from which publishing was triggered. `["maya", "nuke"]` +- **`tasks`** - Current task. `["modeling", "animation"]` + + ![global_integrate_new_template_name_profile](assets/global_integrate_new_subset_group.png) + +(This image shows use case where only assets published from 'photoshop', for all families for all tasks should be marked as grouped with a capitalized name of Task where they are published from.) \ No newline at end of file