1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 */
16
17 /** \file
18 * \ingroup edscene
19 */
20
21 #include <stdio.h>
22 #include <string.h>
23
24 #include "BLI_compiler_attrs.h"
25 #include "BLI_listbase.h"
26 #include "BLI_string.h"
27
28 #include "BKE_context.h"
29 #include "BKE_global.h"
30 #include "BKE_layer.h"
31 #include "BKE_lib_id.h"
32 #include "BKE_main.h"
33 #include "BKE_node.h"
34 #include "BKE_report.h"
35 #include "BKE_scene.h"
36
37 #include "DEG_depsgraph.h"
38 #include "DEG_depsgraph_build.h"
39
40 #include "BLT_translation.h"
41
42 #include "ED_object.h"
43 #include "ED_render.h"
44 #include "ED_scene.h"
45 #include "ED_screen.h"
46 #include "ED_util.h"
47
48 #include "RNA_access.h"
49 #include "RNA_define.h"
50
51 #include "WM_api.h"
52 #include "WM_types.h"
53
ED_scene_add(Main * bmain,bContext * C,wmWindow * win,eSceneCopyMethod method)54 Scene *ED_scene_add(Main *bmain, bContext *C, wmWindow *win, eSceneCopyMethod method)
55 {
56 Scene *scene_new;
57
58 if (method == SCE_COPY_NEW) {
59 scene_new = BKE_scene_add(bmain, DATA_("Scene"));
60 }
61 else { /* different kinds of copying */
62 Scene *scene_old = WM_window_get_active_scene(win);
63
64 /* We are going to deep-copy collections, objects and various object data, we need to have
65 * up-to-date obdata for that. */
66 if (method == SCE_COPY_FULL) {
67 ED_editors_flush_edits(bmain);
68 }
69
70 scene_new = BKE_scene_duplicate(bmain, scene_old, method);
71 }
72
73 WM_window_set_active_scene(bmain, C, win, scene_new);
74
75 WM_event_add_notifier(C, NC_SCENE | ND_SCENEBROWSE, scene_new);
76
77 return scene_new;
78 }
79
80 /**
81 * \note Only call outside of area/region loops
82 * \return true if successful
83 */
ED_scene_delete(bContext * C,Main * bmain,Scene * scene)84 bool ED_scene_delete(bContext *C, Main *bmain, Scene *scene)
85 {
86 Scene *scene_new;
87
88 /* kill running jobs */
89 wmWindowManager *wm = bmain->wm.first;
90 WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_ANY);
91
92 if (scene->id.prev) {
93 scene_new = scene->id.prev;
94 }
95 else if (scene->id.next) {
96 scene_new = scene->id.next;
97 }
98 else {
99 return false;
100 }
101
102 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
103 if (win->parent != NULL) { /* We only care about main windows here... */
104 continue;
105 }
106 if (win->scene == scene) {
107 WM_window_set_active_scene(bmain, C, win, scene_new);
108 }
109 }
110
111 BKE_id_delete(bmain, scene);
112
113 return true;
114 }
115
116 /* Depsgraph updates after scene becomes active in a window. */
ED_scene_change_update(Main * bmain,Scene * scene,ViewLayer * layer)117 void ED_scene_change_update(Main *bmain, Scene *scene, ViewLayer *layer)
118 {
119 Depsgraph *depsgraph = BKE_scene_ensure_depsgraph(bmain, scene, layer);
120
121 BKE_scene_set_background(bmain, scene);
122 DEG_graph_relations_update(depsgraph);
123 DEG_on_visible_update(bmain, false);
124
125 ED_render_engine_changed(bmain, false);
126 ED_update_for_newframe(bmain, depsgraph);
127 }
128
view_layer_remove_poll(const Scene * scene,const ViewLayer * layer)129 static bool view_layer_remove_poll(const Scene *scene, const ViewLayer *layer)
130 {
131 const int act = BLI_findindex(&scene->view_layers, layer);
132
133 if (act == -1) {
134 return false;
135 }
136 if ((scene->view_layers.first == scene->view_layers.last) &&
137 (scene->view_layers.first == layer)) {
138 /* ensure 1 layer is kept */
139 return false;
140 }
141
142 return true;
143 }
144
view_layer_remove_unset_nodetrees(const Main * bmain,Scene * scene,ViewLayer * layer)145 static void view_layer_remove_unset_nodetrees(const Main *bmain, Scene *scene, ViewLayer *layer)
146 {
147 int act_layer_index = BLI_findindex(&scene->view_layers, layer);
148
149 for (Scene *sce = bmain->scenes.first; sce; sce = sce->id.next) {
150 if (sce->nodetree) {
151 BKE_nodetree_remove_layer_n(sce->nodetree, scene, act_layer_index);
152 }
153 }
154 }
155
ED_scene_view_layer_delete(Main * bmain,Scene * scene,ViewLayer * layer,ReportList * reports)156 bool ED_scene_view_layer_delete(Main *bmain, Scene *scene, ViewLayer *layer, ReportList *reports)
157 {
158 if (view_layer_remove_poll(scene, layer) == false) {
159 if (reports) {
160 BKE_reportf(reports,
161 RPT_ERROR,
162 "View layer '%s' could not be removed from scene '%s'",
163 layer->name,
164 scene->id.name + 2);
165 }
166
167 return false;
168 }
169
170 /* We need to unset nodetrees before removing the layer, otherwise its index will be -1. */
171 view_layer_remove_unset_nodetrees(bmain, scene, layer);
172
173 BLI_remlink(&scene->view_layers, layer);
174 BLI_assert(BLI_listbase_is_empty(&scene->view_layers) == false);
175
176 /* Remove from windows. */
177 wmWindowManager *wm = bmain->wm.first;
178 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
179 if (win->scene == scene && STREQ(win->view_layer_name, layer->name)) {
180 ViewLayer *first_layer = BKE_view_layer_default_view(scene);
181 STRNCPY(win->view_layer_name, first_layer->name);
182 }
183 }
184
185 BKE_scene_free_view_layer_depsgraph(scene, layer);
186
187 BKE_view_layer_free(layer);
188
189 DEG_id_tag_update(&scene->id, 0);
190 DEG_relations_tag_update(bmain);
191 WM_main_add_notifier(NC_SCENE | ND_LAYER | NA_REMOVED, scene);
192
193 return true;
194 }
195
scene_new_exec(bContext * C,wmOperator * op)196 static int scene_new_exec(bContext *C, wmOperator *op)
197 {
198 Main *bmain = CTX_data_main(C);
199 wmWindow *win = CTX_wm_window(C);
200 int type = RNA_enum_get(op->ptr, "type");
201
202 ED_scene_add(bmain, C, win, type);
203
204 return OPERATOR_FINISHED;
205 }
206
SCENE_OT_new(wmOperatorType * ot)207 static void SCENE_OT_new(wmOperatorType *ot)
208 {
209 static EnumPropertyItem type_items[] = {
210 {SCE_COPY_NEW, "NEW", 0, "New", "Add a new, empty scene with default settings"},
211 {SCE_COPY_EMPTY,
212 "EMPTY",
213 0,
214 "Copy Settings",
215 "Add a new, empty scene, and copy settings from the current scene"},
216 {SCE_COPY_LINK_COLLECTION,
217 "LINK_COPY",
218 0,
219 "Linked Copy",
220 "Link in the collections from the current scene (shallow copy)"},
221 {SCE_COPY_FULL, "FULL_COPY", 0, "Full Copy", "Make a full copy of the current scene"},
222 {0, NULL, 0, NULL, NULL},
223 };
224
225 /* identifiers */
226 ot->name = "New Scene";
227 ot->description = "Add new scene by type";
228 ot->idname = "SCENE_OT_new";
229
230 /* api callbacks */
231 ot->exec = scene_new_exec;
232 ot->invoke = WM_menu_invoke;
233
234 /* flags */
235 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
236
237 /* properties */
238 ot->prop = RNA_def_enum(ot->srna, "type", type_items, 0, "Type", "");
239 }
240
scene_delete_poll(bContext * C)241 static bool scene_delete_poll(bContext *C)
242 {
243 Scene *scene = CTX_data_scene(C);
244 return (scene->id.prev || scene->id.next);
245 }
246
scene_delete_exec(bContext * C,wmOperator * UNUSED (op))247 static int scene_delete_exec(bContext *C, wmOperator *UNUSED(op))
248 {
249 Scene *scene = CTX_data_scene(C);
250
251 if (ED_scene_delete(C, CTX_data_main(C), scene) == false) {
252 return OPERATOR_CANCELLED;
253 }
254
255 if (G.debug & G_DEBUG) {
256 printf("scene delete %p\n", scene);
257 }
258
259 WM_event_add_notifier(C, NC_SCENE | NA_REMOVED, scene);
260
261 return OPERATOR_FINISHED;
262 }
263
SCENE_OT_delete(wmOperatorType * ot)264 static void SCENE_OT_delete(wmOperatorType *ot)
265 {
266 /* identifiers */
267 ot->name = "Delete Scene";
268 ot->description = "Delete active scene";
269 ot->idname = "SCENE_OT_delete";
270
271 /* api callbacks */
272 ot->exec = scene_delete_exec;
273 ot->poll = scene_delete_poll;
274
275 /* flags */
276 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
277 }
278
ED_operatortypes_scene(void)279 void ED_operatortypes_scene(void)
280 {
281 WM_operatortype_append(SCENE_OT_new);
282 WM_operatortype_append(SCENE_OT_delete);
283 }
284