Blender V5.0
versioning_420.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#define DNA_DEPRECATED_ALLOW
10
11/* Define macros in `DNA_genfile.h`. */
12#define DNA_GENFILE_VERSIONING_MACROS
13
14#include "DNA_anim_types.h"
15#include "DNA_brush_types.h"
17#include "DNA_defaults.h"
18#include "DNA_genfile.h"
19#include "DNA_light_types.h"
21#include "DNA_material_types.h"
22#include "DNA_sequence_types.h"
24#include "DNA_world_types.h"
25
26#undef DNA_GENFILE_VERSIONING_MACROS
27
28#include "BLI_listbase.h"
29#include "BLI_math_vector.h"
30#include "BLI_string.h"
31#include "BLI_string_utf8.h"
32
33#include "BKE_anim_data.hh"
34#include "BKE_colortools.hh"
35#include "BKE_customdata.hh"
36#include "BKE_grease_pencil.hh"
37#include "BKE_main.hh"
38#include "BKE_material.hh"
39#include "BKE_node.hh"
41#include "BKE_report.hh"
42
43#include "MOV_enums.hh"
44
45#include "SEQ_iterator.hh"
46#include "SEQ_sequencer.hh"
47
48#include "BLT_translation.hh"
49
50#include "BLO_read_write.hh"
51
52#include "readfile.hh"
53
54#include "versioning_common.hh"
55
61{
62 const blender::StringRef rna_path(fcurve->rna_path);
63 constexpr char const *rna_path_prefix = "collections[";
64 if (!rna_path.startswith(rna_path_prefix)) {
65 return;
66 }
67
68 const std::string path_remainder(rna_path.drop_known_prefix(rna_path_prefix));
69 MEM_freeN(fcurve->rna_path);
70 fcurve->rna_path = BLI_sprintfN("collections_all[%s", path_remainder.c_str());
71}
72
74{
78
79 short *material_len = BKE_object_material_len_p(object);
80 if (!material_len) {
81 return;
82 }
83
84 using namespace blender;
85 bool hide_shadows = *material_len > 0;
86 for (int i : IndexRange(*material_len)) {
87 Material *material = BKE_object_material_get(object, i + 1);
88 if (!material || material->blend_shadow != MA_BS_NONE) {
89 hide_shadows = false;
90 }
91 }
92
93 /* Enable the hide_shadow flag only if there's not any shadow casting material. */
95}
96
105 /* Alpha input is 0. */
107 /* Alpha input is 1. */
109 /* Alpha is between 0 and 1, from a graph input or the result of one blending operation. */
111 /* Alpha is unknown and the result of more than one blending operation. */
113 };
114
115 /* Socket that is the source of the potential semi-transparency. */
116 bNodeSocket *socket = nullptr;
117 /* State of the source. */
119 /* True if socket is transparency instead of alpha (e.g: `1-alpha`). */
120 bool is_transparency = false;
121
122 static AlphaSource alpha_source(bNodeSocket *fac, bool inverted = false)
123 {
124 return {fac, ALPHA_SEMI_TRANSPARENT, inverted};
125 }
127 {
128 return {nullptr, ALPHA_OPAQUE, false};
129 }
130 static AlphaSource fully_transparent(bNodeSocket *socket = nullptr, bool inverted = false)
131 {
132 return {socket, ALPHA_FULLY_TRANSPARENT, inverted};
133 }
135 {
136 return {nullptr, ALPHA_COMPLEX_MIX, false};
137 }
138
139 bool is_opaque() const
140 {
141 return state == ALPHA_OPAQUE;
142 }
144 {
146 }
147 bool is_transparent() const
148 {
149 return state != ALPHA_OPAQUE;
150 }
152 {
154 }
155 bool is_complex() const
156 {
157 return state == ALPHA_COMPLEX_MIX;
158 }
159
160 /* Combine two source together with a blending parameter. */
161 static AlphaSource mix(const AlphaSource &a, const AlphaSource &b, bNodeSocket *fac)
162 {
163 if (a.is_complex() || b.is_complex()) {
164 return complex_alpha();
165 }
166 if (a.is_semi_transparent() || b.is_semi_transparent()) {
167 return complex_alpha();
168 }
169 if (a.is_fully_transparent() && b.is_fully_transparent()) {
170 return fully_transparent();
171 }
172 if (a.is_opaque() && b.is_opaque()) {
173 return opaque();
174 }
175 /* Only one of them is fully transparent. */
176 return alpha_source(fac, !a.is_transparent());
177 }
178
179 /* Combine two source together with an additive blending parameter. */
180 static AlphaSource add(const AlphaSource &a, const AlphaSource &b)
181 {
182 if (a.is_complex() || b.is_complex()) {
183 return complex_alpha();
184 }
185 if (a.is_semi_transparent() && b.is_transparent()) {
186 return complex_alpha();
187 }
188 if (a.is_transparent() && b.is_semi_transparent()) {
189 return complex_alpha();
190 }
191 /* Either one of them is opaque or they are both opaque. */
192 return a.is_transparent() ? a : b;
193 }
194};
195
200{
201 if (depth > 100) {
202 /* Protection against infinite / very long recursion.
203 * Also a node-tree with that much depth is likely to not be compatible. */
205 }
206
207 if (socket->link == nullptr) {
208 /* Unconnected closure socket is always opaque black. */
209 return AlphaSource::opaque();
210 }
211
212 bNode *node = socket->link->fromnode;
213
214 switch (node->type_legacy) {
215 case NODE_REROUTE: {
217 static_cast<bNodeSocket *>(BLI_findlink(&node->inputs, 0)), depth + 1);
218 }
219
220 case NODE_GROUP: {
222 }
223
225 bNodeSocket *socket = blender::bke::node_find_socket(*node, SOCK_IN, "Color");
226 if (socket->link == nullptr) {
227 float *socket_color_value = version_cycles_node_socket_rgba_value(socket);
228 if ((socket_color_value[0] == 0.0f) && (socket_color_value[1] == 0.0f) &&
229 (socket_color_value[2] == 0.0f))
230 {
231 return AlphaSource::opaque();
232 }
233 if ((socket_color_value[0] == 1.0f) && (socket_color_value[1] == 1.0f) &&
234 (socket_color_value[2] == 1.0f))
235 {
236 return AlphaSource::fully_transparent(socket, true);
237 }
238 }
239 return AlphaSource::alpha_source(socket, true);
240 }
241
242 case SH_NODE_MIX_SHADER: {
243 bNodeSocket *socket = blender::bke::node_find_socket(*node, SOCK_IN, "Fac");
245 static_cast<bNodeSocket *>(BLI_findlink(&node->inputs, 1)), depth + 1);
247 static_cast<bNodeSocket *>(BLI_findlink(&node->inputs, 2)), depth + 1);
248
249 if (socket->link == nullptr) {
250 float socket_float_value = *version_cycles_node_socket_float_value(socket);
251 if (socket_float_value == 0.0f) {
252 return src0;
253 }
254 if (socket_float_value == 1.0f) {
255 return src1;
256 }
257 }
258 return AlphaSource::mix(src0, src1, socket);
259 }
260
261 case SH_NODE_ADD_SHADER: {
263 static_cast<bNodeSocket *>(BLI_findlink(&node->inputs, 0)), depth + 1);
265 static_cast<bNodeSocket *>(BLI_findlink(&node->inputs, 1)), depth + 1);
266 return AlphaSource::add(src0, src1);
267 }
268
270 bNodeSocket *socket = blender::bke::node_find_socket(*node, SOCK_IN, "Alpha");
271 if (socket->link == nullptr) {
272 float socket_value = *version_cycles_node_socket_float_value(socket);
273 if (socket_value == 0.0f) {
274 return AlphaSource::fully_transparent(socket);
275 }
276 if (socket_value == 1.0f) {
277 return AlphaSource::opaque();
278 }
279 }
280 return AlphaSource::alpha_source(socket);
281 }
282
284 bNodeSocket *socket = blender::bke::node_find_socket(*node, SOCK_IN, "Transparency");
285 if (socket->link == nullptr) {
286 float socket_value = *version_cycles_node_socket_float_value(socket);
287 if (socket_value == 0.0f) {
288 return AlphaSource::fully_transparent(socket, true);
289 }
290 if (socket_value == 1.0f) {
291 return AlphaSource::opaque();
292 }
293 }
294 return AlphaSource::alpha_source(socket, true);
295 }
296
297 default:
298 return AlphaSource::opaque();
299 }
300}
301
311{
313 if (output_node == nullptr) {
314 return true;
315 }
316 bNodeSocket *surface_socket = blender::bke::node_find_socket(*output_node, SOCK_IN, "Surface");
317
318 AlphaSource alpha = versioning_eevee_alpha_source_get(surface_socket);
319
320 if (alpha.is_complex()) {
321 return false;
322 }
323 if (alpha.socket == nullptr) {
324 return true;
325 }
326
327 bool is_opaque = (threshold == 2.0f);
328 if (is_opaque) {
329 if (alpha.socket->link != nullptr) {
331 }
332
333 float value = (alpha.is_transparency) ? 0.0f : 1.0f;
334 float values[4] = {value, value, value, 1.0f};
335
336 /* Set default value to opaque. */
337 if (alpha.socket->type == SOCK_RGBA) {
339 }
340 else {
342 }
343 }
344 else {
345 if (alpha.socket->link != nullptr) {
346 /* Insert math node. */
347 bNode *to_node = alpha.socket->link->tonode;
348 bNode *from_node = alpha.socket->link->fromnode;
349 bNodeSocket *to_socket = alpha.socket->link->tosock;
350 bNodeSocket *from_socket = alpha.socket->link->fromsock;
352
353 bNode *math_node = blender::bke::node_add_node(nullptr, *ntree, "ShaderNodeMath");
354 math_node->custom1 = NODE_MATH_GREATER_THAN;
355 math_node->flag |= NODE_COLLAPSED;
356 math_node->parent = to_node->parent;
357 math_node->locx_legacy = to_node->locx_legacy - math_node->width - 30;
358 math_node->locy_legacy = min_ff(to_node->locy_legacy, from_node->locy_legacy);
359
360 bNodeSocket *input_1 = static_cast<bNodeSocket *>(BLI_findlink(&math_node->inputs, 0));
361 bNodeSocket *input_2 = static_cast<bNodeSocket *>(BLI_findlink(&math_node->inputs, 1));
362 bNodeSocket *output = static_cast<bNodeSocket *>(math_node->outputs.first);
363 bNodeSocket *alpha_sock = input_1;
364 bNodeSocket *threshold_sock = input_2;
365
366 blender::bke::node_add_link(*ntree, *from_node, *from_socket, *math_node, *alpha_sock);
367 blender::bke::node_add_link(*ntree, *math_node, *output, *to_node, *to_socket);
368
370 1.0f - threshold :
371 threshold;
372 }
373 else {
374 /* Modify alpha value directly. */
375 if (alpha.socket->type == SOCK_RGBA) {
376 float *default_value = version_cycles_node_socket_rgba_value(alpha.socket);
377 float sum = default_value[0] + default_value[1] + default_value[2];
378 /* Don't do the division if possible to avoid float imprecision. */
379 float avg = (sum >= 3.0f) ? 1.0f : (sum / 3.0f);
380 float value = float((alpha.is_transparency) ? (avg > 1.0f - threshold) :
381 (avg > threshold));
382 float values[4] = {value, value, value, 1.0f};
383 copy_v4_v4(default_value, values);
384 }
385 else {
386 float *default_value = version_cycles_node_socket_float_value(alpha.socket);
387 *default_value = float((alpha.is_transparency) ? (*default_value > 1.0f - threshold) :
388 (*default_value > threshold));
389 }
390 }
391 }
392 return true;
393}
394
396{
397 if (!material->use_nodes || material->nodetree == nullptr) {
398 return;
399 }
400 bNodeTree *ntree = material->nodetree;
401
404 if (output_node == nullptr) {
405 return;
406 }
407
408 bNodeSocket *existing_out_sock = blender::bke::node_find_socket(
409 *output_node, SOCK_IN, "Surface");
410 bNodeSocket *volume_sock = blender::bke::node_find_socket(*output_node, SOCK_IN, "Volume");
411 if (existing_out_sock->link == nullptr && volume_sock->link) {
412 /* Don't apply versioning to a material that only has a volumetric input as this makes the
413 * object surface opaque to the camera, hiding the volume inside. */
414 return;
415 }
416
417 if (output_node->custom1 == SHD_OUTPUT_ALL) {
418 /* We do not want to affect Cycles. So we split the output into two specific outputs. */
419 output_node->custom1 = SHD_OUTPUT_CYCLES;
420
421 bNode *new_output = blender::bke::node_add_node(nullptr, *ntree, "ShaderNodeOutputMaterial");
422 new_output->custom1 = SHD_OUTPUT_EEVEE;
423 new_output->parent = output_node->parent;
424 new_output->locx_legacy = output_node->locx_legacy;
425 new_output->locy_legacy = output_node->locy_legacy - output_node->height - 120;
426
427 auto copy_link = [&](const char *socket_name) {
428 bNodeSocket *sock = blender::bke::node_find_socket(*output_node, SOCK_IN, socket_name);
429 if (sock && sock->link) {
430 bNodeLink *link = sock->link;
431 bNodeSocket *to_sock = blender::bke::node_find_socket(*new_output, SOCK_IN, socket_name);
433 *ntree, *link->fromnode, *link->fromsock, *new_output, *to_sock);
434 }
435 };
436
437 /* Don't copy surface as that is handled later */
438 copy_link("Volume");
439 copy_link("Displacement");
440 copy_link("Thickness");
441
442 output_node = new_output;
443 }
444
445 bNodeSocket *out_sock = blender::bke::node_find_socket(*output_node, SOCK_IN, "Surface");
446 bNodeSocket *old_out_sock = blender::bke::node_find_socket(*old_output_node, SOCK_IN, "Surface");
447
448 /* Add mix node for mixing between original material, and transparent BSDF for shadows */
449 bNode *mix_node = blender::bke::node_add_node(nullptr, *ntree, "ShaderNodeMixShader");
450 STRNCPY(mix_node->label, "Disable Shadow");
451 mix_node->flag |= NODE_COLLAPSED;
452 mix_node->parent = output_node->parent;
453 mix_node->locx_legacy = output_node->locx_legacy;
454 mix_node->locy_legacy = output_node->locy_legacy - output_node->height - 120;
455 bNodeSocket *mix_fac = static_cast<bNodeSocket *>(BLI_findlink(&mix_node->inputs, 0));
456 bNodeSocket *mix_in_1 = static_cast<bNodeSocket *>(BLI_findlink(&mix_node->inputs, 1));
457 bNodeSocket *mix_in_2 = static_cast<bNodeSocket *>(BLI_findlink(&mix_node->inputs, 2));
458 bNodeSocket *mix_out = static_cast<bNodeSocket *>(BLI_findlink(&mix_node->outputs, 0));
459 if (old_out_sock->link != nullptr) {
461 *old_out_sock->link->fromnode,
462 *old_out_sock->link->fromsock,
463 *mix_node,
464 *mix_in_1);
465 if (out_sock->link != nullptr) {
466 blender::bke::node_remove_link(ntree, *out_sock->link);
467 }
468 }
469 blender::bke::node_add_link(*ntree, *mix_node, *mix_out, *output_node, *out_sock);
470
471 /* Add light path node to control shadow visibility */
472 bNode *lp_node = blender::bke::node_add_node(nullptr, *ntree, "ShaderNodeLightPath");
473 lp_node->flag |= NODE_COLLAPSED;
474 lp_node->parent = output_node->parent;
475 lp_node->locx_legacy = output_node->locx_legacy;
476 lp_node->locy_legacy = mix_node->locy_legacy + 35;
477 bNodeSocket *is_shadow = blender::bke::node_find_socket(*lp_node, SOCK_OUT, "Is Shadow Ray");
478 blender::bke::node_add_link(*ntree, *lp_node, *is_shadow, *mix_node, *mix_fac);
479 /* Hide unconnected sockets for cleaner look. */
480 LISTBASE_FOREACH (bNodeSocket *, sock, &lp_node->outputs) {
481 if (sock != is_shadow) {
482 sock->flag |= SOCK_HIDDEN;
483 }
484 }
485
486 /* Add transparent BSDF to make shadows transparent. */
487 bNode *bsdf_node = blender::bke::node_add_node(nullptr, *ntree, "ShaderNodeBsdfTransparent");
488 bsdf_node->flag |= NODE_COLLAPSED;
489 bsdf_node->parent = output_node->parent;
490 bsdf_node->locx_legacy = output_node->locx_legacy;
491 bsdf_node->locy_legacy = mix_node->locy_legacy - 35;
492 bNodeSocket *bsdf_out = blender::bke::node_find_socket(*bsdf_node, SOCK_OUT, "BSDF");
493 blender::bke::node_add_link(*ntree, *bsdf_node, *bsdf_out, *mix_node, *mix_in_2);
494}
495
497{
498 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 15)) {
499 /* Change drivers and animation on "armature.collections" to
500 * ".collections_all", so that they are drawn correctly in the tree view,
501 * and keep working when the collection is moved around in the hierarchy. */
502 LISTBASE_FOREACH (bArmature *, arm, &bmain->armatures) {
503 AnimData *adt = BKE_animdata_from_id(&arm->id);
504 if (!adt) {
505 continue;
506 }
507
508 LISTBASE_FOREACH (FCurve *, fcurve, &adt->drivers) {
510 }
511 if (adt->action) {
512 LISTBASE_FOREACH (FCurve *, fcurve, &adt->action->curves) {
514 }
515 }
516 }
517 }
518
519 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 23)) {
520 /* Shift animation data to accommodate the new Roughness input. */
523 }
524
525 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 50)) {
527 LISTBASE_FOREACH (Object *, object, &bmain->objects) {
529 }
530 }
531 }
532
533 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 51)) {
534 /* Convert blend method to math nodes. */
536 LISTBASE_FOREACH (Material *, material, &bmain->materials) {
537 if (!material->use_nodes || material->nodetree == nullptr) {
538 /* Nothing to version. */
539 }
540 else if (ELEM(material->blend_method, MA_BM_HASHED, MA_BM_BLEND)) {
541 /* Compatible modes. Nothing to change. */
542 }
543 else if (material->blend_shadow == MA_BS_NONE) {
544 /* No need to match the surface since shadows are disabled. */
545 }
546 else if (material->blend_shadow == MA_BS_SOLID) {
547 /* This is already versioned an transferred to `transparent_shadows`. */
548 }
549 else if ((material->blend_shadow == MA_BS_CLIP && material->blend_method != MA_BM_CLIP) ||
550 (material->blend_shadow == MA_BS_HASHED))
551 {
553 fd->reports,
555 RPT_("Material %s could not be converted because of different Blend Mode "
556 "and Shadow Mode (need manual adjustment)\n"),
557 material->id.name + 2);
558 }
559 else {
560 /* TODO(fclem): Check if threshold is driven or has animation. Bail out if needed? */
561
562 float threshold = (material->blend_method == MA_BM_CLIP) ? material->alpha_threshold :
563 2.0f;
564
565 if (!versioning_eevee_material_blend_mode_settings(material->nodetree, threshold)) {
568 RPT_("Material %s could not be converted because of non-trivial "
569 "alpha blending (need manual adjustment)\n"),
570 material->id.name + 2);
571 }
572 }
573
574 if (material->blend_shadow == MA_BS_NONE) {
576 }
577 /* Set blend_mode & blend_shadow for forward compatibility. */
578 material->blend_method = (material->blend_method != MA_BM_BLEND) ? MA_BM_HASHED :
580 material->blend_shadow = (material->blend_shadow == MA_BS_SOLID) ? MA_BS_SOLID :
582 }
583 }
584 }
585}
586
588{
589 /* R_IMF_IMTYPE_AVIRAW and R_IMF_IMTYPE_AVIJPEG. */
590 constexpr char deprecated_avi_raw_imtype = 15;
591 constexpr char deprecated_avi_jpeg_imtype = 16;
592 if (ELEM(scene->r.im_format.imtype, deprecated_avi_raw_imtype, deprecated_avi_jpeg_imtype)) {
594 }
595}
596
597/* The Hue Correct curve now wraps around by specifying CUMA_USE_WRAPPING, which means it no longer
598 * makes sense to have curve maps outside of the [0, 1] range, so enable clipping and reset the
599 * clip and view ranges. */
600static void hue_correct_set_wrapping(CurveMapping *curve_mapping)
601{
602 curve_mapping->flag |= CUMA_DO_CLIP;
603 curve_mapping->flag |= CUMA_USE_WRAPPING;
604
605 curve_mapping->clipr.xmin = 0.0f;
606 curve_mapping->clipr.xmax = 1.0f;
607 curve_mapping->clipr.ymin = 0.0f;
608 curve_mapping->clipr.ymax = 1.0f;
609
610 curve_mapping->curr.xmin = 0.0f;
611 curve_mapping->curr.xmax = 1.0f;
612 curve_mapping->curr.ymin = 0.0f;
613 curve_mapping->curr.ymax = 1.0f;
614}
615
616static bool strip_hue_correct_set_wrapping(Strip *strip, void * /*user_data*/)
617{
619 if (smd->type == eSeqModifierType_HueCorrect) {
621 CurveMapping *cumap = (CurveMapping *)&hcmd->curve_mapping;
623 }
624 }
625 return true;
626}
627
629{
630 if (ntree->type == NTREE_COMPOSIT) {
631 LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree->nodes) {
632
633 if (node->type_legacy == CMP_NODE_HUECORRECT) {
634 CurveMapping *cumap = (CurveMapping *)node->storage;
636 }
637 }
638 }
639}
640
642{
643 LISTBASE_FOREACH (bScreen *, screen, &bmain.screens) {
644 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
645 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
646 if (sl->spacetype != SPACE_IMAGE) {
647 continue;
648 }
649
650 ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase : &sl->regionbase;
651
652 if (ARegion *new_shelf_region = do_versions_add_region_if_not_found(
653 regionbase, RGN_TYPE_ASSET_SHELF, __func__, RGN_TYPE_TOOL_HEADER))
654 {
655 new_shelf_region->regiondata = MEM_callocN<RegionAssetShelf>(__func__);
656 new_shelf_region->alignment = RGN_ALIGN_BOTTOM;
657 new_shelf_region->flag |= RGN_FLAG_HIDDEN;
658 }
659 if (ARegion *new_shelf_header = do_versions_add_region_if_not_found(
661 {
662 new_shelf_header->alignment = RGN_ALIGN_BOTTOM | RGN_ALIGN_HIDE_WITH_PREV;
663 }
664 }
665 }
666 }
667}
668
669/* Convert EEVEE-Legacy refraction depth to EEVEE-Next thickness tree. */
670static void version_refraction_depth_to_thickness_value(bNodeTree *ntree, float thickness)
671{
672 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
673 if (node->type_legacy != SH_NODE_OUTPUT_MATERIAL) {
674 continue;
675 }
676
677 bNodeSocket *thickness_socket = blender::bke::node_find_socket(*node, SOCK_IN, "Thickness");
678 if (thickness_socket == nullptr) {
679 continue;
680 }
681
682 bool has_link = false;
683 LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
684 if (link->tosock == thickness_socket) {
685 /* Something is already plugged in. Don't modify anything. */
686 has_link = true;
687 }
688 }
689
690 if (has_link) {
691 continue;
692 }
693 bNode *value_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_VALUE);
694 value_node->parent = node->parent;
695 value_node->locx_legacy = node->locx_legacy;
696 value_node->locy_legacy = node->locy_legacy - 160.0f;
697 bNodeSocket *socket_value = blender::bke::node_find_socket(*value_node, SOCK_OUT, "Value");
698
699 *version_cycles_node_socket_float_value(socket_value) = thickness;
700
701 blender::bke::node_add_link(*ntree, *value_node, *socket_value, *node, *thickness_socket);
702 }
703
705}
706
707static void versioning_update_timecode(short int *tc)
708{
709 /* 2 = IMB_TC_FREE_RUN, 4 = IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN. */
710 if (ELEM(*tc, 2, 4)) {
711 *tc = IMB_TC_RECORD_RUN;
712 }
713}
714
715static bool strip_proxies_timecode_update(Strip *strip, void * /*user_data*/)
716{
717 if (strip->data == nullptr || strip->data->proxy == nullptr) {
718 return true;
719 }
720 StripProxy *proxy = strip->data->proxy;
722 return true;
723}
724
725static bool strip_text_data_update(Strip *strip, void * /*user_data*/)
726{
727 if (strip->type != STRIP_TYPE_TEXT || strip->effectdata == nullptr) {
728 return true;
729 }
730
731 TextVars *data = static_cast<TextVars *>(strip->effectdata);
732 if (data->shadow_angle == 0.0f) {
733 data->shadow_angle = DEG2RADF(65.0f);
734 data->shadow_offset = 0.04f;
735 data->shadow_blur = 0.0f;
736 }
737 if (data->outline_width == 0.0f) {
738 data->outline_color[3] = 0.7f;
739 data->outline_width = 0.05f;
740 }
741 return true;
742}
743
745{
746 using namespace blender;
747 for (GreasePencilDrawingBase *base : grease_pencil->drawings()) {
748 if (base->type != GP_DRAWING) {
749 continue;
750 }
751 bke::greasepencil::Drawing &drawing = reinterpret_cast<GreasePencilDrawing *>(base)->wrap();
752 const int layer_index = CustomData_get_named_layer_index(
753 &drawing.geometry.curve_data_legacy, CD_PROP_FLOAT, "hardness");
754 if (layer_index == -1) {
755 continue;
756 }
757 float *data = static_cast<float *>(
760 "hardness",
761 drawing.geometry.curve_num));
762 for (const int i : IndexRange(drawing.geometry.curve_num)) {
763 data[i] = 1.0f - data[i];
764 }
765 /* Rename the layer. */
766 STRNCPY_UTF8(drawing.geometry.curve_data_legacy.layers[layer_index].name, "softness");
767 }
768}
769
770void blo_do_versions_420(FileData *fd, Library * /*lib*/, Main *bmain)
771{
772 /* Keep point/spot light soft falloff for files created before 4.0. */
773 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 0)) {
774 LISTBASE_FOREACH (Light *, light, &bmain->lights) {
775 if (ELEM(light->type, LA_LOCAL, LA_SPOT)) {
776 light->mode |= LA_USE_SOFT_FALLOFF;
777 }
778 }
779 }
780
781 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 1)) {
782 using namespace blender::bke::greasepencil;
783 /* Initialize newly added scale layer transform to one. */
784 LISTBASE_FOREACH (GreasePencil *, grease_pencil, &bmain->grease_pencils) {
785 for (Layer *layer : grease_pencil->layers_for_write()) {
786 copy_v3_fl(layer->scale, 1.0f);
787 }
788 }
789 }
790
791 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 2)) {
792 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
793 bool is_cycles = scene && STREQ(scene->r.engine, RE_engine_id_CYCLES);
794 if (is_cycles) {
795 if (IDProperty *cscene = version_cycles_properties_from_ID(&scene->id)) {
796 int cposition = version_cycles_property_int(cscene, "motion_blur_position", 1);
797 BLI_assert(cposition >= 0 && cposition < 3);
798 int order_conversion[3] = {SCE_MB_START, SCE_MB_CENTER, SCE_MB_END};
799 scene->r.motion_blur_position = order_conversion[std::clamp(cposition, 0, 2)];
800 }
801 }
802 else {
804 scene->r.mode, scene->eevee.flag & SCE_EEVEE_MOTION_BLUR_ENABLED_DEPRECATED, R_MBLUR);
805 scene->r.motion_blur_position = scene->eevee.motion_blur_position_deprecated;
806 scene->r.motion_blur_shutter = scene->eevee.motion_blur_shutter_deprecated;
807 }
808 }
809 }
810
811 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 3)) {
812 constexpr int NTREE_EXECUTION_MODE_CPU = 0;
813 constexpr int NTREE_EXECUTION_MODE_FULL_FRAME = 1;
814
815 constexpr int NTREE_COM_GROUPNODE_BUFFER = 1 << 3;
816 constexpr int NTREE_COM_OPENCL = 1 << 1;
817
818 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
819 if (ntree->type != NTREE_COMPOSIT) {
820 continue;
821 }
822
823 ntree->flag &= ~(NTREE_COM_GROUPNODE_BUFFER | NTREE_COM_OPENCL);
824
825 if (ntree->execution_mode == NTREE_EXECUTION_MODE_FULL_FRAME) {
826 ntree->execution_mode = NTREE_EXECUTION_MODE_CPU;
827 }
828 }
830 }
831
832 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 4)) {
833 if (!DNA_struct_member_exists(fd->filesdna, "SpaceImage", "float", "stretch_opacity")) {
834 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
835 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
836 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
837 if (sl->spacetype == SPACE_IMAGE) {
838 SpaceImage *sima = reinterpret_cast<SpaceImage *>(sl);
839 sima->stretch_opacity = 0.9f;
840 }
841 }
842 }
843 }
844 }
845 }
846
847 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 5)) {
848 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
850 }
851 }
852
853 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 6)) {
854 LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
855 if (BrushCurvesSculptSettings *settings = brush->curves_sculpt_settings) {
857 settings->curve_radius = 0.01f;
858 }
859 }
860 }
861
862 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 8)) {
863 LISTBASE_FOREACH (Light *, light, &bmain->lights) {
864 light->shadow_filter_radius = 1.0f;
865 }
866 }
867
868 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 9)) {
869 const float default_snap_angle_increment = DEG2RADF(5.0f);
870 const float default_snap_angle_increment_precision = DEG2RADF(1.0f);
871 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
872 scene->toolsettings->snap_angle_increment_2d = default_snap_angle_increment;
873 scene->toolsettings->snap_angle_increment_3d = default_snap_angle_increment;
874 scene->toolsettings->snap_angle_increment_2d_precision =
875 default_snap_angle_increment_precision;
876 scene->toolsettings->snap_angle_increment_3d_precision =
877 default_snap_angle_increment_precision;
878 }
879 }
880
881 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 10)) {
882 if (!DNA_struct_member_exists(fd->filesdna, "SceneEEVEE", "int", "gtao_resolution")) {
883 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
884 scene->eevee.fast_gi_resolution = 2;
885 }
886 }
887 }
888
889 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 12)) {
890 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
892 }
894
895 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
896 if (scene->ed != nullptr) {
897 blender::seq::foreach_strip(&scene->ed->seqbase, strip_hue_correct_set_wrapping, nullptr);
898 }
899 }
900 }
901
902 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 14)) {
903 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
904 if (bMotionPath *mpath = ob->mpath) {
905 mpath->color_post[0] = 0.1f;
906 mpath->color_post[1] = 1.0f;
907 mpath->color_post[2] = 0.1f;
908 }
909 if (!ob->pose) {
910 continue;
911 }
912 LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
913 if (bMotionPath *mpath = pchan->mpath) {
914 mpath->color_post[0] = 0.1f;
915 mpath->color_post[1] = 1.0f;
916 mpath->color_post[2] = 0.1f;
917 }
918 }
919 }
920 }
921
922 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 18)) {
923 if (!DNA_struct_member_exists(fd->filesdna, "Light", "float", "transmission_fac")) {
924 LISTBASE_FOREACH (Light *, light, &bmain->lights) {
925 /* Refracted light was not supported in legacy EEVEE. Set it to zero for compatibility with
926 * older files. */
927 light->transmission_fac = 0.0f;
928 }
929 }
930 }
931
932 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 19)) {
933 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
934 /* Keep legacy EEVEE old behavior. */
935 scene->eevee.flag |= SCE_EEVEE_VOLUME_CUSTOM_RANGE;
936 }
937
938 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
939 scene->eevee.clamp_surface_indirect = 10.0f;
940 /* Make contribution of indirect lighting very small (but non-null) to avoid world lighting
941 * and volume lightprobe changing the appearance of volume objects. */
942 scene->eevee.clamp_volume_indirect = 1e-8f;
943 }
944 }
945
946 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 20)) {
947 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
948 SequencerToolSettings *sequencer_tool_settings = blender::seq::tool_settings_ensure(scene);
949 sequencer_tool_settings->snap_mode |= SEQ_SNAP_TO_MARKERS;
950 }
951 }
952
953 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 21)) {
955 }
956
957 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 22)) {
958 /* Display missing media in sequencer by default. */
959 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
960 if (scene->ed != nullptr) {
961 scene->ed->show_missing_media_flag |= SEQ_EDIT_SHOW_MISSING_MEDIA;
962 }
963 }
964 }
965
966 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 24)) {
967 if (!DNA_struct_member_exists(fd->filesdna, "Material", "char", "thickness_mode")) {
968 LISTBASE_FOREACH (Material *, material, &bmain->materials) {
969 if (material->blend_flag & MA_BL_TRANSLUCENCY) {
970 /* EEVEE Legacy used thickness from shadow map when translucency was on. */
971 material->blend_flag |= MA_BL_THICKNESS_FROM_SHADOW;
972 }
973 if ((material->blend_flag & MA_BL_SS_REFRACTION) && material->use_nodes &&
974 material->nodetree)
975 {
976 /* EEVEE Legacy used slab assumption. */
977 material->thickness_mode = MA_THICKNESS_SLAB;
978 version_refraction_depth_to_thickness_value(material->nodetree, material->refract_depth);
979 }
980 }
981 }
982 }
983
984 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 25)) {
985 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
986 if (ntree->type != NTREE_COMPOSIT) {
987 continue;
988 }
989 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
990 if (node->type_legacy != CMP_NODE_BLUR) {
991 continue;
992 }
993
994 NodeBlurData &blur_data = *static_cast<NodeBlurData *>(node->storage);
995
996 if (blur_data.filtertype != R_FILTER_FAST_GAUSS) {
997 continue;
998 }
999
1000 /* The size of the Fast Gaussian mode of blur decreased by the following factor to match
1001 * other blur sizes. So increase it back. */
1002 const float size_factor = 3.0f / 2.0f;
1003 blur_data.sizex *= size_factor;
1004 blur_data.sizey *= size_factor;
1005 blur_data.percentx *= size_factor;
1006 blur_data.percenty *= size_factor;
1007 }
1008 }
1010 }
1011
1012 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 26)) {
1013 if (!DNA_struct_member_exists(fd->filesdna, "SceneEEVEE", "float", "shadow_resolution_scale"))
1014 {
1015 SceneEEVEE default_scene_eevee = *DNA_struct_default_get(SceneEEVEE);
1016 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1017 scene->eevee.shadow_resolution_scale = default_scene_eevee.shadow_resolution_scale;
1018 }
1019 }
1020 }
1021
1022 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 27)) {
1023 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1024 if (scene->ed != nullptr) {
1025 scene->ed->cache_flag &= ~(SEQ_CACHE_UNUSED_5 | SEQ_CACHE_UNUSED_6 | SEQ_CACHE_UNUSED_7 |
1027 }
1028 }
1029 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1030 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1031 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1032 if (sl->spacetype == SPACE_SEQ) {
1033 SpaceSeq *sseq = (SpaceSeq *)sl;
1035 }
1036 }
1037 }
1038 }
1039 }
1040
1041 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 28)) {
1042 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1043 if (scene->ed != nullptr) {
1044 blender::seq::foreach_strip(&scene->ed->seqbase, strip_proxies_timecode_update, nullptr);
1045 }
1046 }
1047
1048 LISTBASE_FOREACH (MovieClip *, clip, &bmain->movieclips) {
1049 MovieClipProxy proxy = clip->proxy;
1051 }
1052 }
1053
1054 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 29)) {
1055 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1056 if (scene->ed) {
1057 blender::seq::foreach_strip(&scene->ed->seqbase, strip_text_data_update, nullptr);
1058 }
1059 }
1060 }
1061
1062 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 30)) {
1063 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1064 if (scene->nodetree) {
1065 scene->nodetree->flag &= ~NTREE_UNUSED_2;
1066 }
1067 }
1068 }
1069
1070 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 31)) {
1071 LISTBASE_FOREACH (LightProbe *, lightprobe, &bmain->lightprobes) {
1072 /* Guess a somewhat correct density given the resolution. But very low resolution need
1073 * a decent enough density to work. */
1074 lightprobe->grid_surfel_density = max_ii(20,
1075 2 * max_iii(lightprobe->grid_resolution_x,
1076 lightprobe->grid_resolution_y,
1077 lightprobe->grid_resolution_z));
1078 }
1079 }
1080
1081 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 31)) {
1082 bool only_uses_eevee_legacy_or_workbench = true;
1083 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1085 only_uses_eevee_legacy_or_workbench = false;
1086 }
1087 }
1088 /* Mark old EEVEE world volumes for showing conversion operator. */
1089 LISTBASE_FOREACH (World *, world, &bmain->worlds) {
1090 if (world->nodetree) {
1091 bNode *output_node = version_eevee_output_node_get(world->nodetree, SH_NODE_OUTPUT_WORLD);
1092 if (output_node) {
1093 bNodeSocket *volume_input_socket = static_cast<bNodeSocket *>(
1094 BLI_findlink(&output_node->inputs, 1));
1095 if (volume_input_socket) {
1096 LISTBASE_FOREACH (bNodeLink *, node_link, &world->nodetree->links) {
1097 if (node_link->tonode == output_node && node_link->tosock == volume_input_socket) {
1098 world->flag |= WO_USE_EEVEE_FINITE_VOLUME;
1099 /* Only display a warning message if we are sure this can be used by EEVEE. */
1100 if (only_uses_eevee_legacy_or_workbench) {
1103 RPT_("%s contains a volume shader that might need to be "
1104 "converted to object (see world volume panel)\n"),
1105 world->id.name + 2);
1106 }
1107 }
1108 }
1109 }
1110 }
1111 }
1112 }
1113 }
1114
1115 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 33)) {
1116 constexpr int NTREE_EXECUTION_MODE_GPU = 2;
1117
1118 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1119 if (scene->nodetree) {
1120 if (scene->nodetree->execution_mode == NTREE_EXECUTION_MODE_GPU) {
1121 scene->r.compositor_device = SCE_COMPOSITOR_DEVICE_GPU;
1122 }
1123 scene->r.compositor_precision = scene->nodetree->precision;
1124 }
1125 }
1126 }
1127
1128 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 34)) {
1129 float shadow_max_res_sun = 0.001f;
1130 float shadow_max_res_local = 0.001f;
1131 bool shadow_resolution_absolute = false;
1132 /* Try to get default resolution from scene setting. */
1133 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1134 shadow_max_res_local = (2.0f * M_SQRT2) / scene->eevee.shadow_cube_size_deprecated;
1135 /* Round to avoid weird numbers in the UI. */
1136 shadow_max_res_local = ceil(shadow_max_res_local * 1000.0f) / 1000.0f;
1137 shadow_resolution_absolute = true;
1138 break;
1139 }
1140
1141 LISTBASE_FOREACH (Light *, light, &bmain->lights) {
1142 if (light->type == LA_SUN) {
1143 /* Sun are too complex to convert. Need user interaction. */
1144 light->shadow_maximum_resolution = shadow_max_res_sun;
1145 SET_FLAG_FROM_TEST(light->mode, false, LA_SHAD_RES_ABSOLUTE);
1146 }
1147 else {
1148 light->shadow_maximum_resolution = shadow_max_res_local;
1149 SET_FLAG_FROM_TEST(light->mode, shadow_resolution_absolute, LA_SHAD_RES_ABSOLUTE);
1150 }
1151 }
1152 }
1153
1154 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 36)) {
1155 LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
1156 /* Only for grease pencil brushes. */
1157 if (brush->gpencil_settings) {
1158 /* Use the `Scene` radius unit by default (confusingly named `BRUSH_LOCK_SIZE`).
1159 * Convert the radius to be the same visual size as in GPv2. */
1160 brush->flag |= BRUSH_LOCK_SIZE;
1161 brush->unprojected_size = brush->size *
1163 }
1164 }
1165 }
1166
1167 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 37)) {
1168 const World *default_world = DNA_struct_default_get(World);
1169 LISTBASE_FOREACH (World *, world, &bmain->worlds) {
1170 world->sun_threshold = default_world->sun_threshold;
1171 world->sun_angle = default_world->sun_angle;
1172 world->sun_shadow_maximum_resolution = default_world->sun_shadow_maximum_resolution;
1173 /* Having the sun extracted is mandatory to keep the same look and avoid too much light
1174 * leaking compared to EEVEE-Legacy. But adding shadows might create performance overhead and
1175 * change the result in a very different way. So we disable shadows in older file. */
1176 world->flag &= ~WO_USE_SUN_SHADOW;
1177 }
1178 }
1179
1180 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 38)) {
1181 LISTBASE_FOREACH (GreasePencil *, grease_pencil, &bmain->grease_pencils) {
1183 }
1184 }
1185
1186 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 39)) {
1187 /* Unify cast shadow property with Cycles. */
1189 const Light *default_light = DNA_struct_default_get(Light);
1190 LISTBASE_FOREACH (Light *, light, &bmain->lights) {
1191 IDProperty *clight = version_cycles_properties_from_ID(&light->id);
1192 if (clight) {
1194 clight, "cast_shadow", default_light->mode & LA_SHADOW);
1195 SET_FLAG_FROM_TEST(light->mode, value, LA_SHADOW);
1196 }
1197 }
1198 }
1199 }
1200
1201 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 40)) {
1202 LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
1203 version_node_input_socket_name(ntree, FN_NODE_COMBINE_TRANSFORM, "Location", "Translation");
1205 ntree, FN_NODE_SEPARATE_TRANSFORM, "Location", "Translation");
1206 }
1207 }
1208
1209 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 41)) {
1210 const Light *default_light = DNA_struct_default_get(Light);
1211 LISTBASE_FOREACH (Light *, light, &bmain->lights) {
1212 light->shadow_jitter_overblur = default_light->shadow_jitter_overblur;
1213 }
1214 }
1215
1216 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 43)) {
1217 const World *default_world = DNA_struct_default_get(World);
1218 LISTBASE_FOREACH (World *, world, &bmain->worlds) {
1219 world->sun_shadow_maximum_resolution = default_world->sun_shadow_maximum_resolution;
1220 world->sun_shadow_filter_radius = default_world->sun_shadow_filter_radius;
1221 }
1222 }
1223
1224 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 44)) {
1225 const Scene *default_scene = DNA_struct_default_get(Scene);
1226 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1227 scene->eevee.fast_gi_step_count = default_scene->eevee.fast_gi_step_count;
1228 scene->eevee.fast_gi_ray_count = default_scene->eevee.fast_gi_ray_count;
1229 }
1230 }
1231
1232 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 45)) {
1233 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1234 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1235 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1236 if (sl->spacetype == SPACE_VIEW3D) {
1237 View3D *v3d = reinterpret_cast<View3D *>(sl);
1239 }
1240 }
1241 }
1242 }
1243 }
1244
1245 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 46)) {
1246 const Scene *default_scene = DNA_struct_default_get(Scene);
1247 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1248 scene->eevee.fast_gi_thickness_near = default_scene->eevee.fast_gi_thickness_near;
1249 scene->eevee.fast_gi_thickness_far = default_scene->eevee.fast_gi_thickness_far;
1250 }
1251 }
1252 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 48)) {
1253 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
1254 if (!ob->pose) {
1255 continue;
1256 }
1257 LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
1258 pchan->custom_shape_wire_width = 1.0;
1259 }
1260 }
1261 }
1262
1263 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 49)) {
1264 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1265 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1266 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1267 if (sl->spacetype == SPACE_VIEW3D) {
1268 View3D *v3d = reinterpret_cast<View3D *>(sl);
1270 }
1271 }
1272 }
1273 }
1274 }
1275
1276 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 50)) {
1277 LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
1278 if (ntree->type != NTREE_GEOMETRY) {
1279 continue;
1280 }
1281 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
1282 if (node->type_legacy != GEO_NODE_CAPTURE_ATTRIBUTE) {
1283 continue;
1284 }
1286 node->storage);
1287 if (storage->next_identifier > 0) {
1288 continue;
1289 }
1290 storage->capture_items_num = 1;
1292 storage->capture_items_num, __func__);
1294 item.data_type = storage->data_type_legacy;
1295 item.identifier = storage->next_identifier++;
1296 item.name = BLI_strdup("Value");
1297 }
1298 }
1299 }
1300
1301 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 53)) {
1302 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1303 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1304 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1305 if (sl->spacetype == SPACE_NODE) {
1306 SpaceNode *snode = reinterpret_cast<SpaceNode *>(sl);
1308 }
1309 }
1310 }
1311 }
1312 }
1313
1314 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 55)) {
1315 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1316 if (ntree->type != NTREE_COMPOSIT) {
1317 continue;
1318 }
1319 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
1320 if (node->type_legacy != CMP_NODE_CURVE_RGB) {
1321 continue;
1322 }
1323
1324 CurveMapping &curve_mapping = *static_cast<CurveMapping *>(node->storage);
1325
1326 /* Film-like tone only works with the combined curve, which is the fourth curve, so make
1327 * the combined curve current, as we now hide the rest of the curves since they no longer
1328 * have an effect. */
1329 if (curve_mapping.tone == CURVE_TONE_FILMLIKE) {
1330 curve_mapping.cur = 3;
1331 }
1332 }
1333 }
1335 }
1336
1337 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 60) ||
1338 (bmain->versionfile == 403 && !MAIN_VERSION_FILE_ATLEAST(bmain, 403, 3)))
1339 {
1340 /* Limit Rotation constraints from old files should use the legacy Limit
1341 * Rotation behavior. */
1342 LISTBASE_FOREACH (Object *, obj, &bmain->objects) {
1343 LISTBASE_FOREACH (bConstraint *, constraint, &obj->constraints) {
1344 if (constraint->type != CONSTRAINT_TYPE_ROTLIMIT) {
1345 continue;
1346 }
1347 static_cast<bRotLimitConstraint *>(constraint->data)->flag |= LIMIT_ROT_LEGACY_BEHAVIOR;
1348 }
1349
1350 if (!obj->pose) {
1351 continue;
1352 }
1353 LISTBASE_FOREACH (bPoseChannel *, pbone, &obj->pose->chanbase) {
1354 LISTBASE_FOREACH (bConstraint *, constraint, &pbone->constraints) {
1355 if (constraint->type != CONSTRAINT_TYPE_ROTLIMIT) {
1356 continue;
1357 }
1358 static_cast<bRotLimitConstraint *>(constraint->data)->flag |= LIMIT_ROT_LEGACY_BEHAVIOR;
1359 }
1360 }
1361 }
1362 }
1363
1364 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 61)) {
1365 /* LIGHT_PROBE_RESOLUTION_64 has been removed in EEVEE-Next as the tedrahedral mapping is to
1366 * low res to be usable. */
1367 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1368 scene->eevee.gi_cubemap_resolution = std::max(scene->eevee.gi_cubemap_resolution, 128);
1369 }
1370 }
1371
1372 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 64)) {
1374 /* Re-apply versioning made for EEVEE-Next in 4.1 before it got delayed. */
1375 LISTBASE_FOREACH (Material *, material, &bmain->materials) {
1376 bool transparent_shadows = material->blend_shadow != MA_BS_SOLID;
1377 SET_FLAG_FROM_TEST(material->blend_flag, transparent_shadows, MA_BL_TRANSPARENT_SHADOW);
1378 }
1379 LISTBASE_FOREACH (Material *, mat, &bmain->materials) {
1380 mat->surface_render_method = (mat->blend_method == MA_BM_BLEND) ?
1383 }
1384 }
1385 }
1386
1387 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 65)) {
1388 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
1389 if (node_tree->type != NTREE_COMPOSIT) {
1390 continue;
1391 }
1392 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
1393 if (node->type_legacy == CMP_NODE_DENOISE) {
1394 if (node->storage == nullptr) {
1395 /* Some known files were saved without a valid storage. These are likely corrupt files
1396 * that have been produced by a non official blender release. The node type will be set
1397 * to Undefined during linking, see #ntree_set_typeinfo. However, a valid storage might
1398 * be needed for future versioning (before linking), see
1399 * #do_version_denoise_menus_to_inputs so we set a valid storage at this stage such
1400 * that the node becomes well defined. */
1401 NodeDenoise *ndg = MEM_callocN<NodeDenoise>(__func__);
1402 ndg->hdr = true;
1403 ndg->prefilter = CMP_NODE_DENOISE_PREFILTER_ACCURATE;
1404 node->storage = ndg;
1405 }
1406 }
1407 }
1408 }
1410 }
1411}
AnimData * BKE_animdata_from_id(const ID *id)
Definition anim_data.cc:83
CustomData interface, see also DNA_customdata_types.h.
void * CustomData_get_layer_named_for_write(CustomData *data, eCustomDataType type, blender::StringRef name, int totelem)
int CustomData_get_named_layer_index(const CustomData *data, eCustomDataType type, blender::StringRef name)
Low-level operations for grease pencil.
#define MAIN_VERSION_FILE_ATLEAST(main, ver, subver)
Definition BKE_main.hh:658
General operations, lookup, etc. for materials.
short * BKE_object_material_len_p(Object *ob)
Material * BKE_object_material_get(Object *ob, short act)
#define NODE_REROUTE
Definition BKE_node.hh:813
#define FOREACH_NODETREE_END
Definition BKE_node.hh:881
#define NODE_GROUP
Definition BKE_node.hh:811
#define FOREACH_NODETREE_BEGIN(bmain, _nodetree, _id)
Definition BKE_node.hh:871
#define SH_NODE_MIX_SHADER
#define CMP_NODE_DENOISE
#define FN_NODE_SEPARATE_TRANSFORM
#define SH_NODE_OUTPUT_WORLD
#define SH_NODE_BSDF_PRINCIPLED
#define SH_NODE_ADD_SHADER
#define SH_NODE_SUBSURFACE_SCATTERING
#define SH_NODE_VALUE
#define CMP_NODE_HUECORRECT
#define SH_NODE_BSDF_TRANSPARENT
#define SH_NODE_OUTPUT_MATERIAL
#define CMP_NODE_CURVE_RGB
#define FN_NODE_COMBINE_TRANSFORM
#define SH_NODE_EEVEE_SPECULAR
#define GEO_NODE_CAPTURE_ATTRIBUTE
#define CMP_NODE_BLUR
@ RPT_WARNING
Definition BKE_report.hh:38
#define BLI_assert(a)
Definition BLI_assert.h:46
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)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
MINLINE int max_iii(int a, int b, int c)
#define DEG2RADF(_deg)
#define M_SQRT2
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void copy_v3_fl(float r[3], float f)
char * BLI_sprintfN(const char *__restrict format,...) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
Definition string.cc:41
#define STR_ELEM(...)
Definition BLI_string.h:661
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:693
#define STRNCPY_UTF8(dst, src)
#define SET_FLAG_FROM_TEST(value, test, flag)
#define ELEM(...)
#define STREQ(a, b)
void BLO_reportf_wrap(BlendFileReadReport *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
#define RPT_(msgid)
@ BRUSH_LOCK_SIZE
@ BRUSH_CURVES_SCULPT_FLAG_INTERPOLATE_RADIUS
@ CUMA_DO_CLIP
@ CUMA_USE_WRAPPING
@ CURVE_TONE_FILMLIKE
@ CONSTRAINT_TYPE_ROTLIMIT
@ LIMIT_ROT_LEGACY_BEHAVIOR
@ CD_PROP_FLOAT
#define DNA_struct_default_get(struct_name)
blenloader genfile private function prototypes
@ LA_LOCAL
@ LA_SPOT
@ LA_SUN
@ LA_SHAD_RES_ABSOLUTE
@ LA_SHADOW
@ LA_USE_SOFT_FALLOFF
@ MA_BL_TRANSPARENT_SHADOW
@ MA_BL_THICKNESS_FROM_SHADOW
@ MA_BL_TRANSLUCENCY
@ MA_BL_SS_REFRACTION
@ MA_SURFACE_METHOD_DEFERRED
@ MA_SURFACE_METHOD_FORWARD
@ MA_BM_CLIP
@ MA_BM_HASHED
@ MA_BM_BLEND
@ MA_BS_HASHED
@ MA_BS_CLIP
@ MA_BS_NONE
@ MA_BS_SOLID
@ MA_THICKNESS_SLAB
@ NODE_MATH_GREATER_THAN
@ SHD_OUTPUT_CYCLES
@ SHD_OUTPUT_ALL
@ SHD_OUTPUT_EEVEE
@ NTREE_UNUSED_2
@ NODE_COLLAPSED
@ NTREE_SHADER
@ NTREE_GEOMETRY
@ NTREE_COMPOSIT
@ SOCK_OUT
@ SOCK_IN
@ SOCK_HIDDEN
@ SOCK_RGBA
@ CMP_NODE_DENOISE_PREFILTER_ACCURATE
@ OB_HIDE_SHADOW
@ SCE_MB_START
@ SCE_MB_END
@ SCE_MB_CENTER
@ R_MBLUR
@ SCE_EEVEE_VOLUME_CUSTOM_RANGE
@ SCE_EEVEE_MOTION_BLUR_ENABLED_DEPRECATED
@ SCE_COMPOSITOR_DEVICE_GPU
@ SEQ_SNAP_TO_MARKERS
@ R_FILTER_FAST_GAUSS
@ R_IMF_IMTYPE_FFMPEG
@ RGN_ALIGN_HIDE_WITH_PREV
@ RGN_ALIGN_BOTTOM
@ RGN_TYPE_TOOL_HEADER
@ RGN_TYPE_ASSET_SHELF_HEADER
@ RGN_TYPE_ASSET_SHELF
@ RGN_FLAG_HIDDEN
@ eSeqModifierType_HueCorrect
@ SEQ_CACHE_UNUSED_8
@ SEQ_CACHE_UNUSED_5
@ SEQ_CACHE_UNUSED_7
@ SEQ_CACHE_UNUSED_6
@ SEQ_CACHE_UNUSED_9
@ STRIP_TYPE_TEXT
@ SEQ_EDIT_SHOW_MISSING_MEDIA
@ SN_OVERLAY_SHOW_REROUTE_AUTO_LABELS
@ SPACE_NODE
@ SPACE_SEQ
@ SPACE_IMAGE
@ SPACE_VIEW3D
@ SEQ_CACHE_SHOW_FINAL_OUT
@ V3D_SHOW_CAMERA_PASSEPARTOUT
@ V3D_SHOW_CAMERA_GUIDES
@ WO_USE_SUN_SHADOW
@ WO_USE_EEVEE_FINITE_VOLUME
@ IMB_TC_RECORD_RUN
Definition MOV_enums.hh:54
BMesh const char void * data
static T sum(const btAlignedObjectArray< T > &items)
constexpr bool startswith(StringRef prefix) const
constexpr StringRef drop_known_prefix(StringRef prefix) const
nullptr float
#define output
#define ceil
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_freeN(void *vmemh)
Definition mallocn.cc:113
constexpr float LEGACY_RADIUS_CONVERSION_FACTOR
bNodeSocket * node_find_socket(bNode &node, eNodeSocketInOut in_out, StringRef identifier)
Definition node.cc:2532
bNode * node_add_node(const bContext *C, bNodeTree &ntree, StringRef idname, std::optional< int > unique_identifier=std::nullopt)
Definition node.cc:3477
void node_remove_link(bNodeTree *ntree, bNodeLink &link)
Definition node.cc:3847
bNode * node_add_static_node(const bContext *C, bNodeTree &ntree, int type)
Definition node.cc:3500
bNodeLink & node_add_link(bNodeTree &ntree, bNode &fromnode, bNodeSocket &fromsock, bNode &tonode, bNodeSocket &tosock)
Definition node.cc:3810
void foreach_strip(ListBase *seqbase, ForEachFunc callback, void *user_data)
Definition iterator.cc:59
SequencerToolSettings * tool_settings_ensure(Scene *scene)
Definition sequencer.cc:375
float wrap(float value, float max, float min)
Definition node_math.h:103
const char * RE_engine_id_CYCLES
Definition scene.cc:1583
const char * RE_engine_id_BLENDER_WORKBENCH
Definition scene.cc:1582
const char * RE_engine_id_BLENDER_EEVEE
Definition scene.cc:1580
bool is_complex() const
static AlphaSource alpha_source(bNodeSocket *fac, bool inverted=false)
bool is_opaque() const
bool is_fully_transparent() const
bool is_transparent() const
static AlphaSource opaque()
AlphaState state
bool is_semi_transparent() const
bNodeSocket * socket
static AlphaSource mix(const AlphaSource &a, const AlphaSource &b, bNodeSocket *fac)
static AlphaSource fully_transparent(bNodeSocket *socket=nullptr, bool inverted=false)
static AlphaSource complex_alpha()
static AlphaSource add(const AlphaSource &a, const AlphaSource &b)
bAction * action
ListBase drivers
CustomData curve_data_legacy
CustomDataLayer * layers
char * rna_path
BlendFileReadReport * reports
Definition readfile.hh:192
SDNA * filesdna
Definition readfile.hh:105
struct CurveMapping curve_mapping
float shadow_jitter_overblur
void * first
ListBase lightprobes
Definition BKE_main.hh:296
ListBase brushes
Definition BKE_main.hh:302
ListBase scenes
Definition BKE_main.hh:278
ListBase grease_pencils
Definition BKE_main.hh:310
ListBase movieclips
Definition BKE_main.hh:311
ListBase lights
Definition BKE_main.hh:288
ListBase nodetrees
Definition BKE_main.hh:301
ListBase materials
Definition BKE_main.hh:284
ListBase armatures
Definition BKE_main.hh:299
ListBase worlds
Definition BKE_main.hh:291
ListBase screens
Definition BKE_main.hh:292
short versionfile
Definition BKE_main.hh:181
ListBase objects
Definition BKE_main.hh:280
struct bNodeTree * nodetree
NodeGeometryAttributeCaptureItem * capture_items
short visibility_flag
struct ImageFormatData im_format
float fast_gi_thickness_near
float shadow_resolution_scale
float fast_gi_thickness_far
struct RenderData r
struct SceneEEVEE eevee
float stretch_opacity
SpaceNodeOverlay overlay
struct SequencerCacheOverlay cache_overlay
StripProxy * proxy
StripData * data
void * effectdata
ListBase modifiers
float sun_angle
float sun_shadow_maximum_resolution
float sun_shadow_filter_radius
float sun_threshold
ListBase curves
struct bNodeLink * link
ListBase nodes
ListBase links
int16_t custom1
float width
ListBase inputs
float height
float locx_legacy
struct bNode * parent
int16_t type_legacy
float locy_legacy
char label[64]
ListBase outputs
float xmax
float xmin
float ymax
float ymin
i
Definition text_draw.cc:230
static bool strip_text_data_update(Strip *strip, void *)
static void versioning_node_hue_correct_set_wrappng(bNodeTree *ntree)
static void versioning_eevee_material_shadow_none(Material *material)
void blo_do_versions_420(FileData *fd, Library *, Main *bmain)
static bool versioning_eevee_material_blend_mode_settings(bNodeTree *ntree, float threshold)
static void version_bonecollection_anim(FCurve *fcurve)
static void image_settings_avi_to_ffmpeg(Scene *scene)
void do_versions_after_linking_420(FileData *fd, Main *bmain)
static void convert_grease_pencil_stroke_hardness_to_softness(GreasePencil *grease_pencil)
static void add_image_editor_asset_shelf(Main &bmain)
static bool strip_hue_correct_set_wrapping(Strip *strip, void *)
static void hue_correct_set_wrapping(CurveMapping *curve_mapping)
static bool strip_proxies_timecode_update(Strip *strip, void *)
static AlphaSource versioning_eevee_alpha_source_get(bNodeSocket *socket, int depth=0)
static void version_refraction_depth_to_thickness_value(bNodeTree *ntree, float thickness)
static void versioning_eevee_shadow_settings(Object *object)
static void versioning_update_timecode(short int *tc)
bNode * version_eevee_output_node_get(bNodeTree *ntree, int16_t node_type)
bool all_scenes_use(Main *bmain, const blender::Span< const char * > engines)
float * version_cycles_node_socket_float_value(bNodeSocket *socket)
IDProperty * version_cycles_properties_from_ID(ID *id)
int version_cycles_property_int(IDProperty *idprop, const char *name, int default_value)
float * version_cycles_node_socket_rgba_value(bNodeSocket *socket)
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_input_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)
void version_socket_update_is_used(bNodeTree *ntree)
ARegion * do_versions_add_region_if_not_found(ListBase *regionbase, int region_type, const char *, int link_after_region_type)
void version_node_output_socket_name(bNodeTree *ntree, const int node_type, const char *old_name, const char *new_name)
uint8_t flag
Definition wm_window.cc:145