Blender V5.0
versioning_400.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#define DNA_DEPRECATED_ALLOW
10
11#include "ANIM_armature_iter.hh"
13
14/* Define macros in `DNA_genfile.h`. */
15#define DNA_GENFILE_VERSIONING_MACROS
16
17#include "DNA_brush_types.h"
18#include "DNA_camera_types.h"
19#include "DNA_defaults.h"
20#include "DNA_genfile.h"
21#include "DNA_light_types.h"
23#include "DNA_modifier_types.h"
24#include "DNA_node_types.h"
25#include "DNA_particle_types.h"
26#include "DNA_screen_types.h"
27#include "DNA_sequence_types.h"
28#include "DNA_world_types.h"
29
30#undef DNA_GENFILE_VERSIONING_MACROS
31
32#include "BLI_listbase.h"
33#include "BLI_math_vector.h"
34#include "BLI_string.h"
35#include "BLI_string_utf8.h"
36
37#include "BLT_translation.hh"
38
39#include "BKE_anim_data.hh"
40#include "BKE_animsys.h"
41#include "BKE_attribute.hh"
42#include "BKE_curve.hh"
43#include "BKE_effect.h"
44#include "BKE_grease_pencil.hh"
45#include "BKE_idprop.hh"
46#include "BKE_main.hh"
48#include "BKE_node.hh"
50#include "BKE_node_runtime.hh"
51#include "BKE_report.hh"
52#include "BKE_scene.hh"
53#include "BKE_texture.h"
54#include "BKE_tracking.h"
55
56#include "SEQ_iterator.hh"
57#include "SEQ_retiming.hh"
58#include "SEQ_sequencer.hh"
59#include "SEQ_time.hh"
60
61#include "BLO_read_write.hh"
62
63#include "readfile.hh"
64
65#include "versioning_common.hh"
66
68{
69 for (bNode *node : ntree->all_nodes()) {
70 if (node->id == nullptr && ((node->type_legacy == CMP_NODE_R_LAYERS) ||
71 (node->type_legacy == CMP_NODE_CRYPTOMATTE &&
72 node->custom1 == CMP_NODE_CRYPTOMATTE_SOURCE_RENDER)))
73 {
74 node->id = &scene->id;
75 }
76 }
77}
78
79/* Move bone-group color to the individual bones. */
81{
82 using PoseSet = blender::Set<bPose *>;
84
85 /* Gather a mapping from armature to the poses that use it. */
86 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
87 if (ob->type != OB_ARMATURE || !ob->pose) {
88 continue;
89 }
90
91 bArmature *arm = reinterpret_cast<bArmature *>(ob->data);
92 BLI_assert_msg(GS(arm->id.name) == ID_AR,
93 "Expected ARMATURE object to have an Armature as data");
94
95 /* There is no guarantee that the current state of poses is in sync with the Armature data.
96 *
97 * NOTE: No need to handle user reference-counting in readfile code. */
98 BKE_pose_ensure(bmain, ob, arm, false);
99
100 PoseSet &pose_set = armature_poses.lookup_or_add_default(arm);
101 pose_set.add(ob->pose);
102 }
103
104 /* Move colors from the pose's bone-group to either the armature bones or the
105 * pose bones, depending on how many poses use the Armature. */
106 for (const PoseSet &pose_set : armature_poses.values()) {
107 /* If the Armature is shared, the bone group colors might be different, and thus they have to
108 * be stored on the pose bones. If the Armature is NOT shared, the bone colors can be stored
109 * directly on the Armature bones. */
110 const bool store_on_armature = pose_set.size() == 1;
111
112 for (bPose *pose : pose_set) {
113 LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
114 const bActionGroup *bgrp = (const bActionGroup *)BLI_findlink(&pose->agroups,
115 (pchan->agrp_index - 1));
116 if (!bgrp) {
117 continue;
118 }
119
120 BoneColor &bone_color = store_on_armature ? pchan->bone->color : pchan->color;
121 bone_color.palette_index = bgrp->customCol;
122 memcpy(&bone_color.custom, &bgrp->cs, sizeof(bone_color.custom));
123 }
124 }
125 }
126}
127
129{
130 char bcoll_name[MAX_NAME];
131 char custom_prop_name[MAX_NAME];
132
133 LISTBASE_FOREACH (bArmature *, arm, &bmain->armatures) {
134 IDProperty *arm_idprops = IDP_GetProperties(&arm->id);
135
136 BLI_assert_msg(arm->edbo == nullptr, "did not expect an Armature to be saved in edit mode");
137 const uint layer_used = arm->layer_used;
138
139 /* Construct a bone collection for each layer that contains at least one bone. */
141 for (uint layer = 0; layer < 32; ++layer) {
142 const uint layer_mask = 1u << layer;
143 if ((layer_used & layer_mask) == 0) {
144 /* Layer is empty, so no need to convert to collection. */
145 continue;
146 }
147
148 /* Construct a suitable name for this bone layer. */
149 bcoll_name[0] = '\0';
150 if (arm_idprops) {
151 /* See if we can use the layer name from the Bone Manager add-on. This is a popular add-on
152 * for managing bone layers and giving them names. */
153 SNPRINTF_UTF8(custom_prop_name, "layer_name_%u", layer);
154 IDProperty *prop = IDP_GetPropertyFromGroup(arm_idprops, custom_prop_name);
155 if (prop != nullptr && prop->type == IDP_STRING && IDP_string_get(prop)[0] != '\0') {
156 SNPRINTF_UTF8(bcoll_name, "Layer %u - %s", layer + 1, IDP_string_get(prop));
157 }
158 }
159 if (bcoll_name[0] == '\0') {
160 /* Either there was no name defined in the custom property, or
161 * it was the empty string. */
162 SNPRINTF_UTF8(bcoll_name, "Layer %u", layer + 1);
163 }
164
165 /* Create a new bone collection for this layer. */
166 BoneCollection *bcoll = ANIM_armature_bonecoll_new(arm, bcoll_name);
167 layermask_collection.append(std::make_pair(layer_mask, bcoll));
168
169 if ((arm->layer & layer_mask) == 0) {
170 ANIM_bonecoll_hide(arm, bcoll);
171 }
172 }
173
174 /* Iterate over the bones to assign them to their layers. */
175 blender::animrig::ANIM_armature_foreach_bone(&arm->bonebase, [&](Bone *bone) {
176 for (auto layer_bcoll : layermask_collection) {
177 const uint layer_mask = layer_bcoll.first;
178 if ((bone->layer & layer_mask) == 0) {
179 continue;
180 }
181
182 BoneCollection *bcoll = layer_bcoll.second;
183 ANIM_armature_bonecoll_assign(bcoll, bone);
184 }
185 });
186 }
187}
188
190{
191 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
192 if (ob->type != OB_ARMATURE || !ob->pose) {
193 continue;
194 }
195
196 /* Convert the bone groups on a bone-by-bone basis. */
197 bArmature *arm = reinterpret_cast<bArmature *>(ob->data);
198 bPose *pose = ob->pose;
199
201 /* Convert all bone groups, regardless of whether they contain any bones. */
202 LISTBASE_FOREACH (bActionGroup *, bgrp, &pose->agroups) {
203 BoneCollection *bcoll = ANIM_armature_bonecoll_new(arm, bgrp->name);
204 collections_by_group.add_new(bgrp, bcoll);
205
206 /* Before now, bone visibility was determined by armature layers, and bone
207 * groups did not have any impact on this. To retain the behavior, that
208 * hiding all layers a bone is on hides the bone, the
209 * bone-group-collections should be created hidden. */
210 ANIM_bonecoll_hide(arm, bcoll);
211 }
212
213 /* Assign the bones to their bone group based collection. */
214 LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
215 /* Find the bone group of this pose channel. */
216 const bActionGroup *bgrp = (const bActionGroup *)BLI_findlink(&pose->agroups,
217 (pchan->agrp_index - 1));
218 if (!bgrp) {
219 continue;
220 }
221
222 /* Assign the bone. */
223 BoneCollection *bcoll = collections_by_group.lookup(bgrp);
224 ANIM_armature_bonecoll_assign(bcoll, pchan->bone);
225 }
226
227 /* The list of bone groups (pose->agroups) is intentionally left alone here. This will allow
228 * for older versions of Blender to open the file with bone groups intact. Of course the bone
229 * groups will not be updated any more, but this way the data at least survives an accidental
230 * save with Blender 4.0. */
231 }
232}
233
235{
236 ID *id = &ntree->id;
238
239 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
240 if (node->type_legacy != SH_NODE_BSDF_PRINCIPLED) {
241 continue;
242 }
243
244 char node_name_escaped[MAX_NAME * 2];
245 BLI_str_escape(node_name_escaped, node->name, sizeof(node_name_escaped));
246 std::string prefix = "nodes[\"" + std::string(node_name_escaped) + "\"].inputs";
247
248 /* Remove animdata for inputs 18 (Transmission Roughness) and 3 (Subsurface Color). */
249 BKE_animdata_fix_paths_remove(id, (prefix + "[18]").c_str());
250 BKE_animdata_fix_paths_remove(id, (prefix + "[3]").c_str());
251
252 /* Order is important here: If we e.g. want to change A->B and B->C, but perform A->B first,
253 * then later we don't know whether a B entry is an original B (and therefore should be
254 * changed to C) or used to be A and was already handled.
255 * In practice, going reverse mostly works, the two notable dependency chains are:
256 * - 8->13, then 2->8, then 9->2 (13 was changed before)
257 * - 1->9, then 6->1 (9 was changed before)
258 * - 4->10, then 21->4 (10 was changed before)
259 *
260 * 0 (Base Color) and 17 (Transmission) are fine as-is. */
261 std::pair<int, int> remap_table[] = {
262 {20, 27}, /* Emission Strength */
263 {19, 26}, /* Emission */
264 {16, 3}, /* IOR */
265 {15, 19}, /* Clearcoat Roughness */
266 {14, 18}, /* Clearcoat */
267 {13, 25}, /* Sheen Tint */
268 {12, 23}, /* Sheen */
269 {11, 15}, /* Anisotropic Rotation */
270 {10, 14}, /* Anisotropic */
271 {8, 13}, /* Specular Tint */
272 {2, 8}, /* Subsurface Radius */
273 {9, 2}, /* Roughness */
274 {7, 12}, /* Specular */
275 {1, 9}, /* Subsurface Scale */
276 {6, 1}, /* Metallic */
277 {5, 11}, /* Subsurface Anisotropy */
278 {4, 10}, /* Subsurface IOR */
279 {21, 4} /* Alpha */
280 };
281 for (const auto &entry : remap_table) {
283 id, adt, owner_id, prefix.c_str(), nullptr, nullptr, entry.first, entry.second, false);
284 }
285 }
286}
287
288static bool versioning_convert_strip_speed_factor(Strip *strip, void *user_data)
289{
290 const Scene *scene = static_cast<Scene *>(user_data);
291 const float speed_factor = strip->speed_factor;
292
293 if (speed_factor == 1.0f || !blender::seq::retiming_is_allowed(strip) ||
295 {
296 return true;
297 }
298
300 SeqRetimingKey *last_key = &blender::seq::retiming_keys_get(strip)[1];
301
302 last_key->strip_frame_index = (strip->len) / speed_factor;
303
304 if (strip->type == STRIP_TYPE_SOUND_RAM) {
305 const int prev_length = strip->len - strip->startofs - strip->endofs;
306 const float left_handle = blender::seq::time_left_handle_frame_get(scene, strip);
307 blender::seq::time_right_handle_frame_set(scene, strip, left_handle + prev_length);
308 }
309
310 return true;
311}
312
314{
315 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 9)) {
316 /* Fix area light scaling. */
317 LISTBASE_FOREACH (Light *, light, &bmain->lights) {
318 light->energy = light->energy_deprecated;
319 if (light->type == LA_AREA) {
320 light->energy *= M_PI_4;
321 }
322 }
323
324 /* XXX This was added several years ago in `lib_link` code of Scene... Should be safe enough
325 * here. */
326 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
327 if (scene->nodetree) {
328 version_composite_nodetree_null_id(scene->nodetree, scene);
329 }
330 }
331
332 /* XXX This was added many years ago (1c19940198) in `lib_link` code of particles as a bug-fix.
333 * But this is actually versioning. Should be safe enough here. */
334 LISTBASE_FOREACH (ParticleSettings *, part, &bmain->particles) {
335 if (!part->effector_weights) {
336 part->effector_weights = BKE_effector_add_weights(part->force_group);
337 }
338 }
339
340 /* Object proxies have been deprecated sine 3.x era, so their update & sanity check can now
341 * happen in do_versions code. */
342 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
343 if (ob->proxy) {
344 /* Paranoia check, actually a proxy_from pointer should never be written... */
345 if (!ID_IS_LINKED(ob->proxy)) {
346 ob->proxy->proxy_from = nullptr;
347 ob->proxy = nullptr;
348
349 if (ob->id.lib) {
351 RPT_INFO,
352 RPT_("Proxy lost from object %s lib %s\n"),
353 ob->id.name + 2,
354 ob->id.lib->filepath);
355 }
356 else {
358 RPT_INFO,
359 RPT_("Proxy lost from object %s lib <NONE>\n"),
360 ob->id.name + 2);
361 }
363 }
364 else {
365 /* This triggers object_update to always use a copy. */
366 ob->proxy->proxy_from = ob;
367 }
368 }
369 }
370 }
371
372 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 21)) {
373 if (!DNA_struct_member_exists(fd->filesdna, "bPoseChannel", "BoneColor", "color")) {
375 }
376
377 if (!DNA_struct_member_exists(fd->filesdna, "bArmature", "ListBase", "collections")) {
380 }
381 }
382
383 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 24)) {
384 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
385 if (ntree->type == NTREE_SHADER) {
386 /* Convert animdata on the Principled BSDF sockets. */
388 }
389 }
391 }
392
393 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 27)) {
394 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
396 if (ed != nullptr) {
398 }
399 }
400 }
401
402 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 34)) {
404 }
405}
406
425
427{
428 MovieTracking &tracking = movieclip.tracking;
429 MovieTrackingObject *active_tracking_object = BKE_tracking_object_get_active(&tracking);
430 MovieTrackingObject *tracking_camera_object = BKE_tracking_object_get_camera(&tracking);
431
432 BLI_assert(tracking_camera_object != nullptr);
433
434 if (BLI_listbase_is_empty(&tracking_camera_object->tracks)) {
435 tracking_camera_object->tracks = tracking.tracks_legacy;
436 active_tracking_object->active_track = tracking.act_track_legacy;
437 }
438
439 if (BLI_listbase_is_empty(&tracking_camera_object->plane_tracks)) {
440 tracking_camera_object->plane_tracks = tracking.plane_tracks_legacy;
441 active_tracking_object->active_plane_track = tracking.act_plane_track_legacy;
442 }
443
444 if (tracking_camera_object->reconstruction.cameras == nullptr) {
445 tracking_camera_object->reconstruction = tracking.reconstruction_legacy;
446 }
447
448 /* Clear pointers in the legacy storage.
449 * Always do it, in the case something got missed in the logic above, so that the legacy storage
450 * is always ensured to be empty after load. */
453 tracking.act_track_legacy = nullptr;
454 tracking.act_plane_track_legacy = nullptr;
456}
457
459{
460 LISTBASE_FOREACH (MovieClip *, movieclip, &bmain->movieclips) {
462 }
463}
464
466{
467 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
468 if (node->type_legacy == SH_NODE_BSDF_GLOSSY_LEGACY) {
469 STRNCPY_UTF8(node->idname, "ShaderNodeBsdfAnisotropic");
470 node->type_legacy = SH_NODE_BSDF_GLOSSY;
471 }
472 }
473}
474
476{
477 /* Find all glossy, glass and refraction BSDF nodes that have their distribution
478 * set to SHARP and set them to GGX, disconnect any link to the Roughness input
479 * and set its value to zero. */
480 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
482 {
483 continue;
484 }
485 if (node->custom1 != SHD_GLOSSY_SHARP_DEPRECATED) {
486 continue;
487 }
488
489 node->custom1 = SHD_GLOSSY_GGX;
490 LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
491 if (!STREQ(socket->identifier, "Roughness")) {
492 continue;
493 }
494
495 if (socket->link != nullptr) {
496 blender::bke::node_remove_link(ntree, *socket->link);
497 }
498 bNodeSocketValueFloat *socket_value = (bNodeSocketValueFloat *)socket->default_value;
499 socket_value->value = 0.0f;
500
501 break;
502 }
503 }
504}
505
507{
508 LISTBASE_FOREACH (Mesh *, mesh, &bmain.meshes) {
510 }
511
512 LISTBASE_FOREACH (bNodeTree *, ntree, &bmain.nodetrees) {
513 if (ntree->type == NTREE_GEOMETRY) {
514 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
515 if (STR_ELEM(node->idname,
516 "GeometryNodeStoreNamedAttribute",
517 "GeometryNodeInputNamedAttribute"))
518 {
519 bNodeSocket *socket = blender::bke::node_find_socket(*node, SOCK_IN, "Name");
520 if (STREQ(socket->default_value_typed<bNodeSocketValueString>()->value, "crease")) {
521 STRNCPY_UTF8(socket->default_value_typed<bNodeSocketValueString>()->value,
522 "crease_edge");
523 }
524 }
525 }
526 }
527 }
528
529 LISTBASE_FOREACH (Object *, object, &bmain.objects) {
530 LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
531 if (md->type != eModifierType_Nodes) {
532 continue;
533 }
534 if (IDProperty *settings = reinterpret_cast<NodesModifierData *>(md)->settings.properties) {
535 LISTBASE_FOREACH (IDProperty *, prop, &settings->data.group) {
536 if (blender::StringRef(prop->name).endswith("_attribute_name")) {
537 if (STREQ(IDP_string_get(prop), "crease")) {
538 IDP_AssignString(prop, "crease_edge");
539 }
540 }
541 }
542 }
543 }
544 }
545}
546
548{
549 /* The normal of a spot light was set to the incoming light direction, replace with the
550 * `Incoming` socket from the Geometry shader node. */
551 bNode *geometry_node = nullptr;
552 bNode *transform_node = nullptr;
553 bNodeSocket *incoming_socket = nullptr;
554 bNodeSocket *vec_in_socket = nullptr;
555 bNodeSocket *vec_out_socket = nullptr;
556
557 LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) {
558 if (link->fromnode->type_legacy == SH_NODE_TEX_COORD &&
559 STREQ(link->fromsock->identifier, "Normal"))
560 {
561 if (geometry_node == nullptr) {
562 geometry_node = blender::bke::node_add_static_node(nullptr, *ntree, SH_NODE_NEW_GEOMETRY);
563 incoming_socket = blender::bke::node_find_socket(*geometry_node, SOCK_OUT, "Incoming");
564
565 transform_node = blender::bke::node_add_static_node(
566 nullptr, *ntree, SH_NODE_VECT_TRANSFORM);
567 vec_in_socket = blender::bke::node_find_socket(*transform_node, SOCK_IN, "Vector");
568 vec_out_socket = blender::bke::node_find_socket(*transform_node, SOCK_OUT, "Vector");
569
570 NodeShaderVectTransform *nodeprop = (NodeShaderVectTransform *)transform_node->storage;
572
574 *ntree, *geometry_node, *incoming_socket, *transform_node, *vec_in_socket);
575 }
577 *ntree, *transform_node, *vec_out_socket, *link->tonode, *link->tosock);
578 blender::bke::node_remove_link(ntree, *link);
579 }
580 }
581}
582
583/* Version VertexWeightEdit modifier to make existing weights exclusive of the threshold. */
585{
586 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
587 if (ob->type != OB_MESH) {
588 continue;
589 }
590
591 LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
592 if (md->type == eModifierType_WeightVGEdit) {
593 WeightVGEditModifierData *wmd = reinterpret_cast<WeightVGEditModifierData *>(md);
594 wmd->add_threshold = nexttoward(wmd->add_threshold, 2.0);
595 wmd->rem_threshold = nexttoward(wmd->rem_threshold, -1.0);
596 }
597 }
598 }
599}
600
602{
603 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
604 if (node->type_legacy != SH_NODE_BSDF_PRINCIPLED) {
605 continue;
606 }
607 bNodeSocket *sock = blender::bke::node_find_socket(*node, SOCK_IN, "Transmission Roughness");
608 if (sock != nullptr) {
609 blender::bke::node_remove_socket(*ntree, *node, *sock);
610 }
611 }
612}
613
614/* Convert legacy Velvet BSDF nodes into the new Sheen BSDF node. */
616{
617 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
618 if (node->type_legacy == SH_NODE_BSDF_SHEEN) {
619 STRNCPY_UTF8(node->idname, "ShaderNodeBsdfSheen");
620
621 bNodeSocket *sigmaInput = blender::bke::node_find_socket(*node, SOCK_IN, "Sigma");
622 if (sigmaInput != nullptr) {
623 node->custom1 = SHD_SHEEN_ASHIKHMIN;
624 STRNCPY_UTF8(sigmaInput->identifier, "Roughness");
625 STRNCPY_UTF8(sigmaInput->name, "Roughness");
626 }
627 }
628 }
629}
630
631/* Convert sheen inputs on the Principled BSDF. */
633{
634 auto check_node = [](const bNode *node) {
635 return (node->type_legacy == SH_NODE_BSDF_PRINCIPLED) &&
636 (blender::bke::node_find_socket(*node, SOCK_IN, "Sheen Roughness") == nullptr);
637 };
638 auto update_input = [ntree](bNode *node, bNodeSocket *input) {
639 /* Change socket type to Color. */
641
642 /* Account for the change in intensity between the old and new model.
643 * If the Sheen input is set to a fixed value, adjust it and set the tint to white.
644 * Otherwise, if it's connected, keep it as-is but set the tint to 0.2 instead. */
646 if (sheen != nullptr && sheen->link == nullptr) {
648
649 static float default_value[] = {1.0f, 1.0f, 1.0f, 1.0f};
651 }
652 else {
653 static float default_value[] = {0.2f, 0.2f, 0.2f, 1.0f};
655 }
656 };
657 auto update_input_link = [](bNode *, bNodeSocket *, bNode *, bNodeSocket *) {
658 /* Don't replace the link here, tint works differently enough now to make conversion
659 * impractical. */
660 };
661
662 version_update_node_input(ntree, check_node, "Sheen Tint", update_input, update_input_link);
663}
664
665/* Replace old Principled Hair BSDF as a variant in the new Principled Hair BSDF. */
667{
668 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
669 if (node->type_legacy != SH_NODE_BSDF_HAIR_PRINCIPLED) {
670 continue;
671 }
674 data->parametrization = node->custom1;
675
676 node->storage = data;
677 }
678}
679
681 const eNodeSocketInOut in_out)
682{
685
686 /* Move reusable data. */
687 new_socket->name = BLI_strdup(legacy_socket.name);
688 new_socket->identifier = BLI_strdup(legacy_socket.identifier);
689 new_socket->description = BLI_strdup(legacy_socket.description);
690 /* If the socket idname includes a subtype (e.g. "NodeSocketFloatFactor") this will convert it to
691 * the base type name ("NodeSocketFloat"). */
692 new_socket->socket_type = BLI_strdup(
694 new_socket->flag = (in_out == SOCK_IN ? NODE_INTERFACE_SOCKET_INPUT :
697 new_socket->flag, legacy_socket.flag & SOCK_HIDE_VALUE, NODE_INTERFACE_SOCKET_HIDE_VALUE);
698 SET_FLAG_FROM_TEST(new_socket->flag,
699 legacy_socket.flag & SOCK_HIDE_IN_MODIFIER,
701 new_socket->attribute_domain = legacy_socket.attribute_domain;
702
703 /* The following data are stolen from the old data, the ownership of their memory is directly
704 * transferred to the new data. */
705 new_socket->default_attribute_name = legacy_socket.default_attribute_name;
706 legacy_socket.default_attribute_name = nullptr;
707 new_socket->socket_data = legacy_socket.default_value;
708 legacy_socket.default_value = nullptr;
709 new_socket->properties = legacy_socket.prop;
710 legacy_socket.prop = nullptr;
711
712 /* Unused data. */
713 MEM_delete(legacy_socket.runtime);
714 legacy_socket.runtime = nullptr;
715
716 return &new_socket->item;
717}
718
720{
721 bNodeTreeInterface &tree_interface = ntree->tree_interface;
722
723 const int num_inputs = BLI_listbase_count(&ntree->inputs_legacy);
724 const int num_outputs = BLI_listbase_count(&ntree->outputs_legacy);
725 tree_interface.root_panel.items_num = num_inputs + num_outputs;
727 size_t(tree_interface.root_panel.items_num), __func__);
728
729 /* Convert outputs first to retain old outputs/inputs ordering. */
730 int index;
731 LISTBASE_FOREACH_INDEX (bNodeSocket *, socket, &ntree->outputs_legacy, index) {
732 tree_interface.root_panel.items_array[index] = legacy_socket_move_to_interface(*socket,
733 SOCK_OUT);
734 }
735 LISTBASE_FOREACH_INDEX (bNodeSocket *, socket, &ntree->inputs_legacy, index) {
736 tree_interface.root_panel.items_array[num_outputs + index] = legacy_socket_move_to_interface(
737 *socket, SOCK_IN);
738 }
739}
740
741/* Convert coat inputs on the Principled BSDF. */
743{
744 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
745 if (node->type_legacy != SH_NODE_BSDF_PRINCIPLED) {
746 continue;
747 }
748 if (blender::bke::node_find_socket(*node, SOCK_IN, "Coat IOR") != nullptr) {
749 continue;
750 }
752 *ntree, *node, SOCK_IN, SOCK_FLOAT, PROP_NONE, "Coat IOR", "Coat IOR");
753
754 /* Adjust for 4x change in intensity. */
755 bNodeSocket *coat_input = blender::bke::node_find_socket(*node, SOCK_IN, "Clearcoat");
756 *version_cycles_node_socket_float_value(coat_input) *= 0.25f;
757 /* When the coat input is dynamic, instead of inserting a *0.25 math node, set the Coat IOR
758 * to 1.2 instead - this also roughly quarters reflectivity compared to the 1.5 default. */
759 *version_cycles_node_socket_float_value(coat_ior_input) = (coat_input->link) ? 1.2f : 1.5f;
760 }
761
762 /* Rename sockets. */
763 version_node_input_socket_name(ntree, SH_NODE_BSDF_PRINCIPLED, "Clearcoat", "Coat");
765 ntree, SH_NODE_BSDF_PRINCIPLED, "Clearcoat Roughness", "Coat Roughness");
767 ntree, SH_NODE_BSDF_PRINCIPLED, "Clearcoat Normal", "Coat Normal");
768}
769
770/* Convert subsurface inputs on the Principled BSDF. */
772{
773 /* - Create Subsurface Scale input
774 * - If a node's Subsurface input was connected or nonzero:
775 * - Make the Base Color a mix of old Base Color and Subsurface Color,
776 * using Subsurface as the mix factor
777 * - Move Subsurface link and default value to the new Subsurface Scale input
778 * - Set the Subsurface input to 1.0
779 * - Remove Subsurface Color input
780 */
781 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
782 if (node->type_legacy != SH_NODE_BSDF_PRINCIPLED) {
783 continue;
784 }
785 if (blender::bke::node_find_socket(*node, SOCK_IN, "Subsurface Scale")) {
786 /* Node is already updated. */
787 continue;
788 }
789
790 /* Add Scale input */
792 *ntree, *node, SOCK_IN, SOCK_FLOAT, PROP_DISTANCE, "Subsurface Scale", "Subsurface Scale");
793
794 bNodeSocket *subsurf = blender::bke::node_find_socket(*node, SOCK_IN, "Subsurface");
795 float *subsurf_val = version_cycles_node_socket_float_value(subsurf);
796
797 if (!subsurf->link && *subsurf_val == 0.0f) {
799 }
800 else {
801 *version_cycles_node_socket_float_value(scale_in) = *subsurf_val;
802 }
803
804 if (subsurf->link == nullptr && *subsurf_val == 0.0f) {
805 /* Node doesn't use Subsurf, we're done here. */
806 continue;
807 }
808
809 /* Fix up Subsurface Color input */
810 bNodeSocket *base_col = blender::bke::node_find_socket(*node, SOCK_IN, "Base Color");
811 bNodeSocket *subsurf_col = blender::bke::node_find_socket(*node, SOCK_IN, "Subsurface Color");
812 float *base_col_val = version_cycles_node_socket_rgba_value(base_col);
813 float *subsurf_col_val = version_cycles_node_socket_rgba_value(subsurf_col);
814 /* If any of the three inputs is dynamic, we need a Mix node. */
815 if (subsurf->link || subsurf_col->link || base_col->link) {
817 static_cast<NodeShaderMix *>(mix->storage)->data_type = SOCK_RGBA;
818 mix->locx_legacy = node->locx_legacy - 170;
819 mix->locy_legacy = node->locy_legacy - 120;
820
823 bNodeSocket *fac_in = blender::bke::node_find_socket(*mix, SOCK_IN, "Factor_Float");
824 bNodeSocket *result_out = blender::bke::node_find_socket(*mix, SOCK_OUT, "Result_Color");
825
828 *version_cycles_node_socket_float_value(fac_in) = *subsurf_val;
829
830 if (base_col->link) {
832 *ntree, *base_col->link->fromnode, *base_col->link->fromsock, *mix, *a_in);
833 blender::bke::node_remove_link(ntree, *base_col->link);
834 }
835 if (subsurf_col->link) {
837 *ntree, *subsurf_col->link->fromnode, *subsurf_col->link->fromsock, *mix, *b_in);
838 blender::bke::node_remove_link(ntree, *subsurf_col->link);
839 }
840 if (subsurf->link) {
842 *ntree, *subsurf->link->fromnode, *subsurf->link->fromsock, *mix, *fac_in);
844 *ntree, *subsurf->link->fromnode, *subsurf->link->fromsock, *node, *scale_in);
845 blender::bke::node_remove_link(ntree, *subsurf->link);
846 }
847 blender::bke::node_add_link(*ntree, *mix, *result_out, *node, *base_col);
848 }
849 /* Mix the fixed values. */
850 interp_v4_v4v4(base_col_val, base_col_val, subsurf_col_val, *subsurf_val);
851
852 /* Set node to 100% subsurface, 0% diffuse. */
853 *subsurf_val = 1.0f;
854
855 /* Delete Subsurface Color input */
856 blender::bke::node_remove_socket(*ntree, *node, *subsurf_col);
857 }
858}
859
860/* Convert emission inputs on the Principled BSDF. */
862{
863 /* Blender 3.x and before would default to Emission = 0.0, Emission Strength = 1.0.
864 * Now we default the other way around (1.0 and 0.0), but because the Strength input was added
865 * a bit later, a file that only has the Emission socket would now end up as (1.0, 0.0) instead
866 * of (1.0, 1.0).
867 * Therefore, set strength to 1.0 for those files.
868 */
869 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
870 if (node->type_legacy != SH_NODE_BSDF_PRINCIPLED) {
871 continue;
872 }
873 if (!blender::bke::node_find_socket(*node, SOCK_IN, "Emission")) {
874 /* Old enough to have neither, new defaults are fine. */
875 continue;
876 }
877 if (blender::bke::node_find_socket(*node, SOCK_IN, "Emission Strength")) {
878 /* New enough to have both, no need to do anything. */
879 continue;
880 }
882 *ntree, *node, SOCK_IN, SOCK_FLOAT, PROP_NONE, "Emission Strength", "Emission Strength");
884 }
885}
886
888 const bNodeTreeInterfaceSocket &src,
889 char *identifier)
890{
891 /* Node socket copy function based on bNodeTreeInterface::item_copy to avoid using blenkernel. */
892 dst.name = BLI_strdup_null(src.name);
896 dst.identifier = identifier;
897 if (src.properties) {
899 }
900 if (src.socket_data != nullptr) {
902 /* No user count increment needed, gets reset after versioning. */
903 }
904}
905
907 const bNodeTreeInterfaceItem &item,
908 const int initial_pos)
909{
910 const bool sockets_above_panels = !(panel.flag &
913
914 int pos = initial_pos;
915
916 if (sockets_above_panels) {
917 if (item.item_type == NODE_INTERFACE_PANEL) {
918 /* Find the closest valid position from the end, only panels at or after #position. */
919 for (int test_pos = items.size() - 1; test_pos >= initial_pos; test_pos--) {
920 if (test_pos < 0) {
921 /* Initial position is out of range but valid. */
922 break;
923 }
924 if (items[test_pos]->item_type != NODE_INTERFACE_PANEL) {
925 /* Found valid position, insert after the last socket item. */
926 pos = test_pos + 1;
927 break;
928 }
929 }
930 }
931 else {
932 /* Find the closest valid position from the start, no panels at or after #position. */
933 for (int test_pos = 0; test_pos <= initial_pos; test_pos++) {
934 if (test_pos >= items.size()) {
935 /* Initial position is out of range but valid. */
936 break;
937 }
938 if (items[test_pos]->item_type == NODE_INTERFACE_PANEL) {
939 /* Found valid position, inserting moves the first panel. */
940 pos = test_pos;
941 break;
942 }
943 }
944 }
945 }
946
947 return pos;
948}
949
952 int position)
953{
954 /* Apply any constraints on the item positions. */
955 position = version_nodes_find_valid_insert_position_for_item(parent, socket.item, position);
956 position = std::min(std::max(position, 0), parent.items_num);
957
959 parent.items_num};
960 parent.items_num++;
962 parent.items().take_front(position).copy_from(old_items.take_front(position));
963 parent.items().drop_front(position + 1).copy_from(old_items.drop_front(position));
964 parent.items()[position] = &socket.item;
965
966 if (old_items.data()) {
967 MEM_freeN(old_items.data());
968 }
969}
970
971/* Node group interface copy function based on bNodeTreeInterface::insert_item_copy. */
975 int position)
976{
977 if (parent == nullptr) {
978 parent = &tree_interface.root_panel;
979 }
980
981 bNodeTreeInterfaceSocket *csocket = static_cast<bNodeTreeInterfaceSocket *>(
982 MEM_dupallocN(&socket));
983 /* Generate a new unique identifier.
984 * This might break existing links, but the identifiers were duplicate anyway. */
985 char *dst_identifier = BLI_sprintfN("Socket_%d", tree_interface.next_uid++);
986 version_copy_socket(*csocket, socket, dst_identifier);
987
988 version_nodes_insert_item(*parent, *csocket, position);
989
990 /* Original socket becomes output. */
992 /* Copied socket becomes input. */
994}
995
997{
998 /* True if item a should be above item b. */
999 auto item_compare = [](const bNodeTreeInterfaceItem *a,
1000 const bNodeTreeInterfaceItem *b) -> bool {
1001 if (a->item_type != b->item_type) {
1002 /* Keep sockets above panels. */
1003 return a->item_type == NODE_INTERFACE_SOCKET;
1004 }
1005 /* Keep outputs above inputs. */
1006 if (a->item_type == NODE_INTERFACE_SOCKET) {
1007 const bNodeTreeInterfaceSocket *sa = reinterpret_cast<const bNodeTreeInterfaceSocket *>(a);
1008 const bNodeTreeInterfaceSocket *sb = reinterpret_cast<const bNodeTreeInterfaceSocket *>(b);
1009 const bool is_output_a = sa->flag & NODE_INTERFACE_SOCKET_OUTPUT;
1010 const bool is_output_b = sb->flag & NODE_INTERFACE_SOCKET_OUTPUT;
1011 if (is_output_a != is_output_b) {
1012 return is_output_a;
1013 }
1014 }
1015
1016 return false;
1017 };
1018
1019 /* Sort panel content. */
1020 std::stable_sort(panel.items().begin(), panel.items().end(), item_compare);
1021
1022 /* Sort any child panels too. */
1023 for (bNodeTreeInterfaceItem *item : panel.items()) {
1024 if (item->item_type == NODE_INTERFACE_PANEL) {
1026 *reinterpret_cast<bNodeTreeInterfacePanel *>(item));
1027 }
1028 }
1029}
1030
1031/* Convert specular tint in Principled BSDF. */
1033{
1034 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
1035 if (node->type_legacy != SH_NODE_BSDF_PRINCIPLED) {
1036 continue;
1037 }
1038 bNodeSocket *specular_tint_sock = blender::bke::node_find_socket(
1039 *node, SOCK_IN, "Specular Tint");
1040 if (specular_tint_sock->type == SOCK_RGBA) {
1041 /* Node is already updated. */
1042 continue;
1043 }
1044
1045 bNodeSocket *base_color_sock = blender::bke::node_find_socket(*node, SOCK_IN, "Base Color");
1046 bNodeSocket *metallic_sock = blender::bke::node_find_socket(*node, SOCK_IN, "Metallic");
1047 float specular_tint_old = *version_cycles_node_socket_float_value(specular_tint_sock);
1048 float *base_color = version_cycles_node_socket_rgba_value(base_color_sock);
1049 float metallic = *version_cycles_node_socket_float_value(metallic_sock);
1050
1051 /* Change socket type to Color. */
1052 blender::bke::node_modify_socket_type_static(ntree, node, specular_tint_sock, SOCK_RGBA, 0);
1053 float *specular_tint = version_cycles_node_socket_rgba_value(specular_tint_sock);
1054
1055 /* The conversion logic here is that the new Specular Tint should be
1056 * mix(one, mix(base_color, one, metallic), old_specular_tint).
1057 * This needs to be handled both for the fixed values, as well as for any potential connected
1058 * inputs. */
1059
1060 static float one[] = {1.0f, 1.0f, 1.0f, 1.0f};
1061
1062 /* Mix the fixed values. */
1063 float metallic_mix[4];
1064 interp_v4_v4v4(metallic_mix, base_color, one, metallic);
1065 interp_v4_v4v4(specular_tint, one, metallic_mix, specular_tint_old);
1066
1067 if (specular_tint_sock->link == nullptr && specular_tint_old <= 0.0f) {
1068 /* Specular Tint was fixed at zero, we don't need any conversion node setup. */
1069 continue;
1070 }
1071
1072 /* If the Metallic input is dynamic, or fixed > 0 and base color is dynamic,
1073 * we need to insert a node to compute the metallic_mix.
1074 * Otherwise, use whatever is connected to the base color, or the static value
1075 * if it's unconnected. */
1076 bNodeSocket *metallic_mix_out = nullptr;
1077 bNode *metallic_mix_node = nullptr;
1078 if (metallic_sock->link || (base_color_sock->link && metallic > 0.0f)) {
1079 /* Metallic Mix needs to be dynamically mixed. */
1081 static_cast<NodeShaderMix *>(mix->storage)->data_type = SOCK_RGBA;
1082 mix->locx_legacy = node->locx_legacy - 270;
1083 mix->locy_legacy = node->locy_legacy - 120;
1084
1087 bNodeSocket *fac_in = blender::bke::node_find_socket(*mix, SOCK_IN, "Factor_Float");
1088 metallic_mix_out = blender::bke::node_find_socket(*mix, SOCK_OUT, "Result_Color");
1089 metallic_mix_node = mix;
1090
1092 if (base_color_sock->link) {
1094 *base_color_sock->link->fromnode,
1095 *base_color_sock->link->fromsock,
1096 *mix,
1097 *a_in);
1098 }
1100 *version_cycles_node_socket_float_value(fac_in) = metallic;
1101 if (metallic_sock->link) {
1103 *ntree, *metallic_sock->link->fromnode, *metallic_sock->link->fromsock, *mix, *fac_in);
1104 }
1105 }
1106 else if (base_color_sock->link) {
1107 /* Metallic Mix is a no-op and equivalent to Base Color. */
1108 metallic_mix_out = base_color_sock->link->fromsock;
1109 metallic_mix_node = base_color_sock->link->fromnode;
1110 }
1111
1112 /* Similar to above, if the Specular Tint input is dynamic, or fixed > 0 and metallic mix
1113 * is dynamic, we need to insert a node to compute the new specular tint. */
1114 if (specular_tint_sock->link || (metallic_mix_out && specular_tint_old > 0.0f)) {
1116 static_cast<NodeShaderMix *>(mix->storage)->data_type = SOCK_RGBA;
1117 mix->locx_legacy = node->locx_legacy - 170;
1118 mix->locy_legacy = node->locy_legacy - 120;
1119
1122 bNodeSocket *fac_in = blender::bke::node_find_socket(*mix, SOCK_IN, "Factor_Float");
1123 bNodeSocket *result_out = blender::bke::node_find_socket(*mix, SOCK_OUT, "Result_Color");
1124
1127 if (metallic_mix_out) {
1128 blender::bke::node_add_link(*ntree, *metallic_mix_node, *metallic_mix_out, *mix, *b_in);
1129 }
1130 *version_cycles_node_socket_float_value(fac_in) = specular_tint_old;
1131 if (specular_tint_sock->link) {
1133 *specular_tint_sock->link->fromnode,
1134 *specular_tint_sock->link->fromsock,
1135 *mix,
1136 *fac_in);
1137 blender::bke::node_remove_link(ntree, *specular_tint_sock->link);
1138 }
1139 blender::bke::node_add_link(*ntree, *mix, *result_out, *node, *specular_tint_sock);
1140 }
1141 }
1142}
1143
1144/* Rename various Principled BSDF sockets. */
1146{
1147 version_node_input_socket_name(ntree, SH_NODE_BSDF_PRINCIPLED, "Emission", "Emission Color");
1148 version_node_input_socket_name(ntree, SH_NODE_BSDF_PRINCIPLED, "Specular", "Specular IOR Level");
1150 ntree, SH_NODE_BSDF_PRINCIPLED, "Subsurface", "Subsurface Weight");
1152 ntree, SH_NODE_BSDF_PRINCIPLED, "Transmission", "Transmission Weight");
1153 version_node_input_socket_name(ntree, SH_NODE_BSDF_PRINCIPLED, "Coat", "Coat Weight");
1154 version_node_input_socket_name(ntree, SH_NODE_BSDF_PRINCIPLED, "Sheen", "Sheen Weight");
1155}
1156
1158{
1159 /* Any node group with a first socket geometry output can potentially be a modifier. Previously
1160 * this wasn't an explicit option, so better to enable too many groups rather than too few. */
1161 LISTBASE_FOREACH (bNodeTree *, group, &bmain.nodetrees) {
1162 if (group->type != NTREE_GEOMETRY) {
1163 continue;
1164 }
1165 group->tree_interface.foreach_item([&](const bNodeTreeInterfaceItem &item) {
1166 if (item.item_type != NODE_INTERFACE_SOCKET) {
1167 return true;
1168 }
1169 const auto &socket = reinterpret_cast<const bNodeTreeInterfaceSocket &>(item);
1170 if ((socket.flag & NODE_INTERFACE_SOCKET_OUTPUT) == 0) {
1171 return true;
1172 }
1173 if (!STREQ(socket.socket_type, "NodeSocketGeometry")) {
1174 return true;
1175 }
1176 if (!group->geometry_node_asset_traits) {
1177 group->geometry_node_asset_traits = MEM_callocN<GeometryNodeAssetTraits>(__func__);
1178 }
1179 group->geometry_node_asset_traits->flag |= GEO_NODE_ASSET_MODIFIER;
1180 return false;
1181 });
1182 }
1183}
1184
1185void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
1186{
1187 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 1)) {
1188 LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) {
1190 }
1192 }
1193
1194 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 2)) {
1195 LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) {
1197 }
1198 }
1199
1200 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 5)) {
1201 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1202 ToolSettings *ts = scene->toolsettings;
1203 if (ts->snap_mode_tools != SCE_SNAP_TO_NONE) {
1205 }
1206
1207#define SCE_SNAP_PROJECT (1 << 3)
1208 if (ts->snap_flag & SCE_SNAP_PROJECT) {
1209 ts->snap_mode &= ~(1 << 2); /* SCE_SNAP_TO_FACE */
1210 ts->snap_mode |= (1 << 8); /* SCE_SNAP_INDIVIDUAL_PROJECT */
1211 }
1212#undef SCE_SNAP_PROJECT
1213 }
1214 }
1215
1216 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 6)) {
1217 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1220 }
1222 }
1223
1224 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 7)) {
1226 }
1227
1228 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 8)) {
1229 LISTBASE_FOREACH (bAction *, act, &bmain->actions) {
1230 act->frame_start = max_ff(act->frame_start, MINAFRAMEF);
1231 act->frame_end = min_ff(act->frame_end, MAXFRAMEF);
1232 }
1233 }
1234
1235 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 9)) {
1236 LISTBASE_FOREACH (Light *, light, &bmain->lights) {
1237 if (light->type == LA_SPOT && light->nodetree) {
1239 }
1240 }
1241 }
1242
1243 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 10)) {
1244 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1245 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1246 LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) {
1247 if (space->spacetype == SPACE_NODE) {
1248 SpaceNode *snode = reinterpret_cast<SpaceNode *>(space);
1250 }
1251 }
1252 }
1253 }
1254 }
1255
1256 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 11)) {
1258 }
1259
1260 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 12)) {
1261 if (!DNA_struct_member_exists(fd->filesdna, "LightProbe", "int", "grid_bake_samples")) {
1262 LISTBASE_FOREACH (LightProbe *, lightprobe, &bmain->lightprobes) {
1263 lightprobe->grid_bake_samples = 2048;
1264 lightprobe->grid_normal_bias = 0.3f;
1265 lightprobe->grid_view_bias = 0.0f;
1266 lightprobe->grid_facing_bias = 0.5f;
1267 lightprobe->grid_dilation_threshold = 0.5f;
1268 lightprobe->grid_dilation_radius = 1.0f;
1269 }
1270 }
1271
1272 /* Set default bake resolution. */
1273 if (!DNA_struct_member_exists(fd->filesdna, "World", "int", "probe_resolution")) {
1274 LISTBASE_FOREACH (World *, world, &bmain->worlds) {
1275 world->probe_resolution = LIGHT_PROBE_RESOLUTION_1024;
1276 }
1277 }
1278
1279 if (!DNA_struct_member_exists(fd->filesdna, "LightProbe", "float", "grid_surface_bias")) {
1280 LISTBASE_FOREACH (LightProbe *, lightprobe, &bmain->lightprobes) {
1281 lightprobe->grid_surface_bias = 0.05f;
1282 lightprobe->grid_escape_bias = 0.1f;
1283 }
1284 }
1285
1286 /* Clear removed "Z Buffer" flag. */
1287 {
1288 const int R_IMF_FLAG_ZBUF_LEGACY = 1 << 0;
1289 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1290 scene->r.im_format.flag &= ~R_IMF_FLAG_ZBUF_LEGACY;
1291 }
1292 }
1293
1294 /* Reset the layer opacity for all layers to 1. */
1295 LISTBASE_FOREACH (GreasePencil *, grease_pencil, &bmain->grease_pencils) {
1296 for (blender::bke::greasepencil::Layer *layer : grease_pencil->layers_for_write()) {
1297 layer->opacity = 1.0f;
1298 }
1299 }
1300
1301 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1302 if (ntree->type == NTREE_SHADER) {
1303 /* Remove Transmission Roughness from Principled BSDF. */
1305 /* Convert legacy Velvet BSDF nodes into the new Sheen BSDF node. */
1307 /* Convert sheen inputs on the Principled BSDF. */
1309 }
1310 }
1312
1313 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1314 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1315 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1316 ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
1317 &sl->regionbase;
1318
1319 /* Layout based regions used to also disallow resizing, now these are separate flags.
1320 * Make sure they are set together for old regions. */
1321 LISTBASE_FOREACH (ARegion *, region, regionbase) {
1322 if (region->flag & RGN_FLAG_DYNAMIC_SIZE) {
1323 region->flag |= RGN_FLAG_NO_USER_RESIZE;
1324 }
1325 }
1326 }
1327 }
1328 }
1329 }
1330
1331 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 13)) {
1332 /* For the scenes configured to use the "None" display disable the color management
1333 * again. This will handle situation when the "None" display is removed and is replaced with
1334 * a "Raw" view instead.
1335 *
1336 * Note that this versioning will do nothing if the "None" display exists in the OCIO
1337 * configuration. */
1338 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1339 const ColorManagedDisplaySettings &display_settings = scene->display_settings;
1340 if (STREQ(display_settings.display_device, "None")) {
1342 }
1343 }
1344 }
1345
1346 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 14)) {
1347 if (!DNA_struct_member_exists(fd->filesdna, "SceneEEVEE", "int", "ray_tracing_method")) {
1348 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1349 scene->eevee.ray_tracing_method = RAYTRACE_EEVEE_METHOD_SCREEN;
1350 }
1351 }
1352
1353 if (!DNA_struct_exists(fd->filesdna, "RegionAssetShelf")) {
1354 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1355 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1356 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1357 if (sl->spacetype != SPACE_VIEW3D) {
1358 continue;
1359 }
1360
1361 ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
1362 &sl->regionbase;
1363
1364 if (ARegion *new_shelf_region = do_versions_add_region_if_not_found(
1365 regionbase,
1367 "asset shelf for view3d (versioning)",
1369 {
1370 new_shelf_region->alignment = RGN_ALIGN_BOTTOM;
1371 }
1372 if (ARegion *new_shelf_header = do_versions_add_region_if_not_found(
1373 regionbase,
1375 "asset shelf header for view3d (versioning)",
1377 {
1378 new_shelf_header->alignment = RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV;
1379 }
1380 }
1381 }
1382 }
1383 }
1384 }
1385
1386 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 16)) {
1387 /* Set Normalize property of Noise Texture node to true. */
1388 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1389 if (ntree->type != NTREE_CUSTOM) {
1390 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
1391 if (node->type_legacy == SH_NODE_TEX_NOISE) {
1392 if (!node->storage) {
1393 NodeTexNoise *tex = MEM_callocN<NodeTexNoise>(__func__);
1396 tex->dimensions = 3;
1397 tex->type = SHD_NOISE_FBM;
1398 node->storage = tex;
1399 }
1400 ((NodeTexNoise *)node->storage)->normalize = true;
1401 }
1402 }
1403 }
1404 }
1406 }
1407
1408 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 17)) {
1409 if (!DNA_struct_exists(fd->filesdna, "NodeShaderHairPrincipled")) {
1410 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1411 if (ntree->type == NTREE_SHADER) {
1413 }
1414 }
1416 }
1417
1418 /* Panorama properties shared with Eevee. */
1419 if (!DNA_struct_member_exists(fd->filesdna, "Camera", "float", "fisheye_fov")) {
1420 Camera default_cam = *DNA_struct_default_get(Camera);
1421 LISTBASE_FOREACH (Camera *, camera, &bmain->cameras) {
1422 IDProperty *ccam = version_cycles_properties_from_ID(&camera->id);
1423 if (ccam) {
1424 camera->panorama_type = version_cycles_property_int(
1425 ccam, "panorama_type", default_cam.panorama_type);
1426 camera->fisheye_fov = version_cycles_property_float(
1427 ccam, "fisheye_fov", default_cam.fisheye_fov);
1428 camera->fisheye_lens = version_cycles_property_float(
1429 ccam, "fisheye_lens", default_cam.fisheye_lens);
1430 camera->latitude_min = version_cycles_property_float(
1431 ccam, "latitude_min", default_cam.latitude_min);
1432 camera->latitude_max = version_cycles_property_float(
1433 ccam, "latitude_max", default_cam.latitude_max);
1434 camera->longitude_min = version_cycles_property_float(
1435 ccam, "longitude_min", default_cam.longitude_min);
1436 camera->longitude_max = version_cycles_property_float(
1437 ccam, "longitude_max", default_cam.longitude_max);
1438 /* Fit to match default projective camera with focal_length 50 and sensor_width 36. */
1439 camera->fisheye_polynomial_k0 = version_cycles_property_float(
1440 ccam, "fisheye_polynomial_k0", default_cam.fisheye_polynomial_k0);
1441 camera->fisheye_polynomial_k1 = version_cycles_property_float(
1442 ccam, "fisheye_polynomial_k1", default_cam.fisheye_polynomial_k1);
1443 camera->fisheye_polynomial_k2 = version_cycles_property_float(
1444 ccam, "fisheye_polynomial_k2", default_cam.fisheye_polynomial_k2);
1445 camera->fisheye_polynomial_k3 = version_cycles_property_float(
1446 ccam, "fisheye_polynomial_k3", default_cam.fisheye_polynomial_k3);
1447 camera->fisheye_polynomial_k4 = version_cycles_property_float(
1448 ccam, "fisheye_polynomial_k4", default_cam.fisheye_polynomial_k4);
1449 }
1450 else {
1451 camera->panorama_type = default_cam.panorama_type;
1452 camera->fisheye_fov = default_cam.fisheye_fov;
1453 camera->fisheye_lens = default_cam.fisheye_lens;
1454 camera->latitude_min = default_cam.latitude_min;
1455 camera->latitude_max = default_cam.latitude_max;
1456 camera->longitude_min = default_cam.longitude_min;
1457 camera->longitude_max = default_cam.longitude_max;
1458 /* Fit to match default projective camera with focal_length 50 and sensor_width 36. */
1459 camera->fisheye_polynomial_k0 = default_cam.fisheye_polynomial_k0;
1460 camera->fisheye_polynomial_k1 = default_cam.fisheye_polynomial_k1;
1461 camera->fisheye_polynomial_k2 = default_cam.fisheye_polynomial_k2;
1462 camera->fisheye_polynomial_k3 = default_cam.fisheye_polynomial_k3;
1463 camera->fisheye_polynomial_k4 = default_cam.fisheye_polynomial_k4;
1464 }
1465 }
1466 }
1467
1468 if (!DNA_struct_member_exists(fd->filesdna, "LightProbe", "float", "grid_flag")) {
1469 LISTBASE_FOREACH (LightProbe *, lightprobe, &bmain->lightprobes) {
1470 /* Keep old behavior of baking the whole lighting. */
1473 }
1474 }
1475
1476 if (!DNA_struct_member_exists(fd->filesdna, "SceneEEVEE", "int", "gi_irradiance_pool_size")) {
1477 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1478 scene->eevee.gi_irradiance_pool_size = 16;
1479 }
1480 }
1481
1482 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1483 scene->toolsettings->snap_flag_anim |= SCE_SNAP;
1484 scene->toolsettings->snap_anim_mode |= (1 << 10); /* SCE_SNAP_TO_FRAME */
1485 }
1486 }
1487
1488 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 20)) {
1489 /* Convert old socket lists into new interface items. */
1490 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1492 /* Clear legacy sockets after conversion.
1493 * Internal data pointers have been moved or freed already. */
1494 BLI_freelistN(&ntree->inputs_legacy);
1495 BLI_freelistN(&ntree->outputs_legacy);
1496 }
1498 }
1499 else {
1500 /* Legacy node tree sockets are created for forward compatibility,
1501 * but have to be freed after loading and versioning. */
1502 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1503 LISTBASE_FOREACH_MUTABLE (bNodeSocket *, legacy_socket, &ntree->inputs_legacy) {
1504 MEM_SAFE_FREE(legacy_socket->default_attribute_name);
1505 MEM_SAFE_FREE(legacy_socket->default_value);
1506 if (legacy_socket->prop) {
1507 IDP_FreeProperty(legacy_socket->prop);
1508 }
1509 MEM_delete(legacy_socket->runtime);
1510 MEM_freeN(legacy_socket);
1511 }
1512 LISTBASE_FOREACH_MUTABLE (bNodeSocket *, legacy_socket, &ntree->outputs_legacy) {
1513 MEM_SAFE_FREE(legacy_socket->default_attribute_name);
1514 MEM_SAFE_FREE(legacy_socket->default_value);
1515 if (legacy_socket->prop) {
1516 IDP_FreeProperty(legacy_socket->prop);
1517 }
1518 MEM_delete(legacy_socket->runtime);
1519 MEM_freeN(legacy_socket);
1520 }
1521 BLI_listbase_clear(&ntree->inputs_legacy);
1522 BLI_listbase_clear(&ntree->outputs_legacy);
1523 }
1525 }
1526
1527 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 22)) {
1528 /* Initialize root panel flags in files created before these flags were added. */
1529 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1530 ntree->tree_interface.root_panel.flag |= NODE_INTERFACE_PANEL_ALLOW_CHILD_PANELS_LEGACY;
1531 }
1533 }
1534
1535 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 23)) {
1536 LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
1537 if (ntree->type == NTREE_GEOMETRY) {
1538 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
1539 if (node->type_legacy == GEO_NODE_SET_SHADE_SMOOTH) {
1540 node->custom1 = int8_t(blender::bke::AttrDomain::Face);
1541 }
1542 }
1543 }
1544 }
1545 }
1546
1547 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 24)) {
1548 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1549 if (ntree->type == NTREE_SHADER) {
1550 /* Convert coat inputs on the Principled BSDF. */
1552 /* Convert subsurface inputs on the Principled BSDF. */
1554 /* Convert emission on the Principled BSDF. */
1556 }
1557 }
1559
1560 {
1561 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1562 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1563 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1564 const ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
1565 &sl->regionbase;
1566 LISTBASE_FOREACH (ARegion *, region, regionbase) {
1567 if (region->regiontype != RGN_TYPE_ASSET_SHELF) {
1568 continue;
1569 }
1570
1571 RegionAssetShelf *shelf_data = static_cast<RegionAssetShelf *>(region->regiondata);
1572 if (shelf_data && shelf_data->active_shelf &&
1573 (shelf_data->active_shelf->preferred_row_count == 0))
1574 {
1575 shelf_data->active_shelf->preferred_row_count = 1;
1576 }
1577 }
1578 }
1579 }
1580 }
1581 }
1582
1583 /* Convert sockets with both input and output flag into two separate sockets. */
1584 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1586 ntree->tree_interface.foreach_item([&](bNodeTreeInterfaceItem &item) {
1587 if (item.item_type == NODE_INTERFACE_SOCKET) {
1588 bNodeTreeInterfaceSocket &socket = reinterpret_cast<bNodeTreeInterfaceSocket &>(item);
1589 if ((socket.flag & NODE_INTERFACE_SOCKET_INPUT) &&
1591 {
1592 sockets_to_split.append(&socket);
1593 }
1594 }
1595 return true;
1596 });
1597
1598 for (bNodeTreeInterfaceSocket *socket : sockets_to_split) {
1599 const int position = ntree->tree_interface.find_item_position(socket->item);
1600 bNodeTreeInterfacePanel *parent = ntree->tree_interface.find_item_parent(socket->item);
1601 version_node_group_split_socket(ntree->tree_interface, *socket, parent, position + 1);
1602 }
1603 }
1605 }
1606
1607 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 25)) {
1608 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1609 if (ntree->type == NTREE_SHADER) {
1610 /* Convert specular tint on the Principled BSDF. */
1612 /* Rename some sockets. */
1614 }
1615 }
1617 }
1618
1619 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 26)) {
1621
1622 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1623 scene->simulation_frame_start = scene->r.sfra;
1624 scene->simulation_frame_end = scene->r.efra;
1625 }
1626 }
1627
1628 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 27)) {
1629 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1630 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1631 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1632 if (sl->spacetype == SPACE_SEQ) {
1633 SpaceSeq *sseq = (SpaceSeq *)sl;
1635 }
1636 }
1637 }
1638 }
1639
1640 if (!DNA_struct_member_exists(fd->filesdna, "SceneEEVEE", "int", "shadow_step_count")) {
1641 SceneEEVEE default_scene_eevee = *DNA_struct_default_get(SceneEEVEE);
1642 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1643 scene->eevee.shadow_ray_count = default_scene_eevee.shadow_ray_count;
1644 scene->eevee.shadow_step_count = default_scene_eevee.shadow_step_count;
1645 }
1646 }
1647 }
1648
1649 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 28)) {
1650 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1651 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1652 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1653 const ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
1654 &sl->regionbase;
1655 LISTBASE_FOREACH (ARegion *, region, regionbase) {
1656 if (region->regiontype != RGN_TYPE_ASSET_SHELF) {
1657 continue;
1658 }
1659
1660 RegionAssetShelf *shelf_data = static_cast<RegionAssetShelf *>(region->regiondata);
1661 if (shelf_data && shelf_data->active_shelf) {
1662 AssetShelfSettings &settings = shelf_data->active_shelf->settings;
1665 }
1666
1667 region->flag |= RGN_FLAG_HIDDEN;
1668 }
1669 }
1670 }
1671 }
1672 }
1673
1674 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 29)) {
1675 /* Unhide all Reroute nodes. */
1676 FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1677 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
1678 if (node->is_reroute()) {
1679 static_cast<bNodeSocket *>(node->inputs.first)->flag &= ~SOCK_HIDDEN;
1680 static_cast<bNodeSocket *>(node->outputs.first)->flag &= ~SOCK_HIDDEN;
1681 }
1682 }
1683 }
1685 }
1686
1687 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 30)) {
1688 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1689 ToolSettings *ts = scene->toolsettings;
1690 enum { IS_DEFAULT = 0, IS_UV, IS_NODE, IS_ANIM };
1691 auto versioning_snap_to = [](short snap_to_old, int type) {
1692 eSnapMode snap_to_new = SCE_SNAP_TO_NONE;
1693 if (snap_to_old & (1 << 0)) {
1694 snap_to_new |= type == IS_NODE ? SCE_SNAP_TO_NONE :
1695 type == IS_ANIM ? SCE_SNAP_TO_FRAME :
1697 }
1698 if (snap_to_old & (1 << 1)) {
1699 snap_to_new |= type == IS_NODE ? SCE_SNAP_TO_NONE :
1700 type == IS_ANIM ? SCE_SNAP_TO_SECOND :
1702 }
1703 if (ELEM(type, IS_DEFAULT, IS_ANIM) && snap_to_old & (1 << 2)) {
1704 snap_to_new |= type == IS_DEFAULT ? SCE_SNAP_TO_FACE : SCE_SNAP_TO_MARKERS;
1705 }
1706 if (type == IS_DEFAULT && snap_to_old & (1 << 3)) {
1707 snap_to_new |= SCE_SNAP_TO_VOLUME;
1708 }
1709 if (type == IS_DEFAULT && snap_to_old & (1 << 4)) {
1710 snap_to_new |= SCE_SNAP_TO_EDGE_MIDPOINT;
1711 }
1712 if (type == IS_DEFAULT && snap_to_old & (1 << 5)) {
1713 snap_to_new |= SCE_SNAP_TO_EDGE_PERPENDICULAR;
1714 }
1715 if (ELEM(type, IS_DEFAULT, IS_UV, IS_NODE) && snap_to_old & (1 << 6)) {
1716 snap_to_new |= SCE_SNAP_TO_INCREMENT;
1717 }
1718 if (ELEM(type, IS_DEFAULT, IS_UV, IS_NODE) && snap_to_old & (1 << 7)) {
1719 snap_to_new |= SCE_SNAP_TO_GRID;
1720 }
1721 if (type == IS_DEFAULT && snap_to_old & (1 << 8)) {
1722 snap_to_new |= SCE_SNAP_INDIVIDUAL_NEAREST;
1723 }
1724 if (type == IS_DEFAULT && snap_to_old & (1 << 9)) {
1725 snap_to_new |= SCE_SNAP_INDIVIDUAL_PROJECT;
1726 }
1727 if (snap_to_old & (1 << 10)) {
1728 snap_to_new |= SCE_SNAP_TO_FRAME;
1729 }
1730 if (snap_to_old & (1 << 11)) {
1731 snap_to_new |= SCE_SNAP_TO_SECOND;
1732 }
1733 if (snap_to_old & (1 << 12)) {
1734 snap_to_new |= SCE_SNAP_TO_MARKERS;
1735 }
1736
1737 if (!snap_to_new) {
1738 snap_to_new = eSnapMode(1 << 0);
1739 }
1740
1741 return snap_to_new;
1742 };
1743
1744 ts->snap_mode = versioning_snap_to(ts->snap_mode, IS_DEFAULT);
1745 ts->snap_uv_mode = versioning_snap_to(ts->snap_uv_mode, IS_UV);
1746 ts->snap_node_mode = versioning_snap_to(ts->snap_node_mode, IS_NODE);
1747 ts->snap_anim_mode = versioning_snap_to(ts->snap_anim_mode, IS_ANIM);
1748 }
1749 }
1750
1751 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 31)) {
1752 LISTBASE_FOREACH (Curve *, curve, &bmain->curves) {
1753 /* No need to check the curves type, this will be null for non text curves. */
1754 if (CharInfo *info = curve->strinfo) {
1755 for (int i = curve->len_char32 - 1; i >= 0; i--, info++) {
1756 if (info->mat_nr > 0) {
1758 info->mat_nr--;
1759 }
1760 }
1761 }
1762 }
1763 }
1764
1765 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 33)) {
1766 /* Fix node group socket order by sorting outputs and inputs. */
1767 LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
1768 versioning_node_group_sort_sockets_recursive(ntree->tree_interface.root_panel);
1769 }
1770 }
1771}
Iterators for armatures.
C++ functions to deal with Armature collections (i.e. the successor of bone layers).
void ANIM_bonecoll_hide(bArmature *armature, BoneCollection *bcoll)
bool ANIM_armature_bonecoll_assign(BoneCollection *bcoll, Bone *bone)
BoneCollection * ANIM_armature_bonecoll_new(bArmature *armature, const char *name, int parent_index=-1)
AnimData * BKE_animdata_from_id(const ID *id)
Definition anim_data.cc:83
void BKE_animdata_fix_paths_rename(struct ID *owner_id, struct AnimData *adt, struct ID *ref_id, const char *prefix, const char *oldName, const char *newName, int oldSubscript, int newSubscript, bool verify_paths)
bool BKE_animdata_fix_paths_remove(struct ID *id, const char *prefix)
void BKE_pose_ensure(Main *bmain, Object *ob, bArmature *arm, bool do_id_user)
struct EffectorWeights * BKE_effector_add_weights(struct Collection *collection)
Definition effect.cc:58
Low-level operations for grease pencil.
IDProperty * IDP_GetPropertyFromGroup(const IDProperty *prop, blender::StringRef name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:747
void IDP_AssignString(IDProperty *prop, const char *st) ATTR_NONNULL()
Definition idprop.cc:439
void IDP_FreeProperty(IDProperty *prop)
Definition idprop.cc:1251
#define IDP_string_get(prop)
IDProperty * IDP_CopyProperty_ex(const IDProperty *prop, int flag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:845
IDProperty * IDP_GetProperties(ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition idprop.cc:877
#define MAIN_VERSION_FILE_ATLEAST(main, ver, subver)
Definition BKE_main.hh:658
void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh)
void BKE_mesh_legacy_edge_crease_to_layers(Mesh *mesh)
void BKE_mesh_legacy_face_set_to_generic(Mesh *mesh)
void BKE_mesh_legacy_sharp_faces_from_flags(Mesh *mesh)
void BKE_mesh_legacy_convert_edges_to_generic(Mesh *mesh)
void BKE_mesh_legacy_bevel_weight_to_generic(Mesh *mesh)
void BKE_mesh_legacy_face_map_to_generic(Main *bmain)
void BKE_mesh_legacy_convert_loops_to_corners(Mesh *mesh)
void BKE_mesh_legacy_convert_verts_to_positions(Mesh *mesh)
void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh)
void BKE_mesh_legacy_bevel_weight_to_layers(Mesh *mesh)
void BKE_mesh_legacy_crease_to_generic(Mesh *mesh)
void BKE_mesh_legacy_convert_flags_to_selection_layers(Mesh *mesh)
void BKE_mesh_legacy_convert_polys_to_offsets(Mesh *mesh)
void BKE_mesh_legacy_uv_seam_from_flags(Mesh *mesh)
void BKE_mesh_legacy_convert_mpoly_to_material_indices(Mesh *mesh)
void BKE_mesh_legacy_sharp_edges_from_flags(Mesh *mesh)
void BKE_mesh_legacy_attribute_flags_to_strings(Mesh *mesh)
#define FOREACH_NODETREE_END
Definition BKE_node.hh:881
#define FOREACH_NODETREE_BEGIN(bmain, _nodetree, _id)
Definition BKE_node.hh:871
#define SH_NODE_TEX_NOISE
#define SH_NODE_BSDF_PRINCIPLED
#define GEO_NODE_SET_SHADE_SMOOTH
#define CMP_NODE_CRYPTOMATTE
#define SH_NODE_BSDF_SHEEN
#define SH_NODE_TEX_COORD
#define SH_NODE_VECT_TRANSFORM
#define SH_NODE_BSDF_HAIR_PRINCIPLED
#define SH_NODE_BSDF_GLOSSY
#define SH_NODE_MIX
#define SH_NODE_BSDF_GLASS
#define CMP_NODE_R_LAYERS
#define SH_NODE_NEW_GEOMETRY
#define SH_NODE_BSDF_GLOSSY_LEGACY
#define SH_NODE_BSDF_REFRACTION
@ RPT_INFO
Definition BKE_report.hh:35
void BKE_scene_disable_color_management(Scene *scene)
Definition scene.cc:2864
void BKE_texture_mapping_default(struct TexMapping *texmap, int type)
Definition texture.cc:234
void BKE_texture_colormapping_default(struct ColorMapping *colormap)
Definition texture.cc:337
struct MovieTrackingObject * BKE_tracking_object_get_camera(const struct MovieTracking *tracking)
struct MovieTrackingObject * BKE_tracking_object_get_active(const struct MovieTracking *tracking)
#define BLI_assert(a)
Definition BLI_assert.h:46
#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)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:497
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:524
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
#define M_PI_4
MINLINE void copy_v4_v4(float r[4], const float a[4])
void interp_v4_v4v4(float r[4], const float a[4], const float b[4], float t)
char * BLI_sprintfN(const char *__restrict format,...) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
Definition string.cc:41
#define STR_ELEM(...)
Definition BLI_string.h:661
char * BLI_strdup_null(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_MALLOC
Definition string.cc:46
size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define SNPRINTF_UTF8(dst, format,...)
#define STRNCPY_UTF8(dst, src)
unsigned int uint
#define SET_FLAG_FROM_TEST(value, test, flag)
#define ELEM(...)
#define STREQ(a, b)
void BLO_reportf_wrap(BlendFileReadReport *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
#define RPT_(msgid)
#define ID_IS_LINKED(_id)
Definition DNA_ID.h:694
@ ID_AR
@ IDP_STRING
@ ASSET_LIBRARY_ALL
#define DNA_struct_default_get(struct_name)
#define MAX_NAME
Definition DNA_defs.h:50
blenloader genfile private function prototypes
@ LA_AREA
@ LA_SPOT
@ LIGHTPROBE_GRID_CAPTURE_EMISSION
@ LIGHTPROBE_GRID_CAPTURE_WORLD
@ LIGHTPROBE_GRID_CAPTURE_INDIRECT
@ eModifierType_Nodes
@ eModifierType_WeightVGEdit
@ NODE_INTERFACE_PANEL_ALLOW_SOCKETS_AFTER_PANELS
@ NODE_INTERFACE_PANEL_ALLOW_CHILD_PANELS_LEGACY
@ NODE_INTERFACE_SOCKET_HIDE_IN_MODIFIER
@ NODE_INTERFACE_SOCKET_HIDE_VALUE
#define SHD_SHEEN_ASHIKHMIN
@ GEO_NODE_ASSET_MODIFIER
@ SHD_NOISE_FBM
@ CMP_NODE_CRYPTOMATTE_SOURCE_RENDER
@ SHD_GLOSSY_SHARP_DEPRECATED
@ SHD_GLOSSY_GGX
@ NTREE_CUSTOM
@ NTREE_SHADER
@ NTREE_GEOMETRY
@ SHD_VECT_TRANSFORM_TYPE_NORMAL
eNodeSocketInOut
@ SOCK_OUT
@ SOCK_IN
@ SOCK_HIDE_VALUE
@ SOCK_HIDE_IN_MODIFIER
@ SOCK_HIDDEN
@ SOCK_FLOAT
@ SOCK_RGBA
@ SHD_PRINCIPLED_HAIR_CHIANG
@ OB_ARMATURE
@ OB_MESH
@ RAYTRACE_EEVEE_METHOD_SCREEN
#define SCE_SNAP_TO_GEOM
#define MAXFRAMEF
#define SCE_SNAP_TO_VERTEX
@ SCE_SNAP
#define MINAFRAMEF
@ SCE_SNAP_INDIVIDUAL_NEAREST
@ SCE_SNAP_TO_EDGE
@ SCE_SNAP_TO_FACE
@ SCE_SNAP_TO_MARKERS
@ SCE_SNAP_INDIVIDUAL_PROJECT
@ SCE_SNAP_TO_INCREMENT
@ SCE_SNAP_TO_GRID
@ SCE_SNAP_TO_EDGE_MIDPOINT
@ SCE_SNAP_TO_FRAME
@ SCE_SNAP_TO_SECOND
@ SCE_SNAP_TO_VOLUME
@ SCE_SNAP_TO_EDGE_PERPENDICULAR
@ SCE_SNAP_TO_NONE
@ RGN_ALIGN_BOTTOM
@ RGN_SPLIT_PREV
@ RGN_TYPE_TOOL_HEADER
@ RGN_TYPE_ASSET_SHELF_HEADER
@ RGN_TYPE_ASSET_SHELF
@ RGN_FLAG_DYNAMIC_SIZE
@ RGN_FLAG_HIDDEN
@ RGN_FLAG_NO_USER_RESIZE
@ STRIP_TYPE_SOUND_RAM
@ SN_OVERLAY_SHOW_PREVIEWS
@ SPACE_NODE
@ SPACE_SEQ
@ SPACE_VIEW3D
@ SEQ_TIMELINE_SHOW_STRIP_RETIMING
@ TEXMAP_TYPE_POINT
@ LIGHT_PROBE_RESOLUTION_1024
#define MEM_SAFE_FREE(v)
@ PROP_DISTANCE
Definition RNA_types.hh:256
@ PROP_NONE
Definition RNA_types.hh:233
BMesh const char void * data
Value & lookup_or_add_default(const Key &key)
Definition BLI_map.hh:639
ValueIterator values() const &
Definition BLI_map.hh:884
const Value & lookup(const Key &key) const
Definition BLI_map.hh:545
void add_new(const Key &key, const Value &value)
Definition BLI_map.hh:265
constexpr T * data() const
Definition BLI_span.hh:539
constexpr MutableSpan drop_front(const int64_t n) const
Definition BLI_span.hh:607
constexpr MutableSpan take_front(const int64_t n) const
Definition BLI_span.hh:629
constexpr int64_t size() const
Definition BLI_span.hh:252
constexpr bool endswith(StringRef suffix) const
constexpr const char * data() const
void append(const T &value)
#define GS(x)
uint pos
#define input
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:123
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:133
void * MEM_dupallocN(const void *vmemh)
Definition mallocn.cc:143
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
static void ANIM_armature_foreach_bone(ListBase *bones, CB callback)
void node_modify_socket_type_static(bNodeTree *ntree, bNode *node, bNodeSocket *sock, int type, int subtype)
Definition node.cc:2791
bNodeSocket * node_find_socket(bNode &node, eNodeSocketInOut in_out, StringRef identifier)
Definition node.cc:2532
void node_remove_socket(bNodeTree &ntree, bNode &node, bNodeSocket &sock)
Definition node.cc:3243
void node_remove_link(bNodeTree *ntree, bNodeLink &link)
Definition node.cc:3847
bNode * node_add_static_node(const bContext *C, bNodeTree &ntree, int type)
Definition node.cc:3500
bNodeLink & node_add_link(bNodeTree &ntree, bNode &fromnode, bNodeSocket &fromsock, bNode &tonode, bNodeSocket &tosock)
Definition node.cc:3810
bNodeSocket * node_add_static_socket(bNodeTree &ntree, bNode &node, eNodeSocketInOut in_out, int type, int subtype, StringRefNull identifier, StringRefNull name)
Definition node.cc:3197
void foreach_strip(ListBase *seqbase, ForEachFunc callback, void *user_data)
Definition iterator.cc:59
int retiming_keys_count(const Strip *strip)
Editing * editing_get(const Scene *scene)
Definition sequencer.cc:286
MutableSpan< SeqRetimingKey > retiming_keys_get(const Strip *strip)
void retiming_data_ensure(Strip *strip)
int time_left_handle_frame_get(const Scene *, const Strip *strip)
bool retiming_is_allowed(const Strip *strip)
void time_right_handle_frame_set(const Scene *scene, Strip *strip, int timeline_frame)
#define mix
closure color sheen(normal N, float roughness) BUILTIN
AssetLibraryReference asset_library_reference
AssetShelfSettings settings
short preferred_row_count
struct BlendFileReadReport::@124362246150331065306145367225174223236260272332 count
ThemeWireColor custom
char panorama_type
float latitude_max
float fisheye_polynomial_k3
float longitude_max
float fisheye_polynomial_k1
float latitude_min
float fisheye_polynomial_k2
float fisheye_fov
float fisheye_polynomial_k0
float fisheye_polynomial_k4
float fisheye_lens
float longitude_min
ListBase seqbase
BlendFileReadReport * reports
Definition readfile.hh:192
SDNA * filesdna
Definition readfile.hh:105
ListBase group
Definition DNA_ID.h:143
IDPropertyData data
Definition DNA_ID.h:169
char type
Definition DNA_ID.h:156
Definition DNA_ID.h:414
char name[258]
Definition DNA_ID.h:432
ListBase lightprobes
Definition BKE_main.hh:296
ListBase scenes
Definition BKE_main.hh:278
ListBase grease_pencils
Definition BKE_main.hh:310
ListBase actions
Definition BKE_main.hh:300
ListBase meshes
Definition BKE_main.hh:281
ListBase movieclips
Definition BKE_main.hh:311
ListBase lights
Definition BKE_main.hh:288
ListBase nodetrees
Definition BKE_main.hh:301
ListBase particles
Definition BKE_main.hh:303
ListBase cameras
Definition BKE_main.hh:289
ListBase armatures
Definition BKE_main.hh:299
ListBase curves
Definition BKE_main.hh:282
ListBase worlds
Definition BKE_main.hh:291
ListBase screens
Definition BKE_main.hh:292
ListBase objects
Definition BKE_main.hh:280
struct MovieTracking tracking
MovieTrackingPlaneTrack * active_plane_track
MovieTrackingReconstruction reconstruction
MovieTrackingTrack * active_track
struct MovieReconstructedCamera * cameras
MovieTrackingPlaneTrack * act_plane_track_legacy
MovieTrackingReconstruction reconstruction_legacy
ListBase plane_tracks_legacy
MovieTrackingTrack * act_track_legacy
TexMapping tex_mapping
ColorMapping color_mapping
NodeTexBase base
AssetShelf * active_shelf
SpaceNodeOverlay overlay
struct SequencerTimelineOverlay timeline_overlay
float speed_factor
ThemeWireColor cs
IDProperty * prop
bNodeSocketRuntimeHandle * runtime
struct bNodeLink * link
char description[64]
char * default_attribute_name
void * default_value
char identifier[64]
char idname[64]
bNodeTreeInterfaceItem ** items_array
bNodeTreeInterfacePanel root_panel
bNodeTreeInterface tree_interface
ListBase nodes
ListBase links
void * storage
ListBase chanbase
ListBase agroups
i
Definition text_draw.cc:230
static void version_principled_bsdf_subsurface(bNodeTree *ntree)
static void versioning_remove_microfacet_sharp_distribution(bNodeTree *ntree)
static void version_replace_velvet_sheen_node(bNodeTree *ntree)
static void version_principled_bsdf_emission(bNodeTree *ntree)
void do_versions_after_linking_400(FileData *fd, Main *bmain)
static void version_node_group_split_socket(bNodeTreeInterface &tree_interface, bNodeTreeInterfaceSocket &socket, bNodeTreeInterfacePanel *parent, int position)
static bool versioning_convert_strip_speed_factor(Strip *strip, void *user_data)
static void version_principled_bsdf_specular_tint(bNodeTree *ntree)
static void version_principled_bsdf_update_animdata(ID *owner_id, bNodeTree *ntree)
static void version_composite_nodetree_null_id(bNodeTree *ntree, Scene *scene)
static void version_bonelayers_to_bonecollections(Main *bmain)
static void versioning_replace_legacy_glossy_node(bNodeTree *ntree)
static void version_vertex_weight_edit_preserve_threshold_exclusivity(Main *bmain)
static void version_principled_transmission_roughness(bNodeTree *ntree)
static void version_principled_bsdf_rename_sockets(bNodeTree *ntree)
static bNodeTreeInterfaceItem * legacy_socket_move_to_interface(bNodeSocket &legacy_socket, const eNodeSocketInOut in_out)
static void version_replace_texcoord_normal_socket(bNodeTree *ntree)
static void versioning_node_group_sort_sockets_recursive(bNodeTreeInterfacePanel &panel)
static void version_movieclips_legacy_camera_object(Main *bmain)
static void version_copy_socket(bNodeTreeInterfaceSocket &dst, const bNodeTreeInterfaceSocket &src, char *identifier)
static void version_principled_bsdf_coat(bNodeTree *ntree)
static void enable_geometry_nodes_is_modifier(Main &bmain)
static void version_nodes_insert_item(bNodeTreeInterfacePanel &parent, bNodeTreeInterfaceSocket &socket, int position)
static void version_motion_tracking_legacy_camera_object(MovieClip &movieclip)
static void versioning_convert_node_tree_socket_lists_to_interface(bNodeTree *ntree)
void blo_do_versions_400(FileData *fd, Library *, Main *bmain)
#define SCE_SNAP_PROJECT
static void version_replace_principled_hair_model(bNodeTree *ntree)
static void version_principled_bsdf_sheen(bNodeTree *ntree)
static void version_mesh_legacy_to_struct_of_array_format(Mesh &mesh)
static int version_nodes_find_valid_insert_position_for_item(const bNodeTreeInterfacePanel &panel, const bNodeTreeInterfaceItem &item, const int initial_pos)
static void version_bonegroups_to_bonecollections(Main *bmain)
static void version_mesh_crease_generic(Main &bmain)
static void version_bonegroup_migrate_color(Main *bmain)
float * version_cycles_node_socket_float_value(bNodeSocket *socket)
IDProperty * version_cycles_properties_from_ID(ID *id)
int version_cycles_property_int(IDProperty *idprop, const char *name, int default_value)
void version_update_node_input(bNodeTree *ntree, FunctionRef< bool(bNode *)> check_node, const char *socket_identifier, FunctionRef< void(bNode *, bNodeSocket *)> update_input, FunctionRef< void(bNode *, bNodeSocket *, bNode *, bNodeSocket *)> update_input_link)
float * version_cycles_node_socket_rgba_value(bNodeSocket *socket)
void version_node_input_socket_name(bNodeTree *ntree, const int node_type, const char *old_name, const char *new_name)
StringRef legacy_socket_idname_to_socket_type(StringRef idname)
float version_cycles_property_float(IDProperty *idprop, const char *name, float default_value)
ARegion * do_versions_add_region_if_not_found(ListBase *regionbase, int region_type, const char *, int link_after_region_type)
uint8_t flag
Definition wm_window.cc:145