Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unreal: Added settings for rendering #4575

Merged
merged 5 commits into from
Apr 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 52 additions & 19 deletions openpype/hosts/unreal/api/rendering.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import unreal

from openpype.settings import get_project_settings
from openpype.pipeline import Anatomy
from openpype.hosts.unreal.api import pipeline
from openpype.widgets.message_window import Window
Expand Down Expand Up @@ -33,7 +34,7 @@ def start_rendering():
"""
Start the rendering process.
"""
print("Starting rendering...")
unreal.log("Starting rendering...")

# Get selected sequences
assets = unreal.EditorUtilityLibrary.get_selected_assets()
Expand Down Expand Up @@ -76,6 +77,13 @@ def start_rendering():

ar = unreal.AssetRegistryHelpers.get_asset_registry()

data = get_project_settings(project)
config = None
config_path = str(data.get("unreal").get("render_config_path"))
if config_path and unreal.EditorAssetLibrary.does_asset_exist(config_path):
unreal.log("Found saved render configuration")
config = ar.get_asset_by_object_path(config_path).get_asset()

for i in inst_data:
sequence = ar.get_asset_by_object_path(i["sequence"]).get_asset()

Expand All @@ -91,55 +99,80 @@ def start_rendering():
# Get all the sequences to render. If there are subsequences,
# add them and their frame ranges to the render list. We also
# use the names for the output paths.
for s in sequences:
subscenes = pipeline.get_subsequences(s.get('sequence'))
for seq in sequences:
subscenes = pipeline.get_subsequences(seq.get('sequence'))

if subscenes:
for ss in subscenes:
for sub_seq in subscenes:
sequences.append({
"sequence": ss.get_sequence(),
"output": (f"{s.get('output')}/"
f"{ss.get_sequence().get_name()}"),
"sequence": sub_seq.get_sequence(),
"output": (f"{seq.get('output')}/"
f"{sub_seq.get_sequence().get_name()}"),
"frame_range": (
ss.get_start_frame(), ss.get_end_frame())
sub_seq.get_start_frame(), sub_seq.get_end_frame())
})
else:
# Avoid rendering camera sequences
if "_camera" not in s.get('sequence').get_name():
render_list.append(s)
if "_camera" not in seq.get('sequence').get_name():
render_list.append(seq)

# Create the rendering jobs and add them to the queue.
for r in render_list:
for render_setting in render_list:
job = queue.allocate_new_job(unreal.MoviePipelineExecutorJob)
job.sequence = unreal.SoftObjectPath(i["master_sequence"])
job.map = unreal.SoftObjectPath(i["master_level"])
job.author = "OpenPype"

# If we have a saved configuration, copy it to the job.
if config:
job.get_configuration().copy_from(config)

# User data could be used to pass data to the job, that can be
# read in the job's OnJobFinished callback. We could,
# for instance, pass the AvalonPublishInstance's path to the job.
# job.user_data = ""

output_dir = render_setting.get('output')
shot_name = render_setting.get('sequence').get_name()

settings = job.get_configuration().find_or_add_setting_by_class(
unreal.MoviePipelineOutputSetting)
settings.output_resolution = unreal.IntPoint(1920, 1080)
settings.custom_start_frame = r.get("frame_range")[0]
settings.custom_end_frame = r.get("frame_range")[1]
settings.custom_start_frame = render_setting.get("frame_range")[0]
settings.custom_end_frame = render_setting.get("frame_range")[1]
settings.use_custom_playback_range = True
settings.file_name_format = "{sequence_name}.{frame_number}"
settings.output_directory.path = f"{render_dir}/{r.get('output')}"
settings.file_name_format = f"{shot_name}" + ".{frame_number}"
settings.output_directory.path = f"{render_dir}/{output_dir}"

renderPass = job.get_configuration().find_or_add_setting_by_class(
job.get_configuration().find_or_add_setting_by_class(
unreal.MoviePipelineDeferredPassBase)
renderPass.disable_multisample_effects = True

job.get_configuration().find_or_add_setting_by_class(
unreal.MoviePipelineImageSequenceOutput_PNG)
render_format = data.get("unreal").get("render_format", "png")

if render_format == "png":
job.get_configuration().find_or_add_setting_by_class(
unreal.MoviePipelineImageSequenceOutput_PNG)
elif render_format == "exr":
job.get_configuration().find_or_add_setting_by_class(
unreal.MoviePipelineImageSequenceOutput_EXR)
elif render_format == "jpg":
job.get_configuration().find_or_add_setting_by_class(
unreal.MoviePipelineImageSequenceOutput_JPG)
elif render_format == "bmp":
job.get_configuration().find_or_add_setting_by_class(
unreal.MoviePipelineImageSequenceOutput_BMP)

# If there are jobs in the queue, start the rendering process.
if queue.get_jobs():
global executor
executor = unreal.MoviePipelinePIEExecutor()

preroll_frames = data.get("unreal").get("preroll_frames", 0)

settings = unreal.MoviePipelinePIEExecutorSettings()
settings.set_editor_property(
"initial_delay_frame_count", preroll_frames)

executor.on_executor_finished_delegate.add_callable_unique(
_queue_finish_callback)
executor.on_individual_job_finished_delegate.add_callable_unique(
Expand Down
3 changes: 3 additions & 0 deletions openpype/settings/defaults/project_settings/unreal.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
},
"level_sequences_for_layouts": false,
"delete_unmatched_assets": false,
"render_config_path": "",
"preroll_frames": 0,
"render_format": "png",
"project_setup": {
"dev_mode": true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,28 @@
"key": "delete_unmatched_assets",
"label": "Delete assets that are not matched"
},
{
"type": "text",
"key": "render_config_path",
"label": "Render Config Path"
},
{
"type": "number",
"key": "preroll_frames",
"label": "Pre-roll frames"
},
{
"key": "render_format",
"label": "Render format",
"type": "enum",
"multiselection": false,
"enum_items": [
{"png": "PNG"},
{"exr": "EXR"},
{"jpg": "JPG"},
{"bmp": "BMP"}
]
},
{
"type": "dict",
"collapsible": true,
Expand Down
Loading