Blender V5.0
versioning_500.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2025 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#define DNA_DEPRECATED_ALLOW
10
11#include <fmt/format.h>
12
13#include "MEM_guardedalloc.h"
14
15/* Define macros in `DNA_genfile.h`. */
16#define DNA_GENFILE_VERSIONING_MACROS
17
18#include "DNA_ID.h"
19#include "DNA_brush_types.h"
20#include "DNA_camera_types.h"
21#include "DNA_curves_types.h"
22#include "DNA_defaults.h"
23#include "DNA_genfile.h"
25#include "DNA_material_types.h"
26#include "DNA_mesh_types.h"
27#include "DNA_modifier_types.h"
28#include "DNA_node_types.h"
29#include "DNA_rigidbody_types.h"
30#include "DNA_scene_types.h"
31#include "DNA_screen_types.h"
32#include "DNA_sequence_types.h"
34#include "DNA_workspace_types.h"
35#include "DNA_world_types.h"
36
37#include "BLI_function_ref.hh"
38#include "BLI_listbase.h"
39#include "BLI_math_color.h"
40#include "BLI_math_numbers.hh"
41#include "BLI_math_vector.h"
42#include "BLI_math_vector.hh"
44#include "BLI_set.hh"
45#include "BLI_string_ref.hh"
46#include "BLI_string_utf8.h"
47#include "BLI_string_utils.hh"
48#include "BLI_sys_types.h"
49
50#include "BKE_anim_data.hh"
51#include "BKE_animsys.h"
52#include "BKE_armature.hh"
54#include "BKE_colortools.hh"
55#include "BKE_curves.hh"
56#include "BKE_grease_pencil.hh"
57#include "BKE_idprop.hh"
58#include "BKE_image_format.hh"
59#include "BKE_lib_id.hh"
60#include "BKE_main.hh"
62#include "BKE_node.hh"
64#include "BKE_node_runtime.hh"
65#include "BKE_paint.hh"
66#include "BKE_pointcache.h"
67#include "BKE_report.hh"
68
69#include "BLT_translation.hh"
70
71#include "BLO_read_write.hh"
72
73#include "SEQ_edit.hh"
74#include "SEQ_effects.hh"
75#include "SEQ_iterator.hh"
76#include "SEQ_modifier.hh"
77#include "SEQ_relations.hh"
78#include "SEQ_sequencer.hh"
79#include "SEQ_utils.hh"
80
81#include "WM_api.hh"
82
83#include "AS_asset_library.hh"
84
85#include "readfile.hh"
86
87#include "versioning_common.hh"
88
89// #include "CLG_log.h"
90// static CLG_LogRef LOG = {"blend.doversion"};
91
92static void idprops_process(IDProperty *idprops, IDProperty **system_idprops)
93{
94 BLI_assert(*system_idprops == nullptr);
95 if (idprops) {
96 /* Other ID pointers have not yet been relinked, do not try to access them for refcounting. */
97 *system_idprops = IDP_CopyProperty_ex(idprops, LIB_ID_CREATE_NO_USER_REFCOUNT);
98 }
99}
100
102{
103 ID *id_iter;
104 FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
105 idprops_process(id_iter->properties, &id_iter->system_properties);
106 }
108
109 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
110 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
111 idprops_process(view_layer->id_properties, &view_layer->system_properties);
112 }
113
114 if (scene->ed != nullptr) {
115 blender::seq::foreach_strip(&scene->ed->seqbase, [](Strip *strip) -> bool {
116 idprops_process(strip->prop, &strip->system_properties);
117 return true;
118 });
119 }
120 }
121
122 LISTBASE_FOREACH (Object *, object, &bmain->objects) {
123 if (!object->pose) {
124 continue;
125 }
126 LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
127 idprops_process(pchan->prop, &pchan->system_properties);
128 }
129 }
130
131 LISTBASE_FOREACH (bArmature *, armature, &bmain->armatures) {
132 for (BoneCollection *bcoll : armature->collections_span()) {
133 idprops_process(bcoll->prop, &bcoll->system_properties);
134 }
135 /* There is no way to iterate directly over all bones of an armature currently, use a recursive
136 * approach instead. */
137 auto process_bone_recursive = [](const auto &process_bone_recursive, Bone *bone) -> void {
138 idprops_process(bone->prop, &bone->system_properties);
139 LISTBASE_FOREACH (Bone *, bone_it, &bone->childbase) {
140 process_bone_recursive(process_bone_recursive, bone_it);
141 }
142 };
143 LISTBASE_FOREACH (Bone *, bone_it, &armature->bonebase) {
144 process_bone_recursive(process_bone_recursive, bone_it);
145 }
146 }
147}
148/* Separate callback for nodes, because they had the split implemented later. */
150{
151 FOREACH_NODETREE_BEGIN (bmain, node_tree, id_owner) {
152 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
153 idprops_process(node->prop, &node->system_properties);
154 }
155 }
157}
158/* Separate callback for non-root bones, because they were missed in the initial implementation. */
160{
161 LISTBASE_FOREACH (bArmature *, armature, &bmain->armatures) {
162 /* There is no way to iterate directly over all bones of an armature currently, use a recursive
163 * approach instead. */
164 auto process_bone_recursive = [](const auto &process_bone_recursive, Bone *bone) -> void {
165 /* Do not overwrite children bones' system properties if they were already defined by some
166 * scripts or add-on e.g. */
167 if (bone->system_properties == nullptr) {
168 idprops_process(bone->prop, &bone->system_properties);
169 }
170 LISTBASE_FOREACH (Bone *, bone_it, &bone->childbase) {
171 process_bone_recursive(process_bone_recursive, bone_it);
172 }
173 };
174 LISTBASE_FOREACH (Bone *, bone_it, &armature->bonebase) {
175 LISTBASE_FOREACH (Bone *, bone_child_it, &bone_it->childbase) {
176 process_bone_recursive(process_bone_recursive, bone_child_it);
177 }
178 }
179 }
180}
181
183{
184 for (CustomDataLayer &layer : blender::MutableSpan(custom_data.layers, custom_data.totlayer)) {
185 if (layer.name == name) {
186 return &layer;
187 }
188 }
189 return nullptr;
190}
191
193{
194 using namespace blender;
195 CustomDataLayer *old_seam_layer = find_old_seam_layer(mesh.edge_data, ".uv_seam");
196 if (!old_seam_layer) {
197 return;
198 }
199 Set<StringRef> names;
200 for (const CustomDataLayer &layer : Span(mesh.vert_data.layers, mesh.vert_data.totlayer)) {
201 if (layer.type & CD_MASK_PROP_ALL) {
202 names.add(layer.name);
203 }
204 }
205 for (const CustomDataLayer &layer : Span(mesh.edge_data.layers, mesh.edge_data.totlayer)) {
206 if (layer.type & CD_MASK_PROP_ALL) {
207 names.add(layer.name);
208 }
209 }
210 for (const CustomDataLayer &layer : Span(mesh.face_data.layers, mesh.face_data.totlayer)) {
211 if (layer.type & CD_MASK_PROP_ALL) {
212 names.add(layer.name);
213 }
214 }
215 for (const CustomDataLayer &layer : Span(mesh.corner_data.layers, mesh.corner_data.totlayer)) {
216 if (layer.type & CD_MASK_PROP_ALL) {
217 names.add(layer.name);
218 }
219 }
220 LISTBASE_FOREACH (const bDeformGroup *, vertex_group, &mesh.vertex_group_names) {
221 names.add(vertex_group->name);
222 }
223
224 /* If the new UV name is already taken, still rename the attribute so it becomes visible in the
225 * list. Then the user can deal with the name conflict themselves. */
226 const std::string new_name = BLI_uniquename_cb(
227 [&](const StringRef name) { return names.contains(name); }, '.', "uv_seam");
228 STRNCPY_UTF8(old_seam_layer->name, new_name.c_str());
229}
230
231static void update_brush_sizes(Main &bmain)
232{
233 /* This conversion was originally done in 582c7d94b8, between subversion 1 (84bee96757) and
234 * subversion 2 (fa03c53d4a). The original change should have come with a subversion bump to be
235 * filled in later, but since it didn't, the best we can do is use subversion 1 for this check.
236 * Thankfully, this only results in a single day window in which a user would have had to
237 * download the build where this versioning was not correctly applied. */
238 LISTBASE_FOREACH (Brush *, brush, &bmain.brushes) {
239 brush->size *= 2;
240 brush->unprojected_size *= 2.0f;
241 }
242
243 auto apply_to_paint = [&](Paint *paint) {
244 if (paint == nullptr) {
245 return;
246 }
247 UnifiedPaintSettings &ups = paint->unified_paint_settings;
248
249 ups.size *= 2;
250 ups.unprojected_size *= 2.0f;
251 };
252
253 LISTBASE_FOREACH (Scene *, scene, &bmain.scenes) {
254 scene->toolsettings->unified_paint_settings.size *= 2;
255 scene->toolsettings->unified_paint_settings.unprojected_size *= 2.0f;
256 apply_to_paint(reinterpret_cast<Paint *>(scene->toolsettings->vpaint));
257 apply_to_paint(reinterpret_cast<Paint *>(scene->toolsettings->wpaint));
258 apply_to_paint(reinterpret_cast<Paint *>(scene->toolsettings->sculpt));
259 apply_to_paint(reinterpret_cast<Paint *>(scene->toolsettings->gp_paint));
260 apply_to_paint(reinterpret_cast<Paint *>(scene->toolsettings->gp_vertexpaint));
261 apply_to_paint(reinterpret_cast<Paint *>(scene->toolsettings->gp_sculptpaint));
262 apply_to_paint(reinterpret_cast<Paint *>(scene->toolsettings->gp_weightpaint));
263 apply_to_paint(reinterpret_cast<Paint *>(scene->toolsettings->curves_sculpt));
264 apply_to_paint(reinterpret_cast<Paint *>(&scene->toolsettings->imapaint));
265 }
266}
267
269{
270 LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
271 if (node->type_legacy == NODE_EVALUATE_CLOSURE) {
272 auto *storage = static_cast<NodeEvaluateClosure *>(node->storage);
273 if (!storage) {
274 /* Can happen with certain files saved in 4.5 which did not officially support closures
275 * yet. */
276 continue;
277 }
278 for (const int i : blender::IndexRange(storage->input_items.items_num)) {
279 NodeEvaluateClosureInputItem &item = storage->input_items.items[i];
282 }
283 }
284 for (const int i : blender::IndexRange(storage->output_items.items_num)) {
285 NodeEvaluateClosureOutputItem &item = storage->output_items.items[i];
288 }
289 }
290 }
291 }
292}
293
295{
296 /* In geometry nodes, replace shader combine/separate color nodes with function nodes */
297 if (ntree->type == NTREE_GEOMETRY) {
302
307
308 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
309 switch (node->type_legacy) {
311 node->type_legacy = FN_NODE_COMBINE_COLOR;
313 storage->mode = NODE_COMBSEP_COLOR_RGB;
314 STRNCPY_UTF8(node->idname, "FunctionNodeCombineColor");
315 node->storage = storage;
316 break;
317 }
319 node->type_legacy = FN_NODE_SEPARATE_COLOR;
321 storage->mode = NODE_COMBSEP_COLOR_RGB;
322 STRNCPY_UTF8(node->idname, "FunctionNodeSeparateColor");
323
324 node->storage = storage;
325 break;
326 }
327 }
328 }
329 }
330
331 /* In compositing nodes, replace combine/separate RGBA/HSVA/YCbCrA/YCCA nodes with
332 * combine/separate color */
333 if (ntree->type == NTREE_COMPOSIT) {
338
343
348
353
358
363
368
373
374 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
375 switch (node->type_legacy) {
377 node->type_legacy = CMP_NODE_COMBINE_COLOR;
380 STRNCPY_UTF8(node->idname, "CompositorNodeCombineColor");
381 node->storage = storage;
382 break;
383 }
385 node->type_legacy = CMP_NODE_COMBINE_COLOR;
388 STRNCPY_UTF8(node->idname, "CompositorNodeCombineColor");
389 node->storage = storage;
390 break;
391 }
393 node->type_legacy = CMP_NODE_COMBINE_COLOR;
396 storage->ycc_mode = node->custom1;
397 STRNCPY_UTF8(node->idname, "CompositorNodeCombineColor");
398 node->storage = storage;
399 break;
400 }
402 node->type_legacy = CMP_NODE_COMBINE_COLOR;
405 STRNCPY_UTF8(node->idname, "CompositorNodeCombineColor");
406 node->storage = storage;
407 break;
408 }
410 node->type_legacy = CMP_NODE_SEPARATE_COLOR;
413 STRNCPY_UTF8(node->idname, "CompositorNodeSeparateColor");
414 node->storage = storage;
415 break;
416 }
418 node->type_legacy = CMP_NODE_SEPARATE_COLOR;
421 STRNCPY_UTF8(node->idname, "CompositorNodeSeparateColor");
422 node->storage = storage;
423 break;
424 }
426 node->type_legacy = CMP_NODE_SEPARATE_COLOR;
429 storage->ycc_mode = node->custom1;
430 STRNCPY_UTF8(node->idname, "CompositorNodeSeparateColor");
431 node->storage = storage;
432 break;
433 }
435 node->type_legacy = CMP_NODE_SEPARATE_COLOR;
438 STRNCPY_UTF8(node->idname, "CompositorNodeSeparateColor");
439 node->storage = storage;
440 break;
441 }
442 }
443 }
444 }
445
446 /* In texture nodes, replace combine/separate RGBA with combine/separate color */
447 if (ntree->type == NTREE_TEXTURE) {
448 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
449 switch (node->type_legacy) {
451 node->type_legacy = TEX_NODE_COMBINE_COLOR;
452 node->custom1 = NODE_COMBSEP_COLOR_RGB;
453 STRNCPY_UTF8(node->idname, "TextureNodeCombineColor");
454 break;
455 }
457 node->type_legacy = TEX_NODE_SEPARATE_COLOR;
458 node->custom1 = NODE_COMBSEP_COLOR_RGB;
459 STRNCPY_UTF8(node->idname, "TextureNodeSeparateColor");
460 break;
461 }
462 }
463 }
464 }
465
466 /* In shader nodes, replace combine/separate RGB/HSV with combine/separate color */
467 if (ntree->type == NTREE_SHADER) {
472
476
481
485
486 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
487 switch (node->type_legacy) {
489 node->type_legacy = SH_NODE_COMBINE_COLOR;
491 storage->mode = NODE_COMBSEP_COLOR_RGB;
492 STRNCPY_UTF8(node->idname, "ShaderNodeCombineColor");
493 node->storage = storage;
494 break;
495 }
497 node->type_legacy = SH_NODE_COMBINE_COLOR;
499 storage->mode = NODE_COMBSEP_COLOR_HSV;
500 STRNCPY_UTF8(node->idname, "ShaderNodeCombineColor");
501 node->storage = storage;
502 break;
503 }
505 node->type_legacy = SH_NODE_SEPARATE_COLOR;
507 storage->mode = NODE_COMBSEP_COLOR_RGB;
508 STRNCPY_UTF8(node->idname, "ShaderNodeSeparateColor");
509 node->storage = storage;
510 break;
511 }
513 node->type_legacy = SH_NODE_SEPARATE_COLOR;
515 storage->mode = NODE_COMBSEP_COLOR_HSV;
516 STRNCPY_UTF8(node->idname, "ShaderNodeSeparateColor");
517 node->storage = storage;
518 break;
519 }
520 }
521 }
522 }
523}
524
525/* "Use Nodes" was removed. */
527{
528 if (scene->nodetree == nullptr && scene->compositing_node_group == nullptr) {
529 /* scene->use_nodes is set to false by default. Files saved without compositing node trees
530 * should not disable compositing. */
531 return;
532 }
533 if (scene->use_nodes == false && scene->r.scemode & R_DOCOMP) {
534 /* A compositing node tree exists but users explicitly disabled compositing. */
535 scene->r.scemode &= ~R_DOCOMP;
536 }
537 /* Ignore use_nodes otherwise. */
538}
539
540/* The Dot output of the Normal node was removed, so replace it with a dot product vector math
541 * node, noting that the Dot output was actually negative the dot product of the normalized
542 * node vector with the input. */
544{
545 bNodeSocket *normal_input = blender::bke::node_find_socket(*node, SOCK_IN, "Normal");
546 bNodeSocket *normal_output = blender::bke::node_find_socket(*node, SOCK_OUT, "Normal");
547 bNodeSocket *dot_output = blender::bke::node_find_socket(*node, SOCK_OUT, "Dot");
548
549 /* Find the links going into and out from the node. */
550 bNodeLink *normal_input_link = nullptr;
551 bool is_normal_ontput_needed = false;
552 bool is_dot_output_used = false;
553 LISTBASE_FOREACH (bNodeLink *, link, &node_tree->links) {
554 if (link->tosock == normal_input) {
555 normal_input_link = link;
556 }
557
558 if (link->fromsock == normal_output) {
559 is_normal_ontput_needed = true;
560 }
561
562 if (link->fromsock == dot_output) {
563 is_dot_output_used = true;
564 }
565 }
566
567 /* The dot output is unused, nothing to do. */
568 if (!is_dot_output_used) {
569 return;
570 }
571
572 /* Take the dot product with negative the node normal. */
573 bNode *dot_product_node = blender::bke::node_add_node(
574 nullptr, *node_tree, "ShaderNodeVectorMath");
575 dot_product_node->custom1 = NODE_VECTOR_MATH_DOT_PRODUCT;
576 dot_product_node->flag |= NODE_COLLAPSED;
577 dot_product_node->parent = node->parent;
578 dot_product_node->location[0] = node->location[0];
579 dot_product_node->location[1] = node->location[1];
580
581 bNodeSocket *dot_product_a_input = blender::bke::node_find_socket(
582 *dot_product_node, SOCK_IN, "Vector");
583 bNodeSocket *dot_product_b_input = blender::bke::node_find_socket(
584 *dot_product_node, SOCK_IN, "Vector_001");
585 bNodeSocket *dot_product_output = blender::bke::node_find_socket(
586 *dot_product_node, SOCK_OUT, "Value");
587
588 copy_v3_v3(static_cast<bNodeSocketValueVector *>(dot_product_a_input->default_value)->value,
589 static_cast<bNodeSocketValueVector *>(normal_input->default_value)->value);
590
591 if (normal_input_link) {
592 version_node_add_link(*node_tree,
593 *normal_input_link->fromnode,
594 *normal_input_link->fromsock,
595 *dot_product_node,
596 *dot_product_a_input);
597 blender::bke::node_remove_link(node_tree, *normal_input_link);
598 }
599
600 /* Notice that we normalize and take the negative to reproduce the same behavior as the old
601 * Normal node. */
602 const blender::float3 node_normal =
603 normal_output->default_value_typed<bNodeSocketValueVector>()->value;
604 const blender::float3 normalized_node_normal = -blender::math::normalize(node_normal);
605 copy_v3_v3(static_cast<bNodeSocketValueVector *>(dot_product_b_input->default_value)->value,
606 normalized_node_normal);
607
608 LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &node_tree->links) {
609 if (link->fromsock != dot_output) {
610 continue;
611 }
612
614 *node_tree, *dot_product_node, *dot_product_output, *link->tonode, *link->tosock);
615 blender::bke::node_remove_link(node_tree, *link);
616 }
617
618 /* If only the Dot output was used, remove the node, making sure to initialize the node types to
619 * allow removal. */
620 if (!is_normal_ontput_needed) {
622 version_node_remove(*node_tree, *node);
623 }
624}
625
627{
628 if (blender::bke::node_find_socket(node, SOCK_IN, "Mode")) {
629 return;
630 }
631 bNodeSocket &socket = version_node_add_socket(ntree, node, SOCK_IN, "NodeSocketMenu", "Mode");
632 socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom1;
633}
634
636{
637 if (blender::bke::node_find_socket(node, SOCK_IN, "Resolution Mode")) {
638 return;
639 }
640 const NodeGeometryPointsToVolume &storage = *static_cast<NodeGeometryPointsToVolume *>(
641 node.storage);
643 ntree, node, SOCK_IN, "NodeSocketMenu", "Resolution Mode");
644 socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.resolution_mode;
645}
646
648{
649 if (!blender::bke::node_find_socket(node, SOCK_IN, "Quad Method")) {
651 ntree, node, SOCK_IN, "NodeSocketMenu", "Quad Method");
652 socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom1;
653 }
654 if (!blender::bke::node_find_socket(node, SOCK_IN, "N-gon Method")) {
656 ntree, node, SOCK_IN, "NodeSocketMenu", "N-gon Method");
657 socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom2;
658 }
659}
660
662{
663 if (blender::bke::node_find_socket(node, SOCK_IN, "Resolution Mode")) {
664 return;
665 }
666 const NodeGeometryVolumeToMesh &storage = *static_cast<NodeGeometryVolumeToMesh *>(node.storage);
668 ntree, node, SOCK_IN, "NodeSocketMenu", "Resolution Mode");
669 socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.resolution_mode;
670}
671
673{
674 if (blender::bke::node_find_socket(node, SOCK_IN, "Operation")) {
675 return;
676 }
678 ntree, node, SOCK_IN, "NodeSocketMenu", "Operation");
679 socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom1;
680}
681
683{
684 if (blender::bke::node_find_socket(node, SOCK_IN, "Mode")) {
685 return;
686 }
687 const auto &storage = *static_cast<NodeGeometryCurveFill *>(node.storage);
688 bNodeSocket &socket = version_node_add_socket(ntree, node, SOCK_IN, "NodeSocketMenu", "Mode");
689 socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.mode;
690}
691
693{
694 if (blender::bke::node_find_socket(node, SOCK_IN, "Mode")) {
695 return;
696 }
697 const auto &storage = *static_cast<NodeGeometryCurveFillet *>(node.storage);
698 bNodeSocket &socket = version_node_add_socket(ntree, node, SOCK_IN, "NodeSocketMenu", "Mode");
699 socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.mode;
700}
701
703{
704 if (blender::bke::node_find_socket(node, SOCK_IN, "Mode")) {
705 return;
706 }
707 const auto &storage = *static_cast<NodeGeometryCurveResample *>(node.storage);
708 bNodeSocket &socket = version_node_add_socket(ntree, node, SOCK_IN, "NodeSocketMenu", "Mode");
709 socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.mode;
710}
711
713{
714 if (blender::bke::node_find_socket(node, SOCK_IN, "Mode")) {
715 return;
716 }
717 const auto &storage = *static_cast<NodeGeometryDistributePointsInVolume *>(node.storage);
718 bNodeSocket &socket = version_node_add_socket(ntree, node, SOCK_IN, "NodeSocketMenu", "Mode");
719 socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.mode;
720}
721
723{
724 if (blender::bke::node_find_socket(node, SOCK_IN, "Mode")) {
725 return;
726 }
727 const auto &storage = *static_cast<NodeGeometryMergeByDistance *>(node.storage);
728 bNodeSocket &socket = version_node_add_socket(ntree, node, SOCK_IN, "NodeSocketMenu", "Mode");
729 socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.mode;
730}
731
733{
734 if (blender::bke::node_find_socket(node, SOCK_IN, "Resolution Mode")) {
735 return;
736 }
737 const auto &storage = *static_cast<NodeGeometryMeshToVolume *>(node.storage);
739 ntree, node, SOCK_IN, "NodeSocketMenu", "Resolution Mode");
740 socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.resolution_mode;
741}
742
744{
745 if (blender::bke::node_find_socket(node, SOCK_IN, "Interpolation")) {
746 return;
747 }
748 const auto &storage = *static_cast<NodeGeometryRaycast *>(node.storage);
750 ntree, node, SOCK_IN, "NodeSocketMenu", "Interpolation");
751 socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.mapping;
752}
753
755{
756 if (blender::bke::node_find_socket(node, SOCK_IN, "Pattern Mode")) {
757 return;
758 }
760 ntree, node, SOCK_IN, "NodeSocketMenu", "Pattern Mode");
761 socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom1;
762}
763
765{
766 if (blender::bke::node_find_socket(node, SOCK_IN, "Interpolation")) {
767 return;
768 }
770 ntree, node, SOCK_IN, "NodeSocketMenu", "Interpolation");
771 socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom2;
772}
773
775{
776 if (blender::bke::node_find_socket(node, SOCK_IN, "Scale Mode")) {
777 return;
778 }
780 ntree, node, SOCK_IN, "NodeSocketMenu", "Scale Mode");
781 socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom2;
782}
783
785{
786 if (blender::bke::node_find_socket(node, SOCK_IN, "Mode")) {
787 return;
788 }
789 bNodeSocket &socket = version_node_add_socket(ntree, node, SOCK_IN, "NodeSocketMenu", "Mode");
790 socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom1;
791}
792
794{
795 auto &storage = *static_cast<NodeGeometrySubdivisionSurface *>(node.storage);
796 if (!blender::bke::node_find_socket(node, SOCK_IN, "UV Smooth")) {
798 ntree, node, SOCK_IN, "NodeSocketMenu", "UV Smooth");
799 socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.uv_smooth;
800 }
801 if (!blender::bke::node_find_socket(node, SOCK_IN, "Boundary Smooth")) {
803 ntree, node, SOCK_IN, "NodeSocketMenu", "Boundary Smooth");
804 socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.boundary_smooth;
805 }
806}
807
809{
810 if (blender::bke::node_find_socket(node, SOCK_IN, "Method")) {
811 return;
812 }
813 bNodeSocket &socket = version_node_add_socket(ntree, node, SOCK_IN, "NodeSocketMenu", "Method");
814 socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom1;
815}
816
818{
819 if (blender::bke::node_find_socket(node, SOCK_IN, "Method")) {
820 return;
821 }
822 const auto &storage = *static_cast<NodeGeometryUVUnwrap *>(node.storage);
823 bNodeSocket &socket = version_node_add_socket(ntree, node, SOCK_IN, "NodeSocketMenu", "Method");
824 socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.method;
825}
826
828{
829 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
830 if (scene->ed != nullptr) {
831 blender::seq::foreach_strip(&scene->ed->seqbase, [&](Strip *strip) -> bool {
832 if (strip->type == STRIP_TYPE_TEXT && strip->effectdata != nullptr) {
833 TextVars *data = static_cast<TextVars *>(strip->effectdata);
834 if (data->text_ptr == nullptr) {
835 data->text_ptr = BLI_strdup(data->text_legacy);
836 data->text_len_bytes = strlen(data->text_ptr);
837 }
838 }
839 return true;
840 });
841 }
842 }
843}
844
846 Scene &scene, blender::FunctionRef<void(Scene &scene, Paint *paint)> func)
847{
848 func(scene, reinterpret_cast<Paint *>(scene.toolsettings->vpaint));
849 func(scene, reinterpret_cast<Paint *>(scene.toolsettings->wpaint));
850 func(scene, reinterpret_cast<Paint *>(scene.toolsettings->sculpt));
851 func(scene, reinterpret_cast<Paint *>(scene.toolsettings->gp_paint));
852 func(scene, reinterpret_cast<Paint *>(scene.toolsettings->gp_vertexpaint));
853 func(scene, reinterpret_cast<Paint *>(scene.toolsettings->gp_sculptpaint));
854 func(scene, reinterpret_cast<Paint *>(scene.toolsettings->gp_weightpaint));
855 func(scene, reinterpret_cast<Paint *>(scene.toolsettings->curves_sculpt));
856 func(scene, reinterpret_cast<Paint *>(&scene.toolsettings->imapaint));
857}
858
859static void copy_unified_paint_settings(Scene &scene, Paint *paint)
860{
861 if (paint == nullptr) {
862 return;
863 }
864
865 const UnifiedPaintSettings &scene_ups = scene.toolsettings->unified_paint_settings;
867
868 ups.size = scene_ups.size;
869 ups.unprojected_size = scene_ups.unprojected_size;
870 ups.alpha = scene_ups.alpha;
871 ups.weight = scene_ups.weight;
872 copy_v3_v3(ups.color, scene_ups.color);
873 copy_v3_v3(ups.rgb, scene_ups.rgb);
875 copy_v3_v3(ups.secondary_rgb, scene_ups.secondary_rgb);
876 ups.color_jitter_flag = scene_ups.color_jitter_flag;
877 copy_v3_v3(ups.hsv_jitter, scene_ups.hsv_jitter);
878
879 BLI_assert(ups.curve_rand_hue == nullptr);
880 BLI_assert(ups.curve_rand_saturation == nullptr);
881 BLI_assert(ups.curve_rand_value == nullptr);
885 ups.flag = scene_ups.flag;
886}
887
888/* The Use Alpha option is does not exist in the new generic Mix node, it essentially just
889 * multiplied the factor by the alpha of the second input. */
890static void do_version_mix_color_use_alpha(bNodeTree *node_tree, bNode *node)
891{
892 if (!(node->custom2 & SHD_MIXRGB_USE_ALPHA)) {
893 return;
894 }
895
897
898 bNodeSocket *factor_input = blender::bke::node_find_socket(*node, SOCK_IN, "Factor_Float");
899 bNodeSocket *b_input = blender::bke::node_find_socket(*node, SOCK_IN, "B_Color");
900
901 /* Find the links going into the factor and B input of the Mix node. */
902 bNodeLink *factor_link = nullptr;
903 bNodeLink *b_link = nullptr;
904 LISTBASE_FOREACH (bNodeLink *, link, &node_tree->links) {
905 if (link->tosock == factor_input) {
906 factor_link = link;
907 }
908 else if (link->tosock == b_input) {
909 b_link = link;
910 }
911 }
912
913 /* If neither sockets are connected, just multiply the factor by the alpha of the B input. */
914 if (!factor_link && !b_link) {
915 static_cast<bNodeSocketValueFloat *>(factor_input->default_value)->value *=
916 static_cast<bNodeSocketValueRGBA *>(b_input->default_value)->value[3];
917 return;
918 }
919
920 /* Otherwise, add a multiply node to do the multiplication. */
921 bNode *multiply_node = blender::bke::node_add_static_node(nullptr, *node_tree, SH_NODE_MATH);
922 multiply_node->parent = node->parent;
923 multiply_node->custom1 = NODE_MATH_MULTIPLY;
924 multiply_node->location[0] = node->location[0] - node->width - 20.0f;
925 multiply_node->location[1] = node->location[1];
926 multiply_node->flag |= NODE_COLLAPSED;
927
928 bNodeSocket *multiply_input_a = static_cast<bNodeSocket *>(
929 BLI_findlink(&multiply_node->inputs, 0));
930 bNodeSocket *multiply_input_b = static_cast<bNodeSocket *>(
931 BLI_findlink(&multiply_node->inputs, 1));
932 bNodeSocket *multiply_output = blender::bke::node_find_socket(*multiply_node, SOCK_OUT, "Value");
933
934 /* Connect the output of the multiply node to the math node. */
935 version_node_add_link(*node_tree, *multiply_node, *multiply_output, *node, *factor_input);
936
937 if (factor_link) {
938 /* The factor input is linked, so connect its origin to the first input of the multiply and
939 * remove the original link. */
940 version_node_add_link(*node_tree,
941 *factor_link->fromnode,
942 *factor_link->fromsock,
943 *multiply_node,
944 *multiply_input_a);
945 blender::bke::node_remove_link(node_tree, *factor_link);
946 }
947 else {
948 /* Otherwise, the factor is unlinked and we just copy the factor value to the first input in
949 * the multiply. */
950 static_cast<bNodeSocketValueFloat *>(multiply_input_a->default_value)->value =
951 static_cast<bNodeSocketValueFloat *>(factor_input->default_value)->value;
952 }
953
954 if (b_link) {
955 /* The B input is linked, so extract the alpha of its origin and connect it to the second input
956 * of the multiply and remove the original link. */
957 bNode *separate_color_node = blender::bke::node_add_static_node(
958 nullptr, *node_tree, CMP_NODE_SEPARATE_COLOR);
959 separate_color_node->parent = node->parent;
960 separate_color_node->location[0] = multiply_node->location[0] - multiply_node->width - 20.0f;
961 separate_color_node->location[1] = multiply_node->location[1];
962 separate_color_node->flag |= NODE_COLLAPSED;
963
965 *separate_color_node, SOCK_IN, "Image");
967 *separate_color_node, SOCK_OUT, "Alpha");
968
970 *node_tree, *b_link->fromnode, *b_link->fromsock, *separate_color_node, *image_input);
972 *node_tree, *separate_color_node, *alpha_output, *multiply_node, *multiply_input_b);
973 }
974 else {
975 /* Otherwise, the B input is unlinked and we just copy the alpha value to the second input in
976 * the multiply. */
977 static_cast<bNodeSocketValueFloat *>(multiply_input_b->default_value)->value =
978 static_cast<bNodeSocketValueRGBA *>(b_input->default_value)->value[3];
979 }
980
982}
983
984/* The Map Value node is now deprecated and should be replaced by other nodes. The node essentially
985 * just computes (value + offset) * size and clamps based on min and max. */
986static void do_version_map_value_node(bNodeTree *node_tree, bNode *node)
987{
989
990 const TexMapping &texture_mapping = *static_cast<TexMapping *>(node->storage);
991 const bool use_min = texture_mapping.flag & TEXMAP_CLIP_MIN;
992 const bool use_max = texture_mapping.flag & TEXMAP_CLIP_MAX;
993 const float offset = texture_mapping.loc[0];
994 const float size = texture_mapping.size[0];
995 const float min = texture_mapping.min[0];
996 const float max = texture_mapping.max[0];
997
998 bNodeSocket *value_input = blender::bke::node_find_socket(*node, SOCK_IN, "Value");
999
1000 /* Find the link going into the value input Map Value node. */
1001 bNodeLink *value_link = nullptr;
1002 LISTBASE_FOREACH (bNodeLink *, link, &node_tree->links) {
1003 if (link->tosock == value_input) {
1004 value_link = link;
1005 }
1006 }
1007
1008 bNode *frame = blender::bke::node_add_static_node(nullptr, *node_tree, NODE_FRAME);
1009 frame->parent = node->parent;
1010 STRNCPY(frame->label, RPT_("Versioning: Map Value node was removed"));
1011 NodeFrame *frame_data = static_cast<NodeFrame *>(frame->storage);
1012 frame_data->label_size = 10;
1013
1014 /* If the value input is not connected, add a value node with the computed value. */
1015 if (!value_link) {
1016 const float value = static_cast<bNodeSocketValueFloat *>(value_input->default_value)->value;
1017 const float mapped_value = (value + offset) * size;
1018 const float min_clamped_value = use_min ? blender::math::max(mapped_value, min) : mapped_value;
1019 const float clamped_value = use_max ? blender::math::min(min_clamped_value, max) :
1020 min_clamped_value;
1021
1022 bNode &value_node = version_node_add_empty(*node_tree, "ShaderNodeValue");
1023 bNodeSocket &value_output = version_node_add_socket(
1024 *node_tree, value_node, SOCK_OUT, "NodeSocketFloat", "Value");
1025
1026 value_node.parent = frame;
1027 value_node.location[0] = node->location[0];
1028 value_node.location[1] = node->location[1];
1029
1030 static_cast<bNodeSocketValueFloat *>(value_output.default_value)->value = clamped_value;
1031
1032 /* Relink from the Map Value node to the value node. */
1033 LISTBASE_FOREACH_BACKWARD_MUTABLE (bNodeLink *, link, &node_tree->links) {
1034 if (link->fromnode != node) {
1035 continue;
1036 }
1037
1038 version_node_add_link(*node_tree, value_node, value_output, *link->tonode, *link->tosock);
1039 blender::bke::node_remove_link(node_tree, *link);
1040 }
1041
1042 MEM_freeN(&texture_mapping);
1043 node->storage = nullptr;
1044 version_node_remove(*node_tree, *node);
1045
1047 return;
1048 }
1049
1050 /* Otherwise, add math nodes to do the computation, starting with an add node to add the offset
1051 * of the range. */
1052 bNode &add_node = version_node_add_empty(*node_tree, "ShaderNodeMath");
1053 bNodeSocket &add_input_a = version_node_add_socket(
1054 *node_tree, add_node, SOCK_IN, "NodeSocketFloat", "Value");
1055 bNodeSocket &add_input_b = version_node_add_socket(
1056 *node_tree, add_node, SOCK_IN, "NodeSocketFloat", "Value_001");
1057 version_node_add_socket(*node_tree, add_node, SOCK_IN, "NodeSocketFloat", "Value_002");
1058
1060 *node_tree, add_node, SOCK_OUT, "NodeSocketFloat", "Value");
1061
1062 add_node.parent = frame;
1063 add_node.custom1 = NODE_MATH_ADD;
1064 add_node.location[0] = node->location[0];
1065 add_node.location[1] = node->location[1];
1066 add_node.flag |= NODE_COLLAPSED;
1067
1068 /* Connect the origin of the node to the first input of the add node and remove the original
1069 * link. */
1071 *node_tree, *value_link->fromnode, *value_link->fromsock, add_node, add_input_a);
1072 blender::bke::node_remove_link(node_tree, *value_link);
1073
1074 /* Set the offset to the second input of the add node. */
1075 static_cast<bNodeSocketValueFloat *>(add_input_b.default_value)->value = offset;
1076
1077 /* Add a multiply node to multiply by the size. */
1078 bNode &multiply_node = version_node_add_empty(*node_tree, "ShaderNodeMath");
1079 multiply_node.parent = frame;
1080 multiply_node.custom1 = NODE_MATH_MULTIPLY;
1081 multiply_node.location[0] = add_node.location[0];
1082 multiply_node.location[1] = add_node.location[1] - 40.0f;
1083 multiply_node.flag |= NODE_COLLAPSED;
1084
1085 bNodeSocket &multiply_input_a = version_node_add_socket(
1086 *node_tree, multiply_node, SOCK_IN, "NodeSocketFloat", "Value");
1087 bNodeSocket &multiply_input_b = version_node_add_socket(
1088 *node_tree, multiply_node, SOCK_IN, "NodeSocketFloat", "Value_001");
1089 version_node_add_socket(*node_tree, multiply_node, SOCK_IN, "NodeSocketFloat", "Value_002");
1090
1091 bNodeSocket &multiply_output = version_node_add_socket(
1092 *node_tree, multiply_node, SOCK_OUT, "NodeSocketFloat", "Value");
1093
1094 /* Connect the output of the add node to the first input of the multiply node. */
1095 version_node_add_link(*node_tree, add_node, add_output, multiply_node, multiply_input_a);
1096
1097 /* Set the size to the second input of the multiply node. */
1098 static_cast<bNodeSocketValueFloat *>(multiply_input_b.default_value)->value = size;
1099
1100 bNode *final_node = &multiply_node;
1101 bNodeSocket *final_output = &multiply_output;
1102
1103 if (use_min) {
1104 /* Add a maximum node to clamp by the minimum. */
1105 bNode &max_node = version_node_add_empty(*node_tree, "ShaderNodeMath");
1106 max_node.parent = frame;
1107 max_node.custom1 = NODE_MATH_MAXIMUM;
1108 max_node.location[0] = final_node->location[0];
1109 max_node.location[1] = final_node->location[1] - 40.0f;
1110 max_node.flag |= NODE_COLLAPSED;
1111
1112 bNodeSocket &max_input_a = version_node_add_socket(
1113 *node_tree, max_node, SOCK_IN, "NodeSocketFloat", "Value");
1114 bNodeSocket &max_input_b = version_node_add_socket(
1115 *node_tree, max_node, SOCK_IN, "NodeSocketFloat", "Value_001");
1116 version_node_add_socket(*node_tree, max_node, SOCK_IN, "NodeSocketFloat", "Value_002");
1118 *node_tree, max_node, SOCK_OUT, "NodeSocketFloat", "Value");
1119
1120 /* Connect the output of the final node to the first input of the maximum node. */
1121 version_node_add_link(*node_tree, *final_node, *final_output, max_node, max_input_a);
1122
1123 /* Set the minimum to the second input of the maximum node. */
1124 static_cast<bNodeSocketValueFloat *>(max_input_b.default_value)->value = min;
1125
1126 final_node = &max_node;
1127 final_output = &max_output;
1128 }
1129
1130 if (use_max) {
1131 /* Add a minimum node to clamp by the maximum. */
1132 bNode &min_node = version_node_add_empty(*node_tree, "ShaderNodeMath");
1133 min_node.parent = frame;
1134 min_node.custom1 = NODE_MATH_MINIMUM;
1135 min_node.location[0] = final_node->location[0];
1136 min_node.location[1] = final_node->location[1] - 40.0f;
1137 min_node.flag |= NODE_COLLAPSED;
1138
1139 bNodeSocket &min_input_a = version_node_add_socket(
1140 *node_tree, min_node, SOCK_IN, "NodeSocketFloat", "Value");
1141 bNodeSocket &min_input_b = version_node_add_socket(
1142 *node_tree, min_node, SOCK_IN, "NodeSocketFloat", "Value_001");
1143 version_node_add_socket(*node_tree, min_node, SOCK_IN, "NodeSocketFloat", "Value_002");
1145 *node_tree, min_node, SOCK_OUT, "NodeSocketFloat", "Value");
1146
1147 /* Connect the output of the final node to the first input of the minimum node. */
1148 version_node_add_link(*node_tree, *final_node, *final_output, min_node, min_input_a);
1149
1150 /* Set the maximum to the second input of the minimum node. */
1151 static_cast<bNodeSocketValueFloat *>(min_input_b.default_value)->value = max;
1152
1153 final_node = &min_node;
1154 final_output = &min_output;
1155 }
1156
1157 /* Relink from the Map Value node to the final node. */
1158 LISTBASE_FOREACH_BACKWARD_MUTABLE (bNodeLink *, link, &node_tree->links) {
1159 if (link->fromnode != node) {
1160 continue;
1161 }
1162
1163 version_node_add_link(*node_tree, *final_node, *final_output, *link->tonode, *link->tosock);
1164 blender::bke::node_remove_link(node_tree, *link);
1165 }
1166
1167 MEM_freeN(&texture_mapping);
1168 node->storage = nullptr;
1169
1170 version_node_remove(*node_tree, *node);
1171
1173}
1174
1175/* The compositor Value, Color Ramp, Mix Color, Map Range, Map Value, Math, Combine XYZ, Separate
1176 * XYZ, and Vector Curves nodes are now deprecated and should be replaced by their generic Shader
1177 * node counterpart. */
1179{
1180 LISTBASE_FOREACH_MUTABLE (bNode *, node, &node_tree->nodes) {
1181 switch (node->type_legacy) {
1183 node->type_legacy = SH_NODE_VALUE;
1184 STRNCPY_UTF8(node->idname, "ShaderNodeValue");
1185 break;
1187 node->type_legacy = SH_NODE_MATH;
1188 STRNCPY_UTF8(node->idname, "ShaderNodeMath");
1189 break;
1191 node->type_legacy = SH_NODE_COMBXYZ;
1192 STRNCPY_UTF8(node->idname, "ShaderNodeCombineXYZ");
1193 break;
1195 node->type_legacy = SH_NODE_SEPXYZ;
1196 STRNCPY_UTF8(node->idname, "ShaderNodeSeparateXYZ");
1197 break;
1199 node->type_legacy = SH_NODE_CURVE_VEC;
1200 STRNCPY_UTF8(node->idname, "ShaderNodeVectorCurve");
1201 break;
1203 node->type_legacy = SH_NODE_VALTORGB;
1204 STRNCPY_UTF8(node->idname, "ShaderNodeValToRGB");
1205
1206 /* Compositor node uses "Image" as the output name while the shader node uses "Color" as
1207 * the output name. */
1208 bNodeSocket *image_output = blender::bke::node_find_socket(*node, SOCK_OUT, "Image");
1209 STRNCPY_UTF8(image_output->identifier, "Color");
1210 STRNCPY_UTF8(image_output->name, "Color");
1211
1212 break;
1213 }
1215 node->type_legacy = SH_NODE_MAP_RANGE;
1216 STRNCPY_UTF8(node->idname, "ShaderNodeMapRange");
1217
1218 /* Transfer options from node to NodeMapRange storage. */
1220 data->clamp = node->custom1;
1221 data->data_type = CD_PROP_FLOAT;
1222 data->interpolation_type = NODE_MAP_RANGE_LINEAR;
1223 node->storage = data;
1224
1225 /* Compositor node uses "Value" as the output name while the shader node uses "Result" as
1226 * the output name. */
1227 bNodeSocket *value_output = blender::bke::node_find_socket(*node, SOCK_OUT, "Value");
1228 STRNCPY_UTF8(value_output->identifier, "Result");
1229 STRNCPY_UTF8(value_output->name, "Result");
1230
1231 break;
1232 }
1234 node->type_legacy = SH_NODE_MIX;
1235 STRNCPY_UTF8(node->idname, "ShaderNodeMix");
1236
1237 /* Transfer options from node to NodeShaderMix storage. */
1239 data->data_type = SOCK_RGBA;
1240 data->factor_mode = NODE_MIX_MODE_UNIFORM;
1241 data->clamp_factor = 0;
1242 data->clamp_result = node->custom2 & SHD_MIXRGB_CLAMP ? 1 : 0;
1243 data->blend_type = node->custom1;
1244 node->storage = data;
1245
1246 /* Compositor node uses "Fac", "Image", and ("Image" "Image_001") as socket names and
1247 * identifiers while the shader node uses ("Factor", "Factor_Float"), ("A", "A_Color"),
1248 * ("B", "B_Color"), and ("Result", "Result_Color") as socket names and identifiers. */
1249 bNodeSocket *factor_input = blender::bke::node_find_socket(*node, SOCK_IN, "Fac");
1250 STRNCPY_UTF8(factor_input->identifier, "Factor_Float");
1251 STRNCPY_UTF8(factor_input->name, "Factor");
1252 bNodeSocket *first_input = blender::bke::node_find_socket(*node, SOCK_IN, "Image");
1253 STRNCPY_UTF8(first_input->identifier, "A_Color");
1254 STRNCPY_UTF8(first_input->name, "A");
1255 bNodeSocket *second_input = blender::bke::node_find_socket(*node, SOCK_IN, "Image_001");
1256 STRNCPY_UTF8(second_input->identifier, "B_Color");
1257 STRNCPY_UTF8(second_input->name, "B");
1258 bNodeSocket *image_output = blender::bke::node_find_socket(*node, SOCK_OUT, "Image");
1259 STRNCPY_UTF8(image_output->identifier, "Result_Color");
1260 STRNCPY_UTF8(image_output->name, "Result");
1261
1262 do_version_mix_color_use_alpha(node_tree, node);
1263
1264 break;
1265 }
1267 do_version_map_value_node(node_tree, node);
1268 break;
1269 }
1270 default:
1271 break;
1272 }
1273 }
1274}
1275
1276/* Equivalent to do_version_convert_to_generic_nodes but performed after linking for handing things
1277 * like animation or node construction. */
1279 bNodeTree *node_tree,
1280 ID *id)
1281{
1282 LISTBASE_FOREACH_MUTABLE (bNode *, node, &node_tree->nodes) {
1283 char escaped_node_name[sizeof(node->name) * 2 + 1];
1284 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
1285 const std::string rna_path_prefix = fmt::format("nodes[\"{}\"].inputs", escaped_node_name);
1286
1287 switch (node->type_legacy) {
1288 /* Notice that we use the shader type because the node is already converted in versioning
1289 * before linking. */
1290 case SH_NODE_CURVE_VEC: {
1291 /* The node gained a new Factor input as a first socket, so the vector socket moved to be
1292 * the second socket and we need to transfer its animation as well. */
1294 bmain, id, rna_path_prefix.c_str(), nullptr, nullptr, 0, 1, false);
1295 break;
1296 }
1297 /* Notice that we use the shader type because the node is already converted in versioning
1298 * before linking. */
1299 case SH_NODE_MIX: {
1300 /* The node gained multiple new sockets after the factor socket, so the second and third
1301 * sockets moved to be the 7th and 8th sockets. */
1303 bmain, id, rna_path_prefix.c_str(), nullptr, nullptr, 1, 6, false);
1305 bmain, id, rna_path_prefix.c_str(), nullptr, nullptr, 2, 7, false);
1306 break;
1307 }
1308 default:
1309 break;
1310 }
1311 }
1312}
1313
1314static void do_version_split_node_rotation(bNodeTree *node_tree, bNode *node)
1315{
1316 using namespace blender;
1317
1318 bNodeSocket *factor_input = bke::node_find_socket(*node, SOCK_IN, "Factor");
1319 float factor = factor_input->default_value_typed<bNodeSocketValueFloat>()->value;
1320
1321 bNodeSocket *rotation_input = bke::node_find_socket(*node, SOCK_IN, "Rotation");
1322 if (!rotation_input) {
1323 rotation_input = bke::node_add_static_socket(
1324 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_ANGLE, "Rotation", "Rotation");
1325 }
1326
1327 bNodeSocket *position_input = bke::node_find_socket(*node, SOCK_IN, "Position");
1328 if (!position_input) {
1329 position_input = bke::node_add_static_socket(
1330 *node_tree, *node, SOCK_IN, SOCK_VECTOR, PROP_FACTOR, "Position", "Position");
1331 }
1332
1333 constexpr int CMP_NODE_SPLIT_HORIZONTAL = 0;
1334 constexpr int CMP_NODE_SPLIT_VERTICAL = 1;
1335
1336 switch (node->custom2) {
1337 case CMP_NODE_SPLIT_HORIZONTAL: {
1338 rotation_input->default_value_typed<bNodeSocketValueFloat>()->value =
1340 position_input->default_value_typed<bNodeSocketValueVector>()->value[0] = factor;
1341 /* The y-coordinate doesn't matter in this case, so set the value to 0.5 so that the gizmo
1342 * appears nicely at the center. */
1343 position_input->default_value_typed<bNodeSocketValueVector>()->value[1] = 0.5f;
1344 break;
1345 }
1346 case CMP_NODE_SPLIT_VERTICAL: {
1347 rotation_input->default_value_typed<bNodeSocketValueFloat>()->value = 0.0f;
1348 position_input->default_value_typed<bNodeSocketValueVector>()->value[0] = 0.5f;
1349 position_input->default_value_typed<bNodeSocketValueVector>()->value[1] = factor;
1350 break;
1351 }
1352 }
1353}
1354
1356{
1357 ListBase pidlist;
1358
1359 BKE_ptcache_ids_from_object(&pidlist, object, nullptr, 0);
1360
1361 LISTBASE_FOREACH (PTCacheID *, pid, &pidlist) {
1362 bool found_incompatible_cache = false;
1363 if (ELEM(pid->cache->compression,
1366 {
1367 pid->cache->compression = PTCACHE_COMPRESS_ZSTD_FILTERED;
1368 found_incompatible_cache = true;
1369 }
1370 if (pid->type == PTCACHE_TYPE_DYNAMICPAINT) {
1371 /* Dynamicpaint was hardcoded to use LZO. */
1372 found_incompatible_cache = true;
1373 }
1374
1375 if (!found_incompatible_cache) {
1376 continue;
1377 }
1378
1379 std::string cache_type;
1380 switch (pid->type) {
1382 cache_type = RPT_("Softbody");
1383 break;
1385 cache_type = RPT_("Particle");
1386 break;
1387 case PTCACHE_TYPE_CLOTH:
1388 cache_type = RPT_("Cloth");
1389 break;
1391 cache_type = RPT_("Smoke Domain");
1392 break;
1394 cache_type = RPT_("Smoke");
1395 break;
1397 cache_type = RPT_("Dynamic Paint");
1398 break;
1400 /* Rigidbody caches shouldn't have any disk caches, but keep it here just in case. */
1401 cache_type = RPT_("Rigidbody");
1402 break;
1403 }
1405 fd->reports,
1407 RPT_("%s Cache in object %s can not be read because it uses an "
1408 "outdated compression method. You need to delete the caches and re-bake."),
1409 cache_type.c_str(),
1410 pid->owner_id->name + 2);
1411 }
1412
1413 BLI_freelistN(&pidlist);
1414}
1415
1417{
1418 /* Because this change is backported into the 4.5 branch, we need to avoid performing versioning
1419 * in case the user updated their custom brush assets between using 4.5 and 5.0 to avoid
1420 * overwriting their changes.
1421 *
1422 * See #142104
1423 */
1424 if ((brush->flag2 & BRUSH_JITTER_COLOR) != 0 || !is_zero_v3(brush->hsv_jitter)) {
1425 return;
1426 }
1427
1428 BrushGpencilSettings *settings = brush->gpencil_settings;
1429 float old_hsv_jitter[3] = {
1430 settings->random_hue, settings->random_saturation, settings->random_value};
1431 if (!is_zero_v3(old_hsv_jitter)) {
1432 brush->flag2 |= BRUSH_JITTER_COLOR;
1433 }
1434 copy_v3_v3(brush->hsv_jitter, old_hsv_jitter);
1435 if (brush->curve_rand_hue) {
1438 }
1439 else {
1441 }
1442 if (brush->curve_rand_saturation) {
1445 }
1446 else {
1448 }
1449 if (brush->curve_rand_value) {
1452 }
1453 else {
1455 }
1456}
1457
1458/* The Sun beams node was removed and the Glare node should be used instead, so we need to
1459 * make the replacement. */
1460static void do_version_sun_beams(bNodeTree &node_tree, bNode &node)
1461{
1463
1464 bNodeSocket *old_image_input = blender::bke::node_find_socket(node, SOCK_IN, "Image");
1465 bNodeSocket *old_source_input = blender::bke::node_find_socket(node, SOCK_IN, "Source");
1466 bNodeSocket *old_length_input = blender::bke::node_find_socket(node, SOCK_IN, "Length");
1467 bNodeSocket *old_image_output = blender::bke::node_find_socket(node, SOCK_OUT, "Image");
1468
1469 bNode *glare_node = blender::bke::node_add_node(nullptr, node_tree, "CompositorNodeGlare");
1470 glare_node->parent = node.parent;
1471 glare_node->location[0] = node.location[0];
1472 glare_node->location[1] = node.location[1];
1473
1474 bNodeSocket *image_input = blender::bke::node_find_socket(*glare_node, SOCK_IN, "Image");
1475 bNodeSocket *type_input = blender::bke::node_find_socket(*glare_node, SOCK_IN, "Type");
1476 bNodeSocket *quality_input = blender::bke::node_find_socket(*glare_node, SOCK_IN, "Quality");
1478 *glare_node, SOCK_IN, "Highlights Threshold");
1479 bNodeSocket *size_input = blender::bke::node_find_socket(*glare_node, SOCK_IN, "Size");
1480 bNodeSocket *source_input = blender::bke::node_find_socket(*glare_node, SOCK_IN, "Sun Position");
1481 bNodeSocket *glare_output = blender::bke::node_find_socket(*glare_node, SOCK_OUT, "Glare");
1482
1483 type_input->default_value_typed<bNodeSocketValueMenu>()->value = CMP_NODE_GLARE_SUN_BEAMS;
1484 quality_input->default_value_typed<bNodeSocketValueMenu>()->value = CMP_NODE_GLARE_QUALITY_HIGH;
1485 copy_v4_v4(image_input->default_value_typed<bNodeSocketValueRGBA>()->value,
1486 old_image_input->default_value_typed<bNodeSocketValueRGBA>()->value);
1487 threshold_input->default_value_typed<bNodeSocketValueFloat>()->value = 0.0f;
1488 size_input->default_value_typed<bNodeSocketValueFloat>()->value =
1489 old_length_input->default_value_typed<bNodeSocketValueFloat>()->value;
1490 copy_v2_v2(source_input->default_value_typed<bNodeSocketValueVector>()->value,
1491 old_source_input->default_value_typed<bNodeSocketValueVector>()->value);
1492
1493 LISTBASE_FOREACH_BACKWARD_MUTABLE (bNodeLink *, link, &node_tree.links) {
1494 if (link->tosock == old_image_input) {
1496 node_tree, *link->fromnode, *link->fromsock, *glare_node, *image_input);
1497 blender::bke::node_remove_link(&node_tree, *link);
1498 continue;
1499 }
1500
1501 if (link->tosock == old_source_input) {
1503 node_tree, *link->fromnode, *link->fromsock, *glare_node, *source_input);
1504 blender::bke::node_remove_link(&node_tree, *link);
1505 continue;
1506 }
1507
1508 if (link->tosock == old_length_input) {
1509 version_node_add_link(node_tree, *link->fromnode, *link->fromsock, *glare_node, *size_input);
1510 blender::bke::node_remove_link(&node_tree, *link);
1511 continue;
1512 }
1513
1514 if (link->fromsock == old_image_output) {
1515 version_node_add_link(node_tree, *link->tonode, *link->tosock, *glare_node, *glare_output);
1516 blender::bke::node_remove_link(&node_tree, *link);
1517 }
1518 }
1519
1520 version_node_remove(node_tree, node);
1521}
1522
1523/* The Composite node was removed and a Group Output node should be used instead, so we need to
1524 * make the replacement. But first note that the Group Output node relies on the node tree
1525 * interface, so we ensure a default interface with a single input and output. This is only for
1526 * root trees used as scene compositing node groups, for other node trees, we remove all composite
1527 * nodes since they are no longer supported inside groups. */
1529{
1531
1532 /* Remove inactive nodes. */
1533 if (!(node.flag & NODE_DO_OUTPUT)) {
1534 version_node_remove(node_tree, node);
1535 return;
1536 }
1537
1538 bNodeSocket *old_image_input = blender::bke::node_find_socket(node, SOCK_IN, "Image");
1539
1540 /* Find the link going into the Image input of the Composite node. */
1541 bNodeLink *image_link = nullptr;
1542 LISTBASE_FOREACH (bNodeLink *, link, &node_tree.links) {
1543 if (link->tosock == old_image_input) {
1544 image_link = link;
1545 }
1546 }
1547
1548 bNode *group_output_node = blender::bke::node_add_node(nullptr, node_tree, "NodeGroupOutput");
1549 group_output_node->parent = node.parent;
1550 group_output_node->location[0] = node.location[0];
1551 group_output_node->location[1] = node.location[1];
1552
1553 bNodeSocket *image_input = static_cast<bNodeSocket *>(group_output_node->inputs.first);
1554 BLI_assert(blender::StringRef(image_input->name) == "Image");
1555 copy_v4_v4(image_input->default_value_typed<bNodeSocketValueRGBA>()->value,
1556 old_image_input->default_value_typed<bNodeSocketValueRGBA>()->value);
1557
1558 if (image_link) {
1560 node_tree, *image_link->fromnode, *image_link->fromsock, *group_output_node, *image_input);
1561 blender::bke::node_remove_link(&node_tree, *image_link);
1562 }
1563
1564 version_node_remove(node_tree, node);
1565}
1566
1567/* The file output node started using item accessors, so we need to free socket storage and copy
1568 * them to the new items members. Additionally, the base path was split into a directory and a file
1569 * name, so we need to split it. */
1571{
1572 if (node.storage == nullptr) {
1573 return;
1574 }
1575
1577
1578 /* The directory previously stored both the directory and the file name. */
1579 char directory[FILE_MAX] = "";
1580 char file_name[FILE_MAX] = "";
1581 BLI_path_split_dir_file(data->directory, directory, FILE_MAX, file_name, FILE_MAX);
1582 STRNCPY(data->directory, directory);
1583 data->file_name = BLI_strdup_null(file_name);
1584
1585 data->items_count = BLI_listbase_count(&node.inputs);
1586 data->items = MEM_calloc_arrayN<NodeCompositorFileOutputItem>(data->items_count, __func__);
1587 int i = 0;
1589 NodeImageMultiFileSocket *old_item_data = static_cast<NodeImageMultiFileSocket *>(
1590 input->storage);
1591 NodeCompositorFileOutputItem *item_data = &data->items[i];
1592
1593 item_data->identifier = i;
1594 BKE_image_format_copy(&item_data->format, &old_item_data->format);
1595 item_data->save_as_render = old_item_data->save_as_render;
1596 item_data->override_node_format = !bool(old_item_data->use_node_format);
1597
1598 item_data->socket_type = input->type;
1599 if (item_data->socket_type == SOCK_VECTOR) {
1600 item_data->vector_socket_dimensions =
1601 input->default_value_typed<bNodeSocketValueVector>()->dimensions;
1602 }
1603
1604 if (data->format.imtype == R_IMF_IMTYPE_MULTILAYER) {
1605 item_data->name = BLI_strdup(old_item_data->layer);
1606 }
1607 else {
1608 item_data->name = BLI_strdup(old_item_data->path);
1609 }
1610
1611 const std::string identifier = "Item_" + std::to_string(item_data->identifier);
1612 STRNCPY(input->identifier, identifier.c_str());
1613
1614 BKE_image_format_free(&old_item_data->format);
1615 MEM_freeN(old_item_data);
1616 input->storage = nullptr;
1617 }
1618}
1619
1620/* Updates the media type of the given format to match its imtype. */
1622{
1623 if (BKE_imtype_is_image(format->imtype)) {
1624 format->media_type = MEDIA_TYPE_IMAGE;
1625 }
1626 else if (BKE_imtype_is_multi_layer_image(format->imtype)) {
1628 }
1629 else if (BKE_imtype_is_movie(format->imtype)) {
1630 format->media_type = MEDIA_TYPE_VIDEO;
1631 }
1632 else {
1634 }
1635}
1636
1638{
1639 if (world->use_nodes) {
1640 return;
1641 }
1642
1643 /* Users defined a world node tree, but deactivated it by disabling "Use Nodes". So we
1644 * simulate the same effect by creating a new World Output node and setting it to active. */
1645 bNodeTree *ntree = world->nodetree;
1646 if (ntree == nullptr) {
1647 /* In case the world was defined through Python API it might have been missing a node tree. */
1649 bmain, &world->id, "World Node Tree Versioning", "ShaderNodeTree");
1650 }
1651
1652 bNode *old_output = nullptr;
1653 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
1654 if (STREQ(node->idname, "ShaderNodeOutputWorld") && (node->flag & NODE_DO_OUTPUT)) {
1655 old_output = node;
1656 old_output->flag &= ~NODE_DO_OUTPUT;
1657 }
1658 }
1659
1660 bNode &new_output = version_node_add_empty(*ntree, "ShaderNodeOutputWorld");
1661 bNodeSocket &output_surface_input = version_node_add_socket(
1662 *ntree, new_output, SOCK_IN, "NodeSocketShader", "Surface");
1663 version_node_add_socket(*ntree, new_output, SOCK_IN, "NodeSocketShader", "Volume");
1664 new_output.flag |= NODE_DO_OUTPUT;
1665
1666 bNode &background = version_node_add_empty(*ntree, "ShaderNodeBackground");
1667 bNodeSocket &background_color_output = version_node_add_socket(
1668 *ntree, background, SOCK_OUT, "NodeSocketShader", "Background");
1669 bNodeSocket &background_color_input = version_node_add_socket(
1670 *ntree, background, SOCK_IN, "NodeSocketColor", "Color");
1671 bNodeSocket &background_strength_input = version_node_add_socket(
1672 *ntree, background, SOCK_IN, "NodeSocketFloat", "Strength");
1673 bNodeSocket &background_weight_input = version_node_add_socket(
1674 *ntree, background, SOCK_IN, "NodeSocketFloat", "Weight");
1675 background_weight_input.flag |= SOCK_UNAVAIL;
1676
1678 *ntree, background, background_color_output, new_output, output_surface_input);
1679
1680 bNodeSocketValueRGBA *rgba = background_color_input.default_value_typed<bNodeSocketValueRGBA>();
1681 rgba->value[0] = world->horr;
1682 rgba->value[1] = world->horg;
1683 rgba->value[2] = world->horb;
1684 rgba->value[3] = 1.0f;
1685 background_strength_input.default_value_typed<bNodeSocketValueFloat>()->value = 1.0f;
1686
1687 if (old_output != nullptr) {
1688 /* Position the newly created node after the old output. Assume the old output node is at
1689 * the far right of the node tree. */
1690 background.location[0] = old_output->location[0] + 1.5f * old_output->width;
1691 background.location[1] = old_output->location[1];
1692 }
1693
1694 new_output.location[0] = background.location[0] + 2.0f * background.width;
1695 new_output.location[1] = background.location[1];
1696
1697 bNode *frame = blender::bke::node_add_static_node(nullptr, *ntree, NODE_FRAME);
1698 STRNCPY(frame->label, RPT_("Versioning: Use Nodes was removed"));
1699 background.parent = frame;
1700 new_output.parent = frame;
1701}
1702
1704{
1705 if (blender::bke::node_find_socket(node, SOCK_IN, "Type")) {
1706 return;
1707 }
1708 const auto &storage = *static_cast<NodeBlurData *>(node.storage);
1709 bNodeSocket &socket = version_node_add_socket(ntree, node, SOCK_IN, "NodeSocketMenu", "Type");
1710 socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.filtertype;
1711}
1712
1714{
1715 if (blender::bke::node_find_socket(node, SOCK_IN, "Type")) {
1716 return;
1717 }
1718 bNodeSocket &socket = version_node_add_socket(ntree, node, SOCK_IN, "NodeSocketMenu", "Type");
1719 socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom1;
1720}
1721
1723{
1724 if (blender::bke::node_find_socket(node, SOCK_IN, "Channel")) {
1725 return;
1726 }
1727 bNodeSocket &socket = version_node_add_socket(ntree, node, SOCK_IN, "NodeSocketMenu", "Channel");
1728 socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom1;
1729}
1730
1732{
1733 if (blender::bke::node_find_socket(node, SOCK_IN, "Type")) {
1734 return;
1735 }
1736 bNodeSocket &type_socket = version_node_add_socket(
1737 ntree, node, SOCK_IN, "NodeSocketMenu", "Type");
1738 type_socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom1;
1739
1740 const auto &storage = *static_cast<NodeDilateErode *>(node.storage);
1741 bNodeSocket &falloff_socket = version_node_add_socket(
1742 ntree, node, SOCK_IN, "NodeSocketMenu", "Falloff");
1743 falloff_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.falloff;
1744}
1745
1747{
1748 if (blender::bke::node_find_socket(node, SOCK_IN, "Type")) {
1749 return;
1750 }
1751
1752 const auto &storage = *static_cast<NodeTonemap *>(node.storage);
1753 bNodeSocket &socket = version_node_add_socket(ntree, node, SOCK_IN, "NodeSocketMenu", "Type");
1754 socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.type;
1755}
1756
1758{
1759 if (blender::bke::node_find_socket(node, SOCK_IN, "Type")) {
1760 return;
1761 }
1762
1763 const auto &storage = *static_cast<NodeLensDist *>(node.storage);
1764 bNodeSocket &socket = version_node_add_socket(ntree, node, SOCK_IN, "NodeSocketMenu", "Type");
1765 socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.distortion_type;
1766}
1767
1769{
1770 if (blender::bke::node_find_socket(node, SOCK_IN, "Type")) {
1771 return;
1772 }
1773
1774 const auto &storage = *static_cast<NodeKuwaharaData *>(node.storage);
1775 bNodeSocket &socket = version_node_add_socket(ntree, node, SOCK_IN, "NodeSocketMenu", "Type");
1776 socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.variation;
1777}
1778
1780{
1781 if (blender::bke::node_find_socket(node, SOCK_IN, "Prefilter")) {
1782 return;
1783 }
1784
1785 const auto &storage = *static_cast<NodeDenoise *>(node.storage);
1786 bNodeSocket &prefilter_socket = version_node_add_socket(
1787 ntree, node, SOCK_IN, "NodeSocketMenu", "Prefilter");
1788 prefilter_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.prefilter;
1789 bNodeSocket &quality_socket = version_node_add_socket(
1790 ntree, node, SOCK_IN, "NodeSocketMenu", "Quality");
1791 quality_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.quality;
1792}
1793
1795{
1796 if (blender::bke::node_find_socket(node, SOCK_IN, "Interpolation")) {
1797 return;
1798 }
1799
1800 const auto &storage = *static_cast<NodeTranslateData *>(node.storage);
1801 bNodeSocket &interpolation_socket = version_node_add_socket(
1802 ntree, node, SOCK_IN, "NodeSocketMenu", "Interpolation");
1803 interpolation_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.interpolation;
1804 bNodeSocket &extension_x_socket = version_node_add_socket(
1805 ntree, node, SOCK_IN, "NodeSocketMenu", "Extension X");
1806 extension_x_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.extension_x;
1807 bNodeSocket &extension_y_socket = version_node_add_socket(
1808 ntree, node, SOCK_IN, "NodeSocketMenu", "Extension Y");
1809 extension_y_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.extension_y;
1810}
1811
1813{
1814 if (blender::bke::node_find_socket(node, SOCK_IN, "Interpolation")) {
1815 return;
1816 }
1817
1818 const auto &storage = *static_cast<NodeTransformData *>(node.storage);
1819 bNodeSocket &interpolation_socket = version_node_add_socket(
1820 ntree, node, SOCK_IN, "NodeSocketMenu", "Interpolation");
1821 interpolation_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.interpolation;
1822 bNodeSocket &extension_x_socket = version_node_add_socket(
1823 ntree, node, SOCK_IN, "NodeSocketMenu", "Extension X");
1824 extension_x_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.extension_x;
1825 bNodeSocket &extension_y_socket = version_node_add_socket(
1826 ntree, node, SOCK_IN, "NodeSocketMenu", "Extension Y");
1827 extension_y_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.extension_y;
1828}
1829
1831{
1832 if (blender::bke::node_find_socket(node, SOCK_IN, "Interpolation")) {
1833 return;
1834 }
1835
1836 const auto &storage = *static_cast<NodeCornerPinData *>(node.storage);
1837 bNodeSocket &interpolation_socket = version_node_add_socket(
1838 ntree, node, SOCK_IN, "NodeSocketMenu", "Interpolation");
1839 interpolation_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.interpolation;
1840 bNodeSocket &extension_x_socket = version_node_add_socket(
1841 ntree, node, SOCK_IN, "NodeSocketMenu", "Extension X");
1842 extension_x_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.extension_x;
1843 bNodeSocket &extension_y_socket = version_node_add_socket(
1844 ntree, node, SOCK_IN, "NodeSocketMenu", "Extension Y");
1845 extension_y_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.extension_y;
1846}
1847
1849{
1850 if (blender::bke::node_find_socket(node, SOCK_IN, "Interpolation")) {
1851 return;
1852 }
1853
1854 const auto &storage = *static_cast<NodeMapUVData *>(node.storage);
1855 bNodeSocket &interpolation_socket = version_node_add_socket(
1856 ntree, node, SOCK_IN, "NodeSocketMenu", "Interpolation");
1857 interpolation_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.interpolation;
1858 bNodeSocket &extension_x_socket = version_node_add_socket(
1859 ntree, node, SOCK_IN, "NodeSocketMenu", "Extension X");
1860 extension_x_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.extension_x;
1861 bNodeSocket &extension_y_socket = version_node_add_socket(
1862 ntree, node, SOCK_IN, "NodeSocketMenu", "Extension Y");
1863 extension_y_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.extension_y;
1864}
1865
1867{
1868 if (blender::bke::node_find_socket(node, SOCK_IN, "Interpolation")) {
1869 return;
1870 }
1871
1872 bNodeSocket &type_socket = version_node_add_socket(
1873 ntree, node, SOCK_IN, "NodeSocketMenu", "Type");
1874 type_socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom1;
1875 bNodeSocket &frame_type_socket = version_node_add_socket(
1876 ntree, node, SOCK_IN, "NodeSocketMenu", "Frame Type");
1877 frame_type_socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom2;
1878
1879 const auto &storage = *static_cast<NodeScaleData *>(node.storage);
1880 bNodeSocket &interpolation_socket = version_node_add_socket(
1881 ntree, node, SOCK_IN, "NodeSocketMenu", "Interpolation");
1882 interpolation_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.interpolation;
1883 bNodeSocket &extension_x_socket = version_node_add_socket(
1884 ntree, node, SOCK_IN, "NodeSocketMenu", "Extension X");
1885 extension_x_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.extension_x;
1886 bNodeSocket &extension_y_socket = version_node_add_socket(
1887 ntree, node, SOCK_IN, "NodeSocketMenu", "Extension Y");
1888 extension_y_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.extension_y;
1889}
1890
1892{
1893 if (blender::bke::node_find_socket(node, SOCK_IN, "Interpolation")) {
1894 return;
1895 }
1896
1897 const auto &storage = *static_cast<NodeRotateData *>(node.storage);
1898 bNodeSocket &interpolation_socket = version_node_add_socket(
1899 ntree, node, SOCK_IN, "NodeSocketMenu", "Interpolation");
1900 interpolation_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.interpolation;
1901 bNodeSocket &extension_x_socket = version_node_add_socket(
1902 ntree, node, SOCK_IN, "NodeSocketMenu", "Extension X");
1903 extension_x_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.extension_x;
1904 bNodeSocket &extension_y_socket = version_node_add_socket(
1905 ntree, node, SOCK_IN, "NodeSocketMenu", "Extension Y");
1906 extension_y_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.extension_y;
1907}
1908
1910{
1911 if (blender::bke::node_find_socket(node, SOCK_IN, "Interpolation")) {
1912 return;
1913 }
1914
1915 const auto &storage = *static_cast<NodeDisplaceData *>(node.storage);
1916 bNodeSocket &interpolation_socket = version_node_add_socket(
1917 ntree, node, SOCK_IN, "NodeSocketMenu", "Interpolation");
1918 interpolation_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.interpolation;
1919 bNodeSocket &extension_x_socket = version_node_add_socket(
1920 ntree, node, SOCK_IN, "NodeSocketMenu", "Extension X");
1921 extension_x_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.extension_x;
1922 bNodeSocket &extension_y_socket = version_node_add_socket(
1923 ntree, node, SOCK_IN, "NodeSocketMenu", "Extension Y");
1924 extension_y_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.extension_y;
1925}
1926
1928{
1929 if (blender::bke::node_find_socket(node, SOCK_IN, "Interpolation")) {
1930 return;
1931 }
1932
1933 bNodeSocket &interpolation_socket = version_node_add_socket(
1934 ntree, node, SOCK_IN, "NodeSocketMenu", "Interpolation");
1935 interpolation_socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom1;
1936}
1937
1939{
1940 if (blender::bke::node_find_socket(node, SOCK_IN, "Operation")) {
1941 return;
1942 }
1943
1944 bNodeSocket &operation_socket = version_node_add_socket(
1945 ntree, node, SOCK_IN, "NodeSocketMenu", "Operation");
1946 operation_socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom1;
1947}
1948
1950{
1951 if (blender::bke::node_find_socket(node, SOCK_IN, "Operation")) {
1952 return;
1953 }
1954
1955 bNodeSocket &operation_socket = version_node_add_socket(
1956 ntree, node, SOCK_IN, "NodeSocketMenu", "Operation");
1957 operation_socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom1;
1958}
1959
1961{
1962 if (blender::bke::node_find_socket(node, SOCK_IN, "Mode")) {
1963 return;
1964 }
1965
1966 bNodeSocket &mode_socket = version_node_add_socket(
1967 ntree, node, SOCK_IN, "NodeSocketMenu", "Mode");
1968 mode_socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom1;
1969 bNodeSocket &frame_socket = version_node_add_socket(
1970 ntree, node, SOCK_IN, "NodeSocketInt", "Frame");
1971 frame_socket.default_value_typed<bNodeSocketValueInt>()->value = node.custom2;
1972}
1973
1975{
1976 if (blender::bke::node_find_socket(node, SOCK_IN, "Feather Falloff")) {
1977 return;
1978 }
1979
1980 const auto &storage = *static_cast<NodeKeyingData *>(node.storage);
1981 bNodeSocket &feather_falloff_socket = version_node_add_socket(
1982 ntree, node, SOCK_IN, "NodeSocketMenu", "Feather Falloff");
1983 feather_falloff_socket.default_value_typed<bNodeSocketValueMenu>()->value =
1984 storage.feather_falloff;
1985}
1986
1988{
1989 if (blender::bke::node_find_socket(node, SOCK_IN, "Size Source")) {
1990 return;
1991 }
1992
1993 bNodeSocket &size_source_socket = version_node_add_socket(
1994 ntree, node, SOCK_IN, "NodeSocketMenu", "Size Source");
1995 size_source_socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom1;
1996}
1997
1999{
2000 if (blender::bke::node_find_socket(node, SOCK_IN, "Type")) {
2001 return;
2002 }
2003
2004 bNodeSocket &type_socket = version_node_add_socket(
2005 ntree, node, SOCK_IN, "NodeSocketMenu", "Type");
2006 type_socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom1;
2007}
2008
2010{
2011 if (blender::bke::node_find_socket(node, SOCK_IN, "Type")) {
2012 return;
2013 }
2014
2015 const auto &storage = *static_cast<NodeGlare *>(node.storage);
2016 bNodeSocket &type_socket = version_node_add_socket(
2017 ntree, node, SOCK_IN, "NodeSocketMenu", "Type");
2018 type_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.type;
2019 bNodeSocket &quality_socket = version_node_add_socket(
2020 ntree, node, SOCK_IN, "NodeSocketMenu", "Quality");
2021 quality_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.quality;
2022}
2023
2025{
2026 /* When opening and saving 5.0 files with bundle/closure nodes in 4.5, the storage is lost, since
2027 * Blender 4.5 does not officially support these features yet (they were experimental features
2028 * though). This versioning code just adds back the storage so that it does not crash further
2029 * down the line. */
2030 LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
2031 if (node->storage) {
2032 continue;
2033 }
2034 switch (node->type_legacy) {
2035 case NODE_CLOSURE_INPUT: {
2036 node->storage = MEM_callocN<NodeClosureInput>(__func__);
2037 break;
2038 }
2039 case NODE_CLOSURE_OUTPUT: {
2040 node->storage = MEM_callocN<NodeClosureOutput>(__func__);
2041 break;
2042 }
2043 case NODE_EVALUATE_CLOSURE: {
2044 node->storage = MEM_callocN<NodeEvaluateClosure>(__func__);
2045 break;
2046 }
2047 case NODE_COMBINE_BUNDLE: {
2048 node->storage = MEM_callocN<NodeCombineBundle>(__func__);
2049 break;
2050 }
2051 case NODE_SEPARATE_BUNDLE: {
2052 node->storage = MEM_callocN<NodeSeparateBundle>(__func__);
2053 break;
2054 }
2055 }
2056 }
2057}
2058
2060{
2061 if (material->use_nodes) {
2062 return;
2063 }
2064
2065 /* Users defined a material node tree, but deactivated it by disabling "Use Nodes". So we
2066 * simulate the same effect by creating a new Material Output node and setting it to active. */
2067 bNodeTree *ntree = material->nodetree;
2068 if (ntree == nullptr) {
2069 /* In case the material was created in Python API it might have been missing a node tree. */
2071 bmain, &material->id, "Material Node Tree Versioning", "ShaderNodeTree");
2072 }
2073
2074 bNode *old_output = nullptr;
2075 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
2076 if (STREQ(node->idname, "ShaderNodeOutputMaterial") && (node->flag & NODE_DO_OUTPUT)) {
2077 old_output = node;
2078 old_output->flag &= ~NODE_DO_OUTPUT;
2079 }
2080 }
2081
2082 bNode *frame = blender::bke::node_add_static_node(nullptr, *ntree, NODE_FRAME);
2083 STRNCPY(frame->label, RPT_("Versioning: Use Nodes was removed"));
2084
2085 {
2086 /* For EEVEE, we use a principled BSDF shader because we need to recreate the metallic,
2087 * specular and roughness properties of the material for use_nodes = false.*/
2088 bNode &new_output_eevee = version_node_add_empty(*ntree, "ShaderNodeOutputMaterial");
2089 bNodeSocket &output_surface_input = version_node_add_socket(
2090 *ntree, new_output_eevee, SOCK_IN, "NodeSocketShader", "Surface");
2091 version_node_add_socket(*ntree, new_output_eevee, SOCK_IN, "NodeSocketShader", "Volume");
2092 version_node_add_socket(*ntree, new_output_eevee, SOCK_IN, "NodeSocketVector", "Displacement");
2093 version_node_add_socket(*ntree, new_output_eevee, SOCK_IN, "NodeSocketFloat", "Thickness");
2094
2095 version_node_add_socket(*ntree, new_output_eevee, SOCK_IN, "NodeSocketShader", "Volume");
2096 new_output_eevee.flag |= NODE_DO_OUTPUT;
2097 new_output_eevee.custom1 = SHD_OUTPUT_EEVEE;
2098
2100 nullptr, *ntree, SH_NODE_BSDF_PRINCIPLED);
2101 bNodeSocket &shader_bsdf_output = *blender::bke::node_find_socket(
2102 shader_eevee, SOCK_OUT, "BSDF");
2103 bNodeSocket &shader_color_input = *blender::bke::node_find_socket(
2104 shader_eevee, SOCK_IN, "Base Color");
2106 shader_eevee, SOCK_IN, "Specular IOR Level");
2108 shader_eevee, SOCK_IN, "Metallic");
2109 bNodeSocket &roughness_input = *blender::bke::node_find_socket(
2110 shader_eevee, SOCK_IN, "Roughness");
2111
2113 *ntree, shader_eevee, shader_bsdf_output, new_output_eevee, output_surface_input);
2114
2115 bNodeSocketValueRGBA *rgba = shader_color_input.default_value_typed<bNodeSocketValueRGBA>();
2116 rgba->value[0] = material->r;
2117 rgba->value[1] = material->g;
2118 rgba->value[2] = material->b;
2119 rgba->value[3] = material->a;
2120 roughness_input.default_value_typed<bNodeSocketValueFloat>()->value = material->roughness;
2121 metallic_input.default_value_typed<bNodeSocketValueFloat>()->value = material->metallic;
2122 specular_input.default_value_typed<bNodeSocketValueFloat>()->value = material->spec;
2123
2124 if (old_output != nullptr) {
2125 /* Position the newly created node after the old output. Assume the old output node is at
2126 * the far right of the node tree. */
2127 shader_eevee.location[0] = old_output->location[0] + 1.5f * old_output->width;
2128 shader_eevee.location[1] = old_output->location[1];
2129 }
2130
2131 new_output_eevee.location[0] = shader_eevee.location[0] + 2.0f * shader_eevee.width;
2132 new_output_eevee.location[1] = shader_eevee.location[1];
2133
2134 shader_eevee.parent = frame;
2135 new_output_eevee.parent = frame;
2136 }
2137
2138 {
2139 /* For Cycles, a simple diffuse BSDF is sufficient. */
2140 bNode &new_output_cycles = version_node_add_empty(*ntree, "ShaderNodeOutputMaterial");
2141 bNodeSocket &output_surface_input = version_node_add_socket(
2142 *ntree, new_output_cycles, SOCK_IN, "NodeSocketShader", "Surface");
2143 version_node_add_socket(*ntree, new_output_cycles, SOCK_IN, "NodeSocketShader", "Volume");
2145 *ntree, new_output_cycles, SOCK_IN, "NodeSocketVector", "Displacement");
2146 version_node_add_socket(*ntree, new_output_cycles, SOCK_IN, "NodeSocketFloat", "Thickness");
2147 /* We don't activate the output explicitly to avoid having two active outputs. We assume
2148 * `node_tree.get_output_node('Cycles')` will return this node. */
2149 new_output_cycles.custom1 = SHD_OUTPUT_CYCLES;
2150
2151 bNode &shader_cycles = *blender::bke::node_add_static_node(
2152 nullptr, *ntree, SH_NODE_BSDF_DIFFUSE);
2153 bNodeSocket &shader_bsdf_output = *blender::bke::node_find_socket(
2154 shader_cycles, SOCK_OUT, "BSDF");
2155 bNodeSocket &shader_color_input = *blender::bke::node_find_socket(
2156 shader_cycles, SOCK_IN, "Color");
2157
2159 *ntree, shader_cycles, shader_bsdf_output, new_output_cycles, output_surface_input);
2160
2161 bNodeSocketValueRGBA *rgba = shader_color_input.default_value_typed<bNodeSocketValueRGBA>();
2162 rgba->value[0] = material->r;
2163 rgba->value[1] = material->g;
2164 rgba->value[2] = material->b;
2165 rgba->value[3] = material->a;
2166
2167 if (old_output != nullptr) {
2168 shader_cycles.location[0] = old_output->location[0] + 1.5f * old_output->width;
2169 shader_cycles.location[1] = old_output->location[1] + 2.0f * old_output->height;
2170 }
2171
2172 new_output_cycles.location[0] = shader_cycles.location[0] + 3.0f * shader_cycles.width;
2173 new_output_cycles.location[1] = shader_cycles.location[1];
2174
2175 shader_cycles.parent = frame;
2176 new_output_cycles.parent = frame;
2177 }
2178}
2179
2181{
2182 if (blender::bke::node_find_socket(node, SOCK_IN, "Type")) {
2183 return;
2184 }
2185
2186 const auto &storage = *static_cast<NodeSetAlpha *>(node.storage);
2187 bNodeSocket &socket = version_node_add_socket(ntree, node, SOCK_IN, "NodeSocketMenu", "Type");
2188 socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.mode;
2189}
2190
2192{
2193 if (blender::bke::node_find_socket(node, SOCK_IN, "Color Space")) {
2194 return;
2195 }
2196
2197 const auto &storage = *static_cast<NodeChroma *>(node.storage);
2198 bNodeSocket &color_space_socket = version_node_add_socket(
2199 ntree, node, SOCK_IN, "NodeSocketMenu", "Color Space");
2200 color_space_socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom1 - 1;
2201 bNodeSocket &rgb_key_channel_socket = version_node_add_socket(
2202 ntree, node, SOCK_IN, "NodeSocketMenu", "RGB Key Channel");
2203 rgb_key_channel_socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom2 - 1;
2204 bNodeSocket &hsv_key_channel_socket = version_node_add_socket(
2205 ntree, node, SOCK_IN, "NodeSocketMenu", "HSV Key Channel");
2206 hsv_key_channel_socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom2 - 1;
2207 bNodeSocket &yuv_key_channel_socket = version_node_add_socket(
2208 ntree, node, SOCK_IN, "NodeSocketMenu", "YUV Key Channel");
2209 yuv_key_channel_socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom2 - 1;
2210 bNodeSocket &ycc_key_channel_socket = version_node_add_socket(
2211 ntree, node, SOCK_IN, "NodeSocketMenu", "YCbCr Key Channel");
2212 ycc_key_channel_socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom2 - 1;
2213
2214 bNodeSocket &limit_method_socket = version_node_add_socket(
2215 ntree, node, SOCK_IN, "NodeSocketMenu", "Limit Method");
2216 limit_method_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.algorithm;
2217 bNodeSocket &rgb_limit_channel_socket = version_node_add_socket(
2218 ntree, node, SOCK_IN, "NodeSocketMenu", "RGB Limit Channel");
2219 rgb_limit_channel_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.channel -
2220 1;
2221 bNodeSocket &hsv_limit_channel_socket = version_node_add_socket(
2222 ntree, node, SOCK_IN, "NodeSocketMenu", "HSV Limit Channel");
2223 hsv_limit_channel_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.channel -
2224 1;
2225 bNodeSocket &yuv_limit_channel_socket = version_node_add_socket(
2226 ntree, node, SOCK_IN, "NodeSocketMenu", "YUV Limit Channel");
2227 yuv_limit_channel_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.channel -
2228 1;
2229 bNodeSocket &ycc_limit_channel_socket = version_node_add_socket(
2230 ntree, node, SOCK_IN, "NodeSocketMenu", "YCbCr Limit Channel");
2231 ycc_limit_channel_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.channel -
2232 1;
2233}
2234
2236{
2237 if (blender::bke::node_find_socket(node, SOCK_IN, "Type")) {
2238 return;
2239 }
2240
2241 bNodeSocket &socket = version_node_add_socket(ntree, node, SOCK_IN, "NodeSocketMenu", "Type");
2242 socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom1;
2243}
2244
2246{
2247 if (blender::bke::node_find_socket(node, SOCK_IN, "Type")) {
2248 return;
2249 }
2250
2251 bNodeSocket &socket = version_node_add_socket(ntree, node, SOCK_IN, "NodeSocketMenu", "Type");
2252 socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom1;
2253}
2254
2256{
2257 if (blender::bke::node_find_socket(node, SOCK_IN, "Color Space")) {
2258 return;
2259 }
2260
2261 auto &storage = *static_cast<NodeChroma *>(node.storage);
2263 ntree, node, SOCK_IN, "NodeSocketMenu", "Color Space");
2264 socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.channel - 1;
2265}
2266
2268{
2269 if (blender::bke::node_find_socket(node, SOCK_IN, "Spill Channel")) {
2270 return;
2271 }
2272
2273 bNodeSocket &spill_channel_socket = version_node_add_socket(
2274 ntree, node, SOCK_IN, "NodeSocketMenu", "Spill Channel");
2275 spill_channel_socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom1 - 1;
2276 bNodeSocket &limit_method_socket = version_node_add_socket(
2277 ntree, node, SOCK_IN, "NodeSocketMenu", "Limit Method");
2278 limit_method_socket.default_value_typed<bNodeSocketValueMenu>()->value = node.custom2;
2279
2280 auto &storage = *static_cast<NodeColorspill *>(node.storage);
2281 bNodeSocket &limit_channel_socket = version_node_add_socket(
2282 ntree, node, SOCK_IN, "NodeSocketMenu", "Limit Channel");
2283 limit_channel_socket.default_value_typed<bNodeSocketValueMenu>()->value = storage.limchan;
2284}
2285
2287{
2288 if (blender::bke::node_find_socket(node, SOCK_IN, "Image Edges")) {
2289 return;
2290 }
2291
2292 bNodeSocket &image_edges_socket = version_node_add_socket(
2293 ntree, node, SOCK_IN, "NodeSocketBool", "Image Edges");
2294 image_edges_socket.default_value_typed<bNodeSocketValueBoolean>()->value = bool(node.custom2);
2295 bNodeSocket &only_inside_outer_socket = version_node_add_socket(
2296 ntree, node, SOCK_IN, "NodeSocketBool", "Only Inside Outer");
2297 only_inside_outer_socket.default_value_typed<bNodeSocketValueBoolean>()->value = bool(
2298 node.custom1);
2299}
2300
2302{
2303 LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
2304 if (node->type_legacy != GEO_NODE_VIEWER) {
2305 continue;
2306 }
2307 NodeGeometryViewer *storage = static_cast<NodeGeometryViewer *>(node->storage);
2308 const int input_sockets_num = BLI_listbase_count(&node->inputs);
2309 if (input_sockets_num == storage->items_num + 1) {
2310 /* Make versioning idempotent. */
2311 continue;
2312 }
2313 storage->items_num = 2;
2314 storage->items = MEM_calloc_arrayN<NodeGeometryViewerItem>(2, __func__);
2315 NodeGeometryViewerItem &geometry_item = storage->items[0];
2316 geometry_item.name = BLI_strdup("Geometry");
2317 geometry_item.socket_type = SOCK_GEOMETRY;
2318 geometry_item.identifier = 0;
2319 NodeGeometryViewerItem &value_item = storage->items[1];
2320 value_item.name = BLI_strdup("Value");
2323 .value_or(SOCK_FLOAT);
2324 value_item.identifier = 1;
2325 storage->next_identifier = 2;
2326 }
2327}
2328
2330{
2332
2333 bNodeSocket *displacement_input = blender::bke::node_find_socket(node, SOCK_IN, "Displacement");
2334 bNodeSocket *x_scale_input = blender::bke::node_find_socket(node, SOCK_IN, "X Scale");
2335 bNodeSocket *y_scale_input = blender::bke::node_find_socket(node, SOCK_IN, "Y Scale");
2336
2337 /* Find the link going into the inputs of the node. */
2338 bNodeLink *displacement_link = nullptr;
2339 bNodeLink *x_scale_link = nullptr;
2340 bNodeLink *y_scale_link = nullptr;
2341 LISTBASE_FOREACH (bNodeLink *, link, &node_tree.links) {
2342 if (link->tosock == displacement_input) {
2343 displacement_link = link;
2344 }
2345 if (link->tosock == x_scale_input) {
2346 x_scale_link = link;
2347 }
2348 if (link->tosock == y_scale_input) {
2349 y_scale_link = link;
2350 }
2351 }
2352
2353 bNode *multiply_node = blender::bke::node_add_node(nullptr, node_tree, "ShaderNodeVectorMath");
2354 multiply_node->parent = node.parent;
2355 multiply_node->location[0] = node.location[0] - node.width - 20.0f;
2356 multiply_node->location[1] = node.location[1];
2357 multiply_node->custom1 = NODE_VECTOR_MATH_MULTIPLY;
2358
2359 bNodeSocket *multiply_a_input = blender::bke::node_find_socket(
2360 *multiply_node, SOCK_IN, "Vector");
2361 bNodeSocket *multiply_b_input = blender::bke::node_find_socket(
2362 *multiply_node, SOCK_IN, "Vector_001");
2364 *multiply_node, SOCK_OUT, "Vector");
2365
2366 copy_v2_v2(multiply_a_input->default_value_typed<bNodeSocketValueVector>()->value,
2367 displacement_input->default_value_typed<bNodeSocketValueVector>()->value);
2368 if (displacement_link) {
2369 version_node_add_link(node_tree,
2370 *displacement_link->fromnode,
2371 *displacement_link->fromsock,
2372 *multiply_node,
2373 *multiply_a_input);
2374 blender::bke::node_remove_link(&node_tree, *displacement_link);
2375 }
2376
2377 version_node_add_link(node_tree, *multiply_node, *multiply_output, node, *displacement_input);
2378
2379 bNode *combine_node = blender::bke::node_add_node(nullptr, node_tree, "ShaderNodeCombineXYZ");
2380 combine_node->parent = node.parent;
2381 combine_node->location[0] = multiply_node->location[0] - multiply_node->width - 20.0f;
2382 combine_node->location[1] = multiply_node->location[1];
2383
2384 bNodeSocket *combine_x_input = blender::bke::node_find_socket(*combine_node, SOCK_IN, "X");
2385 bNodeSocket *combine_y_input = blender::bke::node_find_socket(*combine_node, SOCK_IN, "Y");
2386 bNodeSocket *combine_output = blender::bke::node_find_socket(*combine_node, SOCK_OUT, "Vector");
2387
2389 node_tree, *combine_node, *combine_output, *multiply_node, *multiply_b_input);
2390
2391 combine_x_input->default_value_typed<bNodeSocketValueFloat>()->value =
2392 x_scale_input->default_value_typed<bNodeSocketValueFloat>()->value;
2393 if (x_scale_link) {
2394 version_node_add_link(node_tree,
2395 *x_scale_link->fromnode,
2396 *x_scale_link->fromsock,
2397 *combine_node,
2398 *combine_x_input);
2399 blender::bke::node_remove_link(&node_tree, *x_scale_link);
2400 }
2401
2402 combine_y_input->default_value_typed<bNodeSocketValueFloat>()->value =
2403 y_scale_input->default_value_typed<bNodeSocketValueFloat>()->value;
2404 if (y_scale_link) {
2405 version_node_add_link(node_tree,
2406 *y_scale_link->fromnode,
2407 *y_scale_link->fromsock,
2408 *combine_node,
2409 *combine_y_input);
2410 blender::bke::node_remove_link(&node_tree, *y_scale_link);
2411 }
2412}
2413
2414/* The Size input is now in pixels, while previously, it was relative to 0.01 of the greater image
2415 * dimension. */
2417{
2419
2420 bNodeSocket *image_input = blender::bke::node_find_socket(node, SOCK_IN, "Image");
2421 bNodeSocket *size_input = blender::bke::node_find_socket(node, SOCK_IN, "Size");
2422
2423 /* Find the link going into the inputs of the node. */
2424 bNodeLink *image_link = nullptr;
2425 bNodeLink *size_link = nullptr;
2426 LISTBASE_FOREACH (bNodeLink *, link, &node_tree.links) {
2427 if (link->tosock == size_input) {
2428 size_link = link;
2429 }
2430 if (link->tosock == image_input) {
2431 image_link = link;
2432 }
2433 }
2434
2435 bNode &multiply_node = version_node_add_empty(node_tree, "ShaderNodeMath");
2436 multiply_node.parent = node.parent;
2437 multiply_node.location[0] = node.location[0] - node.width - 20.0f;
2438 multiply_node.location[1] = node.location[1];
2439 multiply_node.custom1 = NODE_MATH_MULTIPLY;
2440
2441 bNodeSocket &multiply_a_input = version_node_add_socket(
2442 node_tree, multiply_node, SOCK_IN, "NodeSocketFloat", "Value");
2443 bNodeSocket &multiply_b_input = version_node_add_socket(
2444 node_tree, multiply_node, SOCK_IN, "NodeSocketFloat", "Value_001");
2445 bNodeSocket &multiply_output = version_node_add_socket(
2446 node_tree, multiply_node, SOCK_OUT, "NodeSocketFloat", "Value");
2447
2448 multiply_a_input.default_value_typed<bNodeSocketValueFloat>()->value =
2449 size_input->default_value_typed<bNodeSocketValueFloat>()->value;
2450 if (size_link) {
2452 node_tree, *size_link->fromnode, *size_link->fromsock, multiply_node, multiply_a_input);
2453 blender::bke::node_remove_link(&node_tree, *size_link);
2454 }
2455
2456 version_node_add_link(node_tree, multiply_node, multiply_output, node, *size_input);
2457
2458 bNode *relative_to_pixel_node = blender::bke::node_add_node(
2459 nullptr, node_tree, "CompositorNodeRelativeToPixel");
2460 relative_to_pixel_node->parent = node.parent;
2461 relative_to_pixel_node->location[0] = multiply_node.location[0] - multiply_node.width - 20.0f;
2462 relative_to_pixel_node->location[1] = multiply_node.location[1];
2463 relative_to_pixel_node->custom1 = CMP_NODE_RELATIVE_TO_PIXEL_DATA_TYPE_FLOAT;
2465
2466 bNodeSocket *relative_to_pixel_image_input = blender::bke::node_find_socket(
2467 *relative_to_pixel_node, SOCK_IN, "Image");
2468 bNodeSocket *relative_to_pixel_value_input = blender::bke::node_find_socket(
2469 *relative_to_pixel_node, SOCK_IN, "Float Value");
2470 bNodeSocket *relative_to_pixel_value_output = blender::bke::node_find_socket(
2471 *relative_to_pixel_node, SOCK_OUT, "Float Value");
2472
2473 version_node_add_link(node_tree,
2474 *relative_to_pixel_node,
2475 *relative_to_pixel_value_output,
2476 multiply_node,
2477 multiply_b_input);
2478
2479 relative_to_pixel_value_input->default_value_typed<bNodeSocketValueFloat>()->value = 0.01f;
2480 if (image_link) {
2481 version_node_add_link(node_tree,
2482 *image_link->fromnode,
2483 *image_link->fromsock,
2484 *relative_to_pixel_node,
2485 *relative_to_pixel_image_input);
2486 }
2487}
2488
2490{
2491 bScreen *screen = WM_window_get_active_screen(win);
2492 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
2493 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
2494 if (sl->spacetype == SPACE_SEQ) {
2495 return true;
2496 }
2497 }
2498 }
2499 return false;
2500}
2501
2502/* Merge transform effect properties with strip transform. Because this effect could use modifiers,
2503 * change its type to gaussian blur with 0 radius. */
2505{
2506 blender::seq::foreach_strip(&scene->ed->seqbase, [&](Strip *strip) -> bool {
2507 if (strip->type == STRIP_TYPE_TRANSFORM_LEGACY && strip->effectdata != nullptr) {
2508 TransformVarsLegacy *tv = static_cast<TransformVarsLegacy *>(strip->effectdata);
2509 StripTransform *transform = strip->data->transform;
2510 blender::float2 offset(tv->xIni, tv->yIni);
2511 if (tv->percent == 1) {
2512 blender::float2 scene_resolution(scene->r.xsch, scene->r.ysch);
2513 offset *= scene_resolution;
2514 }
2515 transform->xofs += offset.x;
2516 transform->yofs += offset.y;
2517 transform->scale_x *= tv->ScalexIni;
2518 transform->scale_y *= tv->ScaleyIni;
2519 transform->rotation += tv->rotIni;
2520 blender::seq::EffectHandle sh = blender::seq::strip_effect_handle_get(strip);
2521 sh.free(strip, true);
2522 strip->type = STRIP_TYPE_GAUSSIAN_BLUR;
2523 sh = blender::seq::strip_effect_handle_get(strip);
2524 sh.init(strip);
2525 GaussianBlurVars *gv = static_cast<GaussianBlurVars *>(strip->effectdata);
2526 gv->size_x = gv->size_y = 0.0f;
2527 blender::seq::edit_strip_name_set(scene, strip, "Transform Placeholder (Migrated)");
2528 blender::seq::ensure_unique_name(strip, scene);
2529 }
2530 return true;
2531 });
2532}
2533
2534/* The LGG mode of the Color Balance node was being done in sRGB space, while now it is done in
2535 * linear space. So a Gamma node will be added before and after the node to perform the adjustment
2536 * in sRGB space. */
2538{
2539 bNodeSocket *image_input = blender::bke::node_find_socket(node, SOCK_IN, "Image");
2540 bNodeSocket *type_input = blender::bke::node_find_socket(node, SOCK_IN, "Type");
2541 bNodeSocket *image_output = blender::bke::node_find_socket(node, SOCK_OUT, "Image");
2542
2543 /* Find the links going into and out of the node. */
2544 bNodeLink *image_input_link = nullptr;
2545 bNodeLink *type_input_link = nullptr;
2546 LISTBASE_FOREACH (bNodeLink *, link, &node_tree.links) {
2547 if (link->tosock == image_input) {
2548 image_input_link = link;
2549 }
2550 if (link->tosock == type_input) {
2551 type_input_link = link;
2552 }
2553 }
2554
2555 if (type_input_link || !type_input ||
2556 type_input->default_value_typed<bNodeSocketValueMenu>()->value != CMP_NODE_COLOR_BALANCE_LGG)
2557 {
2558 return;
2559 }
2560
2561 bNode *inverse_gamma_node = blender::bke::node_add_static_node(
2562 nullptr, node_tree, SH_NODE_GAMMA);
2563 inverse_gamma_node->parent = node.parent;
2564 inverse_gamma_node->location[0] = node.location[0];
2565 inverse_gamma_node->location[1] = node.location[1];
2566
2567 bNodeSocket *inverse_gamma_color_input = blender::bke::node_find_socket(
2568 *inverse_gamma_node, SOCK_IN, "Color");
2569 copy_v4_v4(inverse_gamma_color_input->default_value_typed<bNodeSocketValueRGBA>()->value,
2570 image_input->default_value_typed<bNodeSocketValueRGBA>()->value);
2571 bNodeSocket *inverse_gamma_color_output = blender::bke::node_find_socket(
2572 *inverse_gamma_node, SOCK_OUT, "Color");
2573
2574 bNodeSocket *inverse_gamma_input = blender::bke::node_find_socket(
2575 *inverse_gamma_node, SOCK_IN, "Gamma");
2576 inverse_gamma_input->default_value_typed<bNodeSocketValueFloat>()->value = 1.0f / 2.2f;
2577
2579 node_tree, *inverse_gamma_node, *inverse_gamma_color_output, node, *image_input);
2580 if (image_input_link) {
2581 version_node_add_link(node_tree,
2582 *image_input_link->fromnode,
2583 *image_input_link->fromsock,
2584 *inverse_gamma_node,
2585 *inverse_gamma_color_input);
2586 blender::bke::node_remove_link(&node_tree, *image_input_link);
2587 }
2588
2589 bNode *gamma_node = blender::bke::node_add_static_node(nullptr, node_tree, SH_NODE_GAMMA);
2590 gamma_node->parent = node.parent;
2591 gamma_node->location[0] = node.location[0];
2592 gamma_node->location[1] = node.location[1];
2593
2594 bNodeSocket *gamma_color_input = blender::bke::node_find_socket(*gamma_node, SOCK_IN, "Color");
2595 bNodeSocket *gamma_color_output = blender::bke::node_find_socket(*gamma_node, SOCK_OUT, "Color");
2596
2597 bNodeSocket *gamma_input = blender::bke::node_find_socket(*gamma_node, SOCK_IN, "Gamma");
2598 gamma_input->default_value_typed<bNodeSocketValueFloat>()->value = 2.2f;
2599
2600 LISTBASE_FOREACH_BACKWARD_MUTABLE (bNodeLink *, link, &node_tree.links) {
2601 if (link->fromsock != image_output) {
2602 continue;
2603 }
2604
2606 node_tree, *gamma_node, *gamma_color_output, *link->tonode, *link->tosock);
2607 blender::bke::node_remove_link(&node_tree, *link);
2608 }
2609
2610 version_node_add_link(node_tree, node, *image_output, *gamma_node, *gamma_color_input);
2611}
2612
2614{
2615 using namespace blender::animrig;
2616 constexpr char const *hide_prop_prefix = "bones[";
2617 constexpr char const *hide_prop_suffix = "\"].hide";
2618
2619 blender::Vector<FCurve *> drivers_to_fix;
2620 LISTBASE_FOREACH (FCurve *, fcurve, &arm_adt->drivers) {
2621 const blender::StringRef rna_path(fcurve->rna_path);
2622 int quoted_bone_name_start = 0;
2623 int quoted_bone_name_end = 0;
2624 const bool is_prefix_found = BLI_str_quoted_substr_range(
2625 fcurve->rna_path, hide_prop_prefix, &quoted_bone_name_start, &quoted_bone_name_end);
2626 if (is_prefix_found && STREQ(fcurve->rna_path + quoted_bone_name_end, hide_prop_suffix)) {
2627 drivers_to_fix.append(fcurve);
2628 }
2629 }
2630
2631 if (drivers_to_fix.is_empty()) {
2632 return;
2633 }
2634
2635 for (Object *ob : users) {
2636 AnimData *ob_adt = BKE_animdata_ensure_id(&ob->id);
2637 for (FCurve *original : drivers_to_fix) {
2638 /* Has to be a copy in case there is more than 1 object using the armature. */
2639 FCurve *copy = BKE_fcurve_copy(original);
2640 char *fixed_path = BLI_string_joinN("pose.", copy->rna_path);
2641 MEM_SAFE_FREE(copy->rna_path);
2642 copy->rna_path = fixed_path;
2643 BLI_addtail(&ob_adt->drivers, copy);
2644 }
2645 }
2646
2647 for (FCurve *original : drivers_to_fix) {
2648 BLI_remlink(&arm_adt->drivers, original);
2649 BKE_fcurve_free(original);
2650 }
2651}
2652
2654{
2655 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 9)) {
2656 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
2657 if (STREQ(scene->r.engine, RE_engine_id_BLENDER_EEVEE_NEXT)) {
2658 STRNCPY_UTF8(scene->r.engine, RE_engine_id_BLENDER_EEVEE);
2659 }
2660 }
2661 }
2662
2663 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 27)) {
2664 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
2665 if (ntree->type == NTREE_COMPOSIT) {
2667 }
2668 }
2670 }
2671
2672 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 37)) {
2673 LISTBASE_FOREACH (Object *, object, &bmain->objects) {
2675 }
2676 }
2677
2678 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 41)) {
2679 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
2680 bNodeTree *node_tree = version_get_scene_compositor_node_tree(bmain, scene);
2681 if (node_tree) {
2682 /* Add a default interface for the node tree. See the versioning function below for more
2683 * details. */
2684 node_tree->tree_interface.clear_items();
2685 node_tree->tree_interface.add_socket(
2686 DATA_("Image"), "", "NodeSocketColor", NODE_INTERFACE_SOCKET_INPUT, nullptr);
2687 node_tree->tree_interface.add_socket(
2688 DATA_("Image"), "", "NodeSocketColor", NODE_INTERFACE_SOCKET_OUTPUT, nullptr);
2689
2690 LISTBASE_FOREACH_BACKWARD_MUTABLE (bNode *, node, &node_tree->nodes) {
2691 if (node->type_legacy == CMP_NODE_COMPOSITE_DEPRECATED) {
2692 do_version_composite_node_in_scene_tree(*node_tree, *node);
2693 }
2694 }
2695 }
2696 }
2697 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
2699 if (node_tree->type == NTREE_COMPOSIT) {
2700 LISTBASE_FOREACH_BACKWARD_MUTABLE (bNode *, node, &node_tree->nodes) {
2701 if (node->type_legacy == CMP_NODE_COMPOSITE_DEPRECATED) {
2702 /* See do_version_composite_node_in_scene_tree. */
2703 version_node_remove(*node_tree, *node);
2704 }
2705 }
2706 }
2707 }
2709 }
2710
2711 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 54)) {
2712 LISTBASE_FOREACH (Object *, object, &bmain->objects) {
2713 if (object->type != OB_ARMATURE || !object->data) {
2714 continue;
2715 }
2716 BKE_pose_rebuild(nullptr, object, static_cast<bArmature *>(object->data), false);
2717 LISTBASE_FOREACH (bPoseChannel *, pose_bone, &object->pose->chanbase) {
2718 if (pose_bone->bone->flag & BONE_HIDDEN_P) {
2719 pose_bone->drawflag |= PCHAN_DRAW_HIDDEN;
2720 }
2721 else {
2722 pose_bone->drawflag &= ~PCHAN_DRAW_HIDDEN;
2723 }
2724 }
2725 }
2726 }
2727
2728 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 57)) {
2729 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
2730 if (node_tree->type == NTREE_COMPOSIT) {
2731 LISTBASE_FOREACH_BACKWARD_MUTABLE (bNode *, node, &node_tree->nodes) {
2732 if (node->type_legacy == CMP_NODE_SUNBEAMS_DEPRECATED) {
2733 do_version_sun_beams(*node_tree, *node);
2734 }
2735 }
2736 }
2737 }
2739 }
2740
2741 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 63)) {
2742 LISTBASE_FOREACH (wmWindowManager *, wm, &bmain->wm) {
2743 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
2745 Scene *scene = WM_window_get_active_scene(win);
2746 if (scene->ed != nullptr) {
2747 WorkSpace *workspace = WM_window_get_active_workspace(win);
2748 workspace->sequencer_scene = scene;
2749 }
2750 }
2751 }
2752 }
2753 }
2754
2755 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 97)) {
2756 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
2757 if (scene->ed != nullptr) {
2759 }
2760 }
2761 }
2762
2763 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 101)) {
2764 const uint8_t default_flags = DNA_struct_default_get(ToolSettings)->fix_to_cam_flag;
2765 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
2766 if (!scene->toolsettings) {
2767 continue;
2768 }
2769 scene->toolsettings->fix_to_cam_flag = default_flags;
2770 }
2771 }
2772
2773 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 110)) {
2774 /* Build map of armature->object to quickly find out afterwards which armature is used by which
2775 * objects. */
2777 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
2778 if (ob->type != OB_ARMATURE || !ob->data) {
2779 continue;
2780 }
2781 bArmature *arm = reinterpret_cast<bArmature *>(ob->data);
2782 blender::Vector<Object *> &users = armature_usage_map.lookup_or_add_default(arm);
2783 users.append(ob);
2784 }
2785
2786 LISTBASE_FOREACH (bArmature *, armature, &bmain->armatures) {
2787 AnimData *arm_adt = BKE_animdata_from_id(&armature->id);
2788
2789 if (!arm_adt || BLI_listbase_is_empty(&arm_adt->drivers)) {
2790 continue;
2791 }
2792
2793 blender::Vector<Object *> *users = armature_usage_map.lookup_ptr(armature);
2794 if (!users) {
2795 /* If `users` is a nullptr that means there is no user of that armature. That means the
2796 * property won't be fixed for armatures that are not used by an object during versioning.
2797 * However since the driver has to be moved to an object there is no way to fix it in this
2798 * case. */
2799 continue;
2800 }
2801
2803 }
2804 }
2805
2812}
2813
2815{
2816 using namespace blender;
2817 const Span old_sockets(panel.items_array, panel.items_num);
2818
2820 for (bNodeTreeInterfaceItem *item : old_sockets) {
2821 if (item->item_type == NODE_INTERFACE_PANEL) {
2823 continue;
2824 }
2825 bNodeTreeInterfaceSocket *socket = reinterpret_cast<bNodeTreeInterfaceSocket *>(item);
2826 constexpr int in_and_out = NODE_INTERFACE_SOCKET_INPUT | NODE_INTERFACE_SOCKET_OUTPUT;
2827 if ((socket->flag & in_and_out) != in_and_out) {
2828 continue;
2829 }
2830
2832 new_output->item.item_type = NODE_INTERFACE_SOCKET;
2833 new_output->name = BLI_strdup_null(socket->name);
2834 new_output->description = BLI_strdup_null(socket->description);
2835 new_output->socket_type = BLI_strdup_null(socket->socket_type);
2836 new_output->flag = socket->flag & ~NODE_INTERFACE_SOCKET_INPUT;
2837 new_output->attribute_domain = socket->attribute_domain;
2838 new_output->default_input = socket->default_input;
2840 new_output->identifier = BLI_strdup(socket->identifier);
2841 if (socket->properties) {
2842 new_output->properties = IDP_CopyProperty_ex(socket->properties,
2844 }
2845 new_output->structure_type = socket->structure_type;
2846 new_sockets.append(reinterpret_cast<bNodeTreeInterfaceItem *>(new_output));
2847
2849 }
2850
2851 if (new_sockets.is_empty()) {
2852 return;
2853 }
2854
2855 new_sockets.extend(old_sockets);
2856 VectorData new_socket_data = new_sockets.release();
2857 MEM_freeN(panel.items_array);
2858 panel.items_array = new_socket_data.data;
2859 panel.items_num = new_socket_data.size;
2860}
2861
2870
2872{
2873 using namespace blender;
2874 Map<bNodeSocket *, bNode *> socket_to_node;
2875 LISTBASE_FOREACH (bNode *, node, &node_tree.nodes) {
2876 LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
2877 socket_to_node.add(socket, node);
2878 }
2879 LISTBASE_FOREACH (bNodeSocket *, socket, &node->outputs) {
2880 socket_to_node.add(socket, node);
2881 }
2882 }
2883 LISTBASE_FOREACH (bNodeLink *, link, &node_tree.links) {
2884 bool fixed = false;
2885 bNode *to_node = socket_to_node.lookup(link->tosock);
2886 if (to_node != link->tonode) {
2887 link->tonode = to_node;
2888 fixed = true;
2889 }
2890 bNode *from_node = socket_to_node.lookup(link->fromsock);
2891 if (from_node != link->fromnode) {
2892 link->fromnode = from_node;
2893 fixed = true;
2894 }
2895 if (fixed) {
2898 "Repairing invalid state in node link from %s:%s to %s:%s",
2899 link->fromnode->name,
2900 link->fromsock->identifier,
2901 link->tonode->name,
2902 link->tosock->identifier);
2903 }
2904 }
2905}
2906
2908{
2909 Editing *ed = scene.ed;
2910 if (!ed) {
2911 return;
2912 }
2913 const MetaStack *last_meta_stack = blender::seq::meta_stack_active_get(ed);
2914 if (!last_meta_stack) {
2915 return;
2916 }
2917 ed->current_meta_strip = last_meta_stack->parent_strip;
2918 blender::seq::meta_stack_set(&scene, last_meta_stack->parent_strip);
2919}
2920
2922{
2923 /* Move cycles properties natively into subdivision surface modifier. */
2924 bool experimental_features = false;
2925 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
2926 IDProperty *idprop = version_cycles_properties_from_ID(&scene->id);
2927 if (idprop) {
2928 experimental_features |= version_cycles_property_boolean(idprop, "feature_set", false);
2929 }
2930 }
2931
2932 LISTBASE_FOREACH (Object *, object, &bmain->objects) {
2933 bool use_adaptive_subdivision = false;
2934 float dicing_rate = 1.0f;
2935
2936 IDProperty *idprop = version_cycles_properties_from_ID(&object->id);
2937 if (idprop) {
2938 if (experimental_features) {
2939 use_adaptive_subdivision = version_cycles_property_boolean(
2940 idprop, "use_adaptive_subdivision", false);
2941 }
2942 dicing_rate = version_cycles_property_float(idprop, "dicing_rate", 1.0f);
2943 }
2944
2945 LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
2946 if (md->type == eModifierType_Subsurf) {
2949 smd->adaptive_pixel_size = dicing_rate;
2950 smd->adaptive_object_edge_length = 0.01f;
2951
2952 if (use_adaptive_subdivision) {
2954 }
2955 }
2956 }
2957 }
2958}
2959
2961{
2962 using namespace blender::bke;
2963
2964 LISTBASE_FOREACH_BACKWARD_MUTABLE (bNode *, node, &node_tree->nodes) {
2965 if (node->type_legacy != SH_NODE_TEX_GRADIENT) {
2966 continue;
2967 }
2968 auto *data = static_cast<NodeTexGradient *>(node->storage);
2970 /* Nothing to do. No changes for other gradient types. */
2971 continue;
2972 }
2973
2974 bNodeSocket *factor_output = node_find_socket(*node, SOCK_OUT, "Fac");
2975 bNodeSocket *color_output = node_find_socket(*node, SOCK_OUT, "Color");
2976 bNodeSocket *vector_input = node_find_socket(*node, SOCK_IN, "Vector");
2977
2978 bool is_factor_output_linked = false;
2979 bool is_color_output_linked = false;
2980 bNodeLink *vector_input_link = nullptr;
2981
2982 LISTBASE_FOREACH (bNodeLink *, link, &node_tree->links) {
2983 if (link->fromsock == factor_output) {
2984 is_factor_output_linked = true;
2985 }
2986 else if (link->fromsock == color_output) {
2987 is_color_output_linked = true;
2988 }
2989 else if (link->tosock == vector_input) {
2990 vector_input_link = link;
2991 }
2992 }
2993
2994 if (!is_factor_output_linked && !is_color_output_linked) {
2995 /* Node is not linked, nothing to do. */
2996 continue;
2997 }
2998
2999 bNode *gradient_node = nullptr;
3000 bNodeSocket *gradient_socket = nullptr;
3001
3002 bNode &separate = version_node_add_empty(*node_tree, "ShaderNodeSeparateXYZ");
3003 bNodeSocket &separate_input = version_node_add_socket(
3004 *node_tree, separate, SOCK_IN, "NodeSocketVector", "Vector");
3005 bNodeSocket &separate_x_output = version_node_add_socket(
3006 *node_tree, separate, SOCK_OUT, "NodeSocketFloat", "X");
3007 bNodeSocket &separate_y_output = version_node_add_socket(
3008 *node_tree, separate, SOCK_OUT, "NodeSocketFloat", "Y");
3009 version_node_add_socket(*node_tree, separate, SOCK_OUT, "NodeSocketFloat", "Z");
3010
3011 copy_v2_v2(separate.location, node->location);
3012
3013 switch (data->gradient_type) {
3014 case SHD_BLEND_LINEAR: {
3015 /* Gradient = X */
3016 gradient_node = &separate;
3017 gradient_socket = &separate_x_output;
3018 break;
3019 }
3020 case SHD_BLEND_QUADRATIC: {
3021 /* Gradient = (max(X, 0))^2 */
3022 bNode &max = version_node_add_empty(*node_tree, "ShaderNodeMath");
3023 bNodeSocket &max_input_a = version_node_add_socket(
3024 *node_tree, max, SOCK_IN, "NodeSocketFloat", "Value");
3025 bNodeSocket &max_input_b = version_node_add_socket(
3026 *node_tree, max, SOCK_IN, "NodeSocketFloat", "Value_001");
3027 version_node_add_socket(*node_tree, max, SOCK_IN, "NodeSocketFloat", "Value_002");
3028
3030 *node_tree, max, SOCK_OUT, "NodeSocketFloat", "Value");
3031
3032 max.location[0] = separate.location[0] + 20.0f;
3033 max.location[1] = separate.location[1];
3034
3035 max.custom1 = NODE_MATH_MAXIMUM;
3036
3037 version_node_add_link(*node_tree, separate, separate_x_output, max, max_input_a);
3038 max_input_b.default_value_typed<bNodeSocketValueFloat>()->value = 0.0f;
3039
3040 bNode &multiply = version_node_add_empty(*node_tree, "ShaderNodeMath");
3041
3042 bNodeSocket &multiply_input_a = version_node_add_socket(
3043 *node_tree, multiply, SOCK_IN, "NodeSocketFloat", "Value");
3044 bNodeSocket &multiply_input_b = version_node_add_socket(
3045 *node_tree, multiply, SOCK_IN, "NodeSocketFloat", "Value_001");
3046 version_node_add_socket(*node_tree, multiply, SOCK_IN, "NodeSocketFloat", "Value_002");
3047
3048 bNodeSocket &multiply_output = version_node_add_socket(
3049 *node_tree, multiply, SOCK_OUT, "NodeSocketFloat", "Value");
3050
3051 multiply.location[0] = max.location[0] + 20.0f;
3052 multiply.location[1] = max.location[1];
3053 multiply.custom1 = NODE_MATH_MULTIPLY;
3054
3055 version_node_add_link(*node_tree, max, max_output, multiply, multiply_input_a);
3056 version_node_add_link(*node_tree, max, max_output, multiply, multiply_input_b);
3057
3058 gradient_node = &multiply;
3059 gradient_socket = &multiply_output;
3060 break;
3061 }
3062 case SHD_BLEND_DIAGONAL: {
3063 /* Gradient = (X + Y) * 0.5. */
3064 bNode &add = version_node_add_empty(*node_tree, "ShaderNodeMath");
3065 bNodeSocket &add_input_a = version_node_add_socket(
3066 *node_tree, add, SOCK_IN, "NodeSocketFloat", "Value");
3067 bNodeSocket &add_input_b = version_node_add_socket(
3068 *node_tree, add, SOCK_IN, "NodeSocketFloat", "Value_001");
3069 version_node_add_socket(*node_tree, add, SOCK_IN, "NodeSocketFloat", "Value_002");
3070
3072 *node_tree, add, SOCK_OUT, "NodeSocketFloat", "Value");
3073
3074 add.location[0] = separate.location[0] + 20.0f;
3075 add.location[1] = separate.location[1];
3076 add.custom1 = NODE_MATH_ADD;
3077
3078 version_node_add_link(*node_tree, separate, separate_x_output, add, add_input_a);
3079 version_node_add_link(*node_tree, separate, separate_y_output, add, add_input_b);
3080
3081 bNode &multiply = version_node_add_empty(*node_tree, "ShaderNodeMath");
3082 bNodeSocket &multiply_input_a = version_node_add_socket(
3083 *node_tree, multiply, SOCK_IN, "NodeSocketFloat", "Value");
3084 bNodeSocket &multiply_input_b = version_node_add_socket(
3085 *node_tree, multiply, SOCK_IN, "NodeSocketFloat", "Value_001");
3086 version_node_add_socket(*node_tree, multiply, SOCK_IN, "NodeSocketFloat", "Value_002");
3087
3088 bNodeSocket &multiply_output = version_node_add_socket(
3089 *node_tree, multiply, SOCK_OUT, "NodeSocketFloat", "Value");
3090
3091 copy_v2_v2(multiply.location, node->location);
3092 multiply.location[0] = add.location[0] + 20.0f;
3093 multiply.location[1] = add.location[1];
3094
3095 multiply.custom1 = NODE_MATH_MULTIPLY;
3096
3097 version_node_add_link(*node_tree, add, add_output, multiply, multiply_input_a);
3098
3099 static_cast<bNodeSocketValueFloat *>(multiply_input_b.default_value)->value = 0.5f;
3100
3101 gradient_node = &multiply;
3102 gradient_socket = &multiply_output;
3103 break;
3104 }
3105 }
3106
3107 if (is_factor_output_linked) {
3108 /* Output socket can be connected to multiple nodes, so consider all links. */
3109 LISTBASE_FOREACH_BACKWARD_MUTABLE (bNodeLink *, link, &node_tree->links) {
3110 if (link->fromsock == factor_output) {
3112 *node_tree, *gradient_node, *gradient_socket, *link->tonode, *link->tosock);
3113 node_remove_link(node_tree, *link);
3114 }
3115 }
3116 }
3117
3118 if (is_color_output_linked) {
3119 bNode &combine = version_node_add_empty(*node_tree, "FunctionNodeCombineColor");
3120 bNodeSocket &combine_red = version_node_add_socket(
3121 *node_tree, combine, SOCK_IN, "NodeSocketFloat", "Red");
3122 bNodeSocket &combine_green = version_node_add_socket(
3123 *node_tree, combine, SOCK_IN, "NodeSocketFloat", "Green");
3124 bNodeSocket &combine_blue = version_node_add_socket(
3125 *node_tree, combine, SOCK_IN, "NodeSocketFloat", "Blue");
3126 bNodeSocket &combine_alpha = version_node_add_socket(
3127 *node_tree, combine, SOCK_IN, "NodeSocketFloat", "Alpha");
3128
3129 bNodeSocket &combine_output = version_node_add_socket(
3130 *node_tree, combine, SOCK_OUT, "NodeSocketColor", "Color");
3131
3133 storage->mode = NODE_COMBSEP_COLOR_RGB;
3134 combine.storage = storage;
3135
3136 combine.location[0] = gradient_node->location[0] + 20.0f;
3137 combine.location[1] = gradient_node->location[1];
3138
3139 version_node_add_link(*node_tree, *gradient_node, *gradient_socket, combine, combine_red);
3140 version_node_add_link(*node_tree, *gradient_node, *gradient_socket, combine, combine_green);
3141 version_node_add_link(*node_tree, *gradient_node, *gradient_socket, combine, combine_blue);
3142
3143 static_cast<bNodeSocketValueFloat *>(combine_alpha.default_value)->value = 1.0f;
3144
3145 LISTBASE_FOREACH_BACKWARD_MUTABLE (bNodeLink *, link, &node_tree->links) {
3146 if (link->fromsock == color_output) {
3147 version_node_add_link(*node_tree, combine, combine_output, *link->tonode, *link->tosock);
3148 node_remove_link(node_tree, *link);
3149 }
3150 }
3151
3152 gradient_node = &combine;
3153 gradient_socket = &combine_output;
3154 }
3155
3156 if (vector_input_link) {
3157 version_node_add_link(*node_tree,
3158 *vector_input_link->fromnode,
3159 *vector_input_link->fromsock,
3160 separate,
3161 separate_input);
3162 node_remove_link(node_tree, *vector_input_link);
3163 }
3164 else {
3165 /* Gradient texture's input in geometry nodes defaults to using Input Positon if it's not
3166 * connected. */
3167 bNode &position = version_node_add_empty(*node_tree, "GeometryNodeInputPosition");
3168 bNodeSocket &position_output = version_node_add_socket(
3169 *node_tree, position, SOCK_OUT, "NodeSocketVector", "Position");
3170 position.location[0] = separate.location[0] - 20.0f;
3171 position.location[1] = separate.location[1] - 20.0f;
3172
3173 version_node_add_link(*node_tree, position, position_output, separate, separate_input);
3174 }
3175
3176 node_tree_set_type(*node_tree);
3177 version_node_remove(*node_tree, *node);
3178 }
3179}
3180
3181void blo_do_versions_500(FileData *fd, Library * /*lib*/, Main *bmain)
3182{
3183 using namespace blender;
3184 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 1)) {
3185 LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) {
3189 }
3190
3191 update_brush_sizes(*bmain);
3192 }
3193
3194 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 2)) {
3195 LISTBASE_FOREACH (PointCloud *, pointcloud, &bmain->pointclouds) {
3197 }
3198 }
3199
3200 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 3)) {
3201 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
3202 if (ntree->type == NTREE_GEOMETRY) {
3204 }
3205 }
3207 }
3208
3209 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 7)) {
3210 const int uv_select_island = 1 << 3;
3211 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
3212 ToolSettings *ts = scene->toolsettings;
3213 if (ts->uv_selectmode & uv_select_island) {
3216 }
3217 }
3218 }
3219
3220 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 8)) {
3221 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
3222 if (ntree->type != NTREE_COMPOSIT) {
3223 continue;
3224 }
3225 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
3226 if (node->type_legacy != CMP_NODE_DISPLACE) {
3227 continue;
3228 }
3229 if (node->storage != nullptr) {
3230 continue;
3231 }
3234 node->storage = data;
3235 }
3236 }
3238 }
3239
3240 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 10)) {
3241 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
3242 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
3243 view_layer->eevee.ambient_occlusion_distance = scene->eevee.gtao_distance;
3244 }
3245 }
3246 }
3247
3248 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 13)) {
3249 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
3250 if (ntree->type == NTREE_COMPOSIT) {
3251 version_node_socket_name(ntree, CMP_NODE_VIEW_LEVELS, "Std Dev", "Standard Deviation");
3252 }
3253 }
3255 }
3256
3257 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 14)) {
3258 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
3260 }
3262 }
3263
3264 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 15)) {
3265 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
3266 if (ntree->type == NTREE_COMPOSIT) {
3267 version_node_socket_name(ntree, CMP_NODE_ROTATE, "Degr", "Angle");
3268 }
3269 }
3271 }
3272
3273 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 17)) {
3274 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
3276 }
3277 }
3278
3279 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 20)) {
3280 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
3281 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
3282 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
3283 if (!ELEM(sl->spacetype, SPACE_ACTION, SPACE_GRAPH, SPACE_NLA, SPACE_SEQ)) {
3284 continue;
3285 }
3286 ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
3287 &sl->regionbase;
3289 regionbase, RGN_TYPE_FOOTER, "footer for animation editors", RGN_TYPE_HEADER);
3290 if (new_footer == nullptr) {
3291 continue;
3292 }
3293
3294 new_footer->alignment = (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_TOP :
3296 if (ELEM(sl->spacetype, SPACE_GRAPH, SPACE_NLA)) {
3297 new_footer->flag |= RGN_FLAG_HIDDEN;
3298 }
3299 }
3300 }
3301 }
3302 }
3303
3304 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 21)) {
3305 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
3306 if (node_tree->type == NTREE_COMPOSIT) {
3307 LISTBASE_FOREACH_MUTABLE (bNode *, node, &node_tree->nodes) {
3308 if (node->type_legacy == CMP_NODE_NORMAL) {
3309 do_version_normal_node_dot_product(node_tree, node);
3310 }
3311 }
3312 }
3313 }
3315 }
3316
3317 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 25)) {
3319 }
3320
3321 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 26)) {
3322 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
3324 }
3325 }
3326
3327 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 27)) {
3328 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
3329 if (ntree->type == NTREE_COMPOSIT) {
3331 }
3332 }
3334 }
3335
3336 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 28)) {
3337 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
3338 if (node_tree->type == NTREE_COMPOSIT) {
3339 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
3340 if (node->type_legacy == CMP_NODE_SPLIT) {
3341 do_version_split_node_rotation(node_tree, node);
3342 }
3343 }
3344 }
3345 }
3347 }
3348
3349 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 30)) {
3350 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
3351 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
3352 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
3353 if (sl->spacetype != SPACE_FILE) {
3354 continue;
3355 }
3356 SpaceFile *sfile = reinterpret_cast<SpaceFile *>(sl);
3357 if (sfile->browse_mode != FILE_BROWSE_MODE_ASSETS) {
3358 continue;
3359 }
3361 }
3362 }
3363 }
3364 }
3365
3366 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 32)) {
3367 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
3368 if (ntree->type != NTREE_COMPOSIT) {
3369 continue;
3370 }
3371 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
3372 if (node->type_legacy != CMP_NODE_TRANSLATE) {
3373 continue;
3374 }
3375 if (node->storage == nullptr) {
3376 continue;
3377 }
3378 NodeTranslateData *data = static_cast<NodeTranslateData *>(node->storage);
3379 /* Map old wrap axis to new extension mode. */
3380 switch (data->wrap_axis) {
3382 data->extension_x = CMP_NODE_EXTENSION_MODE_CLIP;
3383 data->extension_y = CMP_NODE_EXTENSION_MODE_CLIP;
3384 break;
3386 data->extension_x = CMP_NODE_EXTENSION_MODE_REPEAT;
3387 data->extension_y = CMP_NODE_EXTENSION_MODE_CLIP;
3388 break;
3390 data->extension_x = CMP_NODE_EXTENSION_MODE_CLIP;
3391 data->extension_y = CMP_NODE_EXTENSION_MODE_REPEAT;
3392 break;
3394 data->extension_x = CMP_NODE_EXTENSION_MODE_REPEAT;
3395 data->extension_y = CMP_NODE_EXTENSION_MODE_REPEAT;
3396 break;
3397 }
3398 }
3400 }
3401 }
3402
3403 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 32)) {
3404 LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) {
3405 mesh->radial_symmetry[0] = 1;
3406 mesh->radial_symmetry[1] = 1;
3407 mesh->radial_symmetry[2] = 1;
3408 }
3409 }
3410
3411 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 33)) {
3414 }
3415 LISTBASE_FOREACH (GreasePencil *, grease_pencil, &bmain->grease_pencils) {
3417 for (const int i : IndexRange(grease_pencil->drawing_array_num)) {
3418 GreasePencilDrawingBase *drawing_base = grease_pencil->drawing_array[i];
3419 if (drawing_base->type == GP_DRAWING) {
3420 GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_base);
3422 }
3423 }
3424 }
3425 }
3426
3427 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 34)) {
3428 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
3429 if (ntree->type != NTREE_COMPOSIT) {
3430 continue;
3431 }
3432 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
3433 if (node->type_legacy != CMP_NODE_SCALE) {
3434 continue;
3435 }
3436 if (node->storage == nullptr) {
3437 continue;
3438 }
3439 NodeScaleData *data = static_cast<NodeScaleData *>(node->storage);
3440 data->extension_x = CMP_NODE_EXTENSION_MODE_CLIP;
3441 data->extension_y = CMP_NODE_EXTENSION_MODE_CLIP;
3442 }
3444 }
3445 }
3446
3447 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 35)) {
3448 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
3449 if (ntree->type != NTREE_COMPOSIT) {
3450 continue;
3451 }
3452 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
3453 if (node->type_legacy != CMP_NODE_TRANSFORM) {
3454 continue;
3455 }
3456 if (node->storage != nullptr) {
3457 continue;
3458 }
3460 data->interpolation = node->custom1;
3461 data->extension_x = CMP_NODE_EXTENSION_MODE_CLIP;
3462 data->extension_y = CMP_NODE_EXTENSION_MODE_CLIP;
3463 node->storage = data;
3464 }
3466 }
3467 }
3468
3469 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 36)) {
3470 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
3471 if (ntree->type == NTREE_COMPOSIT) {
3473 version_node_input_socket_name(ntree, CMP_NODE_ZCOMBINE, "Image_001", "B");
3474
3475 version_node_input_socket_name(ntree, CMP_NODE_ZCOMBINE, "Z", "Depth A");
3476 version_node_input_socket_name(ntree, CMP_NODE_ZCOMBINE, "Z_001", "Depth B");
3477
3478 version_node_output_socket_name(ntree, CMP_NODE_ZCOMBINE, "Image", "Result");
3480 }
3481 }
3483 }
3484
3485 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 38)) {
3486 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
3487 if (node_tree->type == NTREE_GEOMETRY) {
3488 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
3489 if (node->type_legacy == GEO_NODE_TRANSFORM_GEOMETRY) {
3491 }
3492 else if (node->type_legacy == GEO_NODE_POINTS_TO_VOLUME) {
3494 }
3495 else if (node->type_legacy == GEO_NODE_TRIANGULATE) {
3497 }
3498 else if (node->type_legacy == GEO_NODE_VOLUME_TO_MESH) {
3500 }
3501 else if (STREQ(node->idname, "FunctionNodeMatchString")) {
3503 }
3504 }
3505 }
3506 }
3508 }
3509
3510 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 39)) {
3511 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
3512 Editing *ed = seq::editing_get(scene);
3513
3514 if (ed != nullptr) {
3515 seq::foreach_strip(&ed->seqbase, [](Strip *strip) -> bool {
3516 LISTBASE_FOREACH (StripModifierData *, smd, &strip->modifiers) {
3517 seq::modifier_persistent_uid_init(*strip, *smd);
3518 }
3519 return true;
3520 });
3521 }
3522 }
3523 }
3524
3525 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 40)) {
3526 LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
3527 if (brush->gpencil_settings) {
3529 }
3530 }
3531 }
3532
3533 /* ImageFormatData gained a new media type which we need to be set according to the
3534 * existing imtype. */
3535 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 42)) {
3536 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
3537 update_format_media_type(&scene->r.im_format);
3538 }
3539
3540 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
3541 if (node_tree->type != NTREE_COMPOSIT) {
3542 continue;
3543 }
3544
3545 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
3546 if (node->type_legacy != CMP_NODE_OUTPUT_FILE) {
3547 continue;
3548 }
3549
3550 NodeCompositorFileOutput *storage = static_cast<NodeCompositorFileOutput *>(node->storage);
3552
3553 LISTBASE_FOREACH (bNodeSocket *, input, &node->inputs) {
3554 NodeImageMultiFileSocket *input_storage = static_cast<NodeImageMultiFileSocket *>(
3555 input->storage);
3556 update_format_media_type(&input_storage->format);
3557 }
3558 }
3559 }
3561 }
3562
3563 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 43)) {
3564 LISTBASE_FOREACH (World *, world, &bmain->worlds) {
3566 }
3567 }
3568
3569 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 45)) {
3570 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
3571 if (node_tree->type == NTREE_GEOMETRY) {
3572 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
3573 if (node->type_legacy == GEO_NODE_FILL_CURVE) {
3574 do_version_fill_curve_options_to_inputs(*node_tree, *node);
3575 }
3576 else if (node->type_legacy == GEO_NODE_FILLET_CURVE) {
3578 }
3579 else if (node->type_legacy == GEO_NODE_RESAMPLE_CURVE) {
3581 }
3582 else if (node->type_legacy == GEO_NODE_DISTRIBUTE_POINTS_IN_VOLUME) {
3584 }
3585 else if (node->type_legacy == GEO_NODE_MERGE_BY_DISTANCE) {
3587 }
3588 else if (node->type_legacy == GEO_NODE_MESH_TO_VOLUME) {
3590 }
3591 else if (node->type_legacy == GEO_NODE_RAYCAST) {
3592 do_version_raycast_options_to_inputs(*node_tree, *node);
3593 }
3594 else if (node->type_legacy == GEO_NODE_REMOVE_ATTRIBUTE) {
3596 }
3597 else if (node->type_legacy == GEO_NODE_SAMPLE_GRID) {
3599 }
3600 else if (node->type_legacy == GEO_NODE_SCALE_ELEMENTS) {
3602 }
3603 else if (node->type_legacy == GEO_NODE_SET_CURVE_NORMAL) {
3605 }
3606 else if (node->type_legacy == GEO_NODE_SUBDIVISION_SURFACE) {
3608 }
3609 else if (node->type_legacy == GEO_NODE_UV_PACK_ISLANDS) {
3611 }
3612 else if (node->type_legacy == GEO_NODE_UV_UNWRAP) {
3613 do_version_uv_unwrap_options_to_inputs(*node_tree, *node);
3614 }
3615 }
3616 }
3617 }
3619 }
3620
3621 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 46)) {
3622 /* Versioning from 0a0dd4ca37 was wrong, it only created asset shelf regions for Node Editors
3623 * that are Compositors. If you change a non-Node Editor (e.g. an Image Editor) to a Compositor
3624 * Editor, all is fine (SpaceLink *node_create gets called, the regions set up correctly), but
3625 * changing an existing Node Editor (e.g. Shader or Geometry Nodes) to a Compositor, no new
3626 * Space gets set up (rightfully so) and we are then missing the regions. Now corrected below
3627 * (version bump in 5.1 since that is also affected). */
3628 }
3629
3630 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 48)) {
3631 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
3632 if (ntree->type != NTREE_COMPOSIT) {
3633 continue;
3634 }
3635 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
3636 if (node->type_legacy != CMP_NODE_ROTATE) {
3637 continue;
3638 }
3639 if (node->storage != nullptr) {
3640 continue;
3641 }
3643 data->interpolation = node->custom1;
3644 data->extension_x = CMP_NODE_EXTENSION_MODE_CLIP;
3645 data->extension_y = CMP_NODE_EXTENSION_MODE_CLIP;
3646 node->storage = data;
3647 }
3649 }
3650 }
3651
3652 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 49)) {
3653 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
3654 if (ntree->type != NTREE_COMPOSIT) {
3655 continue;
3656 }
3657 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
3658 if (node->type_legacy != CMP_NODE_DISPLACE) {
3659 continue;
3660 }
3661 if (node->storage == nullptr) {
3662 continue;
3663 }
3664 NodeDisplaceData *data = static_cast<NodeDisplaceData *>(node->storage);
3665 data->extension_x = CMP_NODE_EXTENSION_MODE_CLIP;
3666 data->extension_y = CMP_NODE_EXTENSION_MODE_CLIP;
3667 }
3669 }
3670 }
3671
3672 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 50)) {
3673 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
3674 if (ntree->type != NTREE_COMPOSIT) {
3675 continue;
3676 }
3677 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
3678 if (node->type_legacy != CMP_NODE_MAP_UV) {
3679 continue;
3680 }
3681 if (node->storage != nullptr) {
3682 continue;
3683 }
3685 data->interpolation = node->custom2;
3686 data->extension_x = CMP_NODE_EXTENSION_MODE_CLIP;
3687 data->extension_y = CMP_NODE_EXTENSION_MODE_CLIP;
3688 node->storage = data;
3689 }
3691 }
3692 }
3693 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 51)) {
3694 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
3695 if (ntree->type != NTREE_COMPOSIT) {
3696 continue;
3697 }
3698 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
3699 if (node->type_legacy != CMP_NODE_CORNERPIN) {
3700 continue;
3701 }
3702 if (node->storage != nullptr) {
3703 continue;
3704 }
3706 data->interpolation = node->custom1;
3707 data->extension_x = CMP_NODE_EXTENSION_MODE_CLIP;
3708 data->extension_y = CMP_NODE_EXTENSION_MODE_CLIP;
3709 node->storage = data;
3710 }
3712 }
3713 }
3714
3715 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 54)) {
3716 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
3717 if (node_tree->type != NTREE_COMPOSIT) {
3718 continue;
3719 }
3720 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
3721 if (node->type_legacy == CMP_NODE_OUTPUT_FILE) {
3723 }
3724 }
3726 }
3727 }
3728
3729 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 58)) {
3730 LISTBASE_FOREACH (Object *, object, &bmain->objects) {
3731 LISTBASE_FOREACH (ModifierData *, modifier, &object->modifiers) {
3733 continue;
3734 }
3736 modifier);
3737 if (lmd->radius != 0.0f) {
3738 continue;
3739 }
3740 lmd->radius = float(lmd->thickness_legacy) *
3742 }
3743 }
3744 }
3745 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 61)) {
3746 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
3747 if (ntree->type != NTREE_COMPOSIT) {
3748 continue;
3749 }
3752
3753 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
3754 if (node->type_legacy == CMP_NODE_GAMMA_DEPRECATED) {
3755 node->type_legacy = SH_NODE_GAMMA;
3756 STRNCPY_UTF8(node->idname, "ShaderNodeGamma");
3757 }
3758 }
3759 }
3761 }
3762
3763 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 63)) {
3764 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
3765 if (scene->r.bake_flag & R_BAKE_MULTIRES) {
3766 scene->r.bake.type = scene->r.bake_mode;
3767 scene->r.bake.flag |= (scene->r.bake_flag & (R_BAKE_MULTIRES | R_BAKE_LORES_MESH));
3768 scene->r.bake.margin_type = scene->r.bake_margin_type;
3769 scene->r.bake.margin = scene->r.bake_margin;
3770 }
3771 else {
3772 scene->r.bake.type = R_BAKE_NORMALS;
3773 }
3774 }
3775 }
3776
3777 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 62)) {
3778 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
3779 scene->r.bake.displacement_space = R_BAKE_SPACE_OBJECT;
3780 }
3781 }
3782
3783 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 64)) {
3784 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
3786 }
3788 }
3789
3790 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 65)) {
3791 LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
3792 srgb_to_linearrgb_v3_v3(brush->color, brush->rgb);
3793 srgb_to_linearrgb_v3_v3(brush->secondary_color, brush->secondary_rgb);
3794 }
3795 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
3796 UnifiedPaintSettings &ups = scene->toolsettings->unified_paint_settings;
3797 srgb_to_linearrgb_v3_v3(ups.color, ups.rgb);
3798 srgb_to_linearrgb_v3_v3(ups.secondary_color, ups.secondary_rgb);
3799
3800 for_each_mode_paint_settings(*scene, [](Scene & /*scene*/, Paint *paint) {
3801 if (paint != nullptr) {
3802 UnifiedPaintSettings &ups = paint->unified_paint_settings;
3803 srgb_to_linearrgb_v3_v3(ups.color, ups.rgb);
3804 srgb_to_linearrgb_v3_v3(ups.secondary_color, ups.secondary_rgb);
3805 }
3806 });
3807 }
3808 LISTBASE_FOREACH (Palette *, palette, &bmain->palettes) {
3809 LISTBASE_FOREACH (PaletteColor *, color, &palette->colors) {
3810 srgb_to_linearrgb_v3_v3(color->color, color->rgb);
3811 }
3812 }
3813 }
3814
3815 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 66)) {
3816 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
3817 if (node_tree->type != NTREE_COMPOSIT) {
3818 continue;
3819 }
3820 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
3821 if (node->type_legacy == CMP_NODE_BLUR) {
3822 do_version_blur_menus_to_inputs(*node_tree, *node);
3823 }
3824 else if (node->type_legacy == CMP_NODE_FILTER) {
3825 do_version_filter_menus_to_inputs(*node_tree, *node);
3826 }
3827 else if (node->type_legacy == CMP_NODE_VIEW_LEVELS) {
3828 do_version_levels_menus_to_inputs(*node_tree, *node);
3829 }
3830 else if (node->type_legacy == CMP_NODE_DILATEERODE) {
3831 do_version_dilate_menus_to_inputs(*node_tree, *node);
3832 }
3833 else if (node->type_legacy == CMP_NODE_TONEMAP) {
3834 do_version_tone_map_menus_to_inputs(*node_tree, *node);
3835 }
3836 else if (node->type_legacy == CMP_NODE_LENSDIST) {
3838 }
3839 else if (node->type_legacy == CMP_NODE_KUWAHARA) {
3840 do_version_kuwahara_menus_to_inputs(*node_tree, *node);
3841 }
3842 else if (node->type_legacy == CMP_NODE_DENOISE) {
3843 do_version_denoise_menus_to_inputs(*node_tree, *node);
3844 }
3845 else if (node->type_legacy == CMP_NODE_TRANSLATE) {
3846 do_version_translate_menus_to_inputs(*node_tree, *node);
3847 }
3848 else if (node->type_legacy == CMP_NODE_TRANSFORM) {
3849 do_version_transform_menus_to_inputs(*node_tree, *node);
3850 }
3851 else if (node->type_legacy == CMP_NODE_CORNERPIN) {
3852 do_version_corner_pin_menus_to_inputs(*node_tree, *node);
3853 }
3854 else if (node->type_legacy == CMP_NODE_MAP_UV) {
3855 do_version_map_uv_menus_to_inputs(*node_tree, *node);
3856 }
3857 else if (node->type_legacy == CMP_NODE_SCALE) {
3858 do_version_scale_menus_to_inputs(*node_tree, *node);
3859 }
3860 else if (node->type_legacy == CMP_NODE_ROTATE) {
3861 do_version_rotate_menus_to_inputs(*node_tree, *node);
3862 }
3863 else if (node->type_legacy == CMP_NODE_DISPLACE) {
3864 do_version_displace_menus_to_inputs(*node_tree, *node);
3865 }
3866 else if (node->type_legacy == CMP_NODE_STABILIZE2D) {
3867 do_version_stabilize_2d_menus_to_inputs(*node_tree, *node);
3868 }
3869 else if (node->type_legacy == CMP_NODE_MASK_BOX) {
3870 do_version_box_mask_menus_to_inputs(*node_tree, *node);
3871 }
3872 else if (node->type_legacy == CMP_NODE_MASK_ELLIPSE) {
3873 do_version_ellipse_mask_menus_to_inputs(*node_tree, *node);
3874 }
3875 else if (node->type_legacy == CMP_NODE_TRACKPOS) {
3877 }
3878 else if (node->type_legacy == CMP_NODE_KEYING) {
3879 do_version_keying_menus_to_inputs(*node_tree, *node);
3880 }
3881 else if (node->type_legacy == CMP_NODE_MASK) {
3882 do_version_mask_menus_to_inputs(*node_tree, *node);
3883 }
3884 else if (node->type_legacy == CMP_NODE_MOVIEDISTORTION) {
3886 }
3887 else if (node->type_legacy == CMP_NODE_GLARE) {
3888 do_version_glare_menus_to_inputs(*node_tree, *node);
3889 }
3890 }
3891 }
3893 }
3894
3895 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 67)) {
3896 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
3898 }
3900 }
3901
3902 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 68)) {
3903 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
3905 }
3906 }
3907
3908 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 71)) {
3909 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
3910 scene->toolsettings->uvsculpt.size *= 2;
3911 }
3912 }
3913
3914 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 72)) {
3915 LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
3916 if (brush->curve_size == nullptr) {
3917 brush->curve_size = BKE_paint_default_curve();
3918 }
3919 if (brush->curve_strength == nullptr) {
3920 brush->curve_strength = BKE_paint_default_curve();
3921 }
3922 if (brush->curve_jitter == nullptr) {
3923 brush->curve_jitter = BKE_paint_default_curve();
3924 }
3925 }
3926 }
3927
3928 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 73)) {
3929 /* Old files created on WIN32 use `\r`. */
3930 LISTBASE_FOREACH (Curve *, cu, &bmain->curves) {
3931 if (cu->str) {
3932 BLI_string_replace_char(cu->str, '\r', '\n');
3933 }
3934 }
3935 }
3936
3937 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 74)) {
3938 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
3939 if (scene->ed != nullptr) {
3940 /* Set the first strip modifier as the active one and uncollapse the root panel. */
3941 blender::seq::foreach_strip(&scene->ed->seqbase, [&](Strip *strip) -> bool {
3942 seq::modifier_set_active(strip,
3943 static_cast<StripModifierData *>(strip->modifiers.first));
3944 LISTBASE_FOREACH (StripModifierData *, smd, &strip->modifiers) {
3945 smd->layout_panel_open_flag |= UI_PANEL_DATA_EXPAND_ROOT;
3946 }
3947 return true;
3948 });
3949 }
3950 }
3951 }
3952
3953 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 75)) {
3954 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
3955 if (ntree->type == NTREE_COMPOSIT) {
3956 version_node_socket_name(ntree, CMP_NODE_RGB, "RGBA", "Color");
3957 }
3958 }
3960 }
3961
3962 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 81)) {
3963 LISTBASE_FOREACH (Material *, material, &bmain->materials) {
3964 do_version_material_remove_use_nodes(bmain, material);
3965 }
3966 }
3967
3968 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 82)) {
3969 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
3970 if (node_tree->type != NTREE_COMPOSIT) {
3971 continue;
3972 }
3973 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
3974 if (node->type_legacy == CMP_NODE_SETALPHA) {
3975 do_version_set_alpha_menus_to_inputs(*node_tree, *node);
3976 }
3977 else if (node->type_legacy == CMP_NODE_CHANNEL_MATTE) {
3979 }
3980 else if (node->type_legacy == CMP_NODE_COLORBALANCE) {
3982 }
3983 else if (node->type_legacy == CMP_NODE_PREMULKEY) {
3985 }
3986 else if (node->type_legacy == CMP_NODE_DIST_MATTE) {
3988 }
3989 else if (node->type_legacy == CMP_NODE_COLOR_SPILL) {
3990 do_version_color_spill_menus_to_inputs(*node_tree, *node);
3991 }
3992 }
3993 }
3995 }
3996
3997 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 83)) {
3998 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
3999 if (node_tree->type != NTREE_COMPOSIT) {
4000 continue;
4001 }
4002 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4003 if (node->type_legacy == CMP_NODE_DOUBLEEDGEMASK) {
4005 }
4006 }
4007 }
4009 }
4010
4011 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 84)) {
4012 /* Add sidebar to the preferences editor. */
4013 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
4014 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
4015 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
4016 if (sl->spacetype == SPACE_USERPREF) {
4017 ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
4018 &sl->regionbase;
4020 regionbase, RGN_TYPE_UI, "sidebar for preferences", RGN_TYPE_HEADER);
4021 if (new_sidebar != nullptr) {
4022 new_sidebar->alignment = RGN_ALIGN_LEFT;
4023 new_sidebar->flag &= ~RGN_FLAG_HIDDEN;
4024 }
4025 }
4026 }
4027 }
4028 }
4029 }
4030
4031 if (MAIN_VERSION_FILE_ATLEAST(bmain, 500, 23) && !MAIN_VERSION_FILE_ATLEAST(bmain, 500, 85)) {
4032 /* Old sky textures were temporarily removed and restored. */
4033 /* Change default Sky Texture to Nishita (after removal of old sky models) */
4034 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
4035 if (ntree->type == NTREE_SHADER) {
4036 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
4037 if (node->type_legacy == SH_NODE_TEX_SKY && node->storage) {
4038 NodeTexSky *tex = (NodeTexSky *)node->storage;
4039 if (tex->sky_model == 0) {
4040 tex->sky_model = SHD_SKY_SINGLE_SCATTERING;
4041 }
4042 if (tex->sky_model == 1) {
4043 tex->sky_model = SHD_SKY_MULTIPLE_SCATTERING;
4044 }
4045 }
4046 }
4047 }
4048 }
4050 }
4051
4052 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 86)) {
4053 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
4054 if (ntree->type != NTREE_GEOMETRY) {
4055 continue;
4056 }
4058 }
4060 }
4061
4062 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 87)) {
4063 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4064 if (node_tree->type != NTREE_COMPOSIT) {
4065 continue;
4066 }
4067 version_node_input_socket_name(node_tree, CMP_NODE_ALPHAOVER, "Image_001", "Foreground");
4068 version_node_input_socket_name(node_tree, CMP_NODE_ALPHAOVER, "Image", "Background");
4069 }
4071 }
4072
4073 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 88)) {
4074 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4075 if (node_tree->type != NTREE_COMPOSIT) {
4076 continue;
4077 }
4078 version_node_input_socket_name(node_tree, CMP_NODE_DISPLACE, "Vector", "Displacement");
4079 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4080 if (node->type_legacy == CMP_NODE_DISPLACE) {
4082 }
4083 }
4084 }
4086 }
4087
4088 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 89)) {
4089 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4090 if (node_tree->type != NTREE_COMPOSIT) {
4091 continue;
4092 }
4093 version_node_input_socket_name(node_tree, CMP_NODE_BOKEHBLUR, "Bounding box", "Mask");
4094 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4095 if (node->type_legacy == CMP_NODE_BOKEHBLUR) {
4096 do_version_bokeh_blur_pixel_size(*node_tree, *node);
4097 }
4098 }
4099 }
4101 }
4102
4103 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 89)) {
4104 /* Node Editor: toggle overlays on. */
4105 if (!DNA_struct_exists(fd->filesdna, "SpaceClipOverlay")) {
4106 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
4107 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
4108 LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) {
4109 if (space->spacetype == SPACE_CLIP) {
4110 SpaceClip *sclip = (SpaceClip *)space;
4111 sclip->overlay.flag |= SC_SHOW_OVERLAYS;
4112 sclip->overlay.flag |= SC_SHOW_CURSOR;
4113 }
4114 }
4115 }
4116 }
4117 }
4118 }
4119
4120 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 92)) {
4122 }
4123
4124 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 95)) {
4125 LISTBASE_FOREACH (Camera *, camera, &bmain->cameras) {
4126 float default_col[4] = {0.5f, 0.5f, 0.5f, 1.0f};
4127 copy_v4_v4(camera->composition_guide_color, default_col);
4128 }
4129 }
4130
4131 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 97)) {
4132 /* Enable new "Optional Label" setting for all menu sockets. This was implicit before. */
4133 FOREACH_NODETREE_BEGIN (bmain, tree, id) {
4134 tree->tree_interface.foreach_item([&](bNodeTreeInterfaceItem &item) {
4135 if (item.item_type != NODE_INTERFACE_SOCKET) {
4136 return true;
4137 }
4138 auto &socket = reinterpret_cast<bNodeTreeInterfaceSocket &>(item);
4139 if (!STREQ(socket.socket_type, "NodeSocketMenu")) {
4140 return true;
4141 }
4143 return true;
4144 });
4145 }
4147 }
4148
4149 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 98)) {
4150 /* For a brief period of time, these values were not properly versioned, so it is possible for
4151 * files to be in an odd state. This versioning was formerly run in 4.2 subversion 23. */
4152 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
4153 UvSculpt &uvsculpt = scene->toolsettings->uvsculpt;
4154 if (uvsculpt.size == 0 || uvsculpt.curve_distance_falloff == nullptr) {
4155 uvsculpt.size = 100;
4156 uvsculpt.strength = 1.0f;
4158 if (uvsculpt.curve_distance_falloff == nullptr) {
4159 uvsculpt.curve_distance_falloff = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
4160 }
4161 }
4162 }
4163 }
4164
4165 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 99)) {
4166 LISTBASE_FOREACH (wmWindowManager *, wm, &bmain->wm) {
4167 wm->xr.session_settings.fly_speed = 3.0f;
4168 }
4169 }
4170
4171 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 102)) {
4172 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
4173 scene->r.time_jump_delta = 1.0f;
4174 scene->r.time_jump_unit = 1;
4175 }
4176 }
4177
4178 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 103)) {
4179 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4180 if (node_tree->type == NTREE_COMPOSIT) {
4181 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4182 if (node->type_legacy == CMP_NODE_COLORBALANCE) {
4184 }
4185 }
4186 }
4187 }
4189 }
4190
4191 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 104)) {
4192 /* Dope Sheet Editor: toggle overlays on. */
4193 if (!DNA_struct_exists(fd->filesdna, "SpaceActionOverlays")) {
4194 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
4195 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
4196 LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) {
4197 if (space->spacetype == SPACE_ACTION) {
4198 SpaceAction *space_action = (SpaceAction *)space;
4199 space_action->overlays.flag |= ADS_OVERLAY_SHOW_OVERLAYS;
4201 }
4202 }
4203 }
4204 }
4205 }
4206 }
4207
4208 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 105)) {
4209 LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) {
4211 }
4212 }
4213
4214 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 106)) {
4215 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4216 if (node_tree->type != NTREE_COMPOSIT) {
4217 continue;
4218 }
4220 node_tree, CMP_NODE_COLORCORRECTION, "Master Lift", "Master Offset");
4222 node_tree, CMP_NODE_COLORCORRECTION, "Highlights Lift", "Highlights Offset");
4224 node_tree, CMP_NODE_COLORCORRECTION, "Midtones Lift", "Midtones Offset");
4226 node_tree, CMP_NODE_COLORCORRECTION, "Shadows Lift", "Shadows Offset");
4227 }
4229 }
4230
4231 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 107)) {
4232 LISTBASE_FOREACH (Material *, material, &bmain->materials) {
4233 /* The flag was actually interpreted as reversed. */
4234 material->blend_flag ^= MA_BL_LIGHTPROBE_VOLUME_DOUBLE_SIDED;
4235 }
4236 }
4237
4238 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 108)) {
4239 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
4240 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
4241 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
4242 if (sl->spacetype == SPACE_IMAGE) {
4243 SpaceImage *sima = reinterpret_cast<SpaceImage *>(sl);
4245 }
4246 }
4247 }
4248 }
4249 }
4250
4251 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 109)) {
4252 LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
4253 repair_node_link_node_pointers(*fd, *ntree);
4254 }
4255 }
4256
4257 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 112)) {
4258 /* The ownership of these pointers was moved to #CustomData in #customdata_version_242 and they
4259 * became deprecated in 05952aa94d33ee when we started using implicit-sharing. However, they
4260 * were never cleared and became dangling pointers. */
4261 LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) {
4262 mesh->mpoly = nullptr;
4263 mesh->mloop = nullptr;
4264 mesh->mvert = nullptr;
4265 mesh->medge = nullptr;
4266 mesh->dvert = nullptr;
4267 mesh->mtface = nullptr;
4268 mesh->tface = nullptr;
4269 mesh->mcol = nullptr;
4270 mesh->mface = nullptr;
4271 }
4272 }
4273
4274 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 501, 2)) {
4275 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
4276 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
4277 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
4278 if (sl->spacetype != SPACE_NODE) {
4279 continue;
4280 }
4281
4282 ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
4283 &sl->regionbase;
4284
4285 if (ARegion *new_shelf_region = do_versions_add_region_if_not_found(
4286 regionbase,
4288 "Asset shelf for compositing (versioning)",
4290 {
4291 new_shelf_region->alignment = RGN_ALIGN_BOTTOM;
4292 }
4293 if (ARegion *new_shelf_header = do_versions_add_region_if_not_found(
4294 regionbase,
4296 "Asset shelf header for compositing (versioning)",
4298 {
4299 new_shelf_header->alignment = RGN_ALIGN_BOTTOM | RGN_ALIGN_HIDE_WITH_PREV;
4300 }
4301 }
4302 }
4303 }
4304 }
4305
4306 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 113)) {
4307 /* Clear mute flag on node types that set ntype->no_muting = true. */
4308 static const Set<std::string> no_muting_nodes = {"CompositorNodeViewer",
4309 "NodeClosureInput",
4310 "NodeClosureOutput",
4311 "GeometryNodeForeachGeometryElementInput",
4312 "GeometryNodeForeachGeometryElementOutput",
4313 "GeometryNodeRepeatInput",
4314 "GeometryNodeRepeatOutput",
4315 "GeometryNodeSimulationInput",
4316 "GeometryNodeSimulationOutput",
4317 "GeometryNodeViewer",
4318 "NodeGroupInput",
4319 "NodeGroupOutput",
4320 "ShaderNodeOutputAOV",
4321 "ShaderNodeOutputLight",
4322 "ShaderNodeOutputLineStyle",
4323 "ShaderNodeOutputMaterial",
4324 "ShaderNodeOutputWorld",
4325 "TextureNodeOutput",
4326 "TextureNodeViewer"};
4327 LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
4328 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
4329 if (no_muting_nodes.contains(node->idname)) {
4330 node->flag &= ~NODE_MUTED;
4331 }
4332 }
4333 }
4334 }
4335
4336 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 114)) {
4337 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
4338 if (!scene->ed) {
4339 continue;
4340 }
4341 blender::seq::foreach_strip(&scene->ed->seqbase, [&](Strip *strip) {
4342 LISTBASE_FOREACH (StripModifierData *, md, &strip->modifiers) {
4343 md->ui_expand_flag = md->layout_panel_open_flag & UI_PANEL_DATA_EXPAND_ROOT;
4344 }
4345 return true;
4346 });
4347 }
4348 }
4349
4350 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 115)) {
4351 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4352 if (ELEM(GS(id->name), ID_MA, ID_LA, ID_WO, ID_TE, ID_SCE, ID_LS)) {
4353 /* These node trees should not have interface sockets. However, in some files they were
4354 * added through the Python API. Remove these interface sockets here before they cause
4355 * problems further down the line. */
4357 }
4358 }
4360 }
4361
4362 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 117)) {
4363 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4364 if (node_tree->type == NTREE_GEOMETRY) {
4365 /* Gradient Texture node did not clamp results for the Compositor CPU and geometry nodes.
4366 * The compositor is not versioned to unify it with GPU backend. */
4368 }
4369 }
4371 }
4372
4379
4380 /* Keep this versioning always enabled at the bottom of the function; it can only be moved
4381 * behind a subversion bump when the file format is changed. */
4382 LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) {
4384 }
4385
4386 /* TODO: Can be moved to subversion bump. */
4388}
void AS_asset_library_import_method_ensure_valid(Main &bmain)
AnimData * BKE_animdata_ensure_id(ID *id)
Definition anim_data.cc:97
AnimData * BKE_animdata_from_id(const ID *id)
Definition anim_data.cc:83
void BKE_animdata_fix_paths_rename_all_ex(struct Main *bmain, struct ID *ref_id, const char *prefix, const char *oldName, const char *newName, int oldSubscript, int newSubscript, bool verify_paths)
void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm, bool do_id_user)
void BKE_curvemapping_free_data(CurveMapping *cumap)
CurveMapping * BKE_curvemapping_copy(const CurveMapping *cumap)
CurveMapping * BKE_curvemapping_add(int tot, float minx, float miny, float maxx, float maxy)
Definition colortools.cc:89
void BKE_curvemapping_copy_data(CurveMapping *target, const CurveMapping *cumap)
Low-level operations for curves.
FCurve * BKE_fcurve_copy(const FCurve *fcu)
void BKE_fcurve_free(FCurve *fcu)
Low-level operations for grease pencil.
IDProperty * IDP_CopyProperty_ex(const IDProperty *prop, int flag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:845
void BKE_image_format_free(ImageFormatData *imf)
bool BKE_imtype_is_image(char imtype)
bool BKE_imtype_is_multi_layer_image(char imtype)
bool BKE_imtype_is_movie(char imtype)
void BKE_image_format_copy(ImageFormatData *imf_dst, const ImageFormatData *imf_src)
@ LIB_ID_CREATE_NO_USER_REFCOUNT
#define FOREACH_MAIN_ID_END
Definition BKE_main.hh:583
#define MAIN_VERSION_FILE_ATLEAST(main, ver, subver)
Definition BKE_main.hh:658
#define FOREACH_MAIN_ID_BEGIN(_bmain, _id)
Definition BKE_main.hh:577
#define FOREACH_NODETREE_END
Definition BKE_node.hh:881
#define FOREACH_NODETREE_BEGIN(bmain, _nodetree, _id)
Definition BKE_node.hh:871
#define NODE_FRAME
Definition BKE_node.hh:812
#define GEO_NODE_MERGE_BY_DISTANCE
#define GEO_NODE_TRIANGULATE
#define CMP_NODE_PREMULKEY
#define CMP_NODE_DENOISE
#define SH_NODE_COMBINE_COLOR
#define NODE_EVALUATE_CLOSURE
#define CMP_NODE_MASK
#define CMP_NODE_SCALE
#define GEO_NODE_SUBDIVISION_SURFACE
#define SH_NODE_TEX_GRADIENT
#define SH_NODE_COMBRGB_LEGACY
#define CMP_NODE_MATH_DEPRECATED
#define CMP_NODE_SEPHSVA_LEGACY
#define CMP_NODE_VALUE_DEPRECATED
#define CMP_NODE_COLOR_SPILL
#define SH_NODE_COMBXYZ
#define CMP_NODE_CORNERPIN
#define GEO_NODE_MESH_TO_VOLUME
#define CMP_NODE_MASK_ELLIPSE
#define CMP_NODE_DISPLACE
#define CMP_NODE_COMBYCCA_LEGACY
#define SH_NODE_BSDF_PRINCIPLED
#define CMP_NODE_SEPRGBA_LEGACY
#define CMP_NODE_SEPARATE_COLOR
#define CMP_NODE_TRANSLATE
#define GEO_NODE_VIEWER
#define GEO_NODE_UV_PACK_ISLANDS
#define CMP_NODE_MOVIEDISTORTION
#define CMP_NODE_TONEMAP
#define SH_NODE_SEPARATE_COLOR
#define CMP_NODE_MAP_RANGE_DEPRECATED
#define CMP_NODE_COLORBALANCE
#define SH_NODE_MAP_RANGE
#define GEO_NODE_REMOVE_ATTRIBUTE
#define TEX_NODE_DECOMPOSE_LEGACY
#define GEO_NODE_UV_UNWRAP
#define SH_NODE_SEPRGB_LEGACY
#define CMP_NODE_COMBYUVA_LEGACY
#define CMP_NODE_ROTATE
#define CMP_NODE_KUWAHARA
#define CMP_NODE_FILTER
#define SH_NODE_VALUE
#define SH_NODE_CURVE_VEC
#define CMP_NODE_ALPHAOVER
#define CMP_NODE_MAP_VALUE_DEPRECATED
#define CMP_NODE_SEPYUVA_LEGACY
#define TEX_NODE_COMBINE_COLOR
#define SH_NODE_MATH
#define CMP_NODE_COMBHSVA_LEGACY
#define GEO_NODE_TRANSFORM_GEOMETRY
#define CMP_NODE_COMBINE_XYZ_DEPRECATED
#define FN_NODE_COMBINE_COLOR
#define CMP_NODE_GLARE
#define SH_NODE_SEPXYZ
#define GEO_NODE_RAYCAST
#define TEX_NODE_SEPARATE_COLOR
#define CMP_NODE_TRANSFORM
#define CMP_NODE_DILATEERODE
#define CMP_NODE_SPLIT
#define SH_NODE_BSDF_DIFFUSE
#define SH_NODE_GAMMA
#define CMP_NODE_BOKEHBLUR
#define SH_NODE_SEPHSV_LEGACY
#define TEX_NODE_COMPOSE_LEGACY
#define CMP_NODE_LENSDIST
#define GEO_NODE_SAMPLE_GRID
#define GEO_NODE_FILLET_CURVE
#define CMP_NODE_ZCOMBINE
#define NODE_CLOSURE_OUTPUT
#define CMP_NODE_MAP_UV
#define SH_NODE_TEX_SKY
#define CMP_NODE_TRACKPOS
#define CMP_NODE_SUNBEAMS_DEPRECATED
#define CMP_NODE_MIX_RGB_DEPRECATED
#define CMP_NODE_OUTPUT_FILE
#define CMP_NODE_COLORCORRECTION
#define CMP_NODE_SETALPHA
#define CMP_NODE_DOUBLEEDGEMASK
#define CMP_NODE_GAMMA_DEPRECATED
#define GEO_NODE_RESAMPLE_CURVE
#define CMP_NODE_VALTORGB_DEPRECATED
#define CMP_NODE_STABILIZE2D
#define SH_NODE_MIX
#define CMP_NODE_COMBINE_COLOR
#define SH_NODE_VALTORGB
#define GEO_NODE_SCALE_ELEMENTS
#define NODE_COMBINE_BUNDLE
#define CMP_NODE_COMBRGBA_LEGACY
#define CMP_NODE_COMPOSITE_DEPRECATED
#define CMP_NODE_RGB
#define CMP_NODE_MASK_BOX
#define FN_NODE_SEPARATE_COLOR
#define GEO_NODE_FILL_CURVE
#define CMP_NODE_KEYING
#define GEO_NODE_POINTS_TO_VOLUME
#define CMP_NODE_SEPYCCA_LEGACY
#define GEO_NODE_DISTRIBUTE_POINTS_IN_VOLUME
#define CMP_NODE_DIST_MATTE
#define NODE_SEPARATE_BUNDLE
#define NODE_CLOSURE_INPUT
#define CMP_NODE_SEPARATE_XYZ_DEPRECATED
#define CMP_NODE_NORMAL
#define CMP_NODE_VIEW_LEVELS
#define SH_NODE_COMBHSV_LEGACY
#define CMP_NODE_CURVE_VEC_DEPRECATED
#define CMP_NODE_BLUR
#define GEO_NODE_VOLUME_TO_MESH
#define GEO_NODE_SET_CURVE_NORMAL
#define CMP_NODE_CHANNEL_MATTE
CurveMapping * BKE_paint_default_curve()
Definition scene.cc:146
#define PTCACHE_TYPE_SMOKE_HIGHRES
void BKE_ptcache_ids_from_object(struct ListBase *lb, struct Object *ob, struct Scene *scene, int duplis)
#define PTCACHE_TYPE_CLOTH
#define PTCACHE_TYPE_DYNAMICPAINT
#define PTCACHE_TYPE_PARTICLES
#define PTCACHE_TYPE_SOFTBODY
#define PTCACHE_TYPE_SMOKE_DOMAIN
#define PTCACHE_TYPE_RIGIDBODY
@ RPT_WARNING
Definition BKE_report.hh:38
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#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)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:497
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
#define LISTBASE_FOREACH_BACKWARD_MUTABLE(type, var, list)
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:131
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:524
void srgb_to_linearrgb_v3_v3(float linear[3], const float srgb[3])
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE bool is_zero_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
#define FILE_MAX
void BLI_path_split_dir_file(const char *filepath, char *dir, size_t dir_maxncpy, char *file, size_t file_maxncpy) ATTR_NONNULL(1
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
Definition string.cc:41
bool BLI_str_quoted_substr_range(const char *__restrict str, const char *__restrict prefix, int *__restrict r_start, int *__restrict r_end) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
char * BLI_strdup_null(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_MALLOC
Definition string.cc:46
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:693
size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define STRNCPY_UTF8(dst, src)
#define BLI_string_joinN(...)
size_t void BLI_uniquename_cb(blender::FunctionRef< bool(blender::StringRefNull)> unique_check, const char *defname, char delim, char *name, size_t name_maxncpy) ATTR_NONNULL(2
void BLI_string_replace_char(char *str, char src, char dst) ATTR_NONNULL(1)
#define ELEM(...)
#define STREQ(a, b)
void BLO_reportf_wrap(BlendFileReadReport *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
#define RPT_(msgid)
#define DATA_(msgid)
ID and Library types, which are fundamental for SDNA.
#define FILTER_ID_SCE
Definition DNA_ID.h:1217
@ ID_TE
@ ID_LA
@ ID_SCE
@ ID_LS
@ ID_WO
@ ID_MA
@ ADS_SHOW_SCENE_STRIP_FRAME_RANGE
@ ADS_OVERLAY_SHOW_OVERLAYS
@ PCHAN_DRAW_HIDDEN
@ BONE_HIDDEN_P
@ BRUSH_CURVE_SMOOTH
@ BRUSH_JITTER_COLOR
#define CD_MASK_PROP_ALL
@ CD_PROP_FLOAT
#define DNA_struct_default_get(struct_name)
blenloader genfile private function prototypes
@ IMA_SHOW_SEQUENCER_SCENE
@ MA_BL_LIGHTPROBE_VOLUME_DOUBLE_SIDED
@ eModifierType_Subsurf
@ eModifierType_GreasePencilLineart
@ eSubsurfModifierFlag_UseAdaptiveSubdivision
@ SUBSURF_ADAPTIVE_SPACE_PIXEL
@ NODE_INTERFACE_SOCKET_OPTIONAL_LABEL
@ NODE_INTERFACE_SOCKET_STRUCTURE_TYPE_DYNAMIC
@ NODE_INTERFACE_SOCKET_STRUCTURE_TYPE_AUTO
@ NODE_VECTOR_MATH_DOT_PRODUCT
@ NODE_VECTOR_MATH_MULTIPLY
@ CMP_NODE_INTERPOLATION_ANISOTROPIC
@ CMP_NODE_COMBSEP_COLOR_YCC
@ CMP_NODE_COMBSEP_COLOR_YUV
@ CMP_NODE_COMBSEP_COLOR_RGB
@ CMP_NODE_COMBSEP_COLOR_HSV
@ CMP_NODE_GLARE_QUALITY_HIGH
@ NODE_MATH_MINIMUM
@ NODE_MATH_ADD
@ NODE_MATH_MAXIMUM
@ NODE_MATH_MULTIPLY
@ CMP_NODE_EXTENSION_MODE_CLIP
@ CMP_NODE_EXTENSION_MODE_REPEAT
@ SHD_BLEND_DIAGONAL
@ SHD_BLEND_LINEAR
@ SHD_BLEND_QUADRATIC
@ SHD_OUTPUT_CYCLES
@ SHD_OUTPUT_EEVEE
@ CMP_NODE_RELATIVE_TO_PIXEL_DATA_TYPE_FLOAT
@ SHD_SKY_MULTIPLE_SCATTERING
@ SHD_SKY_SINGLE_SCATTERING
@ NODE_DO_OUTPUT
@ NODE_COLLAPSED
@ NODE_MUTED
@ NTREE_TEXTURE
@ NTREE_SHADER
@ NTREE_GEOMETRY
@ NTREE_COMPOSIT
@ CMP_NODE_TRANSLATE_REPEAT_AXIS_XY
@ CMP_NODE_TRANSLATE_REPEAT_AXIS_Y
@ CMP_NODE_TRANSLATE_REPEAT_AXIS_NONE
@ CMP_NODE_TRANSLATE_REPEAT_AXIS_X
@ SOCK_OUT
@ SOCK_IN
@ NODE_MIX_MODE_UNIFORM
@ SOCK_UNAVAIL
@ SOCK_VECTOR
@ SOCK_FLOAT
@ SOCK_GEOMETRY
@ SOCK_RGBA
@ NODE_COMBSEP_COLOR_RGB
@ NODE_COMBSEP_COLOR_HSV
@ NODE_MAP_RANGE_LINEAR
@ CMP_NODE_COLOR_BALANCE_LGG
@ SHD_MIXRGB_USE_ALPHA
@ SHD_MIXRGB_CLAMP
@ CMP_NODE_RELATIVE_TO_PIXEL_REFERENCE_DIMENSION_GREATER
@ CMP_NODE_GLARE_SUN_BEAMS
@ OB_ARMATURE
@ PTCACHE_COMPRESS_LZO_DEPRECATED
@ PTCACHE_COMPRESS_LZMA_DEPRECATED
@ PTCACHE_COMPRESS_ZSTD_FILTERED
Types and defines for representing Rigid Body entities.
@ UV_SELECT_VERT
@ MEDIA_TYPE_MULTI_LAYER_IMAGE
@ MEDIA_TYPE_VIDEO
@ MEDIA_TYPE_IMAGE
@ R_BAKE_NORMALS
@ R_BAKE_SPACE_OBJECT
@ R_BAKE_LORES_MESH
@ R_BAKE_MULTIRES
@ UV_FLAG_SELECT_ISLAND
@ R_IMF_IMTYPE_MULTILAYER
@ R_DOCOMP
@ RGN_ALIGN_HIDE_WITH_PREV
@ RGN_ALIGN_BOTTOM
@ RGN_ALIGN_LEFT
@ RGN_ALIGN_TOP
@ RGN_TYPE_UI
@ RGN_TYPE_ASSET_SHELF_HEADER
@ RGN_TYPE_ASSET_SHELF
@ RGN_TYPE_FOOTER
@ RGN_TYPE_HEADER
@ RGN_FLAG_HIDDEN
@ SPACE_CLIP
@ SPACE_ACTION
@ SPACE_NODE
@ SPACE_USERPREF
@ SPACE_FILE
@ SPACE_NLA
@ SPACE_SEQ
@ SPACE_IMAGE
@ SPACE_GRAPH
@ SC_SHOW_CURSOR
@ SC_SHOW_OVERLAYS
@ FILE_BROWSE_MODE_ASSETS
@ TEXMAP_CLIP_MIN
@ TEXMAP_CLIP_MAX
@ USER_HEADER_BOTTOM
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
@ PROP_ANGLE
Definition RNA_types.hh:252
@ PROP_FACTOR
Definition RNA_types.hh:251
#define U
BMesh const char void * data
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
bool add(const Key &key, const Value &value)
Definition BLI_map.hh:295
const Value & lookup(const Key &key) const
Definition BLI_map.hh:545
bool contains(const Key &key) const
Definition BLI_set.hh:310
bool add(const Key &key)
Definition BLI_set.hh:248
void append(const T &value)
bool is_empty() const
void extend(Span< T > array)
VectorData< T, Allocator > release()
const Value * lookup_ptr(const Key &key) const
Definition BLI_map.hh:508
Value & lookup_or_add_default(const Key &key)
Definition BLI_map.hh:639
void append(const T &value)
bool is_empty() const
nullptr float
int users
KDTree_3d * tree
#define GS(x)
#define input
#define fixed
format
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
static void add(blender::Map< std::string, std::string > &messages, Message &msg)
Definition msgfmt.cc:222
constexpr float LEGACY_RADIUS_CONVERSION_FACTOR
void mesh_sculpt_mask_to_generic(Mesh &mesh)
void mesh_freestyle_marks_to_generic(Mesh &mesh)
bNodeTree * node_tree_add_tree_embedded(Main *bmain, ID *owner_id, StringRefNull name, StringRefNull idname)
Definition node.cc:4098
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 pointcloud_convert_customdata_to_storage(PointCloud &pointcloud)
void node_remove_link(bNodeTree *ntree, bNodeLink &link)
Definition node.cc:3847
void node_tree_set_type(bNodeTree &ntree)
Definition node.cc:2254
std::optional< eNodeSocketDatatype > custom_data_type_to_socket_type(eCustomDataType type)
Definition node.cc:5168
bNode * node_add_static_node(const bContext *C, bNodeTree &ntree, int type)
Definition node.cc:3500
void curves_convert_customdata_to_storage(CurvesGeometry &curves)
void grease_pencil_convert_customdata_to_storage(GreasePencil &grease_pencil)
bNodeSocket * node_add_static_socket(bNodeTree &ntree, bNode &node, eNodeSocketInOut in_out, int type, int subtype, StringRefNull identifier, StringRefNull name)
Definition node.cc:3197
void mesh_custom_normals_to_generic(Mesh &mesh)
void mesh_uv_select_to_single_attribute(Mesh &mesh)
T min(const T &a, const T &b)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
T max(const T &a, const T &b)
void foreach_strip(ListBase *seqbase, ForEachFunc callback, void *user_data)
Definition iterator.cc:59
Editing * editing_get(const Scene *scene)
Definition sequencer.cc:286
void meta_stack_set(const Scene *scene, Strip *dst)
Definition sequencer.cc:463
MetaStack * meta_stack_active_get(const Editing *ed)
Definition sequencer.cc:454
VecBase< float, 3 > float3
static void copy(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node)
const char * name
const char * RE_engine_id_BLENDER_EEVEE_NEXT
Definition scene.cc:1581
const char * RE_engine_id_BLENDER_EEVEE
Definition scene.cc:1580
#define min(a, b)
Definition sort.cc:36
ListBase drivers
ListBase childbase
struct CurveMapping * curve_rand_saturation
struct CurveMapping * curve_rand_hue
struct CurveMapping * curve_rand_value
struct CurveMapping * curve_rand_saturation
struct CurveMapping * curve_rand_hue
struct CurveMapping * curve_rand_value
struct BrushGpencilSettings * gpencil_settings
float hsv_jitter[3]
CustomDataLayer * layers
ListBase seqbase
FileSelectParams base_params
BlendFileReadReport * reports
Definition readfile.hh:192
Definition DNA_ID.h:414
IDProperty * system_properties
Definition DNA_ID.h:489
IDProperty * properties
Definition DNA_ID.h:480
void * first
ListBase brushes
Definition BKE_main.hh:302
ListBase scenes
Definition BKE_main.hh:278
ListBase grease_pencils
Definition BKE_main.hh:310
ListBase wm
Definition BKE_main.hh:307
ListBase meshes
Definition BKE_main.hh:281
ListBase hair_curves
Definition BKE_main.hh:320
ListBase pointclouds
Definition BKE_main.hh:321
ListBase armatures
Definition BKE_main.hh:299
ListBase screens
Definition BKE_main.hh:292
ListBase objects
Definition BKE_main.hh:280
struct bNodeTree * nodetree
CustomData edge_data
CustomData corner_data
CustomData face_data
ListBase vertex_group_names
CustomData vert_data
NodeGeometryViewerItem * items
struct UnifiedPaintSettings unified_paint_settings
struct ToolSettings * toolsettings
struct Editing * ed
struct bNodeTree * compositing_node_group
struct RenderData r
SpaceActionOverlays overlays
struct SpaceClipOverlay overlay
FileAssetSelectParams * asset_params
struct ImageUser iuser
GpWeightPaint * gp_weightpaint
struct ImagePaintSettings imapaint
GpSculptPaint * gp_sculptpaint
CurvesSculpt * curves_sculpt
GpVertexPaint * gp_vertexpaint
struct CurveMapping * curve_rand_value
struct CurveMapping * curve_rand_saturation
struct CurveMapping * curve_rand_hue
struct CurveMapping * curve_distance_falloff
int8_t curve_distance_falloff_preset
struct Scene * sequencer_scene
struct bNodeTree * nodetree
float horg
float horb
float horr
void * default_value
char identifier[64]
bNodeTreeInterfaceItem ** items_array
bNodeTreeInterfacePanel root_panel
bNodeTreeInterface tree_interface
ListBase nodes
ListBase links
float location[2]
int16_t custom1
float width
ListBase inputs
float height
struct bNode * parent
void * storage
char label[64]
int16_t custom2
ListBase areabase
i
Definition text_draw.cc:230
max
Definition text_draw.cc:251
static bNode * add_node(bNodeTree *ntree, const int type, const blender::float2 loc)
static void do_version_distribute_points_in_volume_options_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_world_remove_use_nodes(Main *bmain, World *world)
static void do_version_texture_gradient_clamp(bNodeTree *node_tree)
static void do_version_rotate_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_normal_node_dot_product(bNodeTree *node_tree, bNode *node)
static void do_version_merge_by_distance_options_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_map_uv_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_match_string_options_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_filter_menus_to_inputs(bNodeTree &ntree, bNode &node)
void do_versions_after_linking_500(FileData *fd, Main *bmain)
static void do_version_sun_beams(bNodeTree &node_tree, bNode &node)
static void do_version_lens_distortion_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_volume_to_mesh_options_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_keying_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_uv_unwrap_options_to_inputs(bNodeTree &ntree, bNode &node)
static void sequencer_remove_listbase_pointers(Scene &scene)
static void do_version_composite_node_in_scene_tree(bNodeTree &node_tree, bNode &node)
static void update_brush_sizes(Main &bmain)
static void versioning_replace_legacy_combined_and_separate_color_nodes(bNodeTree *ntree)
static void do_version_glare_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_movie_distortion_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_displace_node_remove_xy_scale(bNodeTree &node_tree, bNode &node)
static void do_version_map_value_node(bNodeTree *node_tree, bNode *node)
static void do_version_remove_lzo_and_lzma_compression(FileData *fd, Object *object)
static void do_version_denoise_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void initialize_missing_closure_and_bundle_node_storage(bNodeTree &ntree)
static void do_version_mix_color_use_alpha(bNodeTree *node_tree, bNode *node)
static void remove_in_and_out_node_interface(bNodeTree &node_tree)
static void do_version_points_to_volume_options_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_levels_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_dilate_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_transform_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void sequencer_substitute_transform_effects(Scene *scene)
static void version_seq_text_from_legacy(Main *bmain)
static void do_version_color_balance_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_material_remove_use_nodes(Main *bmain, Material *material)
static void do_version_corner_pin_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_channel_matte_menus_to_inputs(bNodeTree &ntree, bNode &node)
void version_system_idprops_generate(Main *bmain)
static void do_version_adaptive_subdivision(Main *bmain)
static void do_version_convert_alpha_menus_to_inputs(bNodeTree &ntree, bNode &node)
void version_system_idprops_nodes_generate(Main *bmain)
static void for_each_mode_paint_settings(Scene &scene, blender::FunctionRef< void(Scene &scene, Paint *paint)> func)
static void do_version_tone_map_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_lift_gamma_gain_srgb_to_linear(bNodeTree &node_tree, bNode &node)
static void do_version_sample_grid_options_to_inputs(bNodeTree &ntree, bNode &node)
static void version_bone_hide_property_driver(AnimData *arm_adt, blender::Vector< Object * > &users)
static void do_version_convert_to_generic_nodes_after_linking(Main *bmain, bNodeTree *node_tree, ID *id)
static void do_version_mask_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void idprops_process(IDProperty *idprops, IDProperty **system_idprops)
static void do_version_transform_geometry_options_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_mesh_to_volume_options_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_displace_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void copy_unified_paint_settings(Scene &scene, Paint *paint)
static void do_version_subdivision_surface_options_to_inputs(bNodeTree &ntree, bNode &node)
static void repair_node_link_node_pointers(FileData &fd, bNodeTree &node_tree)
static bool window_has_sequence_editor_open(const wmWindow *win)
static void do_version_color_spill_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_remove_attribute_options_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_kuwahara_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_box_mask_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_fillet_curve_options_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_fill_curve_options_to_inputs(bNodeTree &ntree, bNode &node)
static CustomDataLayer * find_old_seam_layer(CustomData &custom_data, const blender::StringRef name)
static void update_format_media_type(ImageFormatData *format)
static void remove_in_and_out_node_panel_recursive(bNodeTreeInterfacePanel &panel)
static void do_version_stabilize_2d_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_scale_elements_options_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_raycast_options_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_scene_remove_use_nodes(Scene *scene)
static void do_version_triangulate_options_to_inputs(bNodeTree &ntree, bNode &node)
static void version_dynamic_viewer_node_items(bNodeTree &ntree)
static void do_version_split_node_rotation(bNodeTree *node_tree, bNode *node)
static void do_version_track_position_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void initialize_closure_input_structure_types(bNodeTree &ntree)
static void do_version_convert_gp_jitter_values(Brush *brush)
static void do_version_resample_curve_options_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_distance_matte_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_blur_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_uv_pack_islands_options_to_inputs(bNodeTree &ntree, bNode &node)
void version_system_idprops_children_bones_generate(Main *bmain)
static void do_version_set_curve_normal_options_to_inputs(bNodeTree &ntree, bNode &node)
void blo_do_versions_500(FileData *fd, Library *, Main *bmain)
static void do_version_scale_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_file_output_node(bNode &node)
static void do_version_convert_to_generic_nodes(bNodeTree *node_tree)
static void do_version_double_edge_mask_options_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_ellipse_mask_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_translate_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void do_version_bokeh_blur_pixel_size(bNodeTree &node_tree, bNode &node)
static void do_version_set_alpha_menus_to_inputs(bNodeTree &ntree, bNode &node)
static void rename_mesh_uv_seam_attribute(Mesh &mesh)
void version_node_remove(bNodeTree &ntree, bNode &node)
IDProperty * version_cycles_properties_from_ID(ID *id)
void version_node_tree_clear_interface(bNodeTree &ntree)
bNodeSocket & version_node_add_socket(bNodeTree &ntree, bNode &node, const eNodeSocketInOut in_out, const char *idname, const char *identifier)
void version_node_input_socket_name(bNodeTree *ntree, const int node_type, const char *old_name, const char *new_name)
bNode & version_node_add_empty(bNodeTree &ntree, const char *idname)
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)
void version_socket_update_is_used(bNodeTree *ntree)
bNodeLink & version_node_add_link(bNodeTree &ntree, bNode &node_a, bNodeSocket &socket_a, bNode &node_b, bNodeSocket &socket_b)
float version_cycles_property_float(IDProperty *idprop, const char *name, float default_value)
bNodeTree * version_get_scene_compositor_node_tree(Main *bmain, Scene *scene)
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)
Scene * WM_window_get_active_scene(const wmWindow *win)
WorkSpace * WM_window_get_active_workspace(const wmWindow *win)
bScreen * WM_window_get_active_screen(const wmWindow *win)