Skip to content

Commit

Permalink
Merge pull request #19 from planetx-vfx/feature/FP-86/add-multiple-pr…
Browse files Browse the repository at this point in the history
…eview-exports

FP-86 Add multiple exports to the preview delivery
  • Loading branch information
MaximumFX authored Oct 4, 2024
2 parents 4272eb4 + 2efe989 commit 330cd7c
Show file tree
Hide file tree
Showing 12 changed files with 325 additions and 97 deletions.
18 changes: 17 additions & 1 deletion info.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ configuration:

delivery_preview:
type: template
fields: context, prj, delivery_date, delivery_version, task_name, version, *
fields: context, prj, delivery_date, delivery_version, task_name, version, delivery_preview_extension, *
description: "Template to deliver the previews to."

csv_submission_form:
Expand All @@ -57,6 +57,22 @@ configuration:
fields: context, *
description: "Folder to saves CSV templates."

# --- LISTS ---
delivery_preview_outputs:
type: list
values:
type: dict
items:
name:
type: str
extension:
type: str
default_enabled:
type: bool
default_value: true
settings:
type: dict

# --- STRINGS ---
shot_status_field:
type: str
Expand Down
64 changes: 63 additions & 1 deletion python/app/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ def __init__(self):
self.connect_buttons()
self.load_shots()
self.load_csv_templates()
self.load_preview_outputs()

