Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2006 Blender Foundation. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): none yet. 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #include "node_composite_util.h" 00034 00035 00036 /* **************** IMAGE (and RenderResult, multilayer image) ******************** */ 00037 00038 static bNodeSocketTemplate cmp_node_rlayers_out[]= { 00039 { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, 00040 { SOCK_FLOAT, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, 00041 { SOCK_FLOAT, 0, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, 00042 { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, 00043 { SOCK_VECTOR, 0, "UV", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, 00044 { SOCK_VECTOR, 0, "Speed", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, 00045 { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, 00046 { SOCK_RGBA, 0, "Diffuse", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, 00047 { SOCK_RGBA, 0, "Specular", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, 00048 { SOCK_RGBA, 0, "Shadow", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, 00049 { SOCK_RGBA, 0, "AO", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, 00050 { SOCK_RGBA, 0, "Reflect", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, 00051 { SOCK_RGBA, 0, "Refract", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, 00052 { SOCK_RGBA, 0, "Indirect", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, 00053 { SOCK_FLOAT, 0, "IndexOB", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, 00054 { SOCK_FLOAT, 0, "IndexMA", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, 00055 { SOCK_FLOAT, 0, "Mist", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, 00056 { SOCK_RGBA, 0, "Emit", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, 00057 { SOCK_RGBA, 0, "Environment",0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, 00058 { -1, 0, "" } 00059 }; 00060 00061 /* float buffer from the image with matching color management */ 00062 float *node_composit_get_float_buffer(RenderData *rd, ImBuf *ibuf, int *alloc) 00063 { 00064 float *rect; 00065 int predivide= (ibuf->flags & IB_cm_predivide); 00066 00067 *alloc= FALSE; 00068 00069 if(rd->color_mgt_flag & R_COLOR_MANAGEMENT) { 00070 if(ibuf->profile != IB_PROFILE_NONE) { 00071 rect= ibuf->rect_float; 00072 } 00073 else { 00074 rect= MEM_mapallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, "node_composit_get_image"); 00075 00076 IMB_buffer_float_from_float(rect, ibuf->rect_float, 00077 4, IB_PROFILE_LINEAR_RGB, IB_PROFILE_SRGB, predivide, 00078 ibuf->x, ibuf->y, ibuf->x, ibuf->x); 00079 00080 *alloc= TRUE; 00081 } 00082 } 00083 else { 00084 if(ibuf->profile == IB_PROFILE_NONE) { 00085 rect= ibuf->rect_float; 00086 } 00087 else { 00088 rect= MEM_mapallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, "node_composit_get_image"); 00089 00090 IMB_buffer_float_from_float(rect, ibuf->rect_float, 00091 4, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, predivide, 00092 ibuf->x, ibuf->y, ibuf->x, ibuf->x); 00093 00094 *alloc= TRUE; 00095 } 00096 } 00097 00098 return rect; 00099 } 00100 00101 /* note: this function is used for multilayer too, to ensure uniform 00102 handling with BKE_image_get_ibuf() */ 00103 static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *iuser) 00104 { 00105 ImBuf *ibuf; 00106 CompBuf *stackbuf; 00107 int type; 00108 00109 float *rect; 00110 int alloc= FALSE; 00111 00112 ibuf= BKE_image_get_ibuf(ima, iuser); 00113 if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) { 00114 return NULL; 00115 } 00116 00117 if (ibuf->rect_float == NULL) { 00118 IMB_float_from_rect(ibuf); 00119 } 00120 00121 /* now we need a float buffer from the image with matching color management */ 00122 /* XXX weak code, multilayer is excluded from this */ 00123 if(ibuf->channels == 4 && ima->rr==NULL) { 00124 rect= node_composit_get_float_buffer(rd, ibuf, &alloc); 00125 } 00126 else { 00127 /* non-rgba passes can't use color profiles */ 00128 rect= ibuf->rect_float; 00129 } 00130 /* done coercing into the correct color management */ 00131 00132 00133 type= ibuf->channels; 00134 00135 if(rd->scemode & R_COMP_CROP) { 00136 stackbuf= get_cropped_compbuf(&rd->disprect, rect, ibuf->x, ibuf->y, type); 00137 if(alloc) 00138 MEM_freeN(rect); 00139 } 00140 else { 00141 /* we put imbuf copy on stack, cbuf knows rect is from other ibuf when freed! */ 00142 stackbuf= alloc_compbuf(ibuf->x, ibuf->y, type, FALSE); 00143 stackbuf->rect= rect; 00144 stackbuf->malloc= alloc; 00145 } 00146 00147 /*code to respect the premul flag of images; I'm 00148 not sure if this is a good idea for multilayer images, 00149 since it never worked before for them. 00150 if (type==CB_RGBA && ima->flag & IMA_DO_PREMUL) { 00151 //premul the image 00152 int i; 00153 float *pixel = stackbuf->rect; 00154 00155 for (i=0; i<stackbuf->x*stackbuf->y; i++, pixel += 4) { 00156 pixel[0] *= pixel[3]; 00157 pixel[1] *= pixel[3]; 00158 pixel[2] *= pixel[3]; 00159 } 00160 } 00161 */ 00162 return stackbuf; 00163 } 00164 00165 static CompBuf *node_composit_get_zimage(bNode *node, RenderData *rd) 00166 { 00167 ImBuf *ibuf= BKE_image_get_ibuf((Image *)node->id, node->storage); 00168 CompBuf *zbuf= NULL; 00169 00170 if(ibuf && ibuf->zbuf_float) { 00171 if(rd->scemode & R_COMP_CROP) { 00172 zbuf= get_cropped_compbuf(&rd->disprect, ibuf->zbuf_float, ibuf->x, ibuf->y, CB_VAL); 00173 } 00174 else { 00175 zbuf= alloc_compbuf(ibuf->x, ibuf->y, CB_VAL, 0); 00176 zbuf->rect= ibuf->zbuf_float; 00177 } 00178 } 00179 return zbuf; 00180 } 00181 00182 /* check if layer is available, returns pass buffer */ 00183 static CompBuf *compbuf_multilayer_get(RenderData *rd, RenderLayer *rl, Image *ima, ImageUser *iuser, int passtype) 00184 { 00185 RenderPass *rpass; 00186 short index; 00187 00188 for(index=0, rpass= rl->passes.first; rpass; rpass= rpass->next, index++) 00189 if(rpass->passtype==passtype) 00190 break; 00191 00192 if(rpass) { 00193 CompBuf *cbuf; 00194 00195 iuser->pass= index; 00196 BKE_image_multilayer_index(ima->rr, iuser); 00197 cbuf= node_composit_get_image(rd, ima, iuser); 00198 00199 return cbuf; 00200 } 00201 return NULL; 00202 } 00203 00204 static void outputs_multilayer_get(RenderData *rd, RenderLayer *rl, bNodeStack **out, Image *ima, ImageUser *iuser) 00205 { 00206 if(out[RRES_OUT_Z]->hasoutput) 00207 out[RRES_OUT_Z]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_Z); 00208 if(out[RRES_OUT_VEC]->hasoutput) 00209 out[RRES_OUT_VEC]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_VECTOR); 00210 if(out[RRES_OUT_NORMAL]->hasoutput) 00211 out[RRES_OUT_NORMAL]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_NORMAL); 00212 if(out[RRES_OUT_UV]->hasoutput) 00213 out[RRES_OUT_UV]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_UV); 00214 00215 if(out[RRES_OUT_RGBA]->hasoutput) 00216 out[RRES_OUT_RGBA]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_RGBA); 00217 if(out[RRES_OUT_DIFF]->hasoutput) 00218 out[RRES_OUT_DIFF]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_DIFFUSE); 00219 if(out[RRES_OUT_SPEC]->hasoutput) 00220 out[RRES_OUT_SPEC]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_SPEC); 00221 if(out[RRES_OUT_SHADOW]->hasoutput) 00222 out[RRES_OUT_SHADOW]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_SHADOW); 00223 if(out[RRES_OUT_AO]->hasoutput) 00224 out[RRES_OUT_AO]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_AO); 00225 if(out[RRES_OUT_REFLECT]->hasoutput) 00226 out[RRES_OUT_REFLECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_REFLECT); 00227 if(out[RRES_OUT_REFRACT]->hasoutput) 00228 out[RRES_OUT_REFRACT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_REFRACT); 00229 if(out[RRES_OUT_INDIRECT]->hasoutput) 00230 out[RRES_OUT_INDIRECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_INDIRECT); 00231 if(out[RRES_OUT_INDEXOB]->hasoutput) 00232 out[RRES_OUT_INDEXOB]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_INDEXOB); 00233 if(out[RRES_OUT_INDEXMA]->hasoutput) 00234 out[RRES_OUT_INDEXMA]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_INDEXMA); 00235 if(out[RRES_OUT_MIST]->hasoutput) 00236 out[RRES_OUT_MIST]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_MIST); 00237 if(out[RRES_OUT_EMIT]->hasoutput) 00238 out[RRES_OUT_EMIT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_EMIT); 00239 if(out[RRES_OUT_ENV]->hasoutput) 00240 out[RRES_OUT_ENV]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_ENVIRONMENT); 00241 } 00242 00243 00244 static void node_composit_exec_image(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out) 00245 { 00246 00247 /* image assigned to output */ 00248 /* stack order input sockets: col, alpha */ 00249 if(node->id) { 00250 RenderData *rd= data; 00251 Image *ima= (Image *)node->id; 00252 ImageUser *iuser= (ImageUser *)node->storage; 00253 CompBuf *stackbuf= NULL; 00254 00255 /* first set the right frame number in iuser */ 00256 BKE_image_user_calc_frame(iuser, rd->cfra, 0); 00257 00258 /* force a load, we assume iuser index will be set OK anyway */ 00259 if(ima->type==IMA_TYPE_MULTILAYER) 00260 BKE_image_get_ibuf(ima, iuser); 00261 00262 if(ima->type==IMA_TYPE_MULTILAYER && ima->rr) { 00263 RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer); 00264 00265 if(rl) { 00266 out[0]->data= stackbuf= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_COMBINED); 00267 00268 /* go over all layers */ 00269 outputs_multilayer_get(rd, rl, out, ima, iuser); 00270 } 00271 } 00272 else { 00273 stackbuf= node_composit_get_image(rd, ima, iuser); 00274 00275 if (stackbuf) { 00276 /*respect image premul option*/ 00277 if (stackbuf->type==CB_RGBA && ima->flag & IMA_DO_PREMUL) { 00278 int i; 00279 float *pixel; 00280 00281 /*first duplicate stackbuf->rect, since it's just a pointer 00282 to the source imbuf, and we don't want to change that.*/ 00283 stackbuf->rect = MEM_dupallocN(stackbuf->rect); 00284 00285 /* since stackbuf now has allocated memory, rather than just a pointer, 00286 * mark it as allocated so it can be freed properly */ 00287 stackbuf->malloc=1; 00288 00289 /*premul the image*/ 00290 pixel = stackbuf->rect; 00291 for (i=0; i<stackbuf->x*stackbuf->y; i++, pixel += 4) { 00292 pixel[0] *= pixel[3]; 00293 pixel[1] *= pixel[3]; 00294 pixel[2] *= pixel[3]; 00295 } 00296 } 00297 00298 /* put image on stack */ 00299 out[0]->data= stackbuf; 00300 00301 if(out[2]->hasoutput) 00302 out[2]->data= node_composit_get_zimage(node, rd); 00303 } 00304 } 00305 00306 /* alpha and preview for both types */ 00307 if(stackbuf) { 00308 if(out[1]->hasoutput) 00309 out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A); 00310 00311 generate_preview(data, node, stackbuf); 00312 } 00313 } 00314 } 00315 00316 static void node_composit_init_image(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) 00317 { 00318 ImageUser *iuser= MEM_callocN(sizeof(ImageUser), "node image user"); 00319 node->storage= iuser; 00320 iuser->frames= 1; 00321 iuser->sfra= 1; 00322 iuser->fie_ima= 2; 00323 iuser->ok= 1; 00324 } 00325 00326 void register_node_type_cmp_image(bNodeTreeType *ttype) 00327 { 00328 static bNodeType ntype; 00329 00330 node_type_base(ttype, &ntype, CMP_NODE_IMAGE, "Image", NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS); 00331 node_type_socket_templates(&ntype, NULL, cmp_node_rlayers_out); 00332 node_type_size(&ntype, 120, 80, 300); 00333 node_type_init(&ntype, node_composit_init_image); 00334 node_type_storage(&ntype, "ImageUser", node_free_standard_storage, node_copy_standard_storage); 00335 node_type_exec(&ntype, node_composit_exec_image); 00336 00337 nodeRegisterType(ttype, &ntype); 00338 } 00339 00340 00341 /* **************** RENDER RESULT ******************** */ 00342 00343 static CompBuf *compbuf_from_pass(RenderData *rd, RenderLayer *rl, int rectx, int recty, int passcode) 00344 { 00345 float *fp= RE_RenderLayerGetPass(rl, passcode); 00346 if(fp) { 00347 CompBuf *buf; 00348 int buftype= CB_VEC3; 00349 00350 if(ELEM4(passcode, SCE_PASS_Z, SCE_PASS_INDEXOB, SCE_PASS_MIST, SCE_PASS_INDEXMA)) 00351 buftype= CB_VAL; 00352 else if(passcode==SCE_PASS_VECTOR) 00353 buftype= CB_VEC4; 00354 else if(ELEM(passcode, SCE_PASS_COMBINED, SCE_PASS_RGBA)) 00355 buftype= CB_RGBA; 00356 00357 if(rd->scemode & R_COMP_CROP) 00358 buf= get_cropped_compbuf(&rd->disprect, fp, rectx, recty, buftype); 00359 else { 00360 buf= alloc_compbuf(rectx, recty, buftype, 0); 00361 buf->rect= fp; 00362 } 00363 return buf; 00364 } 00365 return NULL; 00366 } 00367 00368 static void node_composit_rlayers_out(RenderData *rd, RenderLayer *rl, bNodeStack **out, int rectx, int recty) 00369 { 00370 if(out[RRES_OUT_Z]->hasoutput) 00371 out[RRES_OUT_Z]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_Z); 00372 if(out[RRES_OUT_VEC]->hasoutput) 00373 out[RRES_OUT_VEC]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_VECTOR); 00374 if(out[RRES_OUT_NORMAL]->hasoutput) 00375 out[RRES_OUT_NORMAL]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_NORMAL); 00376 if(out[RRES_OUT_UV]->hasoutput) 00377 out[RRES_OUT_UV]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_UV); 00378 00379 if(out[RRES_OUT_RGBA]->hasoutput) 00380 out[RRES_OUT_RGBA]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_RGBA); 00381 if(out[RRES_OUT_DIFF]->hasoutput) 00382 out[RRES_OUT_DIFF]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_DIFFUSE); 00383 if(out[RRES_OUT_SPEC]->hasoutput) 00384 out[RRES_OUT_SPEC]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_SPEC); 00385 if(out[RRES_OUT_SHADOW]->hasoutput) 00386 out[RRES_OUT_SHADOW]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_SHADOW); 00387 if(out[RRES_OUT_AO]->hasoutput) 00388 out[RRES_OUT_AO]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_AO); 00389 if(out[RRES_OUT_REFLECT]->hasoutput) 00390 out[RRES_OUT_REFLECT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_REFLECT); 00391 if(out[RRES_OUT_REFRACT]->hasoutput) 00392 out[RRES_OUT_REFRACT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_REFRACT); 00393 if(out[RRES_OUT_INDIRECT]->hasoutput) 00394 out[RRES_OUT_INDIRECT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_INDIRECT); 00395 if(out[RRES_OUT_INDEXOB]->hasoutput) 00396 out[RRES_OUT_INDEXOB]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_INDEXOB); 00397 if(out[RRES_OUT_INDEXMA]->hasoutput) 00398 out[RRES_OUT_INDEXMA]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_INDEXMA); 00399 if(out[RRES_OUT_MIST]->hasoutput) 00400 out[RRES_OUT_MIST]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_MIST); 00401 if(out[RRES_OUT_EMIT]->hasoutput) 00402 out[RRES_OUT_EMIT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_EMIT); 00403 if(out[RRES_OUT_ENV]->hasoutput) 00404 out[RRES_OUT_ENV]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_ENVIRONMENT); 00405 } 00406 00407 static void node_composit_exec_rlayers(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out) 00408 { 00409 Scene *sce= (Scene *)node->id; 00410 Render *re= (sce)? RE_GetRender(sce->id.name): NULL; 00411 RenderData *rd= data; 00412 RenderResult *rr= NULL; 00413 00414 if(re) 00415 rr= RE_AcquireResultRead(re); 00416 00417 if(rr) { 00418 SceneRenderLayer *srl= BLI_findlink(&sce->r.layers, node->custom1); 00419 if(srl) { 00420 RenderLayer *rl= RE_GetRenderLayer(rr, srl->name); 00421 if(rl && rl->rectf) { 00422 CompBuf *stackbuf; 00423 00424 /* we put render rect on stack, cbuf knows rect is from other ibuf when freed! */ 00425 if(rd->scemode & R_COMP_CROP) 00426 stackbuf= get_cropped_compbuf(&rd->disprect, rl->rectf, rr->rectx, rr->recty, CB_RGBA); 00427 else { 00428 stackbuf= alloc_compbuf(rr->rectx, rr->recty, CB_RGBA, 0); 00429 stackbuf->rect= rl->rectf; 00430 } 00431 if(stackbuf==NULL) { 00432 printf("Error; Preview Panel in UV Window returns zero sized image\n"); 00433 } 00434 else { 00435 stackbuf->xof= rr->xof; 00436 stackbuf->yof= rr->yof; 00437 00438 /* put on stack */ 00439 out[RRES_OUT_IMAGE]->data= stackbuf; 00440 00441 if(out[RRES_OUT_ALPHA]->hasoutput) 00442 out[RRES_OUT_ALPHA]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A); 00443 00444 node_composit_rlayers_out(rd, rl, out, rr->rectx, rr->recty); 00445 00446 generate_preview(data, node, stackbuf); 00447 } 00448 } 00449 } 00450 } 00451 00452 if(re) 00453 RE_ReleaseResult(re); 00454 } 00455 00456 00457 void register_node_type_cmp_rlayers(bNodeTreeType *ttype) 00458 { 00459 static bNodeType ntype; 00460 00461 node_type_base(ttype, &ntype, CMP_NODE_R_LAYERS, "Render Layers", NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS); 00462 node_type_socket_templates(&ntype, NULL, cmp_node_rlayers_out); 00463 node_type_size(&ntype, 150, 100, 300); 00464 node_type_exec(&ntype, node_composit_exec_rlayers); 00465 00466 nodeRegisterType(ttype, &ntype); 00467 }