improve image sequence usability, problem was when the image didn't load there was no way to know the frame that blender was attempting to read.

added a label for image sequence images showing the image file's frame, even when not able to load, this also gives realtime feedback to the user while dragging the frame offset/start/duration buttons about so they can better understand how these settings work.
This commit is contained in:
2011-05-01 14:02:40 +00:00
parent 1093f69e50
commit 5440b57432
5 changed files with 107 additions and 72 deletions

View File

@@ -133,6 +133,7 @@ void BKE_image_assign_ibuf(struct Image *ima, struct ImBuf *ibuf);
/* called on frame change or before render */
void BKE_image_user_calc_frame(struct ImageUser *iuser, int cfra, int fieldnr);
int BKE_image_user_get_frame(const struct ImageUser *iuser, int cfra, int fieldnr);
/* fix things in ImageUser when new image gets assigned */
void BKE_image_user_new_image(struct Image *ima, struct ImageUser *iuser);

View File

@@ -1671,8 +1671,15 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
/* read ibuf */
ibuf = IMB_loadiffname(name, flag);
if(G.f & G_DEBUG) printf("loaded %s\n", name);
#if 0
if(ibuf) {
printf(AT" loaded %s\n", name);
} else {
printf(AT" missed %s\n", name);
}
#endif
if (ibuf) {
#ifdef WITH_OPENEXR
/* handle multilayer case, don't assign ibuf. will be handled in BKE_image_get_ibuf */
@@ -2228,21 +2235,19 @@ void BKE_image_release_ibuf(Image *ima, void *lock)
/* warning, this can allocate generated images */
ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
{
/* here (+fie_ima/2-1) makes sure that division happens correctly */
return BKE_image_acquire_ibuf(ima, iuser, NULL);
}
void BKE_image_user_calc_frame(ImageUser *iuser, int cfra, int fieldnr)
int BKE_image_user_get_frame(const ImageUser *iuser, int cfra, int fieldnr)
{
int len;
/* here (+fie_ima/2-1) makes sure that division happens correctly */
len= (iuser->fie_ima*iuser->frames)/2;
const int len= (iuser->fie_ima*iuser->frames)/2;
if(len==0) {
iuser->framenr= 0;
return 0;
}
else {
int imanr;
int framenr;
cfra= cfra - iuser->sfra+1;
/* cyclic */
@@ -2251,31 +2256,38 @@ void BKE_image_user_calc_frame(ImageUser *iuser, int cfra, int fieldnr)
if(cfra < 0) cfra+= len;
if(cfra==0) cfra= len;
}
if(cfra<0) cfra= 0;
else if(cfra>len) cfra= len;
/* convert current frame to current field */
cfra= 2*(cfra);
if(fieldnr) cfra++;
/* transform to images space */
imanr= (cfra+iuser->fie_ima-2)/iuser->fie_ima;
if(imanr>iuser->frames) imanr= iuser->frames;
imanr+= iuser->offset;
framenr= (cfra+iuser->fie_ima-2)/iuser->fie_ima;
if(framenr>iuser->frames) framenr= iuser->frames;
framenr+= iuser->offset;
if(iuser->cycl) {
imanr= ( (imanr) % len );
while(imanr < 0) imanr+= len;
if(imanr==0) imanr= len;
framenr= ( (framenr) % len );
while(framenr < 0) framenr+= len;
if(framenr==0) framenr= len;
}
/* allows image users to handle redraws */
if(iuser->flag & IMA_ANIM_ALWAYS)
if(imanr!=iuser->framenr)
iuser->flag |= IMA_ANIM_REFRESHED;
iuser->framenr= imanr;
if(iuser->ok==0) iuser->ok= 1;
return framenr;
}
}
void BKE_image_user_calc_frame(ImageUser *iuser, int cfra, int fieldnr)
{
const int framenr= BKE_image_user_get_frame(iuser, cfra, fieldnr);
/* allows image users to handle redraws */
if(iuser->flag & IMA_ANIM_ALWAYS)
if(framenr!=iuser->framenr)
iuser->flag |= IMA_ANIM_REFRESHED;
iuser->framenr= framenr;
if(iuser->ok==0) iuser->ok= 1;
}

View File

