Create a custom Render Graph node and pre-populate values?

Hi,<br>

I’m working on integrating Render Graph into our pipeline, and I need to be able to set some variables ahead of time in order to interact properly with our publish process.

I’ve been able to access and set MRG variables with the ExecuteScript node - but what I would like is a custom Node that I can prepopulate with the allowed options from the users environment.

Meaning I would like:

A node that can either execute a command to populate when created

or

A node that I can populate different UI elements with the necessary information.

I haven’t been able to find much information on either - could someone point me in the right direction?

Possibly there is a base node that I can inherit from?

I’m mostly developing in Python, but if it needs to be C++ that’s fine. Just looking for a way forward.

Side question:

Currently to access MRG variables I am:

calling **get_or_create_variable_overrides()**

looping through all variables to get the proper one

setting the value

updating with: **update_graph_variable_overrides()**

This feels like it is a bit work for setting vars. Am I missing an easier way? Or is this the the proper workflow?

I’m not entirely sure I understand what the specific goal is here. Nodes in general are self-contained and not intended to be able to edit other nodes. It’s not clear to me if you just want a node that has properties on it (in the details panel) that you can then read from your Execute Script node, or if you’re trying to set default values for Graph User Variables, or if you’re trying to set different default values for other node’s properties (ie: changing the default Output Directory in the Global Output Settings node).

A general overview of the graph is that you can have multiple copies of nodes in the graph, and then at runtime, we “flatten” the graph, giving priority to a property found further downstream (further to the right), based on whether or not the Override checkbox is checked on the left side of a property. So if you want to override an existing node’s values, the intention is that you re-declare that node with a new value and the override checked, and you won’t have to make any edits to the upstream value. It is not designed for nodes to be able to change other node’s properties, and it’s not designed that a node can change the User Variables when added.

The Execute Script node is run once the render starts, and is given a copy of the graph, allowing you to make topology/value changes without worrying about the changes leaking back out to the saved assets. So it is generally recommended that your execute script node is the one who makes alterations to the actual graph at runtime, based on looking up values from either things in the graph, or User Variables.

If you’re just looking to create a new node that has properties in the Details Panel that you can read from your Execute Script node to do further work to the overall graph, you’ll need to use C++ (as Python classes cannot be serialized). You can do this by inheriting from UMovieGraphSettingNode. Please note that the bOverride_ pattern is required for the value to show up in the final flattened graph, ie:

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Overrides, meta = (InlineEditConditionToggle))

uint8 bOverride_OutputDirectory : 1;

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = “File Output”, meta=(EditCondition=“bOverride_OutputDirectory”))

FDirectoryPath OutputDirectory;

The bOverride_ variable name must EXACTLY match the variable name, just with a bOverride_ prefix.

With regard to the get_or_create_variable_overrides, the API for this has improved in the upcoming 5.6 release, and you can now search for nodes by name, so it now looks closer to:

`variable_overrides = my_job.get_or_create_variable_overrides(graph_asset)

variable_overrides.set_value_int32(graph_asset.get_variable_by_name(“TileCount”), tileCount)
variable_overrides.set_variable_assignment_enable_state(graph_asset.get_variable_by_name(“TileCount”), True)
variable_overrides.set_value_float(graph_asset.get_variable_by_name(“OverlapPercentage”), overlapRatio * 100)
variable_overrides.set_variable_assignment_enable_state(graph_asset.get_variable_by_name(“OverlapPercentage”), True)`

The variables that exist inside of the job are separate from the actual graph variables (as they can have their own values that are unique from the defaults set in the Graph), which is why the job has a get_or_create_variable_overrides call, it creates the container that stores a copy of the variables and their values.

Hey [mention removed]​, thanks for the response.

To clarify a little, the node doesn’t need to affect other nodes. It can be self contained.

What I am trying to do is create a command line argument at the end of the render, to call a publish process. But I would like a node to be populated, dynamically, with options for the publish process.

Meaning, I want the node to call out to the pipeline, gather said options, and display them to the user for override. I would need to grab that before the graph starts.

I assume I will have to inherit a node for that. I’ll take a look at UMovieGraphSettingNode, but I would still take any advice.

The execute script node will collect those settings and create the command at the end.

Thanks for your time.

[mention removed]​ gotcha.

I think I can get something working with this info. I’ve got a node, I’ve been able to expose those values to override and I should be able to grab them with the callbacks.

Thanks for your help.

Hey [mention removed]​ [mention removed]​

Things are running well (for local render) so far, but I have a couple of follow up questions I am hoping you can help me with.

I can’t seem to pull a string value of an DirectoryPath, on Output Directory, on_job_start. I can see the value in serialized_string but I would still have to parse it. I’m probably missing something.

I can get the value on_job_finished from the output settings, but it is still a templated string ({project_dir} for example).

Is it possible to get the resolved string value of Output Directory in the callbacks?

Or at the very least get the path as a string, rather than a serialized string, so I can replace the tokens?

Thanks for your time.

[mention removed]​ thanks for the detailed write up, that all makes sense. I think I conveniently forgot about render_layer_data, I should be able to use that.

I hope you don’t mind me chaining questions here, but I have one more and then hopefully I am off to the races - well at least until I start working on remote rendering :wink:

I am able to populate a drop down on the node with meta=(GetOptions..) to get an Array of FStrings from a function (which I am hoping will allow me to fill that array with the info I pull from the pipe) but when it appears in the Queue window - for override - it only appears as an FString. Is there a way to get the override as a dropdown as well? I would use an Enum, but that would stop me from dynamically populating the dropdown.

Thanks again, this has been really helpful.