[Bf-blender-cvs] [ccee251] master: Support for loading multiple images from the file selector

Campbell Barton noreply at git.blender.org
Fri Jul 15 08:03:05 CEST 2016


Commit: ccee251a40f985492cffe3eac905a6b50e751d72
Author: Campbell Barton
Date:   Fri Jul 15 16:02:46 2016 +1000
Branches: master
https://developer.blender.org/rBccee251a40f985492cffe3eac905a6b50e751d72

Support for loading multiple images from the file selector

D2035 by @jside, extended to support mixing single images and sequences in the one selection.

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

M	source/blender/editors/space_image/image_ops.c

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

diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 06caf93..1538842 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1061,6 +1061,12 @@ typedef struct ImageOpenData {
 	ImageFormatData im_format;
 } ImageOpenData;
 
+typedef struct ImageFrameRange {
+	struct ImageFrameRange *next, *prev;
+	ListBase frames;
+	char filepath[FILE_MAX];
+} ImageFrameRange;
+
 typedef struct ImageFrame {
 	struct ImageFrame *next, *prev;
 	int framenr;
@@ -1086,10 +1092,10 @@ static void image_open_cancel(bContext *UNUSED(C), wmOperator *op)
  * \param frames [out] the list of frame numbers found in the files matching the first one by name
  * \param path [out] the full path of the first file in the list of image files
  */
-static void image_sequence_get_frames(PointerRNA *ptr, ListBase *frames, char *path, const size_t maxlen)
+static void image_sequence_get_frame_ranges(PointerRNA *ptr, ListBase *frames_all)
 {
 	char dir[FILE_MAXDIR];
-	bool is_first_entry = true;
+	ImageFrameRange *frame_range = NULL;
 
 	RNA_string_get(ptr, "directory", dir);
 	RNA_BEGIN (ptr, itemptr, "files")
@@ -1101,29 +1107,26 @@ static void image_sequence_get_frames(PointerRNA *ptr, ListBase *frames, char *p
 		ImageFrame *frame = MEM_callocN(sizeof(ImageFrame), "image_frame");
 
 		/* use the first file in the list as base filename */
-		if (is_first_entry) {
-			BLI_join_dirfile(path, maxlen, dir, filename);
-			frame->framenr = BLI_stringdec(filename, base_head, base_tail, &digits);
-			BLI_addtail(frames, frame);
-			is_first_entry = false;
+		frame->framenr = BLI_stringdec(filename, head, tail, &digits);
+
+		/* still in the same sequence */
+		if ((frame_range != NULL) &&
+		    (STREQLEN(base_head, head, FILE_MAX)) &&
+		    (STREQLEN(base_tail, tail, FILE_MAX)))
+		{
+			/* pass */
 		}
 		else {
-			frame->framenr = BLI_stringdec(filename, head, tail, &digits);
+			/* 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);
 
-			/* still in the same sequence */
-			if ((STREQLEN(base_head, head, FILE_MAX)) &&
-			    (STREQLEN(base_tail, tail, FILE_MAX)))
-			{
-				BLI_addtail(frames, frame);
-			}
-			else {
-				/* different file base name found, is ignored */
-				MEM_freeN(filename);
-				MEM_freeN(frame);
-				break;
-			}
+			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
@@ -1164,6 +1167,52 @@ static int image_sequence_get_len(ListBase *frames, int *ofs)
 	return 0;
 }
 
+static Image *image_open_single(
+        wmOperator *op, const char *filepath, const char *relbase,
+        bool is_relative_path, bool use_multiview, int frame_seq_len)
+{
+	bool exists = false;
+	Image *ima = NULL;
+
+	errno = 0;
+	ima = BKE_image_load_exists_ex(filepath, &exists);
+
+	if (!ima) {
+		if (op->customdata) MEM_freeN(op->customdata);
+		BKE_reportf(op->reports, RPT_ERROR, "Cannot read '%s': %s",
+		            filepath, errno ? strerror(errno) : TIP_("unsupported image format"));
+		return NULL;
+	}
+
+	if (!exists) {
+		/* only image path after save, never ibuf */
+		if (is_relative_path) {
+			BLI_path_rel(ima->name, relbase);
+		}
+
+		/* handle multiview images */
+		if (use_multiview) {
+			ImageOpenData *iod = op->customdata;
+			ImageFormatData *imf = &iod->im_format;
+
+			ima->flag |= IMA_USE_VIEWS;
+			ima->views_format = imf->views_format;
+			*ima->stereo3d_format = imf->stereo3d_format;
+		}
+		else {
+			ima->flag &= ~IMA_USE_VIEWS;
+			BKE_image_free_views(ima);
+		}
+
+		if ((frame_seq_len > 1) && (ima->source == IMA_SRC_FILE)) {
+			ima->source = IMA_SRC_SEQUENCE;
+		}
+	}
+
+	return ima;
+}
+
+
 static int image_open_exec(bContext *C, wmOperator *op)
 {
 	Main *bmain = CTX_data_main(C);
@@ -1174,70 +1223,60 @@ static int image_open_exec(bContext *C, wmOperator *op)
 	ImageOpenData *iod = op->customdata;
 	PointerRNA idptr;
 	Image *ima = NULL;
-	char path[FILE_MAX];
+	char filepath[FILE_MAX];
 	int frame_seq_len = 0;
 	int frame_ofs = 1;
-	bool exists = false;
 
 	const bool is_relative_path = RNA_boolean_get(op->ptr, "relative_path");
+	const bool use_multiview    = RNA_boolean_get(op->ptr, "use_multiview");
 
-	RNA_string_get(op->ptr, "filepath", path);
+	if (!op->customdata)
+		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"))
 	{
-		/* only to pass to imbuf */
-		char path_full[FILE_MAX];
-		BLI_strncpy(path_full, path, sizeof(path_full));
-		BLI_path_abs(path_full, G.main->name);
+		bool was_relative = BLI_path_is_rel(filepath);
+		ListBase frame_ranges_all;
 
-		if (!IMB_isanim(path_full)) {
-			bool was_relative = BLI_path_is_rel(path);
-			ListBase frames;
+		BLI_listbase_clear(&frame_ranges_all);
+		image_sequence_get_frame_ranges(op->ptr, &frame_ranges_all);
+		for (ImageFrameRange *frame_range = frame_ranges_all.first; frame_range; frame_range = frame_range->next) {
+			int frame_range_ofs;
+			int frame_range_seq_len = image_sequence_get_len(&frame_range->frames, &frame_range_ofs);
+			BLI_freelistN(&frame_range->frames);
 
-			BLI_listbase_clear(&frames);
-			image_sequence_get_frames(op->ptr, &frames, path, sizeof(path));
-			frame_seq_len = image_sequence_get_len(&frames, &frame_ofs);
-			BLI_freelistN(&frames);
+			char filepath_range[FILE_MAX];
+			BLI_strncpy(filepath_range, frame_range->filepath, sizeof(filepath_range));
 
 			if (was_relative) {
-				BLI_path_rel(path, G.main->name);
+				BLI_path_rel(filepath_range, bmain->name);
 			}
-		}
-	}
-
-	errno = 0;
 
-	ima = BKE_image_load_exists_ex(path, &exists);
+			Image *ima_range = image_open_single(
+			         op, filepath_range, bmain->name,
+			         is_relative_path, use_multiview, frame_range_seq_len);
 
-	if (!ima) {
-		if (op->customdata) MEM_freeN(op->customdata);
-		BKE_reportf(op->reports, RPT_ERROR, "Cannot read '%s': %s",
-		            path, errno ? strerror(errno) : TIP_("unsupported image format"));
-		return OPERATOR_CANCELLED;
-	}
-
-	if (!op->customdata)
-		image_open_init(C, op);
-
-	/* handle multiview images */
-	if (RNA_boolean_get(op->ptr, "use_multiview")) {
-		ImageFormatData *imf = &iod->im_format;
-
-		ima->flag |= IMA_USE_VIEWS;
-		ima->views_format = imf->views_format;
-		*ima->stereo3d_format = imf->stereo3d_format;
+			/* take the first image */
+			if ((ima == NULL) && ima_range) {
+				ima = ima_range;
+				frame_seq_len = frame_range_seq_len;
+				frame_ofs = frame_range_ofs;
+			}
+		}
+		BLI_freelistN(&frame_ranges_all);
 	}
 	else {
-		ima->flag &= ~IMA_USE_VIEWS;
-		BKE_image_free_views(ima);
+		/* for drag & drop etc. */
+		ima = image_open_single(
+		        op, filepath, bmain->name,
+		        is_relative_path, use_multiview, 1);
 	}
 
-	/* only image path after save, never ibuf */
-	if (is_relative_path) {
-		if (!exists) {
-			BLI_path_rel(ima->name, bmain->name);
-		}
+	if (ima == NULL) {
+		return OPERATOR_CANCELLED;
 	}
 
 	/* hook into UI */
@@ -1245,11 +1284,8 @@ static int image_open_exec(bContext *C, wmOperator *op)
 
 	if (iod->pprop.prop) {
 		/* when creating new ID blocks, use is already 1, but RNA
-		 * pointer se also increases user, so this compensates it */
+		 * pointer also increases user, so this compensates it */
 		id_us_min(&ima->id);
-		if ((frame_seq_len > 1) && ima->source == IMA_SRC_FILE) {
-			ima->source = IMA_SRC_SEQUENCE;
-		}
 		RNA_id_pointer_create(&ima->id, &idptr);
 		RNA_property_pointer_set(&iod->pprop.ptr, iod->pprop.prop, idptr);
 		RNA_property_update(C, &iod->pprop.ptr, iod->pprop.prop);




More information about the Bf-blender-cvs mailing list