[Bf-blender-cvs] [18f06186778] blender2.8: Fix T58412: in weight paint + pose mode certain armature operations crash.

Alexander Gavrilov noreply at git.blender.org
Sat Dec 1 17:48:57 CET 2018


Commit: 18f06186778ea67583a362a611b1efa8c9da5fbd
Author: Alexander Gavrilov
Date:   Sat Dec 1 19:43:10 2018 +0300
Branches: blender2.8
https://developer.blender.org/rB18f06186778ea67583a362a611b1efa8c9da5fbd

Fix T58412: in weight paint + pose mode certain armature operations crash.

The cause is that FOREACH_OBJECT_IN_MODE_BEGIN assumed that the active
object is in the correct mode, which is wrong in this case. It also
only considered objects of the same type as active, which had to be
replaced with an explicit type parameter.

===================================================================

M	source/blender/blenkernel/BKE_layer.h
M	source/blender/blenkernel/intern/layer.c
M	source/blender/blenkernel/intern/layer_utils.c
M	source/blender/draw/intern/draw_manager.c
M	source/blender/editors/armature/armature_edit.c
M	source/blender/editors/armature/pose_edit.c
M	source/blender/editors/armature/pose_slide.c
M	source/blender/editors/armature/pose_transform.c
M	source/blender/editors/armature/pose_utils.c
M	source/blender/editors/screen/screen_context.c
M	source/blender/editors/space_info/info_stats.c
M	source/blender/editors/space_view3d/view3d_edit.c
M	source/blender/editors/space_view3d/view3d_select.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index e98fa189379..db363148bc8 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -160,6 +160,7 @@ void BKE_view_layer_selected_editable_objects_iterator_end(BLI_Iterator *iter);
 
 struct ObjectsInModeIteratorData {
 	int object_mode;
+	int object_type;
 	struct ViewLayer *view_layer;
 	struct View3D *v3d;
 	struct Base *base_active;
@@ -226,10 +227,11 @@ void BKE_view_layer_visible_bases_iterator_end(BLI_Iterator *iter);
 	ITER_END;                                                                 \
 } ((void)0)
 
