mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
style fix
This commit is contained in:
parent
281d53bb01
commit
8002dc4f4f
9 changed files with 275 additions and 306 deletions
|
|
@ -134,19 +134,21 @@ def get_default_render_folder(project_setting=None):
|
|||
|
||||
|
||||
def set_framerange(startFrame, endFrame):
|
||||
"""Get/set the type of time range to be rendered.
|
||||
|
||||
Possible values are:
|
||||
|
||||
1 -Single frame.
|
||||
|
||||
2 -Active time segment ( animationRange ).
|
||||
|
||||
3 -User specified Range.
|
||||
|
||||
4 -User specified Frame pickup string (for example "1,3,5-12").
|
||||
"""
|
||||
# hard-code, there should be a custom setting for this
|
||||
Args:
|
||||
start_frame (int): Start frame number.
|
||||
end_frame (int): End frame number.
|
||||
Note:
|
||||
Frame range can be specified in different types. Possible values are:
|
||||
|
||||
* `1` - Single frame.
|
||||
* `2` - Active time segment ( animationRange ).
|
||||
* `3` - User specified Range.
|
||||
* `4` - User specified Frame pickup string (for example `1,3,5-12`).
|
||||
|
||||
Todo:
|
||||
Current type is hard-coded, there should be a custom setting for this.
|
||||
"""
|
||||
rt.rendTimeType = 4
|
||||
if startFrame is not None and endFrame is not None:
|
||||
frameRange = "{0}-{1}".format(startFrame, endFrame)
|
||||
|
|
@ -157,3 +159,15 @@ def get_multipass_setting(project_setting=None):
|
|||
return (project_setting["max"]
|
||||
["RenderSettings"]
|
||||
["multipass"])
|
||||
|
||||
def get_max_version():
|
||||
"""
|
||||
Args:
|
||||
get max version date for deadline
|
||||
|
||||
Returns:
|
||||
#(25000, 62, 0, 25, 0, 0, 997, 2023, "")
|
||||
max_info[7] = max version date
|
||||
"""
|
||||
max_info = rt.maxversion()
|
||||
return max_info[7]
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ from openpype.pipeline import legacy_io
|
|||
|
||||
class RenderProducts(object):
|
||||
|
||||
@classmethod
|
||||
def __init__(self, project_settings=None):
|
||||
self._project_settings = project_settings
|
||||
if not self._project_settings:
|
||||
|
|
@ -36,15 +35,11 @@ class RenderProducts(object):
|
|||
filename,
|
||||
container)
|
||||
|
||||
context = get_current_project_asset()
|
||||
startFrame = context["data"].get("frameStart")
|
||||
endFrame = context["data"].get("frameEnd") + 1
|
||||
|
||||
img_fmt = self._project_settings["max"]["RenderSettings"]["image_format"] # noqa
|
||||
full_render_list = self.beauty_render_product(output_file,
|
||||
startFrame,
|
||||
endFrame,
|
||||
img_fmt)
|
||||
full_render_list = []
|
||||
beauty = self.beauty_render_product(output_file, img_fmt)
|
||||
full_render_list.append(beauty)
|
||||
|
||||
renderer_class = get_current_renderer()
|
||||
renderer = str(renderer_class).split(":")[0]
|
||||
|
||||
|
|
@ -60,41 +55,29 @@ class RenderProducts(object):
|
|||
renderer == "Quicksilver_Hardware_Renderer"
|
||||
):
|
||||
render_elem_list = self.render_elements_product(output_file,
|
||||
startFrame,
|
||||
endFrame,
|
||||
img_fmt)
|
||||
for render_elem in render_elem_list:
|
||||
full_render_list.append(render_elem)
|
||||
if render_elem_list:
|
||||
for render_elem in render_elem_list:
|
||||
full_render_list.append(render_elem)
|
||||
|
||||
return full_render_list
|
||||
|
||||
if renderer == "Arnold":
|
||||
aov_list = self.arnold_render_product(output_file,
|
||||
startFrame,
|
||||
endFrame,
|
||||
img_fmt)
|
||||
if aov_list:
|
||||
for aov in aov_list:
|
||||
full_render_list.append(aov)
|
||||
return full_render_list
|
||||
|
||||
def beauty_render_product(self, folder, startFrame, endFrame, fmt):
|
||||
# get the beauty
|
||||
beauty_frame_range = list()
|
||||
|
||||
for f in range(startFrame, endFrame):
|
||||
beauty = "{0}.{1}.{2}".format(folder,
|
||||
str(f),
|
||||
fmt)
|
||||
beauty = beauty.replace("\\", "/")
|
||||
beauty_frame_range.append(beauty)
|
||||
|
||||
return beauty_frame_range
|
||||
|
||||
def beauty_render_product(self, folder, fmt):
|
||||
beauty_output = f"{folder}.####.{fmt}"
|
||||
beauty_output = beauty_output.replace("\\", "/")
|
||||
return beauty_output
|
||||
# TODO: Get the arnold render product
|
||||
def arnold_render_product(self, folder, startFrame, endFrame, fmt):
|
||||
def arnold_render_product(self, folder, fmt):
|
||||
"""Get all the Arnold AOVs"""
|
||||
aovs = list()
|
||||
aovs = []
|
||||
|
||||
amw = rt.MaxtoAOps.AOVsManagerWindow()
|
||||
aov_mgr = rt.renderers.current.AOVManager
|
||||
|
|
@ -105,21 +88,17 @@ class RenderProducts(object):
|
|||
for i in range(aov_group_num):
|
||||
# get the specific AOV group
|
||||
for aov in aov_mgr.drivers[i].aov_list:
|
||||
for f in range(startFrame, endFrame):
|
||||
render_element = "{0}_{1}.{2}.{3}".format(folder,
|
||||
str(aov.name),
|
||||
str(f),
|
||||
fmt)
|
||||
render_element = render_element.replace("\\", "/")
|
||||
aovs.append(render_element)
|
||||
render_element = f"{folder}_{aov.name}.####.{fmt}"
|
||||
render_element = render_element.replace("\\", "/")
|
||||
aovs.append(render_element)
|
||||
# close the AOVs manager window
|
||||
amw.close()
|
||||
|
||||
return aovs
|
||||
|
||||
def render_elements_product(self, folder, startFrame, endFrame, fmt):
|
||||
def render_elements_product(self, folder, fmt):
|
||||
"""Get all the render element output files. """
|
||||
render_dirname = list()
|
||||
render_dirname = []
|
||||
|
||||
render_elem = rt.maxOps.GetCurRenderElementMgr()
|
||||
render_elem_num = render_elem.NumRenderElements()
|
||||
|
|
@ -128,16 +107,11 @@ class RenderProducts(object):
|
|||
renderlayer_name = render_elem.GetRenderElement(i)
|
||||
target, renderpass = str(renderlayer_name).split(":")
|
||||
if renderlayer_name.enabled:
|
||||
for f in range(startFrame, endFrame):
|
||||
render_element = "{0}_{1}.{2}.{3}".format(folder,
|
||||
renderpass,
|
||||
str(f),
|
||||
fmt)
|
||||
render_element = render_element.replace("\\", "/")
|
||||
render_dirname.append(render_element)
|
||||
render_element = f"{folder}_{renderpass}.####.{fmt}"
|
||||
render_element = render_element.replace("\\", "/")
|
||||
render_dirname.append(render_element)
|
||||
|
||||
return render_dirname
|
||||
|
||||
def image_format(self):
|
||||
img_fmt = self._project_settings["max"]["RenderSettings"]["image_format"] # noqa
|
||||
return img_fmt
|
||||
return self._project_settings["max"]["RenderSettings"]["image_format"] # noqa
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ class RenderSettings(object):
|
|||
"underscore": "_"
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def __init__(self, project_settings=None):
|
||||
self._project_settings = project_settings
|
||||
if not self._project_settings:
|
||||
|
|
@ -41,7 +40,7 @@ class RenderSettings(object):
|
|||
if not found:
|
||||
raise RuntimeError("Camera not found")
|
||||
|
||||
def set_renderoutput(self, container):
|
||||
def render_output(self, container):
|
||||
folder = rt.maxFilePath
|
||||
# hard-coded, should be customized in the setting
|
||||
file = rt.maxFileName
|
||||
|
|
@ -144,7 +143,7 @@ class RenderSettings(object):
|
|||
aov_name = "{0}_{1}..{2}".format(dir, renderpass, ext)
|
||||
render_elem.SetRenderElementFileName(i, aov_name)
|
||||
|
||||
def get_renderoutput(self, container, output_dir):
|
||||
def get_render_output(self, container, output_dir):
|
||||
output = os.path.join(output_dir, container)
|
||||
img_fmt = self._project_settings["max"]["RenderSettings"]["image_format"] # noqa
|
||||
outputFilename = "{0}..{1}".format(output, img_fmt)
|
||||
|
|
|
|||
|
|
@ -30,4 +30,4 @@ class CreateRender(plugin.MaxCreator):
|
|||
# set viewport camera for rendering(mandatory for deadline)
|
||||
RenderSettings().set_render_camera(sel_obj)
|
||||
# set output paths for rendering(mandatory for deadline)
|
||||
RenderSettings().set_renderoutput(container_name)
|
||||
RenderSettings().render_output(container_name)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ import os
|
|||
import pyblish.api
|
||||
|
||||
from pymxs import runtime as rt
|
||||
from openpype.pipeline import legacy_io
|
||||
from openpype.pipeline import get_current_asset_name
|
||||
from openpype.hosts.max.api.lib import get_max_version
|
||||
from openpype.hosts.max.api.lib_renderproducts import RenderProducts
|
||||
from openpype.client import get_last_version_by_subset_name
|
||||
|
||||
|
|
@ -25,7 +26,7 @@ class CollectRender(pyblish.api.InstancePlugin):
|
|||
filepath = current_file.replace("\\", "/")
|
||||
|
||||
context.data['currentFile'] = current_file
|
||||
asset = legacy_io.Session["AVALON_ASSET"]
|
||||
asset = get_current_asset_name()
|
||||
|
||||
render_layer_files = RenderProducts().render_product(instance.name)
|
||||
folder = folder.replace("\\", "/")
|
||||
|
|
@ -51,6 +52,7 @@ class CollectRender(pyblish.api.InstancePlugin):
|
|||
"subset": instance.name,
|
||||
"asset": asset,
|
||||
"publish": True,
|
||||
"maxversion": str(get_max_version()),
|
||||
"imageFormat": imgFormat,
|
||||
"family": 'maxrender',
|
||||
"families": ['maxrender'],
|
||||
|
|
|
|||
|
|
@ -1,237 +0,0 @@
|
|||
import os
|
||||
import json
|
||||
import getpass
|
||||
|
||||
import requests
|
||||
import pyblish.api
|
||||
|
||||
from openpype.pipeline import legacy_io
|
||||
from openpype.settings import get_project_settings
|
||||
from openpype.hosts.max.api.lib import (
|
||||
get_current_renderer,
|
||||
get_multipass_setting
|
||||
)
|
||||
from openpype.hosts.max.api.lib_rendersettings import RenderSettings
|
||||
|
||||
|
||||
class MaxSubmitRenderDeadline(pyblish.api.InstancePlugin):
|
||||
"""
|
||||
3DMax File Submit Render Deadline
|
||||
|
||||
"""
|
||||
|
||||
label = "Submit 3DsMax Render to Deadline"
|
||||
order = pyblish.api.IntegratorOrder
|
||||
hosts = ["max"]
|
||||
families = ["maxrender"]
|
||||
targets = ["local"]
|
||||
use_published = True
|
||||
priority = 50
|
||||
chunk_size = 1
|
||||
group = None
|
||||
deadline_pool = None
|
||||
deadline_pool_secondary = None
|
||||
framePerTask = 1
|
||||
|
||||
def process(self, instance):
|
||||
context = instance.context
|
||||
filepath = context.data["currentFile"]
|
||||
filename = os.path.basename(filepath)
|
||||
comment = context.data.get("comment", "")
|
||||
deadline_user = context.data.get("deadlineUser", getpass.getuser())
|
||||
jobname = "{0} - {1}".format(filename, instance.name)
|
||||
|
||||
# StartFrame to EndFrame
|
||||
frames = "{start}-{end}".format(
|
||||
start=int(instance.data["frameStart"]),
|
||||
end=int(instance.data["frameEnd"])
|
||||
)
|
||||
if self.use_published:
|
||||
for item in context:
|
||||
if "workfile" in item.data["families"]:
|
||||
msg = "Workfile (scene) must be published along"
|
||||
assert item.data["publish"] is True, msg
|
||||
|
||||
template_data = item.data.get("anatomyData")
|
||||
rep = item.data.get("representations")[0].get("name")
|
||||
template_data["representation"] = rep
|
||||
template_data["ext"] = rep
|
||||
template_data["comment"] = None
|
||||
anatomy_data = context.data["anatomy"]
|
||||
anatomy_filled = anatomy_data.format(template_data)
|
||||
template_filled = anatomy_filled["publish"]["path"]
|
||||
filepath = os.path.normpath(template_filled)
|
||||
filepath = filepath.replace("\\", "/")
|
||||
self.log.info(
|
||||
"Using published scene for render {}".format(filepath)
|
||||
)
|
||||
if not os.path.exists(filepath):
|
||||
self.log.error("published scene does not exist!")
|
||||
|
||||
new_scene = self._clean_name(filepath)
|
||||
# use the anatomy data for setting up the path of the files
|
||||
orig_scene = self._clean_name(instance.context.data["currentFile"])
|
||||
expected_files = instance.data.get("expectedFiles")
|
||||
|
||||
new_exp = []
|
||||
for file in expected_files:
|
||||
new_file = str(file).replace(orig_scene, new_scene)
|
||||
new_exp.append(new_file)
|
||||
|
||||
instance.data["expectedFiles"] = new_exp
|
||||
|
||||
metadata_folder = instance.data.get("publishRenderMetadataFolder")
|
||||
if metadata_folder:
|
||||
metadata_folder = metadata_folder.replace(orig_scene,
|
||||
new_scene)
|
||||
instance.data["publishRenderMetadataFolder"] = metadata_folder
|
||||
|
||||
payload = {
|
||||
"JobInfo": {
|
||||
# Top-level group name
|
||||
"BatchName": filename,
|
||||
|
||||
# Job name, as seen in Monitor
|
||||
"Name": jobname,
|
||||
|
||||
# Arbitrary username, for visualisation in Monitor
|
||||
"UserName": deadline_user,
|
||||
|
||||
"Plugin": instance.data["plugin"],
|
||||
"Group": self.group,
|
||||
"Pool": self.deadline_pool,
|
||||
"secondaryPool": self.deadline_pool_secondary,
|
||||
"Frames": frames,
|
||||
"ChunkSize": self.chunk_size,
|
||||
"Priority": instance.data.get("priority", self.priority),
|
||||
"Comment": comment,
|
||||
"FramesPerTask": self.framePerTask
|
||||
},
|
||||
"PluginInfo": {
|
||||
# Input
|
||||
"SceneFile": filepath,
|
||||
"Version": "2023",
|
||||
"SaveFile": True,
|
||||
# Mandatory for Deadline
|
||||
# Houdini version without patch number
|
||||
|
||||
"IgnoreInputs": True
|
||||
},
|
||||
|
||||
# Mandatory for Deadline, may be empty
|
||||
"AuxFiles": []
|
||||
}
|
||||
# Include critical environment variables with submission + api.Session
|
||||
keys = [
|
||||
# Submit along the current Avalon tool setup that we launched
|
||||
# this application with so the Render Slave can build its own
|
||||
# similar environment using it, e.g. "maya2018;vray4.x;yeti3.1.9"
|
||||
"AVALON_TOOLS",
|
||||
"OPENPYPE_VERSION"
|
||||
]
|
||||
# Add mongo url if it's enabled
|
||||
if context.data.get("deadlinePassMongoUrl"):
|
||||
keys.append("OPENPYPE_MONGO")
|
||||
|
||||
environment = dict({key: os.environ[key] for key in keys
|
||||
if key in os.environ}, **legacy_io.Session)
|
||||
|
||||
payload["JobInfo"].update({
|
||||
"EnvironmentKeyValue%d" % index: "{key}={value}".format(
|
||||
key=key,
|
||||
value=environment[key]
|
||||
) for index, key in enumerate(environment)
|
||||
})
|
||||
|
||||
# Include OutputFilename entries
|
||||
# The first entry also enables double-click to preview rendered
|
||||
# frames from Deadline Monitor
|
||||
output_data = {}
|
||||
# need to be fixed
|
||||
for i, filepath in enumerate(instance.data["expectedFiles"]):
|
||||
dirname = os.path.dirname(filepath)
|
||||
fname = os.path.basename(filepath)
|
||||
output_data["OutputDirectory%d" % i] = dirname.replace("\\", "/")
|
||||
output_data["OutputFilename%d" % i] = fname
|
||||
|
||||
if not os.path.exists(dirname):
|
||||
self.log.info("Ensuring output directory exists: %s" %
|
||||
dirname)
|
||||
os.makedirs(dirname)
|
||||
|
||||
plugin_data = {}
|
||||
project_setting = get_project_settings(
|
||||
legacy_io.Session["AVALON_PROJECT"]
|
||||
)
|
||||
|
||||
multipass = get_multipass_setting(project_setting)
|
||||
if multipass:
|
||||
plugin_data["DisableMultipass"] = 0
|
||||
else:
|
||||
plugin_data["DisableMultipass"] = 1
|
||||
|
||||
if self.use_published:
|
||||
old_output_dir = os.path.dirname(expected_files[0])
|
||||
output_beauty = RenderSettings().get_renderoutput(instance.name,
|
||||
old_output_dir)
|
||||
output_beauty = output_beauty.replace(orig_scene, new_scene)
|
||||
output_beauty = output_beauty.replace("\\", "/")
|
||||
plugin_data["RenderOutput"] = output_beauty
|
||||
|
||||
renderer_class = get_current_renderer()
|
||||
renderer = str(renderer_class).split(":")[0]
|
||||
if (
|
||||
renderer == "ART_Renderer" or
|
||||
renderer == "Redshift_Renderer" or
|
||||
renderer == "V_Ray_6_Hotfix_3" or
|
||||
renderer == "V_Ray_GPU_6_Hotfix_3" or
|
||||
renderer == "Default_Scanline_Renderer" or
|
||||
renderer == "Quicksilver_Hardware_Renderer"
|
||||
):
|
||||
render_elem_list = RenderSettings().get_render_element()
|
||||
for i, element in enumerate(render_elem_list):
|
||||
element = element.replace(orig_scene, new_scene)
|
||||
plugin_data["RenderElementOutputFilename%d" % i] = element # noqa
|
||||
|
||||
self.log.debug("plugin data:{}".format(plugin_data))
|
||||
self.log.info("Scene name was switched {} -> {}".format(
|
||||
orig_scene, new_scene
|
||||
))
|
||||
|
||||
payload["JobInfo"].update(output_data)
|
||||
payload["PluginInfo"].update(plugin_data)
|
||||
|
||||
self.submit(instance, payload)
|
||||
|
||||
def submit(self, instance, payload):
|
||||
|
||||
context = instance.context
|
||||
deadline_url = context.data.get("defaultDeadline")
|
||||
deadline_url = instance.data.get(
|
||||
"deadlineUrl", deadline_url)
|
||||
|
||||
assert deadline_url, "Requires Deadline Webservice URL"
|
||||
|
||||
plugin = payload["JobInfo"]["Plugin"]
|
||||
self.log.info("Using Render Plugin : {}".format(plugin))
|
||||
|
||||
self.log.info("Submitting..")
|
||||
self.log.debug(json.dumps(payload, indent=4, sort_keys=True))
|
||||
|
||||
# E.g. http://192.168.0.1:8082/api/jobs
|
||||
url = "{}/api/jobs".format(deadline_url)
|
||||
response = requests.post(url, json=payload)
|
||||
if not response.ok:
|
||||
raise Exception(response.text)
|
||||
# Store output dir for unified publisher (expectedFilesequence)
|
||||
expected_files = instance.data["expectedFiles"]
|
||||
output_dir = os.path.dirname(expected_files[0])
|
||||
instance.data["toBeRenderedOn"] = "deadline"
|
||||
instance.data["outputDir"] = output_dir
|
||||
instance.data["deadlineSubmissionJob"] = response.json()
|
||||
|
||||
def rename_render_element(self):
|
||||
pass
|
||||
|
||||
def _clean_name(self, path):
|
||||
return os.path.splitext(os.path.basename(path))[0]
|
||||
217
openpype/modules/deadline/plugins/publish/submit_max_deadline.py
Normal file
217
openpype/modules/deadline/plugins/publish/submit_max_deadline.py
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
import os
|
||||
import getpass
|
||||
import copy
|
||||
|
||||
import attr
|
||||
from openpype.pipeline import legacy_io
|
||||
from openpype.settings import get_project_settings
|
||||
from openpype.hosts.max.api.lib import (
|
||||
get_current_renderer,
|
||||
get_multipass_setting
|
||||
)
|
||||
from openpype.hosts.max.api.lib_rendersettings import RenderSettings
|
||||
from openpype_modules.deadline import abstract_submit_deadline
|
||||
from openpype_modules.deadline.abstract_submit_deadline import DeadlineJobInfo
|
||||
|
||||
|
||||
@attr.s
|
||||
class MaxPluginInfo(object):
|
||||
SceneFile = attr.ib(default=None) # Input
|
||||
Version = attr.ib(default=None) # Mandatory for Deadline
|
||||
SaveFile = attr.ib(default=True)
|
||||
IgnoreInputs = attr.ib(default=True)
|
||||
|
||||
|
||||
class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline):
|
||||
|
||||
label = "Submit Render to Deadline"
|
||||
hosts = ["max"]
|
||||
families = ["maxrender"]
|
||||
targets = ["local"]
|
||||
|
||||
use_published = True
|
||||
priority = 50
|
||||
tile_priority = 50
|
||||
chunk_size = 1
|
||||
jobInfo = {}
|
||||
pluginInfo = {}
|
||||
group = None
|
||||
deadline_pool = None
|
||||
deadline_pool_secondary = None
|
||||
framePerTask = 1
|
||||
|
||||
def get_job_info(self):
|
||||
job_info = DeadlineJobInfo(Plugin="3dsmax")
|
||||
|
||||
# todo: test whether this works for existing production cases
|
||||
# where custom jobInfo was stored in the project settings
|
||||
job_info.update(self.jobInfo)
|
||||
|
||||
instance = self._instance
|
||||
context = instance.context
|
||||
|
||||
# Always use the original work file name for the Job name even when
|
||||
# rendering is done from the published Work File. The original work
|
||||
# file name is clearer because it can also have subversion strings,
|
||||
# etc. which are stripped for the published file.
|
||||
src_filepath = context.data["currentFile"]
|
||||
src_filename = os.path.basename(src_filepath)
|
||||
|
||||
job_info.Name = "%s - %s" % (src_filename, instance.name)
|
||||
job_info.BatchName = src_filename
|
||||
job_info.Plugin = instance.data["plugin"]
|
||||
job_info.UserName = context.data.get("deadlineUser", getpass.getuser())
|
||||
|
||||
# Deadline requires integers in frame range
|
||||
frames = "{start}-{end}".format(
|
||||
start=int(instance.data["frameStart"]),
|
||||
end=int(instance.data["frameEnd"])
|
||||
)
|
||||
job_info.Frames = frames
|
||||
|
||||
job_info.Pool = instance.data.get("primaryPool")
|
||||
job_info.SecondaryPool = instance.data.get("secondaryPool")
|
||||
job_info.ChunkSize = instance.data.get("chunkSize", 1)
|
||||
job_info.Comment = context.data.get("comment")
|
||||
job_info.Priority = instance.data.get("priority", self.priority)
|
||||
job_info.FramesPerTask = instance.data.get("framesPerTask", 1)
|
||||
|
||||
if self.group:
|
||||
job_info.Group = self.group
|
||||
|
||||
# Add options from RenderGlobals
|
||||
render_globals = instance.data.get("renderGlobals", {})
|
||||
job_info.update(render_globals)
|
||||
|
||||
keys = [
|
||||
"FTRACK_API_KEY",
|
||||
"FTRACK_API_USER",
|
||||
"FTRACK_SERVER",
|
||||
"OPENPYPE_SG_USER",
|
||||
"AVALON_PROJECT",
|
||||
"AVALON_ASSET",
|
||||
"AVALON_TASK",
|
||||
"AVALON_APP_NAME",
|
||||
"OPENPYPE_DEV",
|
||||
"OPENPYPE_VERSION",
|
||||
"IS_TEST"
|
||||
]
|
||||
# Add mongo url if it's enabled
|
||||
if self._instance.context.data.get("deadlinePassMongoUrl"):
|
||||
keys.append("OPENPYPE_MONGO")
|
||||
|
||||
environment = dict({key: os.environ[key] for key in keys
|
||||
if key in os.environ}, **legacy_io.Session)
|
||||
|
||||
for key in keys:
|
||||
value = environment.get(key)
|
||||
if not value:
|
||||
continue
|
||||
job_info.EnvironmentKeyValue[key] = value
|
||||
|
||||
# to recognize job from PYPE for turning Event On/Off
|
||||
job_info.EnvironmentKeyValue["OPENPYPE_RENDER_JOB"] = "1"
|
||||
job_info.EnvironmentKeyValue["OPENPYPE_LOG_NO_COLORS"] = "1"
|
||||
|
||||
# Add list of expected files to job
|
||||
# ---------------------------------
|
||||
exp = instance.data.get("expectedFiles")
|
||||
for filepath in exp:
|
||||
job_info.OutputDirectory += os.path.dirname(filepath)
|
||||
job_info.OutputFilename += os.path.basename(filepath)
|
||||
|
||||
return job_info
|
||||
|
||||
def get_plugin_info(self):
|
||||
instance = self._instance
|
||||
|
||||
plugin_info = MaxPluginInfo(
|
||||
SceneFile=self.scene_path,
|
||||
Version=instance.data["maxversion"],
|
||||
SaveFile = True,
|
||||
IgnoreInputs = True
|
||||
)
|
||||
|
||||
plugin_payload = attr.asdict(plugin_info)
|
||||
|
||||
# Patching with pluginInfo from settings
|
||||
for key, value in self.pluginInfo.items():
|
||||
plugin_payload[key] = value
|
||||
|
||||
return plugin_payload
|
||||
|
||||
def process_submission(self):
|
||||
|
||||
instance = self._instance
|
||||
context = instance.context
|
||||
filepath = self.scene_path
|
||||
|
||||
expected_files = instance.data["expectedFiles"]
|
||||
if not expected_files:
|
||||
raise RuntimeError("No Render Elements found!")
|
||||
output_dir = os.path.dirname(expected_files[0])
|
||||
instance.data["outputDir"] = output_dir
|
||||
instance.data["toBeRenderedOn"] = "deadline"
|
||||
|
||||
filename = os.path.basename(filepath)
|
||||
|
||||
payload_data = {
|
||||
"filename": filename,
|
||||
"dirname": output_dir
|
||||
}
|
||||
|
||||
self.log.debug("Submitting 3dsMax render..")
|
||||
payload = self._use_puhlished_name(payload_data)
|
||||
job_info, plugin_info = payload
|
||||
self.submit(self.assemble_payload(job_info, plugin_info))
|
||||
|
||||
def _use_puhlished_name(self, data):
|
||||
instance = self._instance
|
||||
job_info = copy.deepcopy(self.job_info)
|
||||
plugin_info = copy.deepcopy(self.plugin_info)
|
||||
plugin_data = {}
|
||||
project_setting = get_project_settings(
|
||||
legacy_io.Session["AVALON_PROJECT"]
|
||||
)
|
||||
|
||||
multipass = get_multipass_setting(project_setting)
|
||||
if multipass:
|
||||
plugin_data["DisableMultipass"] = 0
|
||||
else:
|
||||
plugin_data["DisableMultipass"] = 1
|
||||
|
||||
expected_files = instance.data.get("expectedFiles")
|
||||
if not expected_files:
|
||||
raise RuntimeError("No render elements found")
|
||||
old_output_dir = os.path.dirname(expected_files[0])
|
||||
output_beauty = RenderSettings().get_render_output(instance.name,
|
||||
old_output_dir)
|
||||
filepath = self.from_published_scene()
|
||||
def _clean_name(path):
|
||||
return os.path.splitext(os.path.basename(path))[0]
|
||||
new_scene = _clean_name(filepath)
|
||||
orig_scene = _clean_name(instance.context.data["currentFile"])
|
||||
|
||||
output_beauty = output_beauty.replace(orig_scene, new_scene)
|
||||
output_beauty = output_beauty.replace("\\", "/")
|
||||
plugin_data["RenderOutput"] = output_beauty
|
||||
|
||||
renderer_class = get_current_renderer()
|
||||
renderer = str(renderer_class).split(":")[0]
|
||||
if (
|
||||
renderer == "ART_Renderer" or
|
||||
renderer == "Redshift_Renderer" or
|
||||
renderer == "V_Ray_6_Hotfix_3" or
|
||||
renderer == "V_Ray_GPU_6_Hotfix_3" or
|
||||
renderer == "Default_Scanline_Renderer" or
|
||||
renderer == "Quicksilver_Hardware_Renderer"
|
||||
):
|
||||
render_elem_list = RenderSettings().get_render_element()
|
||||
for i, element in enumerate(render_elem_list):
|
||||
element = element.replace(orig_scene, new_scene)
|
||||
plugin_data["RenderElementOutputFilename%d" % i] = element # noqa
|
||||
|
||||
self.log.debug("plugin data:{}".format(plugin_data))
|
||||
plugin_info.update(plugin_data)
|
||||
|
||||
return job_info, plugin_info
|
||||
|
|
@ -36,7 +36,7 @@
|
|||
"scene_patches": [],
|
||||
"strict_error_checking": true
|
||||
},
|
||||
"MaxSubmitRenderDeadline": {
|
||||
"MaxSubmitDeadline": {
|
||||
"enabled": true,
|
||||
"optional": false,
|
||||
"active": true,
|
||||
|
|
@ -122,4 +122,4 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@
|
|||
{
|
||||
"type": "dict",
|
||||
"collapsible": true,
|
||||
"key": "MaxSubmitRenderDeadline",
|
||||
"key": "MaxSubmitDeadline",
|
||||
"label": "3dsMax Submit to Deadline",
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue