Blender V4.5
versioning_410.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#define DNA_DEPRECATED_ALLOW
10
11#include "ANIM_armature_iter.hh"
12
13/* Define macros in `DNA_genfile.h`. */
14#define DNA_GENFILE_VERSIONING_MACROS
15
16#include "DNA_anim_types.h"
17#include "DNA_brush_types.h"
18#include "DNA_defaults.h"
19#include "DNA_genfile.h"
21#include "DNA_material_types.h"
22#include "DNA_mesh_types.h"
23#include "DNA_modifier_types.h"
24#include "DNA_scene_types.h"
25#include "DNA_screen_types.h"
26#include "DNA_sequence_types.h"
27
28#undef DNA_GENFILE_VERSIONING_MACROS
29
30#include "BLI_listbase.h"
31#include "BLI_math_vector.h"
33#include "BLI_string.h"
34#include "BLI_task.hh"
35
36#include "BKE_anim_data.hh"
37#include "BKE_armature.hh"
38#include "BKE_grease_pencil.hh"
39#include "BKE_main.hh"
40#include "BKE_nla.hh"
41#include "BKE_node.hh"
43#include "BKE_node_runtime.hh"
44
45#include "SEQ_iterator.hh"
46#include "SEQ_sequencer.hh"
47
48#include "readfile.hh"
49
50#include "versioning_common.hh"
51
64{
65 bool any_valid_tweakmode_left = false;
66
67 ID *id;
68 FOREACH_MAIN_ID_BEGIN (bmain, id) {
70 if (!adt || !(adt->flag & ADT_NLA_EDIT_ON)) {
71 continue;
72 }
73
74 if (adt->act_track && adt->actstrip) {
75 /* Expected case. */
76 any_valid_tweakmode_left = true;
77 continue;
78 }
79
80 /* Not enough info in the blend file to reliably stay in tweak mode. This is the most important
81 * part of this versioning code, as it prevents future nullptr access. */
82 BKE_nla_tweakmode_exit({*id, *adt});
83 }
85
86 if (any_valid_tweakmode_left) {
87 /* There are still NLA strips correctly in tweak mode. */
88 return;
89 }
90
91 /* Nothing is in a valid tweakmode, so just disable the corresponding flags on all scenes. */
92 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
93 scene->flag &= ~SCE_NLA_EDIT_ON;
94 }
95}
96
98{
99 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 23)) {
101 }
102}
103
105{
106 using namespace blender;
107 for (GreasePencilDrawingBase *base : grease_pencil->drawings()) {
108 if (base->type != GP_DRAWING) {
109 continue;
110 }
111 bke::greasepencil::Drawing &drawing = reinterpret_cast<GreasePencilDrawing *>(base)->wrap();
112 MutableSpan<float> radii = drawing.radii_for_write();
113 threading::parallel_for(radii.index_range(), 8192, [&](const IndexRange range) {
114 for (const int i : range) {
115 radii[i] *= bke::greasepencil::LEGACY_RADIUS_CONVERSION_FACTOR;
116 }
117 });
118 }
119}
120
122{
123 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
124 if (node->type_legacy != SH_NODE_TEX_NOISE) {
125 continue;
126 }
127
128 (static_cast<NodeTexNoise *>(node->storage))->type = SHD_NOISE_FBM;
129
130 bNodeSocket *roughness_socket = blender::bke::node_find_socket(*node, SOCK_IN, "Roughness");
131 if (roughness_socket == nullptr) {
132 /* Noise Texture node was created before the Roughness input was added. */
133 continue;
134 }
135
136 float *roughness = version_cycles_node_socket_float_value(roughness_socket);
137
138 bNodeLink *roughness_link = nullptr;
139 bNode *roughness_from_node = nullptr;
140 bNodeSocket *roughness_from_socket = nullptr;
141
142 LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
143 /* Find links, nodes and sockets. */
144 if (link->tosock == roughness_socket) {
145 roughness_link = link;
146 roughness_from_node = link->fromnode;
147 roughness_from_socket = link->fromsock;
148 }
149 }
150
151 if (roughness_link != nullptr) {
152 /* Add Clamp node before Roughness input. */
153
154 bNode *clamp_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_CLAMP);
155 clamp_node->parent = node->parent;
156 clamp_node->custom1 = NODE_CLAMP_MINMAX;
157 clamp_node->locx_legacy = node->locx_legacy;
158 clamp_node->locy_legacy = node->locy_legacy - 300.0f;
159 clamp_node->flag |= NODE_HIDDEN;
160 bNodeSocket *clamp_socket_value = blender::bke::node_find_socket(
161 *clamp_node, SOCK_IN, "Value");
162 bNodeSocket *clamp_socket_min = blender::bke::node_find_socket(*clamp_node, SOCK_IN, "Min");
163 bNodeSocket *clamp_socket_max = blender::bke::node_find_socket(*clamp_node, SOCK_IN, "Max");
165 *clamp_node, SOCK_OUT, "Result");
166
167 *version_cycles_node_socket_float_value(clamp_socket_min) = 0.0f;
168 *version_cycles_node_socket_float_value(clamp_socket_max) = 1.0f;
169
170 blender::bke::node_remove_link(ntree, *roughness_link);
172 *ntree, *roughness_from_node, *roughness_from_socket, *clamp_node, *clamp_socket_value);
174 *ntree, *clamp_node, *clamp_socket_out, *node, *roughness_socket);
175 }
176 else {
177 *roughness = std::clamp(*roughness, 0.0f, 1.0f);
178 }
179 }
180
182}
183
185{
186 version_node_input_socket_name(ntree, SH_NODE_TEX_MUSGRAVE_DEPRECATED, "Dimension", "Roughness");
187 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
188 if (node->type_legacy != SH_NODE_TEX_MUSGRAVE_DEPRECATED) {
189 continue;
190 }
191
192 STRNCPY(node->idname, "ShaderNodeTexNoise");
193 node->type_legacy = SH_NODE_TEX_NOISE;
195 data->base = (static_cast<NodeTexMusgrave *>(node->storage))->base;
196 data->dimensions = (static_cast<NodeTexMusgrave *>(node->storage))->dimensions;
197 data->normalize = false;
198 data->type = (static_cast<NodeTexMusgrave *>(node->storage))->musgrave_type;
199 MEM_freeN(node->storage);
200 node->storage = data;
201
202 bNodeLink *detail_link = nullptr;
203 bNode *detail_from_node = nullptr;
204 bNodeSocket *detail_from_socket = nullptr;
205
206 bNodeLink *roughness_link = nullptr;
207 bNode *roughness_from_node = nullptr;
208 bNodeSocket *roughness_from_socket = nullptr;
209
210 bNodeLink *lacunarity_link = nullptr;
211 bNode *lacunarity_from_node = nullptr;
212 bNodeSocket *lacunarity_from_socket = nullptr;
213
214 LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
215 /* Find links, nodes and sockets. */
216 if (link->tonode == node) {
217 if (STREQ(link->tosock->identifier, "Detail")) {
218 detail_link = link;
219 detail_from_node = link->fromnode;
220 detail_from_socket = link->fromsock;
221 }
222 if (STREQ(link->tosock->identifier, "Roughness")) {
223 roughness_link = link;
224 roughness_from_node = link->fromnode;
225 roughness_from_socket = link->fromsock;
226 }
227 if (STREQ(link->tosock->identifier, "Lacunarity")) {
228 lacunarity_link = link;
229 lacunarity_from_node = link->fromnode;
230 lacunarity_from_socket = link->fromsock;
231 }
232 }
233 }
234
235 uint8_t noise_type = (static_cast<NodeTexNoise *>(node->storage))->type;
236 float locy_offset = 0.0f;
237
238 bNodeSocket *fac_socket = blender::bke::node_find_socket(*node, SOCK_OUT, "Fac");
239 /* Clear label because Musgrave output socket label is set to "Height" instead of "Fac". */
240 fac_socket->label[0] = '\0';
241
242 bNodeSocket *detail_socket = blender::bke::node_find_socket(*node, SOCK_IN, "Detail");
243 float *detail = version_cycles_node_socket_float_value(detail_socket);
244
245 if (detail_link != nullptr) {
246 locy_offset -= 80.0f;
247
248 /* Add Minimum Math node and Subtract Math node before Detail input. */
249
250 bNode *min_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_MATH);
251 min_node->parent = node->parent;
252 min_node->custom1 = NODE_MATH_MINIMUM;
253 min_node->locx_legacy = node->locx_legacy;
254 min_node->locy_legacy = node->locy_legacy - 320.0f;
255 min_node->flag |= NODE_HIDDEN;
256 bNodeSocket *min_socket_A = static_cast<bNodeSocket *>(BLI_findlink(&min_node->inputs, 0));
257 bNodeSocket *min_socket_B = static_cast<bNodeSocket *>(BLI_findlink(&min_node->inputs, 1));
258 bNodeSocket *min_socket_out = blender::bke::node_find_socket(*min_node, SOCK_OUT, "Value");
259
260 bNode *sub1_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_MATH);
261 sub1_node->parent = node->parent;
262 sub1_node->custom1 = NODE_MATH_SUBTRACT;
263 sub1_node->locx_legacy = node->locx_legacy;
264 sub1_node->locy_legacy = node->locy_legacy - 360.0f;
265 sub1_node->flag |= NODE_HIDDEN;
266 bNodeSocket *sub1_socket_A = static_cast<bNodeSocket *>(BLI_findlink(&sub1_node->inputs, 0));
267 bNodeSocket *sub1_socket_B = static_cast<bNodeSocket *>(BLI_findlink(&sub1_node->inputs, 1));
268 bNodeSocket *sub1_socket_out = blender::bke::node_find_socket(*sub1_node, SOCK_OUT, "Value");
269
270 *version_cycles_node_socket_float_value(min_socket_B) = 14.0f;
271 *version_cycles_node_socket_float_value(sub1_socket_B) = 1.0f;
272
273 blender::bke::node_remove_link(ntree, *detail_link);
275 *ntree, *detail_from_node, *detail_from_socket, *sub1_node, *sub1_socket_A);
276 blender::bke::node_add_link(*ntree, *sub1_node, *sub1_socket_out, *min_node, *min_socket_A);
277 blender::bke::node_add_link(*ntree, *min_node, *min_socket_out, *node, *detail_socket);
278
280 locy_offset -= 40.0f;
281
282 /* Add Greater Than Math node before Subtract Math node. */
283
284 bNode *greater_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_MATH);
285 greater_node->parent = node->parent;
286 greater_node->custom1 = NODE_MATH_GREATER_THAN;
287 greater_node->locx_legacy = node->locx_legacy;
288 greater_node->locy_legacy = node->locy_legacy - 400.0f;
289 greater_node->flag |= NODE_HIDDEN;
290 bNodeSocket *greater_socket_A = static_cast<bNodeSocket *>(
291 BLI_findlink(&greater_node->inputs, 0));
292 bNodeSocket *greater_socket_B = static_cast<bNodeSocket *>(
293 BLI_findlink(&greater_node->inputs, 1));
294 bNodeSocket *greater_socket_out = blender::bke::node_find_socket(
295 *greater_node, SOCK_OUT, "Value");
296
297 *version_cycles_node_socket_float_value(greater_socket_B) = 1.0f;
298
300 *ntree, *detail_from_node, *detail_from_socket, *greater_node, *greater_socket_A);
302 *ntree, *greater_node, *greater_socket_out, *sub1_node, *sub1_socket_B);
303 }
304 else {
305 /* Add Clamp node and Multiply Math node behind Fac output. */
306
307 bNode *clamp_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_CLAMP);
308 clamp_node->parent = node->parent;
309 clamp_node->custom1 = NODE_CLAMP_MINMAX;
310 clamp_node->locx_legacy = node->locx_legacy;
311 clamp_node->locy_legacy = node->locy_legacy + 40.0f;
312 clamp_node->flag |= NODE_HIDDEN;
313 bNodeSocket *clamp_socket_value = blender::bke::node_find_socket(
314 *clamp_node, SOCK_IN, "Value");
316 *clamp_node, SOCK_IN, "Min");
318 *clamp_node, SOCK_IN, "Max");
320 *clamp_node, SOCK_OUT, "Result");
321
322 bNode *mul_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_MATH);
323 mul_node->parent = node->parent;
324 mul_node->custom1 = NODE_MATH_MULTIPLY;
325 mul_node->locx_legacy = node->locx_legacy;
326 mul_node->locy_legacy = node->locy_legacy + 80.0f;
327 mul_node->flag |= NODE_HIDDEN;
328 bNodeSocket *mul_socket_A = static_cast<bNodeSocket *>(BLI_findlink(&mul_node->inputs, 0));
329 bNodeSocket *mul_socket_B = static_cast<bNodeSocket *>(BLI_findlink(&mul_node->inputs, 1));
330 bNodeSocket *mul_socket_out = blender::bke::node_find_socket(*mul_node, SOCK_OUT, "Value");
331
332 *version_cycles_node_socket_float_value(clamp_socket_min) = 0.0f;
333 *version_cycles_node_socket_float_value(clamp_socket_max) = 1.0f;
334
335 if (noise_type == SHD_NOISE_MULTIFRACTAL) {
336 /* Add Subtract Math node and Add Math node after Multiply Math node. */
337
338 bNode *sub2_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_MATH);
339 sub2_node->parent = node->parent;
340 sub2_node->custom1 = NODE_MATH_SUBTRACT;
341 sub2_node->custom2 = SHD_MATH_CLAMP;
342 sub2_node->locx_legacy = node->locx_legacy;
343 sub2_node->locy_legacy = node->locy_legacy + 120.0f;
344 sub2_node->flag |= NODE_HIDDEN;
345 bNodeSocket *sub2_socket_A = static_cast<bNodeSocket *>(
346 BLI_findlink(&sub2_node->inputs, 0));
347 bNodeSocket *sub2_socket_B = static_cast<bNodeSocket *>(
348 BLI_findlink(&sub2_node->inputs, 1));
350 *sub2_node, SOCK_OUT, "Value");
351
353 add_node->parent = node->parent;
354 add_node->custom1 = NODE_MATH_ADD;
355 add_node->locx_legacy = node->locx_legacy;
356 add_node->locy_legacy = node->locy_legacy + 160.0f;
357 add_node->flag |= NODE_HIDDEN;
358 bNodeSocket *add_socket_A = static_cast<bNodeSocket *>(
359 BLI_findlink(&add_node->inputs, 0));
360 bNodeSocket *add_socket_B = static_cast<bNodeSocket *>(
361 BLI_findlink(&add_node->inputs, 1));
363 *add_node, SOCK_OUT, "Value");
364
365 *version_cycles_node_socket_float_value(sub2_socket_A) = 1.0f;
366
368 if (link->fromsock == fac_socket) {
370 *ntree, *add_node, *add_socket_out, *link->tonode, *link->tosock);
371 blender::bke::node_remove_link(ntree, *link);
372 }
373 }
374
376 *ntree, *mul_node, *mul_socket_out, *add_node, *add_socket_A);
378 *ntree, *detail_from_node, *detail_from_socket, *sub2_node, *sub2_socket_B);
380 *ntree, *sub2_node, *sub2_socket_out, *add_node, *add_socket_B);
381 }
382 else {
384 if (link->fromsock == fac_socket) {
386 *ntree, *mul_node, *mul_socket_out, *link->tonode, *link->tosock);
387 blender::bke::node_remove_link(ntree, *link);
388 }
389 }
390 }
391
392 blender::bke::node_add_link(*ntree, *node, *fac_socket, *mul_node, *mul_socket_A);
394 *ntree, *detail_from_node, *detail_from_socket, *clamp_node, *clamp_socket_value);
396 *ntree, *clamp_node, *clamp_socket_out, *mul_node, *mul_socket_B);
397 }
398 }
399 else {
400 if (*detail < 1.0f) {
402 /* Add Multiply Math node behind Fac output. */
403
404 bNode *mul_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_MATH);
405 mul_node->parent = node->parent;
406 mul_node->custom1 = NODE_MATH_MULTIPLY;
407 mul_node->locx_legacy = node->locx_legacy;
408 mul_node->locy_legacy = node->locy_legacy + 40.0f;
409 mul_node->flag |= NODE_HIDDEN;
410 bNodeSocket *mul_socket_A = static_cast<bNodeSocket *>(
411 BLI_findlink(&mul_node->inputs, 0));
412 bNodeSocket *mul_socket_B = static_cast<bNodeSocket *>(
413 BLI_findlink(&mul_node->inputs, 1));
415 *mul_node, SOCK_OUT, "Value");
416
418
419 if (noise_type == SHD_NOISE_MULTIFRACTAL) {
420 /* Add an Add Math node after Multiply Math node. */
421
423 add_node->parent = node->parent;
424 add_node->custom1 = NODE_MATH_ADD;
425 add_node->locx_legacy = node->locx_legacy;
426 add_node->locy_legacy = node->locy_legacy + 80.0f;
427 add_node->flag |= NODE_HIDDEN;
428 bNodeSocket *add_socket_A = static_cast<bNodeSocket *>(
429 BLI_findlink(&add_node->inputs, 0));
430 bNodeSocket *add_socket_B = static_cast<bNodeSocket *>(
431 BLI_findlink(&add_node->inputs, 1));
433 *add_node, SOCK_OUT, "Value");
434
435 *version_cycles_node_socket_float_value(add_socket_B) = 1.0f - *detail;
436
438 if (link->fromsock == fac_socket) {
440 *ntree, *add_node, *add_socket_out, *link->tonode, *link->tosock);
441 blender::bke::node_remove_link(ntree, *link);
442 }
443 }
444
446 *ntree, *mul_node, *mul_socket_out, *add_node, *add_socket_A);
447 }
448 else {
450 if (link->fromsock == fac_socket) {
452 *ntree, *mul_node, *mul_socket_out, *link->tonode, *link->tosock);
453 blender::bke::node_remove_link(ntree, *link);
454 }
455 }
456 }
457
458 blender::bke::node_add_link(*ntree, *node, *fac_socket, *mul_node, *mul_socket_A);
459
460 *detail = 0.0f;
461 }
462 }
463 else {
464 *detail = std::fminf(*detail - 1.0f, 14.0f);
465 }
466 }
467
468 bNodeSocket *roughness_socket = blender::bke::node_find_socket(*node, SOCK_IN, "Roughness");
469 float *roughness = version_cycles_node_socket_float_value(roughness_socket);
470 bNodeSocket *lacunarity_socket = blender::bke::node_find_socket(*node, SOCK_IN, "Lacunarity");
471 float *lacunarity = version_cycles_node_socket_float_value(lacunarity_socket);
472
473 *roughness = std::fmaxf(*roughness, 1e-5f);
474 *lacunarity = std::fmaxf(*lacunarity, 1e-5f);
475
476 if (roughness_link != nullptr) {
477 /* Add Maximum Math node after output of roughness_from_node. Add Multiply Math node and
478 * Power Math node before Roughness input. */
479
480 bNode *max1_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_MATH);
481 max1_node->parent = node->parent;
482 max1_node->custom1 = NODE_MATH_MAXIMUM;
483 max1_node->locx_legacy = node->locx_legacy;
484 max1_node->locy_legacy = node->locy_legacy - 400.0f + locy_offset;
485 max1_node->flag |= NODE_HIDDEN;
486 bNodeSocket *max1_socket_A = static_cast<bNodeSocket *>(BLI_findlink(&max1_node->inputs, 0));
487 bNodeSocket *max1_socket_B = static_cast<bNodeSocket *>(BLI_findlink(&max1_node->inputs, 1));
488 bNodeSocket *max1_socket_out = blender::bke::node_find_socket(*max1_node, SOCK_OUT, "Value");
489
490 bNode *mul_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_MATH);
491 mul_node->parent = node->parent;
492 mul_node->custom1 = NODE_MATH_MULTIPLY;
493 mul_node->locx_legacy = node->locx_legacy;
494 mul_node->locy_legacy = node->locy_legacy - 360.0f + locy_offset;
495 mul_node->flag |= NODE_HIDDEN;
496 bNodeSocket *mul_socket_A = static_cast<bNodeSocket *>(BLI_findlink(&mul_node->inputs, 0));
497 bNodeSocket *mul_socket_B = static_cast<bNodeSocket *>(BLI_findlink(&mul_node->inputs, 1));
498 bNodeSocket *mul_socket_out = blender::bke::node_find_socket(*mul_node, SOCK_OUT, "Value");
499
500 bNode *pow_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_MATH);
501 pow_node->parent = node->parent;
502 pow_node->custom1 = NODE_MATH_POWER;
503 pow_node->locx_legacy = node->locx_legacy;
504 pow_node->locy_legacy = node->locy_legacy - 320.0f + locy_offset;
505 pow_node->flag |= NODE_HIDDEN;
506 bNodeSocket *pow_socket_A = static_cast<bNodeSocket *>(BLI_findlink(&pow_node->inputs, 0));
507 bNodeSocket *pow_socket_B = static_cast<bNodeSocket *>(BLI_findlink(&pow_node->inputs, 1));
508 bNodeSocket *pow_socket_out = blender::bke::node_find_socket(*pow_node, SOCK_OUT, "Value");
509
510 *version_cycles_node_socket_float_value(max1_socket_B) = -1e-5f;
511 *version_cycles_node_socket_float_value(mul_socket_B) = -1.0f;
512 *version_cycles_node_socket_float_value(pow_socket_A) = *lacunarity;
513
514 blender::bke::node_remove_link(ntree, *roughness_link);
516 *ntree, *roughness_from_node, *roughness_from_socket, *max1_node, *max1_socket_A);
517 blender::bke::node_add_link(*ntree, *max1_node, *max1_socket_out, *mul_node, *mul_socket_A);
518 blender::bke::node_add_link(*ntree, *mul_node, *mul_socket_out, *pow_node, *pow_socket_B);
519 blender::bke::node_add_link(*ntree, *pow_node, *pow_socket_out, *node, *roughness_socket);
520
521 if (lacunarity_link != nullptr) {
522 /* Add Maximum Math node after output of lacunarity_from_node. */
523
524 bNode *max2_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_MATH);
525 max2_node->parent = node->parent;
526 max2_node->custom1 = NODE_MATH_MAXIMUM;
527 max2_node->locx_legacy = node->locx_legacy;
528 max2_node->locy_legacy = node->locy_legacy - 440.0f + locy_offset;
529 max2_node->flag |= NODE_HIDDEN;
530 bNodeSocket *max2_socket_A = static_cast<bNodeSocket *>(
531 BLI_findlink(&max2_node->inputs, 0));
532 bNodeSocket *max2_socket_B = static_cast<bNodeSocket *>(
533 BLI_findlink(&max2_node->inputs, 1));
535 *max2_node, SOCK_OUT, "Value");
536
537 *version_cycles_node_socket_float_value(max2_socket_B) = -1e-5f;
538
539 blender::bke::node_remove_link(ntree, *lacunarity_link);
541 *ntree, *lacunarity_from_node, *lacunarity_from_socket, *max2_node, *max2_socket_A);
543 *ntree, *max2_node, *max2_socket_out, *pow_node, *pow_socket_A);
545 *ntree, *max2_node, *max2_socket_out, *node, *lacunarity_socket);
546 }
547 }
548 else if ((lacunarity_link != nullptr) && (roughness_link == nullptr)) {
549 /* Add Maximum Math node after output of lacunarity_from_node. Add Power Math node before
550 * Roughness input. */
551
552 bNode *max2_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_MATH);
553 max2_node->parent = node->parent;
554 max2_node->custom1 = NODE_MATH_MAXIMUM;
555 max2_node->locx_legacy = node->locx_legacy;
556 max2_node->locy_legacy = node->locy_legacy - 360.0f + locy_offset;
557 max2_node->flag |= NODE_HIDDEN;
558 bNodeSocket *max2_socket_A = static_cast<bNodeSocket *>(BLI_findlink(&max2_node->inputs, 0));
559 bNodeSocket *max2_socket_B = static_cast<bNodeSocket *>(BLI_findlink(&max2_node->inputs, 1));
560 bNodeSocket *max2_socket_out = blender::bke::node_find_socket(*max2_node, SOCK_OUT, "Value");
561
562 bNode *pow_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_MATH);
563 pow_node->parent = node->parent;
564 pow_node->custom1 = NODE_MATH_POWER;
565 pow_node->locx_legacy = node->locx_legacy;
566 pow_node->locy_legacy = node->locy_legacy - 320.0f + locy_offset;
567 pow_node->flag |= NODE_HIDDEN;
568 bNodeSocket *pow_socket_A = static_cast<bNodeSocket *>(BLI_findlink(&pow_node->inputs, 0));
569 bNodeSocket *pow_socket_B = static_cast<bNodeSocket *>(BLI_findlink(&pow_node->inputs, 1));
570 bNodeSocket *pow_socket_out = blender::bke::node_find_socket(*pow_node, SOCK_OUT, "Value");
571
572 *version_cycles_node_socket_float_value(max2_socket_B) = -1e-5f;
573 *version_cycles_node_socket_float_value(pow_socket_A) = *lacunarity;
574 *version_cycles_node_socket_float_value(pow_socket_B) = -(*roughness);
575
576 blender::bke::node_remove_link(ntree, *lacunarity_link);
578 *ntree, *lacunarity_from_node, *lacunarity_from_socket, *max2_node, *max2_socket_A);
579 blender::bke::node_add_link(*ntree, *max2_node, *max2_socket_out, *pow_node, *pow_socket_A);
580 blender::bke::node_add_link(*ntree, *max2_node, *max2_socket_out, *node, *lacunarity_socket);
581 blender::bke::node_add_link(*ntree, *pow_node, *pow_socket_out, *node, *roughness_socket);
582 }
583 else {
584 *roughness = std::pow(*lacunarity, -(*roughness));
585 }
586 }
587
589}
590
592{
593 /* Split viewer was replaced with a regular split node, so add a viewer node,
594 * and link it to the new split node to achieve the same behavior of the split viewer node. */
595
596 LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree->nodes) {
597 if (node->type_legacy != CMP_NODE_SPLITVIEWER__DEPRECATED) {
598 continue;
599 }
600
601 STRNCPY(node->idname, "CompositorNodeSplit");
602 node->type_legacy = CMP_NODE_SPLIT;
603 MEM_freeN(node->storage);
604 node->storage = nullptr;
605
606 bNode *viewer_node = blender::bke::node_add_static_node(nullptr, *ntree, CMP_NODE_VIEWER);
607 /* Nodes are created stacked on top of each other, so separate them a bit. */
608 viewer_node->locx_legacy = node->locx_legacy + node->width + viewer_node->width / 4.0f;
609 viewer_node->locy_legacy = node->locy_legacy;
610 viewer_node->flag &= ~NODE_PREVIEW;
611
613 *ntree, *node, SOCK_OUT, SOCK_IMAGE, PROP_NONE, "Image", "Image");
614 bNodeSocket *viewer_in_socket = blender::bke::node_find_socket(*viewer_node, SOCK_IN, "Image");
615
616 blender::bke::node_add_link(*ntree, *node, *split_out_socket, *viewer_node, *viewer_in_socket);
617 }
618}
619
621 ListBase sockets, const char *separator, const std::optional<int> total = std::nullopt)
622{
623 int index = 0;
624 LISTBASE_FOREACH (bNodeSocket *, socket, &sockets) {
625 if (socket->is_available()) {
626 if (char *pos = strstr(socket->identifier, separator)) {
627 /* End the identifier at the separator so that the old suffix is ignored. */
628 *pos = '\0';
629
630 if (total.has_value()) {
631 index++;
632 if (index == *total) {
633 return;
634 }
635 }
636 }
637 }
638 else {
639 /* Rename existing identifiers so that they don't conflict with the renamed one. Those will
640 * be removed after versioning code. */
641 BLI_strncat(socket->identifier, "_deprecated", sizeof(socket->identifier));
642 }
643 }
644}
645
647{
648 LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
649 switch (node->type_legacy) {
651 /* This node requires the extra `total` parameter, because the `Group Index` identifier
652 * also has a space in the name, that should not be treated as separator. */
655 break;
662 case GEO_NODE_RAYCAST:
667 case GEO_NODE_VIEWER:
670 break;
671 }
672 }
673}
674
676{
677 LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
678 if (!ELEM(node->type_legacy, GEO_NODE_SWITCH, GEO_NODE_SAMPLE_CURVE)) {
679 continue;
680 }
683 }
684}
685
687 bNode &node,
688 bNodeSocket &socket)
689{
690 if (socket.type == SOCK_ROTATION) {
691 return;
692 }
693 socket.type = SOCK_ROTATION;
694 STRNCPY(socket.idname, "NodeSocketRotation");
695 auto *old_value = static_cast<bNodeSocketValueVector *>(socket.default_value);
696 auto *new_value = MEM_callocN<bNodeSocketValueRotation>(__func__);
697 copy_v3_v3(new_value->value_euler, old_value->value);
698 socket.default_value = new_value;
699 MEM_freeN(old_value);
700 LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree.links) {
701 if (link->tosock != &socket) {
702 continue;
703 }
704 if (ELEM(link->fromsock->type, SOCK_ROTATION, SOCK_VECTOR, SOCK_FLOAT) &&
705 !link->fromnode->is_reroute())
706 {
707 /* No need to add the conversion node when implicit conversions will work. */
708 continue;
709 }
710 if (STREQ(link->fromnode->idname, "FunctionNodeEulerToRotation")) {
711 /* Make versioning idempotent. */
712 continue;
713 }
714 bNode *convert = blender::bke::node_add_node(nullptr, ntree, "FunctionNodeEulerToRotation");
715 convert->parent = node.parent;
716 convert->locx_legacy = node.locx_legacy - 40;
717 convert->locy_legacy = node.locy_legacy;
718 link->tonode = convert;
719 link->tosock = blender::bke::node_find_socket(*convert, SOCK_IN, "Euler");
720
722 *convert,
723 *blender::bke::node_find_socket(*convert, SOCK_OUT, "Rotation"),
724 node,
725 socket);
726 }
727}
728
730 bNode &node,
731 bNodeSocket &socket)
732{
733 /* Rely on generic node declaration update to change the socket type. */
734 LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree.links) {
735 if (link->fromsock != &socket) {
736 continue;
737 }
738 if (ELEM(link->tosock->type, SOCK_ROTATION, SOCK_VECTOR) && !link->tonode->is_reroute()) {
739 /* No need to add the conversion node when implicit conversions will work. */
740 continue;
741 }
742 if (STREQ(link->tonode->idname, "FunctionNodeRotationToEuler"))
743 { /* Make versioning idempotent. */
744 continue;
745 }
746 bNode *convert = blender::bke::node_add_node(nullptr, ntree, "FunctionNodeRotationToEuler");
747 convert->parent = node.parent;
748 convert->locx_legacy = node.locx_legacy + 40;
749 convert->locy_legacy = node.locy_legacy;
750 link->fromnode = convert;
751 link->fromsock = blender::bke::node_find_socket(*convert, SOCK_OUT, "Euler");
752
754 node,
755 socket,
756 *convert,
757 *blender::bke::node_find_socket(*convert, SOCK_IN, "Rotation"));
758 }
759}
760
762{
763 LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree.nodes) {
764 if (STR_ELEM(node->idname,
765 "GeometryNodeInstanceOnPoints",
766 "GeometryNodeRotateInstances",
767 "GeometryNodeTransform"))
768 {
769 bNodeSocket *socket = blender::bke::node_find_socket(*node, SOCK_IN, "Rotation");
770 change_input_socket_to_rotation_type(ntree, *node, *socket);
771 }
772 if (STR_ELEM(node->idname,
773 "GeometryNodeDistributePointsOnFaces",
774 "GeometryNodeObjectInfo",
775 "GeometryNodeInputInstanceRotation"))
776 {
777 bNodeSocket *socket = blender::bke::node_find_socket(*node, SOCK_OUT, "Rotation");
778 change_output_socket_to_rotation_type(ntree, *node, *socket);
779 }
780 }
781}
782
784{
785 using namespace blender;
787 LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) {
788 if (link->fromnode->type_legacy == GEO_NODE_OBJECT_INFO) {
789 out_links_per_socket.add(link->fromsock, link);
790 }
791 }
792
793 LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree.nodes) {
794 if (node->type_legacy != GEO_NODE_OBJECT_INFO) {
795 continue;
796 }
797 bNodeSocket *scale = blender::bke::node_find_socket(*node, SOCK_OUT, "Scale");
798 const Span<bNodeLink *> links = out_links_per_socket.lookup(scale);
799 if (links.is_empty()) {
800 continue;
801 }
802 bNode *absolute_value = blender::bke::node_add_node(nullptr, ntree, "ShaderNodeVectorMath");
803 absolute_value->custom1 = NODE_VECTOR_MATH_ABSOLUTE;
804 absolute_value->parent = node->parent;
805 absolute_value->locx_legacy = node->locx_legacy + 100;
806 absolute_value->locy_legacy = node->locy_legacy - 50;
808 *node,
809 *scale,
810 *absolute_value,
811 *static_cast<bNodeSocket *>(absolute_value->inputs.first));
812 for (bNodeLink *link : links) {
813 link->fromnode = absolute_value;
814 link->fromsock = static_cast<bNodeSocket *>(absolute_value->outputs.first);
815 }
816 }
817}
818
824{
825 bNodeTreeInterface &tree_interface = ntree->tree_interface;
826
827 tree_interface.foreach_item([](bNodeTreeInterfaceItem &item) -> bool {
828 if (item.item_type == NODE_INTERFACE_SOCKET) {
829 bNodeTreeInterfaceSocket &socket = reinterpret_cast<bNodeTreeInterfaceSocket &>(item);
831 socket.socket_type);
832 if (socket.socket_type != corrected_socket_type) {
833 MEM_freeN(socket.socket_type);
834 socket.socket_type = BLI_strdup(corrected_socket_type.data());
835 }
836 }
837 return true;
838 });
839}
840
841static bool strip_filter_bilinear_to_auto(Strip *strip, void * /*user_data*/)
842{
844 if (transform != nullptr && transform->filter == SEQ_TRANSFORM_FILTER_BILINEAR) {
846 }
847 return true;
848}
849
850void blo_do_versions_410(FileData *fd, Library * /*lib*/, Main *bmain)
851{
852 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 1)) {
853 LISTBASE_FOREACH (GreasePencil *, grease_pencil, &bmain->grease_pencils) {
855 }
856 }
857
858 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 4)) {
859 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
860 if (ntree->type != NTREE_CUSTOM) {
861 /* versioning_update_noise_texture_node must be done before
862 * versioning_replace_musgrave_texture_node. */
864
865 /* Convert Musgrave Texture nodes to Noise Texture nodes. */
867 }
868 }
870 }
871
872 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 5)) {
873 /* Unify Material::blend_shadow and Cycles.use_transparent_shadows into the
874 * Material::blend_flag. */
875 bool is_eevee = all_scenes_use(bmain,
877 LISTBASE_FOREACH (Material *, material, &bmain->materials) {
878 bool transparent_shadows = true;
879 if (is_eevee) {
880 transparent_shadows = material->blend_shadow != MA_BS_SOLID;
881 }
882 else if (IDProperty *cmat = version_cycles_properties_from_ID(&material->id)) {
883 transparent_shadows = version_cycles_property_boolean(
884 cmat, "use_transparent_shadow", true);
885 }
886 SET_FLAG_FROM_TEST(material->blend_flag, transparent_shadows, MA_BL_TRANSPARENT_SHADOW);
887 }
888 }
889
890 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 5)) {
892 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
893 if (ntree->type == NTREE_COMPOSIT) {
895 }
896 }
898 }
899
900 /* 401 6 did not require any do_version here. */
901
902 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 7)) {
903 if (!DNA_struct_member_exists(fd->filesdna, "SceneEEVEE", "int", "volumetric_ray_depth")) {
905 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
906 scene->eevee.volumetric_ray_depth = default_eevee.volumetric_ray_depth;
907 }
908 }
909
910 if (!DNA_struct_member_exists(fd->filesdna, "Material", "char", "surface_render_method")) {
911 LISTBASE_FOREACH (Material *, mat, &bmain->materials) {
912 mat->surface_render_method = (mat->blend_method == MA_BM_BLEND) ?
915 }
916 }
917
918 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
919 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
920 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
921 const ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
922 &sl->regionbase;
923 LISTBASE_FOREACH (ARegion *, region, regionbase) {
924 if (region->regiontype != RGN_TYPE_ASSET_SHELF_HEADER) {
925 continue;
926 }
927 region->alignment &= ~RGN_SPLIT_PREV;
928 region->alignment |= RGN_ALIGN_HIDE_WITH_PREV;
929 }
930 }
931 }
932 }
933
934 if (!DNA_struct_member_exists(fd->filesdna, "SceneEEVEE", "float", "gtao_thickness")) {
936 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
937 scene->eevee.gtao_thickness = default_eevee.gtao_thickness;
938 scene->eevee.gtao_focus = default_eevee.gtao_focus;
939 }
940 }
941
942 if (!DNA_struct_member_exists(fd->filesdna, "LightProbe", "float", "data_display_size")) {
944 LISTBASE_FOREACH (LightProbe *, probe, &bmain->lightprobes) {
945 probe->data_display_size = default_probe.data_display_size;
946 }
947 }
948
949 LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) {
950 mesh->flag &= ~ME_NO_OVERLAPPING_TOPOLOGY;
951 }
952 }
953
954 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 8)) {
955 LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
956 if (ntree->type != NTREE_GEOMETRY) {
957 continue;
958 }
960 }
961 }
962
963 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 9)) {
964 if (!DNA_struct_member_exists(fd->filesdna, "Material", "char", "displacement_method")) {
965 /* Replace Cycles.displacement_method by Material::displacement_method. */
966 LISTBASE_FOREACH (Material *, material, &bmain->materials) {
967 int displacement_method = MA_DISPLACEMENT_BUMP;
968 if (IDProperty *cmat = version_cycles_properties_from_ID(&material->id)) {
969 displacement_method = version_cycles_property_int(
970 cmat, "displacement_method", MA_DISPLACEMENT_BUMP);
971 }
972 material->displacement_method = displacement_method;
973 }
974 }
975
976 /* Prevent custom bone colors from having alpha zero.
977 * Part of the fix for issue #115434. */
978 LISTBASE_FOREACH (bArmature *, arm, &bmain->armatures) {
979 blender::animrig::ANIM_armature_foreach_bone(&arm->bonebase, [](Bone *bone) {
980 bone->color.custom.solid[3] = 255;
981 bone->color.custom.select[3] = 255;
982 bone->color.custom.active[3] = 255;
983 });
984 if (arm->edbo) {
985 LISTBASE_FOREACH (EditBone *, ebone, arm->edbo) {
986 ebone->color.custom.solid[3] = 255;
987 ebone->color.custom.select[3] = 255;
988 ebone->color.custom.active[3] = 255;
989 }
990 }
991 }
992 LISTBASE_FOREACH (Object *, obj, &bmain->objects) {
993 if (obj->pose == nullptr) {
994 continue;
995 }
996 LISTBASE_FOREACH (bPoseChannel *, pchan, &obj->pose->chanbase) {
997 pchan->color.custom.solid[3] = 255;
998 pchan->color.custom.select[3] = 255;
999 pchan->color.custom.active[3] = 255;
1000 }
1001 }
1002 }
1003
1004 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 10)) {
1005 if (!DNA_struct_member_exists(
1006 fd->filesdna, "SceneEEVEE", "RaytraceEEVEE", "ray_tracing_options"))
1007 {
1008 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1009 scene->eevee.ray_tracing_options.flag = RAYTRACE_EEVEE_USE_DENOISE;
1010 scene->eevee.ray_tracing_options.denoise_stages = RAYTRACE_EEVEE_DENOISE_SPATIAL |
1013 scene->eevee.ray_tracing_options.screen_trace_quality = 0.25f;
1014 scene->eevee.ray_tracing_options.screen_trace_thickness = 0.2f;
1015 scene->eevee.ray_tracing_options.trace_max_roughness = 0.5f;
1016 scene->eevee.ray_tracing_options.resolution_scale = 2;
1017 }
1018 }
1019
1020 LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
1021 if (ntree->type == NTREE_GEOMETRY) {
1025 }
1026 }
1027 }
1028
1029 if (MAIN_VERSION_FILE_ATLEAST(bmain, 400, 20) && !MAIN_VERSION_FILE_ATLEAST(bmain, 401, 11)) {
1030 /* Convert old socket lists into new interface items. */
1031 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1033 }
1035 }
1036
1037 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 12)) {
1038 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1039 if (ntree->type == NTREE_COMPOSIT) {
1040 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
1041 if (node->type_legacy == CMP_NODE_PIXELATE) {
1042 node->custom1 = 1;
1043 }
1044 }
1045 }
1046 }
1048 }
1049
1050 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 13)) {
1051 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1052 if (ntree->type == NTREE_COMPOSIT) {
1053 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
1054 if (node->type_legacy == CMP_NODE_MAP_UV) {
1056 }
1057 }
1058 }
1059 }
1061 }
1062
1063 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 14)) {
1064 const Brush *default_brush = DNA_struct_default_get(Brush);
1065 LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
1066 brush->automasking_start_normal_limit = default_brush->automasking_start_normal_limit;
1067 brush->automasking_start_normal_falloff = default_brush->automasking_start_normal_falloff;
1068
1069 brush->automasking_view_normal_limit = default_brush->automasking_view_normal_limit;
1070 brush->automasking_view_normal_falloff = default_brush->automasking_view_normal_falloff;
1071 }
1072 }
1073
1074 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 15)) {
1075 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1076 if (ntree->type == NTREE_COMPOSIT) {
1077 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
1078 if (node->type_legacy == CMP_NODE_KEYING) {
1079 NodeKeyingData &keying_data = *static_cast<NodeKeyingData *>(node->storage);
1080 keying_data.edge_kernel_radius = max_ii(keying_data.edge_kernel_radius - 1, 0);
1081 }
1082 }
1083 }
1084 }
1086 }
1087
1088 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 16)) {
1089 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1090 Sculpt *sculpt = scene->toolsettings->sculpt;
1091 if (sculpt != nullptr) {
1092 Sculpt default_sculpt = *DNA_struct_default_get(Sculpt);
1095 }
1096 }
1097 }
1098
1099 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 17)) {
1100 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1101 ToolSettings *ts = scene->toolsettings;
1102 int input_sample_values[9];
1103
1104 input_sample_values[0] = ts->imapaint.paint.num_input_samples_deprecated;
1105 input_sample_values[1] = ts->sculpt != nullptr ?
1107 1;
1108 input_sample_values[2] = ts->curves_sculpt != nullptr ?
1110 1;
1111
1112 input_sample_values[3] = ts->gp_paint != nullptr ?
1114 1;
1115 input_sample_values[4] = ts->gp_vertexpaint != nullptr ?
1117 1;
1118 input_sample_values[5] = ts->gp_sculptpaint != nullptr ?
1120 1;
1121 input_sample_values[6] = ts->gp_weightpaint != nullptr ?
1123 1;
1124
1125 input_sample_values[7] = ts->vpaint != nullptr ?
1127 1;
1128 input_sample_values[8] = ts->wpaint != nullptr ?
1130 1;
1131
1132 int unified_value = 1;
1133 for (int i = 0; i < 9; i++) {
1134 if (input_sample_values[i] != 1) {
1135 if (unified_value == 1) {
1136 unified_value = input_sample_values[i];
1137 }
1138 else {
1139 /* In the case of a user having multiple tools with different num_input_value values
1140 * set we cannot support this in the single UnifiedPaintSettings value, so fallback
1141 * to 1 instead of deciding that one value is more canonical than the other.
1142 */
1143 break;
1144 }
1145 }
1146 }
1147
1148 ts->unified_paint_settings.input_samples = unified_value;
1149 }
1150 LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
1151 brush->input_samples = 1;
1152 }
1153 }
1154
1155 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 18)) {
1156 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1157 if (scene->ed != nullptr) {
1159 &scene->ed->seqbase, strip_filter_bilinear_to_auto, nullptr);
1160 }
1161 }
1162 }
1163
1164 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 19)) {
1165 LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
1166 if (ntree->type == NTREE_GEOMETRY) {
1167 version_node_socket_name(ntree, FN_NODE_ROTATE_ROTATION, "Rotation 1", "Rotation");
1168 version_node_socket_name(ntree, FN_NODE_ROTATE_ROTATION, "Rotation 2", "Rotate By");
1169 }
1170 }
1171 }
1172
1173 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 20)) {
1174 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
1175 int uid = 1;
1176 LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
1177 /* These identifiers are not necessarily stable for linked data. If the linked data has a
1178 * new modifier inserted, the identifiers of other modifiers can change. */
1179 md->persistent_uid = uid++;
1180 }
1181 }
1182 }
1183
1184 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 21)) {
1185 LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
1186 /* The `sculpt_flag` was used to store the `BRUSH_DIR_IN`
1187 * With the fix for #115313 this is now just using the `brush->flag`. */
1188 if (brush->gpencil_settings && (brush->gpencil_settings->sculpt_flag & BRUSH_DIR_IN) != 0) {
1189 brush->flag |= BRUSH_DIR_IN;
1190 }
1191 }
1192 }
1193}
Iterators for armatures.
AnimData * BKE_animdata_from_id(const ID *id)
Definition anim_data.cc:82
Low-level operations for grease pencil.
#define FOREACH_MAIN_ID_END
Definition BKE_main.hh:563
#define MAIN_VERSION_FILE_ATLEAST(main, ver, subver)
Definition BKE_main.hh:634
#define FOREACH_MAIN_ID_BEGIN(_bmain, _id)
Definition BKE_main.hh:557
void BKE_nla_tweakmode_exit(OwnedAnimData owned_adt)
#define FOREACH_NODETREE_END
Definition BKE_node.hh:866
#define FOREACH_NODETREE_BEGIN(bmain, _nodetree, _id)
Definition BKE_node.hh:856
#define SH_NODE_TEX_NOISE
#define GEO_NODE_OBJECT_INFO
#define GEO_NODE_STORE_NAMED_ATTRIBUTE
#define FN_NODE_ROTATE_ROTATION
#define CMP_NODE_VIEWER
#define GEO_NODE_SAMPLE_NEAREST_SURFACE
#define GEO_NODE_EVALUATE_AT_INDEX
#define GEO_NODE_ATTRIBUTE_STATISTIC
#define GEO_NODE_VIEWER
#define SH_NODE_MATH
#define GEO_NODE_INPUT_NAMED_ATTRIBUTE
#define GEO_NODE_RAYCAST
#define CMP_NODE_SPLIT
#define GEO_NODE_SWITCH
#define GEO_NODE_EVALUATE_ON_DOMAIN
#define CMP_NODE_MAP_UV
#define GEO_NODE_ACCUMULATE_FIELD
#define GEO_NODE_SAMPLE_CURVE
#define SH_NODE_TEX_MUSGRAVE_DEPRECATED
#define CMP_NODE_PIXELATE
#define GEO_NODE_SAMPLE_UV_SURFACE
#define SH_NODE_CLAMP
#define GEO_NODE_CAPTURE_ATTRIBUTE
#define CMP_NODE_SPLITVIEWER__DEPRECATED
#define CMP_NODE_KEYING
#define GEO_NODE_BLUR_ATTRIBUTE
#define GEO_NODE_SAMPLE_INDEX
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:534
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
#define LISTBASE_FOREACH_BACKWARD_MUTABLE(type, var, list)
MINLINE int max_ii(int a, int b)
MINLINE void copy_v3_v3(float r[3], const float a[3])
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
Definition string.cc:41
#define STR_ELEM(...)
Definition BLI_string.h:656
char char size_t char * BLI_strncat(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:688
#define SET_FLAG_FROM_TEST(value, test, flag)
#define ELEM(...)
#define STREQ(a, b)
@ ADT_NLA_EDIT_ON
@ BRUSH_DIR_IN
#define DNA_struct_default_get(struct_name)
blenloader genfile private function prototypes
@ MA_DISPLACEMENT_BUMP
@ MA_BS_SOLID
@ MA_BM_BLEND
@ MA_SURFACE_METHOD_DEFERRED
@ MA_SURFACE_METHOD_FORWARD
@ MA_BL_TRANSPARENT_SHADOW
@ ME_NO_OVERLAPPING_TOPOLOGY
@ NODE_VECTOR_MATH_ABSOLUTE
@ NODE_MATH_POWER
@ NODE_MATH_MINIMUM
@ NODE_MATH_GREATER_THAN
@ NODE_MATH_ADD
@ NODE_MATH_MAXIMUM
@ NODE_MATH_MULTIPLY
@ NODE_MATH_SUBTRACT
@ NTREE_CUSTOM
@ NTREE_GEOMETRY
@ NTREE_COMPOSIT
@ CMP_NODE_MAP_UV_FILTERING_ANISOTROPIC
@ SHD_MATH_CLAMP
@ SOCK_OUT
@ SOCK_IN
@ NODE_HIDDEN
@ NODE_PREVIEW
@ SOCK_VECTOR
@ SOCK_FLOAT
@ SOCK_IMAGE
@ SOCK_ROTATION
@ NODE_CLAMP_MINMAX
@ SHD_NOISE_FBM
@ SHD_NOISE_MULTIFRACTAL
@ SHD_NOISE_RIDGED_MULTIFRACTAL
@ SHD_NOISE_HETERO_TERRAIN
@ SCE_NLA_EDIT_ON
@ RAYTRACE_EEVEE_USE_DENOISE
@ RAYTRACE_EEVEE_DENOISE_BILATERAL
@ RAYTRACE_EEVEE_DENOISE_SPATIAL
@ RAYTRACE_EEVEE_DENOISE_TEMPORAL
@ RGN_TYPE_ASSET_SHELF_HEADER
@ RGN_ALIGN_HIDE_WITH_PREV
@ RGN_SPLIT_PREV
@ SEQ_TRANSFORM_FILTER_AUTO
@ SEQ_TRANSFORM_FILTER_BILINEAR
@ PROP_NONE
Definition RNA_types.hh:221
BMesh const char void * data
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
Span< Value > lookup(const Key &key) const
void add(const Key &key, const Value &value)
constexpr IndexRange index_range() const
Definition BLI_span.hh:670
constexpr bool is_empty() const
Definition BLI_span.hh:260
constexpr const char * data() const
MutableSpan< float > radii_for_write()
uint pos
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
static void ANIM_armature_foreach_bone(ListBase *bones, CB callback)
bNodeSocket * node_find_socket(bNode &node, eNodeSocketInOut in_out, StringRef identifier)
Definition node.cc:2864
bNode * node_add_node(const bContext *C, bNodeTree &ntree, StringRef idname)
Definition node.cc:3788
void node_remove_link(bNodeTree *ntree, bNodeLink &link)
Definition node.cc:4124
bNode * node_add_static_node(const bContext *C, bNodeTree &ntree, int type)
Definition node.cc:3804
bNodeLink & node_add_link(bNodeTree &ntree, bNode &fromnode, bNodeSocket &fromsock, bNode &tonode, bNodeSocket &tosock)
Definition node.cc:4087
bNodeSocket * node_add_static_socket(bNodeTree &ntree, bNode &node, eNodeSocketInOut in_out, int type, int subtype, StringRefNull identifier, StringRefNull name)
Definition node.cc:3529
void for_each_callback(ListBase *seqbase, ForEachFunc callback, void *user_data)
Definition iterator.cc:59
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
Definition BLI_task.hh:93
float wrap(float value, float max, float min)
Definition node_math.h:71
const char * RE_engine_id_BLENDER_EEVEE_NEXT
Definition scene.cc:1626
const char * RE_engine_id_BLENDER_EEVEE
Definition scene.cc:1625
NlaStrip * actstrip
NlaTrack * act_track
float automasking_view_normal_limit
float automasking_start_normal_limit
float automasking_start_normal_falloff
float automasking_view_normal_falloff
SDNA * filesdna
Definition readfile.hh:103
Definition DNA_ID.h:404
void * first
ListBase lightprobes
Definition BKE_main.hh:265
ListBase brushes
Definition BKE_main.hh:271
ListBase scenes
Definition BKE_main.hh:245
ListBase grease_pencils
Definition BKE_main.hh:279
ListBase meshes
Definition BKE_main.hh:248
ListBase nodetrees
Definition BKE_main.hh:270
ListBase materials
Definition BKE_main.hh:251
ListBase armatures
Definition BKE_main.hh:268
ListBase screens
Definition BKE_main.hh:261
ListBase objects
Definition BKE_main.hh:247
int num_input_samples_deprecated
int automasking_boundary_edges_propagation_steps
StripTransform * transform
StripData * data
GpWeightPaint * gp_weightpaint
struct ImagePaintSettings imapaint
GpSculptPaint * gp_sculptpaint
struct UnifiedPaintSettings unified_paint_settings
CurvesSculpt * curves_sculpt
GpVertexPaint * gp_vertexpaint
void * default_value
char idname[64]
bNodeTreeInterface tree_interface
ListBase nodes
ListBase links
int16_t custom1
float width
ListBase inputs
float locx_legacy
struct bNode * parent
float locy_legacy
ListBase outputs
int16_t custom2
i
Definition text_draw.cc:230
static bNode * add_node(bNodeTree *ntree, const int type, const blender::float2 loc)
static void versioning_nodes_dynamic_sockets_2(bNodeTree &ntree)
static bool strip_filter_bilinear_to_auto(Strip *strip, void *)
static void versioning_replace_musgrave_texture_node(bNodeTree *ntree)
static void version_nla_tweakmode_incomplete(Main *bmain)
static void version_socket_identifier_suffixes_for_dynamic_types(ListBase sockets, const char *separator, const std::optional< int > total=std::nullopt)
static void versioning_fix_socket_subtype_idnames(bNodeTree *ntree)
void do_versions_after_linking_410(FileData *, Main *bmain)
static void fix_geometry_nodes_object_info_scale(bNodeTree &ntree)
static void change_input_socket_to_rotation_type(bNodeTree &ntree, bNode &node, bNodeSocket &socket)
static void versioning_update_noise_texture_node(bNodeTree *ntree)
static void versioning_replace_splitviewer(bNodeTree *ntree)
static void change_output_socket_to_rotation_type(bNodeTree &ntree, bNode &node, bNodeSocket &socket)
static void version_geometry_nodes_use_rotation_socket(bNodeTree &ntree)
static void versioning_nodes_dynamic_sockets(bNodeTree &ntree)
void blo_do_versions_410(FileData *fd, Library *, Main *bmain)
static void versioning_grease_pencil_stroke_radii_scaling(GreasePencil *grease_pencil)
bool all_scenes_use(Main *bmain, const blender::Span< const char * > engines)
float * version_cycles_node_socket_float_value(bNodeSocket *socket)
IDProperty * version_cycles_properties_from_ID(ID *id)
int version_cycles_property_int(IDProperty *idprop, const char *name, int default_value)
void version_node_input_socket_name(bNodeTree *ntree, const int node_type, const char *old_name, const char *new_name)
void version_node_socket_name(bNodeTree *ntree, const int node_type, const char *old_name, const char *new_name)
StringRef legacy_socket_idname_to_socket_type(StringRef idname)
bool version_cycles_property_boolean(IDProperty *idprop, const char *name, bool default_value)
void version_socket_update_is_used(bNodeTree *ntree)