Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_node/node_relationships.c')
-rw-r--r--source/blender/editors/space_node/node_relationships.c229
1 files changed, 203 insertions, 26 deletions
diff --git a/source/blender/editors/space_node/node_relationships.c b/source/blender/editors/space_node/node_relationships.c
index d6edfcce8e8..2cc44d72c72 100644
--- a/source/blender/editors/space_node/node_relationships.c
+++ b/source/blender/editors/space_node/node_relationships.c
@@ -280,7 +280,7 @@ static void pick_input_link_by_link_intersect(const bContext *C,
float distance = dist_squared_to_line_segment_v2(cursor, l1, l2);
if (distance < cursor_link_touch_distance) {
link_to_pick = link;
- RNA_int_set(op->ptr, "last_picked_link_index", link->multi_input_socket_index);
+ nldrag->last_picked_multi_input_socket_link = link_to_pick;
}
}
}
@@ -290,13 +290,9 @@ static void pick_input_link_by_link_intersect(const bContext *C,
* Not essential for the basic behavior, but can make interaction feel a bit better if
* the mouse moves to the right and loses the "selection." */
if (!link_to_pick) {
- int last_picked_link_index = RNA_int_get(op->ptr, "last_picked_link_index");
- if (last_picked_link_index > -1) {
- LISTBASE_FOREACH (bNodeLink *, link, &snode->edittree->links) {
- if (link->multi_input_socket_index == last_picked_link_index) {
- link_to_pick = link;
- }
- }
+ bNodeLink *last_picked_link = nldrag->last_picked_multi_input_socket_link;
+ if (last_picked_link) {
+ link_to_pick = last_picked_link;
}
}
@@ -438,6 +434,75 @@ static bool snode_autoconnect_input(SpaceNode *snode,
return true;
}
+typedef struct LinkAndPosition {
+ struct bNodeLink *link;
+ float multi_socket_position[2];
+} LinkAndPosition;
+
+static int compare_link_by_y_position(const void *a, const void *b)
+{
+ const LinkAndPosition *link_and_position_a = *(const LinkAndPosition **)a;
+ const LinkAndPosition *link_and_position_b = *(const LinkAndPosition **)b;
+
+ BLI_assert(link_and_position_a->link->tosock == link_and_position_b->link->tosock);
+ const float link_a_y = link_and_position_a->multi_socket_position[1];
+ const float link_b_y = link_and_position_b->multi_socket_position[1];
+ return link_a_y > link_b_y ? 1 : -1;
+}
+
+void sort_multi_input_socket_links(SpaceNode *snode,
+ bNode *node,
+ bNodeLink *drag_link,
+ float cursor[2])
+{
+ LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
+ if (!(socket->flag & SOCK_MULTI_INPUT)) {
+ continue;
+ }
+ /* The total is calculated in #node_update_nodetree, which runs before this draw step. */
+ int total_inputs = socket->total_inputs + 1;
+ struct LinkAndPosition **input_links = MEM_malloc_arrayN(
+ total_inputs, sizeof(LinkAndPosition *), __func__);
+
+ int index = 0;
+ LISTBASE_FOREACH (bNodeLink *, link, &snode->edittree->links) {
+ if (link->tosock == socket) {
+ struct LinkAndPosition *link_and_position = MEM_callocN(sizeof(struct LinkAndPosition),
+ __func__);
+ link_and_position->link = link;
+ node_link_calculate_multi_input_position(link->tosock->locx,
+ link->tosock->locy,
+ link->multi_input_socket_index,
+ link->tosock->total_inputs,
+ link_and_position->multi_socket_position);
+ input_links[index] = link_and_position;
+ index++;
+ }
+ }
+
+ if (drag_link) {
+ LinkAndPosition *link_and_position = MEM_callocN(sizeof(LinkAndPosition), __func__);
+ link_and_position->link = drag_link;
+ copy_v2_v2(link_and_position->multi_socket_position, cursor);
+ input_links[index] = link_and_position;
+ index++;
+ }
+
+ qsort(input_links, index, sizeof(bNodeLink *), compare_link_by_y_position);
+
+ for (int i = 0; i < index; i++) {
+ input_links[i]->link->multi_input_socket_index = i;
+ }
+
+ for (int i = 0; i < index; i++) {
+ if (input_links[i]) {
+ MEM_freeN(input_links[i]);
+ }
+ }
+ MEM_freeN(input_links);
+ }
+}
+
static void snode_autoconnect(Main *bmain,
SpaceNode *snode,
const bool allow_multiple,
@@ -820,24 +885,39 @@ static void node_link_find_socket(bContext *C, wmOperator *op, float cursor[2])
LISTBASE_FOREACH (LinkData *, linkdata, &nldrag->links) {
bNodeLink *link = linkdata->data;
- /* skip if this is already the target socket */
- if (link->tosock == tsock) {
- continue;
- }
/* skip if socket is on the same node as the fromsock */
if (tnode && link->fromnode == tnode) {
continue;
}
+ /* Skip if tsock is already linked with this output. */
+ bNodeLink *existing_link_connected_to_fromsock = NULL;
+ LISTBASE_FOREACH (bNodeLink *, existing_link, &snode->edittree->links) {
+ if (existing_link->fromsock == link->fromsock && existing_link->tosock == tsock) {
+ existing_link_connected_to_fromsock = existing_link;
+ break;
+ }
+ }
+
/* attach links to the socket */
link->tonode = tnode;
link->tosock = tsock;
+ nldrag->last_node_hovered_while_dragging_a_link = tnode;
+ if (existing_link_connected_to_fromsock) {
+ link->multi_input_socket_index =
+ existing_link_connected_to_fromsock->multi_input_socket_index;
+ continue;
+ }
+ sort_multi_input_socket_links(snode, tnode, link, cursor);
}
}
else {
LISTBASE_FOREACH (LinkData *, linkdata, &nldrag->links) {
bNodeLink *link = linkdata->data;
-
+ if (nldrag->last_node_hovered_while_dragging_a_link) {
+ sort_multi_input_socket_links(
+ snode, nldrag->last_node_hovered_while_dragging_a_link, NULL, cursor);
+ }
link->tonode = NULL;
link->tosock = NULL;
}
@@ -1032,7 +1112,6 @@ static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
float cursor[2];
UI_view2d_region_to_view(&region->v2d, event->mval[0], event->mval[1], &cursor[0], &cursor[1]);
RNA_float_set_array(op->ptr, "drag_start", cursor);
- RNA_int_set(op->ptr, "last_picked_link_index", -1);
RNA_boolean_set(op->ptr, "has_link_picked", false);
ED_preview_kill_jobs(CTX_wm_manager(C), bmain);
@@ -1102,15 +1181,6 @@ void NODE_OT_link(wmOperatorType *ot)
-UI_PRECISION_FLOAT_MAX,
UI_PRECISION_FLOAT_MAX);
RNA_def_property_flag(prop, PROP_HIDDEN);
- RNA_def_int(ot->srna,
- "last_picked_link_index",
- -1,
- -1,
- 4095,
- "Last Picked Link Index",
- "The index of the last picked link on a multi-input socket",
- -1,
- 4095);
RNA_def_property_flag(prop, PROP_HIDDEN);
}
@@ -1157,8 +1227,8 @@ void NODE_OT_link_make(wmOperatorType *ot)
ot->srna, "replace", 0, "Replace", "Replace socket connections with the new links");
}
-/* ********************** Cut Link operator ***************** */
-static bool cut_links_intersect(bNodeLink *link, const float mcoords[][2], int tot)
+/* ********************** Node Link Intersect ***************** */
+static bool node_links_intersect(bNodeLink *link, const float mcoords[][2], int tot)
{
float coord_array[NODE_LINK_RESOL + 1][2];
@@ -1174,6 +1244,7 @@ static bool cut_links_intersect(bNodeLink *link, const float mcoords[][2], int t
return 0;
}
+/* ********************** Cut Link operator ***************** */
static int cut_links_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
@@ -1206,7 +1277,7 @@ static int cut_links_exec(bContext *C, wmOperator *op)
continue;
}
- if (cut_links_intersect(link, mcoords, i)) {
+ if (node_links_intersect(link, mcoords, i)) {
if (found == false) {
/* TODO(sergey): Why did we kill jobs twice? */
@@ -1265,6 +1336,110 @@ void NODE_OT_links_cut(wmOperatorType *ot)
RNA_def_int(ot->srna, "cursor", WM_CURSOR_KNIFE, 0, INT_MAX, "Cursor", "", 0, INT_MAX);
}
+/* ********************** Mute links operator ***************** */
+
+static int mute_links_exec(bContext *C, wmOperator *op)
+{
+ Main *bmain = CTX_data_main(C);
+ SpaceNode *snode = CTX_wm_space_node(C);
+ ARegion *region = CTX_wm_region(C);
+ bool do_tag_update = false;
+
+ int i = 0;
+ float mcoords[256][2];
+ RNA_BEGIN (op->ptr, itemptr, "path") {
+ float loc[2];
+
+ RNA_float_get_array(&itemptr, "loc", loc);
+ UI_view2d_region_to_view(
+ &region->v2d, (int)loc[0], (int)loc[1], &mcoords[i][0], &mcoords[i][1]);
+ i++;
+ if (i >= 256) {
+ break;
+ }
+ }
+ RNA_END;
+
+ if (i > 1) {
+ ED_preview_kill_jobs(CTX_wm_manager(C), bmain);
+
+ /* Count intersected links and clear test flag. */
+ int tot = 0;
+ LISTBASE_FOREACH (bNodeLink *, link, &snode->edittree->links) {
+ if (nodeLinkIsHidden(link)) {
+ continue;
+ }
+ link->flag &= ~NODE_LINK_TEST;
+ if (node_links_intersect(link, mcoords, i)) {
+ tot++;
+ }
+ }
+ if (tot == 0) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Mute links. */
+ LISTBASE_FOREACH (bNodeLink *, link, &snode->edittree->links) {
+ if (nodeLinkIsHidden(link) || (link->flag & NODE_LINK_TEST)) {
+ continue;
+ }
+
+ if (node_links_intersect(link, mcoords, i)) {
+ do_tag_update |= (do_tag_update ||
+ node_connected_to_output(bmain, snode->edittree, link->tonode));
+
+ snode_update(snode, link->tonode);
+ nodeMuteLinkToggle(snode->edittree, link);
+ }
+ }
+
+ /* Clear remaining test flags. */
+ LISTBASE_FOREACH (bNodeLink *, link, &snode->edittree->links) {
+ if (nodeLinkIsHidden(link)) {
+ continue;
+ }
+ link->flag &= ~NODE_LINK_TEST;
+ }
+
+ do_tag_update |= ED_node_is_geometry(snode);
+
+ ntreeUpdateTree(CTX_data_main(C), snode->edittree);
+ snode_notify(C, snode);
+ if (do_tag_update) {
+ snode_dag_update(C, snode);
+ }
+
+ return OPERATOR_FINISHED;
+ }
+
+ return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
+}
+
+void NODE_OT_links_mute(wmOperatorType *ot)
+{
+ ot->name = "Mute Links";
+ ot->idname = "NODE_OT_links_mute";
+ ot->description = "Use the mouse to mute links";
+
+ ot->invoke = WM_gesture_lines_invoke;
+ ot->modal = WM_gesture_lines_modal;
+ ot->exec = mute_links_exec;
+ ot->cancel = WM_gesture_lines_cancel;
+
+ ot->poll = ED_operator_node_editable;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ PropertyRNA *prop;
+ prop = RNA_def_collection_runtime(ot->srna, "path", &RNA_OperatorMousePath, "Path", "");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+
+ /* internal */
+ RNA_def_int(ot->srna, "cursor", WM_CURSOR_MUTE, 0, INT_MAX, "Cursor", "", 0, INT_MAX);
+}
+
/* ********************** Detach links operator ***************** */
static int detach_links_exec(bContext *C, wmOperator *UNUSED(op))
@@ -2104,6 +2279,8 @@ void ED_node_link_insert(Main *bmain, ScrArea *area)
snode_update(snode, select);
ED_node_tag_update_id((ID *)snode->edittree);
ED_node_tag_update_id(snode->id);
+
+ sort_multi_input_socket_links(snode, node, NULL, NULL);
}
}
}