Skip to content

validate_render_inputs

ValidateRenderCompositorNodeFileOutputConnected

Bases: BlenderInstancePlugin, OptionalPyblishPluginMixin

Validate the Compositor File Output Node has all its image slots connected to an input.

Source code in client/ayon_blender/plugins/publish/validate_render_inputs.py
14
15
16
17
18
19
20
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
class ValidateRenderCompositorNodeFileOutputConnected(
    plugin.BlenderInstancePlugin,
    OptionalPyblishPluginMixin
):
    """Validate the Compositor File Output Node has all its image slots
    connected to an input."""

    order = pyblish.api.ValidatorOrder
    hosts = ["blender"]
    families = ["render"]
    label = "Validate Render Inputs"
    # TODO: Not sure how to select a Compositor Node through Python API so
    #       until then, we can't select the node via the UI.
    # actions = [SelectInvalidAction]
    optional = True

    def process(self, instance):
        if not self.is_active(instance.data):
            return

        invalid = self.get_invalid(instance)

        if invalid:

            node = invalid[0].node
            node_name = node.name

            labels = []
            for socket in invalid:
                label = socket.name
                labels.append(label)

            raise PublishValidationError(
                f"The Compositor File Output Node '{node_name}' has the "
                "following unconnected image slots:\n{}".format(
                    "\n".join(f"- {label}" for label in labels)
                ),
                title="Unconnected image slots",
                description=self.get_description(),
            )

    @classmethod
    def get_invalid(cls, instance):
        output: bpy.types.CompositorNodeOutputFile = (
            instance.data["transientData"]["instance_node"]
        )

        # Check all the slots are connected
        invalid = []
        for input_ in output.inputs:
            # Assume all `NodeSocketColor` entries have inputs.
            # TODO: Validate only entries that relate to the `slots`, but how?
            if isinstance(input_, bpy.types.NodeSocketColor):
                if not input_.links:
                    invalid.append(input_)

        return invalid

    @staticmethod
    def get_description():
        return inspect.cleandoc("""### Unconnected image slots

        The Compositor File Output Node has unconnected input image slots.
        Make sure to connect each of the individual slots to an input, or
        remove the irrelevant slots if they are not needed.
        """)