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

feat: Add custom OCIO config to job attachments when enabled #16

Merged
merged 12 commits into from
Sep 19, 2023
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
assetReferences:
inputs:
directories:
- /normalized/job/bundle/dir/luts
- /tmp/luts
filenames:
- /normalized/job/bundle/dir/config.ocio
- /normalized/job/bundle/dir/ocio.nk
outputs:
directories:
- /normalized/cwd/output
referencedPaths: []
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
parameterValues:
- name: Frames
value: 1-100
- name: NukeScriptFile
value: /normalized/job/bundle/dir/ocio.nk
- name: ProxyMode
value: 'false'
- name: deadline:targetTaskRunStatus
value: READY
- name: deadline:maxFailedTasksCount
value: 20
- name: deadline:maxRetriesPerTask
value: 5
- name: deadline:priority
value: 50
213 changes: 213 additions & 0 deletions job_bundle_output_tests/ocio/expected_job_bundle/template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
specificationVersion: jobtemplate-2023-09
name: ocio.nk
parameterDefinitions:
- name: NukeScriptFile
type: PATH
objectType: FILE
dataFlow: IN
userInterface:
control: CHOOSE_INPUT_FILE
label: Nuke Script File
fileFilters:
- label: Nuke Script Files
patterns:
- '*.nk'
- label: All Files
patterns:
- '*'
description: The Nuke script file to render.
- name: Frames
type: STRING
description: The frames to render. E.g. 1-3,8,11-15
minLength: 1
- name: WriteNode
type: STRING
userInterface:
control: DROPDOWN_LIST
label: Write Node
description: Which write node to render ('All Write Nodes' for all of them)
default: All Write Nodes
allowedValues:
- All Write Nodes
- Write1
- name: View
type: STRING
userInterface:
control: DROPDOWN_LIST
description: Which view to render ('All Views' for all of them)
default: All Views
allowedValues:
- All Views
- main
- name: ProxyMode
type: STRING
userInterface:
control: CHECK_BOX
label: Proxy Mode
description: Render in Proxy Mode.
default: 'false'
allowedValues:
- 'true'
- 'false'
- name: ContinueOnError
type: STRING
userInterface:
control: CHECK_BOX
label: Continue On Error
description: Continue processing when errors occur.
default: 'false'
allowedValues:
- 'true'
- 'false'
jobEnvironments:
- name: Rez
description: Initializes and destroys the Rez environment for the job.
script:
actions:
onEnter:
command: '{{ Env.File.Enter }}'
onExit:
command: '{{ Env.File.Exit }}'
embeddedFiles:
- name: Enter
filename: rez-enter.sh
type: TEXT
runnable: true
data: |
#!/bin/env bash

set -euo pipefail

if [ ! -z "{{Param.RezPackages}}" ]; then
echo "Rez Package List:"
echo " {{Param.RezPackages}}"

# Create the environment
/usr/local/bin/deadline-rez init \
-d "{{Session.WorkingDirectory}}" \
{{Param.RezPackages}}

# Capture the environment's vars
{{Env.File.InitialVars}}
. /usr/local/bin/deadline-rez activate \
-d "{{Session.WorkingDirectory}}"
{{Env.File.CaptureVars}}
else
echo "No Rez Packages, skipping environment creation."
fi
- name: Exit
filename: rez-exit.sh
type: TEXT
runnable: true
data: |
#!/bin/env bash

set -euo pipefail

if [ ! -z "{{Param.RezPackages}}" ]; then
echo "Rez Package List:"
echo " {{Param.RezPackages}}"

/usr/local/bin/deadline-rez destroy \
-d "{{ Session.WorkingDirectory }}"
else
echo "No Rez Packages, skipping environment teardown."
fi
- name: InitialVars
filename: initial-vars.sh
type: TEXT
runnable: true
data: |
#!/usr/bin/env python3
import os, json
envfile = "{{Session.WorkingDirectory}}/.envInitial"
with open(envfile, "w", encoding="utf8") as f:
json.dump(dict(os.environ), f)
- name: CaptureVars
filename: capture-vars.sh
type: TEXT
runnable: true
data: |
#!/usr/bin/env python3
import os, json, sys
envfile = "{{Session.WorkingDirectory}}/.envInitial"
if os.path.isfile(envfile):
with open(envfile, "r", encoding="utf8") as f:
before = json.load(f)
else:
print("No initial environment found, must run Env.File.CaptureVars script first")
sys.exit(1)
after = dict(os.environ)

put = {k: v for k, v in after.items() if v != before.get(k)}
delete = {k for k in before if k not in after}

