Fix T61051: crash with multi-object mixed mode snapping
authorPhilipp Oeser <info@graphics-engineer.com>
Thu, 31 Jan 2019 12:01:52 +0000 (13:01 +0100)
committerPhilipp Oeser <info@graphics-engineer.com>
Wed, 6 Feb 2019 08:46:20 +0000 (09:46 +0100)
rBec3357e03ab1 introduced multi-object snapping.
Seems like this was done without mixed-mode selections in mind.

So code assumed that all selected objects are actually armatures [which
can fail].
In 2.7 this was not a problem, because code only took active object into
account, 2.8 was iterating over all selected_editable_objects.

Now just iterate over objects in posemode instead

Reviewers: brecht, dfelinto

Maniphest Tasks: T61051

Differential Revision: https://developer.blender.org/D4287

source/blender/editors/space_view3d/view3d_snap.c

index 47b085572220abb6796578fc210b6392f9b46c15..506d8f31bb07cafe9e52fbc1eb8de92968e3cfbd 100644 (file)
@@ -308,8 +308,12 @@ static int snap_selected_to_location(bContext *C, const float snap_target_global
        }
        else if (obact && (obact->mode & OB_MODE_POSE)) {
                struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID);
-               CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
-               {
+               ViewLayer *view_layer = CTX_data_view_layer(C);
+               uint objects_len = 0;
+               Object **objects = BKE_view_layer_array_from_objects_in_mode_unique_data(view_layer, CTX_wm_view3d(C),
+                                                                                        &objects_len, OB_MODE_POSE);
+               for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+                       Object *ob = objects[ob_index];
                        bPoseChannel *pchan;
                        bArmature *arm = ob->data;
                        float snap_target_local[3];
@@ -373,7 +377,7 @@ static int snap_selected_to_location(bContext *C, const float snap_target_global
 
                        DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
                }
-               CTX_DATA_END;
+               MEM_freeN(objects);
        }
        else {
                struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID);