Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenloader/intern/versioning_300.c')
-rw-r--r--source/blender/blenloader/intern/versioning_300.c928
1 files changed, 901 insertions, 27 deletions
diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c
index e65fd3e6754..81fc6086951 100644
--- a/source/blender/blenloader/intern/versioning_300.c
+++ b/source/blender/blenloader/intern/versioning_300.c
@@ -22,12 +22,15 @@
#include <string.h>
+#include "CLG_log.h"
+
#include "MEM_guardedalloc.h"
#include "BLI_listbase.h"
#include "BLI_math_vector.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
+#include "BLI_string_utils.h"
#include "BLI_utildefines.h"
#include "DNA_anim_types.h"
@@ -42,19 +45,26 @@
#include "DNA_listBase.h"
#include "DNA_material_types.h"
#include "DNA_modifier_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
#include "DNA_text_types.h"
#include "DNA_workspace_types.h"
#include "BKE_action.h"
+#include "BKE_anim_data.h"
#include "BKE_animsys.h"
+#include "BKE_armature.h"
#include "BKE_asset.h"
#include "BKE_collection.h"
#include "BKE_deform.h"
#include "BKE_fcurve.h"
#include "BKE_fcurve_driver.h"
#include "BKE_idprop.h"
+#include "BKE_image.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_override.h"
#include "BKE_main.h"
+#include "BKE_modifier.h"
#include "BKE_node.h"
#include "RNA_access.h"
@@ -66,11 +76,14 @@
#include "SEQ_iterator.h"
#include "SEQ_sequencer.h"
+#include "SEQ_time.h"
#include "RNA_access.h"
#include "versioning_common.h"
+static CLG_LogRef LOG = {"blo.readfile.doversion"};
+
static IDProperty *idproperty_find_ui_container(IDProperty *idprop_group)
{
LISTBASE_FOREACH (IDProperty *, prop, &idprop_group->data.group) {
@@ -153,18 +166,18 @@ static void version_idproperty_move_data_float(IDPropertyUIDataFloat *ui_data,
IDProperty *default_value = IDP_GetPropertyFromGroup(prop_ui_data, "default");
if (default_value != NULL) {
if (default_value->type == IDP_ARRAY) {
- const int size = default_value->len;
- ui_data->default_array_len = size;
+ const int array_len = default_value->len;
+ ui_data->default_array_len = array_len;
if (default_value->subtype == IDP_FLOAT) {
- ui_data->default_array = MEM_malloc_arrayN(size, sizeof(double), __func__);
+ ui_data->default_array = MEM_malloc_arrayN(array_len, sizeof(double), __func__);
const float *old_default_array = IDP_Array(default_value);
for (int i = 0; i < ui_data->default_array_len; i++) {
ui_data->default_array[i] = (double)old_default_array[i];
}
}
else if (default_value->subtype == IDP_DOUBLE) {
- ui_data->default_array = MEM_malloc_arrayN(size, sizeof(double), __func__);
- memcpy(ui_data->default_array, IDP_Array(default_value), sizeof(double) * size);
+ ui_data->default_array = MEM_malloc_arrayN(array_len, sizeof(double), __func__);
+ memcpy(ui_data->default_array, IDP_Array(default_value), sizeof(double) * array_len);
}
}
else if (ELEM(default_value->type, IDP_DOUBLE, IDP_FLOAT)) {
@@ -376,6 +389,7 @@ static void move_vertex_group_names_to_object_data(Main *bmain)
/* Clear the list in case the it was already assigned from another object. */
BLI_freelistN(new_defbase);
*new_defbase = object->defbase;
+ BKE_object_defgroup_active_index_set(object, object->actdef);
}
}
}
@@ -455,6 +469,22 @@ static bool do_versions_sequencer_color_tags(Sequence *seq, void *UNUSED(user_da
return true;
}
+static bool do_versions_sequencer_color_balance_sop(Sequence *seq, void *UNUSED(user_data))
+{
+ LISTBASE_FOREACH (SequenceModifierData *, smd, &seq->modifiers) {
+ if (smd->type == seqModifierType_ColorBalance) {
+ StripColorBalance *cb = &((ColorBalanceModifierData *)smd)->color_balance;
+ cb->method = SEQ_COLOR_BALANCE_METHOD_LIFTGAMMAGAIN;
+ for (int i = 0; i < 3; i++) {
+ copy_v3_fl(cb->slope, 1.0f);
+ copy_v3_fl(cb->offset, 1.0f);
+ copy_v3_fl(cb->power, 1.0f);
+ }
+ }
+ }
+ return true;
+}
+
static bNodeLink *find_connected_link(bNodeTree *ntree, bNodeSocket *in_socket)
{
LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
@@ -498,17 +528,17 @@ static void version_geometry_nodes_add_realize_instance_nodes(bNodeTree *ntree)
{
LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree->nodes) {
if (ELEM(node->type,
- GEO_NODE_ATTRIBUTE_CAPTURE,
+ GEO_NODE_CAPTURE_ATTRIBUTE,
GEO_NODE_SEPARATE_COMPONENTS,
GEO_NODE_CONVEX_HULL,
GEO_NODE_CURVE_LENGTH,
- GEO_NODE_BOOLEAN,
- GEO_NODE_CURVE_FILLET,
- GEO_NODE_CURVE_RESAMPLE,
+ GEO_NODE_MESH_BOOLEAN,
+ GEO_NODE_FILLET_CURVE,
+ GEO_NODE_RESAMPLE_CURVE,
GEO_NODE_CURVE_TO_MESH,
- GEO_NODE_CURVE_TRIM,
- GEO_NODE_MATERIAL_REPLACE,
- GEO_NODE_MESH_SUBDIVIDE,
+ GEO_NODE_TRIM_CURVE,
+ GEO_NODE_REPLACE_MATERIAL,
+ GEO_NODE_SUBDIVIDE_MESH,
GEO_NODE_ATTRIBUTE_REMOVE,
GEO_NODE_TRIANGULATE)) {
bNodeSocket *geometry_socket = node->inputs.first;
@@ -516,12 +546,60 @@ static void version_geometry_nodes_add_realize_instance_nodes(bNodeTree *ntree)
}
/* Also realize instances for the profile input of the curve to mesh node. */
if (node->type == GEO_NODE_CURVE_TO_MESH) {
- bNodeSocket *profile_socket = node->inputs.last;
+ bNodeSocket *profile_socket = (bNodeSocket *)BLI_findlink(&node->inputs, 1);
add_realize_instances_before_socket(ntree, node, profile_socket);
}
}
}
+/**
+ * The geometry nodes modifier used to realize instances for the next modifier implicitly. Now it
+ * is done with the realize instances node. It also used to convert meshes to point clouds
+ * automatically, which is also now done with a specific node.
+ */
+static bNodeTree *add_realize_node_tree(Main *bmain)
+{
+ bNodeTree *node_tree = ntreeAddTree(bmain, "Realize Instances 2.93 Legacy", "GeometryNodeTree");
+
+ ntreeAddSocketInterface(node_tree, SOCK_IN, "NodeSocketGeometry", "Geometry");
+ ntreeAddSocketInterface(node_tree, SOCK_OUT, "NodeSocketGeometry", "Geometry");
+
+ bNode *group_input = nodeAddStaticNode(NULL, node_tree, NODE_GROUP_INPUT);
+ group_input->locx = -400.0f;
+ bNode *group_output = nodeAddStaticNode(NULL, node_tree, NODE_GROUP_OUTPUT);
+ group_output->locx = 500.0f;
+ group_output->flag |= NODE_DO_OUTPUT;
+
+ bNode *join = nodeAddStaticNode(NULL, node_tree, GEO_NODE_JOIN_GEOMETRY);
+ join->locx = group_output->locx - 175.0f;
+ join->locy = group_output->locy;
+ bNode *conv = nodeAddStaticNode(NULL, node_tree, GEO_NODE_POINTS_TO_VERTICES);
+ conv->locx = join->locx - 175.0f;
+ conv->locy = join->locy - 70.0;
+ bNode *separate = nodeAddStaticNode(NULL, node_tree, GEO_NODE_SEPARATE_COMPONENTS);
+ separate->locx = join->locx - 350.0f;
+ separate->locy = join->locy + 50.0f;
+ bNode *realize = nodeAddStaticNode(NULL, node_tree, GEO_NODE_REALIZE_INSTANCES);
+ realize->locx = separate->locx - 200.0f;
+ realize->locy = join->locy;
+
+ nodeAddLink(node_tree, group_input, group_input->outputs.first, realize, realize->inputs.first);
+ nodeAddLink(node_tree, realize, realize->outputs.first, separate, separate->inputs.first);
+ nodeAddLink(node_tree, conv, conv->outputs.first, join, join->inputs.first);
+ nodeAddLink(node_tree, separate, BLI_findlink(&separate->outputs, 3), join, join->inputs.first);
+ nodeAddLink(node_tree, separate, BLI_findlink(&separate->outputs, 1), conv, conv->inputs.first);
+ nodeAddLink(node_tree, separate, BLI_findlink(&separate->outputs, 2), join, join->inputs.first);
+ nodeAddLink(node_tree, separate, separate->outputs.first, join, join->inputs.first);
+ nodeAddLink(node_tree, join, join->outputs.first, group_output, group_output->inputs.first);
+
+ LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
+ nodeSetSelected(node, false);
+ }
+
+ version_socket_update_is_used(node_tree);
+ return node_tree;
+}
+
void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
{
if (MAIN_VERSION_ATLEAST(bmain, 300, 0) && !MAIN_VERSION_ATLEAST(bmain, 300, 1)) {
@@ -578,6 +656,10 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
}
}
+ if (!MAIN_VERSION_ATLEAST(bmain, 300, 25)) {
+ version_node_socket_index_animdata(bmain, NTREE_SHADER, SH_NODE_BSDF_PRINCIPLED, 4, 2, 25);
+ }
+
if (!MAIN_VERSION_ATLEAST(bmain, 300, 26)) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
ToolSettings *tool_settings = scene->toolsettings;
@@ -616,6 +698,90 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
do_versions_idproperty_ui_data(bmain);
}
+ if (!MAIN_VERSION_ATLEAST(bmain, 300, 32)) {
+ /* Update Switch Node Non-Fields switch input to Switch_001. */
+ LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
+ if (ntree->type != NTREE_GEOMETRY) {
+ continue;
+ }
+
+ LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
+ if (link->tonode->type == GEO_NODE_SWITCH) {
+ if (STREQ(link->tosock->identifier, "Switch")) {
+ bNode *to_node = link->tonode;
+
+ uint8_t mode = ((NodeSwitch *)to_node->storage)->input_type;
+ if (ELEM(mode,
+ SOCK_GEOMETRY,
+ SOCK_OBJECT,
+ SOCK_COLLECTION,
+ SOCK_TEXTURE,
+ SOCK_MATERIAL)) {
+ link->tosock = link->tosock->next;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 300, 33)) {
+ /* This was missing from #move_vertex_group_names_to_object_data. */
+ LISTBASE_FOREACH (Object *, object, &bmain->objects) {
+ if (ELEM(object->type, OB_MESH, OB_LATTICE, OB_GPENCIL)) {
+ /* This uses the fact that the active vertex group index starts counting at 1. */
+ if (BKE_object_defgroup_active_index_get(object) == 0) {
+ BKE_object_defgroup_active_index_set(object, object->actdef);
+ }
+ }
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 300, 35)) {
+ /* Add a new modifier to realize instances from previous modifiers.
+ * Previously that was done automatically by geometry nodes. */
+ bNodeTree *realize_instances_node_tree = NULL;
+ LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
+ LISTBASE_FOREACH_MUTABLE (ModifierData *, md, &ob->modifiers) {
+ if (md->type != eModifierType_Nodes) {
+ continue;
+ }
+ if (md->next == NULL) {
+ break;
+ }
+ if (md->next->type == eModifierType_Nodes) {
+ continue;
+ }
+ NodesModifierData *nmd = (NodesModifierData *)md;
+ if (nmd->node_group == NULL) {
+ continue;
+ }
+
+ NodesModifierData *new_nmd = (NodesModifierData *)BKE_modifier_new(eModifierType_Nodes);
+ STRNCPY(new_nmd->modifier.name, "Realize Instances 2.93 Legacy");
+ BKE_modifier_unique_name(&ob->modifiers, &new_nmd->modifier);
+ BLI_insertlinkafter(&ob->modifiers, md, new_nmd);
+ if (realize_instances_node_tree == NULL) {
+ realize_instances_node_tree = add_realize_node_tree(bmain);
+ }
+ new_nmd->node_group = realize_instances_node_tree;
+ }
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 300, 37)) {
+ LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
+ if (ntree->type == NTREE_GEOMETRY) {
+ LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree->nodes) {
+ if (node->type == GEO_NODE_BOUNDING_BOX) {
+ bNodeSocket *geometry_socket = node->inputs.first;
+ add_realize_instances_before_socket(ntree, node, geometry_socket);
+ }
+ }
+ }
+ }
+ }
+
/**
* Versioning code until next subversion bump goes here.
*
@@ -628,6 +794,40 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
*/
{
/* Keep this block, even when empty. */
+
+ { /* Ensure driver variable names are unique within the driver. */
+ ID *id;
+ FOREACH_MAIN_ID_BEGIN (bmain, id) {
+ AnimData *adt = BKE_animdata_from_id(id);
+ if (adt == NULL) {
+ continue;
+ }
+ LISTBASE_FOREACH (FCurve *, fcu, &adt->drivers) {
+ ChannelDriver *driver = fcu->driver;
+ /* Ensure the uniqueness front to back. Given a list of identically
+ * named variables, the last one gets to keep its original name. This
+ * matches the evaluation order, and thus shouldn't change the evaluated
+ * value of the driver expression. */
+ LISTBASE_FOREACH (DriverVar *, dvar, &driver->variables) {
+ BLI_uniquename(&driver->variables,
+ dvar,
+ dvar->name,
+ '_',
+ offsetof(DriverVar, name),
+ sizeof(dvar->name));
+ }
+ }
+ }
+ FOREACH_MAIN_ID_END;
+ }
+
+ /* Ensure tiled image sources contain a UDIM token. */
+ LISTBASE_FOREACH (Image *, ima, &bmain->images) {
+ if (ima->source == IMA_SRC_TILED) {
+ char *filename = (char *)BLI_path_basename(ima->filepath);
+ BKE_image_ensure_tile_token(filename);
+ }
+ }
}
}
@@ -767,9 +967,9 @@ static bool geometry_node_is_293_legacy(const short node_type)
/* Not legacy: No attribute inputs or outputs. */
case GEO_NODE_TRIANGULATE:
case GEO_NODE_TRANSFORM:
- case GEO_NODE_BOOLEAN:
+ case GEO_NODE_MESH_BOOLEAN:
case GEO_NODE_IS_VIEWPORT:
- case GEO_NODE_MESH_SUBDIVIDE:
+ case GEO_NODE_SUBDIVIDE_MESH:
case GEO_NODE_MESH_PRIMITIVE_CUBE:
case GEO_NODE_MESH_PRIMITIVE_CIRCLE:
case GEO_NODE_MESH_PRIMITIVE_UV_SPHERE:
@@ -779,9 +979,9 @@ static bool geometry_node_is_293_legacy(const short node_type)
case GEO_NODE_MESH_PRIMITIVE_LINE:
case GEO_NODE_MESH_PRIMITIVE_GRID:
case GEO_NODE_BOUNDING_BOX:
- case GEO_NODE_CURVE_RESAMPLE:
+ case GEO_NODE_RESAMPLE_CURVE:
case GEO_NODE_INPUT_MATERIAL:
- case GEO_NODE_MATERIAL_REPLACE:
+ case GEO_NODE_REPLACE_MATERIAL:
case GEO_NODE_CURVE_LENGTH:
case GEO_NODE_CONVEX_HULL:
case GEO_NODE_SEPARATE_COMPONENTS:
@@ -793,8 +993,8 @@ static bool geometry_node_is_293_legacy(const short node_type)
case GEO_NODE_VIEWER:
case GEO_NODE_CURVE_PRIMITIVE_LINE:
case GEO_NODE_CURVE_PRIMITIVE_QUADRILATERAL:
- case GEO_NODE_CURVE_FILL:
- case GEO_NODE_CURVE_TRIM:
+ case GEO_NODE_FILL_CURVE:
+ case GEO_NODE_TRIM_CURVE:
case GEO_NODE_CURVE_TO_MESH:
return false;
@@ -803,7 +1003,7 @@ static bool geometry_node_is_293_legacy(const short node_type)
case GEO_NODE_SET_POSITION:
case GEO_NODE_INPUT_INDEX:
case GEO_NODE_INPUT_NORMAL:
- case GEO_NODE_ATTRIBUTE_CAPTURE:
+ case GEO_NODE_CAPTURE_ATTRIBUTE:
return false;
/* Maybe legacy: Might need special attribute handling, depending on design. */
@@ -816,7 +1016,7 @@ static bool geometry_node_is_293_legacy(const short node_type)
/* Maybe legacy: Special case for grid names? Or finish patch from level set branch to
* generate a mesh for all grids in the volume. */
- case GEO_NODE_VOLUME_TO_MESH:
+ case GEO_NODE_LEGACY_VOLUME_TO_MESH:
return false;
/* Legacy: Transferred *all* attributes before, will not transfer all built-ins now. */
@@ -908,12 +1108,12 @@ static bool seq_transform_origin_set(Sequence *seq, void *UNUSED(user_data))
static void do_version_subsurface_methods(bNode *node)
{
if (node->type == SH_NODE_SUBSURFACE_SCATTERING) {
- if (node->custom1 != SHD_SUBSURFACE_RANDOM_WALK) {
+ if (!ELEM(node->custom1, SHD_SUBSURFACE_BURLEY, SHD_SUBSURFACE_RANDOM_WALK)) {
node->custom1 = SHD_SUBSURFACE_RANDOM_WALK_FIXED_RADIUS;
}
}
else if (node->type == SH_NODE_BSDF_PRINCIPLED) {
- if (node->custom2 != SHD_SUBSURFACE_RANDOM_WALK) {
+ if (!ELEM(node->custom2, SHD_SUBSURFACE_BURLEY, SHD_SUBSURFACE_RANDOM_WALK)) {
node->custom2 = SHD_SUBSURFACE_RANDOM_WALK_FIXED_RADIUS;
}
}
@@ -960,6 +1160,327 @@ static void version_geometry_nodes_add_attribute_input_settings(NodesModifierDat
}
}
+/* Copy of the function before the fixes. */
+static void legacy_vec_roll_to_mat3_normalized(const float nor[3],
+ const float roll,
+ float r_mat[3][3])
+{
+ const float SAFE_THRESHOLD = 1.0e-5f; /* theta above this value has good enough precision. */
+ const float CRITICAL_THRESHOLD = 1.0e-9f; /* above this is safe under certain conditions. */
+ const float THRESHOLD_SQUARED = CRITICAL_THRESHOLD * CRITICAL_THRESHOLD;
+
+ const float x = nor[0];
+ const float y = nor[1];
+ const float z = nor[2];
+
+ const float theta = 1.0f + y; /* remapping Y from [-1,+1] to [0,2]. */
+ const float theta_alt = x * x + z * z; /* Helper value for matrix calculations. */
+ float rMatrix[3][3], bMatrix[3][3];
+
+ BLI_ASSERT_UNIT_V3(nor);
+
+ /* When theta is close to zero (nor is aligned close to negative Y Axis),
+ * we have to check we do have non-null X/Z components as well.
+ * Also, due to float precision errors, nor can be (0.0, -0.99999994, 0.0) which results
+ * in theta being close to zero. This will cause problems when theta is used as divisor.
+ */
+ if (theta > SAFE_THRESHOLD || (theta > CRITICAL_THRESHOLD && theta_alt > THRESHOLD_SQUARED)) {
+ /* nor is *not* aligned to negative Y-axis (0,-1,0). */
+
+ bMatrix[0][1] = -x;
+ bMatrix[1][0] = x;
+ bMatrix[1][1] = y;
+ bMatrix[1][2] = z;
+ bMatrix[2][1] = -z;
+
+ if (theta > SAFE_THRESHOLD) {
+ /* nor differs significantly from negative Y axis (0,-1,0): apply the general case. */
+ bMatrix[0][0] = 1 - x * x / theta;
+ bMatrix[2][2] = 1 - z * z / theta;
+ bMatrix[2][0] = bMatrix[0][2] = -x * z / theta;
+ }
+ else {
+ /* nor is close to negative Y axis (0,-1,0): apply the special case. */
+ bMatrix[0][0] = (x + z) * (x - z) / -theta_alt;
+ bMatrix[2][2] = -bMatrix[0][0];
+ bMatrix[2][0] = bMatrix[0][2] = 2.0f * x * z / theta_alt;
+ }
+ }
+ else {
+ /* nor is very close to negative Y axis (0,-1,0): use simple symmetry by Z axis. */
+ unit_m3(bMatrix);
+ bMatrix[0][0] = bMatrix[1][1] = -1.0;
+ }
+
+ /* Make Roll matrix */
+ axis_angle_normalized_to_mat3(rMatrix, nor, roll);
+
+ /* Combine and output result */
+ mul_m3_m3m3(r_mat, rMatrix, bMatrix);
+}
+
+static void correct_bone_roll_value(const float head[3],
+ const float tail[3],
+ const float check_x_axis[3],
+ const float check_y_axis[3],
+ float *r_roll)
+{
+ const float SAFE_THRESHOLD = 1.0e-5f;
+ float vec[3], bone_mat[3][3], vec2[3];
+
+ /* Compute the Y axis vector. */
+ sub_v3_v3v3(vec, tail, head);
+ normalize_v3(vec);
+
+ /* Only correct when in the danger zone. */
+ if (1.0f + vec[1] < SAFE_THRESHOLD * 2 && (vec[0] || vec[2])) {
+ /* Use the armature matrix to double-check if adjustment is needed.
+ * This should minimize issues if the file is bounced back and forth between
+ * 2.92 and 2.91, provided Edit Mode isn't entered on the armature in 2.91. */
+ vec_roll_to_mat3(vec, *r_roll, bone_mat);
+
+ UNUSED_VARS_NDEBUG(check_y_axis);
+ BLI_assert(dot_v3v3(bone_mat[1], check_y_axis) > 0.999f);
+
+ if (dot_v3v3(bone_mat[0], check_x_axis) < 0.999f) {
+ /* Recompute roll using legacy code to interpret the old value. */
+ legacy_vec_roll_to_mat3_normalized(vec, *r_roll, bone_mat);
+ mat3_to_vec_roll(bone_mat, vec2, r_roll);
+ BLI_assert(compare_v3v3(vec, vec2, 0.001f));
+ }
+ }
+}
+
+/* Update the armature Bone roll fields for bones very close to -Y direction. */
+static void do_version_bones_roll(ListBase *lb)
+{
+ LISTBASE_FOREACH (Bone *, bone, lb) {
+ /* Parent-relative orientation (used for posing). */
+ correct_bone_roll_value(
+ bone->head, bone->tail, bone->bone_mat[0], bone->bone_mat[1], &bone->roll);
+
+ /* Absolute orientation (used for Edit mode). */
+ correct_bone_roll_value(
+ bone->arm_head, bone->arm_tail, bone->arm_mat[0], bone->arm_mat[1], &bone->arm_roll);
+
+ do_version_bones_roll(&bone->childbase);
+ }
+}
+
+static void version_geometry_nodes_set_position_node_offset(bNodeTree *ntree)
+{
+ /* Add the new Offset socket. */
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ if (node->type != GEO_NODE_SET_POSITION) {
+ continue;
+ }
+ if (BLI_listbase_count(&node->inputs) < 4) {
+ /* The offset socket didn't exist in the file yet. */
+ return;
+ }
+ bNodeSocket *old_offset_socket = BLI_findlink(&node->inputs, 3);
+ if (old_offset_socket->type == SOCK_VECTOR) {
+ /* Versioning happened already. */
+ return;
+ }
+ /* Change identifier of old socket, so that the there is no name collision. */
+ STRNCPY(old_offset_socket->identifier, "Offset_old");
+ nodeAddStaticSocket(ntree, node, SOCK_IN, SOCK_VECTOR, PROP_TRANSLATION, "Offset", "Offset");
+ }
+
+ /* Relink links that were connected to Position while Offset was enabled. */
+ LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
+ if (link->tonode->type != GEO_NODE_SET_POSITION) {
+ continue;
+ }
+ if (!STREQ(link->tosock->identifier, "Position")) {
+ continue;
+ }
+ bNodeSocket *old_offset_socket = BLI_findlink(&link->tonode->inputs, 3);
+ /* This assumes that the offset is not linked to something else. That seems to be a reasonable
+ * assumption, because the node is probably only ever used in one or the other mode. */
+ const bool offset_enabled =
+ ((bNodeSocketValueBoolean *)old_offset_socket->default_value)->value;
+ if (offset_enabled) {
+ /* Relink to new offset socket. */
+ link->tosock = old_offset_socket->next;
+ }
+ }
+
+ /* Remove old Offset socket. */
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ if (node->type != GEO_NODE_SET_POSITION) {
+ continue;
+ }
+ bNodeSocket *old_offset_socket = BLI_findlink(&node->inputs, 3);
+ nodeRemoveSocket(ntree, node, old_offset_socket);
+ }
+}
+
+static void version_node_tree_socket_id_delim(bNodeTree *ntree)
+{
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
+ version_node_socket_id_delim(socket);
+ }
+ LISTBASE_FOREACH (bNodeSocket *, socket, &node->outputs) {
+ version_node_socket_id_delim(socket);
+ }
+ }
+}
+
+static bool version_fix_seq_meta_range(Sequence *seq, void *user_data)
+{
+ Scene *scene = (Scene *)user_data;
+ if (seq->type == SEQ_TYPE_META) {
+ SEQ_time_update_meta_strip_range(scene, seq);
+ }
+ return true;
+}
+
+/* Those `version_liboverride_rnacollections_*` functions mimic the old, pre-3.0 code to find
+ * anchor and source items in the given list of modifiers, constraints etc., using only the
+ * `subitem_local` data of the override property operation.
+ *
+ * Then they convert it into the new, proper `subitem_reference` data for the anchor, and
+ * `subitem_local` for the source.
+ *
+ * NOTE: Here only the stored override ID is available, unlike in the `override_apply` functions.
+ */
+
+static void version_liboverride_rnacollections_insertion_object_constraints(
+ ListBase *constraints, IDOverrideLibraryProperty *op)
+{
+ LISTBASE_FOREACH_MUTABLE (IDOverrideLibraryPropertyOperation *, opop, &op->operations) {
+ if (opop->operation != IDOVERRIDE_LIBRARY_OP_INSERT_AFTER) {
+ continue;
+ }
+ bConstraint *constraint_anchor = BLI_listbase_string_or_index_find(constraints,
+ opop->subitem_local_name,
+ offsetof(bConstraint, name),
+ opop->subitem_local_index);
+ bConstraint *constraint_src = constraint_anchor != NULL ? constraint_anchor->next :
+ constraints->first;
+
+ if (constraint_src == NULL) {
+ /* Invalid case, just remove that override property operation. */
+ CLOG_ERROR(&LOG, "Could not find source constraint in stored override data");
+ BKE_lib_override_library_property_operation_delete(op, opop);
+ continue;
+ }
+
+ opop->subitem_reference_name = opop->subitem_local_name;
+ opop->subitem_local_name = BLI_strdup(constraint_src->name);
+ opop->subitem_reference_index = opop->subitem_local_index;
+ opop->subitem_local_index++;
+ }
+}
+
+static void version_liboverride_rnacollections_insertion_object(Object *object)
+{
+ IDOverrideLibrary *liboverride = object->id.override_library;
+ IDOverrideLibraryProperty *op;
+
+ op = BKE_lib_override_library_property_find(liboverride, "modifiers");
+ if (op != NULL) {
+ LISTBASE_FOREACH_MUTABLE (IDOverrideLibraryPropertyOperation *, opop, &op->operations) {
+ if (opop->operation != IDOVERRIDE_LIBRARY_OP_INSERT_AFTER) {
+ continue;
+ }
+ ModifierData *mod_anchor = BLI_listbase_string_or_index_find(&object->modifiers,
+ opop->subitem_local_name,
+ offsetof(ModifierData, name),
+ opop->subitem_local_index);
+ ModifierData *mod_src = mod_anchor != NULL ? mod_anchor->next : object->modifiers.first;
+
+ if (mod_src == NULL) {
+ /* Invalid case, just remove that override property operation. */
+ CLOG_ERROR(&LOG, "Could not find source modifier in stored override data");
+ BKE_lib_override_library_property_operation_delete(op, opop);
+ continue;
+ }
+
+ opop->subitem_reference_name = opop->subitem_local_name;
+ opop->subitem_local_name = BLI_strdup(mod_src->name);
+ opop->subitem_reference_index = opop->subitem_local_index;
+ opop->subitem_local_index++;
+ }
+ }
+
+ op = BKE_lib_override_library_property_find(liboverride, "grease_pencil_modifiers");
+ if (op != NULL) {
+ LISTBASE_FOREACH_MUTABLE (IDOverrideLibraryPropertyOperation *, opop, &op->operations) {
+ if (opop->operation != IDOVERRIDE_LIBRARY_OP_INSERT_AFTER) {
+ continue;
+ }
+ GpencilModifierData *gp_mod_anchor = BLI_listbase_string_or_index_find(
+ &object->greasepencil_modifiers,
+ opop->subitem_local_name,
+ offsetof(GpencilModifierData, name),
+ opop->subitem_local_index);
+ GpencilModifierData *gp_mod_src = gp_mod_anchor != NULL ?
+ gp_mod_anchor->next :
+ object->greasepencil_modifiers.first;
+
+ if (gp_mod_src == NULL) {
+ /* Invalid case, just remove that override property operation. */
+ CLOG_ERROR(&LOG, "Could not find source GP modifier in stored override data");
+ BKE_lib_override_library_property_operation_delete(op, opop);
+ continue;
+ }
+
+ opop->subitem_reference_name = opop->subitem_local_name;
+ opop->subitem_local_name = BLI_strdup(gp_mod_src->name);
+ opop->subitem_reference_index = opop->subitem_local_index;
+ opop->subitem_local_index++;
+ }
+ }
+
+ op = BKE_lib_override_library_property_find(liboverride, "constraints");
+ if (op != NULL) {
+ version_liboverride_rnacollections_insertion_object_constraints(&object->constraints, op);
+ }
+
+ if (object->pose != NULL) {
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
+ char rna_path[FILE_MAXFILE];
+ BLI_snprintf(rna_path, sizeof(rna_path), "pose.bones[\"%s\"].constraints", pchan->name);
+ op = BKE_lib_override_library_property_find(liboverride, rna_path);
+ if (op != NULL) {
+ version_liboverride_rnacollections_insertion_object_constraints(&pchan->constraints, op);
+ }
+ }
+ }
+}
+
+static void version_liboverride_rnacollections_insertion_animdata(ID *id)
+{
+ AnimData *anim_data = BKE_animdata_from_id(id);
+ if (anim_data == NULL) {
+ return;
+ }
+
+ IDOverrideLibrary *liboverride = id->override_library;
+ IDOverrideLibraryProperty *op;
+
+ op = BKE_lib_override_library_property_find(liboverride, "animation_data.nla_tracks");
+ if (op != NULL) {
+ LISTBASE_FOREACH (IDOverrideLibraryPropertyOperation *, opop, &op->operations) {
+ if (opop->operation != IDOVERRIDE_LIBRARY_OP_INSERT_AFTER) {
+ continue;
+ }
+ /* NLA tracks are only referenced by index, which limits possibilities, basically they are
+ * always added at the end of the list, see #rna_NLA_tracks_override_apply.
+ *
+ * This makes things simple here. */
+ opop->subitem_reference_name = opop->subitem_local_name;
+ opop->subitem_local_name = NULL;
+ opop->subitem_reference_index = opop->subitem_local_index;
+ opop->subitem_local_index++;
+ }
+ }
+}
+
/* NOLINTNEXTLINE: readability-function-size */
void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
{
@@ -1039,7 +1560,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
FOREACH_NODETREE_END;
- if (!DNA_struct_elem_find(fd->filesdna, "FileAssetSelectParams", "int", "import_type")) {
+ if (!DNA_struct_elem_find(fd->filesdna, "FileAssetSelectParams", "short", "import_type")) {
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
@@ -1173,7 +1694,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
if (ntree->type == NTREE_GEOMETRY) {
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
- if (node->type == GEO_NODE_MESH_SUBDIVIDE) {
+ if (node->type == GEO_NODE_SUBDIVIDE_MESH) {
strcpy(node->idname, "GeometryNodeMeshSubdivide");
}
}
@@ -1552,7 +2073,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
SpaceFile *sfile = (SpaceFile *)sl;
if (sfile->params) {
sfile->params->flag &= ~(FILE_PARAMS_FLAG_UNUSED_1 | FILE_PARAMS_FLAG_UNUSED_2 |
- FILE_PARAMS_FLAG_UNUSED_3 | FILE_PARAMS_FLAG_UNUSED_4);
+ FILE_PARAMS_FLAG_UNUSED_3 | FILE_PATH_TOKENS_ALLOW);
}
/* New default import type: Append with reuse. */
@@ -1658,7 +2179,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
- /* Show vse color tags by default. */
+ /* Show sequencer color tags by default. */
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
@@ -1669,6 +2190,299 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
}
+
+ /* Set defaults for new color balance modifier parameters. */
+ LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
+ if (scene->ed != NULL) {
+ SEQ_for_each_callback(&scene->ed->seqbase, do_versions_sequencer_color_balance_sop, NULL);
+ }
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 300, 33)) {
+ for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
+ switch (sl->spacetype) {
+ case SPACE_SEQ: {
+ SpaceSeq *sseq = (SpaceSeq *)sl;
+ enum { SEQ_DRAW_SEQUENCE = 0 };
+ if (sseq->mainb == SEQ_DRAW_SEQUENCE) {
+ sseq->mainb = SEQ_DRAW_IMG_IMBUF;
+ }
+ break;
+ }
+ case SPACE_TEXT: {
+ SpaceText *st = (SpaceText *)sl;
+ st->flags &= ~ST_FLAG_UNUSED_4;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 300, 36)) {
+ /* Update the `idnames` for renamed geometry and function nodes. */
+ LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
+ if (ntree->type != NTREE_GEOMETRY) {
+ continue;
+ }
+ version_node_id(ntree, FN_NODE_COMPARE, "FunctionNodeCompareFloats");
+ version_node_id(ntree, GEO_NODE_CAPTURE_ATTRIBUTE, "GeometryNodeCaptureAttribute");
+ version_node_id(ntree, GEO_NODE_MESH_BOOLEAN, "GeometryNodeMeshBoolean");
+ version_node_id(ntree, GEO_NODE_FILL_CURVE, "GeometryNodeFillCurve");
+ version_node_id(ntree, GEO_NODE_FILLET_CURVE, "GeometryNodeFilletCurve");
+ version_node_id(ntree, GEO_NODE_REVERSE_CURVE, "GeometryNodeReverseCurve");
+ version_node_id(ntree, GEO_NODE_SAMPLE_CURVE, "GeometryNodeSampleCurve");
+ version_node_id(ntree, GEO_NODE_RESAMPLE_CURVE, "GeometryNodeResampleCurve");
+ version_node_id(ntree, GEO_NODE_SUBDIVIDE_CURVE, "GeometryNodeSubdivideCurve");
+ version_node_id(ntree, GEO_NODE_TRIM_CURVE, "GeometryNodeTrimCurve");
+ version_node_id(ntree, GEO_NODE_REPLACE_MATERIAL, "GeometryNodeReplaceMaterial");
+ version_node_id(ntree, GEO_NODE_SUBDIVIDE_MESH, "GeometryNodeSubdivideMesh");
+ version_node_id(ntree, GEO_NODE_SET_MATERIAL, "GeometryNodeSetMaterial");
+ version_node_id(ntree, GEO_NODE_SPLIT_EDGES, "GeometryNodeSplitEdges");
+ }
+
+ /* Update bone roll after a fix to vec_roll_to_mat3_normalized. */
+ LISTBASE_FOREACH (bArmature *, arm, &bmain->armatures) {
+ do_version_bones_roll(&arm->bonebase);
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 300, 37)) {
+ /* Node Editor: toggle overlays on. */
+ if (!DNA_struct_find(fd->filesdna, "SpaceNodeOverlay")) {
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) {
+ if (space->spacetype == SPACE_NODE) {
+ SpaceNode *snode = (SpaceNode *)space;
+ snode->overlay.flag |= SN_OVERLAY_SHOW_OVERLAYS;
+ snode->overlay.flag |= SN_OVERLAY_SHOW_WIRE_COLORS;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 300, 38)) {
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) {
+ if (space->spacetype == SPACE_FILE) {
+ SpaceFile *sfile = (SpaceFile *)space;
+ FileAssetSelectParams *asset_params = sfile->asset_params;
+ if (asset_params) {
+ asset_params->base_params.filter_id = FILTER_ID_ALL;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 300, 39)) {
+ LISTBASE_FOREACH (wmWindowManager *, wm, &bmain->wm) {
+ wm->xr.session_settings.base_scale = 1.0f;
+ wm->xr.session_settings.draw_flags |= (V3D_OFSDRAW_SHOW_SELECTION |
+ V3D_OFSDRAW_XR_SHOW_CONTROLLERS |
+ V3D_OFSDRAW_XR_SHOW_CUSTOM_OVERLAYS);
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 300, 40)) {
+ /* Update the `idnames` for renamed geometry and function nodes. */
+ LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
+ if (ntree->type != NTREE_GEOMETRY) {
+ continue;
+ }
+ version_node_id(ntree, FN_NODE_SLICE_STRING, "FunctionNodeSliceString");
+ version_geometry_nodes_set_position_node_offset(ntree);
+ version_node_id(ntree, GEO_NODE_LEGACY_VOLUME_TO_MESH, "GeometryNodeLegacyVolumeToMesh");
+ }
+
+ /* Add storage to viewer node. */
+ LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
+ if (ntree->type != NTREE_GEOMETRY) {
+ continue;
+ }
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ if (node->type == GEO_NODE_VIEWER) {
+ if (node->storage == NULL) {
+ NodeGeometryViewer *data = (NodeGeometryViewer *)MEM_callocN(
+ sizeof(NodeGeometryViewer), __func__);
+ data->data_type = CD_PROP_FLOAT;
+ node->storage = data;
+ }
+ }
+ }
+ }
+
+ LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
+ if (ntree->type == NTREE_GEOMETRY) {
+ version_node_input_socket_name(
+ ntree, GEO_NODE_DISTRIBUTE_POINTS_ON_FACES, "Geometry", "Mesh");
+ version_node_input_socket_name(ntree, GEO_NODE_POINTS_TO_VOLUME, "Geometry", "Points");
+ version_node_output_socket_name(ntree, GEO_NODE_POINTS_TO_VOLUME, "Geometry", "Volume");
+ version_node_socket_name(ntree, GEO_NODE_SUBDIVISION_SURFACE, "Geometry", "Mesh");
+ version_node_socket_name(ntree, GEO_NODE_RESAMPLE_CURVE, "Geometry", "Curve");
+ version_node_socket_name(ntree, GEO_NODE_SUBDIVIDE_CURVE, "Geometry", "Curve");
+ version_node_socket_name(ntree, GEO_NODE_SET_CURVE_RADIUS, "Geometry", "Curve");
+ version_node_socket_name(ntree, GEO_NODE_SET_CURVE_TILT, "Geometry", "Curve");
+ version_node_socket_name(ntree, GEO_NODE_SET_CURVE_HANDLES, "Geometry", "Curve");
+ version_node_socket_name(ntree, GEO_NODE_TRANSLATE_INSTANCES, "Geometry", "Instances");
+ version_node_socket_name(ntree, GEO_NODE_ROTATE_INSTANCES, "Geometry", "Instances");
+ version_node_socket_name(ntree, GEO_NODE_SCALE_INSTANCES, "Geometry", "Instances");
+ version_node_output_socket_name(ntree, GEO_NODE_MESH_BOOLEAN, "Geometry", "Mesh");
+ version_node_input_socket_name(ntree, GEO_NODE_MESH_BOOLEAN, "Geometry 1", "Mesh 1");
+ version_node_input_socket_name(ntree, GEO_NODE_MESH_BOOLEAN, "Geometry 2", "Mesh 2");
+ version_node_socket_name(ntree, GEO_NODE_SUBDIVIDE_MESH, "Geometry", "Mesh");
+ version_node_socket_name(ntree, GEO_NODE_TRIANGULATE, "Geometry", "Mesh");
+ version_node_output_socket_name(ntree, GEO_NODE_MESH_PRIMITIVE_CONE, "Geometry", "Mesh");
+ version_node_output_socket_name(ntree, GEO_NODE_MESH_PRIMITIVE_CUBE, "Geometry", "Mesh");
+ version_node_output_socket_name(
+ ntree, GEO_NODE_MESH_PRIMITIVE_CYLINDER, "Geometry", "Mesh");
+ version_node_output_socket_name(ntree, GEO_NODE_MESH_PRIMITIVE_GRID, "Geometry", "Mesh");
+ version_node_output_socket_name(
+ ntree, GEO_NODE_MESH_PRIMITIVE_ICO_SPHERE, "Geometry", "Mesh");
+ version_node_output_socket_name(ntree, GEO_NODE_MESH_PRIMITIVE_CIRCLE, "Geometry", "Mesh");
+ version_node_output_socket_name(ntree, GEO_NODE_MESH_PRIMITIVE_LINE, "Geometry", "Mesh");
+ version_node_output_socket_name(
+ ntree, GEO_NODE_MESH_PRIMITIVE_UV_SPHERE, "Geometry", "Mesh");
+ version_node_socket_name(ntree, GEO_NODE_SET_POINT_RADIUS, "Geometry", "Points");
+ }
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 300, 42)) {
+ /* Use consistent socket identifiers for the math node.
+ * The code to make unique identifiers from the names was inconsistent. */
+ FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
+ if (ntree->type != NTREE_CUSTOM) {
+ version_node_tree_socket_id_delim(ntree);
+ }
+ }
+ FOREACH_NODETREE_END;
+
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
+ if (sl->spacetype == SPACE_SEQ) {
+ ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
+ &sl->regionbase;
+ LISTBASE_FOREACH (ARegion *, region, regionbase) {
+ if (region->regiontype == RGN_TYPE_WINDOW) {
+ region->v2d.min[1] = 1.0f;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Change minimum zoom to 0.05f in the node editor. */
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
+ if (sl->spacetype == SPACE_NODE) {
+ ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
+ &sl->regionbase;
+ LISTBASE_FOREACH (ARegion *, region, regionbase) {
+ if (region->regiontype == RGN_TYPE_WINDOW) {
+ if (region->v2d.minzoom > 0.05f) {
+ region->v2d.minzoom = 0.05f;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
+ Editing *ed = SEQ_editing_get(scene);
+ /* Make sure range of meta strips is correct.
+ * It was possible to save .blend file with incorrect state of meta strip
+ * range. The root cause is expected to be fixed, but need to ensure files
+ * with invalid meta strip range are corrected. */
+ if (ed != NULL) {
+ SEQ_for_each_callback(&ed->seqbase, version_fix_seq_meta_range, scene);
+ }
+ }
+ }
+
+ /* Special case to handle older in-development 3.1 files, before change from 3.0 branch gets
+ * merged in master. */
+ if (!MAIN_VERSION_ATLEAST(bmain, 300, 42) ||
+ (bmain->versionfile == 301 && !MAIN_VERSION_ATLEAST(bmain, 301, 3))) {
+ /* Update LibOverride operations regarding insertions in RNA collections (i.e. modifiers,
+ * constraints and NLA tracks). */
+ ID *id_iter;
+ FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
+ if (ID_IS_OVERRIDE_LIBRARY_REAL(id_iter)) {
+ version_liboverride_rnacollections_insertion_animdata(id_iter);
+ if (GS(id_iter->name) == ID_OB) {
+ version_liboverride_rnacollections_insertion_object((Object *)id_iter);
+ }
+ }
+ }
+ FOREACH_MAIN_ID_END;
+ }
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 301, 4)) {
+ LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
+ if (ntree->type != NTREE_GEOMETRY) {
+ continue;
+ }
+ version_node_id(ntree, GEO_NODE_CURVE_SPLINE_PARAMETER, "GeometryNodeSplineParameter");
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ if (node->type == GEO_NODE_CURVE_SPLINE_PARAMETER) {
+ version_node_add_socket_if_not_exist(
+ ntree, node, SOCK_OUT, SOCK_INT, PROP_NONE, "Index", "Index");
+ }
+
+ /* Convert float compare into a more general compare node. */
+ if (node->type == FN_NODE_COMPARE) {
+ if (node->storage == NULL) {
+ NodeFunctionCompare *data = (NodeFunctionCompare *)MEM_callocN(
+ sizeof(NodeFunctionCompare), __func__);
+ data->data_type = SOCK_FLOAT;
+ data->operation = node->custom1;
+ strcpy(node->idname, "FunctionNodeCompare");
+ node->storage = data;
+ }
+ }
+ }
+ }
+
+ /* Add a toggle for the breadcrumbs overlay in the node editor. */
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) {
+ if (space->spacetype == SPACE_NODE) {
+ SpaceNode *snode = (SpaceNode *)space;
+ snode->overlay.flag |= SN_OVERLAY_SHOW_PATH;
+ }
+ }
+ }
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 301, 5)) {
+ LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
+ if (ntree->type != NTREE_GEOMETRY) {
+ continue;
+ }
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ if (node->type != GEO_NODE_REALIZE_INSTANCES) {
+ continue;
+ }
+ node->custom1 |= GEO_NODE_REALIZE_INSTANCES_LEGACY_BEHAVIOR;
+ }
+ }
}
/**
@@ -1682,5 +2496,65 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
*/
{
/* Keep this block, even when empty. */
+
+ /* Add node storage for map range node. */
+ FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ if (node->type == SH_NODE_MAP_RANGE) {
+ if (node->storage == NULL) {
+ NodeMapRange *data = MEM_callocN(sizeof(NodeMapRange), __func__);
+ data->clamp = node->custom1;
+ data->data_type = CD_PROP_FLOAT;
+ data->interpolation_type = node->custom2;
+ node->storage = data;
+ }
+ }
+ }
+ }
+ FOREACH_NODETREE_END;
+
+ /* Update spreadsheet data set region type. */
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
+ if (sl->spacetype == SPACE_SPREADSHEET) {
+ ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
+ &sl->regionbase;
+ LISTBASE_FOREACH (ARegion *, region, regionbase) {
+ if (region->regiontype == RGN_TYPE_CHANNELS) {
+ region->regiontype = RGN_TYPE_TOOLS;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Initialize the bone wireframe opacity setting. */
+ if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "bone_wire_alpha")) {
+ for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
+ if (sl->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = (View3D *)sl;
+ v3d->overlay.bone_wire_alpha = 1.0f;
+ }
+ }
+ }
+ }
+ }
+
+ /* Rename sockets on multiple nodes */
+ LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
+ if (ntree->type == NTREE_GEOMETRY) {
+ version_node_output_socket_name(
+ ntree, GEO_NODE_STRING_TO_CURVES, "Curves", "Curve Instances");
+ version_node_output_socket_name(
+ ntree, GEO_NODE_INPUT_MESH_EDGE_ANGLE, "Angle", "Unsigned Angle");
+ version_node_output_socket_name(
+ ntree, GEO_NODE_INPUT_MESH_ISLAND, "Index", "Island Index");
+ version_node_input_socket_name(ntree, GEO_NODE_TRANSFER_ATTRIBUTE, "Target", "Source");
+ }
+ }
}
}