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
This commit is contained in:
2018-06-14 22:46:30 +02:00
parent 51f1ed8221
commit 525be2f579
14 changed files with 364 additions and 77 deletions

View File

@@ -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,

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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);
}
}
}
}
}
}

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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)

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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 */