def closeEvent(self, event):
"""
Expand Down Expand Up @@ -195,6 +196,48 @@ def load_letterbox_defaults(self, project):
)
self.view.settings["letterbox_h"].setText("1")

def load_preview_outputs(self):
"""Load the preview output checkboxes"""
for i, output in enumerate(
self.model.settings.delivery_preview_outputs
):
key = f"preview_output_{i}_enabled"
self.view.settings[key] = QtWidgets.QCheckBox(
text=f"{output.extension.upper()} - {output.name}",
objectName=key,
)
self.view.settings[key].setChecked(output.default_enabled)
self.view.settings[key].stateChanged.connect(
self.toggle_preview_output
)
self.view.preview_outputs.addWidget(self.view.settings[key])

def toggle_preview_output(self, state):
"""Disable other conflicting output previews"""
if state != QtCore.Qt.Checked:
return

key = self.sender().objectName()
index = int(re.match("preview_output_([0-9]+)_enabled", key).group(1))

toggled_output = self.model.settings.delivery_preview_outputs[index]

other_outputs = [
po
for po in self.model.settings.delivery_preview_outputs
if po.extension == toggled_output.extension
and po != toggled_output
]

if len(other_outputs) == 0:
return

for output in other_outputs:
i = self.model.settings.delivery_preview_outputs.index(output)
if i == -1:
continue
self.view.settings[f"preview_output_{i}_enabled"].setChecked(False)

def open_delivery_folder(self):
"""Opens the delivery folder."""
self.model.open_delivery_folder()
Expand Down Expand Up @@ -409,6 +452,21 @@ def get_user_settings(self) -> UserSettings | None:
float(self.view.settings["letterbox_opacity"].text()),
)

delivery_preview_outputs = []
input_preview_outputs = list(
enumerate(self.model.settings.delivery_preview_outputs)
)
input_preview_outputs.reverse()
for i, output in input_preview_outputs:
if self.view.settings[f"preview_output_{i}_enabled"].isChecked():
if not any(
[
output.extension == out.extension
for out in delivery_preview_outputs
]
):
delivery_preview_outputs.append(output)

csv_fields = []
csv_success = True
if self.view.settings["csv_fields"].size() > 0:
Expand Down Expand Up @@ -463,5 +521,9 @@ def get_user_settings(self) -> UserSettings | None:
return None

return UserSettings(
delivery_version, delivery_location, letterbox, csv_fields
delivery_version,
delivery_location,
letterbox,
delivery_preview_outputs,
csv_fields,
)
147 changes: 84 additions & 63 deletions python/app/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -688,11 +688,6 @@ def deliver_version(
delivery_folder_template.apply_fields(template_fields)
)

# Get the output preview path
output_preview_path = Path(
delivery_preview_template.apply_fields(template_fields)
)

# Get the input preview path
preview_movie_file = Path(version.path_to_movie)

Expand All @@ -709,60 +704,94 @@ def deliver_version(
/ delivery_folder_name
)

output_preview_path = (
delivery_folder / output_preview_path.name
)

delivery_sequence_path = (
delivery_folder
/ delivery_sequence_path.parent.name
/ delivery_sequence_path.name
)

# Get count of total jobs
preview_jobs = 0
if deliverables.deliver_preview:
process = NukeProcess(
version,
show_validation_error,
show_validation_message,
update_progress_bars,
0.5 if deliverables.deliver_sequence else 1.0,
)
args = [
"-t",
self.slate_path,
str(version.first_frame),
str(version.last_frame),
str(version.fps),
preview_movie_file.as_posix(),
output_preview_path.as_posix(),
self.settings.sg_server_path,
self.settings.sg_script_name,
self.settings.sg_script_key,
self.logo_path,
"--version-id",
version.id_str,
"-idt",
self.settings.preview_colorspace_idt,
"-odt",
self.settings.preview_colorspace_odt,
"--font-path",
self.font_path,
"--font-bold-path",
self.font_bold_path,
]
if timecode_ref_path is not None:
args.extend(["--timecode-ref", str(timecode_ref_path)])
if user_settings.letterbox is not None:
args.extend(["--letterbox", str(user_settings.letterbox)])

process.run(
self.nuke_path,
args,
)
preview_jobs = len(user_settings.delivery_preview_outputs)
sequence_jobs = 0
if deliverables.deliver_sequence:
sequence_jobs = 1

self.logger.info(
f"Finished rendering preview to {output_preview_path}."
)
total_jobs = preview_jobs + sequence_jobs
current_job = 0

def update_progress(progress: float):
version.progress = (progress + current_job) / total_jobs
update_progress_bars(version)

if deliverables.deliver_preview:
for output in user_settings.delivery_preview_outputs:

preview_template_fields = {
**template_fields,
"delivery_preview_extension": output.extension,
}
# Get the output preview path
output_preview_path = Path(
delivery_preview_template.apply_fields(
preview_template_fields
)
)
if user_settings.delivery_location is not None:
output_preview_path = (
delivery_folder / output_preview_path.name
)

process = NukeProcess(
version,
show_validation_error,
show_validation_message,
update_progress,
f"{output.extension.upper()} - {output.name}",
)
args = [
"-t",
self.slate_path,
str(version.first_frame),
str(version.last_frame),
str(version.fps),
preview_movie_file.as_posix(),
output_preview_path.as_posix(),
self.settings.sg_server_path,
self.settings.sg_script_name,
self.settings.sg_script_key,
self.logo_path,
"--version-id",
version.id_str,
"-idt",
self.settings.preview_colorspace_idt,
"-odt",
self.settings.preview_colorspace_odt,
"--font-path",
self.font_path,
"--font-bold-path",
self.font_bold_path,
"--write-settings",
output.to_cli_string(),
]
if timecode_ref_path is not None:
args.extend(["--timecode-ref", str(timecode_ref_path)])
if user_settings.letterbox is not None:
args.extend(
["--letterbox", str(user_settings.letterbox)]
)

process.run(
self.nuke_path,
args,
)

self.logger.info(
f"Finished rendering preview to {output_preview_path}."
)

current_job += 1

if deliverables.deliver_sequence:
# Create sequence delivery folder
Expand Down Expand Up @@ -795,18 +824,10 @@ def deliver_version(
else:
shutil.copyfile(publish_file, delivery_file)

if deliverables.deliver_preview:
version.progress = (
0.5
+ (frame - version.first_frame)
/ (version.last_frame - version.first_frame)
* 0.5
)
else:
version.progress = (frame - version.first_frame) / (
version.last_frame - version.first_frame
)
update_progress_bars(version)
update_progress(
(frame - version.first_frame)
/ (version.last_frame - version.first_frame)
)

self.logger.info(
f"Finished linking {version.sequence_path} to {delivery_sequence_path}."
Expand Down
38 changes: 26 additions & 12 deletions python/app/models/ExportShotsThread.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,17 +222,28 @@ def create_csv(
)
).name
to_deliver.append(
(sequence_name, version.sequence_path)
(sequence_name, version.sequence_path, "")
)
if deliverables.deliver_preview:
preview_name = Path(
delivery_preview_template.apply_fields(
version_template_fields
for (
output
) in self.user_settings.delivery_preview_outputs:
output_template_fields = {
**version_template_fields,
"delivery_preview_extension": output.extension,
}
preview_name = Path(
delivery_preview_template.apply_fields(
output_template_fields
)
).name
to_deliver.append(
(
preview_name,
version.path_to_movie,
output.name,
)
)
).name
to_deliver.append(
(preview_name, version.path_to_movie)
)

csv_data = {}
for (
Expand Down Expand Up @@ -260,7 +271,7 @@ def create_csv(
else:
csv_data[entity] = {}

for file_name, source_file_path in to_deliver:
for file_name, source_file_path, codec in to_deliver:
csv_fields = []

for key, value in self.user_settings.csv_fields:
Expand All @@ -278,6 +289,10 @@ def create_csv(
elif (
field == "codec" or field == "compression"
):
if codec != "":
csv_fields.append(codec)
continue

if file_name.endswith(".exr"):
metadata = (
parse_exr_metadata.read_exr_header(
Expand All @@ -295,9 +310,8 @@ def create_csv(
csv_fields.append("")
continue
else:
# Set H.264 as the codec is hardcoded in the slate Nuke script
csv_fields.append("H.264")
continue
csv_fields.append("")
continue
elif field == "folder":
csv_fields.append(delivery_folder.name)
continue
Expand Down
Loading

0 comments on commit 330cd7c

Please sign in to comment.