Skip to content

Commit 3cc024e

Browse files
fix: Fix an Marked takes frame issue. (#498)
Signed-off-by: Karthik Bekal Pattathana <133984042+karthikbekalp@users.noreply.github.com>
1 parent a47081c commit 3cc024e

9 files changed

Lines changed: 266 additions & 4 deletions

File tree

src/deadline/cinema4d_submitter/cinema4d_render_submitter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ def _get_parameter_values(
163163
if settings.override_frame_range:
164164
frame_list = settings.frame_list
165165
else:
166-
frame_list = Animation.frame_list()
166+
frame_list = submit_takes[0].frame_range
167167
parameter_values.append({"name": "Frames", "value": frame_list})
168168

169169
# Check for any overlap between the job parameters we've defined and the

test/AGENTS.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ Each settings case changes only the named setting group before exporting:
214214
| `shared_job_settings` | Job name, priority, maximum failed tasks, maximum retries |
215215
| `job_specific_output_path` | Override Output Path and path value |
216216
| `job_specific_multi_pass_path` | Override Multi-Pass Path and path value |
217-
| `job_specific_take_selection` | Current, Main, and All Takes modes and their generated steps |
217+
| `job_specific_take_selection` | Current, Main, Marked, and All Takes modes and their generated steps |
218218
| `physical_multi_takes` | All Takes naming, truncation, and deduplication edge cases |
219219
| `job_specific_frame_range` | Override Frame Range and frame expression |
220220
| `job_specific_detailed_logging` | Detailed logging |
@@ -223,6 +223,11 @@ Each settings case changes only the named setting group before exporting:
223223
| `job_specific_task_chunking` | Frames per chunk and target chunk duration |
224224
| `job_specific_tile_rendering` | Tile rendering, columns, and rows |
225225

226+
Unit tests in
227+
`test/unit/deadline_submitter_for_cinema4d/test_cinema4d_render_submitter.py`
228+
also cover take-name truncation, OpenJD parameter-name collisions, and `$take`
229+
path sanitization.
230+
226231
The environment-gated **Include Adaptor Wheels** developer option is excluded
227232
because it is not present in the customer-facing dialog.
228233

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
assetReferences:
2+
inputs:
3+
directories: []
4+
filenames:
5+
- PATH_TO_BE_REPLACED/deadline-cloud-for-cinema-4d/test/integ_xa11y/test_cases/job_specific_take_selection/actual/job_specific_take_selection.c4d
6+
outputs:
7+
directories:
8+
- PATH_TO_BE_REPLACED/deadline-cloud-for-cinema-4d/test/integ_xa11y/test_cases/job_specific_take_selection/actual/renders
9+
referencedPaths: []
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
parameterValues:
2+
- name: Cinema4DFile
3+
value: PATH_TO_BE_REPLACED/deadline-cloud-for-cinema-4d/test/integ_xa11y/test_cases/job_specific_take_selection/actual/job_specific_take_selection.c4d
4+
- name: SubmitterIntegrationVersion
5+
value: 0.11.4.post17.g91d4fbd80.d20260720
6+
- name: OutputPath
7+
value: PATH_TO_BE_REPLACED/deadline-cloud-for-cinema-4d/test/integ_xa11y/test_cases/job_specific_take_selection/actual/renders/job_specific_take_selection_$take
8+
- name: MultiPassPath
9+
value: ''
10+
- name: ActivateErrorChecking
11+
value: '1'
12+
- name: DetailedLogging
13+
value: '0'
14+
- name: UseCachedText
15+
value: '0'
16+
- name: ChunkSize
17+
value: 1
18+
- name: TargetChunkDuration
19+
value: 0
20+
- name: Frames
21+
value: '2'
22+
- name: deadline:targetTaskRunStatus
23+
value: READY
24+
- name: deadline:maxFailedTasksCount
25+
value: 20
26+
- name: deadline:maxRetriesPerTask
27+
value: 5
28+
- name: deadline:priority
29+
value: 50
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
specificationVersion: jobtemplate-2023-09
2+
extensions:
3+
- TASK_CHUNKING
4+
name: job_specific_take_selection.c4d
5+
parameterDefinitions:
6+
- name: Cinema4DFile
7+
type: PATH
8+
objectType: FILE
9+
dataFlow: IN
10+
userInterface:
11+
control: CHOOSE_INPUT_FILE
12+
label: Cinema4D Document File
13+
groupLabel: Cinema4D Settings
14+
fileFilters:
15+
- label: Cinema4D document files
16+
patterns:
17+
- '*.c4d'
18+
- label: All Files
19+
patterns:
20+
- '*'
21+
description: The Cinema4D document file to render.
22+
- name: SubmitterIntegrationVersion
23+
type: STRING
24+
userInterface:
25+
control: HIDDEN
26+
label: Submitter Integration Version
27+
groupLabel: Cinema4D Settings
28+
description: The Cinema 4D submitter integration version.
29+
- name: Frames
30+
type: STRING
31+
userInterface:
32+
control: LINE_EDIT
33+
label: Frames
34+
groupLabel: Cinema4D Settings
35+
description: The frames to render. E.g. 1-3,8,11-15
36+
minLength: 1
37+
- name: ChunkSize
38+
type: INT
39+
default: 1
40+
minValue: 1
41+
description: |
42+
Number of frames per chunk. Use 1 for one frame per task (default). Higher values group frames into chunks to reduce per-task overhead.
43+
userInterface:
44+
control: SPIN_BOX
45+
label: Frames Per Chunk
46+
groupLabel: Cinema4D Settings
47+
- name: TargetChunkDuration
48+
type: INT
49+
default: 0
50+
minValue: 0
51+
description: |
52+
Target render time per chunk in seconds. Deadline Cloud will automatically adjust how many frames are grouped together to hit this target. Set to 0 to always use the fixed frames-per-chunk value.
53+
userInterface:
54+
control: SPIN_BOX
55+
label: Target Chunk Duration (Seconds)
56+
groupLabel: Cinema4D Settings
57+
- name: OutputPath
58+
type: PATH
59+
objectType: FILE
60+
dataFlow: OUT
61+
userInterface:
62+
control: CHOOSE_OUTPUT_FILE
63+
label: Default image output
64+
groupLabel: Cinema4D Settings
65+
description: Image output path
66+
- name: MultiPassPath
67+
type: PATH
68+
objectType: FILE
69+
dataFlow: OUT
70+
userInterface:
71+
control: CHOOSE_OUTPUT_FILE
72+
label: Multi-pass output path
73+
groupLabel: Cinema4D Settings
74+
description: Multi-pass image output
75+
- name: ActivateErrorChecking
76+
type: STRING
77+
userInterface:
78+
control: CHECK_BOX
79+
label: Activate automatic error checking
80+
groupLabel: Cinema4D Settings
81+
description: Fail when errors occur.
82+
default: '1'
83+
allowedValues:
84+
- '1'
85+
- '0'
86+
- name: DetailedLogging
87+
type: STRING
88+
userInterface:
89+
control: CHECK_BOX
90+
label: Enable Detailed Logging
91+
groupLabel: Cinema4D Settings
92+
description: Enable detailed Cinema 4D + Redshift renderer logging for debugging.
93+
default: '0'
94+
allowedValues:
95+
- '1'
96+
- '0'
97+
- name: UseCachedText
98+
type: STRING
99+
userInterface:
100+
control: CHECK_BOX
101+
label: Use cached text during render
102+
groupLabel: Cinema4D Settings
103+
description: Prevents incorrect or missing text by using cached fonts. If there
104+
are no fonts in the scene, this is ignored. If there are fonts in the scene, this
105+
will increase rendering time.
106+
default: '0'
107+
allowedValues:
108+
- '1'
109+
- '0'
110+
steps:
111+
- name: A
112+
parameterSpace:
113+
taskParameterDefinitions:
114+
- name: Frame
115+
type: CHUNK[INT]
116+
range: '{{Param.Frames}}'
117+
chunks:
118+
defaultTaskCount: '{{Param.ChunkSize}}'
119+
targetRuntimeSeconds: '{{Param.TargetChunkDuration}}'
120+
rangeConstraint: CONTIGUOUS
121+
stepEnvironments:
122+
- name: Cinema4D
123+
description: Runs Cinema4D in the background.
124+
variables:
125+
PYTHONUNBUFFERED: '1'
126+
SUBMITTER_INTEGRATION_VERSION: '{{Param.SubmitterIntegrationVersion}}'
127+
script:
128+
embeddedFiles:
129+
- name: initData
130+
filename: init-data.yaml
131+
type: TEXT
132+
data: |
133+
take: A
134+
activate_error_checking: '{{Param.ActivateErrorChecking}}'
135+
use_cached_text: '{{Param.UseCachedText}}'
136+
scene_file: {{Param.Cinema4DFile}}
137+
output_path: PATH_TO_BE_REPLACED/deadline-cloud-for-cinema-4d/test/integ_xa11y/test_cases/job_specific_take_selection/actual/renders/job_specific_take_selection_A
138+
multi_pass_path: ''
139+
actions:
140+
onEnter:
141+
command: cinema4d-openjd
142+
args:
143+
- daemon
144+
- start
145+
- --path-mapping-rules
146+
- file://{{Session.PathMappingRulesFile}}
147+
- --connection-file
148+
- '{{Session.WorkingDirectory}}/connection.json'
149+
- --init-data
150+
- file://{{Env.File.initData}}
151+
cancelation:
152+
mode: NOTIFY_THEN_TERMINATE
153+
timeout: 600
154+
onExit:
155+
command: cinema4d-openjd
156+
args:
157+
- daemon
158+
- stop
159+
- --connection-file
160+
- '{{ Session.WorkingDirectory }}/connection.json'
161+
cancelation:
162+
mode: NOTIFY_THEN_TERMINATE
163+
timeout: 300
164+
script:
165+
embeddedFiles:
166+
- name: runData
167+
filename: run-data.yaml
168+
type: TEXT
169+
data: |
170+
frame: '{{Task.Param.Frame}}'
171+
actions:
172+
onRun:
173+
command: cinema4d-openjd
174+
args:
175+
- daemon
176+
- run
177+
- --connection-file
178+
- '{{ Session.WorkingDirectory }}/connection.json'
179+
- --run-data
180+
- file://{{ Task.File.runData }}
181+
cancelation:
182+
mode: NOTIFY_THEN_TERMINATE
183+
timeout: 172800
23.6 KB
Loading

test/integ_xa11y/test_cases/job_specific_take_selection/input/scene.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,10 @@ def main():
3939
take_a.SetRenderData(take_data, render_settings_2)
4040

4141
selection_variant = sys.argv[2]
42-
if selection_variant not in ("current", "main", "all"):
42+
if selection_variant not in ("current", "main", "marked", "all"):
4343
raise ValueError(f"Unknown take-selection variant: {selection_variant}")
44+
main_take.SetChecked(False)
45+
take_a.SetChecked(selection_variant == "marked")
4446
take_data.SetCurrentTake(take_a if selection_variant == "current" else main_take)
4547

4648
save_dir = sys.argv[1]

test/integ_xa11y/test_cinema4d.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,7 @@ def _run_integ_case(
662662
_TAKE_SELECTIONS = [
663663
pytest.param("current", "Current Take", id="current"),
664664
pytest.param("main", "Main Take", id="main"),
665+
pytest.param("marked", "Marked Takes", id="marked"),
665666
pytest.param("all", "All Takes", id="all"),
666667
]
667668

@@ -690,7 +691,7 @@ def test_job_specific_take_selection(
690691
expected_variant: str,
691692
selection: str,
692693
) -> None:
693-
"""Verify Current, Main, and All Takes produce the intended job steps."""
694+
"""Verify Current, Main, Marked, and All Takes produce the intended job steps."""
694695
_run_integ_case(
695696
cinema4d_location,
696697
test_cases_folder_location,
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
3+
from unittest.mock import Mock, patch
4+
5+
import xa11y
6+
7+
from test.integ_xa11y import submitter_ui
8+
9+
10+
def test_activate_take_option_clicks_macos_press_target() -> None:
11+
option_element = Mock(actions=["press"])
12+
option_element.parent.return_value = None
13+
option = Mock()
14+
option.element.return_value = option_element
15+
input_sim = Mock()
16+
17+
with patch.object(submitter_ui.xa11y, "input_sim", return_value=input_sim):
18+
submitter_ui._activate_take_option(option, "Marked Takes")
19+
20+
option.press.assert_not_called()
21+
input_sim.click.assert_called_once_with(option_element)
22+
23+
24+
def test_wait_for_take_selection_confirms_highlighted_row() -> None:
25+
combo = Mock()
26+
combo.wait_until.side_effect = [xa11y.TimeoutError(), None]
27+
input_sim = Mock()
28+
29+
with patch.object(submitter_ui.xa11y, "input_sim", return_value=input_sim):
30+
submitter_ui._wait_for_take_selection(combo, "Current Take")
31+
32+
assert [call.kwargs["timeout"] for call in combo.wait_until.call_args_list] == [1.0, 10.0]
33+
input_sim.press.assert_called_once_with("Enter")

0 commit comments

Comments
 (0)