Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/node.c
| Show First 20 Lines • Show All 1,400 Lines • ▼ Show 20 Lines | bNodeTree *ntreeAddTree(Main *bmain, const char *name, const char *idname) | ||||
| /* trees are created as local trees for compositor, material or texture nodes, | /* trees are created as local trees for compositor, material or texture nodes, | ||||
| * node groups and other tree types are created as library data. | * node groups and other tree types are created as library data. | ||||
| */ | */ | ||||
| if (bmain) { | if (bmain) { | ||||
| ntree = BKE_libblock_alloc(bmain, ID_NT, name, 0); | ntree = BKE_libblock_alloc(bmain, ID_NT, name, 0); | ||||
| } | } | ||||
| else { | else { | ||||
| ntree = MEM_callocN(sizeof(bNodeTree), "new node tree"); | ntree = MEM_callocN(sizeof(bNodeTree), "new node tree"); | ||||
| ntree->id.flag |= LIB_PRIVATE_DATA; | |||||
| *((short *)ntree->id.name) = ID_NT; | *((short *)ntree->id.name) = ID_NT; | ||||
| BLI_strncpy(ntree->id.name + 2, name, sizeof(ntree->id.name)); | BLI_strncpy(ntree->id.name + 2, name, sizeof(ntree->id.name)); | ||||
| } | } | ||||
| /* Types are fully initialized at this point, | /* Types are fully initialized at this point, | ||||
| * if an undefined node is added later this will be reset. | * if an undefined node is added later this will be reset. | ||||
| */ | */ | ||||
| ntree->init |= NTREE_TYPE_INIT; | ntree->init |= NTREE_TYPE_INIT; | ||||
| ▲ Show 20 Lines • Show All 750 Lines • ▼ Show 20 Lines | if (node->type == NODE_GROUP_OUTPUT) { | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* here we could recursively set which nodes have to be done, | /* here we could recursively set which nodes have to be done, | ||||
| * might be different for editor or for "real" use... */ | * might be different for editor or for "real" use... */ | ||||
| } | } | ||||
| /* Returns the private NodeTree object of the datablock, if it has one. */ | |||||
| bNodeTree *ntreeFromID(const ID *id) | bNodeTree *ntreeFromID(const ID *id) | ||||
| { | { | ||||
| switch (GS(id->name)) { | switch (GS(id->name)) { | ||||
| case ID_MA: | case ID_MA: | ||||
| return ((const Material *)id)->nodetree; | return ((const Material *)id)->nodetree; | ||||
| case ID_LA: | case ID_LA: | ||||
| return ((const Light *)id)->nodetree; | return ((const Light *)id)->nodetree; | ||||
| case ID_WO: | case ID_WO: | ||||
| return ((const World *)id)->nodetree; | return ((const World *)id)->nodetree; | ||||
| case ID_TE: | case ID_TE: | ||||
| return ((const Tex *)id)->nodetree; | return ((const Tex *)id)->nodetree; | ||||
| case ID_SCE: | case ID_SCE: | ||||
| return ((const Scene *)id)->nodetree; | return ((const Scene *)id)->nodetree; | ||||
| case ID_LS: | case ID_LS: | ||||
| return ((const FreestyleLineStyle *)id)->nodetree; | return ((const FreestyleLineStyle *)id)->nodetree; | ||||
| default: | default: | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| } | } | ||||
| /* Finds the datablock that owns the given tree. May return the tree itself, or NULL. */ | |||||
| ID *BKE_node_tree_find_owner_ID(Main *bmain, struct bNodeTree *ntree) | |||||
| { | |||||
| if ((ntree->id.flag & LIB_PRIVATE_DATA) == 0) { | |||||
| return &ntree->id; | |||||
| } | |||||
| ListBase *lists[] = {&bmain->materials, | |||||
| &bmain->lights, | |||||
| &bmain->worlds, | |||||
| &bmain->textures, | |||||
| &bmain->scenes, | |||||
| &bmain->linestyles, | |||||
| NULL}; | |||||
| for (int i = 0; lists[i] != NULL; i++) { | |||||
| LISTBASE_FOREACH (ID *, id, lists[i]) { | |||||
| if (ntreeFromID(id) == ntree) { | |||||
| return id; | |||||
| } | |||||
| } | |||||
| } | |||||
mont29: I would not hard-code which kind of IDs can have ntrees in too many places, this is always an… | |||||
angavrilovAuthorUnsubmitted Done Inline ActionsI think it's not a problem here because it's right next to ntreeFromID. This is no different from another function with a switch. I changed the doversion code to simply scan all IDs since it's only supposed to run once. angavrilov: I think it's not a problem here because it's right next to ntreeFromID. This is no different… | |||||
| return NULL; | |||||
| } | |||||
| void ntreeMakeLocal(Main *bmain, bNodeTree *ntree, bool id_in_mainlist, const bool lib_local) | void ntreeMakeLocal(Main *bmain, bNodeTree *ntree, bool id_in_mainlist, const bool lib_local) | ||||
| { | { | ||||
| BKE_id_make_local_generic(bmain, &ntree->id, id_in_mainlist, lib_local); | BKE_id_make_local_generic(bmain, &ntree->id, id_in_mainlist, lib_local); | ||||
| } | } | ||||
| int ntreeNodeExists(bNodeTree *ntree, bNode *testnode) | int ntreeNodeExists(bNodeTree *ntree, bNode *testnode) | ||||
| { | { | ||||
| bNode *node = ntree->nodes.first; | bNode *node = ntree->nodes.first; | ||||
| ▲ Show 20 Lines • Show All 1,935 Lines • Show Last 20 Lines | |||||
I would not hard-code which kind of IDs can have ntrees in too many places, this is always an issue when you change the code...
Think a function to check if an ID code can have nodes would be nice (ntreeIDTypeCanHaveNodes() ? defined next to ntreeFromID()), then you can loop over the whole Main DB (FOREACH_MAIN_LISTBASE_BEGIN), check whether first ID of each type can actually have nodes, and go forward if they do (FOREACH_MAIN_LISTBASE_ID_BEGIN), with virtually no extra processing time, and with fully future-proof code.
Same in versioning file of course.