New "use placeholders" feature of the sequencer did not detect correct

filenames.

Added BLI_path utility functions to decompose a path name and
extract the frame number. It should be useful in autocollapse
feature as well
This commit is contained in:
2015-06-04 20:40:11 +02:00
parent 455ca1b28f
commit 2cbe60b476
5 changed files with 130 additions and 45 deletions

View File

@@ -132,6 +132,8 @@ bool BLI_parent_dir(char *path) ATTR_NONNULL();
bool BLI_path_abs(char *path, const char *basepath) ATTR_NONNULL(); bool BLI_path_abs(char *path, const char *basepath) ATTR_NONNULL();
bool BLI_path_frame(char *path, int frame, int digits) ATTR_NONNULL(); bool BLI_path_frame(char *path, int frame, int digits) ATTR_NONNULL();
bool BLI_path_frame_range(char *path, int sta, int end, int digits) ATTR_NONNULL(); bool BLI_path_frame_range(char *path, int sta, int end, int digits) ATTR_NONNULL();
bool BLI_path_frame_get(char *path, int *r_frame, int *numdigits) ATTR_NONNULL();
void BLI_path_frame_strip(char *path, bool setsharp, char *ext) ATTR_NONNULL();
bool BLI_path_frame_check_chars(const char *path) ATTR_NONNULL(); bool BLI_path_frame_check_chars(const char *path) ATTR_NONNULL();
bool BLI_path_cwd(char *path) ATTR_NONNULL(); bool BLI_path_cwd(char *path) ATTR_NONNULL();
void BLI_path_rel(char *file, const char *relfile) ATTR_NONNULL(); void BLI_path_rel(char *file, const char *relfile) ATTR_NONNULL();

View File

@@ -858,6 +858,111 @@ bool BLI_path_frame_range(char *path, int sta, int end, int digits)
return false; return false;
} }
/**
* Get the frame from a filename formatted by blender's frame scheme
*/
bool BLI_path_frame_get(char *path, int *r_frame, int *r_numdigits)
{
if (path && *path) {
char *file = (char *)BLI_last_slash(path);
char *c;
int len, numdigits;
numdigits = *r_numdigits = 0;
if (file == NULL)
file = path;
/* first get the extension part */
len = strlen(file);
c = file + len;
/* isolate extension */
while (--c != file) {
if (*c == '.') {
c--;
break;
}
}
/* find start of number */
while (c != (file - 1) && isdigit(*c)) {
c--;
numdigits++;
}
if (numdigits) {
char prevchar;
c++;
prevchar = c[numdigits];
c[numdigits] = 0;
/* was the number really an extension? */
*r_frame = atoi(c);
c[numdigits] = prevchar;
*r_numdigits = numdigits;
return true;
}
}
return false;
}
void BLI_path_frame_strip(char *path, bool setsharp, char *ext)
{
if (path && *path) {
char *file = (char *)BLI_last_slash(path);
char *c, *suffix;
int len;
int numdigits = 0;
if (file == NULL)
file = path;
/* first get the extension part */
len = strlen(file);
c = file + len;
/* isolate extension */
while (--c != file) {
if (*c == '.') {
c--;
break;
}
}
suffix = c + 1;
/* find start of number */
while (c != (file - 1) && isdigit(*c)) {
c--;
numdigits++;
}
c++;
if(numdigits) {
/* replace the number with the suffix and terminate the string */
while (numdigits--) {
if (ext) *ext++ = *suffix;
if (setsharp) *c++ = '#';
else *c++ = *suffix;
suffix++;
}
*c = 0;
if (ext) *ext = 0;
}
}
}
/** /**
* Check if we have '#' chars, usable for #BLI_path_frame, #BLI_path_frame_range * Check if we have '#' chars, usable for #BLI_path_frame, #BLI_path_frame_range
*/ */

View File

