me-main #1

Merged
Nate Rupsis merged 123 commits from me-main into main 2023-02-13 18:39:11 +01:00
7 changed files with 54 additions and 50 deletions
Showing only changes of commit d411be8a99 - Show all commits

View File

@ -35,19 +35,10 @@ def draw_node_group_add_menu(context, layout):
if node_tree: if node_tree:
from nodeitems_builtins import node_tree_group_type from nodeitems_builtins import node_tree_group_type
def contains_group(nodetree, group):
if nodetree == group:
return True
for node in nodetree.nodes:
if node.bl_idname in node_tree_group_type.values() and node.node_tree is not None:
if contains_group(node.node_tree, group):
return True
return False
groups = [ groups = [
group for group in context.blend_data.node_groups group for group in context.blend_data.node_groups
if (group.bl_idname == node_tree.bl_idname and if (group.bl_idname == node_tree.bl_idname and
not contains_group(group, node_tree) and not group.contains_tree(node_tree) and
not group.name.startswith('.')) not group.name.startswith('.'))
] ]
if groups: if groups:

View File

@ -76,21 +76,11 @@ def node_group_items(context):
yield NodeItemCustom(draw=lambda self, layout, context: layout.separator()) yield NodeItemCustom(draw=lambda self, layout, context: layout.separator())
def contains_group(nodetree, group):
if nodetree == group:
return True
else:
for node in nodetree.nodes:
if node.bl_idname in node_tree_group_type.values() and node.node_tree is not None:
if contains_group(node.node_tree, group):
return True
return False
for group in context.blend_data.node_groups: for group in context.blend_data.node_groups:
if group.bl_idname != ntree.bl_idname: if group.bl_idname != ntree.bl_idname:
continue continue
# filter out recursive groups # filter out recursive groups
if contains_group(group, ntree): if group.contains_tree(ntree):
continue continue
# filter out hidden nodetrees # filter out hidden nodetrees
if group.name.startswith('.'): if group.name.startswith('.'):

View File

@ -504,7 +504,13 @@ struct bNodeTree *ntreeFromID(struct ID *id);
void ntreeFreeLocalNode(struct bNodeTree *ntree, struct bNode *node); void ntreeFreeLocalNode(struct bNodeTree *ntree, struct bNode *node);
void ntreeFreeLocalTree(struct bNodeTree *ntree); void ntreeFreeLocalTree(struct bNodeTree *ntree);
struct bNode *ntreeFindType(struct bNodeTree *ntree, int type); struct bNode *ntreeFindType(struct bNodeTree *ntree, int type);
bool ntreeHasTree(const struct bNodeTree *ntree, const struct bNodeTree *lookup);
/**
* Check recursively if a node tree contains another.
*/
bool ntreeContainsTree(const struct bNodeTree *tree_to_search_in,
const struct bNodeTree *tree_to_search_for);
void ntreeUpdateAllNew(struct Main *main); void ntreeUpdateAllNew(struct Main *main);
void ntreeUpdateAllUsers(struct Main *main, struct ID *id); void ntreeUpdateAllUsers(struct Main *main, struct ID *id);

View File

