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:
-rw-r--r--release/scripts/startup/bl_ui/space_image.py43
-rw-r--r--source/blender/blenkernel/BKE_image.h6
-rw-r--r--source/blender/blenkernel/intern/image.c136
-rw-r--r--source/blender/blenloader/intern/readfile.c18
-rw-r--r--source/blender/blenloader/intern/versioning_280.c12
-rw-r--r--source/blender/editors/space_image/image_buttons.c20
-rw-r--r--source/blender/editors/space_image/image_edit.c12
-rw-r--r--source/blender/editors/space_image/image_intern.h3
-rw-r--r--source/blender/editors/space_image/image_ops.c93
-rw-r--r--source/blender/editors/space_image/space_image.c5
-rw-r--r--source/blender/makesdna/DNA_image_types.h7
-rw-r--r--source/blender/makesrna/intern/rna_image.c77
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h1
-rw-r--r--source/blender/render/intern/source/pipeline.c8
14 files changed, 364 insertions, 77 deletions
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)
oldnewmap_insert(fd->imamap, ima->gputexture[a], ima->gputexture[a], 0);
if (ima->rr)
oldnewmap_insert(fd->imamap, ima->rr, ima->rr, 0);
- for (a=0; a < IMA_MAX_RENDER_SLOT; a++)
- if (ima->renders[a])
- oldnewmap_insert(fd->imamap, ima->renders[a], ima->renders[a], 0);
+ LISTBASE_FOREACH(RenderSlot *, slot, &ima->renderslots)
+ if (slot->render)
+ oldnewmap_insert(fd->imamap, slot->render, slot->render, 0);
}
for (; sce; sce = sce->id.next) {
if (sce->nodetree && sce->nodetree->previews) {
@@ -1685,8 +1685,8 @@ void blo_end_image_pointer_map(FileData *fd, Main *oldmain)
}
ima->rr = NULL;
}
- for (i = 0; i < IMA_MAX_RENDER_SLOT; i++)
- ima->renders[i] = newimaadr(fd, ima->renders[i]);
+ LISTBASE_FOREACH(RenderSlot *, slot, &ima->renderslots)
+ slot->render = newimaadr(fd, slot->render);
for (i = 0; i < TEXTARGET_COUNT; i++)
ima->gputexture[i] = newimaadr(fd, ima->gputexture[i]);
@@ -3921,14 +3921,16 @@ static void direct_link_image(FileData *fd, Image *ima)
}
/* undo system, try to restore render buffers */
+ link_list(fd, &(ima->renderslots));
if (fd->imamap) {
int a;
- for (a = 0; a < IMA_MAX_RENDER_SLOT; a++)
- ima->renders[a] = newimaadr(fd, ima->renders[a]);
+ LISTBASE_FOREACH(RenderSlot *, slot, &ima->renderslots)
+ slot->render = newimaadr(fd, slot->render);
}
else {
- memset(ima->renders, 0, sizeof(ima->renders));
+ LISTBASE_FOREACH(RenderSlot *, slot, &ima->renderslots)
+ slot->render = NULL;
ima->last_render_slot = ima->render_slot;
}
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 055632ded06..a5d2ced6858 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -60,6 +60,7 @@
#include "BKE_customdata.h"
#include "BKE_freestyle.h"
#include "BKE_idprop.h"
+#include "BKE_image.h"
#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
@@ -1586,5 +1587,16 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
}
+ if (!DNA_struct_elem_find(fd->filesdna, "Image", "ListBase", "renderslot")) {
+ for (Image *ima = bmain->image.first; ima; ima = ima->id.next) {
+ if (ima->type == IMA_TYPE_R_RESULT) {
+ for (int i = 0; i < 8; i++) {
+ RenderSlot *slot = MEM_callocN(sizeof(RenderSlot), "Image Render Slot Init");
+ BLI_snprintf(slot->name, sizeof(slot->name), "Slot %d", i+1);
+ BLI_addtail(&ima->renderslots, slot);
+ }
+ }
+ }
+ }
}
}
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index e0a1afc4537..7236a99ad80 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -291,23 +291,24 @@ static void ui_imageuser_slot_menu(bContext *UNUSED(C), uiLayout *layout, void *
{
uiBlock *block = uiLayoutGetBlock(layout);
Image *image = image_p;
- int slot;
+ int slot_id;
uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("Slot"),
0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
uiItemS(layout);
- slot = IMA_MAX_RENDER_SLOT;
- while (slot--) {
+ slot_id = BLI_listbase_count(&image->renderslots) - 1;
+ for (RenderSlot *slot = image->renderslots.last; slot; slot = slot->prev) {
char str[64];
- if (image->render_slots[slot].name[0] != '\0') {
- BLI_strncpy(str, image->render_slots[slot].name, sizeof(str));
+ if (slot->name[0] != '\0') {
+ BLI_strncpy(str, slot->name, sizeof(str));
}
else {
- BLI_snprintf(str, sizeof(str), IFACE_("Slot %d"), slot + 1);
+ BLI_snprintf(str, sizeof(str), IFACE_("Slot %d"), slot_id + 1);
}
uiDefButS(block, UI_BTYPE_BUT_MENU, B_NOP, str, 0, 0,
- UI_UNIT_X * 5, UI_UNIT_X, &image->render_slot, (float) slot, 0.0, 0, -1, "");
+ UI_UNIT_X * 5, UI_UNIT_X, &image->render_slot, (float) slot_id, 0.0, 0, -1, "");
+ slot_id--;
}
}
@@ -708,8 +709,9 @@ static void uiblock_layer_pass_buttons(
/* menu buts */
if (render_slot) {
char str[64];
- if (image->render_slots[*render_slot].name[0] != '\0') {
- BLI_strncpy(str, image->render_slots[*render_slot].name, sizeof(str));
+ RenderSlot *slot = BKE_image_get_renderslot(image, *render_slot);
+ if (slot->name[0] != '\0') {
+ BLI_strncpy(str, slot->name, sizeof(str));
}
else {
BLI_snprintf(str, sizeof(str), IFACE_("Slot %d"), *render_slot + 1);
diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c
index 0eb6a2400d2..72d0051d260 100644
--- a/source/blender/editors/space_image/image_edit.c
+++ b/source/blender/editors/space_image/image_edit.c
@@ -34,6 +34,7 @@
#include "DNA_scene_types.h"
#include "BLI_rect.h"
+#include "BLI_listbase.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
@@ -302,17 +303,18 @@ bool ED_image_slot_cycle(struct Image *image, int direction)
BLI_assert(ELEM(direction, -1, 1));
- for (i = 1; i < IMA_MAX_RENDER_SLOT; i++) {
- slot = (cur + ((direction == -1) ? -i : i)) % IMA_MAX_RENDER_SLOT;
- if (slot < 0) slot += IMA_MAX_RENDER_SLOT;
+ int num_slots = BLI_listbase_count(&image->renderslots);
+ for (i = 1; i < num_slots; i++) {
+ slot = (cur + ((direction == -1) ? -i : i)) % num_slots;
+ if (slot < 0) slot += num_slots;
- if (image->renders[slot] || slot == image->last_render_slot) {
+ if (BKE_image_get_renderslot(image, slot)->render || slot == image->last_render_slot) {
image->render_slot = slot;
break;
}
}
- if (i == IMA_MAX_RENDER_SLOT) {
+ if (i == num_slots) {
image->render_slot = ((cur == 1) ? 0 : 1);
}
diff --git a/source/blender/editors/space_image/image_intern.h b/source/blender/editors/space_image/image_intern.h
index 9167a193f2d..49c2690daaf 100644
--- a/source/blender/editors/space_image/image_intern.h
+++ b/source/blender/editors/space_image/image_intern.h
@@ -83,6 +83,9 @@ void IMAGE_OT_unpack(struct wmOperatorType *ot);
void IMAGE_OT_invert(struct wmOperatorType *ot);
void IMAGE_OT_cycle_render_slot(struct wmOperatorType *ot);
+void IMAGE_OT_clear_render_slot(struct wmOperatorType *ot);
+void IMAGE_OT_add_render_slot(struct wmOperatorType *ot);
+void IMAGE_OT_remove_render_slot(struct wmOperatorType *ot);
void IMAGE_OT_sample(struct wmOperatorType *ot);
void IMAGE_OT_sample_line(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 39544eb55dd..44ff1086e27 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -3464,7 +3464,7 @@ static int image_cycle_render_slot_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_IMAGE | ND_DRAW, NULL);
/* no undo push for browsing existing */
- if (ima->renders[ima->render_slot] || ima->render_slot == ima->last_render_slot)
+ if (BKE_image_get_renderslot(ima, ima->render_slot)->render || ima->render_slot == ima->last_render_slot)
return OPERATOR_CANCELLED;
return OPERATOR_FINISHED;
@@ -3487,6 +3487,97 @@ void IMAGE_OT_cycle_render_slot(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "reverse", 0, "Cycle in Reverse", "");
}
+/********************* clear render slot operator *********************/
+
+static int image_clear_render_slot_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceImage *sima = CTX_wm_space_image(C);
+ Image *ima = CTX_data_edit_image(C);
+
+ if (!BKE_image_clear_renderslot(ima, &sima->iuser, ima->render_slot)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ WM_event_add_notifier(C, NC_IMAGE | ND_DRAW, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void IMAGE_OT_clear_render_slot(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Clear Render Slot";
+ ot->idname = "IMAGE_OT_clear_render_slot";
+ ot->description = "Clear the currently selected render slot";
+
+ /* api callbacks */
+ ot->exec = image_clear_render_slot_exec;
+ ot->poll = image_cycle_render_slot_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER;
+}
+
+/********************* add render slot operator *********************/
+
+static int image_add_render_slot_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Image *ima = CTX_data_edit_image(C);
+
+ RenderSlot *slot = BKE_image_add_renderslot(ima, NULL);
+ ima->render_slot = BLI_findindex(&ima->renderslots, slot);
+
+ WM_event_add_notifier(C, NC_IMAGE | ND_DRAW, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void IMAGE_OT_add_render_slot(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Add Render Slot";
+ ot->idname = "IMAGE_OT_add_render_slot";
+ ot->description = "Add a new render slot";
+
+ /* api callbacks */
+ ot->exec = image_add_render_slot_exec;
+ ot->poll = image_cycle_render_slot_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER;
+}
+
+/********************* remove render slot operator *********************/
+
+static int image_remove_render_slot_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceImage *sima = CTX_wm_space_image(C);
+ Image *ima = CTX_data_edit_image(C);
+
+ if (!BKE_image_remove_renderslot(ima, &sima->iuser, ima->render_slot)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ WM_event_add_notifier(C, NC_IMAGE | ND_DRAW, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void IMAGE_OT_remove_render_slot(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Remove Render Slot";
+ ot->idname = "IMAGE_OT_remove_render_slot";
+ ot->description = "Remove the current render slot";
+
+ /* api callbacks */
+ ot->exec = image_remove_render_slot_exec;
+ ot->poll = image_cycle_render_slot_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER;
+}
+
/********************** change frame operator *********************/
static int change_frame_poll(bContext *C)
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index a73ed09a632..e84b596530e 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -272,6 +272,9 @@ static void image_operatortypes(void)
WM_operatortype_append(IMAGE_OT_invert);
WM_operatortype_append(IMAGE_OT_cycle_render_slot);
+ WM_operatortype_append(IMAGE_OT_clear_render_slot);
+ WM_operatortype_append(IMAGE_OT_add_render_slot);
+ WM_operatortype_append(IMAGE_OT_remove_render_slot);
WM_operatortype_append(IMAGE_OT_sample);
WM_operatortype_append(IMAGE_OT_sample_line);
@@ -358,7 +361,7 @@ static void image_keymap(struct wmKeyConfig *keyconf)
RNA_boolean_set(kmi->ptr, "toggle", true);
/* fast switch to render slots */
- for (i = 0; i < MIN2(IMA_MAX_RENDER_SLOT, 9); i++) {
+ for (i = 0; i < 9; i++) {
kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_int", ONEKEY + i, KM_PRESS, 0, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.image.render_slots.active_index");
RNA_int_set(kmi->ptr, "value", i);
diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h
index 327b77f12b3..40fa9d40072 100644
--- a/source/blender/makesdna/DNA_image_types.h
+++ b/source/blender/makesdna/DNA_image_types.h
@@ -80,7 +80,9 @@ typedef struct ImagePackedFile {
} ImagePackedFile;
typedef struct RenderSlot {
+ struct RenderSlot *next, *prev;
char name[64]; /* 64 = MAX_NAME */
+ struct RenderResult *render;
} RenderSlot;
/* iuser->flag */
@@ -108,7 +110,7 @@ typedef struct Image {
ListBase anims;
struct RenderResult *rr;
- struct RenderResult *renders[8]; /* IMA_MAX_RENDER_SLOT */
+ ListBase renderslots;
short render_slot, last_render_slot;
int flag;
@@ -148,8 +150,6 @@ typedef struct Image {
char views_format;
ListBase views; /* ImageView */
struct Stereo3dFormat *stereo3d_format;
-
- RenderSlot render_slots[8]; /* 8 = IMA_MAX_RENDER_SLOT */
} Image;
@@ -191,7 +191,6 @@ enum {
/* render */
#define IMA_MAX_RENDER_TEXT 512
-#define IMA_MAX_RENDER_SLOT 8
/* gen_flag */
#define IMA_GEN_FLOAT 1
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index 5736643ab0e..d2b9ee47765 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -462,16 +462,19 @@ static PointerRNA rna_Image_packed_file_get(PointerRNA *ptr)
}
}
-static void rna_Image_render_slots_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+static void rna_RenderSlot_clear(ID *id, RenderSlot *slot, ImageUser *iuser)
{
- Image *image = (Image *)ptr->id.data;
- rna_iterator_array_begin(iter, (void *)image->render_slots, sizeof(RenderSlot), IMA_MAX_RENDER_SLOT, 0, NULL);
+ Image *image = (Image *) id;
+ int index = BLI_findindex(&image->renderslots, slot);
+ BKE_image_clear_renderslot(image, iuser, index);
+
+ WM_main_add_notifier(NC_IMAGE | ND_DISPLAY, image);
}
static PointerRNA rna_render_slots_active_get(PointerRNA *ptr)
{
Image *image = (Image *)ptr->id.data;
- RenderSlot *render_slot = &image->render_slots[image->render_slot];
+ RenderSlot *render_slot = BKE_image_get_renderslot(image, image->render_slot);
return rna_pointer_inherit_refine(ptr, &RNA_RenderSlot, render_slot);
}
@@ -480,9 +483,9 @@ static void rna_render_slots_active_set(PointerRNA *ptr, PointerRNA value)
{
Image *image = (Image *)ptr->id.data;
if (value.id.data == image) {
- RenderSlot *render_slot = (RenderSlot *)value.data;
- int index = render_slot - image->render_slots;
- image->render_slot = CLAMPIS(index, 0, IMA_MAX_RENDER_SLOT - 1);
+ RenderSlot *slot = (RenderSlot *)value.data;
+ int index = BLI_findindex(&image->renderslots, slot);
+ if (index != -1) image->render_slot = index;
}
}
@@ -495,8 +498,17 @@ static int rna_render_slots_active_index_get(PointerRNA *ptr)
static void rna_render_slots_active_index_set(PointerRNA *ptr, int value)
{
Image *image = (Image *)ptr->id.data;
+ int num_slots = BLI_listbase_count(&image->renderslots);
image->render_slot = value;
- CLAMP(image->render_slot, 0, IMA_MAX_RENDER_SLOT - 1);
+ CLAMP(image->render_slot, 0, num_slots - 1);
+}
+
+static void rna_render_slots_active_index_range(PointerRNA *ptr, int *min, int *max,
+ int *UNUSED(softmin), int *UNUSED(softmax))
+{
+ Image *image = (Image *)ptr->id.data;
+ *min = 0;
+ *max = max_ii(0, BLI_listbase_count(&image->renderslots) - 1);
}
#else
@@ -596,7 +608,9 @@ static void rna_def_image_packed_files(BlenderRNA *brna)
static void rna_def_render_slot(BlenderRNA *brna)
{
StructRNA *srna;
- PropertyRNA *prop;
+ PropertyRNA *prop, *parm;
+ FunctionRNA *func;
+
srna = RNA_def_struct(brna, "RenderSlot", NULL);
RNA_def_struct_ui_text(srna, "Render Slot", "Parameters defining the render slot");
@@ -604,32 +618,45 @@ static void rna_def_render_slot(BlenderRNA *brna)
RNA_def_property_string_sdna(prop, NULL, "name");
RNA_def_property_ui_text(prop, "Name", "Render slot name");
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, NULL);
+
+ func = RNA_def_function(srna, "clear", "rna_RenderSlot_clear");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID);
+ RNA_def_function_ui_description(func, "Clear the render slot");
+ parm = RNA_def_pointer(func, "iuser", "ImageUser", "ImageUser", "");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
}
-static void rna_def_render_slots(BlenderRNA *brna)
+static void rna_def_render_slots(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
- PropertyRNA *prop;
+ FunctionRNA *func;
+ PropertyRNA *prop, *parm;
+ RNA_def_property_srna(cprop, "RenderSlots");
srna = RNA_def_struct(brna, "RenderSlots", NULL);
- RNA_def_struct_sdna(srna, "RenderSlot");
- RNA_def_struct_ui_text(srna, "Render Slots", "Collection of the render slots");
+ RNA_def_struct_sdna(srna, "Image");
+ RNA_def_struct_ui_text(srna, "Render Layers", "Collection of render layers");
+
+ prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "render_slot");
+ RNA_def_property_int_funcs(prop, "rna_render_slots_active_index_get",
+ "rna_render_slots_active_index_set",
+ "rna_render_slots_active_index_range");
+ RNA_def_property_ui_text(prop, "Active", "Active render slot of the image");
+ RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, NULL);
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "RenderSlot");
RNA_def_property_pointer_funcs(prop, "rna_render_slots_active_get", "rna_render_slots_active_set", NULL, NULL);
- RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_NULL);
RNA_def_property_ui_text(prop, "Active", "Active render slot of the image");
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, NULL);
- prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_NONE);
- RNA_def_property_int_funcs(prop, "rna_render_slots_active_index_get",
- "rna_render_slots_active_index_set",
- NULL);
- RNA_def_property_range(prop, 0, IMA_MAX_RENDER_SLOT);
- RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Active Index", "Index of an active render slot of the image");
- RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, NULL);
+ func = RNA_def_function(srna, "new", "BKE_image_add_renderslot");
+ RNA_def_function_ui_description(func, "Add a render slot to the image");
+ parm = RNA_def_string(func, "name", NULL, 0, "Name", "New name for the render slot");
+ parm = RNA_def_pointer(func, "result", "RenderSlot", "", "Newly created render layer");
+ RNA_def_function_return(func, parm);
}
static void rna_def_image(BlenderRNA *brna)
@@ -811,10 +838,9 @@ static void rna_def_image(BlenderRNA *brna)
prop = RNA_def_property(srna, "render_slots", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "RenderSlot");
+ RNA_def_property_collection_sdna(prop, NULL, "renderslots", NULL);
RNA_def_property_ui_text(prop, "Render Slots", "Render slots of the image");
- RNA_def_property_collection_funcs(prop, "rna_Image_render_slots_begin", "rna_iterator_array_next",
- "rna_iterator_array_end", "rna_iterator_array_get", NULL, NULL, NULL, NULL);
- RNA_def_property_srna(prop, "RenderSlots");
+ rna_def_render_slots(brna, prop);
/*
* Image.has_data and Image.depth are temporary,
@@ -897,7 +923,6 @@ static void rna_def_image(BlenderRNA *brna)
void RNA_def_image(BlenderRNA *brna)
{
rna_def_render_slot(brna);
- rna_def_render_slots(brna);
rna_def_image(brna);
rna_def_imageuser(brna);
rna_def_image_packed_files(brna);
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index 5cb14df8308..bde3c1c8cb3 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -221,6 +221,7 @@ void RE_ReleaseResultImageViews(struct Render *re, struct RenderResult *rr);
void RE_AcquireResultImage(struct Render *re, struct RenderResult *rr, const int view_id);
void RE_ReleaseResultImage(struct Render *re);
void RE_SwapResult(struct Render *re, struct RenderResult **rr);
+void RE_ClearResult(struct Render *re);
struct RenderStats *RE_GetStats(struct Render *re);
void RE_ResultGet32(struct Render *re, unsigned int *rect);
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 62257caa43b..14160782898 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -330,6 +330,14 @@ RenderResult *RE_AcquireResultWrite(Render *re)
return NULL;
}
+void RE_ClearResult(Render *re)
+{
+ if (re) {
+ render_result_free(re->result);
+ re->result = NULL;
+ }
+}
+
void RE_SwapResult(Render *re, RenderResult **rr)
{
/* for keeping render buffers */