Blender V4.3
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
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"
22#include "DNA_defaults.h"
25#include "DNA_linestyle_types.h"
26#include "DNA_mask_types.h"
27#include "DNA_material_types.h"
28#include "DNA_mesh_types.h"
29#include "DNA_node_types.h"
30#include "DNA_object_types.h"
31#include "DNA_rigidbody_types.h"
32#include "DNA_scene_types.h"
33#include "DNA_screen_types.h"
34#include "DNA_sequence_types.h"
35#include "DNA_sound_types.h"
36#include "DNA_space_types.h"
37#include "DNA_text_types.h"
38#include "DNA_vfont_types.h"
39#include "DNA_view3d_types.h"
41#include "DNA_world_types.h"
42
43#include "BKE_callbacks.hh"
44#include "BLI_blenlib.h"
45#include "BLI_math_rotation.h"
46#include "BLI_string.h"
47#include "BLI_string_utils.hh"
48#include "BLI_task.h"
49#include "BLI_threads.h"
50#include "BLI_utildefines.h"
51
52#include "BLO_readfile.hh"
53
54#include "BLT_translation.hh"
55
56#include "BKE_action.hh"
57#include "BKE_anim_data.hh"
58#include "BKE_animsys.h"
59#include "BKE_bpath.hh"
60#include "BKE_collection.hh"
61#include "BKE_colortools.hh"
62#include "BKE_curveprofile.h"
63#include "BKE_duplilist.hh"
64#include "BKE_editmesh.hh"
65#include "BKE_effect.h"
66#include "BKE_fcurve.hh"
67#include "BKE_idprop.hh"
68#include "BKE_idtype.hh"
69#include "BKE_image.hh"
70#include "BKE_image_format.hh"
71#include "BKE_layer.hh"
72#include "BKE_lib_id.hh"
73#include "BKE_lib_query.hh"
74#include "BKE_lib_remap.hh"
75#include "BKE_main.hh"
76#include "BKE_mesh_types.hh"
77#include "BKE_node_runtime.hh"
78#include "BKE_paint.hh"
79#include "BKE_pointcache.h"
80#include "BKE_preview_image.hh"
81#include "BKE_rigidbody.h"
82#include "BKE_scene.hh"
83#include "BKE_scene_runtime.hh"
84#include "BKE_screen.hh"
85#include "BKE_sound.h"
86#include "BKE_unit.hh"
87#include "BKE_workspace.hh"
88
89#include "DEG_depsgraph.hh"
93
94#include "RE_engine.h"
95
96#include "RNA_access.hh"
97
98#include "SEQ_iterator.hh"
99#include "SEQ_sequencer.hh"
100
101#include "BLO_read_write.hh"
102
103#include "IMB_colormanagement.hh"
104#include "IMB_imbuf.hh"
105
106#include "DRW_engine.hh"
107
108#include "bmesh.hh"
109
112
119
121
122{
123 CurveMapping *cumap = BKE_curvemapping_add(1, 0, 0, 1, 1);
124
125 cumap->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
126 cumap->preset = CURVE_PRESET_LINE;
127
128 BKE_curvemap_reset(cumap->cm, &cumap->clipr, cumap->preset, CURVEMAP_SLOPE_POSITIVE);
129 BKE_curvemapping_changed(cumap, false);
131
132 return cumap;
133}
134
145
146static void scene_init_data(ID *id)
147{
148 Scene *scene = (Scene *)id;
149 const char *colorspace_name;
150 SceneRenderView *srv;
151 CurveMapping *mblur_shutter_curve;
152
154
156
157 STRNCPY(scene->r.bake.filepath, U.renderdir);
158
159 mblur_shutter_curve = &scene->r.mblur_shutter_curve;
160 BKE_curvemapping_set_defaults(mblur_shutter_curve, 1, 0.0f, 0.0f, 1.0f, 1.0f, HD_AUTO);
161 BKE_curvemapping_init(mblur_shutter_curve);
162 BKE_curvemap_reset(mblur_shutter_curve->cm,
163 &mblur_shutter_curve->clipr,
166
167 scene->toolsettings = DNA_struct_default_alloc(ToolSettings);
168
169 scene->toolsettings->autokey_mode = uchar(U.autokey_mode);
170
171 /* Grease pencil multi-frame falloff curve. */
172 scene->toolsettings->gp_sculpt.cur_falloff = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
173 CurveMapping *gp_falloff_curve = scene->toolsettings->gp_sculpt.cur_falloff;
174 BKE_curvemapping_init(gp_falloff_curve);
176 gp_falloff_curve->cm, &gp_falloff_curve->clipr, CURVE_PRESET_GAUSS, CURVEMAP_SLOPE_POSITIVE);
177
178 scene->toolsettings->gp_sculpt.cur_primitive = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
179 CurveMapping *gp_primitive_curve = scene->toolsettings->gp_sculpt.cur_primitive;
180 BKE_curvemapping_init(gp_primitive_curve);
181 BKE_curvemap_reset(gp_primitive_curve->cm,
182 &gp_primitive_curve->clipr,
185
186 scene->unit.system = USER_UNIT_METRIC;
187 scene->unit.scale_length = 1.0f;
191 scene->unit.temperature_unit = uchar(
193
194 /* Anti-Aliasing threshold. */
195 scene->grease_pencil_settings.smaa_threshold = 1.0f;
196
197 {
199 pset = &scene->toolsettings->particle;
200 for (size_t i = 1; i < ARRAY_SIZE(pset->brush); i++) {
201 pset->brush[i] = pset->brush[0];
202 }
203 pset->brush[PE_BRUSH_CUT].strength = 1.0f;
204 }
205
207
208 STRNCPY(scene->r.pic, U.renderdir);
209
210 /* NOTE: in header_info.c the scene copy happens...,
211 * if you add more to renderdata it has to be checked there. */
212
213 /* multiview - stereo */
215 srv = static_cast<SceneRenderView *>(scene->r.views.first);
217
219 srv = static_cast<SceneRenderView *>(scene->r.views.last);
221
223
224 /* color management */
226
227 BKE_color_managed_display_settings_init(&scene->display_settings);
229 &scene->view_settings, &scene->display_settings, "AgX");
230 STRNCPY(scene->sequencer_colorspace_settings.name, colorspace_name);
231
232 BKE_image_format_init(&scene->r.im_format, true);
233 BKE_image_format_init(&scene->r.bake.im_format, true);
234
235 /* Curve Profile */
236 scene->toolsettings->custom_bevel_profile_preset = BKE_curveprofile_add(PROF_PRESET_LINE);
237
238 /* Sequencer */
239 scene->toolsettings->sequencer_tool_settings = SEQ_tool_settings_init();
240
241 for (size_t i = 0; i < ARRAY_SIZE(scene->orientation_slots); i++) {
242 scene->orientation_slots[i].index_custom = -1;
243 }
244
245 /* Master Collection */
246 scene->master_collection = BKE_collection_master_add(scene);
247
248 BKE_view_layer_add(scene, DATA_("ViewLayer"), nullptr, VIEWLAYER_ADD_NEW);
249
250 scene->runtime = MEM_new<SceneRuntime>(__func__);
251}
252
253static void scene_copy_markers(Scene *scene_dst, const Scene *scene_src, const int flag)
254{
255 BLI_duplicatelist(&scene_dst->markers, &scene_src->markers);
256 LISTBASE_FOREACH (TimeMarker *, marker, &scene_dst->markers) {
257 if (marker->prop != nullptr) {
258 marker->prop = IDP_CopyProperty_ex(marker->prop, flag);
259 }
260 }
261}
262
263static void scene_copy_data(Main *bmain,
264 std::optional<Library *> owner_library,
265 ID *id_dst,
266 const ID *id_src,
267 const int flag)
268{
269 Scene *scene_dst = (Scene *)id_dst;
270 const Scene *scene_src = (const Scene *)id_src;
271 /* Never handle user-count here for own sub-data. */
272 const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
273 /* Always need allocation of the embedded ID data. */
274 const int flag_embedded_id_data = flag_subdata & ~LIB_ID_CREATE_NO_ALLOCATE;
275
276 scene_dst->ed = nullptr;
277 scene_dst->depsgraph_hash = nullptr;
278 scene_dst->fps_info = nullptr;
279
280 /* Master Collection */
281 if (scene_src->master_collection) {
282 BKE_id_copy_in_lib(bmain,
283 owner_library,
284 &scene_src->master_collection->id,
285 &scene_dst->id,
286 reinterpret_cast<ID **>(&scene_dst->master_collection),
287 flag_embedded_id_data);
288 }
289
290 /* View Layers */
291 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene_src->view_layers) {
292 BKE_view_layer_synced_ensure(scene_src, view_layer);
293 }
294 BLI_duplicatelist(&scene_dst->view_layers, &scene_src->view_layers);
295 for (ViewLayer *view_layer_src = static_cast<ViewLayer *>(scene_src->view_layers.first),
296 *view_layer_dst = static_cast<ViewLayer *>(scene_dst->view_layers.first);
297 view_layer_src;
298 view_layer_src = view_layer_src->next, view_layer_dst = view_layer_dst->next)
299 {
300 BKE_view_layer_copy_data(scene_dst, scene_src, view_layer_dst, view_layer_src, flag_subdata);
301 }
302
303 scene_copy_markers(scene_dst, scene_src, flag);
304
305 BLI_duplicatelist(&(scene_dst->transform_spaces), &(scene_src->transform_spaces));
306 BLI_duplicatelist(&(scene_dst->r.views), &(scene_src->r.views));
307 BKE_keyingsets_copy(&(scene_dst->keyingsets), &(scene_src->keyingsets));
308
309 if (scene_src->nodetree) {
310 BKE_id_copy_in_lib(bmain,
311 owner_library,
312 &scene_src->nodetree->id,
313 &scene_dst->id,
314 reinterpret_cast<ID **>(&scene_dst->nodetree),
315 flag_embedded_id_data);
316 /* TODO this should not be needed anymore? Should be handled by generic remapping code in
317 * #BKE_id_copy_in_lib. */
319 scene_dst->nodetree,
320 (void *)(&scene_src->id),
321 &scene_dst->id,
323 }
324
325 if (scene_src->rigidbody_world) {
327 flag_subdata);
328 }
329
330 /* copy color management settings */
332 &scene_src->display_settings);
336
337 BKE_image_format_copy(&scene_dst->r.im_format, &scene_src->r.im_format);
338 BKE_image_format_copy(&scene_dst->r.bake.im_format, &scene_src->r.bake.im_format);
339
341
342 /* tool settings */
343 scene_dst->toolsettings = BKE_toolsettings_copy(scene_dst->toolsettings, flag_subdata);
344
345 if (scene_src->display.shading.prop) {
346 scene_dst->display.shading.prop = IDP_CopyProperty(scene_src->display.shading.prop);
347 }
348
350
351 /* Copy sequencer, this is local data! */
352 if (scene_src->ed) {
353 scene_dst->ed = MEM_cnew<Editing>(__func__);
354 scene_dst->ed->seqbasep = &scene_dst->ed->seqbase;
355 scene_dst->ed->cache_flag = scene_src->ed->cache_flag;
356 scene_dst->ed->show_missing_media_flag = scene_src->ed->show_missing_media_flag;
357 scene_dst->ed->proxy_storage = scene_src->ed->proxy_storage;
358 STRNCPY(scene_dst->ed->proxy_dir, scene_src->ed->proxy_dir);
360 scene_dst,
361 &scene_dst->ed->seqbase,
362 &scene_src->ed->seqbase,
364 flag_subdata);
365 BLI_duplicatelist(&scene_dst->ed->channels, &scene_src->ed->channels);
366 scene_dst->ed->displayed_channels = &scene_dst->ed->channels;
367 }
368
369 if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
370 BKE_previewimg_id_copy(&scene_dst->id, &scene_src->id);
371 }
372 else {
373 scene_dst->preview = nullptr;
374 }
375
376 BKE_scene_copy_data_eevee(scene_dst, scene_src);
377
378 scene_dst->runtime = MEM_new<SceneRuntime>(__func__);
379}
380
381static void scene_free_markers(Scene *scene, bool do_id_user)
382{
383 LISTBASE_FOREACH_MUTABLE (TimeMarker *, marker, &scene->markers) {
384 if (marker->prop != nullptr) {
385 IDP_FreePropertyContent_ex(marker->prop, do_id_user);
386 MEM_freeN(marker->prop);
387 }
388 MEM_freeN(marker);
389 }
390}
391
392static void scene_free_data(ID *id)
393{
394 Scene *scene = (Scene *)id;
395 const bool do_id_user = false;
396
398
399 SEQ_editing_free(scene, do_id_user);
400
401 BKE_keyingsets_free(&scene->keyingsets);
402
403 /* is no lib link block, but scene extension */
404 if (scene->nodetree) {
406 MEM_freeN(scene->nodetree);
407 scene->nodetree = nullptr;
408 }
409
410 if (scene->rigidbody_world) {
411 /* Prevent rigidbody freeing code to follow other IDs pointers, this should never be allowed
412 * nor necessary from here, and with new undo code, those pointers may be fully invalid or
413 * worse, pointing to data actually belonging to new BMain! */
414 scene->rigidbody_world->constraints = nullptr;
415 scene->rigidbody_world->group = nullptr;
417 }
418
419 scene_free_markers(scene, do_id_user);
420 BLI_freelistN(&scene->transform_spaces);
421 BLI_freelistN(&scene->r.views);
422
423 BKE_toolsettings_free(scene->toolsettings);
424 scene->toolsettings = nullptr;
425
427
428 MEM_SAFE_FREE(scene->fps_info);
429
431
432 BKE_color_managed_view_settings_free(&scene->view_settings);
433 BKE_image_format_free(&scene->r.im_format);
434 BKE_image_format_free(&scene->r.bake.im_format);
435
436 BKE_previewimg_free(&scene->preview);
437 BKE_curvemapping_free_data(&scene->r.mblur_shutter_curve);
438
439 LISTBASE_FOREACH_MUTABLE (ViewLayer *, view_layer, &scene->view_layers) {
440 BLI_remlink(&scene->view_layers, view_layer);
441 BKE_view_layer_free_ex(view_layer, do_id_user);
442 }
443
444 /* Master Collection */
445 /* TODO: what to do with do_id_user? it's also true when just
446 * closing the file which seems wrong? should decrement users
447 * for objects directly in the master collection? then other
448 * collections in the scene need to do it too? */
449 if (scene->master_collection) {
450 BKE_collection_free_data(scene->master_collection);
451 BKE_libblock_free_data_py(&scene->master_collection->id);
452 MEM_freeN(scene->master_collection);
453 scene->master_collection = nullptr;
454 }
455
456 if (scene->display.shading.prop) {
457 IDP_FreeProperty(scene->display.shading.prop);
458 scene->display.shading.prop = nullptr;
459 }
460
461 /* These are freed on `do_versions`. */
462 BLI_assert(scene->layer_properties == nullptr);
463
464 MEM_delete(scene->runtime);
465}
466
468 ID **id_pointer,
469 void *user_data,
470 int cb_flag)
471{
472 LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
474 data, BKE_lib_query_foreachid_process(data, id_pointer, cb_flag));
475}
476
482 /* Undo when preserving tool-settings from old scene, we also want to try to preserve that ID
483 * pointer from its old scene's value. */
485 /* Undo when preserving tool-settings from old scene, we want to keep the new value of that ID
486 * pointer. */
488};
489
491 ID **id_p,
493 BlendLibReader *reader,
494 ID **id_old_p,
495 const uint cb_flag)
496{
497 switch (action) {
499 ID *id_old = *id_old_p;
500 /* Old data has not been remapped to new values of the pointers, if we want to keep the old
501 * pointer here we need its new address. */
502 ID *id_old_new = id_old != nullptr ? BLO_read_get_new_id_address_from_session_uid(
503 reader, id_old->session_uid) :
504 nullptr;
505 /* The new address may be the same as the old one, in which case there is nothing to do. */
506 if (id_old_new == id_old) {
507 break;
508 }
509 if (id_old_new != nullptr) {
510 BLI_assert(id_old == id_old_new->orig_id);
511 *id_old_p = id_old_new;
512 if (cb_flag & IDWALK_CB_USER) {
513 id_us_plus_no_lib(id_old_new);
514 id_us_min(id_old);
515 }
516 break;
517 }
518
519 /* We failed to find a new valid pointer for the previous ID, just keep the current one as
520 * if we had been under #SCENE_FOREACH_UNDO_NO_RESTORE case.
521 *
522 * There is a nasty twist here though: a previous call to 'undo_preserve' on the Scene ID may
523 * have modified it, even though the undo step detected it as unmodified. In such case, the
524 * value of `*id_p` may end up also pointing to an invalid (no more in newly read Main) ID,
525 * so it also needs to be checked from its `session_uid`. */
526 ID *id = *id_p;
527 ID *id_new = id != nullptr ?
528 BLO_read_get_new_id_address_from_session_uid(reader, id->session_uid) :
529 nullptr;
530 if (id_new != id) {
531 *id_p = id_new;
532 if (cb_flag & IDWALK_CB_USER) {
533 id_us_plus_no_lib(id_new);
534 id_us_min(id);
535 }
536 }
537 std::swap(*id_p, *id_old_p);
538 break;
539 }
541 /* Counteract the swap of the whole ToolSettings container struct. */
542 std::swap(*id_p, *id_old_p);
543 break;
544 }
545}
546
547/* Special handling is needed here, as `scene_foreach_toolsettings` (and its dependency
548 * `scene_foreach_paint`) are also used by `scene_undo_preserve`, where `LibraryForeachIDData
549 * *data` is nullptr. */
550#define BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER_P( \
551 _data, _id_p, _do_undo_restore, _action, _reader, _id_old_p, _cb_flag) \
552 { \
553 if (_do_undo_restore) { \
554 scene_foreach_toolsettings_id_pointer_process( \
555 (ID **)(_id_p), _action, _reader, (ID **)(_id_old_p), _cb_flag); \
556 } \
557 else { \
558 BLI_assert((_data) != nullptr); \
559 BKE_LIB_FOREACHID_PROCESS_IDSUPER_P(_data, _id_p, _cb_flag); \
560 } \
561 } \
562 (void)0
563
564#define BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_FUNCTION_CALL( \
565 _data, _do_undo_restore, _func_call) \
566 { \
567 if (_do_undo_restore) { \
568 _func_call; \
569 } \
570 else { \
571 BLI_assert((_data) != nullptr); \
572 BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(_data, _func_call); \
573 } \
574 } \
575 (void)0
576
578 Paint *paint,
579 const bool do_undo_restore,
580 BlendLibReader *reader,
581 Paint *paint_old)
582{
583 /* `paint` may be nullptr in 'undo_preserve' case, when the relevant sub-data does not exist in
584 * newly read toolsettings, but does exist in old existing ones.
585 *
586 * This function should never be called in case the old toolsettings do not have the relevant
587 * `paint_old` data. */
588 BLI_assert(paint_old != nullptr);
589
590 Brush *brush_tmp = nullptr;
591 Brush **brush_p = paint ? &paint->brush : &brush_tmp;
593 brush_p,
594 do_undo_restore,
596 reader,
597 &paint_old->brush,
599
600 Brush *eraser_brush_tmp = nullptr;
601 Brush **eraser_brush_p = paint ? &paint->eraser_brush : &eraser_brush_tmp;
603 eraser_brush_p,
604 do_undo_restore,
606 reader,
607 &paint_old->eraser_brush,
609
610 Palette *palette_tmp = nullptr;
611 Palette **palette_p = paint ? &paint->palette : &palette_tmp;
613 palette_p,
614 do_undo_restore,
616 reader,
617 &paint_old->palette,
619}
620
622 ToolSettings *toolsett,
623 const bool do_undo_restore,
624 BlendLibReader *reader,
625 ToolSettings *toolsett_old)
626{
627 /* In regular foreach_id case, only one set of data is processed, both pointers are expected to
628 * be the same.
629 *
630 * In undo_preserve case, both pointers may be different (see #lib_link_all for why they may be
631 * the same in some cases). */
632 BLI_assert(do_undo_restore || (toolsett == toolsett_old));
633 BLI_assert(!ELEM(nullptr, toolsett, toolsett_old));
634
635 /* NOTE: In 'undo_preserve' case, the 'old' data is the source of truth here, since it is the one
636 * that will be re-used in newly read Main and therefore needs valid, existing in new Main, ID
637 * pointers. */
638
640 &toolsett->particle.scene,
641 do_undo_restore,
643 reader,
644 &toolsett_old->particle.scene,
647 &toolsett->particle.object,
648 do_undo_restore,
650 reader,
651 &toolsett_old->particle.object,
654 &toolsett->particle.shape_object,
655 do_undo_restore,
657 reader,
658 &toolsett_old->particle.shape_object,
660
662 data, &toolsett->imapaint.paint, do_undo_restore, reader, &toolsett_old->imapaint.paint);
664 &toolsett->imapaint.stencil,
665 do_undo_restore,
667 reader,
668 &toolsett_old->imapaint.stencil,
671 &toolsett->imapaint.clone,
672 do_undo_restore,
674 reader,
675 &toolsett_old->imapaint.clone,
678 &toolsett->imapaint.canvas,
679 do_undo_restore,
681 reader,
682 &toolsett_old->imapaint.canvas,
684
685 Paint *paint, *paint_old;
686
687 if (toolsett_old->vpaint) {
688 paint = toolsett->vpaint ? &toolsett->vpaint->paint : nullptr;
689 paint_old = &toolsett_old->vpaint->paint;
691 data,
692 do_undo_restore,
693 scene_foreach_paint(data, paint, do_undo_restore, reader, paint_old));
694 }
695 if (toolsett_old->wpaint) {
696 paint = toolsett->wpaint ? &toolsett->wpaint->paint : nullptr;
697 paint_old = &toolsett_old->wpaint->paint;
699 data,
700 do_undo_restore,
701 scene_foreach_paint(data, paint, do_undo_restore, reader, paint_old));
702 }
703 if (toolsett_old->sculpt) {
704 paint = toolsett->sculpt ? &toolsett->sculpt->paint : nullptr;
705 paint_old = &toolsett_old->sculpt->paint;
707 data,
708 do_undo_restore,
709 scene_foreach_paint(data, paint, do_undo_restore, reader, paint_old));
710
711 Object *gravity_object = toolsett->sculpt ? toolsett->sculpt->gravity_object : nullptr;
712 Object *gravity_object_old = toolsett_old->sculpt->gravity_object;
714 &gravity_object,
715 do_undo_restore,
717 reader,
718 &gravity_object_old,
720 if (toolsett->sculpt) {
721 toolsett->sculpt->gravity_object = gravity_object;
722 }
723 toolsett_old->sculpt->gravity_object = gravity_object_old;
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 }
789 const int cb_flag = is_master ? IDWALK_CB_EMBEDDED_NOT_OWNING : IDWALK_CB_NOP;
790 BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, lc->collection, cb_flag | IDWALK_CB_DIRECT_WEAK_LINK);
791 scene_foreach_layer_collection(data, &lc->layer_collections, false);
792 }
793}
794
795static bool seq_foreach_member_id_cb(Sequence *seq, void *user_data)
796{
797 LibraryForeachIDData *data = static_cast<LibraryForeachIDData *>(user_data);
799
800/* Only for deprecated data. */
801#define FOREACHID_PROCESS_ID_NOCHECK(_data, _id_super, _cb_flag) \
802 { \
803 BKE_lib_query_foreachid_process((_data), reinterpret_cast<ID **>(&(_id_super)), (_cb_flag)); \
804 if (BKE_lib_query_foreachid_iter_stop(_data)) { \
805 return false; \
806 } \
807 } \
808 ((void)0)
809
810#define FOREACHID_PROCESS_IDSUPER(_data, _id_super, _cb_flag) \
811 { \
812 CHECK_TYPE(&((_id_super)->id), ID *); \
813 FOREACHID_PROCESS_ID_NOCHECK(_data, _id_super, _cb_flag); \
814 } \
815 ((void)0)
816
823 BKE_lib_query_idpropertiesForeachIDLink_callback(prop, data);
824 });
826 FOREACHID_PROCESS_IDSUPER(data, smd->mask_id, IDWALK_CB_USER);
827 }
828
829 if (seq->type == SEQ_TYPE_TEXT && seq->effectdata) {
830 TextVars *text_data = static_cast<TextVars *>(seq->effectdata);
832 }
833
836 }
837
838#undef FOREACHID_PROCESS_IDSUPER
839#undef FOREACHID_PROCESS_ID_NOCHECK
840
841 return true;
842}
843
845{
846 Scene *scene = reinterpret_cast<Scene *>(id);
848
854 BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, scene->r.bake.cage_object, IDWALK_CB_NOP);
855 if (scene->nodetree) {
856 /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
858 data, BKE_library_foreach_ID_embedded(data, (ID **)&scene->nodetree));
859 }
860 if (scene->ed) {
862 data, SEQ_for_each_callback(&scene->ed->seqbase, seq_foreach_member_id_cb, data));
863 }
864
866 BKE_keyingsets_foreach_id(data, &scene->keyingsets));
867
868 /* This pointer can be nullptr during old files reading, better be safe than sorry. */
869 if (scene->master_collection != nullptr) {
871 data, BKE_library_foreach_ID_embedded(data, (ID **)&scene->master_collection));
872 }
873
874 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
875 BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, view_layer->mat_override, IDWALK_CB_USER);
876 BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, view_layer->world_override, IDWALK_CB_USER);
878 data,
879 IDP_foreach_property(view_layer->id_properties, IDP_TYPE_FILTER_ID, [&](IDProperty *prop) {
880 BKE_lib_query_idpropertiesForeachIDLink_callback(prop, data);
881 }));
882
883 BKE_view_layer_synced_ensure(scene, view_layer);
886 data,
887 base->object,
889 }
890
892 data, scene_foreach_layer_collection(data, &view_layer->layer_collections, true));
893
894 LISTBASE_FOREACH (FreestyleModuleConfig *, fmc, &view_layer->freestyle_config.modules) {
896 }
897
898 LISTBASE_FOREACH (FreestyleLineSet *, fls, &view_layer->freestyle_config.linesets) {
901 }
902 }
903
904 LISTBASE_FOREACH (TimeMarker *, marker, &scene->markers) {
907 data, IDP_foreach_property(marker->prop, IDP_TYPE_FILTER_ID, [&](IDProperty *prop) {
908 BKE_lib_query_idpropertiesForeachIDLink_callback(prop, data);
909 }));
910 }
911
912 ToolSettings *toolsett = scene->toolsettings;
913 if (toolsett) {
915 data, scene_foreach_toolsettings(data, toolsett, false, nullptr, toolsett));
916 }
917
918 if (scene->rigidbody_world) {
920 data,
922 scene->rigidbody_world, scene_foreach_rigidbodyworldSceneLooper, data));
923 }
924
926 LISTBASE_FOREACH_MUTABLE (Base *, base_legacy, &scene->base) {
927 BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, base_legacy->object, IDWALK_CB_NOP);
928 }
929
930 LISTBASE_FOREACH (SceneRenderLayer *, srl, &scene->r.layers) {
931 BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, srl->mat_override, IDWALK_CB_USER);
932 LISTBASE_FOREACH (FreestyleModuleConfig *, fmc, &srl->freestyleConfig.modules) {
934 }
935 LISTBASE_FOREACH (FreestyleLineSet *, fls, &srl->freestyleConfig.linesets) {
938 }
939 }
940 }
941}
942
943static bool seq_foreach_path_callback(Sequence *seq, void *user_data)
944{
945 if (SEQ_HAS_PATH(seq)) {
946 StripElem *se = seq->strip->stripdata;
947 BPathForeachPathData *bpath_data = (BPathForeachPathData *)user_data;
948
949 if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM) && se) {
951 seq->strip->dirpath,
952 sizeof(seq->strip->dirpath),
953 se->filename,
954 sizeof(se->filename));
955 }
956 else if ((seq->type == SEQ_TYPE_IMAGE) && se) {
957 /* NOTE: An option not to loop over all strips could be useful? */
958 uint len = uint(MEM_allocN_len(se)) / uint(sizeof(*se));
959 uint i;
960
962 /* only operate on one path */
963 len = std::min(1u, len);
964 }
965
966 for (i = 0; i < len; i++, se++) {
968 seq->strip->dirpath,
969 sizeof(seq->strip->dirpath),
970 se->filename,
971 sizeof(se->filename));
972 }
973 }
974 else {
975 /* simple case */
977 bpath_data, seq->strip->dirpath, sizeof(seq->strip->dirpath));
978 }
979 }
980 return true;
981}
982
983static void scene_foreach_path(ID *id, BPathForeachPathData *bpath_data)
984{
985 Scene *scene = (Scene *)id;
986 if (scene->ed != nullptr) {
987 SEQ_for_each_callback(&scene->ed->seqbase, seq_foreach_path_callback, bpath_data);
988 }
989}
990
991static void scene_foreach_cache(ID *id,
992 IDTypeForeachCacheFunctionCallback function_callback,
993 void *user_data)
994{
995 Scene *scene = (Scene *)id;
996 if (scene->ed != nullptr) {
997 IDCacheKey key;
998 key.id_session_uid = id->session_uid;
999 /* Preserve VSE thumbnail cache across global undo steps. */
1000 key.identifier = offsetof(Editing, runtime.thumbnail_cache);
1001 function_callback(id, &key, (void **)&scene->ed->runtime.thumbnail_cache, 0, user_data);
1002 }
1003}
1004
1005static void scene_blend_write(BlendWriter *writer, ID *id, const void *id_address)
1006{
1007 Scene *sce = (Scene *)id;
1008
1009 BLO_Write_IDBuffer *temp_embedded_id_buffer = BLO_write_allocate_id_buffer();
1010
1011 if (BLO_write_is_undo(writer)) {
1012 /* Clean up, important in undo case to reduce false detection of changed data-blocks. */
1013 /* XXX This UI data should not be stored in Scene at all... */
1014 memset(&sce->cursor, 0, sizeof(sce->cursor));
1015 }
1016
1017 /* write LibData */
1018 BLO_write_id_struct(writer, Scene, id_address, &sce->id);
1019 BKE_id_blend_write(writer, &sce->id);
1020
1022
1023 /* direct data */
1024 ToolSettings *tos = sce->toolsettings;
1025 BLO_write_struct(writer, ToolSettings, tos);
1026 if (tos->vpaint) {
1027 BLO_write_struct(writer, VPaint, tos->vpaint);
1028 BKE_paint_blend_write(writer, &tos->vpaint->paint);
1029 }
1030 if (tos->wpaint) {
1031 BLO_write_struct(writer, VPaint, tos->wpaint);
1032 BKE_paint_blend_write(writer, &tos->wpaint->paint);
1033 }
1034 if (tos->sculpt) {
1035 BLO_write_struct(writer, Sculpt, tos->sculpt);
1036 if (tos->sculpt->automasking_cavity_curve) {
1038 }
1041 }
1042
1043 BKE_paint_blend_write(writer, &tos->sculpt->paint);
1044 }
1045 if (tos->uvsculpt.strength_curve) {
1047 }
1048 if (tos->gp_paint) {
1049 BLO_write_struct(writer, GpPaint, tos->gp_paint);
1050 BKE_paint_blend_write(writer, &tos->gp_paint->paint);
1051 }
1052 if (tos->gp_vertexpaint) {
1055 }
1056 if (tos->gp_sculptpaint) {
1059 }
1060 if (tos->gp_weightpaint) {
1063 }
1064 if (tos->curves_sculpt) {
1067 }
1068 /* write grease-pencil custom ipo curve to file */
1069 if (tos->gp_interpolate.custom_ipo) {
1071 }
1072 /* write grease-pencil multi-frame falloff curve to file */
1073 if (tos->gp_sculpt.cur_falloff) {
1075 }
1076 /* write grease-pencil primitive curve to file */
1077 if (tos->gp_sculpt.cur_primitive) {
1079 }
1080 /* Write the curve profile to the file. */
1081 if (tos->custom_bevel_profile_preset) {
1083 }
1084 if (tos->sequencer_tool_settings) {
1086 }
1087
1088 BKE_paint_blend_write(writer, &tos->imapaint.paint);
1089
1090 Editing *ed = sce->ed;
1091 if (ed) {
1092 BLO_write_struct(writer, Editing, ed);
1093
1094 SEQ_blend_write(writer, &ed->seqbase);
1095 LISTBASE_FOREACH (SeqTimelineChannel *, channel, &ed->channels) {
1096 BLO_write_struct(writer, SeqTimelineChannel, channel);
1097 }
1098 /* new; meta stack too, even when its nasty restore code */
1099 LISTBASE_FOREACH (MetaStack *, ms, &ed->metastack) {
1100 BLO_write_struct(writer, MetaStack, ms);
1101 }
1102 }
1103
1104 /* writing dynamic list of TimeMarkers to the blend file */
1105 LISTBASE_FOREACH (TimeMarker *, marker, &sce->markers) {
1106 BLO_write_struct(writer, TimeMarker, marker);
1107
1108 if (marker->prop != nullptr) {
1109 IDP_BlendWrite(writer, marker->prop);
1110 }
1111 }
1112
1113 /* writing dynamic list of TransformOrientations to the blend file */
1116 }
1117
1118 /* writing MultiView to the blend file */
1119 LISTBASE_FOREACH (SceneRenderView *, srv, &sce->r.views) {
1120 BLO_write_struct(writer, SceneRenderView, srv);
1121 }
1122
1123 if (sce->nodetree) {
1125 temp_embedded_id_buffer, &sce->nodetree->id, BLO_write_is_undo(writer));
1126 bNodeTree *temp_nodetree = reinterpret_cast<bNodeTree *>(
1127 BLO_write_get_id_buffer_temp_id(temp_embedded_id_buffer));
1128 /* Set deprecated chunksize for forward compatibility. */
1129 temp_nodetree->chunksize = 256;
1130 BLO_write_struct_at_address(writer, bNodeTree, sce->nodetree, temp_nodetree);
1131 blender::bke::node_tree_blend_write(writer, temp_nodetree);
1132 }
1133
1137
1138 /* writing RigidBodyWorld data to the blend file */
1139 if (sce->rigidbody_world) {
1140 /* Set deprecated pointers to prevent crashes of older Blenders */
1141 sce->rigidbody_world->pointcache = sce->rigidbody_world->shared->pointcache;
1142 sce->rigidbody_world->ptcaches = sce->rigidbody_world->shared->ptcaches;
1144
1148 }
1149
1150 BKE_previewimg_blend_write(writer, sce->preview);
1152
1153 LISTBASE_FOREACH (ViewLayer *, view_layer, &sce->view_layers) {
1154 BKE_view_layer_blend_write(writer, sce, view_layer);
1155 }
1156
1157 if (sce->master_collection) {
1159 temp_embedded_id_buffer, &sce->master_collection->id, BLO_write_is_undo(writer));
1161 writer,
1162 reinterpret_cast<Collection *>(BLO_write_get_id_buffer_temp_id(temp_embedded_id_buffer)));
1164 Collection,
1165 sce->master_collection,
1166 BLO_write_get_id_buffer_temp_id(temp_embedded_id_buffer));
1168 writer,
1169 reinterpret_cast<Collection *>(BLO_write_get_id_buffer_temp_id(temp_embedded_id_buffer)));
1170 }
1171
1173
1174 /* Freed on `do_versions()`. */
1175 BLI_assert(sce->layer_properties == nullptr);
1176
1177 BLO_write_destroy_id_buffer(&temp_embedded_id_buffer);
1178}
1179
1180static void direct_link_paint_helper(BlendDataReader *reader, const Scene *scene, Paint **paint)
1181{
1182 /* TODO: is this needed. */
1183 BLO_read_struct(reader, Paint, paint);
1184
1185 if (*paint) {
1186 BKE_paint_blend_read_data(reader, scene, *paint);
1187 }
1188}
1189
1191{
1192 BLO_read_struct_list(reader, Sequence, lb);
1193
1194 LISTBASE_FOREACH_MUTABLE (Sequence *, seq, lb) {
1195 /* Sanity check. */
1196 if (!SEQ_is_valid_strip_channel(seq)) {
1197 BLI_freelinkN(lb, seq);
1199 }
1200 else if (seq->seqbase.first) {
1201 link_recurs_seq(reader, &seq->seqbase);
1202 }
1203 }
1204}
1205
1207{
1208 Scene *sce = (Scene *)id;
1209
1210 sce->depsgraph_hash = nullptr;
1211 sce->fps_info = nullptr;
1212
1213 memset(&sce->customdata_mask, 0, sizeof(sce->customdata_mask));
1214 memset(&sce->customdata_mask_modal, 0, sizeof(sce->customdata_mask_modal));
1215
1217
1218 /* set users to one by default, not in lib-link, this will increase it for compo nodes */
1219 id_us_ensure_real(&sce->id);
1220
1221 sce->runtime = MEM_new<SceneRuntime>(__func__);
1222
1223 BLO_read_struct_list(reader, Base, &(sce->base));
1224
1227
1228 BLO_read_struct(reader, Base, &sce->basact);
1229
1231 if (sce->toolsettings) {
1232
1233 /* Reset last_location and last_hit, so they are not remembered across sessions. In some files
1234 * these are also NaN, which could lead to crashes in painting. */
1236 zero_v3(ups->last_location);
1237 ups->last_hit = 0;
1238
1239 direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->sculpt);
1240 direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->vpaint);
1241 direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->wpaint);
1242 direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->gp_paint);
1247
1249
1250 sce->toolsettings->particle.paintcursor = nullptr;
1251 sce->toolsettings->particle.scene = nullptr;
1252 sce->toolsettings->particle.object = nullptr;
1253 sce->toolsettings->gp_sculpt.paintcursor = nullptr;
1258 }
1259
1260 if (sce->toolsettings->sculpt) {
1264
1268 }
1269
1274 }
1275
1277 }
1278
1279 /* Relink grease pencil interpolation curves. */
1283 }
1284 /* Relink grease pencil multi-frame falloff curve. */
1288 }
1289 /* Relink grease pencil primitive curve. */
1293 }
1294
1295 /* Relink toolsettings curve profile. */
1299 }
1300
1303 }
1304
1305 if (sce->ed) {
1306 ListBase *old_seqbasep = &sce->ed->seqbase;
1307 ListBase *old_displayed_channels = &sce->ed->channels;
1308
1309 BLO_read_struct(reader, Editing, &sce->ed);
1310 Editing *ed = sce->ed;
1311
1312 ed->act_seq = static_cast<Sequence *>(
1314 ed->cache = nullptr;
1315 ed->prefetch_job = nullptr;
1316 ed->runtime.sequence_lookup = nullptr;
1317 ed->runtime.media_presence = nullptr;
1318 ed->runtime.thumbnail_cache = nullptr;
1319
1320 /* recursive link sequences, lb will be correctly initialized */
1321 link_recurs_seq(reader, &ed->seqbase);
1322
1323 /* Read in sequence member data. */
1324 SEQ_blend_read(reader, &ed->seqbase);
1326
1327 /* link metastack, slight abuse of structs here,
1328 * have to restore pointer to internal part in struct */
1329 {
1330 void *seqbase_poin;
1331 void *channels_poin;
1332 /* This whole thing with seqbasep offsets is really not good
1333 * and prevents changes to the Sequence struct. A more correct approach
1334 * would be to calculate offset using sDNA from the file (NOT from the
1335 * current Blender). Even better would be having some sort of dedicated
1336 * map of seqbase pointers to avoid this offset magic. */
1337 constexpr intptr_t seqbase_offset = offsetof(Sequence, seqbase);
1338 constexpr intptr_t channels_offset = offsetof(Sequence, channels);
1339#if ARCH_CPU_64_BITS
1340 static_assert(seqbase_offset == 264, "Sequence seqbase member offset cannot be changed");
1341 static_assert(channels_offset == 280, "Sequence channels member offset cannot be changed");
1342#else
1343 static_assert(seqbase_offset == 204, "Sequence seqbase member offset cannot be changed");
1344 static_assert(channels_offset == 212, "Sequence channels member offset cannot be changed");
1345#endif
1346
1347 /* seqbase root pointer */
1348 if (ed->seqbasep == old_seqbasep) {
1349 ed->seqbasep = &ed->seqbase;
1350 }
1351 else {
1352 seqbase_poin = POINTER_OFFSET(ed->seqbasep, -seqbase_offset);
1353
1354 seqbase_poin = BLO_read_get_new_data_address_no_us(reader, seqbase_poin, sizeof(Sequence));
1355
1356 if (seqbase_poin) {
1357 ed->seqbasep = (ListBase *)POINTER_OFFSET(seqbase_poin, seqbase_offset);
1358 }
1359 else {
1360 ed->seqbasep = &ed->seqbase;
1361 }
1362 }
1363
1364 /* Active channels root pointer. */
1365 if (ELEM(ed->displayed_channels, old_displayed_channels, nullptr)) {
1366 ed->displayed_channels = &ed->channels;
1367 }
1368 else {
1369 channels_poin = POINTER_OFFSET(ed->displayed_channels, -channels_offset);
1371 reader, channels_poin, sizeof(SeqTimelineChannel));
1372
1373 if (channels_poin) {
1374 ed->displayed_channels = (ListBase *)POINTER_OFFSET(channels_poin, channels_offset);
1375 }
1376 else {
1377 ed->displayed_channels = &ed->channels;
1378 }
1379 }
1380
1381 /* stack */
1382 BLO_read_struct_list(reader, MetaStack, &(ed->metastack));
1383
1384 LISTBASE_FOREACH (MetaStack *, ms, &ed->metastack) {
1385 BLO_read_struct(reader, Sequence, &ms->parseq);
1386
1387 if (ms->oldbasep == old_seqbasep) {
1388 ms->oldbasep = &ed->seqbase;
1389 }
1390 else {
1391 seqbase_poin = POINTER_OFFSET(ms->oldbasep, -seqbase_offset);
1393 reader, seqbase_poin, sizeof(Sequence));
1394 if (seqbase_poin) {
1395 ms->oldbasep = (ListBase *)POINTER_OFFSET(seqbase_poin, seqbase_offset);
1396 }
1397 else {
1398 ms->oldbasep = &ed->seqbase;
1399 }
1400 }
1401
1402 if (ELEM(ms->old_channels, old_displayed_channels, nullptr)) {
1403 ms->old_channels = &ed->channels;
1404 }
1405 else {
1406 channels_poin = POINTER_OFFSET(ms->old_channels, -channels_offset);
1408 reader, channels_poin, sizeof(SeqTimelineChannel));
1409
1410 if (channels_poin) {
1411 ms->old_channels = (ListBase *)POINTER_OFFSET(channels_poin, channels_offset);
1412 }
1413 else {
1414 ms->old_channels = &ed->channels;
1415 }
1416 }
1417 }
1418 }
1419 }
1420
1421#ifdef DURIAN_CAMERA_SWITCH
1422 /* Runtime */
1423 sce->r.mode &= ~R_NO_CAMERA_SWITCH;
1424#endif
1425
1426 BLO_read_struct_list(reader, TimeMarker, &(sce->markers));
1427 LISTBASE_FOREACH (TimeMarker *, marker, &sce->markers) {
1428 BLO_read_struct(reader, IDProperty, &marker->prop);
1429 IDP_BlendDataRead(reader, &marker->prop);
1430 }
1431
1433 BLO_read_struct_list(reader, SceneRenderLayer, &(sce->r.layers));
1434 BLO_read_struct_list(reader, SceneRenderView, &(sce->r.views));
1435
1436 LISTBASE_FOREACH (SceneRenderLayer *, srl, &sce->r.layers) {
1437 BLO_read_struct(reader, IDProperty, &srl->prop);
1438 IDP_BlendDataRead(reader, &srl->prop);
1439 BLO_read_struct_list(reader, FreestyleModuleConfig, &(srl->freestyleConfig.modules));
1440 BLO_read_struct_list(reader, FreestyleLineSet, &(srl->freestyleConfig.linesets));
1441 }
1442
1446
1448 RigidBodyWorld *rbw = sce->rigidbody_world;
1449 if (rbw) {
1451
1452 if (rbw->shared == nullptr) {
1453 /* Link deprecated caches if they exist, so we can use them for versioning.
1454 * We should only do this when rbw->shared == nullptr, because those pointers
1455 * are always set (for compatibility with older Blenders). We mustn't link
1456 * the same pointcache twice. */
1457 BKE_ptcache_blend_read_data(reader, &rbw->ptcaches, &rbw->pointcache, false);
1458
1459 /* make sure simulation starts from the beginning after loading file */
1460 if (rbw->pointcache) {
1461 rbw->ltime = float(rbw->pointcache->startframe);
1462 }
1463 }
1464 else {
1465 /* must nullify the reference to physics sim object, since it no-longer exist
1466 * (and will need to be recalculated)
1467 */
1468 rbw->shared->physics_world = nullptr;
1469
1470 /* link caches */
1471 BKE_ptcache_blend_read_data(reader, &rbw->shared->ptcaches, &rbw->shared->pointcache, false);
1472
1473 /* make sure simulation starts from the beginning after loading file */
1474 if (rbw->shared->pointcache) {
1475 rbw->ltime = float(rbw->shared->pointcache->startframe);
1476 }
1477 }
1478 rbw->objects = nullptr;
1479 rbw->numbodies = 0;
1480
1481 /* set effector weights */
1483 if (!rbw->effector_weights) {
1485 }
1486 }
1487
1488 BLO_read_struct(reader, PreviewImage, &sce->preview);
1489 BKE_previewimg_blend_read(reader, sce->preview);
1490
1492
1493 /* insert into global old-new map for reading without UI (link_global accesses it again) */
1494 BLO_read_glob_list(reader, &sce->view_layers);
1495 LISTBASE_FOREACH (ViewLayer *, view_layer, &sce->view_layers) {
1496 BKE_view_layer_blend_read_data(reader, view_layer);
1497 }
1498
1500
1502 IDP_BlendDataRead(reader, &sce->layer_properties);
1503}
1504
1505/* patch for missing scene IDs, can't be in do-versions */
1507{
1508 Scene *sce = reinterpret_cast<Scene *>(id);
1509
1510 LISTBASE_FOREACH_MUTABLE (Base *, base_legacy, &sce->base) {
1511 if (base_legacy->object == nullptr) {
1514 RPT_("LIB: object lost from scene: '%s'"),
1515 sce->id.name + 2);
1516 BLI_remlink(&sce->base, base_legacy);
1517 if (base_legacy == sce->basact) {
1518 sce->basact = nullptr;
1519 }
1520 MEM_freeN(base_legacy);
1521 }
1522 }
1523
1524 LISTBASE_FOREACH (ViewLayer *, view_layer, &sce->view_layers) {
1525 BKE_view_layer_blend_read_after_liblink(reader, id, view_layer);
1526 }
1527
1528#ifdef USE_SETSCENE_CHECK
1529 if (sce->set != nullptr) {
1531 }
1532#endif
1533 if (ID_IS_LINKED(sce)) {
1534 /* Linked scenes never have NLA tweak mode enabled. This works in concert with code in
1535 * BKE_animdata_blend_read_data, which also ensures that linked AnimData structs are never
1536 * linked in NLA tweak mode. */
1537 sce->flag &= ~SCE_NLA_EDIT_ON;
1538 }
1539}
1540
1541static void scene_undo_preserve(BlendLibReader *reader, ID *id_new, ID *id_old)
1542{
1543 Scene *scene_new = (Scene *)id_new;
1544 Scene *scene_old = (Scene *)id_old;
1545
1546 std::swap(scene_old->cursor, scene_new->cursor);
1547 if (scene_new->toolsettings != nullptr && scene_old->toolsettings != nullptr) {
1548 /* First try to restore ID pointers that can be and should be preserved (like brushes or
1549 * palettes), and counteract the swap of the whole ToolSettings structs below for the others
1550 * (like object ones). */
1552 nullptr, scene_new->toolsettings, true, reader, scene_old->toolsettings);
1553 std::swap(*scene_old->toolsettings, *scene_new->toolsettings);
1554 }
1555}
1556
1557static void scene_lib_override_apply_post(ID *id_dst, ID * /*id_src*/)
1558{
1559 Scene *scene = (Scene *)id_dst;
1560
1561 if (scene->rigidbody_world != nullptr) {
1562 PTCacheID pid;
1563 BKE_ptcache_id_from_rigidbody(&pid, nullptr, scene->rigidbody_world);
1564 LISTBASE_FOREACH (PointCache *, point_cache, pid.ptcaches) {
1565 point_cache->flag |= PTCACHE_FLAG_INFO_DIRTY;
1566 }
1567 }
1568}
1569
1571{
1572 IDTypeInfo info{};
1573 info.id_code = ID_SCE;
1574 info.id_filter = FILTER_ID_SCE;
1575 info.dependencies_id_types = (FILTER_ID_OB | FILTER_ID_WO | FILTER_ID_SCE | FILTER_ID_MC |
1579 info.main_listbase_index = INDEX_ID_SCE;
1580 info.struct_size = sizeof(Scene);
1581 info.name = "Scene";
1582 info.name_plural = "scenes";
1583 info.translation_context = BLT_I18NCONTEXT_ID_SCENE;
1584 info.flags = IDTYPE_FLAGS_NEVER_UNUSED;
1585 info.asset_type_info = nullptr;
1586
1587 info.init_data = scene_init_data;
1588 info.copy_data = scene_copy_data;
1589 info.free_data = scene_free_data;
1590 /* For now default `BKE_lib_id_make_local_generic()` should work, may need more work though to
1591 * support all possible corner cases. */
1592 info.make_local = nullptr;
1593 info.foreach_id = scene_foreach_id;
1594 info.foreach_cache = scene_foreach_cache;
1595 info.foreach_path = scene_foreach_path;
1596 info.owner_pointer_get = nullptr;
1597
1598 info.blend_write = scene_blend_write;
1599 info.blend_read_data = scene_blend_read_data;
1600 info.blend_read_after_liblink = scene_blend_read_after_liblink;
1601
1602 info.blend_read_undo_preserve = scene_undo_preserve;
1603
1604 info.lib_override_apply_post = scene_lib_override_apply_post;
1605 return info;
1606}
1608
1609const char *RE_engine_id_BLENDER_EEVEE = "BLENDER_EEVEE";
1610const char *RE_engine_id_BLENDER_EEVEE_NEXT = "BLENDER_EEVEE_NEXT";
1611const char *RE_engine_id_BLENDER_WORKBENCH = "BLENDER_WORKBENCH";
1612const char *RE_engine_id_CYCLES = "CYCLES";
1613
1615{
1616 AnimData *adt = BKE_animdata_from_id(&sce->id);
1617
1618 if (adt && adt->action) {
1619 LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, &adt->action->curves) {
1620 if ((fcu->rna_path) && strstr(fcu->rna_path, "sequences_all")) {
1622 BKE_fcurve_free(fcu);
1623 }
1624 }
1625 }
1626}
1627
1629{
1630 if (toolsettings == nullptr) {
1631 return nullptr;
1632 }
1633 ToolSettings *ts = static_cast<ToolSettings *>(MEM_dupallocN(toolsettings));
1634 if (ts->vpaint) {
1635 ts->vpaint = static_cast<VPaint *>(MEM_dupallocN(ts->vpaint));
1636 BKE_paint_copy(&ts->vpaint->paint, &ts->vpaint->paint, flag);
1637 }
1638 if (ts->wpaint) {
1639 ts->wpaint = static_cast<VPaint *>(MEM_dupallocN(ts->wpaint));
1640 BKE_paint_copy(&ts->wpaint->paint, &ts->wpaint->paint, flag);
1641 }
1642 if (ts->sculpt) {
1643 ts->sculpt = static_cast<Sculpt *>(MEM_dupallocN(ts->sculpt));
1644 BKE_paint_copy(&ts->sculpt->paint, &ts->sculpt->paint, flag);
1645
1650 }
1651
1656 }
1657 }
1658 if (ts->uvsculpt.strength_curve) {
1661 }
1662 if (ts->gp_paint) {
1663 ts->gp_paint = static_cast<GpPaint *>(MEM_dupallocN(ts->gp_paint));
1665 }
1666 if (ts->gp_vertexpaint) {
1667 ts->gp_vertexpaint = static_cast<GpVertexPaint *>(MEM_dupallocN(ts->gp_vertexpaint));
1669 }
1670 if (ts->gp_sculptpaint) {
1671 ts->gp_sculptpaint = static_cast<GpSculptPaint *>(MEM_dupallocN(ts->gp_sculptpaint));
1673 }
1674 if (ts->gp_weightpaint) {
1675 ts->gp_weightpaint = static_cast<GpWeightPaint *>(MEM_dupallocN(ts->gp_weightpaint));
1677 }
1678 if (ts->curves_sculpt) {
1679 ts->curves_sculpt = static_cast<CurvesSculpt *>(MEM_dupallocN(ts->curves_sculpt));
1681 }
1682
1684 ts->particle.paintcursor = nullptr;
1685 ts->particle.scene = nullptr;
1686 ts->particle.object = nullptr;
1687
1688 /* duplicate Grease Pencil interpolation curve */
1690 /* Duplicate Grease Pencil multi-frame falloff. */
1693
1695
1697 return ts;
1698}
1699
1701{
1702 if (toolsettings == nullptr) {
1703 return;
1704 }
1705 if (toolsettings->vpaint) {
1706 BKE_paint_free(&toolsettings->vpaint->paint);
1707 MEM_freeN(toolsettings->vpaint);
1708 }
1709 if (toolsettings->wpaint) {
1710 BKE_paint_free(&toolsettings->wpaint->paint);
1711 MEM_freeN(toolsettings->wpaint);
1712 }
1713 if (toolsettings->sculpt) {
1714 if (toolsettings->sculpt->automasking_cavity_curve) {
1716 }
1717 if (toolsettings->sculpt->automasking_cavity_curve_op) {
1719 }
1720
1721 BKE_paint_free(&toolsettings->sculpt->paint);
1722 MEM_freeN(toolsettings->sculpt);
1723 }
1724 if (toolsettings->uvsculpt.strength_curve) {
1726 }
1727 if (toolsettings->gp_paint) {
1728 BKE_paint_free(&toolsettings->gp_paint->paint);
1729 MEM_freeN(toolsettings->gp_paint);
1730 }
1731 if (toolsettings->gp_vertexpaint) {
1732 BKE_paint_free(&toolsettings->gp_vertexpaint->paint);
1733 MEM_freeN(toolsettings->gp_vertexpaint);
1734 }
1735 if (toolsettings->gp_sculptpaint) {
1736 BKE_paint_free(&toolsettings->gp_sculptpaint->paint);
1737 MEM_freeN(toolsettings->gp_sculptpaint);
1738 }
1739 if (toolsettings->gp_weightpaint) {
1740 BKE_paint_free(&toolsettings->gp_weightpaint->paint);
1741 MEM_freeN(toolsettings->gp_weightpaint);
1742 }
1743 if (toolsettings->curves_sculpt) {
1744 BKE_paint_free(&toolsettings->curves_sculpt->paint);
1745 MEM_freeN(toolsettings->curves_sculpt);
1746 }
1747 BKE_paint_free(&toolsettings->imapaint.paint);
1748
1749 /* free Grease Pencil interpolation curve */
1750 if (toolsettings->gp_interpolate.custom_ipo) {
1752 }
1753 /* free Grease Pencil multi-frame falloff curve */
1754 if (toolsettings->gp_sculpt.cur_falloff) {
1756 }
1757 if (toolsettings->gp_sculpt.cur_primitive) {
1759 }
1760
1761 if (toolsettings->custom_bevel_profile_preset) {
1763 }
1764
1765 if (toolsettings->sequencer_tool_settings) {
1767 }
1768
1769 MEM_freeN(toolsettings);
1770}
1771
1772void BKE_scene_copy_data_eevee(Scene *sce_dst, const Scene *sce_src)
1773{
1774 /* Copy eevee data between scenes. */
1775 sce_dst->eevee = sce_src->eevee;
1776}
1777
1779{
1780 Scene *sce_copy;
1781
1782 /* TODO: this should/could most likely be replaced by call to more generic code at some point...
1783 * But for now, let's keep it well isolated here. */
1784 if (type == SCE_COPY_EMPTY) {
1785 ListBase rv;
1786
1787 sce_copy = BKE_scene_add(bmain, sce->id.name + 2);
1788
1789 rv = sce_copy->r.views;
1791 sce_copy->r = sce->r;
1792 sce_copy->r.views = rv;
1793 sce_copy->unit = sce->unit;
1794 sce_copy->physics_settings = sce->physics_settings;
1795 sce_copy->audio = sce->audio;
1796 BKE_scene_copy_data_eevee(sce_copy, sce);
1797
1798 if (sce->id.properties) {
1799 sce_copy->id.properties = IDP_CopyProperty(sce->id.properties);
1800 }
1801
1802 BKE_sound_destroy_scene(sce_copy);
1803
1804 /* copy color management settings */
1809
1810 BKE_image_format_copy(&sce_copy->r.im_format, &sce->r.im_format);
1812
1814
1815 /* viewport display settings */
1816 sce_copy->display = sce->display;
1817
1818 /* tool settings */
1820 sce_copy->toolsettings = BKE_toolsettings_copy(sce->toolsettings, 0);
1821
1823
1824 /* grease pencil */
1825 sce_copy->gpd = nullptr;
1826
1827 sce_copy->preview = nullptr;
1828
1829 return sce_copy;
1830 }
1831
1832 eDupli_ID_Flags duplicate_flags = (eDupli_ID_Flags)(U.dupflag | USER_DUP_OBJECT);
1833
1834 sce_copy = (Scene *)BKE_id_copy(bmain, (ID *)sce);
1835 id_us_min(&sce_copy->id);
1836 id_us_ensure_real(&sce_copy->id);
1837
1838 BKE_animdata_duplicate_id_action(bmain, &sce_copy->id, duplicate_flags);
1839
1840 /* Extra actions, most notably SCE_FULL_COPY also duplicates several 'children' datablocks. */
1841
1842 if (type == SCE_COPY_FULL) {
1843 /* Scene duplication is always root of duplication currently. */
1844 const bool is_subprocess = false;
1845 const bool is_root_id = true;
1846 const int copy_flags = LIB_ID_COPY_DEFAULT;
1847
1848 if (!is_subprocess) {
1850 }
1851 if (is_root_id) {
1852 /* In case root duplicated ID is linked, assume we want to get a local copy of it and
1853 * duplicate all expected linked data. */
1854 if (ID_IS_LINKED(sce)) {
1855 duplicate_flags = (eDupli_ID_Flags)(duplicate_flags | USER_DUP_LINKED_ID);
1856 }
1857 }
1858
1859 /* Copy Freestyle LineStyle datablocks. */
1860 LISTBASE_FOREACH (ViewLayer *, view_layer_dst, &sce_copy->view_layers) {
1861 LISTBASE_FOREACH (FreestyleLineSet *, lineset, &view_layer_dst->freestyle_config.linesets) {
1862 BKE_id_copy_for_duplicate(bmain, (ID *)lineset->linestyle, duplicate_flags, copy_flags);
1863 }
1864 }
1865
1866 /* Full copy of world (included animations) */
1867 BKE_id_copy_for_duplicate(bmain, (ID *)sce->world, duplicate_flags, copy_flags);
1868
1869 /* Full copy of GreasePencil. */
1870 BKE_id_copy_for_duplicate(bmain, (ID *)sce->gpd, duplicate_flags, copy_flags);
1871
1872 /* Deep-duplicate collections and objects (using preferences' settings for which sub-data to
1873 * duplicate along the object itself). */
1875 nullptr,
1876 nullptr,
1877 sce_copy->master_collection,
1878 duplicate_flags,
1880
1881 /* Rigid body world collections may not be instantiated as scene's collections, ensure they
1882 * also get properly duplicated. */
1883 if (sce_copy->rigidbody_world != nullptr) {
1884 if (sce_copy->rigidbody_world->group != nullptr) {
1886 nullptr,
1887 nullptr,
1888 sce_copy->rigidbody_world->group,
1889 duplicate_flags,
1891 }
1892 if (sce_copy->rigidbody_world->constraints != nullptr) {
1894 nullptr,
1895 nullptr,
1896 sce_copy->rigidbody_world->constraints,
1897 duplicate_flags,
1899 }
1900 }
1901
1902 if (!is_subprocess) {
1903 /* This code will follow into all ID links using an ID tagged with ID_TAG_NEW. */
1904 BKE_libblock_relink_to_newid(bmain, &sce_copy->id, 0);
1905
1906#ifndef NDEBUG
1907 /* Call to `BKE_libblock_relink_to_newid` above is supposed to have cleared all those
1908 * flags. */
1909 ID *id_iter;
1910 FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
1911 BLI_assert((id_iter->tag & ID_TAG_NEW) == 0);
1912 }
1914#endif
1915
1916 /* Cleanup. */
1918
1920 }
1921 }
1922 else {
1923 /* Remove sequencer if not full copy */
1924 /* XXX Why in Hell? :/ */
1925 remove_sequencer_fcurves(sce_copy);
1926 SEQ_editing_free(sce_copy, true);
1927 }
1928
1929 return sce_copy;
1930}
1931
1933{
1934 if (sce->rigidbody_world) {
1936 }
1937}
1938
1939bool BKE_scene_can_be_removed(const Main *bmain, const Scene *scene)
1940{
1941 /* Linked scenes can always be removed. */
1942 if (ID_IS_LINKED(scene)) {
1943 return true;
1944 }
1945 /* Local scenes can only be removed, when there is at least one local scene left. */
1946 LISTBASE_FOREACH (Scene *, other_scene, &bmain->scenes) {
1947 if (other_scene != scene && !ID_IS_LINKED(other_scene)) {
1948 return true;
1949 }
1950 }
1951 return false;
1952}
1953
1954Scene *BKE_scene_add(Main *bmain, const char *name)
1955{
1956 Scene *sce = static_cast<Scene *>(BKE_id_new(bmain, ID_SCE, name));
1957 id_us_min(&sce->id);
1958 id_us_ensure_real(&sce->id);
1959
1960 return sce;
1961}
1962
1964{
1965 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
1966 BKE_view_layer_synced_ensure(scene, view_layer);
1967 if (BLI_findptr(BKE_view_layer_object_bases_get(view_layer), ob, offsetof(Base, object))) {
1968 return true;
1969 }
1970 }
1971 return false;
1972}
1973
1974Object *BKE_scene_object_find_by_name(const Scene *scene, const char *name)
1975{
1976 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
1977 BKE_view_layer_synced_ensure(scene, view_layer);
1979 if (STREQ(base->object->id.name + 2, name)) {
1980 return base->object;
1981 }
1982 }
1983 }
1984 return nullptr;
1985}
1986
1988{
1989 /* check for cyclic sets, for reading old files but also for definite security (py?) */
1990 BKE_scene_validate_setscene(bmain, scene);
1991
1992 /* Deselect objects (for data select). */
1993 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
1994 ob->flag &= ~SELECT;
1995 }
1996
1997 /* copy layers and flags from bases to objects */
1998 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
1999 BKE_view_layer_synced_ensure(scene, view_layer);
2001 /* collection patch... */
2003 }
2004 }
2005 /* No full animation update, this to enable render code to work
2006 * (render code calls own animation updates). */
2007}
2008
2009Scene *BKE_scene_set_name(Main *bmain, const char *name)
2010{
2011 Scene *sce = (Scene *)BKE_libblock_find_name(bmain, ID_SCE, name);
2012 if (sce) {
2013 BKE_scene_set_background(bmain, sce);
2014 printf("Scene switch for render: '%s' in file: '%s'\n", name, BKE_main_blendfile_path(bmain));
2015 return sce;
2016 }
2017
2018 printf("Can't find scene: '%s' in file: '%s'\n", name, BKE_main_blendfile_path(bmain));
2019 return nullptr;
2020}
2021
2023 Depsgraph *depsgraph, SceneBaseIter *iter, Scene **scene, int val, Base **base, Object **ob)
2024{
2025 bool run_again = true;
2026
2027 /* init */
2028 if (val == 0) {
2029 iter->phase = F_START;
2030 iter->dupob = nullptr;
2031 iter->duplilist = nullptr;
2032 iter->dupli_refob = nullptr;
2033 }
2034 else {
2035 /* run_again is set when a duplilist has been ended */
2036 while (run_again) {
2037 run_again = false;
2038
2039 /* the first base */
2040 if (iter->phase == F_START) {
2043 BKE_view_layer_synced_ensure(*scene, view_layer);
2044 *base = static_cast<Base *>(BKE_view_layer_object_bases_get(view_layer)->first);
2045 if (*base) {
2046 *ob = (*base)->object;
2047 iter->phase = F_SCENE;
2048 }
2049 else {
2050 /* exception: empty scene layer */
2051 while ((*scene)->set) {
2052 (*scene) = (*scene)->set;
2053 ViewLayer *view_layer_set = BKE_view_layer_default_render(*scene);
2054 BKE_view_layer_synced_ensure(*scene, view_layer_set);
2055 ListBase *object_bases = BKE_view_layer_object_bases_get(view_layer_set);
2056 if (object_bases->first) {
2057 *base = static_cast<Base *>(object_bases->first);
2058 *ob = (*base)->object;
2059 iter->phase = F_SCENE;
2060 break;
2061 }
2062 }
2063 }
2064 }
2065 else {
2066 if (*base && iter->phase != F_DUPLI) {
2067 *base = (*base)->next;
2068 if (*base) {
2069 *ob = (*base)->object;
2070 }
2071 else {
2072 if (iter->phase == F_SCENE) {
2073 /* (*scene) is finished, now do the set */
2074 while ((*scene)->set) {
2075 (*scene) = (*scene)->set;
2076 ViewLayer *view_layer_set = BKE_view_layer_default_render(*scene);
2077 BKE_view_layer_synced_ensure(*scene, view_layer_set);
2078 ListBase *object_bases = BKE_view_layer_object_bases_get(view_layer_set);
2079 if (object_bases->first) {
2080 *base = static_cast<Base *>(object_bases->first);
2081 *ob = (*base)->object;
2082 break;
2083 }
2084 }
2085 }
2086 }
2087 }
2088 }
2089
2090 if (*base == nullptr) {
2091 iter->phase = F_START;
2092 }
2093 else {
2094 if (iter->phase != F_DUPLI) {
2095 if (depsgraph && (*base)->object->transflag & OB_DUPLI) {
2096 /* Collections cannot be duplicated for meta-balls yet,
2097 * this enters eternal loop because of
2098 * makeDispListMBall getting called inside of collection_duplilist */
2099 if ((*base)->object->instance_collection == nullptr) {
2100 iter->duplilist = object_duplilist(depsgraph, (*scene), (*base)->object);
2101
2102 iter->dupob = static_cast<DupliObject *>(iter->duplilist->first);
2103
2104 if (!iter->dupob) {
2106 iter->duplilist = nullptr;
2107 }
2108 iter->dupli_refob = nullptr;
2109 }
2110 }
2111 }
2112 /* handle dupli's */
2113 if (iter->dupob) {
2114 (*base)->flag_legacy |= OB_FROMDUPLI;
2115 *ob = iter->dupob->ob;
2116 iter->phase = F_DUPLI;
2117
2118 if (iter->dupli_refob != *ob) {
2119 if (iter->dupli_refob) {
2120 /* Restore previous object's real matrix. */
2121 copy_m4_m4(iter->dupli_refob->runtime->object_to_world.ptr(), iter->omat);
2122 }
2123 /* Backup new object's real matrix. */
2124 iter->dupli_refob = *ob;
2125 copy_m4_m4(iter->omat, iter->dupli_refob->object_to_world().ptr());
2126 }
2127 copy_m4_m4((*ob)->runtime->object_to_world.ptr(), iter->dupob->mat);
2128
2129 iter->dupob = iter->dupob->next;
2130 }
2131 else if (iter->phase == F_DUPLI) {
2132 iter->phase = F_SCENE;
2133 (*base)->flag_legacy &= ~OB_FROMDUPLI;
2134
2135 if (iter->dupli_refob) {
2136 /* Restore last object's real matrix. */
2137 copy_m4_m4(iter->dupli_refob->runtime->object_to_world.ptr(), iter->omat);
2138 iter->dupli_refob = nullptr;
2139 }
2140
2142 iter->duplilist = nullptr;
2143 run_again = true;
2144 }
2145 }
2146 }
2147 }
2148
2149 return iter->phase;
2150}
2151
2152bool BKE_scene_has_view_layer(const Scene *scene, const ViewLayer *layer)
2153{
2154 return BLI_findindex(&scene->view_layers, layer) != -1;
2155}
2156
2157Scene *BKE_scene_find_from_collection(const Main *bmain, const Collection *collection)
2158{
2159 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
2160 LISTBASE_FOREACH (ViewLayer *, layer, &scene->view_layers) {
2161 if (BKE_view_layer_has_collection(layer, collection)) {
2162 return scene;
2163 }
2164 }
2165 }
2166
2167 return nullptr;
2168}
2169
2170#ifdef DURIAN_CAMERA_SWITCH
2171Object *BKE_scene_camera_switch_find(Scene *scene)
2172{
2173 if (scene->r.mode & R_NO_CAMERA_SWITCH) {
2174 return nullptr;
2175 }
2176
2177 const int ctime = int(BKE_scene_ctime_get(scene));
2178 int frame = -(MAXFRAME + 1);
2179 int min_frame = MAXFRAME + 1;
2180 Object *camera = nullptr;
2181 Object *first_camera = nullptr;
2182
2183 LISTBASE_FOREACH (TimeMarker *, m, &scene->markers) {
2184 if (m->camera && (m->camera->visibility_flag & OB_HIDE_RENDER) == 0) {
2185 if ((m->frame <= ctime) && (m->frame > frame)) {
2186 camera = m->camera;
2187 frame = m->frame;
2188
2189 if (frame == ctime) {
2190 break;
2191 }
2192 }
2193
2194 if (m->frame < min_frame) {
2195 first_camera = m->camera;
2196 min_frame = m->frame;
2197 }
2198 }
2199 }
2200
2201 if (camera == nullptr) {
2202 /* If there's no marker to the left of current frame,
2203 * use camera from left-most marker to solve all sort
2204 * of Schrodinger uncertainties.
2205 */
2206 return first_camera;
2207 }
2208
2209 return camera;
2210}
2211#endif
2212
2214{
2215#ifdef DURIAN_CAMERA_SWITCH
2216 Object *camera = BKE_scene_camera_switch_find(scene);
2217 if (camera && (camera != scene->camera)) {
2218 scene->camera = camera;
2220 return true;
2221 }
2222#else
2223 (void)scene;
2224#endif
2225 return false;
2226}
2227
2228const char *BKE_scene_find_marker_name(const Scene *scene, int frame)
2229{
2230 const ListBase *markers = &scene->markers;
2231 const TimeMarker *m1, *m2;
2232
2233 /* search through markers for match */
2234 for (m1 = static_cast<const TimeMarker *>(markers->first),
2235 m2 = static_cast<const TimeMarker *>(markers->last);
2236 m1 && m2;
2237 m1 = m1->next, m2 = m2->prev)
2238 {
2239 if (m1->frame == frame) {
2240 return m1->name;
2241 }
2242
2243 if (m1 == m2) {
2244 break;
2245 }
2246
2247 if (m2->frame == frame) {
2248 return m2->name;
2249 }
2250 }
2251
2252 return nullptr;
2253}
2254
2255const char *BKE_scene_find_last_marker_name(const Scene *scene, int frame)
2256{
2257 const TimeMarker *best_marker = nullptr;
2258 int best_frame = -MAXFRAME * 2;
2259 LISTBASE_FOREACH (const TimeMarker *, marker, &scene->markers) {
2260 if (marker->frame == frame) {
2261 return marker->name;
2262 }
2263
2264 if (marker->frame > best_frame && marker->frame < frame) {
2265 best_marker = marker;
2266 best_frame = marker->frame;
2267 }
2268 }
2269
2270 return best_marker ? best_marker->name : nullptr;
2271}
2272
2273int BKE_scene_frame_snap_by_seconds(Scene *scene, double interval_in_seconds, int frame)
2274{
2275 const int fps = round_db_to_int(FPS * interval_in_seconds);
2276 const int second_prev = frame - mod_i(frame, fps);
2277 const int second_next = second_prev + fps;
2278 const int delta_prev = frame - second_prev;
2279 const int delta_next = second_next - frame;
2280 return (delta_prev < delta_next) ? second_prev : second_next;
2281}
2282
2283void BKE_scene_remove_rigidbody_object(Main *bmain, Scene *scene, Object *ob, const bool free_us)
2284{
2285 /* remove rigid body constraint from world before removing object */
2286 if (ob->rigidbody_constraint) {
2287 BKE_rigidbody_remove_constraint(bmain, scene, ob, free_us);
2288 }
2289 /* remove rigid body object from world before removing object */
2290 if (ob->rigidbody_object) {
2291 BKE_rigidbody_remove_object(bmain, scene, ob, free_us);
2292 }
2293}
2294
2296{
2297 Scene *sce_iter;
2298 int a, totscene;
2299
2300 if (sce->set == nullptr) {
2301 return true;
2302 }
2303 totscene = BLI_listbase_count(&bmain->scenes);
2304
2305 for (a = 0, sce_iter = sce; sce_iter->set; sce_iter = sce_iter->set, a++) {
2306 /* more iterations than scenes means we have a cycle */
2307 if (a > totscene) {
2308 /* The tested scene gets zeroed, that's typically current scene. */
2309 sce->set = nullptr;
2310 return false;
2311 }
2312 }
2313
2314 return true;
2315}
2316
2317float BKE_scene_ctime_get(const Scene *scene)
2318{
2319 return BKE_scene_frame_to_ctime(scene, scene->r.cfra);
2320}
2321
2322float BKE_scene_frame_to_ctime(const Scene *scene, const int frame)
2323{
2324 float ctime = frame;
2325 ctime += scene->r.subframe;
2326 ctime *= scene->r.framelen;
2327
2328 return ctime;
2329}
2330
2331float BKE_scene_frame_get(const Scene *scene)
2332{
2333 return scene->r.cfra + scene->r.subframe;
2334}
2335
2336void BKE_scene_frame_set(Scene *scene, float frame)
2337{
2338 double intpart;
2339 scene->r.subframe = modf(double(frame), &intpart);
2340 scene->r.cfra = int(intpart);
2341}
2342
2343/* -------------------------------------------------------------------- */
2348{
2349 if ((scene->orientation_slots[slot_index].flag & SELECT) == 0) {
2350 slot_index = SCE_ORIENT_DEFAULT;
2351 }
2352 return &scene->orientation_slots[slot_index];
2353}
2354
2356{
2359 int slot_index = SCE_ORIENT_DEFAULT;
2361 slot_index = SCE_ORIENT_TRANSLATE;
2362 }
2364 slot_index = SCE_ORIENT_ROTATE;
2365 }
2366 else if (flag & V3D_GIZMO_SHOW_OBJECT_SCALE) {
2367 slot_index = SCE_ORIENT_SCALE;
2368 }
2369 return BKE_scene_orientation_slot_get(scene, slot_index);
2370}
2371
2373{
2374 const bool is_custom = orientation >= V3D_ORIENT_CUSTOM;
2375 orient_slot->type = is_custom ? V3D_ORIENT_CUSTOM : orientation;
2376 orient_slot->index_custom = is_custom ? (orientation - V3D_ORIENT_CUSTOM) : -1;
2377}
2378
2380{
2381 return (orient_slot->type == V3D_ORIENT_CUSTOM) ?
2382 (orient_slot->type + orient_slot->index_custom) :
2383 orient_slot->type;
2384}
2385
2386int BKE_scene_orientation_get_index(Scene *scene, int slot_index)
2387{
2388 TransformOrientationSlot *orient_slot = BKE_scene_orientation_slot_get(scene, slot_index);
2389 return BKE_scene_orientation_slot_get_index(orient_slot);
2390}
2391
2397
2401{
2402 wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
2403 LISTBASE_FOREACH (const wmWindow *, window, &wm->windows) {
2404 const bScreen *screen = BKE_workspace_active_screen_get(window->workspace_hook);
2405 Scene *scene = window->scene;
2406 RenderEngineType *type = RE_engines_find(scene->r.engine);
2407
2408 if (type->draw_engine || !type->render) {
2409 continue;
2410 }
2411
2412 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
2413 View3D *v3d = static_cast<View3D *>(area->spacedata.first);
2414 if (area->spacetype != SPACE_VIEW3D) {
2415 continue;
2416 }
2417 if (v3d->shading.type == OB_RENDER) {
2418 return true;
2419 }
2420 }
2421 }
2422 return false;
2423}
2424
2425/* TODO(@ideasman42): shouldn't we be able to use 'DEG_get_view_layer' here?
2426 * Currently this is nullptr on load, so don't. */
2428 const Scene *scene,
2429 ViewLayer *view_layer)
2430{
2431 /* This is needed to prepare mesh to be used by the render
2432 * engine from the viewport rendering. We do loading here
2433 * so all the objects which shares the same mesh datablock
2434 * are nicely tagged for update and updated.
2435 *
2436 * This makes it so viewport render engine doesn't need to
2437 * call loading of the edit data for the mesh objects.
2438 */
2439 BKE_view_layer_synced_ensure(scene, view_layer);
2440 Object *obedit = BKE_view_layer_edit_object_get(view_layer);
2441 if (obedit) {
2442 Mesh *mesh = static_cast<Mesh *>(obedit->data);
2443 if ((obedit->type == OB_MESH) &&
2444 ((obedit->id.recalc & ID_RECALC_ALL) || (mesh->id.recalc & ID_RECALC_ALL)))
2445 {
2447 BMesh *bm = mesh->runtime->edit_mesh->bm;
2449 params.calc_object_remap = true;
2450 params.update_shapekey_indices = true;
2451 BM_mesh_bm_to_me(bmain, bm, mesh, &params);
2452 DEG_id_tag_update(&mesh->id, 0);
2453 }
2454 }
2455 }
2456}
2457
2458void BKE_scene_update_sound(Depsgraph *depsgraph, Main *bmain)
2459{
2461 const int recalc = scene->id.recalc;
2463 if (recalc & ID_RECALC_FRAME_CHANGE) {
2464 BKE_sound_seek_scene(bmain, scene);
2465 }
2466 if (recalc & ID_RECALC_AUDIO_FPS) {
2467 BKE_sound_update_fps(bmain, scene);
2468 }
2469 if (recalc & ID_RECALC_AUDIO_VOLUME) {
2470 BKE_sound_set_scene_volume(scene, scene->audio.volume);
2471 }
2472 if (recalc & ID_RECALC_AUDIO_MUTE) {
2473 const bool is_mute = (DEG_get_mode(depsgraph) == DAG_EVAL_VIEWPORT) &&
2474 (scene->audio.flag & AUDIO_MUTE);
2475 BKE_sound_mute_scene(scene, is_mute);
2476 }
2477 if (recalc & ID_RECALC_AUDIO_LISTENER) {
2479 }
2481}
2482
2483void BKE_scene_update_tag_audio_volume(Depsgraph * /*depsgraph*/, Scene *scene)
2484{
2485 BLI_assert(DEG_is_evaluated_id(&scene->id));
2486 /* The volume is actually updated in BKE_scene_update_sound(), from either
2487 * scene_graph_update_tagged() or from BKE_scene_graph_update_for_newframe(). */
2488 scene->id.recalc |= ID_RECALC_AUDIO_VOLUME;
2489}
2490
2491/* TODO(sergey): This actually should become view_layer_graph or so.
2492 * Same applies to update_for_newframe.
2493 *
2494 * If only_if_tagged is truth then the function will do nothing if the dependency graph is up
2495 * to date already.
2496 */
2497static void scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain, bool only_if_tagged)
2498{
2499 if (only_if_tagged && DEG_is_fully_evaluated(depsgraph)) {
2500 return;
2501 }
2502
2505 bool used_multiple_passes = false;
2506
2507 bool run_callbacks = DEG_id_type_any_updated(depsgraph);
2508 if (run_callbacks) {
2510 }
2511
2512 for (int pass = 0; pass < 2; pass++) {
2513 /* (Re-)build dependency graph if needed. */
2515 /* Uncomment this to check if graph was properly tagged for update. */
2516 // DEG_debug_graph_relations_validate(depsgraph, bmain, scene);
2517 /* Flush editing data if needed. */
2518 prepare_mesh_for_viewport_render(bmain, scene, view_layer);
2519 /* Update all objects: drivers, matrices, etc. flags set
2520 * by depsgraph or manual, no layer check here, gets correct flushed. */
2522 /* Update sound system. */
2524 /* Notify python about depsgraph update. */
2525 if (run_callbacks) {
2527 bmain, &scene->id, depsgraph, BKE_CB_EVT_DEPSGRAPH_UPDATE_POST);
2528
2529 /* It is possible that the custom callback modified scene and removed some IDs from the main
2530 * database. In this case DEG_editors_update() will crash because it iterates over all IDs
2531 * which depsgraph was built for.
2532 *
2533 * The solution is to update relations prior to this call, avoiding access to freed IDs.
2534 * Should be safe because relations update is supposed to preserve flags of all IDs which are
2535 * still a part of the dependency graph. If an ID is kicked out of the dependency graph it
2536 * should also be fine because when/if it's added to another dependency graph it will need to
2537 * be tagged for an update anyway.
2538 *
2539 * If there are no relations changed by the callback this call will do nothing. */
2541 }
2542
2543 /* If user callback did not tag anything for update we can skip second iteration.
2544 * Otherwise we update scene once again, but without running callbacks to bring
2545 * scene to a fully evaluated state with user modifications taken into account. */
2547 break;
2548 }
2549
2550 /* Clear recalc flags for second pass, but back them up for editors update. */
2551 const bool backup = true;
2553 used_multiple_passes = true;
2554 run_callbacks = false;
2555 }
2556
2557 /* Inform editors about changes, using recalc flags from both passes. */
2558 if (used_multiple_passes) {
2560 }
2561 const bool is_time_update = false;
2562 DEG_editors_update(depsgraph, is_time_update);
2563
2564 const bool backup = false;
2566}
2567
2569{
2570 scene_graph_update_tagged(depsgraph, bmain, false);
2571}
2572
2574{
2576}
2577
2578void BKE_scene_graph_update_for_newframe_ex(Depsgraph *depsgraph, const bool clear_recalc)
2579{
2581 Main *bmain = DEG_get_bmain(depsgraph);
2582 bool used_multiple_passes = false;
2583
2584 /* Keep this first. */
2586
2587 for (int pass = 0; pass < 2; pass++) {
2588 /* Update animated image textures for particles, modifiers, gpu, etc,
2589 * call this at the start so modifiers with textures don't lag 1 frame.
2590 */
2591 BKE_image_editors_update_frame(bmain, scene->r.cfra);
2593 /* Update all objects: drivers, matrices, etc. flags set
2594 * by depsgraph or manual, no layer check here, gets correct flushed.
2595 *
2596 * NOTE: Only update for new frame on first iteration. Second iteration is for ensuring user
2597 * edits from callback are properly taken into account. Doing a time update on those would
2598 * lose any possible unkeyed changes made by the handler. */
2599 if (pass == 0) {
2600 const float frame = BKE_scene_frame_get(scene);
2602 }
2603 else {
2605 }
2606 /* Update sound system animation. */
2608
2609 /* Notify editors and python about recalc. */
2610 if (pass == 0) {
2612
2613 /* NOTE: Similar to this case in scene_graph_update_tagged(). Need to ensure that
2614 * DEG_editors_update() doesn't access freed memory of possibly removed ID. */
2616 }
2617
2618 /* If user callback did not tag anything for update we can skip second iteration.
2619 * Otherwise we update scene once again, but without running callbacks to bring
2620 * scene to a fully evaluated state with user modifications taken into account. */
2622 break;
2623 }
2624
2625 /* Clear recalc flags for second pass, but back them up for editors update. */
2626 const bool backup = true;
2628 used_multiple_passes = true;
2629 }
2630
2631 /* Inform editors about changes, using recalc flags from both passes. */
2632 if (used_multiple_passes) {
2634 }
2635
2636 const bool is_time_update = true;
2637 DEG_editors_update(depsgraph, is_time_update);
2638
2639 /* Clear recalc flags, can be skipped for e.g. renderers that will read these
2640 * and clear the flags later. */
2641 if (clear_recalc) {
2642 const bool backup = false;
2644 }
2645}
2646
2651
2653{
2654 Depsgraph *depsgraph = BKE_scene_ensure_depsgraph(bmain, scene, view_layer);
2657}
2658
2660{
2661 if (!name) {
2662 name = DATA_("RenderView");
2663 }
2664
2665 SceneRenderView *srv = MEM_cnew<SceneRenderView>(__func__);
2666 STRNCPY(srv->name, name);
2667 BLI_uniquename(&sce->r.views,
2668 srv,
2669 DATA_("RenderView"),
2670 '.',
2672 sizeof(srv->name));
2673 BLI_addtail(&sce->r.views, srv);
2674
2675 return srv;
2676}
2677
2679{
2680 const int act = BLI_findindex(&scene->r.views, srv);
2681
2682 if (act == -1) {
2683 return false;
2684 }
2685 if (scene->r.views.first == scene->r.views.last) {
2686 /* ensure 1 view is kept */
2687 return false;
2688 }
2689
2690 BLI_remlink(&scene->r.views, srv);
2691 MEM_freeN(srv);
2692
2693 scene->r.actview = 0;
2694
2695 return true;
2696}
2697
2698/* render simplification */
2699
2700int get_render_subsurf_level(const RenderData *r, int lvl, bool for_render)
2701{
2702 if (r->mode & R_SIMPLIFY) {
2703 if (for_render) {
2704 return min_ii(r->simplify_subsurf_render, lvl);
2705 }
2706
2707 return min_ii(r->simplify_subsurf, lvl);
2708 }
2709
2710 return lvl;
2711}
2712
2713int get_render_child_particle_number(const RenderData *r, int child_num, bool for_render)
2714{
2715 if (r->mode & R_SIMPLIFY) {
2716 if (for_render) {
2717 return int(r->simplify_particles_render * child_num);
2718 }
2719
2720 return int(r->simplify_particles * child_num);
2721 }
2722
2723 return child_num;
2724}
2725
2726Base *_setlooper_base_step(Scene **sce_iter, ViewLayer *view_layer, Base *base)
2727{
2728 if (base && base->next) {
2729 /* Common case, step to the next. */
2730 return base->next;
2731 }
2732 if ((base == nullptr) && (view_layer != nullptr)) {
2733 /* First time looping, return the scenes first base. */
2734 /* For the first loop we should get the layer from workspace when available. */
2735 BKE_view_layer_synced_ensure(*sce_iter, view_layer);
2736 ListBase *object_bases = BKE_view_layer_object_bases_get(view_layer);
2737 if (object_bases->first) {
2738 return static_cast<Base *>(object_bases->first);
2739 }
2740 /* No base on this scene layer. */
2741 goto next_set;
2742 }
2743 else {
2744 next_set:
2745 /* Reached the end, get the next base in the set. */
2746 while ((*sce_iter = (*sce_iter)->set)) {
2747 ViewLayer *view_layer_set = BKE_view_layer_default_render(*sce_iter);
2748 base = (Base *)BKE_view_layer_object_bases_get(view_layer_set)->first;
2749
2750 if (base) {
2751 return base;
2752 }
2753 }
2754 }
2755
2756 return nullptr;
2757}
2758
2760{
2761 RenderEngineType *type = RE_engines_find(scene->r.engine);
2762 return (type && type->flag & RE_USE_SHADING_NODES_CUSTOM);
2763}
2764
2766{
2767 RenderEngineType *type = RE_engines_find(scene->r.engine);
2768 return (type && type->flag & RE_USE_SPHERICAL_STEREO);
2769}
2770
2772{
2773 return STREQ(scene->r.engine, RE_engine_id_BLENDER_EEVEE) ||
2774 STREQ(scene->r.engine, RE_engine_id_BLENDER_EEVEE_NEXT);
2775}
2776
2778{
2779 return STREQ(scene->r.engine, RE_engine_id_BLENDER_WORKBENCH);
2780}
2781
2783{
2784 return STREQ(scene->r.engine, RE_engine_id_CYCLES);
2785}
2786
2788{
2790}
2791
2792/* This enumeration has to match the one defined in the Cycles addon. */
2797
2799{
2801 PointerRNA scene_ptr = RNA_id_pointer_create(&scene->id);
2802 PointerRNA cycles_ptr = RNA_pointer_get(&scene_ptr, "cycles");
2803
2804 if (RNA_pointer_is_null(&cycles_ptr)) {
2805 /* The pointer only exists if Cycles is enabled. */
2806 return false;
2807 }
2808
2809 return RNA_enum_get(&cycles_ptr, "feature_set") == CYCLES_FEATURES_EXPERIMENTAL;
2810}
2811
2812void BKE_scene_base_flag_to_objects(const Scene *scene, ViewLayer *view_layer)
2813{
2814 BKE_view_layer_synced_ensure(scene, view_layer);
2817 }
2818}
2819
2821{
2822 Object *ob = base->object;
2823 ob->base_flag = base->flag;
2824}
2825
2827{
2828 ColorManagedDisplaySettings *display_settings = &scene->display_settings;
2829 ColorManagedViewSettings *view_settings = &scene->view_settings;
2830 const char *view;
2831 const char *none_display_name;
2832
2833 none_display_name = IMB_colormanagement_display_get_none_name();
2834
2835 STRNCPY(display_settings->display_device, none_display_name);
2836
2838
2839 if (view) {
2840 STRNCPY(view_settings->view_transform, view);
2841 }
2842}
2843
2845{
2846 return scene && scene->rigidbody_world && scene->rigidbody_world->group &&
2847 !(scene->rigidbody_world->flag & RBW_FLAG_MUTED);
2848}
2849
2851{
2852 int threads;
2853
2854 /* override set from command line? */
2856
2857 if (threads > 0) {
2858 return threads;
2859 }
2860
2861 /* fixed number of threads specified in scene? */
2862 if (rd->mode & R_FIXED_THREADS) {
2863 threads = rd->threads;
2864 }
2865 else {
2866 threads = BLI_system_thread_count();
2867 }
2868
2869 return max_ii(threads, 1);
2870}
2871
2873{
2874 return BKE_render_num_threads(&scene->r);
2875}
2876
2877void BKE_render_resolution(const RenderData *r, const bool use_crop, int *r_width, int *r_height)
2878{
2879 *r_width = (r->xsch * r->size) / 100;
2880 *r_height = (r->ysch * r->size) / 100;
2881
2882 if (use_crop && (r->mode & R_BORDER) && (r->mode & R_CROP)) {
2883 /* Compute the difference between the integer bounds instead of multiplying by the float
2884 * border size directly to be consistent with how the render pipeline computes render size, see
2885 * for instance render_init_from_main. That's because difference in rounding and imprecisions
2886 * can cause off by one errors. */
2887 *r_width = int(r->border.xmax * *r_width) - int(r->border.xmin * *r_width);
2888 *r_height = int(r->border.ymax * *r_height) - int(r->border.ymin * *r_height);
2889 }
2890}
2891
2893{
2894 if (r->preview_pixel_size == 0) {
2895 return (U.pixelsize > 1.5f) ? 2 : 1;
2896 }
2897 return r->preview_pixel_size;
2898}
2899
2900double BKE_scene_unit_scale(const UnitSettings *unit, const int unit_type, double value)
2901{
2902 if (unit->system == USER_UNIT_NONE) {
2903 /* Never apply scale_length when not using a unit setting! */
2904 return value;
2905 }
2906
2907 switch (unit_type) {
2908 case B_UNIT_LENGTH:
2909 case B_UNIT_VELOCITY:
2911 return value * double(unit->scale_length);
2912 case B_UNIT_AREA:
2913 case B_UNIT_POWER:
2914 return value * pow(unit->scale_length, 2);
2915 case B_UNIT_VOLUME:
2916 return value * pow(unit->scale_length, 3);
2917 case B_UNIT_MASS:
2918 return value * pow(unit->scale_length, 3);
2919 case B_UNIT_CAMERA: /* *Do not* use scene's unit scale for camera focal lens! See #42026. */
2920 case B_UNIT_WAVELENGTH: /* Wavelength values are independent of the scene scale. */
2921 default:
2922 return value;
2923 }
2924}
2925
2926/******************** multiview *************************/
2927
2929{
2930 int totviews = 0;
2931
2932 if ((rd->scemode & R_MULTIVIEW) == 0) {
2933 return 1;
2934 }
2935
2937 SceneRenderView *srv = static_cast<SceneRenderView *>(
2939 if ((srv && srv->viewflag & SCE_VIEW_DISABLE) == 0) {
2940 totviews++;
2941 }
2942
2943 srv = static_cast<SceneRenderView *>(
2945 if ((srv && srv->viewflag & SCE_VIEW_DISABLE) == 0) {
2946 totviews++;
2947 }
2948 }
2949 else {
2950 LISTBASE_FOREACH (SceneRenderView *, srv, &rd->views) {
2951 if ((srv->viewflag & SCE_VIEW_DISABLE) == 0) {
2952 totviews++;
2953 }
2954 }
2955 }
2956 return totviews;
2957}
2958
2960{
2961 SceneRenderView *srv[2];
2962
2963 if ((rd->scemode & R_MULTIVIEW) == 0) {
2964 return false;
2965 }
2966
2967 srv[0] = (SceneRenderView *)BLI_findstring(
2969 srv[1] = (SceneRenderView *)BLI_findstring(
2971
2972 return (srv[0] && ((srv[0]->viewflag & SCE_VIEW_DISABLE) == 0) && srv[1] &&
2973 ((srv[1]->viewflag & SCE_VIEW_DISABLE) == 0));
2974}
2975
2977{
2978 if (srv == nullptr) {
2979 return false;
2980 }
2981
2982 if ((rd->scemode & R_MULTIVIEW) == 0) {
2983 return false;
2984 }
2985
2986 if (srv->viewflag & SCE_VIEW_DISABLE) {
2987 return false;
2988 }
2989
2991 return true;
2992 }
2993
2994 /* SCE_VIEWS_SETUP_BASIC */
2996 return true;
2997 }
2998
2999 return false;
3000}
3001
3002bool BKE_scene_multiview_is_render_view_first(const RenderData *rd, const char *viewname)
3003{
3004 if ((rd->scemode & R_MULTIVIEW) == 0) {
3005 return true;
3006 }
3007
3008 if ((!viewname) || (!viewname[0])) {
3009 return true;
3010 }
3011
3012 LISTBASE_FOREACH (const SceneRenderView *, srv, &rd->views) {
3014 return STREQ(viewname, srv->name);
3015 }
3016 }
3017
3018 return true;
3019}
3020
3021bool BKE_scene_multiview_is_render_view_last(const RenderData *rd, const char *viewname)
3022{
3023 if ((rd->scemode & R_MULTIVIEW) == 0) {
3024 return true;
3025 }
3026
3027 if ((!viewname) || (!viewname[0])) {
3028 return true;
3029 }
3030
3031 LISTBASE_FOREACH_BACKWARD (const SceneRenderView *, srv, &rd->views) {
3033 return STREQ(viewname, srv->name);
3034 }
3035 }
3036
3037 return true;
3038}
3039
3041{
3042 SceneRenderView *srv;
3043 size_t nr;
3044
3045 if ((rd->scemode & R_MULTIVIEW) == 0) {
3046 return nullptr;
3047 }
3048
3049 for (srv = static_cast<SceneRenderView *>(rd->views.first), nr = 0; srv; srv = srv->next) {
3051 if (nr++ == view_id) {
3052 return srv;
3053 }
3054 }
3055 }
3056 return srv;
3057}
3058
3059const char *BKE_scene_multiview_render_view_name_get(const RenderData *rd, const int view_id)
3060{
3062
3063 if (srv) {
3064 return srv->name;
3065 }
3066
3067 return "";
3068}
3069
3070int BKE_scene_multiview_view_id_get(const RenderData *rd, const char *viewname)
3071{
3072 SceneRenderView *srv;
3073 size_t nr;
3074
3075 if ((!rd) || ((rd->scemode & R_MULTIVIEW) == 0)) {
3076 return 0;
3077 }
3078
3079 if ((!viewname) || (!viewname[0])) {
3080 return 0;
3081 }
3082
3083 for (srv = static_cast<SceneRenderView *>(rd->views.first), nr = 0; srv; srv = srv->next) {
3085 if (STREQ(viewname, srv->name)) {
3086 return nr;
3087 }
3088
3089 nr += 1;
3090 }
3091 }
3092
3093 return 0;
3094}
3095
3097 const char *filepath,
3098 char *r_filepath)
3099{
3100 BLI_strncpy(r_filepath, filepath, FILE_MAX);
3101 BLI_path_suffix(r_filepath, FILE_MAX, srv->suffix, "");
3102}
3103
3105 const char *filepath,
3106 const char *viewname,
3107 char *r_filepath)
3108{
3109 SceneRenderView *srv;
3110 char suffix[FILE_MAX];
3111
3112 srv = static_cast<SceneRenderView *>(
3113 BLI_findstring(&rd->views, viewname, offsetof(SceneRenderView, name)));
3114 if (srv) {
3115 STRNCPY(suffix, srv->suffix);
3116 }
3117 else {
3118 STRNCPY(suffix, viewname);
3119 }
3120
3121 BLI_strncpy(r_filepath, filepath, FILE_MAX);
3122 BLI_path_suffix(r_filepath, FILE_MAX, suffix, "");
3123}
3124
3125const char *BKE_scene_multiview_view_suffix_get(const RenderData *rd, const char *viewname)
3126{
3127 SceneRenderView *srv;
3128
3129 if ((viewname == nullptr) || (viewname[0] == '\0')) {
3130 return viewname;
3131 }
3132
3133 srv = static_cast<SceneRenderView *>(
3134 BLI_findstring(&rd->views, viewname, offsetof(SceneRenderView, name)));
3135 if (srv) {
3136 return srv->suffix;
3137 }
3138
3139 return viewname;
3140}
3141
3142const char *BKE_scene_multiview_view_id_suffix_get(const RenderData *rd, const int view_id)
3143{
3144 if ((rd->scemode & R_MULTIVIEW) == 0) {
3145 return "";
3146 }
3147
3148 const char *viewname = BKE_scene_multiview_render_view_name_get(rd, view_id);
3149 return BKE_scene_multiview_view_suffix_get(rd, viewname);
3150}
3151
3153 const char *filepath,
3154 char *r_prefix,
3155 const char **r_ext)
3156{
3157 const char *unused;
3158 const char delims[] = {'.', '\0'};
3159
3160 r_prefix[0] = '\0';
3161
3162 /* Split `filepath` into base name and extension. */
3163 const size_t basename_len = BLI_str_rpartition(filepath, delims, r_ext, &unused);
3164 if (*r_ext == nullptr) {
3165 return;
3166 }
3167 BLI_assert(basename_len > 0);
3168
3169 /* Split base name into prefix and known suffix. */
3170 LISTBASE_FOREACH (SceneRenderView *, srv, &scene->r.views) {
3171 if (BKE_scene_multiview_is_render_view_active(&scene->r, srv)) {
3172 const size_t suffix_len = strlen(srv->suffix);
3173 if (basename_len >= suffix_len &&
3174 STREQLEN(filepath + basename_len - suffix_len, srv->suffix, suffix_len))
3175 {
3176 BLI_strncpy(r_prefix, filepath, basename_len - suffix_len + 1);
3177 break;
3178 }
3179 }
3180 }
3181}
3182
3184 const size_t width,
3185 const size_t height,
3186 size_t *r_width,
3187 size_t *r_height)
3188{
3192 width,
3193 height,
3194 r_width,
3195 r_height);
3196 }
3197 else {
3198 *r_width = width;
3199 *r_height = height;
3200 }
3201}
3202
3204{
3205 if (BKE_imtype_is_movie(rd->im_format.imtype) == false) {
3206 return 0;
3207 }
3208
3209 if ((rd->scemode & R_MULTIVIEW) == 0) {
3210 return 1;
3211 }
3212
3214 return 1;
3215 }
3216
3217 /* R_IMF_VIEWS_INDIVIDUAL */
3219}
3220
3221/* Manipulation of depsgraph storage. */
3222
3223/* This is a key which identifies depsgraph. */
3226 /* TODO(sergey): Need to include window somehow (same layer might be in a
3227 * different states in different windows).
3228 */
3229};
3230
3231static uint depsgraph_key_hash(const void *key_v)
3232{
3233 const DepsgraphKey *key = static_cast<const DepsgraphKey *>(key_v);
3235 /* TODO(sergey): Include hash from other fields in the key. */
3236 return hash;
3237}
3238
3239static bool depsgraph_key_compare(const void *key_a_v, const void *key_b_v)
3240{
3241 const DepsgraphKey *key_a = static_cast<const DepsgraphKey *>(key_a_v);
3242 const DepsgraphKey *key_b = static_cast<const DepsgraphKey *>(key_b_v);
3243 /* TODO(sergey): Compare rest of. */
3244 return !(key_a->view_layer == key_b->view_layer);
3245}
3246
3247static void depsgraph_key_free(void *key_v)
3248{
3249 DepsgraphKey *key = static_cast<DepsgraphKey *>(key_v);
3250 MEM_freeN(key);
3251}
3252
3253static void depsgraph_key_value_free(void *value)
3254{
3255 Depsgraph *depsgraph = static_cast<Depsgraph *>(value);
3257}
3258
3260{
3261 scene->depsgraph_hash = BLI_ghash_new(
3262 depsgraph_key_hash, depsgraph_key_compare, "Scene Depsgraph Hash");
3263}
3264
3266{
3267 if (scene->depsgraph_hash == nullptr) {
3269 }
3270}
3271
3273{
3274 if (scene->depsgraph_hash == nullptr) {
3275 return;
3276 }
3278 scene->depsgraph_hash = nullptr;
3279}
3280
3282{
3283 if (scene->depsgraph_hash != nullptr) {
3284 DepsgraphKey key = {view_layer};
3285 BLI_ghash_remove(scene->depsgraph_hash, &key, depsgraph_key_free, depsgraph_key_value_free);
3286 }
3287}
3288
3289/* Query depsgraph for a specific contexts. */
3290
3291static Depsgraph **scene_get_depsgraph_p(Scene *scene,
3292 ViewLayer *view_layer,
3293 const bool allocate_ghash_entry)
3294{
3295 /* bmain may be nullptr here! */
3296 BLI_assert(scene != nullptr);
3297 BLI_assert(view_layer != nullptr);
3298 BLI_assert(BKE_scene_has_view_layer(scene, view_layer));
3299
3300 /* Make sure hash itself exists. */
3301 if (allocate_ghash_entry) {
3303 }
3304 if (scene->depsgraph_hash == nullptr) {
3305 return nullptr;
3306 }
3307
3308 DepsgraphKey key;
3309 key.view_layer = view_layer;
3310
3311 Depsgraph **depsgraph_ptr;
3312 if (!allocate_ghash_entry) {
3313 depsgraph_ptr = (Depsgraph **)BLI_ghash_lookup_p(scene->depsgraph_hash, &key);
3314 return depsgraph_ptr;
3315 }
3316
3317 DepsgraphKey **key_ptr;
3319 scene->depsgraph_hash, &key, (void ***)&key_ptr, (void ***)&depsgraph_ptr))
3320 {
3321 return depsgraph_ptr;
3322 }
3323
3324 /* Depsgraph was not found in the ghash, but the key still needs allocating. */
3325 *key_ptr = MEM_cnew<DepsgraphKey>(__func__);
3326 **key_ptr = key;
3327
3328 *depsgraph_ptr = nullptr;
3329 return depsgraph_ptr;
3330}
3331
3332static Depsgraph **scene_ensure_depsgraph_p(Main *bmain, Scene *scene, ViewLayer *view_layer)
3333{
3334 BLI_assert(bmain != nullptr);
3335
3336 Depsgraph **depsgraph_ptr = scene_get_depsgraph_p(scene, view_layer, true);
3337 if (depsgraph_ptr == nullptr) {
3338 /* The scene has no depsgraph hash. */
3339 return nullptr;
3340 }
3341 if (*depsgraph_ptr != nullptr) {
3342 /* The depsgraph was found, no need to allocate. */
3343 return depsgraph_ptr;
3344 }
3345
3346 /* Allocate a new depsgraph. scene_get_depsgraph_p() already ensured that the pointer is stored
3347 * in the scene's depsgraph hash. */
3348 *depsgraph_ptr = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_VIEWPORT);
3349
3350 /* TODO(sergey): Would be cool to avoid string format print,
3351 * but is a bit tricky because we can't know in advance whether
3352 * we will ever enable debug messages for this depsgraph.
3353 */
3354 char name[1024];
3355 SNPRINTF(name, "%s :: %s", scene->id.name, view_layer->name);
3356 DEG_debug_name_set(*depsgraph_ptr, name);
3357
3358 /* These viewport depsgraphs communicate changes to the editors. */
3359 DEG_enable_editors_update(*depsgraph_ptr);
3360
3361 return depsgraph_ptr;
3362}
3363
3364Depsgraph *BKE_scene_get_depsgraph(const Scene *scene, const ViewLayer *view_layer)
3365{
3366 BLI_assert(BKE_scene_has_view_layer(scene, view_layer));
3367
3368 if (scene->depsgraph_hash == nullptr) {
3369 return nullptr;
3370 }
3371
3372 DepsgraphKey key;
3373 key.view_layer = view_layer;
3374 return static_cast<Depsgraph *>(BLI_ghash_lookup(scene->depsgraph_hash, &key));
3375}
3376
3377Depsgraph *BKE_scene_ensure_depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer)
3378{
3379 Depsgraph **depsgraph_ptr = scene_ensure_depsgraph_p(bmain, scene, view_layer);
3380 return (depsgraph_ptr != nullptr) ? *depsgraph_ptr : nullptr;
3381}
3382
3383static char *scene_undo_depsgraph_gen_key(Scene *scene, ViewLayer *view_layer, char *key_full)
3384{
3385 if (key_full == nullptr) {
3386 key_full = static_cast<char *>(MEM_callocN(MAX_ID_NAME + FILE_MAX + MAX_NAME, __func__));
3387 }
3388
3389 size_t key_full_offset = BLI_strncpy_rlen(key_full, scene->id.name, MAX_ID_NAME);
3390 if (ID_IS_LINKED(scene)) {
3391 key_full_offset += BLI_strncpy_rlen(
3392 key_full + key_full_offset, scene->id.lib->filepath, FILE_MAX);
3393 }
3394 key_full_offset += BLI_strncpy_rlen(key_full + key_full_offset, view_layer->name, MAX_NAME);
3395 BLI_assert(key_full_offset < MAX_ID_NAME + FILE_MAX + MAX_NAME);
3396
3397 return key_full;
3398}
3399
3401{
3402 GHash *depsgraph_extract = BLI_ghash_new(
3404
3405 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
3406 if (scene->depsgraph_hash == nullptr) {
3407 /* In some cases, e.g. when undo has to perform multiple steps at once, no depsgraph will
3408 * be built so this pointer may be nullptr. */
3409 continue;
3410 }
3411 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
3412 DepsgraphKey key;
3413 key.view_layer = view_layer;
3414 Depsgraph **depsgraph = (Depsgraph **)BLI_ghash_lookup_p(scene->depsgraph_hash, &key);
3415
3416 if (depsgraph != nullptr && *depsgraph != nullptr) {
3417 char *key_full = scene_undo_depsgraph_gen_key(scene, view_layer, nullptr);
3418
3419 /* We steal the depsgraph from the scene. */
3420 BLI_ghash_insert(depsgraph_extract, key_full, *depsgraph);
3421 *depsgraph = nullptr;
3422 }
3423 }
3424 }
3425
3426 return depsgraph_extract;
3427}
3428
3429void BKE_scene_undo_depsgraphs_restore(Main *bmain, GHash *depsgraph_extract)
3430{
3431 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
3432 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
3433 char key_full[MAX_ID_NAME + FILE_MAX + MAX_NAME] = {0};
3434 scene_undo_depsgraph_gen_key(scene, view_layer, key_full);
3435
3436 Depsgraph **depsgraph_extract_ptr = (Depsgraph **)BLI_ghash_lookup_p(depsgraph_extract,
3437 key_full);
3438 if (depsgraph_extract_ptr == nullptr) {
3439 continue;
3440 }
3441 BLI_assert(*depsgraph_extract_ptr != nullptr);
3442
3443 Depsgraph **depsgraph_scene_ptr = scene_get_depsgraph_p(scene, view_layer, true);
3444 BLI_assert(depsgraph_scene_ptr != nullptr);
3445 BLI_assert(*depsgraph_scene_ptr == nullptr);
3446
3447 /* We steal the depsgraph back from our 'extract' storage to the scene. */
3448 Depsgraph *depsgraph = *depsgraph_extract_ptr;
3449
3450 DEG_graph_replace_owners(depsgraph, bmain, scene, view_layer);
3451
3453
3454 *depsgraph_scene_ptr = depsgraph;
3455 *depsgraph_extract_ptr = nullptr;
3456 }
3457 }
3458
3460}
3461
3462/* -------------------------------------------------------------------- */
3467{
3468 const int orientation_index = BKE_scene_transform_orientation_get_index(scene, orientation);
3469
3470 for (int i = 0; i < ARRAY_SIZE(scene->orientation_slots); i++) {
3471 TransformOrientationSlot *orient_slot = &scene->orientation_slots[i];
3472 if (orient_slot->index_custom == orientation_index) {
3473 /* could also use orientation_index-- */
3474 orient_slot->type = V3D_ORIENT_GLOBAL;
3475 orient_slot->index_custom = -1;
3476 }
3477 else if (orient_slot->index_custom > orientation_index) {
3478 BLI_assert(orient_slot->type == V3D_ORIENT_CUSTOM);
3479 orient_slot->index_custom--;
3480 }
3481 }
3482
3483 BLI_freelinkN(&scene->transform_spaces, orientation);
3484}
3485
3487{
3488 return static_cast<TransformOrientation *>(BLI_findlink(&scene->transform_spaces, index));
3489}
3490
3492 const TransformOrientation *orientation)
3493{
3494 return BLI_findindex(&scene->transform_spaces, orientation);
3495}
3496
3499/* -------------------------------------------------------------------- */
3505template<> blender::float3x3 View3DCursor::matrix<blender::float3x3>() const
3506{
3508 if (this->rotation_mode > 0) {
3509 eulO_to_mat3(mat.ptr(), this->rotation_euler, this->rotation_mode);
3510 }
3511 else if (this->rotation_mode == ROT_MODE_AXISANGLE) {
3512 axis_angle_to_mat3(mat.ptr(), this->rotation_axis, this->rotation_angle);
3513 }
3514 else {
3515 float tquat[4];
3516 normalize_qt_qt(tquat, this->rotation_quaternion);
3517 quat_to_mat3(mat.ptr(), tquat);
3518 }
3519 return mat;
3520}
3521
3522blender::math::Quaternion View3DCursor::rotation() const
3523{
3525 if (this->rotation_mode > 0) {
3526 eulO_to_quat(&quat.w, this->rotation_euler, this->rotation_mode);
3527 }
3528 else if (this->rotation_mode == ROT_MODE_AXISANGLE) {
3529 axis_angle_to_quat(&quat.w, this->rotation_axis, this->rotation_angle);
3530 }
3531 else {
3532 normalize_qt_qt(&quat.w, this->rotation_quaternion);
3533 }
3534 return quat;
3535}
3536
3537void View3DCursor::set_matrix(const blender::float3x3 &mat, const bool use_compat)
3538{
3539 BLI_ASSERT_UNIT_M3(mat.ptr());
3540
3541 switch (this->rotation_mode) {
3542 case ROT_MODE_QUAT: {
3543 float quat[4];
3544 mat3_normalized_to_quat(quat, mat.ptr());
3545 if (use_compat) {
3546 float quat_orig[4];
3547 copy_v4_v4(quat_orig, this->rotation_quaternion);
3548 quat_to_compatible_quat(this->rotation_quaternion, quat, quat_orig);
3549 }
3550 else {
3551 copy_v4_v4(this->rotation_quaternion, quat);
3552 }
3553 break;
3554 }
3555 case ROT_MODE_AXISANGLE: {
3556 mat3_to_axis_angle(this->rotation_axis, &this->rotation_angle, mat.ptr());
3557 break;
3558 }
3559 default: {
3560 if (use_compat) {
3562 this->rotation_euler, this->rotation_euler, this->rotation_mode, mat.ptr());
3563 }
3564 else {
3565 mat3_to_eulO(this->rotation_euler, this->rotation_mode, mat.ptr());
3566 }
3567 break;
3568 }
3569 }
3570}
3571
3572void View3DCursor::set_rotation(const blender::math::Quaternion &quat, bool use_compat)
3573{
3574 BLI_ASSERT_UNIT_QUAT(&quat.w);
3575
3576 switch (this->rotation_mode) {
3577 case ROT_MODE_QUAT: {
3578 if (use_compat) {
3579 float quat_orig[4];
3580 copy_v4_v4(quat_orig, this->rotation_quaternion);
3581 quat_to_compatible_quat(this->rotation_quaternion, &quat.w, quat_orig);
3582 }
3583 else {
3584 copy_qt_qt(this->rotation_quaternion, &quat.w);
3585 }
3586 break;
3587 }
3588 case ROT_MODE_AXISANGLE: {
3589 quat_to_axis_angle(this->rotation_axis, &this->rotation_angle, &quat.w);
3590 break;
3591 }
3592 default: {
3593 if (use_compat) {
3595 this->rotation_euler, this->rotation_euler, this->rotation_mode, &quat.w);
3596 }
3597 else {
3598 quat_to_eulO(this->rotation_euler, this->rotation_mode, &quat.w);
3599 }
3600 break;
3601 }
3602 }
3603}
3604
3605template<> blender::float4x4 View3DCursor::matrix<blender::float4x4>() const
3606{
3607 blender::float4x4 mat(this->matrix<blender::float3x3>());
3608 mat.location() = blender::float3(this->location);
3609 return mat;
3610}
3611
3612void View3DCursor::set_matrix(const blender::float4x4 &mat, const bool use_compat)
3613{
3614 this->set_matrix(blender::float3x3(mat), use_compat);
3615 copy_v3_v3(this->location, mat.location());
3616}
3617
Blender kernel action and pose functionality.
void action_groups_remove_channel(bAction *act, FCurve *fcu)
AnimData * BKE_animdata_from_id(const ID *id)
Definition anim_data.cc:89
void BKE_animdata_duplicate_id_action(Main *bmain, ID *id, uint duplicate_flags)
Definition anim_data.cc:521
void BKE_keyingsets_free(struct ListBase *list)
Definition anim_sys.cc:283
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:320
void BKE_keyingsets_blend_write(struct BlendWriter *writer, struct ListBase *list)
Definition anim_sys.cc:302
void BKE_keyingsets_foreach_id(struct LibraryForeachIDData *data, const struct ListBase *keyingsets)
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:154
bool BKE_bpath_foreach_path_fixed_process(BPathForeachPathData *bpath_data, char *path, size_t path_maxncpy)
Definition bpath.cc:123
@ BKE_BPATH_FOREACH_PATH_SKIP_MULTIFILE
Definition BKE_bpath.hh:55
void BKE_callback_exec_id(Main *bmain, ID *id, eCbEvent evt)
Definition callbacks.cc:44
@ 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:53
Collection * BKE_collection_master_add(Scene *scene)
void BKE_collection_blend_write_nolib(BlendWriter *writer, Collection *collection)
void BKE_collection_blend_write_prepare_nolib(BlendWriter *writer, Collection *collection)
void BKE_collection_free_data(Collection *collection)
Collection * BKE_collection_duplicate(Main *bmain, Collection *parent, CollectionChild *child_old, Collection *collection, uint duplicate_flags, uint duplicate_options)
@ CURVEMAP_SLOPE_POS_NEG
@ CURVEMAP_SLOPE_POSITIVE
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
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:90
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)
ListBase * object_duplilist(Depsgraph *depsgraph, Scene *sce, Object *ob)
void free_object_duplilist(ListBase *lb)
struct EffectorWeights * BKE_effector_add_weights(struct Collection *collection)
Definition effect.cc:57
void BKE_fcurve_free(FCurve *fcu)
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:1227
void IDP_FreePropertyContent_ex(IDProperty *prop, bool do_id_user)
Definition idprop.cc:1189
IDProperty * IDP_CopyProperty_ex(const IDProperty *prop, int flag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:843
IDProperty * IDP_CopyProperty(const IDProperty *prop) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:861
void IDP_BlendWrite(BlendWriter *writer, const IDProperty *prop)
Definition idprop.cc:1437
@ IDTYPE_FLAGS_NEVER_UNUSED
Definition BKE_idtype.hh:64
IDTypeInfo IDType_ID_SCE
Definition scene.cc:1607
void(*)(ID *id, const IDCacheKey *cache_key, void **cache_p, uint flags, void *user_data) IDTypeForeachCacheFunctionCallback
Definition BKE_idtype.hh:98
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:770
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:1657
void BKE_libblock_free_data_py(ID *id)
@ 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:1947
struct ID * BKE_id_copy_in_lib(Main *bmain, std::optional< Library * > owner_library, const ID *id, const ID *new_owner_id, ID **new_id_p, int flag)
Definition lib_id.cc:656
void id_us_ensure_real(ID *id)
Definition lib_id.cc:306
ID * BKE_id_copy(Main *bmain, const ID *id)
Definition lib_id.cc:765
void * BKE_id_new(Main *bmain, short type, const char *name)
Definition lib_id.cc:1482
void id_us_plus_no_lib(ID *id)
Definition lib_id.cc:335
void id_us_min(ID *id)
Definition lib_id.cc:359
@ LIB_ID_DUPLICATE_IS_SUBPROCESS
void BKE_id_blend_write(BlendWriter *writer, ID *id)
Definition lib_id.cc:2560
void BKE_lib_query_foreachid_process(LibraryForeachIDData *data, ID **id_pp, int cb_flag)
Definition lib_query.cc:71
#define BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data_, func_call_)
#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:163
@ 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
int BKE_lib_query_foreachid_process_flags_get(const LibraryForeachIDData *data)
Definition lib_query.cc:120
@ IDWALK_DO_DEPRECATED_POINTERS
@ IDWALK_NO_ORIG_POINTERS_ACCESS
@ ID_REMAP_SKIP_USER_CLEAR
@ ID_REMAP_SKIP_NEVER_NULL_USAGE
void BKE_libblock_relink_to_newid(Main *bmain, ID *id, int remap_flag) ATTR_NONNULL()
Definition lib_remap.cc:921
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:844
#define FOREACH_MAIN_ID_END
Definition BKE_main.hh:500
#define FOREACH_MAIN_ID_BEGIN(_bmain, _id)
Definition BKE_main.hh:494
const char * BKE_main_blendfile_path(const Main *bmain) ATTR_NONNULL()
Definition main.cc:832
void BKE_paint_free(Paint *paint)
Definition paint.cc:1801
CurveMapping * BKE_sculpt_default_cavity_curve()
Definition scene.cc:120
void BKE_paint_copy(const Paint *src, Paint *dst, int flag)
Definition paint.cc:1818
void BKE_sculpt_check_cavity_curves(Sculpt *sd)
Definition scene.cc:135
void BKE_paint_blend_read_data(BlendDataReader *reader, const Scene *scene, Paint *paint)
Definition paint.cc:1894
void BKE_paint_blend_write(BlendWriter *writer, Paint *paint)
Definition paint.cc:1862
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:89
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_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:2877
Scene * BKE_scene_set_name(Main *bmain, const char *name)
Definition scene.cc:2009
int BKE_scene_transform_orientation_get_index(const Scene *scene, const TransformOrientation *orientation)
Definition scene.cc:3491
void BKE_scene_graph_evaluated_ensure(Depsgraph *depsgraph, Main *bmain)
Definition scene.cc:2573
void BKE_scene_disable_color_management(Scene *scene)
Definition scene.cc:2826
bool BKE_scene_uses_cycles(const Scene *scene)
Definition scene.cc:2782
void BKE_scene_copy_data_eevee(Scene *sce_dst, const Scene *sce_src)
Definition scene.cc:1772
float BKE_scene_ctime_get(const Scene *scene)
Definition scene.cc:2317
int get_render_subsurf_level(const RenderData *r, int lvl, bool for_render)
Definition scene.cc:2700
void BKE_scene_undo_depsgraphs_restore(Main *bmain, GHash *depsgraph_extract)
Definition scene.cc:3429
Object * BKE_scene_object_find_by_name(const Scene *scene, const char *name)
Definition scene.cc:1974
int BKE_scene_num_threads(const Scene *scene)
Definition scene.cc:2872
int get_render_child_particle_number(const RenderData *r, int child_num, bool for_render)
Definition scene.cc:2713
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:3259
void BKE_scene_free_view_layer_depsgraph(Scene *scene, ViewLayer *view_layer)
Definition scene.cc:3281
void BKE_toolsettings_free(ToolSettings *toolsettings)
Definition scene.cc:1700
void BKE_scene_graph_update_for_newframe_ex(Depsgraph *depsgraph, bool clear_recalc)
Definition scene.cc:2578
void BKE_scene_free_depsgraph_hash(Scene *scene)
Definition scene.cc:3272
int BKE_scene_multiview_num_views_get(const RenderData *rd)
Definition scene.cc:2928
bool BKE_scene_multiview_is_render_view_active(const RenderData *rd, const SceneRenderView *srv)
Definition scene.cc:2976
int BKE_scene_frame_snap_by_seconds(Scene *scene, double interval_in_seconds, int frame)
Definition scene.cc:2273
TransformOrientationSlot * BKE_scene_orientation_slot_get(Scene *scene, int slot_index)
Definition scene.cc:2347
void BKE_scene_transform_orientation_remove(Scene *scene, TransformOrientation *orientation)
Definition scene.cc:3466
bool BKE_scene_check_rigidbody_active(const Scene *scene)
Definition scene.cc:2844
int BKE_render_preview_pixel_size(const RenderData *r)
Definition scene.cc:2892
void BKE_scene_view_layer_graph_evaluated_ensure(Main *bmain, Scene *scene, ViewLayer *view_layer)
Definition scene.cc:2652
const char * BKE_scene_multiview_view_id_suffix_get(const RenderData *rd, int view_id)
Definition scene.cc:3142
bool BKE_scene_has_view_layer(const Scene *scene, const ViewLayer *layer)
Definition scene.cc:2152
TransformOrientationSlot * BKE_scene_orientation_slot_get_from_flag(Scene *scene, int flag)
Definition scene.cc:2355
int BKE_render_num_threads(const RenderData *r)
Definition scene.cc:2850
void BKE_scene_frame_set(Scene *scene, float frame)
Definition scene.cc:2336
void BKE_scene_multiview_view_prefix_get(Scene *scene, const char *filepath, char *r_prefix, const char **r_ext)
Definition scene.cc:3152
void BKE_scene_remove_rigidbody_object(Main *bmain, Scene *scene, Object *ob, bool free_us)
Definition scene.cc:2283
int BKE_scene_base_iter_next(Depsgraph *depsgraph, SceneBaseIter *iter, Scene **scene, int val, Base **base, Object **ob)
Definition scene.cc:2022
const char * BKE_scene_multiview_view_suffix_get(const RenderData *rd, const char *viewname)
Definition scene.cc:3125
bool BKE_scene_camera_switch_update(Scene *scene)
Definition scene.cc:2213
TransformOrientation * BKE_scene_transform_orientation_find(const Scene *scene, int index)
Definition scene.cc:3486
Depsgraph * BKE_scene_ensure_depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer)
Definition scene.cc:3377
bool BKE_scene_uses_cycles_experimental_features(Scene *scene)
Definition scene.cc:2798
bool BKE_scene_multiview_is_stereo3d(const RenderData *rd)
Definition scene.cc:2959
bool BKE_scene_multiview_is_render_view_first(const RenderData *rd, const char *viewname)
Definition scene.cc:3002
GHash * BKE_scene_undo_depsgraphs_extract(Main *bmain)
Definition scene.cc:3400
ToolSettings * BKE_toolsettings_copy(ToolSettings *toolsettings, int flag)
Definition scene.cc:1628
int BKE_scene_orientation_slot_get_index(const TransformOrientationSlot *orient_slot)
Definition scene.cc:2379
float BKE_scene_frame_get(const Scene *scene)
Definition scene.cc:2331
void BKE_scene_groups_relink(Scene *sce)
Definition scene.cc:1932
bool BKE_scene_can_be_removed(const Main *bmain, const Scene *scene)
Definition scene.cc:1939
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:3183
bool BKE_scene_multiview_is_render_view_last(const RenderData *rd, const char *viewname)
Definition scene.cc:3021
bool BKE_scene_use_spherical_stereo(Scene *scene)
Definition scene.cc:2765
Scene * BKE_scene_duplicate(Main *bmain, Scene *sce, eSceneCopyMethod type)
Definition scene.cc:1778
void BKE_scene_ensure_depsgraph_hash(Scene *scene)
Definition scene.cc:3265
void BKE_scene_update_sound(Depsgraph *depsgraph, Main *bmain)
Definition scene.cc:2458
void BKE_scene_multiview_view_filepath_get(const RenderData *rd, const char *filepath, const char *view, char *r_filepath)
Definition scene.cc:3104
void BKE_scene_update_tag_audio_volume(Depsgraph *, Scene *scene)
Definition scene.cc:2483
bool BKE_scene_uses_shader_previews(const Scene *scene)
Definition scene.cc:2787
SceneRenderView * BKE_scene_multiview_render_view_findindex(const RenderData *rd, int view_id)
Definition scene.cc:3040
int BKE_scene_orientation_get_index_from_flag(Scene *scene, int flag)
Definition scene.cc:2392
bool BKE_scene_validate_setscene(Main *bmain, Scene *sce)
Definition scene.cc:2295
int BKE_scene_multiview_num_videos_get(const RenderData *rd)
Definition scene.cc:3203
Scene * BKE_scene_add(Main *bmain, const char *name)
Definition scene.cc:1954
int BKE_scene_orientation_get_index(Scene *scene, int slot_index)
Definition scene.cc:2386
bool BKE_scene_object_find(Scene *scene, Object *ob)
Definition scene.cc:1963
void BKE_scene_orientation_slot_set_index(TransformOrientationSlot *orient_slot, int orientation)
Definition scene.cc:2372
const char * BKE_scene_find_last_marker_name(const Scene *scene, int frame)
Definition scene.cc:2255
void BKE_scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain)
Definition scene.cc:2568
bool BKE_scene_use_shading_nodes_custom(Scene *scene)
Definition scene.cc:2759
double BKE_scene_unit_scale(const UnitSettings *unit, int unit_type, double value)
Definition scene.cc:2900
void BKE_scene_multiview_filepath_get(const SceneRenderView *srv, const char *filepath, char *r_filepath)
Definition scene.cc:3096
int BKE_scene_multiview_view_id_get(const RenderData *rd, const char *viewname)
Definition scene.cc:3070
void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph)
Definition scene.cc:2647
Depsgraph * BKE_scene_get_depsgraph(const Scene *scene, const ViewLayer *view_layer)
Definition scene.cc:3364
void BKE_scene_set_background(Main *bmain, Scene *sce)
Definition scene.cc:1987
void BKE_scene_base_flag_to_objects(const Scene *scene, ViewLayer *view_layer)
Definition scene.cc:2812
bool BKE_scene_remove_render_view(Scene *scene, SceneRenderView *srv)
Definition scene.cc:2678
SceneRenderView * BKE_scene_add_render_view(Scene *sce, const char *name)
Definition scene.cc:2659
Base * _setlooper_base_step(Scene **sce_iter, ViewLayer *view_layer, Base *base)
Definition scene.cc:2726
float BKE_scene_frame_to_ctime(const Scene *scene, int frame)
Definition scene.cc:2322
Scene * BKE_scene_find_from_collection(const Main *bmain, const Collection *collection)
Definition scene.cc:2157
void BKE_scene_object_base_flag_sync_from_base(Base *base)
Definition scene.cc:2820
bool BKE_scene_uses_blender_workbench(const Scene *scene)
Definition scene.cc:2777
const char * BKE_scene_multiview_render_view_name_get(const RenderData *rd, int view_id)
Definition scene.cc:3059
bool BKE_scene_uses_blender_eevee(const Scene *scene)
Definition scene.cc:2771
const char * BKE_scene_find_marker_name(const Scene *scene, int frame)
Definition scene.cc:2228
void BKE_screen_view3d_shading_blend_read_data(BlendDataReader *reader, View3DShading *shading)
Definition screen.cc:1055
void BKE_screen_view3d_shading_blend_write(BlendWriter *writer, View3DShading *shading)
Definition screen.cc:1048
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:2495
@ B_UNIT_AREA
Definition BKE_unit.hh:108
@ B_UNIT_VOLUME
Definition BKE_unit.hh:109
@ B_UNIT_LENGTH
Definition BKE_unit.hh:107
@ B_UNIT_TEMPERATURE
Definition BKE_unit.hh:118
@ B_UNIT_CAMERA
Definition BKE_unit.hh:116
@ B_UNIT_ACCELERATION
Definition BKE_unit.hh:115
@ B_UNIT_MASS
Definition BKE_unit.hh:110
@ B_UNIT_WAVELENGTH
Definition BKE_unit.hh:119
@ B_UNIT_POWER
Definition BKE_unit.hh:117
@ B_UNIT_TIME
Definition BKE_unit.hh:112
@ B_UNIT_VELOCITY
Definition BKE_unit.hh:114
bScreen * BKE_workspace_active_screen_get(const WorkSpaceInstanceHook *hook) GETTER_ATTRS
Definition workspace.cc:613
#define BLI_assert(a)
Definition BLI_assert.h:50
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.c:686
void ** BLI_ghash_lookup_p(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.c:745
bool BLI_ghash_remove(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition BLI_ghash.c:787
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.c:731
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition BLI_ghash.c:707
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition BLI_ghash.c: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.c:768
void * BLI_findstring(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define LISTBASE_FOREACH(type, var, list)
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:269
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
#define LISTBASE_FOREACH_BACKWARD(type, var, list)
void void void void void void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:496
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:130
void * BLI_findptr(const struct ListBase *listbase, const void *ptr, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT 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:653
#define STRNCPY(dst, src)
Definition BLI_string.h:593
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:597
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 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 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)
ID * BLO_read_get_new_id_address_from_session_uid(BlendLibReader *reader, uint session_uid) ATTR_NONNULL(1)
Definition readfile.cc:4893
void * BLO_read_get_new_data_address_no_us(BlendDataReader *reader, const void *old_address, size_t expected_size)
Definition readfile.cc:4857
BlendFileReadReport * BLO_read_data_reports(BlendDataReader *reader)
Definition readfile.cc:5150
BLO_Write_IDBuffer * BLO_write_allocate_id_buffer()
void BLO_read_glob_list(BlendDataReader *reader, ListBase *list)
Definition readfile.cc:5145
#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:5165
void BLO_write_init_id_buffer_from_id(BLO_Write_IDBuffer *id_buffer, ID *id, const bool is_undo)
void BLO_write_destroy_id_buffer(BLO_Write_IDBuffer **id_buffer)
ID * BLO_write_get_id_buffer_temp_id(BLO_Write_IDBuffer *id_buffer)
#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)
typedef double(DMatrix)[4][4]
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:273
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:280
void DEG_graph_free(Depsgraph *graph)
Definition depsgraph.cc:301
void DEG_ids_restore_recalc(Depsgraph *depsgraph)
void DEG_make_active(Depsgraph *depsgraph)
Definition depsgraph.cc:331
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)
bool DEG_is_evaluated_id(const ID *id)
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
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)
#define FILTER_ID_GD_LEGACY
Definition DNA_ID.h:1169
#define FILTER_ID_OB
Definition DNA_ID.h:1181
#define FILTER_ID_MC
Definition DNA_ID.h:1177
@ ID_RECALC_AUDIO_FPS
Definition DNA_ID.h:1094
@ ID_RECALC_AUDIO_LISTENER
Definition DNA_ID.h:1097
@ ID_RECALC_FRAME_CHANGE
Definition DNA_ID.h:1092
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1085
@ ID_RECALC_AUDIO_MUTE
Definition DNA_ID.h:1096
@ ID_RECALC_ALL
Definition DNA_ID.h:1155
@ ID_RECALC_AUDIO_VOLUME
Definition DNA_ID.h:1095
#define FILTER_ID_MA
Definition DNA_ID.h:1175
#define FILTER_ID_SO
Definition DNA_ID.h:1186
#define FILTER_ID_BR
Definition DNA_ID.h:1166
#define ID_IS_LINKED(_id)
Definition DNA_ID.h:654
#define MAX_ID_NAME
Definition DNA_ID.h:377
#define FILTER_ID_GR
Definition DNA_ID.h:1170
#define FILTER_ID_LS
Definition DNA_ID.h:1173
@ ID_FLAG_EMBEDDED_DATA
Definition DNA_ID.h:725
@ ID_TAG_NEW
Definition DNA_ID.h:865
#define FILTER_ID_MSK
Definition DNA_ID.h:1179
@ INDEX_ID_SCE
Definition DNA_ID.h:1317
#define FILTER_ID_PAL
Definition DNA_ID.h:1182
#define FILTER_ID_IM
Definition DNA_ID.h:1171
#define FILTER_ID_SCE
Definition DNA_ID.h:1184
#define FILTER_ID_WO
Definition DNA_ID.h:1190
#define FILTER_ID_NT
Definition DNA_ID.h:1180
#define FILTER_ID_TXT
Definition DNA_ID.h:1188
@ ID_SCE
@ IDP_TYPE_FILTER_ID
@ ROT_MODE_QUAT
@ ROT_MODE_AXISANGLE
Object groups, one object can be in many groups at once.
@ 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)
#define MAX_NAME
Definition DNA_defs.h:50
@ OB_RENDER
Object is a sort of wrapper for general info.
@ OB_HIDE_RENDER
@ OB_FROMDUPLI
@ OB_MESH
@ OB_DUPLI
@ PTCACHE_FLAG_INFO_DIRTY
Types and defines for representing Rigid Body entities.
@ RBW_FLAG_MUTED
@ USER_UNIT_METRIC
@ USER_UNIT_NONE
@ SCE_VIEW_DISABLE
@ SCE_ORIENT_DEFAULT
@ SCE_ORIENT_ROTATE
@ SCE_ORIENT_TRANSLATE
@ SCE_ORIENT_SCALE
#define STEREO_LEFT_NAME
@ F_DUPLI
@ F_START
@ F_SCENE
@ R_MULTIVIEW
struct Scene Scene
@ R_IMF_VIEWS_STEREO_3D
@ R_NO_CAMERA_SWITCH
@ R_CROP
@ R_SIMPLIFY
@ R_FIXED_THREADS
@ R_BORDER
@ S3D_SQUEEZED_FRAME
@ SCE_VIEWS_FORMAT_STEREO_3D
@ SCE_VIEWS_FORMAT_MULTIVIEW
@ SCE_READFILE_LIBLINK_NEED_SETSCENE_CHECK
#define STEREO_LEFT_SUFFIX
#define STEREO_RIGHT_NAME
@ PE_BRUSH_CUT
#define STEREO_RIGHT_SUFFIX
#define FPS
@ AUDIO_MUTE
#define MAXFRAME
@ SEQ_TYPE_SOUND_RAM
@ SEQ_TYPE_TEXT
@ SEQ_TYPE_IMAGE
@ SEQ_TYPE_MOVIE
#define SEQ_HAS_PATH(_seq)
@ SPACE_VIEW3D
eDupli_ID_Flags
@ USER_DUP_LINKED_ID
@ USER_DUP_OBJECT
@ V3D_GIZMO_SHOW_OBJECT_ROTATE
@ V3D_GIZMO_SHOW_OBJECT_SCALE
@ V3D_GIZMO_SHOW_OBJECT_TRANSLATE
@ V3D_ORIENT_CUSTOM
@ V3D_ORIENT_GLOBAL
void DRW_drawdata_free(ID *id)
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)
const char * IMB_colormanagement_role_colorspace_name_get(int role)
@ COLOR_ROLE_DEFAULT_SEQUENCER
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.
#define MEM_SAFE_FREE(v)
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between camera
@ RE_USE_SHADING_NODES_CUSTOM
Definition RE_engine.h:51
@ RE_USE_SPHERICAL_STEREO
Definition RE_engine.h:52
#define SEQ_DUPE_ALL
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *mesh, const BMeshToMeshParams *params)
unsigned int U
Definition btGjkEpa3.h:78
pow(value.r - subtrahend, 2.0)") .do_static_compilation(true)
#define printf
#define SELECT
const Depsgraph * depsgraph
#define offsetof(t, d)
int len
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
const vector< Marker > & markers
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
RenderEngineType * RE_engines_find(const char *idname)
void SEQ_for_each_callback(ListBase *seqbase, SeqForEachFunc callback, void *user_data)
Definition iterator.cc:43
size_t(* MEM_allocN_len)(const void *vmemh)
Definition mallocn.cc:36
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
void *(* MEM_dupallocN)(const void *vmemh)
Definition mallocn.cc:39
void node_tree_blend_write(BlendWriter *writer, bNodeTree *ntree)
Definition node.cc:760
void node_tree_free_embedded_tree(bNodeTree *ntree)
Definition node.cc:3632
VecBase< float, 3 > float3
#define hash
Definition noise.c: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)
static bool seq_foreach_member_id_cb(Sequence *seq, void *user_data)
Definition scene.cc:795
#define BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_FUNCTION_CALL(_data, _do_undo_restore, _func_call)
Definition scene.cc:564
static void scene_undo_preserve(BlendLibReader *reader, ID *id_new, ID *id_old)
Definition scene.cc:1541
static uint depsgraph_key_hash(const void *key_v)
Definition scene.cc:3231
static void scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain, bool only_if_tagged)
Definition scene.cc:2497
static void depsgraph_key_free(void *key_v)
Definition scene.cc:3247
const char * RE_engine_id_CYCLES
Definition scene.cc:1612
static void scene_blend_read_data(BlendDataReader *reader, ID *id)
Definition scene.cc:1206
static void direct_link_paint_helper(BlendDataReader *reader, const Scene *scene, Paint **paint)
Definition scene.cc:1180
const char * RE_engine_id_BLENDER_EEVEE_NEXT
Definition scene.cc:1610
eSceneForeachUndoPreserveProcess
Definition scene.cc:481
@ SCENE_FOREACH_UNDO_NO_RESTORE
Definition scene.cc:487
@ SCENE_FOREACH_UNDO_RESTORE
Definition scene.cc:484
static void link_recurs_seq(BlendDataReader *reader, ListBase *lb)
Definition scene.cc:1190
#define FOREACHID_PROCESS_IDSUPER(_data, _id_super, _cb_flag)
static void scene_blend_read_after_liblink(BlendLibReader *reader, ID *id)
Definition scene.cc:1506
static bool depsgraph_key_compare(const void *key_a_v, const void *key_b_v)
Definition scene.cc:3239
#define FOREACHID_PROCESS_ID_NOCHECK(_data, _id_super, _cb_flag)
static void scene_free_markers(Scene *scene, bool do_id_user)
Definition scene.cc:381
static void scene_copy_markers(Scene *scene_dst, const Scene *scene_src, const int flag)
Definition scene.cc:253
static void remove_sequencer_fcurves(Scene *sce)
Definition scene.cc:1614
static void scene_blend_write(BlendWriter *writer, ID *id, const void *id_address)
Definition scene.cc:1005
eCyclesFeatureSet
Definition scene.cc:2793
@ CYCLES_FEATURES_SUPPORTED
Definition scene.cc:2794
@ CYCLES_FEATURES_EXPERIMENTAL
Definition scene.cc:2795
const char * RE_engine_id_BLENDER_WORKBENCH
Definition scene.cc:1611
static void scene_init_data(ID *id)
Definition scene.cc:146
static char * scene_undo_depsgraph_gen_key(Scene *scene, ViewLayer *view_layer, char *key_full)
Definition scene.cc:3383
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:490
static void prepare_mesh_for_viewport_render(Main *bmain, const Scene *scene, ViewLayer *view_layer)
Definition scene.cc:2427
static Depsgraph ** scene_ensure_depsgraph_p(Main *bmain, Scene *scene, ViewLayer *view_layer)
Definition scene.cc:3332
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:263
static void scene_foreach_rigidbodyworldSceneLooper(RigidBodyWorld *, ID **id_pointer, void *user_data, int cb_flag)
Definition scene.cc:467
const char * RE_engine_id_BLENDER_EEVEE
Definition scene.cc:1609
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:3291
#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:550
static void scene_foreach_id(ID *id, LibraryForeachIDData *data)
Definition scene.cc:844
static void scene_free_data(ID *id)
Definition scene.cc:392
static bool seq_foreach_path_callback(Sequence *seq, void *user_data)
Definition scene.cc:943
static void scene_foreach_cache(ID *id, IDTypeForeachCacheFunctionCallback function_callback, void *user_data)
Definition scene.cc:991
static void scene_foreach_toolsettings(LibraryForeachIDData *data, ToolSettings *toolsett, const bool do_undo_restore, BlendLibReader *reader, ToolSettings *toolsett_old)
Definition scene.cc:621
static void scene_foreach_path(ID *id, BPathForeachPathData *bpath_data)
Definition scene.cc:983
static bool check_rendered_viewport_visible(Main *bmain)
Definition scene.cc:2400
static void depsgraph_key_value_free(void *value)
Definition scene.cc:3253
static void scene_foreach_paint(LibraryForeachIDData *data, Paint *paint, const bool do_undo_restore, BlendLibReader *reader, Paint *paint_old)
Definition scene.cc:577
static void scene_lib_override_apply_post(ID *id_dst, ID *)
Definition scene.cc:1557
void SEQ_tool_settings_free(SequencerToolSettings *tool_settings)
Definition sequencer.cc:369
void SEQ_sequence_base_dupli_recursive(const Scene *scene_src, Scene *scene_dst, ListBase *nseqbase, const ListBase *seqbase, int dupe_flag, const int flag)
Definition sequencer.cc:653
void SEQ_editing_free(Scene *scene, const bool do_id_user)
Definition sequencer.cc:284
SequencerToolSettings * SEQ_tool_settings_init()
Definition sequencer.cc:342
SequencerToolSettings * SEQ_tool_settings_copy(SequencerToolSettings *tool_settings)
Definition sequencer.cc:701
void SEQ_blend_read(BlendDataReader *reader, ListBase *seqbase)
Definition sequencer.cc:922
bool SEQ_is_valid_strip_channel(const Sequence *seq)
Definition sequencer.cc:696
void SEQ_blend_write(BlendWriter *writer, ListBase *seqbase)
Definition sequencer.cc:803
constexpr IDTypeInfo get_type_info()
_W64 int intptr_t
Definition stdint.h:118
bAction * action
eBPathForeachFlag flag
Definition BKE_bpath.hh:88
struct ImageFormatData im_format
struct Base * next
short flag
struct Object * object
struct BlendFileReadReport::@128 count
CurveMap cm[4]
const ViewLayer * view_layer
Definition scene.cc:3225
float mat[4][4]
DupliObject * next
ThumbnailCache * thumbnail_cache
MediaPresence * media_presence
struct SequenceLookup * sequence_lookup
ListBase seqbase
struct PrefetchJob * prefetch_job
ListBase * seqbasep
Sequence * act_seq
ListBase channels
char proxy_dir[1024]
int show_missing_media_flag
ListBase * displayed_channels
ListBase metastack
struct SeqCache * cache
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:69
size_t identifier
Definition BKE_idtype.hh:72
short id_code
Definition DNA_ID.h:413
unsigned int recalc
Definition DNA_ID.h:437
int tag
Definition DNA_ID.h:434
IDProperty * properties
Definition DNA_ID.h:456
struct ID * orig_id
Definition DNA_ID.h:466
char name[66]
Definition DNA_ID.h:425
unsigned int session_uid
Definition DNA_ID.h:454
Stereo3dFormat stereo3d_format
struct Image * stencil
struct Image * canvas
void * first
ListBase scenes
Definition BKE_main.hh:210
ListBase wm
Definition BKE_main.hh:239
ListBase objects
Definition BKE_main.hh:212
void set(const SocketType &input, bool value)
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
float simplify_particles_render
struct ImageFormatData im_format
short preview_pixel_size
short simplify_subsurf_render
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
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
struct UnitSettings unit
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
struct MovieClip * clip
struct Scene * scene
struct Object * scene_camera
struct Mask * mask
ListBase modifiers
struct bSound * sound
struct IDProperty * prop
char filename[256]
char dirpath[768]
StripElem * stripdata
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 * strength_curve
struct IDProperty * prop
View3DShading shading
char name[64]
ListBase curves
const c_style_mat & ptr() const
float xmax
float xmin
float ymax
float ymin
uint8_t flag
Definition wm_window.cc:138