Blender V4.5
versioning_290.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8/* allow readfile to use deprecated functionality */
9#define DNA_DEPRECATED_ALLOW
10
11#include <algorithm>
12
13#include "BLI_listbase.h"
14#include "BLI_math_matrix.h"
15#include "BLI_math_rotation.h"
16#include "BLI_string.h"
17#include "BLI_utildefines.h"
18
19/* Define macros in `DNA_genfile.h`. */
20#define DNA_GENFILE_VERSIONING_MACROS
21
22#include "DNA_anim_types.h"
23#include "DNA_armature_types.h"
24#include "DNA_brush_types.h"
25#include "DNA_cachefile_types.h"
28#include "DNA_fluid_types.h"
29#include "DNA_genfile.h"
32#include "DNA_light_types.h"
33#include "DNA_mesh_types.h"
34#include "DNA_meshdata_types.h"
35#include "DNA_modifier_types.h"
36#include "DNA_object_types.h"
37#include "DNA_particle_types.h"
39#include "DNA_rigidbody_types.h"
40#include "DNA_screen_types.h"
41#include "DNA_sequence_types.h"
42#include "DNA_shader_fx_types.h"
43#include "DNA_space_types.h"
44#include "DNA_text_types.h"
45#include "DNA_tracking_types.h"
46#include "DNA_userdef_types.h"
48#include "DNA_workspace_types.h"
49
50#undef DNA_GENFILE_VERSIONING_MACROS
51
52#include "BKE_armature.hh"
53#include "BKE_collection.hh"
54#include "BKE_colortools.hh"
55#include "BKE_cryptomatte.h"
56#include "BKE_curve.hh"
57#include "BKE_customdata.hh"
58#include "BKE_fcurve.hh"
59#include "BKE_gpencil_legacy.h"
60#include "BKE_lib_id.hh"
61#include "BKE_main.hh"
62#include "BKE_mesh.hh"
64#include "BKE_multires.hh"
65#include "BKE_node.hh"
67
68#include "IMB_imbuf_enums.h"
69#include "MEM_guardedalloc.h"
70
71#include "SEQ_proxy.hh"
72#include "SEQ_sequencer.hh"
73#include "SEQ_time.hh"
74
75#include "BLO_readfile.hh"
76#include "readfile.hh"
77#include "versioning_common.hh"
78
79/* Make preferences read-only, use `versioning_userdef.cc`. */
80#define U (*((const UserDef *)&U))
81
83{
85
86 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
87 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
88 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
89 switch (sl->spacetype) {
90 case SPACE_SEQ: {
91 SpaceSeq *sseq = (SpaceSeq *)sl;
92 if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
93 render_size = eSpaceSeq_Proxy_RenderSize(sseq->render_size);
94 break;
95 }
96 }
97 }
98 }
99 }
100 }
101
102 return render_size;
103}
104
105static bool can_use_proxy(const Strip *strip, int psize)
106{
107 if (strip->data->proxy == nullptr) {
108 return false;
109 }
110 short size_flags = strip->data->proxy->build_size_flags;
111 return (strip->flag & SEQ_USE_PROXY) != 0 && psize != IMB_PROXY_NONE &&
112 (size_flags & psize) != 0;
113}
114
115/* image_size is width or height depending what RNA property is converted - X or Y. */
117 const Scene *scene,
118 const char *path,
119 const int image_size,
120 const int scene_size)
121{
122 if (scene->adt == nullptr || scene->adt->action == nullptr) {
123 return;
124 }
125
126 /* Hardcoded legacy bit-flags which has been removed. */
127 const uint32_t use_transform_flag = (1 << 16);
128 const uint32_t use_crop_flag = (1 << 17);
129
130 /* Convert offset animation, but only if crop is not used. */
131 if ((strip->flag & use_transform_flag) != 0 && (strip->flag & use_crop_flag) == 0) {
132 FCurve *fcu = BKE_fcurve_find(&scene->adt->action->curves, path, 0);
133 if (fcu != nullptr && !BKE_fcurve_is_empty(fcu)) {
134 BezTriple *bezt = fcu->bezt;
135 for (int i = 0; i < fcu->totvert; i++, bezt++) {
136 /* Same math as with old_image_center_*, but simplified. */
137 bezt->vec[0][1] = (image_size - scene_size) / 2 + bezt->vec[0][1];
138 bezt->vec[1][1] = (image_size - scene_size) / 2 + bezt->vec[1][1];
139 bezt->vec[2][1] = (image_size - scene_size) / 2 + bezt->vec[2][1];
140 }
141 }
142 }
143 else { /* Else, remove offset animation. */
144 FCurve *fcu = BKE_fcurve_find(&scene->adt->action->curves, path, 0);
145 BLI_remlink(&scene->adt->action->curves, fcu);
146 BKE_fcurve_free(fcu);
147 }
148}
149
150static void strip_convert_transform_crop(const Scene *scene,
151 Strip *strip,
152 const eSpaceSeq_Proxy_RenderSize render_size)
153{
154 if (strip->data->transform == nullptr) {
155 strip->data->transform = MEM_callocN<StripTransform>(__func__);
156 }
157 if (strip->data->crop == nullptr) {
158 strip->data->crop = MEM_callocN<StripCrop>(__func__);
159 }
160
161 StripCrop *c = strip->data->crop;
162 StripTransform *t = strip->data->transform;
163 int old_image_center_x = scene->r.xsch / 2;
164 int old_image_center_y = scene->r.ysch / 2;
165 int image_size_x = scene->r.xsch;
166 int image_size_y = scene->r.ysch;
167
168 /* Hard-coded legacy bit-flags which has been removed. */
169 const uint32_t use_transform_flag = (1 << 16);
170 const uint32_t use_crop_flag = (1 << 17);
171
172 const StripElem *s_elem = strip->data->stripdata;
173 if (s_elem != nullptr) {
174 image_size_x = s_elem->orig_width;
175 image_size_y = s_elem->orig_height;
176
177 if (can_use_proxy(strip, blender::seq::rendersize_to_proxysize(render_size))) {
178 image_size_x /= blender::seq::rendersize_to_scale_factor(render_size);
179 image_size_y /= blender::seq::rendersize_to_scale_factor(render_size);
180 }
181 }
182
183 /* Default scale. */
184 if (t->scale_x == 0.0f && t->scale_y == 0.0f) {
185 t->scale_x = 1.0f;
186 t->scale_y = 1.0f;
187 }
188
189 /* Clear crop if it was unused. This must happen before converting values. */
190 if ((strip->flag & use_crop_flag) == 0) {
191 c->bottom = c->top = c->left = c->right = 0;
192 }
193
194 if ((strip->flag & use_transform_flag) == 0) {
195 t->xofs = t->yofs = 0;
196
197 /* Reverse scale to fit for strips not using offset. */
198 float project_aspect = float(scene->r.xsch) / float(scene->r.ysch);
199 float image_aspect = float(image_size_x) / float(image_size_y);
200 if (project_aspect > image_aspect) {
201 t->scale_x = project_aspect / image_aspect;
202 }
203 else {
204 t->scale_y = image_aspect / project_aspect;
205 }
206 }
207
208 if ((strip->flag & use_crop_flag) != 0 && (strip->flag & use_transform_flag) == 0) {
209 /* Calculate image offset. */
210 float s_x = scene->r.xsch / image_size_x;
211 float s_y = scene->r.ysch / image_size_y;
212 old_image_center_x += c->right * s_x - c->left * s_x;
213 old_image_center_y += c->top * s_y - c->bottom * s_y;
214
215 /* Convert crop to scale. */
216 int cropped_image_size_x = image_size_x - c->right - c->left;
217 int cropped_image_size_y = image_size_y - c->top - c->bottom;
218 c->bottom = c->top = c->left = c->right = 0;
219 t->scale_x *= float(image_size_x) / float(cropped_image_size_x);
220 t->scale_y *= float(image_size_y) / float(cropped_image_size_y);
221 }
222
223 if ((strip->flag & use_transform_flag) != 0) {
224 /* Convert image offset. */
225 old_image_center_x = image_size_x / 2 - c->left + t->xofs;
226 old_image_center_y = image_size_y / 2 - c->bottom + t->yofs;
227
228 /* Preserve original image size. */
229 t->scale_x = t->scale_y = std::max(float(image_size_x) / float(scene->r.xsch),
230 float(image_size_y) / float(scene->r.ysch));
231
232 /* Convert crop. */
233 if ((strip->flag & use_crop_flag) != 0) {
234 c->top /= t->scale_x;
235 c->bottom /= t->scale_x;
236 c->left /= t->scale_x;
237 c->right /= t->scale_x;
238 }
239 }
240
241 t->xofs = old_image_center_x - scene->r.xsch / 2;
242 t->yofs = old_image_center_y - scene->r.ysch / 2;
243
244 char name_esc[(sizeof(strip->name) - 2) * 2], *path;
245 BLI_str_escape(name_esc, strip->name + 2, sizeof(name_esc));
246
247 path = BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].transform.offset_x", name_esc);
248 strip_convert_transform_animation(strip, scene, path, image_size_x, scene->r.xsch);
249 MEM_freeN(path);
250 path = BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].transform.offset_y", name_esc);
251 strip_convert_transform_animation(strip, scene, path, image_size_y, scene->r.ysch);
252 MEM_freeN(path);
253
254 strip->flag &= ~use_transform_flag;
255 strip->flag &= ~use_crop_flag;
256}
257
258static void strip_convert_transform_crop_lb(const Scene *scene,
259 const ListBase *lb,
260 const eSpaceSeq_Proxy_RenderSize render_size)
261{
262
263 LISTBASE_FOREACH (Strip *, strip, lb) {
264 if (!ELEM(strip->type, STRIP_TYPE_SOUND_RAM, STRIP_TYPE_SOUND_HD)) {
265 strip_convert_transform_crop(scene, strip, render_size);
266 }
267 if (strip->type == STRIP_TYPE_META) {
268 strip_convert_transform_crop_lb(scene, &strip->seqbase, render_size);
269 }
270 }
271}
272
274 const char *path,
275 const float scale_to_fit_factor)
276{
277 if (scene->adt == nullptr || scene->adt->action == nullptr) {
278 return;
279 }
280
281 FCurve *fcu = BKE_fcurve_find(&scene->adt->action->curves, path, 0);
282 if (fcu != nullptr && !BKE_fcurve_is_empty(fcu)) {
283 BezTriple *bezt = fcu->bezt;
284 for (int i = 0; i < fcu->totvert; i++, bezt++) {
285 /* Same math as with old_image_center_*, but simplified. */
286 bezt->vec[0][1] *= scale_to_fit_factor;
287 bezt->vec[1][1] *= scale_to_fit_factor;
288 bezt->vec[2][1] *= scale_to_fit_factor;
289 }
290 }
291}
292
293static void strip_convert_transform_crop_2(const Scene *scene,
294 Strip *strip,
295 const eSpaceSeq_Proxy_RenderSize render_size)
296{
297 const StripElem *s_elem = strip->data->stripdata;
298 if (s_elem == nullptr) {
299 return;
300 }
301
302 StripCrop *c = strip->data->crop;
303 StripTransform *t = strip->data->transform;
304 int image_size_x = s_elem->orig_width;
305 int image_size_y = s_elem->orig_height;
306
307 if (can_use_proxy(strip, blender::seq::rendersize_to_proxysize(render_size))) {
308 image_size_x /= blender::seq::rendersize_to_scale_factor(render_size);
309 image_size_y /= blender::seq::rendersize_to_scale_factor(render_size);
310 }
311
312 /* Calculate scale factor, so image fits in preview area with original aspect ratio. */
313 const float scale_to_fit_factor = std::min(float(scene->r.xsch) / float(image_size_x),
314 float(scene->r.ysch) / float(image_size_y));
315 t->scale_x *= scale_to_fit_factor;
316 t->scale_y *= scale_to_fit_factor;
317 c->top /= scale_to_fit_factor;
318 c->bottom /= scale_to_fit_factor;
319 c->left /= scale_to_fit_factor;
320 c->right /= scale_to_fit_factor;
321
322 char name_esc[(sizeof(strip->name) - 2) * 2], *path;
323 BLI_str_escape(name_esc, strip->name + 2, sizeof(name_esc));
324 path = BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].transform.scale_x", name_esc);
325 strip_convert_transform_animation_2(scene, path, scale_to_fit_factor);
326 MEM_freeN(path);
327 path = BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].transform.scale_y", name_esc);
328 strip_convert_transform_animation_2(scene, path, scale_to_fit_factor);
329 MEM_freeN(path);
330 path = BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].crop.min_x", name_esc);
331 strip_convert_transform_animation_2(scene, path, 1 / scale_to_fit_factor);
332 MEM_freeN(path);
333 path = BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].crop.max_x", name_esc);
334 strip_convert_transform_animation_2(scene, path, 1 / scale_to_fit_factor);
335 MEM_freeN(path);
336 path = BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].crop.min_y", name_esc);
337 strip_convert_transform_animation_2(scene, path, 1 / scale_to_fit_factor);
338 MEM_freeN(path);
339 path = BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].crop.max_x", name_esc);
340 strip_convert_transform_animation_2(scene, path, 1 / scale_to_fit_factor);
341 MEM_freeN(path);
342}
343
345 const ListBase *lb,
346 const eSpaceSeq_Proxy_RenderSize render_size)
347{
348
349 LISTBASE_FOREACH (Strip *, strip, lb) {
350 if (!ELEM(strip->type, STRIP_TYPE_SOUND_RAM, STRIP_TYPE_SOUND_HD)) {
351 strip_convert_transform_crop_2(scene, strip, render_size);
352 }
353 if (strip->type == STRIP_TYPE_META) {
354 strip_convert_transform_crop_lb_2(scene, &strip->seqbase, render_size);
355 }
356 }
357}
358
360{
362
363 if (ed == nullptr) {
364 return;
365 }
366
368 /* Update ms->disp_range from meta. */
369 if (ms->disp_range[0] == ms->disp_range[1]) {
370 ms->disp_range[0] = blender::seq::time_left_handle_frame_get(scene, ms->parent_strip);
371 ms->disp_range[1] = blender::seq::time_right_handle_frame_get(scene, ms->parent_strip);
372 }
373
374 /* Update meta strip endpoints. */
375 blender::seq::time_left_handle_frame_set(scene, ms->parent_strip, ms->disp_range[0]);
376 blender::seq::time_right_handle_frame_set(scene, ms->parent_strip, ms->disp_range[1]);
377
378 /* Recalculate effects using meta strip. */
379 LISTBASE_FOREACH (Strip *, strip, ms->oldbasep) {
380 if (strip->input2) {
381 strip->start = strip->startdisp = max_ii(strip->input1->startdisp,
382 strip->input2->startdisp);
383 strip->enddisp = min_ii(strip->input1->enddisp, strip->input2->enddisp);
384 }
385 }
386
387 /* Ensure that active seqbase points to active meta strip seqbase. */
390 }
391}
392
394 const int node_type,
395 const char *old_name,
396 const char *new_name)
397{
398 /* Duplicate a link going into the original socket. */
399 LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) {
400 if (link->tonode->type_legacy == node_type) {
401 bNode *node = link->tonode;
402 bNodeSocket *dest_socket = blender::bke::node_find_socket(*node, SOCK_IN, new_name);
403 BLI_assert(dest_socket);
404 if (STREQ(link->tosock->name, old_name)) {
405 blender::bke::node_add_link(*ntree, *link->fromnode, *link->fromsock, *node, *dest_socket);
406 }
407 }
408 }
409
410 /* Duplicate the default value from the old socket and assign it to the new socket. */
411 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
412 if (node->type_legacy == node_type) {
413 bNodeSocket *source_socket = blender::bke::node_find_socket(*node, SOCK_IN, old_name);
414 bNodeSocket *dest_socket = blender::bke::node_find_socket(*node, SOCK_IN, new_name);
415 BLI_assert(source_socket && dest_socket);
416 if (dest_socket->default_value) {
417 MEM_freeN(dest_socket->default_value);
418 }
419 dest_socket->default_value = MEM_dupallocN(source_socket->default_value);
420 }
421 }
422}
423
425{
426 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 290, 1)) {
427 /* Patch old grease pencil modifiers material filter. */
428 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
429 LISTBASE_FOREACH (GpencilModifierData *, md, &ob->greasepencil_modifiers) {
430 switch (md->type) {
433 if (gpmd->materialname[0] != '\0') {
434 gpmd->material = static_cast<Material *>(
435 BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2));
436 gpmd->materialname[0] = '\0';
437 }
438 break;
439 }
442 if (gpmd->materialname[0] != '\0') {
443 gpmd->material = static_cast<Material *>(
444 BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2));
445 gpmd->materialname[0] = '\0';
446 }
447 break;
448 }
451 if (gpmd->materialname[0] != '\0') {
452 gpmd->material = static_cast<Material *>(
453 BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2));
454 gpmd->materialname[0] = '\0';
455 }
456 break;
457 }
460 if (gpmd->materialname[0] != '\0') {
461 gpmd->material = static_cast<Material *>(
462 BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2));
463 gpmd->materialname[0] = '\0';
464 }
465 break;
466 }
469 if (gpmd->materialname[0] != '\0') {
470 gpmd->material = static_cast<Material *>(
471 BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2));
472 gpmd->materialname[0] = '\0';
473 }
474 break;
475 }
478 if (gpmd->materialname[0] != '\0') {
479 gpmd->material = static_cast<Material *>(
480 BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2));
481 gpmd->materialname[0] = '\0';
482 }
483 break;
484 }
487 if (gpmd->materialname[0] != '\0') {
488 gpmd->material = static_cast<Material *>(
489 BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2));
490 gpmd->materialname[0] = '\0';
491 }
492 break;
493 }
496 if (gpmd->materialname[0] != '\0') {
497 gpmd->material = static_cast<Material *>(
498 BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2));
499 gpmd->materialname[0] = '\0';
500 }
501 break;
502 }
505 if (gpmd->materialname[0] != '\0') {
506 gpmd->material = static_cast<Material *>(
507 BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2));
508 gpmd->materialname[0] = '\0';
509 }
510 break;
511 }
514 if (gpmd->materialname[0] != '\0') {
515 gpmd->material = static_cast<Material *>(
516 BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2));
517 gpmd->materialname[0] = '\0';
518 }
519 break;
520 }
523 if (gpmd->materialname[0] != '\0') {
524 gpmd->material = static_cast<Material *>(
525 BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2));
526 gpmd->materialname[0] = '\0';
527 }
528 break;
529 }
532 if (gpmd->materialname[0] != '\0') {
533 gpmd->material = static_cast<Material *>(
534 BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2));
535 gpmd->materialname[0] = '\0';
536 }
537 break;
538 }
541 if (gpmd->materialname[0] != '\0') {
542 gpmd->material = static_cast<Material *>(
543 BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2));
544 gpmd->materialname[0] = '\0';
545 }
546 break;
547 }
550 if (gpmd->materialname[0] != '\0') {
551 gpmd->material = static_cast<Material *>(
552 BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2));
553 gpmd->materialname[0] = '\0';
554 }
555 break;
556 }
557 default:
558 break;
559 }
560 }
561 }
562
563 /* Patch first frame for old files. */
564 Scene *scene = static_cast<Scene *>(bmain->scenes.first);
565 if (scene != nullptr) {
566 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
567 if (ob->type != OB_GPENCIL_LEGACY) {
568 continue;
569 }
570 bGPdata *gpd = static_cast<bGPdata *>(ob->data);
571 LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
572 bGPDframe *gpf = static_cast<bGPDframe *>(gpl->frames.first);
573 if (gpf && gpf->framenum > scene->r.sfra) {
574 bGPDframe *gpf_dup = BKE_gpencil_frame_duplicate(gpf, true);
575 gpf_dup->framenum = scene->r.sfra;
576 BLI_addhead(&gpl->frames, gpf_dup);
577 }
578 }
579 }
580 }
581 }
582
583 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 291, 1)) {
584 LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
585 if (BKE_collection_cycles_fix(bmain, collection)) {
586 printf(
587 "WARNING: Cycle detected in collection '%s', fixed as best as possible.\n"
588 "You may have to reconstruct your View Layers...\n",
589 collection->id.name);
590 }
591 }
592 }
593
594 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 291, 8)) {
599
608 }
609
610 /* Convert all Multires displacement to Catmull-Clark subdivision limit surface. */
611 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 292, 1)) {
612 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
613 LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
614 if (md->type == eModifierType_Multires) {
616 if (mmd->simple) {
618 }
619 }
620 }
621 }
622 }
623
624 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 292, 2)) {
625
627
628 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
629 if (scene->ed != nullptr) {
630 strip_convert_transform_crop_lb(scene, &scene->ed->seqbase, render_size);
631 }
632 }
633 }
634
635 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 292, 8)) {
636 /* Systematically rebuild pose-bones to ensure consistent ordering matching the one of bones in
637 * Armature obdata. */
638 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
639 if (ob->type == OB_ARMATURE) {
640 BKE_pose_rebuild(bmain, ob, static_cast<bArmature *>(ob->data), true);
641 }
642 }
643
644 /* Wet Paint Radius Factor */
645 LISTBASE_FOREACH (Brush *, br, &bmain->brushes) {
646 if (br->ob_mode & OB_MODE_SCULPT && br->wet_paint_radius_factor == 0.0f) {
647 br->wet_paint_radius_factor = 1.0f;
648 }
649 }
650
652 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
653 if (scene->ed != nullptr) {
654 strip_convert_transform_crop_lb_2(scene, &scene->ed->seqbase, render_size);
655 }
656 }
657 }
658
659 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 293, 16)) {
660 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
662 }
663
664 /* Add a separate socket for Grid node X and Y size. */
665 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
666 if (ntree->type == NTREE_GEOMETRY) {
668 }
670 }
671 }
672
673 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 293, 20)) {
674 /* Set zero user text objects to have a fake user. */
675 LISTBASE_FOREACH (Text *, text, &bmain->texts) {
676 if (text->id.us == 0) {
677 id_fake_user_set(&text->id);
678 }
679 }
680 }
681
688}
689
691{
692 const bool was_closed_x = panel->flag & PNL_UNUSED_1;
693 const bool was_closed_y = panel->flag & PNL_CLOSED; /* That value was the Y closed flag. */
694
695 SET_FLAG_FROM_TEST(panel->flag, was_closed_x || was_closed_y, PNL_CLOSED);
696
697 /* Clear the old PNL_CLOSEDX flag. */
698 panel->flag &= ~PNL_UNUSED_1;
699
700 LISTBASE_FOREACH (Panel *, child_panel, &panel->children) {
702 }
703}
704
706{
707 /* Change to generic named float/float3 attributes. */
708 enum {
709 CD_LOCATION = 43,
710 CD_RADIUS = 44,
711 };
712
713 for (int i = 0; i < pdata->totlayer; i++) {
714 CustomDataLayer *layer = &pdata->layers[i];
715 if (layer->type == CD_LOCATION) {
716 STRNCPY(layer->name, "Position");
717 layer->type = CD_PROP_FLOAT3;
718 }
719 else if (layer->type == CD_RADIUS) {
720 STRNCPY(layer->name, "Radius");
721 layer->type = CD_PROP_FLOAT;
722 }
723 }
724}
725
727{
728 /* Change from capital initial letter to lower case (#82693). */
729 for (int i = 0; i < pdata->totlayer; i++) {
730 CustomDataLayer *layer = &pdata->layers[i];
731 if (layer->type == CD_PROP_FLOAT3 && STREQ(layer->name, "Position")) {
732 STRNCPY(layer->name, "position");
733 }
734 else if (layer->type == CD_PROP_FLOAT && STREQ(layer->name, "Radius")) {
735 STRNCPY(layer->name, "radius");
736 }
737 }
738}
739
740/* Move FCurve handles towards the control point in such a way that the curve itself doesn't
741 * change. Since 2.91 FCurves are computed slightly differently, which requires this update to keep
742 * the same animation result. Previous versions scaled down overlapping handles during evaluation.
743 * This function applies the old correction to the actual animation data instead. */
745{
746 uint i = 1;
747 for (BezTriple *bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
748 /* Only adjust bezier key-frames. */
749 if (bezt->ipo != BEZT_IPO_BEZ) {
750 continue;
751 }
752
753 BezTriple *nextbezt = bezt + 1;
754 const float v1[2] = {bezt->vec[1][0], bezt->vec[1][1]};
755 const float v2[2] = {bezt->vec[2][0], bezt->vec[2][1]};
756 const float v3[2] = {nextbezt->vec[0][0], nextbezt->vec[0][1]};
757 const float v4[2] = {nextbezt->vec[1][0], nextbezt->vec[1][1]};
758
759 /* If the handles have no length, no need to do any corrections. */
760 if (v1[0] == v2[0] && v3[0] == v4[0]) {
761 continue;
762 }
763
764 /* Calculate handle deltas. */
765 float delta1[2], delta2[2];
766 sub_v2_v2v2(delta1, v1, v2);
767 sub_v2_v2v2(delta2, v4, v3);
768
769 const float len1 = fabsf(delta1[0]); /* Length of handle of first key. */
770 const float len2 = fabsf(delta2[0]); /* Length of handle of second key. */
771
772 /* Overlapping handles used to be internally scaled down in previous versions.
773 * We bake the handles onto these previously virtual values. */
774 const float time_delta = v4[0] - v1[0];
775 const float total_len = len1 + len2;
776 if (total_len <= time_delta) {
777 continue;
778 }
779
780 const float factor = time_delta / total_len;
781 /* Current key-frame's right handle: */
782 madd_v2_v2v2fl(bezt->vec[2], v1, delta1, -factor); /* vec[2] = v1 - factor * delta1 */
783 /* Next key-frame's left handle: */
784 madd_v2_v2v2fl(nextbezt->vec[0], v4, delta2, -factor); /* vec[0] = v4 - factor * delta2 */
785 }
786}
787
789{
790 LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) {
791 if (link->tonode->type_legacy == GEO_NODE_JOIN_GEOMETRY &&
792 !(link->tosock->flag & SOCK_MULTI_INPUT))
793 {
794 link->tosock = static_cast<bNodeSocket *>(link->tonode->inputs.first);
795 }
796 }
797 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
798 if (node->type_legacy == GEO_NODE_JOIN_GEOMETRY) {
799 bNodeSocket *socket = static_cast<bNodeSocket *>(node->inputs.first);
800 socket->flag |= SOCK_MULTI_INPUT;
801 socket->limit = 4095;
802 blender::bke::node_remove_socket(*ntree, *node, *socket->next);
803 }
804 }
805}
806
807/* NOLINTNEXTLINE: readability-function-size */
808void blo_do_versions_290(FileData *fd, Library * /*lib*/, Main *bmain)
809{
810 UNUSED_VARS(fd);
811
812 if (MAIN_VERSION_FILE_ATLEAST(bmain, 290, 2) && MAIN_VERSION_FILE_OLDER(bmain, 291, 1)) {
813 /* In this range, the extrude manifold could generate meshes with degenerated face. */
814 LISTBASE_FOREACH (Mesh *, me, &bmain->meshes) {
815 const MPoly *polys = static_cast<const MPoly *>(
816 CustomData_get_layer(&me->face_data, CD_MPOLY));
817 for (const int i : blender::IndexRange(me->faces_num)) {
818 if (polys[i].totloop == 2) {
819 bool changed;
823 me,
824 reinterpret_cast<float(*)[3]>(me->vert_positions_for_write().data()),
825 me->verts_num,
826 me->edges_for_write().data(),
827 me->edges_num,
829 &me->fdata_legacy, CD_MFACE, me->totface_legacy),
830 me->totface_legacy,
831 me->corner_verts().data(),
832 me->corner_edges_for_write().data(),
833 me->corners_num,
834 me->face_offsets().data(),
835 me->faces_num,
836 me->deform_verts_for_write().data(),
837 false,
838 true,
839 &changed);
840 break;
841 }
842 }
843 }
844 }
845
847 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 290, 2)) {
848 {
849 short id_codes[] = {ID_BR, ID_PAL};
850 for (int i = 0; i < ARRAY_SIZE(id_codes); i++) {
851 ListBase *lb = which_libbase(bmain, id_codes[i]);
853 }
854 }
855
856 if (!DNA_struct_member_exists(fd->filesdna, "SpaceImage", "float", "uv_opacity")) {
857 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
858 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
859 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
860 if (sl->spacetype == SPACE_IMAGE) {
861 SpaceImage *sima = (SpaceImage *)sl;
862 sima->uv_opacity = 1.0f;
863 }
864 }
865 }
866 }
867 }
868
869 /* Init Grease Pencil new random curves. */
870 if (!DNA_struct_member_exists(fd->filesdna, "BrushGpencilSettings", "float", "random_hue")) {
871 LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
872 if ((brush->gpencil_settings) && (brush->gpencil_settings->curve_rand_pressure == nullptr))
873 {
874 brush->gpencil_settings->curve_rand_pressure = BKE_curvemapping_add(
875 1, 0.0f, 0.0f, 1.0f, 1.0f);
876 brush->gpencil_settings->curve_rand_strength = BKE_curvemapping_add(
877 1, 0.0f, 0.0f, 1.0f, 1.0f);
878 brush->gpencil_settings->curve_rand_uv = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
879 brush->gpencil_settings->curve_rand_hue = BKE_curvemapping_add(
880 1, 0.0f, 0.0f, 1.0f, 1.0f);
881 brush->gpencil_settings->curve_rand_saturation = BKE_curvemapping_add(
882 1, 0.0f, 0.0f, 1.0f, 1.0f);
883 brush->gpencil_settings->curve_rand_value = BKE_curvemapping_add(
884 1, 0.0f, 0.0f, 1.0f, 1.0f);
885 }
886 }
887 }
888 }
889
890 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 290, 4)) {
891 /* Clear old deprecated bit-flag from edit weights modifiers, we now use it for something else.
892 */
893 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
894 LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
895 if (md->type == eModifierType_WeightVGEdit) {
897 }
898 }
899 }
900
901 /* Initialize parameters of the new Nishita sky model. */
902 if (!DNA_struct_member_exists(fd->filesdna, "NodeTexSky", "float", "sun_size")) {
903 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
904 if (ntree->type == NTREE_SHADER) {
905 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
906 if (node->type_legacy == SH_NODE_TEX_SKY && node->storage) {
907 NodeTexSky *tex = (NodeTexSky *)node->storage;
908 tex->sun_disc = true;
909 tex->sun_size = DEG2RADF(0.545);
910 tex->sun_elevation = M_PI_2;
911 tex->sun_rotation = 0.0f;
912 tex->altitude = 0.0f;
913 tex->air_density = 1.0f;
914 tex->dust_density = 1.0f;
915 tex->ozone_density = 1.0f;
916 }
917 }
918 }
919 }
921 }
922 }
923
924 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 290, 5)) {
925 /* New denoiser settings. */
926 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
927 IDProperty *cscene = version_cycles_properties_from_ID(&scene->id);
928
929 /* Check if any view layers had (optix) denoising enabled.
930 * Both view and render layers because conversion only happens after linking. */
931 bool use_optix = false;
932 bool use_denoising = false;
933 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
934 IDProperty *cview_layer = version_cycles_properties_from_view_layer(view_layer);
935 if (cview_layer) {
936 use_denoising = use_denoising ||
937 version_cycles_property_boolean(cview_layer, "use_denoising", false);
938 use_optix = use_optix ||
939 version_cycles_property_boolean(cview_layer, "use_optix_denoising", false);
940 }
941 }
942 LISTBASE_FOREACH (SceneRenderLayer *, render_layer, &scene->r.layers) {
943 IDProperty *crender_layer = version_cycles_properties_from_render_layer(render_layer);
944 if (crender_layer) {
945 use_denoising = use_denoising ||
946 version_cycles_property_boolean(crender_layer, "use_denoising", false);
947 use_optix = use_optix ||
948 version_cycles_property_boolean(crender_layer, "use_optix_denoising", false);
949 }
950 }
951
952 if (cscene) {
953 enum {
954 DENOISER_AUTO = 0,
955 DENOISER_NLM = 1,
956 DENOISER_OPTIX = 2,
957 };
958
959 /* Enable denoiser if it was enabled for one view layer before. */
961 cscene, "denoiser", (use_optix) ? DENOISER_OPTIX : DENOISER_NLM);
962 version_cycles_property_boolean_set(cscene, "use_denoising", use_denoising);
963
964 /* Migrate Optix denoiser to new settings. */
965 if (version_cycles_property_int(cscene, "preview_denoising", 0)) {
966 version_cycles_property_boolean_set(cscene, "use_preview_denoising", true);
967 version_cycles_property_int_set(cscene, "preview_denoiser", DENOISER_AUTO);
968 }
969 }
970
971 /* Enable denoising in all view layer if there was no denoising before,
972 * so that enabling the scene settings auto enables it for all view layers. */
973 if (!use_denoising) {
974 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
975 IDProperty *cview_layer = version_cycles_properties_from_view_layer(view_layer);
976 if (cview_layer) {
977 version_cycles_property_boolean_set(cview_layer, "use_denoising", true);
978 }
979 }
980 LISTBASE_FOREACH (SceneRenderLayer *, render_layer, &scene->r.layers) {
981 IDProperty *crender_layer = version_cycles_properties_from_render_layer(render_layer);
982 if (crender_layer) {
983 version_cycles_property_boolean_set(crender_layer, "use_denoising", true);
984 }
985 }
986 }
987 }
988 }
989
990 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 290, 6)) {
991 /* Transition to saving expansion for all of a modifier's sub-panels. */
992 if (!DNA_struct_member_exists(fd->filesdna, "ModifierData", "short", "ui_expand_flag")) {
993 LISTBASE_FOREACH (Object *, object, &bmain->objects) {
994 LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
995 if (md->mode & eModifierMode_Expanded_DEPRECATED) {
996 md->ui_expand_flag = UI_PANEL_DATA_EXPAND_ROOT;
997 }
998 else {
999 md->ui_expand_flag = 0;
1000 }
1001 }
1002 }
1003 }
1004
1005 /* EEVEE Motion blur new parameters. */
1006 if (!DNA_struct_member_exists(fd->filesdna, "SceneEEVEE", "float", "motion_blur_depth_scale"))
1007 {
1008 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1009 scene->eevee.motion_blur_depth_scale = 100.0f;
1010 scene->eevee.motion_blur_max = 32;
1011 }
1012 }
1013
1014 if (!DNA_struct_member_exists(fd->filesdna, "SceneEEVEE", "int", "motion_blur_steps")) {
1015 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1016 scene->eevee.motion_blur_steps = 1;
1017 }
1018 }
1019
1020 /* Transition to saving expansion for all of a constraint's sub-panels. */
1021 if (!DNA_struct_member_exists(fd->filesdna, "bConstraint", "short", "ui_expand_flag")) {
1022 LISTBASE_FOREACH (Object *, object, &bmain->objects) {
1023 LISTBASE_FOREACH (bConstraint *, con, &object->constraints) {
1024 if (con->flag & CONSTRAINT_EXPAND_DEPRECATED) {
1025 con->ui_expand_flag = UI_PANEL_DATA_EXPAND_ROOT;
1026 }
1027 else {
1028 con->ui_expand_flag = 0;
1029 }
1030 }
1031 }
1032 }
1033
1034 /* Transition to saving expansion for all of grease pencil modifier's sub-panels. */
1035 if (!DNA_struct_member_exists(fd->filesdna, "GpencilModifierData", "short", "ui_expand_flag"))
1036 {
1037 LISTBASE_FOREACH (Object *, object, &bmain->objects) {
1038 LISTBASE_FOREACH (GpencilModifierData *, md, &object->greasepencil_modifiers) {
1039 if (md->mode & eGpencilModifierMode_Expanded_DEPRECATED) {
1040 md->ui_expand_flag = UI_PANEL_DATA_EXPAND_ROOT;
1041 }
1042 else {
1043 md->ui_expand_flag = 0;
1044 }
1045 }
1046 }
1047 }
1048
1049 /* Transition to saving expansion for all of an effect's sub-panels. */
1050 if (!DNA_struct_member_exists(fd->filesdna, "ShaderFxData", "short", "ui_expand_flag")) {
1051 LISTBASE_FOREACH (Object *, object, &bmain->objects) {
1052 LISTBASE_FOREACH (ShaderFxData *, fx, &object->shader_fx) {
1053 if (fx->mode & eShaderFxMode_Expanded_DEPRECATED) {
1054 fx->ui_expand_flag = UI_PANEL_DATA_EXPAND_ROOT;
1055 }
1056 else {
1057 fx->ui_expand_flag = 0;
1058 }
1059 }
1060 }
1061 }
1062
1063 /* Refactor bevel profile type to use an enum. */
1064 if (!DNA_struct_member_exists(fd->filesdna, "BevelModifierData", "short", "profile_type")) {
1065 LISTBASE_FOREACH (Object *, object, &bmain->objects) {
1066 LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
1067 if (md->type == eModifierType_Bevel) {
1069 bool use_custom_profile = bmd->flags & MOD_BEVEL_CUSTOM_PROFILE_DEPRECATED;
1070 bmd->profile_type = use_custom_profile ? MOD_BEVEL_PROFILE_CUSTOM :
1072 }
1073 }
1074 }
1075 }
1076
1077 /* Change ocean modifier values from [0, 10] to [0, 1] ranges. */
1078 LISTBASE_FOREACH (Object *, object, &bmain->objects) {
1079 LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
1080 if (md->type == eModifierType_Ocean) {
1082 omd->wave_alignment *= 0.1f;
1083 omd->sharpen_peak_jonswap *= 0.1f;
1084 }
1085 }
1086 }
1087 }
1088
1089 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 291, 1)) {
1090
1091 /* Initialize additional parameter of the Nishita sky model and change altitude unit. */
1092 if (!DNA_struct_member_exists(fd->filesdna, "NodeTexSky", "float", "sun_intensity")) {
1093 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1094 if (ntree->type == NTREE_SHADER) {
1095 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
1096 if (node->type_legacy == SH_NODE_TEX_SKY && node->storage) {
1097 NodeTexSky *tex = (NodeTexSky *)node->storage;
1098 tex->sun_intensity = 1.0f;
1099 tex->altitude *= 0.001f;
1100 }
1101 }
1102 }
1103 }
1105 }
1106
1107 /* Refactor bevel affect type to use an enum. */
1108 if (!DNA_struct_member_exists(fd->filesdna, "BevelModifierData", "char", "affect_type")) {
1109 LISTBASE_FOREACH (Object *, object, &bmain->objects) {
1110 LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
1111 if (md->type == eModifierType_Bevel) {
1113 const bool use_vertex_bevel = bmd->flags & MOD_BEVEL_VERT_DEPRECATED;
1114 bmd->affect_type = use_vertex_bevel ? MOD_BEVEL_AFFECT_VERTICES :
1116 }
1117 }
1118 }
1119 }
1120
1121 /* Initialize additional velocity parameter for #CacheFile's. */
1122 if (!DNA_struct_member_exists(
1123 fd->filesdna, "MeshSeqCacheModifierData", "float", "velocity_scale"))
1124 {
1125 LISTBASE_FOREACH (Object *, object, &bmain->objects) {
1126 LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
1127 if (md->type == eModifierType_MeshSequenceCache) {
1129 mcmd->velocity_scale = 1.0f;
1130 }
1131 }
1132 }
1133 }
1134
1135 if (!DNA_struct_member_exists(fd->filesdna, "CacheFile", "char", "velocity_unit")) {
1136 LISTBASE_FOREACH (CacheFile *, cache_file, &bmain->cachefiles) {
1137 STRNCPY(cache_file->velocity_name, ".velocities");
1138 cache_file->velocity_unit = CACHEFILE_VELOCITY_UNIT_SECOND;
1139 }
1140 }
1141
1142 if (!DNA_struct_member_exists(fd->filesdna, "OceanModifierData", "int", "viewport_resolution"))
1143 {
1144 LISTBASE_FOREACH (Object *, object, &bmain->objects) {
1145 LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
1146 if (md->type == eModifierType_Ocean) {
1148 omd->viewport_resolution = omd->resolution;
1149 }
1150 }
1151 }
1152 }
1153
1154 /* Remove panel X axis collapsing, a remnant of horizontal panel alignment. */
1155 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1156 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1157 LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
1158 LISTBASE_FOREACH (Panel *, panel, &region->panels) {
1160 }
1161 }
1162 }
1163 }
1164 }
1165
1166 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 291, 2)) {
1167 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1168 RigidBodyWorld *rbw = scene->rigidbody_world;
1169
1170 if (rbw == nullptr) {
1171 continue;
1172 }
1173
1174 /* The sub-step method changed from "per second" to "per frame".
1175 * To get the new value simply divide the old bullet sim FPS with the scene FPS. */
1176 rbw->substeps_per_frame /= FPS;
1177
1178 if (rbw->substeps_per_frame <= 0) {
1179 rbw->substeps_per_frame = 1;
1180 }
1181 }
1182
1183 /* PointCloud attributes. */
1184 LISTBASE_FOREACH (PointCloud *, pointcloud, &bmain->pointclouds) {
1185 do_versions_point_attributes(&pointcloud->pdata);
1186 }
1187
1188 /* Show outliner mode column by default. */
1189 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1190 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1191 LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) {
1192 if (space->spacetype == SPACE_OUTLINER) {
1193 SpaceOutliner *space_outliner = (SpaceOutliner *)space;
1194
1195 space_outliner->flag |= SO_MODE_COLUMN;
1196 }
1197 }
1198 }
1199 }
1200
1201 /* Solver and Collections for Boolean. */
1202 LISTBASE_FOREACH (Object *, object, &bmain->objects) {
1203 LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
1204 if (md->type == eModifierType_Boolean) {
1208 }
1209 }
1210 }
1211 }
1212
1213 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 291, 4) && MAIN_VERSION_FILE_ATLEAST(bmain, 291, 1)) {
1214 /* Due to a48d78ce07f4f, CustomData.totlayer and CustomData.maxlayer has been written
1215 * incorrectly. Fortunately, the size of the layers array has been written to the .blend file
1216 * as well, so we can reconstruct totlayer and maxlayer from that. */
1217 LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) {
1218 mesh->vert_data.totlayer = mesh->vert_data.maxlayer = MEM_allocN_len(
1219 mesh->vert_data.layers) /
1220 sizeof(CustomDataLayer);
1221 mesh->edge_data.totlayer = mesh->edge_data.maxlayer = MEM_allocN_len(
1222 mesh->edge_data.layers) /
1223 sizeof(CustomDataLayer);
1224 /* We can be sure that mesh->fdata is empty for files written by 2.90. */
1225 mesh->corner_data.totlayer = mesh->corner_data.maxlayer = MEM_allocN_len(
1226 mesh->corner_data.layers) /
1227 sizeof(CustomDataLayer);
1228 mesh->face_data.totlayer = mesh->face_data.maxlayer = MEM_allocN_len(
1229 mesh->face_data.layers) /
1230 sizeof(CustomDataLayer);
1231 }
1232 }
1233
1234 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 291, 5)) {
1235 /* Fix fcurves to allow for new bezier handles behavior (#75881 and D8752). */
1236 LISTBASE_FOREACH (bAction *, act, &bmain->actions) {
1237 LISTBASE_FOREACH (FCurve *, fcu, &act->curves) {
1238 /* Only need to fix Bezier curves with at least 2 key-frames. */
1239 if (fcu->totvert < 2 || fcu->bezt == nullptr) {
1240 continue;
1241 }
1243 }
1244 }
1245
1246 LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
1247 collection->color_tag = COLLECTION_COLOR_NONE;
1248 }
1249 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1250 /* Old files do not have a master collection, but it will be created by
1251 * `BKE_collection_master_add()`. */
1252 if (scene->master_collection) {
1253 scene->master_collection->color_tag = COLLECTION_COLOR_NONE;
1254 }
1255 }
1256
1257 /* Add custom profile and bevel mode to curve bevels. */
1258 if (!DNA_struct_member_exists(fd->filesdna, "Curve", "char", "bevel_mode")) {
1259 LISTBASE_FOREACH (Curve *, curve, &bmain->curves) {
1260 if (curve->bevobj != nullptr) {
1261 curve->bevel_mode = CU_BEV_MODE_OBJECT;
1262 }
1263 else {
1264 curve->bevel_mode = CU_BEV_MODE_ROUND;
1265 }
1266 }
1267 }
1268
1269 /* Ensure that new viewport display fields are initialized correctly. */
1270 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
1271 LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
1272 if (md->type == eModifierType_Fluid) {
1274 if (fmd->domain != nullptr) {
1275 if (!fmd->domain->coba_field && fmd->domain->type == FLUID_DOMAIN_TYPE_LIQUID) {
1277 }
1278 fmd->domain->grid_scale = 1.0;
1279 fmd->domain->gridlines_upper_bound = 1.0;
1281 const float grid_lines[4] = {1.0, 0.0, 0.0, 1.0};
1282 copy_v4_v4(fmd->domain->gridlines_range_color, grid_lines);
1283 }
1284 }
1285 }
1286 }
1287 }
1288
1289 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 291, 6)) {
1290 /* Darken Inactive Overlay. */
1291 if (!DNA_struct_member_exists(fd->filesdna, "View3DOverlay", "float", "fade_alpha")) {
1292 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1293 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1294 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1295 if (sl->spacetype == SPACE_VIEW3D) {
1296 View3D *v3d = (View3D *)sl;
1297 v3d->overlay.fade_alpha = 0.40f;
1299 }
1300 }
1301 }
1302 }
1303 }
1304
1305 /* Unify symmetry as a mesh property. */
1306 if (!DNA_struct_member_exists(fd->filesdna, "Mesh", "char", "symmetry")) {
1307 LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) {
1308 /* The previous flags used to store mesh symmetry in edit-mode match the new ones that are
1309 * used in #Mesh.symmetry. */
1310 mesh->symmetry = mesh->editflag & (ME_SYMMETRY_X | ME_SYMMETRY_Y | ME_SYMMETRY_Z);
1311 }
1312 }
1313
1314 /* Alembic importer: allow vertex interpolation by default. */
1315 LISTBASE_FOREACH (Object *, object, &bmain->objects) {
1316 LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
1317 if (md->type != eModifierType_MeshSequenceCache) {
1318 continue;
1319 }
1320
1323 }
1324 }
1325 }
1326
1327 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 291, 7)) {
1328 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1329 scene->r.simplify_volumes = 1.0f;
1330 }
1331 }
1332
1333 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 291, 8)) {
1334 if (!DNA_struct_member_exists(fd->filesdna, "WorkSpaceDataRelation", "int", "parentid")) {
1335 LISTBASE_FOREACH (WorkSpace *, workspace, &bmain->workspaces) {
1337 WorkSpaceDataRelation *, relation, &workspace->hook_layout_relations)
1338 {
1339 relation->parent = blo_read_get_new_globaldata_address(fd, relation->parent);
1340 BLI_assert(relation->parentid == 0);
1341 if (relation->parent != nullptr) {
1342 LISTBASE_FOREACH (wmWindowManager *, wm, &bmain->wm) {
1343 wmWindow *win = static_cast<wmWindow *>(
1344 BLI_findptr(&wm->windows, relation->parent, offsetof(wmWindow, workspace_hook)));
1345 if (win != nullptr) {
1346 relation->parentid = win->winid;
1347 break;
1348 }
1349 }
1350 if (relation->parentid == 0) {
1352 false,
1353 "Found a valid parent for workspace data relation, but no valid parent id.");
1354 }
1355 }
1356 if (relation->parentid == 0) {
1357 BLI_freelinkN(&workspace->hook_layout_relations, relation);
1358 }
1359 }
1360 }
1361 }
1362
1363 /* UV/Image show overlay option. */
1364 if (!DNA_struct_exists(fd->filesdna, "SpaceImageOverlay")) {
1365 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1366 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1367 LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) {
1368 if (space->spacetype == SPACE_IMAGE) {
1369 SpaceImage *sima = (SpaceImage *)space;
1371 }
1372 }
1373 }
1374 }
1375 }
1376
1377 /* Ensure that particle systems generated by fluid modifier have correct phystype. */
1378 LISTBASE_FOREACH (ParticleSettings *, part, &bmain->particles) {
1380 {
1381 part->phystype = PART_PHYS_NO;
1382 }
1383 }
1384 }
1385
1386 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 291, 9)) {
1387 /* Remove options of legacy UV/Image editor */
1388 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1389 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1390 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1391 switch (sl->spacetype) {
1392 case SPACE_IMAGE: {
1393 SpaceImage *sima = (SpaceImage *)sl;
1394 sima->flag &= ~SI_FLAG_UNUSED_20;
1395 break;
1396 }
1397 }
1398 }
1399 }
1400 }
1401
1402 if (!DNA_struct_member_exists(
1403 fd->filesdna, "FluidModifierData", "float", "fractions_distance"))
1404 {
1405 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
1406 LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
1407 if (md->type == eModifierType_Fluid) {
1409 if (fmd->domain) {
1410 fmd->domain->fractions_distance = 0.5;
1411 }
1412 }
1413 }
1414 }
1415 }
1416 }
1417
1418 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 292, 1)) {
1419 {
1420 const int LEGACY_REFINE_RADIAL_DISTORTION_K1 = (1 << 2);
1421
1422 LISTBASE_FOREACH (MovieClip *, clip, &bmain->movieclips) {
1423 MovieTracking *tracking = &clip->tracking;
1424 MovieTrackingSettings *settings = &tracking->settings;
1425 int new_refine_camera_intrinsics = 0;
1426
1428 new_refine_camera_intrinsics |= REFINE_FOCAL_LENGTH;
1429 }
1430
1432 new_refine_camera_intrinsics |= REFINE_PRINCIPAL_POINT;
1433 }
1434
1435 /* The end goal is to enable radial distortion refinement if either K1 or K2 were set for
1436 * refinement. It is enough to only check for L1 it was not possible to refine K2 without
1437 * K1. */
1438 if (settings->refine_camera_intrinsics & LEGACY_REFINE_RADIAL_DISTORTION_K1) {
1439 new_refine_camera_intrinsics |= REFINE_RADIAL_DISTORTION;
1440 }
1441
1442 settings->refine_camera_intrinsics = new_refine_camera_intrinsics;
1443 }
1444 }
1445 }
1446
1447 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 292, 5)) {
1448 /* Initialize the opacity of the overlay wireframe */
1449 if (!DNA_struct_member_exists(fd->filesdna, "View3DOverlay", "float", "wireframe_opacity")) {
1450 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1451 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1452 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1453 if (sl->spacetype == SPACE_VIEW3D) {
1454 View3D *v3d = (View3D *)sl;
1455 v3d->overlay.wireframe_opacity = 1.0f;
1456 }
1457 }
1458 }
1459 }
1460 }
1461
1462 /* Replace object hidden filter with inverted object visible filter. */
1463 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1464 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1465 LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) {
1466 if (space->spacetype == SPACE_OUTLINER) {
1467 SpaceOutliner *space_outliner = (SpaceOutliner *)space;
1468 if (space_outliner->filter_state == SO_FILTER_OB_HIDDEN) {
1469 space_outliner->filter_state = SO_FILTER_OB_VISIBLE;
1470 space_outliner->filter |= SO_FILTER_OB_STATE_INVERSE;
1471 }
1472 }
1473 }
1474 }
1475 }
1476
1477 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
1478 LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
1479 if (md->type == eModifierType_WeightVGProximity) {
1481 if (wmd->cmap_curve == nullptr) {
1482 wmd->cmap_curve = BKE_curvemapping_add(1, 0.0, 0.0, 1.0, 1.0);
1484 }
1485 }
1486 }
1487 }
1488
1489 /* PointCloud attributes names. */
1490 LISTBASE_FOREACH (PointCloud *, pointcloud, &bmain->pointclouds) {
1491 do_versions_point_attribute_names(&pointcloud->pdata);
1492 }
1493
1494 /* Cryptomatte render pass */
1495 if (!DNA_struct_member_exists(fd->filesdna, "ViewLayer", "short", "cryptomatte_levels")) {
1496 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1497 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
1498 view_layer->cryptomatte_levels = 6;
1499 view_layer->cryptomatte_flag = VIEW_LAYER_CRYPTOMATTE_ACCURATE;
1500 }
1501 }
1502 }
1503 }
1504
1505 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 292, 7)) {
1506 /* Make all IDProperties used as interface of geometry node trees overridable. */
1507 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
1508 LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
1509 if (md->type == eModifierType_Nodes) {
1511 IDProperty *nmd_properties = nmd->settings.properties;
1512
1513 BLI_assert(nmd_properties->type == IDP_GROUP);
1514 LISTBASE_FOREACH (IDProperty *, nmd_socket_idprop, &nmd_properties->data.group) {
1515 nmd_socket_idprop->flag |= IDP_FLAG_OVERRIDABLE_LIBRARY;
1516 }
1517 }
1518 }
1519 }
1520
1521 /* EEVEE/Cycles Volumes consistency */
1522 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1523 /* Remove Volume Transmittance render pass from each view layer. */
1524 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
1525 view_layer->eevee.render_passes &= ~EEVEE_RENDER_PASS_UNUSED_8;
1526 }
1527
1528 /* Rename Render-layer Socket `VolumeScatterCol` to `VolumeDir`. */
1529 if (scene->nodetree) {
1530 LISTBASE_FOREACH (bNode *, node, &scene->nodetree->nodes) {
1531 if (node->type_legacy == CMP_NODE_R_LAYERS) {
1532 LISTBASE_FOREACH (bNodeSocket *, output_socket, &node->outputs) {
1533 const char *volume_scatter = "VolumeScatterCol";
1534 if (STREQLEN(output_socket->name, volume_scatter, MAX_NAME)) {
1535 STRNCPY(output_socket->name, RE_PASSNAME_VOLUME_LIGHT);
1536 }
1537 }
1538 }
1539 }
1540 }
1541 }
1542
1543 /* Convert `NodeCryptomatte->storage->matte_id` to `NodeCryptomatte->storage->entries` */
1544 if (!DNA_struct_exists(fd->filesdna, "CryptomatteEntry")) {
1545 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1546 if (scene->nodetree) {
1547 LISTBASE_FOREACH (bNode *, node, &scene->nodetree->nodes) {
1548 if (node->type_legacy == CMP_NODE_CRYPTOMATTE_LEGACY) {
1549 NodeCryptomatte *storage = (NodeCryptomatte *)node->storage;
1550 char *matte_id = storage->matte_id;
1551 if (matte_id == nullptr || strlen(storage->matte_id) == 0) {
1552 continue;
1553 }
1555 }
1556 }
1557 }
1558 }
1559 }
1560
1561 /* Overlay elements in the sequencer. */
1562 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1563 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1564 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1565 if (sl->spacetype == SPACE_SEQ) {
1566 SpaceSeq *sseq = (SpaceSeq *)sl;
1569 }
1570 }
1571 }
1572 }
1573 }
1574
1575 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 292, 8)) {
1576 LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
1577 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
1578 if (STREQ(node->idname, "GeometryNodeRandomAttribute")) {
1579 STRNCPY(node->idname, "GeometryLegacyNodeAttributeRandomize");
1580 }
1581 }
1582 }
1583
1584 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1585 if (scene->toolsettings->sequencer_tool_settings == nullptr) {
1586 scene->toolsettings->sequencer_tool_settings = blender::seq::tool_settings_init();
1587 }
1588 }
1589 }
1590
1591 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 292, 9)) {
1592 /* Default properties editors to auto outliner sync. */
1593 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1594 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1595 LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) {
1596 if (space->spacetype == SPACE_PROPERTIES) {
1597 SpaceProperties *space_properties = (SpaceProperties *)space;
1598 space_properties->outliner_sync = PROPERTIES_SYNC_AUTO;
1599 }
1600 }
1601 }
1602 }
1603
1604 /* Ensure that new viscosity strength field is initialized correctly. */
1605 if (!DNA_struct_member_exists(fd->filesdna, "FluidModifierData", "float", "viscosity_value")) {
1606 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
1607 LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
1608 if (md->type == eModifierType_Fluid) {
1610 if (fmd->domain != nullptr) {
1611 fmd->domain->viscosity_value = 0.05;
1612 }
1613 }
1614 }
1615 }
1616 }
1617 }
1618
1619 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 292, 10)) {
1620 if (!DNA_struct_exists(fd->filesdna, "NodeSetAlpha")) {
1621 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1622 if (ntree->type != NTREE_COMPOSIT) {
1623 continue;
1624 }
1625 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
1626 if (node->type_legacy != CMP_NODE_SETALPHA) {
1627 continue;
1628 }
1629 NodeSetAlpha *storage = MEM_callocN<NodeSetAlpha>("NodeSetAlpha");
1631 node->storage = storage;
1632 }
1633 }
1635 }
1636
1637 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1639 if (ed == nullptr) {
1640 continue;
1641 }
1643 }
1644 }
1645
1646 /* Enable "Save as Render" option for file output node by default (apply view transform to image
1647 * on save) */
1648 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 292, 11)) {
1649 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1650 if (ntree->type == NTREE_COMPOSIT) {
1651 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
1652 if (node->type_legacy == CMP_NODE_OUTPUT_FILE) {
1653 LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
1655 sock->storage);
1656 simf->save_as_render = true;
1657 }
1658 }
1659 }
1660 }
1661 }
1663 }
1664
1665 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 293, 1)) {
1666 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1667 if (ntree->type == NTREE_GEOMETRY) {
1668 version_node_socket_name(ntree, GEO_NODE_MESH_BOOLEAN, "Geometry A", "Geometry 1");
1669 version_node_socket_name(ntree, GEO_NODE_MESH_BOOLEAN, "Geometry B", "Geometry 2");
1670 }
1671 }
1673
1674 /* Init grease pencil default curve resolution. */
1675 if (!DNA_struct_member_exists(fd->filesdna, "bGPdata", "int", "curve_edit_resolution")) {
1676 LISTBASE_FOREACH (bGPdata *, gpd, &bmain->gpencils) {
1677 gpd->curve_edit_resolution = GP_DEFAULT_CURVE_RESOLUTION;
1679 }
1680 }
1681 /* Init grease pencil curve editing error threshold. */
1682 if (!DNA_struct_member_exists(fd->filesdna, "bGPdata", "float", "curve_edit_threshold")) {
1683 LISTBASE_FOREACH (bGPdata *, gpd, &bmain->gpencils) {
1684 gpd->curve_edit_threshold = GP_DEFAULT_CURVE_ERROR;
1685 gpd->curve_edit_corner_angle = GP_DEFAULT_CURVE_EDIT_CORNER_ANGLE;
1686 }
1687 }
1688 }
1689
1690 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 292, 14) ||
1691 ((bmain->versionfile == 293) && !MAIN_VERSION_FILE_ATLEAST(bmain, 293, 1)))
1692 {
1693 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1694 if (ntree->type != NTREE_GEOMETRY) {
1695 continue;
1696 }
1697 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
1698 if (node->type_legacy == GEO_NODE_OBJECT_INFO && node->storage == nullptr) {
1700 data->transform_space = GEO_NODE_TRANSFORM_SPACE_RELATIVE;
1701 node->storage = data;
1702 }
1703 }
1704 }
1706 }
1707
1708 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 293, 1)) {
1709 /* Grease pencil layer transform matrix. */
1710 if (!DNA_struct_member_exists(fd->filesdna, "bGPDlayer", "float", "location[0]")) {
1711 LISTBASE_FOREACH (bGPdata *, gpd, &bmain->gpencils) {
1712 LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
1713 zero_v3(gpl->location);
1714 zero_v3(gpl->rotation);
1715 copy_v3_fl(gpl->scale, 1.0f);
1716 loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
1717 invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
1718 }
1719 }
1720 }
1721 /* Fix Fill factor for grease pencil fill brushes. */
1722 LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
1723 if ((brush->gpencil_settings) && (brush->gpencil_settings->fill_factor == 0.0f)) {
1724 brush->gpencil_settings->fill_factor = 1.0f;
1725 }
1726 }
1727 }
1728
1729 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 293, 5)) {
1730 /* Change Nishita sky model Altitude unit. */
1731 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1732 if (ntree->type == NTREE_SHADER) {
1733 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
1734 if (node->type_legacy == SH_NODE_TEX_SKY && node->storage) {
1735 NodeTexSky *tex = (NodeTexSky *)node->storage;
1736 tex->altitude *= 1000.0f;
1737 }
1738 }
1739 }
1740 }
1742 }
1743
1744 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 293, 6)) {
1745 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1746 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1747 LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) {
1748 /* Enable Outliner render visibility column. */
1749 if (space->spacetype == SPACE_OUTLINER) {
1750 SpaceOutliner *space_outliner = (SpaceOutliner *)space;
1751 space_outliner->show_restrict_flags |= SO_RESTRICT_RENDER;
1752 }
1753 }
1754 }
1755 }
1756 }
1757
1758 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 293, 7)) {
1759 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1760 if (ntree->type == NTREE_GEOMETRY) {
1762 }
1763 }
1765 }
1766
1767 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 293, 9)) {
1768 if (!DNA_struct_member_exists(fd->filesdna, "SceneEEVEE", "float", "bokeh_overblur")) {
1769 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1770 scene->eevee.bokeh_neighbor_max = 10.0f;
1771 scene->eevee.bokeh_overblur = 5.0f;
1772 }
1773 }
1774
1775 /* Add sub-panels for FModifiers, which requires a field to store expansion. */
1776 if (!DNA_struct_member_exists(fd->filesdna, "FModifier", "short", "ui_expand_flag")) {
1777 LISTBASE_FOREACH (bAction *, act, &bmain->actions) {
1778 LISTBASE_FOREACH (FCurve *, fcu, &act->curves) {
1779 LISTBASE_FOREACH (FModifier *, fcm, &fcu->modifiers) {
1780 SET_FLAG_FROM_TEST(fcm->ui_expand_flag,
1781 fcm->flag & FMODIFIER_FLAG_EXPANDED,
1783 }
1784 }
1785 }
1786 }
1787 }
1788
1789 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 293, 10)) {
1790 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1791 /* Fix old scene with too many samples that were not being used.
1792 * Now they are properly used and might produce a huge slowdown.
1793 * So we clamp to what the old max actual was. */
1794 scene->eevee.volumetric_shadow_samples = std::min(scene->eevee.volumetric_shadow_samples,
1795 32);
1796 }
1797 }
1798
1799 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 293, 11)) {
1800 LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
1801 if (ntree->type == NTREE_GEOMETRY) {
1802 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
1803 if (STREQ(node->idname, "GeometryNodeSubdivisionSurfaceSimple")) {
1804 STRNCPY(node->idname, "GeometryNodeSubdivide");
1805 }
1806 if (STREQ(node->idname, "GeometryNodeSubdivisionSurface")) {
1807 STRNCPY(node->idname, "GeometryNodeSubdivideSmooth");
1808 }
1809 }
1810 }
1811 }
1812 }
1813
1814 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 293, 12)) {
1815 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1816 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1817 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1818 switch (sl->spacetype) {
1819 case SPACE_SEQ: {
1820 SpaceSeq *sseq = (SpaceSeq *)sl;
1821 if (ELEM(sseq->render_size,
1826 {
1827 sseq->flag |= SEQ_USE_PROXIES;
1828 }
1829 if (sseq->render_size == SEQ_RENDER_SIZE_FULL) {
1831 }
1832 }
1833 }
1834 }
1835 }
1836 }
1837
1838 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1839 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1840 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1841 if (sl->spacetype == SPACE_SPREADSHEET) {
1842 ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
1843 &sl->regionbase;
1845 regionbase, RGN_TYPE_FOOTER, "footer for spreadsheet", RGN_TYPE_HEADER);
1846 if (new_footer != nullptr) {
1847 new_footer->alignment = (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_TOP :
1849 }
1850 }
1851 }
1852 }
1853 }
1854 }
1855
1856 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 293, 13)) {
1857 LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
1858 if (ntree->type == NTREE_GEOMETRY) {
1859 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
1860 if (STREQ(node->idname, "GeometryNodeSubdivideSmooth")) {
1861 STRNCPY(node->idname, "GeometryNodeSubdivisionSurface");
1862 }
1863 }
1864 }
1865 }
1866 }
1867
1868 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 293, 14)) {
1869 if (!DNA_struct_member_exists(fd->filesdna, "Light", "float", "diff_fac")) {
1870 LISTBASE_FOREACH (Light *, light, &bmain->lights) {
1871 light->diff_fac = 1.0f;
1872 light->volume_fac = 1.0f;
1873 }
1874 }
1875 }
1876
1877 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 293, 15)) {
1878 LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
1879 if (ntree->type == NTREE_GEOMETRY) {
1880 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
1881 if (STREQ(node->idname, "GeometryNodeMeshPlane")) {
1882 STRNCPY(node->idname, "GeometryNodeMeshGrid");
1883 }
1884 }
1885 }
1886 }
1887 }
1888
1889 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 293, 16)) {
1890 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1891 if (ntree->type == NTREE_GEOMETRY) {
1893 }
1895 }
1896
1897 /* The CU_2D flag has been removed. */
1898 LISTBASE_FOREACH (Curve *, cu, &bmain->curves) {
1899#define CU_2D (1 << 3)
1900 ListBase *nurbs = BKE_curve_nurbs_get(cu);
1901 bool is_2d = true;
1902
1903 LISTBASE_FOREACH (Nurb *, nu, nurbs) {
1904 if (nu->flag & CU_2D) {
1905 nu->flag &= ~CU_2D;
1906 }
1907 else {
1908 is_2d = false;
1909 }
1910 }
1911#undef CU_2D
1912 if (!is_2d && CU_IS_2D(cu)) {
1913 cu->flag |= CU_3D;
1914 }
1915 }
1916 }
1917
1918 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 293, 18)) {
1919 if (!DNA_struct_member_exists(fd->filesdna, "bArmature", "float", "axes_position")) {
1920 /* Convert the axes draw position to its old default (tip of bone). */
1921 LISTBASE_FOREACH (bArmature *, arm, &bmain->armatures) {
1922 arm->axes_position = 1.0;
1923 }
1924 }
1925
1926 /* Initialize the spread parameter for area lights. */
1927 if (!DNA_struct_member_exists(fd->filesdna, "Light", "float", "area_spread")) {
1928 LISTBASE_FOREACH (Light *, la, &bmain->lights) {
1929 la->area_spread = DEG2RADF(180.0f);
1930 }
1931 }
1932
1933 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1934 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1935 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1936 if (sl->spacetype == SPACE_NODE) {
1937 SpaceNode *snode = (SpaceNode *)sl;
1938 LISTBASE_FOREACH (bNodeTreePath *, path, &snode->treepath) {
1939 STRNCPY(path->display_name, path->node_name);
1940 }
1941 }
1942 }
1943 }
1944 }
1945 }
1946
1947 /* Set default value for the new bisect_threshold parameter in the mirror modifier. */
1948 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 293, 19)) {
1949 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
1950 LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
1951 if (md->type == eModifierType_Mirror) {
1953 /* This was the previous hard-coded value. */
1954 mmd->bisect_threshold = 0.001f;
1955 }
1956 }
1957 }
1958
1959 LISTBASE_FOREACH (Curve *, cu, &bmain->curves) {
1960 /* Turn on clamping as this was implicit before. */
1961 cu->flag |= CU_PATH_CLAMP;
1962 }
1963 }
1964
1971}
void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm, bool do_id_user)
Definition armature.cc:2877
bool BKE_collection_cycles_fix(Main *bmain, Collection *collection)
void BKE_curvemapping_init(CurveMapping *cumap)
CurveMapping * BKE_curvemapping_add(int tot, float minx, float miny, float maxx, float maxy)
Definition colortools.cc:89
void BKE_cryptomatte_matte_id_to_entries(struct NodeCryptomatte *node_storage, const char *matte_id)
#define CU_IS_2D(cu)
Definition BKE_curve.hh:89
ListBase * BKE_curve_nurbs_get(Curve *cu)
Definition curve.cc:4962
CustomData interface, see also DNA_customdata_types.h.
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
void * CustomData_get_layer_for_write(CustomData *data, eCustomDataType type, int totelem)
FCurve * BKE_fcurve_find(ListBase *list, const char rna_path[], int array_index)
bool BKE_fcurve_is_empty(const FCurve *fcu)
void BKE_fcurve_free(FCurve *fcu)
struct bGPDframe * BKE_gpencil_frame_duplicate(const struct bGPDframe *gpf_src, bool dup_strokes)
void BKE_main_id_repair_duplicate_names_listbase(Main *bmain, ListBase *lb)
Definition lib_id.cc:1248
void id_fake_user_set(ID *id)
Definition lib_id.cc:391
ListBase * which_libbase(Main *bmain, short type)
Definition main.cc:887
#define MAIN_VERSION_FILE_ATLEAST(main, ver, subver)
Definition BKE_main.hh:634
#define MAIN_VERSION_FILE_OLDER(main, ver, subver)
Definition BKE_main.hh:638
bool BKE_mesh_validate_arrays(Mesh *mesh, float(*vert_positions)[3], unsigned int verts_num, blender::int2 *edges, unsigned int edges_num, MFace *legacy_faces, unsigned int legacy_faces_num, const int *corner_verts, int *corner_edges, unsigned int corners_num, const int *face_offsets, unsigned int faces_num, MDeformVert *dverts, bool do_verbose, bool do_fixes, bool *r_change)
void BKE_mesh_legacy_convert_loops_to_corners(Mesh *mesh)
void BKE_mesh_legacy_convert_polys_to_offsets(Mesh *mesh)
void multires_do_versions_simple_to_catmull_clark(Object *object, MultiresModifierData *mmd)
#define FOREACH_NODETREE_END
Definition BKE_node.hh:866
#define FOREACH_NODETREE_BEGIN(bmain, _nodetree, _id)
Definition BKE_node.hh:856
#define GEO_NODE_OBJECT_INFO
#define SH_NODE_BSDF_PRINCIPLED
#define GEO_NODE_MESH_BOOLEAN
#define SH_NODE_TEX_SKY
#define CMP_NODE_CRYPTOMATTE_LEGACY
#define GEO_NODE_MESH_PRIMITIVE_GRID
#define CMP_NODE_OUTPUT_FILE
#define CMP_NODE_SETALPHA
#define CMP_NODE_R_LAYERS
#define GEO_NODE_JOIN_GEOMETRY
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
#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 BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:131
void BLI_addhead(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:91
void * BLI_findptr(const struct ListBase *listbase, const void *ptr, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
#define DEG2RADF(_deg)
#define M_PI_2
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
void loc_eul_size_to_mat4(float R[4][4], const float loc[3], const float eul[3], const float size[3])
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void madd_v2_v2v2fl(float r[2], const float a[2], const float b[2], float f)
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE void copy_v3_fl(float r[3], float f)
MINLINE void zero_v3(float r[3])
char * BLI_sprintfN(const char *__restrict format,...) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:688
size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
unsigned int uint
#define ARRAY_SIZE(arr)
#define UNUSED_VARS(...)
#define STREQLEN(a, b, n)
#define SET_FLAG_FROM_TEST(value, test, flag)
#define ELEM(...)
#define STREQ(a, b)
external readfile function prototypes.
@ ID_PAL
@ ID_BR
@ IDP_GROUP
@ IDP_FLAG_OVERRIDABLE_LIBRARY
@ CACHEFILE_VELOCITY_UNIT_SECOND
Object groups, one object can be in many groups at once.
@ COLLECTION_COLOR_NONE
@ CU_BEV_MODE_OBJECT
@ CU_BEV_MODE_ROUND
@ BEZT_IPO_BEZ
@ CU_3D
@ CU_PATH_CLAMP
@ CD_PROP_FLOAT
@ CD_PROP_FLOAT3
@ FLUID_DOMAIN_FIELD_PHI
@ FLUID_DOMAIN_TYPE_LIQUID
blenloader genfile private function prototypes
#define GP_DEFAULT_CURVE_EDIT_CORNER_ANGLE
#define GP_DEFAULT_CURVE_RESOLUTION
#define GP_DEFAULT_CURVE_ERROR
@ GP_DATA_CURVE_ADAPTIVE_RESOLUTION
@ eGpencilModifierType_Array
@ eGpencilModifierType_Noise
@ eGpencilModifierType_Mirror
@ eGpencilModifierType_Color
@ eGpencilModifierType_Multiply
@ eGpencilModifierType_Texture
@ eGpencilModifierType_Subdiv
@ eGpencilModifierType_Lattice
@ eGpencilModifierType_Opacity
@ eGpencilModifierType_Hook
@ eGpencilModifierType_Simplify
@ eGpencilModifierType_Smooth
@ eGpencilModifierType_Thick
@ eGpencilModifierType_Offset
@ VIEW_LAYER_CRYPTOMATTE_ACCURATE
@ EEVEE_RENDER_PASS_UNUSED_8
@ ME_SYMMETRY_X
@ ME_SYMMETRY_Y
@ ME_SYMMETRY_Z
@ eBooleanModifierSolver_Float
@ eBooleanModifierFlag_Object
@ eModifierType_Mirror
@ eModifierType_WeightVGProximity
@ eModifierType_Boolean
@ eModifierType_Fluid
@ eModifierType_MeshSequenceCache
@ eModifierType_Ocean
@ eModifierType_Nodes
@ eModifierType_Bevel
@ eModifierType_WeightVGEdit
@ eModifierType_Multires
@ MOD_WVG_EDIT_WEIGHTS_NORMALIZE
@ MOD_MESHSEQ_INTERPOLATE_VERTICES
@ MOD_BEVEL_PROFILE_CUSTOM
@ MOD_BEVEL_PROFILE_SUPERELLIPSE
@ MOD_BEVEL_AFFECT_EDGES
@ MOD_BEVEL_AFFECT_VERTICES
@ NTREE_SHADER
@ NTREE_GEOMETRY
@ NTREE_COMPOSIT
@ SOCK_IN
@ CMP_NODE_SETALPHA_MODE_REPLACE_ALPHA
@ SOCK_MULTI_INPUT
@ GEO_NODE_TRANSFORM_SPACE_RELATIVE
@ OB_MODE_SCULPT
Object is a sort of wrapper for general info.
@ OB_ARMATURE
@ OB_GPENCIL_LEGACY
@ PART_FLUID_FLIP
@ PART_FLUID_BUBBLE
@ PART_FLUID_FOAM
@ PART_FLUID_SPRAY
@ PART_PHYS_NO
Types and defines for representing Rigid Body entities.
#define RE_PASSNAME_VOLUME_LIGHT
#define FPS
@ PNL_UNUSED_1
@ PNL_CLOSED
@ UI_PANEL_DATA_EXPAND_ROOT
@ RGN_TYPE_FOOTER
@ RGN_TYPE_HEADER
@ RGN_ALIGN_BOTTOM
@ RGN_ALIGN_TOP
@ SEQ_CACHE_STORE_RAW
@ SEQ_CACHE_STORE_FINAL_OUT
@ SEQ_USE_PROXY
@ STRIP_TYPE_SOUND_HD
@ STRIP_TYPE_SOUND_RAM
@ STRIP_TYPE_META
@ SI_FLAG_UNUSED_20
@ SI_OVERLAY_SHOW_OVERLAYS
eSpaceSeq_Proxy_RenderSize
@ SEQ_RENDER_SIZE_PROXY_25
@ SEQ_RENDER_SIZE_PROXY_75
@ SEQ_RENDER_SIZE_PROXY_50
@ SEQ_RENDER_SIZE_FULL
@ SEQ_RENDER_SIZE_PROXY_100
@ SPACE_OUTLINER
@ SPACE_NODE
@ SPACE_SPREADSHEET
@ SPACE_PROPERTIES
@ SPACE_SEQ
@ SPACE_IMAGE
@ SPACE_VIEW3D
@ SEQ_TIMELINE_SHOW_STRIP_DURATION
@ SEQ_TIMELINE_SHOW_STRIP_SOURCE
@ SEQ_TIMELINE_SHOW_STRIP_NAME
@ SO_RESTRICT_RENDER
@ SO_FILTER_OB_STATE_INVERSE
@ SO_MODE_COLUMN
@ SO_FILTER_OB_VISIBLE
@ SO_FILTER_OB_HIDDEN
@ SEQ_DRAW_IMG_IMBUF
@ SEQ_USE_PROXIES
@ SEQ_SHOW_OVERLAY
@ PROPERTIES_SYNC_AUTO
@ REFINE_PRINCIPAL_POINT
@ REFINE_RADIAL_DISTORTION
@ REFINE_FOCAL_LENGTH
@ USER_HEADER_BOTTOM
@ V3D_OVERLAY_FADE_INACTIVE
@ IMB_PROXY_NONE
Read Guarded memory(de)allocation.
#define U
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert * v2
@ DENOISER_OPTIX
Definition denoise.h:12
#define offsetof(t, d)
#define fabsf(x)
#define printf(...)
#define MAX_NAME
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
bNodeSocket * node_find_socket(bNode &node, eNodeSocketInOut in_out, StringRef identifier)
Definition node.cc:2864
void node_remove_socket(bNodeTree &ntree, bNode &node, bNodeSocket &sock)
Definition node.cc:3575
bNodeLink & node_add_link(bNodeTree &ntree, bNode &fromnode, bNodeSocket &fromsock, bNode &tonode, bNodeSocket &tosock)
Definition node.cc:4087
int time_right_handle_frame_get(const Scene *scene, const Strip *strip)
SequencerToolSettings * tool_settings_init()
Definition sequencer.cc:346
Editing * editing_get(const Scene *scene)
Definition sequencer.cc:272
double rendersize_to_scale_factor(int render_size)
Definition proxy.cc:87
void active_seqbase_set(Editing *ed, ListBase *seqbase)
Definition sequencer.cc:429
int time_left_handle_frame_get(const Scene *, const Strip *strip)
int rendersize_to_proxysize(int render_size)
Definition proxy.cc:72
MetaStack * meta_stack_active_get(const Editing *ed)
Definition sequencer.cc:452
void time_left_handle_frame_set(const Scene *scene, Strip *strip, int timeline_frame)
void time_right_handle_frame_set(const Scene *scene, Strip *strip, int timeline_frame)
void * blo_read_get_new_globaldata_address(FileData *fd, const void *adr)
Definition readfile.cc:1523
bAction * action
float vec[3][3]
CustomDataLayer * layers
ListBase metastack
BezTriple * bezt
unsigned int totvert
SDNA * filesdna
Definition readfile.hh:103
struct FluidDomainSettings * domain
ListBase group
Definition DNA_ID.h:138
IDPropertyData data
Definition DNA_ID.h:159
char type
Definition DNA_ID.h:146
Definition DNA_ID.h:404
void * first
ListBase brushes
Definition BKE_main.hh:271
ListBase scenes
Definition BKE_main.hh:245
ListBase wm
Definition BKE_main.hh:276
ListBase actions
Definition BKE_main.hh:269
ListBase texts
Definition BKE_main.hh:263
ListBase meshes
Definition BKE_main.hh:248
ListBase movieclips
Definition BKE_main.hh:280
ListBase lights
Definition BKE_main.hh:255
ListBase nodetrees
Definition BKE_main.hh:270
ListBase particles
Definition BKE_main.hh:272
ListBase materials
Definition BKE_main.hh:251
ListBase pointclouds
Definition BKE_main.hh:290
ListBase armatures
Definition BKE_main.hh:268
ListBase curves
Definition BKE_main.hh:249
ListBase screens
Definition BKE_main.hh:261
short versionfile
Definition BKE_main.hh:156
ListBase workspaces
Definition BKE_main.hh:284
ListBase collections
Definition BKE_main.hh:267
ListBase gpencils
Definition BKE_main.hh:278
ListBase objects
Definition BKE_main.hh:247
ListBase cachefiles
Definition BKE_main.hh:283
MovieTrackingSettings settings
struct NodesModifierSettings settings
struct IDProperty * properties
ListBase children
struct RenderData r
struct AnimData * adt
SpaceImageOverlay overlay
ListBase treepath
short render_size
StripProxy * proxy
StripCrop * crop
StripTransform * transform
StripElem * stripdata
StripData * data
ListBase seqbase
char name[64]
View3DOverlay overlay
ListBase curves
struct bNodeSocket * next
void * default_value
ListBase nodes
ListBase links
i
Definition text_draw.cc:230
static void strip_convert_transform_crop_lb(const Scene *scene, const ListBase *lb, const eSpaceSeq_Proxy_RenderSize render_size)
static bool can_use_proxy(const Strip *strip, int psize)
static void strip_convert_transform_animation_2(const Scene *scene, const char *path, const float scale_to_fit_factor)
static void strip_convert_transform_animation(const Strip *strip, const Scene *scene, const char *path, const int image_size, const int scene_size)
static void version_node_socket_duplicate(bNodeTree *ntree, const int node_type, const char *old_name, const char *new_name)
static void strip_convert_transform_crop(const Scene *scene, Strip *strip, const eSpaceSeq_Proxy_RenderSize render_size)
static void version_node_join_geometry_for_multi_input_socket(bNodeTree *ntree)
static void strip_convert_transform_crop_2(const Scene *scene, Strip *strip, const eSpaceSeq_Proxy_RenderSize render_size)
static void do_versions_291_fcurve_handles_limit(FCurve *fcu)
void do_versions_after_linking_290(FileData *, Main *bmain)
static void panels_remove_x_closed_flag_recursive(Panel *panel)
#define CU_2D
static void strip_convert_transform_crop_lb_2(const Scene *scene, const ListBase *lb, const eSpaceSeq_Proxy_RenderSize render_size)
void blo_do_versions_290(FileData *fd, Library *, Main *bmain)
static void do_versions_point_attributes(CustomData *pdata)
static eSpaceSeq_Proxy_RenderSize get_sequencer_render_size(Main *bmain)
static void seq_update_meta_disp_range(Scene *scene)
static void do_versions_point_attribute_names(CustomData *pdata)
void version_cycles_property_int_set(IDProperty *idprop, const char *name, int value)
IDProperty * version_cycles_properties_from_ID(ID *id)
int version_cycles_property_int(IDProperty *idprop, const char *name, int default_value)
IDProperty * version_cycles_properties_from_render_layer(SceneRenderLayer *render_layer)
void version_node_socket_index_animdata(Main *bmain, const int node_tree_type, const int node_type, const int socket_index_orig, const int socket_index_offset, const int total_number_of_sockets)
void version_node_socket_name(bNodeTree *ntree, const int node_type, const char *old_name, const char *new_name)
bool version_cycles_property_boolean(IDProperty *idprop, const char *name, bool default_value)
IDProperty * version_cycles_properties_from_view_layer(ViewLayer *view_layer)
void version_cycles_property_boolean_set(IDProperty *idprop, const char *name, bool value)
ARegion * do_versions_add_region_if_not_found(ListBase *regionbase, int region_type, const char *, int link_after_region_type)