203 lines
5.4 KiB
C
203 lines
5.4 KiB
C
![]() |
/*
|
||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU General Public License
|
||
|
* as published by the Free Software Foundation; either version 2
|
||
|
* of the License, or (at your option) any later version.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program; if not, write to the Free Software Foundation,
|
||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||
|
*
|
||
|
* ***** END GPL LICENSE BLOCK *****
|
||
|
*/
|
||
|
|
||
|
/** \file blender/editors/scene/scene_edit.c
|
||
|
* \ingroup edscene
|
||
|
*/
|
||
|
|
||
|
#include <stdio.h>
|
||
|
|
||
|
#include "BKE_context.h"
|
||
|
#include "BKE_depsgraph.h"
|
||
|
#include "BKE_global.h"
|
||
|
#include "BKE_library_remap.h"
|
||
|
#include "BKE_main.h"
|
||
|
#include "BKE_scene.h"
|
||
|
#include "BKE_workspace.h"
|
||
|
|
||
|
#include "BLI_compiler_attrs.h"
|
||
|
#include "BLI_listbase.h"
|
||
|
|
||
|
#include "BLT_translation.h"
|
||
|
|
||
|
#include "ED_object.h"
|
||
|
#include "ED_render.h"
|
||
|
#include "ED_scene.h"
|
||
|
#include "ED_screen.h"
|
||
|
#include "ED_util.h"
|
||
|
|
||
|
#include "RNA_access.h"
|
||
|
#include "RNA_define.h"
|
||
|
|
||
|
#include "WM_api.h"
|
||
|
#include "WM_types.h"
|
||
|
|
||
|
|
||
|
Scene *ED_scene_add(Main *bmain, bContext *C, wmWindow *win, eSceneCopyMethod method)
|
||
|
{
|
||
|
Scene *scene_new;
|
||
|
|
||
|
if (method == SCE_COPY_NEW) {
|
||
|
scene_new = BKE_scene_add(bmain, DATA_("Scene"));
|
||
|
}
|
||
|
else { /* different kinds of copying */
|
||
|
Scene *scene_old = WM_window_get_active_scene(win);
|
||
|
|
||
|
scene_new = BKE_scene_copy(bmain, scene_old, method);
|
||
|
|
||
|
/* these can't be handled in blenkernel currently, so do them here */
|
||
|
if (method == SCE_COPY_LINK_DATA) {
|
||
|
ED_object_single_users(bmain, scene_new, false, true);
|
||
|
}
|
||
|
else if (method == SCE_COPY_FULL) {
|
||
|
ED_editors_flush_edits(C, false);
|
||
|
ED_object_single_users(bmain, scene_new, true, true);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
WM_window_change_active_scene(bmain, C, win, scene_new);
|
||
|
|
||
|
WM_event_add_notifier(C, NC_SCENE | ND_SCENEBROWSE, scene_new);
|
||
|
|
||
|
return scene_new;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* \note Only call outside of area/region loops
|
||
|
* \return true if successful
|
||
|
*/
|
||
|
bool ED_scene_delete(bContext *C, Main *bmain, wmWindow *win, Scene *scene)
|
||
|
{
|
||
|
Scene *scene_new;
|
||
|
|
||
|
if (scene->id.prev)
|
||
|
scene_new = scene->id.prev;
|
||
|
else if (scene->id.next)
|
||
|
scene_new = scene->id.next;
|
||
|
else
|
||
|
return false;
|
||
|
|
||
|
WM_window_change_active_scene(bmain, C, win, scene_new);
|
||
|
|
||
|
BKE_libblock_remap(bmain, scene, scene_new, ID_REMAP_SKIP_INDIRECT_USAGE | ID_REMAP_SKIP_NEVER_NULL_USAGE);
|
||
|
BKE_libblock_free(bmain, scene);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void ED_scene_exit(bContext *C)
|
||
|
{
|
||
|
ED_object_editmode_exit(C, EM_FREEDATA | EM_DO_UNDO);
|
||
|
}
|
||
|
|
||
|
void ED_scene_changed_update(Main *bmain, bContext *C, Scene *scene_new, const bScreen *active_screen)
|
||
|
{
|
||
|
/* XXX Just using active scene render-layer for workspace when switching,
|
||
|
* but workspace should remember the last one set. Could store render-layer
|
||
|
* per window-workspace combination (using WorkSpaceDataRelation) */
|
||
|
SceneLayer *layer_new = BLI_findlink(&scene_new->render_layers, scene_new->active_layer);
|
||
|
|
||
|
CTX_data_scene_set(C, scene_new);
|
||
|
BKE_workspace_render_layer_set(CTX_wm_workspace(C), layer_new);
|
||
|
BKE_scene_set_background(bmain, scene_new);
|
||
|
DAG_on_visible_update(bmain, false);
|
||
|
|
||
|
ED_screen_update_after_scene_change(active_screen, scene_new);
|
||
|
ED_render_engine_changed(bmain);
|
||
|
ED_update_for_newframe(bmain, scene_new, 1);
|
||
|
|
||
|
/* complete redraw */
|
||
|
WM_event_add_notifier(C, NC_WINDOW, NULL);
|
||
|
}
|
||
|
|
||
|
static int scene_new_exec(bContext *C, wmOperator *op)
|
||
|
{
|
||
|
Main *bmain = CTX_data_main(C);
|
||
|
wmWindow *win = CTX_wm_window(C);
|
||
|
int type = RNA_enum_get(op->ptr, "type");
|
||
|
|
||
|
ED_scene_add(bmain, C, win, type);
|
||
|
|
||
|
return OPERATOR_FINISHED;
|
||
|
}
|
||
|
|
||
|
static void SCENE_OT_new(wmOperatorType *ot)
|
||
|
{
|
||
|
static EnumPropertyItem type_items[] = {
|
||
|
{SCE_COPY_NEW, "NEW", 0, "New", "Add new scene"},
|
||
|
{SCE_COPY_EMPTY, "EMPTY", 0, "Copy Settings", "Make a copy without any objects"},
|
||
|
{SCE_COPY_LINK_OB, "LINK_OBJECTS", 0, "Link Objects", "Link to the objects from the current scene"},
|
||
|
{SCE_COPY_LINK_DATA, "LINK_OBJECT_DATA", 0, "Link Object Data", "Copy objects linked to data from the current scene"},
|
||
|
{SCE_COPY_FULL, "FULL_COPY", 0, "Full Copy", "Make a full copy of the current scene"},
|
||
|
{0, NULL, 0, NULL, NULL}
|
||
|
};
|
||
|
|
||
|
/* identifiers */
|
||
|
ot->name = "New Scene";
|
||
|
ot->description = "Add new scene by type";
|
||
|
ot->idname = "SCENE_OT_new";
|
||
|
|
||
|
/* api callbacks */
|
||
|
ot->exec = scene_new_exec;
|
||
|
ot->invoke = WM_menu_invoke;
|
||
|
|
||
|
/* flags */
|
||
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||
|
|
||
|
/* properties */
|
||
|
ot->prop = RNA_def_enum(ot->srna, "type", type_items, 0, "Type", "");
|
||
|
}
|
||
|
|
||
|
static int scene_delete_exec(bContext *C, wmOperator *UNUSED(op))
|
||
|
{
|
||
|
Scene *scene = CTX_data_scene(C);
|
||
|
|
||
|
if (ED_scene_delete(C, CTX_data_main(C), CTX_wm_window(C), scene) == false) {
|
||
|
return OPERATOR_CANCELLED;
|
||
|
}
|
||
|
|
||
|
if (G.debug & G_DEBUG)
|
||
|
printf("scene delete %p\n", scene);
|
||
|
|
||
|
WM_event_add_notifier(C, NC_SCENE | NA_REMOVED, scene);
|
||
|
|
||
|
return OPERATOR_FINISHED;
|
||
|
}
|
||
|
|
||
|
static void SCENE_OT_delete(wmOperatorType *ot)
|
||
|
{
|
||
|
/* identifiers */
|
||
|
ot->name = "Delete Scene";
|
||
|
ot->description = "Delete active scene";
|
||
|
ot->idname = "SCENE_OT_delete";
|
||
|
|
||
|
/* api callbacks */
|
||
|
ot->exec = scene_delete_exec;
|
||
|
|
||
|
/* flags */
|
||
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||
|
}
|
||
|
|
||
|
void ED_operatortypes_scene(void)
|
||
|
{
|
||
|
WM_operatortype_append(SCENE_OT_new);
|
||
|
WM_operatortype_append(SCENE_OT_delete);
|
||
|
}
|