Skip to content

load_model

ModelAbcLoader

Bases: LoaderPlugin

Loading model with the Alembic loader.

Source code in client/ayon_max/plugins/load/load_model.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
 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
class ModelAbcLoader(load.LoaderPlugin):
    """Loading model with the Alembic loader."""

    product_types = {"model"}
    label = "Load Model with Alembic"
    representations = {"abc"}
    order = -10
    icon = "code-fork"
    color = "orange"

    def load(self, context, name=None, namespace=None, data=None):
        from pymxs import runtime as rt

        file_path = os.path.normpath(self.filepath_from_context(context))

        abc_before = {
            c
            for c in rt.rootNode.Children
            if rt.classOf(c) == rt.AlembicContainer
        }

        rt.AlembicImport.ImportToRoot = False
        rt.AlembicImport.CustomAttributes = True
        rt.AlembicImport.UVs = True
        rt.AlembicImport.VertexColors = True
        rt.importFile(file_path, rt.name("noPrompt"), using=rt.AlembicImport)

        abc_after = {
            c
            for c in rt.rootNode.Children
            if rt.classOf(c) == rt.AlembicContainer
        }

        # This should yield new AlembicContainer node
        abc_containers = abc_after.difference(abc_before)

        if len(abc_containers) != 1:
            self.log.error("Something failed when loading.")

        abc_container = abc_containers.pop()

        namespace = unique_namespace(
            name + "_",
            suffix="_",
        )
        abc_objects = []
        for abc_object in abc_container.Children:
            abc_object.name = f"{namespace}:{abc_object.name}"
            abc_objects.append(abc_object)
        # rename the abc container with namespace
        abc_container_name = f"{namespace}:{name}"
        abc_container.name = abc_container_name
        abc_objects.append(abc_container)

        return containerise(
            name, abc_objects, context,
            namespace, loader=self.__class__.__name__
        )

    def update(self, container, context):
        from pymxs import runtime as rt

        repre_entity = context["representation"]
        path = os.path.normpath(self.filepath_from_context(context))
        node = rt.GetNodeByName(container["instance_node"])
        node_list = [n for n in get_previous_loaded_object(node)
                     if rt.ClassOf(n) == rt.AlembicContainer]
        with maintained_selection():
            rt.Select(node_list)

            for alembic in rt.Selection:
                abc = rt.GetNodeByName(alembic.name)
                rt.Select(abc.Children)
                for abc_con in abc.Children:
                    abc_con.source = path
                    rt.Select(abc_con.Children)
                    for abc_obj in abc_con.Children:
                        abc_obj.source = path

        lib.imprint(container["instance_node"], {
            "representation": repre_entity["id"],
            "project_name": context["project"]["name"]
        })

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

    def remove(self, container):
        from pymxs import runtime as rt
        node = rt.GetNodeByName(container["instance_node"])
        remove_container_data(node)


    @staticmethod
    def get_container_children(parent, type_name):
        from pymxs import runtime as rt

        def list_children(node):
            children = []
            for c in node.Children:
                children.append(c)
                children += list_children(c)
            return children

        filtered = []
        for child in list_children(parent):
            class_type = str(rt.ClassOf(child.baseObject))
            if class_type == type_name:
                filtered.append(child)

        return filtered