-
Notifications
You must be signed in to change notification settings - Fork 32
feat: add V-Ray export workflow with tile rendering #217
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
Open
ZainAallii
wants to merge
1
commit into
aws-deadline:mainline
Choose a base branch
from
ZainAallii:feature/vray-standalone
base: mainline
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,111 @@ | ||
| # V-Ray Standalone Submitter — File Map | ||
|
|
||
| Overview of all files added for the V-Ray Standalone workflow. | ||
|
|
||
| ``` | ||
| src/deadline/max_submitter/ | ||
| ├── vray_standalone_submitter.py — Main submitter logic: job bundle creation for | ||
| │ local export and farm export modes, path mapping | ||
| │ script loading, vrscene path fix script loading, | ||
| │ tile rendering integration | ||
| ├── vrscene_settings.py — Settings dataclass with sticky persistence (export | ||
| │ mode, region grid, output format, movie settings) | ||
| ├── ui/ | ||
| │ └── vray_standalone_tab.py — Qt UI tab: export mode radios, job options, region | ||
| │ grid spinners, output format dropdown, browse button | ||
| ├── utilities/ | ||
| │ ├── vrscene_job_submission.py — Job template loading and parameter builders: | ||
| │ │ tile coordinate calculation, script injection, | ||
| │ │ parameter value builders for all job types | ||
| │ ├── vrscene_utils.py — V-Ray helpers: renderer detection, vrscene export | ||
| │ │ (local), settings validation, output format detection | ||
| │ └── vray_executable_utils.py — Executable path resolution for vray.exe and | ||
| │ 3dsmaxcmd.exe (env vars + install path fallback) | ||
| ├── scripts/ | ||
| │ ├── fix_vrscene_paths.py — Farm script: runs 3dsmaxcmd export then reverses | ||
| │ │ session paths so render -remapPath works correctly | ||
| │ ├── path_mapping_render.py — Farm script: reads path mapping rules and calls | ||
| │ │ vray.exe with -remapPath arguments | ||
| │ ├── tile_render.py — Farm script: renders a single tile region with vray.exe | ||
ZainAallii marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| │ ├── tile_merge.py — Farm script: merges tile images into complete frames | ||
| │ │ using Pillow (PNG/JPEG/TIFF) or OpenEXR | ||
| │ ├── create_movie.py — Farm script: creates MP4 from frames (future release) | ||
| │ └── export_vrscene_farm.ms — MAXScript: exports vrscene on the farm worker via | ||
| │ 3dsmaxcmd, called by fix_vrscene_paths.py | ||
| └── job_templates/ | ||
| ├── vray_render_job_template.yaml — OpenJD template: single-step vray.exe render | ||
| ├── vray_export_job_template.yaml — OpenJD template: vrscene export step (farm mode) | ||
| ├── vray_tile_render_job_template.yaml — OpenJD template: RenderRegions + MergeRegions steps | ||
| └── vray_combined_job_template.yaml — OpenJD template: export + render combined (farm mode) | ||
|
|
||
| install_files/ | ||
| └── AWSDeadline-SubmitToDeadlineCloud-VRayStandalone.mcr — 3ds Max macro for menu entry | ||
| (installer bundling: follow-up PR) | ||
|
|
||
| force_reload.ms — Dev helper: reloads Python modules in 3ds Max | ||
| ``` | ||
|
|
||
| ## Architecture Integration | ||
|
|
||
| How the V-Ray Standalone feature relates to the existing submitter/adaptor architecture. | ||
|
|
||
| ### Existing Architecture Flow | ||
|
|
||
| ``` | ||
| run_ui.py | ||
| → show_job_bundle_submitter() | ||
| → SubmitMaxJobToDeadlineDialog( | ||
| job_setup_widget_type = SceneSettingsWidget, | ||
| on_create_job_bundle_callback = on_create_job_bundle_callback | ||
| ) | ||
| ``` | ||
|
|
||
| The existing callback builds an OpenJD job template that uses the `3dsmax-openjd` adaptor. | ||
| The farm worker launches 3ds Max and renders inside it. | ||
|
|
||
| ### V-Ray Hook Points | ||
|
|
||
| The V-Ray feature hooks into the existing architecture at exactly two points: | ||
|
|
||
| 1. **`submit_dialog.py`** — `SubmitMaxJobToDeadlineDialog.__init__()` intercepts the original | ||
| callback, wraps it in `_on_create_job_bundle_wrapper()`, and calls | ||
| `_add_vray_export_tab_if_available()`. When V-Ray is the active renderer, a "V-Ray Export" | ||
| tab appears in the dialog. | ||
|
|
||
| 2. **Submit-time routing** — The wrapper checks `vray_export_widget.is_vray_export_enabled()`: | ||
| - Enabled → routes to `on_create_vrscene_job_bundle_callback` with `VRSceneRenderSubmitterUISettings` | ||
| - Disabled → passes through to the original `on_create_job_bundle_callback` with `RenderSubmitterUISettings` | ||
|
|
||
| No other existing files are modified (except `data_const.py` for the settings file extension constant). | ||
|
|
||
| ### Adaptor vs Adaptor-Free | ||
|
|
||
| | | Existing 3ds Max Workflow | V-Ray Standalone Workflow | | ||
| |---|---|---| | ||
| | Rendering | `3dsmax-openjd` adaptor launches 3ds Max on the farm | Farm scripts call `vray.exe` directly | | ||
ZainAallii marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| | Job template | Loaded from `default_max_job_template.yaml` | Loaded from YAML files in `job_templates/` | | ||
| | Path mapping | Handled by the adaptor | `path_mapping_render.py` reads `Session.PathMappingRulesFile` | | ||
| | Settings class | `RenderSubmitterUISettings` | `VRSceneRenderSubmitterUISettings` | | ||
| | UI tab | `SceneSettingsWidget` | `VRayStandaloneSettingsWidget` | | ||
| | Sticky settings ext | `.deadline_render_settings.json` | `.deadline_vrscene_settings.json` | | ||
|
|
||
| ### Executable Path Resolution | ||
|
|
||
| Farm workers need `vray.exe` (Windows) on the `PATH` or via environment variable. | ||
| Set `VRAY_EXECUTABLE` to the full path of `vray.exe` on each worker — this is the recommended | ||
| approach and should be configured in the fleet host configuration or worker environment. | ||
| The fallback derives the path from `VRAY_FOR_3DSMAX{version}_MAIN` (set by the V-Ray installer). | ||
|
|
||
| Similarly, farm export mode requires `3dsmaxcmd.exe`. Set `MAXCMD_EXECUTABLE` to its full path, | ||
| or the submitter will derive it from the current 3ds Max installation at submit time. | ||
|
|
||
| ### Coupling Summary | ||
|
|
||
| The V-Ray feature is a parallel workflow that shares the dialog shell but has its own: | ||
| - Settings dataclass (`vrscene_settings.py`) | ||
| - UI tab (`vray_standalone_tab.py`) | ||
| - Submit callback (`vray_standalone_submitter.py`) | ||
| - Job templates (`job_templates/`) | ||
| - Farm scripts (`scripts/`) | ||
|
|
||
| Everything is additive. The only modified existing files are `submit_dialog.py` (callback wrapper + tab injection) and `data_const.py` (one constant). | ||
49 changes: 49 additions & 0 deletions
49
install_files/AWSDeadline-SubmitToDeadlineCloud-VRayStandalone.mcr
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| -- AWS Deadline Cloud - V-Ray Standalone Submitter Macro | ||
| -- Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
|
|
||
| macroScript SubmitToDeadlineCloudVRayStandalone | ||
ZainAallii marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| category:"AWS Deadline Cloud" | ||
| buttonText:"Submit V-Ray Standalone" | ||
| toolTip:"Submit V-Ray Standalone Render Job To Deadline Cloud" | ||
| icon:#("Deadline",1) | ||
| ( | ||
| -- Check if V-Ray is the current renderer | ||
| local isVRay = false | ||
| try | ||
| ( | ||
| local rendererName = (classof renderers.current) as string | ||
| isVRay = (findString rendererName "VRay" != undefined) or (findString rendererName "V_Ray" != undefined) | ||
| ) | ||
| catch | ||
| ( | ||
| isVRay = false | ||
| ) | ||
|
|
||
| if not isVRay then | ||
| ( | ||
| messageBox "V-Ray Standalone workflow requires V-Ray as the active renderer.\n\nPlease set V-Ray as your current renderer to use this workflow." title:"V-Ray Not Active" | ||
| return false | ||
| ) | ||
|
|
||
| -- Import the Python module and run the UI | ||
| python.Execute "import sys" | ||
| python.Execute "import os" | ||
|
|
||
| -- Try development path first, then installed path | ||
| local devPath = "C:\\Users\\Administrator\\gitrepos\\deadline-cloud-for-3ds-max\\src\\deadline\\max_submitter" | ||
ZainAallii marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| local installedPath = (getDir #scripts) + "\\deadline\\max_submitter" | ||
|
|
||
| local submitterPath = installedPath | ||
| if (doesFileExist (devPath + "\\run_vray_standalone_ui.py")) then ( | ||
| submitterPath = devPath | ||
| format "Using development path: %\n" submitterPath | ||
| ) else ( | ||
| format "Using installed path: %\n" submitterPath | ||
| ) | ||
|
|
||
| python.Execute ("sys.path.insert(0, r'" + submitterPath + "')") | ||
|
|
||
| -- Launch the V-Ray Standalone submitter | ||
| python.Execute "from run_vray_standalone_ui import main" | ||
| python.Execute "main()" | ||
| ) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| -- V-Ray Standalone Export MAXScript Job | ||
| -- Runs on Deadline workers to export vrscene files | ||
| -- Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
|
|
||
| try | ||
ZainAallii marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ( | ||
| local du = DeadlineUtil -- Interface provided by Deadline 3ds Max plugin | ||
| if du == undefined do | ||
| ( | ||
| -- Stand-in struct for testing outside Deadline | ||
| struct DeadlineUtilStruct | ||
| ( | ||
| fn SetTitle title = ( format "Title: %\n" title ), | ||
| fn SetProgress percent = (true), | ||
| fn FailRender msg = ( throw msg ), | ||
| fn GetJobInfoEntry key = ( undefined ), | ||
| fn LogMessage msg = ( format "INFO: %\n" msg ), | ||
| fn WarnMessage msg = ( format "WARNING: %\n" msg ), | ||
| CurrentFrame = ((sliderTime as string) as integer), | ||
| CurrentTask = ( -1 ), | ||
| SceneFileName = ( maxFilePath + maxFileName ), | ||
| SceneFilePath = ( maxFilePath ) | ||
| ) | ||
| du = DeadlineUtilStruct() | ||
| ) | ||
|
|
||
| fn ExportToVRayStd exportPath startFrame endFrame incrBaseFrame: = | ||
| ( | ||
| -- Create output directory | ||
| makeDir (getFileNamePath exportPath) all:true | ||
| sysinfo.currentdir = getFileNamePath exportPath | ||
|
|
||
| -- Ensure VRayRT is the active shade renderer | ||
| if not (iskindof renderers.activeShade VRayRT) do | ||
| renderers.activeShade = VRayRT() | ||
|
|
||
| -- Export based on frame range | ||
| if startFrame == endFrame then | ||
| -- Single frame export | ||
| vrayExportRTScene exportPath separateFiles:false | ||
| else if incrBaseFrame != unsupplied and incrBaseFrame != startFrame then | ||
| -- Incremental export (not first frame) | ||
| vrayExportRTScene exportPath separateFiles:false startFrame:startFrame endFrame:endFrame incrBaseFrame:incrBaseFrame | ||
| else | ||
| -- Full animation or first frame of incremental | ||
| vrayExportRTScene exportPath separateFiles:false startFrame:startFrame endFrame:endFrame | ||
| ) | ||
|
|
||
| local st = timestamp() | ||
|
|
||
| du.SetTitle "VRSCENE Export MAXScript Job" | ||
| du.LogMessage ">Starting VRSCENE Export MAXScript Job..." | ||
|
|
||
| -- Get job parameters | ||
| local startFrame = (du.GetJobInfoEntry "Render_StartFrame") as integer | ||
| local endFrame = (du.GetJobInfoEntry "Render_EndFrame") as integer | ||
| local vrsceneName = du.GetJobInfoEntry "Render_InputFilename" | ||
| local exportAnimationMode = du.GetJobInfoEntry "Render_ExportAnimationMode" | ||
|
|
||
| -- Default to Single File mode | ||
| if exportAnimationMode == "" do | ||
| exportAnimationMode = "1" | ||
| exportAnimationMode = exportAnimationMode as integer | ||
|
|
||
| du.LogMessage ">Exporting VRSCENE File..." | ||
|
|
||
| case exportAnimationMode of | ||
| ( | ||
| 1: ( | ||
| -- Single File: Export entire animation to one vrscene | ||
| ExportToVRayStd vrsceneName startFrame endFrame | ||
| ) | ||
| 2: ( | ||
| -- File Per Frame: Export current frame to separate vrscene | ||
| local frameVrsceneName = (getFilenamePath vrsceneName) + (getFilenameFile vrsceneName) + "." + (formattedPrint du.CurrentFrame format:"04i") + (getFilenameType vrsceneName) | ||
| ExportToVRayStd frameVrsceneName du.CurrentFrame (du.CurrentFrame + 1) | ||
| ) | ||
| 3: ( | ||
| -- File Per Frame (Incremental): Export with reference to first frame | ||
| local frameVrsceneName = (getFilenamePath vrsceneName) + (getFilenameFile vrsceneName) + "." + (formattedPrint du.CurrentFrame format:"04i") + (getFilenameType vrsceneName) | ||
| ExportToVRayStd frameVrsceneName du.CurrentFrame (du.CurrentFrame + 1) incrBaseFrame:startFrame | ||
| ) | ||
| ) | ||
|
|
||
| du.LogMessage ("+Finished VRSCENE Export MAXScript Job in "+ ((timestamp() - st)/1000.0) as string + " sec.") | ||
| true | ||
| ) | ||
| catch | ||
| ( | ||
| -- Error handling with stack trace (Max 2017+) | ||
| if ((maxVersion())[1]/1000 as integer) >= 19 then | ||
| ( | ||
| if hasCurrentExceptionStackTrace() then | ||
| ( | ||
| local errorMessage = getCurrentException() | ||
| DeadlineUtil.WarnMessage("MaxScript Error: " + errorMessage) | ||
| local stackTrace = getCurrentExceptionStackTrace() | ||
| stackTrace = filterString stackTrace "\n" | ||
| for line in stackTrace do | ||
| DeadlineUtil.WarnMessage(line) | ||
| ) | ||
| ) | ||
| throw() | ||
| ) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
src/deadline/max_submitter/job_templates/vray_combined_job_template.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| specificationVersion: 'jobtemplate-2023-09' | ||
| name: VRay Export and Render | ||
| parameterDefinitions: | ||
| - name: MaxCmdExecutable | ||
| type: STRING | ||
| default: 3dsmaxcmd | ||
| description: 3dsmaxcmd.exe executable for MAXScript execution | ||
| - name: VRayExecutable | ||
| type: STRING | ||
| default: vray | ||
| description: V-Ray Standalone executable | ||
| - name: SceneFile | ||
| type: PATH | ||
| objectType: FILE | ||
| dataFlow: IN | ||
| description: The 3ds Max scene file to export | ||
| - name: VRSceneOutputPath | ||
| type: PATH | ||
| objectType: FILE | ||
| dataFlow: INOUT | ||
| description: Output path for the vrscene file(s) | ||
| - name: OutputDir | ||
| type: PATH | ||
| objectType: DIRECTORY | ||
| dataFlow: OUT | ||
| description: Output directory for rendered images | ||
| - name: Frames | ||
| type: STRING | ||
| description: Frame range | ||
| - name: ExportAnimationMode | ||
| type: INT | ||
| default: '1' | ||
| allowedValues: | ||
| - '1' | ||
| - '2' | ||
| - '3' | ||
| description: 1=Single File, 2=File Per Frame, 3=File Per Frame (Incremental) | ||
| - name: OutputFileName | ||
| type: STRING | ||
| description: Output filename with extension | ||
| - name: RegionColumns | ||
| type: INT | ||
| description: Number of region columns | ||
| - name: RegionRows | ||
| type: INT | ||
| description: Number of region rows |
51 changes: 51 additions & 0 deletions
51
src/deadline/max_submitter/job_templates/vray_export_job_template.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| specificationVersion: 'jobtemplate-2023-09' | ||
| name: VRayStandaloneExport | ||
| parameterDefinitions: | ||
| - name: SceneFile | ||
| type: PATH | ||
| objectType: FILE | ||
| dataFlow: IN | ||
| description: The 3ds Max scene file to export | ||
| - name: VRSceneOutputPath | ||
| type: PATH | ||
| objectType: FILE | ||
| dataFlow: OUT | ||
| description: Output path for the vrscene file | ||
| - name: StartFrame | ||
| type: INT | ||
| default: '1' | ||
| - name: EndFrame | ||
| type: INT | ||
| default: '1' | ||
| - name: ExportAnimationMode | ||
| type: INT | ||
| default: '1' | ||
| allowedValues: | ||
| - '1' | ||
| - '2' | ||
| - '3' | ||
| description: 1=Single File, 2=File Per Frame, 3=File Per Frame (Incremental) | ||
| steps: | ||
| - name: ExportVRScene | ||
| parameterSpace: | ||
| taskParameterDefinitions: | ||
| - name: Frame | ||
| type: INT | ||
| range: '{{Param.StartFrame}}-{{Param.EndFrame}}' | ||
| stepEnvironments: | ||
| - name: 3dsMax | ||
| description: Runs 3ds Max to export vrscene | ||
| script: | ||
| actions: | ||
| onRun: | ||
| command: 3dsmaxbatch | ||
| args: | ||
| - -sceneFile | ||
| - '{{Param.SceneFile}}' | ||
| - -script | ||
| - '{{Task.File.ExportScript}}' | ||
| embeddedFiles: | ||
| - name: ExportScript | ||
| type: TEXT | ||
| filename: export_vrscene.ms | ||
| data: INJECT_EXPORT_SCRIPT |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.