Skip to content

collect_instances

CollectNewInstances

Bases: MayaInstancePlugin

Gather members for instances and pre-defined attribute

This collector takes into account assets that are associated with an objectSet and marked with a unique identifier;

Identifier

id (str): "ayon.create.instance"

Limitations
  • Does not take into account nodes connected to those within an objectSet. Extractors are assumed to export with history preserved, but this limits what they will be able to achieve and the amount of data available to validators. An additional collector could also append this input data into the instance, as we do for pype.rig with collect_history.
Source code in client/ayon_maya/plugins/publish/collect_instances.py
  8
  9
 10
 11
 12
 13
 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
 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
class CollectNewInstances(plugin.MayaInstancePlugin):
    """Gather members for instances and pre-defined attribute

    This collector takes into account assets that are associated with
    an objectSet and marked with a unique identifier;

    Identifier:
        id (str): "ayon.create.instance"

    Limitations:
        - Does not take into account nodes connected to those
            within an objectSet. Extractors are assumed to export
            with history preserved, but this limits what they will
            be able to achieve and the amount of data available
            to validators. An additional collector could also
            append this input data into the instance, as we do
            for `pype.rig` with collect_history.

    """

    label = "Collect New Instance Data"
    order = pyblish.api.CollectorOrder
    hosts = ["maya"]

    valid_empty_product_types = {"workfile", "renderlayer"}

    def process(self, instance):

        objset = instance.data.get("instance_node")
        if not objset:
            self.log.debug("Instance has no `instance_node` data")

        # TODO: We might not want to do this in the future
        # Merge creator attributes into instance.data just backwards compatible
        # code still runs as expected
        creator_attributes = instance.data.get("creator_attributes", {})
        if creator_attributes:
            instance.data.update(creator_attributes)

        members = cmds.sets(objset, query=True) or []
        if members:
            # Collect members
            members = cmds.ls(members, long=True) or []

            # Collect full hierarchy
            dag_members = cmds.ls(members, type="dagNode", long=True)
            children = get_all_children(dag_members,
                                        ignore_intermediate_objects=True)

            members_hierarchy = set(members)
            members_hierarchy.update(children)
            if creator_attributes.get("includeParentHierarchy", True):
                members_hierarchy.update(self.get_all_parents(dag_members))

            instance[:] = members_hierarchy

        elif (
            instance.data["productType"] not in self.valid_empty_product_types
        ):
            self.log.warning("Empty instance: \"%s\" " % objset)
        # Store the exact members of the object set
        instance.data["setMembers"] = members

        # TODO: This might make more sense as a separate collector
        # Convert frame values to integers
        for attr_name in (
            "handleStart", "handleEnd", "frameStart", "frameEnd",
        ):
            value = instance.data.get(attr_name)
            if value is not None:
                instance.data[attr_name] = int(value)

        # Append start frame and end frame to label if present
        if "frameStart" in instance.data and "frameEnd" in instance.data:
            # Take handles from context if not set locally on the instance
            for key in ["handleStart", "handleEnd"]:
                if key not in instance.data:
                    value = instance.context.data[key]
                    if value is not None:
                        value = int(value)
                    instance.data[key] = value

            instance.data["frameStartHandle"] = int(
                instance.data["frameStart"] - instance.data["handleStart"]
            )
            instance.data["frameEndHandle"] = int(
                instance.data["frameEnd"] + instance.data["handleEnd"]
            )

    def get_all_parents(self, nodes):
        """Get all parents by using string operations (optimization)

        Args:
            nodes (iterable): the nodes which are found in the objectSet

        Returns:
            set
        """

        parents = set()
        for node in nodes:
            split_parts = node.split("|")
            items = [
                "|".join(split_parts[:i]) for i in range(2, len(split_parts))
            ]
            parents.update(items)

        return parents

get_all_parents(nodes)

Get all parents by using string operations (optimization)

Parameters:

Name Type Description Default
nodes iterable

the nodes which are found in the objectSet

required

Returns:

Type Description

set

Source code in client/ayon_maya/plugins/publish/collect_instances.py
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
def get_all_parents(self, nodes):
    """Get all parents by using string operations (optimization)

    Args:
        nodes (iterable): the nodes which are found in the objectSet

    Returns:
        set
    """

    parents = set()
    for node in nodes:
        split_parts = node.split("|")
        items = [
            "|".join(split_parts[:i]) for i in range(2, len(split_parts))
        ]
        parents.update(items)

    return parents