Skip to content

load_model_usd

ModelUSDLoader

Bases: LoaderPlugin

Loading model with the USD loader.

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

    product_types = {"model"}
    label = "Load Model(USD)"
    representations = {"usda"}
    order = -10
    icon = "code-fork"
    color = "orange"

    def load(self, context, name=None, namespace=None, data=None):
        # asset_filepath
        plugin_info = get_plugins()
        if "usdimport.dli" not in plugin_info:
            raise LoadError("No USDImporter loaded/installed in Max..")
        filepath = os.path.normpath(self.filepath_from_context(context))
        import_options = rt.USDImporter.CreateOptions()
        base_filename = os.path.basename(filepath)
        _, ext = os.path.splitext(base_filename)
        log_filepath = filepath.replace(ext, "txt")

        rt.LogPath = log_filepath
        rt.LogLevel = rt.Name("info")
        rt.USDImporter.importFile(filepath,
                                  importOptions=import_options)
        namespace = unique_namespace(
            name + "_",
            suffix="_",
        )
        asset = rt.GetNodeByName(name)
        usd_objects = []

        for usd_asset in asset.Children:
            usd_asset.name = f"{namespace}:{usd_asset.name}"
            usd_objects.append(usd_asset)

        asset_name = f"{namespace}:{name}"
        asset.name = asset_name
        # need to get the correct container after renamed
        asset = rt.GetNodeByName(asset_name)
        usd_objects.append(asset)

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

    def update(self, container, context):
        repre_entity = context["representation"]
        path = os.path.normpath(self.filepath_from_context(context))
        node_name = container["instance_node"]
        node = rt.GetNodeByName(node_name)
        namespace, name = get_namespace(node_name)
        node_list = get_previous_loaded_object(node)
        rt.Select(node_list)
        prev_objects = [sel for sel in rt.GetCurrentSelection()
                        if sel != rt.Container
                        and sel.name != node_name]
        transform_data = object_transform_set(prev_objects)
        for n in prev_objects:
            rt.Delete(n)

        import_options = rt.USDImporter.CreateOptions()
        base_filename = os.path.basename(path)
        _, ext = os.path.splitext(base_filename)
        log_filepath = path.replace(ext, "txt")

        rt.LogPath = log_filepath
        rt.LogLevel = rt.Name("info")
        rt.USDImporter.importFile(
            path, importOptions=import_options)

        asset = rt.GetNodeByName(name)
        usd_objects = []
        for children in asset.Children:
            children.name = f"{namespace}:{children.name}"
            usd_objects.append(children)
            children_transform = f"{children}.transform"
            if children_transform in transform_data.keys():
                children.pos = transform_data[children_transform] or 0
                children.scale = transform_data[
                    f"{children}.scale"] or 0

        asset.name = f"{namespace}:{asset.name}"
        usd_objects.append(asset)
        update_custom_attribute_data(node, usd_objects)
        with maintained_selection():
            rt.Select(node)

        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)