[Bf-blender-cvs] [da38cb622e0] master: Cleanup: split image sequence detection into own file, and make it reusable

Brecht Van Lommel noreply at git.blender.org
Wed Feb 26 19:26:04 CET 2020


Commit: da38cb622e0f2e6389fee3ffb148ca77b5979014
Author: Brecht Van Lommel
Date:   Fri Feb 7 00:01:50 2020 +0100
Branches: master
https://developer.blender.org/rBda38cb622e0f2e6389fee3ffb148ca77b5979014

Cleanup: split image sequence detection into own file, and make it reusable

===================================================================

M	source/blender/editors/include/ED_image.h
M	source/blender/editors/space_image/CMakeLists.txt
M	source/blender/editors/space_image/image_ops.c
A	source/blender/editors/space_image/image_sequence.c

===================================================================

diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h
index e6d8684a8b2..d78c2620253 100644
--- a/source/blender/editors/include/ED_image.h
+++ b/source/blender/editors/include/ED_image.h
@@ -24,15 +24,21 @@
 #ifndef __ED_IMAGE_H__
 #define __ED_IMAGE_H__
 
+#include "DNA_listBase.h"
+#include "DNA_space_types.h"
+
 struct ARegion;
 struct ImBuf;
 struct Image;
 struct ImageUser;
+struct LinkNodePair;
+struct Main;
 struct ReportList;
 struct Scene;
 struct SpaceImage;
 struct ViewLayer;
 struct bContext;
+struct wmOperator;
 struct wmWindowManager;
 
 /* image_edit.c, exported for transform */
@@ -116,4 +122,24 @@ bool ED_image_should_save_modified(const struct bContext *C);
 int ED_image_save_all_modified_info(const struct bContext *C, struct ReportList *reports);
 bool ED_image_save_all_modified(const struct bContext *C, struct ReportList *reports);
 
+/* image_sequence.c */
+typedef struct ImageFrameRange {
+  struct ImageFrameRange *next, *prev;
+
+  /** Absolute file path of the first file in the range. */
+  char filepath[FILE_MAX];
+  /* Sequence parameters. */
+  int length;
+  int offset;
+  /* UDIM tiles. */
+  ListBase udim_tiles;
+
+  /* Temporary data. */
+  ListBase frames;
+} ImageFrameRange;
+
+ListBase ED_image_filesel_detect_sequences(struct Main *bmain,
+                                           struct wmOperator *op,
+                                           const bool detect_udim);
+
 #endif /* __ED_IMAGE_H__ */
