diff --git a/release/scripts/ui/space_node.py b/release/scripts/ui/space_node.py index 31ac25ff41a..98c24d407de 100644 --- a/release/scripts/ui/space_node.py +++ b/release/scripts/ui/space_node.py @@ -71,6 +71,7 @@ class NODE_HT_header(bpy.types.Header): if snode.show_backdrop: row = layout.row(align=True) row.prop(snode, "backdrop_channels", text="", expand=True) + layout.prop(snode, "use_auto_render") layout.separator() diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 941083734b4..455e1739b98 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -193,6 +193,7 @@ void nodeClearActiveID(struct bNodeTree *ntree, short idtype); void NodeTagChanged(struct bNodeTree *ntree, struct bNode *node); int NodeTagIDChanged(struct bNodeTree *ntree, struct ID *id); +void ntreeClearTags(struct bNodeTree *ntree); /* ************** Groups ****************** */ diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index cedf4e93247..0c5c72627cb 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -41,6 +41,7 @@ #include "DNA_lattice_types.h" #include "DNA_key_types.h" #include "DNA_mesh_types.h" +#include "DNA_node_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_windowmanager_types.h" @@ -54,6 +55,7 @@ #include "BKE_key.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_node.h" #include "BKE_mball.h" #include "BKE_modifier.h" #include "BKE_object.h" @@ -1923,6 +1925,28 @@ static void dag_scene_flush_layers(Scene *sce, int lay) flush_layer_node(sce, itA->node, lasttime); } +static void dag_tag_renderlayers(Scene *sce, unsigned int lay) +{ + if(sce->nodetree) { + bNode *node; + Base *base; + unsigned int lay_changed; + + for(base= sce->base.first; base; base= base->next) + if(base->lay & lay) + if(base->object->recalc) + lay_changed |= base->lay; + + for(node= sce->nodetree->nodes.first; node; node= node->next) { + if(node->id==(ID *)sce) { + SceneRenderLayer *srl= BLI_findlink(&sce->r.layers, node->custom1); + if(srl && (srl->lay & lay_changed)) + NodeTagChanged(sce->nodetree, node); + } + } + } +} + /* flushes all recalc flags in objects down the dependency tree */ void DAG_scene_flush_update(Main *bmain, Scene *sce, unsigned int lay, const short time) { @@ -1967,6 +1991,8 @@ void DAG_scene_flush_update(Main *bmain, Scene *sce, unsigned int lay, const sho } } } + + dag_tag_renderlayers(sce, lay); } static int object_modifiers_use_time(Object *ob) diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index f6487bf1d19..69f01633192 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -3182,10 +3182,7 @@ int ntreeCompositTagAnimated(bNodeTree *ntree) NodeTagChanged(ntree, node); tagged= 1; } - else if(node->type==CMP_NODE_R_LAYERS) { - NodeTagChanged(ntree, node); - tagged= 1; - } + /* here was tag render layer, but this is called after a render, so re-composites fail */ else if(node->type==NODE_GROUP) { if( ntreeCompositTagAnimated((bNodeTree *)node->id) ) { NodeTagChanged(ntree, node); @@ -3210,6 +3207,21 @@ void ntreeCompositTagGenerators(bNodeTree *ntree) } } +/* XXX after render animation system gets a refresh, this call allows composite to end clean */ +void ntreeClearTags(bNodeTree *ntree) +{ + bNode *node; + + if(ntree==NULL) return; + + for(node= ntree->nodes.first; node; node= node->next) { + node->need_exec= 0; + if(node->type==NODE_GROUP) + ntreeClearTags((bNodeTree *)node->id); + } +} + + int ntreeTexTagAnimated(bNodeTree *ntree) { bNode *node; diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 96994ab1df4..f38a5691a6f 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -596,6 +596,9 @@ static void render_endjob(void *rjv) /* else the frame will not update for the original value */ ED_update_for_newframe(G.main, rj->scene, rj->win->screen, 1); + /* XXX above function sets all tags in nodes */ + ntreeClearTags(rj->scene->nodetree); + if(rj->srl) { NodeTagIDChanged(rj->scene->nodetree, &rj->scene->id); WM_main_add_notifier(NC_NODE|NA_EDITED, rj->scene); @@ -648,6 +651,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event) wmJob *steve; RenderJob *rj; Image *ima; + int jobflag; const short is_animation= RNA_boolean_get(op->ptr, "animation"); const short is_write_still= RNA_boolean_get(op->ptr, "write_still"); @@ -701,6 +705,8 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event) /* ensure at least 1 area shows result */ screen_set_image_output(C, event->x, event->y); + jobflag= WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY|WM_JOB_PROGRESS; + /* single layer re-render */ if(RNA_property_is_set(op->ptr, "layer")) { SceneRenderLayer *rl; @@ -712,11 +718,12 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event) scn = (Scene *)BLI_findstring(&mainp->scene, scene_name, offsetof(ID, name) + 2); rl = (SceneRenderLayer *)BLI_findstring(&scene->r.layers, rl_name, offsetof(SceneRenderLayer, name)); - + if (scn && rl) { scene = scn; srl = rl; } + jobflag |= WM_JOB_SUSPEND; } /* job custom data */ @@ -733,7 +740,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event) rj->reports= op->reports; /* setup job */ - steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Render", WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY|WM_JOB_PROGRESS); + steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Render", jobflag); WM_jobs_customdata(steve, rj, render_freejob); WM_jobs_timer(steve, 0.2, NC_SCENE|ND_RENDER_RESULT, 0); WM_jobs_callbacks(steve, render_startjob, NULL, NULL, render_endjob); diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 834f3483871..1279863802a 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -2158,6 +2158,51 @@ void NODE_OT_read_fullsamplelayers(wmOperatorType *ot) ot->flag= 0; } +int node_render_changed_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *sce= CTX_data_scene(C); + bNode *node; + + for(node= sce->nodetree->nodes.first; node; node= node->next) { + if(node->id==(ID *)sce && node->need_exec) { + break; + } + } + if(node) { + SceneRenderLayer *srl= BLI_findlink(&sce->r.layers, node->custom1); + + if(srl) { + PointerRNA op_ptr; + + WM_operator_properties_create(&op_ptr, "RENDER_OT_render"); + RNA_string_set(&op_ptr, "layer", srl->name); + RNA_string_set(&op_ptr, "scene", sce->id.name+2); + + WM_operator_name_call(C, "RENDER_OT_render", WM_OP_INVOKE_DEFAULT, &op_ptr); + + WM_operator_properties_free(&op_ptr); + + return OPERATOR_FINISHED; + } + + } + return OPERATOR_CANCELLED; +} + +void NODE_OT_render_changed(wmOperatorType *ot) +{ + + ot->name= "Render Changed Layer"; + ot->idname= "NODE_OT_render_changed"; + + ot->exec= node_render_changed_exec; + + ot->poll= composite_node_active; + + /* flags */ + ot->flag= 0; +} + /* ****************** Make Group operator ******************* */ diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 66bf9310db8..5d67eb77e28 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -92,7 +92,7 @@ void node_tree_verify_groups(bNodeTree *nodetree); void snode_autoconnect(SpaceNode *snode, int allow_multiple, int replace); int node_has_hidden_sockets(bNode *node); void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set); - +int node_render_changed_exec(bContext *, wmOperator *); void NODE_OT_duplicate(struct wmOperatorType *ot); void NODE_OT_delete(struct wmOperatorType *ot); @@ -115,6 +115,7 @@ void NODE_OT_show_cyclic_dependencies(struct wmOperatorType *ot); void NODE_OT_link_viewer(struct wmOperatorType *ot); void NODE_OT_read_fullsamplelayers(struct wmOperatorType *ot); void NODE_OT_read_renderlayers(struct wmOperatorType *ot); +void NODE_OT_render_changed(struct wmOperatorType *ot); void NODE_OT_backimage_move(struct wmOperatorType *ot); void NODE_OT_backimage_zoom(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index 781682c9185..db5c493dcd9 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -78,6 +78,7 @@ void node_operatortypes(void) WM_operatortype_append(NODE_OT_read_renderlayers); WM_operatortype_append(NODE_OT_read_fullsamplelayers); + WM_operatortype_append(NODE_OT_render_changed); WM_operatortype_append(NODE_OT_backimage_move); WM_operatortype_append(NODE_OT_backimage_zoom); @@ -170,6 +171,8 @@ void node_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "NODE_OT_read_renderlayers", RKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "NODE_OT_read_fullsamplelayers", RKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "NODE_OT_render_changed", ZKEY, KM_PRESS, 0, 0); + transform_keymap_for_space(keyconf, keymap, SPACE_NODE); } diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index eb8c34fe8bd..dab6568bea6 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -172,13 +172,21 @@ static void node_area_listener(ScrArea *sa, wmNotifier *wmn) case ND_FRAME: ED_area_tag_refresh(sa); break; + case ND_TRANSFORM_DONE: + if(type==NTREE_COMPOSIT) { + if(snode->flag & SNODE_AUTO_RENDER) { + snode->recalc= 1; + ED_area_tag_refresh(sa); + } + } + break; } break; case NC_WM: if(wmn->data==ND_FILEREAD) ED_area_tag_refresh(sa); break; - + /* future: add ID checks? */ case NC_MATERIAL: if(type==NTREE_SHADER) { @@ -212,7 +220,7 @@ static void node_area_listener(ScrArea *sa, wmNotifier *wmn) case NC_IMAGE: if (wmn->action == NA_EDITED) { - if(snode->treetype==NTREE_COMPOSIT) { + if(type==NTREE_COMPOSIT) { Scene *scene= wmn->window->screen->scene; /* note that NodeTagIDChanged is alredy called by BKE_image_signal() on all @@ -241,8 +249,15 @@ static void node_area_refresh(const struct bContext *C, struct ScrArea *sa) } else if(snode->treetype==NTREE_COMPOSIT) { Scene *scene= (Scene *)snode->id; - if(scene->use_nodes) - snode_composite_job(C, sa); + if(scene->use_nodes) { + /* recalc is set on 3d view changes for auto compo */ + if(snode->recalc) { + snode->recalc= 0; + node_render_changed_exec((struct bContext*)C, NULL); + } + else + snode_composite_job(C, sa); + } } else if(snode->treetype==NTREE_TEXTURE) { Tex *tex= (Tex *)snode->id; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 2d541b63bd0..394dd433060 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -338,7 +338,7 @@ static void viewRedrawForce(const bContext *C, TransInfo *t) } } -static void viewRedrawPost(TransInfo *t) +static void viewRedrawPost(bContext *C, TransInfo *t) { ED_area_headerprint(t->sa, NULL); @@ -346,6 +346,10 @@ static void viewRedrawPost(TransInfo *t) /* if autokeying is enabled, send notifiers that keyframes were added */ if (IS_AUTOKEY_ON(t->scene)) WM_main_add_notifier(NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL); + + /* XXX temp, first hack to get auto-render in compositor work (ton) */ + WM_event_add_notifier(C, NC_SCENE|ND_TRANSFORM_DONE, CTX_data_scene(C)); + } #if 0 // TRANSFORM_FIX_ME @@ -1817,7 +1821,7 @@ int transformEnd(bContext *C, TransInfo *t) postTrans(C, t); /* send events out for redraws */ - viewRedrawPost(t); + viewRedrawPost(C, t); /* Undo as last, certainly after special_trans_update! */ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 49a4df043fb..90961a5cc15 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -396,8 +396,9 @@ typedef struct SpaceNode { float mx, my; /* mousepos for drawing socketless link */ struct bNodeTree *nodetree, *edittree; - int treetype; /* treetype: as same nodetree->type */ - short texfrom, pad; /* texfrom object, world or brush */ + int treetype; /* treetype: as same nodetree->type */ + short texfrom; /* texfrom object, world or brush */ + short recalc; /* currently on 0/1, for auto compo */ struct bGPdata *gpd; /* grease-pencil data */ } SpaceNode; @@ -407,6 +408,7 @@ typedef struct SpaceNode { #define SNODE_DISPGP 4 #define SNODE_USE_ALPHA 8 #define SNODE_SHOW_ALPHA 16 +#define SNODE_AUTO_RENDER 32 /* snode->texfrom */ #define SNODE_TEX_OBJECT 0 diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 45622f500df..afb0b82b8a5 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -2263,6 +2263,11 @@ static void rna_def_space_node(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Backdrop", "Use active Viewer Node output as backdrop for compositing nodes"); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_NODE_VIEW, NULL); + prop= RNA_def_property(srna, "use_auto_render", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SNODE_AUTO_RENDER); + RNA_def_property_ui_text(prop, "Auto Render", "Re-render and composite changed layer on 3D edits"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_NODE_VIEW, NULL); + prop= RNA_def_property(srna, "backdrop_zoom", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "zoom"); RNA_def_property_range(prop, 0.01f, FLT_MAX); diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 728e5f1a800..8590534df30 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -193,6 +193,7 @@ typedef struct wmNotifier { #define ND_TOOLSETTINGS (15<<16) #define ND_LAYER (16<<16) #define ND_FRAME_RANGE (17<<16) +#define ND_TRANSFORM_DONE (18<<16) #define ND_WORLD (92<<16) #define ND_LAYER_CONTENT (101<<16)