[Bf-blender-cvs] [bdbcb0df106] master: Image Editor: Load UDIMs even if secondary tile is selected

Lukas Stockner noreply at git.blender.org
Wed Dec 18 01:52:39 CET 2019


Commit: bdbcb0df1060e3c8a331f929848dee70ca0d5f38
Author: Lukas Stockner
Date:   Wed Dec 18 01:47:48 2019 +0100
Branches: master
https://developer.blender.org/rBbdbcb0df1060e3c8a331f929848dee70ca0d5f38

Image Editor: Load UDIMs even if secondary tile is selected

Previously the user had to select the 1001 tile for this to work,
now any tile will work as long as the 1001 tile still exists on disk.

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

M	source/blender/blenlib/BLI_path_util.h
M	source/blender/blenlib/intern/path_util.c
M	source/blender/editors/space_image/image_ops.c

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

diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h
index 75d5cb286ac..d2f651609f1 100644
--- a/source/blender/blenlib/BLI_path_util.h
+++ b/source/blender/blenlib/BLI_path_util.h
@@ -81,6 +81,12 @@ bool BLI_ensure_filename(char *filepath, size_t maxlen, const char *filename) AT
 int BLI_stringdec(const char *string, char *head, char *start, unsigned short *numlen);
 void BLI_stringenc(
     char *string, const char *head, const char *tail, unsigned short numlen, int pic);
+void BLI_stringenc_path(char *string,
+                        const char *dir,
+                        const char *head,
+                        const char *tail,
+                        unsigned short numlen,
+                        int pic);
 
 /* removes trailing slash */
 void BLI_cleanup_file(const char *relabase, char *path) ATTR_NONNULL(2);
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index dff1f77c1ab..cd1a0e2c328 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -157,6 +157,20 @@ void BLI_stringenc(
   sprintf(string, "%s%.*d%s", head, numlen, MAX2(0, pic), tail);
 }
 
+/**
+ * Returns in area pointed to by string a string of the form "<dir><head><pic><tail>", where pic
+ * is formatted as numlen digits with leading zeroes.
+ */
+void BLI_stringenc_path(char *string,
+                        const char *dir,
+                        const char *head,
+                        const char *tail,
+                        unsigned short numlen,
+                        int pic)
+{
+  sprintf(string, "%s%s%.*d%s", dir, head, numlen, MAX2(0, pic), tail);
+}
+
 static int BLI_path_unc_prefix_len(const char *path); /* defined below in same file */
 
 /* ******************** string encoding ***************** */
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 04d5661ca77..9b091979f1e 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1267,49 +1267,61 @@ static int image_cmp_frame(const void *a, const void *b)
   return 0;
 }
 