diff --git a/source/blender/editors/space_image/CMakeLists.txt b/source/blender/editors/space_image/CMakeLists.txt
index 5abcff436f1..12de74c6ae7 100644
--- a/source/blender/editors/space_image/CMakeLists.txt
+++ b/source/blender/editors/space_image/CMakeLists.txt
@@ -43,6 +43,7 @@ set(SRC
   image_draw.c
   image_edit.c
   image_ops.c
+  image_sequence.c
   image_undo.c
   space_image.c
 
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index a3fa03b18b7..fe1cb1ead9e 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1207,18 +1207,6 @@ typedef struct ImageOpenData {
   ImageFormatData im_format;
 } ImageOpenData;
 
-typedef struct ImageFrameRange {
-  struct ImageFrameRange *next, *prev;
-  ListBase frames;
-  /**  The full path of the first file in the list of image files */
-  char filepath[FILE_MAX];
-} ImageFrameRange;
-
-typedef struct ImageFrame {
-  struct ImageFrame *next, *prev;
-  int framenr;
-} ImageFrame;
-
 static void image_open_init(bContext *C, wmOperator *op)
 {
   ImageOpenData *iod;
@@ -1233,179 +1221,18 @@ static void image_open_cancel(bContext *UNUSED(C), wmOperator *op)
   op->customdata = NULL;
 }
 
-/**
- * Get a list of frames from the list of image files matching the first file name sequence pattern.
- * \param ptr[in]: The RNA pointer containing the "directory" entry and "files" collection.
- * \param frames_all[out]: the list of frame numbers found in the files matching
- * the first one by name.
- */
-static void image_sequence_get_frame_ranges(PointerRNA *ptr, ListBase *frames_all)
-{
-  char dir[FILE_MAXDIR];
-  const bool do_frame_range = RNA_boolean_get(ptr, "use_sequence_detection");
-  ImageFrameRange *frame_range = NULL;
-
-  RNA_string_get(ptr, "directory", dir);
-  RNA_BEGIN (ptr, itemptr, "files") {
-    char base_head[FILE_MAX], base_tail[FILE_MAX];
-    char head[FILE_MAX], tail[FILE_MAX];
-    unsigned short digits;
-    char *filename = RNA_string_get_alloc(&itemptr, "name", NULL, 0);
-    ImageFrame *frame = MEM_callocN(sizeof(ImageFrame), "image_frame");
-
-    /* use the first file in the list as base filename */
-    frame->framenr = BLI_stringdec(filename, head, tail, &digits);
-
-    /* still in the same sequence */
-    if (do_frame_range && (frame_range != NULL) && (STREQLEN(base_head, head, FILE_MAX)) &&
-        (STREQLEN(base_tail, tail, FILE_MAX))) {
-      /* pass */
-    }
-    else {
-      /* start a new frame range */
-      frame_range = MEM_callocN(sizeof(*frame_range), __func__);
-      BLI_join_dirfile(frame_range->filepath, sizeof(frame_range->filepath), dir, filename);
-      BLI_addtail(frames_all, frame_range);
-
-      BLI_strncpy(base_head, head, sizeof(base_head));
-      BLI_strncpy(base_tail, tail, sizeof(base_tail));
-    }
-
-    BLI_addtail(&frame_range->frames, frame);
-    MEM_freeN(filename);
-  }
-  RNA_END;
-}
-
-static int image_cmp_frame(const void *a, const void *b)
-{
-  const ImageFrame *frame_a = a;
-  const ImageFrame *frame_b = b;
-
-  if (frame_a->framenr < frame_b->framenr) {
-    return -1;
-  }
-  if (frame_a->framenr > frame_b->framenr) {
-    return 1;
-  }
-  return 0;
-}
-
-/* Checks whether the given filepath refers to a UDIM texture.
- * If yes, the range from 1001 to the highest tile is returned, otherwise 0.
- *
- * If the result is positive, the filepath will be overwritten with that of
- * the 1001 tile.
- * udim_tiles may get filled even if the result ultimately is false! */
-static int image_get_udim(char *filepath, LinkNodePair *udim_tiles)
-{
-  char filename[FILE_MAX], dirname[FILE_MAXDIR];
-  BLI_split_dirfile(filepath, dirname, filename, sizeof(dirname), sizeof(filename));
-
-  unsigned short digits;
-  char base_head[FILE_MAX], base_tail[FILE_MAX];
-  int id = BLI_stringdec(filename, base_head, base_tail, &digits);
-
-  if (id < 1001 || id >= IMA_UDIM_MAX) {
-    return 0;
-  }
-
-  bool is_udim = true;
-  bool has_primary = false;
-  int max_udim = 0;
-
-  struct direntry *dir;
-  uint totfile = BLI_filelist_dir_contents(dirname, &dir);
-  for (int i = 0; i < totfile; i++) {
-    if (!(dir[i].type & S_IFREG)) {
-      continue;
-    }
-    char head[FILE_MAX], tail[FILE_MAX];
-    id = BLI_stringdec(dir[i].relname, head, tail, &digits);
-
-    if (digits > 4 || !(STREQLEN(base_head, head, FILE_MAX)) ||
-        !(STREQLEN(base_tail, tail, FILE_MAX))) {
-      continue;
-    }
-
-    if (id < 1001 || id >= IMA_UDIM_MAX) {
-      is_udim = false;
-      break;
-    }
-    if (id == 1001) {
-      has_primary = true;
-    }
-
-    BLI_linklist_append(udim_tiles, POINTER_FROM_INT(id));
-    max_udim = max_ii(max_udim, id);
-  }
-  BLI_filelist_free(dir, totfile);
-
-  if (is_udim && has_primary) {
-    char primary_filename[FILE_MAX];
-    BLI_stringenc(primary_filename, base_head, base_tail, digits, 1001);
-    BLI_join_dirfile(filepath, FILE_MAX, dirname, primary_filename);
-    return max_udim - 1000;
-  }
-  return 0;
-}
-
-/**
- * Return the start (offset) and the length of the sequence of
- * continuous frames in the list of frames.
- *
- * \param frames: [in] the list of frame numbers, as a side-effect the list is sorted.
- * \param ofs: [out] offset the first frame number in the sequence.
- * \return the number of contiguous frames in the sequence
- */
-static int image_sequence_get_len(ImageFrameRange *frame_range,
-                                  int *ofs,
-                                  char *filepath_range,
-                                  LinkNodePair *udim_tiles)
-{
-  ImageFrame *frame;
-
-  BLI_listbase_sort(&frame_range->frames, image_cmp_frame);
-  BLI_strncpy(filepath_range, frame_range->filepath, FILE_MAX);
-
-  frame = frame_range->frames.first;
-  if (frame != NULL) {
-    int frame_curr = frame->framenr;
-    (*ofs) = frame_curr;
-
-    if (udim_tiles != NULL) {
-      int len_udim = image_get_udim(filepath_range, udim_tiles);
-      if (len_udim > 0) {
-        *ofs = 1001;
-        return len_udim;
-      }
-    }
-
-    while (frame != NULL && (frame->framenr == frame_curr)) {
-      frame_curr++;
-      frame = frame->next;
-    }
-    return frame_curr - (*ofs);
-  }
-  *ofs = 0;
-  return 0;
-}
-
 static Image *image_open_single(Main *bmain,
                                 wmOperator *op,
-                                const char *filepath,
+                                ImageFrameRange *range,
                                 const char *relbase,
                                 bool is_relative_path,
-                                bool use_multiview,
-                                int frame_seq_len,
-                                int frame_seq_ofs,
-                                LinkNodePair *udim_tiles)
+                                bool use_multiview)
 {
   bool exists = false;
   Image *ima = NULL;
 
   errno = 0;
-  ima = BKE_image_load_exists_ex(bmain, filepath, &exists);
+  ima = BKE_image_load_exists_ex(bmain, range->filepath, &exists);
 
   if (!ima) {
     if (op->customdata) {
@@ -1414,7 +1241,7 @@ static Image *image_open_single(Main *bmain,
     BKE_reportf(op->reports,
                 RPT_ERROR,
                 "Cannot read '%s': %s",
-                filepath,
+                range->filepath,
                 errno ? strerror(errno) : TIP_("unsupported image format"));
     return NULL;
   }
@@ -1439,11 +1266,11 @@ static Image *image_open_single(Main *bmain,
       BKE_image_free_views(ima);
     }
 
-    if ((frame_seq_len > 1) && (ima->source == IMA_SRC_FILE)) {
-      if (udim_tiles && frame_seq_ofs == 1001) {
+    if ((range->length > 1) && (ima->source == IMA_SRC_FILE)) {
+      if (range->udim_tiles.first && range->offset == 1001) {
         ima->source = IMA_SRC_TILED;
-        for (LinkNode *node = udim_tiles->list; node; node = node->next) {
-          BKE_image_add_tile(ima, POINTER_AS_INT(node->link), NULL);
+        for (LinkData *node = range->udim_tiles.first; node; node = node->next) {
+          BKE_image_add_tile(ima, POINTER_AS_INT(node->data), NULL);
         }
       }
       else {
@@ -1464,7 +1291,6 @@ static int image_open_exec(bContext *C, wmOperator *op)
   ImageUser *iuser = NULL;
   ImageOpenData *iod = op->customdata;
   Image *ima = NULL;
-  char filepath[FILE_MAX];
   int frame_seq_len = 0;
   int frame_ofs = 1;
 
@@ -1476,83 +1302,21 @@ static int image_open_exec(bContext *C, wmOperator *op)
     image_open_init(C, op);
   }
 
-  RNA_string_get(op->ptr, "filepath", filepath);
-
-  if (RNA_struct_property_is_set(op->ptr, "directory") &&
-      RNA_struct_property_is_set(op->ptr, "files")) {
-    bool was_relative = BLI_path_is_rel(filep

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list