Fix #105720: crash when adding viewer node #105877
|
@ -151,13 +151,6 @@ class bNodeTreeRuntime : NonCopyable, NonMovable {
|
|||
Vector<bNode *> root_frames;
|
||||
Vector<bNodeSocket *> interface_inputs;
|
||||
Vector<bNodeSocket *> interface_outputs;
|
||||
|
||||
/**
|
||||
* The location of all sockets in the tree, calculated while drawing the nodes.
|
||||
* Indexed with #bNodeSocket::index_in_tree(). In the node tree's "world space"
|
||||
* (the same as #bNode::runtime::totr).
|
||||
*/
|
||||
Vector<float2> all_socket_locations;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -183,6 +176,13 @@ class bNodeSocketRuntime : NonCopyable, NonMovable {
|
|||
*/
|
||||
short total_inputs = 0;
|
||||
|
||||
/**
|
||||
* The location of the socket in the tree, calculated while drawing the nodes and invalid if the
|
||||
|
||||
* node tree hasn't been drawn yet. In the node tree's "world space" (the same as
|
||||
* #bNode::runtime::totr).
|
||||
*/
|
||||
float2 location;
|
||||
|
||||
/** Only valid when #topology_cache_is_dirty is false. */
|
||||
Vector<bNodeLink *> directly_linked_links;
|
||||
Vector<bNodeSocket *> directly_linked_sockets;
|
||||
|
|
|
@ -1589,12 +1589,11 @@ void draw_nodespace_back_pix(const bContext &C,
|
|||
GPU_matrix_pop();
|
||||
}
|
||||
|
||||
static float2 socket_link_connection_location(const Span<float2> socket_locations,
|
||||
const bNode &node,
|
||||
static float2 socket_link_connection_location(const bNode &node,
|
||||
const bNodeSocket &socket,
|
||||
const bNodeLink &link)
|
||||
{
|
||||
const float2 socket_location = socket_locations[socket.index_in_tree()];
|
||||
const float2 socket_location = socket.runtime->location;
|
||||
if (socket.is_multi_input() && socket.is_input() && !(node.flag & NODE_HIDDEN)) {
|
||||
return node_link_calculate_multi_input_position(
|
||||
socket_location, link.multi_input_socket_index, socket.runtime->total_inputs);
|
||||
|
@ -1628,13 +1627,11 @@ static void calculate_inner_link_bezier_points(std::array<float2, 4> &points)
|
|||
}
|
||||
}
|
||||
|
||||
static std::array<float2, 4> node_link_bezier_points(const Span<float2> socket_locations,
|
||||
const bNodeLink &link)
|
||||
static std::array<float2, 4> node_link_bezier_points(const bNodeLink &link)
|
||||
{
|
||||
std::array<float2, 4> points;
|
||||
points[0] = socket_link_connection_location(
|
||||
socket_locations, *link.fromnode, *link.fromsock, link);
|
||||
points[3] = socket_link_connection_location(socket_locations, *link.tonode, *link.tosock, link);
|
||||
points[0] = socket_link_connection_location(*link.fromnode, *link.fromsock, link);
|
||||
points[3] = socket_link_connection_location(*link.tonode, *link.tosock, link);
|
||||
calculate_inner_link_bezier_points(points);
|
||||
return points;
|
||||
}
|
||||
|
@ -1650,11 +1647,10 @@ static bool node_link_draw_is_visible(const View2D &v2d, const std::array<float2
|
|||
return true;
|
||||
}
|
||||
|
||||
void node_link_bezier_points_evaluated(const Span<float2> socket_locations,
|
||||
const bNodeLink &link,
|
||||
void node_link_bezier_points_evaluated(const bNodeLink &link,
|
||||
std::array<float2, NODE_LINK_RESOL + 1> &coords)
|
||||
{
|
||||
const std::array<float2, 4> points = node_link_bezier_points(socket_locations, link);
|
||||
const std::array<float2, 4> points = node_link_bezier_points(link);
|
||||
|
||||
/* The extra +1 in size is required by these functions and would be removed ideally. */
|
||||
BKE_curve_forward_diff_bezier(points[0].x,
|
||||
|
@ -2041,9 +2037,7 @@ static NodeLinkDrawConfig nodelink_get_draw_config(const bContext &C,
|
|||
|
||||
const bNodeTree &node_tree = *snode.edittree;
|
||||
|
||||
draw_config.dim_factor = selected ? 1.0f :
|
||||
node_link_dim_factor(
|
||||
node_tree.runtime->all_socket_locations, v2d, link);
|
||||
draw_config.dim_factor = selected ? 1.0f : node_link_dim_factor(v2d, link);
|
||||
|
||||
bTheme *btheme = UI_GetTheme();
|
||||
draw_config.dash_alpha = btheme->space_node.dash_alpha;
|
||||
|
@ -2167,8 +2161,7 @@ void node_draw_link_bezier(const bContext &C,
|
|||
const bool selected)
|
||||
{
|
||||
const bNodeTree &node_tree = *snode.edittree;
|
||||
const std::array<float2, 4> points = node_link_bezier_points(
|
||||
node_tree.runtime->all_socket_locations, link);
|
||||
const std::array<float2, 4> points = node_link_bezier_points(link);
|
||||
if (!node_link_draw_is_visible(v2d, points)) {
|
||||
return;
|
||||
}
|
||||
|
@ -2231,15 +2224,10 @@ static std::array<float2, 4> node_link_bezier_points_dragged(const SpaceNode &sn
|
|||
const float2 cursor = snode.runtime->cursor * UI_DPI_FAC;
|
||||
std::array<float2, 4> points;
|
||||
points[0] = link.fromsock ?
|
||||
socket_link_connection_location(node_tree.runtime->all_socket_locations,
|
||||
*link.fromnode,
|
||||
*link.fromsock,
|
||||
link) :
|
||||
cursor;
|
||||
points[3] = link.tosock ?
|
||||
socket_link_connection_location(
|
||||
node_tree.runtime->all_socket_locations, *link.tonode, *link.tosock, link) :
|
||||
socket_link_connection_location(*link.fromnode, *link.fromsock, link) :
|
||||
cursor;
|
||||
points[3] = link.tosock ? socket_link_connection_location(*link.tonode, *link.tosock, link) :
|
||||
cursor;
|
||||
calculate_inner_link_bezier_points(points);
|
||||
return points;
|
||||
}
|
||||
|
|
|
@ -109,12 +109,10 @@ bNode *add_static_node(const bContext &C, int type, const float2 &location)
|
|||
/** \name Add Reroute Operator
|
||||
* \{ */
|
||||
|
||||
std::optional<float2> link_path_intersection(const Span<float2> socket_locations,
|
||||
const bNodeLink &link,
|
||||
const Span<float2> path)
|
||||
std::optional<float2> link_path_intersection(const bNodeLink &link, const Span<float2> path)
|
||||
{
|
||||
std::array<float2, NODE_LINK_RESOL + 1> coords;
|
||||
node_link_bezier_points_evaluated(socket_locations, link, coords);
|
||||
node_link_bezier_points_evaluated(link, coords);
|
||||
|
||||
for (const int i : path.index_range().drop_back(1)) {
|
||||
for (const int j : IndexRange(NODE_LINK_RESOL)) {
|
||||
|
@ -140,7 +138,6 @@ static int add_reroute_exec(bContext *C, wmOperator *op)
|
|||
const ARegion ®ion = *CTX_wm_region(C);
|
||||
SpaceNode &snode = *CTX_wm_space_node(C);
|
||||
bNodeTree &ntree = *snode.edittree;
|
||||
const Span<float2> socket_locations = ntree.runtime->all_socket_locations;
|
||||
|
||||
Vector<float2> path;
|
||||
RNA_BEGIN (op->ptr, itemptr, "path") {
|
||||
|
@ -172,10 +169,10 @@ static int add_reroute_exec(bContext *C, wmOperator *op)
|
|||
Map<bNodeSocket *, RerouteCutsForSocket> cuts_per_socket;
|
||||
|
||||
LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) {
|
||||
if (node_link_is_hidden_or_dimmed(socket_locations, region.v2d, *link)) {
|
||||
if (node_link_is_hidden_or_dimmed(region.v2d, *link)) {
|
||||
continue;
|
||||
}
|
||||
const std::optional<float2> cut = link_path_intersection(socket_locations, *link, path);
|
||||
const std::optional<float2> cut = link_path_intersection(*link, path);
|
||||
if (!cut) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -268,9 +268,6 @@ void node_sort(bNodeTree &ntree)
|
|||
ntree.runtime->nodes_by_id.add_new(sort_nodes[i]);
|
||||
sort_nodes[i]->runtime->index_in_tree = i;
|
||||
}
|
||||
|
||||
/* Nodes have been reordered; the socket locations are invalid until the node tree is redrawn. */
|
||||
ntree.runtime->all_socket_locations.clear();
|
||||
}
|
||||
|
||||
static Array<uiBlock *> node_uiblocks_init(const bContext &C, const Span<bNode *> nodes)
|
||||
|
@ -321,8 +318,7 @@ static void node_update_basis(const bContext &C,
|
|||
const TreeDrawContext & /*tree_draw_ctx*/,
|
||||
bNodeTree &ntree,
|
||||
bNode &node,
|
||||
uiBlock &block,
|
||||
MutableSpan<float2> socket_locations)
|
||||
uiBlock &block)
|
||||
{
|
||||
PointerRNA nodeptr;
|
||||
RNA_pointer_create(&ntree.id, &RNA_Node, &node, &nodeptr);
|
||||
|
@ -392,8 +388,7 @@ static void node_update_basis(const bContext &C,
|
|||
buty = min_ii(buty, dy - NODE_DY);
|
||||
|
||||
/* Round the socket location to stop it from jiggling. */
|
||||
socket_locations[socket->index_in_tree()] = float2(round(loc.x + NODE_WIDTH(node)),
|
||||
round(dy - NODE_DYS));
|
||||
socket->runtime->location = float2(round(loc.x + NODE_WIDTH(node)), round(dy - NODE_DYS));
|
||||
|
||||
dy = buty;
|
||||
if (socket->next) {
|
||||
|
@ -525,7 +520,7 @@ static void node_update_basis(const bContext &C,
|
|||
buty = min_ii(buty, dy - NODE_DY);
|
||||
|
||||
/* Round the socket vertical position to stop it from jiggling. */
|
||||
socket_locations[socket->index_in_tree()] = float2(loc.x, round(dy - NODE_DYS));
|
||||
socket->runtime->location = float2(loc.x, round(dy - NODE_DYS));
|
||||
|
||||
dy = buty - multi_input_socket_offset * 0.5;
|
||||
if (socket->next) {
|
||||
|
@ -555,7 +550,7 @@ static void node_update_basis(const bContext &C,
|
|||
/**
|
||||
* Based on settings in node, sets drawing rect info.
|
||||
*/
|
||||
static void node_update_hidden(bNode &node, uiBlock &block, MutableSpan<float2> socket_locations)
|
||||
static void node_update_hidden(bNode &node, uiBlock &block)
|
||||
{
|
||||
int totin = 0, totout = 0;
|
||||
|
||||
|
@ -595,7 +590,7 @@ static void node_update_hidden(bNode &node, uiBlock &block, MutableSpan<float2>
|
|||
for (bNodeSocket *socket : node.output_sockets()) {
|
||||
if (socket->is_visible()) {
|
||||
/* Round the socket location to stop it from jiggling. */
|
||||
socket_locations[socket->index_in_tree()] = {
|
||||
socket->runtime->location = {
|
||||
round(node.runtime->totr.xmax - hiddenrad + sinf(rad) * hiddenrad),
|
||||
round(node.runtime->totr.ymin + hiddenrad + cosf(rad) * hiddenrad)};
|
||||
rad += drad;
|
||||
|
@ -608,7 +603,7 @@ static void node_update_hidden(bNode &node, uiBlock &block, MutableSpan<float2>
|
|||
for (bNodeSocket *socket : node.input_sockets()) {
|
||||
if (socket->is_visible()) {
|
||||
/* Round the socket location to stop it from jiggling. */
|
||||
socket_locations[socket->index_in_tree()] = {
|
||||
socket->runtime->location = {
|
||||
round(node.runtime->totr.xmin + hiddenrad + sinf(rad) * hiddenrad),
|
||||
round(node.runtime->totr.ymin + hiddenrad + cosf(rad) * hiddenrad)};
|
||||
rad += drad;
|
||||
|
@ -1188,7 +1183,6 @@ void node_socket_add_tooltip(const bNodeTree &ntree, const bNodeSocket &sock, ui
|
|||
|
||||
static void node_socket_draw_nested(const bContext &C,
|
||||
const bNodeTree &ntree,
|
||||
const Span<float2> socket_locations,
|
||||
PointerRNA &node_ptr,
|
||||
uiBlock &block,
|
||||
const bNodeSocket &sock,
|
||||
|
@ -1200,7 +1194,7 @@ static void node_socket_draw_nested(const bContext &C,
|
|||
const float size,
|
||||
const bool selected)
|
||||
{
|
||||
const float2 location = socket_locations[sock.index_in_tree()];
|
||||
const float2 location = sock.runtime->location;
|
||||
|
||||
float color[4];
|
||||
float outline_color[4];
|
||||
|
@ -1402,7 +1396,6 @@ static void node_draw_shadow(const SpaceNode &snode,
|
|||
static void node_draw_sockets(const View2D &v2d,
|
||||
const bContext &C,
|
||||
const bNodeTree &ntree,
|
||||
const Span<float2> socket_locations,
|
||||
const bNode &node,
|
||||
uiBlock &block,
|
||||
const bool draw_outputs,
|
||||
|
@ -1462,7 +1455,6 @@ static void node_draw_sockets(const View2D &v2d,
|
|||
|
||||
node_socket_draw_nested(C,
|
||||
ntree,
|
||||
socket_locations,
|
||||
node_ptr,
|
||||
block,
|
||||
*sock,
|
||||
|
@ -1489,7 +1481,6 @@ static void node_draw_sockets(const View2D &v2d,
|
|||
|
||||
node_socket_draw_nested(C,
|
||||
ntree,
|
||||
socket_locations,
|
||||
node_ptr,
|
||||
block,
|
||||
*sock,
|
||||
|
@ -1528,7 +1519,6 @@ static void node_draw_sockets(const View2D &v2d,
|
|||
if (select_all || (sock->flag & SELECT)) {
|
||||
node_socket_draw_nested(C,
|
||||
ntree,
|
||||
socket_locations,
|
||||
node_ptr,
|
||||
block,
|
||||
*sock,
|
||||
|
@ -1556,7 +1546,6 @@ static void node_draw_sockets(const View2D &v2d,
|
|||
if (select_all || (sock->flag & SELECT)) {
|
||||
node_socket_draw_nested(C,
|
||||
ntree,
|
||||
socket_locations,
|
||||
node_ptr,
|
||||
block,
|
||||
*sock,
|
||||
|
@ -1602,7 +1591,7 @@ static void node_draw_sockets(const View2D &v2d,
|
|||
node_socket_color_get(C, ntree, node_ptr, *socket, color);
|
||||
node_socket_outline_color_get(socket->flag & SELECT, socket->type, outline_color);
|
||||
|
||||
const float2 location = socket_locations[socket->index_in_tree()];
|
||||
const float2 location = socket->runtime->location;
|
||||
node_socket_draw_multi_input(color, outline_color, width, height, location);
|
||||
}
|
||||
}
|
||||
|
@ -2109,7 +2098,6 @@ static void node_draw_basis(const bContext &C,
|
|||
const View2D &v2d,
|
||||
const SpaceNode &snode,
|
||||
bNodeTree &ntree,
|
||||
const Span<float2> socket_locations,
|
||||
const bNode &node,
|
||||
uiBlock &block,
|
||||
bNodeInstanceKey key)
|
||||
|
@ -2410,7 +2398,7 @@ static void node_draw_basis(const bContext &C,
|
|||
|
||||
/* Skip slow socket drawing if zoom is small. */
|
||||
if (scale > 0.2f) {
|
||||
node_draw_sockets(v2d, C, ntree, socket_locations, node, block, true, false);
|
||||
node_draw_sockets(v2d, C, ntree, node, block, true, false);
|
||||
}
|
||||
|
||||
/* Preview. */
|
||||
|
@ -2434,7 +2422,6 @@ static void node_draw_hidden(const bContext &C,
|
|||
const View2D &v2d,
|
||||
const SpaceNode &snode,
|
||||
bNodeTree &ntree,
|
||||
const Span<float2> socket_locations,
|
||||
bNode &node,
|
||||
uiBlock &block)
|
||||
{
|
||||
|
@ -2604,7 +2591,7 @@ static void node_draw_hidden(const bContext &C,
|
|||
immUnbindProgram();
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
|
||||
node_draw_sockets(v2d, C, ntree, socket_locations, node, block, true, false);
|
||||
node_draw_sockets(v2d, C, ntree, node, block, true, false);
|
||||
|
||||
UI_block_end(&C, &block);
|
||||
UI_block_draw(&C, &block);
|
||||
|
@ -2739,13 +2726,13 @@ static void frame_node_prepare_for_draw(bNode &node, Span<bNode *> nodes)
|
|||
node.runtime->totr = rect;
|
||||
}
|
||||
|
||||
static void reroute_node_prepare_for_draw(bNode &node, MutableSpan<float2> socket_locations)
|
||||
static void reroute_node_prepare_for_draw(bNode &node)
|
||||
{
|
||||
const float2 loc = node_to_view(node, float2(0));
|
||||
|
||||
/* Reroute node has exactly one input and one output, both in the same place. */
|
||||
socket_locations[node.input_socket(0).index_in_tree()] = loc;
|
||||
socket_locations[node.output_socket(0).index_in_tree()] = loc;
|
||||
node.input_socket(0).runtime->location = loc;
|
||||
node.output_socket(0).runtime->location = loc;
|
||||
|
||||
const float size = 8.0f;
|
||||
node.width = size * 2;
|
||||
|
@ -2759,8 +2746,7 @@ static void node_update_nodetree(const bContext &C,
|
|||
TreeDrawContext &tree_draw_ctx,
|
||||
bNodeTree &ntree,
|
||||
Span<bNode *> nodes,
|
||||
Span<uiBlock *> blocks,
|
||||
MutableSpan<float2> socket_locations)
|
||||
Span<uiBlock *> blocks)
|
||||
{
|
||||
/* Make sure socket "used" tags are correct, for displaying value buttons. */
|
||||
SpaceNode *snode = CTX_wm_space_node(&C);
|
||||
|
@ -2776,14 +2762,14 @@ static void node_update_nodetree(const bContext &C,
|
|||
}
|
||||
|
||||
if (node.is_reroute()) {
|
||||
reroute_node_prepare_for_draw(node, socket_locations);
|
||||
reroute_node_prepare_for_draw(node);
|
||||
}
|
||||
else {
|
||||
if (node.flag & NODE_HIDDEN) {
|
||||
node_update_hidden(node, block, socket_locations);
|
||||
node_update_hidden(node, block);
|
||||
}
|
||||
else {
|
||||
node_update_basis(C, tree_draw_ctx, ntree, node, block, socket_locations);
|
||||
node_update_basis(C, tree_draw_ctx, ntree, node, block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2936,12 +2922,8 @@ static void frame_node_draw(const bContext &C,
|
|||
UI_block_draw(&C, &block);
|
||||
}
|
||||
|
||||
static void reroute_node_draw(const bContext &C,
|
||||
ARegion ®ion,
|
||||
bNodeTree &ntree,
|
||||
const Span<float2> socket_locations,
|
||||
const bNode &node,
|
||||
uiBlock &block)
|
||||
static void reroute_node_draw(
|
||||
const bContext &C, ARegion ®ion, bNodeTree &ntree, const bNode &node, uiBlock &block)
|
||||
{
|
||||
/* Skip if out of view. */
|
||||
const rctf &rct = node.runtime->totr;
|
||||
|
@ -2979,8 +2961,7 @@ static void reroute_node_draw(const bContext &C,
|
|||
|
||||
/* Only draw input socket as they all are placed on the same position highlight
|
||||
* if node itself is selected, since we don't display the node body separately. */
|
||||
node_draw_sockets(
|
||||
region.v2d, C, ntree, socket_locations, node, block, false, node.flag & SELECT);
|
||||
node_draw_sockets(region.v2d, C, ntree, node, block, false, node.flag & SELECT);
|
||||
|
||||
UI_block_end(&C, &block);
|
||||
UI_block_draw(&C, &block);
|
||||
|
@ -2991,7 +2972,6 @@ static void node_draw(const bContext &C,
|
|||
ARegion ®ion,
|
||||
const SpaceNode &snode,
|
||||
bNodeTree &ntree,
|
||||
const Span<float2> socket_locations,
|
||||
bNode &node,
|
||||
uiBlock &block,
|
||||
bNodeInstanceKey key)
|
||||
|
@ -3000,15 +2980,15 @@ static void node_draw(const bContext &C,
|
|||
frame_node_draw(C, tree_draw_ctx, region, snode, ntree, node, block);
|
||||
}
|
||||
else if (node.is_reroute()) {
|
||||
reroute_node_draw(C, region, ntree, socket_locations, node, block);
|
||||
reroute_node_draw(C, region, ntree, node, block);
|
||||
}
|
||||
else {
|
||||
const View2D &v2d = region.v2d;
|
||||
if (node.flag & NODE_HIDDEN) {
|
||||
node_draw_hidden(C, tree_draw_ctx, v2d, snode, ntree, socket_locations, node, block);
|
||||
node_draw_hidden(C, tree_draw_ctx, v2d, snode, ntree, node, block);
|
||||
}
|
||||
else {
|
||||
node_draw_basis(C, tree_draw_ctx, v2d, snode, ntree, socket_locations, node, block, key);
|
||||
node_draw_basis(C, tree_draw_ctx, v2d, snode, ntree, node, block, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3020,7 +3000,6 @@ static void node_draw_nodetree(const bContext &C,
|
|||
ARegion ®ion,
|
||||
SpaceNode &snode,
|
||||
bNodeTree &ntree,
|
||||
const Span<float2> socket_locations,
|
||||
Span<bNode *> nodes,
|
||||
Span<uiBlock *> blocks,
|
||||
bNodeInstanceKey parent_key)
|
||||
|
@ -3042,8 +3021,7 @@ static void node_draw_nodetree(const bContext &C,
|
|||
}
|
||||
|
||||
const bNodeInstanceKey key = BKE_node_instance_key(parent_key, &ntree, nodes[i]);
|
||||
node_draw(
|
||||
C, tree_draw_ctx, region, snode, ntree, socket_locations, *nodes[i], *blocks[i], key);
|
||||
node_draw(C, tree_draw_ctx, region, snode, ntree, *nodes[i], *blocks[i], key);
|
||||
}
|
||||
|
||||
/* Node lines. */
|
||||
|
@ -3073,8 +3051,7 @@ static void node_draw_nodetree(const bContext &C,
|
|||
}
|
||||
|
||||
const bNodeInstanceKey key = BKE_node_instance_key(parent_key, &ntree, nodes[i]);
|
||||
node_draw(
|
||||
C, tree_draw_ctx, region, snode, ntree, socket_locations, *nodes[i], *blocks[i], key);
|
||||
node_draw(C, tree_draw_ctx, region, snode, ntree, *nodes[i], *blocks[i], key);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3181,19 +3158,9 @@ static void draw_nodetree(const bContext &C,
|
|||
else if (ntree.type == NTREE_COMPOSIT) {
|
||||
tree_draw_ctx.used_by_realtime_compositor = realtime_compositor_is_in_use(C);
|
||||
}
|
||||
ntree.runtime->all_socket_locations.reinitialize(ntree.all_sockets().size());
|
||||
|
||||
node_update_nodetree(
|
||||
C, tree_draw_ctx, ntree, nodes, blocks, ntree.runtime->all_socket_locations);
|
||||
node_draw_nodetree(C,
|
||||
tree_draw_ctx,
|
||||
region,
|
||||
*snode,
|
||||
ntree,
|
||||
ntree.runtime->all_socket_locations,
|
||||
nodes,
|
||||
blocks,
|
||||
parent_key);
|
||||
node_update_nodetree(C, tree_draw_ctx, ntree, nodes, blocks);
|
||||
node_draw_nodetree(C, tree_draw_ctx, region, *snode, ntree, nodes, blocks, parent_key);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1099,12 +1099,10 @@ void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set)
|
|||
}
|
||||
}
|
||||
|
||||
static bool cursor_isect_multi_input_socket(const Span<float2> socket_locations,
|
||||
const float2 &cursor,
|
||||
const bNodeSocket &socket)
|
||||
static bool cursor_isect_multi_input_socket(const float2 &cursor, const bNodeSocket &socket)
|
||||
{
|
||||
const float node_socket_height = node_socket_calculate_height(socket);
|
||||
const float2 location = socket_locations[socket.index_in_tree()];
|
||||
const float2 location = socket.runtime->location;
|
||||
/* `.xmax = socket->locx + NODE_SOCKSIZE * 5.5f`
|
||||
* would be the same behavior as for regular sockets.
|
||||
* But keep it smaller because for multi-input socket you
|
||||
|
@ -1131,11 +1129,6 @@ bNodeSocket *node_find_indicated_socket(SpaceNode &snode,
|
|||
|
||||
bNodeTree &node_tree = *snode.edittree;
|
||||
node_tree.ensure_topology_cache();
|
||||
const Span<float2> socket_locations = node_tree.runtime->all_socket_locations;
|
||||
if (socket_locations.size() != node_tree.all_sockets().size()) {
|
||||
/* Sockets haven't been drawn yet, e.g. when the file is currently opening. */
|
||||
return nullptr;
|
||||
}
|
||||
const Span<bNode *> nodes = node_tree.all_nodes();
|
||||
if (nodes.is_empty()) {
|
||||
return nullptr;
|
||||
|
@ -1160,9 +1153,9 @@ bNodeSocket *node_find_indicated_socket(SpaceNode &snode,
|
|||
if (in_out & SOCK_IN) {
|
||||
for (bNodeSocket *sock : node.input_sockets()) {
|
||||
if (sock->is_visible()) {
|
||||
const float2 location = socket_locations[sock->index_in_tree()];
|
||||
const float2 location = sock->runtime->location;
|
||||
if (sock->flag & SOCK_MULTI_INPUT && !(node.flag & NODE_HIDDEN)) {
|
||||
if (cursor_isect_multi_input_socket(socket_locations, cursor, *sock)) {
|
||||
if (cursor_isect_multi_input_socket(cursor, *sock)) {
|
||||
if (!socket_is_occluded(location, node, snode)) {
|
||||
return sock;
|
||||
}
|
||||
|
@ -1179,7 +1172,7 @@ bNodeSocket *node_find_indicated_socket(SpaceNode &snode,
|
|||
if (in_out & SOCK_OUT) {
|
||||
for (bNodeSocket *sock : node.output_sockets()) {
|
||||
if (sock->is_visible()) {
|
||||
const float2 location = socket_locations[sock->index_in_tree()];
|
||||
const float2 location = sock->runtime->location;
|
||||
if (BLI_rctf_isect_pt(&rect, location.x, location.y)) {
|
||||
if (!socket_is_occluded(location, node, snode)) {
|
||||
return sock;
|
||||
|
@ -1199,16 +1192,14 @@ bNodeSocket *node_find_indicated_socket(SpaceNode &snode,
|
|||
/** \name Node Link Dimming
|
||||
* \{ */
|
||||
|
||||
float node_link_dim_factor(const Span<float2> socket_locations,
|
||||
const View2D &v2d,
|
||||
const bNodeLink &link)
|
||||
float node_link_dim_factor(const View2D &v2d, const bNodeLink &link)
|
||||
{
|
||||
if (link.fromsock == nullptr || link.tosock == nullptr) {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
const float2 from = socket_locations[link.fromsock->index_in_tree()];
|
||||
const float2 to = socket_locations[link.tosock->index_in_tree()];
|
||||
const float2 from = link.fromsock->runtime->location;
|
||||
const float2 to = link.tosock->runtime->location;
|
||||
|
||||
const float min_endpoint_distance = std::min(
|
||||
std::max(BLI_rctf_length_x(&v2d.cur, from.x), BLI_rctf_length_y(&v2d.cur, from.y)),
|
||||
|
@ -1221,11 +1212,9 @@ float node_link_dim_factor(const Span<float2> socket_locations,
|
|||
return std::clamp(1.0f - min_endpoint_distance / viewport_width * 10.0f, 0.05f, 1.0f);
|
||||
}
|
||||
|
||||
bool node_link_is_hidden_or_dimmed(const Span<float2> socket_locations,
|
||||
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(socket_locations, v2d, link) < 0.5f;
|
||||
return nodeLinkIsHidden(&link) || node_link_dim_factor(v2d, link) < 0.5f;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -247,13 +247,10 @@ void node_draw_link_bezier(const bContext &C,
|
|||
int th_col3,
|
||||
bool selected);
|
||||
|
||||
void node_link_bezier_points_evaluated(Span<float2> all_socket_locations,
|
||||
const bNodeLink &link,
|
||||
void node_link_bezier_points_evaluated(const bNodeLink &link,
|
||||
std::array<float2, NODE_LINK_RESOL + 1> &coords);
|
||||
|
||||
std::optional<float2> link_path_intersection(Span<float2> socket_locations,
|
||||
const bNodeLink &link,
|
||||
Span<float2> path);
|
||||
std::optional<float2> link_path_intersection(const bNodeLink &link, Span<float2> path);
|
||||
|
||||
void draw_nodespace_back_pix(const bContext &C,
|
||||
ARegion ®ion,
|
||||
|
@ -325,12 +322,8 @@ int node_render_changed_exec(bContext *, wmOperator *);
|
|||
bNodeSocket *node_find_indicated_socket(SpaceNode &snode,
|
||||
const float2 &cursor,
|
||||
eNodeSocketInOut in_out);
|
||||
float node_link_dim_factor(Span<float2> socket_locations,
|
||||
const View2D &v2d,
|
||||
const bNodeLink &link);
|
||||
bool node_link_is_hidden_or_dimmed(Span<float2> socket_locations,
|
||||
const View2D &v2d,
|
||||
const bNodeLink &link);
|
||||
float node_link_dim_factor(const View2D &v2d, const bNodeLink &link);
|
||||
bool node_link_is_hidden_or_dimmed(const View2D &v2d, const bNodeLink &link);
|
||||
|
||||
void NODE_OT_duplicate(wmOperatorType *ot);
|
||||
void NODE_OT_delete(wmOperatorType *ot);
|
||||
|
|
|
@ -122,10 +122,6 @@ static void pick_input_link_by_link_intersect(const bContext &C,
|
|||
{
|
||||
SpaceNode *snode = CTX_wm_space_node(&C);
|
||||
bNodeTree &node_tree = *snode->edittree;
|
||||
const Span<float2> socket_locations = node_tree.runtime->all_socket_locations;
|
||||
if (socket_locations.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
float2 drag_start;
|
||||
RNA_float_get_array(op.ptr, "drag_start", drag_start);
|
||||
|
@ -140,7 +136,7 @@ static void pick_input_link_by_link_intersect(const bContext &C,
|
|||
for (bNodeLink *link : socket->directly_linked_links()) {
|
||||
/* Test if the cursor is near a link. */
|
||||
std::array<float2, NODE_LINK_RESOL + 1> coords;
|
||||
node_link_bezier_points_evaluated(socket_locations, *link, coords);
|
||||
node_link_bezier_points_evaluated(*link, coords);
|
||||
|
||||
for (const int i : IndexRange(coords.size() - 1)) {
|
||||
const float distance = dist_squared_to_line_segment_v2(cursor, coords[i], coords[i + 1]);
|
||||
|
@ -293,12 +289,11 @@ struct LinkAndPosition {
|
|||
float2 multi_socket_position;
|
||||
};
|
||||
|
||||
static void sort_multi_input_socket_links_with_drag(const Span<float2> socket_locations,
|
||||
bNodeSocket &socket,
|
||||
static void sort_multi_input_socket_links_with_drag(bNodeSocket &socket,
|
||||
bNodeLink &drag_link,
|
||||
const float2 &cursor)
|
||||
{
|
||||
const float2 &socket_location = socket_locations[socket.index_in_tree()];
|
||||
const float2 &socket_location = socket.runtime->location;
|
||||
|
||||
Vector<LinkAndPosition, 8> links;
|
||||
for (bNodeLink *link : socket.directly_linked_links()) {
|
||||
|
@ -646,8 +641,7 @@ static int view_socket(const bContext &C,
|
|||
}
|
||||
}
|
||||
if (viewer_node == nullptr) {
|
||||
const float2 socket_location =
|
||||
btree.runtime->all_socket_locations[bsocket_to_view.index_in_tree()];
|
||||
const float2 socket_location = bsocket_to_view.runtime->location;
|
||||
const int viewer_type = get_default_viewer_type(&C);
|
||||
const float2 location{socket_location.x / UI_DPI_FAC + 100, socket_location.y / UI_DPI_FAC};
|
||||
viewer_node = add_static_node(C, viewer_type, location);
|
||||
|
@ -1114,12 +1108,7 @@ static void node_link_cancel(bContext *C, wmOperator *op)
|
|||
static void node_link_find_socket(bContext &C, wmOperator &op, const float2 &cursor)
|
||||
{
|
||||
SpaceNode &snode = *CTX_wm_space_node(&C);
|
||||
bNodeTree &node_tree = *snode.edittree;
|
||||
bNodeLinkDrag &nldrag = *static_cast<bNodeLinkDrag *>(op.customdata);
|
||||
const Span<float2> socket_locations = node_tree.runtime->all_socket_locations;
|
||||
if (socket_locations.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (nldrag.in_out == SOCK_OUT) {
|
||||
if (bNodeSocket *tsock = node_find_indicated_socket(snode, cursor, SOCK_IN)) {
|
||||
|
@ -1150,7 +1139,7 @@ static void node_link_find_socket(bContext &C, wmOperator &op, const float2 &cur
|
|||
continue;
|
||||
}
|
||||
if (tsock && tsock->is_multi_input()) {
|
||||
sort_multi_input_socket_links_with_drag(socket_locations, *tsock, link, cursor);
|
||||
sort_multi_input_socket_links_with_drag(*tsock, link, cursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1523,15 +1512,14 @@ static int cut_links_exec(bContext *C, wmOperator *op)
|
|||
|
||||
bNodeTree &node_tree = *snode.edittree;
|
||||
node_tree.ensure_topology_cache();
|
||||
const Span<float2> socket_locations = node_tree.runtime->all_socket_locations;
|
||||
|
||||
Set<bNodeLink *> links_to_remove;
|
||||
LISTBASE_FOREACH (bNodeLink *, link, &node_tree.links) {
|
||||
if (node_link_is_hidden_or_dimmed(socket_locations, region.v2d, *link)) {
|
||||
if (node_link_is_hidden_or_dimmed(region.v2d, *link)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (link_path_intersection(socket_locations, *link, path)) {
|
||||
if (link_path_intersection(*link, path)) {
|
||||
|
||||
if (!found) {
|
||||
/* TODO(sergey): Why did we kill jobs twice? */
|
||||
|
@ -1609,7 +1597,6 @@ static int mute_links_exec(bContext *C, wmOperator *op)
|
|||
SpaceNode &snode = *CTX_wm_space_node(C);
|
||||
const ARegion ®ion = *CTX_wm_region(C);
|
||||
bNodeTree &ntree = *snode.edittree;
|
||||
const Span<float2> socket_locations = ntree.runtime->all_socket_locations;
|
||||
|
||||
Vector<float2> path;
|
||||
RNA_BEGIN (op->ptr, itemptr, "path") {
|
||||
|
@ -1634,10 +1621,10 @@ static int mute_links_exec(bContext *C, wmOperator *op)
|
|||
|
||||
Set<bNodeLink *> affected_links;
|
||||
LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) {
|
||||
if (node_link_is_hidden_or_dimmed(socket_locations, region.v2d, *link)) {
|
||||
if (node_link_is_hidden_or_dimmed(region.v2d, *link)) {
|
||||
continue;
|
||||
}
|
||||
if (!link_path_intersection(socket_locations, *link, path)) {
|
||||
if (!link_path_intersection(*link, path)) {
|
||||
continue;
|
||||
}
|
||||
affected_links.add(link);
|
||||
|
@ -2092,10 +2079,6 @@ void node_insert_on_link_flags_set(SpaceNode &snode, const ARegion ®ion)
|
|||
{
|
||||
bNodeTree &node_tree = *snode.edittree;
|
||||
node_tree.ensure_topology_cache();
|
||||
const Span<float2> socket_locations = node_tree.runtime->all_socket_locations;
|
||||
if (socket_locations.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
node_insert_on_link_flags_clear(node_tree);
|
||||
|
||||
|
@ -2108,12 +2091,12 @@ void node_insert_on_link_flags_set(SpaceNode &snode, const ARegion ®ion)
|
|||
bNodeLink *selink = nullptr;
|
||||
float dist_best = FLT_MAX;
|
||||
LISTBASE_FOREACH (bNodeLink *, link, &node_tree.links) {
|
||||
if (node_link_is_hidden_or_dimmed(socket_locations, region.v2d, *link)) {
|
||||
if (node_link_is_hidden_or_dimmed(region.v2d, *link)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::array<float2, NODE_LINK_RESOL + 1> coords;
|
||||
node_link_bezier_points_evaluated(socket_locations, *link, coords);
|
||||
node_link_bezier_points_evaluated(*link, coords);
|
||||
float dist = FLT_MAX;
|
||||
|
||||
/* Loop over link coords to find shortest dist to upper left node edge of a intersected line
|
||||
|
|
Loading…
Reference in New Issue
Maybe add
and invalid if the node tree hasn't been drawn yet
to the first sentence