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:
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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, ¤t_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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user