Blender V4.5
versioning_450.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2025 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#define DNA_DEPRECATED_ALLOW
10
11#include <fmt/format.h>
12
13#include "DNA_anim_types.h"
14#include "DNA_brush_types.h"
15#include "DNA_defaults.h"
16#include "DNA_light_types.h"
17#include "DNA_mesh_types.h"
18#include "DNA_modifier_types.h"
20#include "DNA_sequence_types.h"
21
22#include "BLI_listbase.h"
23#include "BLI_math_vector.h"
24#include "BLI_set.hh"
25#include "BLI_string.h"
26#include "BLI_string_utf8.h"
27#include "BLI_string_utils.hh"
28#include "BLI_sys_types.h"
29
30#include "BKE_anim_data.hh"
31#include "BKE_animsys.h"
32#include "BKE_armature.hh"
33#include "BKE_curves.hh"
34#include "BKE_customdata.hh"
35#include "BKE_fcurve.hh"
36#include "BKE_grease_pencil.hh"
37#include "BKE_idprop.hh"
38#include "BKE_lib_id.hh"
39#include "BKE_lib_override.hh"
40#include "BKE_lib_query.hh"
41#include "BKE_main.hh"
43#include "BKE_node.hh"
45#include "BKE_node_runtime.hh"
46#include "BKE_paint.hh"
47
48#include "SEQ_iterator.hh"
49#include "SEQ_sequencer.hh"
50
51#include "ANIM_action.hh"
53#include "ANIM_armature_iter.hh"
54#include "BKE_colortools.hh"
55
56#include "RNA_access.hh"
57
58#include "readfile.hh"
59
60#include "versioning_common.hh"
61
62// static CLG_LogRef LOG = {"blo.readfile.doversion"};
63
65{
66 auto idprops_process = [](IDProperty **idprops, IDProperty *system_idprops) -> void {
67 if (system_idprops) {
68 /* Other ID pointers have not yet been relinked,
69 * do not try to access them for reference-counting. */
70 if (*idprops) {
71 IDP_MergeGroup_ex(*idprops, system_idprops, true, LIB_ID_CREATE_NO_USER_REFCOUNT);
72 }
73 else {
74 *idprops = IDP_CopyProperty_ex(system_idprops, LIB_ID_CREATE_NO_USER_REFCOUNT);
75 }
76 }
77 };
78
79 ID *id_iter;
80 FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
81 idprops_process(&id_iter->properties, id_iter->system_properties);
82 }
84
85 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
86 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
87 idprops_process(&view_layer->id_properties, view_layer->system_properties);
88 }
89
90 if (scene->ed != nullptr) {
91 blender::seq::for_each_callback(&scene->ed->seqbase,
92 [&idprops_process](Strip *strip) -> bool {
93 idprops_process(&strip->prop, strip->system_properties);
94 return true;
95 });
96 }
97 }
98
99 LISTBASE_FOREACH (Object *, object, &bmain->objects) {
100 if (!object->pose) {
101 continue;
102 }
103 LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
104 idprops_process(&pchan->prop, pchan->system_properties);
105 }
106 }
107
108 LISTBASE_FOREACH (bArmature *, armature, &bmain->armatures) {
109 for (BoneCollection *bcoll : armature->collections_span()) {
110 idprops_process(&bcoll->prop, bcoll->system_properties);
111 }
112 LISTBASE_FOREACH (Bone *, bone, &armature->bonebase) {
113 idprops_process(&bone->prop, bone->system_properties);
114 }
115 }
116}
117
119{
120 LISTBASE_FOREACH (FModifier *, fcurve_modifier, &fcurve.modifiers) {
121 if (fcurve_modifier->type != FMODIFIER_TYPE_NOISE) {
122 continue;
123 }
124 FMod_Noise *data = static_cast<FMod_Noise *>(fcurve_modifier->data);
125 if (data->legacy_noise) {
126 /* We don't want to modify anything if the noise is set to legacy, because the issue only
127 * occurred on the new style noise. */
128 continue;
129 }
130 data->offset *= data->size;
131 }
132}
133
139{
140 auto fix_curves = [](blender::bke::CurvesGeometry &curves) {
141 if (curves.custom_knots != nullptr) {
142 return;
143 }
144
145 int8_t *knot_modes = static_cast<int8_t *>(CustomData_get_layer_named_for_write(
146 &curves.curve_data, CD_PROP_INT8, "knots_mode", curves.curve_num));
147 if (knot_modes == nullptr) {
148 return;
149 }
150
151 for (const int curve : curves.curves_range()) {
152 int8_t &knot_mode = knot_modes[curve];
153 if (knot_mode == NURBS_KNOT_MODE_CUSTOM) {
154 knot_mode = NURBS_KNOT_MODE_NORMAL;
155 }
156 }
157 curves.nurbs_custom_knots_update_size();
158 };
159
160 LISTBASE_FOREACH (Curves *, curves_id, &bmain->hair_curves) {
161 blender::bke::CurvesGeometry &curves = curves_id->geometry.wrap();
162 fix_curves(curves);
163 }
164
165 LISTBASE_FOREACH (GreasePencil *, grease_pencil, &bmain->grease_pencils) {
166 for (GreasePencilDrawingBase *base : grease_pencil->drawings()) {
167 if (base->type != GP_DRAWING) {
168 continue;
169 }
171 reinterpret_cast<GreasePencilDrawing *>(base)->wrap();
172 fix_curves(drawing.strokes_for_write());
173 }
174 }
175}
176
178{
179 LISTBASE_FOREACH (NlaStrip *, strip, &strips) {
180 LISTBASE_FOREACH (FCurve *, fcurve, &strip->fcurves) {
182 }
183
184 /* Check sub-strips (if meta-strips). */
186 }
187}
188
189/* The compositor Value, Color Ramp, Mix Color, Map Range, Map Value, Math, Combine XYZ, Separate
190 * XYZ, and Vector Curves nodes are now deprecated and should be replaced by their generic Shader
191 * node counterpart. */
193{
194 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
195 switch (node->type_legacy) {
196 case CMP_NODE_VALUE:
197 node->type_legacy = SH_NODE_VALUE;
198 STRNCPY(node->idname, "ShaderNodeValue");
199 break;
200 case CMP_NODE_MATH:
201 node->type_legacy = SH_NODE_MATH;
202 STRNCPY(node->idname, "ShaderNodeMath");
203 break;
205 node->type_legacy = SH_NODE_COMBXYZ;
206 STRNCPY(node->idname, "ShaderNodeCombineXYZ");
207 break;
209 node->type_legacy = SH_NODE_SEPXYZ;
210 STRNCPY(node->idname, "ShaderNodeSeparateXYZ");
211 break;
213 node->type_legacy = SH_NODE_CURVE_VEC;
214 STRNCPY(node->idname, "ShaderNodeVectorCurve");
215 break;
216 case CMP_NODE_VALTORGB: {
217 node->type_legacy = SH_NODE_VALTORGB;
218 STRNCPY(node->idname, "ShaderNodeValToRGB");
219
220 /* Compositor node uses "Image" as the output name while the shader node uses "Color" as
221 * the output name. */
222 bNodeSocket *image_output = blender::bke::node_find_socket(*node, SOCK_OUT, "Image");
223 STRNCPY(image_output->identifier, "Color");
224 STRNCPY(image_output->name, "Color");
225
226 break;
227 }
228 case CMP_NODE_MAP_RANGE: {
229 node->type_legacy = SH_NODE_MAP_RANGE;
230 STRNCPY(node->idname, "ShaderNodeMapRange");
231
232 /* Transfer options from node to NodeMapRange storage. */
234 data->clamp = node->custom1;
235 data->data_type = CD_PROP_FLOAT;
236 data->interpolation_type = NODE_MAP_RANGE_LINEAR;
237 node->storage = data;
238
239 /* Compositor node uses "Value" as the output name while the shader node uses "Result" as
240 * the output name. */
241 bNodeSocket *value_output = blender::bke::node_find_socket(*node, SOCK_OUT, "Value");
242 STRNCPY(value_output->identifier, "Result");
243 STRNCPY(value_output->name, "Result");
244
245 break;
246 }
247 case CMP_NODE_MIX_RGB: {
248 node->type_legacy = SH_NODE_MIX;
249 STRNCPY(node->idname, "ShaderNodeMix");
250
251 /* Transfer options from node to NodeShaderMix storage. */
253 data->data_type = SOCK_RGBA;
254 data->factor_mode = NODE_MIX_MODE_UNIFORM;
255 data->clamp_factor = 0;
256 data->clamp_result = node->custom2 & SHD_MIXRGB_CLAMP ? 1 : 0;
257 data->blend_type = node->custom1;
258 node->storage = data;
259
260 /* Compositor node uses "Fac", "Image", and ("Image" "Image_001") as socket names and
261 * identifiers while the shader node uses ("Factor", "Factor_Float"), ("A", "A_Color"),
262 * ("B", "B_Color"), and ("Result", "Result_Color") as socket names and identifiers. */
263 bNodeSocket *factor_input = blender::bke::node_find_socket(*node, SOCK_IN, "Fac");
264 STRNCPY(factor_input->identifier, "Factor_Float");
265 STRNCPY(factor_input->name, "Factor");
266 bNodeSocket *first_input = blender::bke::node_find_socket(*node, SOCK_IN, "Image");
267 STRNCPY(first_input->identifier, "A_Color");
268 STRNCPY(first_input->name, "A");
269 bNodeSocket *second_input = blender::bke::node_find_socket(*node, SOCK_IN, "Image_001");
270 STRNCPY(second_input->identifier, "B_Color");
271 STRNCPY(second_input->name, "B");
272 bNodeSocket *image_output = blender::bke::node_find_socket(*node, SOCK_OUT, "Image");
273 STRNCPY(image_output->identifier, "Result_Color");
274 STRNCPY(image_output->name, "Result");
275
276 break;
277 }
278 default:
279 break;
280 }
281 }
282}
283
284/* The Use Alpha option is does not exist in the new generic Mix node, it essentially just
285 * multiplied the factor by the alpha of the second input. */
286static void do_version_mix_color_use_alpha(bNodeTree *node_tree, bNode *node)
287{
288 if (!(node->custom2 & SHD_MIXRGB_USE_ALPHA)) {
289 return;
290 }
291
292 bNodeSocket *factor_input = blender::bke::node_find_socket(*node, SOCK_IN, "Factor_Float");
293 bNodeSocket *b_input = blender::bke::node_find_socket(*node, SOCK_IN, "B_Color");
294
295 /* Find the links going into the factor and B input of the Mix node. */
296 bNodeLink *factor_link = nullptr;
297 bNodeLink *b_link = nullptr;
298 LISTBASE_FOREACH (bNodeLink *, link, &node_tree->links) {
299 if (link->tosock == factor_input) {
300 factor_link = link;
301 }
302 else if (link->tosock == b_input) {
303 b_link = link;
304 }
305 }
306
307 /* If neither sockets are connected, just multiply the factor by the alpha of the B input. */
308 if (!factor_link && !b_link) {
309 static_cast<bNodeSocketValueFloat *>(factor_input->default_value)->value *=
310 static_cast<bNodeSocketValueRGBA *>(b_input->default_value)->value[3];
311 return;
312 }
313
314 /* Otherwise, add a multiply node to do the multiplication. */
315 bNode *multiply_node = blender::bke::node_add_static_node(nullptr, *node_tree, SH_NODE_MATH);
316 multiply_node->parent = node->parent;
317 multiply_node->custom1 = NODE_MATH_MULTIPLY;
318 multiply_node->location[0] = node->location[0] - node->width - 20.0f;
319 multiply_node->location[1] = node->location[1];
320 multiply_node->flag |= NODE_HIDDEN;
321
322 bNodeSocket *multiply_input_a = static_cast<bNodeSocket *>(
323 BLI_findlink(&multiply_node->inputs, 0));
324 bNodeSocket *multiply_input_b = static_cast<bNodeSocket *>(
325 BLI_findlink(&multiply_node->inputs, 1));
326 bNodeSocket *multiply_output = blender::bke::node_find_socket(*multiply_node, SOCK_OUT, "Value");
327
328 /* Connect the output of the multiply node to the math node. */
329 version_node_add_link(*node_tree, *multiply_node, *multiply_output, *node, *factor_input);
330
331 if (factor_link) {
332 /* The factor input is linked, so connect its origin to the first input of the multiply and
333 * remove the original link. */
334 version_node_add_link(*node_tree,
335 *factor_link->fromnode,
336 *factor_link->fromsock,
337 *multiply_node,
338 *multiply_input_a);
339 blender::bke::node_remove_link(node_tree, *factor_link);
340 }
341 else {
342 /* Otherwise, the factor is unlinked and we just copy the factor value to the first input in
343 * the multiply.*/
344 static_cast<bNodeSocketValueFloat *>(multiply_input_a->default_value)->value =
345 static_cast<bNodeSocketValueFloat *>(factor_input->default_value)->value;
346 }
347
348 if (b_link) {
349 /* The B input is linked, so extract the alpha of its origin and connect it to the second input
350 * of the multiply and remove the original link. */
351 bNode *separate_color_node = blender::bke::node_add_static_node(
352 nullptr, *node_tree, CMP_NODE_SEPARATE_COLOR);
353 separate_color_node->parent = node->parent;
354 separate_color_node->location[0] = multiply_node->location[0] - multiply_node->width - 20.0f;
355 separate_color_node->location[1] = multiply_node->location[1];
356 separate_color_node->flag |= NODE_HIDDEN;
357
359 *separate_color_node, SOCK_IN, "Image");
361 *separate_color_node, SOCK_OUT, "Alpha");
362
364 *node_tree, *b_link->fromnode, *b_link->fromsock, *separate_color_node, *image_input);
366 *node_tree, *separate_color_node, *alpha_output, *multiply_node, *multiply_input_b);
367 }
368 else {
369 /* Otherwise, the B input is unlinked and we just copy the alpha value to the second input in
370 * the multiply.*/
371 static_cast<bNodeSocketValueFloat *>(multiply_input_b->default_value)->value =
372 static_cast<bNodeSocketValueRGBA *>(b_input->default_value)->value[3];
373 }
374
376}
377
378/* The Map Value node is now deprecated and should be replaced by other nodes. The node essentially
379 * just computes (value + offset) * size and clamps based on min and max. */
380static void do_version_map_value_node(bNodeTree *node_tree, bNode *node)
381{
382 const TexMapping &texture_mapping = *static_cast<TexMapping *>(node->storage);
383 const bool use_min = texture_mapping.flag & TEXMAP_CLIP_MIN;
384 const bool use_max = texture_mapping.flag & TEXMAP_CLIP_MAX;
385 const float offset = texture_mapping.loc[0];
386 const float size = texture_mapping.size[0];
387 const float min = texture_mapping.min[0];
388 const float max = texture_mapping.max[0];
389
390 bNodeSocket *value_input = blender::bke::node_find_socket(*node, SOCK_IN, "Value");
391
392 /* Find the link going into the value input Map Value node. */
393 bNodeLink *value_link = nullptr;
394 LISTBASE_FOREACH (bNodeLink *, link, &node_tree->links) {
395 if (link->tosock == value_input) {
396 value_link = link;
397 }
398 }
399
400 /* If the value input is not connected, add a value node with the computed value. */
401 if (!value_link) {
402 const float value = static_cast<bNodeSocketValueFloat *>(value_input->default_value)->value;
403 const float mapped_value = (value + offset) * size;
404 const float min_clamped_value = use_min ? blender::math::max(mapped_value, min) : mapped_value;
405 const float clamped_value = use_max ? blender::math::min(min_clamped_value, max) :
406 min_clamped_value;
407
408 bNode *value_node = blender::bke::node_add_static_node(nullptr, *node_tree, SH_NODE_VALUE);
409 value_node->parent = node->parent;
410 value_node->location[0] = node->location[0];
411 value_node->location[1] = node->location[1];
412
413 bNodeSocket *value_output = blender::bke::node_find_socket(*value_node, SOCK_OUT, "Value");
414 static_cast<bNodeSocketValueFloat *>(value_output->default_value)->value = clamped_value;
415
416 /* Relink from the Map Value node to the value node. */
417 LISTBASE_FOREACH_BACKWARD_MUTABLE (bNodeLink *, link, &node_tree->links) {
418 if (link->fromnode != node) {
419 continue;
420 }
421
422 version_node_add_link(*node_tree, *value_node, *value_output, *link->tonode, *link->tosock);
423 blender::bke::node_remove_link(node_tree, *link);
424 }
425
426 blender::bke::node_remove_node(nullptr, *node_tree, *node, false);
427
429 return;
430 }
431
432 /* Otherwise, add math nodes to do the computation, starting with an add node to add the offset
433 * of the range. */
435 add_node->parent = node->parent;
436 add_node->custom1 = NODE_MATH_ADD;
437 add_node->location[0] = node->location[0];
438 add_node->location[1] = node->location[1];
439 add_node->flag |= NODE_HIDDEN;
440
441 bNodeSocket *add_input_a = static_cast<bNodeSocket *>(BLI_findlink(&add_node->inputs, 0));
442 bNodeSocket *add_input_b = static_cast<bNodeSocket *>(BLI_findlink(&add_node->inputs, 1));
444
445 /* Connect the origin of the node to the first input of the add node and remove the original
446 * link. */
448 *node_tree, *value_link->fromnode, *value_link->fromsock, *add_node, *add_input_a);
449 blender::bke::node_remove_link(node_tree, *value_link);
450
451 /* Set the offset to the second input of the add node. */
452 static_cast<bNodeSocketValueFloat *>(add_input_b->default_value)->value = offset;
453
454 /* Add a multiply node to multiply by the size. */
455 bNode *multiply_node = blender::bke::node_add_static_node(nullptr, *node_tree, SH_NODE_MATH);
456 multiply_node->parent = node->parent;
457 multiply_node->custom1 = NODE_MATH_MULTIPLY;
458 multiply_node->location[0] = add_node->location[0];
459 multiply_node->location[1] = add_node->location[1] - 40.0f;
460 multiply_node->flag |= NODE_HIDDEN;
461
462 bNodeSocket *multiply_input_a = static_cast<bNodeSocket *>(
463 BLI_findlink(&multiply_node->inputs, 0));
464 bNodeSocket *multiply_input_b = static_cast<bNodeSocket *>(
465 BLI_findlink(&multiply_node->inputs, 1));
466 bNodeSocket *multiply_output = blender::bke::node_find_socket(*multiply_node, SOCK_OUT, "Value");
467
468 /* Connect the output of the add node to the first input of the multiply node. */
469 version_node_add_link(*node_tree, *add_node, *add_output, *multiply_node, *multiply_input_a);
470
471 /* Set the size to the second input of the multiply node. */
472 static_cast<bNodeSocketValueFloat *>(multiply_input_b->default_value)->value = size;
473
474 bNode *final_node = multiply_node;
475 bNodeSocket *final_output = multiply_output;
476
477 if (use_min) {
478 /* Add a maximum node to clamp by the minimum. */
479 bNode *max_node = blender::bke::node_add_static_node(nullptr, *node_tree, SH_NODE_MATH);
480 max_node->parent = node->parent;
481 max_node->custom1 = NODE_MATH_MAXIMUM;
482 max_node->location[0] = final_node->location[0];
483 max_node->location[1] = final_node->location[1] - 40.0f;
484 max_node->flag |= NODE_HIDDEN;
485
486 bNodeSocket *max_input_a = static_cast<bNodeSocket *>(BLI_findlink(&max_node->inputs, 0));
487 bNodeSocket *max_input_b = static_cast<bNodeSocket *>(BLI_findlink(&max_node->inputs, 1));
488 bNodeSocket *max_output = blender::bke::node_find_socket(*max_node, SOCK_OUT, "Value");
489
490 /* Connect the output of the final node to the first input of the maximum node. */
491 version_node_add_link(*node_tree, *final_node, *final_output, *max_node, *max_input_a);
492
493 /* Set the minimum to the second input of the maximum node. */
494 static_cast<bNodeSocketValueFloat *>(max_input_b->default_value)->value = min;
495
496 final_node = max_node;
497 final_output = max_output;
498 }
499
500 if (use_max) {
501 /* Add a minimum node to clamp by the maximum. */
502 bNode *min_node = blender::bke::node_add_static_node(nullptr, *node_tree, SH_NODE_MATH);
503 min_node->parent = node->parent;
504 min_node->custom1 = NODE_MATH_MINIMUM;
505 min_node->location[0] = final_node->location[0];
506 min_node->location[1] = final_node->location[1] - 40.0f;
507 min_node->flag |= NODE_HIDDEN;
508
509 bNodeSocket *min_input_a = static_cast<bNodeSocket *>(BLI_findlink(&min_node->inputs, 0));
510 bNodeSocket *min_input_b = static_cast<bNodeSocket *>(BLI_findlink(&min_node->inputs, 1));
511 bNodeSocket *min_output = blender::bke::node_find_socket(*min_node, SOCK_OUT, "Value");
512
513 /* Connect the output of the final node to the first input of the minimum node. */
514 version_node_add_link(*node_tree, *final_node, *final_output, *min_node, *min_input_a);
515
516 /* Set the maximum to the second input of the minimum node. */
517 static_cast<bNodeSocketValueFloat *>(min_input_b->default_value)->value = max;
518
519 final_node = min_node;
520 final_output = min_output;
521 }
522
523 /* Relink from the Map Value node to the final node. */
524 LISTBASE_FOREACH_BACKWARD_MUTABLE (bNodeLink *, link, &node_tree->links) {
525 if (link->fromnode != node) {
526 continue;
527 }
528
529 version_node_add_link(*node_tree, *final_node, *final_output, *link->tonode, *link->tosock);
530 blender::bke::node_remove_link(node_tree, *link);
531 }
532
533 blender::bke::node_remove_node(nullptr, *node_tree, *node, false);
534
536}
537
538/* Equivalent to do_version_convert_to_generic_nodes but performed after linking for handing things
539 * like animation or node construction. */
541 bNodeTree *node_tree,
542 ID *id)
543{
544 LISTBASE_FOREACH_MUTABLE (bNode *, node, &node_tree->nodes) {
545 char escaped_node_name[sizeof(node->name) * 2 + 1];
546 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
547 const std::string rna_path_prefix = fmt::format("nodes[\"{}\"].inputs", escaped_node_name);
548
549 switch (node->type_legacy) {
550 /* Notice that we use the shader type because the node is already converted in versioning
551 * before linking. */
552 case SH_NODE_CURVE_VEC: {
553 /* The node gained a new Factor input as a first socket, so the vector socket moved to be
554 * the second socket and we need to transfer its animation as well. */
556 bmain, id, rna_path_prefix.c_str(), nullptr, nullptr, 0, 1, false);
557 break;
558 }
559 /* Notice that we use the shader type because the node is already converted in versioning
560 * before linking. */
561 case SH_NODE_MIX: {
562 /* The node gained multiple new sockets after the factor socket, so the second and third
563 * sockets moved to be the 7th and 8th sockets. */
565 bmain, id, rna_path_prefix.c_str(), nullptr, nullptr, 1, 6, false);
567 bmain, id, rna_path_prefix.c_str(), nullptr, nullptr, 2, 7, false);
568
569 do_version_mix_color_use_alpha(node_tree, node);
570
571 break;
572 }
573 case CMP_NODE_MAP_VALUE: {
574 do_version_map_value_node(node_tree, node);
575 break;
576 }
577 default:
578 break;
579 }
580 }
581}
582
583/* A new Clamp boolean input was added that either enables clamping or disables it. Previously,
584 * Clamp was disabled when the maximum was zero. So we enable Clamp for non zero or linked maximum
585 * input. */
587{
588 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
589 if (node->type_legacy != CMP_NODE_GLARE) {
590 continue;
591 }
592
593 bNodeSocket *clamp_input = blender::bke::node_find_socket(*node, SOCK_IN, "Clamp Highlights");
595 *node, SOCK_IN, "Maximum Highlights");
596
597 const float maximum = maximum_input->default_value_typed<bNodeSocketValueFloat>()->value;
598 if (version_node_socket_is_used(maximum_input) || maximum != 0.0) {
599 clamp_input->default_value_typed<bNodeSocketValueBoolean>()->value = true;
600 }
601 }
602}
603
604/* The Rotate Star 45 option was converted into a Diagonal Star input. */
606{
607 NodeGlare *storage = static_cast<NodeGlare *>(node->storage);
608 if (!storage) {
609 return;
610 }
611
612 /* Input already exists, was already versioned. */
613 if (blender::bke::node_find_socket(*node, SOCK_IN, "Diagonal Star")) {
614 return;
615 }
616
618 *node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Diagonal Star", "Diagonal");
619 diagonal_star_input->default_value_typed<bNodeSocketValueBoolean>()->value = storage->star_45;
620}
621
622/* The Rotate Star 45 option was converted into a Diagonal Star input. */
624 bNode *node)
625{
626 /* Compute the RNA path of the node. */
627 char escaped_node_name[sizeof(node->name) * 2 + 1];
628 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
629 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
630
631 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
632 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
633 * path. */
634 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
635 return;
636 }
637
638 /* Change the RNA path of the FCurve from the old property to the new input. */
639 if (BLI_str_endswith(fcurve->rna_path, "use_rotate_45")) {
640 MEM_freeN(fcurve->rna_path);
641 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[14].default_value");
642 }
643 });
644}
645
646/* The options were converted into inputs. */
648{
649 NodeBokehImage *storage = static_cast<NodeBokehImage *>(node->storage);
650 if (!storage) {
651 return;
652 }
653
654 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Flaps")) {
656 *node_tree, *node, SOCK_IN, SOCK_INT, PROP_NONE, "Flaps", "Flaps");
657 input->default_value_typed<bNodeSocketValueInt>()->value = storage->flaps;
658 }
659
660 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Angle")) {
662 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_ANGLE, "Angle", "Angle");
663 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->angle;
664 }
665
666 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Roundness")) {
668 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Roundness", "Roundness");
669 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->rounding;
670 }
671
672 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Catadioptric Size")) {
674 *node,
675 SOCK_IN,
678 "Catadioptric Size",
679 "Catadioptric Size");
680 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->catadioptric;
681 }
682
683 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Color Shift")) {
685 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Color Shift", "Color Shift");
686 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->lensshift;
687 }
688
689 MEM_freeN(storage);
690 node->storage = nullptr;
691}
692
693/* The options were converted into inputs. */
695 bNode *node)
696{
697 /* Compute the RNA path of the node. */
698 char escaped_node_name[sizeof(node->name) * 2 + 1];
699 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
700 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
701
702 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
703 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
704 * path. */
705 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
706 return;
707 }
708
709 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
710 * values of the FCurves frames when needed. */
711 char *old_rna_path = fcurve->rna_path;
712 if (BLI_str_endswith(fcurve->rna_path, "flaps")) {
713 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[0].default_value");
714 }
715 else if (BLI_str_endswith(fcurve->rna_path, "angle")) {
716 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[1].default_value");
717 }
718 else if (BLI_str_endswith(fcurve->rna_path, "rounding")) {
719 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
720 }
721 else if (BLI_str_endswith(fcurve->rna_path, "catadioptric")) {
722 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
723 }
724 else if (BLI_str_endswith(fcurve->rna_path, "shift")) {
725 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[4].default_value");
726 }
727
728 /* The RNA path was changed, free the old path. */
729 if (fcurve->rna_path != old_rna_path) {
730 MEM_freeN(old_rna_path);
731 }
732 });
733}
734
735/* The options were converted into inputs. */
737{
738 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Start Frame")) {
740 *node_tree, *node, SOCK_IN, SOCK_INT, PROP_NONE, "Start Frame", "Start Frame");
741 input->default_value_typed<bNodeSocketValueInt>()->value = node->custom1;
742 }
743
744 if (!blender::bke::node_find_socket(*node, SOCK_IN, "End Frame")) {
746 *node_tree, *node, SOCK_IN, SOCK_INT, PROP_NONE, "End Frame", "End Frame");
747 input->default_value_typed<bNodeSocketValueInt>()->value = node->custom2;
748 }
749}
750
751/* The options were converted into inputs. */
753 bNode *node)
754{
755 /* Compute the RNA path of the node. */
756 char escaped_node_name[sizeof(node->name) * 2 + 1];
757 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
758 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
759
760 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
761 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
762 * path. */
763 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
764 return;
765 }
766
767 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
768 * values of the FCurves frames when needed. */
769 char *old_rna_path = fcurve->rna_path;
770 if (BLI_str_endswith(fcurve->rna_path, "frame_start")) {
771 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[0].default_value");
772 }
773 else if (BLI_str_endswith(fcurve->rna_path, "frame_end")) {
774 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[1].default_value");
775 }
776
777 /* The RNA path was changed, free the old path. */
778 if (fcurve->rna_path != old_rna_path) {
779 MEM_freeN(old_rna_path);
780 }
781 });
782}
783
784/* The options were converted into inputs. */
786{
787 NodeMask *storage = static_cast<NodeMask *>(node->storage);
788 if (!storage) {
789 return;
790 }
791
792 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Size X")) {
794 *node_tree, *node, SOCK_IN, SOCK_INT, PROP_NONE, "Size X", "Size X");
795 input->default_value_typed<bNodeSocketValueInt>()->value = storage->size_x;
796 }
797
798 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Size Y")) {
800 *node_tree, *node, SOCK_IN, SOCK_INT, PROP_NONE, "Size Y", "Size Y");
801 input->default_value_typed<bNodeSocketValueInt>()->value = storage->size_y;
802 }
803
804 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Feather")) {
806 *node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Feather", "Feather");
807 input->default_value_typed<bNodeSocketValueBoolean>()->value = !(
809 }
810
811 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Motion Blur")) {
813 *node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Motion Blur", "Motion Blur");
814 input->default_value_typed<bNodeSocketValueBoolean>()->value = bool(
816 }
817
818 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Motion Blur Samples")) {
820 *node_tree, *node, SOCK_IN, SOCK_INT, PROP_NONE, "Motion Blur Samples", "Samples");
821 input->default_value_typed<bNodeSocketValueInt>()->value = node->custom2;
822 }
823
824 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Motion Blur Shutter")) {
826 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Motion Blur Shutter", "Shutter");
827 input->default_value_typed<bNodeSocketValueFloat>()->value = node->custom3;
828 }
829
830 MEM_freeN(storage);
831 node->storage = nullptr;
832}
833
834/* The options were converted into inputs. */
836{
837 /* Compute the RNA path of the node. */
838 char escaped_node_name[sizeof(node->name) * 2 + 1];
839 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
840 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
841
842 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
843 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
844 * path. */
845 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
846 return;
847 }
848
849 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
850 * values of the FCurves frames when needed. */
851 char *old_rna_path = fcurve->rna_path;
852 if (BLI_str_endswith(fcurve->rna_path, "size_x")) {
853 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[0].default_value");
854 }
855 else if (BLI_str_endswith(fcurve->rna_path, "size_y")) {
856 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[1].default_value");
857 }
858 else if (BLI_str_endswith(fcurve->rna_path, "use_feather")) {
859 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
860 }
861 else if (BLI_str_endswith(fcurve->rna_path, "use_motion_blur")) {
862 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
863 }
864 else if (BLI_str_endswith(fcurve->rna_path, "motion_blur_samples")) {
865 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[4].default_value");
866 }
867 else if (BLI_str_endswith(fcurve->rna_path, "motion_blur_shutter")) {
868 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[5].default_value");
869 }
870
871 /* The RNA path was changed, free the old path. */
872 if (fcurve->rna_path != old_rna_path) {
873 MEM_freeN(old_rna_path);
874 }
875 });
876}
877
878/* The options were converted into inputs. */
880{
881 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Switch")) {
883 *node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Switch", "Switch");
884 input->default_value_typed<bNodeSocketValueBoolean>()->value = bool(node->custom1);
885 }
886}
887
888/* The options were converted into inputs. */
890{
891 /* Compute the RNA path of the node. */
892 char escaped_node_name[sizeof(node->name) * 2 + 1];
893 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
894 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
895
896 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
897 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
898 * path. */
899 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
900 return;
901 }
902
903 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
904 * values of the FCurves frames when needed. */
905 char *old_rna_path = fcurve->rna_path;
906 if (BLI_str_endswith(fcurve->rna_path, "check")) {
907 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[0].default_value");
908 }
909 else if (BLI_str_endswith(fcurve->rna_path, "inputs[0].default_value")) {
910 /* The new input was added at the start, so offset the animation indices by 1. */
911 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[1].default_value");
912 }
913 else if (BLI_str_endswith(fcurve->rna_path, "inputs[1].default_value")) {
914 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
915 }
916
917 /* The RNA path was changed, free the old path. */
918 if (fcurve->rna_path != old_rna_path) {
919 MEM_freeN(old_rna_path);
920 }
921 });
922}
923
924/* The options were converted into inputs. */
926{
927 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Factor")) {
929 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Factor", "Factor");
930 input->default_value_typed<bNodeSocketValueFloat>()->value = node->custom1 / 100.0f;
931 }
932}
933
934/* The options were converted into inputs. */
936{
937 /* Compute the RNA path of the node. */
938 char escaped_node_name[sizeof(node->name) * 2 + 1];
939 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
940 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
941
942 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
943 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
944 * path. */
945 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
946 return;
947 }
948
949 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
950 * values of the FCurves frames when needed. */
951 char *old_rna_path = fcurve->rna_path;
952 if (BLI_str_endswith(fcurve->rna_path, "factor")) {
953 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[0].default_value");
954 adjust_fcurve_key_frame_values(
955 fcurve, PROP_FLOAT, [&](const float value) { return value / 100.0f; });
956 }
957 else if (BLI_str_endswith(fcurve->rna_path, "inputs[0].default_value")) {
958 /* The new input was added at the start, so offset the animation indices by 1. */
959 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[1].default_value");
960 }
961 else if (BLI_str_endswith(fcurve->rna_path, "inputs[1].default_value")) {
962 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
963 }
964
965 /* The RNA path was changed, free the old path. */
966 if (fcurve->rna_path != old_rna_path) {
967 MEM_freeN(old_rna_path);
968 }
969 });
970}
971
972/* The options were converted into inputs. */
974{
975 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Invert Color")) {
977 *node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Invert Color", "Invert Color");
978 input->default_value_typed<bNodeSocketValueBoolean>()->value = bool(node->custom1 &
980 }
981
982 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Invert Alpha")) {
984 *node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Invert Alpha", "Invert Alpha");
985 input->default_value_typed<bNodeSocketValueBoolean>()->value = bool(node->custom1 &
986 CMP_CHAN_A);
987 }
988}
989
990/* The options were converted into inputs. */
992{
993 /* Compute the RNA path of the node. */
994 char escaped_node_name[sizeof(node->name) * 2 + 1];
995 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
996 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
997
998 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
999 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
1000 * path. */
1001 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
1002 return;
1003 }
1004
1005 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
1006 * values of the FCurves frames when needed. */
1007 char *old_rna_path = fcurve->rna_path;
1008 if (BLI_str_endswith(fcurve->rna_path, "invert_rgb")) {
1009 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
1010 }
1011 else if (BLI_str_endswith(fcurve->rna_path, "invert_alpha")) {
1012 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
1013 }
1014
1015 /* The RNA path was changed, free the old path. */
1016 if (fcurve->rna_path != old_rna_path) {
1017 MEM_freeN(old_rna_path);
1018 }
1019 });
1020}
1021
1022/* The options were converted into inputs. */
1024{
1025 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Use Alpha")) {
1027 *node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Use Alpha", "Use Alpha");
1028 input->default_value_typed<bNodeSocketValueBoolean>()->value = bool(node->custom1);
1029 }
1030
1031 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Anti-Alias")) {
1033 *node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Anti-Alias", "Anti-Alias");
1034 input->default_value_typed<bNodeSocketValueBoolean>()->value = !bool(node->custom2);
1035 }
1036}
1037
1038/* The options were converted into inputs. */
1040 bNode *node)
1041{
1042 /* Compute the RNA path of the node. */
1043 char escaped_node_name[sizeof(node->name) * 2 + 1];
1044 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
1045 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
1046
1047 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
1048 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
1049 * path. */
1050 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
1051 return;
1052 }
1053
1054 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
1055 * values of the FCurves frames when needed. */
1056 char *old_rna_path = fcurve->rna_path;
1057 if (BLI_str_endswith(fcurve->rna_path, "use_alpha")) {
1058 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[4].default_value");
1059 }
1060 else if (BLI_str_endswith(fcurve->rna_path, "use_antialias_z")) {
1061 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[5].default_value");
1062 }
1063
1064 /* The RNA path was changed, free the old path. */
1065 if (fcurve->rna_path != old_rna_path) {
1066 MEM_freeN(old_rna_path);
1067 }
1068 });
1069}
1070
1071/* The options were converted into inputs. */
1073{
1074 NodeTonemap *storage = static_cast<NodeTonemap *>(node->storage);
1075 if (!storage) {
1076 return;
1077 }
1078
1079 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Key")) {
1081 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_NONE, "Key", "Key");
1082 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->key;
1083 }
1084
1085 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Balance")) {
1087 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_NONE, "Balance", "Balance");
1088 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->offset;
1089 }
1090
1091 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Gamma")) {
1093 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_NONE, "Gamma", "Gamma");
1094 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->gamma;
1095 }
1096
1097 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Intensity")) {
1099 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_NONE, "Intensity", "Intensity");
1100 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->f;
1101 }
1102
1103 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Contrast")) {
1105 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_NONE, "Contrast", "Contrast");
1106 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->m;
1107 }
1108
1109 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Light Adaptation")) {
1111 *node,
1112 SOCK_IN,
1113 SOCK_FLOAT,
1115 "Light Adaptation",
1116 "Light Adaptation");
1117 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->a;
1118 }
1119
1120 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Chromatic Adaptation")) {
1122 *node,
1123 SOCK_IN,
1124 SOCK_FLOAT,
1126 "Chromatic Adaptation",
1127 "Chromatic Adaptation");
1128 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->c;
1129 }
1130}
1131
1132/* The options were converted into inputs. */
1134{
1135 /* Compute the RNA path of the node. */
1136 char escaped_node_name[sizeof(node->name) * 2 + 1];
1137 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
1138 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
1139
1140 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
1141 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
1142 * path. */
1143 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
1144 return;
1145 }
1146
1147 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
1148 * values of the FCurves frames when needed. */
1149 char *old_rna_path = fcurve->rna_path;
1150 if (BLI_str_endswith(fcurve->rna_path, "key")) {
1151 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[1].default_value");
1152 }
1153 else if (BLI_str_endswith(fcurve->rna_path, "offset")) {
1154 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
1155 }
1156 else if (BLI_str_endswith(fcurve->rna_path, "gamma")) {
1157 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
1158 }
1159 else if (BLI_str_endswith(fcurve->rna_path, "intensity")) {
1160 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[4].default_value");
1161 }
1162 else if (BLI_str_endswith(fcurve->rna_path, "contrast")) {
1163 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[5].default_value");
1164 }
1165 else if (BLI_str_endswith(fcurve->rna_path, "adaptation")) {
1166 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[6].default_value");
1167 }
1168 else if (BLI_str_endswith(fcurve->rna_path, "correction")) {
1169 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[7].default_value");
1170 }
1171
1172 /* The RNA path was changed, free the old path. */
1173 if (fcurve->rna_path != old_rna_path) {
1174 MEM_freeN(old_rna_path);
1175 }
1176 });
1177}
1178
1179/* The options were converted into inputs. */
1181{
1182 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Size")) {
1184 *node_tree, *node, SOCK_IN, SOCK_INT, PROP_NONE, "Size", "Size");
1185 input->default_value_typed<bNodeSocketValueInt>()->value = node->custom2;
1186 }
1187
1188 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Falloff Size")) {
1190 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_NONE, "Falloff Size", "Falloff Size");
1191 input->default_value_typed<bNodeSocketValueFloat>()->value = node->custom3;
1192 }
1193}
1194
1195/* The options were converted into inputs. */
1197{
1198 /* Compute the RNA path of the node. */
1199 char escaped_node_name[sizeof(node->name) * 2 + 1];
1200 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
1201 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
1202
1203 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
1204 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
1205 * path. */
1206 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
1207 return;
1208 }
1209
1210 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
1211 * values of the FCurves frames when needed. */
1212 char *old_rna_path = fcurve->rna_path;
1213 if (BLI_str_endswith(fcurve->rna_path, "distance")) {
1214 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[1].default_value");
1215 }
1216 else if (BLI_str_endswith(fcurve->rna_path, "edge")) {
1217 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
1218 }
1219
1220 /* The RNA path was changed, free the old path. */
1221 if (fcurve->rna_path != old_rna_path) {
1222 MEM_freeN(old_rna_path);
1223 }
1224 });
1225}
1226
1227/* The options were converted into inputs. */
1229{
1230 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Size")) {
1232 *node_tree, *node, SOCK_IN, SOCK_INT, PROP_NONE, "Size", "Size");
1233 input->default_value_typed<bNodeSocketValueInt>()->value = node->custom2;
1234 }
1235}
1236
1237/* The options were converted into inputs. */
1239{
1240 /* Compute the RNA path of the node. */
1241 char escaped_node_name[sizeof(node->name) * 2 + 1];
1242 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
1243 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
1244
1245 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
1246 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
1247 * path. */
1248 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
1249 return;
1250 }
1251
1252 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
1253 * values of the FCurves frames when needed. */
1254 char *old_rna_path = fcurve->rna_path;
1255 if (BLI_str_endswith(fcurve->rna_path, "distance")) {
1256 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[1].default_value");
1257 }
1258
1259 /* The RNA path was changed, free the old path. */
1260 if (fcurve->rna_path != old_rna_path) {
1261 MEM_freeN(old_rna_path);
1262 }
1263 });
1264}
1265
1266/* The options were converted into inputs. */
1268{
1269 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Size")) {
1271 *node_tree, *node, SOCK_IN, SOCK_INT, PROP_NONE, "Size", "Size");
1272 input->default_value_typed<bNodeSocketValueInt>()->value = node->custom1;
1273 }
1274}
1275
1276/* The options were converted into inputs. */
1278{
1279 /* Compute the RNA path of the node. */
1280 char escaped_node_name[sizeof(node->name) * 2 + 1];
1281 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
1282 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
1283
1284 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
1285 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
1286 * path. */
1287 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
1288 return;
1289 }
1290
1291 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
1292 * values of the FCurves frames when needed. */
1293 char *old_rna_path = fcurve->rna_path;
1294 if (BLI_str_endswith(fcurve->rna_path, "pixel_size")) {
1295 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[1].default_value");
1296 }
1297
1298 /* The RNA path was changed, free the old path. */
1299 if (fcurve->rna_path != old_rna_path) {
1300 MEM_freeN(old_rna_path);
1301 }
1302 });
1303}
1304
1305/* The options were converted into inputs. */
1307{
1308 NodeKuwaharaData *storage = static_cast<NodeKuwaharaData *>(node->storage);
1309 if (!storage) {
1310 return;
1311 }
1312
1313 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Uniformity")) {
1315 *node_tree, *node, SOCK_IN, SOCK_INT, PROP_NONE, "Uniformity", "Uniformity");
1316 input->default_value_typed<bNodeSocketValueInt>()->value = storage->uniformity;
1317 }
1318
1319 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Sharpness")) {
1321 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Sharpness", "Sharpness");
1322 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->sharpness;
1323 }
1324
1325 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Eccentricity")) {
1327 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Eccentricity", "Eccentricity");
1328 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->eccentricity;
1329 }
1330
1331 if (!blender::bke::node_find_socket(*node, SOCK_IN, "High Precision")) {
1333 *node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "High Precision", "High Precision");
1334 input->default_value_typed<bNodeSocketValueBoolean>()->value = storage->high_precision;
1335 }
1336}
1337
1338/* The options were converted into inputs. */
1340{
1341 /* Compute the RNA path of the node. */
1342 char escaped_node_name[sizeof(node->name) * 2 + 1];
1343 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
1344 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
1345
1346 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
1347 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
1348 * path. */
1349 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
1350 return;
1351 }
1352
1353 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
1354 * values of the FCurves frames when needed. */
1355 char *old_rna_path = fcurve->rna_path;
1356 if (BLI_str_endswith(fcurve->rna_path, "uniformity")) {
1357 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
1358 }
1359 else if (BLI_str_endswith(fcurve->rna_path, "sharpness")) {
1360 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
1361 }
1362 else if (BLI_str_endswith(fcurve->rna_path, "eccentricity")) {
1363 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[4].default_value");
1364 }
1365 else if (BLI_str_endswith(fcurve->rna_path, "high_precision")) {
1366 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[5].default_value");
1367 }
1368
1369 /* The RNA path was changed, free the old path. */
1370 if (fcurve->rna_path != old_rna_path) {
1371 MEM_freeN(old_rna_path);
1372 }
1373 });
1374}
1375
1376/* The options were converted into inputs. */
1378{
1379 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Color Threshold")) {
1381 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_NONE, "Color Threshold", "Color Threshold");
1382 input->default_value_typed<bNodeSocketValueFloat>()->value = node->custom3;
1383 }
1384
1385 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Neighbor Threshold")) {
1387 *node,
1388 SOCK_IN,
1389 SOCK_FLOAT,
1391 "Neighbor Threshold",
1392 "Neighbor Threshold");
1393 input->default_value_typed<bNodeSocketValueFloat>()->value = node->custom4;
1394 }
1395}
1396
1397/* The options were converted into inputs. */
1399 bNode *node)
1400{
1401 /* Compute the RNA path of the node. */
1402 char escaped_node_name[sizeof(node->name) * 2 + 1];
1403 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
1404 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
1405
1406 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
1407 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
1408 * path. */
1409 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
1410 return;
1411 }
1412
1413 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
1414 * values of the FCurves frames when needed. */
1415 char *old_rna_path = fcurve->rna_path;
1416 if (BLI_str_endswith(fcurve->rna_path, "threshold")) {
1417 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
1418 }
1419 else if (BLI_str_endswith(fcurve->rna_path, "threshold_neighbor")) {
1420 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
1421 }
1422
1423 /* The RNA path was changed, free the old path. */
1424 if (fcurve->rna_path != old_rna_path) {
1425 MEM_freeN(old_rna_path);
1426 }
1427 });
1428}
1429
1430/* The options were converted into inputs. */
1432{
1433 NodeDenoise *storage = static_cast<NodeDenoise *>(node->storage);
1434 if (!storage) {
1435 return;
1436 }
1437
1438 if (!blender::bke::node_find_socket(*node, SOCK_IN, "HDR")) {
1440 *node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "HDR", "HDR");
1441 input->default_value_typed<bNodeSocketValueBoolean>()->value = storage->hdr;
1442 }
1443}
1444
1445/* The options were converted into inputs. */
1447{
1448 /* Compute the RNA path of the node. */
1449 char escaped_node_name[sizeof(node->name) * 2 + 1];
1450 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
1451 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
1452
1453 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
1454 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
1455 * path. */
1456 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
1457 return;
1458 }
1459
1460 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
1461 * values of the FCurves frames when needed. */
1462 char *old_rna_path = fcurve->rna_path;
1463 if (BLI_str_endswith(fcurve->rna_path, "use_hdr")) {
1464 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
1465 }
1466
1467 /* The RNA path was changed, free the old path. */
1468 if (fcurve->rna_path != old_rna_path) {
1469 MEM_freeN(old_rna_path);
1470 }
1471 });
1472}
1473
1474/* The options were converted into inputs. */
1476{
1477 NodeAntiAliasingData *storage = static_cast<NodeAntiAliasingData *>(node->storage);
1478 if (!storage) {
1479 return;
1480 }
1481
1482 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Threshold")) {
1484 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Threshold", "Threshold");
1485 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->threshold;
1486 }
1487
1488 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Contrast Limit")) {
1490 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_NONE, "Contrast Limit", "Contrast Limit");
1491 /* Contrast limit was previously divided by 10. */
1492 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->contrast_limit * 10.0f;
1493 }
1494
1495 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Corner Rounding")) {
1497 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Corner Rounding", "Corner Rounding");
1498 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->corner_rounding;
1499 }
1500
1501 MEM_freeN(storage);
1502 node->storage = nullptr;
1503}
1504
1505/* The options were converted into inputs. */
1507 bNode *node)
1508{
1509 /* Compute the RNA path of the node. */
1510 char escaped_node_name[sizeof(node->name) * 2 + 1];
1511 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
1512 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
1513
1514 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
1515 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
1516 * path. */
1517 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
1518 return;
1519 }
1520
1521 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
1522 * values of the FCurves frames when needed. */
1523 char *old_rna_path = fcurve->rna_path;
1524 if (BLI_str_endswith(fcurve->rna_path, "threshold")) {
1525 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[1].default_value");
1526 }
1527 else if (BLI_str_endswith(fcurve->rna_path, "contrast_limit")) {
1528 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
1529 /* Contrast limit was previously divided by 10. */
1530 adjust_fcurve_key_frame_values(
1531 fcurve, PROP_FLOAT, [&](const float value) { return value * 10.0f; });
1532 }
1533 else if (BLI_str_endswith(fcurve->rna_path, "corner_rounding")) {
1534 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
1535 }
1536
1537 /* The RNA path was changed, free the old path. */
1538 if (fcurve->rna_path != old_rna_path) {
1539 MEM_freeN(old_rna_path);
1540 }
1541 });
1542}
1543
1544/* The options were converted into inputs. */
1546{
1547 NodeBlurData *storage = static_cast<NodeBlurData *>(node->storage);
1548 if (!storage) {
1549 return;
1550 }
1551
1552 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Samples")) {
1554 *node_tree, *node, SOCK_IN, SOCK_INT, PROP_NONE, "Samples", "Samples");
1555 input->default_value_typed<bNodeSocketValueInt>()->value = storage->samples;
1556 }
1557
1558 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Shutter")) {
1560 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_NONE, "Shutter", "Shutter");
1561 /* Shutter was previously divided by 2. */
1562 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->fac * 2.0f;
1563 }
1564
1565 MEM_freeN(storage);
1566 node->storage = nullptr;
1567}
1568
1569/* The options were converted into inputs. */
1571 bNode *node)
1572{
1573 /* Compute the RNA path of the node. */
1574 char escaped_node_name[sizeof(node->name) * 2 + 1];
1575 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
1576 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
1577
1578 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
1579 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
1580 * path. */
1581 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
1582 return;
1583 }
1584
1585 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
1586 * values of the FCurves frames when needed. */
1587 char *old_rna_path = fcurve->rna_path;
1588 if (BLI_str_endswith(fcurve->rna_path, "samples")) {
1589 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
1590 }
1591 else if (BLI_str_endswith(fcurve->rna_path, "factor")) {
1592 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[4].default_value");
1593 /* Shutter was previously divided by 2. */
1594 adjust_fcurve_key_frame_values(
1595 fcurve, PROP_FLOAT, [&](const float value) { return value * 2.0f; });
1596 }
1597
1598 /* The RNA path was changed, free the old path. */
1599 if (fcurve->rna_path != old_rna_path) {
1600 MEM_freeN(old_rna_path);
1601 }
1602 });
1603}
1604
1605/* The options were converted into inputs. */
1607{
1608 NodeChroma *storage = static_cast<NodeChroma *>(node->storage);
1609 if (!storage) {
1610 return;
1611 }
1612
1613 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Minimum")) {
1615 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Minimum", "Minimum");
1616 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->t2;
1617 }
1618
1619 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Maximum")) {
1621 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Maximum", "Maximum");
1622 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->t1;
1623 }
1624}
1625
1626/* The options were converted into inputs. */
1628 bNode *node)
1629{
1630 /* Compute the RNA path of the node. */
1631 char escaped_node_name[sizeof(node->name) * 2 + 1];
1632 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
1633 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
1634
1635 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
1636 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
1637 * path. */
1638 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
1639 return;
1640 }
1641
1642 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
1643 * values of the FCurves frames when needed. */
1644 char *old_rna_path = fcurve->rna_path;
1645 if (BLI_str_endswith(fcurve->rna_path, "limit_min")) {
1646 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[1].default_value");
1647 }
1648 else if (BLI_str_endswith(fcurve->rna_path, "limit_max")) {
1649 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
1650 }
1651
1652 /* The RNA path was changed, free the old path. */
1653 if (fcurve->rna_path != old_rna_path) {
1654 MEM_freeN(old_rna_path);
1655 }
1656 });
1657}
1658
1659/* The options were converted into inputs. */
1661{
1662 NodeChroma *storage = static_cast<NodeChroma *>(node->storage);
1663 if (!storage) {
1664 return;
1665 }
1666
1667 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Minimum")) {
1669 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_ANGLE, "Minimum", "Minimum");
1670 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->t2;
1671 }
1672
1673 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Maximum")) {
1675 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_ANGLE, "Maximum", "Maximum");
1676 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->t1;
1677 }
1678
1679 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Falloff")) {
1681 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Falloff", "Falloff");
1682 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->fstrength;
1683 }
1684
1685 MEM_freeN(storage);
1686 node->storage = nullptr;
1687}
1688
1689/* The options were converted into inputs. */
1691 bNode *node)
1692{
1693 /* Compute the RNA path of the node. */
1694 char escaped_node_name[sizeof(node->name) * 2 + 1];
1695 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
1696 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
1697
1698 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
1699 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
1700 * path. */
1701 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
1702 return;
1703 }
1704
1705 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
1706 * values of the FCurves frames when needed. */
1707 char *old_rna_path = fcurve->rna_path;
1708 if (BLI_str_endswith(fcurve->rna_path, "threshold")) {
1709 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
1710 }
1711 else if (BLI_str_endswith(fcurve->rna_path, "tolerance")) {
1712 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
1713 }
1714 else if (BLI_str_endswith(fcurve->rna_path, "gain")) {
1715 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[4].default_value");
1716 }
1717
1718 /* The RNA path was changed, free the old path. */
1719 if (fcurve->rna_path != old_rna_path) {
1720 MEM_freeN(old_rna_path);
1721 }
1722 });
1723}
1724
1725/* The options were converted into inputs. */
1727{
1728 NodeChroma *storage = static_cast<NodeChroma *>(node->storage);
1729 if (!storage) {
1730 return;
1731 }
1732
1733 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Hue")) {
1735 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Hue", "Hue");
1736 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->t1;
1737 }
1738
1739 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Saturation")) {
1741 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Saturation", "Saturation");
1742 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->t2;
1743 }
1744
1745 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Value")) {
1747 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Value", "Value");
1748 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->t3;
1749 }
1750
1751 MEM_freeN(storage);
1752 node->storage = nullptr;
1753}
1754
1755/* The options were converted into inputs. */
1757 bNode *node)
1758{
1759 /* Compute the RNA path of the node. */
1760 char escaped_node_name[sizeof(node->name) * 2 + 1];
1761 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
1762 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
1763
1764 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
1765 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
1766 * path. */
1767 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
1768 return;
1769 }
1770
1771 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
1772 * values of the FCurves frames when needed. */
1773 char *old_rna_path = fcurve->rna_path;
1774 if (BLI_str_endswith(fcurve->rna_path, "color_hue")) {
1775 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
1776 }
1777 else if (BLI_str_endswith(fcurve->rna_path, "color_saturation")) {
1778 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
1779 }
1780 else if (BLI_str_endswith(fcurve->rna_path, "color_value")) {
1781 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[4].default_value");
1782 }
1783
1784 /* The RNA path was changed, free the old path. */
1785 if (fcurve->rna_path != old_rna_path) {
1786 MEM_freeN(old_rna_path);
1787 }
1788 });
1789}
1790
1791/* The options were converted into inputs. */
1793{
1794 NodeChroma *storage = static_cast<NodeChroma *>(node->storage);
1795 if (!storage) {
1796 return;
1797 }
1798
1799 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Tolerance")) {
1801 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Tolerance", "Tolerance");
1802 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->t1;
1803 }
1804
1805 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Falloff")) {
1807 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Falloff", "Falloff");
1808 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->t2;
1809 }
1810
1811 MEM_freeN(storage);
1812 node->storage = nullptr;
1813}
1814
1815/* The options were converted into inputs. */
1817 bNode *node)
1818{
1819 /* Compute the RNA path of the node. */
1820 char escaped_node_name[sizeof(node->name) * 2 + 1];
1821 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
1822 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
1823
1824 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
1825 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
1826 * path. */
1827 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
1828 return;
1829 }
1830
1831 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
1832 * values of the FCurves frames when needed. */
1833 char *old_rna_path = fcurve->rna_path;
1834 if (BLI_str_endswith(fcurve->rna_path, "tolerance")) {
1835 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
1836 }
1837 else if (BLI_str_endswith(fcurve->rna_path, "falloff")) {
1838 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
1839 }
1840
1841 /* The RNA path was changed, free the old path. */
1842 if (fcurve->rna_path != old_rna_path) {
1843 MEM_freeN(old_rna_path);
1844 }
1845 });
1846}
1847
1848/* The options were converted into inputs. */
1850{
1851 NodeChroma *storage = static_cast<NodeChroma *>(node->storage);
1852 if (!storage) {
1853 return;
1854 }
1855
1856 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Tolerance")) {
1858 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Tolerance", "Tolerance");
1859 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->t1;
1860 }
1861
1862 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Falloff")) {
1864 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Falloff", "Falloff");
1865 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->t2;
1866 }
1867}
1868
1869/* The options were converted into inputs. */
1871 bNode *node)
1872{
1873 /* Compute the RNA path of the node. */
1874 char escaped_node_name[sizeof(node->name) * 2 + 1];
1875 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
1876 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
1877
1878 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
1879 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
1880 * path. */
1881 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
1882 return;
1883 }
1884
1885 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
1886 * values of the FCurves frames when needed. */
1887 char *old_rna_path = fcurve->rna_path;
1888 if (BLI_str_endswith(fcurve->rna_path, "tolerance")) {
1889 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
1890 }
1891 else if (BLI_str_endswith(fcurve->rna_path, "falloff")) {
1892 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
1893 }
1894
1895 /* The RNA path was changed, free the old path. */
1896 if (fcurve->rna_path != old_rna_path) {
1897 MEM_freeN(old_rna_path);
1898 }
1899 });
1900}
1901
1902/* The options were converted into inputs. */
1904{
1905 NodeChroma *storage = static_cast<NodeChroma *>(node->storage);
1906 if (!storage) {
1907 return;
1908 }
1909
1910 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Minimum")) {
1912 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Minimum", "Minimum");
1913 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->t2;
1914 }
1915
1916 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Maximum")) {
1918 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Maximum", "Maximum");
1919 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->t1;
1920 }
1921
1922 MEM_freeN(storage);
1923 node->storage = nullptr;
1924}
1925
1926/* The options were converted into inputs. */
1928 bNode *node)
1929{
1930 /* Compute the RNA path of the node. */
1931 char escaped_node_name[sizeof(node->name) * 2 + 1];
1932 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
1933 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
1934
1935 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
1936 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
1937 * path. */
1938 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
1939 return;
1940 }
1941
1942 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
1943 * values of the FCurves frames when needed. */
1944 char *old_rna_path = fcurve->rna_path;
1945 if (BLI_str_endswith(fcurve->rna_path, "limit_min")) {
1946 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[1].default_value");
1947 }
1948 else if (BLI_str_endswith(fcurve->rna_path, "limit_max")) {
1949 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
1950 }
1951
1952 /* The RNA path was changed, free the old path. */
1953 if (fcurve->rna_path != old_rna_path) {
1954 MEM_freeN(old_rna_path);
1955 }
1956 });
1957}
1958
1959/* The options were converted into inputs. */
1961{
1962 NodeColorspill *storage = static_cast<NodeColorspill *>(node->storage);
1963 if (!storage) {
1964 return;
1965 }
1966
1967 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Limit Strength")) {
1969 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Limit Strength", "Limit Strength");
1970 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->limscale;
1971 }
1972
1973 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Use Spill Strength")) {
1975 *node,
1976 SOCK_IN,
1978 PROP_NONE,
1979 "Use Spill Strength",
1980 "Use Spill Strength");
1981 input->default_value_typed<bNodeSocketValueBoolean>()->value = bool(storage->unspill);
1982 }
1983
1984 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Spill Strength")) {
1986 *node_tree, *node, SOCK_IN, SOCK_RGBA, PROP_NONE, "Spill Strength", "Spill Strength");
1987 input->default_value_typed<bNodeSocketValueRGBA>()->value[0] = storage->uspillr;
1988 input->default_value_typed<bNodeSocketValueRGBA>()->value[1] = storage->uspillg;
1989 input->default_value_typed<bNodeSocketValueRGBA>()->value[2] = storage->uspillb;
1990 }
1991}
1992
1993/* The options were converted into inputs. */
1995 bNode *node)
1996{
1997 /* Compute the RNA path of the node. */
1998 char escaped_node_name[sizeof(node->name) * 2 + 1];
1999 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
2000 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
2001
2002 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
2003 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
2004 * path. */
2005 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
2006 return;
2007 }
2008
2009 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
2010 * values of the FCurves frames when needed. */
2011 char *old_rna_path = fcurve->rna_path;
2012 if (BLI_str_endswith(fcurve->rna_path, "ratio")) {
2013 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
2014 }
2015 else if (BLI_str_endswith(fcurve->rna_path, "use_unspill")) {
2016 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
2017 }
2018 else if (BLI_str_endswith(fcurve->rna_path, "unspill_red")) {
2019 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[4].default_value");
2020 fcurve->array_index = 0;
2021 }
2022 else if (BLI_str_endswith(fcurve->rna_path, "unspill_green")) {
2023 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[4].default_value");
2024 fcurve->array_index = 1;
2025 }
2026 else if (BLI_str_endswith(fcurve->rna_path, "unspill_blue")) {
2027 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[4].default_value");
2028 fcurve->array_index = 2;
2029 }
2030
2031 /* The RNA path was changed, free the old path. */
2032 if (fcurve->rna_path != old_rna_path) {
2033 MEM_freeN(old_rna_path);
2034 }
2035 });
2036}
2037
2038/* The options were converted into inputs. */
2040{
2041 NodeKeyingScreenData *storage = static_cast<NodeKeyingScreenData *>(node->storage);
2042 if (!storage) {
2043 return;
2044 }
2045
2046 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Smoothness")) {
2048 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Smoothness", "Smoothness");
2049 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->smoothness;
2050 }
2051}
2052
2053/* The options were converted into inputs. */
2055 bNode *node)
2056{
2057 /* Compute the RNA path of the node. */
2058 char escaped_node_name[sizeof(node->name) * 2 + 1];
2059 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
2060 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
2061
2062 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
2063 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
2064 * path. */
2065 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
2066 return;
2067 }
2068
2069 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
2070 * values of the FCurves frames when needed. */
2071 char *old_rna_path = fcurve->rna_path;
2072 if (BLI_str_endswith(fcurve->rna_path, "smoothness")) {
2073 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[0].default_value");
2074 }
2075
2076 /* The RNA path was changed, free the old path. */
2077 if (fcurve->rna_path != old_rna_path) {
2078 MEM_freeN(old_rna_path);
2079 }
2080 });
2081}
2082
2083/* The options were converted into inputs. */
2085{
2086 NodeKeyingData *storage = static_cast<NodeKeyingData *>(node->storage);
2087 if (!storage) {
2088 return;
2089 }
2090
2091 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Preprocess Blur Size")) {
2093 *node,
2094 SOCK_IN,
2095 SOCK_INT,
2096 PROP_NONE,
2097 "Preprocess Blur Size",
2098 "Preprocess Blur Size");
2099 input->default_value_typed<bNodeSocketValueInt>()->value = storage->blur_pre;
2100 }
2101
2102 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Key Balance")) {
2104 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Key Balance", "Key Balance");
2105 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->screen_balance;
2106 }
2107
2108 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Edge Search Size")) {
2110 *node_tree, *node, SOCK_IN, SOCK_INT, PROP_NONE, "Edge Search Size", "Edge Search Size");
2111 input->default_value_typed<bNodeSocketValueInt>()->value = storage->edge_kernel_radius;
2112 }
2113
2114 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Edge Tolerance")) {
2116 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Edge Tolerance", "Edge Tolerance");
2117 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->edge_kernel_tolerance;
2118 }
2119
2120 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Black Level")) {
2122 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Black Level", "Black Level");
2123 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->clip_black;
2124 }
2125
2126 if (!blender::bke::node_find_socket(*node, SOCK_IN, "White Level")) {
2128 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "White Level", "White Level");
2129 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->clip_white;
2130 }
2131
2132 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Postprocess Blur Size")) {
2134 *node,
2135 SOCK_IN,
2136 SOCK_INT,
2137 PROP_NONE,
2138 "Postprocess Blur Size",
2139 "Postprocess Blur Size");
2140 input->default_value_typed<bNodeSocketValueInt>()->value = storage->blur_post;
2141 }
2142
2143 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Postprocess Dilate Size")) {
2145 *node,
2146 SOCK_IN,
2147 SOCK_INT,
2148 PROP_NONE,
2149 "Postprocess Dilate Size",
2150 "Postprocess Dilate Size");
2151 input->default_value_typed<bNodeSocketValueInt>()->value = storage->dilate_distance;
2152 }
2153
2154 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Postprocess Feather Size")) {
2156 *node,
2157 SOCK_IN,
2158 SOCK_INT,
2159 PROP_NONE,
2160 "Postprocess Feather Size",
2161 "Postprocess Feather Size");
2162 input->default_value_typed<bNodeSocketValueInt>()->value = storage->feather_distance;
2163 }
2164
2165 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Despill Strength")) {
2167 *node,
2168 SOCK_IN,
2169 SOCK_FLOAT,
2171 "Despill Strength",
2172 "Despill Strength");
2173 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->despill_factor;
2174 }
2175
2176 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Despill Balance")) {
2178 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Despill Balance", "Despill Balance");
2179 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->despill_balance;
2180 }
2181}
2182
2183/* The options were converted into inputs. */
2185{
2186 /* Compute the RNA path of the node. */
2187 char escaped_node_name[sizeof(node->name) * 2 + 1];
2188 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
2189 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
2190
2191 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
2192 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
2193 * path. */
2194 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
2195 return;
2196 }
2197
2198 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
2199 * values of the FCurves frames when needed. */
2200 char *old_rna_path = fcurve->rna_path;
2201 if (BLI_str_endswith(fcurve->rna_path, "blur_pre")) {
2202 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
2203 }
2204 else if (BLI_str_endswith(fcurve->rna_path, "screen_balance")) {
2205 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
2206 }
2207 else if (BLI_str_endswith(fcurve->rna_path, "clip_black")) {
2208 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[4].default_value");
2209 }
2210 else if (BLI_str_endswith(fcurve->rna_path, "clip_white")) {
2211 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[5].default_value");
2212 }
2213 else if (BLI_str_endswith(fcurve->rna_path, "edge_kernel_radius")) {
2214 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[6].default_value");
2215 }
2216 else if (BLI_str_endswith(fcurve->rna_path, "edge_kernel_tolerance")) {
2217 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[7].default_value");
2218 }
2219 else if (BLI_str_endswith(fcurve->rna_path, "blur_post")) {
2220 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[10].default_value");
2221 }
2222 else if (BLI_str_endswith(fcurve->rna_path, "dilate_distance")) {
2223 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[11].default_value");
2224 }
2225 else if (BLI_str_endswith(fcurve->rna_path, "feather_distance")) {
2226 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[12].default_value");
2227 }
2228 else if (BLI_str_endswith(fcurve->rna_path, "despill_factor")) {
2229 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[13].default_value");
2230 }
2231 else if (BLI_str_endswith(fcurve->rna_path, "despill_balance")) {
2232 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[14].default_value");
2233 }
2234
2235 /* The RNA path was changed, free the old path. */
2236 if (fcurve->rna_path != old_rna_path) {
2237 MEM_freeN(old_rna_path);
2238 }
2239 });
2240}
2241
2242/* The options were converted into inputs. */
2244{
2245 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Index")) {
2247 *node_tree, *node, SOCK_IN, SOCK_INT, PROP_NONE, "Index", "Index");
2248 input->default_value_typed<bNodeSocketValueInt>()->value = node->custom1;
2249 }
2250
2251 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Anti-Alias")) {
2253 *node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Anti-Alias", "Anti-Alias");
2254 input->default_value_typed<bNodeSocketValueBoolean>()->value = bool(node->custom2);
2255 }
2256}
2257
2258/* The options were converted into inputs. */
2260{
2261 /* Compute the RNA path of the node. */
2262 char escaped_node_name[sizeof(node->name) * 2 + 1];
2263 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
2264 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
2265
2266 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
2267 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
2268 * path. */
2269 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
2270 return;
2271 }
2272
2273 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
2274 * values of the FCurves frames when needed. */
2275 char *old_rna_path = fcurve->rna_path;
2276 if (BLI_str_endswith(fcurve->rna_path, "index")) {
2277 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[1].default_value");
2278 }
2279 else if (BLI_str_endswith(fcurve->rna_path, "use_antialiasing")) {
2280 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
2281 }
2282
2283 /* The RNA path was changed, free the old path. */
2284 if (fcurve->rna_path != old_rna_path) {
2285 MEM_freeN(old_rna_path);
2286 }
2287 });
2288}
2289
2290/* The options were converted into inputs. */
2292{
2293 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Invert")) {
2295 *node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Invert", "Invert");
2296 input->default_value_typed<bNodeSocketValueBoolean>()->value = bool(node->custom2);
2297 }
2298}
2299
2300/* The options were converted into inputs. */
2302 bNode *node)
2303{
2304 /* Compute the RNA path of the node. */
2305 char escaped_node_name[sizeof(node->name) * 2 + 1];
2306 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
2307 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
2308
2309 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
2310 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
2311 * path. */
2312 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
2313 return;
2314 }
2315
2316 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
2317 * values of the FCurves frames when needed. */
2318 char *old_rna_path = fcurve->rna_path;
2319 if (BLI_str_endswith(fcurve->rna_path, "invert")) {
2320 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[1].default_value");
2321 }
2322
2323 /* The RNA path was changed, free the old path. */
2324 if (fcurve->rna_path != old_rna_path) {
2325 MEM_freeN(old_rna_path);
2326 }
2327 });
2328}
2329
2330/* The options were converted into inputs. */
2332{
2333 NodePlaneTrackDeformData *storage = static_cast<NodePlaneTrackDeformData *>(node->storage);
2334 if (!storage) {
2335 return;
2336 }
2337
2338 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Motion Blur")) {
2340 *node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Motion Blur", "Motion Blur");
2341 input->default_value_typed<bNodeSocketValueBoolean>()->value = bool(storage->flag);
2342 }
2343
2344 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Motion Blur Samples")) {
2346 *node_tree, *node, SOCK_IN, SOCK_INT, PROP_NONE, "Motion Blur Samples", "Samples");
2347 input->default_value_typed<bNodeSocketValueInt>()->value = storage->motion_blur_samples;
2348 }
2349
2350 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Motion Blur Shutter")) {
2352 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Motion Blur Shutter", "Shutter");
2353 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->motion_blur_shutter;
2354 }
2355}
2356
2357/* The options were converted into inputs. */
2359 bNode *node)
2360{
2361 /* Compute the RNA path of the node. */
2362 char escaped_node_name[sizeof(node->name) * 2 + 1];
2363 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
2364 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
2365
2366 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
2367 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
2368 * path. */
2369 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
2370 return;
2371 }
2372
2373 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
2374 * values of the FCurves frames when needed. */
2375 char *old_rna_path = fcurve->rna_path;
2376 if (BLI_str_endswith(fcurve->rna_path, "use_motion_blur")) {
2377 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[1].default_value");
2378 }
2379 else if (BLI_str_endswith(fcurve->rna_path, "motion_blur_samples")) {
2380 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
2381 }
2382 else if (BLI_str_endswith(fcurve->rna_path, "motion_blur_shutter")) {
2383 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
2384 }
2385
2386 /* The RNA path was changed, free the old path. */
2387 if (fcurve->rna_path != old_rna_path) {
2388 MEM_freeN(old_rna_path);
2389 }
2390 });
2391}
2392
2393/* The options were converted into inputs. */
2395{
2396 NodeColorCorrection *storage = static_cast<NodeColorCorrection *>(node->storage);
2397 if (!storage) {
2398 return;
2399 }
2400
2401 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Master Saturation")) {
2403 *node,
2404 SOCK_IN,
2405 SOCK_FLOAT,
2407 "Master Saturation",
2408 "Master Saturation");
2409 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->master.saturation;
2410 }
2411
2412 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Master Contrast")) {
2414 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Master Contrast", "Master Contrast");
2415 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->master.contrast;
2416 }
2417
2418 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Master Gamma")) {
2420 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Master Gamma", "Master Gamma");
2421 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->master.gamma;
2422 }
2423
2424 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Master Gain")) {
2426 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Master Gain", "Master Gain");
2427 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->master.gain;
2428 }
2429
2430 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Master Lift")) {
2432 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Master Lift", "Master Lift");
2433 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->master.lift;
2434 }
2435
2436 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Shadows Saturation")) {
2438 *node,
2439 SOCK_IN,
2440 SOCK_FLOAT,
2442 "Shadows Saturation",
2443 "Shadows Saturation");
2444 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->shadows.saturation;
2445 }
2446
2447 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Shadows Contrast")) {
2449 *node,
2450 SOCK_IN,
2451 SOCK_FLOAT,
2453 "Shadows Contrast",
2454 "Shadows Contrast");
2455 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->shadows.contrast;
2456 }
2457
2458 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Shadows Gamma")) {
2460 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Shadows Gamma", "Shadows Gamma");
2461 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->shadows.gamma;
2462 }
2463
2464 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Shadows Gain")) {
2466 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Shadows Gain", "Shadows Gain");
2467 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->shadows.gain;
2468 }
2469
2470 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Shadows Lift")) {
2472 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Shadows Lift", "Shadows Lift");
2473 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->shadows.lift;
2474 }
2475
2476 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Midtones Saturation")) {
2478 *node,
2479 SOCK_IN,
2480 SOCK_FLOAT,
2482 "Midtones Saturation",
2483 "Midtones Saturation");
2484 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->midtones.saturation;
2485 }
2486
2487 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Midtones Contrast")) {
2489 *node,
2490 SOCK_IN,
2491 SOCK_FLOAT,
2493 "Midtones Contrast",
2494 "Midtones Contrast");
2495 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->midtones.contrast;
2496 }
2497
2498 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Midtones Gamma")) {
2500 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Midtones Gamma", "Midtones Gamma");
2501 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->midtones.gamma;
2502 }
2503
2504 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Midtones Gain")) {
2506 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Midtones Gain", "Midtones Gain");
2507 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->midtones.gain;
2508 }
2509
2510 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Midtones Lift")) {
2512 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Midtones Lift", "Midtones Lift");
2513 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->midtones.lift;
2514 }
2515
2516 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Highlights Saturation")) {
2518 *node,
2519 SOCK_IN,
2520 SOCK_FLOAT,
2522 "Highlights Saturation",
2523 "Highlights Saturation");
2524 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->highlights.saturation;
2525 }
2526
2527 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Highlights Contrast")) {
2529 *node,
2530 SOCK_IN,
2531 SOCK_FLOAT,
2533 "Highlights Contrast",
2534 "Highlights Contrast");
2535 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->highlights.contrast;
2536 }
2537
2538 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Highlights Gamma")) {
2540 *node,
2541 SOCK_IN,
2542 SOCK_FLOAT,
2544 "Highlights Gamma",
2545 "Highlights Gamma");
2546 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->highlights.gamma;
2547 }
2548
2549 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Highlights Gain")) {
2551 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Highlights Gain", "Highlights Gain");
2552 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->highlights.gain;
2553 }
2554
2555 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Highlights Lift")) {
2557 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Highlights Lift", "Highlights Lift");
2558 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->highlights.lift;
2559 }
2560
2561 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Midtones Start")) {
2563 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Midtones Start", "Midtones Start");
2564 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->startmidtones;
2565 }
2566
2567 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Midtones End")) {
2569 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Midtones End", "Midtones End");
2570 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->endmidtones;
2571 }
2572
2573 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Apply On Red")) {
2575 *node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Apply On Red", "Apply On Red");
2576 input->default_value_typed<bNodeSocketValueBoolean>()->value = bool(node->custom1 & (1 << 0));
2577 }
2578
2579 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Apply On Green")) {
2581 *node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Apply On Green", "Apply On Green");
2582 input->default_value_typed<bNodeSocketValueBoolean>()->value = bool(node->custom1 & (1 << 1));
2583 }
2584
2585 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Apply On Blue")) {
2587 *node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Apply On Blue", "Apply On Blue");
2588 input->default_value_typed<bNodeSocketValueBoolean>()->value = bool(node->custom1 & (1 << 2));
2589 }
2590
2591 MEM_freeN(storage);
2592 node->storage = nullptr;
2593}
2594
2595/* The options were converted into inputs. */
2597 bNode *node)
2598{
2599 /* Compute the RNA path of the node. */
2600 char escaped_node_name[sizeof(node->name) * 2 + 1];
2601 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
2602 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
2603
2604 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
2605 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
2606 * path. */
2607 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
2608 return;
2609 }
2610
2611 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
2612 * values of the FCurves frames when needed. */
2613 char *old_rna_path = fcurve->rna_path;
2614 if (BLI_str_endswith(fcurve->rna_path, "use_motion_blur")) {
2615 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[1].default_value");
2616 }
2617 else if (BLI_str_endswith(fcurve->rna_path, "master_saturation")) {
2618 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
2619 }
2620 else if (BLI_str_endswith(fcurve->rna_path, "master_contrast")) {
2621 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
2622 }
2623 else if (BLI_str_endswith(fcurve->rna_path, "master_gamma")) {
2624 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[4].default_value");
2625 }
2626 else if (BLI_str_endswith(fcurve->rna_path, "master_gain")) {
2627 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[5].default_value");
2628 }
2629 else if (BLI_str_endswith(fcurve->rna_path, "master_lift")) {
2630 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[6].default_value");
2631 }
2632 else if (BLI_str_endswith(fcurve->rna_path, "highlights_saturation")) {
2633 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[7].default_value");
2634 }
2635 else if (BLI_str_endswith(fcurve->rna_path, "highlights_contrast")) {
2636 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[8].default_value");
2637 }
2638 else if (BLI_str_endswith(fcurve->rna_path, "highlights_gamma")) {
2639 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[9].default_value");
2640 }
2641 else if (BLI_str_endswith(fcurve->rna_path, "highlights_gain")) {
2642 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[10].default_value");
2643 }
2644 else if (BLI_str_endswith(fcurve->rna_path, "highlights_lift")) {
2645 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[11].default_value");
2646 }
2647 else if (BLI_str_endswith(fcurve->rna_path, "midtones_saturation")) {
2648 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[12].default_value");
2649 }
2650 else if (BLI_str_endswith(fcurve->rna_path, "midtones_contrast")) {
2651 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[13].default_value");
2652 }
2653 else if (BLI_str_endswith(fcurve->rna_path, "midtones_gamma")) {
2654 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[14].default_value");
2655 }
2656 else if (BLI_str_endswith(fcurve->rna_path, "midtones_gain")) {
2657 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[15].default_value");
2658 }
2659 else if (BLI_str_endswith(fcurve->rna_path, "midtones_lift")) {
2660 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[16].default_value");
2661 }
2662 else if (BLI_str_endswith(fcurve->rna_path, "shadows_saturation")) {
2663 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[17].default_value");
2664 }
2665 else if (BLI_str_endswith(fcurve->rna_path, "shadows_contrast")) {
2666 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[18].default_value");
2667 }
2668 else if (BLI_str_endswith(fcurve->rna_path, "shadows_gamma")) {
2669 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[19].default_value");
2670 }
2671 else if (BLI_str_endswith(fcurve->rna_path, "shadows_gain")) {
2672 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[20].default_value");
2673 }
2674 else if (BLI_str_endswith(fcurve->rna_path, "shadows_lift")) {
2675 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[21].default_value");
2676 }
2677 else if (BLI_str_endswith(fcurve->rna_path, "midtones_start")) {
2678 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[22].default_value");
2679 }
2680 else if (BLI_str_endswith(fcurve->rna_path, "midtones_end")) {
2681 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[23].default_value");
2682 }
2683 else if (BLI_str_endswith(fcurve->rna_path, "red")) {
2684 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[24].default_value");
2685 }
2686 else if (BLI_str_endswith(fcurve->rna_path, "green")) {
2687 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[25].default_value");
2688 }
2689 else if (BLI_str_endswith(fcurve->rna_path, "blue")) {
2690 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[26].default_value");
2691 }
2692
2693 /* The RNA path was changed, free the old path. */
2694 if (fcurve->rna_path != old_rna_path) {
2695 MEM_freeN(old_rna_path);
2696 }
2697 });
2698}
2699
2700/* The options were converted into inputs. */
2702{
2703 NodeLensDist *storage = static_cast<NodeLensDist *>(node->storage);
2704 if (!storage) {
2705 return;
2706 }
2707
2708 /* Use Projector boolean option is now an enum between two types. */
2709 storage->distortion_type = storage->proj ? CMP_NODE_LENS_DISTORTION_HORIZONTAL :
2711
2712 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Jitter")) {
2714 *node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Jitter", "Jitter");
2715 input->default_value_typed<bNodeSocketValueBoolean>()->value = bool(storage->jit);
2716 }
2717
2718 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Fit")) {
2720 *node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Fit", "Fit");
2721 input->default_value_typed<bNodeSocketValueBoolean>()->value = bool(storage->fit);
2722 }
2723}
2724
2725/* The options were converted into inputs. */
2727 bNode *node)
2728{
2729 /* Compute the RNA path of the node. */
2730 char escaped_node_name[sizeof(node->name) * 2 + 1];
2731 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
2732 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
2733
2734 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
2735 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
2736 * path. */
2737 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
2738 return;
2739 }
2740
2741 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
2742 * values of the FCurves frames when needed. */
2743 char *old_rna_path = fcurve->rna_path;
2744 if (BLI_str_endswith(fcurve->rna_path, "use_jitter")) {
2745 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
2746 }
2747 else if (BLI_str_endswith(fcurve->rna_path, "use_fit")) {
2748 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[4].default_value");
2749 }
2750 else if (BLI_str_endswith(fcurve->rna_path, "use_projector")) {
2751 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "distortion_type");
2752 }
2753
2754 /* The RNA path was changed, free the old path. */
2755 if (fcurve->rna_path != old_rna_path) {
2756 MEM_freeN(old_rna_path);
2757 }
2758 });
2759}
2760
2761/* The options were converted into inputs. */
2763{
2764 NodeBoxMask *storage = static_cast<NodeBoxMask *>(node->storage);
2765 if (!storage) {
2766 return;
2767 }
2768
2769 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Position")) {
2771 *node_tree, *node, SOCK_IN, SOCK_VECTOR, PROP_FACTOR, "Position", "Position");
2772 input->default_value_typed<bNodeSocketValueVector>()->value[0] = storage->x;
2773 input->default_value_typed<bNodeSocketValueVector>()->value[1] = storage->y;
2774 }
2775
2776 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Size")) {
2778 *node_tree, *node, SOCK_IN, SOCK_VECTOR, PROP_FACTOR, "Size", "Size");
2779 input->default_value_typed<bNodeSocketValueVector>()->value[0] = storage->width;
2780 input->default_value_typed<bNodeSocketValueVector>()->value[1] = storage->height;
2781 }
2782
2783 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Rotation")) {
2785 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_ANGLE, "Rotation", "Rotation");
2786 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->rotation;
2787 }
2788
2789 MEM_freeN(storage);
2790 node->storage = nullptr;
2791}
2792
2793/* The options were converted into inputs. */
2795{
2796 /* Compute the RNA path of the node. */
2797 char escaped_node_name[sizeof(node->name) * 2 + 1];
2798 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
2799 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
2800
2801 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
2802 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
2803 * path. */
2804 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
2805 return;
2806 }
2807
2808 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
2809 * values of the FCurves frames when needed. */
2810 char *old_rna_path = fcurve->rna_path;
2811 if (BLI_str_endswith(fcurve->rna_path, "x")) {
2812 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
2813 fcurve->array_index = 0;
2814 }
2815 else if (BLI_str_endswith(fcurve->rna_path, "y")) {
2816 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
2817 fcurve->array_index = 1;
2818 }
2819 else if (BLI_str_endswith(fcurve->rna_path, "mask_width")) {
2820 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
2821 fcurve->array_index = 0;
2822 }
2823 else if (BLI_str_endswith(fcurve->rna_path, "mask_height")) {
2824 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
2825 fcurve->array_index = 1;
2826 }
2827 else if (BLI_str_endswith(fcurve->rna_path, "rotation")) {
2828 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[4].default_value");
2829 }
2830
2831 /* The RNA path was changed, free the old path. */
2832 if (fcurve->rna_path != old_rna_path) {
2833 MEM_freeN(old_rna_path);
2834 }
2835 });
2836}
2837
2838/* The options were converted into inputs. */
2840{
2841 NodeEllipseMask *storage = static_cast<NodeEllipseMask *>(node->storage);
2842 if (!storage) {
2843 return;
2844 }
2845
2846 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Position")) {
2848 *node_tree, *node, SOCK_IN, SOCK_VECTOR, PROP_FACTOR, "Position", "Position");
2849 input->default_value_typed<bNodeSocketValueVector>()->value[0] = storage->x;
2850 input->default_value_typed<bNodeSocketValueVector>()->value[1] = storage->y;
2851 }
2852
2853 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Size")) {
2855 *node_tree, *node, SOCK_IN, SOCK_VECTOR, PROP_FACTOR, "Size", "Size");
2856 input->default_value_typed<bNodeSocketValueVector>()->value[0] = storage->width;
2857 input->default_value_typed<bNodeSocketValueVector>()->value[1] = storage->height;
2858 }
2859
2860 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Rotation")) {
2862 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_ANGLE, "Rotation", "Rotation");
2863 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->rotation;
2864 }
2865
2866 MEM_freeN(storage);
2867 node->storage = nullptr;
2868}
2869
2870/* The options were converted into inputs. */
2872 bNode *node)
2873{
2874 /* Compute the RNA path of the node. */
2875 char escaped_node_name[sizeof(node->name) * 2 + 1];
2876 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
2877 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
2878
2879 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
2880 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
2881 * path. */
2882 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
2883 return;
2884 }
2885
2886 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
2887 * values of the FCurves frames when needed. */
2888 char *old_rna_path = fcurve->rna_path;
2889 if (BLI_str_endswith(fcurve->rna_path, "x")) {
2890 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
2891 fcurve->array_index = 0;
2892 }
2893 else if (BLI_str_endswith(fcurve->rna_path, "y")) {
2894 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
2895 fcurve->array_index = 1;
2896 }
2897 else if (BLI_str_endswith(fcurve->rna_path, "mask_width")) {
2898 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
2899 fcurve->array_index = 0;
2900 }
2901 else if (BLI_str_endswith(fcurve->rna_path, "mask_height")) {
2902 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
2903 fcurve->array_index = 1;
2904 }
2905 else if (BLI_str_endswith(fcurve->rna_path, "rotation")) {
2906 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[4].default_value");
2907 }
2908
2909 /* The RNA path was changed, free the old path. */
2910 if (fcurve->rna_path != old_rna_path) {
2911 MEM_freeN(old_rna_path);
2912 }
2913 });
2914}
2915
2916/* The options were converted into inputs. */
2918{
2919 NodeSunBeams *storage = static_cast<NodeSunBeams *>(node->storage);
2920 if (!storage) {
2921 return;
2922 }
2923
2924 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Source")) {
2926 *node_tree, *node, SOCK_IN, SOCK_VECTOR, PROP_FACTOR, "Source", "Source");
2927 input->default_value_typed<bNodeSocketValueVector>()->value[0] = storage->source[0];
2928 input->default_value_typed<bNodeSocketValueVector>()->value[1] = storage->source[1];
2929 }
2930
2931 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Length")) {
2933 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Length", "Length");
2934 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->ray_length;
2935 }
2936
2937 MEM_freeN(storage);
2938 node->storage = nullptr;
2939}
2940
2941/* The options were converted into inputs. */
2943 bNode *node)
2944{
2945 /* Compute the RNA path of the node. */
2946 char escaped_node_name[sizeof(node->name) * 2 + 1];
2947 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
2948 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
2949
2950 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
2951 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
2952 * path. */
2953 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
2954 return;
2955 }
2956
2957 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
2958 * values of the FCurves frames when needed. */
2959 char *old_rna_path = fcurve->rna_path;
2960 if (BLI_str_endswith(fcurve->rna_path, "source")) {
2961 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[1].default_value");
2962 }
2963 else if (BLI_str_endswith(fcurve->rna_path, "ray_length")) {
2964 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
2965 }
2966
2967 /* The RNA path was changed, free the old path. */
2968 if (fcurve->rna_path != old_rna_path) {
2969 MEM_freeN(old_rna_path);
2970 }
2971 });
2972}
2973
2974/* The options were converted into inputs. */
2976{
2977 NodeDBlurData *storage = static_cast<NodeDBlurData *>(node->storage);
2978 if (!storage) {
2979 return;
2980 }
2981
2982 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Samples")) {
2984 *node_tree, *node, SOCK_IN, SOCK_INT, PROP_NONE, "Samples", "Samples");
2985 input->default_value_typed<bNodeSocketValueInt>()->value = storage->iter;
2986 }
2987
2988 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Center")) {
2990 *node_tree, *node, SOCK_IN, SOCK_VECTOR, PROP_FACTOR, "Center", "Center");
2991 input->default_value_typed<bNodeSocketValueVector>()->value[0] = storage->center_x;
2992 input->default_value_typed<bNodeSocketValueVector>()->value[1] = storage->center_y;
2993 }
2994
2995 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Translation Amount")) {
2997 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Translation Amount", "Amount");
2998 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->distance;
2999 }
3000
3001 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Translation Direction")) {
3003 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_ANGLE, "Translation Direction", "Direction");
3004 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->angle;
3005 }
3006
3007 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Rotation")) {
3009 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_ANGLE, "Rotation", "Rotation");
3010 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->spin;
3011 }
3012
3013 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Scale")) {
3015 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_NONE, "Scale", "Scale");
3016 /* Scale was previously minus 1. */
3017 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->zoom + 1.0f;
3018 }
3019
3020 MEM_freeN(storage);
3021 node->storage = nullptr;
3022}
3023
3024/* The options were converted into inputs. */
3026 bNode *node)
3027{
3028 /* Compute the RNA path of the node. */
3029 char escaped_node_name[sizeof(node->name) * 2 + 1];
3030 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
3031 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
3032
3033 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
3034 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
3035 * path. */
3036 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
3037 return;
3038 }
3039
3040 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
3041 * values of the FCurves frames when needed. */
3042 char *old_rna_path = fcurve->rna_path;
3043 if (BLI_str_endswith(fcurve->rna_path, "iterations")) {
3044 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[1].default_value");
3045 }
3046 else if (BLI_str_endswith(fcurve->rna_path, "center_x")) {
3047 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
3048 fcurve->array_index = 0;
3049 }
3050 else if (BLI_str_endswith(fcurve->rna_path, "center_y")) {
3051 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
3052 fcurve->array_index = 1;
3053 }
3054 else if (BLI_str_endswith(fcurve->rna_path, "spin")) {
3055 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
3056 }
3057 else if (BLI_str_endswith(fcurve->rna_path, "zoom")) {
3058 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[4].default_value");
3059 /* Scale was previously minus 1. */
3060 adjust_fcurve_key_frame_values(
3061 fcurve, PROP_FLOAT, [&](const float value) { return value + 1.0f; });
3062 }
3063 else if (BLI_str_endswith(fcurve->rna_path, "distance")) {
3064 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[5].default_value");
3065 }
3066 else if (BLI_str_endswith(fcurve->rna_path, "angle")) {
3067 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[6].default_value");
3068 }
3069
3070 /* The RNA path was changed, free the old path. */
3071 if (fcurve->rna_path != old_rna_path) {
3072 MEM_freeN(old_rna_path);
3073 }
3074 });
3075}
3076
3077/* The options were converted into inputs. */
3079{
3080 NodeBilateralBlurData *storage = static_cast<NodeBilateralBlurData *>(node->storage);
3081 if (!storage) {
3082 return;
3083 }
3084
3085 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Size")) {
3087 *node_tree, *node, SOCK_IN, SOCK_INT, PROP_NONE, "Size", "Size");
3088 input->default_value_typed<bNodeSocketValueInt>()->value = std::ceil(storage->iter +
3089 storage->sigma_space);
3090 }
3091
3092 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Threshold")) {
3094 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_NONE, "Threshold", "Threshold");
3095 /* Threshold was previously multiplied by 3. */
3096 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->sigma_color / 3.0f;
3097 }
3098
3099 MEM_freeN(storage);
3100 node->storage = nullptr;
3101}
3102
3103/* The options were converted into inputs. */
3105 bNode *node)
3106{
3107 /* Compute the RNA path of the node. */
3108 char escaped_node_name[sizeof(node->name) * 2 + 1];
3109 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
3110 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
3111
3112 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
3113 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
3114 * path. */
3115 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
3116 return;
3117 }
3118
3119 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
3120 * values of the FCurves frames when needed. */
3121 char *old_rna_path = fcurve->rna_path;
3122 if (BLI_str_endswith(fcurve->rna_path, "iterations")) {
3123 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
3124 }
3125 else if (BLI_str_endswith(fcurve->rna_path, "sigma_color")) {
3126 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
3127 }
3128
3129 /* The RNA path was changed, free the old path. */
3130 if (fcurve->rna_path != old_rna_path) {
3131 MEM_freeN(old_rna_path);
3132 }
3133 });
3134}
3135
3136/* The Use Alpha option and Alpha input were removed. If Use Alpha was disabled, set the input
3137 * alpha to 1 using a Set Alpha node, otherwise, if the Alpha input is linked, set it to the image
3138 * using a Set Alpha node. */
3140{
3141 /* Maps the names of the viewer and composite nodes to the links going into their image and alpha
3142 * inputs. */
3143 blender::Map<std::string, bNodeLink *> node_to_image_link_map;
3144 blender::Map<std::string, bNodeLink *> node_to_alpha_link_map;
3145
3146 /* Find links going into the composite and viewer nodes. */
3147 LISTBASE_FOREACH (bNodeLink *, link, &node_tree->links) {
3148 if (!ELEM(link->tonode->type_legacy, CMP_NODE_COMPOSITE, CMP_NODE_VIEWER)) {
3149 continue;
3150 }
3151
3152 if (blender::StringRef(link->tosock->identifier) == "Image") {
3153 node_to_image_link_map.add_new(link->tonode->name, link);
3154 }
3155 else if (blender::StringRef(link->tosock->identifier) == "Alpha") {
3156 node_to_alpha_link_map.add_new(link->tonode->name, link);
3157 }
3158 }
3159
3160 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
3161 if (!ELEM(node->type_legacy, CMP_NODE_COMPOSITE, CMP_NODE_VIEWER)) {
3162 continue;
3163 }
3164
3165 bNodeSocket *image_input = blender::bke::node_find_socket(*node, SOCK_IN, "Image");
3166
3167 /* Use Alpha is disabled, so we need to set the alpha to 1. */
3168 if (node->custom2 & CMP_NODE_OUTPUT_IGNORE_ALPHA) {
3169 /* Nothing is connected to the image, just set the default value alpha to 1. */
3170 if (!node_to_image_link_map.contains(node->name)) {
3171 image_input->default_value_typed<bNodeSocketValueRGBA>()->value[3] = 1.0f;
3172 continue;
3173 }
3174
3175 bNodeLink *image_link = node_to_image_link_map.lookup(node->name);
3176
3177 /* Add a set alpha node and make the necessary connections. */
3178 bNode *set_alpha_node = blender::bke::node_add_static_node(
3179 nullptr, *node_tree, CMP_NODE_SETALPHA);
3180 set_alpha_node->parent = node->parent;
3181 set_alpha_node->location[0] = node->location[0] - node->width - 20.0f;
3182 set_alpha_node->location[1] = node->location[1];
3183
3184 NodeSetAlpha *data = static_cast<NodeSetAlpha *>(set_alpha_node->storage);
3186
3188 *set_alpha_node, SOCK_IN, "Image");
3189 bNodeSocket *set_alpha_output = blender::bke::node_find_socket(
3190 *set_alpha_node, SOCK_OUT, "Image");
3191
3192 version_node_add_link(*node_tree,
3193 *image_link->fromnode,
3194 *image_link->fromsock,
3195 *set_alpha_node,
3196 *set_alpha_input);
3197 version_node_add_link(*node_tree, *set_alpha_node, *set_alpha_output, *node, *image_input);
3198
3199 blender::bke::node_remove_link(node_tree, *image_link);
3200 continue;
3201 }
3202
3203 /* If we don't continue, the alpha input is connected and Use Alpha is enabled, so we need to
3204 * set the alpha using a Set Alpha node. */
3205 if (!node_to_alpha_link_map.contains(node->name)) {
3206 continue;
3207 }
3208
3209 bNodeLink *alpha_link = node_to_alpha_link_map.lookup(node->name);
3210
3211 /* Add a set alpha node and make the necessary connections. */
3212 bNode *set_alpha_node = blender::bke::node_add_static_node(
3213 nullptr, *node_tree, CMP_NODE_SETALPHA);
3214 set_alpha_node->parent = node->parent;
3215 set_alpha_node->location[0] = node->location[0] - node->width - 20.0f;
3216 set_alpha_node->location[1] = node->location[1];
3217
3218 NodeSetAlpha *data = static_cast<NodeSetAlpha *>(set_alpha_node->storage);
3220
3222 *set_alpha_node, SOCK_IN, "Image");
3224 *set_alpha_node, SOCK_IN, "Alpha");
3225 bNodeSocket *set_alpha_output = blender::bke::node_find_socket(
3226 *set_alpha_node, SOCK_OUT, "Image");
3227
3228 version_node_add_link(*node_tree,
3229 *alpha_link->fromnode,
3230 *alpha_link->fromsock,
3231 *set_alpha_node,
3232 *set_alpha_alpha);
3233 version_node_add_link(*node_tree, *set_alpha_node, *set_alpha_output, *node, *image_input);
3234 blender::bke::node_remove_link(node_tree, *alpha_link);
3235
3236 if (!node_to_image_link_map.contains(node->name)) {
3237 copy_v4_v4(set_alpha_input->default_value_typed<bNodeSocketValueRGBA>()->value,
3238 image_input->default_value_typed<bNodeSocketValueRGBA>()->value);
3239 }
3240 else {
3241 bNodeLink *image_link = node_to_image_link_map.lookup(node->name);
3242 version_node_add_link(*node_tree,
3243 *image_link->fromnode,
3244 *image_link->fromsock,
3245 *set_alpha_node,
3246 *set_alpha_input);
3247 blender::bke::node_remove_link(node_tree, *image_link);
3248 }
3249 }
3250}
3251
3252/* The Convert Premultiplied option was removed. If enabled, a convert alpha node will be added
3253 * before and after the node to perform the adjustment in straight alpha. */
3255{
3256 LISTBASE_FOREACH_BACKWARD_MUTABLE (bNodeLink *, link, &node_tree->links) {
3257 if (link->tonode->type_legacy != CMP_NODE_BRIGHTCONTRAST) {
3258 continue;
3259 }
3260
3261 if (!bool(link->tonode->custom1)) {
3262 continue;
3263 }
3264
3265 if (blender::StringRef(link->tosock->identifier) != "Image") {
3266 continue;
3267 }
3268
3269 bNode *convert_alpha_node = blender::bke::node_add_static_node(
3270 nullptr, *node_tree, CMP_NODE_PREMULKEY);
3271 convert_alpha_node->parent = link->tonode->parent;
3272 convert_alpha_node->location[0] = link->tonode->location[0] - link->tonode->width - 20.0f;
3273 convert_alpha_node->location[1] = link->tonode->location[1];
3274 convert_alpha_node->custom1 = CMP_NODE_ALPHA_CONVERT_UNPREMULTIPLY;
3275
3276 bNodeSocket *convert_alpha_input = blender::bke::node_find_socket(
3277 *convert_alpha_node, SOCK_IN, "Image");
3278 bNodeSocket *convert_alpha_output = blender::bke::node_find_socket(
3279 *convert_alpha_node, SOCK_OUT, "Image");
3280
3282 *node_tree, *link->fromnode, *link->fromsock, *convert_alpha_node, *convert_alpha_input);
3284 *node_tree, *convert_alpha_node, *convert_alpha_output, *link->tonode, *link->tosock);
3285
3286 blender::bke::node_remove_link(node_tree, *link);
3287 }
3288
3289 LISTBASE_FOREACH_BACKWARD_MUTABLE (bNodeLink *, link, &node_tree->links) {
3290 if (link->fromnode->type_legacy != CMP_NODE_BRIGHTCONTRAST) {
3291 continue;
3292 }
3293
3294 if (!bool(link->fromnode->custom1)) {
3295 continue;
3296 }
3297
3298 bNode *convert_alpha_node = blender::bke::node_add_static_node(
3299 nullptr, *node_tree, CMP_NODE_PREMULKEY);
3300 convert_alpha_node->parent = link->fromnode->parent;
3301 convert_alpha_node->location[0] = link->fromnode->location[0] + link->fromnode->width + 20.0f;
3302 convert_alpha_node->location[1] = link->fromnode->location[1];
3303 convert_alpha_node->custom1 = CMP_NODE_ALPHA_CONVERT_PREMULTIPLY;
3304
3305 bNodeSocket *convert_alpha_input = blender::bke::node_find_socket(
3306 *convert_alpha_node, SOCK_IN, "Image");
3307 bNodeSocket *convert_alpha_output = blender::bke::node_find_socket(
3308 *convert_alpha_node, SOCK_OUT, "Image");
3309
3311 *node_tree, *link->fromnode, *link->fromsock, *convert_alpha_node, *convert_alpha_input);
3313 *node_tree, *convert_alpha_node, *convert_alpha_output, *link->tonode, *link->tosock);
3314
3315 blender::bke::node_remove_link(node_tree, *link);
3316 }
3317}
3318
3319/* The Premultiply Mix option was removed. If enabled, the image is converted to premultiplied then
3320 * to straight, and both are mixed using a mix node. */
3322{
3323 LISTBASE_FOREACH_BACKWARD_MUTABLE (bNodeLink *, link, &node_tree->links) {
3324 if (link->tonode->type_legacy != CMP_NODE_ALPHAOVER) {
3325 continue;
3326 }
3327
3328 const float mix_factor = static_cast<NodeTwoFloats *>(link->tonode->storage)->x;
3329 if (mix_factor == 0.0f) {
3330 continue;
3331 }
3332
3333 if (blender::StringRef(link->tosock->identifier) != "Image_001") {
3334 continue;
3335 }
3336
3337 /* Disable Convert Premultiplied option, since this will be done manually. */
3338 link->tonode->custom1 = false;
3339
3340 bNode *mix_node = blender::bke::node_add_static_node(nullptr, *node_tree, SH_NODE_MIX);
3341 mix_node->parent = link->tonode->parent;
3342 mix_node->location[0] = link->tonode->location[0] - link->tonode->width - 20.0f;
3343 mix_node->location[1] = link->tonode->location[1];
3344 static_cast<NodeShaderMix *>(mix_node->storage)->data_type = SOCK_RGBA;
3345
3346 bNodeSocket *mix_a_input = blender::bke::node_find_socket(*mix_node, SOCK_IN, "A_Color");
3347 bNodeSocket *mix_b_input = blender::bke::node_find_socket(*mix_node, SOCK_IN, "B_Color");
3348 bNodeSocket *mix_factor_input = blender::bke::node_find_socket(
3349 *mix_node, SOCK_IN, "Factor_Float");
3350 bNodeSocket *mix_output = blender::bke::node_find_socket(*mix_node, SOCK_OUT, "Result_Color");
3351
3352 mix_factor_input->default_value_typed<bNodeSocketValueFloat>()->value = mix_factor;
3353
3354 bNode *to_straight_node = blender::bke::node_add_static_node(
3355 nullptr, *node_tree, CMP_NODE_PREMULKEY);
3356 to_straight_node->parent = link->tonode->parent;
3357 to_straight_node->location[0] = mix_node->location[0] - mix_node->width - 20.0f;
3358 to_straight_node->location[1] = mix_node->location[1];
3359 to_straight_node->custom1 = CMP_NODE_ALPHA_CONVERT_UNPREMULTIPLY;
3360
3361 bNodeSocket *to_straight_input = blender::bke::node_find_socket(
3362 *to_straight_node, SOCK_IN, "Image");
3363 bNodeSocket *to_straight_output = blender::bke::node_find_socket(
3364 *to_straight_node, SOCK_OUT, "Image");
3365
3366 bNode *to_premultiplied_node = blender::bke::node_add_static_node(
3367 nullptr, *node_tree, CMP_NODE_PREMULKEY);
3368 to_premultiplied_node->parent = link->tonode->parent;
3369 to_premultiplied_node->location[0] = to_straight_node->location[0] - to_straight_node->width -
3370 20.0f;
3371 to_premultiplied_node->location[1] = to_straight_node->location[1];
3372 to_premultiplied_node->custom1 = CMP_NODE_ALPHA_CONVERT_PREMULTIPLY;
3373
3374 bNodeSocket *to_premultiplied_input = blender::bke::node_find_socket(
3375 *to_premultiplied_node, SOCK_IN, "Image");
3376 bNodeSocket *to_premultiplied_output = blender::bke::node_find_socket(
3377 *to_premultiplied_node, SOCK_OUT, "Image");
3378
3379 version_node_add_link(*node_tree,
3380 *link->fromnode,
3381 *link->fromsock,
3382 *to_premultiplied_node,
3383 *to_premultiplied_input);
3384 version_node_add_link(*node_tree,
3385 *to_premultiplied_node,
3386 *to_premultiplied_output,
3387 *to_straight_node,
3388 *to_straight_input);
3390 *node_tree, *to_premultiplied_node, *to_premultiplied_output, *mix_node, *mix_b_input);
3392 *node_tree, *to_straight_node, *to_straight_output, *mix_node, *mix_a_input);
3393 version_node_add_link(*node_tree, *mix_node, *mix_output, *link->tonode, *link->tosock);
3394
3395 blender::bke::node_remove_link(node_tree, *link);
3396 }
3397
3398 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
3399 if (node->type_legacy == CMP_NODE_ALPHAOVER) {
3400 NodeTwoFloats *storage = static_cast<NodeTwoFloats *>(node->storage);
3401 MEM_freeN(storage);
3402 node->storage = nullptr;
3403 }
3404 }
3405}
3406
3407/* The options were converted into inputs. */
3409{
3410 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Straight Alpha")) {
3412 *node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Straight Alpha", "Straight Alpha");
3413 input->default_value_typed<bNodeSocketValueBoolean>()->value = bool(node->custom1);
3414 }
3415}
3416
3417/* The options were converted into inputs. */
3419 bNode *node)
3420{
3421 /* Compute the RNA path of the node. */
3422 char escaped_node_name[sizeof(node->name) * 2 + 1];
3423 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
3424 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
3425
3426 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
3427 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
3428 * path. */
3429 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
3430 return;
3431 }
3432
3433 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
3434 * values of the FCurves frames when needed. */
3435 char *old_rna_path = fcurve->rna_path;
3436 if (BLI_str_endswith(fcurve->rna_path, "use_premultiply")) {
3437 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
3438 }
3439
3440 /* The RNA path was changed, free the old path. */
3441 if (fcurve->rna_path != old_rna_path) {
3442 MEM_freeN(old_rna_path);
3443 }
3444 });
3445}
3446
3447/* The options were converted into inputs. */
3449{
3450 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Extend Bounds")) {
3452 *node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Extend Bounds", "Extend Bounds");
3453 input->default_value_typed<bNodeSocketValueBoolean>()->value = bool(node->custom1);
3454 }
3455}
3456
3457/* The options were converted into inputs. */
3459 bNode *node)
3460{
3461 /* Compute the RNA path of the node. */
3462 char escaped_node_name[sizeof(node->name) * 2 + 1];
3463 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
3464 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
3465
3466 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
3467 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
3468 * path. */
3469 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
3470 return;
3471 }
3472
3473 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
3474 * values of the FCurves frames when needed. */
3475 char *old_rna_path = fcurve->rna_path;
3476 if (BLI_str_endswith(fcurve->rna_path, "use_extended_bounds")) {
3477 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[4].default_value");
3478 }
3479
3480 /* The RNA path was changed, free the old path. */
3481 if (fcurve->rna_path != old_rna_path) {
3482 MEM_freeN(old_rna_path);
3483 }
3484 });
3485}
3486
3487/* The XY Offset option was removed. If enabled, the image is translated in relative space using X
3488 * and Y, so add a Translate node to achieve the same function. */
3490{
3491 LISTBASE_FOREACH_BACKWARD_MUTABLE (bNodeLink *, link, &node_tree->links) {
3492 if (link->fromnode->type_legacy != CMP_NODE_SCALE) {
3493 continue;
3494 }
3495
3496 if (link->fromnode->custom1 != CMP_NODE_SCALE_RENDER_SIZE) {
3497 continue;
3498 }
3499
3500 const float x = link->fromnode->custom3;
3501 const float y = link->fromnode->custom4;
3502 if (x == 0.0f && y == 0.0f) {
3503 continue;
3504 }
3505
3506 bNode *translate_node = blender::bke::node_add_static_node(
3507 nullptr, *node_tree, CMP_NODE_TRANSLATE);
3508 translate_node->parent = link->fromnode->parent;
3509 translate_node->location[0] = link->fromnode->location[0] + link->fromnode->width + 20.0f;
3510 translate_node->location[1] = link->fromnode->location[1];
3511 static_cast<NodeTranslateData *>(translate_node->storage)->interpolation =
3512 static_cast<NodeScaleData *>(link->fromnode->storage)->interpolation;
3513 static_cast<NodeTranslateData *>(translate_node->storage)->relative = true;
3514
3515 bNodeSocket *translate_image_input = blender::bke::node_find_socket(
3516 *translate_node, SOCK_IN, "Image");
3517 bNodeSocket *translate_x_input = blender::bke::node_find_socket(*translate_node, SOCK_IN, "X");
3518 bNodeSocket *translate_y_input = blender::bke::node_find_socket(*translate_node, SOCK_IN, "Y");
3519 bNodeSocket *translate_image_output = blender::bke::node_find_socket(
3520 *translate_node, SOCK_OUT, "Image");
3521
3522 translate_x_input->default_value_typed<bNodeSocketValueFloat>()->value = x;
3523 translate_y_input->default_value_typed<bNodeSocketValueFloat>()->value = y;
3524
3526 *node_tree, *link->fromnode, *link->fromsock, *translate_node, *translate_image_input);
3528 *node_tree, *translate_node, *translate_image_output, *link->tonode, *link->tosock);
3529
3530 blender::bke::node_remove_link(node_tree, *link);
3531 }
3532}
3533
3539static void version_escape_curly_braces(char string[], const int string_array_length)
3540{
3541 int bytes_processed = 0;
3542 while (bytes_processed < string_array_length && string[bytes_processed] != '\0') {
3543 if (string[bytes_processed] == '{') {
3545 string, string_array_length, bytes_processed, bytes_processed + 1, "{{");
3546 bytes_processed += 2;
3547 continue;
3548 }
3549 if (string[bytes_processed] == '}') {
3551 string, string_array_length, bytes_processed, bytes_processed + 1, "}}");
3552 bytes_processed += 2;
3553 continue;
3554 }
3555 bytes_processed++;
3556 }
3557}
3558
3559/* The Gamma option was removed. If enabled, a Gamma node will be added before and after
3560 * the node to perform the adjustment in sRGB space. */
3562{
3563 LISTBASE_FOREACH_BACKWARD_MUTABLE (bNodeLink *, link, &node_tree->links) {
3564 if (!ELEM(link->tonode->type_legacy, CMP_NODE_BLUR, CMP_NODE_DEFOCUS)) {
3565 continue;
3566 }
3567
3568 if (link->tonode->type_legacy == CMP_NODE_BLUR &&
3569 !bool(static_cast<NodeBlurData *>(link->tonode->storage)->gamma))
3570 {
3571 continue;
3572 }
3573
3574 if (link->tonode->type_legacy == CMP_NODE_DEFOCUS &&
3575 !bool(static_cast<NodeDefocus *>(link->tonode->storage)->gamco))
3576 {
3577 continue;
3578 }
3579
3580 if (blender::StringRef(link->tosock->identifier) != "Image") {
3581 continue;
3582 }
3583
3584 bNode *gamma_node = blender::bke::node_add_static_node(nullptr, *node_tree, CMP_NODE_GAMMA);
3585 gamma_node->parent = link->tonode->parent;
3586 gamma_node->location[0] = link->tonode->location[0] - link->tonode->width - 20.0f;
3587 gamma_node->location[1] = link->tonode->location[1];
3588
3589 bNodeSocket *image_input = blender::bke::node_find_socket(*gamma_node, SOCK_IN, "Image");
3590 bNodeSocket *image_output = blender::bke::node_find_socket(*gamma_node, SOCK_OUT, "Image");
3591
3592 bNodeSocket *gamma_input = blender::bke::node_find_socket(*gamma_node, SOCK_IN, "Gamma");
3593 gamma_input->default_value_typed<bNodeSocketValueFloat>()->value = 2.0f;
3594
3595 version_node_add_link(*node_tree, *link->fromnode, *link->fromsock, *gamma_node, *image_input);
3596 version_node_add_link(*node_tree, *gamma_node, *image_output, *link->tonode, *link->tosock);
3597
3598 blender::bke::node_remove_link(node_tree, *link);
3599 }
3600
3601 LISTBASE_FOREACH_BACKWARD_MUTABLE (bNodeLink *, link, &node_tree->links) {
3602 if (!ELEM(link->fromnode->type_legacy, CMP_NODE_BLUR, CMP_NODE_DEFOCUS)) {
3603 continue;
3604 }
3605
3606 if (link->fromnode->type_legacy == CMP_NODE_BLUR &&
3607 !bool(static_cast<NodeBlurData *>(link->fromnode->storage)->gamma))
3608 {
3609 continue;
3610 }
3611
3612 if (link->fromnode->type_legacy == CMP_NODE_DEFOCUS &&
3613 !bool(static_cast<NodeDefocus *>(link->fromnode->storage)->gamco))
3614 {
3615 continue;
3616 }
3617
3618 bNode *gamma_node = blender::bke::node_add_static_node(nullptr, *node_tree, CMP_NODE_GAMMA);
3619 gamma_node->parent = link->fromnode->parent;
3620 gamma_node->location[0] = link->fromnode->location[0] + link->fromnode->width + 20.0f;
3621 gamma_node->location[1] = link->fromnode->location[1];
3622
3623 bNodeSocket *image_input = blender::bke::node_find_socket(*gamma_node, SOCK_IN, "Image");
3624 bNodeSocket *image_output = blender::bke::node_find_socket(*gamma_node, SOCK_OUT, "Image");
3625
3626 bNodeSocket *gamma_input = blender::bke::node_find_socket(*gamma_node, SOCK_IN, "Gamma");
3627 gamma_input->default_value_typed<bNodeSocketValueFloat>()->value = 0.5f;
3628
3629 version_node_add_link(*node_tree, *link->fromnode, *link->fromsock, *gamma_node, *image_input);
3630 version_node_add_link(*node_tree, *gamma_node, *image_output, *link->tonode, *link->tosock);
3631
3632 blender::bke::node_remove_link(node_tree, *link);
3633 }
3634}
3635
3643{
3644 if (nodetree.type != NTREE_COMPOSIT) {
3645 return;
3646 }
3647
3648 LISTBASE_FOREACH (bNode *, node, &nodetree.nodes) {
3649 if (!STREQ(node->idname, "CompositorNodeOutputFile")) {
3650 continue;
3651 }
3652
3653 NodeImageMultiFile *node_data = static_cast<NodeImageMultiFile *>(node->storage);
3655
3656 LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
3657 NodeImageMultiFileSocket *socket_data = static_cast<NodeImageMultiFileSocket *>(
3658 sock->storage);
3660 }
3661 }
3662}
3663
3664/* The Relative option was removed. Insert Relative To Pixel nodes for the X and Y inputs to
3665 * convert relative values to pixel values. */
3667{
3668 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
3669 if (!STREQ(node->idname, "CompositorNodeTranslate")) {
3670 continue;
3671 }
3672
3673 const NodeTranslateData *data = static_cast<NodeTranslateData *>(node->storage);
3674 if (!data) {
3675 continue;
3676 }
3677
3678 if (!bool(data->relative)) {
3679 continue;
3680 }
3681
3682 /* Find links going into the node. */
3683 bNodeLink *image_link = nullptr;
3684 bNodeLink *x_link = nullptr;
3685 bNodeLink *y_link = nullptr;
3686 LISTBASE_FOREACH (bNodeLink *, link, &node_tree->links) {
3687 if (link->tonode != node) {
3688 continue;
3689 }
3690
3691 if (blender::StringRef(link->tosock->identifier) == "Image") {
3692 image_link = link;
3693 }
3694
3695 if (blender::StringRef(link->tosock->identifier) == "X") {
3696 x_link = link;
3697 }
3698
3699 if (blender::StringRef(link->tosock->identifier) == "Y") {
3700 y_link = link;
3701 }
3702 }
3703
3704 /* Image input is unlinked, so the node does nothing. */
3705 if (!image_link) {
3706 continue;
3707 }
3708
3709 /* Add a Relative To Pixel node, assign it the input of the X translation and connect it to the
3710 * X translation input. */
3711 bNode *x_relative_to_pixel_node = blender::bke::node_add_node(
3712 nullptr, *node_tree, "CompositorNodeRelativeToPixel");
3713 x_relative_to_pixel_node->parent = node->parent;
3714 x_relative_to_pixel_node->location[0] = node->location[0] - node->width - 20.0f;
3715 x_relative_to_pixel_node->location[1] = node->location[1];
3716
3717 x_relative_to_pixel_node->custom1 = CMP_NODE_RELATIVE_TO_PIXEL_DATA_TYPE_FLOAT;
3719
3721 *x_relative_to_pixel_node, SOCK_IN, "Image");
3723 *x_relative_to_pixel_node, SOCK_IN, "Float Value");
3725 *x_relative_to_pixel_node, SOCK_OUT, "Float Value");
3726
3727 bNodeSocket *x_input = blender::bke::node_find_socket(*node, SOCK_IN, "X");
3728 x_value_input->default_value_typed<bNodeSocketValueFloat>()->value =
3729 x_input->default_value_typed<bNodeSocketValueFloat>()->value;
3730
3731 version_node_add_link(*node_tree, *x_relative_to_pixel_node, *x_value_output, *node, *x_input);
3732 version_node_add_link(*node_tree,
3733 *image_link->fromnode,
3734 *image_link->fromsock,
3735 *x_relative_to_pixel_node,
3736 *x_image_input);
3737
3738 if (x_link) {
3739 version_node_add_link(*node_tree,
3740 *x_link->fromnode,
3741 *x_link->fromsock,
3742 *x_relative_to_pixel_node,
3743 *x_value_input);
3744 blender::bke::node_remove_link(node_tree, *x_link);
3745 }
3746
3747 /* Add a Relative To Pixel node, assign it the input of the Y translation and connect it to the
3748 * Y translation input. */
3749 bNode *y_relative_to_pixel_node = blender::bke::node_add_node(
3750 nullptr, *node_tree, "CompositorNodeRelativeToPixel");
3751 y_relative_to_pixel_node->parent = node->parent;
3752 y_relative_to_pixel_node->location[0] = node->location[0] - node->width - 20.0f;
3753 y_relative_to_pixel_node->location[1] = node->location[1] - 20.0f;
3754
3755 y_relative_to_pixel_node->custom1 = CMP_NODE_RELATIVE_TO_PIXEL_DATA_TYPE_FLOAT;
3757
3759 *y_relative_to_pixel_node, SOCK_IN, "Image");
3761 *y_relative_to_pixel_node, SOCK_IN, "Float Value");
3763 *y_relative_to_pixel_node, SOCK_OUT, "Float Value");
3764
3765 bNodeSocket *y_input = blender::bke::node_find_socket(*node, SOCK_IN, "Y");
3766 y_value_input->default_value_typed<bNodeSocketValueFloat>()->value =
3767 y_input->default_value_typed<bNodeSocketValueFloat>()->value;
3768
3769 version_node_add_link(*node_tree, *y_relative_to_pixel_node, *y_value_output, *node, *y_input);
3770 version_node_add_link(*node_tree,
3771 *image_link->fromnode,
3772 *image_link->fromsock,
3773 *y_relative_to_pixel_node,
3774 *y_image_input);
3775
3776 if (y_link) {
3777 version_node_add_link(*node_tree,
3778 *y_link->fromnode,
3779 *y_link->fromsock,
3780 *y_relative_to_pixel_node,
3781 *y_value_input);
3782 blender::bke::node_remove_link(node_tree, *y_link);
3783 }
3784 }
3785}
3786
3787/* The options were converted into inputs, but the Relative option was removed. If relative is
3788 * enabled, we add Relative To Pixel nodes to convert the relative values to pixels. */
3790{
3791 NodeTwoXYs *storage = static_cast<NodeTwoXYs *>(node->storage);
3792 if (!storage) {
3793 return;
3794 }
3795
3796 if (!blender::bke::node_find_socket(*node, SOCK_IN, "X")) {
3798 *node_tree, *node, SOCK_IN, SOCK_INT, PROP_NONE, "X", "X");
3799 input->default_value_typed<bNodeSocketValueInt>()->value = storage->x1;
3800 }
3801
3802 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Y")) {
3804 *node_tree, *node, SOCK_IN, SOCK_INT, PROP_NONE, "Y", "Y");
3805 input->default_value_typed<bNodeSocketValueInt>()->value = storage->y2;
3806 }
3807
3808 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Width")) {
3810 *node_tree, *node, SOCK_IN, SOCK_INT, PROP_NONE, "Width", "Width");
3811 input->default_value_typed<bNodeSocketValueInt>()->value = storage->x2 - storage->x1;
3812 }
3813
3814 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Height")) {
3816 *node_tree, *node, SOCK_IN, SOCK_INT, PROP_NONE, "Height", "Height");
3817 input->default_value_typed<bNodeSocketValueInt>()->value = storage->y1 - storage->y2;
3818 }
3819
3820 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Alpha Crop")) {
3822 *node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Alpha Crop", "Alpha Crop");
3823 input->default_value_typed<bNodeSocketValueBoolean>()->value = !bool(node->custom1);
3824 }
3825
3826 /* Find links going into the node. */
3827 bNodeLink *image_link = nullptr;
3828 LISTBASE_FOREACH (bNodeLink *, link, &node_tree->links) {
3829 if (link->tonode != node) {
3830 continue;
3831 }
3832
3833 if (blender::StringRef(link->tosock->identifier) == "Image") {
3834 image_link = link;
3835 }
3836 }
3837
3838 /* If Relative is not enabled or no image is connected, nothing else to do. */
3839 if (!bool(node->custom2) || !image_link) {
3840 MEM_freeN(storage);
3841 node->storage = nullptr;
3842 return;
3843 }
3844
3845 bNode *x_relative_to_pixel_node = blender::bke::node_add_node(
3846 nullptr, *node_tree, "CompositorNodeRelativeToPixel");
3847 x_relative_to_pixel_node->parent = node->parent;
3848 x_relative_to_pixel_node->location[0] = node->location[0] - node->width - 20.0f;
3849 x_relative_to_pixel_node->location[1] = node->location[1];
3850
3851 x_relative_to_pixel_node->custom1 = CMP_NODE_RELATIVE_TO_PIXEL_DATA_TYPE_FLOAT;
3853
3855 *x_relative_to_pixel_node, SOCK_IN, "Image");
3857 *x_relative_to_pixel_node, SOCK_IN, "Float Value");
3859 *x_relative_to_pixel_node, SOCK_OUT, "Float Value");
3860
3861 x_value_input->default_value_typed<bNodeSocketValueFloat>()->value = storage->fac_x1;
3862
3863 bNodeSocket *x_input = blender::bke::node_find_socket(*node, SOCK_IN, "X");
3864 version_node_add_link(*node_tree, *x_relative_to_pixel_node, *x_value_output, *node, *x_input);
3865 version_node_add_link(*node_tree,
3866 *image_link->fromnode,
3867 *image_link->fromsock,
3868 *x_relative_to_pixel_node,
3869 *x_image_input);
3870
3871 bNode *y_relative_to_pixel_node = blender::bke::node_add_node(
3872 nullptr, *node_tree, "CompositorNodeRelativeToPixel");
3873 y_relative_to_pixel_node->parent = node->parent;
3874 y_relative_to_pixel_node->location[0] = node->location[0] - node->width - 20.0f;
3875 y_relative_to_pixel_node->location[1] = node->location[1] - 10;
3876
3877 y_relative_to_pixel_node->custom1 = CMP_NODE_RELATIVE_TO_PIXEL_DATA_TYPE_FLOAT;
3879
3881 *y_relative_to_pixel_node, SOCK_IN, "Image");
3883 *y_relative_to_pixel_node, SOCK_IN, "Float Value");
3885 *y_relative_to_pixel_node, SOCK_OUT, "Float Value");
3886
3887 bNodeSocket *y_input = blender::bke::node_find_socket(*node, SOCK_IN, "Y");
3888 y_value_input->default_value_typed<bNodeSocketValueFloat>()->value = storage->fac_y2;
3889
3890 version_node_add_link(*node_tree, *y_relative_to_pixel_node, *y_value_output, *node, *y_input);
3891 version_node_add_link(*node_tree,
3892 *image_link->fromnode,
3893 *image_link->fromsock,
3894 *y_relative_to_pixel_node,
3895 *y_image_input);
3896
3897 bNode *width_relative_to_pixel_node = blender::bke::node_add_node(
3898 nullptr, *node_tree, "CompositorNodeRelativeToPixel");
3899 width_relative_to_pixel_node->parent = node->parent;
3900 width_relative_to_pixel_node->location[0] = node->location[0] - node->width - 20.0f;
3901 width_relative_to_pixel_node->location[1] = node->location[1] - 20;
3902
3903 width_relative_to_pixel_node->custom1 = CMP_NODE_RELATIVE_TO_PIXEL_DATA_TYPE_FLOAT;
3904 width_relative_to_pixel_node->custom2 = CMP_NODE_RELATIVE_TO_PIXEL_REFERENCE_DIMENSION_X;
3905
3906 bNodeSocket *width_image_input = blender::bke::node_find_socket(
3907 *width_relative_to_pixel_node, SOCK_IN, "Image");
3908 bNodeSocket *width_value_input = blender::bke::node_find_socket(
3909 *width_relative_to_pixel_node, SOCK_IN, "Float Value");
3910 bNodeSocket *width_value_output = blender::bke::node_find_socket(
3911 *width_relative_to_pixel_node, SOCK_OUT, "Float Value");
3912
3913 bNodeSocket *width_input = blender::bke::node_find_socket(*node, SOCK_IN, "Width");
3914 width_value_input->default_value_typed<bNodeSocketValueFloat>()->value = storage->fac_x2 -
3915 storage->fac_x1;
3916
3918 *node_tree, *width_relative_to_pixel_node, *width_value_output, *node, *width_input);
3919 version_node_add_link(*node_tree,
3920 *image_link->fromnode,
3921 *image_link->fromsock,
3922 *width_relative_to_pixel_node,
3923 *width_image_input);
3924
3925 bNode *height_relative_to_pixel_node = blender::bke::node_add_node(
3926 nullptr, *node_tree, "CompositorNodeRelativeToPixel");
3927 height_relative_to_pixel_node->parent = node->parent;
3928 height_relative_to_pixel_node->location[0] = node->location[0] - node->width - 20.0f;
3929 height_relative_to_pixel_node->location[1] = node->location[1] - 30;
3930
3931 height_relative_to_pixel_node->custom1 = CMP_NODE_RELATIVE_TO_PIXEL_DATA_TYPE_FLOAT;
3932 height_relative_to_pixel_node->custom2 = CMP_NODE_RELATIVE_TO_PIXEL_REFERENCE_DIMENSION_Y;
3933
3934 bNodeSocket *height_image_input = blender::bke::node_find_socket(
3935 *height_relative_to_pixel_node, SOCK_IN, "Image");
3936 bNodeSocket *height_value_input = blender::bke::node_find_socket(
3937 *height_relative_to_pixel_node, SOCK_IN, "Float Value");
3938 bNodeSocket *height_value_output = blender::bke::node_find_socket(
3939 *height_relative_to_pixel_node, SOCK_OUT, "Float Value");
3940
3941 bNodeSocket *height_input = blender::bke::node_find_socket(*node, SOCK_IN, "Height");
3942 height_value_input->default_value_typed<bNodeSocketValueFloat>()->value = storage->fac_y1 -
3943 storage->fac_y2;
3944
3946 *node_tree, *height_relative_to_pixel_node, *height_value_output, *node, *height_input);
3947 version_node_add_link(*node_tree,
3948 *image_link->fromnode,
3949 *image_link->fromsock,
3950 *height_relative_to_pixel_node,
3951 *height_image_input);
3952
3953 MEM_freeN(storage);
3954 node->storage = nullptr;
3955}
3956
3957/* The options were converted into inputs. */
3959{
3960 /* Compute the RNA path of the node. */
3961 char escaped_node_name[sizeof(node->name) * 2 + 1];
3962 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
3963 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
3964
3965 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
3966 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
3967 * path. */
3968 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
3969 return;
3970 }
3971
3972 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
3973 * values of the FCurves frames when needed. */
3974 char *old_rna_path = fcurve->rna_path;
3975 if (BLI_str_endswith(fcurve->rna_path, "min_x")) {
3976 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[1].default_value");
3977 }
3978 else if (BLI_str_endswith(fcurve->rna_path, "max_y")) {
3979 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
3980 }
3981 else if (BLI_str_endswith(fcurve->rna_path, "max_x")) {
3982 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
3983 }
3984 else if (BLI_str_endswith(fcurve->rna_path, "min_y")) {
3985 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[4].default_value");
3986 }
3987 else if (BLI_str_endswith(fcurve->rna_path, "use_crop_size")) {
3988 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[5].default_value");
3989 adjust_fcurve_key_frame_values(
3990 fcurve, PROP_BOOLEAN, [&](const float value) { return 1.0f - value; });
3991 }
3992
3993 /* The RNA path was changed, free the old path. */
3994 if (fcurve->rna_path != old_rna_path) {
3995 MEM_freeN(old_rna_path);
3996 }
3997 });
3998}
3999
4000/* The options were converted into inputs. */
4002{
4003 NodeColorBalance *storage = static_cast<NodeColorBalance *>(node->storage);
4004 if (!storage) {
4005 return;
4006 }
4007
4008 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Color Lift")) {
4010 *node_tree, *node, SOCK_IN, SOCK_RGBA, PROP_NONE, "Color Lift", "Lift");
4011 copy_v3_v3(input->default_value_typed<bNodeSocketValueRGBA>()->value, storage->lift);
4012 }
4013
4014 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Color Gamma")) {
4016 *node_tree, *node, SOCK_IN, SOCK_RGBA, PROP_NONE, "Color Gamma", "Gamma");
4017 copy_v3_v3(input->default_value_typed<bNodeSocketValueRGBA>()->value, storage->gamma);
4018 }
4019
4020 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Color Gain")) {
4022 *node_tree, *node, SOCK_IN, SOCK_RGBA, PROP_NONE, "Color Gain", "Gain");
4023 copy_v3_v3(input->default_value_typed<bNodeSocketValueRGBA>()->value, storage->gain);
4024 }
4025
4026 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Color Offset")) {
4028 *node_tree, *node, SOCK_IN, SOCK_RGBA, PROP_NONE, "Color Offset", "Offset");
4029 copy_v3_v3(input->default_value_typed<bNodeSocketValueRGBA>()->value, storage->offset);
4030 }
4031
4032 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Color Power")) {
4034 *node_tree, *node, SOCK_IN, SOCK_RGBA, PROP_NONE, "Color Power", "Power");
4035 copy_v3_v3(input->default_value_typed<bNodeSocketValueRGBA>()->value, storage->power);
4036 }
4037
4038 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Color Slope")) {
4040 *node_tree, *node, SOCK_IN, SOCK_RGBA, PROP_NONE, "Color Slope", "Slope");
4041 copy_v3_v3(input->default_value_typed<bNodeSocketValueRGBA>()->value, storage->slope);
4042 }
4043
4044 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Base Offset")) {
4046 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_NONE, "Base Offset", "Offset");
4047 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->offset_basis;
4048 }
4049
4050 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Input Temperature")) {
4052 *node,
4053 SOCK_IN,
4054 SOCK_FLOAT,
4056 "Input Temperature",
4057 "Temperature");
4058 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->input_temperature;
4059 }
4060
4061 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Input Tint")) {
4063 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_NONE, "Input Tint", "Tint");
4064 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->input_tint;
4065 }
4066
4067 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Output Temperature")) {
4069 *node,
4070 SOCK_IN,
4071 SOCK_FLOAT,
4073 "Output Temperature",
4074 "Temperature");
4075 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->output_temperature;
4076 }
4077
4078 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Output Tint")) {
4080 *node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_NONE, "Output Tint", "Tint");
4081 input->default_value_typed<bNodeSocketValueFloat>()->value = storage->output_tint;
4082 }
4083
4084 MEM_freeN(storage);
4085 node->storage = nullptr;
4086}
4087
4088/* The options were converted into inputs. */
4090 bNode *node)
4091{
4092 /* Compute the RNA path of the node. */
4093 char escaped_node_name[sizeof(node->name) * 2 + 1];
4094 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
4095 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
4096
4097 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
4098 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
4099 * path. */
4100 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
4101 return;
4102 }
4103
4104 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
4105 * values of the FCurves frames when needed. */
4106 char *old_rna_path = fcurve->rna_path;
4107 if (BLI_str_endswith(fcurve->rna_path, "lift")) {
4108 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
4109 }
4110 else if (BLI_str_endswith(fcurve->rna_path, "gamma")) {
4111 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[5].default_value");
4112 }
4113 else if (BLI_str_endswith(fcurve->rna_path, "gain")) {
4114 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[7].default_value");
4115 }
4116 else if (BLI_str_endswith(fcurve->rna_path, "offset_basis")) {
4117 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[8].default_value");
4118 }
4119 else if (BLI_str_endswith(fcurve->rna_path, "offset")) {
4120 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[9].default_value");
4121 }
4122 else if (BLI_str_endswith(fcurve->rna_path, "power")) {
4123 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[11].default_value");
4124 }
4125 else if (BLI_str_endswith(fcurve->rna_path, "slope")) {
4126 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[13].default_value");
4127 }
4128 else if (BLI_str_endswith(fcurve->rna_path, "input_temperature")) {
4129 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[14].default_value");
4130 }
4131 else if (BLI_str_endswith(fcurve->rna_path, "input_tint")) {
4132 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[15].default_value");
4133 }
4134 else if (BLI_str_endswith(fcurve->rna_path, "output_temperature")) {
4135 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[16].default_value");
4136 }
4137 else if (BLI_str_endswith(fcurve->rna_path, "output_tint")) {
4138 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[17].default_value");
4139 }
4140
4141 /* The RNA path was changed, free the old path. */
4142 if (fcurve->rna_path != old_rna_path) {
4143 MEM_freeN(old_rna_path);
4144 }
4145 });
4146}
4147
4148/* The Coordinates outputs were moved into their own Texture Coordinate node. If used, add a
4149 * Texture Coordinates node and use it instead. */
4151{
4152 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4153 if (!STREQ(node->idname, "CompositorNodeImageInfo")) {
4154 continue;
4155 }
4156
4157 bNodeLink *input_link = nullptr;
4158 bNodeLink *output_texture_link = nullptr;
4159 bNodeLink *output_pixel_link = nullptr;
4160 LISTBASE_FOREACH (bNodeLink *, link, &node_tree->links) {
4161 if (link->tonode == node) {
4162 input_link = link;
4163 }
4164
4165 if (link->fromnode == node &&
4166 blender::StringRef(link->fromsock->identifier) == "Texture Coordinates")
4167 {
4168 output_texture_link = link;
4169 }
4170
4171 if (link->fromnode == node &&
4172 blender::StringRef(link->fromsock->identifier) == "Pixel Coordinates")
4173 {
4174 output_pixel_link = link;
4175 }
4176 }
4177
4178 if (!output_texture_link && !output_pixel_link) {
4179 continue;
4180 }
4181
4182 bNode *image_coordinates_node = blender::bke::node_add_node(
4183 nullptr, *node_tree, "CompositorNodeImageCoordinates");
4184 image_coordinates_node->parent = node->parent;
4185 image_coordinates_node->location[0] = node->location[0];
4186 image_coordinates_node->location[1] = node->location[1] - node->height - 10.0f;
4187
4188 if (input_link) {
4190 *image_coordinates_node, SOCK_IN, "Image");
4191 version_node_add_link(*node_tree,
4192 *input_link->fromnode,
4193 *input_link->fromsock,
4194 *image_coordinates_node,
4195 *image_input);
4196 }
4197
4198 if (output_texture_link) {
4200 *image_coordinates_node, SOCK_OUT, "Uniform");
4201 version_node_add_link(*node_tree,
4202 *image_coordinates_node,
4203 *uniform_output,
4204 *output_texture_link->tonode,
4205 *output_texture_link->tosock);
4206 blender::bke::node_remove_link(node_tree, *output_texture_link);
4207 }
4208
4209 if (output_pixel_link) {
4211 *image_coordinates_node, SOCK_OUT, "Pixel");
4212 version_node_add_link(*node_tree,
4213 *image_coordinates_node,
4214 *pixel_output,
4215 *output_pixel_link->tonode,
4216 *output_pixel_link->tosock);
4217 blender::bke::node_remove_link(node_tree, *output_pixel_link);
4218 }
4219 }
4220}
4221
4222/* Vector sockets can now have different dimensions, so set the dimensions for existing sockets to
4223 * 3.*/
4225{
4226 node_tree->tree_interface.foreach_item([&](bNodeTreeInterfaceItem &item) {
4227 if (item.item_type != NODE_INTERFACE_SOCKET) {
4228 return true;
4229 }
4230
4231 bNodeTreeInterfaceSocket &interface_socket =
4234 interface_socket.socket_type);
4235
4236 if (base_typeinfo->type == SOCK_VECTOR) {
4238 .dimensions = 3;
4239 }
4240 return true;
4241 });
4242
4243 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4244 LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
4245 if (socket->type == SOCK_VECTOR) {
4246 socket->default_value_typed<bNodeSocketValueVector>()->dimensions = 3;
4247 }
4248 }
4249 LISTBASE_FOREACH (bNodeSocket *, socket, &node->outputs) {
4250 if (socket->type == SOCK_VECTOR) {
4251 socket->default_value_typed<bNodeSocketValueVector>()->dimensions = 3;
4252 }
4253 }
4254 }
4255}
4256
4257/* The options were converted into inputs, but the Relative option was removed. If relative is
4258 * enabled, we add Relative To Pixel nodes to convert the relative values to pixels. */
4260{
4261 NodeBlurData *storage = static_cast<NodeBlurData *>(node->storage);
4262 if (!storage) {
4263 return;
4264 }
4265
4266 bNodeSocket *size_input = blender::bke::node_find_socket(*node, SOCK_IN, "Size");
4267 const float old_size = size_input->default_value_typed<bNodeSocketValueFloat>()->value;
4268
4270 node_tree, node, size_input, SOCK_VECTOR, PROP_NONE);
4271 size_input->default_value_typed<bNodeSocketValueVector>()->value[0] = old_size * storage->sizex;
4272 size_input->default_value_typed<bNodeSocketValueVector>()->value[1] = old_size * storage->sizey;
4273
4274 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Extend Bounds")) {
4276 *node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Extend Bounds", "Extend Bounds");
4277 input->default_value_typed<bNodeSocketValueBoolean>()->value = bool(node->custom1 & (1 << 1));
4278 }
4279
4280 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Separable")) {
4282 *node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Separable", "Separable");
4283 input->default_value_typed<bNodeSocketValueBoolean>()->value = !bool(storage->bokeh);
4284 }
4285
4286 /* Find links going into the node. */
4287 bNodeLink *image_link = nullptr;
4288 bNodeLink *size_link = nullptr;
4289 LISTBASE_FOREACH (bNodeLink *, link, &node_tree->links) {
4290 if (link->tonode != node) {
4291 continue;
4292 }
4293
4294 if (blender::StringRef(link->tosock->identifier) == "Image") {
4295 image_link = link;
4296 }
4297
4298 if (blender::StringRef(link->tosock->identifier) == "Size") {
4299 size_link = link;
4300 }
4301 }
4302
4303 if (size_link) {
4304 bNode *multiply_node = blender::bke::node_add_node(
4305 nullptr, *node_tree, "ShaderNodeVectorMath");
4306 multiply_node->parent = node->parent;
4307 multiply_node->location[0] = node->location[0] - node->width - 40.0f;
4308 multiply_node->location[1] = node->location[1];
4309
4310 multiply_node->custom1 = NODE_VECTOR_MATH_SCALE;
4311
4312 bNodeSocket *vector_input = blender::bke::node_find_socket(*multiply_node, SOCK_IN, "Vector");
4313 bNodeSocket *scale_input = blender::bke::node_find_socket(*multiply_node, SOCK_IN, "Scale");
4315 *multiply_node, SOCK_OUT, "Vector");
4316
4317 if (storage->relative) {
4318 vector_input->default_value_typed<bNodeSocketValueVector>()->value[0] = storage->percentx /
4319 100.0f;
4320 vector_input->default_value_typed<bNodeSocketValueVector>()->value[1] = storage->percenty /
4321 100.0f;
4322 }
4323 else {
4324 vector_input->default_value_typed<bNodeSocketValueVector>()->value[0] = storage->sizex;
4325 vector_input->default_value_typed<bNodeSocketValueVector>()->value[1] = storage->sizey;
4326 }
4327
4329 *node_tree, *size_link->fromnode, *size_link->fromsock, *multiply_node, *scale_input);
4330 bNodeLink &new_link = version_node_add_link(
4331 *node_tree, *multiply_node, *vector_output, *node, *size_input);
4332 blender::bke::node_remove_link(node_tree, *size_link);
4333 size_link = &new_link;
4334 }
4335
4336 /* If Relative is not enabled or no image is connected, nothing else to do. */
4337 if (!bool(storage->relative) || !image_link) {
4338 return;
4339 }
4340
4341 bNode *relative_to_pixel_node = blender::bke::node_add_node(
4342 nullptr, *node_tree, "CompositorNodeRelativeToPixel");
4343 relative_to_pixel_node->parent = node->parent;
4344 relative_to_pixel_node->location[0] = node->location[0] - node->width - 20.0f;
4345 relative_to_pixel_node->location[1] = node->location[1];
4346
4347 relative_to_pixel_node->custom1 = CMP_NODE_RELATIVE_TO_PIXEL_DATA_TYPE_VECTOR;
4348 switch (storage->aspect) {
4351 break;
4354 break;
4356 relative_to_pixel_node->custom2 =
4358 break;
4359 default:
4361 break;
4362 }
4363
4365 *relative_to_pixel_node, SOCK_IN, "Image");
4367 *relative_to_pixel_node, SOCK_IN, "Vector Value");
4369 *relative_to_pixel_node, SOCK_OUT, "Vector Value");
4370
4371 version_node_add_link(*node_tree,
4372 *image_link->fromnode,
4373 *image_link->fromsock,
4374 *relative_to_pixel_node,
4375 *image_input);
4376 if (size_link) {
4377 version_node_add_link(*node_tree,
4378 *size_link->fromnode,
4379 *size_link->fromsock,
4380 *relative_to_pixel_node,
4381 *vector_input);
4382 blender::bke::node_remove_link(node_tree, *size_link);
4383 }
4384 else {
4385 vector_input->default_value_typed<bNodeSocketValueVector>()->value[0] = (storage->percentx /
4386 100.0f) *
4387 old_size;
4388 vector_input->default_value_typed<bNodeSocketValueVector>()->value[1] = (storage->percenty /
4389 100.0f) *
4390 old_size;
4391 }
4392 version_node_add_link(*node_tree, *relative_to_pixel_node, *vector_output, *node, *size_input);
4393}
4394
4395/* The options were converted into inputs. */
4397{
4398 /* Compute the RNA path of the node. */
4399 char escaped_node_name[sizeof(node->name) * 2 + 1];
4400 BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
4401 const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
4402
4403 BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
4404 /* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
4405 * path. */
4406 if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
4407 return;
4408 }
4409
4410 /* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
4411 * values of the FCurves frames when needed. */
4412 char *old_rna_path = fcurve->rna_path;
4413 if (BLI_str_endswith(fcurve->rna_path, "size_x")) {
4414 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[1].default_value");
4415 fcurve->array_index = 0;
4416 }
4417 else if (BLI_str_endswith(fcurve->rna_path, "size_y")) {
4418 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[1].default_value");
4419 fcurve->array_index = 1;
4420 }
4421 else if (BLI_str_endswith(fcurve->rna_path, "use_extended_bounds")) {
4422 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
4423 }
4424 else if (BLI_str_endswith(fcurve->rna_path, "use_bokeh")) {
4425 fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
4426 adjust_fcurve_key_frame_values(
4427 fcurve, PROP_BOOLEAN, [&](const float value) { return 1.0f - value; });
4428 }
4429
4430 /* The RNA path was changed, free the old path. */
4431 if (fcurve->rna_path != old_rna_path) {
4432 MEM_freeN(old_rna_path);
4433 }
4434 });
4435}
4436
4437/* Unified paint settings need a default curve for the color jitter options. */
4450
4451/* GP_BRUSH_* settings in gpencil_settings->flag2 were deprecated and replaced with
4452 * brush->color_jitter_flag. */
4475
4476/* The options were converted into inputs. */
4478{
4479 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Flip X")) {
4481 *node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Flip X", "Flip X");
4482 input->default_value_typed<bNodeSocketValueBoolean>()->value = ELEM(node->custom1, 0, 2);
4483 }
4484
4485 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Flip Y")) {
4487 *node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Flip Y", "Flip Y");
4488 input->default_value_typed<bNodeSocketValueBoolean>()->value = ELEM(node->custom1, 1, 2);
4489 }
4490}
4491
4493{
4494 blender::Map<bNodeSocket *, bNodeLink *> links_to_level_and_max_inputs;
4495 LISTBASE_FOREACH (bNodeLink *, link, &tree.links) {
4496 if (link->tosock) {
4497 if (ELEM(blender::StringRef(link->tosock->identifier), "Level", "Max")) {
4498 links_to_level_and_max_inputs.add(link->tosock, link);
4499 }
4500 }
4501 }
4502 LISTBASE_FOREACH_MUTABLE (bNode *, node, &tree.nodes) {
4503 if (!ELEM(node->type_legacy, GEO_NODE_SUBDIVISION_SURFACE, GEO_NODE_SUBDIVIDE_MESH)) {
4504 continue;
4505 }
4506 bNodeSocket *level_input = blender::bke::node_find_socket(*node, SOCK_IN, "Level");
4507 if (!level_input || level_input->type != SOCK_INT) {
4508 continue;
4509 }
4510 bNodeLink *link = links_to_level_and_max_inputs.lookup_default(level_input, nullptr);
4511 if (link) {
4512 bNode *origin_node = link->fromnode;
4513 if (origin_node->type_legacy == SH_NODE_CLAMP) {
4514 bNodeSocket *max_input_socket = blender::bke::node_find_socket(
4515 *origin_node, SOCK_IN, "Max");
4516 if (max_input_socket->type == SOCK_FLOAT &&
4517 !links_to_level_and_max_inputs.contains(max_input_socket))
4518 {
4519 if (max_input_socket->default_value_typed<bNodeSocketValueFloat>()->value <= 11.0f) {
4520 /* There is already a clamp node, so no need to add another one. */
4521 continue;
4522 }
4523 }
4524 }
4525 /* Insert clamp node. */
4526 bNode &clamp_node = version_node_add_empty(tree, "ShaderNodeClamp");
4527 clamp_node.parent = node->parent;
4528 clamp_node.location[0] = node->location[0] - 25;
4529 clamp_node.location[1] = node->location[1];
4530 bNodeSocket &clamp_value_input = version_node_add_socket(
4531 tree, clamp_node, SOCK_IN, "NodeSocketFloat", "Value");
4532 bNodeSocket &clamp_min_input = version_node_add_socket(
4533 tree, clamp_node, SOCK_IN, "NodeSocketFloat", "Min");
4534 bNodeSocket &clamp_max_input = version_node_add_socket(
4535 tree, clamp_node, SOCK_IN, "NodeSocketFloat", "Max");
4536 bNodeSocket &clamp_value_output = version_node_add_socket(
4537 tree, clamp_node, SOCK_OUT, "NodeSocketFloat", "Result");
4538
4539 static_cast<bNodeSocketValueFloat *>(clamp_min_input.default_value)->value = 0.0f;
4540 static_cast<bNodeSocketValueFloat *>(clamp_max_input.default_value)->value = 11.0f;
4541
4542 link->tosock = &clamp_value_input;
4543 version_node_add_link(tree, clamp_node, clamp_value_output, *node, *level_input);
4544 }
4545 else {
4546 /* Clamp value directly. */
4547 bNodeSocketValueInt *value = level_input->default_value_typed<bNodeSocketValueInt>();
4548 value->value = std::clamp(value->value, 0, 11);
4549 }
4550 }
4551
4553}
4554
4556{
4557 BrushGpencilSettings *settings = brush->gpencil_settings;
4558 float old_hsv_jitter[3] = {
4559 settings->random_hue, settings->random_saturation, settings->random_value};
4560 if (!is_zero_v3(old_hsv_jitter)) {
4561 brush->flag2 |= BRUSH_JITTER_COLOR;
4562 }
4563 copy_v3_v3(brush->hsv_jitter, old_hsv_jitter);
4564 if (brush->curve_rand_hue) {
4567 }
4568 else {
4570 }
4571 if (brush->curve_rand_saturation) {
4574 }
4575 else {
4577 }
4578 if (brush->curve_rand_value) {
4581 }
4582 else {
4584 }
4585}
4586
4588{
4589 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 8)) {
4590 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
4591 if (ntree->type == NTREE_COMPOSIT) {
4593 }
4594 }
4596 }
4597
4598 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 12)) {
4600 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
4601 if (ntree->type == NTREE_COMPOSIT) {
4603 }
4604 }
4606 }
4607
4608 /* For each F-Curve, set the F-Curve flags based on the property type it animates. This is to
4609 * correct F-Curves created while the bug (#136347) was in active use. Since this bug did not
4610 * appear before 4.4, and this versioning code has a bit of a performance impact (going over all
4611 * F-Curves of all Actions, and resolving them all to their RNA properties), it will be skipped
4612 * if the blend file is old enough to not be affected. */
4613 if (MAIN_VERSION_FILE_ATLEAST(bmain, 404, 0) && !MAIN_VERSION_FILE_ATLEAST(bmain, 405, 13)) {
4614 LISTBASE_FOREACH (bAction *, dna_action, &bmain->actions) {
4615 blender::animrig::Action &action = dna_action->wrap();
4616 for (const blender::animrig::Slot *slot : action.slots()) {
4617 blender::Span<ID *> slot_users = slot->users(*bmain);
4618 if (slot_users.is_empty()) {
4619 /* If nothing is using this slot, the RNA paths cannot be resolved, and so there
4620 * is no way to find the animated property type. */
4621 continue;
4622 }
4623 blender::animrig::foreach_fcurve_in_action_slot(action, slot->handle, [&](FCurve &fcurve) {
4624 /* Loop over all slot users, because when the slot is shared, not all F-Curves may
4625 * resolve on all users. For example, a custom property might only exist on a subset of
4626 * the users.*/
4627 for (ID *slot_user : slot_users) {
4628 PointerRNA slot_user_ptr = RNA_id_pointer_create(slot_user);
4629 PointerRNA ptr;
4630 PropertyRNA *prop;
4631 if (!RNA_path_resolve_property(&slot_user_ptr, fcurve.rna_path, &ptr, &prop)) {
4632 continue;
4633 }
4634
4635 blender::animrig::update_autoflags_fcurve_direct(&fcurve, RNA_property_type(prop));
4636 break;
4637 }
4638 });
4639 }
4640 }
4641 }
4642
4643 /* Because this was backported to 4.4 (f1e829a459) we need to exclude anything that was already
4644 * saved with that version otherwise we would apply the fix twice. */
4645 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 404, 32) ||
4646 (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 14) && bmain->versionfile >= 405))
4647 {
4648 LISTBASE_FOREACH (bAction *, dna_action, &bmain->actions) {
4649 blender::animrig::Action &action = dna_action->wrap();
4651 action, [&](FCurve &fcurve) { version_fix_fcurve_noise_offset(fcurve); });
4652 }
4653
4654 BKE_animdata_main_cb(bmain, [](ID * /* id */, AnimData *adt) {
4655 LISTBASE_FOREACH (FCurve *, fcurve, &adt->drivers) {
4657 }
4658 LISTBASE_FOREACH (NlaTrack *, track, &adt->nla_tracks) {
4659 nlastrips_apply_fcurve_versioning(track->strips);
4660 }
4661 });
4662 }
4663
4664 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 20)) {
4665 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4666 if (node_tree->type == NTREE_COMPOSIT) {
4667 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4668 if (node->type_legacy == CMP_NODE_GLARE) {
4670 }
4671 }
4672 }
4673 }
4675 }
4676
4677 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 22)) {
4678 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4679 if (node_tree->type == NTREE_COMPOSIT) {
4680 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4681 if (node->type_legacy == CMP_NODE_BOKEHIMAGE) {
4683 }
4684 }
4685 }
4686 }
4688 }
4689
4690 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 23)) {
4691 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4692 if (node_tree->type == NTREE_COMPOSIT) {
4693 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4694 if (node->type_legacy == CMP_NODE_TIME) {
4696 }
4697 }
4698 }
4699 }
4701 }
4702
4703 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 24)) {
4704 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4705 if (node_tree->type == NTREE_COMPOSIT) {
4706 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4707 if (node->type_legacy == CMP_NODE_MASK) {
4709 }
4710 }
4711 }
4712 }
4714 }
4715
4716 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 25)) {
4717 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4718 if (node_tree->type == NTREE_COMPOSIT) {
4719 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4720 if (node->type_legacy == CMP_NODE_SWITCH) {
4722 }
4723 }
4724 }
4725 }
4727 }
4728
4729 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 26)) {
4730 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4731 if (node_tree->type == NTREE_COMPOSIT) {
4732 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4733 if (node->type_legacy == CMP_NODE_SPLIT) {
4735 }
4736 }
4737 }
4738 }
4740 }
4741
4742 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 27)) {
4743 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4744 if (node_tree->type == NTREE_COMPOSIT) {
4745 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4746 if (node->type_legacy == CMP_NODE_INVERT) {
4748 }
4749 }
4750 }
4751 }
4753 }
4754
4755 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 28)) {
4756 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4757 if (node_tree->type == NTREE_COMPOSIT) {
4758 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4759 if (node->type_legacy == CMP_NODE_ZCOMBINE) {
4761 }
4762 }
4763 }
4764 }
4766 }
4767
4768 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 29)) {
4769 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4770 if (node_tree->type == NTREE_COMPOSIT) {
4771 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4772 if (node->type_legacy == CMP_NODE_TONEMAP) {
4774 }
4775 }
4776 }
4777 }
4779 }
4780
4781 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 30)) {
4782 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4783 if (node_tree->type == NTREE_COMPOSIT) {
4784 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4785 if (node->type_legacy == CMP_NODE_DILATEERODE) {
4787 }
4788 }
4789 }
4790 }
4792 }
4793
4794 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 31)) {
4795 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4796 if (node_tree->type == NTREE_COMPOSIT) {
4797 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4798 if (node->type_legacy == CMP_NODE_INPAINT) {
4800 }
4801 }
4802 }
4803 }
4805 }
4806
4807 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 32)) {
4808 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4809 if (node_tree->type == NTREE_COMPOSIT) {
4810 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4811 if (node->type_legacy == CMP_NODE_PIXELATE) {
4813 }
4814 }
4815 }
4816 }
4818 }
4819
4820 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 33)) {
4821 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4822 if (node_tree->type == NTREE_COMPOSIT) {
4823 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4824 if (node->type_legacy == CMP_NODE_KUWAHARA) {
4826 }
4827 }
4828 }
4829 }
4831 }
4832
4833 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 34)) {
4834 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4835 if (node_tree->type == NTREE_COMPOSIT) {
4836 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4837 if (node->type_legacy == CMP_NODE_DESPECKLE) {
4839 }
4840 }
4841 }
4842 }
4844 }
4845
4846 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 35)) {
4847 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4848 if (node_tree->type == NTREE_COMPOSIT) {
4849 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4850 if (node->type_legacy == CMP_NODE_DENOISE) {
4852 }
4853 }
4854 }
4855 }
4857 }
4858
4859 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 36)) {
4860 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4861 if (node_tree->type == NTREE_COMPOSIT) {
4862 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4863 if (node->type_legacy == CMP_NODE_ANTIALIASING) {
4865 }
4866 }
4867 }
4868 }
4870 }
4871
4872 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 37)) {
4873 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4874 if (node_tree->type == NTREE_COMPOSIT) {
4875 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4876 if (node->type_legacy == CMP_NODE_VECBLUR) {
4878 }
4879 }
4880 }
4881 }
4883 }
4884
4885 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 38)) {
4886 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4887 if (node_tree->type == NTREE_COMPOSIT) {
4888 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4889 if (node->type_legacy == CMP_NODE_CHANNEL_MATTE) {
4891 }
4892 }
4893 }
4894 }
4896 }
4897
4898 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 39)) {
4899 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4900 if (node_tree->type == NTREE_COMPOSIT) {
4901 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4902 if (node->type_legacy == CMP_NODE_CHROMA_MATTE) {
4904 }
4905 }
4906 }
4907 }
4909 }
4910
4911 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 40)) {
4912 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4913 if (node_tree->type == NTREE_COMPOSIT) {
4914 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4915 if (node->type_legacy == CMP_NODE_COLOR_MATTE) {
4917 }
4918 }
4919 }
4920 }
4922 }
4923
4924 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 41)) {
4925 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4926 if (node_tree->type == NTREE_COMPOSIT) {
4927 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4928 if (node->type_legacy == CMP_NODE_DIFF_MATTE) {
4930 }
4931 }
4932 }
4933 }
4935 }
4936
4937 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 42)) {
4938 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4939 if (node_tree->type == NTREE_COMPOSIT) {
4940 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4941 if (node->type_legacy == CMP_NODE_DIST_MATTE) {
4943 }
4944 }
4945 }
4946 }
4948 }
4949
4950 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 43)) {
4951 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4952 if (node_tree->type == NTREE_COMPOSIT) {
4953 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4954 if (node->type_legacy == CMP_NODE_LUMA_MATTE) {
4956 }
4957 }
4958 }
4959 }
4961 }
4962
4963 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 44)) {
4964 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4965 if (node_tree->type == NTREE_COMPOSIT) {
4966 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4967 if (node->type_legacy == CMP_NODE_COLOR_SPILL) {
4969 }
4970 }
4971 }
4972 }
4974 }
4975
4976 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 45)) {
4977 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4978 if (node_tree->type == NTREE_COMPOSIT) {
4979 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4980 if (node->type_legacy == CMP_NODE_KEYINGSCREEN) {
4982 }
4983 }
4984 }
4985 }
4987 }
4988
4989 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 47)) {
4990 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
4991 if (node_tree->type == NTREE_COMPOSIT) {
4992 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
4993 if (node->type_legacy == CMP_NODE_KEYING) {
4995 }
4996 }
4997 }
4998 }
5000 }
5001
5002 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 48)) {
5003 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5004 if (node_tree->type == NTREE_COMPOSIT) {
5005 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5006 if (node->type_legacy == CMP_NODE_ID_MASK) {
5008 }
5009 }
5010 }
5011 }
5013 }
5014
5015 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 49)) {
5016 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5017 if (node_tree->type == NTREE_COMPOSIT) {
5018 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5019 if (node->type_legacy == CMP_NODE_STABILIZE2D) {
5021 }
5022 }
5023 }
5024 }
5026 }
5027
5028 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 50)) {
5029 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5030 if (node_tree->type == NTREE_COMPOSIT) {
5031 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5032 if (node->type_legacy == CMP_NODE_PLANETRACKDEFORM) {
5034 }
5035 }
5036 }
5037 }
5039 }
5040
5041 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 52)) {
5042 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5043 if (node_tree->type == NTREE_COMPOSIT) {
5044 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5045 if (node->type_legacy == CMP_NODE_COLORCORRECTION) {
5047 }
5048 }
5049 }
5050 }
5052 }
5053
5054 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 53)) {
5055 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5056 if (node_tree->type == NTREE_COMPOSIT) {
5057 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5058 if (node->type_legacy == CMP_NODE_LENSDIST) {
5060 }
5061 }
5062 }
5063 }
5065 }
5066
5067 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 54)) {
5068 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5069 if (node_tree->type == NTREE_COMPOSIT) {
5070 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5071 if (node->type_legacy == CMP_NODE_MASK_BOX) {
5073 }
5074 }
5075 }
5076 }
5078 }
5079
5080 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 55)) {
5081 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5082 if (node_tree->type == NTREE_COMPOSIT) {
5083 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5084 if (node->type_legacy == CMP_NODE_MASK_ELLIPSE) {
5086 }
5087 }
5088 }
5089 }
5091 }
5092
5093 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 58)) {
5094 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5095 if (node_tree->type == NTREE_COMPOSIT) {
5096 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5097 if (node->type_legacy == CMP_NODE_SUNBEAMS) {
5099 }
5100 }
5101 }
5102 }
5104 }
5105
5106 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 59)) {
5107 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5108 if (node_tree->type == NTREE_COMPOSIT) {
5109 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5110 if (node->type_legacy == CMP_NODE_DBLUR) {
5112 }
5113 }
5114 }
5115 }
5117 }
5118
5119 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 60)) {
5120 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5121 if (node_tree->type == NTREE_COMPOSIT) {
5122 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5123 if (node->type_legacy == CMP_NODE_BILATERALBLUR) {
5125 }
5126 }
5127 }
5128 }
5130 }
5131
5132 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 64)) {
5133 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5134 if (node_tree->type == NTREE_COMPOSIT) {
5135 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5136 if (node->type_legacy == CMP_NODE_ALPHAOVER) {
5138 }
5139 }
5140 }
5141 }
5143 }
5144
5145 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 69)) {
5146 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5147 if (node_tree->type == NTREE_COMPOSIT) {
5148 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5149 if (node->type_legacy == CMP_NODE_BOKEHBLUR) {
5151 }
5152 }
5153 }
5154 }
5156 }
5157
5158 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 75)) {
5159 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5160 if (node_tree->type == NTREE_COMPOSIT) {
5161 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5162 if (node->type_legacy == CMP_NODE_CROP) {
5164 }
5165 }
5166 }
5167 }
5169 }
5170
5171 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 76)) {
5172 ToolSettings toolsettings_default = *DNA_struct_default_get(ToolSettings);
5173 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
5174 scene->toolsettings->snap_playhead_mode = toolsettings_default.snap_playhead_mode;
5175 scene->toolsettings->snap_step_frames = toolsettings_default.snap_step_frames;
5176 scene->toolsettings->snap_step_seconds = toolsettings_default.snap_step_seconds;
5177 scene->toolsettings->playhead_snap_distance = toolsettings_default.playhead_snap_distance;
5178 }
5179 }
5180
5181 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 77)) {
5182 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5183 if (node_tree->type == NTREE_COMPOSIT) {
5184 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5185 if (node->type_legacy == CMP_NODE_COLORBALANCE) {
5187 }
5188 }
5189 }
5190 }
5192 }
5193
5194 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 80)) {
5195 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5196 if (node_tree->type == NTREE_COMPOSIT) {
5197 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5198 if (node->type_legacy == CMP_NODE_BLUR) {
5200 }
5201 }
5202 }
5203 }
5205 }
5206
5207 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 84)) {
5208 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
5210 }
5211
5212 LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
5213 if (brush->gpencil_settings) {
5215 }
5216 }
5217 }
5218
5225}
5226
5228{
5229 for (CustomDataLayer &layer : blender::MutableSpan(custom_data.layers, custom_data.totlayer)) {
5230 if (layer.name == name) {
5231 return &layer;
5232 }
5233 }
5234 return nullptr;
5235}
5236
5238{
5239 using namespace blender;
5240 CustomDataLayer *old_seam_layer = find_old_seam_layer(mesh.edge_data, ".uv_seam");
5241 if (!old_seam_layer) {
5242 return;
5243 }
5244 Set<StringRef> names;
5245 for (const CustomDataLayer &layer : Span(mesh.vert_data.layers, mesh.vert_data.totlayer)) {
5246 if (layer.type & CD_MASK_PROP_ALL) {
5247 names.add(layer.name);
5248 }
5249 }
5250 for (const CustomDataLayer &layer : Span(mesh.edge_data.layers, mesh.edge_data.totlayer)) {
5251 if (layer.type & CD_MASK_PROP_ALL) {
5252 names.add(layer.name);
5253 }
5254 }
5255 for (const CustomDataLayer &layer : Span(mesh.face_data.layers, mesh.face_data.totlayer)) {
5256 if (layer.type & CD_MASK_PROP_ALL) {
5257 names.add(layer.name);
5258 }
5259 }
5260 for (const CustomDataLayer &layer : Span(mesh.corner_data.layers, mesh.corner_data.totlayer)) {
5261 if (layer.type & CD_MASK_PROP_ALL) {
5262 names.add(layer.name);
5263 }
5264 }
5265 LISTBASE_FOREACH (const bDeformGroup *, vertex_group, &mesh.vertex_group_names) {
5266 names.add(vertex_group->name);
5267 }
5268
5269 /* If the new UV name is already taken, still rename the attribute so it becomes visible in the
5270 * list. Then the user can deal with the name conflict themselves. */
5271 const std::string new_name = BLI_uniquename_cb(
5272 [&](const StringRef name) { return names.contains(name); }, '.', "uv_seam");
5273 STRNCPY(old_seam_layer->name, new_name.c_str());
5274}
5275
5277{
5278 using namespace blender;
5279 Set<bNode *> curve_to_mesh_nodes;
5280 LISTBASE_FOREACH (bNode *, node, &tree->nodes) {
5281 if (STREQ(node->idname, "GeometryNodeCurveToMesh")) {
5282 curve_to_mesh_nodes.add(node);
5283 }
5284 }
5285
5286 for (bNode *curve_to_mesh : curve_to_mesh_nodes) {
5288 bke::node_find_socket(*curve_to_mesh, SOCK_IN, "Profile Curve")))
5289 {
5290 /* No additional versioning is needed when the profile curve input is unused. */
5291 continue;
5292 }
5293
5294 if (bke::node_find_socket(*curve_to_mesh, SOCK_IN, "Scale")) {
5295 /* Make versioning idempotent. */
5296 continue;
5297 }
5299 tree, curve_to_mesh, SOCK_IN, SOCK_FLOAT, PROP_NONE, "Scale", "Scale");
5300 /* Use a default scale value of 1. */
5301 scale_socket->default_value_typed<bNodeSocketValueFloat>()->value = 1.0f;
5302
5303 bNode &named_attribute = version_node_add_empty(*tree, "GeometryNodeInputNamedAttribute");
5304 NodeGeometryInputNamedAttribute *named_attribute_storage =
5306 named_attribute_storage->data_type = CD_PROP_FLOAT;
5307 named_attribute.storage = named_attribute_storage;
5308 named_attribute.parent = curve_to_mesh->parent;
5309 named_attribute.location[0] = curve_to_mesh->location[0] - 25;
5310 named_attribute.location[1] = curve_to_mesh->location[1];
5311 named_attribute.flag &= ~NODE_SELECT;
5312
5314 tree, &named_attribute, SOCK_IN, SOCK_STRING, PROP_NONE, "Name", "Name");
5315 STRNCPY(name_input->default_value_typed<bNodeSocketValueString>()->value, "radius");
5316
5318 tree, &named_attribute, SOCK_OUT, SOCK_BOOLEAN, PROP_NONE, "Exists", "Exists");
5320 tree, &named_attribute, SOCK_OUT, SOCK_FLOAT, PROP_NONE, "Attribute", "Attribute");
5321
5322 bNode &switch_node = version_node_add_empty(*tree, "GeometryNodeSwitch");
5323 NodeSwitch *switch_storage = MEM_callocN<NodeSwitch>(__func__);
5324 switch_storage->input_type = SOCK_FLOAT;
5325 switch_node.storage = switch_storage;
5326 switch_node.parent = curve_to_mesh->parent;
5327 switch_node.location[0] = curve_to_mesh->location[0] - 25;
5328 switch_node.location[1] = curve_to_mesh->location[1];
5329 switch_node.flag &= ~NODE_SELECT;
5330
5332 tree, &switch_node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Switch", "Switch");
5334 tree, &switch_node, SOCK_IN, SOCK_FLOAT, PROP_NONE, "False", "False");
5335 false_input->default_value_typed<bNodeSocketValueFloat>()->value = 1.0f;
5336
5338 tree, &switch_node, SOCK_IN, SOCK_FLOAT, PROP_NONE, "True", "True");
5339
5341 named_attribute,
5342 *bke::node_find_socket(named_attribute, SOCK_OUT, "Exists"),
5343 switch_node,
5344 *bke::node_find_socket(switch_node, SOCK_IN, "Switch"));
5346 named_attribute,
5347 *bke::node_find_socket(named_attribute, SOCK_OUT, "Attribute"),
5348 switch_node,
5349 *bke::node_find_socket(switch_node, SOCK_IN, "True"));
5350
5352 tree, &switch_node, SOCK_OUT, SOCK_FLOAT, PROP_NONE, "Output", "Output");
5353
5355 switch_node,
5356 *bke::node_find_socket(switch_node, SOCK_OUT, "Output"),
5357 *curve_to_mesh,
5358 *bke::node_find_socket(*curve_to_mesh, SOCK_IN, "Scale"));
5359 }
5360
5362}
5363
5364static bool strip_effect_overdrop_to_alphaover(Strip *strip, void * /*user_data*/)
5365{
5366 if (strip->type == STRIP_TYPE_OVERDROP_REMOVED) {
5367 strip->type = STRIP_TYPE_ALPHAOVER;
5368 }
5371 }
5372 return true;
5373}
5374
5376{
5377 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
5378 if (scene->ed != nullptr) {
5380 &scene->ed->seqbase, strip_effect_overdrop_to_alphaover, nullptr);
5381 }
5382 }
5383}
5384
5386{
5387 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
5388 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
5389 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
5390 if (sl->spacetype != SPACE_FILE) {
5391 continue;
5392 }
5393 SpaceFile *sfile = reinterpret_cast<SpaceFile *>(sl);
5394 if (sfile->params) {
5395 if (sfile->params->list_thumbnail_size == 0) {
5396 sfile->params->list_thumbnail_size = 16;
5397 }
5398 if (sfile->params->list_column_size == 0) {
5399 sfile->params->list_column_size = 500;
5400 }
5401 }
5402 if (sfile->asset_params) {
5403 if (sfile->asset_params->base_params.list_thumbnail_size == 0) {
5405 }
5406 if (sfile->asset_params->base_params.list_column_size == 0) {
5408 }
5410 }
5411 }
5412 }
5413 }
5414}
5415
5417{
5418 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
5419 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
5420 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
5421 if (sl->spacetype == SPACE_IMAGE) {
5422 SpaceImage *sima = reinterpret_cast<SpaceImage *>(sl);
5423 if (sima->flag & SI_NO_DRAW_TEXPAINT) {
5424 sima->flag |= SI_NO_DRAW_UV_GUIDE;
5425 }
5426 }
5427 }
5428 }
5429 }
5430}
5431
5433{
5434 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
5435 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
5436 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
5437 if (sl->spacetype == SPACE_IMAGE) {
5438 SpaceImage *sima = reinterpret_cast<SpaceImage *>(sl);
5439 /* Remove ID Code from screen name */
5440 const char *workspace_name = screen->id.name + 2;
5441 /* Don't set uv_face_opacity for Texture Paint or Shading since these are workspaces
5442 * where it's important to have unobstructed view of the Image Editor to see Image
5443 * Textures. UV Editing is the only other default workspace with an Image Editor.*/
5444 if (STREQ(workspace_name, "UV Editing")) {
5445 sima->uv_face_opacity = 1.0f;
5446 }
5447 }
5448 }
5449 }
5450 }
5451}
5452
5454{
5455 LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
5456 if (ELEM(brush->sculpt_brush_type,
5457 SCULPT_BRUSH_TYPE_FLATTEN,
5458 SCULPT_BRUSH_TYPE_FILL,
5459 SCULPT_BRUSH_TYPE_SCRAPE))
5460 {
5461 if (brush->sculpt_brush_type == SCULPT_BRUSH_TYPE_FLATTEN) {
5462 brush->plane_height = 1.0f;
5463 brush->plane_depth = 1.0f;
5464 brush->area_radius_factor = 1.0f;
5465 brush->plane_inversion_mode = BRUSH_PLANE_INVERT_DISPLACEMENT;
5466 }
5467
5468 if (brush->sculpt_brush_type == SCULPT_BRUSH_TYPE_FILL) {
5469 brush->plane_height = 0.0f;
5470 brush->plane_depth = 1.0f;
5471 brush->plane_inversion_mode = brush->flag & BRUSH_INVERT_TO_SCRAPE_FILL ?
5474 }
5475
5476 if (brush->sculpt_brush_type == SCULPT_BRUSH_TYPE_SCRAPE) {
5477 brush->plane_height = 1.0f;
5478 brush->plane_depth = 0.0f;
5479 brush->plane_inversion_mode = brush->flag & BRUSH_INVERT_TO_SCRAPE_FILL ?
5482
5483 /* Note, this fix was committed after some users had already run the versioning after
5484 * 4.5 was released. Since 4.5 is an LTS and will be used for the foreseeable future to
5485 * transition between 4.x and 5.x the fix has been added here, even though that does
5486 * not fix the issue for some users with custom brush assets who have started using 4.5
5487 * already.
5488 *
5489 * Since the `sculpt_brush_type` field changed from 'SCULPT_BRUSH_TYPE_SCRAPE' to
5490 * 'SCULPT_BRUSH_TYPE_PLANE', we do not have a value that can be used to definitively apply
5491 * a corrective versioning step along with a subversion bump without potentially affecting
5492 * some false positives.
5493 *
5494 * See #142151 for more details. */
5495 brush->plane_offset *= -1.0f;
5496 }
5497
5498 if (brush->flag & BRUSH_PLANE_TRIM) {
5499 brush->plane_height *= brush->plane_trim;
5500 brush->plane_depth *= brush->plane_trim;
5501 }
5502
5503 brush->stabilize_normal = (brush->flag & BRUSH_ORIGINAL_NORMAL) ? 1.0f : 0.0f;
5504 brush->stabilize_plane = (brush->flag & BRUSH_ORIGINAL_PLANE) ? 1.0f : 0.0f;
5505 brush->flag &= ~BRUSH_ORIGINAL_NORMAL;
5506 brush->flag &= ~BRUSH_ORIGINAL_PLANE;
5507
5508 brush->sculpt_brush_type = SCULPT_BRUSH_TYPE_PLANE;
5509 }
5510 }
5511}
5512
5514{
5515 if (item.item_type == eNodeTreeInterfaceItemType::NODE_INTERFACE_SOCKET) {
5516 auto &socket = reinterpret_cast<bNodeTreeInterfaceSocket &>(item);
5518 socket.structure_type = NODE_INTERFACE_SOCKET_STRUCTURE_TYPE_SINGLE;
5519 }
5520 else {
5521 socket.structure_type = NODE_INTERFACE_SOCKET_STRUCTURE_TYPE_AUTO;
5522 }
5523 }
5524 else {
5525 auto &panel = reinterpret_cast<bNodeTreeInterfacePanel &>(item);
5526 for (bNodeTreeInterfaceItem *item : blender::Span(panel.items_array, panel.items_num)) {
5528 }
5529 }
5530}
5531
5533{
5534 LISTBASE_FOREACH (bArmature *, arm, &bmain->armatures) {
5536 &arm->bonebase, [](Bone *bone) { bone->drawtype = ARM_DRAW_TYPE_ARMATURE_DEFINED; });
5537 BLI_assert_msg(!arm->edbo, "Armatures should not be saved in edit mode");
5538 }
5539}
5540
5541void blo_do_versions_450(FileData * /*fd*/, Library * /*lib*/, Main *bmain)
5542{
5543
5544 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 2)) {
5546 }
5547
5548 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 4)) {
5549 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
5550 if (ntree->type == NTREE_GEOMETRY) {
5552 }
5553 }
5555 }
5556
5557 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 5)) {
5558 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
5559 ToolSettings *tool_settings = scene->toolsettings;
5560 tool_settings->snap_flag_seq |= SCE_SNAP;
5561
5562 SequencerToolSettings *sequencer_tool_settings = blender::seq::tool_settings_ensure(scene);
5563 sequencer_tool_settings->snap_mode |= SEQ_SNAP_TO_FRAME_RANGE;
5564 }
5565 }
5566
5567 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 6)) {
5569 }
5570
5571 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 7)) {
5572 LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
5573 if (ntree->type == NTREE_GEOMETRY) {
5574 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
5575 if (STREQ(node->idname, "GeometryNodeStoreNamedGrid")) {
5576 switch (node->custom1) {
5577 case CD_PROP_FLOAT:
5578 node->custom1 = VOLUME_GRID_FLOAT;
5579 break;
5580 case CD_PROP_FLOAT2:
5581 case CD_PROP_FLOAT3:
5582 node->custom1 = VOLUME_GRID_VECTOR_FLOAT;
5583 break;
5584 default:
5585 node->custom1 = VOLUME_GRID_FLOAT;
5586 break;
5587 }
5588 }
5589 }
5590 }
5591 }
5592 }
5593
5594 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 8)) {
5595 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
5596 if (ntree->type == NTREE_COMPOSIT) {
5598 }
5599 }
5601 }
5602
5603 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 9)) {
5604 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
5605 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
5606 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
5607 if (sl->spacetype != SPACE_FILE) {
5608 continue;
5609 }
5610 SpaceFile *sfile = reinterpret_cast<SpaceFile *>(sl);
5611 if (sfile->asset_params) {
5613 }
5614 }
5615 }
5616 }
5617 }
5618
5619 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 15)) {
5620 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
5621 if (ntree->type != NTREE_COMPOSIT) {
5622 continue;
5623 }
5624 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
5625 if (node->type_legacy != CMP_NODE_SCALE) {
5626 continue;
5627 }
5628 if (node->storage != nullptr) {
5629 continue;
5630 }
5632 data->interpolation = CMP_NODE_INTERPOLATION_BILINEAR;
5633 node->storage = data;
5634 }
5635 }
5637 }
5638
5639 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 16)) {
5640 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
5641 scene->grease_pencil_settings.smaa_threshold_render =
5642 scene->grease_pencil_settings.smaa_threshold;
5643 scene->grease_pencil_settings.aa_samples = 1;
5644 }
5645 }
5646
5647 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 17)) {
5650 }
5651
5652 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 18)) {
5653 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
5654 if (ntree->type == NTREE_COMPOSIT) {
5655 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
5656 if (node->type_legacy == CMP_NODE_CORNERPIN) {
5658 }
5659 }
5660 }
5661 }
5663 }
5664
5665 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 19)) {
5666 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
5667 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
5668 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
5669 if (sl->spacetype == SPACE_PROPERTIES) {
5670 SpaceProperties *sbuts = reinterpret_cast<SpaceProperties *>(sl);
5671 /* Translates to 0xFFFFFFFF, so other tabs can be added without versioning. */
5672 sbuts->visible_tabs = uint(-1);
5673 }
5674 }
5675 }
5676 }
5677 }
5678
5679 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 20)) {
5680 /* Older files uses non-UTF8 aware string copy, ensure names are valid UTF8.
5681 * The slot names are not unique so no further changes are needed. */
5682 LISTBASE_FOREACH (Image *, image, &bmain->images) {
5683 LISTBASE_FOREACH (RenderSlot *, slot, &image->renderslots) {
5684 if (slot->name[0]) {
5685 BLI_str_utf8_invalid_strip(slot->name, STRNLEN(slot->name));
5686 }
5687 }
5688 }
5689 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
5690 scene->r.ppm_factor = 72.0f;
5691 scene->r.ppm_base = 0.0254f;
5692 }
5693 }
5694
5695 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 21)) {
5696 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5697 if (node_tree->type == NTREE_COMPOSIT) {
5698 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5699 if (node->type_legacy == CMP_NODE_GLARE) {
5701 }
5702 }
5703 }
5704 }
5706 }
5707
5708 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 22)) {
5709 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5710 if (node_tree->type == NTREE_COMPOSIT) {
5711 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5712 if (node->type_legacy == CMP_NODE_BOKEHIMAGE) {
5714 }
5715 }
5716 }
5717 }
5719 }
5720
5721 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 23)) {
5722 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5723 if (node_tree->type == NTREE_COMPOSIT) {
5724 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5725 if (node->type_legacy == CMP_NODE_TIME) {
5727 }
5728 }
5729 }
5730 }
5732 }
5733
5734 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 24)) {
5735 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5736 if (node_tree->type == NTREE_COMPOSIT) {
5737 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5738 if (node->type_legacy == CMP_NODE_MASK) {
5740 }
5741 }
5742 }
5743 }
5745 }
5746
5747 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 25)) {
5748 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5749 if (node_tree->type == NTREE_COMPOSIT) {
5750 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5751 if (node->type_legacy == CMP_NODE_SWITCH) {
5753 }
5754 }
5755 }
5756 }
5758 }
5759
5760 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 26)) {
5761 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5762 if (node_tree->type == NTREE_COMPOSIT) {
5763 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5764 if (node->type_legacy == CMP_NODE_SPLIT) {
5766 }
5767 }
5768 }
5769 }
5771 }
5772
5773 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 27)) {
5774 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5775 if (node_tree->type == NTREE_COMPOSIT) {
5776 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5777 if (node->type_legacy == CMP_NODE_INVERT) {
5779 }
5780 }
5781 }
5782 }
5784 }
5785
5786 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 28)) {
5787 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5788 if (node_tree->type == NTREE_COMPOSIT) {
5789 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5790 if (node->type_legacy == CMP_NODE_ZCOMBINE) {
5792 }
5793 }
5794 }
5795 }
5797 }
5798
5799 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 29)) {
5800 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5801 if (node_tree->type == NTREE_COMPOSIT) {
5802 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5803 if (node->type_legacy == CMP_NODE_TONEMAP) {
5805 }
5806 }
5807 }
5808 }
5810 }
5811
5812 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 30)) {
5813 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5814 if (node_tree->type == NTREE_COMPOSIT) {
5815 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5816 if (node->type_legacy == CMP_NODE_DILATEERODE) {
5818 }
5819 }
5820 }
5821 }
5823 }
5824
5825 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 31)) {
5826 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5827 if (node_tree->type == NTREE_COMPOSIT) {
5828 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5829 if (node->type_legacy == CMP_NODE_INPAINT) {
5831 }
5832 }
5833 }
5834 }
5836 }
5837
5838 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 32)) {
5839 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5840 if (node_tree->type == NTREE_COMPOSIT) {
5841 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5842 if (node->type_legacy == CMP_NODE_PIXELATE) {
5844 }
5845 }
5846 }
5847 }
5849 }
5850
5851 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 33)) {
5852 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5853 if (node_tree->type == NTREE_COMPOSIT) {
5854 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5855 if (node->type_legacy == CMP_NODE_KUWAHARA) {
5857 }
5858 }
5859 }
5860 }
5862 }
5863
5864 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 34)) {
5865 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5866 if (node_tree->type == NTREE_COMPOSIT) {
5867 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5868 if (node->type_legacy == CMP_NODE_DESPECKLE) {
5870 }
5871 }
5872 }
5873 }
5875 }
5876
5877 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 35)) {
5878 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5879 if (node_tree->type == NTREE_COMPOSIT) {
5880 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5881 if (node->type_legacy == CMP_NODE_DENOISE) {
5883 }
5884 }
5885 }
5886 }
5888 }
5889
5890 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 36)) {
5891 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5892 if (node_tree->type == NTREE_COMPOSIT) {
5893 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5894 if (node->type_legacy == CMP_NODE_ANTIALIASING) {
5896 }
5897 }
5898 }
5899 }
5901 }
5902
5903 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 37)) {
5904 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5905 if (node_tree->type == NTREE_COMPOSIT) {
5906 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5907 if (node->type_legacy == CMP_NODE_VECBLUR) {
5909 }
5910 }
5911 }
5912 }
5914 }
5915
5916 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 38)) {
5917 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5918 if (node_tree->type == NTREE_COMPOSIT) {
5919 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5920 if (node->type_legacy == CMP_NODE_CHANNEL_MATTE) {
5922 }
5923 }
5924 }
5925 }
5927 }
5928
5929 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 39)) {
5930 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5931 if (node_tree->type == NTREE_COMPOSIT) {
5932 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5933 if (node->type_legacy == CMP_NODE_CHROMA_MATTE) {
5935 }
5936 }
5937 }
5938 }
5940 }
5941
5942 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 40)) {
5943 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5944 if (node_tree->type == NTREE_COMPOSIT) {
5945 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5946 if (node->type_legacy == CMP_NODE_COLOR_MATTE) {
5948 }
5949 }
5950 }
5951 }
5953 }
5954
5955 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 41)) {
5956 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5957 if (node_tree->type == NTREE_COMPOSIT) {
5958 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5959 if (node->type_legacy == CMP_NODE_DIFF_MATTE) {
5961 }
5962 }
5963 }
5964 }
5966 }
5967
5968 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 42)) {
5969 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5970 if (node_tree->type == NTREE_COMPOSIT) {
5971 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5972 if (node->type_legacy == CMP_NODE_DIST_MATTE) {
5974 }
5975 }
5976 }
5977 }
5979 }
5980
5981 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 43)) {
5982 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5983 if (node_tree->type == NTREE_COMPOSIT) {
5984 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5985 if (node->type_legacy == CMP_NODE_LUMA_MATTE) {
5987 }
5988 }
5989 }
5990 }
5992 }
5993
5994 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 44)) {
5995 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
5996 if (node_tree->type == NTREE_COMPOSIT) {
5997 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
5998 if (node->type_legacy == CMP_NODE_COLOR_SPILL) {
6000 }
6001 }
6002 }
6003 }
6005 }
6006
6007 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 45)) {
6008 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6009 if (node_tree->type == NTREE_COMPOSIT) {
6010 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
6011 if (node->type_legacy == CMP_NODE_KEYINGSCREEN) {
6013 }
6014 }
6015 }
6016 }
6018 }
6019
6020 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 46)) {
6021 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
6022 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
6023 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
6024 if (sl->spacetype == SPACE_SEQ) {
6025 ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
6026 &sl->regionbase;
6027 LISTBASE_FOREACH (ARegion *, region, regionbase) {
6028 if (region->regiontype == RGN_TYPE_WINDOW) {
6029 region->v2d.keepzoom |= V2D_KEEPZOOM;
6030 region->v2d.keepofs |= V2D_KEEPOFS_X | V2D_KEEPOFS_Y;
6031 }
6032 }
6033 }
6034 }
6035 }
6036 }
6037 }
6038
6039 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 47)) {
6040 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6041 if (node_tree->type == NTREE_COMPOSIT) {
6042 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
6043 if (node->type_legacy == CMP_NODE_KEYING) {
6045 }
6046 }
6047 }
6048 }
6050 }
6051
6052 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 48)) {
6053 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6054 if (node_tree->type == NTREE_COMPOSIT) {
6055 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
6056 if (node->type_legacy == CMP_NODE_ID_MASK) {
6058 }
6059 }
6060 }
6061 }
6063 }
6064
6065 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 49)) {
6066 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6067 if (node_tree->type == NTREE_COMPOSIT) {
6068 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
6069 if (node->type_legacy == CMP_NODE_STABILIZE2D) {
6071 }
6072 }
6073 }
6074 }
6076 }
6077
6078 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 50)) {
6079 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6080 if (node_tree->type == NTREE_COMPOSIT) {
6081 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
6082 if (node->type_legacy == CMP_NODE_PLANETRACKDEFORM) {
6084 }
6085 }
6086 }
6087 }
6089 }
6090
6091 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 51)) {
6092 const Object *dob = DNA_struct_default_get(Object);
6093 LISTBASE_FOREACH (Object *, object, &bmain->objects) {
6094 object->shadow_terminator_normal_offset = dob->shadow_terminator_normal_offset;
6095 object->shadow_terminator_geometry_offset = dob->shadow_terminator_geometry_offset;
6096 object->shadow_terminator_shading_offset = dob->shadow_terminator_shading_offset;
6097 /* Copy Cycles' property into Blender Object. */
6099 if (cob) {
6100 object->shadow_terminator_geometry_offset = version_cycles_property_float(
6101 cob, "shadow_terminator_geometry_offset", dob->shadow_terminator_geometry_offset);
6102 object->shadow_terminator_shading_offset = version_cycles_property_float(
6103 cob, "shadow_terminator_offset", dob->shadow_terminator_shading_offset);
6104 }
6105 }
6106 }
6107
6108 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 52)) {
6109 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6110 if (node_tree->type == NTREE_COMPOSIT) {
6111 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
6112 if (node->type_legacy == CMP_NODE_COLORCORRECTION) {
6114 }
6115 }
6116 }
6117 }
6119 }
6120
6121 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 53)) {
6122 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6123 if (node_tree->type == NTREE_COMPOSIT) {
6124 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
6125 if (node->type_legacy == CMP_NODE_LENSDIST) {
6127 }
6128 }
6129 }
6130 }
6132 }
6133
6134 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 54)) {
6135 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6136 if (node_tree->type == NTREE_COMPOSIT) {
6137 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
6138 if (node->type_legacy == CMP_NODE_MASK_BOX) {
6140 }
6141 }
6142 }
6143 }
6145 }
6146
6147 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 55)) {
6148 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6149 if (node_tree->type == NTREE_COMPOSIT) {
6150 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
6151 if (node->type_legacy == CMP_NODE_MASK_ELLIPSE) {
6153 }
6154 }
6155 }
6156 }
6158 }
6159
6160 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 56)) {
6162 }
6163
6164 /* Enforce that bone envelope radii match for parent and connected children. */
6165 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 57)) {
6166 LISTBASE_FOREACH (bArmature *, arm, &bmain->armatures) {
6167 blender::animrig::ANIM_armature_foreach_bone(&arm->bonebase, [](Bone *bone) {
6168 if (bone->parent && (bone->flag & BONE_CONNECTED)) {
6169 bone->rad_head = bone->parent->rad_tail;
6170 }
6171 });
6172 if (arm->edbo) {
6173 LISTBASE_FOREACH (EditBone *, ebone, arm->edbo) {
6174 if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
6175 ebone->rad_head = ebone->parent->rad_tail;
6176 }
6177 }
6178 }
6179 }
6180 }
6181
6182 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 58)) {
6183 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6184 if (node_tree->type == NTREE_COMPOSIT) {
6185 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
6186 if (node->type_legacy == CMP_NODE_SUNBEAMS) {
6188 }
6189 }
6190 }
6191 }
6193 }
6194
6195 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 59)) {
6196 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6197 if (node_tree->type == NTREE_COMPOSIT) {
6198 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
6199 if (node->type_legacy == CMP_NODE_DBLUR) {
6201 }
6202 }
6203 }
6204 }
6206 }
6207
6208 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 60)) {
6209 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6210 if (node_tree->type == NTREE_COMPOSIT) {
6211 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
6212 if (node->type_legacy == CMP_NODE_BILATERALBLUR) {
6214 }
6215 }
6216 }
6217 }
6219 }
6220
6221 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 61)) {
6222 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6223 if (node_tree->type == NTREE_COMPOSIT) {
6225 }
6226 }
6228 }
6229
6230 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 62)) {
6231 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6232 if (node_tree->type == NTREE_COMPOSIT) {
6234 }
6235 }
6237 }
6238
6239 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 63)) {
6240 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6241 if (node_tree->type == NTREE_COMPOSIT) {
6243 }
6244 }
6246 }
6247
6248 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 64)) {
6249 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6250 if (node_tree->type == NTREE_COMPOSIT) {
6251 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
6252 if (node->type_legacy == CMP_NODE_ALPHAOVER) {
6254 }
6255 }
6256 }
6257 }
6259 }
6260
6261 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 65)) {
6262 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
6263 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
6264 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
6265 if (sl->spacetype == SPACE_SEQ) {
6266 ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
6267 &sl->regionbase;
6268 LISTBASE_FOREACH (ARegion *, region, regionbase) {
6269 if (region->regiontype == RGN_TYPE_WINDOW) {
6270 region->v2d.flag |= V2D_ZOOM_IGNORE_KEEPOFS;
6271 }
6272 }
6273 }
6274 }
6275 }
6276 }
6277 }
6278
6279 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 66)) {
6280 /* Clear unused draw flag (used to be SEQ_DRAW_BACKDROP). */
6281 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
6282 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
6283 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
6284 if (sl->spacetype == SPACE_SEQ) {
6285 SpaceSeq *space_sequencer = (SpaceSeq *)sl;
6286 space_sequencer->draw_flag &= ~SEQ_DRAW_UNUSED_0;
6287 }
6288 }
6289 }
6290 }
6291 }
6292
6293 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 67)) {
6294 /* Version render output paths (both primary on scene as well as those in
6295 * the File Output compositor node) to escape curly braces. */
6296 {
6297 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
6299 if (scene->nodetree) {
6301 }
6302 }
6303
6304 LISTBASE_FOREACH (bNodeTree *, nodetree, &bmain->nodetrees) {
6306 }
6307 }
6308 }
6309
6310 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 68)) {
6311 /* Fix brush->tip_scale_x which should never be zero. */
6312 LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
6313 if (brush->tip_scale_x == 0.0f) {
6314 brush->tip_scale_x = 1.0f;
6315 }
6316 }
6317 }
6318
6319 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 69)) {
6320 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6321 if (node_tree->type == NTREE_COMPOSIT) {
6322 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
6323 if (node->type_legacy == CMP_NODE_BOKEHBLUR) {
6325 }
6326 }
6327 }
6328 }
6330 }
6331
6332 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 70)) {
6333 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6334 if (node_tree->type == NTREE_COMPOSIT) {
6336 }
6337 }
6339 }
6340
6341 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 71)) {
6342 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6343 if (node_tree->type == NTREE_COMPOSIT) {
6345 }
6346 }
6348 }
6349
6350 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 72)) {
6352 }
6353
6354 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 73)) {
6355 /* Make #Curve::type the source of truth for the curve type.
6356 * Previously #Curve::vfont was checked which is error prone
6357 * since the member can become null at run-time, see: #139133. */
6358 LISTBASE_FOREACH (Curve *, cu, &bmain->curves) {
6359 if (ELEM(cu->ob_type, OB_CURVES_LEGACY, OB_FONT, OB_SURF)) {
6360 continue;
6361 }
6362 short ob_type = OB_CURVES_LEGACY;
6363 if (cu->vfont) {
6364 ob_type = OB_FONT;
6365 }
6366 else {
6367 LISTBASE_FOREACH (const Nurb *, nu, &cu->nurb) {
6368 if (nu->pntsv > 1) {
6369 ob_type = OB_SURF;
6370 break;
6371 }
6372 }
6373 }
6374 cu->ob_type = ob_type;
6375 }
6376 }
6377
6378 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 74)) {
6379 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6380 if (node_tree->type == NTREE_COMPOSIT) {
6382 }
6383 }
6385 }
6386
6387 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 75)) {
6388 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6389 if (node_tree->type == NTREE_COMPOSIT) {
6390 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
6391 if (node->type_legacy == CMP_NODE_CROP) {
6393 }
6394 }
6395 }
6396 }
6398 }
6399
6400 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 76)) {
6401 LISTBASE_FOREACH (Light *, light, &bmain->lights) {
6402 if (light->temperature == 0.0f) {
6403 light->temperature = 6500.0f;
6404 }
6405 }
6406 }
6407
6408 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 77)) {
6409 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6410 if (node_tree->type == NTREE_COMPOSIT) {
6411 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
6412 if (node->type_legacy == CMP_NODE_COLORBALANCE) {
6414 }
6415 }
6416 }
6417 }
6419 }
6420
6421 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 78)) {
6422 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6423 if (node_tree->type == NTREE_COMPOSIT) {
6425 }
6426 }
6428 }
6429
6430 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 79)) {
6431 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6433 }
6435 }
6436
6437 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 80)) {
6438 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6439 if (node_tree->type == NTREE_COMPOSIT) {
6440 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
6441 if (node->type_legacy == CMP_NODE_BLUR) {
6443 }
6444 }
6445 }
6446 }
6448 }
6449
6450 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 81)) {
6451 LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
6452 if (ntree->type == NTREE_GEOMETRY) {
6453 node_interface_single_value_to_structure_type(ntree->tree_interface.root_panel.item);
6454 }
6455 }
6456 }
6457
6458 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 83)) {
6459 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
6460 if (ob->soft) {
6461 ob->soft->fuzzyness = std::max<int>(1, ob->soft->fuzzyness);
6462 }
6463 }
6464 }
6465
6466 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 85)) {
6467 FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
6468 if (node_tree->type == NTREE_COMPOSIT) {
6469 LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
6470 if (node->type_legacy == CMP_NODE_FLIP) {
6472 }
6473 }
6474 }
6475 }
6477 }
6478
6479 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 86)) {
6481 }
6482
6483 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 87)) {
6484 FOREACH_NODETREE_BEGIN (bmain, tree, id) {
6485 if (tree->type == NTREE_GEOMETRY) {
6487 }
6488 }
6490 }
6491
6492 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 88)) {
6493 LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
6494 if (brush->gpencil_settings) {
6496 }
6497 }
6498 }
6499
6500 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 90)) {
6501 LISTBASE_FOREACH (Object *, object, &bmain->objects) {
6502 LISTBASE_FOREACH (ModifierData *, modifier, &object->modifiers) {
6504 continue;
6505 }
6507 modifier);
6508 if (lmd->radius != 0.0f) {
6509 continue;
6510 }
6511 lmd->radius = float(lmd->thickness_legacy) *
6513 }
6514 }
6515 }
6516
6517 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 91)) {
6518 /* For a brief period of time, these values were not properly versioned, so it is possible for
6519 * files to be in an odd state. This versioning was formerly run in 4.2 subversion 23. */
6520 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
6521 UvSculpt &uvsculpt = scene->toolsettings->uvsculpt;
6522 if (uvsculpt.size == 0 || uvsculpt.strength_curve == nullptr) {
6523 uvsculpt.size = 50;
6524 uvsculpt.strength = 1.0f;
6526 if (uvsculpt.strength_curve == nullptr) {
6527 uvsculpt.strength_curve = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
6528 }
6529 }
6530 }
6531 }
6532
6533 /* Fix the fact that previously, making a linked data local and/or clearing a liboverride would
6534 * not properly flag some sub-data like modifiers or constraints as local. */
6535 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 92)) {
6536 ID *id_iter;
6537 FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
6538 if (!ID_IS_LINKED(id_iter) && !ID_IS_OVERRIDE_LIBRARY(id_iter)) {
6540 }
6541 }
6543 }
6544
6545 /* Always run this versioning (keep at the bottom of the function). Meshes are written with the
6546 * legacy format which always needs to be converted to the new format on file load. To be moved
6547 * to a subversion check in 5.0. */
6548 LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) {
6552 }
6553
6560}
Functions and classes to work with Actions.
Functionality to iterate an Action in various ways.
Iterators for armatures.
void BKE_animdata_main_cb(struct Main *bmain, blender::FunctionRef< void(ID *, AnimData *)> func)
void BKE_fcurves_id_cb(struct ID *id, blender::FunctionRef< void(ID *, FCurve *)> func)
void BKE_animdata_fix_paths_rename_all_ex(struct Main *bmain, struct ID *ref_id, const char *prefix, const char *oldName, const char *newName, int oldSubscript, int newSubscript, bool verify_paths)
void BKE_curvemapping_free_data(CurveMapping *cumap)
CurveMapping * BKE_curvemapping_copy(const CurveMapping *cumap)
CurveMapping * BKE_curvemapping_add(int tot, float minx, float miny, float maxx, float maxy)
Definition colortools.cc:89
void BKE_curvemapping_copy_data(CurveMapping *target, const CurveMapping *cumap)
Low-level operations for curves.
CustomData interface, see also DNA_customdata_types.h.
void * CustomData_get_layer_named_for_write(CustomData *data, eCustomDataType type, blender::StringRef name, int totelem)
Low-level operations for grease pencil.
void IDP_MergeGroup_ex(IDProperty *dest, const IDProperty *src, bool do_overwrite, int flag) ATTR_NONNULL()
Definition idprop.cc:679
IDProperty * IDP_CopyProperty_ex(const IDProperty *prop, int flag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:855
@ LIB_ID_CREATE_NO_USER_REFCOUNT
void BKE_lib_override_flag_subdata_local(ID *id)
#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
#define FOREACH_NODETREE_END
Definition BKE_node.hh:866
#define FOREACH_NODETREE_BEGIN(bmain, _nodetree, _id)
Definition BKE_node.hh:856
#define CMP_NODE_PREMULKEY
#define CMP_NODE_DENOISE
#define CMP_NODE_VALTORGB
#define CMP_NODE_MASK
#define CMP_NODE_SCALE
#define GEO_NODE_SUBDIVISION_SURFACE
#define CMP_NODE_COMBINE_XYZ
#define CMP_NODE_COMPOSITE
#define CMP_NODE_MIX_RGB
#define CMP_NODE_VECBLUR
#define CMP_NODE_MAP_RANGE
#define CMP_NODE_TIME
#define CMP_NODE_COLOR_SPILL
#define CMP_CHAN_RGB
#define CMP_NODE_DESPECKLE
#define CMP_NODE_VIEWER
#define CMP_NODE_LUMA_MATTE
#define SH_NODE_COMBXYZ
#define CMP_NODE_CORNERPIN
#define CMP_NODE_KEYINGSCREEN
#define CMP_NODE_MASK_ELLIPSE
#define GEO_NODE_SUBDIVIDE_MESH
#define CMP_NODE_SEPARATE_COLOR
#define CMP_NODE_BILATERALBLUR
#define CMP_NODE_MAP_VALUE
#define CMP_NODE_TRANSLATE
#define CMP_NODE_TONEMAP
#define CMP_NODE_INPAINT
#define CMP_NODE_COLORBALANCE
#define SH_NODE_MAP_RANGE
#define CMP_NODE_BOKEHIMAGE
#define CMP_NODE_KUWAHARA
#define CMP_NODE_DIFF_MATTE
#define CMP_NODE_GAMMA
#define SH_NODE_VALUE
#define SH_NODE_CURVE_VEC
#define CMP_NODE_ALPHAOVER
#define SH_NODE_MATH
#define CMP_NODE_CROP
#define CMP_NODE_CHROMA_MATTE
#define CMP_NODE_GLARE
#define SH_NODE_SEPXYZ
#define CMP_NODE_PLANETRACKDEFORM
#define CMP_NODE_DILATEERODE
#define CMP_NODE_SPLIT
#define CMP_NODE_ID_MASK
#define CMP_NODE_BOKEHBLUR
#define CMP_NODE_LENSDIST
#define CMP_NODE_VALUE
#define CMP_NODE_ZCOMBINE
#define CMP_NODE_MATH
#define CMP_NODE_COLORCORRECTION
#define CMP_NODE_SETALPHA
#define CMP_NODE_STABILIZE2D
#define CMP_NODE_PIXELATE
#define SH_NODE_MIX
#define SH_NODE_VALTORGB
#define CMP_NODE_SWITCH
#define SH_NODE_CLAMP
#define CMP_NODE_MASK_BOX
#define CMP_NODE_DEFOCUS
#define CMP_NODE_KEYING
#define CMP_NODE_SEPARATE_XYZ
#define CMP_NODE_ANTIALIASING
#define CMP_NODE_CURVE_VEC
#define CMP_NODE_INVERT
#define CMP_NODE_COLOR_MATTE
#define CMP_NODE_DIST_MATTE
#define CMP_NODE_SUNBEAMS
#define CMP_NODE_DBLUR
#define CMP_NODE_BLUR
#define CMP_CHAN_A
#define CMP_NODE_BRIGHTCONTRAST
#define CMP_NODE_FLIP
#define CMP_NODE_CHANNEL_MATTE
CurveMapping * BKE_paint_default_curve()
Definition scene.cc:140
@ VOLUME_GRID_VECTOR_FLOAT
@ VOLUME_GRID_FLOAT
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
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 void copy_v4_v4(float r[4], const float a[4])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE bool is_zero_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
#define FILE_MAX
char * BLI_sprintfN(const char *__restrict format,...) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1
#define STRNLEN(str)
Definition BLI_string.h:608
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:688
int bool bool BLI_str_endswith(const char *__restrict str, const char *__restrict end) ATTR_NONNULL(1
size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
int BLI_str_utf8_invalid_strip(char *str, size_t str_len) ATTR_NONNULL(1)
size_t void BLI_uniquename_cb(blender::FunctionRef< bool(blender::StringRefNull)> unique_check, const char *defname, char delim, char *name, size_t name_maxncpy) ATTR_NONNULL(2
size_t BLI_string_replace_range(char *string, size_t string_maxncpy, int src_beg, int src_end, const char *dst)
unsigned int uint
#define ELEM(...)
#define STREQ(a, b)
@ FMODIFIER_TYPE_NOISE
@ BONE_CONNECTED
@ GP_BRUSH_USE_SAT_RAND_PRESS
@ GP_BRUSH_USE_VAL_RAND_PRESS
@ GP_BRUSH_USE_HUE_RAND_PRESS
@ GP_BRUSH_USE_HUE_AT_STROKE
@ GP_BRUSH_USE_VAL_AT_STROKE
@ GP_BRUSH_USE_SAT_AT_STROKE
@ BRUSH_PLANE_INVERT_DISPLACEMENT
@ BRUSH_PLANE_SWAP_HEIGHT_AND_DEPTH
@ BRUSH_CURVE_SMOOTH
@ SCULPT_BRUSH_TYPE_PLANE
@ BRUSH_ORIGINAL_NORMAL
@ BRUSH_ORIGINAL_PLANE
@ BRUSH_PLANE_TRIM
@ BRUSH_INVERT_TO_SCRAPE_FILL
@ BRUSH_COLOR_JITTER_USE_VAL_AT_STROKE
@ BRUSH_COLOR_JITTER_USE_HUE_AT_STROKE
@ BRUSH_COLOR_JITTER_USE_SAT_AT_STROKE
@ BRUSH_COLOR_JITTER_USE_SAT_RAND_PRESS
@ BRUSH_COLOR_JITTER_USE_VAL_RAND_PRESS
@ BRUSH_COLOR_JITTER_USE_HUE_RAND_PRESS
@ BRUSH_JITTER_COLOR
@ NURBS_KNOT_MODE_NORMAL
@ NURBS_KNOT_MODE_CUSTOM
@ CD_PROP_FLOAT
@ CD_PROP_FLOAT3
@ CD_PROP_FLOAT2
#define DNA_struct_default_get(struct_name)
@ eModifierType_GreasePencilLineart
@ NODE_INTERFACE_SOCKET_SINGLE_VALUE_ONLY_LEGACY
@ NODE_INTERFACE_SOCKET_STRUCTURE_TYPE_SINGLE
@ NODE_INTERFACE_SOCKET_STRUCTURE_TYPE_AUTO
@ NODE_VECTOR_MATH_SCALE
@ CMP_NODE_INTERPOLATION_BILINEAR
@ NODE_MATH_MINIMUM
@ NODE_MATH_ADD
@ NODE_MATH_MAXIMUM
@ NODE_MATH_MULTIPLY
@ SHD_MIXRGB_USE_ALPHA
@ SHD_MIXRGB_CLAMP
@ CMP_NODE_BLUR_ASPECT_NONE
@ CMP_NODE_BLUR_ASPECT_X
@ CMP_NODE_BLUR_ASPECT_Y
@ CMP_NODE_RELATIVE_TO_PIXEL_DATA_TYPE_VECTOR
@ CMP_NODE_RELATIVE_TO_PIXEL_DATA_TYPE_FLOAT
@ CMP_NODE_CORNER_PIN_INTERPOLATION_ANISOTROPIC
@ CMP_NODE_ALPHA_CONVERT_UNPREMULTIPLY
@ CMP_NODE_ALPHA_CONVERT_PREMULTIPLY
@ CMP_NODE_MASK_FLAG_NO_FEATHER
@ CMP_NODE_MASK_FLAG_MOTION_BLUR
@ SOCK_OUT
@ SOCK_IN
@ CMP_NODE_SETALPHA_MODE_REPLACE_ALPHA
@ NODE_MIX_MODE_UNIFORM
@ SOCK_INT
@ SOCK_VECTOR
@ SOCK_BOOLEAN
@ SOCK_FLOAT
@ SOCK_STRING
@ SOCK_RGBA
@ NODE_HIDDEN
@ NODE_SELECT
@ CMP_NODE_SCALE_RENDER_SIZE
@ CMP_NODE_RELATIVE_TO_PIXEL_REFERENCE_DIMENSION_PER_DIMENSION
@ CMP_NODE_RELATIVE_TO_PIXEL_REFERENCE_DIMENSION_Y
@ CMP_NODE_RELATIVE_TO_PIXEL_REFERENCE_DIMENSION_X
@ CMP_NODE_OUTPUT_IGNORE_ALPHA
@ NODE_MAP_RANGE_LINEAR
@ CMP_NODE_LENS_DISTORTION_RADIAL
@ CMP_NODE_LENS_DISTORTION_HORIZONTAL
@ NTREE_GEOMETRY
@ NTREE_COMPOSIT
@ OB_SURF
@ OB_FONT
@ OB_CURVES_LEGACY
@ SEQ_SNAP_TO_FRAME_RANGE
@ SCE_SNAP
@ RGN_TYPE_WINDOW
@ STRIP_TYPE_OVERDROP_REMOVED
@ STRIP_TYPE_ALPHAOVER
@ SI_NO_DRAW_UV_GUIDE
@ SPACE_FILE
@ SPACE_PROPERTIES
@ SPACE_SEQ
@ SPACE_IMAGE
@ SEQ_DRAW_UNUSED_0
@ FILE_ASSET_IMPORT_INSTANCE_COLLECTIONS_ON_LINK
@ TEXMAP_CLIP_MIN
@ TEXMAP_CLIP_MAX
@ V2D_KEEPOFS_Y
@ V2D_KEEPOFS_X
@ V2D_ZOOM_IGNORE_KEEPOFS
@ V2D_KEEPZOOM
@ PROP_ANGLE
Definition RNA_types.hh:240
@ PROP_COLOR_TEMPERATURE
Definition RNA_types.hh:278
@ PROP_NONE
Definition RNA_types.hh:221
@ PROP_FACTOR
Definition RNA_types.hh:239
BMesh const char void * data
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
bool contains(const Key &key) const
Definition BLI_set.hh:310
bool add(const Key &key)
Definition BLI_set.hh:248
bool add(const Key &key, const Value &value)
Definition BLI_map.hh:295
const Value & lookup(const Key &key) const
Definition BLI_map.hh:545
Value lookup_default(const Key &key, const Value &default_value) const
Definition BLI_map.hh:570
void add_new(const Key &key, const Value &value)
Definition BLI_map.hh:265
bool contains(const Key &key) const
Definition BLI_map.hh:353
constexpr bool is_empty() const
Definition BLI_span.hh:260
blender::Span< const Slot * > slots() const
bke::CurvesGeometry & strokes_for_write()
KDTree_3d * tree
#define input
#define CD_MASK_PROP_ALL
#define ID_IS_LINKED(_id)
#define ID_IS_OVERRIDE_LIBRARY(_id)
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
void foreach_fcurve_in_action_slot(Action &action, slot_handle_t handle, FunctionRef< void(FCurve &fcurve)> callback)
static void ANIM_armature_foreach_bone(ListBase *bones, CB callback)
void foreach_fcurve_in_action(Action &action, FunctionRef< void(FCurve &fcurve)> callback)
constexpr float LEGACY_RADIUS_CONVERSION_FACTOR
T & get_item_as(bNodeTreeInterfaceItem &item)
T & get_socket_data_as(bNodeTreeInterfaceSocket &item)
void node_modify_socket_type_static(bNodeTree *ntree, bNode *node, bNodeSocket *sock, int type, int subtype)
Definition node.cc:3123
void mesh_sculpt_mask_to_generic(Mesh &mesh)
bNodeSocket * node_find_socket(bNode &node, eNodeSocketInOut in_out, StringRef identifier)
Definition node.cc:2864
void node_remove_node(Main *bmain, bNodeTree &ntree, bNode &node, bool do_id_user, bool remove_animation=true)
Definition node.cc:4649
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
bNodeSocketType * node_socket_type_find(StringRef idname)
Definition node.cc:2794
bNode * node_add_static_node(const bContext *C, bNodeTree &ntree, int type)
Definition node.cc:3804
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 mesh_custom_normals_to_generic(Mesh &mesh)
T min(const T &a, const T &b)
T max(const T &a, const T &b)
void for_each_callback(ListBase *seqbase, ForEachFunc callback, void *user_data)
Definition iterator.cc:59
SequencerToolSettings * tool_settings_ensure(Scene *scene)
Definition sequencer.cc:362
float wrap(float value, float max, float min)
Definition node_math.h:71
#define min(a, b)
Definition sort.cc:36
ListBase drivers
ListBase nla_tracks
struct CurveMapping * curve_rand_saturation
struct CurveMapping * curve_rand_hue
struct CurveMapping * curve_rand_value
struct CurveMapping * curve_rand_saturation
struct CurveMapping * curve_rand_hue
struct CurveMapping * curve_rand_value
struct BrushGpencilSettings * gpencil_settings
int color_jitter_flag
float hsv_jitter[3]
CustomDataLayer * layers
char * rna_path
ListBase modifiers
FileSelectParams base_params
unsigned short list_column_size
unsigned short list_thumbnail_size
Definition DNA_ID.h:404
IDProperty * system_properties
Definition DNA_ID.h:454
IDProperty * properties
Definition DNA_ID.h:446
ListBase brushes
Definition BKE_main.hh:271
ListBase scenes
Definition BKE_main.hh:245
ListBase grease_pencils
Definition BKE_main.hh:279
ListBase actions
Definition BKE_main.hh:269
ListBase hair_curves
Definition BKE_main.hh:289
ListBase nodetrees
Definition BKE_main.hh:270
ListBase armatures
Definition BKE_main.hh:268
ListBase screens
Definition BKE_main.hh:261
ListBase images
Definition BKE_main.hh:253
ListBase objects
Definition BKE_main.hh:247
CustomData edge_data
CustomData corner_data
CustomData face_data
ListBase vertex_group_names
CustomData vert_data
uint8_t input_type
float shadow_terminator_shading_offset
float shadow_terminator_geometry_offset
float shadow_terminator_normal_offset
FileSelectParams * params
FileAssetSelectParams * asset_params
float uv_face_opacity
int16_t snap_step_seconds
struct UnifiedPaintSettings unified_paint_settings
int16_t snap_step_frames
struct CurveMapping * curve_rand_value
struct CurveMapping * curve_rand_saturation
struct CurveMapping * curve_rand_hue
int8_t curve_preset
struct CurveMapping * strength_curve
void * default_value
char identifier[64]
bNodeTreeInterface tree_interface
ListBase nodes
ListBase links
float location[2]
int16_t custom1
float width
ListBase inputs
struct bNode * parent
char name[64]
int16_t type_legacy
float custom4
void * storage
float custom3
int16_t custom2
Defines a socket type.
Definition BKE_node.hh:152
eNodeSocketDatatype type
Definition BKE_node.hh:187
max
Definition text_draw.cc:251
static bNode * add_node(bNodeTree *ntree, const int type, const blender::float2 loc)
static void do_version_alpha_over_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_color_spill_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_init_default_jitter_curves_in_unified_paint_settings(ToolSettings *ts)
static void do_version_tone_map_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_id_mask_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_color_correction_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_color_balance_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_denoise_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_directional_blur_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_translate_node_remove_relative(bNodeTree *node_tree)
static void do_version_tone_map_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_composite_viewer_remove_alpha(bNodeTree *node_tree)
static void do_version_glare_node_star_45_option_to_input_animation(bNodeTree *node_tree, bNode *node)
void blo_do_versions_450(FileData *, Library *, Main *bmain)
static void version_set_default_bone_drawtype(Main *bmain)
static void do_version_denoise_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_luminance_matte_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_bright_contrast_remove_premultiplied(bNodeTree *node_tree)
static void do_version_luminance_matte_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_alpha_over_remove_premultiply(bNodeTree *node_tree)
static void do_version_pixelate_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_stabilize_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_difference_matte_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_stabilize_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_chroma_matte_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static bool strip_effect_overdrop_to_alphaover(Strip *strip, void *)
static void do_version_distance_matte_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void version_escape_curly_braces(char string[], const int string_array_length)
static void do_version_blur_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_anti_alias_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void version_show_texpaint_to_show_uv(Main *bmain)
static void do_version_difference_matte_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_keying_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_despeckle_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_mask_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_bokeh_blur_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_chroma_matte_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_map_value_node(bNodeTree *node_tree, bNode *node)
static void do_version_mix_color_use_alpha(bNodeTree *node_tree, bNode *node)
static void do_version_scale_node_remove_translate(bNodeTree *node_tree)
static void fix_curve_nurbs_knot_mode_custom(Main *bmain)
static void do_version_invert_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_kuwahara_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_dilate_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_z_combine_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_color_matte_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_sun_beams_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_replace_image_info_node_coordinates(bNodeTree *node_tree)
static void do_version_color_spill_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_bokeh_blur_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_sun_beams_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_z_combine_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_split_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_time_curve_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void version_convert_sculpt_planar_brushes(Main *bmain)
static void do_version_id_mask_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_channel_matte_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_bokeh_image_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void version_escape_curly_braces_in_compositor_file_output_nodes(bNodeTree &nodetree)
static void do_convert_gp_jitter_flags(Brush *brush)
static void do_version_plane_track_deform_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_lens_distortion_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void clamp_subdivision_node_level_input(bNodeTree &tree)
static void do_version_switch_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_lens_distortion_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_time_curve_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_box_mask_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_split_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void asset_browser_add_list_view(Main *bmain)
static void do_version_kuwahara_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_crop_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_convert_to_generic_nodes_after_linking(Main *bmain, bNodeTree *node_tree, ID *id)
static void do_version_ellipse_mask_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_color_matte_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_switch_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_plane_track_deform_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
void version_forward_compat_system_idprops(Main *bmain)
static void do_version_despeckle_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_color_correction_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_ellipse_mask_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_box_mask_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_vector_blur_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_dilate_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_alpha_over_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_inpaint_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_vector_sockets_dimensions(bNodeTree *node_tree)
static void do_version_mask_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static CustomDataLayer * find_old_seam_layer(CustomData &custom_data, const blender::StringRef name)
static void do_version_bokeh_image_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_anti_alias_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void nlastrips_apply_fcurve_versioning(ListBase &strips)
void do_versions_after_linking_450(FileData *, Main *bmain)
static void do_version_bilateral_blur_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void version_sequencer_update_overdrop(Main *bmain)
static void do_version_blur_defocus_nodes_remove_gamma(bNodeTree *node_tree)
static void do_version_channel_matte_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_flip_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_convert_gp_jitter_values(Brush *brush)
static void do_version_keying_screen_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_keying_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_new_glare_clamp_input(bNodeTree *node_tree)
static void do_version_glare_node_star_45_option_to_input(bNodeTree *node_tree, bNode *node)
static void do_version_inpaint_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void node_interface_single_value_to_structure_type(bNodeTreeInterfaceItem &item)
static void do_version_bilateral_blur_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_node_curve_to_mesh_scale_input(bNodeTree *tree)
static void do_version_directional_blur_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_convert_to_generic_nodes(bNodeTree *node_tree)
static void do_version_invert_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_color_balance_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void version_fix_fcurve_noise_offset(FCurve &fcurve)
static void do_version_vector_blur_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void version_set_uv_face_overlay_defaults(Main *bmain)
static void do_version_keying_screen_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void do_version_crop_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_pixelate_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
static void do_version_distance_matte_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
static void rename_mesh_uv_seam_attribute(Mesh &mesh)
static void do_version_blur_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
IDProperty * version_cycles_properties_from_ID(ID *id)
bool version_node_socket_is_used(bNodeSocket *sock)
bNodeSocket & version_node_add_socket(bNodeTree &ntree, bNode &node, const eNodeSocketInOut in_out, const char *idname, const char *identifier)
void version_node_socket_index_animdata(Main *bmain, const int node_tree_type, const int node_type, const int socket_index_orig, const int socket_index_offset, const int total_number_of_sockets)
bNode & version_node_add_empty(bNodeTree &ntree, const char *idname)
void version_socket_update_is_used(bNodeTree *ntree)
bNodeLink & version_node_add_link(bNodeTree &ntree, bNode &node_a, bNodeSocket &socket_a, bNode &node_b, bNodeSocket &socket_b)
bNodeSocket * version_node_add_socket_if_not_exist(bNodeTree *ntree, bNode *node, int in_out, int type, int subtype, const char *identifier, const char *name)
float version_cycles_property_float(IDProperty *idprop, const char *name, float default_value)