-static int image_get_udim(const char *filepath, LinkNodePair *udim_tiles)
+/* 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));
 
-  if (strstr(filename, "1001") == NULL) {
+  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;
 
-  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) {
-    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;
-      }
+  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 (id < 1001 || id >= 2000) {
-        is_udim = false;
-        break;
-      }
+    if (digits > 4 || !(STREQLEN(base_head, head, FILE_MAX)) ||
+        !(STREQLEN(base_tail, tail, FILE_MAX))) {
+      continue;
+    }
 
-      BLI_linklist_append(udim_tiles, POINTER_FROM_INT(id));
-      max_udim = max_ii(max_udim, id);
+    if (id < 1001 || id >= IMA_UDIM_MAX) {
+      is_udim = false;
+      break;
+    }
+    if (id == 1001) {
+      has_primary = true;
     }
 
-    BLI_filelist_free(dir, totfile);
+    BLI_linklist_append(udim_tiles, POINTER_FROM_INT(id));
+    max_udim = max_ii(max_udim, id);
   }
+  BLI_filelist_free(dir, totfile);
 
-  return is_udim ? (max_udim - 1001) : 0;
+  if (is_udim && has_primary) {
+    BLI_stringenc_path(filepath, dirname, base_head, base_tail, digits, 1001);
+    return max_udim - 1000;
+  }
+  return 0;
 }
 
 /**
@@ -1320,27 +1332,34 @@ static int image_get_udim(const char *filepath, LinkNodePair *udim_tiles)
  * \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, LinkNodePair *udim_tiles)
+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 && (frame_curr == 1001)) {
-      return 1 + image_get_udim(frame_range->filepath, udim_tiles);
-    }
-    else {
-      while (frame != NULL && (frame->framenr == frame_curr)) {
-        frame_curr++;
-        frame = frame->next;
+    if (udim_tiles != NULL) {
+      int len_udim = image_get_udim(filepath_range, udim_tiles);
+      if (len_udim > 0) {
+        *ofs = 1001;
+        return len_udim;
       }
-      return frame_curr - (*ofs);
     }
+
+    while (frame != NULL && (frame->framenr == frame_curr)) {
+      frame_curr++;
+      frame = frame->next;
+    }
+    return frame_curr - (*ofs);
   }
   *ofs = 0;
   return 0;
@@ -1422,7 +1441,6 @@ static int image_open_exec(bContext *C, wmOperator *op)
   char filepath[FILE_MAX];
   int frame_seq_len = 0;
   int frame_ofs = 1;
-  LinkNodePair udim_tiles = {NULL};
 
   const bool is_relative_path = RNA_boolean_get(op->ptr, "relative_path");
   const bool use_multiview = RNA_boolean_get(op->ptr, "use_multiview");
@@ -1445,13 +1463,13 @@ static int image_open_exec(bContext *C, wmOperator *op)
          frame_range = frame_range->next) {
       int frame_range_ofs;
 
+      LinkNodePair udim_tiles = {NULL};
       LinkNodePair *udim_tiles_ptr = use_udim ? (&udim_tiles) : NULL;
-      int frame_range_seq_len = image_sequence_get_len(
-          frame_range, &frame_range_ofs, udim_tiles_ptr);
-      BLI_freelistN(&frame_range->frames);
 
       char filepath_range[FILE_MAX];
-      BLI_strncpy(filepath_range, frame_range->filepath, sizeof(filepath_range));
+      int frame_range_seq_len = image_sequence_get_len(
+          frame_range, &frame_range_ofs, filepath_range, udim_tiles_ptr);
+      BLI_freelistN(&frame_range->frames);
 
       if (was_relative) {
         BLI_path_rel(filepath_range, BKE_main_blendfile_path(bmain));
@@ -1473,35 +1491,42 @@ static int image_open_exec(bContext *C, wmOperator *op)
         frame_seq_len = frame_range_seq_len;
         frame_ofs = frame_range_ofs;
       }
+
+      BLI_linklist_free(udim_tiles.list, NULL);
     }
     BLI_freelistN(&frame_ranges_all);
   }
   else {
     /* for drag & drop etc. */
+
+    LinkNodePair udim_tiles = {NULL};
     frame_seq_len = 1;
+    char filepath_range[FILE_MAX];
+    BLI_strncpy(filepath_range, filepath, FILE_MAX);
 
-    if (use_udim) {
+    if (use_udim > 0) {
       /* Try to find UDIM tiles corresponding to the image */
-      frame_seq_len = 1 + image_get_udim(filepath, &udim_tiles);
+      int udim_len = image_get_udim(filepath_range, &udim_tiles);
 
       /* If we found something, mark the image as tiled. */
-      if (frame_seq_len > 1) {
+      if (udim_len) {
+        frame_seq_len = udim_len;
         frame_ofs = 1001;
       }
     }
 
     ima = image_open_single(bmain,
                             op,
-                            filepath,
+                            filepath_range,
                             BKE_main_blendfile_path(bmain),
                             is_relative_path,
                             use_multiview,
                             frame_seq_len,
                             frame_ofs,
                             &udim_tiles);
-  }
 
-  BLI_linklist_free(udim_tiles.list, NULL);
+    BLI_linklist_free(udim_tiles.list, NULL);
+  }
 
   if (ima == NULL) {
     return OPERATOR_CANCELLED;



More information about the Bf-blender-cvs mailing list