Nodes: move most runtime data out of bNode

* This patch just moves runtime data to the runtime struct to cleanup
  the dna struct. Arguably, some of this data should not even be there
  because it's very use case specific. This can be cleaned up separately.
* `miniwidth` was removed completely, because it was not used anywhere.
  The corresponding rna property `width_hidden` is kept to avoid
  script breakage, but does not do anything (e.g. node wrangler sets it).
* Since rna is in C, some helper functions where added to access the
  C++ runtime data from rna.
* This size of `bNode` decreases from 432 to 368 bytes.
This commit is contained in:
Jacques Lucke 2022-11-18 12:46:20 +01:00
parent 754f674977
commit 7b82d8f029
34 changed files with 343 additions and 273 deletions

@ -688,6 +688,9 @@ void nodeRemoveNode(struct Main *bmain,
struct bNode *node,
bool do_id_user);
void nodeDimensionsGet(const struct bNode *node, float *r_width, float *r_height);
void nodeTagUpdateID(struct bNode *node);
#ifdef __cplusplus
namespace blender::bke {

@ -146,6 +146,46 @@ class bNodeRuntime : NonCopyable, NonMovable {
/** #eNodeTreeChangedFlag. */
uint32_t changed_flag = 0;
/** Both for dependency and sorting. */
short done = 0;
short level = 0;
/** Used as a boolean for execution. */
uint8_t need_exec = 0;
/** The original node in the tree (for localized tree). */
struct bNode *original = nullptr;
/**
* XXX TODO
* Node totr size depends on the prvr size, which in turn is determined from preview size.
* In earlier versions bNodePreview was stored directly in nodes, but since now there can be
* multiple instances using different preview images it is possible that required node size
* varies between instances. preview_xsize, preview_ysize defines a common reserved size for
* preview rect for now, could be replaced by more accurate node instance drawing,
* but that requires removing totr from DNA and replacing all uses with per-instance data.
*/
/** Reserved size of the preview rect. */
short preview_xsize, preview_ysize = 0;
/** Entire bound-box (world-space). */
rctf totr{};
/** Optional preview area. */
rctf prvr{};
/** Used at runtime when going through the tree. Initialize before use. */
short tmp_flag = 0;
/** Used at runtime when iterating over node branches. */
char iter_flag = 0;
/** Update flags. */
int update = 0;
/** Initial locx for insert offset animation. */
float anim_init_locx;
/** Offset that will be added to locx for insert offset animation. */
float anim_ofsx;
/** Only valid if #topology_cache_is_dirty is false. */
Vector<bNodeSocket *> inputs;
Vector<bNodeSocket *> outputs;

@ -1115,7 +1115,6 @@ static void node_init(const struct bContext *C, bNodeTree *ntree, bNode *node)
node->flag = NODE_SELECT | NODE_OPTIONS | ntype->flag;
node->width = ntype->width;
node->miniwidth = 42.0f;
node->height = ntype->height;
node->color[0] = node->color[1] = node->color[2] = 0.608; /* default theme color */
/* initialize the node name with the node label.
@ -2116,11 +2115,11 @@ static void iter_backwards_ex(const bNodeTree *ntree,
/* Skip links marked as cyclic. */
continue;
}
if (link->fromnode->iter_flag & recursion_mask) {
if (link->fromnode->runtime->iter_flag & recursion_mask) {
continue;
}
link->fromnode->iter_flag |= recursion_mask;
link->fromnode->runtime->iter_flag |= recursion_mask;
if (!callback(link->fromnode, link->tonode, userdata)) {
return;
@ -2145,7 +2144,7 @@ void nodeChainIterBackwards(const bNodeTree *ntree,
/* Reset flag. */
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
node->iter_flag &= ~recursion_mask;
node->runtime->iter_flag &= ~recursion_mask;
}
iter_backwards_ex(ntree, node_start, callback, userdata, recursion_mask);
@ -2789,8 +2788,8 @@ static void node_preview_init_tree_recursive(bNodeInstanceHash *previews,
bNodeInstanceKey key = BKE_node_instance_key(parent_key, ntree, node);
if (BKE_node_preview_used(node)) {
node->preview_xsize = xsize;
node->preview_ysize = ysize;
node->runtime->preview_xsize = xsize;
node->runtime->preview_ysize = ysize;
BKE_node_preview_verify(previews, key, xsize, ysize, false);
}
@ -3277,7 +3276,7 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree)
bNode *node_src = (bNode *)ntree->nodes.first;
bNode *node_local = (bNode *)ltree->nodes.first;
while (node_src != nullptr) {
node_local->original = node_src;
node_local->runtime->original = node_src;
node_src = node_src->next;
node_local = node_local->next;
}
@ -3753,6 +3752,17 @@ bool nodeDeclarationEnsure(bNodeTree *ntree, bNode *node)
return false;
}
void nodeDimensionsGet(const bNode *node, float *r_width, float *r_height)
{
*r_width = node->runtime->totr.xmax - node->runtime->totr.xmin;
*r_height = node->runtime->totr.ymax - node->runtime->totr.ymin;
}
void nodeTagUpdateID(bNode *node)
{
node->runtime->update |= NODE_UPDATE_ID;
}
/* ************** Node Clipboard *********** */
#define USE_NODE_CB_VALIDATE
@ -4064,28 +4074,28 @@ static int node_get_deplist_recurs(bNodeTree *ntree, bNode *node, bNode ***nsort
{
int level = 0xFFF;
node->done = true;
node->runtime->done = true;
/* check linked nodes */
LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
if (link->tonode == node) {
bNode *fromnode = link->fromnode;
if (fromnode->done == 0) {
fromnode->level = node_get_deplist_recurs(ntree, fromnode, nsort);
if (fromnode->runtime->done == 0) {
fromnode->runtime->level = node_get_deplist_recurs(ntree, fromnode, nsort);
}
if (fromnode->level <= level) {
level = fromnode->level - 1;
if (fromnode->runtime->level <= level) {
level = fromnode->runtime->level - 1;
}
}
}
/* check parent node */
if (node->parent) {
if (node->parent->done == 0) {
node->parent->level = node_get_deplist_recurs(ntree, node->parent, nsort);
if (node->parent->runtime->done == 0) {
node->parent->runtime->level = node_get_deplist_recurs(ntree, node->parent, nsort);
}
if (node->parent->level <= level) {
level = node->parent->level - 1;
if (node->parent->runtime->level <= level) {
level = node->parent->runtime->level - 1;
}
}
@ -4103,7 +4113,7 @@ void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***r_deplist,
/* first clear data */
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
node->done = false;
node->runtime->done = false;
(*r_deplist_len)++;
}
if (*r_deplist_len == 0) {
@ -4117,8 +4127,8 @@ void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***r_deplist,
/* recursive check */
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->done == 0) {
node->level = node_get_deplist_recurs(ntree, node, &nsort);
if (node->runtime->done == 0) {
node->runtime->level = node_get_deplist_recurs(ntree, node, &nsort);
}
}
}
@ -4128,13 +4138,13 @@ void ntreeUpdateNodeLevels(bNodeTree *ntree)
{
/* first clear tag */
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
node->done = false;
node->runtime->done = false;
}
/* recursive check */
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->done == 0) {
node->level = node_get_deplist_recurs(ntree, node, nullptr);
if (node->runtime->done == 0) {
node->runtime->level = node_get_deplist_recurs(ntree, node, nullptr);
}
}
}

@ -1275,7 +1275,8 @@ class NodeTreeMainUpdater {
{
LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) {
link->flag |= NODE_LINK_VALID;
if (link->fromnode && link->tonode && link->fromnode->level <= link->tonode->level) {
if (link->fromnode && link->tonode &&
link->fromnode->runtime->level <= link->tonode->runtime->level) {
link->flag &= ~NODE_LINK_VALID;
}
else if (ntree.typeinfo->validate_link) {
@ -1597,7 +1598,7 @@ class NodeTreeMainUpdater {
ntree.runtime->changed_flag = NTREE_CHANGED_NOTHING;
LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
node->runtime->changed_flag = NTREE_CHANGED_NOTHING;
node->update = 0;
node->runtime->update = 0;
LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
socket->runtime->changed_flag = NTREE_CHANGED_NOTHING;
}
@ -1715,7 +1716,7 @@ void BKE_ntree_update_tag_id_changed(Main *bmain, ID *id)
FOREACH_NODETREE_BEGIN (bmain, ntree, ntree_id) {
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->id == id) {
node->update |= NODE_UPDATE_ID;
node->runtime->update |= NODE_UPDATE_ID;
add_node_tag(ntree, node, NTREE_CHANGED_NODE_PROPERTY);
}
}

@ -5,6 +5,8 @@
#include "BLI_multi_value_map.hh"
#include "BKE_node_runtime.hh"
#include "COM_Converter.h"
#include "COM_Debug.h"
@ -222,10 +224,11 @@ PreviewOperation *NodeOperationBuilder::make_preview_operation() const
bNodeInstanceHash *previews = context_->get_preview_hash();
if (previews) {
Scene *scene = context_->get_scene();
PreviewOperation *operation = new PreviewOperation(&scene->view_settings,
&scene->display_settings,
current_node_->get_bnode()->preview_xsize,
current_node_->get_bnode()->preview_ysize);
PreviewOperation *operation = new PreviewOperation(
&scene->view_settings,
&scene->display_settings,
current_node_->get_bnode()->runtime->preview_xsize,
current_node_->get_bnode()->runtime->preview_ysize);
operation->set_bnodetree(context_->get_bnodetree());
operation->verify_preview(previews, current_node_->get_instance_key());
return operation;

@ -232,7 +232,7 @@ NodeResizeDirection node_get_resize_direction(const bNode *node, const int x, co
NodeResizeDirection dir = NODE_RESIZE_NONE;
const rctf &totr = node->totr;
const rctf &totr = node->runtime->totr;
const float size = NODE_RESIZE_MARGIN;
if (x > totr.xmax - size && x <= totr.xmax && y >= totr.ymin && y < totr.ymax) {
@ -253,8 +253,8 @@ NodeResizeDirection node_get_resize_direction(const bNode *node, const int x, co
if (node->flag & NODE_HIDDEN) {
/* right part of node */
rctf totr = node->totr;
totr.xmin = node->totr.xmax - 1.0f * U.widget_unit;
rctf totr = node->runtime->totr;
totr.xmin = node->runtime->totr.xmax - 1.0f * U.widget_unit;
if (BLI_rctf_isect_pt(&totr, x, y)) {
return NODE_RESIZE_RIGHT;
}
@ -263,7 +263,7 @@ NodeResizeDirection node_get_resize_direction(const bNode *node, const int x, co
}
const float size = NODE_RESIZE_MARGIN;
const rctf &totr = node->totr;
const rctf &totr = node->runtime->totr;
NodeResizeDirection dir = NODE_RESIZE_NONE;
if (x >= totr.xmax - size && x < totr.xmax && y >= totr.ymin && y < totr.ymax) {

@ -204,7 +204,7 @@ static int add_reroute_exec(bContext *C, wmOperator *op)
/* Attach the reroute node to frame nodes behind it. */
for (const int i : frame_nodes.index_range()) {
bNode *frame_node = frame_nodes.last(i);
if (BLI_rctf_isect_pt_v(&frame_node->totr, insert_point)) {
if (BLI_rctf_isect_pt_v(&frame_node->runtime->totr, insert_point)) {
nodeAttachNode(&ntree, reroute, frame_node);
break;
}

@ -433,41 +433,41 @@ static void node_update_basis(const bContext &C,
dy -= NODE_DY / 4;
}
node.prvr.xmin = loc.x + NODE_DYS;
node.prvr.xmax = loc.x + NODE_WIDTH(node) - NODE_DYS;
node.runtime->prvr.xmin = loc.x + NODE_DYS;
node.runtime->prvr.xmax = loc.x + NODE_WIDTH(node) - NODE_DYS;
/* preview rect? */
if (node.flag & NODE_PREVIEW) {
float aspect = 1.0f;
if (node.preview_xsize && node.preview_ysize) {
aspect = float(node.preview_ysize) / float(node.preview_xsize);
if (node.runtime->preview_xsize && node.runtime->preview_ysize) {
aspect = float(node.runtime->preview_ysize) / float(node.runtime->preview_xsize);
}
dy -= NODE_DYS / 2;
node.prvr.ymax = dy;
node.runtime->prvr.ymax = dy;
if (aspect <= 1.0f) {
node.prvr.ymin = dy - aspect * (NODE_WIDTH(node) - NODE_DY);
node.runtime->prvr.ymin = dy - aspect * (NODE_WIDTH(node) - NODE_DY);
}
else {
/* Width correction of image. XXX huh? (ton) */
float dx = (NODE_WIDTH(node) - NODE_DYS) - (NODE_WIDTH(node) - NODE_DYS) / aspect;
node.prvr.ymin = dy - (NODE_WIDTH(node) - NODE_DY);
node.runtime->prvr.ymin = dy - (NODE_WIDTH(node) - NODE_DY);
node.prvr.xmin += 0.5f * dx;
node.prvr.xmax -= 0.5f * dx;
node.runtime->prvr.xmin += 0.5f * dx;
node.runtime->prvr.xmax -= 0.5f * dx;
}
dy = node.prvr.ymin - NODE_DYS / 2;
dy = node.runtime->prvr.ymin - NODE_DYS / 2;
/* Make sure that maximums are bigger or equal to minimums. */
if (node.prvr.xmax < node.prvr.xmin) {
SWAP(float, node.prvr.xmax, node.prvr.xmin);
if (node.runtime->prvr.xmax < node.runtime->prvr.xmin) {
SWAP(float, node.runtime->prvr.xmax, node.runtime->prvr.xmin);
}
if (node.prvr.ymax < node.prvr.ymin) {
SWAP(float, node.prvr.ymax, node.prvr.ymin);
if (node.runtime->prvr.ymax < node.runtime->prvr.ymin) {
SWAP(float, node.runtime->prvr.ymax, node.runtime->prvr.ymin);
}
}
@ -564,18 +564,18 @@ static void node_update_basis(const bContext &C,
dy -= NODE_DYS / 2;
}
node.totr.xmin = loc.x;
node.totr.xmax = loc.x + NODE_WIDTH(node);
node.totr.ymax = loc.y;
node.totr.ymin = min_ff(dy, loc.y - 2 * NODE_DY);
node.runtime->totr.xmin = loc.x;
node.runtime->totr.xmax = loc.x + NODE_WIDTH(node);
node.runtime->totr.ymax = loc.y;
node.runtime->totr.ymin = min_ff(dy, loc.y - 2 * NODE_DY);
/* Set the block bounds to clip mouse events from underlying nodes.
* Add a margin for sockets on each side. */
UI_block_bounds_set_explicit(&block,
node.totr.xmin - NODE_SOCKSIZE,
node.totr.ymin,
node.totr.xmax + NODE_SOCKSIZE,
node.totr.ymax);
node.runtime->totr.xmin - NODE_SOCKSIZE,
node.runtime->totr.ymin,
node.runtime->totr.xmax + NODE_SOCKSIZE,
node.runtime->totr.ymax);
}
/**
@ -609,10 +609,10 @@ static void node_update_hidden(bNode &node, uiBlock &block)
hiddenrad += 5.0f * float(tot - 4);
}
node.totr.xmin = loc.x;
node.totr.xmax = loc.x + max_ff(NODE_WIDTH(node), 2 * hiddenrad);
node.totr.ymax = loc.y + (hiddenrad - 0.5f * NODE_DY);
node.totr.ymin = node.totr.ymax - 2 * hiddenrad;
node.runtime->totr.xmin = loc.x;
node.runtime->totr.xmax = loc.x + max_ff(NODE_WIDTH(node), 2 * hiddenrad);
node.runtime->totr.ymax = loc.y + (hiddenrad - 0.5f * NODE_DY);
node.runtime->totr.ymin = node.runtime->totr.ymax - 2 * hiddenrad;
/* Output sockets. */
float rad = float(M_PI) / (1.0f + float(totout));
@ -621,8 +621,8 @@ static void node_update_hidden(bNode &node, uiBlock &block)
LISTBASE_FOREACH (bNodeSocket *, socket, &node.outputs) {
if (!nodeSocketIsHidden(socket)) {
/* Round the socket location to stop it from jiggling. */
socket->locx = round(node.totr.xmax - hiddenrad + sinf(rad) * hiddenrad);
socket->locy = round(node.totr.ymin + hiddenrad + cosf(rad) * hiddenrad);
socket->locx = round(node.runtime->totr.xmax - hiddenrad + sinf(rad) * hiddenrad);
socket->locy = round(node.runtime->totr.ymin + hiddenrad + cosf(rad) * hiddenrad);
rad += drad;
}
}
@ -633,8 +633,8 @@ static void node_update_hidden(bNode &node, uiBlock &block)
LISTBASE_FOREACH (bNodeSocket *, socket, &node.inputs) {
if (!nodeSocketIsHidden(socket)) {
/* Round the socket location to stop it from jiggling. */
socket->locx = round(node.totr.xmin + hiddenrad + sinf(rad) * hiddenrad);
socket->locy = round(node.totr.ymin + hiddenrad + cosf(rad) * hiddenrad);
socket->locx = round(node.runtime->totr.xmin + hiddenrad + sinf(rad) * hiddenrad);
socket->locy = round(node.runtime->totr.ymin + hiddenrad + cosf(rad) * hiddenrad);
rad += drad;
}
}
@ -642,10 +642,10 @@ static void node_update_hidden(bNode &node, uiBlock &block)
/* Set the block bounds to clip mouse events from underlying nodes.
* Add a margin for sockets on each side. */
UI_block_bounds_set_explicit(&block,
node.totr.xmin - NODE_SOCKSIZE,
node.totr.ymin,
node.totr.xmax + NODE_SOCKSIZE,
node.totr.ymax);
node.runtime->totr.xmin - NODE_SOCKSIZE,
node.runtime->totr.ymin,
node.runtime->totr.xmax + NODE_SOCKSIZE,
node.runtime->totr.ymax);
}
static int node_get_colorid(TreeDrawContext &tree_draw_ctx, const bNode &node)
@ -1375,7 +1375,7 @@ static void node_draw_shadow(const SpaceNode &snode,
const float radius,
const float alpha)
{
const rctf &rct = node.totr;
const rctf &rct = node.runtime->totr;
UI_draw_roundbox_corner_set(UI_CNR_ALL);
ui_draw_dropshadow(&rct, radius, snode.runtime->aspect, alpha, node.flag & SELECT);
}
@ -2002,7 +2002,7 @@ static void node_draw_extra_info_panel(TreeDrawContext &tree_draw_ctx,
return;
}
const rctf &rct = node.totr;
const rctf &rct = node.runtime->totr;
float color[4];
rctf extra_info_rect;
@ -2063,7 +2063,7 @@ static void node_draw_basis(const bContext &C,
const float iconbutw = NODE_HEADER_ICON_SIZE;
/* Skip if out of view. */
if (BLI_rctf_isect(&node.totr, &v2d.cur, nullptr) == false) {
if (BLI_rctf_isect(&node.runtime->totr, &v2d.cur, nullptr) == false) {
UI_block_end(&C, &block);
return;
}
@ -2071,7 +2071,7 @@ static void node_draw_basis(const bContext &C,
/* Shadow. */
node_draw_shadow(snode, node, BASIS_RAD, 1.0f);
const rctf &rct = node.totr;
const rctf &rct = node.runtime->totr;
float color[4];
int color_id = node_get_colorid(tree_draw_ctx, node);
@ -2360,8 +2360,8 @@ static void node_draw_basis(const bContext &C,
if (node.flag & NODE_PREVIEW && previews) {
bNodePreview *preview = (bNodePreview *)BKE_node_instance_hash_lookup(previews, key);
if (preview && (preview->xsize && preview->ysize)) {
if (preview->rect && !BLI_rctf_is_empty(&node.prvr)) {
node_draw_preview(preview, &node.prvr);
if (preview->rect && !BLI_rctf_is_empty(&node.runtime->prvr)) {
node_draw_preview(preview, &node.runtime->prvr);
}
}
}
@ -2378,7 +2378,7 @@ static void node_draw_hidden(const bContext &C,
bNode &node,
uiBlock &block)
{
const rctf &rct = node.totr;
const rctf &rct = node.runtime->totr;
float centy = BLI_rctf_cent_y(&rct);
float hiddenrad = BLI_rctf_size_y(&rct) / 2.0f;
@ -2581,7 +2581,7 @@ void node_set_cursor(wmWindow &win, SpaceNode &snode, const float2 &cursor)
/* Check nodes front to back. */
for (node = (bNode *)ntree->nodes.last; node; node = node->prev) {
if (BLI_rctf_isect_pt(&node->totr, cursor[0], cursor[1])) {
if (BLI_rctf_isect_pt(&node->runtime->totr, cursor[0], cursor[1])) {
break; /* First hit on node stops. */
}
}
@ -2651,7 +2651,7 @@ static void frame_node_prepare_for_draw(bNode &node, Span<bNode *> nodes)
}
/* add margin to node rect */
rctf noderect = tnode->totr;
rctf noderect = tnode->runtime->totr;
noderect.xmin -= margin;
noderect.xmax += margin;
noderect.ymin -= margin;
@ -2676,7 +2676,7 @@ static void frame_node_prepare_for_draw(bNode &node, Span<bNode *> nodes)
node.width = max.x - node.offsetx;
node.height = -max.y + node.offsety;
node.totr = rect;
node.runtime->totr = rect;
}
static void reroute_node_prepare_for_draw(bNode &node)
@ -2695,10 +2695,10 @@ static void reroute_node_prepare_for_draw(bNode &node)
const float size = 8.0f;
node.width = size * 2;
node.totr.xmin = loc.x - size;
node.totr.xmax = loc.x + size;
node.totr.ymax = loc.y + size;
node.totr.ymin = loc.y - size;
node.runtime->totr.xmin = loc.x - size;
node.runtime->totr.xmax = loc.x + size;
node.runtime->totr.ymax = loc.y + size;
node.runtime->totr.ymin = loc.y - size;
}
static void node_update_nodetree(const bContext &C,
@ -2773,7 +2773,7 @@ static void frame_node_draw_label(TreeDrawContext &tree_draw_ctx,
const int label_height = ((margin / aspect) + (ascender * aspect));
/* 'x' doesn't need aspect correction */
const rctf &rct = node.totr;
const rctf &rct = node.runtime->totr;
/* XXX a bit hacky, should use separate align values for x and y */
float x = BLI_rctf_cent_x(&rct) - (0.5f * width);
float y = rct.ymax - label_height;
@ -2839,7 +2839,7 @@ static void frame_node_draw(const bContext &C,
uiBlock &block)
{
/* skip if out of view */
if (BLI_rctf_isect(&node.totr, &region.v2d.cur, nullptr) == false) {
if (BLI_rctf_isect(&node.runtime->totr, &region.v2d.cur, nullptr) == false) {
UI_block_end(&C, &block);
return;
}
@ -2859,7 +2859,7 @@ static void frame_node_draw(const bContext &C,
UI_GetThemeColor4fv(TH_NODE_FRAME, color);
}
const rctf &rct = node.totr;
const rctf &rct = node.runtime->totr;
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_4fv(&rct, true, BASIS_RAD, color);
@ -2888,11 +2888,11 @@ static void reroute_node_draw(
const bContext &C, ARegion &region, bNodeTree &ntree, bNode &node, uiBlock &block)
{
char showname[128]; /* 128 used below */
const rctf &rct = node.totr;
const rctf &rct = node.runtime->totr;
/* skip if out of view */
if (rct.xmax < region.v2d.cur.xmin || rct.xmin > region.v2d.cur.xmax ||
rct.ymax < region.v2d.cur.ymin || node.totr.ymin > region.v2d.cur.ymax) {
rct.ymax < region.v2d.cur.ymin || node.runtime->totr.ymin > region.v2d.cur.ymax) {
UI_block_end(&C, &block);
return;
}
@ -2901,8 +2901,8 @@ static void reroute_node_draw(
/* draw title (node label) */
BLI_strncpy(showname, node.label, sizeof(showname));
const short width = 512;
const int x = BLI_rctf_cent_x(&node.totr) - (width / 2);
const int y = node.totr.ymax;
const int x = BLI_rctf_cent_x(&node.runtime->totr) - (width / 2);
const int y = node.runtime->totr.ymax;
uiBut *label_but = uiDefBut(&block,
UI_BTYPE_LABEL,
@ -2977,7 +2977,7 @@ static void node_draw_nodetree(const bContext &C,
#ifdef USE_DRAW_TOT_UPDATE
/* Unrelated to background nodes, update the v2d->tot,
* can be anywhere before we draw the scroll bars. */
BLI_rctf_union(&region.v2d.tot, &nodes[i]->totr);
BLI_rctf_union(&region.v2d.tot, &nodes[i]->runtime->totr);
#endif
if (!(nodes[i]->flag & NODE_BACKGROUND)) {

@ -24,6 +24,7 @@
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_node.h"
#include "BKE_node_runtime.hh"
#include "BKE_node_tree_update.h"
#include "BKE_report.h"
#include "BKE_scene.h"
@ -925,7 +926,7 @@ static bool socket_is_occluded(const float2 &location,
rctf socket_hitbox;
const float socket_hitbox_radius = NODE_SOCKSIZE - 0.1f * U.widget_unit;
BLI_rctf_init_pt_radius(&socket_hitbox, location, socket_hitbox_radius);
if (BLI_rctf_inside_rctf(&node->totr, &socket_hitbox)) {
if (BLI_rctf_inside_rctf(&node->runtime->totr, &socket_hitbox)) {
return true;
}
}
@ -1319,7 +1320,8 @@ bool node_link_is_hidden_or_dimmed(const View2D &v2d, const bNodeLink &link)
/** \name Node Duplicate Operator
* \{ */
static void node_duplicate_reparent_recursive(bNodeTree *ntree, const Map<const bNode *, bNode *> &node_map,
static void node_duplicate_reparent_recursive(bNodeTree *ntree,
const Map<const bNode *, bNode *> &node_map,
bNode *node)
{
bNode *parent;
@ -1935,7 +1937,7 @@ static int node_switch_view_exec(bContext *C, wmOperator * /*op*/)
LISTBASE_FOREACH_MUTABLE (bNode *, node, &snode->edittree->nodes) {
if (node->flag & SELECT) {
/* call the update function from the Switch View node */
node->update = NODE_UPDATE_OPERATOR;
node->runtime->update = NODE_UPDATE_OPERATOR;
}
}
@ -2346,8 +2348,8 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
float2 center = {0.0f, 0.0f};
int num_nodes = 0;
LISTBASE_FOREACH_INDEX (bNode *, node, clipboard_nodes_lb, num_nodes) {
center.x += BLI_rctf_cent_x(&node->totr);
center.y += BLI_rctf_cent_y(&node->totr);
center.x += BLI_rctf_cent_x(&node->runtime->totr);
center.y += BLI_rctf_cent_y(&node->runtime->totr);
}
mul_v2_fl(center, 1.0 / num_nodes);

@ -680,7 +680,7 @@ static bool node_group_make_test_selected(bNodeTree &ntree,
}
}
node->done = 0;
node->runtime->done = 0;
}
/* free local pseudo node tree again */
@ -694,14 +694,14 @@ static bool node_group_make_test_selected(bNodeTree &ntree,
* inputs and outputs to a selection */
LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) {
if (node_group_make_use_node(*link->fromnode, gnode)) {
link->tonode->done |= 1;
link->tonode->runtime->done |= 1;
}
if (node_group_make_use_node(*link->tonode, gnode)) {
link->fromnode->done |= 2;
link->fromnode->runtime->done |= 2;
}
}
LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
if (!(node->flag & NODE_SELECT) && node != gnode && node->done == 3) {
if (!(node->flag & NODE_SELECT) && node != gnode && node->runtime->done == 3) {
return false;
}
}

@ -1642,31 +1642,31 @@ static void node_join_attach_recursive(bNodeTree &ntree,
bNode *frame,
const Set<bNode *> &selected_nodes)
{
node->done |= NODE_JOIN_DONE;
node->runtime->done |= NODE_JOIN_DONE;
if (node == frame) {
node->done |= NODE_JOIN_IS_DESCENDANT;
node->runtime->done |= NODE_JOIN_IS_DESCENDANT;
}
else if (node->parent) {
/* call recursively */
if (!(node->parent->done & NODE_JOIN_DONE)) {
if (!(node->parent->runtime->done & NODE_JOIN_DONE)) {
node_join_attach_recursive(ntree, node->parent, frame, selected_nodes);
}
/* in any case: if the parent is a descendant, so is the child */
if (node->parent->done & NODE_JOIN_IS_DESCENDANT) {
node->done |= NODE_JOIN_IS_DESCENDANT;
if (node->parent->runtime->done & NODE_JOIN_IS_DESCENDANT) {
node->runtime->done |= NODE_JOIN_IS_DESCENDANT;
}
else if (selected_nodes.contains(node)) {
/* if parent is not an descendant of the frame, reattach the node */
nodeDetachNode(&ntree, node);
nodeAttachNode(&ntree, node, frame);
node->done |= NODE_JOIN_IS_DESCENDANT;
node->runtime->done |= NODE_JOIN_IS_DESCENDANT;
}
}
else if (selected_nodes.contains(node)) {
nodeAttachNode(&ntree, node, frame);
node->done |= NODE_JOIN_IS_DESCENDANT;
node->runtime->done |= NODE_JOIN_IS_DESCENDANT;
}
}
@ -1683,11 +1683,11 @@ static int node_join_exec(bContext *C, wmOperator * /*op*/)
/* reset tags */
LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
node->done = 0;
node->runtime->done = 0;
}
LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
if (!(node->done & NODE_JOIN_DONE)) {
if (!(node->runtime->done & NODE_JOIN_DONE)) {
node_join_attach_recursive(ntree, node, frame_node, selected_nodes);
}
}
@ -1733,7 +1733,7 @@ static bNode *node_find_frame_to_attach(ARegion &region,
if ((frame->type != NODE_FRAME) || (frame->flag & NODE_SELECT)) {
continue;
}
if (BLI_rctf_isect_pt_v(&frame->totr, cursor)) {
if (BLI_rctf_isect_pt_v(&frame->runtime->totr, cursor)) {
return frame;
}
}
@ -1817,26 +1817,26 @@ void NODE_OT_attach(wmOperatorType *ot)
static void node_detach_recursive(bNodeTree &ntree, bNode *node)
{
node->done |= NODE_DETACH_DONE;
node->runtime->done |= NODE_DETACH_DONE;
if (node->parent) {
/* call recursively */
if (!(node->parent->done & NODE_DETACH_DONE)) {
if (!(node->parent->runtime->done & NODE_DETACH_DONE)) {
node_detach_recursive(ntree, node->parent);
}
/* in any case: if the parent is a descendant, so is the child */
if (node->parent->done & NODE_DETACH_IS_DESCENDANT) {
node->done |= NODE_DETACH_IS_DESCENDANT;
if (node->parent->runtime->done & NODE_DETACH_IS_DESCENDANT) {
node->runtime->done |= NODE_DETACH_IS_DESCENDANT;
}
else if (node->flag & NODE_SELECT) {
/* if parent is not a descendant of a selected node, detach */
nodeDetachNode(&ntree, node);
node->done |= NODE_DETACH_IS_DESCENDANT;
node->runtime->done |= NODE_DETACH_IS_DESCENDANT;
}
}
else if (node->flag & NODE_SELECT) {
node->done |= NODE_DETACH_IS_DESCENDANT;
node->runtime->done |= NODE_DETACH_IS_DESCENDANT;
}
}
@ -1848,13 +1848,13 @@ static int node_detach_exec(bContext *C, wmOperator * /*op*/)
/* reset tags */
LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
node->done = 0;
node->runtime->done = 0;
}
/* detach nodes recursively
* relative order is preserved here!
*/
LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
if (!(node->done & NODE_DETACH_DONE)) {
if (!(node->runtime->done & NODE_DETACH_DONE)) {
node_detach_recursive(ntree, node);
}
}
@ -1946,10 +1946,11 @@ void node_insert_on_link_flags_set(SpaceNode &snode, const ARegion &region)
* upper left node edge of a intersected line segment */
for (int i = 0; i < NODE_LINK_RESOL; i++) {
/* Check if the node rectangle intersects the line from this point to next one. */
if (BLI_rctf_isect_segment(&node_to_insert->totr, coords[i], coords[i + 1])) {
if (BLI_rctf_isect_segment(&node_to_insert->runtime->totr, coords[i], coords[i + 1])) {
/* store the shortest distance to the upper left edge
* of all intersections found so far */
const float node_xy[] = {node_to_insert->totr.xmin, node_to_insert->totr.ymax};
const float node_xy[] = {node_to_insert->runtime->totr.xmin,
node_to_insert->runtime->totr.ymax};
/* to be precise coords should be clipped by select->totr,
* but not done since there's no real noticeable difference */
@ -2156,8 +2157,8 @@ static void node_offset_apply(bNode &node, const float offset_x)
{
/* NODE_TEST is used to flag nodes that shouldn't be offset (again) */
if ((node.flag & NODE_TEST) == 0) {
node.anim_init_locx = node.locx;
node.anim_ofsx = (offset_x / UI_DPI_FAC);
node.runtime->anim_init_locx = node.locx;
node.runtime->anim_ofsx = (offset_x / UI_DPI_FAC);
node.flag |= NODE_TEST;
}
}
@ -2263,7 +2264,8 @@ static void node_link_insert_offset_ntree(NodeInsertOfsData *iofsd,
const float min_margin = U.node_margin * UI_DPI_FAC;
const float width = NODE_WIDTH(insert);
const bool needs_alignment = (next->totr.xmin - prev->totr.xmax) < (width + (min_margin * 2.0f));
const bool needs_alignment = (next->runtime->totr.xmin - prev->runtime->totr.xmax) <
(width + (min_margin * 2.0f));
float margin = width;
@ -2312,8 +2314,8 @@ static void node_link_insert_offset_ntree(NodeInsertOfsData *iofsd,
/* *** ensure offset at the left (or right for right_alignment case) of insert_node *** */
float dist = right_alignment ? totr_insert.xmin - prev->totr.xmax :
next->totr.xmin - totr_insert.xmax;
float dist = right_alignment ? totr_insert.xmin - prev->runtime->totr.xmax :
next->runtime->totr.xmin - totr_insert.xmax;
/* distance between insert_node and prev is smaller than min margin */
if (dist < min_margin) {
const float addval = (min_margin - dist) * (right_alignment ? 1.0f : -1.0f);
@ -2327,7 +2329,8 @@ static void node_link_insert_offset_ntree(NodeInsertOfsData *iofsd,
/* *** ensure offset at the right (or left for right_alignment case) of insert_node *** */
dist = right_alignment ? next->totr.xmin - totr_insert.xmax : totr_insert.xmin - prev->totr.xmax;
dist = right_alignment ? next->runtime->totr.xmin - totr_insert.xmax :
totr_insert.xmin - prev->runtime->totr.xmax;
/* distance between insert_node and next is smaller than min margin */
if (dist < min_margin) {
const float addval = (min_margin - dist) * (right_alignment ? 1.0f : -1.0f);
@ -2385,12 +2388,14 @@ static int node_insert_offset_modal(bContext *C, wmOperator *op, const wmEvent *
/* handle animation - do this before possibly aborting due to duration, since
* main thread might be so busy that node hasn't reached final position yet */
LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
if (UNLIKELY(node->anim_ofsx)) {
const float endval = node->anim_init_locx + node->anim_ofsx;
if (UNLIKELY(node->runtime->anim_ofsx)) {
const float endval = node->runtime->anim_init_locx + node->runtime->anim_ofsx;
if (IS_EQF(node->locx, endval) == false) {
node->locx = BLI_easing_cubic_ease_in_out(
duration, node->anim_init_locx, node->anim_ofsx, NODE_INSOFS_ANIM_DURATION);
if (node->anim_ofsx < 0) {
node->locx = BLI_easing_cubic_ease_in_out(duration,
node->runtime->anim_init_locx,
node->runtime->anim_ofsx,
NODE_INSOFS_ANIM_DURATION);
if (node->runtime->anim_ofsx < 0) {
CLAMP_MIN(node->locx, endval);
}
else {
@ -2409,7 +2414,7 @@ static int node_insert_offset_modal(bContext *C, wmOperator *op, const wmEvent *
WM_event_remove_timer(CTX_wm_manager(C), nullptr, iofsd->anim_timer);
LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
node->anim_init_locx = node->anim_ofsx = 0.0f;
node->runtime->anim_init_locx = node->runtime->anim_ofsx = 0.0f;
}
MEM_freeN(iofsd);

@ -91,10 +91,10 @@ rctf node_frame_rect_inside(const bNode &node)
{
const float margin = 1.5f * U.widget_unit;
rctf frame_inside = {
node.totr.xmin,
node.totr.xmax,
node.totr.ymin,
node.totr.ymax,
node.runtime->totr.xmin,
node.runtime->totr.xmax,
node.runtime->totr.ymin,
node.runtime->totr.ymax,
};
BLI_rctf_pad(&frame_inside, -margin, -margin);
@ -112,7 +112,7 @@ static bool node_frame_select_isect_mouse(const bNode &node, const float2 &mouse
/* Frame nodes are selectable by their borders (including their whole rect - as for other nodes -
* would prevent e.g. box selection of nodes inside that frame). */
const rctf frame_inside = node_frame_rect_inside(node);
if (BLI_rctf_isect_pt(&node.totr, mouse.x, mouse.y) &&
if (BLI_rctf_isect_pt(&node.runtime->totr, mouse.x, mouse.y) &&
!BLI_rctf_isect_pt(&frame_inside, mouse.x, mouse.y)) {
return true;
}
@ -131,7 +131,7 @@ static bNode *node_under_mouse_select(bNodeTree &ntree, const float2 mouse)
break;
}
default: {
if (BLI_rctf_isect_pt(&node->totr, int(mouse.x), int(mouse.y))) {
if (BLI_rctf_isect_pt(&node->runtime->totr, int(mouse.x), int(mouse.y))) {
return node;
}
break;
@ -159,7 +159,7 @@ static bool node_under_mouse_tweak(const bNodeTree &ntree, const float2 &mouse)
break;
}
default: {
if (BLI_rctf_isect_pt(&node->totr, mouse.x, mouse.y)) {
if (BLI_rctf_isect_pt(&node->runtime->totr, mouse.x, mouse.y)) {
return true;
}
break;
@ -779,7 +779,7 @@ static int node_box_select_exec(bContext *C, wmOperator *op)
/* Frame nodes are selectable by their borders (including their whole rect - as for other
* nodes - would prevent selection of other nodes inside that frame. */
const rctf frame_inside = node_frame_rect_inside(*node);
if (BLI_rctf_isect(&rectf, &node->totr, nullptr) &&
if (BLI_rctf_isect(&rectf, &node->runtime->totr, nullptr) &&
!BLI_rctf_inside_rctf(&frame_inside, &rectf)) {
nodeSetSelected(node, select);
is_inside = true;
@ -787,7 +787,7 @@ static int node_box_select_exec(bContext *C, wmOperator *op)
break;
}
default: {
is_inside = BLI_rctf_isect(&rectf, &node->totr, nullptr);
is_inside = BLI_rctf_isect(&rectf, &node->runtime->totr, nullptr);
break;
}
}
@ -884,14 +884,14 @@ static int node_circleselect_exec(bContext *C, wmOperator *op)
rctf frame_inside = node_frame_rect_inside(*node);
const float radius_adjusted = float(radius) / zoom;
BLI_rctf_pad(&frame_inside, -2.0f * radius_adjusted, -2.0f * radius_adjusted);
if (BLI_rctf_isect_circle(&node->totr, offset, radius_adjusted) &&
if (BLI_rctf_isect_circle(&node->runtime->totr, offset, radius_adjusted) &&
!BLI_rctf_isect_circle(&frame_inside, offset, radius_adjusted)) {
nodeSetSelected(node, select);
}
break;
}
default: {
if (BLI_rctf_isect_circle(&node->totr, offset, radius / zoom)) {
if (BLI_rctf_isect_circle(&node->runtime->totr, offset, radius / zoom)) {
nodeSetSelected(node, select);
}
break;
@ -980,7 +980,7 @@ static bool do_lasso_select_node(bContext *C,
BLI_rctf_rcti_copy(&rectf, &rect);
UI_view2d_region_to_view_rctf(&region->v2d, &rectf, &rectf);
const rctf frame_inside = node_frame_rect_inside(*node);
if (BLI_rctf_isect(&rectf, &node->totr, nullptr) &&
if (BLI_rctf_isect(&rectf, &node->runtime->totr, nullptr) &&
!BLI_rctf_inside_rctf(&frame_inside, &rectf)) {
nodeSetSelected(node, select);
changed = true;
@ -989,7 +989,8 @@ static bool do_lasso_select_node(bContext *C,
}
default: {
int2 screen_co;
const float2 center = {BLI_rctf_cent_x(&node->totr), BLI_rctf_cent_y(&node->totr)};
const float2 center = {BLI_rctf_cent_x(&node->runtime->totr),
BLI_rctf_cent_y(&node->runtime->totr)};
/* marker in screen coords */
if (UI_view2d_view_to_region_clip(
@ -1303,8 +1304,10 @@ static int node_select_same_type_step_exec(bContext *C, wmOperator *op)
node_select_single(*C, *active);
/* is note outside view? */
if (active->totr.xmax < region->v2d.cur.xmin || active->totr.xmin > region->v2d.cur.xmax ||
active->totr.ymax < region->v2d.cur.ymin || active->totr.ymin > region->v2d.cur.ymax) {
if (active->runtime->totr.xmax < region->v2d.cur.xmin ||
active->runtime->totr.xmin > region->v2d.cur.xmax ||
active->runtime->totr.ymax < region->v2d.cur.ymin ||
active->runtime->totr.ymin > region->v2d.cur.ymax) {
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
space_node_view_flag(*C, *snode, *region, NODE_SELECT, smooth_viewtx);
}
@ -1393,8 +1396,10 @@ static void node_find_exec_fn(bContext *C, void * /*arg1*/, void *arg2)
node_select_single(*C, *active);
/* is note outside view? */
if (active->totr.xmax < region->v2d.cur.xmin || active->totr.xmin > region->v2d.cur.xmax ||
active->totr.ymax < region->v2d.cur.ymin || active->totr.ymin > region->v2d.cur.ymax) {
if (active->runtime->totr.xmax < region->v2d.cur.xmin ||
active->runtime->totr.xmin > region->v2d.cur.xmax ||
active->runtime->totr.ymax < region->v2d.cur.ymin ||
active->runtime->totr.ymin > region->v2d.cur.ymax) {
space_node_view_flag(*C, *snode, *region, NODE_SELECT, U.smooth_viewtx);
}
}

@ -16,6 +16,7 @@
#include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_node.h"
#include "BKE_node_runtime.hh"
#include "BKE_screen.h"
#include "ED_image.h"
@ -61,7 +62,7 @@ bool space_node_view_flag(
if (snode.edittree) {
LISTBASE_FOREACH (const bNode *, node, &snode.edittree->nodes) {
if ((node->flag & node_flag) == node_flag) {
BLI_rctf_union(&cur_new, &node->totr);
BLI_rctf_union(&cur_new, &node->runtime->totr);
tot++;
if (node->type == NODE_FRAME) {

@ -55,8 +55,8 @@ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node, const
/* use top-left corner as the transform origin for nodes */
/* Weirdo - but the node system is a mix of free 2d elements and DPI sensitive UI. */
#ifdef USE_NODE_CENTER
td2d->loc[0] = (locx * dpi_fac) + (BLI_rctf_size_x(&node->totr) * +0.5f);
td2d->loc[1] = (locy * dpi_fac) + (BLI_rctf_size_y(&node->totr) * -0.5f);
td2d->loc[0] = (locx * dpi_fac) + (BLI_rctf_size_x(&node->runtime->totr) * +0.5f);
td2d->loc[1] = (locy * dpi_fac) + (BLI_rctf_size_y(&node->runtime->totr) * -0.5f);
#else
td2d->loc[0] = locx * dpi_fac;
td2d->loc[1] = locy * dpi_fac;
@ -246,8 +246,8 @@ static void flushTransNodes(TransInfo *t)
add_v2_v2v2(loc, td2d->loc, offset);
#ifdef USE_NODE_CENTER
loc[0] -= 0.5f * BLI_rctf_size_x(&node->totr);
loc[1] += 0.5f * BLI_rctf_size_y(&node->totr);
loc[0] -= 0.5f * BLI_rctf_size_x(&node->runtime->totr);
loc[1] += 0.5f * BLI_rctf_size_y(&node->runtime->totr);
#endif
/* Weirdo - but the node system is a mix of free 2d elements and DPI sensitive UI. */

@ -22,6 +22,7 @@
#include "BKE_context.h"
#include "BKE_editmesh.h"
#include "BKE_layer.h"
#include "BKE_node_runtime.hh"
#include "BKE_object.h"
#include "BKE_scene.h"
@ -1180,8 +1181,8 @@ static void TargetSnapOffset(TransInfo *t, TransData *td)
if (t->spacetype == SPACE_NODE && td != nullptr) {
bNode *node = static_cast<bNode *>(td->extra);
char border = t->tsnap.snapNodeBorder;
float width = BLI_rctf_size_x(&node->totr);
float height = BLI_rctf_size_y(&node->totr);
float width = BLI_rctf_size_x(&node->runtime->totr);
float height = BLI_rctf_size_y(&node->runtime->totr);
#ifdef USE_NODE_CENTER
if (border & NODE_LEFT) {
@ -1467,8 +1468,8 @@ static bool snapNodeTest(View2D *v2d, bNode *node, eSnapTargetSelect snap_target
/* node is use for snapping only if a) snap mode matches and b) node is inside the view */
return (((snap_target_select & SCE_SNAP_TARGET_NOT_SELECTED) && !(node->flag & NODE_SELECT)) ||
(snap_target_select == SCE_SNAP_TARGET_ALL && !(node->flag & NODE_ACTIVE))) &&
(node->totr.xmin < v2d->cur.xmax && node->totr.xmax > v2d->cur.xmin &&
node->totr.ymin < v2d->cur.ymax && node->totr.ymax > v2d->cur.ymin);
(node->runtime->totr.xmin < v2d->cur.xmax && node->runtime->totr.xmax > v2d->cur.xmin &&
node->runtime->totr.ymin < v2d->cur.ymax && node->runtime->totr.ymax > v2d->cur.ymin);
}
static NodeBorder snapNodeBorder(eSnapMode snap_node_mode)
@ -1498,7 +1499,7 @@ static bool snapNode(ToolSettings *ts,
rcti totr;
int new_dist;
UI_view2d_view_to_region_rcti(v2d, &node->totr, &totr);
UI_view2d_view_to_region_rcti(v2d, &node->runtime->totr, &totr);
if (border & NODE_LEFT) {
new_dist = abs(totr.xmin - mval[0]);

@ -307,12 +307,8 @@ typedef struct bNode {
char name[64];
int flag;
short type;
/** Both for dependency and sorting. */
short done, level;
/** Used as a boolean for execution. */
uint8_t need_exec;
char _pad2[1];
char _pad2[6];
/** Custom user-defined color. */
float color[3];
@ -324,8 +320,6 @@ typedef struct bNode {
struct ID *id;
/** Custom data, must be struct, for storage in file. */
void *storage;
/** The original node in the tree (for localized tree). */
struct bNode *original;
/** List of cached internal links (input to output), for muted nodes and operators. */
ListBase internal_links;
@ -333,17 +327,10 @@ typedef struct bNode {
float locx, locy;
/** Node custom width and height. */
float width, height;
/** Node width if hidden. */
float miniwidth;
/** Additional offset from loc. */
float offsetx, offsety;
/** Initial locx for insert offset animation. */
float anim_init_locx;
/** Offset that will be added to locx for insert offset animation. */
float anim_ofsx;
/** Update flags. */
int update;
char _pad0[4];
/** Custom user-defined label, MAX_NAME. */
char label[64];
@ -351,30 +338,6 @@ typedef struct bNode {
short custom1, custom2;
float custom3, custom4;
char _pad1[4];
/** Entire bound-box (world-space). */
rctf totr;
/** Optional preview area. */
rctf prvr;
/**
* XXX TODO
* Node totr size depends on the prvr size, which in turn is determined from preview size.
* In earlier versions bNodePreview was stored directly in nodes, but since now there can be
* multiple instances using different preview images it is possible that required node size
* varies between instances. preview_xsize, preview_ysize defines a common reserved size for
* preview rect for now, could be replaced by more accurate node instance drawing,
* but that requires removing totr from DNA and replacing all uses with per-instance data.
*/
/** Reserved size of the preview rect. */
short preview_xsize, preview_ysize;
/** Used at runtime when going through the tree. Initialize before use. */
short tmp_flag;
char _pad0;
/** Used at runtime when iterating over node branches. */
char iter_flag;
bNodeRuntimeHandle *runtime;
#ifdef __cplusplus

@ -49,6 +49,8 @@
#include "RE_texture.h"
#include "NOD_composite.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
@ -2620,6 +2622,15 @@ static void rna_Node_width_range(
*max = *softmax = node->typeinfo->maxwidth;
}
static void rna_Node_width_hidden_set(PointerRNA *UNUSED(ptr), float UNUSED(value))
{
}
static float rna_Node_width_hidden_get(PointerRNA *UNUSED(ptr))
{
return 0.0f;
}
static void rna_Node_height_range(
PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
{
@ -2631,8 +2642,7 @@ static void rna_Node_height_range(
static void rna_Node_dimensions_get(PointerRNA *ptr, float *value)
{
bNode *node = ptr->data;
value[0] = node->totr.xmax - node->totr.xmin;
value[1] = node->totr.ymax - node->totr.ymin;
nodeDimensionsGet(node, &value[0], &value[1]);
}
/* ******** Node Socket ******** */
@ -3473,7 +3483,7 @@ static StructRNA *rna_CompositorNodeCustomGroup_register(Main *bmain,
static void rna_CompositorNode_tag_need_exec(bNode *node)
{
node->need_exec = true;
ntreeCompositTagNeedExec(node);
}
static void rna_Node_tex_image_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
@ -3904,7 +3914,7 @@ static void rna_Image_Node_update_id(Main *bmain, Scene *scene, PointerRNA *ptr)
{
bNode *node = (bNode *)ptr->data;
node->update |= NODE_UPDATE_ID;
nodeTagUpdateID(node);
rna_Node_update(bmain, scene, ptr);
}
@ -12189,10 +12199,11 @@ static void rna_def_node(BlenderRNA *brna)
RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL);
prop = RNA_def_property(srna, "width_hidden", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "miniwidth");
RNA_def_property_float_funcs(prop, NULL, NULL, "rna_Node_width_range");
RNA_def_property_ui_text(prop, "Width Hidden", "Width of the node in hidden state");
RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL);
RNA_def_property_float_funcs(
prop, "rna_Node_width_hidden_get", "rna_Node_width_hidden_set", "rna_Node_width_range");
RNA_def_property_ui_text(
prop, "Width Hidden", "Deprecated width of the node when it is collapsed");
RNA_def_property_update(prop, 0, NULL);
prop = RNA_def_property(srna, "height", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "height");

@ -153,6 +153,8 @@ void ntreeCompositExecTree(struct Scene *scene,
*/
void ntreeCompositTagRender(struct Scene *scene);
void ntreeCompositTagNeedExec(bNode *node);
/**
* Update the outputs of the render layer nodes.
* Since the outputs depend on the render engine, this part is a bit complex:

@ -86,8 +86,8 @@ static void localize(bNodeTree *localtree, bNodeTree *ntree)
while (node != nullptr) {
/* Ensure new user input gets handled ok. */
node->need_exec = 0;
local_node->original = node;
node->runtime->need_exec = 0;
local_node->runtime->original = node;
/* move over the compbufs */
/* right after #ntreeCopyTree() `oldsock` pointers are valid */
@ -262,9 +262,14 @@ void ntreeCompositClearTags(bNodeTree *ntree)
}
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
node->need_exec = 0;
node->runtime->need_exec = 0;
if (node->type == NODE_GROUP) {
ntreeCompositClearTags((bNodeTree *)node->id);
}
}
}
void ntreeCompositTagNeedExec(bNode *node)
{
node->runtime->need_exec = true;
}

@ -26,7 +26,7 @@ void cmp_node_update_default(bNodeTree * /*ntree*/, bNode *node)
// sock->cache = nullptr;
}
}
node->need_exec = 1;
node->runtime->need_exec = 1;
}
void cmp_node_type_base(bNodeType *ntype, int type, const char *name, short nclass)

@ -397,7 +397,7 @@ namespace blender::nodes::node_composite_image_cc {
static void cmp_node_image_update(bNodeTree *ntree, bNode *node)
{
/* avoid unnecessary updates, only changes to the image/image user data are of interest */
if (node->update & NODE_UPDATE_ID) {
if (node->runtime->update & NODE_UPDATE_ID) {
cmp_node_image_verify_outputs(ntree, node, false);
}

@ -48,7 +48,7 @@ static void cmp_node_switch_view_update(bNodeTree *ntree, bNode *node)
Scene *scene = (Scene *)node->id;
/* only update when called from the operator button */
if (node->update != NODE_UPDATE_OPERATOR) {
if (node->runtime->update != NODE_UPDATE_OPERATOR) {
return;
}

@ -12,6 +12,7 @@
#include "BKE_global.h"
#include "BKE_node.h"
#include "BKE_node_runtime.hh"
#include "BKE_node_tree_update.h"
#include "MEM_guardedalloc.h"
@ -209,7 +210,7 @@ bNodeTreeExec *ntree_exec_begin(bNodeExecContext *context,
for (sock = (bNodeSocket *)node->inputs.first; sock; sock = sock->next) {
/* disable the node if an input link is invalid */
if (sock->link && !(sock->link->flag & NODE_LINK_VALID)) {
node->need_exec = 0;
node->runtime->need_exec = 0;
}
ns = setup_stack(exec->stack, ntree, node, sock);

@ -30,6 +30,7 @@
#include "BKE_lib_id.h"
#include "BKE_linestyle.h"
#include "BKE_node.h"
#include "BKE_node_runtime.hh"
#include "BKE_node_tree_update.h"
#include "BKE_scene.h"
@ -540,12 +541,14 @@ struct branchIterData {
static bool ntree_branch_count_and_tag_nodes(bNode *fromnode, bNode *tonode, void *userdata)
{
branchIterData *iter = (branchIterData *)userdata;
if (fromnode->tmp_flag == -1 && (iter->node_filter == nullptr || iter->node_filter(fromnode))) {
fromnode->tmp_flag = iter->node_count;
if (fromnode->runtime->tmp_flag == -1 &&
(iter->node_filter == nullptr || iter->node_filter(fromnode))) {
fromnode->runtime->tmp_flag = iter->node_count;
iter->node_count++;
}
if (tonode->tmp_flag == -1 && (iter->node_filter == nullptr || iter->node_filter(tonode))) {
tonode->tmp_flag = iter->node_count;
if (tonode->runtime->tmp_flag == -1 &&
(iter->node_filter == nullptr || iter->node_filter(tonode))) {
tonode->runtime->tmp_flag = iter->node_count;
iter->node_count++;
}
return true;
@ -560,12 +563,12 @@ static bNode *ntree_shader_copy_branch(bNodeTree *ntree,
void (*callback)(bNode *node, int user_data),
int user_data)
{
/* Initialize `tmp_flag`. */
/* Initialize `runtime->tmp_flag`. */
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
node->tmp_flag = -1;
node->runtime->tmp_flag = -1;
}
/* Count and tag all nodes inside the displacement branch of the tree. */
start_node->tmp_flag = 0;
start_node->runtime->tmp_flag = 0;
branchIterData iter_data;
iter_data.node_filter = node_filter;
iter_data.node_count = 1;
@ -573,11 +576,11 @@ static bNode *ntree_shader_copy_branch(bNodeTree *ntree,
/* Make a full copy of the branch */
Array<bNode *> nodes_copy(iter_data.node_count);
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->tmp_flag >= 0) {
int id = node->tmp_flag;
if (node->runtime->tmp_flag >= 0) {
int id = node->runtime->tmp_flag;
nodes_copy[id] = blender::bke::node_copy(
ntree, *node, LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_CREATE_NO_MAIN, false);
nodes_copy[id]->tmp_flag = -2; /* Copy */
nodes_copy[id]->runtime->tmp_flag = -2; /* Copy */
/* Make sure to clear all sockets links as they are invalid. */
LISTBASE_FOREACH (bNodeSocket *, sock, &nodes_copy[id]->inputs) {
sock->link = nullptr;
@ -589,10 +592,11 @@ static bNode *ntree_shader_copy_branch(bNodeTree *ntree,
}
/* Recreate links between copied nodes AND incoming links to the copied nodes. */
LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
if (link->tonode->tmp_flag >= 0) {
bool from_node_copied = link->fromnode->tmp_flag >= 0;
bNode *fromnode = from_node_copied ? nodes_copy[link->fromnode->tmp_flag] : link->fromnode;
bNode *tonode = nodes_copy[link->tonode->tmp_flag];
if (link->tonode->runtime->tmp_flag >= 0) {
bool from_node_copied = link->fromnode->runtime->tmp_flag >= 0;
bNode *fromnode = from_node_copied ? nodes_copy[link->fromnode->runtime->tmp_flag] :
link->fromnode;
bNode *tonode = nodes_copy[link->tonode->runtime->tmp_flag];
bNodeSocket *fromsock = ntree_shader_node_find_output(fromnode, link->fromsock->identifier);
bNodeSocket *tosock = ntree_shader_node_find_input(tonode, link->tosock->identifier);
nodeAddLink(ntree, fromnode, fromsock, tonode, tosock);
@ -604,7 +608,7 @@ static bNode *ntree_shader_copy_branch(bNodeTree *ntree,
callback(nodes_copy[i], user_data);
}
}
bNode *start_node_copy = nodes_copy[start_node->tmp_flag];
bNode *start_node_copy = nodes_copy[start_node->runtime->tmp_flag];
return start_node_copy;
}
@ -646,7 +650,7 @@ static void ntree_weight_tree_merge_weight(bNodeTree *ntree,
{
bNode *addnode = nodeAddStaticNode(nullptr, ntree, SH_NODE_MATH);
addnode->custom1 = NODE_MATH_ADD;
addnode->tmp_flag = -2; /* Copy */
addnode->runtime->tmp_flag = -2; /* Copy */
bNodeSocket *addsock_out = ntree_shader_node_output_get(addnode, 0);
bNodeSocket *addsock_in0 = ntree_shader_node_input_get(addnode, 0);
bNodeSocket *addsock_in1 = ntree_shader_node_input_get(addnode, 1);
@ -667,12 +671,13 @@ static bool ntree_weight_tree_tag_nodes(bNode *fromnode, bNode *tonode, void *us
SH_NODE_OUTPUT_WORLD,
SH_NODE_OUTPUT_MATERIAL,
SH_NODE_SHADERTORGB);
if (tonode->tmp_flag == -1 && to_node_from_weight_tree) {
tonode->tmp_flag = *node_count;
if (tonode->runtime->tmp_flag == -1 && to_node_from_weight_tree) {
tonode->runtime->tmp_flag = *node_count;
*node_count += (tonode->type == SH_NODE_MIX_SHADER) ? 4 : 1;
}
if (fromnode->tmp_flag == -1 && ELEM(fromnode->type, SH_NODE_ADD_SHADER, SH_NODE_MIX_SHADER)) {
fromnode->tmp_flag = *node_count;
if (fromnode->runtime->tmp_flag == -1 &&
ELEM(fromnode->type, SH_NODE_ADD_SHADER, SH_NODE_MIX_SHADER)) {
fromnode->runtime->tmp_flag = *node_count;
*node_count += (fromnode->type == SH_NODE_MIX_SHADER) ? 4 : 1;
}
return to_node_from_weight_tree;
@ -698,17 +703,17 @@ static void ntree_shader_weight_tree_invert(bNodeTree *ntree, bNode *output_node
}
/* Init tmp flag. */
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
node->tmp_flag = -1;
node->runtime->tmp_flag = -1;
}
/* Tag nodes from the weight tree. Only tag output node and mix/add shader nodes. */
output_node->tmp_flag = 0;
output_node->runtime->tmp_flag = 0;
int node_count = 1;
nodeChainIterBackwards(ntree, output_node, ntree_weight_tree_tag_nodes, &node_count, 0);
/* Make a mirror copy of the weight tree. */
Array<bNode *> nodes_copy(node_count);
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->tmp_flag >= 0) {
int id = node->tmp_flag;
if (node->runtime->tmp_flag >= 0) {
int id = node->runtime->tmp_flag;
switch (node->type) {
case SH_NODE_SHADERTORGB:
@ -717,7 +722,7 @@ static void ntree_shader_weight_tree_invert(bNodeTree *ntree, bNode *output_node
case SH_NODE_OUTPUT_MATERIAL: {
/* Start the tree with full weight. */
nodes_copy[id] = nodeAddStaticNode(nullptr, ntree, SH_NODE_VALUE);
nodes_copy[id]->tmp_flag = -2; /* Copy */
nodes_copy[id]->runtime->tmp_flag = -2; /* Copy */
((bNodeSocketValueFloat *)ntree_shader_node_output_get(nodes_copy[id], 0)->default_value)
->value = 1.0f;
break;
@ -727,7 +732,7 @@ static void ntree_shader_weight_tree_invert(bNodeTree *ntree, bNode *output_node
/* TODO(fclem): Better use some kind of reroute node? */
nodes_copy[id] = nodeAddStaticNode(nullptr, ntree, SH_NODE_MATH);
nodes_copy[id]->custom1 = NODE_MATH_ADD;
nodes_copy[id]->tmp_flag = -2; /* Copy */
nodes_copy[id]->runtime->tmp_flag = -2; /* Copy */
((bNodeSocketValueFloat *)ntree_shader_node_input_get(nodes_copy[id], 0)->default_value)
->value = 0.0f;
break;
@ -740,18 +745,18 @@ static void ntree_shader_weight_tree_invert(bNodeTree *ntree, bNode *output_node
/* output = (factor * input_weight) */
nodes_copy[id] = nodeAddStaticNode(nullptr, ntree, SH_NODE_MATH);
nodes_copy[id]->custom1 = NODE_MATH_MULTIPLY;
nodes_copy[id]->tmp_flag = -2; /* Copy */
nodes_copy[id]->runtime->tmp_flag = -2; /* Copy */
id++;
/* output = ((1.0 - factor) * input_weight) <=> (input_weight - factor * input_weight) */
nodes_copy[id] = nodeAddStaticNode(nullptr, ntree, SH_NODE_MATH);
nodes_copy[id]->custom1 = NODE_MATH_SUBTRACT;
nodes_copy[id]->tmp_flag = -2; /* Copy */
nodes_copy[id]->runtime->tmp_flag = -2; /* Copy */
id++;
/* Node sanitizes the input mix factor by clamping it. */
nodes_copy[id] = nodeAddStaticNode(nullptr, ntree, SH_NODE_MATH);
nodes_copy[id]->custom1 = NODE_MATH_ADD;
nodes_copy[id]->custom2 = SHD_MATH_CLAMP;
nodes_copy[id]->tmp_flag = -2; /* Copy */
nodes_copy[id]->runtime->tmp_flag = -2; /* Copy */
((bNodeSocketValueFloat *)ntree_shader_node_input_get(nodes_copy[id], 0)->default_value)
->value = 0.0f;
/* Copy default value if no link present. */
@ -766,7 +771,7 @@ static void ntree_shader_weight_tree_invert(bNodeTree *ntree, bNode *output_node
/* TODO(fclem): Better use some kind of reroute node? */
nodes_copy[id] = nodeAddStaticNode(nullptr, ntree, SH_NODE_MATH);
nodes_copy[id]->custom1 = NODE_MATH_ADD;
nodes_copy[id]->tmp_flag = -2; /* Copy */
nodes_copy[id]->runtime->tmp_flag = -2; /* Copy */
((bNodeSocketValueFloat *)ntree_shader_node_input_get(nodes_copy[id], 0)->default_value)
->value = 0.0f;
id++;
@ -801,7 +806,7 @@ static void ntree_shader_weight_tree_invert(bNodeTree *ntree, bNode *output_node
}
/* Recreate links between copied nodes. */
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->tmp_flag >= 0) {
if (node->runtime->tmp_flag >= 0) {
/* Naming can be confusing here. We use original nodelink name for from/to prefix.
* The final link is in reversed order. */
int socket_index;
@ -815,24 +820,24 @@ static void ntree_shader_weight_tree_invert(bNodeTree *ntree, bNode *output_node
case SH_NODE_OUTPUT_WORLD:
case SH_NODE_OUTPUT_MATERIAL:
case SH_NODE_ADD_SHADER: {
tonode = nodes_copy[node->tmp_flag];
tonode = nodes_copy[node->runtime->tmp_flag];
tosock = ntree_shader_node_output_get(tonode, 0);
break;
}
case SH_NODE_MIX_SHADER: {
if (socket_index == 0) {
/* Mix Factor. */
tonode = nodes_copy[node->tmp_flag + 2];
tonode = nodes_copy[node->runtime->tmp_flag + 2];
tosock = ntree_shader_node_input_get(tonode, 1);
}
else if (socket_index == 1) {
/* Shader 1. */
tonode = nodes_copy[node->tmp_flag + 1];
tonode = nodes_copy[node->runtime->tmp_flag + 1];
tosock = ntree_shader_node_output_get(tonode, 0);
}
else {
/* Shader 2. */
tonode = nodes_copy[node->tmp_flag];
tonode = nodes_copy[node->runtime->tmp_flag];
tosock = ntree_shader_node_output_get(tonode, 0);
}
break;
@ -848,7 +853,7 @@ static void ntree_shader_weight_tree_invert(bNodeTree *ntree, bNode *output_node
switch (fromnode->type) {
case SH_NODE_ADD_SHADER: {
fromnode = nodes_copy[fromnode->tmp_flag];
fromnode = nodes_copy[fromnode->runtime->tmp_flag];
fromsock = ntree_shader_node_input_get(fromnode, 1);
if (fromsock->link) {
ntree_weight_tree_merge_weight(ntree, fromnode, fromsock, &tonode, &tosock);
@ -856,7 +861,7 @@ static void ntree_shader_weight_tree_invert(bNodeTree *ntree, bNode *output_node
break;
}
case SH_NODE_MIX_SHADER: {
fromnode = nodes_copy[fromnode->tmp_flag + 3];
fromnode = nodes_copy[fromnode->runtime->tmp_flag + 3];
fromsock = ntree_shader_node_input_get(fromnode, 1);
if (fromsock->link) {
ntree_weight_tree_merge_weight(ntree, fromnode, fromsock, &tonode, &tosock);
@ -947,8 +952,8 @@ static bool closure_node_filter(const bNode *node)
static bool shader_to_rgba_node_gather(bNode * /*fromnode*/, bNode *tonode, void *userdata)
{
Vector<bNode *> &shader_to_rgba_nodes = *(Vector<bNode *> *)userdata;
if (tonode->tmp_flag == -1 && tonode->type == SH_NODE_SHADERTORGB) {
tonode->tmp_flag = 0;
if (tonode->runtime->tmp_flag == -1 && tonode->type == SH_NODE_SHADERTORGB) {
tonode->runtime->tmp_flag = 0;
shader_to_rgba_nodes.append(tonode);
}
return true;
@ -958,10 +963,10 @@ static bool shader_to_rgba_node_gather(bNode * /*fromnode*/, bNode *tonode, void
static void ntree_shader_shader_to_rgba_branch(bNodeTree *ntree, bNode *output_node)
{
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
node->tmp_flag = -1;
node->runtime->tmp_flag = -1;
}
/* First gather the shader_to_rgba nodes linked to the output. This is separate to avoid
* conflicting usage of the `node->tmp_flag`. */
* conflicting usage of the `node->runtime->tmp_flag`. */
Vector<bNode *> shader_to_rgba_nodes;
nodeChainIterBackwards(ntree, output_node, shader_to_rgba_node_gather, &shader_to_rgba_nodes, 0);
@ -986,8 +991,8 @@ static void ntree_shader_shader_to_rgba_branch(bNodeTree *ntree, bNode *output_n
static bool ntree_branch_node_tag(bNode *fromnode, bNode *tonode, void * /*userdata*/)
{
fromnode->tmp_flag = 1;
tonode->tmp_flag = 1;
fromnode->runtime->tmp_flag = 1;
tonode->runtime->tmp_flag = 1;
return true;
}
@ -999,23 +1004,23 @@ static void ntree_shader_pruned_unused(bNodeTree *ntree, bNode *output_node)
bool changed = false;
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
node->tmp_flag = 0;
node->runtime->tmp_flag = 0;
}
/* Avoid deleting the output node if it is the only node in the tree. */
output_node->tmp_flag = 1;
output_node->runtime->tmp_flag = 1;
nodeChainIterBackwards(ntree, output_node, ntree_branch_node_tag, nullptr, 0);
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->type == SH_NODE_OUTPUT_AOV) {
node->tmp_flag = 1;
node->runtime->tmp_flag = 1;
nodeChainIterBackwards(ntree, node, ntree_branch_node_tag, nullptr, 0);
}
}
LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree->nodes) {
if (node->tmp_flag == 0) {
if (node->runtime->tmp_flag == 0) {
ntreeFreeLocalNode(ntree, node);
changed = true;
}
@ -1070,7 +1075,7 @@ bNodeTreeExec *ntreeShaderBeginExecTree_internal(bNodeExecContext *context,
MEM_callocN(BLENDER_MAX_THREADS * sizeof(ListBase), "thread stack array"));
LISTBASE_FOREACH (bNode *, node, &exec->nodetree->nodes) {
node->need_exec = 1;
node->runtime->need_exec = 1;
}
return exec;

@ -6,6 +6,8 @@
#include "UI_interface.h"
#include "UI_resources.h"
#include "BKE_node_runtime.hh"
namespace blender::nodes::node_shader_bsdf_principled_cc {
static void node_declare(NodeDeclarationBuilder &b)
@ -190,7 +192,7 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat,
}
if (use_subsurf) {
bNodeSocket *socket = (bNodeSocket *)BLI_findlink(&node->original->inputs, 2);
bNodeSocket *socket = (bNodeSocket *)BLI_findlink(&node->runtime->original->inputs, 2);
bNodeSocketValueRGBA *socket_data = (bNodeSocketValueRGBA *)socket->default_value;
/* For some reason it seems that the socket value is in ARGB format. */
use_subsurf = GPU_material_sss_profile_create(mat, &socket_data->value[1]);

@ -4,6 +4,7 @@
#include "node_shader_util.hh"
#include "BKE_context.h"
#include "BKE_node_runtime.hh"
#include "UI_interface.h"
#include "UI_resources.h"
@ -52,8 +53,9 @@ static int gpu_shader_normal_map(GPUMaterial *mat,
if (in[0].link) {
strength = in[0].link;
}
else if (node->original) {
bNodeSocket *socket = static_cast<bNodeSocket *>(BLI_findlink(&node->original->inputs, 0));
else if (node->runtime->original) {
bNodeSocket *socket = static_cast<bNodeSocket *>(
BLI_findlink(&node->runtime->original->inputs, 0));
bNodeSocketValueFloat *socket_data = static_cast<bNodeSocketValueFloat *>(
socket->default_value);
strength = GPU_uniform(&socket_data->value);
@ -66,8 +68,9 @@ static int gpu_shader_normal_map(GPUMaterial *mat,
if (in[1].link) {
newnormal = in[1].link;
}
else if (node->original) {
bNodeSocket *socket = static_cast<bNodeSocket *>(BLI_findlink(&node->original->inputs, 1));
else if (node->runtime->original) {
bNodeSocket *socket = static_cast<bNodeSocket *>(
BLI_findlink(&node->runtime->original->inputs, 1));
bNodeSocketValueRGBA *socket_data = static_cast<bNodeSocketValueRGBA *>(socket->default_value);
newnormal = GPU_uniform(socket_data->value);
}

@ -6,6 +6,8 @@
#include "UI_interface.h"
#include "UI_resources.h"
#include "BKE_node_runtime.hh"
namespace blender::nodes::node_shader_subsurface_scattering_cc {
static void node_declare(NodeDeclarationBuilder &b)
@ -50,7 +52,7 @@ static int node_shader_gpu_subsurface_scattering(GPUMaterial *mat,
GPU_link(mat, "world_normals_get", &in[5].link);
}
bNodeSocket *socket = (bNodeSocket *)BLI_findlink(&node->original->inputs, 2);
bNodeSocket *socket = (bNodeSocket *)BLI_findlink(&node->runtime->original->inputs, 2);
bNodeSocketValueRGBA *socket_data = (bNodeSocketValueRGBA *)socket->default_value;
/* For some reason it seems that the socket value is in ARGB format. */
bool use_subsurf = GPU_material_sss_profile_create(mat, &socket_data->value[1]);

@ -3,6 +3,8 @@
#include "node_shader_util.hh"
#include "BKE_node_runtime.hh"
namespace blender::nodes::node_shader_tex_environment_cc {
static void node_declare(NodeDeclarationBuilder &b)
@ -33,7 +35,7 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
/* We get the image user from the original node, since GPU image keeps
* a pointer to it and the dependency refreshes the original. */
bNode *node_original = node->original ? node->original : node;
bNode *node_original = node->runtime->original ? node->runtime->original : node;
NodeTexImage *tex_original = (NodeTexImage *)node_original->storage;
ImageUser *iuser = &tex_original->iuser;
eGPUSamplerState sampler = GPU_SAMPLER_REPEAT | GPU_SAMPLER_ANISO | GPU_SAMPLER_FILTER;

@ -3,6 +3,8 @@
#include "node_shader_util.hh"
#include "BKE_node_runtime.hh"
namespace blender::nodes::node_shader_tex_image_cc {
static void sh_node_tex_image_declare(NodeDeclarationBuilder &b)
@ -34,7 +36,7 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
/* We get the image user from the original node, since GPU image keeps
* a pointer to it and the dependency refreshes the original. */
bNode *node_original = node->original ? node->original : node;
bNode *node_original = node->runtime->original ? node->runtime->original : node;
NodeTexImage *tex_original = (NodeTexImage *)node_original->storage;
ImageUser *iuser = &tex_original->iuser;

@ -198,7 +198,7 @@ bool ntreeExecThreadNodes(bNodeTreeExec *exec, bNodeThreadStack *nts, void *call
for (n = 0, nodeexec = exec->nodeexec; n < exec->totnodes; n++, nodeexec++) {
node = nodeexec->node;
if (node->need_exec) {
if (node->runtime->need_exec) {
node_get_stack(node, nts->stack, nsin, nsout);
/* Handle muted nodes...
* If the mute func is not set, assume the node should never be muted,
@ -228,7 +228,7 @@ bNodeTreeExec *ntreeTexBeginExecTree_internal(bNodeExecContext *context,
exec->threadstack = MEM_cnew_array<ListBase>(BLENDER_MAX_THREADS, "thread stack array");
for (node = static_cast<bNode *>(exec->nodetree->nodes.first); node; node = node->next) {
node->need_exec = 1;
node->runtime->need_exec = 1;
}
return exec;

@ -44,7 +44,7 @@ void tex_node_type_base(struct bNodeType *ntype, int type, const char *name, sho
static void tex_call_delegate(TexDelegate *dg, float *out, TexParams *params, short thread)
{
if (dg->node->need_exec) {
if (dg->node->runtime->need_exec) {
dg->fn(out, params, dg->node, dg->in, thread);
}
}

@ -33,6 +33,7 @@
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_node.h"
#include "BKE_node_runtime.hh"
#include "BKE_texture.h"
#include "NOD_texture.h"

@ -126,7 +126,7 @@ static void group_execute(void *data,
{
bNode *inode;
for (inode = static_cast<bNode *>(exec->nodetree->nodes.first); inode; inode = inode->next) {
inode->need_exec = 1;
inode->runtime->need_exec = 1;
}
}

@ -38,7 +38,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
zero_v3(dyt);
}
if (node->custom2 || node->need_exec == 0) {
if (node->custom2 || node->runtime->need_exec == 0) {
/* this node refers to its own texture tree! */
copy_v4_v4(out, (fabsf(co[0] - co[1]) < 0.01f) ? white : red);
}