[Bf-blender-cvs] [525be2f579c] blender2.8: Image: Refactor render slots to a dynamic list

Lukas Stockner noreply at git.blender.org
Thu Jun 14 22:56:18 CEST 2018


Commit: 525be2f579c994777328bd7ac206be4769d3e6a4
Author: Lukas Stockner
Date:   Thu Jun 14 22:46:30 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB525be2f579c994777328bd7ac206be4769d3e6a4

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

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

M	release/scripts/startup/bl_ui/space_image.py
M	source/blender/blenkernel/BKE_image.h
M	source/blender/blenkernel/intern/image.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/versioning_280.c
M	source/blender/editors/space_image/image_buttons.c
M	source/blender/editors/space_image/image_edit.c
M	source/blender/editors/space_image/image_intern.h
M	source/blender/editors/space_image/image_ops.c
M	source/blender/editors/space_image/space_image.c
M	source/blender/makesdna/DNA_image_types.h
M	source/blender/makesrna/intern/rna_image.c
M	source/blender/render/extern/include/RE_pipeline.h
M	source/blender/render/intern/source/pipeline.c

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

diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index e8c9925ba9e..1acc8cf601d 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -19,7 +19,7 @@
 # <pep8 compliant>
 import bpy
 import math
-from bpy.types import Header, Menu, Panel
+from bpy.types import Header, Menu, Panel, UIList
 from .properties_paint_common import (
     UnifiedPaintPanel,
     brush_texture_settings,
@@ -724,10 +724,41 @@ class IMAGE_PT_view_properties(Panel):
             row.active = uvedit.show_other_objects
             row.prop(uvedit, "other_uv_filter", text="Filter")
 
-        if show_render and ima:
-            layout.separator()
-            render_slot = ima.render_slots.active
-            layout.prop(render_slot, "name", text="Slot Name")
+
+class IMAGE_UL_render_slots(UIList):
+    def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+        slot = item
+        layout.prop(slot, "name", text="", emboss=False)
+
+
+class IMAGE_PT_render_slots(Panel):
+    bl_space_type = 'IMAGE_EDITOR'
+    bl_region_type = 'UI'
+    bl_label = "Render Slots"
+
+    @classmethod
+    def poll(cls, context):
+        sima = context.space_data
+        return (sima and sima.image and sima.show_render)
+
+    def draw(self, context):
+        layout = self.layout
+
+        sima = context.space_data
+        ima = sima.image
+
+        row = layout.row()
+
+        col = row.column()
+        col.template_list("IMAGE_UL_render_slots", "render_slots", ima, "render_slots", ima.render_slots, "active_index", rows=3)
+
+        col = row.column(align=True)
+        col.operator("image.add_render_slot", icon='ZOOMIN', text="")
+        col.operator("image.remove_render_slot", icon='ZOOMOUT', text="")
+
+        col.separator()
+
+        col.operator("image.clear_render_slot", icon='X', text="")
 
 
 class IMAGE_PT_tools_transform_uvs(Panel, UVToolsPanel):
@@ -1361,6 +1392,8 @@ classes = (
     IMAGE_PT_active_mask_spline,
     IMAGE_PT_active_mask_point,
     IMAGE_PT_image_properties,
+    IMAGE_UL_render_slots,
+    IMAGE_PT_render_slots,
     IMAGE_PT_view_properties,
     IMAGE_PT_tools_transform_uvs,
     IMAGE_PT_tools_align_uvs,
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 546204b5eef..a7d7806997c 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -296,6 +296,12 @@ void BKE_image_file_format_set(struct Image *image, int ftype, const struct ImbF
 bool BKE_image_has_loaded_ibuf(struct Image *image);
 struct ImBuf *BKE_image_get_ibuf_with_name(struct Image *image, const char *name);
 struct ImBuf *BKE_image_get_first_ibuf(struct Image *image);
+
+struct RenderSlot *BKE_image_add_renderslot(struct Image *ima, const char *name);
+bool BKE_image_remove_renderslot(struct Image *ima, struct ImageUser *iuser, int slot);
+struct RenderSlot *BKE_image_get_renderslot(struct Image *ima, int slot);
+bool BKE_image_clear_renderslot(struct Image *ima, struct ImageUser *iuser, int slot);
+
 #ifdef __cplusplus
 }
 #endif
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;
+}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 481acbb163d..b251693a13b 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -1646,9 +1646,9 @@ void blo_make_image_pointer_map(FileData *fd, Main *oldmain)


@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list