-#define FOREACH_BASE_IN_MODE_BEGIN(_view_layer, _v3d, _object_mode, _instance) \
+#define FOREACH_BASE_IN_MODE_BEGIN(_view_layer, _v3d, _object_type, _object_mode, _instance) \
 { \
 	struct ObjectsInModeIteratorData data_ = {                                \
 		.object_mode = _object_mode,                                          \
+		.object_type = _object_type,                                          \
 		.view_layer = _view_layer,                                            \
 		.v3d = _v3d,                                                          \
 		.base_active = _view_layer->basact,                                   \
@@ -244,20 +246,20 @@ void BKE_view_layer_visible_bases_iterator_end(BLI_Iterator *iter);
 } ((void)0)
 
 #define FOREACH_BASE_IN_EDIT_MODE_BEGIN(_view_layer, _v3d, _instance)         \
-	FOREACH_BASE_IN_MODE_BEGIN(_view_layer, _v3d, OB_MODE_EDIT, _instance)
+	FOREACH_BASE_IN_MODE_BEGIN(_view_layer, _v3d, -1, OB_MODE_EDIT, _instance)
 
 #define FOREACH_BASE_IN_EDIT_MODE_END                                         \
 	FOREACH_BASE_IN_MODE_END
 
-#define FOREACH_OBJECT_IN_MODE_BEGIN(_view_layer, _v3d, _object_mode, _instance) \
-	FOREACH_BASE_IN_MODE_BEGIN(_view_layer, _v3d, _object_mode, _base) {      \
+#define FOREACH_OBJECT_IN_MODE_BEGIN(_view_layer, _v3d, _object_type, _object_mode, _instance) \
+	FOREACH_BASE_IN_MODE_BEGIN(_view_layer, _v3d, _object_type, _object_mode, _base) {      \
 		Object *_instance = _base->object;
 
 #define FOREACH_OBJECT_IN_MODE_END                                            \
 	} FOREACH_BASE_IN_MODE_END
 
-#define FOREACH_OBJECT_IN_EDIT_MODE_BEGIN(_view_layer, _instance)             \
-	FOREACH_BASE_IN_EDIT_MODE_BEGIN(_view_layer, _base) {                     \
+#define FOREACH_OBJECT_IN_EDIT_MODE_BEGIN(_view_layer, _v3d, _instance)       \
+	FOREACH_BASE_IN_EDIT_MODE_BEGIN(_view_layer, _v3d, _base) {               \
 		Object *_instance = _base->object;
 
 #define FOREACH_OBJECT_IN_EDIT_MODE_END                                       \
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index f525893a854..c591fa4bd80 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -1414,6 +1414,11 @@ void BKE_view_layer_renderable_objects_iterator_end(BLI_Iterator *UNUSED(iter))
 /** \name BKE_view_layer_bases_in_mode_iterator
  * \{ */
 
+static bool base_is_in_mode(struct ObjectsInModeIteratorData *data, Base *base)
+{
+	return (base->object->type == data->object_type) && (base->object->mode & data->object_mode) != 0;
+}
+
 void BKE_view_layer_bases_in_mode_iterator_begin(BLI_Iterator *iter, void *data_in)
 {
 	struct ObjectsInModeIteratorData *data = data_in;
@@ -1427,7 +1432,12 @@ void BKE_view_layer_bases_in_mode_iterator_begin(BLI_Iterator *iter, void *data_
 	iter->data = data_in;
 	iter->current = base;
 
-	if (object_bases_iterator_is_valid(data->v3d, base) == false) {
+	/* default type is active object type */
+	if (data->object_type < 0) {
+		data->object_type = base->object->type;
+	}
+
+	if (object_bases_iterator_is_valid(data->v3d, base) == false || !base_is_in_mode(data, base)) {
 		BKE_view_layer_bases_in_mode_iterator_next(iter);
 	}
 }
@@ -1449,9 +1459,8 @@ void BKE_view_layer_bases_in_mode_iterator_next(BLI_Iterator *iter)
 	}
 
 	while (base) {
-		if ((base->object->type == data->base_active->object->type) &&
-		    (base != data->base_active) &&
-		    (base->object->mode & data->object_mode) &&
+		if ((base != data->base_active) &&
+		    base_is_in_mode(data, base) &&
 		    object_bases_iterator_is_valid(data->v3d, base))
 		{
 			iter->current = base;
diff --git a/source/blender/blenkernel/intern/layer_utils.c b/source/blender/blenkernel/intern/layer_utils.c
index 2d446af9ac8..fb25ca3ece4 100644
--- a/source/blender/blenkernel/intern/layer_utils.c
+++ b/source/blender/blenkernel/intern/layer_utils.c
@@ -44,7 +44,7 @@ Base **BKE_view_layer_array_from_bases_in_mode_params(
         const struct ObjectsInModeParams *params)
 {
 	if (params->no_dup_data) {
-		FOREACH_BASE_IN_MODE_BEGIN(view_layer, v3d, params->object_mode, base_iter) {
+		FOREACH_BASE_IN_MODE_BEGIN(view_layer, v3d, -1, params->object_mode, base_iter) {
 			ID *id = base_iter->object->data;
 			if (id) {
 				id->tag |= LIB_TAG_DOIT;
@@ -55,7 +55,7 @@ Base **BKE_view_layer_array_from_bases_in_mode_params(
 	Base **base_array = NULL;
 	BLI_array_declare(base_array);
 
-	FOREACH_BASE_IN_MODE_BEGIN(view_layer, v3d, params->object_mode, base_iter) {
+	FOREACH_BASE_IN_MODE_BEGIN(view_layer, v3d, -1, params->object_mode, base_iter) {
 		if (params->filter_fn) {
 			if (!params->filter_fn(base_iter->object, params->filter_userdata)) {
 				continue;
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index ba61f376ce9..10b49950c0f 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -2087,7 +2087,7 @@ void DRW_draw_select_loop(
 #if 0
 			drw_engines_cache_populate(obact);
 #else
-			FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, obact->mode, ob_iter) {
+			FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, obact->type, obact->mode, ob_iter) {
 				drw_engines_cache_populate(ob_iter);
 			}
 			FOREACH_OBJECT_IN_MODE_END;
diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c
index f19fea32698..e44c1b02f22 100644
--- a/source/blender/editors/armature/armature_edit.c
+++ b/source/blender/editors/armature/armature_edit.c
@@ -709,7 +709,7 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op)
 	Object *obedit = NULL;
 	{
 		ViewLayer *view_layer = CTX_data_view_layer(C);
-		FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_MODE_EDIT, ob_iter) {
+		FOREACH_OBJECT_IN_EDIT_MODE_BEGIN (view_layer, v3d, ob_iter) {
 			if (ob_iter->data == arm) {
 				obedit = ob_iter;
 			}
diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c
index 715203135d9..4864f001782 100644
--- a/source/blender/editors/armature/pose_edit.c
+++ b/source/blender/editors/armature/pose_edit.c
@@ -744,7 +744,7 @@ static int pose_flip_names_exec(bContext *C, wmOperator *op)
 	View3D *v3d = CTX_wm_view3d(C);
 	const bool do_strip_numbers = RNA_boolean_get(op->ptr, "do_strip_numbers");
 
-	FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_MODE_POSE, ob)
+	FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob)
 	{
 		bArmature *arm = ob->data;
 		ListBase bones_names = {NULL};
@@ -1329,7 +1329,7 @@ static int pose_flip_quats_exec(bContext *C, wmOperator *UNUSED(op))
 
 	ViewLayer *view_layer = CTX_data_view_layer(C);
 	View3D *v3d = CTX_wm_view3d(C);
-	FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_MODE_POSE, ob_iter) {
+	FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter) {
 		bool changed = false;
 		/* loop through all selected pchans, flipping and keying (as needed) */
 		FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob_iter, pchan) {
diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c
index 2e7c90cee21..52e580a94af 100644
--- a/source/blender/editors/armature/pose_slide.c
+++ b/source/blender/editors/armature/pose_slide.c
@@ -1621,7 +1621,7 @@ static int pose_propagate_exec(bContext *C, wmOperator *op)
 		BLI_freelistN(&modeData.sel_markers);
 
 	/* updates + notifiers */
-	FOREACH_OBJECT_IN_MODE_BEGIN(view_layer, v3d, OB_MODE_POSE, ob) {
+	FOREACH_OBJECT_IN_MODE_BEGIN(view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) {
 		poseAnim_mapping_refresh(C, scene, ob);
 	} FOREACH_OBJECT_IN_MODE_END;
 
diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c
index 7945c85e6d7..0f21f154f48 100644
--- a/source/blender/editors/armature/pose_transform.c
+++ b/source/blender/editors/armature/pose_transform.c
@@ -235,7 +235,7 @@ static int pose_visual_transform_apply_exec(bContext *C, wmOperator *UNUSED(op))
 	View3D *v3d = CTX_wm_view3d(C);
 	Depsgraph *depsgraph = CTX_data_depsgraph(C);
 
-	FOREACH_OBJECT_IN_MODE_BEGIN(view_layer, v3d, OB_MODE_POSE, ob)
+	FOREACH_OBJECT_IN_MODE_BEGIN(view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob)
 	{
 		/* loop over all selected pchans
 		 *
@@ -781,7 +781,7 @@ static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op,
 	/* only clear relevant transforms for selected bones */
 	ViewLayer *view_layer = CTX_data_view_layer(C);
 	View3D *v3d = CTX_wm_view3d(C);
-	FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_MODE_POSE, ob_iter)
+	FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter)
 	{
 		Object *ob_eval = DEG_get_evaluated_object(CTX_data_depsgraph(C), ob_iter); // XXX: UGLY HACK (for autokey + clear transforms)
 		ListBase dsources = {NULL, NULL};
@@ -942,7 +942,7 @@ static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op)
 	float cframe = (float)CFRA;
 	const bool only_select = RNA_boolean_get(op->ptr, "only_selected");
 
-	FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_MODE_POSE, ob)
+	FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob)
 	{
 		if ((ob->adt) && (ob->adt->action)) {
 			/* XXX: this is just like this to avoid contaminating anything else;
diff --git a/source/blender/editors/armature/pose_utils.c b/source/blender/editors/armature/pose_utils.c
index dc4b969371d..8085aad77ee 100644
--- a/source/blender/editors/armature/pose_util

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list