exporting camera scene through instanceplugin by subprocess

This commit is contained in:
Kayla Man 2023-07-20 23:45:08 +08:00
parent 3bb7f871d4
commit f349e720b0
2 changed files with 128 additions and 0 deletions

View file

@ -182,6 +182,24 @@ class RenderSettings(object):
target_layer = rt.batchRenderMgr.GetView(target_layer_no)
return target_layer.outputFilename
def batch_render_elements(self, camera):
target_layer_no = rt.batchRenderMgr.FindView(camera)
target_layer = rt.batchRenderMgr.GetView(target_layer_no)
outputfilename = target_layer.outputFilename
directory = os.path.dirname(outputfilename)
render_elem = rt.maxOps.GetCurRenderElementMgr()
render_elem_num = render_elem.NumRenderElements()
if render_elem_num < 0:
return
ext = self._project_settings["max"]["RenderSettings"]["image_format"] # noqa
for i in range(render_elem_num):
renderlayer_name = render_elem.GetRenderElement(i)
target, renderpass = str(renderlayer_name).split(":")
aov_name = "{0}_{1}_{2}..{3}".format(
directory, camera, renderpass, ext)
render_elem.SetRenderElementFileName(i, aov_name)
def batch_render_layer(self, container,
output_dir, cameras):
outputs = list()

View file

@ -0,0 +1,110 @@
import pyblish.api
import os
import sys
import tempfile
from pymxs import runtime as rt
from openpype.lib import run_subprocess
from openpype.hosts.max.api.lib import get_max_version
from openpype.hosts.max.api.lib_rendersettings import RenderSettings
from openpype.hosts.max.api.lib_renderproducts import RenderProducts
class SaveScenesForCamera(pyblish.api.InstancePlugin):
"""Save scene files for multiple cameras before
deadline submission
"""
label = "Save Scene files for cameras"
order = pyblish.api.ExtractorOrder - 0.48
hosts = ["max"]
families = ["maxrender", "workfile"]
def process(self, instance):
if not instance.data.get("multiCamera"):
self.log.debug("Skipping instance...")
return
current_folder = rt.maxFilePath
current_filename = rt.maxFileName
current_filepath = os.path.join(current_folder, current_filename)
camera_scene_files = []
repres_list = []
scripts = []
filename, ext = os.path.splitext(current_filename)
fmt = RenderProducts().image_format()
cameras = instance.data.get("cameras")
if not cameras:
return
new_folder = "{}_{}".format(current_folder, filename)
os.makedirs(new_folder, exist_ok=True)
for camera in cameras:
new_output = RenderSettings().get_batch_render_output(camera) # noqa
new_output = new_output.replace("\\", "/")
new_filename = "{}_{}{}".format(
filename, camera, ext)
new_filepath = os.path.join(new_folder, new_filename)
new_filepath = new_filepath.replace("\\", "/")
camera_scene_files.append(new_filepath)
RenderSettings().batch_render_elements(camera)
rt.rendOutputFilename = new_output
rt.saveMaxFile(current_filepath)
script = ("""
from pymxs import runtime as rt
import os
new_filepath = "{new_filepath}"
new_output = "{new_output}"
camera = "{camera}"
rt.rendOutputFilename = new_output
directory = os.path.dirname(new_output)
render_elem = rt.maxOps.GetCurRenderElementMgr()
render_elem_num = render_elem.NumRenderElements()
if render_elem_num > 0:
ext = "{ext}"
for i in range(render_elem_num):
renderlayer_name = render_elem.GetRenderElement(i)
target, renderpass = str(renderlayer_name).split(":")
aov_name = directory + "_" + camera + "_" + renderpass + "." + "." + ext
render_elem.SetRenderElementFileName(i, aov_name)
rt.saveMaxFile(new_filepath)
""").format(new_filepath=new_filepath,
new_output=new_output,
camera=camera,
ext=fmt)
scripts.append(script)
max_version = get_max_version()
maxBatch_exe = os.path.join(os.getenv(f"ADSK_3DSMAX_x64_{max_version}"), "3dsmaxbatch")
maxBatch_exe = maxBatch_exe.replace("\\", "/")
if sys.platform == "windows":
maxBatch_exe += ".exe"
maxBatch_exe = os.path.normpath(maxBatch_exe)
with tempfile.TemporaryDirectory() as tmp_dir_name:
tmp_script_path = os.path.join(tmp_dir_name, "extract_scene_files.py")
log_file =os.path.join(tmp_dir_name, "fatal.log")
self.log.info("Using script file: {}".format(tmp_script_path))
with open(tmp_script_path, "wt") as tmp:
for script in scripts:
tmp.write(script+"\n")
tmp.write("rt.quitMax(quiet=True)"+"\n")
tmp.write("import time"+"\n")
tmp.write("time.sleep(3)")
try:
current_filepath = current_filepath.replace("\\","/")
log_file = log_file.replace("\\", "/")
tmp_script_path = tmp_script_path.replace("\\","/")
run_subprocess([maxBatch_exe, tmp_script_path,
"-sceneFile", current_filepath])
except RuntimeError:
self.log.debug("Checking the scene files existing or not")
for camera_scene in camera_scene_files:
if not os.path.exists(camera_scene):
self.log.error("Camera scene files not existed yet!")
raise RuntimeError("MaxBatch.exe doesn't run as expected")
self.log.debug(f"Found Camera scene:{camera_scene}")
if "sceneFiles" not in instance.data:
instance.data["sceneFiles"] = camera_scene_files