diff options
author | Jeroen Bakker <j.bakker@atmind.nl> | 2019-05-08 10:45:20 +0300 |
---|---|---|
committer | Jeroen Bakker <j.bakker@atmind.nl> | 2019-05-09 14:27:23 +0300 |
commit | 8342a124c462104c12a98cca0b16e69920316346 (patch) | |
tree | cfcef9e21038d332476ec38abe5cad83eb27face /source | |
parent | f877022956df3b55e30c312b20f364fd2657805c (diff) |
DepsGraph: Multi ViewLayer Selection
When using multiple viewlayers and switching between them the selection
gets buggy. The reason for this is that the select_id is updated based
on the index in the viewlayer. This makes the select_id not unique as
objects might be shared or not shared at all.
This fix will update the select_id on all objects in main. This will be triggered in all the selection operators.
Reviewed By: sergey, brecht
Maniphest Tasks: T55617
Differential Revision: https://developer.blender.org/D4824
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_object.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 11 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc | 2 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/depsgraph_query_iter.cc | 1 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_armature.c | 9 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 2 | ||||
-rw-r--r-- | source/blender/draw/modes/edit_metaball_mode.c | 5 | ||||
-rw-r--r-- | source/blender/draw/modes/object_mode.c | 7 | ||||
-rw-r--r-- | source/blender/editors/armature/armature_select.c | 8 | ||||
-rw-r--r-- | source/blender/editors/metaball/mball_edit.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_select.c | 24 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_object_types.h | 8 |
12 files changed, 55 insertions, 26 deletions
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 49b35bfccc1..c373fbfe478 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -100,6 +100,8 @@ bool BKE_object_is_mode_compat(const struct Object *ob, eObjectMode object_mode) bool BKE_object_data_is_in_editmode(const struct ID *id); +void BKE_object_update_select_id(struct Main *bmain); + typedef enum eObjectVisibilityResult { OB_VISIBLE_SELF = 1, OB_VISIBLE_PARTICLES = 2, diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 38a8ad2769a..6c2bd5e6127 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -4487,3 +4487,14 @@ void BKE_object_type_set_empty_for_versioning(Object *ob) } ob->mode = OB_MODE_OBJECT; } + +/* Updates select_id of all objects in the given bmain. */ +void BKE_object_update_select_id(struct Main *bmain) +{ + Object *ob = bmain->objects.first; + int select_id = 1; + while (ob) { + ob->runtime.select_id = select_id++; + ob = ob->id.next; + } +}
\ No newline at end of file diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc index 60b711d76d3..b36213d6890 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc @@ -92,7 +92,6 @@ void DepsgraphNodeBuilder::build_view_layer(Scene *scene, /* Get pointer to a CoW version of scene ID. */ Scene *scene_cow = get_cow_datablock(scene); /* Scene objects. */ - int select_id = 1; /* NOTE: Base is used for function bindings as-is, so need to pass CoW base, * but object is expected to be an original one. Hence we go into some * tricks here iterating over the view layer. */ @@ -108,7 +107,6 @@ void DepsgraphNodeBuilder::build_view_layer(Scene *scene, build_object(base_index, base->object, linked_state, true); ++base_index; } - base->object->select_id = select_id++; } build_layer_collections(&view_layer->layer_collections); if (scene->camera != NULL) { diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc index d3bf27747c0..a9fe7c6d5e7 100644 --- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc +++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc @@ -145,7 +145,6 @@ bool deg_objects_dupli_iterator_next(BLI_Iterator *iter) Object *dupli_parent = data->dupli_parent; Object *temp_dupli_object = &data->temp_dupli_object; *temp_dupli_object = *dob->ob; - temp_dupli_object->select_id = dupli_parent->select_id; temp_dupli_object->base_flag = dupli_parent->base_flag | BASE_FROM_DUPLI; temp_dupli_object->base_local_view_bits = dupli_parent->base_local_view_bits; temp_dupli_object->dt = MIN2(temp_dupli_object->dt, dupli_parent->dt); diff --git a/source/blender/draw/intern/draw_armature.c b/source/blender/draw/intern/draw_armature.c index a94d47496e0..6361ff63fd4 100644 --- a/source/blender/draw/intern/draw_armature.c +++ b/source/blender/draw/intern/draw_armature.c @@ -37,6 +37,8 @@ #include "BKE_armature.h" +#include "DEG_depsgraph_query.h" + #include "ED_armature.h" #include "UI_resources.h" @@ -1848,7 +1850,9 @@ static void draw_armature_edit(Object *ob) const bool show_text = DRW_state_show_text(); const bool show_relations = ((draw_ctx->v3d->flag & V3D_HIDE_HELPLINES) == 0); - for (eBone = arm->edbo->first, index = ob->select_id; eBone; + const Object *orig_object = DEG_get_original_object(ob); + + for (eBone = arm->edbo->first, index = orig_object->runtime.select_id; eBone; eBone = eBone->next, index += 0x10000) { if (eBone->layer & arm->layer) { if ((eBone->flag & BONE_HIDDEN_A) == 0) { @@ -1943,7 +1947,8 @@ static void draw_armature_pose(Object *ob, const float const_color[4]) } if (arm->flag & ARM_POSEMODE) { - index = ob->select_id; + const Object *orig_object = DEG_get_original_object(ob); + index = orig_object->runtime.select_id; } } diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 6499957b123..3bf3eaae4a2 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -2386,7 +2386,7 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph, /* This relies on dupli instances being after their instancing object. */ if ((ob->base_flag & BASE_FROM_DUPLI) == 0) { Object *ob_orig = DEG_get_original_object(ob); - DRW_select_load_id(ob_orig->select_id); + DRW_select_load_id(ob_orig->runtime.select_id); } DST.dupli_parent = data_.dupli_parent; DST.dupli_source = data_.dupli_object_current; diff --git a/source/blender/draw/modes/edit_metaball_mode.c b/source/blender/draw/modes/edit_metaball_mode.c index aa7c6863423..e94d394b98f 100644 --- a/source/blender/draw/modes/edit_metaball_mode.c +++ b/source/blender/draw/modes/edit_metaball_mode.c @@ -26,6 +26,8 @@ #include "BKE_object.h" +#include "DEG_depsgraph_query.h" + #include "ED_mball.h" /* If builtin shaders are needed */ @@ -160,7 +162,8 @@ static void EDIT_METABALL_cache_populate(void *vedata, Object *ob) copy_v3_v3(draw_scale_xform[2], scamat[2]); } - int select_id = ob->select_id; + const Object *orig_object = DEG_get_original_object(ob); + int select_id = orig_object->runtime.select_id; for (MetaElem *ml = mb->editelems->first; ml != NULL; ml = ml->next, select_id += 0x10000) { float world_pos[3]; mul_v3_m4v3(world_pos, ob->obmat, &ml->x); diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index 5f4888812f9..c494e222b3d 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -1925,13 +1925,14 @@ static void camera_view3d_stereoscopy_display_extra(OBJECT_ShadingGroupList *sgl static void camera_view3d_reconstruction(OBJECT_ShadingGroupList *sgl, Scene *scene, View3D *v3d, - const Object *camera_object, + Object *camera_object, Object *ob, const float color[4], const bool is_select) { const DRWContextState *draw_ctx = DRW_context_state_get(); Camera *cam = ob->data; + const Object *orig_camera_object = DEG_get_original_object(camera_object); if ((v3d->flag2 & V3D_SHOW_RECONSTRUCTION) == 0) { return; @@ -2012,7 +2013,7 @@ static void camera_view3d_reconstruction(OBJECT_ShadingGroupList *sgl, } if (is_select) { - DRW_select_load_id(camera_object->select_id | (track_index << 16)); + DRW_select_load_id(orig_camera_object->runtime.select_id | (track_index << 16)); track_index++; } @@ -2078,7 +2079,7 @@ static void DRW_shgroup_camera(OBJECT_ShadingGroupList *sgl, Object *ob, ViewLay RegionView3D *rv3d = draw_ctx->rv3d; Camera *cam = ob->data; - const Object *camera_object = DEG_get_evaluated_object(draw_ctx->depsgraph, v3d->camera); + Object *camera_object = DEG_get_evaluated_object(draw_ctx->depsgraph, v3d->camera); const bool is_select = DRW_state_is_select(); const bool is_active = (ob == camera_object); const bool look_through = (is_active && (rv3d->persp == RV3D_CAMOB)); diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c index fbbb68d2003..23ddf77e63d 100644 --- a/source/blender/editors/armature/armature_select.c +++ b/source/blender/editors/armature/armature_select.c @@ -70,7 +70,7 @@ Base *ED_armature_base_and_ebone_from_select_buffer(Base **bases, EditBone *ebone = NULL; /* TODO(campbell): optimize, eg: sort & binary search. */ for (uint base_index = 0; base_index < bases_len; base_index++) { - if (bases[base_index]->object->select_id == hit_object) { + if (bases[base_index]->object->runtime.select_id == hit_object) { base = bases[base_index]; break; } @@ -94,7 +94,7 @@ Object *ED_armature_object_and_ebone_from_select_buffer(Object **objects, EditBone *ebone = NULL; /* TODO(campbell): optimize, eg: sort & binary search. */ for (uint ob_index = 0; ob_index < objects_len; ob_index++) { - if (objects[ob_index]->select_id == hit_object) { + if (objects[ob_index]->runtime.select_id == hit_object) { ob = objects[ob_index]; break; } @@ -118,7 +118,7 @@ Base *ED_armature_base_and_bone_from_select_buffer(Base **bases, Bone *bone = NULL; /* TODO(campbell): optimize, eg: sort & binary search. */ for (uint base_index = 0; base_index < bases_len; base_index++) { - if (bases[base_index]->object->select_id == hit_object) { + if (bases[base_index]->object->runtime.select_id == hit_object) { base = bases[base_index]; break; } @@ -300,6 +300,7 @@ static int armature_select_linked_invoke(bContext *C, wmOperator *op, const wmEv const bool sel = !RNA_boolean_get(op->ptr, "deselect"); view3d_operator_needs_opengl(C); + BKE_object_update_select_id(CTX_data_main(C)); Base *base = NULL; bone = get_nearest_bone(C, event->mval, true, &base); @@ -1817,6 +1818,7 @@ static int armature_shortest_path_pick_invoke(bContext *C, wmOperator *op, const Base *base_dst = NULL; view3d_operator_needs_opengl(C); + BKE_object_update_select_id(CTX_data_main(C)); ebone_src = arm->act_edbone; ebone_dst = get_nearest_bone(C, event->mval, false, &base_dst); diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c index 54143822b61..18ff7ae1a5e 100644 --- a/source/blender/editors/metaball/mball_edit.c +++ b/source/blender/editors/metaball/mball_edit.c @@ -738,7 +738,7 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool dese } const uint hit_object = hitresult & 0xFFFF; - if (vc.obedit->select_id != hit_object) { + if (vc.obedit->runtime.select_id != hit_object) { continue; } diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 2ce23486476..c916e470322 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -57,6 +57,7 @@ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" #include "BKE_global.h" +#include "BKE_main.h" #include "BKE_armature.h" #include "BKE_context.h" @@ -1170,6 +1171,7 @@ static int view3d_lasso_select_exec(bContext *C, wmOperator *op) if (mcords) { view3d_operator_needs_opengl(C); + BKE_object_update_select_id(CTX_data_main(C)); /* setup view context for argument to callbacks */ ED_view3d_viewcontext_init(C, &vc); @@ -1337,7 +1339,7 @@ static Base *object_mouse_select_menu( if (buffer) { for (int a = 0; a < hits; a++) { /* index was converted */ - if (base->object->select_id == (buffer[(4 * a) + 3] & ~0xFFFF0000)) { + if (base->object->runtime.select_id == (buffer[(4 * a) + 3] & ~0xFFFF0000)) { ok = true; break; } @@ -1609,7 +1611,7 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, else { /* only exclude active object when it is selected... */ if (BASACT(view_layer) && (BASACT(view_layer)->flag & BASE_SELECTED) && hits > 1) { - notcol = BASACT(view_layer)->object->select_id; + notcol = BASACT(view_layer)->object->runtime.select_id; } for (a = 0; a < hits; a++) { @@ -1623,7 +1625,7 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, base = FIRSTBASE(view_layer); while (base) { if (BASE_SELECTABLE(v3d, base)) { - if (base->object->select_id == selcol) { + if (base->object->runtime.select_id == selcol) { break; } } @@ -1654,13 +1656,13 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, if (has_bones) { /* skip non-bone objects */ if ((buffer[4 * a + 3] & 0xFFFF0000)) { - if (base->object->select_id == (buffer[(4 * a) + 3] & 0xFFFF)) { + if (base->object->runtime.select_id == (buffer[(4 * a) + 3] & 0xFFFF)) { basact = base; } } } else { - if (base->object->select_id == (buffer[(4 * a) + 3] & 0xFFFF)) { + if (base->object->runtime.select_id == (buffer[(4 * a) + 3] & 0xFFFF)) { basact = base; } } @@ -1693,6 +1695,7 @@ Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2]) /* setup view context for argument to callbacks */ view3d_operator_needs_opengl(C); + BKE_object_update_select_id(CTX_data_main(C)); ED_view3d_viewcontext_init(C, &vc); @@ -1878,7 +1881,7 @@ static bool ed_object_select_pick(bContext *C, /* if there's bundles in buffer select bundles first, * so non-camera elements should be ignored in buffer */ - if (basact->object->select_id != (hitresult & 0xFFFF)) { + if (basact->object->runtime.select_id != (hitresult & 0xFFFF)) { continue; } @@ -2129,6 +2132,7 @@ static int view3d_select_exec(bContext *C, wmOperator *op) RNA_int_get_array(op->ptr, "location", location); view3d_operator_needs_opengl(C); + BKE_object_update_select_id(CTX_data_main(C)); if (object) { obedit = NULL; @@ -2652,7 +2656,7 @@ static bool do_meta_box_select(ViewContext *vc, const rcti *rect, const eSelectO } const uint hit_object = hitresult & 0xFFFF; - if (vc->obedit->select_id != hit_object) { + if (vc->obedit->runtime.select_id != hit_object) { continue; } @@ -2803,7 +2807,7 @@ static bool do_object_box_select(bContext *C, ViewContext *vc, rcti *rect, const for (Base *base = vc->view_layer->object_bases.first; base; base = base->next) { if (BASE_SELECTABLE(v3d, base)) { - if ((base->object->select_id & 0x0000FFFF) != 0) { + if ((base->object->runtime.select_id & 0x0000FFFF) != 0) { BLI_array_append(bases, base); } } @@ -2893,7 +2897,7 @@ static bool do_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, const e /* Select the next bone if we're not switching bases. */ if (col + 4 != col_end) { - if ((base->object->select_id & 0x0000FFFF) != (col[4] & 0x0000FFFF)) { + if ((base->object->runtime.select_id & 0x0000FFFF) != (col[4] & 0x0000FFFF)) { break; } if (base->object->pose != NULL) { @@ -2930,6 +2934,7 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op) bool changed_multi = false; view3d_operator_needs_opengl(C); + BKE_object_update_select_id(CTX_data_main(C)); /* setup view context for argument to callbacks */ ED_view3d_viewcontext_init(C, &vc); @@ -3670,6 +3675,7 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op) if (obedit || BKE_paint_select_elem_test(obact) || (obact && (obact->mode & OB_MODE_POSE))) { view3d_operator_needs_opengl(C); + BKE_object_update_select_id(CTX_data_main(C)); FOREACH_OBJECT_IN_MODE_BEGIN (vc.view_layer, vc.v3d, obact->type, obact->mode, ob_iter) { ED_view3d_viewcontext_init_object(&vc, ob_iter); diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 1aeb4a2f4d2..ae781ac4e9e 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -136,6 +136,10 @@ typedef struct Object_Runtime { /** Only used for drawing the parent/child help-line. */ float parent_display_origin[3]; + /** Selection id of this object; only available in the original object */ + int select_id; + char _pad1[4]; + /** Axis aligned boundbox (in localspace). */ struct BoundBox *bb; @@ -365,9 +369,7 @@ typedef struct Object { char empty_image_visibility_flag; char empty_image_depth; char empty_image_flag; - char _pad8[1]; - - int select_id; + char _pad8[5]; /** Contains data for levels of detail. */ ListBase lodlevels; |