diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py index 0a2e5cee142..e66d078f8c7 100644 --- a/intern/cycles/blender/addon/__init__.py +++ b/intern/cycles/blender/addon/__init__.py @@ -47,17 +47,30 @@ class CyclesRender(bpy.types.RenderEngine): def __del__(self): engine.free(self) - def render(self, scene): - engine.create(self, scene, True) - engine.render(self, scene) + # final render + def update(self, data, scene): + engine.create(self, data, scene) + engine.update(self, data, scene) - def draw(self, scene): + def render(self): + engine.render(self) + + # preview render + # def preview_update(self, context, id): + # pass + # + # def preview_render(self): + # pass + + # viewport render + def view_update(self, context): if not self.session: - engine.create(self, scene, False) - engine.draw(self, scene) + engine.create(self, context.blend_data, context.scene, + context.region, context.space_data, context.region_data) + engine.update(self, context.blend_data, context.scene) - def update(self, scene): - engine.update(self, scene) + def view_draw(self, context): + engine.draw(self, context.region, context.space_data, context.region_data) def register(): properties.register() diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index fb98068766f..a78107735eb 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -23,19 +23,17 @@ def init(): import os.path lib.init(os.path.dirname(__file__)) -def create(engine, scene, offline): +def create(engine, data, scene, region = 0, v3d = 0, rv3d = 0): from cycles import libcycles_blender as lib - data = bpy.data.as_pointer() - scene = scene.as_pointer() - if not offline and bpy.context.area.type == 'VIEW_3D': - region = bpy.context.region.as_pointer() - v3d = bpy.context.space_data.as_pointer() - rv3d = bpy.context.region_data.as_pointer() - else: - region = 0 - v3d = 0 - rv3d = 0 + data = data.as_pointer() + scene = scene.as_pointer() + if region: + region = region.as_pointer() + if v3d: + v3d = v3d.as_pointer() + if rv3d: + rv3d = rv3d.as_pointer() engine.session = lib.create(engine.as_pointer(), data, scene, region, v3d, rv3d) @@ -46,19 +44,18 @@ def free(engine): lib.free(engine.session) del engine.session -def render(engine, scene): +def render(engine): from cycles import libcycles_blender as lib lib.render(engine.session) -def update(engine, scene): +def update(engine, data, scene): from cycles import libcycles_blender as lib lib.sync(engine.session) -def draw(engine, scene): +def draw(engine, region, v3d, rv3d): from cycles import libcycles_blender as lib - v3d = bpy.context.space_data.as_pointer() - rv3d = bpy.context.region_data.as_pointer() - region = bpy.context.region + v3d = v3d.as_pointer() + rv3d = rv3d.as_pointer() # draw render image status, substatus = lib.draw(engine.session, v3d, rv3d) diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h index 9b2c1d117f5..37e547b6688 100644 --- a/source/blender/blenkernel/BKE_depsgraph.h +++ b/source/blender/blenkernel/BKE_depsgraph.h @@ -121,7 +121,8 @@ void DAG_ids_flush_update(struct Main *bmain, int time); void DAG_id_tag_update(struct ID *id, short flag); /* flush all tagged updates */ void DAG_ids_flush_tagged(struct Main *bmain); - /* clear ID recalc flags */ + /* check and clear ID recalc flags */ +void DAG_ids_check_recalc(struct Main *bmain); void DAG_ids_clear_recalc(struct Main *bmain); /* test if any of this id type is tagged for update */ int DAG_id_type_tagged(struct Main *bmain, short idtype); diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 943712167c6..9164085e7b7 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -90,6 +90,8 @@ int scene_check_setscene(struct Main *bmain, struct Scene *sce); float BKE_curframe(struct Scene *scene); void scene_update_tagged(struct Main *bmain, struct Scene *sce); +void scene_clear_tagged(struct Main *bmain, struct Scene *sce); + void scene_update_for_newframe(struct Main *bmain, struct Scene *sce, unsigned int lay); void scene_add_render_layer(struct Scene *sce); diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 72df926b9a7..845f1bc13e8 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -2508,10 +2508,10 @@ void DAG_ids_flush_tagged(Main *bmain) DAG_scene_flush_update(bmain, sce, lay, 0); } -void DAG_ids_clear_recalc(Main *bmain) +void DAG_ids_check_recalc(Main *bmain) { ListBase *lbarray[MAX_LIBARRAY]; - int a, first_tag = 1; + int a; /* loop over all ID types */ a = set_listbasepointers(bmain, lbarray); @@ -2524,11 +2524,28 @@ void DAG_ids_clear_recalc(Main *bmain) looping over all ID's in case there are no tags */ if(id && bmain->id_tag_update[id->name[0]]) { /* do editors update */ - if(first_tag) { - dag_editors_update(bmain, NULL); - first_tag = 0; - } + dag_editors_update(bmain, NULL); + return; + } + } +} + +void DAG_ids_clear_recalc(Main *bmain) +{ + ListBase *lbarray[MAX_LIBARRAY]; + int a; + + /* loop over all ID types */ + a = set_listbasepointers(bmain, lbarray); + + while(a--) { + ListBase *lb = lbarray[a]; + ID *id = lb->first; + + /* we tag based on first ID type character to avoid + looping over all ID's in case there are no tags */ + if(id && bmain->id_tag_update[id->name[0]]) { for(; id; id=id->next) if(id->flag & (LIB_ID_RECALC|LIB_ID_RECALC_DATA)) id->flag &= ~(LIB_ID_RECALC|LIB_ID_RECALC_DATA); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index d4a1eb0330c..81cffe7a182 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -989,13 +989,18 @@ void scene_update_tagged(Main *bmain, Scene *scene) if (scene->physics_settings.quick_cache_step) BKE_ptcache_quick_cache_all(bmain, scene); - - DAG_ids_clear_recalc(bmain); + + DAG_ids_check_recalc(bmain); /* in the future this should handle updates for all datablocks, not only objects and scenes. - brecht */ } +void scene_clear_tagged(Main *bmain, Scene *scene) +{ + DAG_ids_clear_recalc(bmain); +} + /* applies changes right away, does all sets too */ void scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay) { diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h index 623d5dff8a4..8c0fa3a89a3 100644 --- a/source/blender/editors/include/ED_render.h +++ b/source/blender/editors/include/ED_render.h @@ -45,7 +45,7 @@ void ED_operatortypes_render(void); void ED_render_id_flush_update(struct Main *bmain, struct ID *id); void ED_render_engine_changed(struct Main *bmain); -void ED_render_engine_update_tagged(struct Main *bmain); +void ED_render_engine_update_tagged(struct bContext *C, struct Main *bmain); /* render_preview.c */ diff --git a/source/blender/editors/render/CMakeLists.txt b/source/blender/editors/render/CMakeLists.txt index 16cfca8dadb..af2dc5d64a2 100644 --- a/source/blender/editors/render/CMakeLists.txt +++ b/source/blender/editors/render/CMakeLists.txt @@ -41,6 +41,7 @@ set(SRC render_ops.c render_preview.c render_shading.c + render_update.c render_intern.h ) diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index bc84edb3c2e..178a15354fb 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -88,244 +88,6 @@ #include "render_intern.h" // own include -/***************************** Updates *********************************** - * ED_render_id_flush_update gets called from DAG_id_tag_update, to do * - * editor level updates when the ID changes. when these ID blocks are in * - * the dependency graph, we can get rid of the manual dependency checks */ - -static int mtex_use_tex(MTex **mtex, int tot, Tex *tex) -{ - int a; - - if(!mtex) - return 0; - - for(a=0; atex == tex) - return 1; - - return 0; -} - -static int nodes_use_tex(bNodeTree *ntree, Tex *tex) -{ - bNode *node; - - for(node=ntree->nodes.first; node; node= node->next) { - if(node->id) { - if(node->id == (ID*)tex) { - return 1; - } - else if(node->type==NODE_GROUP) { - if(nodes_use_tex((bNodeTree *)node->id, tex)) - return 1; - } - } - } - - return 0; -} - -static void material_changed(Main *UNUSED(bmain), Material *ma) -{ - /* icons */ - BKE_icon_changed(BKE_icon_getid(&ma->id)); - - /* glsl */ - if(ma->gpumaterial.first) - GPU_material_free(ma); -} - -static void texture_changed(Main *bmain, Tex *tex) -{ - Material *ma; - Lamp *la; - World *wo; - - /* icons */ - BKE_icon_changed(BKE_icon_getid(&tex->id)); - - /* find materials */ - for(ma=bmain->mat.first; ma; ma=ma->id.next) { - if(mtex_use_tex(ma->mtex, MAX_MTEX, tex)); - else if(ma->use_nodes && ma->nodetree && nodes_use_tex(ma->nodetree, tex)); - else continue; - - BKE_icon_changed(BKE_icon_getid(&ma->id)); - - if(ma->gpumaterial.first) - GPU_material_free(ma); - } - - /* find lamps */ - for(la=bmain->lamp.first; la; la=la->id.next) { - if(mtex_use_tex(la->mtex, MAX_MTEX, tex)); - else if(la->nodetree && nodes_use_tex(la->nodetree, tex)); - else continue; - - BKE_icon_changed(BKE_icon_getid(&la->id)); - } - - /* find worlds */ - for(wo=bmain->world.first; wo; wo=wo->id.next) { - if(mtex_use_tex(wo->mtex, MAX_MTEX, tex)); - else if(wo->nodetree && nodes_use_tex(wo->nodetree, tex)); - else continue; - - BKE_icon_changed(BKE_icon_getid(&wo->id)); - } -} - -static void lamp_changed(Main *bmain, Lamp *la) -{ - Object *ob; - Material *ma; - - /* icons */ - BKE_icon_changed(BKE_icon_getid(&la->id)); - - /* glsl */ - for(ob=bmain->object.first; ob; ob=ob->id.next) - if(ob->data == la && ob->gpulamp.first) - GPU_lamp_free(ob); - - for(ma=bmain->mat.first; ma; ma=ma->id.next) - if(ma->gpumaterial.first) - GPU_material_free(ma); -} - -static void world_changed(Main *bmain, World *wo) -{ - Material *ma; - - /* icons */ - BKE_icon_changed(BKE_icon_getid(&wo->id)); - - /* glsl */ - for(ma=bmain->mat.first; ma; ma=ma->id.next) - if(ma->gpumaterial.first) - GPU_material_free(ma); -} - -static void image_changed(Main *bmain, Image *ima) -{ - Tex *tex; - - /* icons */ - BKE_icon_changed(BKE_icon_getid(&ima->id)); - - /* textures */ - for(tex=bmain->tex.first; tex; tex=tex->id.next) - if(tex->ima == ima) - texture_changed(bmain, tex); -} - -static void scene_changed(Main *bmain, Scene *UNUSED(scene)) -{ - Object *ob; - Material *ma; - - /* glsl */ - for(ob=bmain->object.first; ob; ob=ob->id.next) - if(ob->gpulamp.first) - GPU_lamp_free(ob); - - for(ma=bmain->mat.first; ma; ma=ma->id.next) - if(ma->gpumaterial.first) - GPU_material_free(ma); -} - -#include "DNA_screen_types.h" -#include "DNA_view3d_types.h" - -#include "RE_engine.h" - -static void update_render_engines(Main *bmain, int tagged_only) -{ - Scene *scene = bmain->scene.first; - bScreen *sc; - ScrArea *sa; - ARegion *ar; - - for(sc=bmain->screen.first; sc; sc=sc->id.next) { - for(sa=sc->areabase.first; sa; sa=sa->next) { - if(sa->spacetype == SPACE_VIEW3D) { - for(ar=sa->regionbase.first; ar; ar=ar->next) { - if(ar->regiontype == RGN_TYPE_WINDOW) { - RegionView3D *rv3d = ar->regiondata; - RenderEngine *engine = rv3d->render_engine; - - if(engine && (!tagged_only || engine->do_update)) { - engine->do_update = 0; - engine->type->update(engine, scene); - } - } - } - } - } - } -} - -void ED_render_engine_update_tagged(Main *bmain) -{ - update_render_engines(bmain, 1); -} - -void ED_render_engine_changed(Main *bmain) -{ - bScreen *sc; - ScrArea *sa; - ARegion *ar; - - for(sc=bmain->screen.first; sc; sc=sc->id.next) { - for(sa=sc->areabase.first; sa; sa=sa->next) { - if(sa->spacetype == SPACE_VIEW3D) { - for(ar=sa->regionbase.first; ar; ar=ar->next) { - if(ar->regiontype == RGN_TYPE_WINDOW) { - RegionView3D *rv3d = ar->regiondata; - - if(rv3d->render_engine) { - RE_engine_free(rv3d->render_engine); - rv3d->render_engine= NULL; - } - } - } - } - } - } -} - -void ED_render_id_flush_update(Main *bmain, ID *id) -{ - if(!id) { - update_render_engines(bmain, 0); - return; - } - - switch(GS(id->name)) { - case ID_MA: - material_changed(bmain, (Material*)id); - break; - case ID_TE: - texture_changed(bmain, (Tex*)id); - break; - case ID_WO: - world_changed(bmain, (World*)id); - break; - case ID_LA: - lamp_changed(bmain, (Lamp*)id); - break; - case ID_IM: - image_changed(bmain, (Image*)id); - break; - case ID_SCE: - scene_changed(bmain, (Scene*)id); - break; - default: - break; - } -} - /********************** material slot operators *********************/ static int material_slot_add_exec(bContext *C, wmOperator *UNUSED(op)) @@ -1332,3 +1094,4 @@ void TEXTURE_OT_slot_paste(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } + diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c new file mode 100644 index 00000000000..c795c35e9d4 --- /dev/null +++ b/source/blender/editors/render/render_update.c @@ -0,0 +1,339 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/render/render_update.c + * \ingroup edrend + */ + +#include +#include + +#include "MEM_guardedalloc.h" + +#include "DNA_lamp_types.h" +#include "DNA_material_types.h" +#include "DNA_node_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_view3d_types.h" +#include "DNA_world_types.h" + +#include "BKE_context.h" +#include "BKE_depsgraph.h" +#include "BKE_icons.h" +#include "BKE_image.h" +#include "BKE_main.h" +#include "BKE_material.h" +#include "BKE_node.h" +#include "BKE_scene.h" +#include "BKE_texture.h" +#include "BKE_world.h" + +#include "GPU_material.h" + +#include "RE_engine.h" + +#include "ED_render.h" + +#include "render_intern.h" // own include + +/***************************** Render Engines ********************************/ + +void ED_render_engine_update_tagged(bContext *C, Main *bmain) +{ + /* viewport rendering update on data changes, happens after depsgraph + * updates if there was any change. context is set to the 3d view */ + bScreen *sc, *prev_sc= CTX_wm_screen(C); + ScrArea *sa, *prev_sa= CTX_wm_area(C); + ARegion *ar, *prev_ar= CTX_wm_region(C); + + for(sc=bmain->screen.first; sc; sc=sc->id.next) { + for(sa=sc->areabase.first; sa; sa=sa->next) { + if(sa->spacetype != SPACE_VIEW3D) + continue; + + for(ar=sa->regionbase.first; ar; ar=ar->next) { + RegionView3D *rv3d; + RenderEngine *engine; + + if(ar->regiontype != RGN_TYPE_WINDOW) + continue; + + rv3d= ar->regiondata; + engine= rv3d->render_engine; + + if(engine && engine->do_update) { + CTX_wm_screen_set(C, sc); + CTX_wm_area_set(C, sa); + CTX_wm_region_set(C, ar); + + engine->do_update= 0; + engine->type->view_update(engine, C); + } + } + } + } + + CTX_wm_screen_set(C, prev_sc); + CTX_wm_area_set(C, prev_sa); + CTX_wm_region_set(C, prev_ar); +} + +void ED_render_engine_changed(Main *bmain) +{ + /* on changing the render engine type, clear all running render engines */ + bScreen *sc; + ScrArea *sa; + ARegion *ar; + + for(sc=bmain->screen.first; sc; sc=sc->id.next) { + for(sa=sc->areabase.first; sa; sa=sa->next) { + if(sa->spacetype != SPACE_VIEW3D) + continue; + + for(ar=sa->regionbase.first; ar; ar=ar->next) { + RegionView3D *rv3d; + + if(ar->regiontype != RGN_TYPE_WINDOW) + continue; + + rv3d= ar->regiondata; + + if(rv3d->render_engine) { + RE_engine_free(rv3d->render_engine); + rv3d->render_engine= NULL; + } + } + } + } +} + +void tag_render_engines(Main *bmain) +{ + /* tag running render engines for update later on */ + bScreen *sc; + ScrArea *sa; + ARegion *ar; + + for(sc=bmain->screen.first; sc; sc=sc->id.next) { + for(sa=sc->areabase.first; sa; sa=sa->next) { + if(sa->spacetype != SPACE_VIEW3D) + continue; + + for(ar=sa->regionbase.first; ar; ar=ar->next) { + RegionView3D *rv3d; + + if(ar->regiontype != RGN_TYPE_WINDOW) + continue; + + rv3d= ar->regiondata; + if(rv3d->render_engine) + rv3d->render_engine->do_update= 1; + } + } + } +} + +/***************************** Updates *********************************** + * ED_render_id_flush_update gets called from DAG_id_tag_update, to do * + * editor level updates when the ID changes. when these ID blocks are in * + * the dependency graph, we can get rid of the manual dependency checks */ + +static int mtex_use_tex(MTex **mtex, int tot, Tex *tex) +{ + int a; + + if(!mtex) + return 0; + + for(a=0; atex == tex) + return 1; + + return 0; +} + +static int nodes_use_tex(bNodeTree *ntree, Tex *tex) +{ + bNode *node; + + for(node=ntree->nodes.first; node; node= node->next) { + if(node->id) { + if(node->id == (ID*)tex) { + return 1; + } + else if(node->type==NODE_GROUP) { + if(nodes_use_tex((bNodeTree *)node->id, tex)) + return 1; + } + } + } + + return 0; +} + +static void material_changed(Main *UNUSED(bmain), Material *ma) +{ + /* icons */ + BKE_icon_changed(BKE_icon_getid(&ma->id)); + + /* glsl */ + if(ma->gpumaterial.first) + GPU_material_free(ma); +} + +static void texture_changed(Main *bmain, Tex *tex) +{ + Material *ma; + Lamp *la; + World *wo; + + /* icons */ + BKE_icon_changed(BKE_icon_getid(&tex->id)); + + /* find materials */ + for(ma=bmain->mat.first; ma; ma=ma->id.next) { + if(mtex_use_tex(ma->mtex, MAX_MTEX, tex)); + else if(ma->use_nodes && ma->nodetree && nodes_use_tex(ma->nodetree, tex)); + else continue; + + BKE_icon_changed(BKE_icon_getid(&ma->id)); + + if(ma->gpumaterial.first) + GPU_material_free(ma); + } + + /* find lamps */ + for(la=bmain->lamp.first; la; la=la->id.next) { + if(mtex_use_tex(la->mtex, MAX_MTEX, tex)); + else if(la->nodetree && nodes_use_tex(la->nodetree, tex)); + else continue; + + BKE_icon_changed(BKE_icon_getid(&la->id)); + } + + /* find worlds */ + for(wo=bmain->world.first; wo; wo=wo->id.next) { + if(mtex_use_tex(wo->mtex, MAX_MTEX, tex)); + else if(wo->nodetree && nodes_use_tex(wo->nodetree, tex)); + else continue; + + BKE_icon_changed(BKE_icon_getid(&wo->id)); + } +} + +static void lamp_changed(Main *bmain, Lamp *la) +{ + Object *ob; + Material *ma; + + /* icons */ + BKE_icon_changed(BKE_icon_getid(&la->id)); + + /* glsl */ + for(ob=bmain->object.first; ob; ob=ob->id.next) + if(ob->data == la && ob->gpulamp.first) + GPU_lamp_free(ob); + + for(ma=bmain->mat.first; ma; ma=ma->id.next) + if(ma->gpumaterial.first) + GPU_material_free(ma); +} + +static void world_changed(Main *bmain, World *wo) +{ + Material *ma; + + /* icons */ + BKE_icon_changed(BKE_icon_getid(&wo->id)); + + /* glsl */ + for(ma=bmain->mat.first; ma; ma=ma->id.next) + if(ma->gpumaterial.first) + GPU_material_free(ma); +} + +static void image_changed(Main *bmain, Image *ima) +{ + Tex *tex; + + /* icons */ + BKE_icon_changed(BKE_icon_getid(&ima->id)); + + /* textures */ + for(tex=bmain->tex.first; tex; tex=tex->id.next) + if(tex->ima == ima) + texture_changed(bmain, tex); +} + +static void scene_changed(Main *bmain, Scene *UNUSED(scene)) +{ + Object *ob; + Material *ma; + + /* glsl */ + for(ob=bmain->object.first; ob; ob=ob->id.next) + if(ob->gpulamp.first) + GPU_lamp_free(ob); + + for(ma=bmain->mat.first; ma; ma=ma->id.next) + if(ma->gpumaterial.first) + GPU_material_free(ma); +} + +void ED_render_id_flush_update(Main *bmain, ID *id) +{ + if(!id) { + tag_render_engines(bmain); + return; + } + + switch(GS(id->name)) { + case ID_MA: + material_changed(bmain, (Material*)id); + break; + case ID_TE: + texture_changed(bmain, (Tex*)id); + break; + case ID_WO: + world_changed(bmain, (World*)id); + break; + case ID_LA: + lamp_changed(bmain, (Lamp*)id); + break; + case ID_IM: + image_changed(bmain, (Image*)id); + break; + case ID_SCE: + scene_changed(bmain, (Scene*)id); + break; + default: + break; + } +} + diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 4f8d69958e8..62f3d762e22 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -616,12 +616,6 @@ static void view3d_recalc_used_layers(ARegion *ar, wmNotifier *wmn, Scene *scene } } -static void view3d_main_area_render_update(RegionView3D *rv3d) -{ - if(rv3d->render_engine) - rv3d->render_engine->type->update(rv3d->render_engine, NULL); -} - static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) { bScreen *sc; @@ -651,7 +645,6 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) case ND_LAYER_CONTENT: view3d_recalc_used_layers(ar, wmn, wmn->reference); ED_region_tag_redraw(ar); - view3d_main_area_render_update(rv3d); break; case ND_FRAME: case ND_TRANSFORM: diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index c0352d30f47..02432eb2098 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -2313,10 +2313,11 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar) if(strcmp(type->idname, scene->r.engine) == 0) break; - if(!type || !type->draw) + if(!type || !type->view_draw) return 0; rv3d->render_engine = RE_engine_create(type); + type->view_update(rv3d->render_engine, C); } view3d_main_area_setup_view(scene, v3d, ar, NULL, NULL); @@ -2327,7 +2328,7 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar) ED_region_pixelspace(ar); type = rv3d->render_engine->type; - type->draw(rv3d->render_engine, scene); + type->view_draw(rv3d->render_engine, C); return 1; } diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index 842a5f49998..ed7e99b9cb5 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -49,43 +49,6 @@ #include "BKE_context.h" #include "BKE_report.h" -/* RenderEngine */ - -static RenderEngineType internal_render_type = { - NULL, NULL, "BLENDER_RENDER", "Blender Render", RE_INTERNAL, NULL, NULL, NULL, {NULL, NULL, NULL}}; -#ifdef WITH_GAMEENGINE -static RenderEngineType internal_game_type = { - NULL, NULL, "BLENDER_GAME", "Blender Game", RE_INTERNAL|RE_GAME, NULL, NULL, NULL, {NULL, NULL, NULL}}; -#endif - -ListBase R_engines = {NULL, NULL}; - -void RE_engines_init(void) -{ - BLI_addtail(&R_engines, &internal_render_type); -#ifdef WITH_GAMEENGINE - BLI_addtail(&R_engines, &internal_game_type); -#endif -} - -void RE_engines_exit(void) -{ - RenderEngineType *type, *next; - - for(type=R_engines.first; type; type=next) { - next= type->next; - - BLI_remlink(&R_engines, type); - - if(!(type->flag & RE_INTERNAL)) { - if(type->ext.free) - type->ext.free(type->ext.data); - - MEM_freeN(type); - } - } -} - LIBEXPORT void engine_tag_redraw(RenderEngine *engine) { engine->do_draw = 1; @@ -96,39 +59,9 @@ LIBEXPORT void engine_tag_update(RenderEngine *engine) engine->do_update = 1; } -static void engine_render(RenderEngine *engine, struct Scene *scene) -{ - PointerRNA ptr; - ParameterList list; - FunctionRNA *func; +/* RenderEngine Callbacks */ - RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr); - func= RNA_struct_find_function(&ptr, "render"); - - RNA_parameter_list_create(&list, &ptr, func); - RNA_parameter_set_lookup(&list, "scene", &scene); - engine->type->ext.call(NULL, &ptr, func, &list); - - RNA_parameter_list_free(&list); -} - -static void engine_draw(RenderEngine *engine, struct Scene *scene) -{ - PointerRNA ptr; - ParameterList list; - FunctionRNA *func; - - RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr); - func= RNA_struct_find_function(&ptr, "draw"); - - RNA_parameter_list_create(&list, &ptr, func); - RNA_parameter_set_lookup(&list, "scene", &scene); - engine->type->ext.call(NULL, &ptr, func, &list); - - RNA_parameter_list_free(&list); -} - -static void engine_update(RenderEngine *engine, struct Scene *scene) +static void engine_update(RenderEngine *engine, Main *bmain, Scene *scene) { PointerRNA ptr; ParameterList list; @@ -138,13 +71,95 @@ static void engine_update(RenderEngine *engine, struct Scene *scene) func= RNA_struct_find_function(&ptr, "update"); RNA_parameter_list_create(&list, &ptr, func); + RNA_parameter_set_lookup(&list, "data", &bmain); RNA_parameter_set_lookup(&list, "scene", &scene); engine->type->ext.call(NULL, &ptr, func, &list); RNA_parameter_list_free(&list); } -static void rna_RenderEngine_unregister(const bContext *C, StructRNA *type) +static void engine_render(RenderEngine *engine) +{ + PointerRNA ptr; + ParameterList list; + FunctionRNA *func; + + RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr); + func= RNA_struct_find_function(&ptr, "render"); + + RNA_parameter_list_create(&list, &ptr, func); + engine->type->ext.call(NULL, &ptr, func, &list); + + RNA_parameter_list_free(&list); +} + +static void engine_preview_update(RenderEngine *engine, const struct bContext *context, struct ID *id) +{ + PointerRNA ptr; + ParameterList list; + FunctionRNA *func; + + RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr); + func= RNA_struct_find_function(&ptr, "preview_update"); + + RNA_parameter_list_create(&list, &ptr, func); + RNA_parameter_set_lookup(&list, "context", &context); + RNA_parameter_set_lookup(&list, "id", &id); + engine->type->ext.call(NULL, &ptr, func, &list); + + RNA_parameter_list_free(&list); +} + +static void engine_preview_render(RenderEngine *engine) +{ + PointerRNA ptr; + ParameterList list; + FunctionRNA *func; + + RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr); + func= RNA_struct_find_function(&ptr, "preview_render"); + + RNA_parameter_list_create(&list, &ptr, func); + engine->type->ext.call(NULL, &ptr, func, &list); + + RNA_parameter_list_free(&list); +} + +static void engine_view_update(RenderEngine *engine, const struct bContext *context) +{ + PointerRNA ptr; + ParameterList list; + FunctionRNA *func; + + RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr); + func= RNA_struct_find_function(&ptr, "view_update"); + + RNA_parameter_list_create(&list, &ptr, func); + RNA_parameter_set_lookup(&list, "context", &context); + engine->type->ext.call(NULL, &ptr, func, &list); + + RNA_parameter_list_free(&list); +} + +static void engine_view_draw(RenderEngine *engine, const struct bContext *context) +{ + PointerRNA ptr; + ParameterList list; + FunctionRNA *func; + + RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr); + func= RNA_struct_find_function(&ptr, "view_draw"); + + RNA_parameter_list_create(&list, &ptr, func); + RNA_parameter_set_lookup(&list, "context", &context); + engine->type->ext.call(NULL, &ptr, func, &list); + + RNA_parameter_list_free(&list); +} + +/* RenderEngine registration */ + +static void rna_RenderEngine_unregister(const struct bContext *C, StructRNA *type) { RenderEngineType *et= RNA_struct_blender_type_get(type); @@ -161,7 +176,7 @@ static StructRNA *rna_RenderEngine_register(bContext *C, ReportList *reports, vo RenderEngineType *et, dummyet = {NULL}; RenderEngine dummyengine= {NULL}; PointerRNA dummyptr; - int have_function[3]; + int have_function[6]; /* setup dummy engine & engine type to store static properties in */ dummyengine.type= &dummyet; @@ -186,7 +201,7 @@ static StructRNA *rna_RenderEngine_register(bContext *C, ReportList *reports, vo } /* create a new engine type */ - et= MEM_callocN(sizeof(RenderEngineType), "python buttons engine"); + et= MEM_callocN(sizeof(RenderEngineType), "python render engine"); memcpy(et, &dummyet, sizeof(dummyet)); et->ext.srna= RNA_def_struct(&BLENDER_RNA, et->idname, "RenderEngine"); @@ -195,9 +210,12 @@ static StructRNA *rna_RenderEngine_register(bContext *C, ReportList *reports, vo et->ext.free= free; RNA_struct_blender_type_set(et->ext.srna, et); - et->render= (have_function[0])? engine_render: NULL; - et->draw= (have_function[1])? engine_draw: NULL; - et->update= (have_function[2])? engine_update: NULL; + et->update= (have_function[0])? engine_update: NULL; + et->render= (have_function[1])? engine_render: NULL; + et->preview_update= (have_function[2])? engine_preview_update: NULL; + et->preview_render= (have_function[3])? engine_preview_render: NULL; + et->view_update= (have_function[4])? engine_view_update: NULL; + et->view_draw= (have_function[5])? engine_view_draw: NULL; BLI_addtail(&R_engines, et); @@ -286,23 +304,39 @@ static void rna_def_render_engine(BlenderRNA *brna) RNA_def_struct_refine_func(srna, "rna_RenderEngine_refine"); RNA_def_struct_register_funcs(srna, "rna_RenderEngine_register", "rna_RenderEngine_unregister", "rna_RenderEngine_instance"); - /* render */ - func= RNA_def_function(srna, "render", NULL); - RNA_def_function_ui_description(func, "Render scene into an image."); - RNA_def_function_flag(func, FUNC_REGISTER); - RNA_def_pointer(func, "scene", "Scene", "", ""); - - /* draw */ - func= RNA_def_function(srna, "draw", NULL); - RNA_def_function_ui_description(func, "Draw progressive render into viewport."); - RNA_def_function_flag(func, FUNC_REGISTER); - RNA_def_pointer(func, "scene", "Scene", "", ""); - + /* final render callbacks */ func= RNA_def_function(srna, "update", NULL); - RNA_def_function_ui_description(func, "Notify data has changed for progressive viewport render."); + RNA_def_function_ui_description(func, "Export scene data for render"); RNA_def_function_flag(func, FUNC_REGISTER); + RNA_def_pointer(func, "data", "BlendData", "", ""); RNA_def_pointer(func, "scene", "Scene", "", ""); + func= RNA_def_function(srna, "render", NULL); + RNA_def_function_ui_description(func, "Execute render"); + RNA_def_function_flag(func, FUNC_REGISTER); + + /* preview render callbacks */ + func= RNA_def_function(srna, "preview_update", NULL); + RNA_def_function_ui_description(func, "Export scene data for preview render of the given datablock"); + RNA_def_function_flag(func, FUNC_REGISTER); + RNA_def_pointer(func, "context", "Context", "", ""); + RNA_def_pointer(func, "id", "ID", "", ""); + + func= RNA_def_function(srna, "preview_render", NULL); + RNA_def_function_ui_description(func, "Execute preview render"); + RNA_def_function_flag(func, FUNC_REGISTER); + + /* viewport render callbacks */ + func= RNA_def_function(srna, "view_update", NULL); + RNA_def_function_ui_description(func, "Update on data changes for viewport render"); + RNA_def_function_flag(func, FUNC_REGISTER); + RNA_def_pointer(func, "context", "Context", "", ""); + + func= RNA_def_function(srna, "view_draw", NULL); + RNA_def_function_ui_description(func, "Draw viewport render"); + RNA_def_function_flag(func, FUNC_REGISTER); + RNA_def_pointer(func, "context", "Context", "", ""); + /* tag for redraw */ RNA_def_function(srna, "tag_redraw", "engine_tag_redraw"); diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index c2194636cd3..23d34074ff4 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -71,6 +71,7 @@ static void rna_Scene_frame_set(Scene *scene, int frame, float subframe) static void rna_Scene_update_tagged(Scene *scene) { scene_update_tagged(G.main, scene); + scene_clear_tagged(G.main, scene); } static void rna_SceneRender_get_frame_path(RenderData *rd, int frame, char *name) diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt index 2ffe3b360e9..f9b629791d7 100644 --- a/source/blender/render/CMakeLists.txt +++ b/source/blender/render/CMakeLists.txt @@ -131,6 +131,10 @@ if(WITH_CODEC_QUICKTIME) add_definitions(-DWITH_QUICKTIME) endif() +if(WITH_GAMEENGINE) + add_definitions(-DWITH_GAMEENGINE) +endif() + if(APPLE) if(CMAKE_OSX_ARCHITECTURES MATCHES "i386" OR CMAKE_OSX_ARCHITECTURES MATCHES "x86_64") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -mfpmath=sse") diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript index 4eff9fe238d..2bf5da19827 100644 --- a/source/blender/render/SConscript +++ b/source/blender/render/SConscript @@ -54,6 +54,9 @@ if env['WITH_BF_QUICKTIME']: if env['WITH_BF_OPENEXR']: defs.append('WITH_OPENEXR') +if env['WITH_BF_GAMEENGINE']: + defs.append('WITH_GAMEENGINE') + if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): incs += ' ' + env['BF_PTHREADS_INC'] diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h index 6793acb1482..e6680386064 100644 --- a/source/blender/render/extern/include/RE_engine.h +++ b/source/blender/render/extern/include/RE_engine.h @@ -63,9 +63,14 @@ typedef struct RenderEngineType { char name[64]; int flag; - void (*render)(struct RenderEngine *engine, struct Scene *scene); - void (*draw)(struct RenderEngine *engine, struct Scene *scene); - void (*update)(struct RenderEngine *engine, struct Scene *scene); + void (*update)(struct RenderEngine *engine, struct Main *bmain, struct Scene *scene); + void (*render)(struct RenderEngine *engine); + + void (*preview_update)(struct RenderEngine *engine, const struct bContext *context, struct ID *id); + void (*preview_render)(struct RenderEngine *engine); + + void (*view_update)(struct RenderEngine *engine, const struct bContext *context); + void (*view_draw)(struct RenderEngine *engine, const struct bContext *context); /* RNA integration */ ExtensionRNA ext; @@ -73,9 +78,11 @@ typedef struct RenderEngineType { typedef struct RenderEngine { RenderEngineType *type; + void *py_instance; + struct Render *re; ListBase fullresult; - void *py_instance; + int do_draw; int do_update; } RenderEngine; diff --git a/source/blender/render/intern/pipeline/engine.c b/source/blender/render/intern/pipeline/engine.c index de99b6e8e7e..f6c9c326240 100644 --- a/source/blender/render/intern/pipeline/engine.c +++ b/source/blender/render/intern/pipeline/engine.c @@ -58,6 +58,52 @@ #include "render_types.h" #include "renderpipeline.h" +/* Render Engine Types */ + +static RenderEngineType internal_render_type = { + NULL, NULL, + "BLENDER_RENDER", "Blender Render", RE_INTERNAL, + NULL, NULL, NULL, NULL, NULL, NULL, + {NULL, NULL, NULL}}; + +#ifdef WITH_GAMEENGINE + +static RenderEngineType internal_game_type = { + NULL, NULL, + "BLENDER_GAME", "Blender Game", RE_INTERNAL|RE_GAME, + NULL, NULL, NULL, NULL, NULL, NULL, + {NULL, NULL, NULL}}; + +#endif + +ListBase R_engines = {NULL, NULL}; + +void RE_engines_init(void) +{ + BLI_addtail(&R_engines, &internal_render_type); +#ifdef WITH_GAMEENGINE + BLI_addtail(&R_engines, &internal_game_type); +#endif +} + +void RE_engines_exit(void) +{ + RenderEngineType *type, *next; + + for(type=R_engines.first; type; type=next) { + next= type->next; + + BLI_remlink(&R_engines, type); + + if(!(type->flag & RE_INTERNAL)) { + if(type->ext.free) + type->ext.free(type->ext.data); + + MEM_freeN(type); + } + } +} + /* Create, Free */ RenderEngine *RE_engine_create(RenderEngineType *type) @@ -198,7 +244,14 @@ int RE_engine_render(Render *re, int do_all) if((re->r.scemode & (R_NO_FRAME_UPDATE|R_PREVIEWBUTS))==0) scene_update_for_newframe(re->main, re->scene, re->lay); - type->render(engine, re->scene); + if(re->r.scemode & R_PREVIEWBUTS) { + //type->preview_update(engine, scene, id); + type->preview_render(engine); + } + else { + type->update(engine, re->main, re->scene); + type->render(engine); + } free_render_result(&engine->fullresult, engine->fullresult.first); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 723df06a125..3f9aa2bcc82 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -320,7 +320,9 @@ void wm_event_do_notifiers(bContext *C) scene_update_tagged(bmain, win->screen->scene); - ED_render_engine_update_tagged(bmain); + ED_render_engine_update_tagged(C, bmain); + + scene_clear_tagged(bmain, win->screen->scene); } } diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 2f5d6702e3e..901ec80a654 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -375,6 +375,8 @@ void RE_AcquireResultImage(struct Render *re, struct RenderResult *rr){} void RE_ReleaseResult(struct Render *re){} void RE_ReleaseResultImage(struct Render *re){} int RE_engine_test_break(struct RenderEngine *engine){return 0;} +void RE_engines_init() {} +void RE_engines_exit() {} /* python */ struct wmOperatorType *WM_operatortype_find(const char *idname, int quiet){return (struct wmOperatorType *) NULL;}