@@ -752,33 +752,20 @@ void SEQUENCER_OT_sound_strip_add(struct wmOperatorType *ot)
RNA_def_boolean(ot->srna, "cache", false, "Cache", "Cache the sound in memory"); RNA_def_boolean(ot->srna, "cache", false, "Cache", "Cache the sound in memory");
} }
int sequencer_image_seq_get_minmax_frame(wmOperator *op, int sfra, int *r_minframe) int sequencer_image_seq_get_minmax_frame(wmOperator *op, int sfra, int *r_minframe, int *r_numdigits)
{ {
int minframe = INT32_MAX, maxframe = INT32_MIN; int minframe = INT32_MAX, maxframe = INT32_MIN;
int numdigits = 0;
RNA_BEGIN (op->ptr, itemptr, "files") RNA_BEGIN (op->ptr, itemptr, "files")
{ {
char *filename = NULL, *filename_stripped; char *filename;
int frame; int frame;
/* just get the first filename */ /* just get the first filename */
filename = RNA_string_get_alloc(&itemptr, "name", NULL, 0); filename = RNA_string_get_alloc(&itemptr, "name", NULL, 0);
if (filename) { if (filename) {
bool is_numeric; if (BLI_path_frame_get(filename, &frame, &numdigits)) {
filename_stripped = filename;
/* strip numeric extensions */
while (*filename_stripped && isdigit(*filename_stripped)) {
filename_stripped++;
}
is_numeric = (filename_stripped != filename && *filename_stripped == '.');
if (is_numeric) {
/* was the number really an extension? */
*filename_stripped = 0;
frame = atoi(filename);
minframe = min_ii(minframe, frame); minframe = min_ii(minframe, frame);
maxframe = max_ii(maxframe, frame); maxframe = max_ii(maxframe, frame);
} }
@@ -794,14 +781,15 @@ int sequencer_image_seq_get_minmax_frame(wmOperator *op, int sfra, int *r_minfra
} }
*r_minframe = minframe; *r_minframe = minframe;
*r_numdigits = numdigits;
return maxframe - minframe + 1; return maxframe - minframe + 1;
} }
void sequencer_image_seq_reserve_frames(wmOperator *op, StripElem *se, int len, int minframe) void sequencer_image_seq_reserve_frames(wmOperator *op, StripElem *se, int len, int minframe, int numdigits)
{ {
int i; int i;
char *filename = NULL, *filename_stripped; char *filename = NULL;
RNA_BEGIN (op->ptr, itemptr, "files") RNA_BEGIN (op->ptr, itemptr, "files")
{ {
/* just get the first filename */ /* just get the first filename */
@@ -810,26 +798,16 @@ void sequencer_image_seq_reserve_frames(wmOperator *op, StripElem *se, int len,
} }
RNA_END; RNA_END;
filename_stripped = filename; if (filename) {
char ext[PATH_MAX];
if (filename_stripped) { char filename_stripped[PATH_MAX];
int numlen = 0; /* strip the frame from filename and substitute with # */
BLI_path_frame_strip(filename, true, ext);
/* strip numeric extensions */
while (*filename_stripped && isdigit(*filename_stripped)) {
filename_stripped++;
numlen++;
}
/* was the number really an extension? */
if (*filename_stripped == '.')
filename_stripped++;
else {
filename_stripped = filename;
}
for (i = 0; i < len; i++, se++) { for (i = 0; i < len; i++, se++) {
BLI_snprintf(se->name, sizeof(se->name), "%0*d.%s", numlen, minframe + i, filename_stripped); BLI_strncpy(filename_stripped, filename, sizeof(filename_stripped));
BLI_path_frame(filename_stripped, minframe + i, numdigits);
BLI_snprintf(se->name, sizeof(se->name), "%s%s", filename_stripped, ext);
} }
MEM_freeN(filename); MEM_freeN(filename);
@@ -840,7 +818,7 @@ void sequencer_image_seq_reserve_frames(wmOperator *op, StripElem *se, int len,
/* add image operator */ /* add image operator */
static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op) static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
{ {
int minframe; int minframe, numdigits;
/* cant use the generic function for this */ /* cant use the generic function for this */
Scene *scene = CTX_data_scene(C); /* only for sound */ Scene *scene = CTX_data_scene(C); /* only for sound */
Editing *ed = BKE_sequencer_editing_get(scene, true); Editing *ed = BKE_sequencer_editing_get(scene, true);
@@ -855,7 +833,7 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
/* images are unique in how they handle this - 1 per strip elem */ /* images are unique in how they handle this - 1 per strip elem */
if (use_placeholders) { if (use_placeholders) {
seq_load.len = sequencer_image_seq_get_minmax_frame(op, seq_load.start_frame, &minframe); seq_load.len = sequencer_image_seq_get_minmax_frame(op, seq_load.start_frame, &minframe, &numdigits);
} }
else { else {
seq_load.len = RNA_property_collection_length(op->ptr, RNA_struct_find_property(op->ptr, "files")); seq_load.len = RNA_property_collection_length(op->ptr, RNA_struct_find_property(op->ptr, "files"));
@@ -873,7 +851,7 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
se = strip->stripdata; se = strip->stripdata;
if (use_placeholders) { if (use_placeholders) {
sequencer_image_seq_reserve_frames(op, se, seq_load.len, minframe); sequencer_image_seq_reserve_frames(op, se, seq_load.len, minframe, numdigits);
} }
else { else {
RNA_BEGIN (op->ptr, itemptr, "files") RNA_BEGIN (op->ptr, itemptr, "files")

View File

@@ -3695,7 +3695,7 @@ static int sequencer_change_path_exec(bContext *C, wmOperator *op)
Sequence *seq = BKE_sequencer_active_get(scene); Sequence *seq = BKE_sequencer_active_get(scene);
const bool is_relative_path = RNA_boolean_get(op->ptr, "relative_path"); const bool is_relative_path = RNA_boolean_get(op->ptr, "relative_path");
const bool use_placeholders = RNA_boolean_get(op->ptr, "use_placeholders"); const bool use_placeholders = RNA_boolean_get(op->ptr, "use_placeholders");
int minframe; int minframe, numdigits;
if (seq->type == SEQ_TYPE_IMAGE) { if (seq->type == SEQ_TYPE_IMAGE) {
char directory[FILE_MAX]; char directory[FILE_MAX];
@@ -3704,7 +3704,7 @@ static int sequencer_change_path_exec(bContext *C, wmOperator *op)
/* need to find min/max frame for placeholders */ /* need to find min/max frame for placeholders */
if (use_placeholders) { if (use_placeholders) {
len = sequencer_image_seq_get_minmax_frame(op, seq->sfra, &minframe); len = sequencer_image_seq_get_minmax_frame(op, seq->sfra, &minframe, &numdigits);
} }
else { else {
len = RNA_property_collection_length(op->ptr, RNA_struct_find_property(op->ptr, "files")); len = RNA_property_collection_length(op->ptr, RNA_struct_find_property(op->ptr, "files"));
@@ -3727,7 +3727,7 @@ static int sequencer_change_path_exec(bContext *C, wmOperator *op)
seq->strip->stripdata = se = MEM_callocN(len * sizeof(StripElem), "stripelem"); seq->strip->stripdata = se = MEM_callocN(len * sizeof(StripElem), "stripelem");
if (use_placeholders) { if (use_placeholders) {
sequencer_image_seq_reserve_frames(op, se, len, minframe); sequencer_image_seq_reserve_frames(op, se, len, minframe, numdigits);
} }
else { else {
RNA_BEGIN (op->ptr, itemptr, "files") RNA_BEGIN (op->ptr, itemptr, "files")

View File

@@ -205,8 +205,8 @@ void SEQUENCER_OT_sample(struct wmOperatorType *ot);
void sequencer_preview_add_sound(const struct bContext *C, struct Sequence *seq); void sequencer_preview_add_sound(const struct bContext *C, struct Sequence *seq);
/* sequencer_add */ /* sequencer_add */
int sequencer_image_seq_get_minmax_frame(struct wmOperator *op, int sfra, int *r_minframe); int sequencer_image_seq_get_minmax_frame(struct wmOperator *op, int sfra, int *r_minframe, int *r_numdigits);
void sequencer_image_seq_reserve_frames(struct wmOperator *op, struct StripElem *se, int len, int minframe); void sequencer_image_seq_reserve_frames(struct wmOperator *op, struct StripElem *se, int len, int minframe, int numdigits);
#endif /* __SEQUENCER_INTERN_H__ */ #endif /* __SEQUENCER_INTERN_H__ */