diff options
Diffstat (limited to 'source/blender/blenloader/intern/versioning_300.c')
-rw-r--r-- | source/blender/blenloader/intern/versioning_300.c | 928 |
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"); + } + } } } |