LEFT | RIGHT |
(no file at all) | |
1 /* | 1 /* |
2 * ***** BEGIN GPL LICENSE BLOCK ***** | 2 * ***** BEGIN GPL LICENSE BLOCK ***** |
3 * | 3 * |
4 * This program is free software; you can redistribute it and/or | 4 * This program is free software; you can redistribute it and/or |
5 * modify it under the terms of the GNU General Public License | 5 * modify it under the terms of the GNU General Public License |
6 * as published by the Free Software Foundation; either version 2 | 6 * as published by the Free Software Foundation; either version 2 |
7 * of the License, or (at your option) any later version.· | 7 * of the License, or (at your option) any later version.· |
8 * | 8 * |
9 * This program is distributed in the hope that it will be useful, | 9 * This program is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 { SOCK_FLOAT, 0, N_("Alpha"),
1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, | 48 { SOCK_FLOAT, 0, N_("Alpha"),
1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, |
49 { SOCK_FLOAT, 0, N_("Z"),
1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, | 49 { SOCK_FLOAT, 0, N_("Z"),
1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, |
50 { SOCK_VECTOR, 0, N_("Normal"), 0.0f, 0.
0f, 0.0f, 0.0f, 0.0f, 1.0f}, | 50 { SOCK_VECTOR, 0, N_("Normal"), 0.0f, 0.
0f, 0.0f, 0.0f, 0.0f, 1.0f}, |
51 { SOCK_VECTOR, 0, N_("UV"),
1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, | 51 { SOCK_VECTOR, 0, N_("UV"),
1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, |
52 { SOCK_VECTOR, 0, N_("Speed"), 1.0f, 0.
0f, 0.0f, 0.0f, 0.0f, 1.0f}, | 52 { SOCK_VECTOR, 0, N_("Speed"), 1.0f, 0.
0f, 0.0f, 0.0f, 0.0f, 1.0f}, |
53 { SOCK_RGBA, 0, N_("Color"),
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, | 53 { SOCK_RGBA, 0, N_("Color"),
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, |
54 { SOCK_RGBA, 0, N_("Diffuse"), 0.0f, 0.
0f, 0.0f, 0.0f, 0.0f, 1.0f}, | 54 { SOCK_RGBA, 0, N_("Diffuse"), 0.0f, 0.
0f, 0.0f, 0.0f, 0.0f, 1.0f}, |
55 { SOCK_RGBA, 0, N_("Specular"), 0.0f, 0.
0f, 0.0f, 0.0f, 0.0f, 1.0f}, | 55 { SOCK_RGBA, 0, N_("Specular"), 0.0f, 0.
0f, 0.0f, 0.0f, 0.0f, 1.0f}, |
56 { SOCK_RGBA, 0, N_("Shadow"),
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, | 56 { SOCK_RGBA, 0, N_("Shadow"),
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, |
57 { SOCK_RGBA, 0, N_("AO"),
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, | 57 { SOCK_RGBA, 0, N_("AO"),
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, |
58 { SOCK_RGBA, 0, N_("Reflect"), 0.0f, 0.
0f, 0.0f, 0.0f, 0.0f, 1.0f}, | |
59 { SOCK_RGBA, 0, N_("Refract"), 0.0f, 0.
0f, 0.0f, 0.0f, 0.0f, 1.0f}, | |
60 { SOCK_RGBA, 0, N_("Indirect"), 0.0f, 0.
0f, 0.0f, 0.0f, 0.0f, 1.0f}, | |
61 { SOCK_FLOAT, 0, N_("IndexOB"), 0.0f, 0.
0f, 0.0f, 0.0f, 0.0f, 1.0f}, | |
62 { SOCK_FLOAT, 0, N_("IndexMA"), 0.0f, 0.
0f, 0.0f, 0.0f, 0.0f, 1.0f}, | |
63 { SOCK_FLOAT, 0, N_("Mist"),
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, | |
64 { SOCK_RGBA, 0, N_("Emit"),
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, | |
65 { SOCK_RGBA, 0, N_("Environment"), 0.0f, 0.
0f, 0.0f, 0.0f, 0.0f, 1.0f}, | |
66 { SOCK_RGBA, 0, N_("Diffuse Direct"), 0.0f, 0.
0f, 0.0f, 0.0f, 0.0f, 1.0f}, | |
67 { SOCK_RGBA, 0, N_("Diffuse Indirect"), 0.0f, 0.0f, 0.0f
, 0.0f, 0.0f, 1.0f}, | |
68 { SOCK_RGBA, 0, N_("Diffuse Color"), 0.0f, 0.
0f, 0.0f, 0.0f, 0.0f, 1.0f}, | |
69 { SOCK_RGBA, 0, N_("Glossy Direct"), 0.0f, 0.
0f, 0.0f, 0.0f, 0.0f, 1.0f}, | |
70 { SOCK_RGBA, 0, N_("Glossy Indirect"), 0.0f, 0.0f, 0.0f
, 0.0f, 0.0f, 1.0f}, | |
71 { SOCK_RGBA, 0, N_("Glossy Color"), 0.0f, 0.
0f, 0.0f, 0.0f, 0.0f, 1.0f}, | |
72 { SOCK_RGBA, 0, N_("Transmission Direct"), 0.0f, 0.0f, 0.0f
, 0.0f, 0.0f, 1.0f}, | |
73 { SOCK_RGBA, 0, N_("Transmission Indirect"), 0.0f, 0.0f, 0.0f
, 0.0f, 0.0f, 1.0f}, | |
74 { SOCK_RGBA, 0, N_("Transmission Color"), 0.0f, 0.0f, 0.0f
, 0.0f, 0.0f, 1.0f}, | |
75 { SOCK_RGBA, 0, N_("Subsurface Direct"), 0.0f, 0.0f, 0.0f
, 0.0f, 0.0f, 1.0f}, | |
76 { SOCK_RGBA, 0, N_("Subsurface Indirect"), 0.0f, 0.0f, 0.0f
, 0.0f, 0.0f, 1.0f}, | |
77 { SOCK_RGBA, 0, N_("Subsurface Color"), 0.0f, 0.0f, 0.0f
, 0.0f, 0.0f, 1.0f}, | |
78 { -1, 0, "" } | 58 { -1, 0, "" } |
79 }; | 59 }; |
80 | 60 |
81 static bNodeSocket *cmp_node_image_add_render_pass_output(bNodeTree *ntree, bNod
e *node, int pass, int rres_index) | |
82 { | |
83 bNodeSocket *sock; | |
84 NodeImageLayer *sockdata; | |
85 ········ | |
86 sock = node_add_socket_from_template(ntree, node, &cmp_node_rlayers_out[
rres_index], SOCK_OUT); | |
87 /* extra socket info */ | |
88 sockdata = MEM_callocN(sizeof(NodeImageLayer), "node image layer"); | |
89 sock->storage = sockdata; | |
90 ········ | |
91 sockdata->pass_flag = pass; | |
92 ········ | |
93 return sock; | |
94 } | |
95 | 61 |
96 static void cmp_node_image_add_render_pass_outputs(bNodeTree *ntree, bNode *node
, int passflag) | 62 /* note: this function is used for multilayer too, to ensure uniform· |
97 { | 63 handling with BKE_image_get_ibuf() */ |
98 if (passflag & SCE_PASS_COMBINED) { | 64 static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *i
user) |
99 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_COMB
INED, RRES_OUT_IMAGE); | |
100 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_COMB
INED, RRES_OUT_ALPHA); | |
101 } | |
102 ········ | |
103 if (passflag & SCE_PASS_Z) | |
104 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_Z, R
RES_OUT_Z); | |
105 if (passflag & SCE_PASS_NORMAL) | |
106 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_NORM
AL, RRES_OUT_NORMAL); | |
107 if (passflag & SCE_PASS_VECTOR) | |
108 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_VECT
OR, RRES_OUT_VEC); | |
109 if (passflag & SCE_PASS_UV) | |
110 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_UV,
RRES_OUT_UV); | |
111 if (passflag & SCE_PASS_RGBA) | |
112 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_RGBA
, RRES_OUT_RGBA); | |
113 if (passflag & SCE_PASS_DIFFUSE) | |
114 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_DIFF
USE, RRES_OUT_DIFF); | |
115 if (passflag & SCE_PASS_SPEC) | |
116 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SPEC
, RRES_OUT_SPEC); | |
117 if (passflag & SCE_PASS_SHADOW) | |
118 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SHAD
OW, RRES_OUT_SHADOW); | |
119 if (passflag & SCE_PASS_AO) | |
120 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_AO,
RRES_OUT_AO); | |
121 if (passflag & SCE_PASS_REFLECT) | |
122 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_REFL
ECT, RRES_OUT_REFLECT); | |
123 if (passflag & SCE_PASS_REFRACT) | |
124 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_REFR
ACT, RRES_OUT_REFRACT); | |
125 if (passflag & SCE_PASS_INDIRECT) | |
126 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_INDI
RECT, RRES_OUT_INDIRECT); | |
127 if (passflag & SCE_PASS_INDEXOB) | |
128 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_INDE
XOB, RRES_OUT_INDEXOB); | |
129 if (passflag & SCE_PASS_INDEXMA) | |
130 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_INDE
XMA, RRES_OUT_INDEXMA); | |
131 if (passflag & SCE_PASS_MIST) | |
132 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_MIST
, RRES_OUT_MIST); | |
133 if (passflag & SCE_PASS_EMIT) | |
134 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_EMIT
, RRES_OUT_EMIT); | |
135 if (passflag & SCE_PASS_ENVIRONMENT) | |
136 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_ENVI
RONMENT, RRES_OUT_ENV); | |
137 ········ | |
138 if (passflag & SCE_PASS_DIFFUSE_DIRECT) | |
139 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_DIFF
USE_DIRECT, RRES_OUT_DIFF_DIRECT); | |
140 if (passflag & SCE_PASS_DIFFUSE_INDIRECT) | |
141 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_DIFF
USE_INDIRECT, RRES_OUT_DIFF_INDIRECT); | |
142 if (passflag & SCE_PASS_DIFFUSE_COLOR) | |
143 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_DIFF
USE_COLOR, RRES_OUT_DIFF_COLOR); | |
144 ········ | |
145 if (passflag & SCE_PASS_GLOSSY_DIRECT) | |
146 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_GLOS
SY_DIRECT, RRES_OUT_GLOSSY_DIRECT); | |
147 if (passflag & SCE_PASS_GLOSSY_INDIRECT) | |
148 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_GLOS
SY_INDIRECT, RRES_OUT_GLOSSY_INDIRECT); | |
149 if (passflag & SCE_PASS_GLOSSY_COLOR) | |
150 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_GLOS
SY_COLOR, RRES_OUT_GLOSSY_COLOR); | |
151 ········ | |
152 if (passflag & SCE_PASS_TRANSM_DIRECT) | |
153 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_TRAN
SM_DIRECT, RRES_OUT_TRANSM_DIRECT); | |
154 if (passflag & SCE_PASS_TRANSM_INDIRECT) | |
155 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_TRAN
SM_INDIRECT, RRES_OUT_TRANSM_INDIRECT); | |
156 if (passflag & SCE_PASS_TRANSM_COLOR) | |
157 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_TRAN
SM_COLOR, RRES_OUT_TRANSM_COLOR); | |
158 ················ | |
159 if (passflag & SCE_PASS_SUBSURFACE_DIRECT) | |
160 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SUBS
URFACE_DIRECT, RRES_OUT_SUBSURFACE_DIRECT); | |
161 if (passflag & SCE_PASS_SUBSURFACE_INDIRECT) | |
162 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SUBS
URFACE_INDIRECT, RRES_OUT_SUBSURFACE_INDIRECT); | |
163 if (passflag & SCE_PASS_SUBSURFACE_COLOR) | |
164 cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SUBS
URFACE_COLOR, RRES_OUT_SUBSURFACE_COLOR); | |
165 } | |
166 | |
167 static void cmp_node_image_add_multilayer_outputs(bNodeTree *ntree, bNode *node,
RenderLayer *rl) | |
168 { | |
169 bNodeSocket *sock; | |
170 NodeImageLayer *sockdata; | |
171 RenderPass *rpass; | |
172 int index; | |
173 for (rpass = rl->passes.first, index = 0; rpass; rpass = rpass->next, ++
index) { | |
174 int type; | |
175 if (rpass->channels == 1) | |
176 type = SOCK_FLOAT; | |
177 else | |
178 type = SOCK_RGBA; | |
179 ················ | |
180 sock = nodeAddStaticSocket(ntree, node, SOCK_OUT, type, PROP_NON
E, rpass->name, rpass->name); | |
181 /* extra socket info */ | |
182 sockdata = MEM_callocN(sizeof(NodeImageLayer), "node image layer
"); | |
183 sock->storage = sockdata; | |
184 ················ | |
185 sockdata->pass_index = index; | |
186 sockdata->pass_flag = rpass->passtype; | |
187 } | |
188 } | |
189 | |
190 static void cmp_node_image_create_outputs(bNodeTree *ntree, bNode *node) | |
191 { | |
192 Image *ima = (Image *)node->id; | |
193 if (ima) { | |
194 ImageUser *iuser = node->storage; | |
195 ImageUser load_iuser = {NULL}; | |
196 ImBuf *ibuf; | |
197 int offset = BKE_image_sequence_guess_offset(ima); | |
198 | |
199 /* It is possible that image user in this node is not | |
200 * properly updated yet. In this case loading image will | |
201 * fail and sockets detection will go wrong. | |
202 * | |
203 * So we manually construct image user to be sure first | |
204 * image from sequence (that one which is set as filename | |
205 * for image datablock) is used for sockets detection | |
206 */ | |
207 load_iuser.ok = 1; | |
208 load_iuser.framenr = offset; | |
209 | |
210 /* make sure ima->type is correct */ | |
211 ibuf = BKE_image_acquire_ibuf(ima, &load_iuser, NULL); | |
212 ················ | |
213 if (ima->rr) { | |
214 RenderLayer *rl = BLI_findlink(&ima->rr->layers, iuser->
layer); | |
215 ························ | |
216 if (rl) { | |
217 if (ima->type != IMA_TYPE_MULTILAYER) | |
218 cmp_node_image_add_render_pass_outputs(n
tree, node, rl->passflag); | |
219 else | |
220 cmp_node_image_add_multilayer_outputs(nt
ree, node, rl); | |
221 } | |
222 else | |
223 cmp_node_image_add_render_pass_outputs(ntree, no
de, RRES_OUT_IMAGE | RRES_OUT_ALPHA); | |
224 } | |
225 else | |
226 cmp_node_image_add_render_pass_outputs(ntree, node, RRES
_OUT_IMAGE | RRES_OUT_ALPHA | RRES_OUT_Z); | |
227 ················ | |
228 BKE_image_release_ibuf(ima, ibuf, NULL); | |
229 } | |
230 else | |
231 cmp_node_image_add_render_pass_outputs(ntree, node, RRES_OUT_IMA
GE | RRES_OUT_ALPHA); | |
232 } | |
233 | |
234 static bNodeSocket *cmp_node_image_output_find_match(bNode *UNUSED(node), bNodeS
ocket *newsock, ListBase *oldsocklist) | |
235 { | |
236 bNodeSocket *sock; | |
237 ········ | |
238 for (sock = oldsocklist->first; sock; sock = sock->next) | |
239 if (STREQ(sock->name, newsock->name)) | |
240 return sock; | |
241 return NULL; | |
242 } | |
243 | |
244 static bNodeSocket *cmp_node_image_output_relink(bNode *node, bNodeSocket *oldso
ck, int oldindex) | |
245 { | |
246 bNodeSocket *sock; | |
247 ········ | |
248 /* first try to find matching socket name */ | |
249 for (sock = node->outputs.first; sock; sock = sock->next) | |
250 if (STREQ(sock->name, oldsock->name)) | |
251 return sock; | |
252 ········ | |
253 /* no matching name, simply link to same index */ | |
254 return BLI_findlink(&node->outputs, oldindex); | |
255 } | |
256 | |
257 static void cmp_node_image_sync_output(bNode *UNUSED(node), bNodeSocket *UNUSED(
newsock), bNodeSocket *UNUSED(oldsock)) | |
258 { | |
259 /* pass */ | |
260 } | |
261 | |
262 /* XXX make this into a generic socket verification function for dynamic socket
replacement (multilayer, groups, static templates) */ | |
263 static void cmp_node_image_verify_outputs(bNodeTree *ntree, bNode *node) | |
264 { | |
265 bNodeSocket *newsock, *oldsock, *oldsock_next; | |
266 ListBase oldsocklist; | |
267 int oldindex; | |
268 bNodeLink *link; | |
269 ········ | |
270 /* store current nodes in oldsocklist, then clear socket list */ | |
271 oldsocklist = node->outputs; | |
272 node->outputs.first = node->outputs.last = NULL; | |
273 ········ | |
274 /* XXX make callback */ | |
275 cmp_node_image_create_outputs(ntree, node); | |
276 ········ | |
277 for (newsock = node->outputs.first; newsock; newsock = newsock->next) { | |
278 /* XXX make callback */ | |
279 oldsock = cmp_node_image_output_find_match(node, newsock, &oldso
cklist); | |
280 if (oldsock) { | |
281 /* XXX make callback */ | |
282 cmp_node_image_sync_output(node, newsock, oldsock); | |
283 } | |
284 } | |
285 ········ | |
286 /* move links to new socket */ | |
287 for (oldsock = oldsocklist.first, oldindex = 0; oldsock; oldsock = oldso
ck->next, ++oldindex) { | |
288 newsock = cmp_node_image_output_relink(node, oldsock, oldindex); | |
289 ················ | |
290 if (newsock) { | |
291 for (link = ntree->links.first; link; link = link->next)
{ | |
292 if (link->fromsock == oldsock) | |
293 link->fromsock = newsock; | |
294 } | |
295 } | |
296 } | |
297 ········ | |
298 /* delete old sockets | |
299 * XXX oldsock is not actually in the node->outputs list any more, | |
300 * but the nodeRemoveSocket function works anyway. In future this | |
301 * should become part of the core code, so can take care of this behavio
r. | |
302 */ | |
303 for (oldsock = oldsocklist.first; oldsock; oldsock = oldsock_next) { | |
304 oldsock_next = oldsock->next; | |
305 MEM_freeN(oldsock->storage); | |
306 nodeRemoveSocket(ntree, node, oldsock); | |
307 } | |
308 } | |
309 | |
310 static void cmp_node_image_update(bNodeTree *ntree, bNode *node) | |
311 { | |
312 /* avoid unnecessary updates, only changes to the image/image user data
are of interest */ | |
313 if (node->update & NODE_UPDATE_ID) | |
314 cmp_node_image_verify_outputs(ntree, node); | |
315 } | |
316 | |
317 static void node_composit_init_image(bNodeTree *ntree, bNode *node) | |
318 { | |
319 ImageUser *iuser = MEM_callocN(sizeof(ImageUser), "node image user"); | |
320 node->storage = iuser; | |
321 iuser->frames = 1; | |
322 iuser->sfra = 1; | |
323 iuser->fie_ima = 2; | |
324 iuser->ok = 1; | |
325 ········ | |
326 /* setup initial outputs */ | |
327 cmp_node_image_verify_outputs(ntree, node); | |
328 } | |
329 | |
330 static void node_composit_free_image(bNode *node) | |
331 { | |
332 bNodeSocket *sock; | |
333 ········ | |
334 /* free extra socket info */ | |
335 for (sock = node->outputs.first; sock; sock = sock->next) | |
336 MEM_freeN(sock->storage); | |
337 ········ | |
338 MEM_freeN(node->storage); | |
339 } | |
340 | |
341 static void node_composit_copy_image(bNodeTree *UNUSED(dest_ntree), bNode *dest_
node, bNode *src_node) | |
342 { | |
343 bNodeSocket *sock; | |
344 ········ | |
345 dest_node->storage = MEM_dupallocN(src_node->storage); | |
346 ········ | |
347 /* copy extra socket info */ | |
348 for (sock = src_node->outputs.first; sock; sock = sock->next) | |
349 sock->new_sock->storage = MEM_dupallocN(sock->storage); | |
350 } | |
351 | |
352 void register_node_type_cmp_image(void) | |
353 { | |
354 static bNodeType ntype; | |
355 | |
356 cmp_node_type_base(&ntype, CMP_NODE_IMAGE, "Image", NODE_CLASS_INPUT, NO
DE_PREVIEW); | |
357 node_type_init(&ntype, node_composit_init_image); | |
358 node_type_storage(&ntype, "ImageUser", node_composit_free_image, node_co
mposit_copy_image); | |
359 node_type_update(&ntype, cmp_node_image_update, NULL); | |
360 | |
361 nodeRegisterType(&ntype); | |
362 } | |
363 | |
364 | |
365 /* **************** RENDER RESULT ******************** */ | |
366 | |
367 static void set_output_visible(bNode *node, int passflag, int index, int pass) | |
368 { | |
369 bNodeSocket *sock = BLI_findlink(&node->outputs, index); | |
370 /* clear the SOCK_HIDDEN flag as well, in case a socket was hidden befor
e */ | |
371 if (passflag & pass) | |
372 sock->flag &= ~(SOCK_HIDDEN | SOCK_UNAVAIL); | |
373 else | |
374 sock->flag |= SOCK_UNAVAIL; | |
375 } | |
376 | |
377 /* clumsy checking... should do dynamic outputs once */ | |
378 void node_cmp_rlayers_force_hidden_passes(bNode *node) | |
379 { | |
380 Scene *scene = (Scene *)node->id; | |
381 SceneRenderLayer *srl; | |
382 int passflag; | |
383 bNodeSocket *sock; | |
384 ········ | |
385 /* must always have valid scene pointer */ | |
386 if (!scene) | |
387 return; | |
388 ········ | |
389 srl = BLI_findlink(&scene->r.layers, node->custom1); | |
390 if (!srl) | |
391 return; | |
392 ········ | |
393 passflag = srl->passflag; | |
394 ········ | |
395 for (sock = node->outputs.first; sock; sock = sock->next) | |
396 sock->flag &= ~SOCK_UNAVAIL; | |
397 ········ | |
398 set_output_visible(node, passflag, RRES_OUT_IMAGE, SCE_
PASS_COMBINED); | |
399 set_output_visible(node, passflag, RRES_OUT_ALPHA, SCE_
PASS_COMBINED); | |
400 ············································································ | |
401 set_output_visible(node, passflag, RRES_OUT_Z, SCE_
PASS_Z); | |
402 set_output_visible(node, passflag, RRES_OUT_NORMAL, SCE_
PASS_NORMAL); | |
403 set_output_visible(node, passflag, RRES_OUT_VEC, SCE_
PASS_VECTOR); | |
404 set_output_visible(node, passflag, RRES_OUT_UV, SCE_
PASS_UV); | |
405 set_output_visible(node, passflag, RRES_OUT_RGBA, SCE_
PASS_RGBA); | |
406 set_output_visible(node, passflag, RRES_OUT_DIFF, SCE_
PASS_DIFFUSE); | |
407 set_output_visible(node, passflag, RRES_OUT_SPEC, SCE_
PASS_SPEC); | |
408 set_output_visible(node, passflag, RRES_OUT_SHADOW, SCE_
PASS_SHADOW); | |
409 set_output_visible(node, passflag, RRES_OUT_AO, SCE_
PASS_AO); | |
410 set_output_visible(node, passflag, RRES_OUT_REFLECT, SCE_
PASS_REFLECT); | |
411 set_output_visible(node, passflag, RRES_OUT_REFRACT, SCE_
PASS_REFRACT); | |
412 set_output_visible(node, passflag, RRES_OUT_INDIRECT, SCE_
PASS_INDIRECT); | |
413 set_output_visible(node, passflag, RRES_OUT_INDEXOB, SCE_
PASS_INDEXOB); | |
414 set_output_visible(node, passflag, RRES_OUT_INDEXMA, SCE_
PASS_INDEXMA); | |
415 set_output_visible(node, passflag, RRES_OUT_MIST, SCE_
PASS_MIST); | |
416 set_output_visible(node, passflag, RRES_OUT_EMIT, SCE_
PASS_EMIT); | |
417 set_output_visible(node, passflag, RRES_OUT_ENV, SCE_
PASS_ENVIRONMENT); | |
418 set_output_visible(node, passflag, RRES_OUT_DIFF_DIRECT, SCE_
PASS_DIFFUSE_DIRECT); | |
419 set_output_visible(node, passflag, RRES_OUT_DIFF_INDIRECT, SCE_
PASS_DIFFUSE_INDIRECT); | |
420 set_output_visible(node, passflag, RRES_OUT_DIFF_COLOR, SCE_
PASS_DIFFUSE_COLOR); | |
421 set_output_visible(node, passflag, RRES_OUT_GLOSSY_DIRECT, SCE_
PASS_GLOSSY_DIRECT); | |
422 set_output_visible(node, passflag, RRES_OUT_GLOSSY_INDIRECT, SCE_
PASS_GLOSSY_INDIRECT); | |
423 set_output_visible(node, passflag, RRES_OUT_GLOSSY_COLOR, SCE_
PASS_GLOSSY_COLOR); | |
424 set_output_visible(node, passflag, RRES_OUT_TRANSM_DIRECT, SCE_
PASS_TRANSM_DIRECT); | |
425 set_output_visible(node, passflag, RRES_OUT_TRANSM_INDIRECT, SCE_
PASS_TRANSM_INDIRECT); | |
426 set_output_visible(node, passflag, RRES_OUT_TRANSM_COLOR, SCE_
PASS_TRANSM_COLOR); | |
427 set_output_visible(node, passflag, RRES_OUT_SUBSURFACE_DIRECT, SCE_
PASS_SUBSURFACE_DIRECT); | |
428 set_output_visible(node, passflag, RRES_OUT_SUBSURFACE_INDIRECT, SCE_
PASS_SUBSURFACE_INDIRECT); | |
429 set_output_visible(node, passflag, RRES_OUT_SUBSURFACE_COLOR, SCE_
PASS_SUBSURFACE_COLOR); | |
430 } | |
431 | |
432 static void node_composit_init_rlayers(const bContext *C, PointerRNA *ptr) | |
433 { | |
434 Scene *scene = CTX_data_scene(C); | |
435 bNode *node = ptr->data; | |
436 ········ | |
437 node->id = &scene->id; | |
438 ········ | |
439 node_cmp_rlayers_force_hidden_passes(node); | |
440 } | |
441 | |
442 static int node_composit_poll_rlayers(bNodeType *UNUSED(ntype), bNodeTree *ntree
) | |
443 { | |
444 if (strcmp(ntree->idname, "CompositorNodeTree") == 0) { | |
445 Scene *scene; | |
446 ················ | |
447 /* XXX ugly: check if ntree is a local scene node tree. | |
448 * Render layers node can only be used in local scene->nodetree, | |
449 * since it directly links to the scene. | |
450 */ | |
451 for (scene = G.main->scene.first; scene; scene = scene->id.next) | |
452 if (scene->nodetree == ntree) | |
453 break; | |
454 ················ | |
455 return (scene != NULL); | |
456 } | |
457 return false; | |
458 } | |
459 | |
460 void register_node_type_cmp_rlayers(void) | |
461 { | |
462 static bNodeType ntype; | |
463 | |
464 cmp_node_type_base(&ntype, CMP_NODE_R_LAYERS, "Render Layers", NODE_CLAS
S_INPUT, NODE_PREVIEW); | |
465 node_type_socket_templates(&ntype, NULL, cmp_node_rlayers_out); | |
466 ntype.initfunc_api = node_composit_init_rlayers; | |
467 ntype.poll = node_composit_poll_rlayers; | |
468 | |
469 nodeRegisterType(&ntype); | |
470 } | |
LEFT | RIGHT |