diff options
author | Lukas Stockner <lukas.stockner@freenet.de> | 2018-06-14 23:46:30 +0300 |
---|---|---|
committer | Lukas Stockner <lukas.stockner@freenet.de> | 2018-06-14 23:46:30 +0300 |
commit | 525be2f579c994777328bd7ac206be4769d3e6a4 (patch) | |
tree | 40c37d025adf13865647ab24267d212c0b2076e1 /source/blender | |
parent | 51f1ed8221042f2e273f5ee47a6053f506a783fc (diff) |
Image: Refactor render slots to a dynamic list
Previously, render slots were hardcoded to a fixed amount.
With this change, render slots now are stored in a list. Therefore, users can add and/or remove as many slots as they want.
Credit to brecht for the UI part.
Reviewers: brecht, sergey
Differential Revision: https://developer.blender.org/D3474
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_image.h | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/image.c | 136 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 18 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_280.c | 12 | ||||
-rw-r--r-- | source/blender/editors/space_image/image_buttons.c | 20 | ||||
-rw-r--r-- | source/blender/editors/space_image/image_edit.c | 12 | ||||
-rw-r--r-- | source/blender/editors/space_image/image_intern.h | 3 | ||||
-rw-r--r-- | source/blender/editors/space_image/image_ops.c | 93 | ||||
-rw-r--r-- | source/blender/editors/space_image/space_image.c | 5 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_image_types.h | 7 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_image.c | 77 | ||||
-rw-r--r-- | source/blender/render/extern/include/RE_pipeline.h | 1 | ||||
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 8 |
13 files changed, 326 insertions, 72 deletions
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, ¤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; +} 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 */ |