Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_image')
-rw-r--r--source/blender/editors/space_image/image_buttons.c71
-rw-r--r--source/blender/editors/space_image/image_ops.c175
2 files changed, 155 insertions, 91 deletions
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index a2db6827b0e..38a54ade367 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -345,6 +345,13 @@ struct ImageUI_Data {
int rpass_index;
};
+static struct ImageUI_Data *ui_imageuser_data_copy(const struct ImageUI_Data *rnd_pt_src)
+{
+ struct ImageUI_Data *rnd_pt_dst = MEM_mallocN(sizeof(*rnd_pt_src), __func__);
+ memcpy(rnd_pt_dst, rnd_pt_src, sizeof(*rnd_pt_src));
+ return rnd_pt_dst;
+}
+
static void ui_imageuser_layer_menu(bContext *UNUSED(C), uiLayout *layout, void *rnd_pt)
{
struct ImageUI_Data *rnd_data = rnd_pt;
@@ -532,9 +539,10 @@ static void ui_imageuser_view_menu_multiview(bContext *UNUSED(C), uiLayout *layo
}
/* 5 layer button callbacks... */
-static void image_multi_cb(bContext *C, void *rr_v, void *iuser_v)
+static void image_multi_cb(bContext *C, void *rnd_pt, void *rr_v)
{
- ImageUser *iuser = iuser_v;
+ struct ImageUI_Data *rnd_data = rnd_pt;
+ ImageUser *iuser = rnd_data->iuser;
BKE_image_multilayer_index(rr_v, iuser);
WM_event_add_notifier(C, NC_IMAGE | ND_DRAW, NULL);
@@ -575,6 +583,8 @@ static bool ui_imageuser_layer_menu_step(bContext *C, int direction, void *rnd_p
BLI_assert(0);
}
+ BKE_image_release_renderresult(scene, image);
+
if (changed) {
BKE_image_multilayer_index(rr, iuser);
WM_event_add_notifier(C, NC_IMAGE | ND_DRAW, NULL);
@@ -662,10 +672,11 @@ static bool ui_imageuser_pass_menu_step(bContext *C, int direction, void *rnd_pt
}
/* 5 view button callbacks... */
-static void image_multiview_cb(bContext *C, void *ima_v, void *iuser_v)
+static void image_multiview_cb(bContext *C, void *rnd_pt, void *UNUSED(arg_v))
{
- Image *ima = ima_v;
- ImageUser *iuser = iuser_v;
+ struct ImageUI_Data *rnd_data = rnd_pt;
+ Image *ima = rnd_data->image;
+ ImageUser *iuser = rnd_data->iuser;
BKE_image_multiview_index(ima, iuser);
WM_event_add_notifier(C, NC_IMAGE | ND_DRAW, NULL);
@@ -692,7 +703,7 @@ static void uiblock_layer_pass_buttons(
uiLayout *layout, Image *image, RenderResult *rr, ImageUser *iuser, int w,
short *render_slot)
{
- static struct ImageUI_Data rnd_pt; /* XXX, workaround */
+ struct ImageUI_Data rnd_pt_local, *rnd_pt = NULL;
uiBlock *block = uiLayoutGetBlock(layout);
uiBut *but;
RenderLayer *rl = NULL;
@@ -708,10 +719,10 @@ static void uiblock_layer_pass_buttons(
wmenu2 = (3 * w) / 5;
wmenu3 = (3 * w) / 6;
wmenu4 = (3 * w) / 6;
-
- rnd_pt.image = image;
- rnd_pt.iuser = iuser;
- rnd_pt.rpass_index = 0;
+
+ rnd_pt_local.image = image;
+ rnd_pt_local.iuser = iuser;
+ rnd_pt_local.rpass_index = 0;
/* menu buts */
if (render_slot) {
@@ -723,10 +734,12 @@ static void uiblock_layer_pass_buttons(
BLI_snprintf(str, sizeof(str), IFACE_("Slot %d"), *render_slot + 1);
}
+ rnd_pt = ui_imageuser_data_copy(&rnd_pt_local);
but = uiDefMenuBut(block, ui_imageuser_slot_menu, image, str, 0, 0, wmenu1, UI_UNIT_Y, TIP_("Select Slot"));
UI_but_func_menu_step_set(but, ui_imageuser_slot_menu_step);
- UI_but_func_set(but, image_multi_cb, rr, iuser);
+ UI_but_funcN_set(but, image_multi_cb, rnd_pt, rr);
UI_but_type_set_menu_from_pulldown(but);
+ rnd_pt = NULL;
}
if (rr) {
@@ -738,15 +751,18 @@ static void uiblock_layer_pass_buttons(
fake_name = ui_imageuser_layer_fake_name(rr);
rpass_index = iuser->layer - (fake_name ? 1 : 0);
rl = BLI_findlink(&rr->layers, rpass_index);
- rnd_pt.rpass_index = rpass_index;
+ rnd_pt_local.rpass_index = rpass_index;
if (RE_layers_have_name(rr)) {
display_name = rl ? rl->name : (fake_name ? fake_name : "");
- but = uiDefMenuBut(block, ui_imageuser_layer_menu, &rnd_pt, display_name,
- 0, 0, wmenu2, UI_UNIT_Y, TIP_("Select Layer"));
+ rnd_pt = ui_imageuser_data_copy(&rnd_pt_local);
+ but = uiDefMenuBut(
+ block, ui_imageuser_layer_menu, rnd_pt, display_name,
+ 0, 0, wmenu2, UI_UNIT_Y, TIP_("Select Layer"));
UI_but_func_menu_step_set(but, ui_imageuser_layer_menu_step);
- UI_but_func_set(but, image_multi_cb, rr, iuser);
+ UI_but_funcN_set(but, image_multi_cb, rnd_pt, rr);
UI_but_type_set_menu_from_pulldown(but);
+ rnd_pt = NULL;
}
/* pass */
@@ -754,11 +770,14 @@ static void uiblock_layer_pass_buttons(
rpass = (rl ? BLI_findlink(&rl->passes, iuser->pass - (fake_name ? 1 : 0)) : NULL);
display_name = rpass ? rpass->internal_name : (fake_name ? fake_name : "");
- but = uiDefMenuBut(block, ui_imageuser_pass_menu, &rnd_pt, IFACE_(display_name),
- 0, 0, wmenu3, UI_UNIT_Y, TIP_("Select Pass"));
+ rnd_pt = ui_imageuser_data_copy(&rnd_pt_local);
+ but = uiDefMenuBut(
+ block, ui_imageuser_pass_menu, rnd_pt, IFACE_(display_name),
+ 0, 0, wmenu3, UI_UNIT_Y, TIP_("Select Pass"));
UI_but_func_menu_step_set(but, ui_imageuser_pass_menu_step);
- UI_but_func_set(but, image_multi_cb, rr, iuser);
+ UI_but_funcN_set(but, image_multi_cb, rnd_pt, rr);
UI_but_type_set_menu_from_pulldown(but);
+ rnd_pt = NULL;
/* view */
if (BLI_listbase_count_ex(&rr->views, 2) > 1 &&
@@ -767,9 +786,13 @@ static void uiblock_layer_pass_buttons(
rview = BLI_findlink(&rr->views, iuser->view);
display_name = rview ? rview->name : "";
- but = uiDefMenuBut(block, ui_imageuser_view_menu_rr, &rnd_pt, display_name, 0, 0, wmenu4, UI_UNIT_Y, TIP_("Select View"));
- UI_but_func_set(but, image_multi_cb, rr, iuser);
+ rnd_pt = ui_imageuser_data_copy(&rnd_pt_local);
+ but = uiDefMenuBut(
+ block, ui_imageuser_view_menu_rr, rnd_pt, display_name,
+ 0, 0, wmenu4, UI_UNIT_Y, TIP_("Select View"));
+ UI_but_funcN_set(but, image_multi_cb, rnd_pt, rr);
UI_but_type_set_menu_from_pulldown(but);
+ rnd_pt = NULL;
}
}
@@ -787,9 +810,13 @@ static void uiblock_layer_pass_buttons(
}
}
- but = uiDefMenuBut(block, ui_imageuser_view_menu_multiview, &rnd_pt, display_name, 0, 0, wmenu1, UI_UNIT_Y, TIP_("Select View"));
- UI_but_func_set(but, image_multiview_cb, image, iuser);
+ rnd_pt = ui_imageuser_data_copy(&rnd_pt_local);
+ but = uiDefMenuBut(
+ block, ui_imageuser_view_menu_multiview, rnd_pt, display_name,
+ 0, 0, wmenu1, UI_UNIT_Y, TIP_("Select View"));
+ UI_but_funcN_set(but, image_multiview_cb, rnd_pt, NULL);
UI_but_type_set_menu_from_pulldown(but);
+ rnd_pt = NULL;
}
}
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 06caf930988..1158e692182 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,9 @@ 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 use 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);
@@ -2359,7 +2396,7 @@ static int image_new_exec(bContext *C, wmOperator *op)
if (prop) {
/* when creating new ID blocks, use is already 1, but RNA
- * pointer se also increases user, so this compensates it */
+ * pointer use also increases user, so this compensates it */
id_us_min(&ima->id);
RNA_id_pointer_create(&ima->id, &idptr);