Skip to content

load_look

Look loader.

LookLoader

Bases: ReferenceLoader

Specific loader for lookdev

Source code in client/ayon_maya/plugins/load/load_look.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
 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
class LookLoader(ayon_maya.api.plugin.ReferenceLoader):
    """Specific loader for lookdev"""

    product_types = {"look"}
    representations = {"ma"}

    label = "Reference look"
    order = -10
    icon = "code-fork"
    color = "orange"

    def process_reference(self, context, name, namespace, options):
        from maya import cmds

        with lib.maintained_selection():
            file_url = self.prepare_root_value(
                file_url=self.filepath_from_context(context),
                project_name=context["project"]["name"]
            )
            nodes = cmds.file(file_url,
                              namespace=namespace,
                              reference=True,
                              returnNewNodes=True)

        self[:] = nodes

    def switch(self, container, context):
        self.update(container, context)

    def update(self, container, context):
        """
            Called by Scene Inventory when look should be updated to current
            version.
            If any reference edits cannot be applied, eg. shader renamed and
            material not present, reference is unloaded and cleaned.
            All failed edits are highlighted to the user via message box.

        Args:
            container: object that has look to be updated
            context: (dict): relationship data to get proper
                                       representation from DB and persisted
                                       data in .json
        Returns:
            None
        """
        from maya import cmds

        # Get reference node from container members
        members = lib.get_container_members(container)
        reference_node = get_reference_node(members, log=self.log)

        shader_nodes = cmds.ls(members, type='shadingEngine')
        orig_nodes = set(self._get_nodes_with_shader(shader_nodes))

        # Trigger the regular reference update on the ReferenceLoader
        super(LookLoader, self).update(container, context)

        # get new applied shaders and nodes from new version
        shader_nodes = cmds.ls(members, type='shadingEngine')
        nodes = set(self._get_nodes_with_shader(shader_nodes))

        version_id = context["version"]["id"]
        project_name = context["project"]["name"]
        json_representation = get_representation_by_name(
            project_name, "json", version_id
        )

        # Load relationships
        shader_relation = get_representation_path(json_representation)
        with open(shader_relation, "r") as f:
            json_data = json.load(f)

        # update of reference could result in failed edits - material is not
        # present because of renaming etc. If so highlight failed edits to user
        failed_edits = cmds.referenceQuery(reference_node,
                                           editStrings=True,
                                           failedEdits=True,
                                           successfulEdits=False)
        if failed_edits:
            # clean references - removes failed reference edits
            cmds.file(cr=reference_node)  # cleanReference

            # reapply shading groups from json representation on orig nodes
            lib.apply_shaders(json_data, shader_nodes, orig_nodes)

            msg = ["During reference update some edits failed.",
                   "All successful edits were kept intact.\n",
                   "Failed and removed edits:"]
            msg.extend(failed_edits)

            msg = ScrollMessageBox(QtWidgets.QMessageBox.Warning,
                                   "Some reference edit failed",
                                   msg)
            msg.exec_()

        attributes = json_data.get("attributes", [])

        # region compute lookup
        nodes_by_id = defaultdict(list)
        for node in nodes:
            nodes_by_id[lib.get_id(node)].append(node)
        lib.apply_attributes(attributes, nodes_by_id)

    def _get_nodes_with_shader(self, shader_nodes):
        """
            Returns list of nodes belonging to specific shaders
        Args:
            shader_nodes: <list> of Shader groups
        Returns
            <list> node names
        """
        from maya import cmds

        for shader in shader_nodes:
            future = cmds.listHistory(shader, future=True)
            connections = cmds.listConnections(future,
                                               type='mesh')
            if connections:
                # Ensure unique entries only to optimize query and results
                connections = list(set(connections))
                return cmds.listRelatives(connections,
                                          shapes=True,
                                          fullPath=True) or []
        return []

update(container, context)

Called by Scene Inventory when look should be updated to current
version.
If any reference edits cannot be applied, eg. shader renamed and
material not present, reference is unloaded and cleaned.
All failed edits are highlighted to the user via message box.

Parameters:

Name Type Description Default
container

object that has look to be updated

required
context

(dict): relationship data to get proper representation from DB and persisted data in .json

required

Returns: None

Source code in client/ayon_maya/plugins/load/load_look.py
 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
116
def update(self, container, context):
    """
        Called by Scene Inventory when look should be updated to current
        version.
        If any reference edits cannot be applied, eg. shader renamed and
        material not present, reference is unloaded and cleaned.
        All failed edits are highlighted to the user via message box.

    Args:
        container: object that has look to be updated
        context: (dict): relationship data to get proper
                                   representation from DB and persisted
                                   data in .json
    Returns:
        None
    """
    from maya import cmds

    # Get reference node from container members
    members = lib.get_container_members(container)
    reference_node = get_reference_node(members, log=self.log)

    shader_nodes = cmds.ls(members, type='shadingEngine')
    orig_nodes = set(self._get_nodes_with_shader(shader_nodes))

    # Trigger the regular reference update on the ReferenceLoader
    super(LookLoader, self).update(container, context)

    # get new applied shaders and nodes from new version
    shader_nodes = cmds.ls(members, type='shadingEngine')
    nodes = set(self._get_nodes_with_shader(shader_nodes))

    version_id = context["version"]["id"]
    project_name = context["project"]["name"]
    json_representation = get_representation_by_name(
        project_name, "json", version_id
    )

    # Load relationships
    shader_relation = get_representation_path(json_representation)
    with open(shader_relation, "r") as f:
        json_data = json.load(f)

    # update of reference could result in failed edits - material is not
    # present because of renaming etc. If so highlight failed edits to user
    failed_edits = cmds.referenceQuery(reference_node,
                                       editStrings=True,
                                       failedEdits=True,
                                       successfulEdits=False)
    if failed_edits:
        # clean references - removes failed reference edits
        cmds.file(cr=reference_node)  # cleanReference

        # reapply shading groups from json representation on orig nodes
        lib.apply_shaders(json_data, shader_nodes, orig_nodes)

        msg = ["During reference update some edits failed.",
               "All successful edits were kept intact.\n",
               "Failed and removed edits:"]
        msg.extend(failed_edits)

        msg = ScrollMessageBox(QtWidgets.QMessageBox.Warning,
                               "Some reference edit failed",
                               msg)
        msg.exec_()

    attributes = json_data.get("attributes", [])

    # region compute lookup
    nodes_by_id = defaultdict(list)
    for node in nodes:
        nodes_by_id[lib.get_id(node)].append(node)
    lib.apply_attributes(attributes, nodes_by_id)