Patch #34204: [Render Animation] Fails with "Error: Specified sample_fmt is not suppo...
[blender.git] / source / blender / blenkernel / intern / node.c
index 5613f25..974a564 100644 (file)
 
 #include "DNA_action_types.h"
 #include "DNA_anim_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_material_types.h"
 #include "DNA_node_types.h"
 #include "DNA_node_types.h"
 #include "DNA_scene_types.h"
+#include "DNA_texture_types.h"
+#include "DNA_world_types.h"
 
 #include "BLI_string.h"
 #include "BLI_math.h"
@@ -403,7 +407,18 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node)
        
        node->new_node = nnode;
        nnode->new_node = NULL;
-       nnode->preview = NULL;
+       
+       /* only shader nodes get pleasant preview updating this way, compo uses own system */
+       if (node->preview) {
+               if (ntree && (ntree->type == NTREE_SHADER)) {
+                       nnode->preview = MEM_dupallocN(node->preview);
+                       if (node->preview->rect)
+                               nnode->preview->rect = MEM_dupallocN(node->preview->rect);
+               }
+               else {
+                       nnode->preview = NULL;
+               }
+       }
        
        if (ntree)
                ntree->update |= NTREE_UPDATE_NODES;
@@ -556,6 +571,12 @@ void nodeInternalRelink(bNodeTree *ntree, bNode *node)
                                        link->fromnode = fromlink->fromnode;
                                        link->fromsock = fromlink->fromsock;
                                        
+                                       /* if the up- or downstream link is invalid,
+                                        * the replacement link will be invalid too.
+                                        */
+                                       if (!(fromlink->flag & NODE_LINK_VALID))
+                                               link->flag &= ~NODE_LINK_VALID;
+                                       
                                        ntree->update |= NTREE_UPDATE_LINKS;
                                }
                                else
@@ -641,7 +662,7 @@ void nodeDetachNode(struct bNode *node)
        }
 }
 
-bNodeTree *ntreeAddTree(const char *name, int type, int nodetype)
+bNodeTree *ntreeAddTree(Main *bmain, const char *name, int type, int nodetype)
 {
        bNodeTree *ntree;
        bNodeType *ntype;
@@ -655,7 +676,7 @@ bNodeTree *ntreeAddTree(const char *name, int type, int nodetype)
                BLI_strncpy(ntree->id.name + 2, name, sizeof(ntree->id.name));
        }
        else
-               ntree = BKE_libblock_alloc(&G.main->nodetree, ID_NT, name);
+               ntree = BKE_libblock_alloc(&bmain->nodetree, ID_NT, name);
        
        ntree->type = type;
        ntree->nodetype = nodetype;
@@ -695,7 +716,7 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, const short do_id_use
        }
        else {
                newtree = MEM_dupallocN(ntree);
-               BKE_libblock_copy_data(&newtree->id, &ntree->id, TRUE); /* copy animdata and ID props */
+               BKE_libblock_copy_data(&newtree->id, &ntree->id, true); /* copy animdata and ID props */
        }
 
        id_us_plus((ID *)newtree->gpd);
@@ -976,6 +997,12 @@ void nodeFreeNode(bNodeTree *ntree, bNode *node)
 
                if (treetype->free_node_cache)
                        treetype->free_node_cache(ntree, node);
+               
+               /* texture node has bad habit of keeping exec data around */
+               if (ntree->type == NTREE_TEXTURE && ntree->execdata) {
+                       ntreeTexEndExecTree(ntree->execdata, 1);
+                       ntree->execdata = NULL;
+               }
        }
        
        /* since it is called while free database, node->id is undefined */
