RuntimeMeshImportExport - Import and Export runtime created static meshes using Assimp library

Amazing!! Thank you.

Available in #2](https://forums.unrealengine.com/unreal-engine/marketplace/1653161-runtimemeshimportexport-import-and-export-runtime-created-static-meshes-using-assimp-library?p=1654091#post1654091)

The editor example project was also updated to contain a seperate map with the interface used in the shipping example

Pushed version 1.9 to the marketplace with 2 fixes.

Hi, this is a great plugin!

I have been trying different things out, but can"t seem to figure out how to keep the imported meshes between app launches, so they keep their settings like static meshes can, is this possible with the current implementation?

I tried looking at some plugins that deal with saving, but they don’t support saving procedural mesh components, I’m not sure which direction should I go, where to search for a possible solution.

I noticed that there is a dna.txt file in the Binaries folder that is being generated and stays there after closing the app, but not sure if that is what I should be using to load? I couldn’t find any other files that would be generated in any of the directories, so I assume I should do the saving on my side, if they stay only in the memory until I quite the app.

There is an FBX Runtime Importer plug-in that uses “FBXMesh_Actor” which I’m not sure if it is a Procedural Mesh or a Static one, but it can also save and load between app launches, so it should be technically possible, though I couldn’t find a way how to use that plug-ins logic to also save these Procedural meshes, they have a different type. I’m trying to stick only to using blueprints, so that could be limiting my options.

Another option that I was thinking about was writing the data to a custom file, but then would I use the break RuntimeMeshImportSectionInfo to store the data and separate them in a way I can read out appropriately for CreateMeshSection to be able to read it out afterwards?

Also for importing collisions, even if I tick the “Create Collision” checkbox to generate collision for the imported mesh, if I compare the visibility channel with other meshes (which had the default collision after importing) this imported mesh doesn’t have one, and so of course also isn’t functioning, should I use custom collision meshes embedded already with a prefix from the source software, or should it still generate a default collision mesh?

Thanks!

Just write the import result to a variable and save it. Use a SaveSystem from the Marketplace. The default solution from Unreal is crap in any event.
After loading, run your normal mesh generation code.

Collision: what do you mean with does not have a visibility channel? You must setup the collision as for every other component. Click the AddProceduralMeshComponent node and see the details pannel.

Got it, thanks!

Collision is working now, I thought it didn’t because when I used “View Mode” -> “Visibility Collision” - then it didn"t show it in pink as it is doing with other models that also have collision, but then it could be related to Procedural Meshes not showing in Visibility Collision channel the same as static meshes, and I had to change a check where I was looking for specific Tag in order to do the action.

Hi, I’ve bought your olugin its working nice. I have few use cases here:

  • I want to import a skeletal mesh with morph targets in it.

would that be possible using your plugin ??