for k, v in put.items():
print(f"updating {k}={v}")
print(f"openjd_env: {k}={v}")
for k in delete:
print(f"openjd_unset_env: {k}")
steps:
- name: Render
parameterSpace:
taskParameterDefinitions:
- name: Frame
type: INT
range: '{{Param.Frames}}'
stepEnvironments:
- name: Nuke
description: Runs Nuke in the background with a script file loaded.
script:
embeddedFiles:
- name: initData
filename: init-data.yaml
type: TEXT
data: |
continue_on_error: {{Param.ContinueOnError}}
proxy: {{Param.ProxyMode}}
script_file: '{{Param.NukeScriptFile}}'
write_nodes:
- '{{Param.WriteNode}}'
views:
- '{{Param.View}}'
actions:
onEnter:
command: NukeAdaptor
args:
- daemon
- start
- --path-mapping-rules
- file://{{Session.PathMappingRulesFile}}
- --connection-file
- '{{Session.WorkingDirectory}}/connection.json'
- --init-data
- file://{{ Env.File.initData }}
cancelation:
mode: NOTIFY_THEN_TERMINATE
onExit:
command: NukeAdaptor
args:
- daemon
- stop
- --connection-file
- '{{ Session.WorkingDirectory }}/connection.json'
cancelation:
mode: NOTIFY_THEN_TERMINATE
script:
embeddedFiles:
- name: runData
filename: run-data.yaml
type: TEXT
data: 'frame: {{Task.Param.Frame}}'
actions:
onRun:
command: NukeAdaptor
args:
- daemon
- run
- --connection-file
- '{{Session.WorkingDirectory}}/connection.json'
- --run-data
- file://{{ Task.File.runData }}
cancelation:
mode: NOTIFY_THEN_TERMINATE
25 changes: 25 additions & 0 deletions job_bundle_output_tests/ocio/scene/config.ocio
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
ocio_profile_version: 2.1

environment:
{}
search_path:
- luts
- /tmp/luts
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that we're providing both of these as input directories for job attachments. Does Nuke apply the path mapping to these search paths automatically, or do we have to do some special processing?

Also, do any of the LUT file formats contain further references to additional files?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added both search paths to this config so we could test relative and absolute. In the relative case OCIO will search relative to the config file's directory. Is that what you mean by path mapping?

Good question about the LUT files, let me take a look.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LUT files do not seem to contain references to other files.

strictparsing: true
luma: [0.2126, 0.7152, 0.0722]
name: deadline-cloud-for-nuke-test-config

roles:
{}

file_rules:
- !<Rule> {name: Default, colorspace: default}

displays:
{}

active_displays: []
active_views: []

colorspaces:
[]
75 changes: 75 additions & 0 deletions job_bundle_output_tests/ocio/scene/ocio.nk
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#! /opt/nuke/Nuke14.0v5/libnuke-14.0.5.so -nx
#write_info Write1 file:"output/output_%04d.png" format:"2048 1556 1" chans:":rgba.red:rgba.green:rgba.blue:" framerange:"1 100" fps:"0" colorspace:"matte_paint" datatype:"8 bit" transfer:"unknown" views:"main" colorManagement:"OCIO"
version 14.0 v5
define_window_layout_xml {<?xml version="1.0" encoding="UTF-8"?>
<layout version="1.0">
<window x="0" y="27" w="1512" h="848" maximized="1" screen="0">
<splitter orientation="1">
<split size="40"/>
<dock id="" hideTitles="1" activePageId="Toolbar.1">
<page id="Toolbar.1"/>
</dock>
<split size="849" stretch="1"/>
<splitter orientation="2">
<split size="473"/>
<dock id="" activePageId="Viewer.1">
<page id="Viewer.1"/>
</dock>
<split size="332"/>
<dock id="" activePageId="DAG.1" focus="true">
<page id="DAG.1"/>
<page id="Curve Editor.1"/>
<page id="DopeSheet.1"/>
</dock>
</splitter>
<split size="615"/>
<dock id="" activePageId="Properties.1">
<page id="Properties.1"/>
<page id="uk.co.thefoundry.backgroundrenderview.1"/>
<page id="Scenegraph.1"/>
</dock>
</splitter>
</window>
</layout>
}
Root {
inputs 0
name /home/rocky/src/deadline-cloud-for-nuke/job_bundle_output_tests/ocio/scene/ocio.nk
format "2048 1556 0 0 2048 1556 1 2K_Super_35(full-ap)"
proxy_type scale
proxy_format "1024 778 0 0 1024 778 1 1K_Super_35(full-ap)"
colorManagement OCIO
OCIO_config custom
customOCIOConfigPath /home/rocky/src/deadline-cloud-for-nuke/job_bundle_output_tests/ocio/scene/config.ocio
defaultViewerLUT "OCIO LUTs"
workingSpaceLUT scene_linear
monitorLut 0
monitorOutLUT "sRGB (default)"
int8Lut matte_paint
int16Lut texture_paint
logLut compositing_log
floatLut scene_linear
}
ColorBars {
inputs 0
name ColorBars1
xpos -53
ypos -134
}
set Nca0bef0 [stack 0]
Write {
file output/output_####.png
colorspace matte_paint
file_type png
checkHashOnRead false
name Write1
xpos 11
ypos -17
}
push $Nca0bef0
Viewer {
frame_range 1-100
name Viewer1
xpos -139
ypos 52
}
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ explicit_package_bases = true
mypy_path = "src"

[[tool.mypy.overrides]]
module = ["nuke.*","PySide2.*"]
module = ["nuke.*","PySide2.*","PyOpenColorIO.*"]
ignore_missing_imports = true

[tool.ruff]
Expand Down
Loading