Unreal converter C++ help

Hey guys,

I’m not sure where to post this and if this is not appropriate please help me move this (there is also no C++ tag).
I havent been in C++ for awhile and also unfamiliar with unreal in general and looking the code has left me stuck at some place I am not sure how to find out about.
Basically I’ve traced the SpeckleConverters in the speckle-unreal connector to the
UObject* UAggregateConverter::ConvertToNativeInternal(const UBase* Object, UWorld* World) function (AggregateConverter.cpp, Line 49), in which it returns Execute_ConvertToNative(Converter, Object, World, MainConverter)

I am not sure where this leads as it seems to refer to the SpeckleConverter.generated files. Visual Studio also stops at ISpeckleConverter’s GENERATED_BODY() line.

My question is if there is a way for me to understand how you are achieving this, and a way for me to trace past this point, because I do not see the actual declaration for the function anywhere? is there a function type that prepends “Execute_” and its recognised by Unreal? I’m quite lost as to where to start looking, and a few pointers in the right direction would be very much welcome.

I was actually looking to see if i could add some stuff if i could get familiar enough with the code base.
At this instance possibly just a quick-fix to add simple collision box to the environment to be able to interact with (mostly the floor and walls) the model. A hint on the general area where this could be achieved would be appreciated as well.
And since I’m here i was wondering if that’s on the roadmap anywhere for the unreal connector.

I hope this is okay and thanks for always being a great help.

1 Like

Hi @eugeneida

Looks like you’ve really taken a deep dive into the Unreal connector, impressive :raised_hands:

Hopefully I can help illuminatesome things (although, this level of depth isn’t strictly necessary to understand if your goal is to write some custom conversion logic, see last few paragraphs)

You’re suspicion was mostly correct. The GENERATE_BODY() macro is used by the UHT source generator, and is required by all classes marked with UClass or USTRUCT.
This macro populates the .generated file with the required constructors and blueprint thunks (yes they are called thunks) to allow a class to work with Unreal’s serialization/reflection and garbage collection system, which are the foundation to how UObjects operate. The .generate files are quite scary, and not really fit for human consumption so I’d recommend not looking at them directly for too long :grin:.

In the case of interfaces like ISpeckleConverter, Unreal does a lot of magic behind the scene to allow them to used and implemented by Blueprint.

So the ISpeckleConverter interface defines a ConvertToNative function.
C++ implementers will implement a ConvertToNative_Implementation function.
And callers will call the Execute_ConvertToNative function.

Not intuitive I know! But this is the Unreal way, and is what facilitates the interop between Unreals blueprint system.
The Unreal docs provide a more complete explanation if you’re curious.


On the topic of using Speckle Unreal,
I recommend you first checkout this tutorial Unreal - Developing Custom Object Conversions that walks you through how you can create your own custom converter.

In your case, you could create a custom mesh converter that first calls the existing and then attaches a collider component.
You can do this in either C++ or Blueprint, either way, you’ll be creating a UObject class/bp that implements ISpeckleConverter and implements CanConvertToNative and ConvertToNative.
Likely, you’ll want to declare a UPROPERTY to pass in the existing mesh converter so that can be called from your function. Then you write your own logic to attach any custom Components you desire.

We did something pretty similar here Grasshopper to Unreal - asset swap / mapping meshes from Grasshopper proof of concept in Blueprint to swap some meshes with native ones.

You may instead prefer to extend/inherit the existing StaticMeshConverter to override the functions you need. This can only be done in C++.

A lot of this can be quite daunting if you’re new to either C++, Unreal, or Speckle. So please don’t hesitate to ask any questions.
And let me know how you get on (since what you’re describing sounds super cool :grin:, id love to hear about your progress)


And as a side note; Generally it’s preferred that you write your own classes rather than modify the existing classes. To avoid any conflicting changes when you come to update your connector with a newer version. Unless of course you’re just experimenting, or looking to contribute back to the Unreal connector, then fork away!

Hi Jedd,

Thanks for the prompt reply as always. There a few things coming up immediately for me (outside of speckle) so i’ll reply first.

So the ISpeckleConverter interface defines a ConvertToNative function.
C++ implementers will implement a ConvertToNative_Implementation function.
And callers will call the Execute_ConvertToNative function.
This was the suspicion and I’m glad for your confirmation. So there is some Unreal magic to put these together and link them as long as they follow this pattern.

I’ll definitely look up the interface doc, it is what i needed. Thanks alot!

On the topic of using Speckle Unreal,
I recommend you first checkout this tutorial Unreal - Developing Custom Object Conversions that walks you through how you can create your own custom converter

I didnt see this back then when I was looking it up, but a cursory glance seems to be what i was wanting to know about Speckle. Also very helpful, again thanks!

And as a side note; Generally it’s preferred that you write your own classes rather than modify the existing classes. To avoid any conflicting changes when you come to update your connector with a newer version. Unless of course you’re just experimenting, or looking to contribute back to the Unreal connector, then fork away!

Oh I plan to give you lots of trouble! :slight_smile: Well to be honest, we are still quite early in development and we definitely haven’t ruled out contributing back to the connector, but absolutely nothing is concrete and we’ll see how we progress.

