Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/node.c')
-rw-r--r--source/blender/blenkernel/intern/node.c152
1 files changed, 105 insertions, 47 deletions
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 757571b9cf6..788b185c6eb 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -74,6 +74,11 @@
#include "NOD_shader.h"
#include "NOD_texture.h"
+/* Fallback types for undefined tree, nodes, sockets */
+bNodeTreeType NodeTreeTypeUndefined;
+bNodeType NodeTypeUndefined;
+bNodeSocketType NodeSocketTypeUndefined;
+
static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType *ntype)
{
@@ -101,12 +106,11 @@ static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType
/* Note: This function is called to initialize node data based on the type.
* The bNodeType may not be registered at creation time of the node,
* so this can be delayed until the node type gets registered.
- * The node->typeinfo must not be used in that case until it is defined!
*/
static void node_init(const struct bContext *C, bNodeTree *ntree, bNode *node)
{
bNodeType *ntype = node->typeinfo;
- if (!ntype)
+ if (ntype == &NodeTypeUndefined)
return;
/* only do this once */
@@ -151,22 +155,24 @@ static void node_init(const struct bContext *C, bNodeTree *ntree, bNode *node)
static void ntree_set_typeinfo(bNodeTree *ntree, bNodeTreeType *typeinfo)
{
- ntree->typeinfo = typeinfo;
-
if (typeinfo) {
+ ntree->typeinfo = typeinfo;
+
/* deprecated integer type */
ntree->type = typeinfo->type;
}
else {
+ ntree->typeinfo = &NodeTreeTypeUndefined;
+
ntree->init &= ~NTREE_TYPE_INIT;
}
}
static void node_set_typeinfo(const struct bContext *C, bNodeTree *ntree, bNode *node, bNodeType *typeinfo)
{
- node->typeinfo = typeinfo;
-
if (typeinfo) {
+ node->typeinfo = typeinfo;
+
/* deprecated integer type */
node->type = typeinfo->type;
@@ -174,21 +180,25 @@ static void node_set_typeinfo(const struct bContext *C, bNodeTree *ntree, bNode
node_init(C, ntree, node);
}
else {
+ node->typeinfo = &NodeTypeUndefined;
+
ntree->init &= ~NTREE_TYPE_INIT;
}
}
static void node_socket_set_typeinfo(bNodeTree *ntree, bNodeSocket *sock, bNodeSocketType *typeinfo)
{
- sock->typeinfo = typeinfo;
-
if (typeinfo) {
+ sock->typeinfo = typeinfo;
+
if (sock->default_value == NULL) {
/* initialize the default_value pointer used by standard socket types */
node_socket_init_default_value(sock);
}
}
else {
+ sock->typeinfo = &NodeSocketTypeUndefined;
+
ntree->init &= ~NTREE_TYPE_INIT;
}
}
@@ -301,14 +311,14 @@ void ntreeTypeFreeLink(bNodeTreeType *nt)
BLI_ghash_remove(nodetreetypes_hash, nt->idname, NULL, ntree_free_type);
}
-GHashIterator *ntreeTypeGetIterator(void)
+bool ntreeIsRegistered(bNodeTree *ntree)
{
- return BLI_ghashIterator_new(nodetreetypes_hash);
+ return (ntree->typeinfo != &NodeTreeTypeUndefined);
}
-int ntreeIsValid(bNodeTree *ntree)
+GHashIterator *ntreeTypeGetIterator(void)
{
- return (ntree && (ntree->init & NTREE_TYPE_INIT));
+ return BLI_ghashIterator_new(nodetreetypes_hash);
}
bNodeType *nodeTypeFind(const char *idname)
@@ -370,6 +380,11 @@ void nodeUnregisterType(bNodeType *nt)
BLI_ghash_remove(nodetypes_hash, nt->idname, NULL, node_free_type);
}
+bool nodeIsRegistered(bNode *node)
+{
+ return (node->typeinfo != &NodeTypeUndefined);
+}
+
GHashIterator *nodeTypeGetIterator(void)
{
return BLI_ghashIterator_new(nodetypes_hash);
@@ -410,6 +425,11 @@ void nodeUnregisterSocketType(bNodeSocketType *st)
BLI_ghash_remove(nodesockettypes_hash, st->idname, NULL, node_free_socket_type);
}
+bool nodeSocketIsRegistered(bNodeSocket *sock)
+{
+ return (sock->typeinfo != &NodeSocketTypeUndefined);
+}
+
GHashIterator *nodeSocketTypeGetIterator(void)
{
return BLI_ghashIterator_new(nodesockettypes_hash);
@@ -1329,7 +1349,7 @@ static void node_preview_init_tree_recursive(bNodeInstanceHash *previews, bNodeT
BKE_node_preview_verify(previews, key, xsize, ysize, create);
}
- if (node->type == NODE_GROUP)
+ if (node->type == NODE_GROUP && node->id)
node_preview_init_tree_recursive(previews, (bNodeTree *)node->id, key, xsize, ysize, create);
}
}
@@ -1354,7 +1374,7 @@ static void node_preview_tag_used_recursive(bNodeInstanceHash *previews, bNodeTr
if (BKE_node_preview_used(node))
BKE_node_instance_hash_tag_key(previews, key);
- if (node->type == NODE_GROUP)
+ if (node->type == NODE_GROUP && node->id)
node_preview_tag_used_recursive(previews, (bNodeTree *)node->id, key);
}
}
@@ -1433,18 +1453,38 @@ void BKE_node_preview_sync_tree(bNodeTree *to_ntree, bNodeTree *from_ntree)
}
}
-void BKE_node_preview_merge_tree(bNodeTree *to_ntree, bNodeTree *from_ntree)
+void BKE_node_preview_merge_tree(bNodeTree *to_ntree, bNodeTree *from_ntree, bool remove_old)
{
- /* free old previews */
- if (to_ntree->previews)
- BKE_node_instance_hash_free(to_ntree->previews, (bNodeInstanceValueFP)BKE_node_preview_free);
-
- /* transfer previews */
- to_ntree->previews = from_ntree->previews;
- from_ntree->previews = NULL;
-
- /* clean up, in case any to_ntree nodes have been removed */
- BKE_node_preview_remove_unused(to_ntree);
+ if (remove_old || !to_ntree->previews) {
+ /* free old previews */
+ if (to_ntree->previews)
+ BKE_node_instance_hash_free(to_ntree->previews, (bNodeInstanceValueFP)BKE_node_preview_free);
+
+ /* transfer previews */
+ to_ntree->previews = from_ntree->previews;
+ from_ntree->previews = NULL;
+
+ /* clean up, in case any to_ntree nodes have been removed */
+ BKE_node_preview_remove_unused(to_ntree);
+ }
+ else {
+ bNodeInstanceHashIterator iter;
+
+ if (from_ntree->previews) {
+ NODE_INSTANCE_HASH_ITER(iter, from_ntree->previews) {
+ bNodeInstanceKey key = BKE_node_instance_hash_iterator_get_key(&iter);
+ bNodePreview *preview = BKE_node_instance_hash_iterator_get_value(&iter);
+
+ /* replace existing previews */
+ BKE_node_instance_hash_remove(to_ntree->previews, key, (bNodeInstanceValueFP)BKE_node_preview_free);
+ BKE_node_instance_hash_insert(to_ntree->previews, key, preview);
+ }
+
+ /* Note: NULL free function here, because pointers have already been moved over to to_ntree->previews! */
+ BKE_node_instance_hash_free(from_ntree->previews, NULL);
+ from_ntree->previews = NULL;
+ }
+ }
}
/* hack warning! this function is only used for shader previews, and
@@ -1887,7 +1927,7 @@ int ntreeOutputExists(bNode *node, bNodeSocket *testsock)
/* returns localized tree for execution in threads */
bNodeTree *ntreeLocalize(bNodeTree *ntree)
{
- if (ntreeIsValid(ntree)) {
+ if (ntree) {
bNodeTree *ltree;
bNode *node;
@@ -1944,13 +1984,7 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree)
/* is called by jobs manager, outside threads, so it doesnt happen during draw */
void ntreeLocalSync(bNodeTree *localtree, bNodeTree *ntree)
{
- if (localtree && ntreeIsValid(ntree)) {
- /* XXX syncing was disabled for compositor nodes.
- * It has to be ensured that there is no concurrent read/write access!
- * Possibly needs a mutex lock or a flag to disable for certain tree types ...
- */
- BKE_node_preview_sync_tree(ntree, localtree);
-
+ if (localtree && ntree) {
if (ntree->typeinfo->local_sync)
ntree->typeinfo->local_sync(localtree, ntree);
}
@@ -1960,9 +1994,7 @@ void ntreeLocalSync(bNodeTree *localtree, bNodeTree *ntree)
/* we have to assume the editor already changed completely */
void ntreeLocalMerge(bNodeTree *localtree, bNodeTree *ntree)
{
- if (localtree && ntreeIsValid(ntree)) {
- BKE_node_preview_merge_tree(ntree, localtree);
-
+ if (localtree && ntree) {
if (ntree->typeinfo->local_merge)
ntree->typeinfo->local_merge(localtree, ntree);
@@ -2006,14 +2038,14 @@ static bNodeSocket *make_socket_template(bNodeTree *ntree, int in_out,
* but reconstructing own_index in writefile.c would require parsing the identifier string.
*/
-#if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 406))
+#if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 406)) || defined(__clang__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
sock->own_index = own_index;
-#if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 406))
+#if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 406)) || defined(__clang__)
# pragma GCC diagnostic pop
#endif
@@ -2425,7 +2457,7 @@ typedef struct bNodeClipboard {
int type;
} bNodeClipboard;
-bNodeClipboard node_clipboard = {{0}};
+static bNodeClipboard node_clipboard = {{NULL}};
void BKE_node_clipboard_init(struct bNodeTree *ntree)
{
@@ -2831,11 +2863,8 @@ void ntreeVerifyNodes(struct Main *main, struct ID *id)
FOREACH_NODETREE(main, ntree, owner_id) {
bNode *node;
- if (!ntreeIsValid(ntree))
- return;
-
for (node = ntree->nodes.first; node; node = node->next)
- if (node->typeinfo && node->typeinfo->verifyfunc)
+ if (node->typeinfo->verifyfunc)
node->typeinfo->verifyfunc(ntree, node, id);
} FOREACH_NODETREE_END
}
@@ -2844,15 +2873,14 @@ void ntreeUpdateTree(bNodeTree *ntree)
{
bNode *node;
+ if (!ntree)
+ return;
+
/* avoid reentrant updates, can be caused by RNA update callbacks */
if (ntree->is_updating)
return;
ntree->is_updating = TRUE;
- /* only if types are initialized */
- if (!ntreeIsValid(ntree))
- return;
-
if (ntree->update & (NTREE_UPDATE_LINKS | NTREE_UPDATE_NODES)) {
/* set the bNodeSocket->link pointers */
ntree_update_link_pointers(ntree);
@@ -3239,6 +3267,34 @@ void node_type_compatibility(struct bNodeType *ntype, short compatibility)
ntype->compatibility = compatibility;
}
+/* callbacks for undefined types */
+
+static int node_undefined_poll(bNodeType *UNUSED(ntype), bNodeTree *UNUSED(nodetree))
+{
+ /* this type can not be added deliberately, it's just a placeholder */
+ return false;
+}
+
+/* register fallback types used for undefined tree, nodes, sockets */
+static void register_undefined_types(void)
+{
+ /* Note: these types are not registered in the type hashes,
+ * they are just used as placeholders in case the actual types are not registered.
+ */
+
+ strcpy(NodeTreeTypeUndefined.idname, "NodeTreeUndefined");
+ strcpy(NodeTreeTypeUndefined.ui_name, "Undefined");
+ strcpy(NodeTreeTypeUndefined.ui_description, "Undefined Node Tree Type");
+
+ node_type_base_custom(&NodeTypeUndefined, "NodeUndefined", "Undefined", 0, 0);
+ NodeTypeUndefined.poll = node_undefined_poll;
+
+ BLI_strncpy(NodeSocketTypeUndefined.idname, "NodeSocketUndefined", sizeof(NodeSocketTypeUndefined.idname));
+ /* extra type info for standard socket types */
+ NodeSocketTypeUndefined.type = SOCK_CUSTOM;
+ NodeSocketTypeUndefined.subtype = PROP_NONE;
+}
+
static void registerCompositNodes(void)
{
register_node_type_cmp_group();
@@ -3464,6 +3520,8 @@ void init_nodesystem(void)
nodetypes_hash = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "nodetypes_hash gh");
nodesockettypes_hash = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "nodesockettypes_hash gh");
+ register_undefined_types();
+
register_standard_node_socket_types();
register_node_tree_type_cmp();