Python or Blueprint example for importing obj file in UE5.1, Interchange Import Pipeline

In UE5 and the previous version, we import assets using code below

 task = unreal.AssetImportTask()
    task.automated = False
    task.destination_path = f"{assetPath}"
    task.destination_name = f"SM_{assetName}"
    task.filename = file_full_path
    task.replace_existing = True
    task.save = False
    task.options = import_options
    asset_tools.import_asset_tasks([task])

But in UE5.1, It only works with FBX file. other type like png texture,obj, etc, work incorrectly. For example, destination_name is invalid, options won’t work.

I know the import framework has changed in UE5.1. Interchange Import Pipeline is a new feature, but I can’t find any example how to use it.

What do you have in your import_options? Do you force FBXimporter? Try removing the set of task.options to see.
AssetImportTask should find good process based on the file extension.

By default Asset import task will use Interchange for supported formats (obj, texture, gltf) fbx is disabled for now. You also have a new variable async_ to perform the import asynchronously for file formats where async import is available.

Else if you want to import with interchange functions directly here are two samples: one to load as assets, one to load as scene. I think the override_pipelines are optional, interchange will chose the default stack defined in your project settings:

### Version Asset

import unreal

obj_path = "D:/demoInterchange/steam_controller_03_gordon/steam_controller_03_gordon.obj"

source_data = unreal.InterchangeManager.create_source_data(obj_path)
import_asset_parameters = unreal.ImportAssetParameters()
import_asset_parameters.is_automated = True

eas = unreal.get_editor_subsystem(unreal.EditorAssetSubsystem)
import_asset_parameters.override_pipelines.append(eas.load_asset("/Interchange/Pipelines/DefaultAssetsPipeline"))
#import_asset_parameters.override_pipelines.append(eas.load_asset("/Game/DemoInterchange/DemoCustomChanges"))

ic_mng = unreal.InterchangeManager.get_interchange_manager_scripted()
ic_mng.import_asset("/game/interchange/obj/",source_data,import_asset_parameters)

### Version Scene

import unreal

gltf_path = "D:/projectPS/gltf/sketchfab/ship_in_a_bottle/scene.gltf"

source_data = unreal.InterchangeManager.create_source_data(gltf_path)
import_asset_parameters = unreal.ImportAssetParameters()
import_asset_parameters.is_automated = True

eas = unreal.get_editor_subsystem(unreal.EditorAssetSubsystem)
import_asset_parameters.override_pipelines.append(eas.load_asset("/Interchange/Pipelines/DefaultSceneAssetsPipeline"))
import_asset_parameters.override_pipelines.append(eas.load_asset("/Interchange/Pipelines/DefaultSceneLevelPipeline"))

ic_mng = unreal.InterchangeManager.get_interchange_manager_scripted()
ic_mng.import_scene("/game/interchange/gltf/",source_data,import_asset_parameters)

Thanks for your reply. As you mentioned above, I forcely use FBXImporter, like this

import_data = unreal.FbxStaticMeshImportData()
import_data.combine_meshes = True
import_data.import_uniform_scale = 100
import_data.auto_generate_collision = False

import_options = unreal.FbxImportUI()
import_options.static_mesh_import_data = import_data

But the file extension is .obj, so the import task use Interchange framework, the parameter options doesn’t work.

I appreciate that you supply a useful snippet for me. I found unreal.ImportAssetParameters only supports a few parameter. what if I want to control the destination_name,combine_meshes,uniform scale, etc, and whether to import materials, textures or not.

One can edit a pipeline asset with python, c.f. this message later down the thread

Else I can propose you the following:

  1. Copy the “/Interchange/Pipelines/DefaultAssetsPipeline” for assets or “/Interchange/Pipelines/DefaultSceneAssetsPipeline” for scene in a folder of your project, such as “MyCustomObjAssetsPipeline”
  2. edit the default value of that asset to set up with the parameters you want (the one in your content folder)
  3. In your python script you override pipeline with this new custom asset you have made.
import_asset_parameters.override_pipelines.append(eas.load_asset("/Game/Interchange/MyCustomObjAssetsPipeline"))

I had the same problem, I had to debug for an afternoon and found that the same code works fine on the 5.03 version of Unreal Engine.

This should be a bug of UE5.1

Thanks, It really helps a lot. Your answer solves most part of my question, and I get some useful information about the workflow of Interchange Pipeline.
The last remained thing is renaming asset when importing. I notice there is an option Use Source Name For Asset, but unfortunately, some asset will be renamed when has the same name with other type asset. For example, import a texture named “AAA.png”, then import a mesh named “AAA.obj”, the mesh will be renamed to “AAA1”. My intention is importing “AAA.png” to “T_AAA”, importing “AAA.obj” to “SM_AAA”. I don’t konw how to do that. In UE5.0, desination_name can rename asset when importing. Also, I can rename my assets before importing. But it’s better if doing in UE.

