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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175 | class CollectBlenderRender(plugin.BlenderInstancePlugin):
"""Gather all publishable render instances."""
order = pyblish.api.CollectorOrder + 0.01
hosts = ["blender"]
families = ["renderlayer"]
label = "Collect Render"
sync_workfile_version = False
@staticmethod
def generate_expected_files(
render_product, frame_start, frame_end, frame_step, ext
):
"""
Generate the expected files for the render product for the beauty
render. This returns a list of files that should be rendered. It
replaces the sequence of `#` with the frame number.
"""
expected_files = {}
aov_files = []
for render_name, render_file in render_product:
path = os.path.dirname(render_file)
file = os.path.basename(render_file)
for frame in range(frame_start, frame_end + 1, frame_step):
frame_str = str(frame).rjust(4, "0")
filename = re.sub("#+", frame_str, file)
expected_file = f"{os.path.join(path, filename)}.{ext}"
aov_files.append(expected_file.replace("\\", "/"))
expected_files[render_name] = [
aov for aov in aov_files if render_name in aov
]
return expected_files
def process(self, instance):
instance_node = instance.data["transientData"]["instance_node"]
render_data = instance_node.get("render_data")
assert render_data, "No render data found."
render_product = render_data.get("render_product")
aov_file_product = render_data.get("aov_file_product")
ext = render_data.get("image_format")
multilayer = render_data.get("multilayer_exr")
review = render_data.get("review", False)
frame_start = instance.data["frameStartHandle"]
frame_end = instance.data["frameEndHandle"]
if multilayer:
expected_files = next((rn_product for rn_product in render_product.values()), None)
expected_beauty = self.generate_expected_files(
expected_files, int(frame_start), int(frame_end),
int(bpy.context.scene.frame_step), ext)
instance.data.update({
"families": ["render", "render.farm"],
"frameStart": frame_start,
"frameEnd": frame_end,
"productType": "render",
"frameStartHandle": frame_start,
"frameEndHandle": frame_end,
"fps": instance.context.data["fps"],
"byFrameStep": bpy.context.scene.frame_step,
"review": review,
"multipartExr": ext == "exr" and multilayer,
"farm": True,
"expectedFiles": [expected_beauty],
# OCIO not currently implemented in Blender, but the following
# settings are required by the schema, so it is hardcoded.
# TODO: Implement OCIO in Blender
"colorspaceConfig": "",
"colorspaceDisplay": "sRGB",
"colorspaceView": "ACES 1.0 SDR-video",
"renderProducts": colorspace.ARenderProduct(
frame_start=frame_start,
frame_end=frame_end
),
})
else:
instance.data["integrate"] = False
self.create_renderlayer_instance(
instance, render_product,
aov_file_product, ext, multilayer,
frame_start, frame_end, review)
def create_renderlayer_instance(self, instance, render_product,
aov_file_product, ext, multilayer,
frame_start, frame_end, review):
context = instance.context
prod_type = "render"
project_name = instance.context.data["projectName"]
folder_entity = ayon_api.get_folder_by_path(
project_name,
instance.data["folderPath"]
)
task_name = instance.data.get("task")
task_entity = None
if folder_entity and task_name:
task_entity = ayon_api.get_task_by_name(
project_name, folder_entity["id"], task_name
)
for view_layer in bpy.context.scene.view_layers:
viewlayer_name = view_layer.name
rn_product = render_product[viewlayer_name]
aov_product = aov_file_product[viewlayer_name] if aov_file_product else {}
viewlayer_product_name = get_product_name(
context.data["projectName"],
task_entity["name"],
task_entity["taskType"],
context.data["hostName"],
product_type=prod_type,
variant=instance.data["variant"] + viewlayer_name,
project_settings=context.data["project_settings"]
)
rn_layer_instance = context.create_instance(viewlayer_product_name)
rn_layer_instance[:] = instance[:]
expected_beauty = self.generate_expected_files(
rn_product, int(frame_start), int(frame_end),
int(bpy.context.scene.frame_step), ext)
expected_aovs = self.generate_expected_files(
aov_product, int(frame_start), int(frame_end),
int(bpy.context.scene.frame_step), ext)
expected_files = expected_beauty | expected_aovs
rn_layer_instance.data.update({
"family": prod_type,
"families": [prod_type, "render.farm"],
"fps": context.data["fps"],
"byFrameStep": instance.data["creator_attributes"].get("step", 1),
"review": review,
"multipartExr": ext == "exr" and multilayer,
"farm": True,
"folderPath": instance.data["folderPath"],
"productName": viewlayer_product_name,
"productType": prod_type,
"expectedFiles": [expected_files],
"frameStart": instance.data["frameStart"],
"frameEnd": instance.data["frameEnd"],
"frameStartHandle": frame_start,
"frameEndHandle": frame_end,
"task": instance.data["task"],
# OCIO not currently implemented in Blender, but the following
# settings are required by the schema, so it is hardcoded.
# TODO: Implement OCIO in Blender
"colorspaceConfig": "",
"colorspaceDisplay": "sRGB",
"colorspaceView": "ACES 1.0 SDR-video",
"renderProducts": colorspace.ARenderProduct(
frame_start=frame_start,
frame_end=frame_end
),
"publish_attributes": instance.data["publish_attributes"]
})
instance.append(rn_layer_instance)
|