only when modified. If it works at runtime, I don`t know

我买了插件,初步测试。bug很多,非常非常多a993e838b5a5faed94d2808c6106cb92bb98f9f5.jpeg
测试了fbx的导入

  1. 没有材质球
  2. 导入的模型都是反的
    百度安全验证

作者请快速回复

  1. 我的模型文件中带有材质信息,导进去没有材质信息。还请解决。
  2. 导入之后的卡顿问题
  3. 合并材质并没有起作用, Draw Call多的离谱. 如下图

我对该插件的评价: 代码看起来很华丽,但是最终效果并不理想。尤其是导入之后的材质问题以及卡顿问题,内存方面是否有问题。

再一个可能是我对插件使用不够,还请作者出一个文档,比如导入之后Merge材质部分 。

下面摘自代码部分:
const EImportMethodSection importMethodSection = EImportMethodSection::MergeSameMaterial
UENUM(BlueprintType)
enum class EImportMethodSection : uint8
{
// Keep the sections separated
Keep,
// Merge all sections of a mesh together
Merge,
// Merge only the sections of a mesh that have the same material
MergeSameMaterial,
};

… this is an english forum and what ever that it, I can’t read it.

If german is easier for you, send me a PM.

that is chinese…

Hey! I had couple of questions for you.

  1. I was not able to import these files can you please check on them? (https://drive.google.com/drive/folders/1dqG2DbHWrZI8H0uj4yLBAcKHf5HfcmXI?usp=sharing)
  2. Are the source files available to make changes to the importer?
  3. When are you releasing an update for UE4.25?

1: .3ds

LogRuntimeMeshImportExport: ImportMeshesOfNode(64): Mesh has no sections, not adding it as mesh to the result. Node: <3DSRoot>
LogRuntimeMeshImportExport: ImportMeshesOfNode(64): Mesh has no sections, not adding it as mesh to the result. Node: carpaint
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: windows
LogRuntimeMeshImportExport: ImportMeshesOfNode(64): Mesh has no sections, not adding it as mesh to the result. Node: glass
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: plastic_tr
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: xenon_lens
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: chrome_str
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: glass_oran
LogRuntimeMeshImportExport: ImportMeshesOfNode(64): Mesh has no sections, not adding it as mesh to the result. Node: black_plas
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: glass_red
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: hybrid_log
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: register_p
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: glass_red_
LogRuntimeMeshImportExport: ImportMeshesOfNode(64): Mesh has no sections, not adding it as mesh to the result. Node: seats_whit
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: seats_blac
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: white_plas
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: interior_d
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: gps_screen
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: gauges
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: black_shin
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: red_button
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: silver
LogRuntimeMeshImportExport: ImportMeshesOfNode(64): Mesh has no sections, not adding it as mesh to the result. Node: chrome
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: net
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: glass_whit
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: glass_ora0
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: chrome_squ
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: chrome_blu
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: black_pla0
LogRuntimeMeshImportExport: ImportMeshesOfNode(64): Mesh has no sections, not adding it as mesh to the result. Node: wheel_righ
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: rim_02
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: rim_logo_0
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: wheel_nuts
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: brake_disc
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: brake_dis0
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: brake_pad_
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: brake_cali
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: tire_02
LogRuntimeMeshImportExport: ImportMeshesOfNode(64): Mesh has no sections, not adding it as mesh to the result. Node: wheel_left
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: brake_dis1
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: brake_dis2
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: brake_cal0
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: brake_pad
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: rim_logo
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: wheel_nut0
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: rim
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: tire
LogRuntimeMeshImportExport: ImportMeshesOfNode(64): Mesh has no sections, not adding it as mesh to the result. Node: wheels_rea
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: brake_dis3
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: brake_cal1
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: brake_pad0
LogRuntimeMeshImportExport: ImportMeshesOfNode(64): Mesh has no sections, not adding it as mesh to the result. Node: rim01
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: rim_logo_1
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: wheel_nut1
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: brake_dis4
LogRuntimeMeshImportExport: ImportMeshesOfNode(64): Mesh has no sections, not adding it as mesh to the result. Node: tire01
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: Object01
LogRuntimeMeshImportExport: ImportMeshesOfNode(68): Importing 1 sections for mesh: Object02

chair .fbx works without issue. you probably got a wrong path

.dae LogRuntimeMeshImportExport: Error: URuntimeMeshImportExportLibrary::ImportScene_AnyThread(958): Assimp failed to import file. File: C:\Users\vr3\Desktop\RuntimeMeshImportExportExample\issues\Car_1DAE.DAE, Error: Collada: C:\Users\vr3\Desktop\RuntimeMeshImportExportExample\issues\Car_1DAE.DAE - Expected end of <author> element.

2: everything included except assim source (github)

3: Is not possible during preview phase of the engine version. Usually 2-3 weeks after release.

Hi Rumbleball,

I’ve been playing with the plugin to see if I could export some of the designs I’ve made within the app I’m working on. After quite a bit of work, I still haven’t managed to get anything out of Unreal. I’ve noticed that the main difference between your blueprint setup (as provided in your sample) and mine is that I’m using an array of static mesh components rather than trying to export a single static mesh. I can also use an array of procedural mesh components, but using the code provided in your sample project didn’t make the cut for these use cases, and I couldn’t find any documentation for these type of situation.

Would you be able to provide an export example using several procedural mesh components or multiple static mesh components?

Are you using cpp or blueprint?
How are you retrieving the static mesh data? Static meshes must be CPU accessible (checkbox in Static Mesh Editor) (search for CPU)

The GetMeshData function from the interface asks you for an array. Just feed a array item per mesh.

All done in blueprints. The way I retrieve the static mesh data is by going over every static mesh component that I add to a blueprint which I then want to export. These static mesh components get stored into an array as they get spawned (as they are part of a builder system), and I iterate through that array on the moment I call the export function. The builder tool works by spawning several of these static mesh components at the end of a mouse trace, so whenever the user clicks on the screen a new static mesh component gets added that covers the distance between the current trace and the previous one (so the static mesh component is just a 1 metre face that sees its scale changed depending on the distance between both traces).

The way I’ve implemented the data retrieval is similar to what you have used in your sample project, which I’ll try to describe next. First, I’ve implemented the interface on the “builder” blueprint, and I’ve added a custom event that gets called whenever I want to start the export operation. The code for that event is quite straightforward, and it mimics what you have set up. This can be seen in the next image:

What I imagine is the important step in the data retrieval process is the next one, the function “GetMeshData”. What I’ve done in there is slightly different to what you have on your end, albeit very similar in concept as far as I can see. Here’s an image:

The idea is to go every static mesh component entry and copy it into a procedural mesh component, and then use a similar setup to what you have on your blueprint to retrieve the different data (vertices, tangents and all of the other bits). I’m not sure if the Copy procedural mesh from static mesh is doing its job though, as the Unreal description for that node reads that it only copies the material info (even though it says something else elsewhere on the net, not very clear on this one). Just in case this node was the faulty one, I created a variant of the function which looks like the following image:

The last picture shows something quite similar to what we did before, but using the “get static mesh” node instead of fiddling with a procedural mesh component. I really thought that would have worked, but still nothing. By nothing I mean to say that something does get exported, and you can see an fbx living in the appropriate folder, but a completely empty one once you try to open it in Max. All I get there is a scene made up from dummies, which seem to match the number of faces that I had on the original building tool at least! haha

Hope that answers the question, let me know if I can shed some more light into the system, I hope I was quite thorough - would really love to be able to export this data, seems like a very powerful tool to have :slight_smile:

Your code seems fine. Do you actually get mesh data? Try to print the vertices.

Did you make your static meshes CPU accessible?

does the log say anything?

Yup, the static meshes are accessible by the CPU. I’ve added a print string node for the vertices, and I get the following results, as seen in the images below:

CaptureB.JPG

So the position of the vertices seems to match those of the static mesh that I’m feeding the static mesh component, but with the original coordinates of the base static mesh rather than taking the scaling into account. So it seems like the “get static mesh” node I’ve highlighted won’t do the job for this particular operation, as it’s only getting the values of the original model. There would need to be a way to calculate the vertex information for a placed static mesh component after any possible transforms, which I’m not sure how to tackle… :S Also, I’m afraid that the log doesn’t say anything beyond that.

What’s also interesting is that I do manage to export something if I don’t use a for loop array, and I just select an index from my static mesh component array as seen below:

As you can see, doing that enables me to import one of the static mesh components that I’m using to feed my tool. This is a very similar process to what you’ve set up on your blueprint sample. Its name appears to be “MyMesh”, which matches the name found in the “GetHierarchicalNodeName” function. That makes me wonder if we would also need to modify said function and run a for each loop there for as many components as we have to make the exporter play nice? However I see that said function only allows for a single string to be returned, and not an array, so I’m not sure how to tackle that one.

@Brais.Brenlla you are not feeding your component transform to the export data. The StaticMesh has no transform. The transform is part of the component.
I just made a test and everything works fine.
Returning multiple elements in the array is no problem.
Check the result from the Export function.

Version for 4.25 will be pushed to the marketplace in about an hour.

Hi again!

I’ve found a workaround after a lot of work, sweat and tears, which involves recalculating all of the vertices and the accompanying data. I then used your sample procedure and it worked well. Thanks for your support so far.

Just as an idea, it would be good to have documentation available (like a PDF or something similar) that tells what each node and function in the plugin does, to be able to properly navigate it and create functionality around it.
Thanks again and cheers for the plugin :wink:

– edited as I’ve seen your reply after I posted this one