Okay, so we are diving one level deeper in interchange. With interchange you can hook between translation of file and creation of asset, as well as post asset creation etc.
So we are going to create a custom pipeline that will modify some of the information that is passed to the factories that will create assets before those factories are run:

  1. you can create a new Interchange blueprint pipeline base blueprint. You will use that blueprint to do extra work on your default interchange import.

  2. you override the event “Scripted Execute Pre import pipeline”.
    you had something like that. Note (1) we want to filter per “Interchange factory base node”. Those are factory node created by the first part of the pipeline and they will create the assets. You note we look for factory nodes for mesh, textures and materials and we rename assets depending on the type of the factory. (2) is another function you might like, it will add an extra folder to the path of the asset. I use it to put textures in a “texture” folder for example.

  3. Now, in a bug free world you should be able to just add that extra pipeline to the stack on import. Note you must still use the MyCustomObjAssetsPipeline and you should use it first in the stack => it is doing all the heavy lifting of import. The new blueprint you are adding is just tweaking nodes that are already created by previous pipeline

import_asset_parameters.override_pipelines.append(eas.load_asset("/Game/Interchange/MyDefaultAssetsPipeline"))
import_asset_parameters.override_pipelines.append(eas.load_asset("/Game/Interchange/BP_PrefixAsset"))

However you cannot add that custom blueprint to the override_pipelines array yet. We have a bug open for that.

  1. I can propose you instead to modify your default pipeline stack in Interchange settings and let “override_pipelines” empty for now.
    In project settings > Interchange, add a new stack in assets, put your two pipelines, and change the default pipeline stack

Now when you import into content folder (asset import) it will do your add prefix by default (import in UI, import in Blueprint, import in python, as long as you do not override pipelines)

  1. You can do the same thing for the scene import pipeline stack. Create a new pipeline stack, add the default mandatory two pipelines and add yours as the 3rd one. then change the default pipeline stack for the scene import
1 Like

@liyangyang0901

you can edit default values of a pipeline asset with python like this

import unreal

eas = unreal.get_editor_subsystem(unreal.EditorAssetSubsystem)
pipeline = eas.load_asset("/game/interchange/MyDefaultAssetsPipeline")
mesh_pipeline = pipeline.get_editor_property("mesh_pipeline")
mesh_pipeline.set_editor_property("combine_static_meshes",True)
eas.save_loaded_asset(pipeline)

Awesome! That’s what I need. Interchange Framework is powerful. just needs more documentation.

Is there a link about that open bug. So I can track the process. I want to import different assets by different pipelines. So when the bug is fixed, I can change my code, and make it more flexible.

1 Like

I have forgotten to create the ticket, now is done.
The link will be active as soon as it gets internal approval.

:clap: Got it!

This topic has been moved from International to Programming & Scripting.

When posting, please review the categories to ensure your topic is posted in the most relevant space. This post has been moved to help other devs with similar questions! :slight_smile:

1 Like

@UE_FlavienP

Hi, related to this topic: It seems that properties set on FbxStaticMeshImportData aren’t being applied when importing FBX files via an import task. The code below applies the modified properties on import in UE 5.0, but doesn’t in UE 5.1. I tried putting a bug in for this issue a month ago, but it hasn’t been officially added to the tracker yet. Do you know if there’s an open bug for this or some kind of workaround?

import unreal

ROOT_LAYER_FILENAME = r"C:\\MyFolder\\test_mesh.fbx"
DESTINATION_CONTENT_PATH = r"/Game/Imported/"
tasks = []

def BuildImportTask(sourcepath, destinationpath):
    task = unreal.AssetImportTask()
    fbximpsettings = unreal.FbxStaticMeshImportData()
    fbximpsettings.set_editor_property('build_nanite', True)
    fbximpsettings.set_editor_property('combine_meshes', True)
    fbximpsettings.set_editor_property('generate_lightmap_u_vs', False)
    task.set_editor_property('destination_path', destinationpath)
    task.set_editor_property('filename', sourcepath)
    task.set_editor_property('automated', True)
    task.set_editor_property('replace_existing', True)
    return task

def ImportMesh():
    tasks.append(BuildImportTask(ROOT_LAYER_FILENAME, DESTINATION_CONTENT_PATH))
    unreal.AssetToolsHelpers.get_asset_tools().import_asset_tasks(tasks)

ImportMesh()

The snippet you give does not work for me in 5.0.
I had to add

    options = unreal.FbxImportUI()
    options.set_editor_property("static_mesh_import_data", fbximpsettings)

    task.set_editor_property("options",options)

In that case the merge mesh and nanite works in 5.0 and 5.1

@UE_FlavienP Odd, I recall that script working in 5.0 perfectly. Regardless, that addition fixed it for me in 5.1 so thank you!