@@ -1007,6 +1034,7 @@ void nodeFreeNode(bNodeTree *ntree, bNode *node)
 /* do not free ntree itself here, BKE_libblock_free calls this function too */
 void ntreeFreeTree_ex(bNodeTree *ntree, const short do_id_user)
 {
+       bNodeTree *tntree;
        bNode *node, *next;
        bNodeSocket *sock;
        
@@ -1019,14 +1047,12 @@ void ntreeFreeTree_ex(bNodeTree *ntree, const short do_id_user)
         */
        if (ntree->execdata) {
                switch (ntree->type) {
-                       case NTREE_COMPOSIT:
-                               ntreeCompositEndExecTree(ntree->execdata, 1);
-                               break;
                        case NTREE_SHADER:
                                ntreeShaderEndExecTree(ntree->execdata, 1);
                                break;
                        case NTREE_TEXTURE:
                                ntreeTexEndExecTree(ntree->execdata, 1);
+                               ntree->execdata = NULL;
                                break;
                }
        }
@@ -1063,6 +1089,14 @@ void ntreeFreeTree_ex(bNodeTree *ntree, const short do_id_user)
        for (sock = ntree->outputs.first; sock; sock = sock->next)
                node_socket_free_default_value(sock->type, sock->default_value);
        BLI_freelistN(&ntree->outputs);
+       
+       /* if ntree is not part of library, free the libblock data explicitly */
+       for (tntree = G.main->nodetree.first; tntree; tntree = tntree->id.next)
+               if (tntree == ntree)
+                       break;
+       if (tntree == NULL) {
+               BKE_libblock_free_data(&ntree->id);
+       }
 }
 /* same as ntreeFreeTree_ex but always manage users */
 void ntreeFreeTree(bNodeTree *ntree)
@@ -1134,6 +1168,18 @@ void ntreeSetOutput(bNodeTree *ntree)
         * might be different for editor or for "real" use... */
 }
 
