Blender V2.61 - r43446

render_update.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  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  * GNU General Public License for more details.
00012  *
00013  * You should have received a copy of the GNU General Public License
00014  * along with this program; if not, write to the Free Software Foundation,
00015  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00016  *
00017  * The Original Code is Copyright (C) 2009 Blender Foundation.
00018  * All rights reserved.
00019  *
00020  * Contributor(s): Blender Foundation
00021  *
00022  * ***** END GPL LICENSE BLOCK *****
00023  */
00024 
00029 #include <stdlib.h>
00030 #include <string.h>
00031 
00032 #include "MEM_guardedalloc.h"
00033 
00034 #include "DNA_lamp_types.h"
00035 #include "DNA_material_types.h"
00036 #include "DNA_node_types.h"
00037 #include "DNA_object_types.h"
00038 #include "DNA_scene_types.h"
00039 #include "DNA_screen_types.h"
00040 #include "DNA_space_types.h"
00041 #include "DNA_view3d_types.h"
00042 #include "DNA_world_types.h"
00043 
00044 #include "BLI_threads.h"
00045 #include "BLI_utildefines.h"
00046 
00047 #include "BKE_context.h"
00048 #include "BKE_depsgraph.h"
00049 #include "BKE_icons.h"
00050 #include "BKE_image.h"
00051 #include "BKE_main.h"
00052 #include "BKE_material.h"
00053 #include "BKE_node.h"
00054 #include "BKE_scene.h"
00055 #include "BKE_texture.h"
00056 #include "BKE_world.h"
00057 
00058 #include "GPU_material.h"
00059 
00060 #include "RE_engine.h"
00061 
00062 #include "ED_node.h"
00063 #include "ED_render.h"
00064 
00065 #include "render_intern.h"  // own include
00066 
00067 /***************************** Render Engines ********************************/
00068 
00069 void ED_render_scene_update(Main *bmain, Scene *scene, int updated)
00070 {
00071     /* viewport rendering update on data changes, happens after depsgraph
00072      * updates if there was any change. context is set to the 3d view */
00073     bContext *C;
00074     bScreen *sc;
00075     ScrArea *sa;
00076     ARegion *ar;
00077 
00078     /* don't do this render engine update if we're updating the scene from
00079        other threads doing e.g. rendering or baking jobs */
00080     if(!BLI_thread_is_main())
00081         return;
00082 
00083     C= CTX_create();
00084     CTX_data_main_set(C, bmain);
00085     CTX_data_scene_set(C, scene);
00086 
00087     CTX_wm_manager_set(C, bmain->wm.first);
00088 
00089     for(sc=bmain->screen.first; sc; sc=sc->id.next) {
00090         for(sa=sc->areabase.first; sa; sa=sa->next) {
00091             if(sa->spacetype != SPACE_VIEW3D)
00092                 continue;
00093 
00094             for(ar=sa->regionbase.first; ar; ar=ar->next) {
00095                 RegionView3D *rv3d;
00096                 RenderEngine *engine;
00097 
00098                 if(ar->regiontype != RGN_TYPE_WINDOW)
00099                     continue;
00100 
00101                 rv3d= ar->regiondata;
00102                 engine= rv3d->render_engine;
00103 
00104                 if(engine && (updated || (engine->flag & RE_ENGINE_DO_UPDATE))) {
00105                     CTX_wm_screen_set(C, sc);
00106                     CTX_wm_area_set(C, sa);
00107                     CTX_wm_region_set(C, ar);
00108 
00109                     engine->flag &= ~RE_ENGINE_DO_UPDATE;
00110                     engine->type->view_update(engine, C);
00111                 }
00112             }
00113         }
00114     }
00115 
00116     CTX_free(C);
00117 }
00118 
00119 void ED_render_engine_changed(Main *bmain)
00120 {
00121     /* on changing the render engine type, clear all running render engines */
00122     bScreen *sc;
00123     ScrArea *sa;
00124     ARegion *ar;
00125 
00126     for(sc=bmain->screen.first; sc; sc=sc->id.next) {
00127         for(sa=sc->areabase.first; sa; sa=sa->next) {
00128             if(sa->spacetype != SPACE_VIEW3D)
00129                 continue;
00130 
00131             for(ar=sa->regionbase.first; ar; ar=ar->next) {
00132                 RegionView3D *rv3d;
00133 
00134                 if(ar->regiontype != RGN_TYPE_WINDOW)
00135                     continue;
00136                 
00137                 rv3d= ar->regiondata;
00138 
00139                 if(rv3d->render_engine) {
00140                     RE_engine_free(rv3d->render_engine);
00141                     rv3d->render_engine= NULL;
00142                 }
00143             }
00144         }
00145     }
00146 }
00147 
00148 /***************************** Updates ***********************************
00149  * ED_render_id_flush_update gets called from DAG_id_tag_update, to do *
00150  * editor level updates when the ID changes. when these ID blocks are in *
00151  * the dependency graph, we can get rid of the manual dependency checks  */
00152 
00153 static int mtex_use_tex(MTex **mtex, int tot, Tex *tex)
00154 {
00155     int a;
00156 
00157     if(!mtex)
00158         return 0;
00159 
00160     for(a=0; a<tot; a++)
00161         if(mtex[a] && mtex[a]->tex == tex)
00162             return 1;
00163     
00164     return 0;
00165 }
00166 
00167 static int nodes_use_tex(bNodeTree *ntree, Tex *tex)
00168 {
00169     bNode *node;
00170 
00171     for(node=ntree->nodes.first; node; node= node->next) {
00172         if(node->id) {
00173             if(node->id == (ID*)tex) {
00174                 return 1;
00175             }
00176             else if(GS(node->id->name) == ID_MA) {
00177                 if(mtex_use_tex(((Material*)node->id)->mtex, MAX_MTEX, tex))
00178                     return 1;
00179             }
00180             else if(node->type==NODE_GROUP) {
00181                 if(nodes_use_tex((bNodeTree *)node->id, tex))
00182                     return 1;
00183             }
00184         }
00185     }
00186 
00187     return 0;
00188 }
00189 
00190 static int nodes_use_material(bNodeTree *ntree, Material *ma)
00191 {
00192     bNode *node;
00193 
00194     for(node=ntree->nodes.first; node; node= node->next) {
00195         if(node->id) {
00196             if(node->id == (ID*)ma) {
00197                 return 1;
00198             }
00199             else if(node->type==NODE_GROUP) {
00200                 if(nodes_use_material((bNodeTree *)node->id, ma))
00201                     return 1;
00202             }
00203         }
00204     }
00205 
00206     return 0;
00207 }
00208 
00209 static void material_changed(Main *bmain, Material *ma)
00210 {
00211     Material *parent;
00212 
00213     /* icons */
00214     BKE_icon_changed(BKE_icon_getid(&ma->id));
00215 
00216     /* glsl */
00217     if(ma->gpumaterial.first)
00218         GPU_material_free(ma);
00219 
00220     /* find node materials using this */
00221     for(parent=bmain->mat.first; parent; parent=parent->id.next) {
00222         if(parent->use_nodes && parent->nodetree && nodes_use_material(parent->nodetree, ma));
00223         else continue;
00224 
00225         BKE_icon_changed(BKE_icon_getid(&parent->id));
00226 
00227         if(parent->gpumaterial.first)
00228             GPU_material_free(parent);
00229     }
00230 }
00231 
00232 static void texture_changed(Main *bmain, Tex *tex)
00233 {
00234     Material *ma;
00235     Lamp *la;
00236     World *wo;
00237     Scene *scene;
00238     bNode *node;
00239 
00240     /* icons */
00241     BKE_icon_changed(BKE_icon_getid(&tex->id));
00242 
00243     /* find materials */
00244     for(ma=bmain->mat.first; ma; ma=ma->id.next) {
00245         if(mtex_use_tex(ma->mtex, MAX_MTEX, tex));
00246         else if(ma->use_nodes && ma->nodetree && nodes_use_tex(ma->nodetree, tex));
00247         else continue;
00248 
00249         BKE_icon_changed(BKE_icon_getid(&ma->id));
00250 
00251         if(ma->gpumaterial.first)
00252             GPU_material_free(ma);
00253     }
00254 
00255     /* find lamps */
00256     for(la=bmain->lamp.first; la; la=la->id.next) {
00257         if(mtex_use_tex(la->mtex, MAX_MTEX, tex));
00258         else if(la->nodetree && nodes_use_tex(la->nodetree, tex));
00259         else continue;
00260 
00261         BKE_icon_changed(BKE_icon_getid(&la->id));
00262     }
00263 
00264     /* find worlds */
00265     for(wo=bmain->world.first; wo; wo=wo->id.next) {
00266         if(mtex_use_tex(wo->mtex, MAX_MTEX, tex));
00267         else if(wo->nodetree && nodes_use_tex(wo->nodetree, tex));
00268         else continue;
00269 
00270         BKE_icon_changed(BKE_icon_getid(&wo->id));
00271     }
00272 
00273     /* find compositing nodes */
00274     for(scene=bmain->scene.first; scene; scene=scene->id.next) {
00275         if(scene->use_nodes && scene->nodetree) {
00276             for(node=scene->nodetree->nodes.first; node; node=node->next) {
00277                 if(node->id == &tex->id)
00278                     ED_node_changed_update(&scene->id, node);
00279             }
00280         }
00281     }
00282 }
00283 
00284 static void lamp_changed(Main *bmain, Lamp *la)
00285 {
00286     Object *ob;
00287     Material *ma;
00288 
00289     /* icons */
00290     BKE_icon_changed(BKE_icon_getid(&la->id));
00291 
00292     /* glsl */
00293     for(ob=bmain->object.first; ob; ob=ob->id.next)
00294         if(ob->data == la && ob->gpulamp.first)
00295             GPU_lamp_free(ob);
00296 
00297     for(ma=bmain->mat.first; ma; ma=ma->id.next)
00298         if(ma->gpumaterial.first)
00299             GPU_material_free(ma);
00300 }
00301 
00302 static void world_changed(Main *bmain, World *wo)
00303 {
00304     Material *ma;
00305 
00306     /* icons */
00307     BKE_icon_changed(BKE_icon_getid(&wo->id));
00308 
00309     /* glsl */
00310     for(ma=bmain->mat.first; ma; ma=ma->id.next)
00311         if(ma->gpumaterial.first)
00312             GPU_material_free(ma);
00313 }
00314 
00315 static void image_changed(Main *bmain, Image *ima)
00316 {
00317     Tex *tex;
00318 
00319     /* icons */
00320     BKE_icon_changed(BKE_icon_getid(&ima->id));
00321 
00322     /* textures */
00323     for(tex=bmain->tex.first; tex; tex=tex->id.next)
00324         if(tex->ima == ima)
00325             texture_changed(bmain, tex);
00326 }
00327 
00328 static void scene_changed(Main *bmain, Scene *UNUSED(scene))
00329 {
00330     Object *ob;
00331     Material *ma;
00332 
00333     /* glsl */
00334     for(ob=bmain->object.first; ob; ob=ob->id.next)
00335         if(ob->gpulamp.first)
00336             GPU_lamp_free(ob);
00337 
00338     for(ma=bmain->mat.first; ma; ma=ma->id.next)
00339         if(ma->gpumaterial.first)
00340             GPU_material_free(ma);
00341 }
00342 
00343 void ED_render_id_flush_update(Main *bmain, ID *id)
00344 {
00345     switch(GS(id->name)) {
00346         case ID_MA:
00347             material_changed(bmain, (Material*)id);
00348             break;
00349         case ID_TE:
00350             texture_changed(bmain, (Tex*)id);
00351             break;
00352         case ID_WO:
00353             world_changed(bmain, (World*)id);
00354             break;
00355         case ID_LA:
00356             lamp_changed(bmain, (Lamp*)id);
00357             break;
00358         case ID_IM:
00359             image_changed(bmain, (Image*)id);
00360             break;
00361         case ID_SCE:
00362             scene_changed(bmain, (Scene*)id);
00363             break;
00364         default:
00365             break;
00366     }
00367 }
00368