Orange; fresh morning feature:
authorTon Roosendaal <ton@blender.org>
Wed, 25 Jan 2006 10:39:29 +0000 (10:39 +0000)
committerTon Roosendaal <ton@blender.org>
Wed, 25 Jan 2006 10:39:29 +0000 (10:39 +0000)
Image Node now supports animations as well. Press the 'Sequence' Icon in
the node to see the options:

- Frs: the amount of images involved in the sequence
- SFra: start frame, the Blender frame number
- First: the number in the name of the first image in the sequence
- Cycl: make the sequence go cyclic

The images are refreshed on each call to execute the node tree, but not
on advancing frames in Blender... I suspect that might make it to slow now,
will first have to code nice threaded/optimized updates in compositor.

source/blender/blenkernel/intern/node_composit.c
source/blender/makesdna/DNA_node_types.h
source/blender/src/drawnode.c

index 8c2202f053d823bc14c74788a0b1a8bf545d3fc5..0b7d5432614ee96591bdfb3165ffe46377074992 100644 (file)
@@ -577,18 +577,84 @@ static bNodeSocketType cmp_node_image_out[]= {
        {       -1, 0, ""       }
 };
 
        {       -1, 0, ""       }
 };
 
+static int calcimanr(int cfra, NodeImageAnim *nia)
+{
+       
+       if(nia->frames==0) return nia->nr;
+       
+       cfra= cfra - nia->sfra;
+       
+       /* cyclic */
+       if(nia->cyclic)
+               cfra= (cfra % nia->frames);
+       else if(cfra>=nia->frames)
+               cfra= nia->frames-1;
+       else if(cfra<0)
+               cfra= 0;
+       
+       cfra+= nia->nr;
+       
+       if(cfra<1) cfra= 1;
+       
+       return cfra;
+}
+
+
+static void animated_image(bNode *node, int cfra)
+{
+       Image *ima;
+       NodeImageAnim *nia;
+       int imanr;
+       unsigned short numlen;
+       char name[FILE_MAXDIR+FILE_MAXFILE], head[FILE_MAXDIR+FILE_MAXFILE], tail[FILE_MAXDIR+FILE_MAXFILE];
+       
+       ima= (Image *)node->id;
+       nia= node->storage;
+       
+       if(nia && nia->frames && ima && ima->name) {    /* frames */
+               strcpy(name, ima->name);
+               
+               imanr= calcimanr(cfra, nia);
+               if(imanr!=ima->lastframe) {
+                       ima->lastframe= imanr;
+                       
+                       BLI_stringdec(name, head, tail, &numlen);
+                       BLI_stringenc(name, head, tail, numlen, imanr);
+                       
+                       ima= add_image(name);
+                       
+                       if(ima) {
+                               ima->flag |= IMA_FROMANIM;
+                               if(node->id) node->id->us--;
+                               node->id= (ID *)ima;
+                               
+                               ima->ok= 1;
+                       }
+               }
+       }
+}
+
+
 static void node_composit_exec_image(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
 {
 static void node_composit_exec_image(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
 {
+       RenderData *rd= data;
+       
        /* image assigned to output */
        /* stack order input sockets: col, alpha */
        if(node->id) {
        /* image assigned to output */
        /* stack order input sockets: col, alpha */
        if(node->id) {
-               Image *ima= (Image *)node->id;
+               Image *ima;
                CompBuf *stackbuf;
                
                CompBuf *stackbuf;
                
+               /* animated image? */
+               if(node->storage)
+                       animated_image(node, rd->cfra);
+               
+               ima= (Image *)node->id;
+               
                /* test if image is OK */
                if(ima->ok==0) return;
                /* test if image is OK */
                if(ima->ok==0) return;
+               
                if(ima->ibuf==NULL) {
                if(ima->ibuf==NULL) {
-                       RenderData *rd= data;
                        
                        load_image(ima, IB_rect, G.sce, rd->cfra);      /* G.sce is current .blend path */
                        if(ima->ibuf==NULL) {
                        
                        load_image(ima, IB_rect, G.sce, rd->cfra);      /* G.sce is current .blend path */
                        if(ima->ibuf==NULL) {
@@ -613,6 +679,8 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **in, b
        }       
 }
 
        }       
 }
 
+/* uses node->storage to indicate animated image */
+
 static bNodeType cmp_node_image= {
        /* type code   */       CMP_NODE_IMAGE,
        /* name        */       "Image",
 static bNodeType cmp_node_image= {
        /* type code   */       CMP_NODE_IMAGE,
        /* name        */       "Image",
@@ -620,7 +688,7 @@ static bNodeType cmp_node_image= {
        /* class+opts  */       NODE_CLASS_GENERATOR, NODE_PREVIEW|NODE_OPTIONS,
        /* input sock  */       NULL,
        /* output sock */       cmp_node_image_out,
        /* class+opts  */       NODE_CLASS_GENERATOR, NODE_PREVIEW|NODE_OPTIONS,
        /* input sock  */       NULL,
        /* output sock */       cmp_node_image_out,
-       /* storage     */       "",
+       /* storage     */       "NodeImageAnim",
        /* execfunc    */       node_composit_exec_image
        
 };
        /* execfunc    */       node_composit_exec_image
        
 };
@@ -1483,5 +1551,7 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
        ntreeExecTree(ntree, rd, 0);    /* threads */
        
        ntreeEndExecTree(ntree);
        ntreeExecTree(ntree, rd, 0);    /* threads */
        
        ntreeEndExecTree(ntree);
+       
+       free_unused_animimages();
 }
 
 }
 
index 783a7bb05a530a5b8689993c5b4af217f9b7b733..5ec487ab3d07dedde28f102f4a43a35608ba162e 100644 (file)
@@ -173,6 +173,12 @@ typedef struct bNodeTree {
 #define NTREE_TYPE_INIT        1
 #define NTREE_EXEC_INIT        2
 
 #define NTREE_TYPE_INIT        1
 #define NTREE_EXEC_INIT        2
 
+/* data structs, for node->storage */
+
+typedef struct NodeImageAnim {
+       short frames, sfra, nr;
+       char cyclic, movie;
+} NodeImageAnim;
 
 #endif
 
 
 #endif
 
index 17aceb24745a9d89ed16bb2575768c7b06b51701..e764b08ee6c0cc0db8fb08824ef1615dbef48195 100644 (file)
@@ -576,12 +576,27 @@ static void node_active_cb(void *ntree_v, void *node_v)
 {
        nodeSetActive(ntree_v, node_v);
 }
 {
        nodeSetActive(ntree_v, node_v);
 }
+static void node_image_anim_cb(void *node_v, void *unused)
+{
+       bNode *node= node_v;
+       NodeImageAnim *nia;
+       
+       if(node->storage) {
+               MEM_freeN(node->storage);
+               node->storage= NULL;
+       }
+       else {
+               nia= node->storage= MEM_callocN(sizeof(NodeImageAnim), "node image anim");
+               nia->sfra= nia->nr= 1;
+       }
+       allqueue(REDRAWNODE, 1);
+}
 
 static int node_composit_buts_image(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
 {
        if(block) {
                uiBut *bt;
 
 static int node_composit_buts_image(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
 {
        if(block) {
                uiBut *bt;
-               short dy= (short)butr->ymin;
+               short dy= (short)butr->ymax-19;
                char *strp;
                
                uiBlockBeginAlign(block);
                char *strp;
                
                uiBlockBeginAlign(block);
@@ -606,15 +621,42 @@ static int node_composit_buts_image(uiBlock *block, bNodeTree *ntree, bNode *nod
                }
                else {
                        /* name button */
                }
                else {
                        /* name button */
-                       short width= (short)(butr->xmax-butr->xmin-19.0f);
+                       short width= (short)(butr->xmax-butr->xmin-38.0f);
                        bt= uiDefBut(block, TEX, B_NOP, "IMA:",
                                                 butr->xmin+19, dy, width, 19, 
                                                 node->id->name+2, 0.0, 19.0, 0, 0, "Image name");
                        uiButSetFunc(bt, node_ID_title_cb, node, NULL);
                        bt= uiDefBut(block, TEX, B_NOP, "IMA:",
                                                 butr->xmin+19, dy, width, 19, 
                                                 node->id->name+2, 0.0, 19.0, 0, 0, "Image name");
                        uiButSetFunc(bt, node_ID_title_cb, node, NULL);
-               }                       
+                       bt= uiDefIconBut(block, BUT, B_NOP, ICON_SEQUENCE,
+                                                butr->xmax-19, dy, 19, 19, 
+                                                node->id->name+2, 0.0, 19.0, 0, 0, "Enable/Disable Image animation");
+                       uiButSetFunc(bt, node_image_anim_cb, node, NULL);
+               }
+               if(node->storage) {
+                       NodeImageAnim *nia= node->storage;
+                       short width= (short)(butr->xmax-butr->xmin)/2;
+                       
+                       dy-= 19;
+                       uiDefButS(block, NUM, B_NODE_EXEC, "Frs:",
+                                         butr->xmin, dy, width, 19, 
+                                         &nia->frames, 0.0, 10000.0, 0, 0, "Amount of images used in animation");
+                       uiDefButS(block, NUM, B_NODE_EXEC, "SFra:",
+                                         butr->xmin+width, dy, width, 19, 
+                                         &nia->sfra, 1.0, 1000.0, 0, 0, "Start frame of animation");
+                       dy-= 19;
+                       uiDefButS(block, NUM, B_NODE_EXEC, "First:",
+                                         butr->xmin, dy, width, 19, 
+                                         &nia->nr, 0.0, 10000.0, 0, 0, "Number in image name, used as first in animation");
+                       uiDefButC(block, TOG, B_NODE_EXEC, "Cycl",
+                                         butr->xmin+width, dy, width, 19, 
+                                         &nia->cyclic, 0.0, 0.0, 0, 0, "Make animation go cyclic");
+                       
+               }
                
        }       
                
        }       
-       return 19;
+       if(node->storage) 
+               return 57;
+       else
+               return 19;
 }
 
 static int node_composit_buts_blur(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
 }
 
 static int node_composit_buts_blur(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)