Blender V2.61 - r43446

node_composite_image.c

Go to the documentation of this file.
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 }