Fix #33628, Segmentation fault after pasting a closed group of nodes into an open group. Finally now there is a proper check for pasting nodes into groups. It uses the poll_instance callback of node types to determine if a node can be added into a specific node tree. Currently this is only implemented for group nodes and does a recursive check to avoid pasting a node group into itself (on any level, also nested groups).

This commit is contained in:
Lukas Toenne
2013-04-03 09:10:29 +00:00
parent bfeef2f5f0
commit bb4ab6a007
5 changed files with 23 additions and 5 deletions

View File

@@ -1978,7 +1978,7 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
bNodeLink *link;
int num_nodes;
float center[2];
int is_clipboard_valid;
int is_clipboard_valid, all_nodes_valid;
/* validate pointers in the clipboard */
is_clipboard_valid = BKE_node_clipboard_validate();
@@ -2000,6 +2000,17 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_WARNING, "Some nodes references could not be restored, will be left empty");
}
/* make sure all clipboard nodes would be valid in the target tree */
all_nodes_valid = TRUE;
for (node = clipboard_nodes_lb->first; node; node = node->next) {
if (!node->typeinfo->poll_instance(node, ntree)) {
all_nodes_valid = FALSE;
BKE_reportf(op->reports, RPT_ERROR, "Cannot add node %s into node tree %s", node->name, ntree->id.name+2);
}
}
if (!all_nodes_valid)
return OPERATOR_CANCELLED;
ED_preview_kill_jobs(C);
/* deselect old nodes */

View File

@@ -51,6 +51,7 @@ void register_node_type_cmp_group(void)
node_type_base_custom(&ntype, "CompositorNodeGroup", "Group", NODE_CLASS_GROUP, NODE_OPTIONS | NODE_CONST_OUTPUT);
ntype.type = NODE_GROUP;
ntype.poll = cmp_node_poll_default;
ntype.poll_instance = node_group_poll_instance;
ntype.update_internal_links = node_update_internal_links_default;
ntype.ext.srna = RNA_struct_find("CompositorNodeGroup");
BLI_assert(ntype.ext.srna != NULL);

View File

@@ -89,11 +89,15 @@ const char *node_group_label(bNode *node)
int node_group_poll_instance(bNode *node, bNodeTree *nodetree)
{
bNodeTree *grouptree = (bNodeTree*)node->id;
if (grouptree)
return nodeGroupPoll(nodetree, grouptree);
if (node->typeinfo->poll(node->typeinfo, nodetree)) {
bNodeTree *grouptree = (bNodeTree*)node->id;
if (grouptree)
return nodeGroupPoll(nodetree, grouptree);
else
return TRUE; /* without a linked node tree, group node is always ok */
}
else
return 1;
return FALSE;
}
int nodeGroupPoll(bNodeTree *nodetree, bNodeTree *grouptree)

View File

@@ -231,6 +231,7 @@ void register_node_type_sh_group(void)
node_type_base_custom(&ntype, "ShaderNodeGroup", "Group", NODE_CLASS_GROUP, NODE_OPTIONS | NODE_CONST_OUTPUT);
ntype.type = NODE_GROUP;
ntype.poll = sh_node_poll_default;
ntype.poll_instance = node_group_poll_instance;
ntype.update_internal_links = node_update_internal_links_default;
ntype.ext.srna = RNA_struct_find("ShaderNodeGroup");
BLI_assert(ntype.ext.srna != NULL);

View File

@@ -159,6 +159,7 @@ void register_node_type_tex_group(void)
node_type_base_custom(&ntype, "TextureNodeGroup", "Group", NODE_CLASS_GROUP, NODE_OPTIONS | NODE_CONST_OUTPUT);
ntype.type = NODE_GROUP;
ntype.poll = tex_node_poll_default;
ntype.poll_instance = node_group_poll_instance;
ntype.update_internal_links = node_update_internal_links_default;
ntype.ext.srna = RNA_struct_find("TextureNodeGroup");
BLI_assert(ntype.ext.srna != NULL);