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:
@@ -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_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_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_cwd(char *path) ATTR_NONNULL();
|
||||
void BLI_path_rel(char *file, const char *relfile) ATTR_NONNULL();
|
||||
|
@@ -858,6 +858,111 @@ bool BLI_path_frame_range(char *path, int sta, int end, int digits)
|
||||
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
|
||||
*/
|
||||
|
@@ -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");
|
||||
}
|
||||
|
||||
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 numdigits = 0;
|
||||
|
||||
RNA_BEGIN (op->ptr, itemptr, "files")
|
||||
{
|
||||
char *filename = NULL, *filename_stripped;
|
||||
char *filename;
|
||||
int frame;
|
||||
/* just get the first filename */
|
||||
filename = RNA_string_get_alloc(&itemptr, "name", NULL, 0);
|
||||
|
||||
if (filename) {
|
||||
bool is_numeric;
|
||||
|
||||
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);
|
||||
if (BLI_path_frame_get(filename, &frame, &numdigits)) {
|
||||
minframe = min_ii(minframe, 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_numdigits = numdigits;
|
||||
|
||||
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;
|
||||
char *filename = NULL, *filename_stripped;
|
||||
char *filename = NULL;
|
||||
RNA_BEGIN (op->ptr, itemptr, "files")
|
||||
{
|
||||
/* just get the first filename */
|
||||
@@ -810,26 +798,16 @@ void sequencer_image_seq_reserve_frames(wmOperator *op, StripElem *se, int len,
|
||||
}
|
||||
RNA_END;
|
||||
|
||||
filename_stripped = filename;
|
||||
|
||||
if (filename_stripped) {
|
||||
int numlen = 0;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
if (filename) {
|
||||
char ext[PATH_MAX];
|
||||
char filename_stripped[PATH_MAX];
|
||||
/* strip the frame from filename and substitute with # */
|
||||
BLI_path_frame_strip(filename, true, ext);
|
||||
|
||||
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);
|
||||
@@ -840,7 +818,7 @@ void sequencer_image_seq_reserve_frames(wmOperator *op, StripElem *se, int len,
|
||||
/* add image operator */
|
||||
static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
int minframe;
|
||||
int minframe, numdigits;
|
||||
/* cant use the generic function for this */
|
||||
Scene *scene = CTX_data_scene(C); /* only for sound */
|
||||
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 */
|
||||
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 {
|
||||
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;
|
||||
|
||||
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 {
|
||||
RNA_BEGIN (op->ptr, itemptr, "files")
|
||||
|
@@ -3695,7 +3695,7 @@ static int sequencer_change_path_exec(bContext *C, wmOperator *op)
|
||||
Sequence *seq = BKE_sequencer_active_get(scene);
|
||||
const bool is_relative_path = RNA_boolean_get(op->ptr, "relative_path");
|
||||
const bool use_placeholders = RNA_boolean_get(op->ptr, "use_placeholders");
|
||||
int minframe;
|
||||
int minframe, numdigits;
|
||||
|
||||
if (seq->type == SEQ_TYPE_IMAGE) {
|
||||
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 */
|
||||
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 {
|
||||
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");
|
||||
|
||||
if (use_placeholders) {
|
||||
sequencer_image_seq_reserve_frames(op, se, len, minframe);
|
||||
sequencer_image_seq_reserve_frames(op, se, len, minframe, numdigits);
|
||||
}
|
||||
else {
|
||||
RNA_BEGIN (op->ptr, itemptr, "files")
|
||||
|
@@ -205,8 +205,8 @@ void SEQUENCER_OT_sample(struct wmOperatorType *ot);
|
||||
void sequencer_preview_add_sound(const struct bContext *C, struct Sequence *seq);
|
||||
|
||||
/* sequencer_add */
|
||||
int sequencer_image_seq_get_minmax_frame(struct wmOperator *op, int sfra, int *r_minframe);
|
||||
void sequencer_image_seq_reserve_frames(struct wmOperator *op, struct StripElem *se, int len, int 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, int numdigits);
|
||||
|
||||
#endif /* __SEQUENCER_INTERN_H__ */
|
||||
|
||||
|
Reference in New Issue
Block a user