Blender V4.5
scene_edit.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cstdio>
10#include <cstring>
11
12#include "BLI_listbase.h"
13#include "BLI_string.h"
14
15#include "DNA_sequence_types.h"
16
17#include "BKE_context.hh"
18#include "BKE_global.hh"
19#include "BKE_layer.hh"
20#include "BKE_lib_id.hh"
21#include "BKE_main.hh"
22#include "BKE_node.hh"
23#include "BKE_report.hh"
24#include "BKE_scene.hh"
25
26#include "DEG_depsgraph.hh"
28
29#include "BLT_translation.hh"
30
31#include "ED_render.hh"
32#include "ED_scene.hh"
33#include "ED_screen.hh"
34#include "ED_util.hh"
35
36#include "SEQ_relations.hh"
37#include "SEQ_select.hh"
38
39#include "RNA_access.hh"
40#include "RNA_define.hh"
41
42#include "WM_api.hh"
43#include "WM_types.hh"
44
45/* -------------------------------------------------------------------- */
48
49static Scene *scene_add(Main *bmain, Scene *scene_old, eSceneCopyMethod method)
50{
51 Scene *scene_new = nullptr;
52 if (method == SCE_COPY_NEW) {
53 scene_new = BKE_scene_add(bmain, DATA_("Scene"));
54 }
55 else { /* different kinds of copying */
56 /* We are going to deep-copy collections, objects and various object data, we need to have
57 * up-to-date obdata for that. */
58 if (method == SCE_COPY_FULL) {
60 }
61
62 scene_new = BKE_scene_duplicate(bmain, scene_old, method);
63 }
64
65 return scene_new;
66}
67
69 bContext *C,
70 eSceneCopyMethod method,
71 const bool assign_strip)
72{
73 Strip *strip = nullptr;
74 Scene *scene_active = CTX_data_scene(C);
75 Scene *scene_strip = nullptr;
76 /* Sequencer need to use as base the scene defined in the strip, not the main scene. */
77 Editing *ed = scene_active->ed;
78 if (ed) {
79 strip = ed->act_strip;
80 if (strip && strip->scene) {
81 scene_strip = strip->scene;
82 }
83 }
84
85 /* If no scene assigned to the strip, only NEW scene mode is logic. */
86 if (scene_strip == nullptr) {
87 method = SCE_COPY_NEW;
88 }
89
90 Scene *scene_new = scene_add(bmain, scene_strip, method);
91
92 /* If don't need assign the scene to the strip, nothing else to do. */
93 if (!assign_strip) {
94 return scene_new;
95 }
96
97 /* As the scene is created in sequencer, do not set the new scene as active.
98 * This is useful for story-boarding where we want to keep actual scene active.
99 * The new scene is linked to the active strip and the viewport updated. */
100 if (scene_new && strip) {
101 strip->scene = scene_new;
102 /* Do a refresh of the sequencer data. */
106 }
107
110
111 return scene_new;
112}
113
115{
116 Scene *scene_old = WM_window_get_active_scene(win);
117 Scene *scene_new = scene_add(bmain, scene_old, method);
118
119 WM_window_set_active_scene(bmain, C, win, scene_new);
120
122
123 return scene_new;
124}
125
126bool ED_scene_delete(bContext *C, Main *bmain, Scene *scene)
127{
128 Scene *scene_new;
129
130 /* kill running jobs */
131 wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
133
134 if (scene->id.prev) {
135 scene_new = static_cast<Scene *>(scene->id.prev);
136 }
137 else if (scene->id.next) {
138 scene_new = static_cast<Scene *>(scene->id.next);
139 }
140 else {
141 return false;
142 }
143
144 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
145 if (win->parent != nullptr) { /* We only care about main windows here... */
146 continue;
147 }
148 if (win->scene == scene) {
149 WM_window_set_active_scene(bmain, C, win, scene_new);
150 }
151 }
152
153 BKE_id_delete(bmain, scene);
154
155 return true;
156}
157
158void ED_scene_change_update(Main *bmain, Scene *scene, ViewLayer *layer)
159{
160 Depsgraph *depsgraph = BKE_scene_ensure_depsgraph(bmain, scene, layer);
161
162 BKE_scene_set_background(bmain, scene);
164 DEG_tag_on_visible_update(bmain, false);
165
166 ED_render_engine_changed(bmain, false);
168}
169
170static bool view_layer_remove_poll(const Scene *scene, const ViewLayer *layer)
171{
172 const int act = BLI_findindex(&scene->view_layers, layer);
173
174 if (act == -1) {
175 return false;
176 }
177 if ((scene->view_layers.first == scene->view_layers.last) && (scene->view_layers.first == layer))
178 {
179 /* ensure 1 layer is kept */
180 return false;
181 }
182
183 return true;
184}
185
186static void view_layer_remove_unset_nodetrees(const Main *bmain, Scene *scene, ViewLayer *layer)
187{
188 int act_layer_index = BLI_findindex(&scene->view_layers, layer);
189
190 for (Scene *sce = static_cast<Scene *>(bmain->scenes.first); sce;
191 sce = static_cast<Scene *>(sce->id.next))
192 {
193 if (sce->nodetree) {
194 blender::bke::node_tree_remove_layer_n(sce->nodetree, scene, act_layer_index);
195 }
196 }
197}
198
200{
201 if (view_layer_remove_poll(scene, layer) == false) {
202 if (reports) {
204 RPT_ERROR,
205 "View layer '%s' could not be removed from scene '%s'",
206 layer->name,
207 scene->id.name + 2);
208 }
209
210 return false;
211 }
212
213 /* We need to unset node-trees before removing the layer, otherwise its index will be -1. */
214 view_layer_remove_unset_nodetrees(bmain, scene, layer);
215
216 BLI_remlink(&scene->view_layers, layer);
218
219 /* Remove from windows. */
220 wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
221 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
222 if (win->scene == scene && STREQ(win->view_layer_name, layer->name)) {
223 ViewLayer *first_layer = BKE_view_layer_default_view(scene);
224 STRNCPY(win->view_layer_name, first_layer->name);
225 }
226 }
227
229
230 BKE_view_layer_free(layer);
231
235
236 return true;
237}
238
240
241/* -------------------------------------------------------------------- */
244
246{
247 Main *bmain = CTX_data_main(C);
248 wmWindow *win = CTX_wm_window(C);
249 int type = RNA_enum_get(op->ptr, "type");
250
251 ED_scene_add(bmain, C, win, eSceneCopyMethod(type));
252
253 return OPERATOR_FINISHED;
254}
255
257 {SCE_COPY_NEW, "NEW", 0, "New", "Add a new, empty scene with default settings"},
259 "EMPTY",
260 0,
261 "Copy Settings",
262 "Add a new, empty scene, and copy settings from the current scene"},
264 "LINK_COPY",
265 0,
266 "Linked Copy",
267 "Link in the collections from the current scene (shallow copy)"},
268 {SCE_COPY_FULL, "FULL_COPY", 0, "Full Copy", "Make a full copy of the current scene"},
269 {0, nullptr, 0, nullptr, nullptr},
270};
271
273{
274
275 /* identifiers */
276 ot->name = "New Scene";
277 ot->description = "Add new scene by type";
278 ot->idname = "SCENE_OT_new";
279
280 /* API callbacks. */
281 ot->exec = scene_new_exec;
282 ot->invoke = WM_menu_invoke;
284
285 /* flags */
287
288 /* properties */
289 ot->prop = RNA_def_enum(ot->srna, "type", scene_new_items, SCE_COPY_NEW, "Type", "");
291}
292
294
295/* -------------------------------------------------------------------- */
298
300{
301 Main *bmain = CTX_data_main(C);
302 int type = RNA_enum_get(op->ptr, "type");
303
304 if (ED_scene_sequencer_add(bmain, C, eSceneCopyMethod(type), true) == nullptr) {
305 return OPERATOR_CANCELLED;
306 }
307
308 return OPERATOR_FINISHED;
309}
310
312{
313 Scene *scene = CTX_data_scene(C);
314 const Strip *strip = blender::seq::select_active_get(scene);
315 return (strip && (strip->type == STRIP_TYPE_SCENE));
316}
317
319 PointerRNA * /*ptr*/,
320 PropertyRNA * /*prop*/,
321 bool *r_free)
322{
323 EnumPropertyItem *item = nullptr;
324 int totitem = 0;
325 uint item_index;
326
328 RNA_enum_item_add(&item, &totitem, &scene_new_items[item_index]);
329
330 bool has_scene_or_no_context = false;
331 if (C == nullptr) {
332 /* For documentation generation. */
333 has_scene_or_no_context = true;
334 }
335 else {
336 Scene *scene = CTX_data_scene(C);
338 if (strip && (strip->type == STRIP_TYPE_SCENE) && (strip->scene != nullptr)) {
339 has_scene_or_no_context = true;
340 }
341 }
342
343 if (has_scene_or_no_context) {
345 for (int i = 0; i < ARRAY_SIZE(values); i++) {
346 item_index = RNA_enum_from_value(scene_new_items, values[i]);
347 RNA_enum_item_add(&item, &totitem, &scene_new_items[item_index]);
348 }
349 }
350
351 RNA_enum_item_end(&item, &totitem);
352 *r_free = true;
353 return item;
354}
355
357{
358
359 /* identifiers */
360 ot->name = "New Scene";
361 ot->description = "Add new scene by type in the sequence editor and assign to active strip";
362 ot->idname = "SCENE_OT_new_sequencer";
363
364 /* API callbacks. */
366 ot->invoke = WM_menu_invoke;
368
369 /* flags */
371
372 /* properties */
373 ot->prop = RNA_def_enum(ot->srna, "type", scene_new_items, SCE_COPY_NEW, "Type", "");
376}
377
379
380/* -------------------------------------------------------------------- */
383
385{
386 Main *bmain = CTX_data_main(C);
387 Scene *scene = CTX_data_scene(C);
388 return BKE_scene_can_be_removed(bmain, scene);
389}
390
392{
393 Scene *scene = CTX_data_scene(C);
394
395 if (ED_scene_delete(C, CTX_data_main(C), scene) == false) {
396 return OPERATOR_CANCELLED;
397 }
398
399 if (G.debug & G_DEBUG) {
400 printf("scene delete %p\n", scene);
401 }
402
404
405 return OPERATOR_FINISHED;
406}
407
409{
410 /* identifiers */
411 ot->name = "Delete Scene";
412 ot->description = "Delete active scene";
413 ot->idname = "SCENE_OT_delete";
414
415 /* API callbacks. */
416 ot->exec = scene_delete_exec;
417 ot->poll = scene_delete_poll;
418
419 /* flags */
421}
422
424
425/* -------------------------------------------------------------------- */
428
435
wmWindow * CTX_wm_window(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
@ G_DEBUG
ViewLayer * BKE_view_layer_default_view(const Scene *scene)
void BKE_view_layer_free(ViewLayer *view_layer)
void BKE_id_delete(Main *bmain, void *idv) ATTR_NONNULL()
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
eSceneCopyMethod
Definition BKE_scene.hh:29
@ SCE_COPY_EMPTY
Definition BKE_scene.hh:31
@ SCE_COPY_NEW
Definition BKE_scene.hh:30
@ SCE_COPY_FULL
Definition BKE_scene.hh:33
@ SCE_COPY_LINK_COLLECTION
Definition BKE_scene.hh:32
void BKE_scene_free_view_layer_depsgraph(Scene *scene, ViewLayer *view_layer)
Definition scene.cc:3331
Depsgraph * BKE_scene_ensure_depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer)
Definition scene.cc:3427
bool BKE_scene_can_be_removed(const Main *bmain, const Scene *scene)
Definition scene.cc:1995
Scene * BKE_scene_duplicate(Main *bmain, Scene *sce, eSceneCopyMethod type)
Definition scene.cc:1825
Scene * BKE_scene_add(Main *bmain, const char *name)
Definition scene.cc:2010
void BKE_scene_set_background(Main *bmain, Scene *sce)
Definition scene.cc:2043
#define BLI_assert(a)
Definition BLI_assert.h:46
int BLI_findindex(const ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:586
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:131
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:688
unsigned int uint
#define ARRAY_SIZE(arr)
#define STREQ(a, b)
#define BLT_I18NCONTEXT_ID_SCENE
#define DATA_(msgid)
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_tag_on_visible_update(Main *bmain, bool do_time)
void DEG_relations_tag_update(Main *bmain)
void DEG_graph_relations_update(Depsgraph *graph)
@ ID_RECALC_AUDIO
Definition DNA_ID.h:1040
@ ID_RECALC_SEQUENCER_STRIPS
Definition DNA_ID.h:1030
@ ID_RECALC_BASE_FLAGS
Definition DNA_ID.h:1012
@ STRIP_TYPE_SCENE
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
void ED_render_engine_changed(Main *bmain, bool update_scene_data)
void ED_update_for_newframe(Main *bmain, Depsgraph *depsgraph)
bool ED_editors_flush_edits(Main *bmain)
Definition ed_util.cc:324
@ PROP_ENUM_NO_TRANSLATE
Definition RNA_types.hh:406
#define C
Definition RandGen.cpp:29
#define ND_SEQUENCER
Definition WM_types.hh:434
#define NC_SCENE
Definition WM_types.hh:375
ReportList * reports
Definition WM_types.hh:1025
#define NA_REMOVED
Definition WM_types.hh:584
#define ND_LAYER
Definition WM_types.hh:447
#define ND_SCENEBROWSE
Definition WM_types.hh:429
@ OPTYPE_UNDO
Definition WM_types.hh:182
@ OPTYPE_REGISTER
Definition WM_types.hh:180
BPy_StructRNA * depsgraph
#define printf(...)
#define G(x, y, z)
void node_tree_remove_layer_n(bNodeTree *ntree, Scene *scene, int layer_index)
Definition node.cc:5714
void relations_invalidate_cache_raw(Scene *scene, Strip *strip)
Strip * select_active_get(const Scene *scene)
int RNA_enum_from_value(const EnumPropertyItem *item, const int value)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
void RNA_enum_item_end(EnumPropertyItem **items, int *totitem)
void RNA_enum_item_add(EnumPropertyItem **items, int *totitem, const EnumPropertyItem *item)
void RNA_def_property_translation_context(PropertyRNA *prop, const char *context)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc)
Scene * ED_scene_sequencer_add(Main *bmain, bContext *C, eSceneCopyMethod method, const bool assign_strip)
Definition scene_edit.cc:68
static const EnumPropertyItem * scene_new_sequencer_enum_itemf(bContext *C, PointerRNA *, PropertyRNA *, bool *r_free)
Scene * ED_scene_add(Main *bmain, bContext *C, wmWindow *win, eSceneCopyMethod method)
static void view_layer_remove_unset_nodetrees(const Main *bmain, Scene *scene, ViewLayer *layer)
bool ED_scene_delete(bContext *C, Main *bmain, Scene *scene)
static void SCENE_OT_new(wmOperatorType *ot)
static void SCENE_OT_new_sequencer(wmOperatorType *ot)
static Scene * scene_add(Main *bmain, Scene *scene_old, eSceneCopyMethod method)
Definition scene_edit.cc:49
static wmOperatorStatus scene_new_sequencer_exec(bContext *C, wmOperator *op)
bool ED_scene_view_layer_delete(Main *bmain, Scene *scene, ViewLayer *layer, ReportList *reports)
static bool scene_delete_poll(bContext *C)
void ED_operatortypes_scene()
static bool scene_new_sequencer_poll(bContext *C)
static wmOperatorStatus scene_delete_exec(bContext *C, wmOperator *)
static bool view_layer_remove_poll(const Scene *scene, const ViewLayer *layer)
static void SCENE_OT_delete(wmOperatorType *ot)
void ED_scene_change_update(Main *bmain, Scene *scene, ViewLayer *layer)
static EnumPropertyItem scene_new_items[]
static wmOperatorStatus scene_new_exec(bContext *C, wmOperator *op)
Strip * act_strip
void * prev
Definition DNA_ID.h:407
void * next
Definition DNA_ID.h:407
char name[66]
Definition DNA_ID.h:415
void * last
void * first
ListBase scenes
Definition BKE_main.hh:245
ListBase wm
Definition BKE_main.hh:276
struct Editing * ed
ListBase view_layers
struct Scene * scene
char name[64]
struct PointerRNA * ptr
i
Definition text_draw.cc:230
void WM_main_add_notifier(uint type, void *reference)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
wmOperatorType * ot
Definition wm_files.cc:4226
void WM_jobs_kill_all_from_owner(wmWindowManager *wm, const void *owner)
Definition wm_jobs.cc:613
void WM_operatortype_append(void(*opfunc)(wmOperatorType *))
wmOperatorStatus WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *)
bool WM_operator_winactive(bContext *C)
void WM_window_set_active_scene(Main *bmain, bContext *C, wmWindow *win, Scene *scene)
Scene * WM_window_get_active_scene(const wmWindow *win)