Cleanup: Deduplicate node parent checking functions #105413

Merged
Hans Goudey merged 4 commits from mod_moder/blender:delete_nodeAttachNodeCheck into main 2023-03-03 22:39:01 +01:00
4 changed files with 38 additions and 61 deletions

View File

@ -757,7 +757,6 @@ void nodeInternalRelink(struct bNodeTree *ntree, struct bNode *node);
void nodeToView(const struct bNode *node, float x, float y, float *rx, float *ry); void nodeToView(const struct bNode *node, float x, float y, float *rx, float *ry);
void nodeFromView(const struct bNode *node, float x, float y, float *rx, float *ry); void nodeFromView(const struct bNode *node, float x, float y, float *rx, float *ry);
bool nodeAttachNodeCheck(const struct bNode *node, const struct bNode *parent);
void nodeAttachNode(struct bNodeTree *ntree, struct bNode *node, struct bNode *parent); void nodeAttachNode(struct bNodeTree *ntree, struct bNode *node, struct bNode *parent);
void nodeDetachNode(struct bNodeTree *ntree, struct bNode *node); void nodeDetachNode(struct bNodeTree *ntree, struct bNode *node);
@ -790,11 +789,7 @@ void nodeFindNode(struct bNodeTree *ntree,
*/ */
struct bNode *nodeFindRootParent(bNode *node); struct bNode *nodeFindRootParent(bNode *node);
/** bool nodeIsParentAndChild(const bNode *parent, const bNode *child);
* \returns true if \a child has \a parent as a parent/grandparent/... etc.
* \note Recursive
*/
bool nodeIsChildOf(const bNode *parent, const bNode *child);
/** /**
* Iterate over a chain of nodes, starting with \a node_start, executing * Iterate over a chain of nodes, starting with \a node_start, executing

View File

@ -2059,13 +2059,13 @@ bNode *nodeFindRootParent(bNode *node)
return node->type == NODE_FRAME ? node : nullptr; return node->type == NODE_FRAME ? node : nullptr;
} }
bool nodeIsChildOf(const bNode *parent, const bNode *child) bool nodeIsParentAndChild(const bNode *parent, const bNode *child)
{ {
if (parent == child) { if (parent == child) {
return true; return true;
} }
if (child->parent) { if (child->parent) {
return nodeIsChildOf(parent, child->parent); return nodeIsParentAndChild(parent, child->parent);
} }
return false; return false;
} }
@ -2573,21 +2573,10 @@ void nodeFromView(const bNode *node, const float x, const float y, float *rx, fl
} }
} }
bool nodeAttachNodeCheck(const bNode *node, const bNode *parent)
{
for (const bNode *parent_iter = node; parent_iter; parent_iter = parent_iter->parent) {
if (parent_iter == parent) {
return true;
}
}
return false;
}
void nodeAttachNode(bNodeTree *ntree, bNode *node, bNode *parent) void nodeAttachNode(bNodeTree *ntree, bNode *node, bNode *parent)
{ {
BLI_assert(parent->type == NODE_FRAME); BLI_assert(parent->type == NODE_FRAME);
BLI_assert(nodeAttachNodeCheck(parent, node) == false); BLI_assert(!nodeIsParentAndChild(parent, node));
float locx, locy; float locx, locy;
nodeToView(node, 0.0f, 0.0f, &locx, &locy); nodeToView(node, 0.0f, 0.0f, &locx, &locy);

View File

@ -1890,31 +1890,25 @@ static int node_attach_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *e
continue; continue;
} }
if (node->parent == nullptr) {
/* Disallow moving a parent into its child. */ /* Disallow moving a parent into its child. */
if (nodeAttachNodeCheck(frame, node) == false) { if (node->is_frame() && nodeIsParentAndChild(node, frame)) {
/* Attach all unparented nodes. */ continue;
nodeAttachNode(&ntree, node, frame); }
}
} if (node->parent == nullptr) {
else { nodeAttachNode(&ntree, node, frame);
/* Attach nodes which share parent with the frame. */ continue;
bNode *parent; }
for (parent = frame->parent; parent; parent = parent->parent) {
if (parent == node->parent) { /* Attach nodes which share parent with the frame. */
break; const bool share_parent = nodeIsParentAndChild(node->parent, frame);
} if (!share_parent) {
continue;
} }
if (parent) {
/* Disallow moving a parent into its child. */
if (nodeAttachNodeCheck(frame, node) == false) {
nodeDetachNode(&ntree, node); nodeDetachNode(&ntree, node);
nodeAttachNode(&ntree, node, frame); nodeAttachNode(&ntree, node, frame);
} }
}
}
}
node_sort(ntree); node_sort(ntree);
WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr); WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
@ -2305,7 +2299,7 @@ static void node_parent_offset_apply(NodeInsertOfsData *data, bNode *parent, con
/* Flag all children as offset to prevent them from being offset /* Flag all children as offset to prevent them from being offset
* separately (they've already moved with the parent). */ * separately (they've already moved with the parent). */
for (bNode *node : data->ntree->all_nodes()) { for (bNode *node : data->ntree->all_nodes()) {
if (nodeIsChildOf(parent, node)) { if (nodeIsParentAndChild(parent, node)) {
/* NODE_TEST is used to flag nodes that shouldn't be offset (again) */ /* NODE_TEST is used to flag nodes that shouldn't be offset (again) */
node->flag |= NODE_TEST; node->flag |= NODE_TEST;
} }
@ -2345,7 +2339,7 @@ static void node_link_insert_offset_frame_chains(bNodeTree *ntree,
const bool reversed) const bool reversed)
{ {
for (bNode *node : ntree->all_nodes()) { for (bNode *node : ntree->all_nodes()) {
if (nodeIsChildOf(parent, node)) { if (nodeIsParentAndChild(parent, node)) {
nodeChainIter(ntree, node, node_link_insert_offset_frame_chain_cb, data, reversed); nodeChainIter(ntree, node, node_link_insert_offset_frame_chain_cb, data, reversed);
} }
} }
@ -2372,7 +2366,7 @@ static bool node_link_insert_offset_chain_cb(bNode *fromnode,
node_offset_apply(*ofs_node, data->offset_x); node_offset_apply(*ofs_node, data->offset_x);
} }
if (nodeIsChildOf(data->insert_parent, ofs_node) == false) { if (!nodeIsParentAndChild(data->insert_parent, ofs_node)) {
data->insert_parent = nullptr; data->insert_parent = nullptr;
} }
} }
@ -2472,7 +2466,7 @@ static void node_link_insert_offset_ntree(NodeInsertOfsData *iofsd,
if (needs_alignment) { if (needs_alignment) {
bNode *offs_node = right_alignment ? next : prev; bNode *offs_node = right_alignment ? next : prev;
if (!offs_node->parent || offs_node->parent == insert.parent || if (!offs_node->parent || offs_node->parent == insert.parent ||
nodeIsChildOf(offs_node->parent, &insert)) { nodeIsParentAndChild(offs_node->parent, &insert)) {
node_offset_apply(*offs_node, addval); node_offset_apply(*offs_node, addval);
} }
else if (!insert.parent && offs_node->parent) { else if (!insert.parent && offs_node->parent) {

View File

@ -2384,7 +2384,11 @@ static void rna_Node_parent_set(PointerRNA *ptr,
bNode *parent = value.data; bNode *parent = value.data;
bNodeTree *ntree = (bNodeTree *)ptr->owner_id; bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
if (parent) { if (!parent) {
nodeDetachNode(ntree, node);
return;
}
/* XXX only Frame node allowed for now, /* XXX only Frame node allowed for now,
* in the future should have a poll function or so to test possible attachment. * in the future should have a poll function or so to test possible attachment.
*/ */
@ -2392,16 +2396,12 @@ static void rna_Node_parent_set(PointerRNA *ptr,
return; return;
} }
/* make sure parent is not attached to the node */ if (nodeIsParentAndChild(node, parent)) {
if (nodeAttachNodeCheck(parent, node)) {
return; return;
} }
}
nodeDetachNode(ntree, node); nodeDetachNode(ntree, node);
if (parent) {
nodeAttachNode(ntree, node, parent); nodeAttachNode(ntree, node, parent);
}
} }
static void rna_Node_internal_links_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) static void rna_Node_internal_links_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
@ -2425,8 +2425,7 @@ static bool rna_Node_parent_poll(PointerRNA *ptr, PointerRNA value)
return false; return false;
} }
/* make sure parent is not attached to the node */ if (node->type == NODE_FRAME && nodeIsParentAndChild(node, parent)) {
if (nodeAttachNodeCheck(parent, node)) {
return false; return false;
} }