[Feature Request] Interchange direct Import to DynamicMesh at runtime

Interchange ImportScene generates an Static Mesh Actor from an .gltf-File.This Static Mesh Actor needs the flag “Allow CPU Access” so that it can be read by CopyfromStaticMesh to make a dynamic mesh.

The dynamicmesh is the requirement for many geometry script functions.

This Option “Allow CPU Access” is located inside the Mesh Editor Subsystem so it is not reachable out of the box at the moment. Espacially runtime imported files (after Compiling) are a problem right now .

Interchange ist quite new and under development so it should be possible not to forget about many Developers, that want to react on 3D Data during runtime by using Geometry Script function. (For Example loading a custom Avater or a self made piece of Deco )

should be an Import Option for Interchange.

There is already a system integrated in Interchange, that is called UserDefinedAttributesAPI, I am going to use this to modify the flag ballowcpuaccess on static meshes, that are imported via interchange. Advices, examples even of unfinished tries are very wanted. Here some Reference I found in the unreal docs: unreal.InterchangeUserDefinedAttributesAPI — Unreal Python 5.1 (Experimental) documentation

I am still working to find a solution. Update: i narrowed down the missing functionality in UE 5.2
Here is a log from the packaged .exe with some extra custom logging to show better, what exactly is happening:

LogInterchangeEngine: Display: Interchange start importing source [C:/…*.step.glb]
In Staticmesh.cpp BuildFromMeshDescription is called Line 6516
In StaticMesh-cpp InitResources was called
In Staticmesh.cpp FStaticMeshRenderData:InitResources is called Line 1866
LogInterchangeEngine: Display: In InterchangeTaskCompletion.cpp Line 120
In InterchangeTaskCompletion.cpp Line 120 Registerallcomponents (actor) was called
In InterchangeTaskCompletion.cpp Line 33 UE::Interchange::FTaskPreAsyncCompletion::DoTask was called that calls next ReleaseTranslatorsSource()
ImportSceneObjectDone wurde ausgeführt für Index:::19
InterchangeManager.cpp 343 FimportAsyncHelper::Cleanup
Read Imported Data
LogGeometry: Warning: GeometryScriptError: CopyMeshFromStaticMesh: Requested LOD Type is not available

The interchange import doesn’t fill out the needed CPU-Data i guess, because in most cases it is not needed. I Found a piece of Code Comment:

FStaticMeshLODResourcesToDynamicMesh can be used to create a FDynamicMesh3 from a FStaticMeshLODResources, which is the variant of the mesh in a StaticMesh Asset used for rendering (and which is available at runtime). The FStaticMeshLODResources has vertices duplicated at any split UV/normal/tangent/color, ie in the overlays there will be a unique overlay element for each base mesh vertex.

my next try is i guess is to try if i can manage to extend Interchange somehow to fill a FDynamicMesh3 object.

The Source code of the Engine has a real good quality and is at the same time very big and complex. Advices or motivational speeches will be appreciated.

If someone wonders what this ominous CPU-Data is, here a piece of sourcecode found in (staticmesh.cpp Line 1519 UE 5.2) ( it is not called in my case so only useful for understanding) :

void FStaticMeshLODResources::DiscardCPUData()
{
VertexBuffers.StaticMeshVertexBuffer.CleanUp();
VertexBuffers.PositionVertexBuffer.CleanUp();
VertexBuffers.ColorVertexBuffer.CleanUp();
IndexBuffer.Discard();
DepthOnlyIndexBuffer.Discard();

if (AdditionalIndexBuffers)
{
AdditionalIndexBuffers->ReversedIndexBuffer.Discard();
AdditionalIndexBuffers->ReversedDepthOnlyIndexBuffer.Discard();
AdditionalIndexBuffers->WireframeIndexBuffer.Discard();
}

#if RHI_RAYTRACING
RayTracingGeometry.RawData.Discard();
#endif
}
It appears to be so simple. Maybe someone want to bite into it and share whatever comes along.

