From 4c1e34a2db56a3b7d5aefa76f8d6866c52983101 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 11 Jan 2023 21:33:12 +0100 Subject: [PATCH 1/6] nuke: existing subset check on nodes in workfile and not in db. Also fixing typo in error message. --- openpype/hosts/nuke/api/plugin.py | 14 ++++++-------- .../hosts/nuke/plugins/create/create_backdrop.py | 7 +++++-- .../hosts/nuke/plugins/create/create_camera.py | 7 +++++-- openpype/hosts/nuke/plugins/create/create_gizmo.py | 7 +++++-- openpype/hosts/nuke/plugins/create/create_model.py | 7 +++++-- .../hosts/nuke/plugins/create/create_source.py | 7 +++++-- .../nuke/plugins/create/create_write_image.py | 7 +++++-- .../nuke/plugins/create/create_write_prerender.py | 7 +++++-- .../nuke/plugins/create/create_write_render.py | 7 +++++-- .../plugins/publish/validate_output_resolution.py | 2 +- 10 files changed, 47 insertions(+), 25 deletions(-) diff --git a/openpype/hosts/nuke/api/plugin.py b/openpype/hosts/nuke/api/plugin.py index abf9144c5b..a2b5c2e4b0 100644 --- a/openpype/hosts/nuke/api/plugin.py +++ b/openpype/hosts/nuke/api/plugin.py @@ -8,11 +8,6 @@ import string from collections import OrderedDict, defaultdict from abc import abstractmethod -from openpype.client import ( - get_asset_by_name, - get_subsets, -) - from openpype.settings import get_current_project_settings from openpype.lib import ( BoolDef, @@ -98,10 +93,13 @@ class NukeCreator(NewCreator): """Check if existing subset name already exists.""" exists = False for node in nuke.allNodes(recurseGroups=True): + # make sure testing node is having instance knob + if INSTANCE_DATA_KNOB not in node.knobs().keys(): + continue node_data = get_node_data(node, INSTANCE_DATA_KNOB) + # test if subset name is matching if subset_name in node_data.get("subset"): exists = True - return exists def create_instance_node( @@ -316,8 +314,8 @@ class NukeWriteCreator(NukeCreator): # make sure subset name is unique if self.check_existing_subset(subset_name, instance_data): raise NukeCreatorError( - ("subset {} is already published" - "definition.").format(subset_name)) + ("Subset '{}' is already created " + "in nodes! Change variant name!").format(subset_name)) instance_node = self.create_instance_node( subset_name, diff --git a/openpype/hosts/nuke/plugins/create/create_backdrop.py b/openpype/hosts/nuke/plugins/create/create_backdrop.py index ebc66e95a7..db65b29998 100644 --- a/openpype/hosts/nuke/plugins/create/create_backdrop.py +++ b/openpype/hosts/nuke/plugins/create/create_backdrop.py @@ -45,8 +45,11 @@ class CreateBackdrop(NukeCreator): def create(self, subset_name, instance_data, pre_create_data): if self.check_existing_subset(subset_name, instance_data): raise NukeCreatorError( - ("Subset name '{}' is already used. " - "Please specify different Variant.").format(subset_name)) + ( + "Subset '{}' is already created " + "in nodes! Change variant name!" + ).format(subset_name) + ) instance = super(CreateBackdrop, self).create( subset_name, diff --git a/openpype/hosts/nuke/plugins/create/create_camera.py b/openpype/hosts/nuke/plugins/create/create_camera.py index dc4a30f513..87d215d21b 100644 --- a/openpype/hosts/nuke/plugins/create/create_camera.py +++ b/openpype/hosts/nuke/plugins/create/create_camera.py @@ -46,8 +46,11 @@ class CreateCamera(NukeCreator): def create(self, subset_name, instance_data, pre_create_data): if self.check_existing_subset(subset_name, instance_data): raise NukeCreatorError( - ("Subset name '{}' is already used. " - "Please specify different Variant.").format(subset_name)) + ( + "Subset '{}' is already created " + "in nodes! Change variant name!" + ).format(subset_name) + ) instance = super(CreateCamera, self).create( subset_name, diff --git a/openpype/hosts/nuke/plugins/create/create_gizmo.py b/openpype/hosts/nuke/plugins/create/create_gizmo.py index 1869874e22..221cad8fb5 100644 --- a/openpype/hosts/nuke/plugins/create/create_gizmo.py +++ b/openpype/hosts/nuke/plugins/create/create_gizmo.py @@ -47,8 +47,11 @@ class CreateGizmo(NukeCreator): def create(self, subset_name, instance_data, pre_create_data): if self.check_existing_subset(subset_name, instance_data): raise NukeCreatorError( - ("Subset name '{}' is already used. " - "Please specify different Variant.").format(subset_name)) + ( + "Subset '{}' is already created " + "in nodes! Change variant name!" + ).format(subset_name) + ) instance = super(CreateGizmo, self).create( subset_name, diff --git a/openpype/hosts/nuke/plugins/create/create_model.py b/openpype/hosts/nuke/plugins/create/create_model.py index 53b3a58288..ea27714095 100644 --- a/openpype/hosts/nuke/plugins/create/create_model.py +++ b/openpype/hosts/nuke/plugins/create/create_model.py @@ -47,8 +47,11 @@ class CreateModel(NukeCreator): def create(self, subset_name, instance_data, pre_create_data): if self.check_existing_subset(subset_name, instance_data): raise NukeCreatorError( - ("Subset name '{}' is already used. " - "Please specify different Variant.").format(subset_name)) + ( + "Subset '{}' is already created " + "in nodes! Change variant name!" + ).format(subset_name) + ) instance = super(CreateModel, self).create( subset_name, diff --git a/openpype/hosts/nuke/plugins/create/create_source.py b/openpype/hosts/nuke/plugins/create/create_source.py index 35fe42c16b..b33d078bfe 100644 --- a/openpype/hosts/nuke/plugins/create/create_source.py +++ b/openpype/hosts/nuke/plugins/create/create_source.py @@ -51,8 +51,11 @@ class CreateSource(NukeCreator): # make sure subset name is unique if self.check_existing_subset(_subset_name, instance_data): raise NukeCreatorError( - ("subset {} is already published" - "definition.").format(_subset_name)) + ( + "Subset '{}' is already created " + "in nodes! Change variant name!" + ).format(subset_name) + ) instance_node = self.create_instance_node( _subset_name, diff --git a/openpype/hosts/nuke/plugins/create/create_write_image.py b/openpype/hosts/nuke/plugins/create/create_write_image.py index cf70063abc..db8f2c54db 100644 --- a/openpype/hosts/nuke/plugins/create/create_write_image.py +++ b/openpype/hosts/nuke/plugins/create/create_write_image.py @@ -120,8 +120,11 @@ class CreateWriteImage(napi.NukeWriteCreator): # make sure subset name is unique if self.check_existing_subset(subset_name, instance_data): raise napi.NukeCreatorError( - ("subset {} is already published" - "definition.").format(subset_name)) + ( + "Subset '{}' is already created " + "in nodes! Change variant name!" + ).format(subset_name) + ) instance_node = self.create_instance_node( subset_name, diff --git a/openpype/hosts/nuke/plugins/create/create_write_prerender.py b/openpype/hosts/nuke/plugins/create/create_write_prerender.py index daa2319c4b..25250c712c 100644 --- a/openpype/hosts/nuke/plugins/create/create_write_prerender.py +++ b/openpype/hosts/nuke/plugins/create/create_write_prerender.py @@ -135,8 +135,11 @@ class CreateWritePrerender(napi.NukeWriteCreator): # make sure subset name is unique if self.check_existing_subset(subset_name, instance_data): raise napi.NukeCreatorError( - ("subset {} is already published" - "definition.").format(subset_name)) + ( + "Subset '{}' is already created " + "in nodes! Change variant name!" + ).format(subset_name) + ) instance_node = self.create_instance_node( subset_name, diff --git a/openpype/hosts/nuke/plugins/create/create_write_render.py b/openpype/hosts/nuke/plugins/create/create_write_render.py index 85133458d1..f6bfd93a89 100644 --- a/openpype/hosts/nuke/plugins/create/create_write_render.py +++ b/openpype/hosts/nuke/plugins/create/create_write_render.py @@ -124,8 +124,11 @@ class CreateWriteRender(napi.NukeWriteCreator): # make sure subset name is unique if self.check_existing_subset(subset_name, instance_data): raise napi.NukeCreatorError( - ("subset {} is already published" - "definition.").format(subset_name)) + ( + "Subset '{}' is already created " + "in nodes! Change variant name!" + ).format(subset_name) + ) instance_node = self.create_instance_node( subset_name, diff --git a/openpype/hosts/nuke/plugins/publish/validate_output_resolution.py b/openpype/hosts/nuke/plugins/publish/validate_output_resolution.py index 70451ebc95..dbcd216a84 100644 --- a/openpype/hosts/nuke/plugins/publish/validate_output_resolution.py +++ b/openpype/hosts/nuke/plugins/publish/validate_output_resolution.py @@ -23,7 +23,7 @@ class ValidateOutputResolution( order = pyblish.api.ValidatorOrder optional = True families = ["render"] - label = "Write Resolution" + label = "Write resolution" hosts = ["nuke"] actions = [RepairAction] From 4bcd90b4152cc336067e74886602b8f3ddb6e9f4 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 16 Jan 2023 14:12:30 +0100 Subject: [PATCH 2/6] nuke: fixes of publishing workflow for nuke 12 --- openpype/hosts/nuke/api/lib.py | 4 +++- openpype/hosts/nuke/plugins/publish/extract_render_local.py | 6 ++---- openpype/plugins/publish/collect_from_create_context.py | 1 - 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/nuke/api/lib.py b/openpype/hosts/nuke/api/lib.py index f2872675ca..c3059aa048 100644 --- a/openpype/hosts/nuke/api/lib.py +++ b/openpype/hosts/nuke/api/lib.py @@ -896,7 +896,9 @@ def get_view_process_node(): ipn_orig = None for v in nuke.allNodes(filter="Viewer"): ipn = v['input_process_node'].getValue() - if "VIEWER_INPUT" not in ipn: + if ipn: + if "VIEWER_INPUT" not in ipn: + return ipn_orig = nuke.toNode(ipn) ipn_orig.setSelected(True) diff --git a/openpype/hosts/nuke/plugins/publish/extract_render_local.py b/openpype/hosts/nuke/plugins/publish/extract_render_local.py index 811b2d4ffb..81fe8cd528 100644 --- a/openpype/hosts/nuke/plugins/publish/extract_render_local.py +++ b/openpype/hosts/nuke/plugins/publish/extract_render_local.py @@ -33,12 +33,10 @@ class NukeRenderLocal(publish.Extractor): if x.Class() == "Write": node = x - self.log.debug("instance collected: {}".format(instance.data)) - first_frame = instance.data.get("frameStartHandle", None) last_frame = instance.data.get("frameEndHandle", None) - node_subset_name = instance.data.get("name", None) + node_subset_name = instance.data["subset"] self.log.info("Starting render") self.log.info("Start frame: {}".format(first_frame)) @@ -65,7 +63,7 @@ class NukeRenderLocal(publish.Extractor): # Render frames nuke.execute( - node_subset_name, + str(node_subset_name), int(first_frame), int(last_frame) ) diff --git a/openpype/plugins/publish/collect_from_create_context.py b/openpype/plugins/publish/collect_from_create_context.py index 9a740c10cd..d3398c885e 100644 --- a/openpype/plugins/publish/collect_from_create_context.py +++ b/openpype/plugins/publish/collect_from_create_context.py @@ -37,7 +37,6 @@ class CollectFromCreateContext(pyblish.api.ContextPlugin): context.data["projectName"] = project_name for created_instance in create_context.instances: - self.log.info(f"created_instance:: {created_instance}") instance_data = created_instance.data_to_store() if instance_data["active"]: thumbnail_path = thumbnail_paths_by_instance_id.get( From 66cde9f6c7b87ae824128af4e34a6f36fa40a509 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 16 Jan 2023 14:59:02 +0100 Subject: [PATCH 3/6] nuke: reverse logic --- openpype/hosts/nuke/api/lib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/nuke/api/lib.py b/openpype/hosts/nuke/api/lib.py index c3059aa048..67c5a3e34c 100644 --- a/openpype/hosts/nuke/api/lib.py +++ b/openpype/hosts/nuke/api/lib.py @@ -897,7 +897,7 @@ def get_view_process_node(): for v in nuke.allNodes(filter="Viewer"): ipn = v['input_process_node'].getValue() if ipn: - if "VIEWER_INPUT" not in ipn: + if "VIEWER_INPUT" in ipn: return ipn_orig = nuke.toNode(ipn) ipn_orig.setSelected(True) From efcb280b7559712b4f05abc6acecb3b71c01153d Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 17 Jan 2023 11:12:14 +0100 Subject: [PATCH 4/6] nuke: improving get view process node --- openpype/hosts/nuke/api/lib.py | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/openpype/hosts/nuke/api/lib.py b/openpype/hosts/nuke/api/lib.py index 67c5a3e34c..b1d76e7d51 100644 --- a/openpype/hosts/nuke/api/lib.py +++ b/openpype/hosts/nuke/api/lib.py @@ -893,17 +893,27 @@ def get_imageio_input_colorspace(filename): def get_view_process_node(): reset_selection() - ipn_orig = None - for v in nuke.allNodes(filter="Viewer"): - ipn = v['input_process_node'].getValue() - if ipn: - if "VIEWER_INPUT" in ipn: - return - ipn_orig = nuke.toNode(ipn) - ipn_orig.setSelected(True) + ipn_node = None + for v_ in nuke.allNodes(filter="Viewer"): + ipn = v_['input_process_node'].getValue() + ipn_node = nuke.toNode(ipn) + if ipn_node: + if ipn == "VIEWER_INPUT": + # since it is set by default we can ignore it + # nobody usually use this + continue + else: + # in case a Viewer node is transfered from + # different workfile with old values + raise NameError(( + "Input process node name '{}' set in " + "Viewer '{}' is does't exists in nodes" + ).format(ipn, v_.name())) - if ipn_orig: - return duplicate_node(ipn_orig) + ipn_node.setSelected(True) + + if ipn_node: + return duplicate_node(ipn_node) def on_script_load(): From 371a841258648741ba792ff9fc280d742d147762 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 17 Jan 2023 11:41:18 +0100 Subject: [PATCH 5/6] nuke: improving condition on subset name check --- openpype/hosts/nuke/api/plugin.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/nuke/api/plugin.py b/openpype/hosts/nuke/api/plugin.py index a2b5c2e4b0..a1cf5ac328 100644 --- a/openpype/hosts/nuke/api/plugin.py +++ b/openpype/hosts/nuke/api/plugin.py @@ -97,9 +97,15 @@ class NukeCreator(NewCreator): if INSTANCE_DATA_KNOB not in node.knobs().keys(): continue node_data = get_node_data(node, INSTANCE_DATA_KNOB) + + if not node_data: + # a node has no instance data + continue + # test if subset name is matching - if subset_name in node_data.get("subset"): + if node_data.get("subset") == subset_name: exists = True + return exists def create_instance_node( From 239c5eae757abe62673cf0a89dc20830991563d9 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 17 Jan 2023 12:07:27 +0100 Subject: [PATCH 6/6] nuke: reworking subset name check --- openpype/hosts/nuke/api/plugin.py | 34 +++++++++++-------- .../nuke/plugins/create/create_backdrop.py | 9 ++--- .../nuke/plugins/create/create_camera.py | 9 ++--- .../hosts/nuke/plugins/create/create_gizmo.py | 9 ++--- .../hosts/nuke/plugins/create/create_model.py | 9 ++--- .../nuke/plugins/create/create_source.py | 8 +---- .../nuke/plugins/create/create_write_image.py | 8 +---- .../plugins/create/create_write_prerender.py | 8 +---- .../plugins/create/create_write_render.py | 8 +---- 9 files changed, 32 insertions(+), 70 deletions(-) diff --git a/openpype/hosts/nuke/api/plugin.py b/openpype/hosts/nuke/api/plugin.py index a1cf5ac328..d3f8357f7d 100644 --- a/openpype/hosts/nuke/api/plugin.py +++ b/openpype/hosts/nuke/api/plugin.py @@ -89,9 +89,17 @@ class NukeCreator(NewCreator): """) node.addKnob(info_knob) - def check_existing_subset(self, subset_name, instance_data): - """Check if existing subset name already exists.""" - exists = False + def check_existing_subset(self, subset_name): + """Make sure subset name is unique. + + It search within all nodes recursively + and checks if subset name is found in + any node having instance data knob. + + Arguments: + subset_name (str): Subset name + """ + for node in nuke.allNodes(recurseGroups=True): # make sure testing node is having instance knob if INSTANCE_DATA_KNOB not in node.knobs().keys(): @@ -104,9 +112,13 @@ class NukeCreator(NewCreator): # test if subset name is matching if node_data.get("subset") == subset_name: - exists = True - - return exists + raise NukeCreatorError( + ( + "A publish instance for '{}' already exists " + "in nodes! Please change the variant " + "name to ensure unique output." + ).format(subset_name) + ) def create_instance_node( self, @@ -165,10 +177,7 @@ class NukeCreator(NewCreator): self.set_selected_nodes(pre_create_data) # make sure subset name is unique - if self.check_existing_subset(subset_name, instance_data): - raise NukeCreatorError( - ("subset {} is already published" - "definition.").format(subset_name)) + self.check_existing_subset(subset_name) try: instance_node = self.create_instance_node( @@ -318,10 +327,7 @@ class NukeWriteCreator(NukeCreator): self.set_selected_nodes(pre_create_data) # make sure subset name is unique - if self.check_existing_subset(subset_name, instance_data): - raise NukeCreatorError( - ("Subset '{}' is already created " - "in nodes! Change variant name!").format(subset_name)) + self.check_existing_subset(subset_name) instance_node = self.create_instance_node( subset_name, diff --git a/openpype/hosts/nuke/plugins/create/create_backdrop.py b/openpype/hosts/nuke/plugins/create/create_backdrop.py index db65b29998..efed1a1493 100644 --- a/openpype/hosts/nuke/plugins/create/create_backdrop.py +++ b/openpype/hosts/nuke/plugins/create/create_backdrop.py @@ -43,13 +43,8 @@ class CreateBackdrop(NukeCreator): return created_node def create(self, subset_name, instance_data, pre_create_data): - if self.check_existing_subset(subset_name, instance_data): - raise NukeCreatorError( - ( - "Subset '{}' is already created " - "in nodes! Change variant name!" - ).format(subset_name) - ) + # make sure subset name is unique + self.check_existing_subset(subset_name) instance = super(CreateBackdrop, self).create( subset_name, diff --git a/openpype/hosts/nuke/plugins/create/create_camera.py b/openpype/hosts/nuke/plugins/create/create_camera.py index 87d215d21b..5553645af6 100644 --- a/openpype/hosts/nuke/plugins/create/create_camera.py +++ b/openpype/hosts/nuke/plugins/create/create_camera.py @@ -44,13 +44,8 @@ class CreateCamera(NukeCreator): return created_node def create(self, subset_name, instance_data, pre_create_data): - if self.check_existing_subset(subset_name, instance_data): - raise NukeCreatorError( - ( - "Subset '{}' is already created " - "in nodes! Change variant name!" - ).format(subset_name) - ) + # make sure subset name is unique + self.check_existing_subset(subset_name) instance = super(CreateCamera, self).create( subset_name, diff --git a/openpype/hosts/nuke/plugins/create/create_gizmo.py b/openpype/hosts/nuke/plugins/create/create_gizmo.py index 221cad8fb5..e3ce70dd59 100644 --- a/openpype/hosts/nuke/plugins/create/create_gizmo.py +++ b/openpype/hosts/nuke/plugins/create/create_gizmo.py @@ -45,13 +45,8 @@ class CreateGizmo(NukeCreator): return created_node def create(self, subset_name, instance_data, pre_create_data): - if self.check_existing_subset(subset_name, instance_data): - raise NukeCreatorError( - ( - "Subset '{}' is already created " - "in nodes! Change variant name!" - ).format(subset_name) - ) + # make sure subset name is unique + self.check_existing_subset(subset_name) instance = super(CreateGizmo, self).create( subset_name, diff --git a/openpype/hosts/nuke/plugins/create/create_model.py b/openpype/hosts/nuke/plugins/create/create_model.py index ea27714095..08a53abca2 100644 --- a/openpype/hosts/nuke/plugins/create/create_model.py +++ b/openpype/hosts/nuke/plugins/create/create_model.py @@ -45,13 +45,8 @@ class CreateModel(NukeCreator): return created_node def create(self, subset_name, instance_data, pre_create_data): - if self.check_existing_subset(subset_name, instance_data): - raise NukeCreatorError( - ( - "Subset '{}' is already created " - "in nodes! Change variant name!" - ).format(subset_name) - ) + # make sure subset name is unique + self.check_existing_subset(subset_name) instance = super(CreateModel, self).create( subset_name, diff --git a/openpype/hosts/nuke/plugins/create/create_source.py b/openpype/hosts/nuke/plugins/create/create_source.py index b33d078bfe..06cf4e6cbf 100644 --- a/openpype/hosts/nuke/plugins/create/create_source.py +++ b/openpype/hosts/nuke/plugins/create/create_source.py @@ -49,13 +49,7 @@ class CreateSource(NukeCreator): _subset_name = subset_name + node_name # make sure subset name is unique - if self.check_existing_subset(_subset_name, instance_data): - raise NukeCreatorError( - ( - "Subset '{}' is already created " - "in nodes! Change variant name!" - ).format(subset_name) - ) + self.check_existing_subset(_subset_name) instance_node = self.create_instance_node( _subset_name, diff --git a/openpype/hosts/nuke/plugins/create/create_write_image.py b/openpype/hosts/nuke/plugins/create/create_write_image.py index db8f2c54db..1e23b3ad7f 100644 --- a/openpype/hosts/nuke/plugins/create/create_write_image.py +++ b/openpype/hosts/nuke/plugins/create/create_write_image.py @@ -118,13 +118,7 @@ class CreateWriteImage(napi.NukeWriteCreator): self.set_selected_nodes(pre_create_data) # make sure subset name is unique - if self.check_existing_subset(subset_name, instance_data): - raise napi.NukeCreatorError( - ( - "Subset '{}' is already created " - "in nodes! Change variant name!" - ).format(subset_name) - ) + self.check_existing_subset(subset_name) instance_node = self.create_instance_node( subset_name, diff --git a/openpype/hosts/nuke/plugins/create/create_write_prerender.py b/openpype/hosts/nuke/plugins/create/create_write_prerender.py index 25250c712c..a15f362dd1 100644 --- a/openpype/hosts/nuke/plugins/create/create_write_prerender.py +++ b/openpype/hosts/nuke/plugins/create/create_write_prerender.py @@ -133,13 +133,7 @@ class CreateWritePrerender(napi.NukeWriteCreator): self.set_selected_nodes(pre_create_data) # make sure subset name is unique - if self.check_existing_subset(subset_name, instance_data): - raise napi.NukeCreatorError( - ( - "Subset '{}' is already created " - "in nodes! Change variant name!" - ).format(subset_name) - ) + self.check_existing_subset(subset_name) instance_node = self.create_instance_node( subset_name, diff --git a/openpype/hosts/nuke/plugins/create/create_write_render.py b/openpype/hosts/nuke/plugins/create/create_write_render.py index f6bfd93a89..481d1d2201 100644 --- a/openpype/hosts/nuke/plugins/create/create_write_render.py +++ b/openpype/hosts/nuke/plugins/create/create_write_render.py @@ -122,13 +122,7 @@ class CreateWriteRender(napi.NukeWriteCreator): self.set_selected_nodes(pre_create_data) # make sure subset name is unique - if self.check_existing_subset(subset_name, instance_data): - raise napi.NukeCreatorError( - ( - "Subset '{}' is already created " - "in nodes! Change variant name!" - ).format(subset_name) - ) + self.check_existing_subset(subset_name) instance_node = self.create_instance_node( subset_name,