Skip to content

validate_no_linked_object

ValidateNoLinkedObject

Bases: InstancePlugin, OptionalPyblishPluginMixin

Validates object is not linked from other file.

Source code in client/ayon_blender/plugins/publish/validate_no_linked_object.py
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
class ValidateNoLinkedObject(pyblish.api.InstancePlugin,
                             OptionalPyblishPluginMixin):
    """Validates object is not linked from other file."""

    label = "Validate No Linked Object"
    order = ValidateContentsOrder
    families = ["look"]
    hosts = ["blender"]
    optional = True
    actions = [RepairAction]

    @classmethod
    def get_invalid(cls, instance):
        """Get invalid objects in the instance.

        Args:
            instance (pyblish.api.Instance): The instance to validate.

        Returns:
            list: A list of invalid objects.
        """
        def _has_library(datablock) -> bool:
            return getattr(datablock, "library", None) is not None

        invalid = []
        for obj in instance:
            if not (
                isinstance(obj, bpy.types.Object)
                and hasattr(obj.data, "materials")
            ):
                continue

            # TODO: Technically this should consider 'library overrides'
            #  accordingly. However, the better approach is likely to find
            #  a way how to write out localized datablocks.
            if _has_library(obj):
                invalid.append(obj)
            if _has_library(obj.data):
                invalid.append(obj.data)
            for material in obj.data.materials:
                if _has_library(material):
                    invalid.append(material)

        return invalid

    def process(self, instance):
        if not self.is_active(instance.data):
            self.log.debug("Skipping Validate No Linked Object.")
            return
        invalid = self.get_invalid(instance)
        if invalid:
            names = ", ".join(obj.name for obj in invalid)
            raise PublishValidationError(
                "Objects found in instance which are linked "
                f"to other files: {names}",
                title="No Linked Objects",
                description=self.get_description()
            )

    def get_description(self):
        return inspect.cleandoc("""
            ### Linked Objects Found
            Objects in the instance are linked to other files.
            Please make the objects local before publishing or
            use the repair action to make them local.
        """
        )

    @classmethod
    def repair(cls, instance):
        invalid_objects = cls.get_invalid(instance)
        for invalid_object in invalid_objects:
            cls.log.debug(f"Making local: {invalid_object.name}")
            local_object = invalid_object.make_local(clear_asset_data=True)
            if local_object == invalid_object:
                cls.log.error(
                    f"Linked data-block {invalid_object.name} could not be"
                    " made local. It may be an indirecft library data-block."
                )

get_invalid(instance) classmethod

Get invalid objects in the instance.

Parameters:

Name Type Description Default
instance Instance

The instance to validate.

required

Returns:

Name Type Description
list

A list of invalid objects.

Source code in client/ayon_blender/plugins/publish/validate_no_linked_object.py
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
@classmethod
def get_invalid(cls, instance):
    """Get invalid objects in the instance.

    Args:
        instance (pyblish.api.Instance): The instance to validate.

    Returns:
        list: A list of invalid objects.
    """
    def _has_library(datablock) -> bool:
        return getattr(datablock, "library", None) is not None

    invalid = []
    for obj in instance:
        if not (
            isinstance(obj, bpy.types.Object)
            and hasattr(obj.data, "materials")
        ):
            continue

        # TODO: Technically this should consider 'library overrides'
        #  accordingly. However, the better approach is likely to find
        #  a way how to write out localized datablocks.
        if _has_library(obj):
            invalid.append(obj)
        if _has_library(obj.data):
            invalid.append(obj.data)
        for material in obj.data.materials:
            if _has_library(material):
                invalid.append(material)

    return invalid