diff options
-rw-r--r-- | release/scripts/startup/bl_ui/space_node.py | 1 | ||||
-rw-r--r-- | source/blender/compositor/intern/COM_ExecutionGroup.cpp | 56 | ||||
-rw-r--r-- | source/blender/compositor/intern/COM_ExecutionGroup.h | 12 | ||||
-rw-r--r-- | source/blender/compositor/intern/COM_ExecutionSystem.cpp | 11 | ||||
-rw-r--r-- | source/blender/editors/space_node/drawnode.c | 18 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_edit.c | 104 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_intern.h | 2 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_ops.c | 4 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_node_types.h | 3 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_nodetree.c | 38 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 1 |
11 files changed, 233 insertions, 17 deletions
diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index 104c1500756..1865b049a03 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -254,6 +254,7 @@ class NODE_PT_quality(bpy.types.Panel): col.prop(tree, "use_opencl") col.prop(tree, "use_groupnode_buffer") col.prop(tree, "two_pass") + col.prop(tree, "use_viewer_border") col.prop(snode, "show_highlight") col.prop(snode, "use_hidden_preview") diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cpp b/source/blender/compositor/intern/COM_ExecutionGroup.cpp index ffc36281874..0868fccceaa 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.cpp +++ b/source/blender/compositor/intern/COM_ExecutionGroup.cpp @@ -60,6 +60,7 @@ ExecutionGroup::ExecutionGroup() this->m_openCL = false; this->m_singleThreaded = false; this->m_chunksFinished = 0; + BLI_rcti_init(&this->m_viewerBorder, 0, 0, 0, 0); } CompositorPriority ExecutionGroup::getRenderPriotrity() @@ -196,6 +197,7 @@ void ExecutionGroup::determineResolution(unsigned int resolution[2]) resolution[0] = operation->getWidth(); resolution[1] = operation->getHeight(); this->setResolution(resolution); + BLI_rcti_init(&this->m_viewerBorder, 0, this->m_width, 0, this->m_height); } void ExecutionGroup::determineNumberOfChunks() @@ -207,8 +209,10 @@ void ExecutionGroup::determineNumberOfChunks() } else { const float chunkSizef = this->m_chunkSize; - this->m_numberOfXChunks = ceil(this->m_width / chunkSizef); - this->m_numberOfYChunks = ceil(this->m_height / chunkSizef); + const int border_width = BLI_rcti_size_x(&this->m_viewerBorder); + const int border_height = BLI_rcti_size_y(&this->m_viewerBorder); + this->m_numberOfXChunks = ceil(border_width / chunkSizef); + this->m_numberOfYChunks = ceil(border_height / chunkSizef); this->m_numberOfChunks = this->m_numberOfXChunks * this->m_numberOfYChunks; } } @@ -245,6 +249,9 @@ void ExecutionGroup::execute(ExecutionSystem *graph) chunkorder = viewer->getChunkOrder(); } + const int border_width = BLI_rcti_size_x(&this->m_viewerBorder); + const int border_height = BLI_rcti_size_y(&this->m_viewerBorder); + switch (chunkorder) { case COM_TO_RANDOM: for (index = 0; index < 2 * this->m_numberOfChunks; index++) { @@ -258,14 +265,14 @@ void ExecutionGroup::execute(ExecutionSystem *graph) case COM_TO_CENTER_OUT: { ChunkOrderHotspot *hotspots[1]; - hotspots[0] = new ChunkOrderHotspot(this->m_width * centerX, this->m_height * centerY, 0.0f); + hotspots[0] = new ChunkOrderHotspot(border_width * centerX, border_height * centerY, 0.0f); rcti rect; ChunkOrder *chunkOrders = (ChunkOrder *)MEM_mallocN(sizeof(ChunkOrder) * this->m_numberOfChunks, __func__); for (index = 0; index < this->m_numberOfChunks; index++) { determineChunkRect(&rect, index); chunkOrders[index].setChunkNumber(index); - chunkOrders[index].setX(rect.xmin); - chunkOrders[index].setY(rect.ymin); + chunkOrders[index].setX(rect.xmin - this->m_viewerBorder.xmin); + chunkOrders[index].setY(rect.ymin - this->m_viewerBorder.ymin); chunkOrders[index].determineDistance(hotspots, 1); } @@ -281,10 +288,10 @@ void ExecutionGroup::execute(ExecutionSystem *graph) case COM_TO_RULE_OF_THIRDS: { ChunkOrderHotspot *hotspots[9]; - unsigned int tx = this->m_width / 6; - unsigned int ty = this->m_height / 6; - unsigned int mx = this->m_width / 2; - unsigned int my = this->m_height / 2; + unsigned int tx = border_width / 6; + unsigned int ty = border_height / 6; + unsigned int mx = border_width / 2; + unsigned int my = border_height / 2; unsigned int bx = mx + 2 * tx; unsigned int by = my + 2 * ty; @@ -303,8 +310,8 @@ void ExecutionGroup::execute(ExecutionSystem *graph) for (index = 0; index < this->m_numberOfChunks; index++) { determineChunkRect(&rect, index); chunkOrders[index].setChunkNumber(index); - chunkOrders[index].setX(rect.xmin); - chunkOrders[index].setY(rect.ymin); + chunkOrders[index].setX(rect.xmin - this->m_viewerBorder.xmin); + chunkOrders[index].setY(rect.ymin - this->m_viewerBorder.ymin); chunkOrders[index].determineDistance(hotspots, 9); } @@ -431,13 +438,18 @@ void ExecutionGroup::finalizeChunkExecution(int chunkNumber, MemoryBuffer **memo inline void ExecutionGroup::determineChunkRect(rcti *rect, const unsigned int xChunk, const unsigned int yChunk) const { + const int border_width = BLI_rcti_size_x(&this->m_viewerBorder); + const int border_height = BLI_rcti_size_y(&this->m_viewerBorder); + if (this->m_singleThreaded) { - BLI_rcti_init(rect, 0, this->m_width, 0, this->m_height); + BLI_rcti_init(rect, this->m_viewerBorder.xmin, border_width, this->m_viewerBorder.ymin, border_height); } else { - const unsigned int minx = xChunk * this->m_chunkSize; - const unsigned int miny = yChunk * this->m_chunkSize; - BLI_rcti_init(rect, minx, min(minx + this->m_chunkSize, this->m_width), miny, min(miny + this->m_chunkSize, this->m_height)); + const unsigned int minx = xChunk * this->m_chunkSize + this->m_viewerBorder.xmin; + const unsigned int miny = yChunk * this->m_chunkSize + this->m_viewerBorder.ymin; + const unsigned int width = min((unsigned int) this->m_viewerBorder.xmax, this->m_width); + const unsigned int height = min((unsigned int) this->m_viewerBorder.ymax, this->m_height); + BLI_rcti_init(rect, min(minx, this->m_width), min(minx + this->m_chunkSize, width), min(miny, this->m_height), min(miny + this->m_chunkSize, height)); } } @@ -472,9 +484,9 @@ bool ExecutionGroup::scheduleAreaWhenPossible(ExecutionSystem *graph, rcti *area float chunkSizef = this->m_chunkSize; int indexx, indexy; - int minxchunk = floor(area->xmin / chunkSizef); + int minxchunk = floor((area->xmin - this->m_viewerBorder.xmin) / chunkSizef); int maxxchunk = ceil((area->xmax - 1) / chunkSizef); - int minychunk = floor(area->ymin / chunkSizef); + int minychunk = floor((area->ymin - this->m_viewerBorder.ymin) / chunkSizef); int maxychunk = ceil((area->ymax - 1) / chunkSizef); minxchunk = max(minxchunk, 0); minychunk = max(minychunk, 0); @@ -574,3 +586,13 @@ bool ExecutionGroup::isOpenCL() { return this->m_openCL; } + +void ExecutionGroup::setViewerBorder(float xmin, float xmax, float ymin, float ymax) +{ + NodeOperation *operation = this->getOutputNodeOperation(); + + if (operation->isViewerOperation()) { + BLI_rcti_init(&this->m_viewerBorder, xmin * this->m_width, xmax * this->m_width, + ymin * this->m_height, ymax * this->m_height); + } +} diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.h b/source/blender/compositor/intern/COM_ExecutionGroup.h index 00104c24194..52f5bae4be9 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.h +++ b/source/blender/compositor/intern/COM_ExecutionGroup.h @@ -161,6 +161,12 @@ private: * @see openCL */ bool m_initialized; + + /** + * @brief denotes boundary for border compositing + * @note measured in pixel space + */ + rcti m_viewerBorder; // methods /** @@ -395,6 +401,12 @@ public: */ CompositorPriority getRenderPriotrity(); + /** + * @brief set border for viewer operation + * @note all the coordinates are assumed to be in normalized space + */ + void setViewerBorder(float xmin, float xmax, float ymin, float ymax); + #ifdef WITH_CXX_GUARDEDALLOC MEM_CXX_CLASS_ALLOC_FUNCS("COM:ExecutionGroup") #endif diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cpp b/source/blender/compositor/intern/COM_ExecutionSystem.cpp index 1ec4ac7699b..2b2af73d0c8 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cpp @@ -78,11 +78,22 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, bNodeTree *editingtree, bool re this->groupOperations(); /* group operations in ExecutionGroups */ unsigned int index; unsigned int resolution[2]; + + rctf *viewer_border = &editingtree->viewer_border; + bool use_viewer_border = (editingtree->flag & NTREE_VIEWER_BORDER) && + viewer_border->xmin < viewer_border->xmax && + viewer_border->ymin < viewer_border->ymax; + for (index = 0; index < this->m_groups.size(); index++) { resolution[0] = 0; resolution[1] = 0; ExecutionGroup *executionGroup = this->m_groups[index]; executionGroup->determineResolution(resolution); + + if (use_viewer_border) { + executionGroup->setViewerBorder(viewer_border->xmin, viewer_border->xmax, + viewer_border->ymin, viewer_border->ymax); + } } #ifdef COM_DEBUG diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 8a2e03f2660..097469f396f 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -3320,6 +3320,7 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode) /** @note draw selected info on backdrop */ if (snode->edittree) { bNode *node = snode->edittree->nodes.first; + rctf *viewer_border = &snode->edittree->viewer_border; while (node) { if (node->flag & NODE_SELECT) { if (node->typeinfo->uibackdropfunc) { @@ -3328,6 +3329,23 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode) } node = node->next; } + + if ((snode->edittree->flag & NTREE_VIEWER_BORDER) && + viewer_border->xmin < viewer_border->xmax && + viewer_border->ymin < viewer_border->ymax) + { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + setlinestyle(3); + cpack(0x4040FF); + + glRectf(x + snode->zoom * viewer_border->xmin * ibuf->x, + y + snode->zoom * viewer_border->ymin * ibuf->y, + x + snode->zoom * viewer_border->xmax * ibuf->x, + y + snode->zoom * viewer_border->ymax * ibuf->y); + + setlinestyle(0); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } } glMatrixMode(GL_PROJECTION); diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index fb4e4f62e52..ad863fca5a5 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -73,6 +73,8 @@ #include "GPU_material.h" +#include "IMB_imbuf_types.h" + #include "node_intern.h" /* own include */ #define USE_ESC_COMPO @@ -2281,3 +2283,105 @@ void NODE_OT_shader_script_update(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +/* ********************** Viewer border ******************/ + +static void viewer_border_corner_to_backdrop(SpaceNode *snode, ARegion *ar, int x, int y, + int backdrop_width, int backdrop_height, + float *fx, float *fy) +{ + float bufx, bufy; + + bufx = backdrop_width * snode->zoom; + bufy = backdrop_height * snode->zoom; + + *fx = (bufx > 0.0f ? ((float) x - 0.5f * ar->winx - snode->xof) / bufx + 0.5f : 0.0f); + *fy = (bufy > 0.0f ? ((float) y - 0.5f * ar->winy - snode->yof) / bufy + 0.5f : 0.0f); +} + +static int viewer_border_exec(bContext *C, wmOperator *op) +{ + Image *ima; + void *lock; + ImBuf *ibuf; + + ED_preview_kill_jobs(C); + + ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); + ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); + + if (ibuf) { + ARegion *ar = CTX_wm_region(C); + SpaceNode *snode = CTX_wm_space_node(C); + bNodeTree *btree = snode->edittree; + rcti rect; + rctf rectf; + + /* get border from operator */ + WM_operator_properties_border_to_rcti(op, &rect); + + /* convert border to unified space within backdrop image */ + viewer_border_corner_to_backdrop(snode, ar, rect.xmin, rect.ymin, ibuf->x, ibuf->y, + &rectf.xmin, &rectf.ymin); + + viewer_border_corner_to_backdrop(snode, ar, rect.xmax, rect.ymax, ibuf->x, ibuf->y, + &rectf.xmax, &rectf.ymax); + + /* clamp coordinates */ + rectf.xmin = max_ff(rectf.xmin, 0.0f); + rectf.ymin = max_ff(rectf.ymin, 0.0f); + rectf.xmax = min_ff(rectf.xmax, 1.0f); + rectf.ymax = min_ff(rectf.ymax, 1.0f); + + if (rectf.xmin < rectf.xmax && rectf.ymin < rectf.ymax) { + btree->viewer_border = rectf; + + if (rectf.xmin == 0.0f && rectf.ymin == 0.0f && + rectf.xmax == 1.0f && rectf.ymax == 1.0f) + { + btree->flag &= ~NTREE_VIEWER_BORDER; + } + else { + if (ibuf->rect) + memset(ibuf->rect, 0, 4 * ibuf->x * ibuf->y); + + if (ibuf->rect_float) + memset(ibuf->rect_float, 0, 4 * ibuf->x * ibuf->y * sizeof(float)); + + ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; + + btree->flag |= NTREE_VIEWER_BORDER; + } + + snode_notify(C, snode); + WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL); + } + else { + btree->flag &= ~NTREE_VIEWER_BORDER; + } + } + + BKE_image_release_ibuf(ima, ibuf, lock); + + return OPERATOR_FINISHED; +} + +void NODE_OT_viewer_border(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Viewer Border"; + ot->description = "Set the boundaries for viewer operations"; + ot->idname = "NODE_OT_viewer_border"; + + /* api callbacks */ + ot->invoke = WM_border_select_invoke; + ot->exec = viewer_border_exec; + ot->modal = WM_border_select_modal; + ot->cancel = WM_border_select_cancel; + ot->poll = composite_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + WM_operator_properties_gesture_border(ot, TRUE); +} diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index e8dd1cf1528..cbf7101a101 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -217,6 +217,8 @@ void NODE_OT_clipboard_paste(struct wmOperatorType *ot); void NODE_OT_shader_script_update(struct wmOperatorType *ot); +void NODE_OT_viewer_border(struct wmOperatorType *ot); + extern const char *node_context_dir[]; // XXXXXX diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index 8adccd9e6c4..d16c6627d3f 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -120,6 +120,8 @@ void node_operatortypes(void) WM_operatortype_append(NODE_OT_clipboard_paste); WM_operatortype_append(NODE_OT_shader_script_update); + + WM_operatortype_append(NODE_OT_viewer_border); } void ED_operatormacros_node(void) @@ -298,5 +300,7 @@ void node_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "NODE_OT_clipboard_copy", CKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "NODE_OT_clipboard_paste", VKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "NODE_OT_viewer_border", BKEY, KM_PRESS, KM_CTRL, 0); + transform_keymap_for_space(keyconf, keymap, SPACE_NODE); } diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 62c997b72c6..b2b23828cee 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -279,6 +279,8 @@ typedef struct bNodeTree { short render_quality; /* Quality setting when rendering */ int chunksize; /* tile size for compositor engine */ + rctf viewer_border; + ListBase inputs, outputs; /* external sockets for group nodes */ /* execution data */ @@ -313,6 +315,7 @@ typedef struct bNodeTree { #define NTREE_COM_OPENCL 2 /* use opencl */ #define NTREE_TWO_PASS 4 /* two pass */ #define NTREE_COM_GROUPNODE_BUFFER 8 /* use groupnode buffers */ +#define NTREE_VIEWER_BORDER 16 /* use a border for viewer nodes */ /* XXX not nice, but needed as a temporary flags * for group updates after library linking. diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index c13481bcb9a..6022929badc 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -55,6 +55,7 @@ #include "rna_internal_types.h" #include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" #include "WM_types.h" @@ -521,6 +522,38 @@ static void rna_Node_material_update(Main *bmain, Scene *scene, PointerRNA *ptr) node_update(bmain, scene, ntree, node); } +static void rna_NodeTree_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + bNodeTree *ntree = (bNodeTree *)ptr->id.data; + + /* when using border, make it so no old data from outside of + * border is hanging around + * ideally shouldn't be in RNA callback, but how to teach + * compo to only clear frame when border usage is actually + * toggling + */ + if (ntree->flag & NTREE_VIEWER_BORDER) { + Image *ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); + void *lock; + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); + + if (ibuf) { + if (ibuf->rect) + memset(ibuf->rect, 0, 4 * ibuf->x * ibuf->y); + + if (ibuf->rect_float) + memset(ibuf->rect_float, 0, 4 * ibuf->x * ibuf->y * sizeof(float)); + + ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; + } + + BKE_image_release_ibuf(ima, ibuf, lock); + } + + WM_main_add_notifier(NC_NODE | NA_EDITED, NULL); + WM_main_add_notifier(NC_SCENE | ND_NODES, &ntree->id); +} + static void rna_NodeGroup_update(Main *bmain, Scene *scene, PointerRNA *ptr) { bNodeTree *ntree = (bNodeTree *)ptr->id.data; @@ -4985,6 +5018,11 @@ static void rna_def_composite_nodetree(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", NTREE_TWO_PASS); RNA_def_property_ui_text(prop, "Two Pass", "Use two pass execution during editing: first calculate fast nodes, " "second pass calculate all nodes"); + + prop = RNA_def_property(srna, "use_viewer_border", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", NTREE_VIEWER_BORDER); + RNA_def_property_ui_text(prop, "Viewer Border", "Use boundaries for viewer nodes and composite backdrop"); + RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, "rna_NodeTree_update"); } static void rna_def_shader_nodetree(BlenderRNA *brna) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 77dc467a4e3..374c3182046 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -4197,6 +4197,7 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_assign(keymap, "MARKER_OT_select_border"); WM_modalkeymap_assign(keymap, "NLA_OT_select_border"); WM_modalkeymap_assign(keymap, "NODE_OT_select_border"); + WM_modalkeymap_assign(keymap, "NODE_OT_viewer_border"); WM_modalkeymap_assign(keymap, "PAINT_OT_hide_show"); WM_modalkeymap_assign(keymap, "OUTLINER_OT_select_border"); // WM_modalkeymap_assign(keymap, "SCREEN_OT_border_select"); // template |