Skip to content

workfile_template_builder

HoudiniPlaceholderPlugin

Bases: PlaceholderPlugin

Base Placeholder Plugin for Houdini with one unified cache.

Inherited classes must still implement populate_placeholder

Source code in client/ayon_houdini/api/workfile_template_builder.py
 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
class HoudiniPlaceholderPlugin(PlaceholderPlugin):
    """Base Placeholder Plugin for Houdini with one unified cache.

    Inherited classes must still implement `populate_placeholder`
    """

    def get_placeholder_node_name(self, placeholder_data):
        return self.identifier.replace(".", "_")

    def create_placeholder_node(self, node_name=None):
        """Create node to be used as placeholder.

        By default, it creates a null node in '/out'.
        Feel free to override it in different workfile build plugins.
        """

        node = hou.node("/out").createNode(
            "null", node_name, force_valid_node_name=True)
        node.moveToGoodPosition()
        parms = node.parmTemplateGroup()
        for parm in {"execute", "renderdialog"}:
            p = parms.find(parm)
            p.hide(True)
            parms.replace(parm, p)
        node.setParmTemplateGroup(parms)
        return node

    def create_placeholder(self, placeholder_data):
        node_name = self.get_placeholder_node_name(placeholder_data)

        placeholder_node = self.create_placeholder_node(node_name)
        HoudiniCreator.customize_node_look(placeholder_node)

        placeholder_data["plugin_identifier"] = self.identifier

        imprint(placeholder_node, placeholder_data)

    def collect_scene_placeholders(self):
        # Read the cache by identifier
        placeholder_nodes = self.builder.get_shared_populate_data(
            self.identifier
        )
        if placeholder_nodes is None:
            placeholder_nodes = []

            nodes = lsattr("plugin_identifier", self.identifier)

            for node in nodes:
                placeholder_nodes.append(node)

            # Set the cache by identifier
            self.builder.set_shared_populate_data(
                    self.identifier, placeholder_nodes
                )

        return placeholder_nodes

    def update_placeholder(self, placeholder_item, placeholder_data):
        placeholder_node = hou.node(placeholder_item.scene_identifier)
        imprint(placeholder_node, placeholder_data, update=True)

        # Update node name
        node_name = self.get_placeholder_node_name(placeholder_data)
        node_name = hou.text.variableName(node_name)
        placeholder_node.setName(node_name, unique_name=True)

    def delete_placeholder(self, placeholder):
        placeholder_node = hou.node(placeholder.scene_identifier)
        placeholder_node.destroy()

create_placeholder_node(node_name=None)

Create node to be used as placeholder.

By default, it creates a null node in '/out'. Feel free to override it in different workfile build plugins.

Source code in client/ayon_houdini/api/workfile_template_builder.py
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
def create_placeholder_node(self, node_name=None):
    """Create node to be used as placeholder.

    By default, it creates a null node in '/out'.
    Feel free to override it in different workfile build plugins.
    """

    node = hou.node("/out").createNode(
        "null", node_name, force_valid_node_name=True)
    node.moveToGoodPosition()
    parms = node.parmTemplateGroup()
    for parm in {"execute", "renderdialog"}:
        p = parms.find(parm)
        p.hide(True)
        parms.replace(parm, p)
    node.setParmTemplateGroup(parms)
    return node

HoudiniTemplateBuilder

Bases: AbstractTemplateBuilder

Concrete implementation of AbstractTemplateBuilder for Houdini

Source code in client/ayon_houdini/api/workfile_template_builder.py
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
class HoudiniTemplateBuilder(AbstractTemplateBuilder):
    """Concrete implementation of AbstractTemplateBuilder for Houdini"""

    def resolve_template_path(self, path, fill_data):
        """Allows additional resolving over the template path using custom
        integration methods, like Houdini's expand string functionality.

        This only works with ayon-core 0.4.5+
        """
        # use default template data formatting
        path = super().resolve_template_path(path, fill_data)

        # escape backslashes for `expandString` and expand houdini vars
        path = path.replace("\\", "\\\\")
        path = hou.text.expandString(path)
        return path

    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 template is already imported

        # Merge (Load) template workfile in the current scene.
        try:
            hou.hipFile.merge(path, ignore_load_warnings=True)
            return True
        except hou.OperationFailed:
            return False

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_houdini/api/workfile_template_builder.py
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
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 template is already imported

    # Merge (Load) template workfile in the current scene.
    try:
        hou.hipFile.merge(path, ignore_load_warnings=True)
        return True
    except hou.OperationFailed:
        return False

resolve_template_path(path, fill_data)

Allows additional resolving over the template path using custom integration methods, like Houdini's expand string functionality.

This only works with ayon-core 0.4.5+

Source code in client/ayon_houdini/api/workfile_template_builder.py
24
25
26
27
28
29
30
31
32
33
34
35
36
def resolve_template_path(self, path, fill_data):
    """Allows additional resolving over the template path using custom
    integration methods, like Houdini's expand string functionality.

    This only works with ayon-core 0.4.5+
    """
    # use default template data formatting
    path = super().resolve_template_path(path, fill_data)

    # escape backslashes for `expandString` and expand houdini vars
    path = path.replace("\\", "\\\\")
    path = hou.text.expandString(path)
    return path