From: Ton Roosendaal Date: Wed, 25 Jan 2006 10:39:29 +0000 (+0000) Subject: Orange; fresh morning feature: X-Git-Url: https://git.blender.org/gitweb/gitweb.cgi/blender-staging.git/commitdiff_plain/7ce61d0fdf858f954052531277ff8479f8bd94dd Orange; fresh morning feature: 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. --- diff --git a/source/blender/blenkernel/intern/node_composit.c b/source/blender/blenkernel/intern/node_composit.c index 8c2202f053d..0b7d5432614 100644 --- a/source/blender/blenkernel/intern/node_composit.c +++ b/source/blender/blenkernel/intern/node_composit.c @@ -577,18 +577,84 @@ static bNodeSocketType cmp_node_image_out[]= { { -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) { + RenderData *rd= data; + /* image assigned to output */ /* stack order input sockets: col, alpha */ if(node->id) { - Image *ima= (Image *)node->id; + Image *ima; 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; + 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) { @@ -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", @@ -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, - /* storage */ "", + /* storage */ "NodeImageAnim", /* 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); + + free_unused_animimages(); } diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 783a7bb05a5..5ec487ab3d0 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -173,6 +173,12 @@ typedef struct bNodeTree { #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 diff --git a/source/blender/src/drawnode.c b/source/blender/src/drawnode.c index 17aceb24745..e764b08ee6c 100644 --- a/source/blender/src/drawnode.c +++ b/source/blender/src/drawnode.c @@ -576,12 +576,27 @@ static void node_active_cb(void *ntree_v, void *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; - short dy= (short)butr->ymin; + short dy= (short)butr->ymax-19; char *strp; uiBlockBeginAlign(block); @@ -606,15 +621,42 @@ static int node_composit_buts_image(uiBlock *block, bNodeTree *ntree, bNode *nod } 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= 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)