mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
getting the filename from render settings and add save_scene before all the extractors running
This commit is contained in:
parent
271d017bdb
commit
56642ac175
5 changed files with 171 additions and 125 deletions
|
|
@ -5,10 +5,8 @@
|
|||
import os
|
||||
from pymxs import runtime as rt
|
||||
from openpype.hosts.max.api.lib import (
|
||||
get_current_renderer,
|
||||
get_default_render_folder
|
||||
get_current_renderer
|
||||
)
|
||||
from openpype.pipeline.context_tools import get_current_project_asset
|
||||
from openpype.settings import get_project_settings
|
||||
from openpype.pipeline import legacy_io
|
||||
|
||||
|
|
@ -22,66 +20,30 @@ class RenderProducts(object):
|
|||
legacy_io.Session["AVALON_PROJECT"]
|
||||
)
|
||||
|
||||
def render_product(self, container):
|
||||
folder = rt.maxFilePath
|
||||
file = rt.maxFileName
|
||||
folder = folder.replace("\\", "/")
|
||||
setting = self._project_settings
|
||||
render_folder = get_default_render_folder(setting)
|
||||
filename, ext = os.path.splitext(file)
|
||||
def get_beauty(self, container):
|
||||
render_dir = os.path.dirname(rt.rendOutputFilename)
|
||||
|
||||
output_file = os.path.join(folder,
|
||||
render_folder,
|
||||
filename,
|
||||
output_file = os.path.join(render_dir,
|
||||
container)
|
||||
# TODO: change the frame range follows the current render setting
|
||||
|
||||
setting = self._project_settings
|
||||
img_fmt = setting["max"]["RenderSettings"]["image_format"] # noqa
|
||||
|
||||
startFrame = int(rt.rendStart)
|
||||
endFrame = int(rt.rendEnd) + 1
|
||||
|
||||
img_fmt = self._project_settings["max"]["RenderSettings"]["image_format"] # noqa
|
||||
rgba_render_list = self.beauty_render_product(output_file,
|
||||
startFrame,
|
||||
endFrame,
|
||||
img_fmt)
|
||||
|
||||
renderer_class = get_current_renderer()
|
||||
renderer = str(renderer_class).split(":")[0]
|
||||
|
||||
render_elem_list = None
|
||||
|
||||
if renderer in [
|
||||
"ART_Renderer",
|
||||
"Redshift_Renderer",
|
||||
"V_Ray_6_Hotfix_3",
|
||||
"V_Ray_GPU_6_Hotfix_3",
|
||||
"Default_Scanline_Renderer",
|
||||
"Quicksilver_Hardware_Renderer",
|
||||
]:
|
||||
render_elem_list = self.render_elements_product(output_file,
|
||||
startFrame,
|
||||
endFrame,
|
||||
img_fmt)
|
||||
|
||||
if renderer == "Arnold":
|
||||
render_elem_list = self.arnold_render_product(output_file,
|
||||
startFrame,
|
||||
endFrame,
|
||||
img_fmt)
|
||||
|
||||
return rgba_render_list, render_elem_list
|
||||
render_dict = {
|
||||
"beauty": self.get_expected_beauty(
|
||||
output_file, startFrame, endFrame, img_fmt)
|
||||
}
|
||||
return render_dict
|
||||
|
||||
def get_aovs(self, container):
|
||||
folder = rt.maxFilePath
|
||||
file = rt.maxFileName
|
||||
folder = folder.replace("\\", "/")
|
||||
setting = self._project_settings
|
||||
render_folder = get_default_render_folder(setting)
|
||||
filename, ext = os.path.splitext(file)
|
||||
render_dir = os.path.dirname(rt.rendOutputFilename)
|
||||
|
||||
output_file = os.path.join(folder,
|
||||
render_folder,
|
||||
filename,
|
||||
output_file = os.path.join(render_dir,
|
||||
container)
|
||||
|
||||
setting = self._project_settings
|
||||
img_fmt = setting["max"]["RenderSettings"]["image_format"] # noqa
|
||||
|
||||
|
|
@ -90,9 +52,9 @@ class RenderProducts(object):
|
|||
renderer_class = get_current_renderer()
|
||||
renderer = str(renderer_class).split(":")[0]
|
||||
render_dict = {}
|
||||
|
||||
if renderer in [
|
||||
"ART_Renderer",
|
||||
"Redshift_Renderer",
|
||||
"V_Ray_6_Hotfix_3",
|
||||
"V_Ray_GPU_6_Hotfix_3",
|
||||
"Default_Scanline_Renderer",
|
||||
|
|
@ -105,6 +67,23 @@ class RenderProducts(object):
|
|||
name: self.get_expected_render_elements(
|
||||
output_file, name, startFrame, endFrame, img_fmt)
|
||||
})
|
||||
if renderer == "Redshift_Renderer":
|
||||
render_name = self.get_render_elements_name()
|
||||
if render_name:
|
||||
rs_AovFiles = rt.Redshift_Renderer().SeparateAovFiles
|
||||
if rs_AovFiles != True and img_fmt == "exr":
|
||||
for name in render_name:
|
||||
if name == "RsCryptomatte":
|
||||
render_dict.update({
|
||||
name: self.get_expected_render_elements(
|
||||
output_file, name, startFrame, endFrame, img_fmt)
|
||||
})
|
||||
else:
|
||||
for name in render_name:
|
||||
render_dict.update({
|
||||
name: self.get_expected_render_elements(
|
||||
output_file, name, startFrame, endFrame, img_fmt)
|
||||
})
|
||||
|
||||
if renderer == "Arnold":
|
||||
render_name = self.get_arnold_product_name()
|
||||
|
|
@ -114,60 +93,31 @@ class RenderProducts(object):
|
|||
name: self.get_expected_arnold_product(
|
||||
output_file, name, startFrame, endFrame, img_fmt)
|
||||
})
|
||||
if renderer in [
|
||||
"V_Ray_6_Hotfix_3",
|
||||
"V_Ray_GPU_6_Hotfix_3"
|
||||
]:
|
||||
if img_fmt !="exr":
|
||||
render_name = self.get_render_elements_name()
|
||||
if render_name:
|
||||
for name in render_name:
|
||||
render_dict.update({
|
||||
name: self.get_expected_render_elements(
|
||||
output_file, name, startFrame, endFrame, img_fmt)
|
||||
})
|
||||
|
||||
return render_dict
|
||||
|
||||
def beauty_render_product(self, folder, startFrame, endFrame, fmt):
|
||||
def get_expected_beauty(self, folder, startFrame, endFrame, fmt):
|
||||
beauty_frame_range = []
|
||||
for f in range(startFrame, endFrame):
|
||||
beauty_output = f"{folder}.{f}.{fmt}"
|
||||
frame = "%04d" % f
|
||||
beauty_output = f"{folder}.{frame}.{fmt}"
|
||||
beauty_output = beauty_output.replace("\\", "/")
|
||||
beauty_frame_range.append(beauty_output)
|
||||
|
||||
return beauty_frame_range
|
||||
|
||||
# TODO: Get the arnold render product
|
||||
def arnold_render_product(self, folder, startFrame, endFrame, fmt):
|
||||
"""Get all the Arnold AOVs"""
|
||||
aovs = []
|
||||
|
||||
amw = rt.MaxtoAOps.AOVsManagerWindow()
|
||||
aov_mgr = rt.renderers.current.AOVManager
|
||||
# Check if there is any aov group set in AOV manager
|
||||
aov_group_num = len(aov_mgr.drivers)
|
||||
if aov_group_num < 1:
|
||||
return
|
||||
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 = f"{folder}_{aov.name}.{f}.{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):
|
||||
"""Get all the render element output files. """
|
||||
render_dirname = []
|
||||
|
||||
render_elem = rt.maxOps.GetCurRenderElementMgr()
|
||||
render_elem_num = render_elem.NumRenderElements()
|
||||
# get render elements from the renders
|
||||
for i in range(render_elem_num):
|
||||
renderlayer_name = render_elem.GetRenderElement(i)
|
||||
target, renderpass = str(renderlayer_name).split(":")
|
||||
if renderlayer_name.enabled:
|
||||
for f in range(startFrame, endFrame):
|
||||
render_element = f"{folder}_{renderpass}.{f}.{fmt}"
|
||||
render_element = render_element.replace("\\", "/")
|
||||
render_dirname.append(render_element)
|
||||
|
||||
return render_dirname
|
||||
|
||||
def get_arnold_product_name(self):
|
||||
"""Get all the Arnold AOVs name"""
|
||||
aov_name = []
|
||||
|
|
@ -193,14 +143,15 @@ class RenderProducts(object):
|
|||
"""Get all the expected Arnold AOVs"""
|
||||
aov_list = []
|
||||
for f in range(startFrame, endFrame):
|
||||
render_element = f"{folder}_{name}.{f}.{fmt}"
|
||||
frame = "%04d" % f
|
||||
render_element = f"{folder}_{name}.{frame}.{fmt}"
|
||||
render_element = render_element.replace("\\", "/")
|
||||
aov_list.append(render_element)
|
||||
|
||||
return aov_list
|
||||
|
||||
def get_render_elements_name(self):
|
||||
"""Get all the render element names. """
|
||||
"""Get all the render element names for general """
|
||||
render_name = []
|
||||
render_elem = rt.maxOps.GetCurRenderElementMgr()
|
||||
render_elem_num = render_elem.NumRenderElements()
|
||||
|
|
@ -209,9 +160,10 @@ class RenderProducts(object):
|
|||
# get render elements from the renders
|
||||
for i in range(render_elem_num):
|
||||
renderlayer_name = render_elem.GetRenderElement(i)
|
||||
if renderlayer_name.enabled or "Cryptomatte" in renderlayer_name:
|
||||
if renderlayer_name.enabled:
|
||||
target, renderpass = str(renderlayer_name).split(":")
|
||||
render_name.append(renderpass)
|
||||
|
||||
return render_name
|
||||
|
||||
def get_expected_render_elements(self, folder, name,
|
||||
|
|
@ -219,7 +171,8 @@ class RenderProducts(object):
|
|||
"""Get all the expected render element output files. """
|
||||
render_elements = []
|
||||
for f in range(startFrame, endFrame):
|
||||
render_element = f"{folder}_{name}.{f}.{fmt}"
|
||||
frame = "%04d" % f
|
||||
render_element = f"{folder}_{name}.{frame}.{fmt}"
|
||||
render_element = render_element.replace("\\", "/")
|
||||
render_elements.append(render_element)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Creator plugin for creating camera."""
|
||||
import os
|
||||
from openpype.hosts.max.api import plugin
|
||||
from openpype.pipeline import CreatedInstance
|
||||
from openpype.hosts.max.api.lib_rendersettings import RenderSettings
|
||||
|
|
@ -14,6 +15,9 @@ class CreateRender(plugin.MaxCreator):
|
|||
def create(self, subset_name, instance_data, pre_create_data):
|
||||
from pymxs import runtime as rt
|
||||
sel_obj = list(rt.selection)
|
||||
file = rt.maxFileName
|
||||
filename, _ = os.path.splitext(file)
|
||||
instance_data["AssetName"] = filename
|
||||
instance = super(CreateRender, self).create(
|
||||
subset_name,
|
||||
instance_data,
|
||||
|
|
|
|||
|
|
@ -29,19 +29,7 @@ class CollectRender(pyblish.api.InstancePlugin):
|
|||
context.data['currentFile'] = current_file
|
||||
asset = get_current_asset_name()
|
||||
|
||||
beauty_list, aov_list = RenderProducts().render_product(instance.name)
|
||||
full_render_list = list()
|
||||
if aov_list:
|
||||
full_render_list.extend(iter(beauty_list))
|
||||
full_render_list.extend(iter(aov_list))
|
||||
|
||||
else:
|
||||
full_render_list = beauty_list
|
||||
|
||||
files_by_aov = {
|
||||
"beauty": beauty_list
|
||||
}
|
||||
|
||||
files_by_aov = RenderProducts().get_beauty(instance.name)
|
||||
folder = folder.replace("\\", "/")
|
||||
aovs = RenderProducts().get_aovs(instance.name)
|
||||
files_by_aov.update(aovs)
|
||||
|
|
@ -67,14 +55,14 @@ class CollectRender(pyblish.api.InstancePlugin):
|
|||
# OCIO config not support in
|
||||
# most of the 3dsmax renderers
|
||||
# so this is currently hard coded
|
||||
setting = instance.context.data["project_settings"]
|
||||
image_io = setting["global"]["imageio"]
|
||||
instance.data["colorspaceConfig"] = image_io["ocio_config"]["filepath"][0] # noqa
|
||||
# TODO: add options for redshift/vray ocio config
|
||||
instance.data["colorspaceConfig"] = ""
|
||||
instance.data["colorspaceDisplay"] = "sRGB"
|
||||
instance.data["colorspaceView"] = "ACES 1.0"
|
||||
instance.data["colorspaceView"] = "ACES 1.0 SDR-video"
|
||||
instance.data["renderProducts"] = colorspace.ARenderProduct()
|
||||
instance.data["publishJobState"] = "Suspended"
|
||||
instance.data["attachTo"] = []
|
||||
|
||||
# also need to get the render dir for coversion
|
||||
data = {
|
||||
"asset": asset,
|
||||
"subset": str(instance.name),
|
||||
|
|
@ -84,7 +72,6 @@ class CollectRender(pyblish.api.InstancePlugin):
|
|||
"family": 'maxrender',
|
||||
"families": ['maxrender'],
|
||||
"source": filepath,
|
||||
"files": full_render_list,
|
||||
"plugin": "3dsmax",
|
||||
"frameStart": int(rt.rendStart),
|
||||
"frameEnd": int(rt.rendEnd),
|
||||
|
|
@ -93,3 +80,4 @@ class CollectRender(pyblish.api.InstancePlugin):
|
|||
}
|
||||
instance.data.update(data)
|
||||
self.log.info("data: {0}".format(data))
|
||||
self.log.debug("expectedFiles:{0}".format(instance.data["expectedFiles"]))
|
||||
|
|
|
|||
26
openpype/hosts/max/plugins/publish/save_scene.py
Normal file
26
openpype/hosts/max/plugins/publish/save_scene.py
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import pyblish.api
|
||||
import os
|
||||
|
||||
|
||||
class SaveCurrentScene(pyblish.api.ContextPlugin):
|
||||
"""Save current scene
|
||||
|
||||
"""
|
||||
|
||||
label = "Save current file"
|
||||
order = pyblish.api.ExtractorOrder - 0.49
|
||||
hosts = ["max"]
|
||||
families = ["maxrender", "workfile"]
|
||||
|
||||
def process(self, context):
|
||||
from pymxs import runtime as rt
|
||||
folder = rt.maxFilePath
|
||||
file = rt.maxFileName
|
||||
current = os.path.join(folder, file)
|
||||
assert context.data["currentFile"] == current
|
||||
|
||||
if rt.checkForSave():
|
||||
self.log.debug("Skipping file save as there "
|
||||
"are no modifications..")
|
||||
return
|
||||
rt.saveMaxFile(current)
|
||||
|
|
@ -78,7 +78,7 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline,
|
|||
job_info.BatchName = src_filename
|
||||
job_info.Plugin = instance.data["plugin"]
|
||||
job_info.UserName = context.data.get("deadlineUser", getpass.getuser())
|
||||
|
||||
job_info.EnableAutoTimeout = True
|
||||
# Deadline requires integers in frame range
|
||||
frames = "{start}-{end}".format(
|
||||
start=int(instance.data["frameStart"]),
|
||||
|
|
@ -207,9 +207,13 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline,
|
|||
first_file = next(self._iter_expected_files(files))
|
||||
rgb_bname = os.path.basename(output_beauty)
|
||||
dir = os.path.dirname(first_file)
|
||||
plugin_data["RenderOutput"] = f"{dir}/{rgb_bname}"
|
||||
|
||||
beauty_name = f"{dir}/{rgb_bname}"
|
||||
beauty_name = beauty_name.replace("\\", "/")
|
||||
plugin_data["RenderOutput"] = beauty_name
|
||||
# as 3dsmax has version with different languages
|
||||
plugin_data["Language"] = "ENU"
|
||||
renderer_class = get_current_renderer()
|
||||
|
||||
renderer = str(renderer_class).split(":")[0]
|
||||
if renderer in [
|
||||
"ART_Renderer",
|
||||
|
|
@ -223,13 +227,84 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline,
|
|||
for i, element in enumerate(render_elem_list):
|
||||
elem_bname = os.path.basename(element)
|
||||
new_elem = f"{dir}/{elem_bname}"
|
||||
new_elem = new_elem.replace("/", "\\")
|
||||
plugin_data["RenderElementOutputFilename%d" % i] = new_elem # noqa
|
||||
|
||||
|
||||
self.log.debug("plugin data:{}".format(plugin_data))
|
||||
plugin_info.update(plugin_data)
|
||||
|
||||
return job_info, plugin_info
|
||||
|
||||
def from_published_scene(self, replace_in_path=True):
|
||||
instance = self._instance
|
||||
workfile_instance = self._get_workfile_instance(instance.context)
|
||||
if workfile_instance is None:
|
||||
return
|
||||
|
||||
# determine published path from Anatomy.
|
||||
template_data = workfile_instance.data.get("anatomyData")
|
||||
rep = workfile_instance.data["representations"][0]
|
||||
template_data["representation"] = rep.get("name")
|
||||
template_data["ext"] = rep.get("ext")
|
||||
template_data["comment"] = None
|
||||
|
||||
anatomy = instance.context.data['anatomy']
|
||||
template_obj = anatomy.templates_obj["publish"]["path"]
|
||||
template_filled = template_obj.format_strict(template_data)
|
||||
file_path = os.path.normpath(template_filled)
|
||||
|
||||
self.log.info("Using published scene for render {}".format(file_path))
|
||||
|
||||
if not os.path.exists(file_path):
|
||||
self.log.error("published scene does not exist!")
|
||||
raise
|
||||
|
||||
if not replace_in_path:
|
||||
return file_path
|
||||
|
||||
# now we need to switch scene in expected files
|
||||
# because <scene> token will now point to published
|
||||
# scene file and that might differ from current one
|
||||
def _clean_name(path):
|
||||
return os.path.splitext(os.path.basename(path))[0]
|
||||
|
||||
new_scene = _clean_name(file_path)
|
||||
orig_scene = _clean_name(instance.data["AssetName"])
|
||||
expected_files = instance.data.get("expectedFiles")
|
||||
|
||||
if isinstance(expected_files[0], dict):
|
||||
# we have aovs and we need to iterate over them
|
||||
new_exp = {}
|
||||
for aov, files in expected_files[0].items():
|
||||
replaced_files = []
|
||||
for f in files:
|
||||
replaced_files.append(
|
||||
str(f).replace(orig_scene, new_scene)
|
||||
)
|
||||
new_exp[aov] = replaced_files
|
||||
# [] might be too much here, TODO
|
||||
instance.data["expectedFiles"] = [new_exp]
|
||||
else:
|
||||
new_exp = []
|
||||
for f in expected_files:
|
||||
new_exp.append(
|
||||
str(f).replace(orig_scene, new_scene)
|
||||
)
|
||||
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
|
||||
|
||||
self.log.info("Scene name was switched {} -> {}".format(
|
||||
orig_scene, new_scene
|
||||
))
|
||||
|
||||
return file_path
|
||||
|
||||
@staticmethod
|
||||
def _iter_expected_files(exp):
|
||||
if isinstance(exp[0], dict):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue