14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114 | class SaveScenesForCamera(pyblish.api.InstancePlugin):
"""Save scene files for multiple cameras without
editing the original scene before deadline submission
"""
label = "Save Scene files for cameras"
order = pyblish.api.ExtractorOrder - 0.48
hosts = ["max"]
families = ["maxrender"]
def process(self, instance):
if not instance.data.get("multiCamera"):
self.log.debug(
"Multi Camera disabled. "
"Skipping to save scene files for cameras")
return
current_folder = rt.maxFilePath
current_filename = rt.maxFileName
current_filepath = os.path.join(current_folder, current_filename)
camera_scene_files = []
scripts = []
filename, ext = os.path.splitext(current_filename)
fmt = RenderProducts().image_format()
cameras = instance.data.get("cameras")
if not cameras:
return
new_folder = f"{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("\\", "/")
camera_name = camera.replace(":", "_")
new_filename = f"{filename}_{camera_name}{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
filename = "{filename}"
new_filepath = "{new_filepath}"
new_output = "{new_output}"
camera = "{camera}"
camera_name = camera.replace(":", "_")
target_camera_node = rt.getNodeByName(camera)
rt.viewport.setCamera(target_camera_node)
rt.rendOutputFilename = new_output
directory = os.path.dirname(rt.rendOutputFilename)
directory = os.path.join(directory, filename)
if not os.path.exists(directory):
os.mkdir(directory)
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 = f"{{directory}}_{{camera_name}}_{{renderpass}}..{ext}"
render_elem.SetRenderElementFileName(i, aov_name)
rt.saveMaxFile(new_filepath)
""").format(filename=instance.name,
new_filepath=new_filepath,
new_output=new_output,
camera=camera,
ext=fmt)
scripts.append(script)
maxbatch_exe = os.path.join(
os.path.dirname(sys.executable), "3dsmaxbatch")
maxbatch_exe = maxbatch_exe.replace("\\", "/")
if platform.system().lower() == "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")
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")
full_script = "\n".join(scripts)
self.log.debug(f"Failed running script {tmp_script_path}:\n{full_script}")
current_filepath = current_filepath.replace("\\", "/")
tmp_script_path = tmp_script_path.replace("\\", "/")
run_subprocess([maxbatch_exe, tmp_script_path,
"-sceneFile", current_filepath],
logger=self.log)
for camera_scene in camera_scene_files:
if not os.path.exists(camera_scene):
full_script = "\n".join(scripts)
self.log.debug(f"Failed running script {tmp_script_path}:\n{full_script}")
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}")
|