Blender V5.0
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_string_utf8.h"
35#include "BLI_task.hh"
36
37#include "BKE_anim_data.hh"
38#include "BKE_armature.hh"
39#include "BKE_grease_pencil.hh"
40#include "BKE_main.hh"
41#include "BKE_nla.hh"
42#include "BKE_node.hh"
44#include "BKE_node_runtime.hh"
45
46#include "SEQ_iterator.hh"
47#include "SEQ_sequencer.hh"
48
49#include "readfile.hh"
50
51#include "versioning_common.hh"
52
65{
66 bool any_valid_tweakmode_left = false;
67
68 ID *id;
69 FOREACH_MAIN_ID_BEGIN (bmain, id) {
71 if (!adt || !(adt->flag & ADT_NLA_EDIT_ON)) {
72 continue;
73 }
74
75 if (adt->act_track && adt->actstrip) {
76 /* Expected case. */
77 any_valid_tweakmode_left = true;
78 continue;
79 }
80
81 /* Not enough info in the blend file to reliably stay in tweak mode. This is the most important
82 * part of this versioning code, as it prevents future nullptr access. */
83 BKE_nla_tweakmode_exit({*id, *adt});
84 }
86
87 if (any_valid_tweakmode_left) {
88 /* There are still NLA strips correctly in tweak mode. */
89 return;
90 }
91
92 /* Nothing is in a valid tweakmode, so just disable the corresponding flags on all scenes. */
93 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
94 scene->flag &= ~SCE_NLA_EDIT_ON;
95 }
96}
97
99{
100 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 23)) {
102 }
103}
104
106{
107 using namespace blender;
108 for (GreasePencilDrawingBase *base : grease_pencil->drawings()) {
109 if (base->type != GP_DRAWING) {
110 continue;
111 }
112 bke::greasepencil::Drawing &drawing = reinterpret_cast<GreasePencilDrawing *>(base)->wrap();
113 MutableSpan<float> radii = drawing.radii_for_write();
114 threading::parallel_for(radii.index_range(), 8192, [&](const IndexRange range) {
115 for (const int i : range) {
116 radii[i] *= bke::greasepencil::LEGACY_RADIUS_CONVERSION_FACTOR;
117 }
118 });
119 }
120}
121
123{
124 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
125 if (node->type_legacy != SH_NODE_TEX_NOISE) {
126 continue;
127 }
128
129 (static_cast<NodeTexNoise *>(node->storage))->type = SHD_NOISE_FBM;
130
131 bNodeSocket *roughness_socket = blender::bke::node_find_socket(*node, SOCK_IN, "Roughness");
132 if (roughness_socket == nullptr) {
133 /* Noise Texture node was created before the Roughness input was added. */
134 continue;
135 }
136
137 float *roughness = version_cycles_node_socket_float_value(roughness_socket);
138
139 bNodeLink *roughness_link = nullptr;
140 bNode *roughness_from_node = nullptr;
141 bNodeSocket *roughness_from_socket = nullptr;
142
143 LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
144 /* Find links, nodes and sockets. */
145 if (link->tosock == roughness_socket) {
146 roughness_link = link;
147 roughness_from_node = link->fromnode;
148 roughness_from_socket = link->fromsock;
149 }
150 }
151
152 if (roughness_link != nullptr) {
153 /* Add Clamp node before Roughness input. */
154
155 bNode *clamp_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_CLAMP);
156 clamp_node->parent = node->parent;
157 clamp_node->custom1 = NODE_CLAMP_MINMAX;
158 clamp_node->locx_legacy = node->locx_legacy;
159 clamp_node->locy_legacy = node->locy_legacy - 300.0f;
160 clamp_node->flag |= NODE_COLLAPSED;
161 bNodeSocket *clamp_socket_value = blender::bke::node_find_socket(
162 *clamp_node, SOCK_IN, "Value");
163 bNodeSocket *clamp_socket_min = blender::bke::node_find_socket(*clamp_node, SOCK_IN, "Min");
164 bNodeSocket *clamp_socket_max = blender::bke::node_find_socket(*clamp_node, SOCK_IN, "Max");
166 *clamp_node, SOCK_OUT, "Result");
167
168 *version_cycles_node_socket_float_value(clamp_socket_min) = 0.0f;
169 *version_cycles_node_socket_float_value(clamp_socket_max) = 1.0f;
170
171 blender::bke::node_remove_link(ntree, *roughness_link);
173 *ntree, *roughness_from_node, *roughness_from_socket, *clamp_node, *clamp_socket_value);
175 *ntree, *clamp_node, *clamp_socket_out, *node, *roughness_socket);
176 }
177 else {
178 *roughness = std::clamp(*roughness, 0.0f, 1.0f);
179 }
180 }
181
183}
184
186{
187 version_node_input_socket_name(ntree, SH_NODE_TEX_MUSGRAVE_DEPRECATED, "Dimension", "Roughness");
188 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
189 if (node->type_legacy != SH_NODE_TEX_MUSGRAVE_DEPRECATED) {
190 continue;
191 }
192
193 STRNCPY_UTF8(node->idname, "ShaderNodeTexNoise");
194 node->type_legacy = SH_NODE_TEX_NOISE;
196 data->base = (static_cast<NodeTexMusgrave *>(node->storage))->base;
197 data->dimensions = (static_cast<NodeTexMusgrave *>(node->storage))->dimensions;
198 data->normalize = false;
199 data->type = (static_cast<NodeTexMusgrave *>(node->storage))->musgrave_type;
200 MEM_freeN(node->storage);
201 node->storage = data;
202
203 bNodeLink *detail_link = nullptr;
204 bNode *detail_from_node = nullptr;
205 bNodeSocket *detail_from_socket = nullptr;
206
207 bNodeLink *roughness_link = nullptr;
208 bNode *roughness_from_node = nullptr;
209 bNodeSocket *roughness_from_socket = nullptr;
210
211 bNodeLink *lacunarity_link = nullptr;
212 bNode *lacunarity_from_node = nullptr;
213 bNodeSocket *lacunarity_from_socket = nullptr;
214
215 LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
216 /* Find links, nodes and sockets. */
217 if (link->tonode == node) {
218 if (STREQ(link->tosock->identifier, "Detail")) {
219 detail_link = link;
220 detail_from_node = link->fromnode;
221 detail_from_socket = link->fromsock;
222 }
223 if (STREQ(link->tosock->identifier, "Roughness")) {
224 roughness_link = link;
225 roughness_from_node = link->fromnode;
226 roughness_from_socket = link->fromsock;
227 }
228 if (STREQ(link->tosock->identifier, "Lacunarity")) {
229 lacunarity_link = link;
230 lacunarity_from_node = link->fromnode;
231 lacunarity_from_socket = link->fromsock;
232 }
233 }
234 }
235
236 uint8_t noise_type = (static_cast<NodeTexNoise *>(node->storage))->type;
237 float locy_offset = 0.0f;
238
239 bNodeSocket *fac_socket = blender::bke::node_find_socket(*node, SOCK_OUT, "Fac");
240 /* Clear label because Musgrave output socket label is set to "Height" instead of "Fac". */
241 fac_socket->label[0] = '\0';
242
243 bNodeSocket *detail_socket = blender::bke::node_find_socket(*node, SOCK_IN, "Detail");
244 float *detail = version_cycles_node_socket_float_value(detail_socket);
245
246 if (detail_link != nullptr) {
247 locy_offset -= 80.0f;
248
249 /* Add Minimum Math node and Subtract Math node before Detail input. */
250
251 bNode *min_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_MATH);
252 min_node->parent = node->parent;
253 min_node->custom1 = NODE_MATH_MINIMUM;
254 min_node->locx_legacy = node->locx_legacy;
255 min_node->locy_legacy = node->locy_legacy - 320.0f;
256 min_node->flag |= NODE_COLLAPSED;
257 bNodeSocket *min_socket_A = static_cast<bNodeSocket *>(BLI_findlink(&min_node->inputs, 0));
258 bNodeSocket *min_socket_B = static_cast<bNodeSocket *>(BLI_findlink(&min_node->inputs, 1));
259 bNodeSocket *min_socket_out = blender::bke::node_find_socket(*min_node, SOCK_OUT, "Value");
260
261 bNode *sub1_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_MATH);
262 sub1_node->parent = node->parent;
263 sub1_node->custom1 = NODE_MATH_SUBTRACT;
264 sub1_node->locx_legacy = node->locx_legacy;
265 sub1_node->locy_legacy = node->locy_legacy - 360.0f;
266 sub1_node->flag |= NODE_COLLAPSED;
267 bNodeSocket *sub1_socket_A = static_cast<bNodeSocket *>(BLI_findlink(&sub1_node->inputs, 0));
268 bNodeSocket *sub1_socket_B = static_cast<bNodeSocket *>(BLI_findlink(&sub1_node->inputs, 1));
269 bNodeSocket *sub1_socket_out = blender::bke::node_find_socket(*sub1_node, SOCK_OUT, "Value");
270
271 *version_cycles_node_socket_float_value(min_socket_B) = 14.0f;
272 *version_cycles_node_socket_float_value(sub1_socket_B) = 1.0f;
273
274 blender::bke::node_remove_link(ntree, *detail_link);
276 *ntree, *detail_from_node, *detail_from_socket, *sub1_node, *sub1_socket_A);
277 blender::bke::node_add_link(*ntree, *sub1_node, *sub1_socket_out, *min_node, *min_socket_A);
278 blender::bke::node_add_link(*ntree, *min_node, *min_socket_out, *node, *detail_socket);
279
281 locy_offset -= 40.0f;
282
283 /* Add Greater Than Math node before Subtract Math node. */
284
285 bNode *greater_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_MATH);
286 greater_node->parent = node->parent;
287 greater_node->custom1 = NODE_MATH_GREATER_THAN;
288 greater_node->locx_legacy = node->locx_legacy;
289 greater_node->locy_legacy = node->locy_legacy - 400.0f;
290 greater_node->flag |= NODE_COLLAPSED;
291 bNodeSocket *greater_socket_A = static_cast<bNodeSocket *>(
292 BLI_findlink(&greater_node->inputs, 0));
293 bNodeSocket *greater_socket_B = static_cast<bNodeSocket *>(
294 BLI_findlink(&greater_node->inputs, 1));
295 bNodeSocket *greater_socket_out = blender::bke::node_find_socket(
296 *greater_node, SOCK_OUT, "Value");
297
298 *version_cycles_node_socket_float_value(greater_socket_B) = 1.0f;
299
301 *ntree, *detail_from_node, *detail_from_socket, *greater_node, *greater_socket_A);
303 *ntree, *greater_node, *greater_socket_out, *sub1_node, *sub1_socket_B);
304 }
305 else {
306 /* Add Clamp node and Multiply Math node behind Fac output. */
307
308 bNode *clamp_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_CLAMP);
309 clamp_node->parent = node->parent;
310 clamp_node->custom1 = NODE_CLAMP_MINMAX;
311 clamp_node->locx_legacy = node->locx_legacy;
312 clamp_node->locy_legacy = node->locy_legacy + 40.0f;
313 clamp_node->flag |= NODE_COLLAPSED;
314 bNodeSocket *clamp_socket_value = blender::bke::node_find_socket(
315 *clamp_node, SOCK_IN, "Value");
317 *clamp_node, SOCK_IN, "Min");
319 *clamp_node, SOCK_IN, "Max");
321 *clamp_node, SOCK_OUT, "Result");
322
323 bNode *mul_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_MATH);
324 mul_node->parent = node->parent;
325 mul_node->custom1 = NODE_MATH_MULTIPLY;
326 mul_node->locx_legacy = node->locx_legacy;
327 mul_node->locy_legacy = node->locy_legacy + 80.0f;
328 mul_node->flag |= NODE_COLLAPSED;
329 bNodeSocket *mul_socket_A = static_cast<bNodeSocket *>(BLI_findlink(&mul_node->inputs, 0));
330 bNodeSocket *mul_socket_B = static_cast<bNodeSocket *>(BLI_findlink(&mul_node->inputs, 1));
331 bNodeSocket *mul_socket_out = blender::bke::node_find_socket(*mul_node, SOCK_OUT, "Value");
332
333 *version_cycles_node_socket_float_value(clamp_socket_min) = 0.0f;
334 *version_cycles_node_socket_float_value(clamp_socket_max) = 1.0f;
335
336 if (noise_type == SHD_NOISE_MULTIFRACTAL) {
337 /* Add Subtract Math node and Add Math node after Multiply Math node. */
338
339 bNode *sub2_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_MATH);
340 sub2_node->parent = node->parent;
341 sub2_node->custom1 = NODE_MATH_SUBTRACT;
342 sub2_node->custom2 = SHD_MATH_CLAMP;
343 sub2_node->locx_legacy = node->locx_legacy;
344 sub2_node->locy_legacy = node->locy_legacy + 120.0f;
345 sub2_node->flag |= NODE_COLLAPSED;
346 bNodeSocket *sub2_socket_A = static_cast<bNodeSocket *>(
347 BLI_findlink(&sub2_node->inputs, 0));
348 bNodeSocket *sub2_socket_B = static_cast<bNodeSocket *>(
349 BLI_findlink(&sub2_node->inputs, 1));
351 *sub2_node, SOCK_OUT, "Value");
352
354 add_node->parent = node->parent;
355 add_node->custom1 = NODE_MATH_ADD;
356 add_node->locx_legacy = node->locx_legacy;
357 add_node->locy_legacy = node->locy_legacy + 160.0f;
358 add_node->flag |= NODE_COLLAPSED;
359 bNodeSocket *add_socket_A = static_cast<bNodeSocket *>(
360 BLI_findlink(&add_node->inputs, 0));
361 bNodeSocket *add_socket_B = static_cast<bNodeSocket *>(
362 BLI_findlink(&add_node->inputs, 1));
364 *add_node, SOCK_OUT, "Value");
365
366 *version_cycles_node_socket_float_value(sub2_socket_A) = 1.0f;
367
369 if (link->fromsock == fac_socket) {
371 *ntree, *add_node, *add_socket_out, *link->tonode, *link->tosock);
372 blender::bke::node_remove_link(ntree, *link);
373 }
374 }
375
377 *ntree, *mul_node, *mul_socket_out, *add_node, *add_socket_A);
379 *ntree, *detail_from_node, *detail_from_socket, *sub2_node, *sub2_socket_B);
381 *ntree, *sub2_node, *sub2_socket_out, *add_node, *add_socket_B);
382 }
383 else {
385 if (link->fromsock == fac_socket) {
387 *ntree, *mul_node, *mul_socket_out, *link->tonode, *link->tosock);
388 blender::bke::node_remove_link(ntree, *link);
389 }
390 }
391 }
392
393 blender::bke::node_add_link(*ntree, *node, *fac_socket, *mul_node, *mul_socket_A);
395 *ntree, *detail_from_node, *detail_from_socket, *clamp_node, *clamp_socket_value);
397 *ntree, *clamp_node, *clamp_socket_out, *mul_node, *mul_socket_B);
398 }
399 }
400 else {
401 if (*detail < 1.0f) {
403 /* Add Multiply Math node behind Fac output. */
404
405 bNode *mul_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_MATH);
406 mul_node->parent = node->parent;
407 mul_node->custom1 = NODE_MATH_MULTIPLY;
408 mul_node->locx_legacy = node->locx_legacy;
409 mul_node->locy_legacy = node->locy_legacy + 40.0f;
410 mul_node->flag |= NODE_COLLAPSED;
411 bNodeSocket *mul_socket_A = static_cast<bNodeSocket *>(
412 BLI_findlink(&mul_node->inputs, 0));
413 bNodeSocket *mul_socket_B = static_cast<bNodeSocket *>(
414 BLI_findlink(&mul_node->inputs, 1));
416 *mul_node, SOCK_OUT, "Value");
417
419
420 if (noise_type == SHD_NOISE_MULTIFRACTAL) {
421 /* Add an Add Math node after Multiply Math node. */
422
424 add_node->parent = node->parent;
425 add_node->custom1 = NODE_MATH_ADD;
426 add_node->locx_legacy = node->locx_legacy;
427 add_node->locy_legacy = node->locy_legacy + 80.0f;
428 add_node->flag |= NODE_COLLAPSED;
429 bNodeSocket *add_socket_A = static_cast<bNodeSocket *>(
430 BLI_findlink(&add_node->inputs, 0));
431 bNodeSocket *add_socket_B = static_cast<bNodeSocket *>(
432 BLI_findlink(&add_node->inputs, 1));
434 *add_node, SOCK_OUT, "Value");
435
436 *version_cycles_node_socket_float_value(add_socket_B) = 1.0f - *detail;
437
439 if (link->fromsock == fac_socket) {
441 *ntree, *add_node, *add_socket_out, *link->tonode, *link->tosock);
442 blender::bke::node_remove_link(ntree, *link);
443 }
444 }
445
447 *ntree, *mul_node, *mul_socket_out, *add_node, *add_socket_A);
448 }
449 else {
451 if (link->fromsock == fac_socket) {
453 *ntree, *mul_node, *mul_socket_out, *link->tonode, *link->tosock);
454 blender::bke::node_remove_link(ntree, *link);
455 }
456 }
457 }
458
459 blender::bke::node_add_link(*ntree, *node, *fac_socket, *mul_node, *mul_socket_A);
460
461 *detail = 0.0f;
462 }
463 }
464 else {
465 *detail = std::fminf(*detail - 1.0f, 14.0f);
466 }
467 }
468
469 bNodeSocket *roughness_socket = blender::bke::node_find_socket(*node, SOCK_IN, "Roughness");
470 float *roughness = version_cycles_node_socket_float_value(roughness_socket);
471 bNodeSocket *lacunarity_socket = blender::bke::node_find_socket(*node, SOCK_IN, "Lacunarity");
472 float *lacunarity = version_cycles_node_socket_float_value(lacunarity_socket);
473
474 *roughness = std::fmaxf(*roughness, 1e-5f);
475 *lacunarity = std::fmaxf(*lacunarity, 1e-5f);
476
477 if (roughness_link != nullptr) {
478 /* Add Maximum Math node after output of roughness_from_node. Add Multiply Math node and
479 * Power Math node before Roughness input. */
480
481 bNode *max1_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_MATH);
482 max1_node->parent = node->parent;
483 max1_node->custom1 = NODE_MATH_MAXIMUM;
484 max1_node->locx_legacy = node->locx_legacy;
485 max1_node->locy_legacy = node->locy_legacy - 400.0f + locy_offset;
486 max1_node->flag |= NODE_COLLAPSED;
487 bNodeSocket *max1_socket_A = static_cast<bNodeSocket *>(BLI_findlink(&max1_node->inputs, 0));
488 bNodeSocket *max1_socket_B = static_cast<bNodeSocket *>(BLI_findlink(&max1_node->inputs, 1));
489 bNodeSocket *max1_socket_out = blender::bke::node_find_socket(*max1_node, SOCK_OUT, "Value");
490
491 bNode *mul_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_MATH);
492 mul_node->parent = node->parent;
493 mul_node->custom1 = NODE_MATH_MULTIPLY;
494 mul_node->locx_legacy = node->locx_legacy;
495 mul_node->locy_legacy = node->locy_legacy - 360.0f + locy_offset;
496 mul_node->flag |= NODE_COLLAPSED;
497 bNodeSocket *mul_socket_A = static_cast<bNodeSocket *>(BLI_findlink(&mul_node->inputs, 0));
498 bNodeSocket *mul_socket_B = static_cast<bNodeSocket *>(BLI_findlink(&mul_node->inputs, 1));
499 bNodeSocket *mul_socket_out = blender::bke::node_find_socket(*mul_node, SOCK_OUT, "Value");
500
501 bNode *pow_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_MATH);
502 pow_node->parent = node->parent;
503 pow_node->custom1 = NODE_MATH_POWER;
504 pow_node->locx_legacy = node->locx_legacy;
505 pow_node->locy_legacy = node->locy_legacy - 320.0f + locy_offset;
506 pow_node->flag |= NODE_COLLAPSED;
507 bNodeSocket *pow_socket_A = static_cast<bNodeSocket *>(BLI_findlink(&pow_node->inputs, 0));
508 bNodeSocket *pow_socket_B = static_cast<bNodeSocket *>(BLI_findlink(&pow_node->inputs, 1));
509 bNodeSocket *pow_socket_out = blender::bke::node_find_socket(*pow_node, SOCK_OUT, "Value");
510
511 *version_cycles_node_socket_float_value(max1_socket_B) = -1e-5f;
512 *version_cycles_node_socket_float_value(mul_socket_B) = -1.0f;
513 *version_cycles_node_socket_float_value(pow_socket_A) = *lacunarity;
514
515 blender::bke::node_remove_link(ntree, *roughness_link);
517 *ntree, *roughness_from_node, *roughness_from_socket, *max1_node, *max1_socket_A);
518 blender::bke::node_add_link(*ntree, *max1_node, *max1_socket_out, *mul_node, *mul_socket_A);
519 blender::bke::node_add_link(*ntree, *mul_node, *mul_socket_out, *pow_node, *pow_socket_B);
520 blender::bke::node_add_link(*ntree, *pow_node, *pow_socket_out, *node, *roughness_socket);
521
522 if (lacunarity_link != nullptr) {
523 /* Add Maximum Math node after output of lacunarity_from_node. */
524
525 bNode *max2_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_MATH);
526 max2_node->parent = node->parent;
527 max2_node->custom1 = NODE_MATH_MAXIMUM;
528 max2_node->locx_legacy = node->locx_legacy;
529 max2_node->locy_legacy = node->locy_legacy - 440.0f + locy_offset;
530 max2_node->flag |= NODE_COLLAPSED;
531 bNodeSocket *max2_socket_A = static_cast<bNodeSocket *>(
532 BLI_findlink(&max2_node->inputs, 0));
533 bNodeSocket *max2_socket_B = static_cast<bNodeSocket *>(
534 BLI_findlink(&max2_node->inputs, 1));
536 *max2_node, SOCK_OUT, "Value");
537
538 *version_cycles_node_socket_float_value(max2_socket_B) = -1e-5f;
539
540 blender::bke::node_remove_link(ntree, *lacunarity_link);
542 *ntree, *lacunarity_from_node, *lacunarity_from_socket, *max2_node, *max2_socket_A);
544 *ntree, *max2_node, *max2_socket_out, *pow_node, *pow_socket_A);
546 *ntree, *max2_node, *max2_socket_out, *node, *lacunarity_socket);
547 }
548 }
549 else if ((lacunarity_link != nullptr) && (roughness_link == nullptr)) {
550 /* Add Maximum Math node after output of lacunarity_from_node. Add Power Math node before
551 * Roughness input. */
552
553 bNode *max2_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_MATH);
554 max2_node->parent = node->parent;
555 max2_node->custom1 = NODE_MATH_MAXIMUM;
556 max2_node->locx_legacy = node->locx_legacy;
557 max2_node->locy_legacy = node->locy_legacy - 360.0f + locy_offset;
558 max2_node->flag |= NODE_COLLAPSED;
559 bNodeSocket *max2_socket_A = static_cast<bNodeSocket *>(BLI_findlink(&max2_node->inputs, 0));
560 bNodeSocket *max2_socket_B = static_cast<bNodeSocket *>(BLI_findlink(&max2_node->inputs, 1));
561 bNodeSocket *max2_socket_out = blender::bke::node_find_socket(*max2_node, SOCK_OUT, "Value");
562
563 bNode *pow_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_MATH);
564 pow_node->parent = node->parent;
565 pow_node->custom1 = NODE_MATH_POWER;
566 pow_node->locx_legacy = node->locx_legacy;
567 pow_node->locy_legacy = node->locy_legacy - 320.0f + locy_offset;
568 pow_node->flag |= NODE_COLLAPSED;
569 bNodeSocket *pow_socket_A = static_cast<bNodeSocket *>(BLI_findlink(&pow_node->inputs, 0));
570 bNodeSocket *pow_socket_B = static_cast<bNodeSocket *>(BLI_findlink(&pow_node->inputs, 1));
571 bNodeSocket *pow_socket_out = blender::bke::node_find_socket(*pow_node, SOCK_OUT, "Value");
572
573 *version_cycles_node_socket_float_value(max2_socket_B) = -1e-5f;
574 *version_cycles_node_socket_float_value(pow_socket_A) = *lacunarity;
575 *version_cycles_node_socket_float_value(pow_socket_B) = -(*roughness);
576
577 blender::bke::node_remove_link(ntree, *lacunarity_link);
579 *ntree, *lacunarity_from_node, *lacunarity_from_socket, *max2_node, *max2_socket_A);
580 blender::bke::node_add_link(*ntree, *max2_node, *max2_socket_out, *pow_node, *pow_socket_A);
581 blender::bke::node_add_link(*ntree, *max2_node, *max2_socket_out, *node, *lacunarity_socket);
582 blender::bke::node_add_link(*ntree, *pow_node, *pow_socket_out, *node, *roughness_socket);
583 }
584 else {
585 *roughness = std::pow(*lacunarity, -(*roughness));
586 }
587 }
588
590}
591
593{
594 /* Split viewer was replaced with a regular split node, so add a viewer node,
595 * and link it to the new split node to achieve the same behavior of the split viewer node. */
596
597 LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree->nodes) {
598 if (node->type_legacy != CMP_NODE_SPLITVIEWER__DEPRECATED) {
599 continue;
600 }
601
602 STRNCPY_UTF8(node->idname, "CompositorNodeSplit");
603 node->type_legacy = CMP_NODE_SPLIT;
604 MEM_freeN(node->storage);
605 node->storage = nullptr;
606
607 bNode *viewer_node = blender::bke::node_add_static_node(nullptr, *ntree, CMP_NODE_VIEWER);
608 /* Nodes are created stacked on top of each other, so separate them a bit. */
609 viewer_node->locx_legacy = node->locx_legacy + node->width + viewer_node->width / 4.0f;
610 viewer_node->locy_legacy = node->locy_legacy;
611 viewer_node->flag &= ~NODE_PREVIEW;
612
614 *ntree, *node, SOCK_OUT, SOCK_IMAGE, PROP_NONE, "Image", "Image");
615 bNodeSocket *viewer_in_socket = blender::bke::node_find_socket(*viewer_node, SOCK_IN, "Image");
616
617 blender::bke::node_add_link(*ntree, *node, *split_out_socket, *viewer_node, *viewer_in_socket);
618 }
619}
620
622 ListBase sockets, const char *separator, const std::optional<int> total = std::nullopt)
623{
624 int index = 0;
625 LISTBASE_FOREACH (bNodeSocket *, socket, &sockets) {
626 if (socket->is_available()) {
627 if (char *pos = strstr(socket->identifier, separator)) {
628 /* End the identifier at the separator so that the old suffix is ignored. */
629 *pos = '\0';
630
631 if (total.has_value()) {
632 index++;
633 if (index == *total) {
634 return;
635 }
636 }
637 }
638 }
639 else {
640 /* Rename existing identifiers so that they don't conflict with the renamed one. Those will
641 * be removed after versioning code. */
642 BLI_strncat(socket->identifier, "_deprecated", sizeof(socket->identifier));
643 }
644 }
645}
646
648{
649 LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
650 switch (node->type_legacy) {
652 /* This node requires the extra `total` parameter, because the `Group Index` identifier
653 * also has a space in the name, that should not be treated as separator. */
656 break;
663 case GEO_NODE_RAYCAST:
668 case GEO_NODE_VIEWER:
671 break;
672 }
673 }
674}
675
677{
678 LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
679 if (!ELEM(node->type_legacy, GEO_NODE_SWITCH, GEO_NODE_SAMPLE_CURVE)) {
680 continue;
681 }
684 }
685}
686
688 bNode &node,
689 bNodeSocket &socket)
690{
691 if (socket.type == SOCK_ROTATION) {
692 return;
693 }
694 socket.type = SOCK_ROTATION;
695 STRNCPY_UTF8(socket.idname, "NodeSocketRotation");
696 auto *old_value = static_cast<bNodeSocketValueVector *>(socket.default_value);
697 auto *new_value = MEM_callocN<bNodeSocketValueRotation>(__func__);
698 copy_v3_v3(new_value->value_euler, old_value->value);
699 socket.default_value = new_value;
700 MEM_freeN(old_value);
701 LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree.links) {
702 if (link->tosock != &socket) {
703 continue;
704 }
705 if (ELEM(link->fromsock->type, SOCK_ROTATION, SOCK_VECTOR, SOCK_FLOAT) &&
706 !link->fromnode->is_reroute())
707 {
708 /* No need to add the conversion node when implicit conversions will work. */
709 continue;
710 }
711 if (STREQ(link->fromnode->idname, "FunctionNodeEulerToRotation")) {
712 /* Make versioning idempotent. */
713 continue;
714 }
715 bNode *convert = blender::bke::node_add_node(nullptr, ntree, "FunctionNodeEulerToRotation");
716 convert->parent = node.parent;
717 convert->locx_legacy = node.locx_legacy - 40;
718 convert->locy_legacy = node.locy_legacy;
719 link->tonode = convert;
720 link->tosock = blender::bke::node_find_socket(*convert, SOCK_IN, "Euler");
721
723 *convert,
724 *blender::bke::node_find_socket(*convert, SOCK_OUT, "Rotation"),
725 node,
726 socket);
727 }
728}
729
731 bNode &node,
732 bNodeSocket &socket)
733{
734 /* Rely on generic node declaration update to change the socket type. */
735 LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree.links) {
736 if (link->fromsock != &socket) {
737 continue;
738 }
739 if (ELEM(link->tosock->type, SOCK_ROTATION, SOCK_VECTOR) && !link->tonode->is_reroute()) {
740 /* No need to add the conversion node when implicit conversions will work. */
741 continue;
742 }
743 if (STREQ(link->tonode->idname, "FunctionNodeRotationToEuler"))
744 { /* Make versioning idempotent. */
745 continue;
746 }
747 bNode *convert = blender::bke::node_add_node(nullptr, ntree, "FunctionNodeRotationToEuler");
748 convert->parent = node.parent;
749 convert->locx_legacy = node.locx_legacy + 40;
750 convert->locy_legacy = node.locy_legacy;
751 link->fromnode = convert;
752 link->fromsock = blender::bke::node_find_socket(*convert, SOCK_OUT, "Euler");
753
755 node,
756 socket,
757 *convert,
758 *blender::bke::node_find_socket(*convert, SOCK_IN, "Rotation"));
759 }
760}
761
763{
764 LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree.nodes) {
765 if (STR_ELEM(node->idname,
766 "GeometryNodeInstanceOnPoints",
767 "GeometryNodeRotateInstances",
768 "GeometryNodeTransform"))
769 {
770 bNodeSocket *socket = blender::bke::node_find_socket(*node, SOCK_IN, "Rotation");
771 change_input_socket_to_rotation_type(ntree, *node, *socket);
772 }
773 if (STR_ELEM(node->idname,
774 "GeometryNodeDistributePointsOnFaces",
775 "GeometryNodeObjectInfo",
776 "GeometryNodeInputInstanceRotation"))
777 {
778 bNodeSocket *socket = blender::bke::node_find_socket(*node, SOCK_OUT, "Rotation");
779 change_output_socket_to_rotation_type(ntree, *node, *socket);
780 }
781 }
782}
783
785{
786 using namespace blender;
788 LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) {
789 if (link->fromnode->type_legacy == GEO_NODE_OBJECT_INFO) {
790 out_links_per_socket.add(link->fromsock, link);
791 }
792 }
793
794 LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree.nodes) {
795 if (node->type_legacy != GEO_NODE_OBJECT_INFO) {
796 continue;
797 }
798 bNodeSocket *scale = blender::bke::node_find_socket(*node, SOCK_OUT, "Scale");
799 const Span<bNodeLink *> links = out_links_per_socket.lookup(scale);
800 if (links.is_empty()) {
801 continue;
802 }
803 bNode *absolute_value = blender::bke::node_add_node(nullptr, ntree, "ShaderNodeVectorMath");
804 absolute_value->custom1 = NODE_VECTOR_MATH_ABSOLUTE;
805 absolute_value->parent = node->parent;
806 absolute_value->locx_legacy = node->locx_legacy + 100;
807 absolute_value->locy_legacy = node->locy_legacy - 50;
809 *node,
810 *scale,
811 *absolute_value,
812 *static_cast<bNodeSocket *>(absolute_value->inputs.first));
813 for (bNodeLink *link : links) {
814 link->fromnode = absolute_value;
815 link->fromsock = static_cast<bNodeSocket *>(absolute_value->outputs.first);
816 }
817 }
818}
819
825{
826 bNodeTreeInterface &tree_interface = ntree->tree_interface;
827
828 tree_interface.foreach_item([](bNodeTreeInterfaceItem &item) -> bool {
829 if (item.item_type == NODE_INTERFACE_SOCKET) {
830 bNodeTreeInterfaceSocket &socket = reinterpret_cast<bNodeTreeInterfaceSocket &>(item);
832 socket.socket_type);
833 if (socket.socket_type != corrected_socket_type) {
834 MEM_freeN(socket.socket_type);
835 socket.socket_type = BLI_strdup(corrected_socket_type.data());
836 }
837 }
838 return true;
839 });
840}
841
842static bool strip_filter_bilinear_to_auto(Strip *strip, void * /*user_data*/)
843{
845 if (transform != nullptr && transform->filter == SEQ_TRANSFORM_FILTER_BILINEAR) {
847 }
848 return true;
849}
850
851void blo_do_versions_410(FileData *fd, Library * /*lib*/, Main *bmain)
852{
853 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 1)) {
854 LISTBASE_FOREACH (GreasePencil *, grease_pencil, &bmain->grease_pencils) {
856 }
857 }
858
859 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 4)) {
860 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
861 if (ntree->type != NTREE_CUSTOM) {
862 /* versioning_update_noise_texture_node must be done before
863 * versioning_replace_musgrave_texture_node. */
865
866 /* Convert Musgrave Texture nodes to Noise Texture nodes. */
868 }
869 }
871 }
872
873 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 5)) {
874 /* Unify Material::blend_shadow and Cycles.use_transparent_shadows into the
875 * Material::blend_flag. */
876 bool is_eevee = all_scenes_use(bmain,
878 LISTBASE_FOREACH (Material *, material, &bmain->materials) {
879 bool transparent_shadows = true;
880 if (is_eevee) {
881 transparent_shadows = material->blend_shadow != MA_BS_SOLID;
882 }
883 else if (IDProperty *cmat = version_cycles_properties_from_ID(&material->id)) {
884 transparent_shadows = version_cycles_property_boolean(
885 cmat, "use_transparent_shadow", true);
886 }
887 SET_FLAG_FROM_TEST(material->blend_flag, transparent_shadows, MA_BL_TRANSPARENT_SHADOW);
888 }
889 }
890
891 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 5)) {
893 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
894 if (ntree->type == NTREE_COMPOSIT) {
896 }
897 }
899 }
900
901 /* 401 6 did not require any do_version here. */
902
903 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 7)) {
904 if (!DNA_struct_member_exists(fd->filesdna, "SceneEEVEE", "int", "volumetric_ray_depth")) {
906 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
907 scene->eevee.volumetric_ray_depth = default_eevee.volumetric_ray_depth;
908 }
909 }
910
911 if (!DNA_struct_member_exists(fd->filesdna, "Material", "char", "surface_render_method")) {
912 LISTBASE_FOREACH (Material *, mat, &bmain->materials) {
913 mat->surface_render_method = (mat->blend_method == MA_BM_BLEND) ?
916 }
917 }
918
919 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
920 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
921 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
922 const ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
923 &sl->regionbase;
924 LISTBASE_FOREACH (ARegion *, region, regionbase) {
925 if (region->regiontype != RGN_TYPE_ASSET_SHELF_HEADER) {
926 continue;
927 }
928 region->alignment &= ~RGN_SPLIT_PREV;
929 region->alignment |= RGN_ALIGN_HIDE_WITH_PREV;
930 }
931 }
932 }
933 }
934
935 if (!DNA_struct_member_exists(fd->filesdna, "SceneEEVEE", "float", "gtao_thickness")) {
937 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
938 scene->eevee.gtao_thickness = default_eevee.gtao_thickness;
939 scene->eevee.fast_gi_bias = default_eevee.fast_gi_bias;
940 }
941 }
942
943 if (!DNA_struct_member_exists(fd->filesdna, "LightProbe", "float", "data_display_size")) {
945 LISTBASE_FOREACH (LightProbe *, probe, &bmain->lightprobes) {
946 probe->data_display_size = default_probe.data_display_size;
947 }
948 }
949
950 LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) {
951 mesh->flag &= ~ME_NO_OVERLAPPING_TOPOLOGY;
952 }
953 }
954
955 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 8)) {
956 LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
957 if (ntree->type != NTREE_GEOMETRY) {
958 continue;
959 }
961 }
962 }
963
964 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 9)) {
965 if (!DNA_struct_member_exists(fd->filesdna, "Material", "char", "displacement_method")) {
966 /* Replace Cycles.displacement_method by Material::displacement_method. */
967 LISTBASE_FOREACH (Material *, material, &bmain->materials) {
968 int displacement_method = MA_DISPLACEMENT_BUMP;
969 if (IDProperty *cmat = version_cycles_properties_from_ID(&material->id)) {
970 displacement_method = version_cycles_property_int(
971 cmat, "displacement_method", MA_DISPLACEMENT_BUMP);
972 }
973 material->displacement_method = displacement_method;
974 }
975 }
976
977 /* Prevent custom bone colors from having alpha zero.
978 * Part of the fix for issue #115434. */
979 LISTBASE_FOREACH (bArmature *, arm, &bmain->armatures) {
980 blender::animrig::ANIM_armature_foreach_bone(&arm->bonebase, [](Bone *bone) {
981 bone->color.custom.solid[3] = 255;
982 bone->color.custom.select[3] = 255;
983 bone->color.custom.active[3] = 255;
984 });
985 if (arm->edbo) {
986 LISTBASE_FOREACH (EditBone *, ebone, arm->edbo) {
987 ebone->color.custom.solid[3] = 255;
988 ebone->color.custom.select[3] = 255;
989 ebone->color.custom.active[3] = 255;
990 }
991 }
992 }
993 LISTBASE_FOREACH (Object *, obj, &bmain->objects) {
994 if (obj->pose == nullptr) {
995 continue;
996 }
997 LISTBASE_FOREACH (bPoseChannel *, pchan, &obj->pose->chanbase) {
998 pchan->color.custom.solid[3] = 255;
999 pchan->color.custom.select[3] = 255;
1000 pchan->color.custom.active[3] = 255;
1001 }
1002 }
1003 }
1004
1005 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 10)) {
1006 if (!DNA_struct_member_exists(
1007 fd->filesdna, "SceneEEVEE", "RaytraceEEVEE", "ray_tracing_options"))
1008 {
1009 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1010 scene->eevee.ray_tracing_options.flag = RAYTRACE_EEVEE_USE_DENOISE;
1011 scene->eevee.ray_tracing_options.denoise_stages = RAYTRACE_EEVEE_DENOISE_SPATIAL |
1014 scene->eevee.ray_tracing_options.screen_trace_quality = 0.25f;
1015 scene->eevee.ray_tracing_options.screen_trace_thickness = 0.2f;
1016 scene->eevee.ray_tracing_options.trace_max_roughness = 0.5f;
1017 scene->eevee.ray_tracing_options.resolution_scale = 2;
1018 }
1019 }
1020
1021 LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
1022 if (ntree->type == NTREE_GEOMETRY) {
1026 }
1027 }
1028 }
1029
1030 if (MAIN_VERSION_FILE_ATLEAST(bmain, 400, 20) && !MAIN_VERSION_FILE_ATLEAST(bmain, 401, 11)) {
1031 /* Convert old socket lists into new interface items. */
1032 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1034 }
1036 }
1037
1038 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 12)) {
1039 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1040 if (ntree->type == NTREE_COMPOSIT) {
1041 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
1042 if (node->type_legacy == CMP_NODE_PIXELATE) {
1043 node->custom1 = 1;
1044 }
1045 }
1046 }
1047 }
1049 }
1050
1051 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 13)) {
1052 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1053 if (ntree->type == NTREE_COMPOSIT) {
1054 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
1055 if (node->type_legacy == CMP_NODE_MAP_UV) {
1056 node->custom2 = CMP_NODE_INTERPOLATION_ANISOTROPIC;
1057 }
1058 }
1059 }
1060 }
1062 }
1063
1064 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 14)) {
1065 const Brush *default_brush = DNA_struct_default_get(Brush);
1066 LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
1067 brush->automasking_start_normal_limit = default_brush->automasking_start_normal_limit;
1068 brush->automasking_start_normal_falloff = default_brush->automasking_start_normal_falloff;
1069
1070 brush->automasking_view_normal_limit = default_brush->automasking_view_normal_limit;
1071 brush->automasking_view_normal_falloff = default_brush->automasking_view_normal_falloff;
1072 }
1073 }
1074
1075 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 15)) {
1076 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1077 if (ntree->type == NTREE_COMPOSIT) {
1078 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
1079 if (node->type_legacy == CMP_NODE_KEYING) {
1080 NodeKeyingData &keying_data = *static_cast<NodeKeyingData *>(node->storage);
1081 keying_data.edge_kernel_radius = max_ii(keying_data.edge_kernel_radius - 1, 0);
1082 }
1083 }
1084 }
1085 }
1087 }
1088
1089 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 16)) {
1090 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1091 Sculpt *sculpt = scene->toolsettings->sculpt;
1092 if (sculpt != nullptr) {
1093 Sculpt default_sculpt = blender::dna::shallow_copy(*DNA_struct_default_get(Sculpt));
1096 }
1097 }
1098 }
1099
1100 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 17)) {
1101 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1102 ToolSettings *ts = scene->toolsettings;
1103 int input_sample_values[9];
1104
1105 input_sample_values[0] = ts->imapaint.paint.num_input_samples_deprecated;
1106 input_sample_values[1] = ts->sculpt != nullptr ?
1108 1;
1109 input_sample_values[2] = ts->curves_sculpt != nullptr ?
1111 1;
1112
1113 input_sample_values[3] = ts->gp_paint != nullptr ?
1115 1;
1116 input_sample_values[4] = ts->gp_vertexpaint != nullptr ?
1118 1;
1119 input_sample_values[5] = ts->gp_sculptpaint != nullptr ?
1121 1;
1122 input_sample_values[6] = ts->gp_weightpaint != nullptr ?
1124 1;
1125
1126 input_sample_values[7] = ts->vpaint != nullptr ?
1128 1;
1129 input_sample_values[8] = ts->wpaint != nullptr ?
1131 1;
1132
1133 int unified_value = 1;
1134 for (int i = 0; i < 9; i++) {
1135 if (input_sample_values[i] != 1) {
1136 if (unified_value == 1) {
1137 unified_value = input_sample_values[i];
1138 }
1139 else {
1140 /* In the case of a user having multiple tools with different num_input_value values
1141 * set we cannot support this in the single UnifiedPaintSettings value, so fallback
1142 * to 1 instead of deciding that one value is more canonical than the other.
1143 */
1144 break;
1145 }
1146 }
1147 }
1148
1149 ts->unified_paint_settings.input_samples = unified_value;
1150 }
1151 LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
1152 brush->input_samples = 1;
1153 }
1154 }
1155
1156 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 18)) {
1157 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1158 if (scene->ed != nullptr) {
1159 blender::seq::foreach_strip(&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:83
Low-level operations for grease pencil.
#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
void BKE_nla_tweakmode_exit(OwnedAnimData owned_adt)
#define FOREACH_NODETREE_END
Definition BKE_node.hh:881
#define FOREACH_NODETREE_BEGIN(bmain, _nodetree, _id)
Definition BKE_node.hh:871
#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:661
char char size_t char * BLI_strncat(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define STRNCPY_UTF8(dst, src)
#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_BL_TRANSPARENT_SHADOW
@ MA_SURFACE_METHOD_DEFERRED
@ MA_SURFACE_METHOD_FORWARD
@ MA_BM_BLEND
@ MA_BS_SOLID
@ MA_DISPLACEMENT_BUMP
@ ME_NO_OVERLAPPING_TOPOLOGY
@ NODE_VECTOR_MATH_ABSOLUTE
@ CMP_NODE_INTERPOLATION_ANISOTROPIC
@ SHD_MATH_CLAMP
@ NODE_MATH_POWER
@ NODE_MATH_MINIMUM
@ NODE_MATH_GREATER_THAN
@ NODE_MATH_ADD
@ NODE_MATH_MAXIMUM
@ NODE_MATH_MULTIPLY
@ NODE_MATH_SUBTRACT
@ SHD_NOISE_FBM
@ SHD_NOISE_MULTIFRACTAL
@ SHD_NOISE_RIDGED_MULTIFRACTAL
@ SHD_NOISE_HETERO_TERRAIN
@ NODE_CLAMP_MINMAX
@ NODE_COLLAPSED
@ NODE_PREVIEW
@ NTREE_CUSTOM
@ NTREE_GEOMETRY
@ NTREE_COMPOSIT
@ SOCK_OUT
@ SOCK_IN
@ SOCK_VECTOR
@ SOCK_FLOAT
@ SOCK_IMAGE
@ SOCK_ROTATION
@ RAYTRACE_EEVEE_USE_DENOISE
@ SCE_NLA_EDIT_ON
@ RAYTRACE_EEVEE_DENOISE_BILATERAL
@ RAYTRACE_EEVEE_DENOISE_SPATIAL
@ RAYTRACE_EEVEE_DENOISE_TEMPORAL
@ RGN_ALIGN_HIDE_WITH_PREV
@ RGN_SPLIT_PREV
@ RGN_TYPE_ASSET_SHELF_HEADER
@ SEQ_TRANSFORM_FILTER_AUTO
@ SEQ_TRANSFORM_FILTER_BILINEAR
@ PROP_NONE
Definition RNA_types.hh:233
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:2532
bNode * node_add_node(const bContext *C, bNodeTree &ntree, StringRef idname, std::optional< int > unique_identifier=std::nullopt)
Definition node.cc:3477
void node_remove_link(bNodeTree *ntree, bNodeLink &link)
Definition node.cc:3847
bNode * node_add_static_node(const bContext *C, bNodeTree &ntree, int type)
Definition node.cc:3500
bNodeLink & node_add_link(bNodeTree &ntree, bNode &fromnode, bNodeSocket &fromsock, bNode &tonode, bNodeSocket &tosock)
Definition node.cc:3810
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 foreach_strip(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:103
const char * RE_engine_id_BLENDER_EEVEE_NEXT
Definition scene.cc:1581
const char * RE_engine_id_BLENDER_EEVEE
Definition scene.cc:1580
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:105
Definition DNA_ID.h:414
void * first
ListBase lightprobes
Definition BKE_main.hh:296
ListBase brushes
Definition BKE_main.hh:302
ListBase scenes
Definition BKE_main.hh:278
ListBase grease_pencils
Definition BKE_main.hh:310
ListBase meshes
Definition BKE_main.hh:281
ListBase nodetrees
Definition BKE_main.hh:301
ListBase materials
Definition BKE_main.hh:284
ListBase armatures
Definition BKE_main.hh:299
ListBase screens
Definition BKE_main.hh:292
ListBase objects
Definition BKE_main.hh:280
int num_input_samples_deprecated
int automasking_boundary_edges_propagation_steps
StripTransform * transform
StripData * data
GpWeightPaint * gp_weightpaint
struct ImagePaintSettings imapaint
GpSculptPaint * gp_sculptpaint
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)