It might be awhile before I post again maybe in this same thread, but I hope to do so as soon as I can!

Hi Jedd,

Had a few things happen, but now I’m back with Speckle for now. So I’m here to bug you about several things (but mostly just one for now)!

I have decided to just get going and try out your Tutorial you’ve linked over here : Unreal - Developing Custom Object Conversions

I am coming from the perspective from someone quite clueless to what is happening in Unreal and Speckle workings in general. So I have some feedback about it.

I wanted to try creating a custom View but decided to just follow the tutorial first, 1) just in case i did anything wrongly i can just refer, 2) I could just copy paste for how without worrying too much about the syntax or anything and try to understand what’s happening instead of getting bogged down by all the details, 3) I was initially also under the impression this was a walk-through example, but it seems more like a explanatory sample. However, View3D was already in use, thus preventing me from just copy pasting. Not a big deal, I just had a View3DModified as a starter, but it would be nice to have something that I could just follow through.

The video/snapshots are made with UE4, which from a new Unreal user starting from UE5, took me a small amount of time to figure out the translations (/mapping to UE5). Also I am not certain if this is a UE4->UE5 difference, but I could not select “Base” as a type (from the dropdown of Input/Output types), I am trying to select “Object” (Seems to say UObject, base of all objects) but I am not sure if this is correct (I am not sure what is the difference). Things seem to work (I think) but I got stuck at a later point, so I cannot be sure.

Now comes to where I am stuck and I have no clue how to proceed.

If you are unable to set an input of type World, then add a Spawn Actor in World node, then collapse to function.

I have done exactly this as I have faced this problem. I could not select “world” and so I’ve created the spawn actor ( where? I’ve tried a few places) and then collapse to function (where to reference this function?) and I still can’t select world and am not quite sure how to pass what is needed. Not quite sure what exactly is happening (Sorry I’m lost!), So I can’t figure it out yet.

Some more feedback at this point:
Some parts are not so explicit and I had to figure it out some parts, perhaps due to my inexperience with Unreal so it might be useful to mention, to add to the tutorial if you see fit.
For example, I did not know the best practice for extending / creating converters, and just created it somewhere in a blank project. The issue is later on when I tried to compile it, there was some linker errors and I had to add SpeckleUnreal and Json to the dependency modules in Build.cs. I hope mentioning this would help some of the later readers of the tutorial.

There is perhaps a typo here?

The ViewToNative to native function will have the following inputs/outputs.

Something else is that it could be useful to have a C++ example, perhaps just a basic one, so that the flow also could be understood, and it would help to illuminate the converters you’ve already done.

I say this as for now I am giving a go at looking at the C++ implementations you have done for the converters, for example StaticMeshConverter but have been finding it a bit obtuse for me but I am working through it for now.

Thanks again for your time.

It occurs to me i should upload my current progress so here it is



1 Like

Hi,

Its been some time and I think perhaps I was too verbose and you might have missed the question amongst all my ramblings and suggestions. Basically I need some clarity about this part

If you are unable to set an input of type World, then add a Spawn Actor in World node, then collapse to function.

and what to do after. (Screenshots in previous post)

Also I’ve been taking a look at the C++ implementation like I said I would and there is something perplexing to me.

Tracing the implementation of converting the meshes into unreal Actors/Objects, leads me to theUAggregateConverter::ConvertToNativeInternal function. This function, has some checks and terminates if a valid converter is not found… and then calls itself. I do not see at any point how is achieving the instantiation of the object… It seems like it just recursively calls itself. I hope you can help me see what I seem to be missing here.

Thanks

Hi @eugeneida,

Thank you for your patience.
I think, all you need to do is hook up the world input to world input of View To Native.

Apologies, the tutorial is not super clear about this.


You may have to point me towards the lines you’re referring to here.
Is it this call to Execute_ConverToNative? in which case, the first paramter is the converter this will be called on, not the aggregate converter. (again, this is is Unreal’s magic source generation for blueprintable interfaces, you’ll notice that function is static)

Hi Jedd,

No problem, figured you had some time off during the holidays, hope you had a good one.

I think, all you need to do is hook up the world input to world input of View To Native.

I see I wasnt exactly clear here. In the previous (more lengthy) post, I described being unable to choose the World then i added Spawn Actor in World and collapsed to a function:

But I am here, and it looks like this :


Screenshot 2024-01-03 155529

I am unable to select the view3d class now, and Spawn Actor in World complains that Transform is a required input. I’m not sure what or which transform this should be either. This is where I meant that the tutorial just mentions this one line and could be expanded as I am not quite sure how to proceed.

This part is about the C++ portion.
Yes, you are right, I had initially misunderstood what it was trying to do and it was confusing me and I managed to figure it out by printing out each step of the conversion so I finally traced it to SpecleConverterComponent (for the relevant part i was looking at)

However, after Line 89 : AActor* ConvertedAsActor = Cast<AActor>(Converted);
adding ConvertedAsActor->SetActorEnableCollision(true); causes a crash in the unreal editor at Line 94 at the IsValid check. I do not know why this is so and havent been able to figure out as it should still be an actor.

I am trying to add some default collision and as a try I’m trying it out at this spot. Is this not correct?

Again, thanks for all the help.