Skip to content

workfile_template_builder

LEGACY_PLACEHOLDER_KEYS = {'product_type', 'family'} module-attribute

Legacy placeholder keys that are deprecated but still supported for backward compatibility.

NukePlaceholderPlugin

Bases: PlaceholderPlugin

Source code in client/ayon_nuke/api/workfile_template_builder.py
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
class NukePlaceholderPlugin(PlaceholderPlugin):
    node_color = 4278190335

    item_class = PlaceholderItem

    def _collect_scene_placeholders(self):
        # Cache placeholder data to shared data
        placeholder_nodes = self.builder.get_shared_populate_data(
            "placeholder_nodes"
        )
        if placeholder_nodes is None:
            placeholder_nodes = {}
            all_groups = collections.deque()
            all_groups.append(nuke.thisGroup())
            while all_groups:
                group = all_groups.popleft()
                for node in group.nodes():
                    if isinstance(node, nuke.Group):
                        all_groups.append(node)

                    node_knobs = node.knobs()
                    if (
                        "is_placeholder" not in node_knobs
                        or not node.knob("is_placeholder").value()
                    ):
                        continue

                    if "empty" in node_knobs and node.knob("empty").value():
                        continue

                    placeholder_nodes[node.fullName()] = node

            self.builder.set_shared_populate_data(
                "placeholder_nodes", placeholder_nodes
            )
        return placeholder_nodes

    def create_placeholder(self, placeholder_data):
        placeholder_data["plugin_identifier"] = self.identifier

        placeholder = nuke.nodes.NoOp()
        placeholder.setName("PLACEHOLDER")
        placeholder.knob("tile_color").setValue(self.node_color)

        imprint(placeholder, placeholder_data)
        imprint(placeholder, {"is_placeholder": True})
        placeholder.knob("is_placeholder").setVisible(False)

    def update_placeholder(self, placeholder_item, placeholder_data):
        node = nuke.toNode(placeholder_item.scene_identifier)
        imprint(node, placeholder_data)

    def _parse_placeholder_node_data(self, node: nuke.Node):
        placeholder_data: dict[str, Any] = {}

        def _get_knob_value(knob):
            if isinstance(knob, (nuke.EvalString_Knob, nuke.String_Knob)):
                # Do not evaluate the contents; return the exact
                # text value we set
                return knob.getText()
            else:
                return knob.getValue()

        # collect current placeholder keys
        for key in self.get_placeholder_keys():
            if knob := node.knob(key):
                placeholder_data[key] = _get_knob_value(knob)
            else:
                placeholder_data[key] = None

        # collect legacy placeholder keys for backward compatibility
        for key in LEGACY_PLACEHOLDER_KEYS:

            if placeholder_data.get(key) is not None:
                continue

            if knob := node.knob(key):
                self.log.warning(
                    f"Legacy placeholder key '{key}' on '{node.fullName()}'"
                    " is deprecated and will be removed in the future."
                    "\nPlease recreate the placeholder to fix this."
                )
                placeholder_data[key] = _get_knob_value(knob)

        return placeholder_data

    def delete_placeholder(self, placeholder):
        """Remove placeholder if building was successful"""
        placeholder_node = nuke.toNode(placeholder.scene_identifier)
        nuke.delete(placeholder_node)

    def collect_placeholders(self):
        output = []
        scene_placeholders = self._collect_scene_placeholders()
        for node_name, node in scene_placeholders.items():
            plugin_identifier_knob = node.knob("plugin_identifier")
            if (
                plugin_identifier_knob is None
                or plugin_identifier_knob.getValue() != self.identifier
            ):
                continue

            placeholder_data = self._parse_placeholder_node_data(node)
            output.append(
                self.item_class(node_name, placeholder_data, self)
            )

        return output

delete_placeholder(placeholder)

Remove placeholder if building was successful

Source code in client/ayon_nuke/api/workfile_template_builder.py
139
140
141
142
def delete_placeholder(self, placeholder):
    """Remove placeholder if building was successful"""
    placeholder_node = nuke.toNode(placeholder.scene_identifier)
    nuke.delete(placeholder_node)

NukeTemplateBuilder

Bases: AbstractTemplateBuilder

Concrete implementation of AbstractTemplateBuilder for nuke

Source code in client/ayon_nuke/api/workfile_template_builder.py
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class NukeTemplateBuilder(AbstractTemplateBuilder):
    """Concrete implementation of AbstractTemplateBuilder for nuke"""

    def import_template(self, path):
        """Import template into current scene.
        Block if a template is already loaded.

        Args:
            path (str): A path to current template (usually given by
            get_template_preset implementation)

        Returns:
            bool: Whether the template was successfully imported or not
        """

        # TODO check if the template is already imported

        nuke.nodePaste(path)
        reset_selection()

        return True

import_template(path)

Import template into current scene. Block if a template is already loaded.

Parameters:

Name Type Description Default
path str

A path to current template (usually given by

required

Returns:

Name Type Description
bool

Whether the template was successfully imported or not

Source code in client/ayon_nuke/api/workfile_template_builder.py
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
def import_template(self, path):
    """Import template into current scene.
    Block if a template is already loaded.

    Args:
        path (str): A path to current template (usually given by
        get_template_preset implementation)

    Returns:
        bool: Whether the template was successfully imported or not
    """

    # TODO check if the template is already imported

    nuke.nodePaste(path)
    reset_selection()

    return True