Optimizing Blueprint for Large-Scale Mesh Handling and Dynamic Coloring

Hi Unreal Engine community,

I am working on a Blueprint that imports approximately 34,000 building meshes from Rhino and uses a table to dynamically change the color of each mesh based on specific criteria. While the Blueprint functions correctly, the execution time is quite slow, taking about 2 minutes per operation. I’m seeking suggestions on how to optimize this to enhance performance.

Blueprint Description: Large-Scale Mesh Handling and Dynamic Coloring posted by anonymous | blueprintUE | PasteBin For Unreal Engine

Purpose: Dynamically changes the color of each building mesh based on data from an imported table.
Process: Automatically imports around 34,000 meshes from Rhino and reads from a table to apply color changes.

Challenges:
The process is significantly slow, and I’m looking to reduce the execution time.
Concerned about whether the volume of meshes being imported and manipulated could be impacting performance.

I would greatly appreciate any insights or advice on methods to streamline this process or modify the Blueprint to improve its efficiency. If there are best practices for handling large quantities of meshes or optimizing data table interactions in Unreal Engine, I would love to learn about those.

Thank you!

Hi Sepid_ar,

We can’t see the nodes text - too blurry, you’ll need to split the snapshot into more or make it bigger.

But 34,000 staticmeshes being spawned or instanced is going to be particularly slow in BP - if you’re importing them too that’s even slower, converting to C++ would help.

1 Like

Thank you for your feedback!

I understand the need for clearer visuals of the Blueprint. Unfortunately, the forum’s limitations prevent me from uploading multiple screenshots directly here. However, I’ve created the Blueprint and provided a link where you can view the entire Blueprint setup:

Regarding the suggestion to convert to C++, I see the potential benefits for handling such a large volume of meshes more efficiently. I’m not very experienced with C++, so any specific guidance on how to start this transition, or particular classes and functions that could be useful, would be greatly appreciated.

Thanks again for your help!

Thanks for that - perfect!

Seeing as the StaticMeshActors are already in the level and you’re just enumerating them you should be able to create this fast enough in Blueprint.

First thing, rather than use “GetAllActorsWithTag” and then cast to StaticMeshActor - use “GetAllActorsOfClassWithTag” - it enumerates a built-in list associated with that class type rather than enumerate all actors so is quite a bit faster - that should help quite a bit.
image

Also - it looks like a lot of that data could be pre-calced (e.g. the tests in floor size etc) - the data table could either have an integer index or the actual color to be used and then you could remove all the tests and set the material directly from that.

1 Like

Thankyou so much,

I have made the adjustments you suggested. Instead of using “GetAllActorsWithTag” and then casting to StaticMeshActor, I am now using “GetAllActorsOfClassWithTag”. This should indeed be more efficient.

I’ve attached the updated Blueprint. Is this what you meant?

Also, I was wondering, does using a “For Each Loop” significantly increase the playing time?

Thanks!

Yes - although you can remove the “Cast to StaticMeshActor” - you’ll find that the objects coming out of the ForEach loop are already StaticMeshActors. You could also change your “Building” variable to be a StaticMeshActor reference, then you wouldn’t need to cast when using that too - casts aren’t too slow, but any nodes not needed in For loops should be optimized out.

Yeah, ForEach loops aren’t particularly fast in BP - especially when you’re nesting them - keeping them to a minimum helps a lot. Caching information they use can also help a lot - for instance, rather than call the GetAllActorsOfClassWithTag each time, you could build a table beforehand, and just reference that.

1 Like

Thank you, RecourseDesign, for your valuable suggestions!

Based on your feedback, I’ve removed the “Cast to StaticMeshActor” since the objects coming out of the ForEach loop are already StaticMeshActors. Also I do not know how to adjusted the “Building” variable to be a StaticMeshActor reference, eliminating the need for casting in this context.

Regarding your advice on optimizing ForEach loops and caching, I’ve attempted to pre-build a table to avoid repeatedly calling GetAllActorsOfClassWithTag during each iteration. I’ve attached a screenshot of the updated Blueprint setup. Could you please confirm if this is what you meant by caching the data for better performance?

Thanks again for your help!

No problem :slight_smile:

You can change the type of the “Building” variable by clicking on the type and typing “staticmesh” into the search box, you should be able to find it then, and select “Object Reference”.

You probably won’t need it though if you’re pre-calcing things.

What I would probably do is pre-calc the data and store it in the actual actors as Tags (or DataAssets which would be faster, but need c++). Then you could just enumerate all actors with a tag you add (something like “usrRhino”) and update their materials straight from the rest of the tags.

I’ve uploaded some clips (not tested, just concept).

The Pre-Calc routine (a Begin-Play, or Call-in-Editor button in a Blueprint - that way you can save the tags with the level and not have to run it each time):

And the routine for when the selection has changed:

1 Like

Thank you so much for your time, RecourseDesign. The two Blueprints you shared were very expert and eye-opening. However, I wanted to clarify why the second part might not work for our project. We are modeling the buildings of an entire city, and we only receive the building meshes from Rhino. Additionally, we have a data table from GIS with specific data for each building. Both the meshes from Rhino and the data from ArcGIS share the same Rhino ID.

In our Blueprint, we aim for Unreal Engine to fetch the data from the GIS table and match it with the Rhino ID from the imported meshes. Based on this data, we then change the color of the meshes accordingly. Therefore, we cannot apply materials to the meshes in Rhino before importing them to Unreal Engine, as shown in this blueprint.

I see - nice!

You can still use that system, in your OnClicked event there, you can be storing the tags in much the same way as the BeginPlay pre-calc does - during play the tags are applied to the actor instances so once set from the OnClicked, your OnSelectionChanged event could be like the one I posted and work.

It does mean you’ll get the long pause when you load the houses - but it should be a lot faster after that.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.