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:
authorAlexander Gavrilov <angavrilov@gmail.com>2018-12-01 19:43:10 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2018-12-01 19:44:24 +0300
commit18f06186778ea67583a362a611b1efa8c9da5fbd (patch)
tree70f2fd8b2d9f9f0d9c47899d2ea210d1b9d8a71a /source/blender/blenkernel
parent9ed522db735b1d798a5d68c6bf547e8123d33a4b (diff)
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.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_layer.h14
-rw-r--r--source/blender/blenkernel/intern/layer.c17
-rw-r--r--source/blender/blenkernel/intern/layer_utils.c4
3 files changed, 23 insertions, 12 deletions
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;