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:
authorLukas Stockner <lukas.stockner@freenet.de>2018-06-14 23:46:30 +0300
committerLukas Stockner <lukas.stockner@freenet.de>2018-06-14 23:46:30 +0300
commit525be2f579c994777328bd7ac206be4769d3e6a4 (patch)
tree40c37d025adf13865647ab24267d212c0b2076e1 /source/blender/blenkernel/intern/image.c
parent51f1ed8221042f2e273f5ee47a6053f506a783fc (diff)
Image: Refactor render slots to a dynamic list
Previously, render slots were hardcoded to a fixed amount. With this change, render slots now are stored in a list. Therefore, users can add and/or remove as many slots as they want. Credit to brecht for the UI part. Reviewers: brecht, sergey Differential Revision: https://developer.blender.org/D3474
Diffstat (limited to 'source/blender/blenkernel/intern/image.c')
-rw-r--r--source/blender/blenkernel/intern/image.c136
1 files changed, 118 insertions, 18 deletions
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index b6b3dd31096..3e7a9de6968 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -342,19 +342,18 @@ void BKE_image_free_buffers(Image *ima)
/** Free (or release) any data used by this image (does not free the image itself). */
void BKE_image_free(Image *ima)
{
- int a;
-
/* Also frees animdata. */
BKE_image_free_buffers(ima);
image_free_packedfiles(ima);
- for (a = 0; a < IMA_MAX_RENDER_SLOT; a++) {
- if (ima->renders[a]) {
- RE_FreeRenderResult(ima->renders[a]);
- ima->renders[a] = NULL;
+ LISTBASE_FOREACH(RenderSlot *, slot, &ima->renderslots) {
+ if (slot->render) {
+ RE_FreeRenderResult(slot->render);
+ slot->render = NULL;
}
}
+ BLI_freelistN(&ima->renderslots);
BKE_image_free_views(ima);
MEM_SAFE_FREE(ima->stereo3d_format);
@@ -380,6 +379,12 @@ static void image_init(Image *ima, short source, short type)
if (source == IMA_SRC_VIEWER)
ima->flag |= IMA_VIEW_AS_RENDER;
+ if (type == IMA_TYPE_R_RESULT) {
+ for (int i = 0; i < 8; i++) {
+ BKE_image_add_renderslot(ima, NULL);
+ }
+ }
+
BKE_color_managed_colorspace_settings_init(&ima->colorspace_settings);
ima->stereo3d_format = MEM_callocN(sizeof(Stereo3dFormat), "Image Stereo Format");
}
@@ -466,8 +471,10 @@ void BKE_image_copy_data(Main *UNUSED(bmain), Image *ima_dst, const Image *ima_s
/* Cleanup stuff that cannot be copied. */
ima_dst->cache = NULL;
ima_dst->rr = NULL;
- for (int i = 0; i < IMA_MAX_RENDER_SLOT; i++) {
- ima_dst->renders[i] = NULL;
+
+ BLI_duplicatelist(&ima_dst->renderslots, &ima_src->renderslots);
+ LISTBASE_FOREACH(RenderSlot *, slot, &ima_dst->renderslots) {
+ slot->render = NULL;
}
BLI_listbase_clear(&ima_dst->anims);
@@ -2997,7 +3004,7 @@ RenderResult *BKE_image_acquire_renderresult(Scene *scene, Image *ima)
if (ima->render_slot == ima->last_render_slot)
rr = RE_AcquireResultRead(RE_GetSceneRender(scene));
else
- rr = ima->renders[ima->render_slot];
+ rr = BKE_image_get_renderslot(ima, ima->render_slot)->render;
/* set proper views */
image_init_multilayer_multiview(ima, rr);
@@ -3031,22 +3038,23 @@ bool BKE_image_is_openexr(struct Image *ima)
void BKE_image_backup_render(Scene *scene, Image *ima, bool free_current_slot)
{
- /* called right before rendering, ima->renders contains render
+ /* called right before rendering, ima->renderslots contains render
* result pointers for everything but the current render */
Render *re = RE_GetSceneRender(scene);
int slot = ima->render_slot, last = ima->last_render_slot;
if (slot != last) {
- ima->renders[last] = NULL;
- RE_SwapResult(re, &ima->renders[last]);
+ RenderSlot *last_slot = BKE_image_get_renderslot(ima, last);
+ last_slot->render = NULL;
+ RE_SwapResult(re, &last_slot->render);
- if (ima->renders[slot]) {
+ RenderSlot *cur_slot = BKE_image_get_renderslot(ima, slot);
+ if (cur_slot->render) {
if (free_current_slot) {
- RE_FreeRenderResult(ima->renders[slot]);
- ima->renders[slot] = NULL;
+ BKE_image_clear_renderslot(ima, NULL, slot);
}
else {
- RE_SwapResult(re, &ima->renders[slot]);
+ RE_SwapResult(re, &cur_slot->render);
}
}
}
@@ -3669,11 +3677,12 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **r_loc
if (BKE_image_is_stereo(ima) && (iuser->flag & IMA_SHOW_STEREO))
actview = iuser->multiview_eye;
+ RenderSlot *slot;
if (from_render) {
RE_AcquireResultImage(re, &rres, actview);
}
- else if (ima->renders[ima->render_slot]) {
- rres = *(ima->renders[ima->render_slot]);
+ else if ((slot = BKE_image_get_renderslot(ima, ima->render_slot))->render) {
+ rres = *(slot->render);
rres.have_combined = ((RenderView *)rres.views.first)->rectf != NULL;
}
else
@@ -4703,3 +4712,94 @@ static void image_update_views_format(Image *ima, ImageUser *iuser)
}
}
}
+
+RenderSlot *BKE_image_add_renderslot(Image *ima, const char *name)
+{
+ RenderSlot *slot = MEM_callocN(sizeof(RenderSlot), "Image new Render Slot");
+ if (name && name[0]) {
+ BLI_strncpy(slot->name, name, sizeof(slot->name));
+ }
+ else {
+ int n = BLI_listbase_count(&ima->renderslots) + 1;
+ BLI_snprintf(slot->name, sizeof(slot->name), "Slot %d", n);
+ }
+ BLI_addtail(&ima->renderslots, slot);
+ return slot;
+}
+
+bool BKE_image_remove_renderslot(Image *ima, ImageUser *iuser, int index)
+{
+ int num_slots = BLI_listbase_count(&ima->renderslots);
+ if (index >= num_slots || num_slots == 1) {
+ return false;
+ }
+
+ RenderSlot *remove_slot = BLI_findlink(&ima->renderslots, index);
+ RenderSlot *current_slot = BLI_findlink(&ima->renderslots, ima->render_slot);
+ RenderSlot *current_last_slot = BLI_findlink(&ima->renderslots, ima->last_render_slot);
+
+ RenderSlot *next_slot;
+ if (current_slot == remove_slot)
+ next_slot = BLI_findlink(&ima->renderslots, (index == num_slots-1)? index-1 : index+1);
+ else
+ next_slot = current_slot;
+
+ /* If the slot to be removed is the slot with the last render, make another slot the last render slot. */
+ if (remove_slot == current_last_slot) {
+ /* Choose the currently selected slot unless that one is being removed, in that case take the next one. */
+ RenderSlot *next_last_slot;
+ if (current_slot == remove_slot)
+ next_last_slot = next_slot;
+ else
+ next_last_slot = current_slot;
+
+ if (!iuser) return false;
+ Render *re = RE_GetSceneRender(iuser->scene);
+ if (!re) return false;
+ RE_SwapResult(re, &current_last_slot->render);
+ RE_SwapResult(re, &next_last_slot->render);
+ current_last_slot = next_last_slot;
+ }
+
+ current_slot = next_slot;
+
+ BLI_remlink(&ima->renderslots, remove_slot);
+
+ ima->render_slot = BLI_findindex(&ima->renderslots, current_slot);
+ ima->last_render_slot = BLI_findindex(&ima->renderslots, current_last_slot);
+
+ if (remove_slot->render) {
+ RE_FreeRenderResult(remove_slot->render);
+ }
+ MEM_freeN(remove_slot);
+
+ return true;
+}
+
+bool BKE_image_clear_renderslot(Image *ima, ImageUser *iuser, int index)
+{
+ if (index == ima->last_render_slot) {
+ if (!iuser) return false;
+ if (G.is_rendering) return false;
+ Render *re = RE_GetSceneRender(iuser->scene);
+ if (!re) return false;
+ RE_ClearResult(re);
+ return true;
+ }
+ else {
+ RenderSlot *slot = BLI_findlink(&ima->renderslots, index);
+ if (!slot) return false;
+ if (slot->render) {
+ RE_FreeRenderResult(slot->render);
+ slot->render = NULL;
+ }
+ return true;
+ }
+}
+
+RenderSlot *BKE_image_get_renderslot(Image *ima, int index)
+{
+ RenderSlot *slot = BLI_findlink(&ima->renderslots, index);
+ BLI_assert(slot);
+ return slot;
+}