{ -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) {
}
}
+/* uses node->storage to indicate animated image */
+
static bNodeType cmp_node_image= {
/* type code */ CMP_NODE_IMAGE,
/* name */ "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
};
ntreeExecTree(ntree, rd, 0); /* threads */
ntreeEndExecTree(ntree);
+
+ free_unused_animimages();
}
{
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);
}
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)