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