@ -3457,21 +3457,41 @@ bNode *ntreeFindType(bNodeTree *ntree, int type)
return nullptr; return nullptr;
} }
bool ntreeHasTree(const bNodeTree *ntree, const bNodeTree *lookup) static bool ntree_contains_tree_exec(const bNodeTree *tree_to_search_in,
const bNodeTree *tree_to_search_for,
Set<const bNodeTree *> &already_passed)
{ {
if (ntree == lookup) { if (tree_to_search_in == tree_to_search_for) {
return true; return true;
} }
for (const bNode *node : ntree->all_nodes()) {
if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id) { tree_to_search_in->ensure_topology_cache();
if (ntreeHasTree((bNodeTree *)node->id, lookup)) { for (const bNode *node_group : tree_to_search_in->group_nodes()) {
const bNodeTree *sub_tree_search_in = reinterpret_cast<const bNodeTree *>(node_group->id);
if (!sub_tree_search_in) {
continue;
}
if (!already_passed.add(sub_tree_search_in)) {
continue;
}
if (ntree_contains_tree_exec(sub_tree_search_in, tree_to_search_for, already_passed)) {
return true; return true;
} }
} }
}
return false; return false;
} }
bool ntreeContainsTree(const bNodeTree *tree_to_search_in, const bNodeTree *tree_to_search_for)
{
if (tree_to_search_in == tree_to_search_for) {
return true;
}
Set<const bNodeTree *> already_passed;
return ntree_contains_tree_exec(tree_to_search_in, tree_to_search_for, already_passed);
}
bNodeLink *nodeFindLink(bNodeTree *ntree, const bNodeSocket *from, const bNodeSocket *to) bNodeLink *nodeFindLink(bNodeTree *ntree, const bNodeSocket *from, const bNodeSocket *to)
{ {
LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) { LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {

View File

@ -715,7 +715,7 @@ void ED_node_set_active(
if ((node->flag & NODE_ACTIVE_TEXTURE) && !was_active_texture) { if ((node->flag & NODE_ACTIVE_TEXTURE) && !was_active_texture) {
/* If active texture changed, free glsl materials. */ /* If active texture changed, free glsl materials. */
LISTBASE_FOREACH (Material *, ma, &bmain->materials) { LISTBASE_FOREACH (Material *, ma, &bmain->materials) {
if (ma->nodetree && ma->use_nodes && ntreeHasTree(ma->nodetree, ntree)) { if (ma->nodetree && ma->use_nodes && ntreeContainsTree(ma->nodetree, ntree)) {
GPU_material_free(&ma->gpumaterial); GPU_material_free(&ma->gpumaterial);
/* Sync to active texpaint slot, otherwise we can end up painting on a different slot /* Sync to active texpaint slot, otherwise we can end up painting on a different slot
@ -734,7 +734,7 @@ void ED_node_set_active(
} }
LISTBASE_FOREACH (World *, wo, &bmain->worlds) { LISTBASE_FOREACH (World *, wo, &bmain->worlds) {
if (wo->nodetree && wo->use_nodes && ntreeHasTree(wo->nodetree, ntree)) { if (wo->nodetree && wo->use_nodes && ntreeContainsTree(wo->nodetree, ntree)) {
GPU_material_free(&wo->gpumaterial); GPU_material_free(&wo->gpumaterial);
} }
} }

View File

@ -1094,24 +1094,6 @@ void NODE_OT_group_make(wmOperatorType *ot)
/** \name Group Insert Operator /** \name Group Insert Operator
* \{ */ * \{ */
static bool node_tree_contains_tree_recursive(const bNodeTree &ntree_to_search_in,
const bNodeTree &ntree_to_search_for)
{
if (&ntree_to_search_in == &ntree_to_search_for) {
return true;
}
ntree_to_search_in.ensure_topology_cache();
for (const bNode *node : ntree_to_search_in.group_nodes()) {
if (node->id) {
if (node_tree_contains_tree_recursive(*reinterpret_cast<bNodeTree *>(node->id),
ntree_to_search_for)) {
return true;
}
}
}
return false;
}
static int node_group_insert_exec(bContext *C, wmOperator *op) static int node_group_insert_exec(bContext *C, wmOperator *op)
{ {
SpaceNode *snode = CTX_wm_space_node(C); SpaceNode *snode = CTX_wm_space_node(C);
@ -1133,7 +1115,7 @@ static int node_group_insert_exec(bContext *C, wmOperator *op)
if (!group->is_group() || group->id == nullptr) { if (!group->is_group() || group->id == nullptr) {
continue; continue;
} }
if (node_tree_contains_tree_recursive(*reinterpret_cast<bNodeTree *>(group->id), *ngroup)) { if (ntreeContainsTree(reinterpret_cast<bNodeTree *>(group->id), ngroup)) {
BKE_reportf( BKE_reportf(
op->reports, RPT_WARNING, "Can not insert group '%s' in '%s'", group->name, gnode->name); op->reports, RPT_WARNING, "Can not insert group '%s' in '%s'", group->name, gnode->name);
return OPERATOR_CANCELLED; return OPERATOR_CANCELLED;

View File

@ -1435,6 +1435,11 @@ static void rna_NodeTree_active_output_set(PointerRNA *ptr, int value)
} }
} }
static bool rna_NodeTree_contains_tree(bNodeTree *tree, bNodeTree *sub_tree)
{
return ntreeContainsTree(tree, sub_tree);
}
static bNodeSocket *rna_NodeTree_inputs_new( static bNodeSocket *rna_NodeTree_inputs_new(
bNodeTree *ntree, Main *bmain, ReportList *reports, const char *type, const char *name) bNodeTree *ntree, Main *bmain, ReportList *reports, const char *type, const char *name)
{ {
@ -12719,6 +12724,16 @@ static void rna_def_nodetree(BlenderRNA *brna)
parm = RNA_def_pointer(func, "context", "Context", "", ""); parm = RNA_def_pointer(func, "context", "Context", "", "");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
func = RNA_def_function(srna, "contains_tree", "rna_NodeTree_contains_tree");
RNA_def_function_ui_description(
func,
"Check if the node tree contains another. Used to avoid creating recursive node groups");
parm = RNA_def_pointer(
func, "sub_tree", "NodeTree", "Node Tree", "Node tree for recursive check");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
parm = RNA_def_property(func, "contained", PROP_BOOLEAN, PROP_NONE);
RNA_def_function_return(func, parm);
/* registration */ /* registration */
prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE); prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "typeinfo->idname"); RNA_def_property_string_sdna(prop, NULL, "typeinfo->idname");