@@ -119,53 +119,62 @@ static void do_image_panel_events(bContext *C, void *UNUSED(arg), int event)
WM_event_add_notifier(C, NC_IMAGE, sima->image);
}
static void image_info(Image *ima, ImBuf *ibuf, char *str)
static void image_info(Scene *scene, ImageUser *iuser, Image *ima, ImBuf *ibuf, char *str)
{
int ofs= 0;
str[0]= 0;
if(ima==NULL) return;
if(ibuf==NULL) {
sprintf(str, "Can not get an image");
return;
}
if(ima->source==IMA_SRC_MOVIE) {
ofs= sprintf(str, "Movie");
if(ima->anim)
ofs+= sprintf(str+ofs, "%d frs", IMB_anim_get_duration(ima->anim));
}
else
ofs= sprintf(str, "Image");
ofs+= sprintf(str+ofs, ": size %d x %d,", ibuf->x, ibuf->y);
if(ibuf->rect_float) {
if(ibuf->channels!=4) {
ofs+= sprintf(str+ofs, "%d float channel(s)", ibuf->channels);
}
else if(ibuf->depth==32)
ofs+= sprintf(str+ofs, " RGBA float");
else
ofs+= sprintf(str+ofs, " RGB float");
ofs+= sprintf(str, "Can't Load Image");
}
else {
if(ibuf->depth==32)
ofs+= sprintf(str+ofs, " RGBA byte");
if(ima->source==IMA_SRC_MOVIE) {
ofs+= sprintf(str, "Movie");
if(ima->anim)
ofs+= sprintf(str+ofs, "%d frs", IMB_anim_get_duration(ima->anim));
}
else
ofs+= sprintf(str+ofs, " RGB byte");
}
if(ibuf->zbuf || ibuf->zbuf_float)
ofs+= sprintf(str+ofs, " + Z");
ofs+= sprintf(str, "Image");
if(ima->source==IMA_SRC_SEQUENCE) {
char *file= BLI_last_slash(ibuf->name);
if(file==NULL) file= ibuf->name;
else file++;
sprintf(str+ofs, ", %s", file);
ofs+= sprintf(str+ofs, ": size %d x %d,", ibuf->x, ibuf->y);
if(ibuf->rect_float) {
if(ibuf->channels!=4) {
ofs+= sprintf(str+ofs, "%d float channel(s)", ibuf->channels);
}
else if(ibuf->depth==32)
ofs+= sprintf(str+ofs, " RGBA float");
else
ofs+= sprintf(str+ofs, " RGB float");
}
else {
if(ibuf->depth==32)
ofs+= sprintf(str+ofs, " RGBA byte");
else
ofs+= sprintf(str+ofs, " RGB byte");
}
if(ibuf->zbuf || ibuf->zbuf_float)
ofs+= sprintf(str+ofs, " + Z");
if(ima->source==IMA_SRC_SEQUENCE) {
char *file= BLI_last_slash(ibuf->name);
if(file==NULL) file= ibuf->name;
else file++;
ofs+= sprintf(str+ofs, ", %s", file);
}
}
/* the frame number, even if we cant */
if(ima->source==IMA_SRC_SEQUENCE) {
/* don't use iuser->framenr directly because it may not be updated if auto-refresh is off */
const int framenr= BKE_image_user_get_frame(iuser, CFRA, 0);
ofs+= sprintf(str+ofs, ", Frame: %d", framenr);
}
(void)ofs;
}
/* gets active viewer user */
@@ -816,7 +825,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
if(ima->source == IMA_SRC_VIEWER) {
ibuf= BKE_image_acquire_ibuf(ima, iuser, &lock);
image_info(ima, ibuf, str);
image_info(scene, iuser, ima, ibuf, str);
BKE_image_release_ibuf(ima, lock);
uiItemL(layout, ima->id.name+2, ICON_NONE);
@@ -888,7 +897,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
else if(ima->source != IMA_SRC_GENERATED) {
if(compact == 0) {
ibuf= BKE_image_acquire_ibuf(ima, iuser, &lock);
image_info(ima, ibuf, str);
image_info(scene, iuser, ima, ibuf, str);
BKE_image_release_ibuf(ima, lock);
uiItemL(layout, str, ICON_NONE);
}

View File

@@ -482,6 +482,7 @@ static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA *
bNode *node= ptr->data;
PointerRNA imaptr;
PropertyRNA *prop;
int source;
uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL);
@@ -495,7 +496,19 @@ static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA *
uiItemR(col, &imaptr, "source", 0, NULL, ICON_NONE);
if (ELEM(RNA_enum_get(&imaptr, "source"), IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) {
source= RNA_enum_get(&imaptr, "source");
if(source == IMA_SRC_SEQUENCE) {
/* don't use iuser->framenr directly because it may not be updated if auto-refresh is off */
Scene *scene= CTX_data_scene(C);
ImageUser *iuser= node->storage;
char tstr[32];
const int framenr= BKE_image_user_get_frame(iuser, CFRA, 0);
BLI_snprintf(tstr, sizeof(tstr), "Frame: %d", framenr);
uiItemL(layout, tstr, ICON_NONE);
}
if (ELEM(source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) {
col= uiLayoutColumn(layout, 1);
uiItemR(col, ptr, "frame_duration", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "frame_start", 0, NULL, ICON_NONE);

View File

@@ -1262,29 +1262,29 @@ static void def_cmp_image(StructRNA *srna)
prop = RNA_def_property(srna, "frame_duration", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "frames");
RNA_def_property_range(prop, 0, MAXFRAMEF);
RNA_def_property_ui_text(prop, "Frames", "Number of images used in animation");
RNA_def_property_ui_text(prop, "Frames", "Sets the number of images of a movie to use"); /* copied from the rna_image.c */
RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "sfra");
RNA_def_property_range(prop, MINAFRAMEF, MAXFRAMEF);
RNA_def_property_ui_text(prop, "Start Frame", "");
RNA_def_property_ui_text(prop, "Start Frame", "Sets the global starting frame of the movie/sequence, assuming first picture has a #1"); /* copied from the rna_image.c */
RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "frame_offset", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "offset");
RNA_def_property_range(prop, MINAFRAMEF, MAXFRAMEF);
RNA_def_property_ui_text(prop, "Offset", "Offsets the number of the frame to use in the animation");
RNA_def_property_ui_text(prop, "Offset", "Offsets the number of the frame to use in the animation"); /* copied from the rna_image.c */
RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "use_cyclic", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "cycl", 1);
RNA_def_property_ui_text(prop, "Cyclic", "");
RNA_def_property_ui_text(prop, "Cyclic", "Cycle the images in the movie"); /* copied from the rna_image.c */
RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "use_auto_refresh", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_ANIM_ALWAYS);
RNA_def_property_ui_text(prop, "Auto-Refresh", "");
RNA_def_property_ui_text(prop, "Auto-Refresh", "Always refresh image on frame changes"); /* copied from the rna_image.c */
RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
prop= RNA_def_property(srna, "layer", PROP_ENUM, PROP_NONE);