diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 4 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_290.c | 25 | ||||
-rw-r--r-- | source/blender/editors/object/object_constraint.c | 7 |
3 files changed, 27 insertions, 9 deletions
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index bb785d310b9..f8d0166b3ca 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -4504,9 +4504,7 @@ static void splineik_free(bConstraint *con) bSplineIKConstraint *data = con->data; /* binding array */ - if (data->points) { - MEM_freeN(data->points); - } + MEM_SAFE_FREE(data->points); } static void splineik_copy(bConstraint *con, bConstraint *srccon) diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c index 7a872ff31b7..c46cdf1c247 100644 --- a/source/blender/blenloader/intern/versioning_290.c +++ b/source/blender/blenloader/intern/versioning_290.c @@ -881,6 +881,19 @@ static ARegion *do_versions_add_region_if_not_found(ListBase *regionbase, return new_region; } +static void do_version_constraints_spline_ik_joint_bindings(ListBase *lb) +{ + /* Binding array data could be freed without properly resetting its size data. */ + LISTBASE_FOREACH (bConstraint *, con, lb) { + if (con->type == CONSTRAINT_TYPE_SPLINEIK) { + bSplineIKConstraint *data = (bSplineIKConstraint *)con->data; + if (data->points == NULL) { + data->numpoints = 0; + } + } + } +} + /* NOLINTNEXTLINE: readability-function-size */ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) { @@ -1086,7 +1099,6 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) } } } - if (!MAIN_VERSION_ATLEAST(bmain, 291, 1)) { /* Initialize additional parameter of the Nishita sky model and change altitude unit. */ @@ -2090,6 +2102,17 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 300, 20)) { ListBase *lb = which_libbase(bmain, ID_VF); BKE_main_id_repair_duplicate_names_listbase(lb); + + /* Fix SplineIK constraint's inconsistency between binding points array and its stored size. */ + LISTBASE_FOREACH (Object *, ob, &bmain->objects) { + /* NOTE: Objects should never have SplineIK constraint, so no need to apply this fix on + * their constraints. */ + if (ob->pose) { + LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) { + do_version_constraints_spline_ik_joint_bindings(&pchan->constraints); + } + } + } } /** diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index 244124a6e0a..427596c2aee 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -432,11 +432,8 @@ static void test_constraint( * free the points array and request a rebind... */ if ((data->points == NULL) || (data->numpoints != data->chainlen + 1)) { - /* free the points array */ - if (data->points) { - MEM_freeN(data->points); - data->points = NULL; - } + MEM_SAFE_FREE(data->points); + data->numpoints = 0; /* clear the bound flag, forcing a rebind next time this is evaluated */ data->flag &= ~CONSTRAINT_SPLINEIK_BOUND; |