1
1

Compare commits

...

9 Commits

Author SHA1 Message Date
47a4271fa0 improve colors 2021-11-08 18:48:40 +01:00
fad89e54db cleanup 2021-11-08 18:32:53 +01:00
1589002793 fix 2021-11-08 18:05:11 +01:00
71debe534c change color 2021-11-08 17:52:19 +01:00
663a1e21d3 progress 2021-11-08 17:47:52 +01:00
8b56f351e2 progress 2021-11-08 17:19:11 +01:00
33729eaf69 improve behavior 2021-11-08 16:52:30 +01:00
2e9854536f progress 2021-11-08 16:48:55 +01:00
fe3f05bbe7 initial link portals 2021-11-08 16:31:18 +01:00
12 changed files with 180 additions and 2 deletions

View File

@@ -2002,6 +2002,7 @@ def km_node_editor(params):
("node.links_cut",
{"type": 'EVT_TWEAK_L' if params.legacy else 'EVT_TWEAK_R', "value": 'ANY', "ctrl": True}, None),
("node.links_mute", {"type": 'EVT_TWEAK_R', "value": 'ANY', "ctrl": True, "alt": True}, None),
("node.make_link_portals", {"type": 'RIGHTMOUSE', "value": 'PRESS', "key_modifier": 'V'}, None),
("node.select_link_viewer", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True, "ctrl": True}, None),
("node.backimage_move", {"type": 'MIDDLEMOUSE', "value": 'PRESS', "alt": True}, None),
("node.backimage_zoom", {"type": 'V', "value": 'PRESS', "repeat": True},

View File

@@ -345,6 +345,7 @@ class NODE_MT_node(Menu):
layout.operator("node.links_cut")
layout.operator("node.links_detach")
layout.operator("node.links_mute")
layout.operator("node.make_link_portals")
layout.separator()

View File

@@ -676,6 +676,7 @@ void nodeRemLink(struct bNodeTree *ntree, struct bNodeLink *link);
void nodeRemSocketLinks(struct bNodeTree *ntree, struct bNodeSocket *sock);
void nodeMuteLinkToggle(struct bNodeTree *ntree, struct bNodeLink *link);
bool nodeLinkIsHidden(const struct bNodeLink *link);
bool nodeLinkIsPortal(const struct bNodeLink *link);
void nodeInternalRelink(struct bNodeTree *ntree, struct bNode *node);
void nodeToView(const struct bNode *node, float x, float y, float *rx, float *ry);

View File

@@ -2590,6 +2590,11 @@ bool nodeLinkIsHidden(const bNodeLink *link)
return nodeSocketIsHidden(link->fromsock) || nodeSocketIsHidden(link->tosock);
}
bool nodeLinkIsPortal(const bNodeLink *link)
{
return link->flag & NODE_LINK_PORTAL;
}
/* Adjust the indices of links connected to the given multi input socket after deleting the link at
* `deleted_index`. This function also works if the link has not yet been deleted. */
static void adjust_multi_input_indices_after_removed_link(bNodeTree *ntree,

View File

@@ -4276,7 +4276,7 @@ void node_draw_link_bezier(const bContext *C,
int th_col2,
int th_col3)
{
const float dim_factor = node_link_dim_factor(v2d, link);
float dim_factor = node_link_dim_factor(v2d, link);
float thickness = 1.5f;
float dash_factor = 1.0f;
@@ -4352,6 +4352,15 @@ void node_draw_link_bezier(const bContext *C,
}
}
if (link->flag & NODE_LINK_PORTAL && link->flag & NODE_LINK_VALID) {
if (link->flag & NODE_LINK_DRAGGED || is_fromnode_selected || is_tonode_selected) {
dim_factor = 0.4f;
}
else {
dim_factor = 0.03f;
}
}
if (g_batch_link.enabled && !highlighted) {
/* Add link to batch. */
nodelink_batch_add_link(snode,

View File

@@ -2154,6 +2154,50 @@ static void node_draw(const bContext *C,
}
}
static void draw_portal_link_indicators(bNodeTree *ntree)
{
Vector<bNodeLink *> portal_links;
LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
const bool from_node_selected = link->fromnode != nullptr &&
link->fromnode->flag & NODE_SELECT;
const bool to_node_selected = link->tonode != nullptr && link->tonode->flag & NODE_SELECT;
if (nodeLinkIsPortal(link) && !from_node_selected && !to_node_selected &&
link->flag & NODE_LINK_VALID) {
portal_links.append(link);
}
}
if (portal_links.is_empty()) {
return;
}
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor3f(0.6f, 0.6f, 0.6f);
immBegin(GPU_PRIM_TRIS, portal_links.size() * 2 * 12);
const float w = 12;
const float h = 1.5;
const float h2 = 3;
for (bNodeLink *link : portal_links) {
{
const float x = link->fromsock->locx;
const float y = link->fromsock->locy;
immRectf_fast(pos, x, y - h, x + w, y + h);
immRectf_fast(pos, x + w, y - h2, x + w + h * 2, y + h2);
}
{
const float x = link->tosock->locx;
const float y = link->tosock->locy;
immRectf_fast(pos, x, y - h, x - w, y + h);
immRectf_fast(pos, x - w, y - h2, x - w - h * 2, y + h2);
}
}
immEnd();
immUnbindProgram();
}
#define USE_DRAW_TOT_UPDATE
void node_draw_nodetree(const bContext *C,
@@ -2190,6 +2234,7 @@ void node_draw_nodetree(const bContext *C,
/* Node lines. */
GPU_blend(GPU_BLEND_ALPHA);
draw_portal_link_indicators(ntree);
nodelink_batch_start(snode);
LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {

View File

@@ -1279,7 +1279,20 @@ float node_link_dim_factor(const View2D *v2d, const bNodeLink *link)
bool node_link_is_hidden_or_dimmed(const View2D *v2d, const bNodeLink *link)
{
return nodeLinkIsHidden(link) || node_link_dim_factor(v2d, link) < 0.5f;
if (nodeLinkIsHidden(link)) {
return true;
}
if (node_link_dim_factor(v2d, link) < 0.5f) {
return true;
}
if (nodeLinkIsPortal(link)) {
if ((link->fromnode == nullptr || (link->fromnode->flag & NODE_SELECT) == 0) &&
(link->tonode == nullptr || (link->tonode->flag & NODE_SELECT) == 0)) {
/* Portal is shown when node is selected. */
return true;
}
}
return false;
}
/* ****************** Duplicate *********************** */

View File

@@ -243,6 +243,7 @@ void NODE_OT_link_make(struct wmOperatorType *ot);
void NODE_OT_links_cut(struct wmOperatorType *ot);
void NODE_OT_links_detach(struct wmOperatorType *ot);
void NODE_OT_links_mute(struct wmOperatorType *ot);
void NODE_OT_make_link_portals(struct wmOperatorType *ot);
void NODE_OT_parent_set(struct wmOperatorType *ot);
void NODE_OT_join(struct wmOperatorType *ot);

View File

@@ -70,6 +70,7 @@ void node_operatortypes(void)
WM_operatortype_append(NODE_OT_links_cut);
WM_operatortype_append(NODE_OT_links_detach);
WM_operatortype_append(NODE_OT_links_mute);
WM_operatortype_append(NODE_OT_make_link_portals);
WM_operatortype_append(NODE_OT_add_reroute);
WM_operatortype_append(NODE_OT_group_make);

View File

@@ -1678,6 +1678,101 @@ void NODE_OT_links_mute(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Make Portal Links Operator
* \{ */
static int make_link_portals_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *region = CTX_wm_region(C);
int tot_coords = 0;
float coords[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], &coords[tot_coords][0], &coords[tot_coords][1]);
tot_coords++;
if (tot_coords >= 256) {
break;
}
}
RNA_END;
if (tot_coords == 0) {
return OPERATOR_CANCELLED;
}
ED_preview_kill_jobs(CTX_wm_manager(C), bmain);
blender::Vector<bNodeLink *> intersecting_links;
LISTBASE_FOREACH (bNodeLink *, link, &snode->edittree->links) {
if (node_link_is_hidden_or_dimmed(&region->v2d, link)) {
continue;
}
if (node_links_intersect(link, coords, tot_coords)) {
intersecting_links.append(link);
}
}
if (intersecting_links.is_empty()) {
return OPERATOR_CANCELLED;
}
bool any_link_is_portal = false;
for (bNodeLink *link : intersecting_links) {
if (nodeLinkIsPortal(link)) {
any_link_is_portal = true;
break;
}
}
if (any_link_is_portal) {
for (bNodeLink *link : intersecting_links) {
link->flag &= ~NODE_LINK_PORTAL;
}
}
else {
for (bNodeLink *link : intersecting_links) {
link->flag |= NODE_LINK_PORTAL;
}
}
snode_notify(C, snode);
return OPERATOR_FINISHED;
}
void NODE_OT_make_link_portals(wmOperatorType *ot)
{
ot->name = "Make Link Portals";
ot->idname = "NODE_OT_make_link_portals";
ot->description = "Use the mouse to create portals from existing links";
ot->invoke = WM_gesture_lines_invoke;
ot->modal = WM_gesture_lines_modal;
ot->exec = make_link_portals_exec;
ot->cancel = WM_gesture_lines_cancel;
ot->poll = ED_operator_node_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR;
/* properties */
PropertyRNA *prop;
prop = RNA_def_collection_runtime(ot->srna, "path", &RNA_OperatorMousePath, "Path", "");
RNA_def_property_flag(prop, (PropertyFlag)(PROP_HIDDEN | PROP_SKIP_SAVE));
/* internal */
RNA_def_int(ot->srna, "cursor", WM_CURSOR_MUTE, 0, INT_MAX, "Cursor", "", 0, INT_MAX);
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Detach Links Operator
* \{ */

View File

@@ -459,6 +459,7 @@ typedef struct bNodeLink {
#define NODE_LINK_TEMP_HIGHLIGHT (1 << 3) /* Link is highlighted for picking. */
#define NODE_LINK_MUTED (1 << 4) /* Link is muted. */
#define NODE_LINK_DRAGGED (1 << 5) /* Node link is being dragged by the user. */
#define NODE_LINK_PORTAL (1 << 6)
/* tree->edit_quality/tree->render_quality */
#define NTREE_QUALITY_HIGH 0

View File

@@ -12566,6 +12566,11 @@ static void rna_def_node_link(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Muted", "Link is muted and can be ignored");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, NULL);
prop = RNA_def_property(srna, "is_portal", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_LINK_PORTAL);
RNA_def_struct_ui_text(srna, "Portal", "Link is portal and is displayed differently");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, NULL);
prop = RNA_def_property(srna, "from_node", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "fromnode");
RNA_def_property_struct_type(prop, "Node");