Skip to content

workfile_template_builder

SilhouettePlaceholderPlugin

Bases: PlaceholderPlugin

Source code in client/ayon_silhouette/api/workfile_template_builder.py
 49
 50
 51
 52
 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
class SilhouettePlaceholderPlugin(PlaceholderPlugin):
    data_key = "ayon.placeholder"
    item_class = PlaceholderItem

    def _create_placeholder_node(
            self, placeholder_data, session, node_type="NullNode"):
        # Create node
        placeholder_node = fx.Node(node_type)
        placeholder_node.label = "PLACEHOLDER"
        session.addNode(placeholder_node)
        lib.set_new_node_position(placeholder_node)
        return placeholder_node

    @lib.undo_chunk("Create placeholder")
    def create_placeholder(self, placeholder_data) -> PlaceholderItem:
        session = fx.activeSession()
        if not session:
            raise RuntimeError("Must have active session.")

        placeholder_data["plugin_identifier"] = self.identifier

        placeholder_node = self._create_placeholder_node(
            placeholder_data, session)

        fx.activate(placeholder_node)

        imprint(placeholder_node, placeholder_data, key=self.data_key)

        item = self.item_class(
            scene_identifier=placeholder_node.id,
            data=placeholder_data,
            plugin=self
        )
        # Add transient data for easier access
        item.transient_data = {
            "node": placeholder_node
        }

        return item

    @lib.undo_chunk("Update placeholder")
    def update_placeholder(self,
                           placeholder_item: PlaceholderItem,
                           placeholder_data: dict):
        node = placeholder_item.transient_data["node"]  # noqa
        placeholder_data["plugin_identifier"] = self.identifier
        imprint(node, placeholder_data, key=self.data_key)

    def _collect_placeholder_nodes(self) -> Dict[str, List[fx.Node]]:
        nodes = self.builder.get_shared_populate_data("placeholder_nodes")
        if nodes is None:
            # Populate cache
            session = fx.activeSession()
            project = fx.activeProject()
            nodes_by_plugin_identifier = {}
            for node in itertools.chain(session.nodes, project.sources):
                node_data = read(node, key=self.data_key)
                if not node_data:
                    continue

                plugin_identifier = node_data.get("plugin_identifier")
                if not plugin_identifier:
                    continue

                nodes_by_plugin_identifier.setdefault(
                    plugin_identifier, []).append(node)

            nodes = nodes_by_plugin_identifier
            self.builder.set_shared_populate_data("placeholder_nodes",
                                                  nodes_by_plugin_identifier)

        return nodes

    def collect_placeholders(self) -> List[PlaceholderItem]:
        nodes_by_identifier = self._collect_placeholder_nodes()

        placeholder_items = []
        for node in nodes_by_identifier.get(self.identifier, []):
            data = self._parse_placeholder_node_data(node)
            placeholder_item = self.item_class(
                scene_identifier=node.id,
                data=data,
                plugin=self)

            # Add transient data for easier access
            placeholder_item.transient_data = {
                "node": node
            }
            placeholder_items.append(placeholder_item)

        return placeholder_items

    def _parse_placeholder_node_data(self, node) -> dict:
        return read(node, key=self.data_key)

    @lib.undo_chunk("Delete placeholder")
    def delete_placeholder(self, placeholder: PlaceholderItem):
        """Remove placeholder if building was successful"""
        node = placeholder.transient_data["node"]  # noqa
        if isinstance(node, fx.Node):
            session = node.session
            session.removeNode(node)
        elif isinstance(node, fx.Source):
            project = node.parent.parent  # Source -> SourceItem -> Project
            project.removeItem(node)
        else:
            raise TypeError(f"Unsupported placeholder node: {node}")

delete_placeholder(placeholder)

Remove placeholder if building was successful

Source code in client/ayon_silhouette/api/workfile_template_builder.py
144
145
146
147
148
149
150
151
152
153
154
155
@lib.undo_chunk("Delete placeholder")
def delete_placeholder(self, placeholder: PlaceholderItem):
    """Remove placeholder if building was successful"""
    node = placeholder.transient_data["node"]  # noqa
    if isinstance(node, fx.Node):
        session = node.session
        session.removeNode(node)
    elif isinstance(node, fx.Source):
        project = node.parent.parent  # Source -> SourceItem -> Project
        project.removeItem(node)
    else:
        raise TypeError(f"Unsupported placeholder node: {node}")

SilhouetteTemplateBuilder

Bases: AbstractTemplateBuilder

Concrete implementation of AbstractTemplateBuilder for Silhouette

Source code in client/ayon_silhouette/api/workfile_template_builder.py
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class SilhouetteTemplateBuilder(AbstractTemplateBuilder):
    """Concrete implementation of AbstractTemplateBuilder for Silhouette"""

    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
        lib.import_project(path)

        # Clear any selection if it occurred on load or import
        fx.select([])

        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_silhouette/api/workfile_template_builder.py
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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
    lib.import_project(path)

    # Clear any selection if it occurred on load or import
    fx.select([])

    return True