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