Blender V4.5
scene.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9/* Allow using deprecated functionality for .blend file I/O. */
10#define DNA_DEPRECATED_ALLOW
11
12#include <cstddef>
13#include <cstdio>
14#include <cstring>
15#include <optional>
16
17#include "MEM_guardedalloc.h"
18
19#include "DNA_anim_types.h"
20#include "DNA_brush_types.h"
23#include "DNA_defaults.h"
26#include "DNA_linestyle_types.h"
27#include "DNA_mask_types.h"
28#include "DNA_material_types.h"
29#include "DNA_mesh_types.h"
30#include "DNA_node_types.h"
31#include "DNA_object_types.h"
32#include "DNA_rigidbody_types.h"
33#include "DNA_scene_types.h"
34#include "DNA_screen_types.h"
35#include "DNA_sequence_types.h"
36#include "DNA_sound_types.h"
37#include "DNA_space_types.h"
38#include "DNA_text_types.h"
39#include "DNA_userdef_types.h"
40#include "DNA_vfont_types.h"
41#include "DNA_view3d_types.h"
43#include "DNA_world_types.h"
44
45#include "BLI_listbase.h"
46#include "BLI_math_base.h"
47#include "BLI_math_rotation.h"
48#include "BLI_path_utils.hh"
49#include "BLI_string.h"
50#include "BLI_string_utils.hh"
51#include "BLI_threads.h"
52#include "BLI_utildefines.h"
53
54#include "BLO_readfile.hh"
55
56#include "BLT_translation.hh"
57
58#include "BKE_action.hh"
59#include "BKE_anim_data.hh"
60#include "BKE_animsys.h"
61#include "BKE_bpath.hh"
62#include "BKE_callbacks.hh"
63#include "BKE_collection.hh"
64#include "BKE_colortools.hh"
65#include "BKE_curveprofile.h"
66#include "BKE_duplilist.hh"
67#include "BKE_editmesh.hh"
68#include "BKE_effect.h"
69#include "BKE_fcurve.hh"
70#include "BKE_idprop.hh"
71#include "BKE_idtype.hh"
72#include "BKE_image.hh"
73#include "BKE_image_format.hh"
74#include "BKE_layer.hh"
75#include "BKE_lib_id.hh"
76#include "BKE_lib_query.hh"
77#include "BKE_lib_remap.hh"
78#include "BKE_main.hh"
79#include "BKE_mesh_types.hh"
80#include "BKE_node_runtime.hh"
81#include "BKE_paint.hh"
82#include "BKE_pointcache.h"
83#include "BKE_preview_image.hh"
84#include "BKE_rigidbody.h"
85#include "BKE_scene.hh"
86#include "BKE_scene_runtime.hh"
87#include "BKE_screen.hh"
88#include "BKE_sound.h"
89#include "BKE_unit.hh"
90#include "BKE_workspace.hh"
91
92#include "ANIM_action.hh"
93
94#include "DEG_depsgraph.hh"
98
99#include "RE_engine.h"
100
101#include "RNA_access.hh"
102
103#include "SEQ_iterator.hh"
104#include "SEQ_sequencer.hh"
105
106#include "BLO_read_write.hh"
107
108#include "IMB_colormanagement.hh"
109#include "IMB_imbuf.hh"
110
111#include "DRW_engine.hh"
112
113#include "bmesh.hh"
114
117
124
126
127{
128 CurveMapping *cumap = BKE_curvemapping_add(1, 0, 0, 1, 1);
129
131 cumap->preset = CURVE_PRESET_LINE;
132
133 BKE_curvemap_reset(cumap->cm, &cumap->clipr, cumap->preset, CURVEMAP_SLOPE_POSITIVE);
134 BKE_curvemapping_changed(cumap, false);
136
137 return cumap;
138}
139
141{
142 CurveMapping *cumap = BKE_curvemapping_add(1, 0, 0, 1, 1);
145
146 return cumap;
147}
148
149static void scene_init_data(ID *id)
150{
151 Scene *scene = (Scene *)id;
152 const char *colorspace_name;
153 SceneRenderView *srv;
154 CurveMapping *mblur_shutter_curve;
155
157
159
160 STRNCPY(scene->r.bake.filepath, U.renderdir);
161
162 mblur_shutter_curve = &scene->r.mblur_shutter_curve;
163 BKE_curvemapping_set_defaults(mblur_shutter_curve, 1, 0.0f, 0.0f, 1.0f, 1.0f, HD_AUTO);
164 BKE_curvemapping_init(mblur_shutter_curve);
165 BKE_curvemap_reset(mblur_shutter_curve->cm,
166 &mblur_shutter_curve->clipr,
169
171
172 scene->toolsettings->autokey_mode = uchar(U.autokey_mode);
173
177
178 /* Grease pencil multi-frame falloff curve. */
179 scene->toolsettings->gp_sculpt.cur_falloff = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
180 CurveMapping *gp_falloff_curve = scene->toolsettings->gp_sculpt.cur_falloff;
181 BKE_curvemapping_init(gp_falloff_curve);
183 gp_falloff_curve->cm, &gp_falloff_curve->clipr, CURVE_PRESET_GAUSS, CURVEMAP_SLOPE_POSITIVE);
184
185 scene->toolsettings->gp_sculpt.cur_primitive = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
186 CurveMapping *gp_primitive_curve = scene->toolsettings->gp_sculpt.cur_primitive;
187 BKE_curvemapping_init(gp_primitive_curve);
188 BKE_curvemap_reset(gp_primitive_curve->cm,
189 &gp_primitive_curve->clipr,
192
194 scene->unit.scale_length = 1.0f;
198 scene->unit.temperature_unit = uchar(
200
201 {
203 pset = &scene->toolsettings->particle;
204 for (size_t i = 1; i < ARRAY_SIZE(pset->brush); i++) {
205 pset->brush[i] = pset->brush[0];
206 }
207 pset->brush[PE_BRUSH_CUT].strength = 1.0f;
208 }
209
211
212 STRNCPY(scene->r.pic, U.renderdir);
213
214 /* NOTE: in header_info.c the scene copy happens...,
215 * if you add more to renderdata it has to be checked there. */
216
217 /* multiview - stereo */
219 srv = static_cast<SceneRenderView *>(scene->r.views.first);
221
223 srv = static_cast<SceneRenderView *>(scene->r.views.last);
225
227
228 /* color management */
230
233 &scene->view_settings, &scene->display_settings, "AgX");
234 STRNCPY(scene->sequencer_colorspace_settings.name, colorspace_name);
235
236 BKE_image_format_init(&scene->r.im_format, true);
237 BKE_image_format_init(&scene->r.bake.im_format, true);
238
239 /* Curve Profile */
241
242 /* Sequencer */
244
245 for (size_t i = 0; i < ARRAY_SIZE(scene->orientation_slots); i++) {
246 scene->orientation_slots[i].index_custom = -1;
247 }
248
249 /* Master Collection */
251
252 BKE_view_layer_add(scene, DATA_("ViewLayer"), nullptr, VIEWLAYER_ADD_NEW);
253
254 scene->runtime = MEM_new<SceneRuntime>(__func__);
255}
256
257static void scene_copy_data(Main *bmain,
258 std::optional<Library *> owner_library,
259 ID *id_dst,
260 const ID *id_src,
261 const int flag)
262{
263 Scene *scene_dst = (Scene *)id_dst;
264 const Scene *scene_src = (const Scene *)id_src;
265 /* Never handle user-count here for own sub-data. */
266 const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
267 /* Always need allocation of the embedded ID data. */
268 const int flag_embedded_id_data = flag_subdata & ~LIB_ID_CREATE_NO_ALLOCATE;
269
270 scene_dst->ed = nullptr;
271 scene_dst->depsgraph_hash = nullptr;
272 scene_dst->fps_info = nullptr;
273
274 /* Master Collection */
275 if (scene_src->master_collection) {
276 BKE_id_copy_in_lib(bmain,
277 owner_library,
278 &scene_src->master_collection->id,
279 &scene_dst->id,
280 reinterpret_cast<ID **>(&scene_dst->master_collection),
281 flag_embedded_id_data);
282 }
283
284 /* View Layers */
285 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene_src->view_layers) {
286 BKE_view_layer_synced_ensure(scene_src, view_layer);
287 }
288 BLI_duplicatelist(&scene_dst->view_layers, &scene_src->view_layers);
289 for (ViewLayer *view_layer_src = static_cast<ViewLayer *>(scene_src->view_layers.first),
290 *view_layer_dst = static_cast<ViewLayer *>(scene_dst->view_layers.first);
291 view_layer_src;
292 view_layer_src = view_layer_src->next, view_layer_dst = view_layer_dst->next)
293 {
294 BKE_view_layer_copy_data(scene_dst, scene_src, view_layer_dst, view_layer_src, flag_subdata);
295 }
296
297 BKE_copy_time_markers(scene_dst->markers, scene_src->markers, flag);
298
299 BLI_duplicatelist(&(scene_dst->transform_spaces), &(scene_src->transform_spaces));
300 BLI_duplicatelist(&(scene_dst->r.views), &(scene_src->r.views));
301 BKE_keyingsets_copy(&(scene_dst->keyingsets), &(scene_src->keyingsets));
302
303 if (scene_src->nodetree) {
304 BKE_id_copy_in_lib(bmain,
305 owner_library,
306 &scene_src->nodetree->id,
307 &scene_dst->id,
308 reinterpret_cast<ID **>(&scene_dst->nodetree),
309 flag_embedded_id_data);
310 /* TODO this should not be needed anymore? Should be handled by generic remapping code in
311 * #BKE_id_copy_in_lib. */
313 scene_dst->nodetree,
314 (void *)(&scene_src->id),
315 &scene_dst->id,
317 }
318
319 if (scene_src->rigidbody_world) {
321 flag_subdata);
322 }
323
324 /* copy color management settings */
326 &scene_src->display_settings);
330
331 BKE_image_format_copy(&scene_dst->r.im_format, &scene_src->r.im_format);
332 BKE_image_format_copy(&scene_dst->r.bake.im_format, &scene_src->r.bake.im_format);
333
335
336 /* tool settings */
337 scene_dst->toolsettings = BKE_toolsettings_copy(scene_dst->toolsettings, flag_subdata);
338
339 if (scene_src->display.shading.prop) {
340 scene_dst->display.shading.prop = IDP_CopyProperty(scene_src->display.shading.prop);
341 }
342
344
345 /* Copy sequencer, this is local data! */
346 if (scene_src->ed) {
347 scene_dst->ed = MEM_callocN<Editing>(__func__);
348 scene_dst->ed->seqbasep = &scene_dst->ed->seqbase;
349 scene_dst->ed->cache_flag = scene_src->ed->cache_flag;
350 scene_dst->ed->show_missing_media_flag = scene_src->ed->show_missing_media_flag;
351 scene_dst->ed->proxy_storage = scene_src->ed->proxy_storage;
352 STRNCPY(scene_dst->ed->proxy_dir, scene_src->ed->proxy_dir);
354 scene_dst,
355 &scene_dst->ed->seqbase,
356 &scene_src->ed->seqbase,
358 flag_subdata);
359 BLI_duplicatelist(&scene_dst->ed->channels, &scene_src->ed->channels);
360 scene_dst->ed->displayed_channels = &scene_dst->ed->channels;
361 }
362
363 if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
364 BKE_previewimg_id_copy(&scene_dst->id, &scene_src->id);
365 }
366 else {
367 scene_dst->preview = nullptr;
368 }
369
370 BKE_scene_copy_data_eevee(scene_dst, scene_src);
371
372 scene_dst->runtime = MEM_new<SceneRuntime>(__func__);
373}
374
375static void scene_free_markers(Scene *scene, bool do_id_user)
376{
377 LISTBASE_FOREACH_MUTABLE (TimeMarker *, marker, &scene->markers) {
378 if (marker->prop != nullptr) {
379 IDP_FreePropertyContent_ex(marker->prop, do_id_user);
380 MEM_freeN(marker->prop);
381 }
382 MEM_freeN(marker);
383 }
384}
385
386static void scene_free_data(ID *id)
387{
388 Scene *scene = (Scene *)id;
389 const bool do_id_user = false;
390
391 blender::seq::editing_free(scene, do_id_user);
392
394
395 /* is no lib link block, but scene extension */
396 if (scene->nodetree) {
398 MEM_freeN(scene->nodetree);
399 scene->nodetree = nullptr;
400 }
401
402 if (scene->rigidbody_world) {
403 /* Prevent rigidbody freeing code to follow other IDs pointers, this should never be allowed
404 * nor necessary from here, and with new undo code, those pointers may be fully invalid or
405 * worse, pointing to data actually belonging to new BMain! */
406 scene->rigidbody_world->constraints = nullptr;
407 scene->rigidbody_world->group = nullptr;
409 }
410
411 scene_free_markers(scene, do_id_user);
413 BLI_freelistN(&scene->r.views);
414
416 scene->toolsettings = nullptr;
417
419
420 MEM_SAFE_FREE(scene->fps_info);
421
423
427
430
431 LISTBASE_FOREACH_MUTABLE (ViewLayer *, view_layer, &scene->view_layers) {
432 BLI_remlink(&scene->view_layers, view_layer);
433 BKE_view_layer_free_ex(view_layer, do_id_user);
434 }
435
436 /* Master Collection */
437 /* TODO: what to do with do_id_user? it's also true when just
438 * closing the file which seems wrong? should decrement users
439 * for objects directly in the master collection? then other
440 * collections in the scene need to do it too? */
441 if (scene->master_collection) {
445 scene->master_collection = nullptr;
446 }
447
448 if (scene->display.shading.prop) {
450 scene->display.shading.prop = nullptr;
451 }
452
453 /* These are freed on `do_versions`. */
454 BLI_assert(scene->layer_properties == nullptr);
455
456 MEM_delete(scene->runtime);
457}
458
460 ID **id_pointer,
461 void *user_data,
462 const LibraryForeachIDCallbackFlag cb_flag)
463{
466 data, BKE_lib_query_foreachid_process(data, id_pointer, cb_flag));
467}
468
474 /* Undo when preserving tool-settings from old scene, we also want to try to preserve that ID
475 * pointer from its old scene's value. */
477 /* Undo when preserving tool-settings from old scene, we want to keep the new value of that ID
478 * pointer. */
480};
481
483 ID **id_p,
485 BlendLibReader *reader,
486 ID **id_old_p,
487 const uint cb_flag)
488{
489 switch (action) {
491 ID *id_old = *id_old_p;
492 /* Old data has not been remapped to new values of the pointers, if we want to keep the old
493 * pointer here we need its new address. */
494 ID *id_old_new = id_old != nullptr ? BLO_read_get_new_id_address_from_session_uid(
495 reader, id_old->session_uid) :
496 nullptr;
497 /* The new address may be the same as the old one, in which case there is nothing to do. */
498 if (id_old_new == id_old) {
499 break;
500 }
501 if (id_old_new != nullptr) {
502 BLI_assert(id_old == id_old_new->orig_id);
503 *id_old_p = id_old_new;
504 if (cb_flag & IDWALK_CB_USER) {
505 id_us_plus_no_lib(id_old_new);
506 id_us_min(id_old);
507 }
508 break;
509 }
510
511 /* We failed to find a new valid pointer for the previous ID, just keep the current one as
512 * if we had been under #SCENE_FOREACH_UNDO_NO_RESTORE case.
513 *
514 * There is a nasty twist here though: a previous call to 'undo_preserve' on the Scene ID may
515 * have modified it, even though the undo step detected it as unmodified. In such case, the
516 * value of `*id_p` may end up also pointing to an invalid (no more in newly read Main) ID,
517 * so it also needs to be checked from its `session_uid`. */
518 ID *id = *id_p;
519 ID *id_new = id != nullptr ?
521 nullptr;
522 if (id_new != id) {
523 *id_p = id_new;
524 if (cb_flag & IDWALK_CB_USER) {
525 id_us_plus_no_lib(id_new);
526 id_us_min(id);
527 }
528 }
529 std::swap(*id_p, *id_old_p);
530 break;
531 }
533 /* Counteract the swap of the whole ToolSettings container struct. */
534 std::swap(*id_p, *id_old_p);
535 break;
536 }
537}
538
539/* Special handling is needed here, as `scene_foreach_toolsettings` (and its dependency
540 * `scene_foreach_paint`) are also used by `scene_undo_preserve`, where `LibraryForeachIDData
541 * *data` is nullptr. */
542#define BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER_P( \
543 _data, _id_p, _do_undo_restore, _action, _reader, _id_old_p, _cb_flag) \
544 { \
545 if (_do_undo_restore) { \
546 scene_foreach_toolsettings_id_pointer_process( \
547 (ID **)(_id_p), _action, _reader, (ID **)(_id_old_p), _cb_flag); \
548 } \
549 else { \
550 BLI_assert((_data) != nullptr); \
551 BKE_LIB_FOREACHID_PROCESS_IDSUPER_P(_data, _id_p, _cb_flag); \
552 } \
553 } \
554 (void)0
555
556#define BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_FUNCTION_CALL( \
557 _data, _do_undo_restore, _func_call) \
558 { \
559 if (_do_undo_restore) { \
560 _func_call; \
561 } \
562 else { \
563 BLI_assert((_data) != nullptr); \
564 BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(_data, _func_call); \
565 } \
566 } \
567 (void)0
568
570 Paint *paint,
571 const bool do_undo_restore,
572 BlendLibReader *reader,
573 Paint *paint_old)
574{
575 /* `paint` may be nullptr in 'undo_preserve' case, when the relevant sub-data does not exist in
576 * newly read toolsettings, but does exist in old existing ones.
577 *
578 * This function should never be called in case the old toolsettings do not have the relevant
579 * `paint_old` data. */
580 BLI_assert(paint_old != nullptr);
581
582 Brush *brush_tmp = nullptr;
583 Brush **brush_p = paint ? &paint->brush : &brush_tmp;
585 brush_p,
586 do_undo_restore,
588 reader,
589 &paint_old->brush,
591
592 Brush *eraser_brush_tmp = nullptr;
593 Brush **eraser_brush_p = paint ? &paint->eraser_brush : &eraser_brush_tmp;
595 eraser_brush_p,
596 do_undo_restore,
598 reader,
599 &paint_old->eraser_brush,
601
602 Palette *palette_tmp = nullptr;
603 Palette **palette_p = paint ? &paint->palette : &palette_tmp;
605 palette_p,
606 do_undo_restore,
608 reader,
609 &paint_old->palette,
611}
612
614 ToolSettings *toolsett,
615 const bool do_undo_restore,
616 BlendLibReader *reader,
617 ToolSettings *toolsett_old)
618{
619 /* In regular foreach_id case, only one set of data is processed, both pointers are expected to
620 * be the same.
621 *
622 * In undo_preserve case, both pointers may be different (see #lib_link_all for why they may be
623 * the same in some cases). */
624 BLI_assert(do_undo_restore || (toolsett == toolsett_old));
625 BLI_assert(!ELEM(nullptr, toolsett, toolsett_old));
626
627 /* NOTE: In 'undo_preserve' case, the 'old' data is the source of truth here, since it is the one
628 * that will be re-used in newly read Main and therefore needs valid, existing in new Main, ID
629 * pointers. */
630
632 &toolsett->particle.scene,
633 do_undo_restore,
635 reader,
636 &toolsett_old->particle.scene,
639 &toolsett->particle.object,
640 do_undo_restore,
642 reader,
643 &toolsett_old->particle.object,
646 &toolsett->particle.shape_object,
647 do_undo_restore,
649 reader,
650 &toolsett_old->particle.shape_object,
652
654 data, &toolsett->imapaint.paint, do_undo_restore, reader, &toolsett_old->imapaint.paint);
656 &toolsett->imapaint.stencil,
657 do_undo_restore,
659 reader,
660 &toolsett_old->imapaint.stencil,
663 &toolsett->imapaint.clone,
664 do_undo_restore,
666 reader,
667 &toolsett_old->imapaint.clone,
670 &toolsett->imapaint.canvas,
671 do_undo_restore,
673 reader,
674 &toolsett_old->imapaint.canvas,
676
677 Paint *paint, *paint_old;
678
679 if (toolsett_old->vpaint) {
680 paint = toolsett->vpaint ? &toolsett->vpaint->paint : nullptr;
681 paint_old = &toolsett_old->vpaint->paint;
683 data,
684 do_undo_restore,
685 scene_foreach_paint(data, paint, do_undo_restore, reader, paint_old));
686 }
687 if (toolsett_old->wpaint) {
688 paint = toolsett->wpaint ? &toolsett->wpaint->paint : nullptr;
689 paint_old = &toolsett_old->wpaint->paint;
691 data,
692 do_undo_restore,
693 scene_foreach_paint(data, paint, do_undo_restore, reader, paint_old));
694 }
695 if (toolsett_old->sculpt) {
696 paint = toolsett->sculpt ? &toolsett->sculpt->paint : nullptr;
697 paint_old = &toolsett_old->sculpt->paint;
699 data,
700 do_undo_restore,
701 scene_foreach_paint(data, paint, do_undo_restore, reader, paint_old));
702
703 /* WARNING: Handling this object pointer is fairly intricated, to support both 'regular'
704 * foreach_id processing (in which case both sets of data, current and old, are the same), and
705 * the restore-after-undo cases. It does not have a helper, because so far it is the only case
706 * of having to deal with non-'paint' data in a sub-toolsett struct. */
707 Object *gravity_object = toolsett->sculpt ? toolsett->sculpt->gravity_object : nullptr;
708 Object *gravity_object_old = toolsett_old->sculpt->gravity_object;
710 &gravity_object,
711 do_undo_restore,
713 reader,
714 &gravity_object_old,
716 if (toolsett->sculpt) {
717 toolsett->sculpt->gravity_object = gravity_object;
718 }
719 /* Do not re-assign `gravity_object_old` object if both current and old data are the same
720 * (foreach_id case), that would nullify assignement above, making remapping cases fail. */
721 if (toolsett_old != toolsett) {
722 toolsett_old->sculpt->gravity_object = gravity_object_old;
723 }
724 }
725 if (toolsett_old->gp_paint) {
726 paint = toolsett->gp_paint ? &toolsett->gp_paint->paint : nullptr;
727 paint_old = &toolsett_old->gp_paint->paint;
729 data,
730 do_undo_restore,
731 scene_foreach_paint(data, paint, do_undo_restore, reader, paint_old));
732 }
733 if (toolsett_old->gp_vertexpaint) {
734 paint = toolsett->gp_vertexpaint ? &toolsett->gp_vertexpaint->paint : nullptr;
735 paint_old = &toolsett_old->gp_vertexpaint->paint;
737 data,
738 do_undo_restore,
739 scene_foreach_paint(data, paint, do_undo_restore, reader, paint_old));
740 }
741 if (toolsett_old->gp_sculptpaint) {
742 paint = toolsett->gp_sculptpaint ? &toolsett->gp_sculptpaint->paint : nullptr;
743 paint_old = &toolsett_old->gp_sculptpaint->paint;
745 data,
746 do_undo_restore,
747 scene_foreach_paint(data, paint, do_undo_restore, reader, paint_old));
748 }
749 if (toolsett_old->gp_weightpaint) {
750 paint = toolsett->gp_weightpaint ? &toolsett->gp_weightpaint->paint : nullptr;
751 paint_old = &toolsett_old->gp_weightpaint->paint;
753 data,
754 do_undo_restore,
755 scene_foreach_paint(data, paint, do_undo_restore, reader, paint_old));
756 }
757 if (toolsett_old->curves_sculpt) {
758 paint = toolsett->curves_sculpt ? &toolsett->curves_sculpt->paint : nullptr;
759 paint_old = &toolsett_old->curves_sculpt->paint;
761 data,
762 do_undo_restore,
763 scene_foreach_paint(data, paint, do_undo_restore, reader, paint_old));
764 }
765
767 data,
769 do_undo_restore,
771 reader,
772 &toolsett_old->gp_sculpt.guide.reference_object,
774}
775
776#undef BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER
777#undef BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_FUNCTION_CALL
778
780 ListBase *lb,
781 const bool is_master)
782{
783 const int data_flags = BKE_lib_query_foreachid_process_flags_get(data);
784
786 if ((data_flags & IDWALK_NO_ORIG_POINTERS_ACCESS) == 0 && lc->collection != nullptr) {
787 BLI_assert(is_master == ((lc->collection->id.flag & ID_FLAG_EMBEDDED_DATA) != 0));
788 }
792 scene_foreach_layer_collection(data, &lc->layer_collections, false);
793 }
794}
795
796static bool strip_foreach_member_id_cb(Strip *strip, void *user_data)
797{
798 LibraryForeachIDData *data = static_cast<LibraryForeachIDData *>(user_data);
800
801/* Only for deprecated data. */
802#define FOREACHID_PROCESS_ID_NOCHECK(_data, _id_super, _cb_flag) \
803 { \
804 BKE_lib_query_foreachid_process((_data), reinterpret_cast<ID **>(&(_id_super)), (_cb_flag)); \
805 if (BKE_lib_query_foreachid_iter_stop(_data)) { \
806 return false; \
807 } \
808 } \
809 ((void)0)
810
811#define FOREACHID_PROCESS_IDSUPER(_data, _id_super, _cb_flag) \
812 { \
813 CHECK_TYPE(&((_id_super)->id), ID *); \
814 FOREACHID_PROCESS_ID_NOCHECK(_data, _id_super, _cb_flag); \
815 } \
816 ((void)0)
817
824 BKE_lib_query_idpropertiesForeachIDLink_callback(prop, data);
825 });
827 BKE_lib_query_idpropertiesForeachIDLink_callback(prop, data);
828 });
831 }
832
833 if (strip->type == STRIP_TYPE_TEXT && strip->effectdata) {
834 TextVars *text_data = static_cast<TextVars *>(strip->effectdata);
836 }
837
840 }
841
842#undef FOREACHID_PROCESS_IDSUPER
843#undef FOREACHID_PROCESS_ID_NOCHECK
844
845 return true;
846}
847
849{
850 Scene *scene = reinterpret_cast<Scene *>(id);
852
859 if (scene->nodetree) {
860 /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
863 }
864 if (scene->ed) {
866 data,
868 }
869
872
873 /* This pointer can be nullptr during old files reading, better be safe than sorry. */
874 if (scene->master_collection != nullptr) {
877 }
878
879 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
880 BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, view_layer->mat_override, IDWALK_CB_USER);
881 BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, view_layer->world_override, IDWALK_CB_USER);
883 data,
884 IDP_foreach_property(view_layer->id_properties, IDP_TYPE_FILTER_ID, [&](IDProperty *prop) {
885 BKE_lib_query_idpropertiesForeachIDLink_callback(prop, data);
886 }));
888 data,
890 view_layer->system_properties, IDP_TYPE_FILTER_ID, [&](IDProperty *prop) {
891 BKE_lib_query_idpropertiesForeachIDLink_callback(prop, data);
892 }));
893
894 BKE_view_layer_synced_ensure(scene, view_layer);
897 data,
898 base->object,
900 }
901
903 data, scene_foreach_layer_collection(data, &view_layer->layer_collections, true));
904
905 LISTBASE_FOREACH (FreestyleModuleConfig *, fmc, &view_layer->freestyle_config.modules) {
907 }
908
909 LISTBASE_FOREACH (FreestyleLineSet *, fls, &view_layer->freestyle_config.linesets) {
912 }
913 }
914
915 LISTBASE_FOREACH (TimeMarker *, marker, &scene->markers) {
918 data, IDP_foreach_property(marker->prop, IDP_TYPE_FILTER_ID, [&](IDProperty *prop) {
919 BKE_lib_query_idpropertiesForeachIDLink_callback(prop, data);
920 }));
921 }
922
923 ToolSettings *toolsett = scene->toolsettings;
924 if (toolsett) {
926 data, scene_foreach_toolsettings(data, toolsett, false, nullptr, toolsett));
927 }
928
929 if (scene->rigidbody_world) {
931 data,
934 }
935
937 LISTBASE_FOREACH_MUTABLE (Base *, base_legacy, &scene->base) {
939 }
940
941 LISTBASE_FOREACH (SceneRenderLayer *, srl, &scene->r.layers) {
943 LISTBASE_FOREACH (FreestyleModuleConfig *, fmc, &srl->freestyleConfig.modules) {
945 }
946 LISTBASE_FOREACH (FreestyleLineSet *, fls, &srl->freestyleConfig.linesets) {
949 }
950 }
951 }
952}
953
954static bool strip_foreach_path_callback(Strip *strip, void *user_data)
955{
956 if (STRIP_HAS_PATH(strip)) {
957 StripElem *se = strip->data->stripdata;
958 BPathForeachPathData *bpath_data = (BPathForeachPathData *)user_data;
959
960 if (ELEM(strip->type, STRIP_TYPE_MOVIE, STRIP_TYPE_SOUND_RAM) && se) {
962 strip->data->dirpath,
963 sizeof(strip->data->dirpath),
964 se->filename,
965 sizeof(se->filename));
966 }
967 else if ((strip->type == STRIP_TYPE_IMAGE) && se) {
968 /* NOTE: An option not to loop over all strips could be useful? */
969 uint len = uint(MEM_allocN_len(se)) / uint(sizeof(*se));
970 uint i;
971
973 /* only operate on one path */
974 len = std::min(1u, len);
975 }
976
977 for (i = 0; i < len; i++, se++) {
979 strip->data->dirpath,
980 sizeof(strip->data->dirpath),
981 se->filename,
982 sizeof(se->filename));
983 }
984 }
985 else {
986 /* simple case */
988 bpath_data, strip->data->dirpath, sizeof(strip->data->dirpath));
989 }
990 }
991 return true;
992}
993
994static void scene_foreach_path(ID *id, BPathForeachPathData *bpath_data)
995{
996 Scene *scene = (Scene *)id;
997 if (scene->ed != nullptr) {
999 }
1000}
1001
1002static void scene_foreach_cache(ID *id,
1003 IDTypeForeachCacheFunctionCallback function_callback,
1004 void *user_data)
1005{
1006 Scene *scene = (Scene *)id;
1007 if (scene->ed != nullptr) {
1008 IDCacheKey key;
1009 key.id_session_uid = id->session_uid;
1010 /* Preserve VSE thumbnail cache across global undo steps. */
1011 key.identifier = offsetof(Editing, runtime.thumbnail_cache);
1012 function_callback(id, &key, (void **)&scene->ed->runtime.thumbnail_cache, 0, user_data);
1013 }
1014}
1015
1016static void scene_blend_write(BlendWriter *writer, ID *id, const void *id_address)
1017{
1018 Scene *sce = (Scene *)id;
1019
1020 if (BLO_write_is_undo(writer)) {
1021 /* Clean up, important in undo case to reduce false detection of changed data-blocks. */
1022 /* XXX This UI data should not be stored in Scene at all... */
1023 sce->cursor = View3DCursor{};
1024 }
1025
1026 /* write LibData */
1027 BLO_write_id_struct(writer, Scene, id_address, &sce->id);
1028 BKE_id_blend_write(writer, &sce->id);
1029
1031
1032 /* direct data */
1033 ToolSettings *tos = sce->toolsettings;
1034 BLO_write_struct(writer, ToolSettings, tos);
1035
1038 }
1039
1042 }
1043
1046 }
1047
1048 if (tos->vpaint) {
1049 BLO_write_struct(writer, VPaint, tos->vpaint);
1050 BKE_paint_blend_write(writer, &tos->vpaint->paint);
1051 }
1052 if (tos->wpaint) {
1053 BLO_write_struct(writer, VPaint, tos->wpaint);
1054 BKE_paint_blend_write(writer, &tos->wpaint->paint);
1055 }
1056 if (tos->sculpt) {
1057 BLO_write_struct(writer, Sculpt, tos->sculpt);
1058 if (tos->sculpt->automasking_cavity_curve) {
1060 }
1063 }
1064
1065 BKE_paint_blend_write(writer, &tos->sculpt->paint);
1066 }
1067 if (tos->uvsculpt.strength_curve) {
1069 }
1070 if (tos->gp_paint) {
1071 BLO_write_struct(writer, GpPaint, tos->gp_paint);
1072 BKE_paint_blend_write(writer, &tos->gp_paint->paint);
1073 }
1074 if (tos->gp_vertexpaint) {
1077 }
1078 if (tos->gp_sculptpaint) {
1081 }
1082 if (tos->gp_weightpaint) {
1085 }
1086 if (tos->curves_sculpt) {
1089 }
1090 /* write grease-pencil custom ipo curve to file */
1091 if (tos->gp_interpolate.custom_ipo) {
1093 }
1094 /* write grease-pencil multi-frame falloff curve to file */
1095 if (tos->gp_sculpt.cur_falloff) {
1097 }
1098 /* write grease-pencil primitive curve to file */
1099 if (tos->gp_sculpt.cur_primitive) {
1101 }
1102 /* Write the curve profile to the file. */
1103 if (tos->custom_bevel_profile_preset) {
1105 }
1106 if (tos->sequencer_tool_settings) {
1108 }
1109
1110 BKE_paint_blend_write(writer, &tos->imapaint.paint);
1111
1112 Editing *ed = sce->ed;
1113 if (ed) {
1114 BLO_write_struct(writer, Editing, ed);
1115
1116 blender::seq::blend_write(writer, &ed->seqbase);
1117 LISTBASE_FOREACH (SeqTimelineChannel *, channel, &ed->channels) {
1118 BLO_write_struct(writer, SeqTimelineChannel, channel);
1119 }
1120 /* new; meta stack too, even when its nasty restore code */
1121 LISTBASE_FOREACH (MetaStack *, ms, &ed->metastack) {
1122 BLO_write_struct(writer, MetaStack, ms);
1123 }
1124 }
1125
1126 /* writing dynamic list of TimeMarkers to the blend file */
1128
1129 /* writing dynamic list of TransformOrientations to the blend file */
1132 }
1133
1134 /* writing MultiView to the blend file */
1135 LISTBASE_FOREACH (SceneRenderView *, srv, &sce->r.views) {
1136 BLO_write_struct(writer, SceneRenderView, srv);
1137 }
1138
1139 if (sce->nodetree) {
1140 BLO_Write_IDBuffer temp_embedded_id_buffer{sce->nodetree->id, writer};
1141 bNodeTree *temp_nodetree = reinterpret_cast<bNodeTree *>(temp_embedded_id_buffer.get());
1142 /* Set deprecated chunksize for forward compatibility. */
1143 temp_nodetree->chunksize = 256;
1144 BLO_write_struct_at_address(writer, bNodeTree, sce->nodetree, temp_nodetree);
1145 blender::bke::node_tree_blend_write(writer, temp_nodetree);
1146 }
1147
1151
1152 /* writing RigidBodyWorld data to the blend file */
1153 if (sce->rigidbody_world) {
1154 /* Set deprecated pointers to prevent crashes of older Blenders */
1155 sce->rigidbody_world->pointcache = sce->rigidbody_world->shared->pointcache;
1156 sce->rigidbody_world->ptcaches = sce->rigidbody_world->shared->ptcaches;
1158
1162 }
1163
1164 BKE_previewimg_blend_write(writer, sce->preview);
1166
1167 LISTBASE_FOREACH (ViewLayer *, view_layer, &sce->view_layers) {
1168 BKE_view_layer_blend_write(writer, sce, view_layer);
1169 }
1170
1171 if (sce->master_collection) {
1172 BLO_Write_IDBuffer temp_embedded_id_buffer{sce->master_collection->id, writer};
1173 Collection *temp_collection = reinterpret_cast<Collection *>(temp_embedded_id_buffer.get());
1174 BKE_collection_blend_write_prepare_nolib(writer, temp_collection);
1175 BLO_write_struct_at_address(writer, Collection, sce->master_collection, temp_collection);
1176 BKE_collection_blend_write_nolib(writer, temp_collection);
1177 }
1178
1180
1181 /* Freed on `do_versions()`. */
1182 BLI_assert(sce->layer_properties == nullptr);
1183}
1184
1185static void direct_link_paint_helper(BlendDataReader *reader, const Scene *scene, Paint **paint)
1186{
1187 /* TODO: is this needed. */
1188 BLO_read_struct(reader, Paint, paint);
1189
1190 if (*paint) {
1191 BKE_paint_blend_read_data(reader, scene, *paint);
1192 }
1193}
1194
1196{
1197 BLO_read_struct_list(reader, Strip, lb);
1198
1199 LISTBASE_FOREACH_MUTABLE (Strip *, strip, lb) {
1200 /* Sanity check. */
1202 BLI_freelinkN(lb, strip);
1204 }
1205 else if (strip->seqbase.first) {
1206 link_recurs_seq(reader, &strip->seqbase);
1207 }
1208 }
1209}
1210
1212{
1213 Scene *sce = (Scene *)id;
1214
1215 sce->depsgraph_hash = nullptr;
1216 sce->fps_info = nullptr;
1217
1220
1222
1223 /* set users to one by default, not in lib-link, this will increase it for compo nodes */
1224 id_us_ensure_real(&sce->id);
1225
1226 sce->runtime = MEM_new<SceneRuntime>(__func__);
1227
1228 BLO_read_struct_list(reader, Base, &(sce->base));
1229
1232
1233 BLO_read_struct(reader, Base, &sce->basact);
1234
1236 if (sce->toolsettings) {
1237
1238 /* Reset last_location and last_hit, so they are not remembered across sessions. In some files
1239 * these are also NaN, which could lead to crashes in painting. */
1241 zero_v3(ups->last_location);
1242 ups->last_hit = 0;
1243
1244 /* Prior to 5.0, the brush->size value is expected to be the radius, not the diameter. To
1245 * ensure correct behavior, convert this when reading newer files. */
1246 if (BLO_read_fileversion_get(reader) >= 500) {
1247 ups->size = std::max(ups->size / 2, 1);
1248 ups->unprojected_radius = std::max(ups->unprojected_radius / 2, 0.001f);
1249
1250 sce->toolsettings->uvsculpt.size = std::max(sce->toolsettings->uvsculpt.size / 2, 1);
1251 }
1252
1254 if (ups->curve_rand_hue) {
1257 }
1258
1260 if (ups->curve_rand_saturation) {
1263 }
1264
1266 if (ups->curve_rand_value) {
1269 }
1270
1271 direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->sculpt);
1272 direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->vpaint);
1273 direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->wpaint);
1274 direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->gp_paint);
1279
1281
1282 sce->toolsettings->particle.paintcursor = nullptr;
1283 sce->toolsettings->particle.scene = nullptr;
1284 sce->toolsettings->particle.object = nullptr;
1285 sce->toolsettings->gp_sculpt.paintcursor = nullptr;
1290 }
1291
1292 if (sce->toolsettings->sculpt) {
1296
1300 }
1301
1306 }
1307
1309 }
1310
1311 /* Relink grease pencil interpolation curves. */
1315 }
1316 /* Relink grease pencil multi-frame falloff curve. */
1320 }
1321 /* Relink grease pencil primitive curve. */
1325 }
1326
1327 /* Relink toolsettings curve profile. */
1331 }
1332
1335 }
1336
1337 if (sce->ed) {
1338 ListBase *old_seqbasep = &sce->ed->seqbase;
1339 ListBase *old_displayed_channels = &sce->ed->channels;
1340
1341 BLO_read_struct(reader, Editing, &sce->ed);
1342 Editing *ed = sce->ed;
1343
1344 ed->act_strip = static_cast<Strip *>(
1346 ed->prefetch_job = nullptr;
1347 ed->runtime.strip_lookup = nullptr;
1348 ed->runtime.media_presence = nullptr;
1349 ed->runtime.thumbnail_cache = nullptr;
1350 ed->runtime.intra_frame_cache = nullptr;
1351 ed->runtime.source_image_cache = nullptr;
1352 ed->runtime.final_image_cache = nullptr;
1353
1354 /* recursive link sequences, lb will be correctly initialized */
1355 link_recurs_seq(reader, &ed->seqbase);
1356
1357 /* Read in sequence member data. */
1358 blender::seq::blend_read(reader, &ed->seqbase);
1360
1361 /* link metastack, slight abuse of structs here,
1362 * have to restore pointer to internal part in struct */
1363 {
1364 const int seqbase_offset_file = BLO_read_struct_member_offset(
1365 reader, "Strip", "ListBase", "seqbase");
1366 const int channels_offset_file = BLO_read_struct_member_offset(
1367 reader, "Strip", "ListBase", "channels");
1368 const size_t seqbase_offset_mem = offsetof(Strip, seqbase);
1369 const size_t channels_offset_mem = offsetof(Strip, channels);
1370
1371 /* seqbase root pointer */
1372 if (ed->seqbasep == old_seqbasep || seqbase_offset_file < 0) {
1373 ed->seqbasep = &ed->seqbase;
1374 }
1375 else {
1376 void *seqbase_poin = POINTER_OFFSET(ed->seqbasep, -seqbase_offset_file);
1377
1378 seqbase_poin = BLO_read_get_new_data_address_no_us(reader, seqbase_poin, sizeof(Strip));
1379
1380 if (seqbase_poin) {
1381 ed->seqbasep = (ListBase *)POINTER_OFFSET(seqbase_poin, seqbase_offset_mem);
1382 }
1383 else {
1384 ed->seqbasep = &ed->seqbase;
1385 }
1386 }
1387
1388 /* Active channels root pointer. */
1389 if (ELEM(ed->displayed_channels, old_displayed_channels, nullptr) ||
1390 channels_offset_file < 0)
1391 {
1392 ed->displayed_channels = &ed->channels;
1393 }
1394 else {
1395 void *channels_poin = POINTER_OFFSET(ed->displayed_channels, -channels_offset_file);
1397 reader, channels_poin, sizeof(SeqTimelineChannel));
1398
1399 if (channels_poin) {
1400 ed->displayed_channels = (ListBase *)POINTER_OFFSET(channels_poin, channels_offset_mem);
1401 }
1402 else {
1403 ed->displayed_channels = &ed->channels;
1404 }
1405 }
1406
1407 /* stack */
1408 BLO_read_struct_list(reader, MetaStack, &(ed->metastack));
1409
1410 LISTBASE_FOREACH (MetaStack *, ms, &ed->metastack) {
1411 BLO_read_struct(reader, Strip, &ms->parent_strip);
1412
1413 if (ms->oldbasep == old_seqbasep || seqbase_offset_file < 0) {
1414 ms->oldbasep = &ed->seqbase;
1415 }
1416 else {
1417 void *seqbase_poin = POINTER_OFFSET(ms->oldbasep, -seqbase_offset_file);
1418 seqbase_poin = BLO_read_get_new_data_address_no_us(reader, seqbase_poin, sizeof(Strip));
1419 if (seqbase_poin) {
1420 ms->oldbasep = (ListBase *)POINTER_OFFSET(seqbase_poin, seqbase_offset_mem);
1421 }
1422 else {
1423 ms->oldbasep = &ed->seqbase;
1424 }
1425 }
1426
1427 if (ELEM(ms->old_channels, old_displayed_channels, nullptr) || channels_offset_file < 0) {
1428 ms->old_channels = &ed->channels;
1429 }
1430 else {
1431 void *channels_poin = POINTER_OFFSET(ms->old_channels, -channels_offset_file);
1433 reader, channels_poin, sizeof(SeqTimelineChannel));
1434
1435 if (channels_poin) {
1436 ms->old_channels = (ListBase *)POINTER_OFFSET(channels_poin, channels_offset_mem);
1437 }
1438 else {
1439 ms->old_channels = &ed->channels;
1440 }
1441 }
1442 }
1443 }
1444 }
1445
1446 /* Runtime */
1447 sce->r.mode &= ~R_NO_CAMERA_SWITCH;
1448
1450
1452 BLO_read_struct_list(reader, SceneRenderLayer, &(sce->r.layers));
1453 BLO_read_struct_list(reader, SceneRenderView, &(sce->r.views));
1454
1455 LISTBASE_FOREACH (SceneRenderLayer *, srl, &sce->r.layers) {
1456 BLO_read_struct(reader, IDProperty, &srl->prop);
1457 IDP_BlendDataRead(reader, &srl->prop);
1458 BLO_read_struct_list(reader, FreestyleModuleConfig, &(srl->freestyleConfig.modules));
1459 BLO_read_struct_list(reader, FreestyleLineSet, &(srl->freestyleConfig.linesets));
1460 }
1461
1465
1467 RigidBodyWorld *rbw = sce->rigidbody_world;
1468 if (rbw) {
1470
1471 if (rbw->shared == nullptr) {
1472 /* Link deprecated caches if they exist, so we can use them for versioning.
1473 * We should only do this when rbw->shared == nullptr, because those pointers
1474 * are always set (for compatibility with older Blenders). We mustn't link
1475 * the same pointcache twice. */
1476 BKE_ptcache_blend_read_data(reader, &rbw->ptcaches, &rbw->pointcache, false);
1477
1478 /* make sure simulation starts from the beginning after loading file */
1479 if (rbw->pointcache) {
1480 rbw->ltime = float(rbw->pointcache->startframe);
1481 }
1482 }
1483 else {
1484 /* link caches */
1485 BKE_ptcache_blend_read_data(reader, &rbw->shared->ptcaches, &rbw->shared->pointcache, false);
1486
1487 /* make sure simulation starts from the beginning after loading file */
1488 if (rbw->shared->pointcache) {
1489 rbw->ltime = float(rbw->shared->pointcache->startframe);
1490 }
1491 }
1492
1494 rbw->objects = nullptr;
1495 rbw->numbodies = 0;
1496
1497 /* set effector weights */
1499 if (!rbw->effector_weights) {
1501 }
1502 }
1503
1504 BLO_read_struct(reader, PreviewImage, &sce->preview);
1505 BKE_previewimg_blend_read(reader, sce->preview);
1506
1508
1509 /* insert into global old-new map for reading without UI (link_global accesses it again) */
1510 BLO_read_glob_list(reader, &sce->view_layers);
1511 LISTBASE_FOREACH (ViewLayer *, view_layer, &sce->view_layers) {
1512 BKE_view_layer_blend_read_data(reader, view_layer);
1513 }
1514
1516
1518 IDP_BlendDataRead(reader, &sce->layer_properties);
1519}
1520
1521/* patch for missing scene IDs, can't be in do-versions */
1523{
1524 Scene *sce = reinterpret_cast<Scene *>(id);
1525
1526 LISTBASE_FOREACH_MUTABLE (Base *, base_legacy, &sce->base) {
1527 if (base_legacy->object == nullptr) {
1530 RPT_("LIB: object lost from scene: '%s'"),
1531 sce->id.name + 2);
1532 BLI_remlink(&sce->base, base_legacy);
1533 if (base_legacy == sce->basact) {
1534 sce->basact = nullptr;
1535 }
1536 MEM_freeN(base_legacy);
1537 }
1538 }
1539
1540 LISTBASE_FOREACH (ViewLayer *, view_layer, &sce->view_layers) {
1541 BKE_view_layer_blend_read_after_liblink(reader, id, view_layer);
1542 }
1543
1544#ifdef USE_SETSCENE_CHECK
1545 if (sce->set != nullptr) {
1547 }
1548#endif
1549 if (ID_IS_LINKED(sce)) {
1550 /* Linked scenes never have NLA tweak mode enabled. This works in concert with code in
1551 * BKE_animdata_blend_read_data, which also ensures that linked AnimData structs are never
1552 * linked in NLA tweak mode. */
1553 sce->flag &= ~SCE_NLA_EDIT_ON;
1554 }
1555}
1556
1557static void scene_undo_preserve(BlendLibReader *reader, ID *id_new, ID *id_old)
1558{
1559 Scene *scene_new = (Scene *)id_new;
1560 Scene *scene_old = (Scene *)id_old;
1561
1562 std::swap(scene_old->cursor, scene_new->cursor);
1563 if (scene_new->toolsettings != nullptr && scene_old->toolsettings != nullptr) {
1564 /* First try to restore ID pointers that can be and should be preserved (like brushes or
1565 * palettes), and counteract the swap of the whole ToolSettings structs below for the others
1566 * (like object ones). */
1568 nullptr, scene_new->toolsettings, true, reader, scene_old->toolsettings);
1569 std::swap(*scene_old->toolsettings, *scene_new->toolsettings);
1570 }
1571}
1572
1573static void scene_lib_override_apply_post(ID *id_dst, ID * /*id_src*/)
1574{
1575 Scene *scene = (Scene *)id_dst;
1576
1577 if (scene->rigidbody_world != nullptr) {
1578 PTCacheID pid;
1579 BKE_ptcache_id_from_rigidbody(&pid, nullptr, scene->rigidbody_world);
1580 LISTBASE_FOREACH (PointCache *, point_cache, pid.ptcaches) {
1581 point_cache->flag |= PTCACHE_FLAG_INFO_DIRTY;
1582 }
1583 }
1584}
1585
1587{
1588 IDTypeInfo info{};
1589 info.id_code = ID_SCE;
1590 info.id_filter = FILTER_ID_SCE;
1596 info.struct_size = sizeof(Scene);
1597 info.name = "Scene";
1598 info.name_plural = "scenes";
1601 info.asset_type_info = nullptr;
1602
1606 /* For now default `BKE_lib_id_make_local_generic()` should work, may need more work though to
1607 * support all possible corner cases. */
1608 info.make_local = nullptr;
1612 info.owner_pointer_get = nullptr;
1613
1617
1619
1621 return info;
1622}
1624
1625const char *RE_engine_id_BLENDER_EEVEE = "BLENDER_EEVEE";
1626const char *RE_engine_id_BLENDER_EEVEE_NEXT = "BLENDER_EEVEE_NEXT";
1627const char *RE_engine_id_BLENDER_WORKBENCH = "BLENDER_WORKBENCH";
1628const char *RE_engine_id_CYCLES = "CYCLES";
1629
1631{
1632 using namespace blender;
1633
1634 std::optional<std::pair<animrig::Action *, animrig::Slot *>> action_and_slot =
1636 if (!action_and_slot) {
1637 return;
1638 }
1639
1640 animrig::Channelbag *channelbag = channelbag_for_action_slot(*action_and_slot->first,
1641 action_and_slot->second->handle);
1642 if (!channelbag) {
1643 return;
1644 }
1645
1646 /* Create a copy of the F-Curve pointers, so iteration is safe while they are removed. */
1647 Vector<FCurve *> fcurves = channelbag->fcurves();
1648
1649 for (FCurve *fcurve : fcurves) {
1650 if ((fcurve->rna_path) && strstr(fcurve->rna_path, "sequence_editor.strips_all")) {
1651 channelbag->fcurve_remove(*fcurve);
1652 }
1653 }
1654}
1655
1657{
1658 if (toolsettings == nullptr) {
1659 return nullptr;
1660 }
1661 ToolSettings *ts = static_cast<ToolSettings *>(MEM_dupallocN(toolsettings));
1662 if (ts->vpaint) {
1663 ts->vpaint = static_cast<VPaint *>(MEM_dupallocN(ts->vpaint));
1664 BKE_paint_copy(&ts->vpaint->paint, &ts->vpaint->paint, flag);
1665 }
1666 if (ts->wpaint) {
1667 ts->wpaint = static_cast<VPaint *>(MEM_dupallocN(ts->wpaint));
1668 BKE_paint_copy(&ts->wpaint->paint, &ts->wpaint->paint, flag);
1669 }
1670 if (ts->sculpt) {
1671 ts->sculpt = static_cast<Sculpt *>(MEM_dupallocN(ts->sculpt));
1672 BKE_paint_copy(&ts->sculpt->paint, &ts->sculpt->paint, flag);
1673
1678 }
1679
1684 }
1685 }
1686 if (ts->uvsculpt.strength_curve) {
1689 }
1690 if (ts->gp_paint) {
1691 ts->gp_paint = static_cast<GpPaint *>(MEM_dupallocN(ts->gp_paint));
1693 }
1694 if (ts->gp_vertexpaint) {
1695 ts->gp_vertexpaint = static_cast<GpVertexPaint *>(MEM_dupallocN(ts->gp_vertexpaint));
1697 }
1698 if (ts->gp_sculptpaint) {
1699 ts->gp_sculptpaint = static_cast<GpSculptPaint *>(MEM_dupallocN(ts->gp_sculptpaint));
1701 }
1702 if (ts->gp_weightpaint) {
1703 ts->gp_weightpaint = static_cast<GpWeightPaint *>(MEM_dupallocN(ts->gp_weightpaint));
1705 }
1706 if (ts->curves_sculpt) {
1707 ts->curves_sculpt = static_cast<CurvesSculpt *>(MEM_dupallocN(ts->curves_sculpt));
1709 }
1710
1711 /* Color jitter curves in unified paint settings. */
1718
1720 ts->particle.paintcursor = nullptr;
1721 ts->particle.scene = nullptr;
1722 ts->particle.object = nullptr;
1723
1724 /* duplicate Grease Pencil interpolation curve */
1726 /* Duplicate Grease Pencil multi-frame falloff. */
1729
1731
1733 return ts;
1734}
1735
1737{
1738 if (toolsettings == nullptr) {
1739 return;
1740 }
1741 if (toolsettings->vpaint) {
1742 BKE_paint_free(&toolsettings->vpaint->paint);
1743 MEM_freeN(toolsettings->vpaint);
1744 }
1745 if (toolsettings->wpaint) {
1746 BKE_paint_free(&toolsettings->wpaint->paint);
1747 MEM_freeN(toolsettings->wpaint);
1748 }
1749 if (toolsettings->sculpt) {
1750 if (toolsettings->sculpt->automasking_cavity_curve) {
1752 }
1753 if (toolsettings->sculpt->automasking_cavity_curve_op) {
1755 }
1756
1757 BKE_paint_free(&toolsettings->sculpt->paint);
1758 MEM_freeN(toolsettings->sculpt);
1759 }
1760 if (toolsettings->uvsculpt.strength_curve) {
1762 }
1763 if (toolsettings->gp_paint) {
1764 BKE_paint_free(&toolsettings->gp_paint->paint);
1765 MEM_freeN(toolsettings->gp_paint);
1766 }
1767 if (toolsettings->gp_vertexpaint) {
1768 BKE_paint_free(&toolsettings->gp_vertexpaint->paint);
1769 MEM_freeN(toolsettings->gp_vertexpaint);
1770 }
1771 if (toolsettings->gp_sculptpaint) {
1772 BKE_paint_free(&toolsettings->gp_sculptpaint->paint);
1773 MEM_freeN(toolsettings->gp_sculptpaint);
1774 }
1775 if (toolsettings->gp_weightpaint) {
1776 BKE_paint_free(&toolsettings->gp_weightpaint->paint);
1777 MEM_freeN(toolsettings->gp_weightpaint);
1778 }
1779 if (toolsettings->curves_sculpt) {
1780 BKE_paint_free(&toolsettings->curves_sculpt->paint);
1781 MEM_freeN(toolsettings->curves_sculpt);
1782 }
1783 BKE_paint_free(&toolsettings->imapaint.paint);
1784
1785 /* Color jitter curves in unified paint settings. */
1786 if (toolsettings->unified_paint_settings.curve_rand_hue) {
1788 }
1791 }
1792 if (toolsettings->unified_paint_settings.curve_rand_value) {
1794 }
1795
1796 /* free Grease Pencil interpolation curve */
1797 if (toolsettings->gp_interpolate.custom_ipo) {
1799 }
1800 /* free Grease Pencil multi-frame falloff curve */
1801 if (toolsettings->gp_sculpt.cur_falloff) {
1803 }
1804 if (toolsettings->gp_sculpt.cur_primitive) {
1806 }
1807
1808 if (toolsettings->custom_bevel_profile_preset) {
1810 }
1811
1812 if (toolsettings->sequencer_tool_settings) {
1814 }
1815
1816 MEM_freeN(toolsettings);
1817}
1818
1819void BKE_scene_copy_data_eevee(Scene *sce_dst, const Scene *sce_src)
1820{
1821 /* Copy eevee data between scenes. */
1822 sce_dst->eevee = sce_src->eevee;
1823}
1824
1826{
1827 Scene *sce_copy;
1828
1829 /* TODO: this should/could most likely be replaced by call to more generic code at some point...
1830 * But for now, let's keep it well isolated here. */
1831 if (type == SCE_COPY_EMPTY) {
1832 ListBase rv;
1833
1834 sce_copy = BKE_scene_add(bmain, sce->id.name + 2);
1835
1836 rv = sce_copy->r.views;
1838 sce_copy->r = sce->r;
1839 sce_copy->r.views = rv;
1840 sce_copy->unit = sce->unit;
1841 sce_copy->physics_settings = sce->physics_settings;
1842 sce_copy->audio = sce->audio;
1843 BKE_scene_copy_data_eevee(sce_copy, sce);
1844
1845 if (sce->id.properties) {
1846 sce_copy->id.properties = IDP_CopyProperty(sce->id.properties);
1847 }
1848 if (sce->id.system_properties) {
1850 }
1851
1852 BKE_sound_destroy_scene(sce_copy);
1853
1854 /* copy color management settings */
1859
1860 BKE_image_format_copy(&sce_copy->r.im_format, &sce->r.im_format);
1862
1864
1865 /* viewport display settings */
1866 sce_copy->display = sce->display;
1867
1868 /* tool settings */
1870 sce_copy->toolsettings = BKE_toolsettings_copy(sce->toolsettings, 0);
1871
1873
1874 /* grease pencil */
1875 sce_copy->gpd = nullptr;
1876
1877 sce_copy->preview = nullptr;
1878
1879 return sce_copy;
1880 }
1881
1882 eDupli_ID_Flags duplicate_flags = (eDupli_ID_Flags)(U.dupflag | USER_DUP_OBJECT);
1883
1884 sce_copy = (Scene *)BKE_id_copy(bmain, (ID *)sce);
1885 id_us_min(&sce_copy->id);
1886 id_us_ensure_real(&sce_copy->id);
1887
1888 BKE_animdata_duplicate_id_action(bmain, &sce_copy->id, duplicate_flags);
1889
1890 /* Extra actions, most notably SCE_FULL_COPY also duplicates several 'children' datablocks. */
1891
1892 if (type == SCE_COPY_FULL) {
1893 /* Scene duplication is always root of duplication currently. */
1894 const bool is_subprocess = false;
1895 const bool is_root_id = true;
1896 const int copy_flags = LIB_ID_COPY_DEFAULT;
1897
1898 if (!is_subprocess) {
1900 }
1901 if (is_root_id) {
1902 /* In case root duplicated ID is linked, assume we want to get a local copy of it and
1903 * duplicate all expected linked data. */
1904 if (ID_IS_LINKED(sce)) {
1905 duplicate_flags = (duplicate_flags | USER_DUP_LINKED_ID);
1906 }
1907 }
1908
1909 /* Copy Freestyle LineStyle datablocks. */
1910 LISTBASE_FOREACH (ViewLayer *, view_layer_dst, &sce_copy->view_layers) {
1911 LISTBASE_FOREACH (FreestyleLineSet *, lineset, &view_layer_dst->freestyle_config.linesets) {
1912 BKE_id_copy_for_duplicate(bmain, (ID *)lineset->linestyle, duplicate_flags, copy_flags);
1913 }
1914 }
1915
1916 /* Full copy of world (included animations) */
1917 BKE_id_copy_for_duplicate(bmain, (ID *)sce->world, duplicate_flags, copy_flags);
1918
1919 /* Full copy of GreasePencil. */
1920 BKE_id_copy_for_duplicate(bmain, (ID *)sce->gpd, duplicate_flags, copy_flags);
1921
1922 /* Deep-duplicate collections and objects (using preferences' settings for which sub-data to
1923 * duplicate along the object itself). */
1925 nullptr,
1926 nullptr,
1927 sce_copy->master_collection,
1928 duplicate_flags,
1930
1931 /* Rigid body world collections may not be instantiated as scene's collections, ensure they
1932 * also get properly duplicated. */
1933 if (sce_copy->rigidbody_world != nullptr) {
1934 if (sce_copy->rigidbody_world->group != nullptr) {
1936 nullptr,
1937 nullptr,
1938 sce_copy->rigidbody_world->group,
1939 duplicate_flags,
1941 }
1942 if (sce_copy->rigidbody_world->constraints != nullptr) {
1944 nullptr,
1945 nullptr,
1946 sce_copy->rigidbody_world->constraints,
1947 duplicate_flags,
1949 }
1950 }
1951
1952 if (!is_subprocess) {
1953 /* This code will follow into all ID links using an ID tagged with ID_TAG_NEW. */
1954 /* Unfortunate, but with some types (e.g. meshes), an object is considered in Edit mode if
1955 * its obdata contains edit mode runtime data. This can be the case of all newly duplicated
1956 * objects, as even though duplicate code move the object back in Object mode, they are still
1957 * using the original obdata ID, leading to them being falsly detected as being in Edit mode,
1958 * and therefore not remapping their obdata to the newly duplicated one.
1959 * See #139715. */
1961
1962#ifndef NDEBUG
1963 /* Call to `BKE_libblock_relink_to_newid` above is supposed to have cleared all those
1964 * flags. */
1965 ID *id_iter;
1966 FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
1967 BLI_assert((id_iter->tag & ID_TAG_NEW) == 0);
1968 }
1970#endif
1971
1972 /* Cleanup. */
1974
1976 }
1977 }
1978 else {
1979 /* Remove sequencer if not full copy */
1980 /* XXX Why in Hell? :/ */
1981 remove_sequencer_fcurves(sce_copy);
1982 blender::seq::editing_free(sce_copy, true);
1983 }
1984
1985 return sce_copy;
1986}
1987
1989{
1990 if (sce->rigidbody_world) {
1992 }
1993}
1994
1995bool BKE_scene_can_be_removed(const Main *bmain, const Scene *scene)
1996{
1997 /* Linked scenes can always be removed. */
1998 if (ID_IS_LINKED(scene)) {
1999 return true;
2000 }
2001 /* Local scenes can only be removed, when there is at least one local scene left. */
2002 LISTBASE_FOREACH (Scene *, other_scene, &bmain->scenes) {
2003 if (other_scene != scene && !ID_IS_LINKED(other_scene)) {
2004 return true;
2005 }
2006 }
2007 return false;
2008}
2009
2010Scene *BKE_scene_add(Main *bmain, const char *name)
2011{
2012 Scene *sce = BKE_id_new<Scene>(bmain, name);
2013 id_us_min(&sce->id);
2014 id_us_ensure_real(&sce->id);
2015
2016 return sce;
2017}
2018
2020{
2021 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
2022 BKE_view_layer_synced_ensure(scene, view_layer);
2023 if (BLI_findptr(BKE_view_layer_object_bases_get(view_layer), ob, offsetof(Base, object))) {
2024 return true;
2025 }
2026 }
2027 return false;
2028}
2029
2030Object *BKE_scene_object_find_by_name(const Scene *scene, const char *name)
2031{
2032 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
2033 BKE_view_layer_synced_ensure(scene, view_layer);
2035 if (STREQ(base->object->id.name + 2, name)) {
2036 return base->object;
2037 }
2038 }
2039 }
2040 return nullptr;
2041}
2042
2044{
2045 /* check for cyclic sets, for reading old files but also for definite security (py?) */
2046 BKE_scene_validate_setscene(bmain, scene);
2047
2048 /* Deselect objects (for data select). */
2049 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
2050 ob->flag &= ~SELECT;
2051 }
2052
2053 /* copy layers and flags from bases to objects */
2054 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
2055 BKE_view_layer_synced_ensure(scene, view_layer);
2057 /* collection patch... */
2059 }
2060 }
2061 /* No full animation update, this to enable render code to work
2062 * (render code calls own animation updates). */
2063}
2064
2065Scene *BKE_scene_set_name(Main *bmain, const char *name)
2066{
2067 Scene *sce = (Scene *)BKE_libblock_find_name(bmain, ID_SCE, name);
2068 if (sce) {
2069 BKE_scene_set_background(bmain, sce);
2070 printf("Scene switch for render: '%s' in file: '%s'\n", name, BKE_main_blendfile_path(bmain));
2071 return sce;
2072 }
2073
2074 printf("Can't find scene: '%s' in file: '%s'\n", name, BKE_main_blendfile_path(bmain));
2075 return nullptr;
2076}
2077
2079 Depsgraph *depsgraph, SceneBaseIter *iter, Scene **scene, int val, Base **base, Object **ob)
2080{
2081 bool run_again = true;
2082
2083 /* init */
2084 if (val == 0) {
2085 iter->phase = F_START;
2086 iter->dupob = nullptr;
2087 iter->duplilist = nullptr;
2088 iter->dupli_refob = nullptr;
2089 }
2090 else {
2091 /* run_again is set when a duplilist has been ended */
2092 while (run_again) {
2093 run_again = false;
2094
2095 /* the first base */
2096 if (iter->phase == F_START) {
2099 BKE_view_layer_synced_ensure(*scene, view_layer);
2100 *base = static_cast<Base *>(BKE_view_layer_object_bases_get(view_layer)->first);
2101 if (*base) {
2102 *ob = (*base)->object;
2103 iter->phase = F_SCENE;
2104 }
2105 else {
2106 /* exception: empty scene layer */
2107 while ((*scene)->set) {
2108 (*scene) = (*scene)->set;
2109 ViewLayer *view_layer_set = BKE_view_layer_default_render(*scene);
2110 BKE_view_layer_synced_ensure(*scene, view_layer_set);
2111 ListBase *object_bases = BKE_view_layer_object_bases_get(view_layer_set);
2112 if (object_bases->first) {
2113 *base = static_cast<Base *>(object_bases->first);
2114 *ob = (*base)->object;
2115 iter->phase = F_SCENE;
2116 break;
2117 }
2118 }
2119 }
2120 }
2121 else {
2122 if (*base && iter->phase != F_DUPLI) {
2123 *base = (*base)->next;
2124 if (*base) {
2125 *ob = (*base)->object;
2126 }
2127 else {
2128 if (iter->phase == F_SCENE) {
2129 /* (*scene) is finished, now do the set */
2130 while ((*scene)->set) {
2131 (*scene) = (*scene)->set;
2132 ViewLayer *view_layer_set = BKE_view_layer_default_render(*scene);
2133 BKE_view_layer_synced_ensure(*scene, view_layer_set);
2134 ListBase *object_bases = BKE_view_layer_object_bases_get(view_layer_set);
2135 if (object_bases->first) {
2136 *base = static_cast<Base *>(object_bases->first);
2137 *ob = (*base)->object;
2138 break;
2139 }
2140 }
2141 }
2142 }
2143 }
2144 }
2145
2146 if (*base == nullptr) {
2147 iter->phase = F_START;
2148 }
2149 else {
2150 if (iter->phase != F_DUPLI) {
2151 if (depsgraph && (*base)->object->transflag & OB_DUPLI) {
2152 /* Collections cannot be duplicated for meta-balls yet,
2153 * this enters eternal loop because of
2154 * makeDispListMBall getting called inside of collection_duplilist */
2155 if ((*base)->object->instance_collection == nullptr) {
2156 iter->duplilist = object_duplilist(depsgraph, (*scene), (*base)->object);
2157
2158 iter->dupob = static_cast<DupliObject *>(iter->duplilist->first);
2159
2160 if (!iter->dupob) {
2162 iter->duplilist = nullptr;
2163 }
2164 iter->dupli_refob = nullptr;
2165 }
2166 }
2167 }
2168 /* handle dupli's */
2169 if (iter->dupob) {
2170 (*base)->flag_legacy |= OB_FROMDUPLI;
2171 *ob = iter->dupob->ob;
2172 iter->phase = F_DUPLI;
2173
2174 if (iter->dupli_refob != *ob) {
2175 if (iter->dupli_refob) {
2176 /* Restore previous object's real matrix. */
2177 copy_m4_m4(iter->dupli_refob->runtime->object_to_world.ptr(), iter->omat);
2178 }
2179 /* Backup new object's real matrix. */
2180 iter->dupli_refob = *ob;
2181 copy_m4_m4(iter->omat, iter->dupli_refob->object_to_world().ptr());
2182 }
2183 copy_m4_m4((*ob)->runtime->object_to_world.ptr(), iter->dupob->mat);
2184
2185 iter->dupob = iter->dupob->next;
2186 }
2187 else if (iter->phase == F_DUPLI) {
2188 iter->phase = F_SCENE;
2189 (*base)->flag_legacy &= ~OB_FROMDUPLI;
2190
2191 if (iter->dupli_refob) {
2192 /* Restore last object's real matrix. */
2193 copy_m4_m4(iter->dupli_refob->runtime->object_to_world.ptr(), iter->omat);
2194 iter->dupli_refob = nullptr;
2195 }
2196
2198 iter->duplilist = nullptr;
2199 run_again = true;
2200 }
2201 }
2202 }
2203 }
2204
2205 return iter->phase;
2206}
2207
2208bool BKE_scene_has_view_layer(const Scene *scene, const ViewLayer *layer)
2209{
2210 return BLI_findindex(&scene->view_layers, layer) != -1;
2211}
2212
2213Scene *BKE_scene_find_from_collection(const Main *bmain, const Collection *collection)
2214{
2215 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
2216 LISTBASE_FOREACH (ViewLayer *, layer, &scene->view_layers) {
2217 if (BKE_view_layer_has_collection(layer, collection)) {
2218 return scene;
2219 }
2220 }
2221 }
2222
2223 return nullptr;
2224}
2225
2227{
2228 if (scene->r.mode & R_NO_CAMERA_SWITCH) {
2229 return nullptr;
2230 }
2231
2232 const int ctime = int(BKE_scene_ctime_get(scene));
2233 int frame = -(MAXFRAME + 1);
2234 int min_frame = MAXFRAME + 1;
2235 Object *camera = nullptr;
2236 Object *first_camera = nullptr;
2237
2238 LISTBASE_FOREACH (TimeMarker *, m, &scene->markers) {
2239 if (m->camera && (m->camera->visibility_flag & OB_HIDE_RENDER) == 0) {
2240 if ((m->frame <= ctime) && (m->frame > frame)) {
2241 camera = m->camera;
2242 frame = m->frame;
2243
2244 if (frame == ctime) {
2245 break;
2246 }
2247 }
2248
2249 if (m->frame < min_frame) {
2250 first_camera = m->camera;
2251 min_frame = m->frame;
2252 }
2253 }
2254 }
2255
2256 if (camera == nullptr) {
2257 /* If there's no marker to the left of current frame,
2258 * use camera from left-most marker to solve all sort
2259 * of Schrodinger uncertainties.
2260 */
2261 return first_camera;
2262 }
2263
2264 return camera;
2265}
2266
2268{
2269 Object *camera = BKE_scene_camera_switch_find(scene);
2270 if (camera && (camera != scene->camera)) {
2271 scene->camera = camera;
2273 return true;
2274 }
2275 return false;
2276}
2277
2278const char *BKE_scene_find_marker_name(const Scene *scene, int frame)
2279{
2280 const ListBase *markers = &scene->markers;
2281 const TimeMarker *m1, *m2;
2282
2283 /* search through markers for match */
2284 for (m1 = static_cast<const TimeMarker *>(markers->first),
2285 m2 = static_cast<const TimeMarker *>(markers->last);
2286 m1 && m2;
2287 m1 = m1->next, m2 = m2->prev)
2288 {
2289 if (m1->frame == frame) {
2290 return m1->name;
2291 }
2292
2293 if (m1 == m2) {
2294 break;
2295 }
2296
2297 if (m2->frame == frame) {
2298 return m2->name;
2299 }
2300 }
2301
2302 return nullptr;
2303}
2304
2305const char *BKE_scene_find_last_marker_name(const Scene *scene, int frame)
2306{
2307 const TimeMarker *best_marker = nullptr;
2308 int best_frame = -MAXFRAME * 2;
2309 LISTBASE_FOREACH (const TimeMarker *, marker, &scene->markers) {
2310 if (marker->frame == frame) {
2311 return marker->name;
2312 }
2313
2314 if (marker->frame > best_frame && marker->frame < frame) {
2315 best_marker = marker;
2316 best_frame = marker->frame;
2317 }
2318 }
2319
2320 return best_marker ? best_marker->name : nullptr;
2321}
2322
2323int BKE_scene_frame_snap_by_seconds(Scene *scene, double interval_in_seconds, int frame)
2324{
2325 const int fps = round_db_to_int(FPS * interval_in_seconds);
2326 const int second_prev = frame - mod_i(frame, fps);
2327 const int second_next = second_prev + fps;
2328 const int delta_prev = frame - second_prev;
2329 const int delta_next = second_next - frame;
2330 return (delta_prev < delta_next) ? second_prev : second_next;
2331}
2332
2333void BKE_scene_remove_rigidbody_object(Main *bmain, Scene *scene, Object *ob, const bool free_us)
2334{
2335 /* remove rigid body constraint from world before removing object */
2336 if (ob->rigidbody_constraint) {
2337 BKE_rigidbody_remove_constraint(bmain, scene, ob, free_us);
2338 }
2339 /* remove rigid body object from world before removing object */
2340 if (ob->rigidbody_object) {
2341 BKE_rigidbody_remove_object(bmain, scene, ob, free_us);
2342 }
2343}
2344
2346{
2347 Scene *sce_iter;
2348 int a, totscene;
2349
2350 if (sce->set == nullptr) {
2351 return true;
2352 }
2353 totscene = BLI_listbase_count(&bmain->scenes);
2354
2355 for (a = 0, sce_iter = sce; sce_iter->set; sce_iter = sce_iter->set, a++) {
2356 /* more iterations than scenes means we have a cycle */
2357 if (a > totscene) {
2358 /* The tested scene gets zeroed, that's typically current scene. */
2359 sce->set = nullptr;
2360 return false;
2361 }
2362 }
2363
2364 return true;
2365}
2366
2367float BKE_scene_ctime_get(const Scene *scene)
2368{
2369 return BKE_scene_frame_to_ctime(scene, scene->r.cfra);
2370}
2371
2372float BKE_scene_frame_to_ctime(const Scene *scene, const int frame)
2373{
2374 float ctime = frame;
2375 ctime += scene->r.subframe;
2376 ctime *= scene->r.framelen;
2377
2378 return ctime;
2379}
2380
2381float BKE_scene_frame_get(const Scene *scene)
2382{
2383 return scene->r.cfra + scene->r.subframe;
2384}
2385
2386void BKE_scene_frame_set(Scene *scene, float frame)
2387{
2388 double intpart;
2389 scene->r.subframe = modf(double(frame), &intpart);
2390 scene->r.cfra = int(intpart);
2391}
2392
2393/* -------------------------------------------------------------------- */
2396
2398{
2399 if ((scene->orientation_slots[slot_index].flag & SELECT) == 0) {
2400 slot_index = SCE_ORIENT_DEFAULT;
2401 }
2402 return &scene->orientation_slots[slot_index];
2403}
2404
2406{
2409 int slot_index = SCE_ORIENT_DEFAULT;
2411 slot_index = SCE_ORIENT_TRANSLATE;
2412 }
2414 slot_index = SCE_ORIENT_ROTATE;
2415 }
2416 else if (flag & V3D_GIZMO_SHOW_OBJECT_SCALE) {
2417 slot_index = SCE_ORIENT_SCALE;
2418 }
2419 return BKE_scene_orientation_slot_get(scene, slot_index);
2420}
2421
2423{
2424 const bool is_custom = orientation >= V3D_ORIENT_CUSTOM;
2425 orient_slot->type = is_custom ? V3D_ORIENT_CUSTOM : orientation;
2426 orient_slot->index_custom = is_custom ? (orientation - V3D_ORIENT_CUSTOM) : -1;
2427}
2428
2430{
2431 return (orient_slot->type == V3D_ORIENT_CUSTOM) ?
2432 (orient_slot->type + orient_slot->index_custom) :
2433 orient_slot->type;
2434}
2435
2436int BKE_scene_orientation_get_index(Scene *scene, int slot_index)
2437{
2438 TransformOrientationSlot *orient_slot = BKE_scene_orientation_slot_get(scene, slot_index);
2439 return BKE_scene_orientation_slot_get_index(orient_slot);
2440}
2441
2447
2449
2451{
2452 wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
2453 LISTBASE_FOREACH (const wmWindow *, window, &wm->windows) {
2454 const bScreen *screen = BKE_workspace_active_screen_get(window->workspace_hook);
2455 Scene *scene = window->scene;
2456 RenderEngineType *type = RE_engines_find(scene->r.engine);
2457
2458 if (type->draw_engine || !type->render) {
2459 continue;
2460 }
2461
2462 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
2463 View3D *v3d = static_cast<View3D *>(area->spacedata.first);
2464 if (area->spacetype != SPACE_VIEW3D) {
2465 continue;
2466 }
2467 if (v3d->shading.type == OB_RENDER) {
2468 return true;
2469 }
2470 }
2471 }
2472 return false;
2473}
2474
2475/* TODO(@ideasman42): shouldn't we be able to use 'DEG_get_view_layer' here?
2476 * Currently this is nullptr on load, so don't. */
2478 const Scene *scene,
2479 ViewLayer *view_layer)
2480{
2481 /* This is needed to prepare mesh to be used by the render
2482 * engine from the viewport rendering. We do loading here
2483 * so all the objects which shares the same mesh datablock
2484 * are nicely tagged for update and updated.
2485 *
2486 * This makes it so viewport render engine doesn't need to
2487 * call loading of the edit data for the mesh objects.
2488 */
2489 BKE_view_layer_synced_ensure(scene, view_layer);
2490 Object *obedit = BKE_view_layer_edit_object_get(view_layer);
2491 if (obedit) {
2492 Mesh *mesh = static_cast<Mesh *>(obedit->data);
2493 if ((obedit->type == OB_MESH) &&
2494 ((obedit->id.recalc & ID_RECALC_ALL) || (mesh->id.recalc & ID_RECALC_ALL)))
2495 {
2497 BMesh *bm = mesh->runtime->edit_mesh->bm;
2499 params.calc_object_remap = true;
2500 params.update_shapekey_indices = true;
2501 BM_mesh_bm_to_me(bmain, bm, mesh, &params);
2502 DEG_id_tag_update(&mesh->id, 0);
2503 }
2504 }
2505 }
2506}
2507
2508void BKE_scene_update_sound(Depsgraph *depsgraph, Main *bmain)
2509{
2511 const int recalc = scene->id.recalc;
2513 if (recalc & ID_RECALC_FRAME_CHANGE) {
2514 BKE_sound_seek_scene(bmain, scene);
2515 }
2516 if (recalc & ID_RECALC_AUDIO_FPS) {
2517 BKE_sound_update_fps(bmain, scene);
2518 }
2519 if (recalc & ID_RECALC_AUDIO_VOLUME) {
2521 }
2522 if (recalc & ID_RECALC_AUDIO_MUTE) {
2523 const bool is_mute = (DEG_get_mode(depsgraph) == DAG_EVAL_VIEWPORT) &&
2524 (scene->audio.flag & AUDIO_MUTE);
2525 BKE_sound_mute_scene(scene, is_mute);
2526 }
2527 if (recalc & ID_RECALC_AUDIO_LISTENER) {
2529 }
2531}
2532
2533void BKE_scene_update_tag_audio_volume(Depsgraph * /*depsgraph*/, Scene *scene)
2534{
2536 /* The volume is actually updated in BKE_scene_update_sound(), from either
2537 * scene_graph_update_tagged() or from BKE_scene_graph_update_for_newframe(). */
2539}
2540
2541/* TODO(sergey): This actually should become view_layer_graph or so.
2542 * Same applies to update_for_newframe.
2543 *
2544 * If only_if_tagged is truth then the function will do nothing if the dependency graph is up
2545 * to date already.
2546 */
2547static void scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain, bool only_if_tagged)
2548{
2549 if (only_if_tagged && DEG_is_fully_evaluated(depsgraph)) {
2550 return;
2551 }
2552
2555 bool used_multiple_passes = false;
2556
2557 bool run_callbacks = DEG_id_type_any_updated(depsgraph);
2558 if (run_callbacks) {
2560 }
2561
2562 for (int pass = 0; pass < 2; pass++) {
2563 /* (Re-)build dependency graph if needed. */
2565 /* Uncomment this to check if graph was properly tagged for update. */
2566 // DEG_debug_graph_relations_validate(depsgraph, bmain, scene, view_layer);
2567 /* Flush editing data if needed. */
2568 prepare_mesh_for_viewport_render(bmain, scene, view_layer);
2569 /* Update all objects: drivers, matrices, etc. flags set
2570 * by depsgraph or manual, no layer check here, gets correct flushed. */
2572 /* Update sound system. */
2574 /* Notify python about depsgraph update. */
2575 if (run_callbacks) {
2578
2579 /* It is possible that the custom callback modified scene and removed some IDs from the main
2580 * database. In this case DEG_editors_update() will crash because it iterates over all IDs
2581 * which depsgraph was built for.
2582 *
2583 * The solution is to update relations prior to this call, avoiding access to freed IDs.
2584 * Should be safe because relations update is supposed to preserve flags of all IDs which are
2585 * still a part of the dependency graph. If an ID is kicked out of the dependency graph it
2586 * should also be fine because when/if it's added to another dependency graph it will need to
2587 * be tagged for an update anyway.
2588 *
2589 * If there are no relations changed by the callback this call will do nothing. */
2591 }
2592
2593 /* If user callback did not tag anything for update we can skip second iteration.
2594 * Otherwise we update scene once again, but without running callbacks to bring
2595 * scene to a fully evaluated state with user modifications taken into account. */
2597 break;
2598 }
2599
2600 /* Clear recalc flags for second pass, but back them up for editors update. */
2601 const bool backup = true;
2603 used_multiple_passes = true;
2604 run_callbacks = false;
2605 }
2606
2607 /* Inform editors about changes, using recalc flags from both passes. */
2608 if (used_multiple_passes) {
2610 }
2611 const bool is_time_update = false;
2612 DEG_editors_update(depsgraph, is_time_update);
2613
2614 const bool backup = false;
2616}
2617
2619{
2620 scene_graph_update_tagged(depsgraph, bmain, false);
2621}
2622
2624{
2626}
2627
2628void BKE_scene_graph_update_for_newframe_ex(Depsgraph *depsgraph, const bool clear_recalc)
2629{
2631 Main *bmain = DEG_get_bmain(depsgraph);
2632 bool used_multiple_passes = false;
2633
2634 /* Keep this first. */
2636
2637 for (int pass = 0; pass < 2; pass++) {
2638 /* Update animated image textures for particles, modifiers, gpu, etc,
2639 * call this at the start so modifiers with textures don't lag 1 frame.
2640 */
2641 BKE_image_editors_update_frame(bmain, scene->r.cfra);
2643 /* Update all objects: drivers, matrices, etc. flags set
2644 * by depsgraph or manual, no layer check here, gets correct flushed.
2645 *
2646 * NOTE: Only update for new frame on first iteration. Second iteration is for ensuring user
2647 * edits from callback are properly taken into account. Doing a time update on those would
2648 * lose any possible unkeyed changes made by the handler. */
2649 if (pass == 0) {
2650 const float frame = BKE_scene_frame_get(scene);
2652 }
2653 else {
2655 }
2656 /* Update sound system animation. */
2658
2659 /* Notify editors and python about recalc. */
2660 if (pass == 0) {
2662
2663 /* NOTE: Similar to this case in scene_graph_update_tagged(). Need to ensure that
2664 * DEG_editors_update() doesn't access freed memory of possibly removed ID. */
2666 }
2667
2668 /* If user callback did not tag anything for update we can skip second iteration.
2669 * Otherwise we update scene once again, but without running callbacks to bring
2670 * scene to a fully evaluated state with user modifications taken into account. */
2672 break;
2673 }
2674
2675 /* Clear recalc flags for second pass, but back them up for editors update. */
2676 const bool backup = true;
2678 used_multiple_passes = true;
2679 }
2680
2681 /* Inform editors about changes, using recalc flags from both passes. */
2682 if (used_multiple_passes) {
2684 }
2685
2686 const bool is_time_update = true;
2687 DEG_editors_update(depsgraph, is_time_update);
2688
2689 /* Clear recalc flags, can be skipped for example renderers that will read these
2690 * and clear the flags later. */
2691 if (clear_recalc) {
2692 const bool backup = false;
2694 }
2695}
2696
2701
2703{
2704 Depsgraph *depsgraph = BKE_scene_ensure_depsgraph(bmain, scene, view_layer);
2707}
2708
2710{
2711 if (!name) {
2712 name = DATA_("RenderView");
2713 }
2714
2716 STRNCPY(srv->name, name);
2717 BLI_uniquename(&sce->r.views,
2718 srv,
2719 DATA_("RenderView"),
2720 '.',
2722 sizeof(srv->name));
2723 BLI_addtail(&sce->r.views, srv);
2724
2725 return srv;
2726}
2727
2729{
2730 const int act = BLI_findindex(&scene->r.views, srv);
2731
2732 if (act == -1) {
2733 return false;
2734 }
2735 if (scene->r.views.first == scene->r.views.last) {
2736 /* ensure 1 view is kept */
2737 return false;
2738 }
2739
2740 BLI_remlink(&scene->r.views, srv);
2741 MEM_freeN(srv);
2742
2743 scene->r.actview = 0;
2744
2745 return true;
2746}
2747
2748/* render simplification */
2749
2750int get_render_subsurf_level(const RenderData *r, int lvl, bool for_render)
2751{
2752 if (r->mode & R_SIMPLIFY) {
2753 if (for_render) {
2754 return min_ii(r->simplify_subsurf_render, lvl);
2755 }
2756
2757 return min_ii(r->simplify_subsurf, lvl);
2758 }
2759
2760 return lvl;
2761}
2762
2763int get_render_child_particle_number(const RenderData *r, int child_num, bool for_render)
2764{
2765 if (r->mode & R_SIMPLIFY) {
2766 if (for_render) {
2767 return int(r->simplify_particles_render * child_num);
2768 }
2769
2770 return int(r->simplify_particles * child_num);
2771 }
2772
2773 return child_num;
2774}
2775
2776Base *_setlooper_base_step(Scene **sce_iter, ViewLayer *view_layer, Base *base)
2777{
2778 if (base && base->next) {
2779 /* Common case, step to the next. */
2780 return base->next;
2781 }
2782 if ((base == nullptr) && (view_layer != nullptr)) {
2783 /* First time looping, return the scenes first base. */
2784 /* For the first loop we should get the layer from workspace when available. */
2785 BKE_view_layer_synced_ensure(*sce_iter, view_layer);
2786 ListBase *object_bases = BKE_view_layer_object_bases_get(view_layer);
2787 if (object_bases->first) {
2788 return static_cast<Base *>(object_bases->first);
2789 }
2790 /* No base on this scene layer. */
2791 goto next_set;
2792 }
2793 else {
2794 next_set:
2795 /* Reached the end, get the next base in the set. */
2796 while ((*sce_iter = (*sce_iter)->set)) {
2797 ViewLayer *view_layer_set = BKE_view_layer_default_render(*sce_iter);
2798 base = (Base *)BKE_view_layer_object_bases_get(view_layer_set)->first;
2799
2800 if (base) {
2801 return base;
2802 }
2803 }
2804 }
2805
2806 return nullptr;
2807}
2808
2810{
2811 RenderEngineType *type = RE_engines_find(scene->r.engine);
2812 return (type && type->flag & RE_USE_SHADING_NODES_CUSTOM);
2813}
2814
2816{
2817 RenderEngineType *type = RE_engines_find(scene->r.engine);
2818 return (type && type->flag & RE_USE_SPHERICAL_STEREO);
2819}
2820
2822{
2823 return STREQ(scene->r.engine, RE_engine_id_BLENDER_EEVEE) ||
2825}
2826
2828{
2830}
2831
2833{
2834 return STREQ(scene->r.engine, RE_engine_id_CYCLES);
2835}
2836
2838{
2840}
2841
2842/* This enumeration has to match the one defined in the Cycles addon. */
2847
2849{
2851 PointerRNA scene_ptr = RNA_id_pointer_create(&scene->id);
2852 PointerRNA cycles_ptr = RNA_pointer_get(&scene_ptr, "cycles");
2853
2854 if (RNA_pointer_is_null(&cycles_ptr)) {
2855 /* The pointer only exists if Cycles is enabled. */
2856 return false;
2857 }
2858
2859 return RNA_enum_get(&cycles_ptr, "feature_set") == CYCLES_FEATURES_EXPERIMENTAL;
2860}
2861
2862void BKE_scene_base_flag_to_objects(const Scene *scene, ViewLayer *view_layer)
2863{
2864 BKE_view_layer_synced_ensure(scene, view_layer);
2867 }
2868}
2869
2871{
2872 Object *ob = base->object;
2873 ob->base_flag = base->flag;
2874}
2875
2877{
2878 ColorManagedDisplaySettings *display_settings = &scene->display_settings;
2879 ColorManagedViewSettings *view_settings = &scene->view_settings;
2880 const char *view;
2881 const char *none_display_name;
2882
2883 none_display_name = IMB_colormanagement_display_get_none_name();
2884
2885 STRNCPY(display_settings->display_device, none_display_name);
2886
2888
2889 if (view) {
2890 STRNCPY(view_settings->view_transform, view);
2891 }
2892}
2893
2895{
2896 return scene && scene->rigidbody_world && scene->rigidbody_world->group &&
2897 !(scene->rigidbody_world->flag & RBW_FLAG_MUTED);
2898}
2899
2901{
2902 int threads;
2903
2904 /* override set from command line? */
2906
2907 if (threads > 0) {
2908 return threads;
2909 }
2910
2911 /* fixed number of threads specified in scene? */
2912 if (rd->mode & R_FIXED_THREADS) {
2913 threads = rd->threads;
2914 }
2915 else {
2916 threads = BLI_system_thread_count();
2917 }
2918
2919 return max_ii(threads, 1);
2920}
2921
2923{
2924 return BKE_render_num_threads(&scene->r);
2925}
2926
2927void BKE_render_resolution(const RenderData *r, const bool use_crop, int *r_width, int *r_height)
2928{
2929 *r_width = (r->xsch * r->size) / 100;
2930 *r_height = (r->ysch * r->size) / 100;
2931
2932 if (use_crop && (r->mode & R_BORDER) && (r->mode & R_CROP)) {
2933 /* Compute the difference between the integer bounds instead of multiplying by the float
2934 * border size directly to be consistent with how the render pipeline computes render size, see
2935 * for instance render_init_from_main. That's because difference in rounding and imprecisions
2936 * can cause off by one errors. */
2937 *r_width = int(r->border.xmax * *r_width) - int(r->border.xmin * *r_width);
2938 *r_height = int(r->border.ymax * *r_height) - int(r->border.ymin * *r_height);
2939 }
2940}
2941
2943{
2944 if (r->preview_pixel_size == 0) {
2945 return (U.pixelsize > 1.5f) ? 2 : 1;
2946 }
2947 return r->preview_pixel_size;
2948}
2949
2950/******************** multiview *************************/
2951
2953{
2954 int totviews = 0;
2955
2956 if ((rd->scemode & R_MULTIVIEW) == 0) {
2957 return 1;
2958 }
2959
2961 SceneRenderView *srv = static_cast<SceneRenderView *>(
2963 if ((srv && srv->viewflag & SCE_VIEW_DISABLE) == 0) {
2964 totviews++;
2965 }
2966
2967 srv = static_cast<SceneRenderView *>(
2969 if ((srv && srv->viewflag & SCE_VIEW_DISABLE) == 0) {
2970 totviews++;
2971 }
2972 }
2973 else {
2974 LISTBASE_FOREACH (SceneRenderView *, srv, &rd->views) {
2975 if ((srv->viewflag & SCE_VIEW_DISABLE) == 0) {
2976 totviews++;
2977 }
2978 }
2979 }
2980 return totviews;
2981}
2982
2984{
2985 SceneRenderView *srv[2];
2986
2987 if ((rd->scemode & R_MULTIVIEW) == 0) {
2988 return false;
2989 }
2990
2991 srv[0] = (SceneRenderView *)BLI_findstring(
2993 srv[1] = (SceneRenderView *)BLI_findstring(
2995
2996 return (srv[0] && ((srv[0]->viewflag & SCE_VIEW_DISABLE) == 0) && srv[1] &&
2997 ((srv[1]->viewflag & SCE_VIEW_DISABLE) == 0));
2998}
2999
3001{
3002 if (srv == nullptr) {
3003 return false;
3004 }
3005
3006 if ((rd->scemode & R_MULTIVIEW) == 0) {
3007 return false;
3008 }
3009
3010 if (srv->viewflag & SCE_VIEW_DISABLE) {
3011 return false;
3012 }
3013
3015 return true;
3016 }
3017
3018 /* SCE_VIEWS_SETUP_BASIC */
3020 return true;
3021 }
3022
3023 return false;
3024}
3025
3026bool BKE_scene_multiview_is_render_view_first(const RenderData *rd, const char *viewname)
3027{
3028 if ((rd->scemode & R_MULTIVIEW) == 0) {
3029 return true;
3030 }
3031
3032 if ((!viewname) || (!viewname[0])) {
3033 return true;
3034 }
3035
3036 LISTBASE_FOREACH (const SceneRenderView *, srv, &rd->views) {
3038 return STREQ(viewname, srv->name);
3039 }
3040 }
3041
3042 return true;
3043}
3044
3045bool BKE_scene_multiview_is_render_view_last(const RenderData *rd, const char *viewname)
3046{
3047 if ((rd->scemode & R_MULTIVIEW) == 0) {
3048 return true;
3049 }
3050
3051 if ((!viewname) || (!viewname[0])) {
3052 return true;
3053 }
3054
3055 LISTBASE_FOREACH_BACKWARD (const SceneRenderView *, srv, &rd->views) {
3057 return STREQ(viewname, srv->name);
3058 }
3059 }
3060
3061 return true;
3062}
3063
3065{
3066 SceneRenderView *srv;
3067 size_t nr;
3068
3069 if ((rd->scemode & R_MULTIVIEW) == 0) {
3070 return nullptr;
3071 }
3072
3073 for (srv = static_cast<SceneRenderView *>(rd->views.first), nr = 0; srv; srv = srv->next) {
3075 if (nr++ == view_id) {
3076 return srv;
3077 }
3078 }
3079 }
3080 return srv;
3081}
3082
3083const char *BKE_scene_multiview_render_view_name_get(const RenderData *rd, const int view_id)
3084{
3086
3087 if (srv) {
3088 return srv->name;
3089 }
3090
3091 return "";
3092}
3093
3094int BKE_scene_multiview_view_id_get(const RenderData *rd, const char *viewname)
3095{
3096 SceneRenderView *srv;
3097 size_t nr;
3098
3099 if ((!rd) || ((rd->scemode & R_MULTIVIEW) == 0)) {
3100 return 0;
3101 }
3102
3103 if ((!viewname) || (!viewname[0])) {
3104 return 0;
3105 }
3106
3107 for (srv = static_cast<SceneRenderView *>(rd->views.first), nr = 0; srv; srv = srv->next) {
3109 if (STREQ(viewname, srv->name)) {
3110 return nr;
3111 }
3112
3113 nr += 1;
3114 }
3115 }
3116
3117 return 0;
3118}
3119
3121 const char *filepath,
3122 char *r_filepath)
3123{
3124 BLI_strncpy(r_filepath, filepath, FILE_MAX);
3125 BLI_path_suffix(r_filepath, FILE_MAX, srv->suffix, "");
3126}
3127
3129 const char *filepath,
3130 const char *viewname,
3131 char *r_filepath)
3132{
3133 SceneRenderView *srv;
3134 char suffix[FILE_MAX];
3135
3136 srv = static_cast<SceneRenderView *>(
3137 BLI_findstring(&rd->views, viewname, offsetof(SceneRenderView, name)));
3138 if (srv) {
3139 STRNCPY(suffix, srv->suffix);
3140 }
3141 else {
3142 STRNCPY(suffix, viewname);
3143 }
3144
3145 BLI_strncpy(r_filepath, filepath, FILE_MAX);
3146 BLI_path_suffix(r_filepath, FILE_MAX, suffix, "");
3147}
3148
3149const char *BKE_scene_multiview_view_suffix_get(const RenderData *rd, const char *viewname)
3150{
3151 SceneRenderView *srv;
3152
3153 if ((viewname == nullptr) || (viewname[0] == '\0')) {
3154 return viewname;
3155 }
3156
3157 srv = static_cast<SceneRenderView *>(
3158 BLI_findstring(&rd->views, viewname, offsetof(SceneRenderView, name)));
3159 if (srv) {
3160 return srv->suffix;
3161 }
3162
3163 return viewname;
3164}
3165
3166const char *BKE_scene_multiview_view_id_suffix_get(const RenderData *rd, const int view_id)
3167{
3168 if ((rd->scemode & R_MULTIVIEW) == 0) {
3169 return "";
3170 }
3171
3172 const char *viewname = BKE_scene_multiview_render_view_name_get(rd, view_id);
3173 return BKE_scene_multiview_view_suffix_get(rd, viewname);
3174}
3175
3177 const char *filepath,
3178 char *r_prefix,
3179 const char **r_ext)
3180{
3181 const char *unused;
3182 const char delims[] = {'.', '\0'};
3183
3184 r_prefix[0] = '\0';
3185
3186 /* Split `filepath` into base name and extension. */
3187 const size_t basename_len = BLI_str_rpartition(filepath, delims, r_ext, &unused);
3188 if (*r_ext == nullptr) {
3189 return;
3190 }
3191 BLI_assert(basename_len > 0);
3192
3193 /* Split base name into prefix and known suffix. */
3194 LISTBASE_FOREACH (SceneRenderView *, srv, &scene->r.views) {
3195 if (BKE_scene_multiview_is_render_view_active(&scene->r, srv)) {
3196 const size_t suffix_len = strlen(srv->suffix);
3197 if (basename_len >= suffix_len &&
3198 STREQLEN(filepath + basename_len - suffix_len, srv->suffix, suffix_len))
3199 {
3200 BLI_strncpy(r_prefix, filepath, basename_len - suffix_len + 1);
3201 break;
3202 }
3203 }
3204 }
3205}
3206
3208 const size_t width,
3209 const size_t height,
3210 size_t *r_width,
3211 size_t *r_height)
3212{
3216 width,
3217 height,
3218 r_width,
3219 r_height);
3220 }
3221 else {
3222 *r_width = width;
3223 *r_height = height;
3224 }
3225}
3226
3228{
3229 if (BKE_imtype_is_movie(rd->im_format.imtype) == false) {
3230 return 0;
3231 }
3232
3233 if ((rd->scemode & R_MULTIVIEW) == 0) {
3234 return 1;
3235 }
3236
3238 return 1;
3239 }
3240
3241 /* R_IMF_VIEWS_INDIVIDUAL */
3243}
3244
3245void BKE_scene_ppm_get(const RenderData *rd, double r_ppm[2])
3246{
3247 /* Should not be zero, prevent divide by zero if it is. */
3248 if (UNLIKELY(rd->ppm_base == 0.0f)) {
3249 /* Zero PPM should be ignored. */
3250 r_ppm[0] = 0.0;
3251 r_ppm[1] = 0.0;
3252 }
3253 /* Non-square aspects result in a lower density on one dimension to indicate
3254 * the image should be stretched to match the original size causing the pixel
3255 * density to be lower on that dimension. */
3256 double xasp = 1.0, yasp = 1.0;
3257 if (rd->xasp < rd->yasp) {
3258 yasp = double(rd->xasp) / double(rd->yasp);
3259 }
3260 else if (rd->xasp > rd->yasp) {
3261 xasp = double(rd->yasp) / double(rd->xasp);
3262 }
3263
3264 const double ppm_base = rd->ppm_base;
3265 const double ppm_factor = rd->ppm_factor;
3266
3267 r_ppm[0] = (ppm_factor / ppm_base) * xasp;
3268 r_ppm[1] = (ppm_factor / ppm_base) * yasp;
3269}
3270
3271/* Manipulation of depsgraph storage. */
3272
3273/* This is a key which identifies depsgraph. */
3276 /* TODO(sergey): Need to include window somehow (same layer might be in a
3277 * different states in different windows).
3278 */
3279};
3280
3281static uint depsgraph_key_hash(const void *key_v)
3282{
3283 const DepsgraphKey *key = static_cast<const DepsgraphKey *>(key_v);
3285 /* TODO(sergey): Include hash from other fields in the key. */
3286 return hash;
3287}
3288
3289static bool depsgraph_key_compare(const void *key_a_v, const void *key_b_v)
3290{
3291 const DepsgraphKey *key_a = static_cast<const DepsgraphKey *>(key_a_v);
3292 const DepsgraphKey *key_b = static_cast<const DepsgraphKey *>(key_b_v);
3293 /* TODO(sergey): Compare rest of. */
3294 return !(key_a->view_layer == key_b->view_layer);
3295}
3296
3297static void depsgraph_key_free(void *key_v)
3298{
3299 DepsgraphKey *key = static_cast<DepsgraphKey *>(key_v);
3300 MEM_freeN(key);
3301}
3302
3303static void depsgraph_key_value_free(void *value)
3304{
3305 Depsgraph *depsgraph = static_cast<Depsgraph *>(value);
3307}
3308
3310{
3312 depsgraph_key_hash, depsgraph_key_compare, "Scene Depsgraph Hash");
3313}
3314
3316{
3317 if (scene->depsgraph_hash == nullptr) {
3319 }
3320}
3321
3323{
3324 if (scene->depsgraph_hash == nullptr) {
3325 return;
3326 }
3328 scene->depsgraph_hash = nullptr;
3329}
3330
3332{
3333 if (scene->depsgraph_hash != nullptr) {
3334 DepsgraphKey key = {view_layer};
3336 }
3337}
3338
3339/* Query depsgraph for a specific contexts. */
3340
3341static Depsgraph **scene_get_depsgraph_p(Scene *scene,
3342 ViewLayer *view_layer,
3343 const bool allocate_ghash_entry)
3344{
3345 /* bmain may be nullptr here! */
3346 BLI_assert(scene != nullptr);
3347 BLI_assert(view_layer != nullptr);
3348 BLI_assert(BKE_scene_has_view_layer(scene, view_layer));
3349
3350 /* Make sure hash itself exists. */
3351 if (allocate_ghash_entry) {
3353 }
3354 if (scene->depsgraph_hash == nullptr) {
3355 return nullptr;
3356 }
3357
3358 DepsgraphKey key;
3359 key.view_layer = view_layer;
3360
3361 Depsgraph **depsgraph_ptr;
3362 if (!allocate_ghash_entry) {
3363 depsgraph_ptr = (Depsgraph **)BLI_ghash_lookup_p(scene->depsgraph_hash, &key);
3364 return depsgraph_ptr;
3365 }
3366
3367 DepsgraphKey **key_ptr;
3369 scene->depsgraph_hash, &key, (void ***)&key_ptr, (void ***)&depsgraph_ptr))
3370 {
3371 return depsgraph_ptr;
3372 }
3373
3374 /* Depsgraph was not found in the ghash, but the key still needs allocating. */
3375 *key_ptr = MEM_callocN<DepsgraphKey>(__func__);
3376 **key_ptr = key;
3377
3378 *depsgraph_ptr = nullptr;
3379 return depsgraph_ptr;
3380}
3381
3382static Depsgraph **scene_ensure_depsgraph_p(Main *bmain, Scene *scene, ViewLayer *view_layer)
3383{
3384 BLI_assert(bmain != nullptr);
3385
3386 Depsgraph **depsgraph_ptr = scene_get_depsgraph_p(scene, view_layer, true);
3387 if (depsgraph_ptr == nullptr) {
3388 /* The scene has no depsgraph hash. */
3389 return nullptr;
3390 }
3391 if (*depsgraph_ptr != nullptr) {
3392 /* The depsgraph was found, no need to allocate. */
3393 return depsgraph_ptr;
3394 }
3395
3396 /* Allocate a new depsgraph. scene_get_depsgraph_p() already ensured that the pointer is stored
3397 * in the scene's depsgraph hash. */
3398 *depsgraph_ptr = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_VIEWPORT);
3399
3400 /* TODO(sergey): Would be cool to avoid string format print,
3401 * but is a bit tricky because we can't know in advance whether
3402 * we will ever enable debug messages for this depsgraph.
3403 */
3404 char name[1024];
3405 SNPRINTF(name, "%s :: %s", scene->id.name, view_layer->name);
3406 DEG_debug_name_set(*depsgraph_ptr, name);
3407
3408 /* These viewport depsgraphs communicate changes to the editors. */
3409 DEG_enable_editors_update(*depsgraph_ptr);
3410
3411 return depsgraph_ptr;
3412}
3413
3414Depsgraph *BKE_scene_get_depsgraph(const Scene *scene, const ViewLayer *view_layer)
3415{
3416 BLI_assert(BKE_scene_has_view_layer(scene, view_layer));
3417
3418 if (scene->depsgraph_hash == nullptr) {
3419 return nullptr;
3420 }
3421
3422 DepsgraphKey key;
3423 key.view_layer = view_layer;
3424 return static_cast<Depsgraph *>(BLI_ghash_lookup(scene->depsgraph_hash, &key));
3425}
3426
3427Depsgraph *BKE_scene_ensure_depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer)
3428{
3429 Depsgraph **depsgraph_ptr = scene_ensure_depsgraph_p(bmain, scene, view_layer);
3430 return (depsgraph_ptr != nullptr) ? *depsgraph_ptr : nullptr;
3431}
3432
3433static char *scene_undo_depsgraph_gen_key(Scene *scene, ViewLayer *view_layer, char *key_full)
3434{
3435 if (key_full == nullptr) {
3436 key_full = MEM_calloc_arrayN<char>(MAX_ID_NAME + FILE_MAX + MAX_NAME, __func__);
3437 }
3438
3439 size_t key_full_offset = BLI_strncpy_rlen(key_full, scene->id.name, MAX_ID_NAME);
3440 if (ID_IS_LINKED(scene)) {
3441 key_full_offset += BLI_strncpy_rlen(
3442 key_full + key_full_offset, scene->id.lib->filepath, FILE_MAX);
3443 }
3444 key_full_offset += BLI_strncpy_rlen(key_full + key_full_offset, view_layer->name, MAX_NAME);
3445 BLI_assert(key_full_offset < MAX_ID_NAME + FILE_MAX + MAX_NAME);
3446
3447 return key_full;
3448}
3449
3451{
3452 GHash *depsgraph_extract = BLI_ghash_new(
3454
3455 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
3456 if (scene->depsgraph_hash == nullptr) {
3457 /* In some cases, e.g. when undo has to perform multiple steps at once, no depsgraph will
3458 * be built so this pointer may be nullptr. */
3459 continue;
3460 }
3461 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
3462 DepsgraphKey key;
3463 key.view_layer = view_layer;
3464 Depsgraph **depsgraph = (Depsgraph **)BLI_ghash_lookup_p(scene->depsgraph_hash, &key);
3465
3466 if (depsgraph != nullptr && *depsgraph != nullptr) {
3467 char *key_full = scene_undo_depsgraph_gen_key(scene, view_layer, nullptr);
3468
3469 /* We steal the depsgraph from the scene. */
3470 BLI_ghash_insert(depsgraph_extract, key_full, *depsgraph);
3471 *depsgraph = nullptr;
3472 }
3473 }
3474 }
3475
3476 return depsgraph_extract;
3477}
3478
3479void BKE_scene_undo_depsgraphs_restore(Main *bmain, GHash *depsgraph_extract)
3480{
3481 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
3482 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
3483 char key_full[MAX_ID_NAME + FILE_MAX + MAX_NAME] = {0};
3484 scene_undo_depsgraph_gen_key(scene, view_layer, key_full);
3485
3486 Depsgraph **depsgraph_extract_ptr = (Depsgraph **)BLI_ghash_lookup_p(depsgraph_extract,
3487 key_full);
3488 if (depsgraph_extract_ptr == nullptr) {
3489 continue;
3490 }
3491 BLI_assert(*depsgraph_extract_ptr != nullptr);
3492
3493 Depsgraph **depsgraph_scene_ptr = scene_get_depsgraph_p(scene, view_layer, true);
3494 BLI_assert(depsgraph_scene_ptr != nullptr);
3495 BLI_assert(*depsgraph_scene_ptr == nullptr);
3496
3497 /* We steal the depsgraph back from our 'extract' storage to the scene. */
3498 Depsgraph *depsgraph = *depsgraph_extract_ptr;
3499
3500 DEG_graph_replace_owners(depsgraph, bmain, scene, view_layer);
3501
3503
3504 *depsgraph_scene_ptr = depsgraph;
3505 *depsgraph_extract_ptr = nullptr;
3506 }
3507 }
3508
3510}
3511
3512/* -------------------------------------------------------------------- */
3515
3517{
3518 const int orientation_index = BKE_scene_transform_orientation_get_index(scene, orientation);
3519
3520 for (int i = 0; i < ARRAY_SIZE(scene->orientation_slots); i++) {
3521 TransformOrientationSlot *orient_slot = &scene->orientation_slots[i];
3522 if (orient_slot->index_custom == orientation_index) {
3523 /* could also use orientation_index-- */
3524 orient_slot->type = V3D_ORIENT_GLOBAL;
3525 orient_slot->index_custom = -1;
3526 }
3527 else if (orient_slot->index_custom > orientation_index) {
3528 BLI_assert(orient_slot->type == V3D_ORIENT_CUSTOM);
3529 orient_slot->index_custom--;
3530 }
3531 }
3532
3533 BLI_freelinkN(&scene->transform_spaces, orientation);
3534}
3535
3537{
3538 return static_cast<TransformOrientation *>(BLI_findlink(&scene->transform_spaces, index));
3539}
3540
3542 const TransformOrientation *orientation)
3543{
3544 return BLI_findindex(&scene->transform_spaces, orientation);
3545}
3546
3548
3549/* -------------------------------------------------------------------- */
3554
3555template<> blender::float3x3 View3DCursor::matrix<blender::float3x3>() const
3556{
3558 if (this->rotation_mode > 0) {
3559 eulO_to_mat3(mat.ptr(), this->rotation_euler, this->rotation_mode);
3560 }
3561 else if (this->rotation_mode == ROT_MODE_AXISANGLE) {
3562 axis_angle_to_mat3(mat.ptr(), this->rotation_axis, this->rotation_angle);
3563 }
3564 else {
3565 float tquat[4];
3566 normalize_qt_qt(tquat, this->rotation_quaternion);
3567 quat_to_mat3(mat.ptr(), tquat);
3568 }
3569 return mat;
3570}
3571
3572blender::math::Quaternion View3DCursor::rotation() const
3573{
3575 if (this->rotation_mode > 0) {
3576 eulO_to_quat(&quat.w, this->rotation_euler, this->rotation_mode);
3577 }
3578 else if (this->rotation_mode == ROT_MODE_AXISANGLE) {
3579 axis_angle_to_quat(&quat.w, this->rotation_axis, this->rotation_angle);
3580 }
3581 else {
3582 normalize_qt_qt(&quat.w, this->rotation_quaternion);
3583 }
3584 return quat;
3585}
3586
3587void View3DCursor::set_matrix(const blender::float3x3 &mat, const bool use_compat)
3588{
3589 BLI_ASSERT_UNIT_M3(mat.ptr());
3590
3591 switch (this->rotation_mode) {
3592 case ROT_MODE_QUAT: {
3593 float quat[4];
3594 mat3_normalized_to_quat(quat, mat.ptr());
3595 if (use_compat) {
3596 float quat_orig[4];
3597 copy_v4_v4(quat_orig, this->rotation_quaternion);
3598 quat_to_compatible_quat(this->rotation_quaternion, quat, quat_orig);
3599 }
3600 else {
3601 copy_v4_v4(this->rotation_quaternion, quat);
3602 }
3603 break;
3604 }
3605 case ROT_MODE_AXISANGLE: {
3606 mat3_to_axis_angle(this->rotation_axis, &this->rotation_angle, mat.ptr());
3607 break;
3608 }
3609 default: {
3610 if (use_compat) {
3612 this->rotation_euler, this->rotation_euler, this->rotation_mode, mat.ptr());
3613 }
3614 else {
3615 mat3_to_eulO(this->rotation_euler, this->rotation_mode, mat.ptr());
3616 }
3617 break;
3618 }
3619 }
3620}
3621
3622void View3DCursor::set_rotation(const blender::math::Quaternion &quat, bool use_compat)
3623{
3624 BLI_ASSERT_UNIT_QUAT(&quat.w);
3625
3626 switch (this->rotation_mode) {
3627 case ROT_MODE_QUAT: {
3628 if (use_compat) {
3629 float quat_orig[4];
3630 copy_v4_v4(quat_orig, this->rotation_quaternion);
3631 quat_to_compatible_quat(this->rotation_quaternion, &quat.w, quat_orig);
3632 }
3633 else {
3634 copy_qt_qt(this->rotation_quaternion, &quat.w);
3635 }
3636 break;
3637 }
3638 case ROT_MODE_AXISANGLE: {
3639 quat_to_axis_angle(this->rotation_axis, &this->rotation_angle, &quat.w);
3640 break;
3641 }
3642 default: {
3643 if (use_compat) {
3645 this->rotation_euler, this->rotation_euler, this->rotation_mode, &quat.w);
3646 }
3647 else {
3648 quat_to_eulO(this->rotation_euler, this->rotation_mode, &quat.w);
3649 }
3650 break;
3651 }
3652 }
3653}
3654
3655template<> blender::float4x4 View3DCursor::matrix<blender::float4x4>() const
3656{
3658 mat.location() = blender::float3(this->location);
3659 return mat;
3660}
3661
3662void View3DCursor::set_matrix(const blender::float4x4 &mat, const bool use_compat)
3663{
3664 this->set_matrix(blender::float3x3(mat), use_compat);
3665 copy_v3_v3(this->location, mat.location());
3666}
3667
Functions and classes to work with Actions.
Blender kernel action and pose functionality.
void BKE_animdata_duplicate_id_action(Main *bmain, ID *id, uint duplicate_flags)
Definition anim_data.cc:437
void BKE_keyingsets_free(struct ListBase *list)
Definition anim_sys.cc:280
void BKE_keyingsets_copy(struct ListBase *newlist, const struct ListBase *list)
void BKE_keyingsets_blend_read_data(struct BlendDataReader *reader, struct ListBase *list)
Definition anim_sys.cc:317
void BKE_time_markers_blend_read(BlendDataReader *reader, ListBase &markers)
Definition anim_sys.cc:4317
void BKE_keyingsets_blend_write(struct BlendWriter *writer, struct ListBase *list)
Definition anim_sys.cc:299
void BKE_keyingsets_foreach_id(struct LibraryForeachIDData *data, const struct ListBase *keyingsets)
void BKE_copy_time_markers(ListBase &markers_dst, const ListBase &markers_src, int flag)
Definition anim_sys.cc:4326
void BKE_time_markers_blend_write(BlendWriter *writer, ListBase &markers)
Definition anim_sys.cc:4306
bool BKE_bpath_foreach_path_dirfile_fixed_process(BPathForeachPathData *bpath_data, char *path_dir, size_t path_dir_maxncpy, char *path_file, size_t path_file_maxncpy)
Definition bpath.cc:156
bool BKE_bpath_foreach_path_fixed_process(BPathForeachPathData *bpath_data, char *path, size_t path_maxncpy)
Definition bpath.cc:125
@ BKE_BPATH_FOREACH_PATH_SKIP_MULTIFILE
Definition BKE_bpath.hh:61
void BKE_callback_exec_id(Main *bmain, ID *id, eCbEvent evt)
Definition callbacks.cc:43
@ BKE_CB_EVT_DEPSGRAPH_UPDATE_PRE
@ BKE_CB_EVT_FRAME_CHANGE_PRE
@ BKE_CB_EVT_FRAME_CHANGE_POST
@ BKE_CB_EVT_DEPSGRAPH_UPDATE_POST
void BKE_callback_exec_id_depsgraph(Main *bmain, ID *id, Depsgraph *depsgraph, eCbEvent evt)
Definition callbacks.cc:52
Collection * BKE_collection_master_add(Scene *scene)
void BKE_collection_blend_write_nolib(BlendWriter *writer, Collection *collection)
Collection * BKE_collection_duplicate(Main *bmain, Collection *parent, CollectionChild *child_old, Collection *collection, eDupli_ID_Flags duplicate_flags, uint duplicate_options)
void BKE_collection_blend_write_prepare_nolib(BlendWriter *writer, Collection *collection)
void BKE_collection_free_data(Collection *collection)
void BKE_curvemapping_free_data(CurveMapping *cumap)
void BKE_color_managed_view_settings_blend_read_data(BlendDataReader *reader, ColorManagedViewSettings *settings)
void BKE_curvemapping_curves_blend_write(BlendWriter *writer, const CurveMapping *cumap)
void BKE_curvemapping_blend_read(BlendDataReader *reader, CurveMapping *cumap)
void BKE_color_managed_display_settings_copy(ColorManagedDisplaySettings *new_settings, const ColorManagedDisplaySettings *settings)
void BKE_color_managed_display_settings_init(ColorManagedDisplaySettings *settings)
void BKE_curvemapping_set_defaults(CurveMapping *cumap, int tot, float minx, float miny, float maxx, float maxy, short default_handle_type)
Definition colortools.cc:40
@ CURVEMAP_SLOPE_POS_NEG
@ CURVEMAP_SLOPE_POSITIVE
void BKE_color_managed_view_settings_free(ColorManagedViewSettings *settings)
CurveMapping * BKE_curvemapping_copy(const CurveMapping *cumap)
void BKE_curvemapping_init(CurveMapping *cumap)
void BKE_color_managed_view_settings_copy(ColorManagedViewSettings *new_settings, const ColorManagedViewSettings *settings)
CurveMapping * BKE_curvemapping_add(int tot, float minx, float miny, float maxx, float maxy)
Definition colortools.cc:89
void BKE_color_managed_view_settings_init_render(ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, const char *view_transform)
void BKE_color_managed_view_settings_blend_write(BlendWriter *writer, ColorManagedViewSettings *settings)
void BKE_curvemap_reset(CurveMap *cuma, const rctf *clipr, int preset, int slope)
void BKE_curvemapping_free(CurveMapping *cumap)
void BKE_curvemapping_changed(CurveMapping *cumap, bool rem_doubles)
void BKE_curvemapping_blend_write(BlendWriter *writer, const CurveMapping *cumap)
void BKE_curvemapping_copy_data(CurveMapping *target, const CurveMapping *cumap)
void BKE_color_managed_colorspace_settings_copy(ColorManagedColorspaceSettings *colorspace_settings, const ColorManagedColorspaceSettings *settings)
struct CurveProfile * BKE_curveprofile_copy(const struct CurveProfile *profile)
void BKE_curveprofile_blend_read(struct BlendDataReader *reader, struct CurveProfile *profile)
struct CurveProfile * BKE_curveprofile_add(eCurveProfilePresets preset)
void BKE_curveprofile_blend_write(struct BlendWriter *writer, const struct CurveProfile *profile)
void BKE_curveprofile_free(struct CurveProfile *profile)
void free_object_duplilist(ListBase *lb)
ListBase * object_duplilist(Depsgraph *depsgraph, Scene *sce, Object *ob, blender::Set< const Object * > *include_objects=nullptr)
struct EffectorWeights * BKE_effector_add_weights(struct Collection *collection)
Definition effect.cc:58
void IDP_foreach_property(IDProperty *id_property_root, int type_filter, blender::FunctionRef< void(IDProperty *id_property)> callback)
#define IDP_BlendDataRead(reader, prop)
void IDP_FreeProperty(IDProperty *prop)
Definition idprop.cc:1243
void IDP_FreePropertyContent_ex(IDProperty *prop, bool do_id_user)
Definition idprop.cc:1205
IDProperty * IDP_CopyProperty(const IDProperty *prop) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:873
IDTypeInfo IDType_ID_SCE
Definition scene.cc:1623
@ IDTYPE_FLAGS_NEVER_UNUSED
Definition BKE_idtype.hh:69
void(*)(ID *id, const IDCacheKey *cache_key, void **cache_p, uint flags, void *user_data) IDTypeForeachCacheFunctionCallback
void BKE_image_editors_update_frame(const Main *bmain, int cfra)
void BKE_image_format_free(ImageFormatData *imf)
void BKE_image_format_init(ImageFormatData *imf, const bool render)
void BKE_image_format_blend_write(BlendWriter *writer, ImageFormatData *imf)
void BKE_image_format_blend_read_data(BlendDataReader *reader, ImageFormatData *imf)
bool BKE_imtype_is_movie(char imtype)
void BKE_image_format_copy(ImageFormatData *imf_dst, const ImageFormatData *imf_src)
void BKE_view_layer_blend_write(BlendWriter *writer, const Scene *scene, ViewLayer *view_layer)
bool BKE_view_layer_has_collection(const ViewLayer *view_layer, const Collection *collection)
void BKE_view_layer_blend_read_data(BlendDataReader *reader, ViewLayer *view_layer)
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
void BKE_view_layer_blend_read_after_liblink(BlendLibReader *reader, ID *self_id, ViewLayer *view_layer)
@ VIEWLAYER_ADD_NEW
Definition BKE_layer.hh:34
void BKE_view_layer_free_ex(ViewLayer *view_layer, bool do_id_user)
ViewLayer * BKE_view_layer_add(Scene *scene, const char *name, ViewLayer *view_layer_source, int type)
ViewLayer * BKE_view_layer_context_active_PLACEHOLDER(const Scene *scene)
void BKE_main_collection_sync(const Main *bmain)
void BKE_view_layer_copy_data(Scene *scene_dst, const Scene *scene_src, ViewLayer *view_layer_dst, const ViewLayer *view_layer_src, int flag)
ViewLayer * BKE_view_layer_default_render(const Scene *scene)
ListBase * BKE_view_layer_object_bases_get(ViewLayer *view_layer)
Object * BKE_view_layer_edit_object_get(const ViewLayer *view_layer)
ID * BKE_id_copy_for_duplicate(Main *bmain, ID *id, eDupli_ID_Flags duplicate_flags, int copy_flags)
Definition lib_id.cc:777
ID * BKE_libblock_find_name(Main *bmain, short type, const char *name, const std::optional< Library * > lib=std::nullopt) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition lib_id.cc:1679
struct ID * BKE_id_copy_in_lib(Main *bmain, std::optional< Library * > owner_library, const ID *id, std::optional< const ID * > new_owner_id, ID **new_id_p, int flag)
Definition lib_id.cc:663
void BKE_libblock_free_data_py(ID *id)
@ LIB_ID_CREATE_NO_ALLOCATE
@ LIB_ID_COPY_NO_PREVIEW
@ LIB_ID_CREATE_NO_USER_REFCOUNT
@ LIB_ID_COPY_DEFAULT
void BKE_main_id_newptr_and_tag_clear(Main *bmain)
Definition lib_id.cc:1981
void id_us_ensure_real(ID *id)
Definition lib_id.cc:308
ID * BKE_id_copy(Main *bmain, const ID *id)
Definition lib_id.cc:772
void * BKE_id_new(Main *bmain, short type, const char *name)
Definition lib_id.cc:1495
void id_us_plus_no_lib(ID *id)
Definition lib_id.cc:337
void id_us_min(ID *id)
Definition lib_id.cc:361
@ LIB_ID_DUPLICATE_IS_SUBPROCESS
void BKE_id_blend_write(BlendWriter *writer, ID *id)
Definition lib_id.cc:2611
#define BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data_, func_call_)
void BKE_lib_query_foreachid_process(LibraryForeachIDData *data, ID **id_pp, LibraryForeachIDCallbackFlag cb_flag)
Definition lib_query.cc:78
#define BKE_LIB_FOREACHID_PROCESS_IDSUPER(data_, id_super_, cb_flag_)
void BKE_library_foreach_ID_embedded(LibraryForeachIDData *data, ID **id_pp)
Definition lib_query.cc:172
LibraryForeachIDCallbackFlag
@ IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE
@ IDWALK_CB_NEVER_SELF
@ IDWALK_CB_USER
@ IDWALK_CB_EMBEDDED_NOT_OWNING
@ IDWALK_CB_DIRECT_WEAK_LINK
@ IDWALK_CB_NOP
LibraryForeachIDFlag BKE_lib_query_foreachid_process_flags_get(const LibraryForeachIDData *data)
Definition lib_query.cc:129
@ IDWALK_DO_DEPRECATED_POINTERS
@ IDWALK_NO_ORIG_POINTERS_ACCESS
void BKE_libblock_relink_to_newid(Main *bmain, ID *id, int remap_flag) ATTR_NONNULL()
Definition lib_remap.cc:919
@ ID_REMAP_SKIP_USER_CLEAR
@ ID_REMAP_SKIP_NEVER_NULL_USAGE
@ ID_REMAP_FORCE_OBDATA_IN_EDITMODE
void BKE_libblock_relink_ex(Main *bmain, void *idv, void *old_idv, void *new_idv, int remap_flags) ATTR_NONNULL(2)
Definition lib_remap.cc:842
#define FOREACH_MAIN_ID_END
Definition BKE_main.hh:563
#define FOREACH_MAIN_ID_BEGIN(_bmain, _id)
Definition BKE_main.hh:557
const char * BKE_main_blendfile_path(const Main *bmain) ATTR_NONNULL()
Definition main.cc:872
void BKE_paint_free(Paint *paint)
Definition paint.cc:1791
CurveMapping * BKE_sculpt_default_cavity_curve()
Definition scene.cc:125
void BKE_paint_copy(const Paint *src, Paint *dst, int flag)
Definition paint.cc:1809
CurveMapping * BKE_paint_default_curve()
Definition scene.cc:140
void BKE_paint_blend_read_data(BlendDataReader *reader, const Scene *scene, Paint *paint)
Definition paint.cc:1941
void BKE_paint_blend_write(BlendWriter *writer, Paint *paint)
Definition paint.cc:1909
void BKE_sculpt_cavity_curves_ensure(Sculpt *sd)
Definition paint.cc:2733
void BKE_ptcache_id_from_rigidbody(PTCacheID *pid, struct Object *ob, struct RigidBodyWorld *rbw)
void BKE_ptcache_blend_read_data(struct BlendDataReader *reader, struct ListBase *ptcaches, struct PointCache **ocache, int force_disk)
void BKE_ptcache_blend_write(struct BlendWriter *writer, struct ListBase *ptcaches)
void BKE_previewimg_blend_write(BlendWriter *writer, const PreviewImage *prv)
void BKE_previewimg_free(PreviewImage **prv)
void BKE_previewimg_blend_read(BlendDataReader *reader, PreviewImage *prv)
void BKE_previewimg_id_copy(ID *new_id, const ID *old_id)
API for Blender-side Rigid Body stuff.
void BKE_rigidbody_remove_constraint(struct Main *bmain, struct Scene *scene, struct Object *ob, bool free_us)
void BKE_rigidbody_remove_object(struct Main *bmain, struct Scene *scene, struct Object *ob, bool free_us)
void BKE_rigidbody_free_world(struct Scene *scene)
Definition rigidbody.cc:108
void BKE_rigidbody_world_id_loop(struct RigidBodyWorld *rbw, RigidbodyWorldIDFunc func, void *userdata)
struct RigidBodyWorld * BKE_rigidbody_world_copy(struct RigidBodyWorld *rbw, int flag)
void BKE_rigidbody_world_init_runtime(struct RigidBodyWorld *rbw)
Definition rigidbody.cc:96
void BKE_rigidbody_world_groups_relink(struct RigidBodyWorld *rbw)
void BKE_render_resolution(const RenderData *r, const bool use_crop, int *r_width, int *r_height)
Definition scene.cc:2927
Scene * BKE_scene_set_name(Main *bmain, const char *name)
Definition scene.cc:2065
int BKE_scene_transform_orientation_get_index(const Scene *scene, const TransformOrientation *orientation)
Definition scene.cc:3541
void BKE_scene_graph_evaluated_ensure(Depsgraph *depsgraph, Main *bmain)
Definition scene.cc:2623
void BKE_scene_disable_color_management(Scene *scene)
Definition scene.cc:2876
bool BKE_scene_uses_cycles(const Scene *scene)
Definition scene.cc:2832
void BKE_scene_copy_data_eevee(Scene *sce_dst, const Scene *sce_src)
Definition scene.cc:1819
float BKE_scene_ctime_get(const Scene *scene)
Definition scene.cc:2367
int get_render_subsurf_level(const RenderData *r, int lvl, bool for_render)
Definition scene.cc:2750
void BKE_scene_undo_depsgraphs_restore(Main *bmain, GHash *depsgraph_extract)
Definition scene.cc:3479
Object * BKE_scene_object_find_by_name(const Scene *scene, const char *name)
Definition scene.cc:2030
int BKE_scene_num_threads(const Scene *scene)
Definition scene.cc:2922
int get_render_child_particle_number(const RenderData *r, int child_num, bool for_render)
Definition scene.cc:2763
eSceneCopyMethod
Definition BKE_scene.hh:29
@ SCE_COPY_EMPTY
Definition BKE_scene.hh:31
@ SCE_COPY_FULL
Definition BKE_scene.hh:33
void BKE_scene_allocate_depsgraph_hash(Scene *scene)
Definition scene.cc:3309
void BKE_scene_free_view_layer_depsgraph(Scene *scene, ViewLayer *view_layer)
Definition scene.cc:3331
void BKE_toolsettings_free(ToolSettings *toolsettings)
Definition scene.cc:1736
void BKE_scene_graph_update_for_newframe_ex(Depsgraph *depsgraph, bool clear_recalc)
Definition scene.cc:2628
void BKE_scene_free_depsgraph_hash(Scene *scene)
Definition scene.cc:3322
int BKE_scene_multiview_num_views_get(const RenderData *rd)
Definition scene.cc:2952
bool BKE_scene_multiview_is_render_view_active(const RenderData *rd, const SceneRenderView *srv)
Definition scene.cc:3000
int BKE_scene_frame_snap_by_seconds(Scene *scene, double interval_in_seconds, int frame)
Definition scene.cc:2323
Object * BKE_scene_camera_switch_find(Scene *scene)
Definition scene.cc:2226
TransformOrientationSlot * BKE_scene_orientation_slot_get(Scene *scene, int slot_index)
Definition scene.cc:2397
void BKE_scene_transform_orientation_remove(Scene *scene, TransformOrientation *orientation)
Definition scene.cc:3516
bool BKE_scene_check_rigidbody_active(const Scene *scene)
Definition scene.cc:2894
int BKE_render_preview_pixel_size(const RenderData *r)
Definition scene.cc:2942
void BKE_scene_view_layer_graph_evaluated_ensure(Main *bmain, Scene *scene, ViewLayer *view_layer)
Definition scene.cc:2702
const char * BKE_scene_multiview_view_id_suffix_get(const RenderData *rd, int view_id)
Definition scene.cc:3166
bool BKE_scene_has_view_layer(const Scene *scene, const ViewLayer *layer)
Definition scene.cc:2208
TransformOrientationSlot * BKE_scene_orientation_slot_get_from_flag(Scene *scene, int flag)
Definition scene.cc:2405
int BKE_render_num_threads(const RenderData *r)
Definition scene.cc:2900
void BKE_scene_frame_set(Scene *scene, float frame)
Definition scene.cc:2386
void BKE_scene_multiview_view_prefix_get(Scene *scene, const char *filepath, char *r_prefix, const char **r_ext)
Definition scene.cc:3176
void BKE_scene_remove_rigidbody_object(Main *bmain, Scene *scene, Object *ob, bool free_us)
Definition scene.cc:2333
int BKE_scene_base_iter_next(Depsgraph *depsgraph, SceneBaseIter *iter, Scene **scene, int val, Base **base, Object **ob)
Definition scene.cc:2078
const char * BKE_scene_multiview_view_suffix_get(const RenderData *rd, const char *viewname)
Definition scene.cc:3149
bool BKE_scene_camera_switch_update(Scene *scene)
Definition scene.cc:2267
TransformOrientation * BKE_scene_transform_orientation_find(const Scene *scene, int index)
Definition scene.cc:3536
Depsgraph * BKE_scene_ensure_depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer)
Definition scene.cc:3427
bool BKE_scene_uses_cycles_experimental_features(Scene *scene)
Definition scene.cc:2848
bool BKE_scene_multiview_is_stereo3d(const RenderData *rd)
Definition scene.cc:2983
bool BKE_scene_multiview_is_render_view_first(const RenderData *rd, const char *viewname)
Definition scene.cc:3026
GHash * BKE_scene_undo_depsgraphs_extract(Main *bmain)
Definition scene.cc:3450
ToolSettings * BKE_toolsettings_copy(ToolSettings *toolsettings, int flag)
Definition scene.cc:1656
int BKE_scene_orientation_slot_get_index(const TransformOrientationSlot *orient_slot)
Definition scene.cc:2429
float BKE_scene_frame_get(const Scene *scene)
Definition scene.cc:2381
void BKE_scene_groups_relink(Scene *sce)
Definition scene.cc:1988
bool BKE_scene_can_be_removed(const Main *bmain, const Scene *scene)
Definition scene.cc:1995
void BKE_scene_multiview_videos_dimensions_get(const RenderData *rd, size_t width, size_t height, size_t *r_width, size_t *r_height)
Definition scene.cc:3207
bool BKE_scene_multiview_is_render_view_last(const RenderData *rd, const char *viewname)
Definition scene.cc:3045
bool BKE_scene_use_spherical_stereo(Scene *scene)
Definition scene.cc:2815
Scene * BKE_scene_duplicate(Main *bmain, Scene *sce, eSceneCopyMethod type)
Definition scene.cc:1825
void BKE_scene_ensure_depsgraph_hash(Scene *scene)
Definition scene.cc:3315
void BKE_scene_update_sound(Depsgraph *depsgraph, Main *bmain)
Definition scene.cc:2508
void BKE_scene_multiview_view_filepath_get(const RenderData *rd, const char *filepath, const char *view, char *r_filepath)
Definition scene.cc:3128
void BKE_scene_update_tag_audio_volume(Depsgraph *, Scene *scene)
Definition scene.cc:2533
bool BKE_scene_uses_shader_previews(const Scene *scene)
Definition scene.cc:2837
SceneRenderView * BKE_scene_multiview_render_view_findindex(const RenderData *rd, int view_id)
Definition scene.cc:3064
int BKE_scene_orientation_get_index_from_flag(Scene *scene, int flag)
Definition scene.cc:2442
bool BKE_scene_validate_setscene(Main *bmain, Scene *sce)
Definition scene.cc:2345
int BKE_scene_multiview_num_videos_get(const RenderData *rd)
Definition scene.cc:3227
Scene * BKE_scene_add(Main *bmain, const char *name)
Definition scene.cc:2010
int BKE_scene_orientation_get_index(Scene *scene, int slot_index)
Definition scene.cc:2436
bool BKE_scene_object_find(Scene *scene, Object *ob)
Definition scene.cc:2019
void BKE_scene_orientation_slot_set_index(TransformOrientationSlot *orient_slot, int orientation)
Definition scene.cc:2422
const char * BKE_scene_find_last_marker_name(const Scene *scene, int frame)
Definition scene.cc:2305
void BKE_scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain)
Definition scene.cc:2618
bool BKE_scene_use_shading_nodes_custom(Scene *scene)
Definition scene.cc:2809
void BKE_scene_multiview_filepath_get(const SceneRenderView *srv, const char *filepath, char *r_filepath)
Definition scene.cc:3120
int BKE_scene_multiview_view_id_get(const RenderData *rd, const char *viewname)
Definition scene.cc:3094
void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph)
Definition scene.cc:2697
Depsgraph * BKE_scene_get_depsgraph(const Scene *scene, const ViewLayer *view_layer)
Definition scene.cc:3414
void BKE_scene_set_background(Main *bmain, Scene *sce)
Definition scene.cc:2043
void BKE_scene_base_flag_to_objects(const Scene *scene, ViewLayer *view_layer)
Definition scene.cc:2862
bool BKE_scene_remove_render_view(Scene *scene, SceneRenderView *srv)
Definition scene.cc:2728
SceneRenderView * BKE_scene_add_render_view(Scene *sce, const char *name)
Definition scene.cc:2709
Base * _setlooper_base_step(Scene **sce_iter, ViewLayer *view_layer, Base *base)
Definition scene.cc:2776
float BKE_scene_frame_to_ctime(const Scene *scene, int frame)
Definition scene.cc:2372
Scene * BKE_scene_find_from_collection(const Main *bmain, const Collection *collection)
Definition scene.cc:2213
void BKE_scene_object_base_flag_sync_from_base(Base *base)
Definition scene.cc:2870
bool BKE_scene_uses_blender_workbench(const Scene *scene)
Definition scene.cc:2827
const char * BKE_scene_multiview_render_view_name_get(const RenderData *rd, int view_id)
Definition scene.cc:3083
bool BKE_scene_uses_blender_eevee(const Scene *scene)
Definition scene.cc:2821
const char * BKE_scene_find_marker_name(const Scene *scene, int frame)
Definition scene.cc:2278
void BKE_scene_ppm_get(const RenderData *rd, double r_ppm[2])
Definition scene.cc:3245
void BKE_screen_view3d_shading_blend_read_data(BlendDataReader *reader, View3DShading *shading)
Definition screen.cc:1090
void BKE_screen_view3d_shading_blend_write(BlendWriter *writer, View3DShading *shading)
Definition screen.cc:1083
void BKE_sound_seek_scene(struct Main *bmain, struct Scene *scene)
void BKE_sound_set_scene_volume(struct Scene *scene, float volume)
void BKE_sound_mute_scene(struct Scene *scene, int muted)
void BKE_sound_ensure_scene(struct Scene *scene)
void BKE_sound_reset_scene_runtime(struct Scene *scene)
void BKE_sound_update_scene_listener(struct Scene *scene)
void BKE_sound_destroy_scene(struct Scene *scene)
void BKE_sound_update_scene(struct Depsgraph *depsgraph, struct Scene *scene)
void BKE_sound_update_fps(struct Main *bmain, struct Scene *scene)
int BKE_unit_base_of_type_get(int system, int type)
Definition unit.cc:2531
@ B_UNIT_LENGTH
Definition BKE_unit.hh:124
@ B_UNIT_TEMPERATURE
Definition BKE_unit.hh:135
@ B_UNIT_MASS
Definition BKE_unit.hh:127
@ B_UNIT_TIME
Definition BKE_unit.hh:129
bScreen * BKE_workspace_active_screen_get(const WorkSpaceInstanceHook *hook) GETTER_ATTRS
Definition workspace.cc:612
#define BLI_assert(a)
Definition BLI_assert.h:46
bool BLI_ghashutil_strcmp(const void *a, const void *b)
unsigned int BLI_ghashutil_ptrhash(const void *key)
unsigned int BLI_ghashutil_strhash_p(const void *ptr)
GHash * BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.cc:686
void ** BLI_ghash_lookup_p(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.cc:745
bool BLI_ghash_remove(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition BLI_ghash.cc:787
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.cc:731
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition BLI_ghash.cc:707
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition BLI_ghash.cc:860
bool BLI_ghash_ensure_p_ex(GHash *gh, const void *key, void ***r_key, void ***r_val) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.cc:768
int BLI_findindex(const ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:586
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:534
#define LISTBASE_FOREACH(type, var, list)
void * BLI_findstring(const ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:608
void BLI_freelinkN(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:270
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
#define LISTBASE_FOREACH_BACKWARD(type, var, list)
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:497
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:131
void * BLI_findptr(const struct ListBase *listbase, const void *ptr, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:524
void void void void void void BLI_duplicatelist(ListBase *dst, const ListBase *src) ATTR_NONNULL(1
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
#define BLI_ASSERT_UNIT_M3(m)
MINLINE int mod_i(int i, int n)
#define BLI_ASSERT_UNIT_QUAT(q)
MINLINE int round_db_to_int(double a)
void copy_m4_m4(float m1[4][4], const float m2[4][4])
void quat_to_compatible_eulO(float eul[3], const float oldrot[3], short order, const float quat[4])
void axis_angle_to_quat(float r[4], const float axis[3], float angle)
void quat_to_mat3(float m[3][3], const float q[4])
void quat_to_eulO(float e[3], short order, const float q[4])
void eulO_to_quat(float q[4], const float e[3], short order)
float normalize_qt_qt(float r[4], const float q[4])
void quat_to_axis_angle(float axis[3], float *angle, const float q[4])
void mat3_to_compatible_eulO(float eul[3], const float oldrot[3], short order, const float mat[3][3])
void eulO_to_mat3(float M[3][3], const float e[3], short order)
void mat3_to_axis_angle(float axis[3], float *angle, const float mat[3][3])
void copy_qt_qt(float q[4], const float a[4])
void quat_to_compatible_quat(float q[4], const float a[4], const float old[4])
void axis_angle_to_mat3(float R[3][3], const float axis[3], float angle)
void mat3_to_eulO(float eul[3], short order, const float m[3][3])
void mat3_normalized_to_quat(float q[4], const float mat[3][3])
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void zero_v3(float r[3])
bool bool BLI_path_suffix(char *path, size_t path_maxncpy, const char *suffix, const char *sep) ATTR_NONNULL(1
#define FILE_MAX
#define STR_ELEM(...)
Definition BLI_string.h:656
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:599
int bool bool bool size_t size_t BLI_str_rpartition(const char *str, const char delim[], const char **sep, const char **suf) ATTR_NONNULL(1
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:688
char char size_t BLI_strncpy_rlen(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
void BLI_uniquename(const struct ListBase *list, void *vlink, const char *defname, char delim, int name_offset, size_t name_maxncpy) ATTR_NONNULL(1
unsigned char uchar
unsigned int uint
int BLI_system_thread_count(void)
Definition threads.cc:253
int BLI_system_num_threads_override_get(void)
Definition threads.cc:294
#define ARRAY_SIZE(arr)
#define STREQLEN(a, b, n)
#define UNLIKELY(x)
#define ELEM(...)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define POINTER_OFFSET(v, ofs)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define STREQ(a, b)
#define BLO_read_data_address(reader, ptr_p)
int BLO_read_struct_member_offset(const BlendDataReader *reader, const char *stype, const char *vartype, const char *name)
Definition readfile.cc:5249
ID * BLO_read_get_new_id_address_from_session_uid(BlendLibReader *reader, uint session_uid) ATTR_NONNULL(1)
Definition readfile.cc:5234
int BLO_read_fileversion_get(BlendDataReader *reader)
Definition readfile.cc:5239
void * BLO_read_get_new_data_address_no_us(BlendDataReader *reader, const void *old_address, size_t expected_size)
Definition readfile.cc:5198
BlendFileReadReport * BLO_read_data_reports(BlendDataReader *reader)
Definition readfile.cc:5500
void BLO_read_glob_list(BlendDataReader *reader, ListBase *list)
Definition readfile.cc:5495
#define BLO_write_id_struct(writer, struct_name, id_address, id)
#define BLO_write_struct(writer, struct_name, data_ptr)
BlendFileReadReport * BLO_read_lib_reports(BlendLibReader *reader)
Definition readfile.cc:5515
#define BLO_read_struct_list(reader, struct_name, list)
#define BLO_read_struct(reader, struct_name, ptr_p)
bool BLO_write_is_undo(BlendWriter *writer)
void BLO_reportf_wrap(BlendFileReadReport *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
#define BLO_write_struct_at_address(writer, struct_name, address, data_ptr)
external readfile function prototypes.
#define RPT_(msgid)
#define BLT_I18NCONTEXT_ID_SCENE
#define DATA_(msgid)
float[3] Vector
void DEG_id_tag_update(ID *id, unsigned int flags)
@ DEG_EVALUATE_SYNC_WRITEBACK_YES
void DEG_editors_update(Depsgraph *depsgraph, bool time)
void DEG_enable_editors_update(Depsgraph *depsgraph)
void DEG_ids_clear_recalc(Depsgraph *depsgraph, bool backup)
@ DAG_EVAL_VIEWPORT
Depsgraph * DEG_graph_new(Main *bmain, Scene *scene, ViewLayer *view_layer, eEvaluationMode mode)
Definition depsgraph.cc:278
void DEG_evaluate_on_refresh(Depsgraph *graph, DepsgraphEvaluateSyncWriteback sync_writeback=DEG_EVALUATE_SYNC_WRITEBACK_NO)
void DEG_graph_replace_owners(Depsgraph *depsgraph, Main *bmain, Scene *scene, ViewLayer *view_layer)
Definition depsgraph.cc:285
void DEG_graph_free(Depsgraph *graph)
Definition depsgraph.cc:306
void DEG_ids_restore_recalc(Depsgraph *depsgraph)
void DEG_make_active(Depsgraph *depsgraph)
Definition depsgraph.cc:336
void DEG_evaluate_on_framechange(Depsgraph *graph, float frame, DepsgraphEvaluateSyncWriteback sync_writeback=DEG_EVALUATE_SYNC_WRITEBACK_NO)
void DEG_graph_tag_relations_update(Depsgraph *graph)
void DEG_graph_relations_update(Depsgraph *graph)
void DEG_debug_name_set(Depsgraph *depsgraph, const char *name)
bool DEG_is_fully_evaluated(const Depsgraph *depsgraph)
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
bool DEG_is_evaluated(const T *id)
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
ViewLayer * DEG_get_evaluated_view_layer(const Depsgraph *graph)
ViewLayer * DEG_get_input_view_layer(const Depsgraph *graph)
Main * DEG_get_bmain(const Depsgraph *graph)
bool DEG_id_type_any_updated(const Depsgraph *depsgraph)
Scene * DEG_get_input_scene(const Depsgraph *graph)
@ ID_FLAG_EMBEDDED_DATA
Definition DNA_ID.h:687
@ ID_RECALC_PARAMETERS
Definition DNA_ID.h:1046
@ ID_RECALC_AUDIO_FPS
Definition DNA_ID.h:1035
@ ID_RECALC_AUDIO_LISTENER
Definition DNA_ID.h:1038
@ ID_RECALC_FRAME_CHANGE
Definition DNA_ID.h:1033
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1026
@ ID_RECALC_AUDIO_MUTE
Definition DNA_ID.h:1037
@ ID_RECALC_ALL
Definition DNA_ID.h:1096
@ ID_RECALC_AUDIO_VOLUME
Definition DNA_ID.h:1036
@ INDEX_ID_SCE
Definition DNA_ID.h:1258
@ ID_TAG_NEW
Definition DNA_ID.h:827
@ ID_SCE
@ IDP_TYPE_FILTER_ID
@ ROT_MODE_QUAT
@ ROT_MODE_AXISANGLE
Object groups, one object can be in many groups at once.
@ CUMA_EXTEND_EXTRAPOLATE
@ CURVE_PRESET_GAUSS
@ CURVE_PRESET_LINE
@ CURVE_PRESET_BELL
@ CURVE_PRESET_MAX
@ HD_AUTO
@ PROF_PRESET_LINE
#define DNA_struct_default_get(struct_name)
#define DNA_struct_default_alloc(struct_name)
@ OB_RENDER
Object is a sort of wrapper for general info.
@ OB_DUPLI
@ OB_HIDE_RENDER
@ OB_MESH
@ OB_FROMDUPLI
@ PTCACHE_FLAG_INFO_DIRTY
Types and defines for representing Rigid Body entities.
@ RBW_FLAG_MUTED
#define STEREO_LEFT_NAME
@ USER_UNIT_METRIC
@ SCE_VIEWS_FORMAT_STEREO_3D
@ SCE_VIEWS_FORMAT_MULTIVIEW
@ AUDIO_MUTE
@ SCE_ORIENT_DEFAULT
@ SCE_ORIENT_ROTATE
@ SCE_ORIENT_TRANSLATE
@ SCE_ORIENT_SCALE
@ S3D_SQUEEZED_FRAME
@ F_DUPLI
@ F_START
@ F_SCENE
@ PE_BRUSH_CUT
@ R_NO_CAMERA_SWITCH
@ R_CROP
@ R_SIMPLIFY
@ R_FIXED_THREADS
@ R_BORDER
#define STEREO_LEFT_SUFFIX
@ R_IMF_VIEWS_STEREO_3D
#define STEREO_RIGHT_NAME
#define STEREO_RIGHT_SUFFIX
#define FPS
@ R_MULTIVIEW
@ SCE_READFILE_LIBLINK_NEED_SETSCENE_CHECK
@ SCE_NLA_EDIT_ON
@ SCE_VIEW_DISABLE
#define MAXFRAME
@ STRIP_TYPE_TEXT
@ STRIP_TYPE_SOUND_RAM
@ STRIP_TYPE_IMAGE
@ STRIP_TYPE_MOVIE
#define STRIP_HAS_PATH(_strip)
@ SPACE_VIEW3D
eDupli_ID_Flags
@ USER_DUP_LINKED_ID
@ USER_DUP_OBJECT
@ V3D_ORIENT_CUSTOM
@ V3D_ORIENT_GLOBAL
@ V3D_GIZMO_SHOW_OBJECT_ROTATE
@ V3D_GIZMO_SHOW_OBJECT_SCALE
@ V3D_GIZMO_SHOW_OBJECT_TRANSLATE
static AppView * view
const char * IMB_colormanagement_display_get_none_name()
const char * IMB_colormanagement_view_get_raw_or_default_name(const char *display_name)
@ COLOR_ROLE_DEFAULT_SEQUENCER
const char * IMB_colormanagement_role_colorspace_name_get(int role)
void IMB_stereo3d_write_dimensions(char mode, bool is_squeezed, size_t width, size_t height, size_t *r_width, size_t *r_height)
Read Guarded memory(de)allocation.
@ RE_USE_SHADING_NODES_CUSTOM
Definition RE_engine.h:47
@ RE_USE_SPHERICAL_STEREO
Definition RE_engine.h:48
#define STRIP_DUPE_ALL
#define U
BMesh const char void * data
BMesh * bm
void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *mesh, const BMeshToMeshParams *params)
BPy_StructRNA * depsgraph
bool fcurve_remove(FCurve &fcurve_to_remove)
blender::Span< const FCurve * > fcurves() const
#define SELECT
#define offsetof(t, d)
#define this
#define modf
#define printf(...)
#define FILTER_ID_GD_LEGACY
#define FILTER_ID_OB
#define FILTER_ID_MC
#define FILTER_ID_MA
#define FILTER_ID_SO
#define MEM_SAFE_FREE(v)
#define FILTER_ID_BR
#define ID_IS_LINKED(_id)
#define MAX_ID_NAME
#define FILTER_ID_GR
#define FILTER_ID_LS
#define FILTER_ID_MSK
#define MAX_NAME
#define FILTER_ID_PAL
#define FILTER_ID_IM
#define FILTER_ID_SCE
#define FILTER_ID_WO
#define FILTER_ID_NT
#define FILTER_ID_TXT
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
RenderEngineType * RE_engines_find(const char *idname)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:123
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void * MEM_dupallocN(const void *vmemh)
Definition mallocn.cc:143
size_t(* MEM_allocN_len)(const void *vmemh)
Definition mallocn.cc:36
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
std::optional< std::pair< Action *, Slot * > > get_action_slot_pair(ID &animated_id)
void node_tree_blend_write(BlendWriter *writer, bNodeTree *ntree)
Definition node.cc:1464
void node_tree_free_embedded_tree(bNodeTree *ntree)
Definition node.cc:4724
QuaternionBase< float > Quaternion
SequencerToolSettings * tool_settings_init()
Definition sequencer.cc:346
SequencerToolSettings * tool_settings_copy(SequencerToolSettings *tool_settings)
Definition sequencer.cc:720
void blend_write(BlendWriter *writer, ListBase *seqbase)
Definition sequencer.cc:822
void tool_settings_free(SequencerToolSettings *tool_settings)
Definition sequencer.cc:373
void editing_free(Scene *scene, const bool do_id_user)
Definition sequencer.cc:293
void for_each_callback(ListBase *seqbase, ForEachFunc callback, void *user_data)
Definition iterator.cc:59
bool is_valid_strip_channel(const Strip *strip)
Definition sequencer.cc:715
void blend_read(BlendDataReader *reader, ListBase *seqbase)
Definition sequencer.cc:949
void seqbase_duplicate_recursive(const Scene *scene_src, Scene *scene_dst, ListBase *nseqbase, const ListBase *seqbase, int dupe_flag, const int flag)
Definition sequencer.cc:692
MatBase< float, 4, 4 > float4x4
MatBase< float, 3, 3 > float3x3
VecBase< float, 3 > float3
#define hash
Definition noise_c.cc:154
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
bool RNA_pointer_is_null(const PointerRNA *ptr)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PointerRNA RNA_id_pointer_create(ID *id)
#define BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_FUNCTION_CALL(_data, _do_undo_restore, _func_call)
Definition scene.cc:556
static void scene_undo_preserve(BlendLibReader *reader, ID *id_new, ID *id_old)
Definition scene.cc:1557
static uint depsgraph_key_hash(const void *key_v)
Definition scene.cc:3281
static void scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain, bool only_if_tagged)
Definition scene.cc:2547
static void depsgraph_key_free(void *key_v)
Definition scene.cc:3297
const char * RE_engine_id_CYCLES
Definition scene.cc:1628
static void scene_blend_read_data(BlendDataReader *reader, ID *id)
Definition scene.cc:1211
static void direct_link_paint_helper(BlendDataReader *reader, const Scene *scene, Paint **paint)
Definition scene.cc:1185
const char * RE_engine_id_BLENDER_EEVEE_NEXT
Definition scene.cc:1626
eSceneForeachUndoPreserveProcess
Definition scene.cc:473
@ SCENE_FOREACH_UNDO_NO_RESTORE
Definition scene.cc:479
@ SCENE_FOREACH_UNDO_RESTORE
Definition scene.cc:476
static void link_recurs_seq(BlendDataReader *reader, ListBase *lb)
Definition scene.cc:1195
#define FOREACHID_PROCESS_IDSUPER(_data, _id_super, _cb_flag)
static void scene_blend_read_after_liblink(BlendLibReader *reader, ID *id)
Definition scene.cc:1522
static bool depsgraph_key_compare(const void *key_a_v, const void *key_b_v)
Definition scene.cc:3289
#define FOREACHID_PROCESS_ID_NOCHECK(_data, _id_super, _cb_flag)
static void scene_free_markers(Scene *scene, bool do_id_user)
Definition scene.cc:375
static void remove_sequencer_fcurves(Scene *sce)
Definition scene.cc:1630
static void scene_blend_write(BlendWriter *writer, ID *id, const void *id_address)
Definition scene.cc:1016
static void scene_foreach_rigidbodyworldSceneLooper(RigidBodyWorld *, ID **id_pointer, void *user_data, const LibraryForeachIDCallbackFlag cb_flag)
Definition scene.cc:459
static bool strip_foreach_path_callback(Strip *strip, void *user_data)
Definition scene.cc:954
eCyclesFeatureSet
Definition scene.cc:2843
@ CYCLES_FEATURES_SUPPORTED
Definition scene.cc:2844
@ CYCLES_FEATURES_EXPERIMENTAL
Definition scene.cc:2845
const char * RE_engine_id_BLENDER_WORKBENCH
Definition scene.cc:1627
static void scene_init_data(ID *id)
Definition scene.cc:149
static char * scene_undo_depsgraph_gen_key(Scene *scene, ViewLayer *view_layer, char *key_full)
Definition scene.cc:3433
static void scene_foreach_toolsettings_id_pointer_process(ID **id_p, const eSceneForeachUndoPreserveProcess action, BlendLibReader *reader, ID **id_old_p, const uint cb_flag)
Definition scene.cc:482
static void prepare_mesh_for_viewport_render(Main *bmain, const Scene *scene, ViewLayer *view_layer)
Definition scene.cc:2477
static Depsgraph ** scene_ensure_depsgraph_p(Main *bmain, Scene *scene, ViewLayer *view_layer)
Definition scene.cc:3382
blender::float3x3 View3DCursor::matrix< blender::float3x3 >() const
Definition scene.cc:3555
static void scene_copy_data(Main *bmain, std::optional< Library * > owner_library, ID *id_dst, const ID *id_src, const int flag)
Definition scene.cc:257
const char * RE_engine_id_BLENDER_EEVEE
Definition scene.cc:1625
static void scene_foreach_layer_collection(LibraryForeachIDData *data, ListBase *lb, const bool is_master)
Definition scene.cc:779
static Depsgraph ** scene_get_depsgraph_p(Scene *scene, ViewLayer *view_layer, const bool allocate_ghash_entry)
Definition scene.cc:3341
#define BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER_P(_data, _id_p, _do_undo_restore, _action, _reader, _id_old_p, _cb_flag)
Definition scene.cc:542
static void scene_foreach_id(ID *id, LibraryForeachIDData *data)
Definition scene.cc:848
static void scene_free_data(ID *id)
Definition scene.cc:386
static bool strip_foreach_member_id_cb(Strip *strip, void *user_data)
Definition scene.cc:796
static void scene_foreach_cache(ID *id, IDTypeForeachCacheFunctionCallback function_callback, void *user_data)
Definition scene.cc:1002
static void scene_foreach_toolsettings(LibraryForeachIDData *data, ToolSettings *toolsett, const bool do_undo_restore, BlendLibReader *reader, ToolSettings *toolsett_old)
Definition scene.cc:613
static void scene_foreach_path(ID *id, BPathForeachPathData *bpath_data)
Definition scene.cc:994
static bool check_rendered_viewport_visible(Main *bmain)
Definition scene.cc:2450
static void depsgraph_key_value_free(void *value)
Definition scene.cc:3303
static void scene_foreach_paint(LibraryForeachIDData *data, Paint *paint, const bool do_undo_restore, BlendLibReader *reader, Paint *paint_old)
Definition scene.cc:569
static void scene_lib_override_apply_post(ID *id_dst, ID *)
Definition scene.cc:1573
constexpr IDTypeInfo get_type_info()
eBPathForeachFlag flag
Definition BKE_bpath.hh:94
struct Object * cage_object
char filepath[1024]
struct ImageFormatData im_format
struct Base * next
short flag
struct Object * object
struct BlendFileReadReport::@365377131325274324253051140175317050064341373234 count
CurveMap cm[4]
const ViewLayer * view_layer
Definition scene.cc:3275
float mat[4][4]
DupliObject * next
IntraFrameCache * intra_frame_cache
ThumbnailCache * thumbnail_cache
MediaPresence * media_presence
FinalImageCache * final_image_cache
StripLookup * strip_lookup
SourceImageCache * source_image_cache
ListBase seqbase
ListBase * seqbasep
Strip * act_strip
ListBase channels
char proxy_dir[1024]
PrefetchJob * prefetch_job
int show_missing_media_flag
ListBase * displayed_channels
ListBase metastack
EditingRuntime runtime
struct CurveMapping * custom_ipo
struct Object * reference_object
struct GP_Sculpt_Guide guide
struct CurveMapping * cur_primitive
struct CurveMapping * cur_falloff
unsigned int id_session_uid
Definition BKE_idtype.hh:74
size_t identifier
Definition BKE_idtype.hh:79
IDTypeBlendReadUndoPreserve blend_read_undo_preserve
int main_listbase_index
short id_code
const char * name
uint64_t dependencies_id_types
IDTypeForeachIDFunction foreach_id
const char * name_plural
IDTypeCopyDataFunction copy_data
IDTypeInitDataFunction init_data
IDTypeForeachCacheFunction foreach_cache
uint64_t id_filter
IDTypeBlendWriteFunction blend_write
IDTypeBlendReadDataFunction blend_read_data
IDTypeFreeDataFunction free_data
uint32_t flags
size_t struct_size
IDTypeMakeLocalFunction make_local
AssetTypeInfo * asset_type_info
IDTypeLibOverrideApplyPost lib_override_apply_post
IDTypeForeachPathFunction foreach_path
const char * translation_context
IDTypeBlendReadAfterLiblinkFunction blend_read_after_liblink
IDTypeEmbeddedOwnerPointerGetFunction owner_pointer_get
Definition DNA_ID.h:404
unsigned int recalc
Definition DNA_ID.h:427
int tag
Definition DNA_ID.h:424
struct Library * lib
Definition DNA_ID.h:410
IDProperty * system_properties
Definition DNA_ID.h:454
IDProperty * properties
Definition DNA_ID.h:446
struct ID * orig_id
Definition DNA_ID.h:466
char name[66]
Definition DNA_ID.h:415
unsigned int session_uid
Definition DNA_ID.h:444
Stereo3dFormat stereo3d_format
struct Image * stencil
struct Image * canvas
char filepath[1024]
Definition DNA_ID.h:507
void * last
void * first
ListBase scenes
Definition BKE_main.hh:245
ListBase wm
Definition BKE_main.hh:276
ListBase objects
Definition BKE_main.hh:247
MeshRuntimeHandle * runtime
short base_flag
ObjectRuntimeHandle * runtime
struct RigidBodyOb * rigidbody_object
struct RigidBodyCon * rigidbody_constraint
struct ListBase * ptcaches
struct Brush * eraser_brush
struct Palette * palette
struct Brush * brush
ParticleBrushData brush[7]
struct Object * shape_object
short simplify_subsurf
struct CurveMapping mblur_shutter_curve
float simplify_particles
struct BakeData bake
char engine[32]
float simplify_particles_render
struct ImageFormatData im_format
char pic[1024]
short preview_pixel_size
short simplify_subsurf_render
void(* render)(struct RenderEngine *engine, struct Depsgraph *depsgraph)
Definition RE_engine.h:80
struct DrawEngineType * draw_engine
Definition RE_engine.h:116
struct PointCache * pointcache
struct Collection * constraints
struct Collection * group
struct RigidBodyWorld_Shared * shared
struct Object ** objects
struct EffectorWeights * effector_weights
float omat[4][4]
Definition BKE_scene.hh:78
DupliObject * dupob
Definition BKE_scene.hh:77
ListBase * duplilist
Definition BKE_scene.hh:76
Object * dupli_refob
Definition BKE_scene.hh:79
View3DShading shading
struct SceneRenderView * next
struct bNodeTree * nodetree
struct Collection * master_collection
struct GHash * depsgraph_hash
struct PhysicsSettings physics_settings
struct RigidBodyWorld * rigidbody_world
IDProperty * layer_properties
struct SceneDisplay display
struct CustomData_MeshMasks customdata_mask
struct MovieClip * clip
ListBase keyingsets
void * fps_info
struct ToolSettings * toolsettings
ColorManagedViewSettings view_settings
struct PreviewImage * preview
SceneRuntimeHandle * runtime
struct Editing * ed
struct bGPdata * gpd
struct RenderData r
View3DCursor cursor
ListBase view_layers
struct CustomData_MeshMasks customdata_mask_modal
TransformOrientationSlot orientation_slots[4]
struct UnitSettings unit
struct Object * camera
ListBase markers
ListBase transform_spaces
struct World * world
ColorManagedColorspaceSettings sequencer_colorspace_settings
struct Scene * set
struct AudioData audio
struct SceneEEVEE eevee
ColorManagedDisplaySettings display_settings
struct Object * gravity_object
struct CurveMapping * automasking_cavity_curve_op
struct CurveMapping * automasking_cavity_curve
StripElem * stripdata
char dirpath[768]
char filename[256]
struct Object * scene_camera
struct Mask * mask
StripData * data
struct IDProperty * prop
struct Scene * scene
struct MovieClip * clip
void * effectdata
struct bSound * sound
struct IDProperty * system_properties
ListBase modifiers
struct VFont * text_font
struct TimeMarker * prev
struct TimeMarker * next
GpWeightPaint * gp_weightpaint
struct ImagePaintSettings imapaint
struct CurveProfile * custom_bevel_profile_preset
struct SequencerToolSettings * sequencer_tool_settings
GpSculptPaint * gp_sculptpaint
struct PaintModeSettings paint_mode
struct UnifiedPaintSettings unified_paint_settings
struct GP_Interpolate_Settings gp_interpolate
struct ParticleEditSettings particle
CurvesSculpt * curves_sculpt
struct GP_Sculpt_Settings gp_sculpt
GpVertexPaint * gp_vertexpaint
struct CurveMapping * curve_rand_value
struct CurveMapping * curve_rand_saturation
struct CurveMapping * curve_rand_hue
struct CurveMapping * strength_curve
struct IDProperty * prop
View3DShading shading
struct ViewLayer * next
char name[64]
ListBase areabase
const c_style_mat & ptr() const
float xmax
float xmin
float ymax
float ymin
i
Definition text_draw.cc:230
uint len
uint8_t flag
Definition wm_window.cc:139