+bNodeTree *ntreeFromID(ID *id)
+{
+       switch (GS(id->name)) {
+               case ID_MA:  return ((Material *)id)->nodetree;
+               case ID_LA:  return ((Lamp *)id)->nodetree;
+               case ID_WO:  return ((World *)id)->nodetree;
+               case ID_TE:  return ((Tex *)id)->nodetree;
+               case ID_SCE: return ((Scene *)id)->nodetree;
+               default: return NULL;
+       }
+}
+
 typedef struct MakeLocalCallData {
        ID *group_id;
        ID *new_id;
@@ -1565,11 +1611,11 @@ int BKE_node_clipboard_validate(void)
 
        /* lists must be aligned */
        BLI_assert(BLI_countlist(&node_clipboard.nodes) ==
-                          BLI_countlist(&node_clipboard.nodes_extra_info));
+                  BLI_countlist(&node_clipboard.nodes_extra_info));
 
        for (node = node_clipboard.nodes.first, node_info = node_clipboard.nodes_extra_info.first;
-                node;
-                node = node->next, node_info = node_info->next)
+            node;
+            node = node->next, node_info = node_info->next)
        {
                /* validate the node against the stored node info */
 
@@ -1601,7 +1647,7 @@ void BKE_node_clipboard_add_node(bNode *node)
 {
 #ifdef USE_NODE_CB_VALIDATE
        /* add extra info */
-       bNodeClipboardExtraInfo *node_info = MEM_mallocN(sizeof(bNodeClipboardExtraInfo), STRINGIFY(bNodeClipboardExtraInfo));
+       bNodeClipboardExtraInfo *node_info = MEM_mallocN(sizeof(bNodeClipboardExtraInfo), "bNodeClipboardExtraInfo");
 
        node_info->id = node->id;
        if (node->id) {
@@ -1995,9 +2041,8 @@ void node_type_base(bNodeTreeType *ttype, bNodeType *ntype, int type, const char
                ntype->update_internal_links = ttype->update_internal_links;
 
        /* default size values */
-       ntype->width = 140;
-       ntype->minwidth = 100;
-       ntype->maxwidth = 320;
+       node_type_size_preset(ntype, NODE_SIZE_DEFAULT);
+       
        ntype->height = 100;
        ntype->minheight = 30;
        ntype->maxheight = FLT_MAX;
@@ -2029,6 +2074,21 @@ void node_type_size(struct bNodeType *ntype, int width, int minwidth, int maxwid
                ntype->maxwidth = maxwidth;
 }
 
+void node_type_size_preset(struct bNodeType *ntype, eNodeSizePreset size)
+{
+       switch (size) {
+               case NODE_SIZE_DEFAULT:
+                       node_type_size(ntype, 140, 100, 320);
+                       break;
+               case NODE_SIZE_SMALL:
+                       node_type_size(ntype, 100, 80, 320);
+                       break;
+               case NODE_SIZE_LARGE:
+                       node_type_size(ntype, 140, 120, 500);
+                       break;
+       }
+}
+
 void node_type_storage(bNodeType *ntype, const char *storagename, void (*freestoragefunc)(struct bNode *), void (*copystoragefunc)(struct bNode *, struct bNode *))
 {
        if (storagename)
@@ -2126,6 +2186,24 @@ void nodeRegisterType(bNodeTreeType *ttype, bNodeType *ntype)
        
        if (found == NULL)
                BLI_addtail(typelist, ntype);
+       
+       /* Associate the RNA struct type with the bNodeType.
+        * Dynamically registered nodes will create an RNA type at runtime
+        * and call RNA_struct_blender_type_set, so this only needs to be done for old RNA types
+        * created in makesrna, which can not be associated to a bNodeType immediately,
+        * since bNodeTypes are registered afterward ...
+        */
+       #define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \
+       if (ID == ntype->type) { \
+               StructRNA *srna = RNA_struct_find(STRINGIFY_ARG(Category##StructName)); \
+               BLI_assert(srna != NULL); \
+               RNA_struct_blender_type_set(srna, ntype); \
+       }
+       
+       /* XXX hack, this file will be moved to the nodes folder in customnodes branch,
+        * then this stupid include path is not needed any more.
+        */
+       #include "intern/rna_nodetree_types.h"
 }
 
 static void registerCompositNodes(bNodeTreeType *ttype)
@@ -2134,8 +2212,6 @@ static void registerCompositNodes(bNodeTreeType *ttype)
        register_node_type_reroute(ttype);
        
        register_node_type_cmp_group(ttype);
-//     register_node_type_cmp_forloop(ttype);
-//     register_node_type_cmp_whileloop(ttype);
        
        register_node_type_cmp_rlayers(ttype);
        register_node_type_cmp_image(ttype);
@@ -2165,6 +2241,7 @@ static void registerCompositNodes(bNodeTreeType *ttype)
        register_node_type_cmp_normal(ttype);
        register_node_type_cmp_curve_vec(ttype);
        register_node_type_cmp_map_value(ttype);
+       register_node_type_cmp_map_range(ttype);
        register_node_type_cmp_normalize(ttype);
        
        register_node_type_cmp_filter(ttype);
@@ -2235,8 +2312,6 @@ static void registerShaderNodes(bNodeTreeType *ttype)
        register_node_type_reroute(ttype);
        
        register_node_type_sh_group(ttype);
-       //register_node_type_sh_forloop(ttype);
-       //register_node_type_sh_whileloop(ttype);
 
        register_node_type_sh_output(ttype);
        register_node_type_sh_material(ttype);
@@ -2272,18 +2347,24 @@ static void registerShaderNodes(bNodeTreeType *ttype)
        register_node_type_sh_layer_weight(ttype);
        register_node_type_sh_tex_coord(ttype);
        register_node_type_sh_particle_info(ttype);
+       register_node_type_sh_hair_info(ttype);
        register_node_type_sh_bump(ttype);
+       register_node_type_sh_script(ttype);
+       register_node_type_sh_tangent(ttype);
+       register_node_type_sh_normal_map(ttype);
 
        register_node_type_sh_background(ttype);
        register_node_type_sh_bsdf_anisotropic(ttype);
        register_node_type_sh_bsdf_diffuse(ttype);
        register_node_type_sh_bsdf_glossy(ttype);
        register_node_type_sh_bsdf_glass(ttype);
+       register_node_type_sh_bsdf_refraction(ttype);
        register_node_type_sh_bsdf_translucent(ttype);
        register_node_type_sh_bsdf_transparent(ttype);
        register_node_type_sh_bsdf_velvet(ttype);
        register_node_type_sh_emission(ttype);
        register_node_type_sh_holdout(ttype);
+       register_node_type_sh_ambient_occlusion(ttype);
        //register_node_type_sh_volume_transparent(ttype);
        //register_node_type_sh_volume_isotropic(ttype);
        register_node_type_sh_mix_shader(ttype);
@@ -2312,8 +2393,6 @@ static void registerTextureNodes(bNodeTreeType *ttype)
        register_node_type_reroute(ttype);
        
        register_node_type_tex_group(ttype);
-//     register_node_type_tex_forloop(ttype);
-//     register_node_type_tex_whileloop(ttype);
        
        register_node_type_tex_math(ttype);
        register_node_type_tex_mix_rgb(ttype);