Is here some #Interchange Framework Expert ?

  1. Which is the most straight forward way of Implementing an Import Function that imports directly into #DynamicMesh ?

(Post packaging Runtime Import of .gltf Files)

From Website: The core component that enables Geometry Script is the UDynamicMesh object.

I know that during Import in (post packaged) Game.exe the function BuildFromMeshDescription is called in staticmesh.cpp

Line 6516 C:\UE\UnrealEngine\Engine\Source\Runtime\Engine\Private\StaticMesh.cpp:

But i have troubles to locate the source code that delivers these imported Data from interchange. There are some virtual function that are maybe overwritten by generated source code after compiling that makes finding difficult.

void UStaticMesh::BuildFromMeshDescription(const FMeshDescription& MeshDescription, FStaticMeshLODResources& LODResources)

  1. Where in the Interchange System is the MeshDescription generating Function in the Source Code ?

My general Problem is that in the “normal” Static Mesh Import Result the CPU-Data is not imported, although the interchange importer has it for sure. The CPU-Data I am looking for is nothing magical, it’s only the unoptimized Vertexes:

staticmesh.cpp 1519 Funktion:
void FStaticMeshLODResources::DiscardCPUData()
{
VertexBuffers.StaticMeshVertexBuffer.CleanUp();
VertexBuffers.PositionVertexBuffer.CleanUp();
VertexBuffers.ColorVertexBuffer.CleanUp();
IndexBuffer.Discard();
DepthOnlyIndexBuffer.Discard();
UE_LOG(LogStaticMesh, Display, TEXT(“In StaticMesh.cpp CPU DATA is Discarded”));
if (AdditionalIndexBuffers)
{
AdditionalIndexBuffers->ReversedIndexBuffer.Discard();
AdditionalIndexBuffers->ReversedDepthOnlyIndexBuffer.Discard();
AdditionalIndexBuffers->WireframeIndexBuffer.Discard();
}

#if RHI_RAYTRACING
RayTracingGeometry.RawData.Discard();
#endif
}

hi, thank you for posting this up!
I need the feature as well!
I am using Niagara system to sample dynamic generated mesh which “Allow CPU access” is turned off by default! And this causes it sampled improperly!
So annoying, did you find a solution yet?

Hi, Yes, I did find a solution:

I Just recompiled the complete Unreal Engine (5.2) with this little change:

in Line 3334 in the constructor of the static mesh in C:\UE\UnrealEngine\Engine\Source\Runtime\Engine\Private\StaticMesh.cpp I added this line:


bAllowCPUAccess = true;

And it is working (not direct, but i can import from the static Mesh that was created by interchange to dynamic mesh )
Extra Info Fastbuild:
I also tried with bDoFastBuild = true; AND false. In both cases it is working, what surprised me somehow. Does someone know what Dofastbuild is exactly ?

  1. This is a quite dirty solution so far, since every static mesh will have CPU Access Data,
    costing resources. So we should make it smarter.

  2. A Script Node with a Singleton Boolean that can be switched on and off, would do the trick. Every time a static mesh is constructed, it could check the Value of this Bool Variable.

  3. The Interchange Manager is already a singleton object so I added:

InterchangeManager.h line 279:
USTRUCT(BlueprintType)
struct INTERCHANGEENGINE_API FImportAssetParameters

InterchangeManager.h line 295:
	// Define a Bool that the static Mesh constructor checks on creating a new static mesh 
	// The constructor than sets its own bool accordingly
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Interchange|ImportAsset")
	bool bKeepCPUData = false;

but had some troubles with including interchangemanager.h in staticmesh.cpp (Now, I know it better, you have to rebuild the solution file every time you add a new include. )

I hope this change would make it in the Unreal Engine, so that the recompilation is no longer necessary to use this feature.

I hope it Helps :+1:

1 Like

This is awesome!! Thanks for posting it up!